(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";

var _jquery = _interopRequireDefault(require("jquery"));

var _Modeler = _interopRequireDefault(require("bpmn-js/lib/Modeler"));

var _bpmnJsPropertiesPanel = _interopRequireDefault(require("bpmn-js-properties-panel"));

var _activiti = _interopRequireDefault(require("../resources/properties-panel/provider/activiti"));

var _activiti2 = _interopRequireDefault(require("../resources/activiti.json"));

var _customTranslate = _interopRequireDefault(require("../resources/customTranslate/customTranslate"));

var _customControls = _interopRequireDefault(require("../resources/customControls"));

var _tools = _interopRequireDefault(require("../resources/tools"));

var _newDiagram = _interopRequireDefault(require("../resources/newDiagram.bpmn"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

//import propertiesPanelModule from '../resources/properties-panel';
const proHost = window.location.protocol + "//" + window.location.host;
const href = window.location.href.split("bpmnjs")[0];
const key = href.split(window.location.host)[1];
const publicurl = proHost + key; // 添加翻译组件

var customTranslateModule = {
  translate: ['value', _customTranslate.default]
};
var container = (0, _jquery.default)('#js-drop-zone');
var canvas = (0, _jquery.default)('#js-canvas');
var bpmnModeler = new _Modeler.default({
  container: canvas,
  propertiesPanel: {
    parent: '#js-properties-panel'
  },
  additionalModules: [_bpmnJsPropertiesPanel.default, _activiti.default, _customControls.default, customTranslateModule],
  moddleExtensions: {
    activiti: _activiti2.default
  }
});
container.removeClass('with-diagram'); // 判断浏览器支持程度

if (!window.FileList || !window.FileReader) {
  window.alert('请使用谷歌、火狐、IE10+浏览器');
} else {
  _tools.default.registerFileDrop(container, _tools.default.createDiagram(_newDiagram.default, bpmnModeler, container));
}

(0, _jquery.default)(function () {
  // 创建bpmn
  var param = _tools.default.getUrlParam(window.location.href);

  (0, _jquery.default)('.item').show();

  if (param.type === 'updateBpmn') {
    //加载后台方法获取xml
    _jquery.default.ajax({
      url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/processDefinition/getProcessDefineXMLByModelId',
      // url: 'http://localhost:8080/processDefinition/getDefinitionXML',
      type: 'GET',
      data: param,
      dataType: 'text',
headers: {
                    'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'),
                  },
      success: function (result) {
        var newXmlData = result;

        _tools.default.createDiagram(newXmlData, bpmnModeler, container);
      },
      error: function (err) {
        console.log(err);
      }
    });
  } else if (param.type === 'lookBpmn') {
    //编辑bpmn
    (0, _jquery.default)('.item').hide();
    (0, _jquery.default)('.download').show();
    const Id = param.deploymentFileUUID || '6d4af2dc-bab0-11ea-b584-3cf011eaafca';
    const Name = param.deploymentName || 'String.bpmn';
    const instanceId = param.instanceId;
    (0, _jquery.default)('.djs-palette').hide();
    (0, _jquery.default)('.properties-panel-parent').hide();

    var param = {
      "deploymentId": Id,
      "resourceName": decodeURI(Name)
    };

    if (instanceId) {
      var param1 = {
        instanceId
      };

      _jquery.default.ajax({
        url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/activitiHistory/gethighLine',
        // url: 'http://localhost:8080/activitiHistory/gethighLine',
        type: 'GET',
        data: param1,
        dataType: 'json',
headers: {
                    'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'),
                  },
        success: function (result) {

          var ColorJson = _tools.default.getByColor(result.data);

          _jquery.default.ajax({
            url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/processDefinition/getDefinitionXML',
            // url: 'http://localhost:8080/processDefinition/getDefinitionXML',
            type: 'GET',
            data: param,
            dataType: 'text',
headers: {
                    'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'),
                  },
            success: function (result) {
              var newXmlData = result;

              _tools.default.createDiagram(newXmlData, bpmnModeler, container);

              setTimeout(function () {
                for (var i in ColorJson) {
                  _tools.default.setColor(ColorJson[i], bpmnModeler);
                }
              }, 200);
            },
            error: function (err) {
              console.log(err);
            }
          });
        },
        error: function (err) {
          console.log(err);
        }
      });
    } else {
      //加载后台方法获取xml
      _jquery.default.ajax({
        url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/processDefinition/getDefinitionXML',
        // url: 'http://localhost:8080/processDefinition/getDefinitionXML',
        type: 'GET',
        data: param,
        dataType: 'text',
headers: {
                    'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'),
                  },
        success: function (result) {
          var newXmlData = result;

          _tools.default.createDiagram(newXmlData, bpmnModeler, container);
        },
        error: function (err) {
          console.log(err);
        }
      });
    }
  } else if (param.type === "historyBpmn") {
    // bpmn历史
    (0, _jquery.default)('.item').hide();
    (0, _jquery.default)('.download').show();
  } // 点击新增


  (0, _jquery.default)('#js-download-diagram').on("click", function () {
    _tools.default.syopen('alert');
  }); // 点击取消

  (0, _jquery.default)('.cancel').on("click", function () {
    _tools.default.syhide('alert');
  }); // 点击确定

  (0, _jquery.default)('#sure').on('click', function () {
    // const text=$("#deploymentName").val()
    const modelId = param.modelId;
    _tools.default.saveBpmn(bpmnModeler,modelId);
  }); // 点击下载

  (0, _jquery.default)("#downloadBpmn").on("click", function () {
    _tools.default.downLoad(bpmnModeler);
  }); // 点击上传

  (0, _jquery.default)("#uploadFile").on("change", function () {
    _tools.default.upload(bpmnModeler, container);
  });
});

},{"../resources/activiti.json":568,"../resources/customControls":571,"../resources/customTranslate/customTranslate":572,"../resources/newDiagram.bpmn":574,"../resources/properties-panel/provider/activiti":610,"../resources/tools":676,"bpmn-js-properties-panel":2,"bpmn-js/lib/Modeler":15,"jquery":348}],2:[function(require,module,exports){
module.exports = require('./lib');

},{"./lib":12}],3:[function(require,module,exports){
'use strict';

var escapeHTML = require('./Utils').escapeHTML;

var domify = require('min-dom').domify,
    domQuery = require('min-dom').query,
    domQueryAll = require('min-dom').queryAll,
    domRemove = require('min-dom').remove,
    domClasses = require('min-dom').classes,
    domClosest = require('min-dom').closest,
    domAttr = require('min-dom').attr,
    domDelegate = require('min-dom').delegate,
    domMatches = require('min-dom').matches;

var forEach = require('lodash/forEach'),
    filter = require('lodash/filter'),
    get = require('lodash/get'),
    keys = require('lodash/keys'),
    isEmpty = require('lodash/isEmpty'),
    isArray = require('lodash/isArray'),
    xor = require('lodash/xor'),
    debounce = require('lodash/debounce');

var updateSelection = require('selection-update');

var scrollTabs = require('scroll-tabs').default;

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var HIDE_CLASS = 'bpp-hidden';
var DEBOUNCE_DELAY = 300;


function isToggle(node) {
  return node.type === 'checkbox' || node.type === 'radio';
}

function isSelect(node) {
  return node.type === 'select-one';
}

function isContentEditable(node) {
  return domAttr(node, 'contenteditable');
}

function getPropertyPlaceholders(node) {
  var selector = 'input[name], textarea[name], [data-value], [contenteditable]';
  var placeholders = domQueryAll(selector, node);
  if ((!placeholders || !placeholders.length) && domMatches(node, selector)) {
    placeholders = [ node ];
  }
  return placeholders;
}

/**
 * Return all active form controls.
 * This excludes the invisible controls unless all is true
 *
 * @param {Element} node
 * @param {Boolean} [all=false]
 */
function getFormControls(node, all) {
  var controls = domQueryAll('input[name], textarea[name], select[name], [contenteditable]', node);

  if (!controls || !controls.length) {
    controls = domMatches(node, 'option') ? [ node ] : controls;
  }

  if (!all) {
    controls = filter(controls, function(node) {
      return !domClosest(node, '.' + HIDE_CLASS);
    });
  }

  return controls;
}

function getFormControlValuesInScope(entryNode) {
  var values = {};

  var controlNodes = getFormControls(entryNode);

  forEach(controlNodes, function(controlNode) {
    var value = controlNode.value;

    var name = domAttr(controlNode, 'name') || domAttr(controlNode, 'data-name');

    // take toggle state into account for radio / checkboxes
    if (isToggle(controlNode)) {
      if (controlNode.checked) {
        if (!domAttr(controlNode, 'value')) {
          value = true;
        } else {
          value = controlNode.value;
        }
      } else {
        value = null;
      }
    } else
    if (isContentEditable(controlNode)) {
      value = controlNode.innerText;
    }

    if (value !== null) {
      // return the actual value
      // handle serialization in entry provider
      // (ie. if empty string should be serialized or not)
      values[name] = value;
    }
  });

  return values;

}

/**
 * Extract input values from entry node
 *
 * @param  {DOMElement} entryNode
 * @returns {Object}
 */
function getFormControlValues(entryNode) {

  var values;

  var listContainer = domQuery('[data-list-entry-container]', entryNode);
  if (listContainer) {
    values = [];
    var listNodes = listContainer.children || [];
    forEach(listNodes, function(listNode) {
      values.push(getFormControlValuesInScope(listNode));
    });
  } else {
    values = getFormControlValuesInScope(entryNode);
  }

  return values;
}

/**
 * Return true if the given form extracted value equals
 * to an old cached version.
 *
 * @param {Object} value
 * @param {Object} oldValue
 * @return {Boolean}
 */
function valueEqual(value, oldValue) {

  if (value && !oldValue) {
    return false;
  }

  var allKeys = keys(value).concat(keys(oldValue));

  return allKeys.every(function(key) {
    return value[key] === oldValue[key];
  });
}

/**
 * Return true if the given form extracted value(s)
 * equal an old cached version.
 *
 * @param {Array<Object>|Object} values
 * @param {Array<Object>|Object} oldValues
 * @return {Boolean}
 */
function valuesEqual(values, oldValues) {

  if (isArray(values)) {

    if (values.length !== oldValues.length) {
      return false;
    }

    return values.every(function(v, idx) {
      return valueEqual(v, oldValues[idx]);
    });
  }

  return valueEqual(values, oldValues);
}

/**
 * Return a mapping of { id: entry } for all entries in the given groups in the given tabs.
 *
 * @param {Object} tabs
 * @return {Object}
 */
function extractEntries(tabs) {
  return keyBy(flattenDeep(map(flattenDeep(map(tabs, 'groups')), 'entries')), 'id');
}

/**
 * Return a mapping of { id: group } for all groups in the given tabs.
 *
 * @param {Object} tabs
 * @return {Object}
 */
function extractGroups(tabs) {
  return keyBy(flattenDeep(map(tabs, 'groups')), 'id');
}

/**
 * A properties panel implementation.
 *
 * To use it provide a `propertiesProvider` component that knows
 * about which properties to display.
 *
 * Properties edit state / visibility can be intercepted
 * via a custom {@link PropertiesActivator}.
 *
 * @class
 * @constructor
 *
 * @param {Object} config
 * @param {EventBus} eventBus
 * @param {Modeling} modeling
 * @param {PropertiesProvider} propertiesProvider
 * @param {Canvas} canvas
 * @param {CommandStack} commandStack
 */
function PropertiesPanel(config, eventBus, modeling, propertiesProvider, commandStack, canvas) {

  this._eventBus = eventBus;
  this._modeling = modeling;
  this._commandStack = commandStack;
  this._canvas = canvas;
  this._propertiesProvider = propertiesProvider;

  this._init(config);
}

PropertiesPanel.$inject = [
  'config.propertiesPanel',
  'eventBus',
  'modeling',
  'propertiesProvider',
  'commandStack',
  'canvas'
];

module.exports = PropertiesPanel;


PropertiesPanel.prototype._init = function(config) {

  var canvas = this._canvas,
      eventBus = this._eventBus;

  var self = this;

  /**
   * Select the root element once it is added to the canvas
   */
  eventBus.on('root.added', function(e) {
    var element = e.element;

    if (isImplicitRoot(element)) {
      return;
    }

    self.update(element);
  });

  eventBus.on('selection.changed', function(e) {
    var newElement = e.newSelection[0];

    var rootElement = canvas.getRootElement();

    if (isImplicitRoot(rootElement)) {
      return;
    }

    self.update(newElement);
  });

  // add / update tab-bar scrolling
  eventBus.on([
    'propertiesPanel.changed',
    'propertiesPanel.resized'
  ], function(event) {

    var tabBarNode = domQuery('.bpp-properties-tab-bar', self._container);

    if (!tabBarNode) {
      return;
    }

    var scroller = scrollTabs.get(tabBarNode);

    if (!scroller) {

      // we did not initialize yet, do that
      // now and make sure we select the active
      // tab on scroll update
      scroller = scrollTabs(tabBarNode, {
        selectors: {
          tabsContainer: '.bpp-properties-tabs-links',
          tab: '.bpp-properties-tabs-links li',
          ignore: '.bpp-hidden',
          active: '.bpp-active'
        }
      });


      scroller.on('scroll', function(newActiveNode, oldActiveNode, direction) {

        var linkNode = domQuery('[data-tab-target]', newActiveNode);

        var tabId = domAttr(linkNode, 'data-tab-target');

        self.activateTab(tabId);
      });
    }

    // react on tab changes and or tabContainer resize
    // and make sure the active tab is shown completely
    scroller.update();
  });

  eventBus.on('elements.changed', function(e) {

    var current = self._current;
    var element = current && current.element;

    if (element) {
      if (e.elements.indexOf(element) !== -1) {
        self.update(element);
      }
    }
  });

  eventBus.on('elementTemplates.changed', function() {
    var current = self._current;
    var element = current && current.element;

    if (element) {
      self.update(element);
    }
  });

  eventBus.on('diagram.destroy', function() {
    self.detach();
  });

  this._container = domify('<div class="bpp-properties-panel"></div>');

  this._bindListeners(this._container);

  if (config && config.parent) {
    this.attachTo(config.parent);
  }
};


PropertiesPanel.prototype.attachTo = function(parentNode) {

  if (!parentNode) {
    throw new Error('parentNode required');
  }

  // ensure we detach from the
  // previous, old parent
  this.detach();

  // unwrap jQuery if provided
  if (parentNode.get && parentNode.constructor.prototype.jquery) {
    parentNode = parentNode.get(0);
  }

  if (typeof parentNode === 'string') {
    parentNode = domQuery(parentNode);
  }

  var container = this._container;

  parentNode.appendChild(container);

  this._emit('attach');
};

PropertiesPanel.prototype.detach = function() {

  var container = this._container,
      parentNode = container.parentNode;

  if (!parentNode) {
    return;
  }

  this._emit('detach');

  parentNode.removeChild(container);
};


/**
 * Select the given tab within the properties panel.
 *
 * @param {Object|String} tab
 */
PropertiesPanel.prototype.activateTab = function(tab) {

  var tabId = typeof tab === 'string' ? tab : tab.id;

  var current = this._current;

  var panelNode = current.panel;

  var allTabNodes = domQueryAll('.bpp-properties-tab', panelNode),
      allTabLinkNodes = domQueryAll('.bpp-properties-tab-link', panelNode);
  forEach(allTabNodes, function(tabNode) {

    var currentTabId = domAttr(tabNode, 'data-tab');
    if(currentTabId == 'general'){
      domClasses(tabNode).toggle('bpp-active', tabId === currentTabId);
    }
  });

  forEach(allTabLinkNodes, function(tabLinkNode) {

    var tabLink = domQuery('[data-tab-target]', tabLinkNode),
        currentTabId = domAttr(tabLink, 'data-tab-target');

    domClasses(tabLinkNode).toggle('bpp-active', tabId === currentTabId);
  });
};

/**
 * Update the DOM representation of the properties panel
 */
PropertiesPanel.prototype.update = function(element) {
  var current = this._current;

  // no actual selection change
  var needsCreate = true;

  if (typeof element === 'undefined') {

    // use RootElement of BPMN diagram to generate properties panel if no element is selected
    element = this._canvas.getRootElement();
  }

  var newTabs = this._propertiesProvider.getTabs(element);

  if (current && current.element === element) {
    // see if we can reuse the existing panel

    needsCreate = this._entriesChanged(current, newTabs);
  }

  if (needsCreate) {

    if (current) {

      // get active tab from the existing panel before remove it
      var activeTabNode = domQuery('.bpp-properties-tab.bpp-active', current.panel);

      var activeTabId;
      if (activeTabNode) {
        activeTabId = domAttr(activeTabNode, 'data-tab');
      }

      // remove old panel
      domRemove(current.panel);
    }

    this._current = this._create(element, newTabs);

    // activate the saved active tab from the remove panel or the first tab
    (activeTabId) ? this.activateTab(activeTabId) : this.activateTab(this._current.tabs[0]);

  }

  if (this._current) {
    // make sure correct tab contents are visible
    this._updateActivation(this._current);

  }

  this._emit('changed');
};


/**
 * Returns true if one of two groups has different entries than the other.
 *
 * @param  {Object} current
 * @param  {Object} newTabs
 * @return {Boolean}
 */
PropertiesPanel.prototype._entriesChanged = function(current, newTabs) {

  var oldEntryIds = keys(current.entries),
      newEntryIds = keys(extractEntries(newTabs));

  return !isEmpty(xor(oldEntryIds, newEntryIds));
};

PropertiesPanel.prototype._emit = function(event) {
  this._eventBus.fire('propertiesPanel.' + event, { panel: this, current: this._current });
};

PropertiesPanel.prototype._bindListeners = function(container) {

  var self = this;

  // handles a change for a given event
  var handleChange = function handleChange(event) {

    // see if we handle a change inside a [data-entry] element.
    // if not, drop out
    var inputNode = event.delegateTarget,
        entryNode = domClosest(inputNode, '[data-entry]'),
        entryId, entry;

    // change from outside a [data-entry] element, simply ignore
    if (!entryNode) {
      return;
    }

    entryId = domAttr(entryNode, 'data-entry');
    entry = self.getEntry(entryId);

    var values = getFormControlValues(entryNode);

    if (event.type === 'change') {

      // - if the "data-on-change" attribute is present and a value is changed,
      //   then the associated action is performed.
      // - if the associated action returns "true" then an update to the business
      //   object is done
      // - if it does not return "true", then only the DOM content is updated
      var onChangeAction = domAttr(inputNode, 'data-on-change');

      if (onChangeAction) {
        var isEntryDirty = self.executeAction(entry, entryNode, onChangeAction, event);

        if (!isEntryDirty) {
          return self.update(self._current.element);
        }
      }
    }
    self.applyChanges(entry, values, entryNode);
    self.updateState(entry, entryNode);
  };

  // debounce update only elements that are target of key events,
  // i.e. INPUT and TEXTAREA. SELECTs will trigger an immediate update anyway.
  domDelegate.bind(container, 'input, textarea, [contenteditable]', 'input', debounce(handleChange, DEBOUNCE_DELAY));
  domDelegate.bind(container, 'input, textarea, select, [contenteditable]', 'change', handleChange);

  // handle key events
  domDelegate.bind(container, 'select', 'keydown', function(e) {

    // DEL
    if (e.keyCode === 46) {
      e.stopPropagation();
      e.preventDefault();
    }
  });

  domDelegate.bind(container, '[data-action]', 'click', function onClick(event) {

    // triggers on all inputs
    var inputNode = event.delegateTarget,
        entryNode = domClosest(inputNode, '[data-entry]');

    var actionId = domAttr(inputNode, 'data-action'),
        entryId = domAttr(entryNode, 'data-entry');

    var entry = self.getEntry(entryId);

    var isEntryDirty = self.executeAction(entry, entryNode, actionId, event);

    if (isEntryDirty) {
      var values = getFormControlValues(entryNode);

      self.applyChanges(entry, values, entryNode);
    }

    self.updateState(entry, entryNode);
  });

  function handleInput(event, element) {
    // triggers on all inputs
    var inputNode = event.delegateTarget;

    var entryNode = domClosest(inputNode, '[data-entry]');

    // only work on data entries
    if (!entryNode) {
      return;
    }

    var eventHandlerId = domAttr(inputNode, 'data-blur'),
        entryId = domAttr(entryNode, 'data-entry');

    var entry = self.getEntry(entryId);

    var isEntryDirty = self.executeAction(entry, entryNode, eventHandlerId, event);

    if (isEntryDirty) {
      var values = getFormControlValues(entryNode);

      self.applyChanges(entry, values, entryNode);
    }

    self.updateState(entry, entryNode);
  }

  domDelegate.bind(container, '[data-blur]', 'blur', handleInput, true);

  // make tab links interactive
  domDelegate.bind(container, '.bpp-properties-tabs-links [data-tab-target]', 'click', function(event) {
    event.preventDefault();

    var delegateTarget = event.delegateTarget;

    var tabId = domAttr(delegateTarget, 'data-tab-target');

    // activate tab on link click
    self.activateTab(tabId);
  });

};

PropertiesPanel.prototype.updateState = function(entry, entryNode) {
  this.updateShow(entry, entryNode);
  this.updateDisable(entry, entryNode);
};

/**
 * Update the visibility of the entry node in the DOM
 */
PropertiesPanel.prototype.updateShow = function(entry, node) {

  var current = this._current;

  if (!current) {
    return;
  }

  var showNodes = domQueryAll('[data-show]', node) || [];

  forEach(showNodes, function(showNode) {

    var expr = domAttr(showNode, 'data-show');
    var fn = get(entry, expr);
    if (fn) {
      var scope = domClosest(showNode, '[data-scope]') || node;
      var shouldShow = fn(current.element, node, showNode, scope) || false;
      if (shouldShow) {
        domClasses(showNode).remove(HIDE_CLASS);
      } else {
        domClasses(showNode).add(HIDE_CLASS);
      }
    }
  });
};

/**
 * Evaluates a given function. If it returns true, then the
 * node is marked as "disabled".
 */
PropertiesPanel.prototype.updateDisable = function(entry, node) {
  var current = this._current;

  if (!current) {
    return;
  }

  var nodes = domQueryAll('[data-disable]', node) || [];

  forEach(nodes, function(currentNode) {
    var expr = domAttr(currentNode, 'data-disable');
    var fn = get(entry, expr);
    if (fn) {
      var scope = domClosest(currentNode, '[data-scope]') || node;
      var shouldDisable = fn(current.element, node, currentNode, scope) || false;
      domAttr(currentNode, 'disabled', shouldDisable ? '' : null);
    }
  });
};

PropertiesPanel.prototype.executeAction = function(entry, entryNode, actionId, event) {
  var current = this._current;

  if (!current) {
    return;
  }

  var fn = get(entry, actionId);
  if (fn) {
    var scopeNode = domClosest(event.target, '[data-scope]') || entryNode;
    return fn.apply(entry, [ current.element, entryNode, event, scopeNode ]);
  }
};

/**
 * Apply changes to the business object by executing a command
 */
PropertiesPanel.prototype.applyChanges = function(entry, values, containerElement) {

  var element = this._current.element;

  // ensure we only update the model if we got dirty changes
  if (valuesEqual(values, entry.oldValues)) {
    return;
  }

  var command = entry.set(element, values, containerElement);

  var commandToExecute;

  if (isArray(command)) {
    if (command.length) {
      commandToExecute = {
        cmd: 'properties-panel.multi-command-executor',
        context: flattenDeep(command)
      };
    }
  } else {
    commandToExecute = command;
  }

  if (commandToExecute) {
    this._commandStack.execute(commandToExecute.cmd, commandToExecute.context || { element : element });
  } else {
    this.update(element);
  }
};


/**
 * apply validation errors in the DOM and show or remove an error message near the entry node.
 */
PropertiesPanel.prototype.applyValidationErrors = function(validationErrors, entryNode) {

  var valid = true;

  var controlNodes = getFormControls(entryNode, true);

  forEach(controlNodes, function(controlNode) {

    var name = domAttr(controlNode, 'name') || domAttr(controlNode, 'data-name');

    var error = validationErrors && validationErrors[name];

    var errorMessageNode = domQuery('.bpp-error-message', controlNode.parentNode);

    if (error) {
      valid = false;

      if (!errorMessageNode) {
        errorMessageNode = domify('<div></div>');

        domClasses(errorMessageNode).add('bpp-error-message');

        // insert errorMessageNode after controlNode
        controlNode.parentNode.insertBefore(errorMessageNode, controlNode.nextSibling);
      }

      errorMessageNode.textContent = error;

      domClasses(controlNode).add('invalid');
    } else {
      domClasses(controlNode).remove('invalid');

      if (errorMessageNode) {
        controlNode.parentNode.removeChild(errorMessageNode);
      }
    }
  });

  return valid;
};


/**
 * Check if the entry contains valid input
 */
PropertiesPanel.prototype.validate = function(entry, values, entryNode) {
  var self = this;

  var current = this._current;

  var valid = true;

  entryNode = entryNode || domQuery('[data-entry="' + entry.id + '"]', current.panel);

  if (values instanceof Array) {
    var listContainer = domQuery('[data-list-entry-container]', entryNode),
        listEntryNodes = listContainer.children || [];

    // create new elements
    for (var i = 0; i < values.length; i++) {
      var listValue = values[i];

      if (entry.validateListItem) {

        var validationErrors = entry.validateListItem(current.element, listValue, entryNode, i),
            listEntryNode = listEntryNodes[i];

        valid = self.applyValidationErrors(validationErrors, listEntryNode) && valid;
      }
    }
  } else {
    if (entry.validate) {
      this.validationErrors = entry.validate(current.element, values, entryNode);

      valid = self.applyValidationErrors(this.validationErrors, entryNode) && valid;
    }
  }

  return valid;
};

PropertiesPanel.prototype.getEntry = function(id) {
  return this._current && this._current.entries[id];
};

var flattenDeep = require('lodash/flattenDeep'),
    keyBy = require('lodash/keyBy'),
    map = require('lodash/map');

PropertiesPanel.prototype._create = function(element, tabs) {

  if (!element) {
    return null;
  }

  var containerNode = this._container;

  var panelNode = this._createPanel(element, tabs);

  containerNode.appendChild(panelNode);

  var entries = extractEntries(tabs);
  var groups = extractGroups(tabs);

  return {
    tabs: tabs,
    groups: groups,
    entries: entries,
    element: element,
    panel: panelNode
  };
};

/**
 * Update variable parts of the entry node on element changes.
 *
 * @param {djs.model.Base} element
 * @param {EntryDescriptor} entry
 * @param {Object} values
 * @param {HTMLElement} entryNode
 * @param {Number} idx
 */
PropertiesPanel.prototype._bindTemplate = function(element, entry, values, entryNode, idx) {

  var eventBus = this._eventBus;

  function isPropertyEditable(entry, propertyName) {
    return eventBus.fire('propertiesPanel.isPropertyEditable', {
      entry: entry,
      propertyName: propertyName,
      element: element
    });
  }

  var inputNodes = getPropertyPlaceholders(entryNode);

  forEach(inputNodes, function(node) {

    var name,
        newValue,
        editable;

    // we deal with an input element
    if ('value' in node || isContentEditable(node) === 'true') {
      name = domAttr(node, 'name') || domAttr(node, 'data-name');
      newValue = values[name];

      editable = isPropertyEditable(entry, name);
      if (editable && entry.editable) {
        editable = entry.editable(element, entryNode, node, name, newValue, idx);
      }

      domAttr(node, 'readonly', editable ? null : '');
      domAttr(node, 'disabled', editable ? null : '');

      // take full control over setting the value
      // and possibly updating the input in entry#setControlValue
      if (entry.setControlValue) {
        entry.setControlValue(element, entryNode, node, name, newValue, idx);
      } else if (isToggle(node)) {
        setToggleValue(node, newValue);
      } else if (isSelect(node)) {
        setSelectValue(node, newValue);
      } else {
        setInputValue(node, newValue);
      }
    }

    // we deal with some non-editable html element
    else {
      name = domAttr(node, 'data-value');
      newValue = values[name];
      if (entry.setControlValue) {
        entry.setControlValue(element, entryNode, node, name, newValue, idx);
      } else {
        setTextValue(node, newValue);
      }
    }
  });
};

// TODO(nikku): WTF freaking name? Change / clarify.
PropertiesPanel.prototype._updateActivation = function(current) {
  var self = this;

  var eventBus = this._eventBus;

  var element = current.element;

  function isEntryVisible(entry) {
    return eventBus.fire('propertiesPanel.isEntryVisible', {
      entry: entry,
      element: element
    });
  }

  function isGroupVisible(group, element, groupNode) {
    if (typeof group.enabled === 'function') {
      return group.enabled(element, groupNode);
    } else {
      return true;
    }
  }

  function isTabVisible(tab, element) {
    if (typeof tab.enabled === 'function') {
      return tab.enabled(element);
    } else {
      return true;
    }
  }

  function toggleVisible(node, visible) {
    domClasses(node).toggle(HIDE_CLASS, !visible);
  }

  // check whether the active tab is visible
  // if not: set the first tab as active tab
  function checkActiveTabVisibility(node, visible) {
    var isActive = domClasses(node).has('bpp-active');
    if (!visible && isActive) {
      self.activateTab(current.tabs[0]);
    }
  }

  function updateLabel(element, selector, text) {
    var labelNode = domQuery(selector, element);

    if (!labelNode) {
      return;
    }

    labelNode.textContent = text;
  }

  var panelNode = current.panel;

  forEach(current.tabs, function(tab) {

    var tabNode = domQuery('[data-tab=' + tab.id + ']', panelNode);
    var tabLinkNode = domQuery('[data-tab-target=' + tab.id + ']', panelNode).parentNode;

    var tabVisible = false;

    forEach(tab.groups, function(group) {

      var groupVisible = false;

      var groupNode = domQuery('[data-group=' + group.id + ']', tabNode);

      forEach(group.entries, function(entry) {

        var entryNode = domQuery('[data-entry="' + entry.id + '"]', groupNode);

        var entryVisible = isEntryVisible(entry);

        groupVisible = groupVisible || entryVisible;

        toggleVisible(entryNode, entryVisible);

        var values = 'get' in entry ? entry.get(element, entryNode) : {};

        if (values instanceof Array) {
          var listEntryContainer = domQuery('[data-list-entry-container]', entryNode);
          var existingElements = listEntryContainer.children || [];

          for (var i = 0; i < values.length; i++) {
            var listValue = values[i];
            var listItemNode = existingElements[i];
            if (!listItemNode) {
              listItemNode = domify(entry.createListEntryTemplate(listValue, i, listEntryContainer));
              listEntryContainer.appendChild(listItemNode);
            }
            domAttr(listItemNode, 'data-index', i);

            self._bindTemplate(element, entry, listValue, listItemNode, i);
          }

          var entriesToRemove = existingElements.length - values.length;

          for (var j = 0; j < entriesToRemove; j++) {
            // remove orphaned element
            listEntryContainer.removeChild(listEntryContainer.lastChild);
          }

        } else {
          self._bindTemplate(element, entry, values, entryNode);
        }

        // update conditionally visible elements
        self.updateState(entry, entryNode);
        self.validate(entry, values, entryNode);

        // remember initial state for later dirty checking
        entry.oldValues = getFormControlValues(entryNode);
      });

      if (typeof group.label === 'function') {
        updateLabel(groupNode, '.group-label', group.label(element, groupNode));
      }

      groupVisible = groupVisible && isGroupVisible(group, element, groupNode);

      tabVisible = tabVisible || groupVisible;

      toggleVisible(groupNode, groupVisible);
    });

    tabVisible = tabVisible && isTabVisible(tab, element);

    toggleVisible(tabNode, tabVisible);
    toggleVisible(tabLinkNode, tabVisible);

    checkActiveTabVisibility(tabNode, tabVisible);
  });

  // inject elements id into header
  updateLabel(panelNode, '[data-label-id]', getBusinessObject(element).id || '');
};

PropertiesPanel.prototype._createPanel = function(element, tabs) {
  var self = this;

  var panelNode = domify('<div class="bpp-properties"></div>'),
      headerNode = domify('<div class="bpp-properties-header">' +
        '<div class="label" data-label-id></div>' +
        '<div class="search">' +
          '<input type="search" placeholder="Search for property" />' +
          '<button><span>Search</span></button>' +
        '</div>' +
      '</div>'),
      tabBarNode = domify('<div class="bpp-properties-tab-bar"></div>'),
      tabLinksNode = domify('<ul class="bpp-properties-tabs-links"></ul>'),
      tabContainerNode = domify('<div class="bpp-properties-tabs-container"></div>');

  panelNode.appendChild(headerNode);

  forEach(tabs, function(tab, tabIndex) {
    if (!tab.id) {
      throw new Error('tab must have an id');
    }
    var updateStype = ''
    if (tab.id != 'general') {
      updateStype = 'display:none'
    }

    var tabNode = domify('<div class="bpp-properties-tab" style="'+updateStype+'" data-tab="' + escapeHTML(tab.id) + '"></div>'),
        tabLinkNode = domify('<li class="bpp-properties-tab-link"  style="'+updateStype+'">  ' +
          '<a href data-tab-target="' + escapeHTML(tab.id) + '">' + escapeHTML(tab.label) + '</a>' +
        '</li>');

    var groups = tab.groups;

    forEach(groups, function(group) {

      if (!group.id) {
        throw new Error('group must have an id');
      }
        var groupNode = domify('<div class="bpp-properties-group" data-group="' + escapeHTML(group.id) + '">' +
            '<span class="group-toggle"></span>' +
            '<span class="group-label">' + escapeHTML(group.label) + '</span>' +
          '</div>');

        // TODO(nre): use event delegation to handle that...
        groupNode.querySelector('.group-toggle').addEventListener('click', function(evt) {
          domClasses(groupNode).toggle('group-closed');
          evt.preventDefault();
          evt.stopPropagation();
        });
        groupNode.addEventListener('click', function(evt) {
          if (!evt.defaultPrevented && domClasses(groupNode).has('group-closed')) {
            domClasses(groupNode).remove('group-closed');
          }
        });

        forEach(group.entries, function(entry) {

          if (!entry.id) {
            throw new Error('entry must have an id');
          }

          var html = entry.html;

          if (typeof html === 'string') {
            html = domify(html);
          }

          // unwrap jquery
          if (html.get && html.constructor.prototype.jquery) {
            html = html.get(0);
          }

          var entryNode = domify('<div class="bpp-properties-entry" data-entry="' + escapeHTML(entry.id) + '"></div>');

          forEach(entry.cssClasses || [], function(cssClass) {
            domClasses(entryNode).add(cssClass);
          });

          entryNode.appendChild(html);

          groupNode.appendChild(entryNode);

          // update conditionally visible elements
          self.updateState(entry, entryNode);
        });

      tabNode.appendChild(groupNode);
    });

    tabLinksNode.appendChild(tabLinkNode);
    tabContainerNode.appendChild(tabNode);
  });

  tabBarNode.appendChild(tabLinksNode);

  panelNode.appendChild(tabBarNode);
  panelNode.appendChild(tabContainerNode);

  return panelNode;
};



function setInputValue(node, value) {

  var contentEditable = isContentEditable(node);

  var oldValue = contentEditable ? node.innerText : node.value;

  var selection;

  // prevents input fields from having the value 'undefined'
  if (value === undefined) {
    value = '';
  }

  if (oldValue === value) {
    return;
  }

  // update selection on undo/redo
  if (document.activeElement === node) {
    selection = updateSelection(getSelection(node), oldValue, value);
  }

  if (contentEditable) {
    node.innerText = value;
  } else {
    node.value = value;
  }

  if (selection) {
    setSelection(node, selection);
  }
}

function setSelectValue(node, value) {
  if (value !== undefined) {
    node.value = value;
  }
}

function setToggleValue(node, value) {
  var nodeValue = node.value;

  node.checked = (value === nodeValue) || (!domAttr(node, 'value') && value);
}

function setTextValue(node, value) {
  node.textContent = value;
}

function getSelection(node) {

  return isContentEditable(node) ? getContentEditableSelection(node) : {
    start: node.selectionStart,
    end: node.selectionEnd
  };
}

function getContentEditableSelection(node) {

  var selection = window.getSelection();

  var focusNode = selection.focusNode,
      focusOffset = selection.focusOffset,
      anchorOffset = selection.anchorOffset;

  if (!focusNode) {
    throw new Error('not selected');
  }

  // verify we have selection on the current element
  if (!node.contains(focusNode)) {
    throw new Error('not selected');
  }

  return {
    start: Math.min(focusOffset, anchorOffset),
    end: Math.max(focusOffset, anchorOffset)
  };
}

function setSelection(node, selection) {

  if (isContentEditable(node)) {
    setContentEditableSelection(node, selection);
  } else {
    node.selectionStart = selection.start;
    node.selectionEnd = selection.end;
  }
}

function setContentEditableSelection(node, selection) {

  var focusNode,
      domRange,
      domSelection;

  focusNode = node.firstChild || node,
  domRange = document.createRange();
  domRange.setStart(focusNode, selection.start);
  domRange.setEnd(focusNode, selection.end);

  domSelection = window.getSelection();
  domSelection.removeAllRanges();
  domSelection.addRange(domRange);
}

function isImplicitRoot(element) {
  return element.id === '__implicitroot';
}

},{"./Utils":4,"bpmn-js/lib/util/ModelUtil":141,"lodash/debounce":516,"lodash/filter":518,"lodash/flattenDeep":521,"lodash/forEach":522,"lodash/get":523,"lodash/isArray":527,"lodash/isEmpty":531,"lodash/keyBy":538,"lodash/keys":539,"lodash/map":540,"lodash/xor":554,"min-dom":556,"scroll-tabs":565,"selection-update":566}],4:[function(require,module,exports){
'use strict';

var domQuery = require('min-dom').query,
    domClear = require('min-dom').clear,
    is = require('bpmn-js/lib/util/ModelUtil').is,
    forEach = require('lodash/forEach'),
    domify = require('min-dom').domify,
    Ids = require('ids').default;

var SPACE_REGEX = /\s/;

// for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar
var QNAME_REGEX = /^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i;

// for ID validation as per BPMN Schema (QName - Namespace)
var ID_REGEX = /^[a-z_][\w-.]*$/i;

var PLACEHOLDER_REGEX = /\$\{([^}]*)\}/g;

var HTML_ESCAPE_MAP = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  '\'': '&#39;'
};

function selectedOption(selectBox) {
  if (selectBox.selectedIndex >= 0) {
    return selectBox.options[selectBox.selectedIndex].value;
  }
}

module.exports.selectedOption = selectedOption;


function selectedType(elementSyntax, inputNode) {
  var typeSelect = domQuery(elementSyntax, inputNode);
  return selectedOption(typeSelect);
}

module.exports.selectedType = selectedType;


/**
 * Retrieve the root element the document this
 * business object is contained in.
 *
 * @return {ModdleElement}
 */
function getRoot(businessObject) {
  var parent = businessObject;
  while (parent.$parent) {
    parent = parent.$parent;
  }
  return parent;
}

module.exports.getRoot = getRoot;


/**
 * filters all elements in the list which have a given type.
 * removes a new list
 */
function filterElementsByType(objectList, type) {
  var list = objectList || [];
  var result = [];
  forEach(list, function(obj) {
    if (is(obj, type)) {
      result.push(obj);
    }
  });
  return result;
}

module.exports.filterElementsByType = filterElementsByType;


function findRootElementsByType(businessObject, referencedType) {
  var root = getRoot(businessObject);

  return filterElementsByType(root.rootElements, referencedType);
}

module.exports.findRootElementsByType = findRootElementsByType;


function removeAllChildren(domElement) {
  while (domElement.firstChild) {
    domElement.removeChild(domElement.firstChild);
  }
}

module.exports.removeAllChildren = removeAllChildren;


/**
 * adds an empty option to the list
 */
function addEmptyParameter(list) {
  return list.push({ 'label': '', 'value': '', 'name': '' });
}

module.exports.addEmptyParameter = addEmptyParameter;


/**
 * returns a list with all root elements for the given parameter 'referencedType'
 */
function refreshOptionsModel(businessObject, referencedType) {
  var model = [];
  var referableObjects = findRootElementsByType(businessObject, referencedType);
  forEach(referableObjects, function(obj) {
    model.push({
      label: (obj.name || '') + ' (id='+obj.id+')',
      value: obj.id,
      name: obj.name
    });
  });
  return model;
}

module.exports.refreshOptionsModel = refreshOptionsModel;


/**
 * fills the drop down with options
 */
function updateOptionsDropDown(domSelector, businessObject, referencedType, entryNode) {
  var options = refreshOptionsModel(businessObject, referencedType);
  addEmptyParameter(options);
  var selectBox = domQuery(domSelector, entryNode);
  domClear(selectBox);

  forEach(options, function(option) {
    var optionEntry = domify('<option value="' + escapeHTML(option.value) + '">' + escapeHTML(option.label) + '</option>');
    selectBox.appendChild(optionEntry);
  });
  return options;
}

module.exports.updateOptionsDropDown = updateOptionsDropDown;


/**
 * checks whether the id value is valid
 *
 * @param {ModdleElement} bo
 * @param {String} idValue
 * @param {Function} translate
 *
 * @return {String} error message
 */
function isIdValid(bo, idValue, translate) {
  var assigned = bo.$model.ids.assigned(idValue);

  var idExists = assigned && assigned !== bo;

  if (!idValue || idExists) {
    return translate('Element must have an unique id.');
  }

  return validateId(idValue, translate);
}

module.exports.isIdValid = isIdValid;


function validateId(idValue, translate) {

  idValue = stripPlaceholders(idValue);

  if (containsSpace(idValue)) {
    return translate('Id must not contain spaces.');
  }

  if (!ID_REGEX.test(idValue)) {

    if (QNAME_REGEX.test(idValue)) {
      return translate('Id must not contain prefix.');
    }

    return translate('Id must be a valid QName.');
  }
}

module.exports.validateId = validateId;


function containsSpace(value) {
  return SPACE_REGEX.test(value);
}

module.exports.containsSpace = containsSpace;


function stripPlaceholders(idValue) {

  // replace expression e.g. ${VERSION_TAG}
  // use only the content between ${}
  // for the REGEX check
  return idValue.replace(PLACEHOLDER_REGEX, '$1');
}

/**
 * generate a semantic id with given prefix
 */
function nextId(prefix) {
  var ids = new Ids([32,32,1]);

  return ids.nextPrefixed(prefix);
}

module.exports.nextId = nextId;


function triggerClickEvent(element) {
  var evt;
  var eventType = 'click';

  if (document.createEvent) {
    try {
      // Chrome, Safari, Firefox
      evt = new MouseEvent((eventType), { view: window, bubbles: true, cancelable: true });
    } catch (e) {
      // IE 11, PhantomJS (wat!)
      evt = document.createEvent('MouseEvent');

      evt.initEvent((eventType), true, true);
    }
    return element.dispatchEvent(evt);
  } else {
    // Welcome IE
    evt = document.createEventObject();

    return element.fireEvent('on' + eventType, evt);
  }
}

module.exports.triggerClickEvent = triggerClickEvent;


function escapeHTML(str) {
  str = '' + str;

  return str && str.replace(/[&<>"']/g, function(match) {
    return HTML_ESCAPE_MAP[match];
  });
}

module.exports.escapeHTML = escapeHTML;
},{"bpmn-js/lib/util/ModelUtil":141,"ids":346,"lodash/forEach":522,"min-dom":556}],5:[function(require,module,exports){
'use strict';

var elementHelper = require('../helper/ElementHelper');

/**
 * A handler capable of creating a new element under a provided parent
 * and updating / creating a reference to it in one atomic action.
 *
 * @class
 * @constructor
 */
function CreateAndReferenceElementHandler(elementRegistry, bpmnFactory) {
  this._elementRegistry = elementRegistry;
  this._bpmnFactory = bpmnFactory;
}

CreateAndReferenceElementHandler.$inject = [ 'elementRegistry', 'bpmnFactory' ];

module.exports = CreateAndReferenceElementHandler;


// api ////////////////////

/**
 * Creates a new element under a provided parent and updates / creates a reference to it in
 * one atomic action.
 *
 * @method  CreateAndReferenceElementHandler#execute
 *
 * @param {Object} context
 * @param {djs.model.Base} context.element which is the context for the reference
 * @param {moddle.referencingObject} context.referencingObject the object which creates the reference
 * @param {String} context.referenceProperty the property of the referencingObject which makes the reference
 * @param {moddle.newObject} context.newObject the new object to add
 * @param {moddle.newObjectContainer} context.newObjectContainer the container for the new object
 *
 * @returns {Array<djs.mode.Base>} the updated element
 */
CreateAndReferenceElementHandler.prototype.execute = function(context) {

  var referencingObject = ensureNotNull(context.referencingObject, 'referencingObject'),
      referenceProperty = ensureNotNull(context.referenceProperty, 'referenceProperty'),
      newObject = ensureNotNull(context.newObject, 'newObject'),
      newObjectContainer = ensureNotNull(context.newObjectContainer, 'newObjectContainer'),
      newObjectParent = ensureNotNull(context.newObjectParent, 'newObjectParent'),
      changed = [ context.element ]; // this will not change any diagram-js elements

  // create new object
  var referencedObject = elementHelper
    .createElement(newObject.type, newObject.properties, newObjectParent, this._bpmnFactory);
  context.referencedObject = referencedObject;

  // add to containing list
  newObjectContainer.push(referencedObject);

  // adjust reference attribute
  context.previousReference = referencingObject[referenceProperty];
  referencingObject[referenceProperty] = referencedObject;

  context.changed = changed;

  // indicate changed on objects affected by the update
  return changed;
};

/**
 * Reverts the update
 *
 * @method  CreateAndReferenceElementHandler#revert
 *
 * @param {Object} context
 *
 * @returns {djs.mode.Base} the updated element
 */
CreateAndReferenceElementHandler.prototype.revert = function(context) {

  var referencingObject = context.referencingObject,
      referenceProperty = context.referenceProperty,
      previousReference = context.previousReference,
      referencedObject = context.referencedObject,
      newObjectContainer = context.newObjectContainer;

  // reset reference
  referencingObject.set(referenceProperty, previousReference);

  // remove new element
  newObjectContainer.splice(newObjectContainer.indexOf(referencedObject), 1);

  return context.changed;
};



// helpers //////////////

function ensureNotNull(prop, name) {
  if (!prop) {
    throw new Error(name + ' required');
  }
  return prop;
}

},{"../helper/ElementHelper":11}],6:[function(require,module,exports){
'use strict';

var forEach = require('lodash/forEach');

var elementHelper = require('../helper/ElementHelper');

/**
 * A handler that implements a BPMN 2.0 property update
 * for business objects which are not represented in the
 * diagram.
 *
 * This is useful in the context of the properties panel in
 * order to update child elements of elements visible in
 * the diagram.
 *
 * Example: perform an update of a specific event definition
 * of an intermediate event.
 *
 * @class
 * @constructor
 */
function CreateBusinessObjectListHandler(elementRegistry, bpmnFactory) {
  this._elementRegistry = elementRegistry;
  this._bpmnFactory = bpmnFactory;
}

CreateBusinessObjectListHandler.$inject = [ 'elementRegistry', 'bpmnFactory' ];

module.exports = CreateBusinessObjectListHandler;

function ensureNotNull(prop, name) {
  if (!prop) {
    throw new Error(name + ' required');
  }
  return prop;

}
function ensureList(prop, name) {
  if (!prop || Object.prototype.toString.call(prop) !== '[object Array]') {
    throw new Error(name + ' needs to be a list');
  }
  return prop;
}

// api /////////////////////////////////////////////

/**
 * Creates a new element under a provided parent and updates / creates a reference to it in
 * one atomic action.
 *
 * @method  CreateBusinessObjectListHandler#execute
 *
 * @param {Object} context
 * @param {djs.model.Base} context.element which is the context for the reference
 * @param {moddle.referencingObject} context.referencingObject the object which creates the reference
 * @param {String} context.referenceProperty the property of the referencingObject which makes the reference
 * @param {moddle.newObject} context.newObject the new object to add
 * @param {moddle.newObjectContainer} context.newObjectContainer the container for the new object
 *
 * @return {Array<djs.mode.Base>} the updated element
 */
CreateBusinessObjectListHandler.prototype.execute = function(context) {

  var currentObject = ensureNotNull(context.currentObject, 'currentObject'),
      propertyName = ensureNotNull(context.propertyName, 'propertyName'),
      newObjects = ensureList(context.newObjects, 'newObjects'),
      changed = [ context.element ]; // this will not change any diagram-js elements


  var childObjects = [];
  var self = this;

  // create new array of business objects
  forEach(newObjects, function(obj) {
    var element = elementHelper.createElement(obj.type, obj.properties, currentObject, self._bpmnFactory);

    childObjects.push(element);
  });
  context.childObject = childObjects;

  // adjust array reference in the parent business object
  context.previousChilds = currentObject[propertyName];
  currentObject[propertyName] = childObjects;

  context.changed = changed;

  // indicate changed on objects affected by the update
  return changed;
};

/**
 * Reverts the update
 *
 * @method  CreateBusinessObjectListHandler#revert
 *
 * @param {Object} context
 *
 * @return {djs.mode.Base} the updated element
 */
CreateBusinessObjectListHandler.prototype.revert = function(context) {

  var currentObject = context.currentObject,
      propertyName = context.propertyName,
      previousChilds = context.previousChilds;

  // remove new element
  currentObject.set(propertyName, previousChilds);

  return context.changed;
};

},{"../helper/ElementHelper":11,"lodash/forEach":522}],7:[function(require,module,exports){
'use strict';

var forEach = require('lodash/forEach');

/**
 * A handler that combines and executes multiple commands.
 *
 * All updates are bundled on the command stack and executed in one step.
 * This also makes it possible to revert the changes in one step.
 *
 * Example use case: remove the camunda:formKey attribute and in addition
 * add all form fields needed for the camunda:formData property.
 *
 * @class
 * @constructor
 */
function MultiCommandHandler(commandStack) {
  this._commandStack = commandStack;
}

MultiCommandHandler.$inject = [ 'commandStack' ];

module.exports = MultiCommandHandler;

MultiCommandHandler.prototype.preExecute = function(context) {

  var commandStack = this._commandStack;

  forEach(context, function(command) {
    commandStack.execute(command.cmd, command.context);
  });
};
},{"lodash/forEach":522}],8:[function(require,module,exports){
'use strict';

var reduce = require('lodash/transform'),
    is = require('bpmn-js/lib/util/ModelUtil').is,
    keys = require('lodash/keys'),
    forEach = require('lodash/forEach');

/**
 * A handler that implements a BPMN 2.0 property update
 * for business objects which are not represented in the
 * diagram.
 *
 * This is useful in the context of the properties panel in
 * order to update child elements of elements visible in
 * the diagram.
 *
 * Example: perform an update of a specific event definition
 * of an intermediate event.
 *
 * @class
 * @constructor
 */
function UpdateBusinessObjectHandler(elementRegistry) {
  this._elementRegistry = elementRegistry;
}

UpdateBusinessObjectHandler.$inject = [ 'elementRegistry' ];

module.exports = UpdateBusinessObjectHandler;

/**
 * returns the root element
 */
function getRoot(businessObject) {
  var parent = businessObject;
  while (parent.$parent) {
    parent = parent.$parent;
  }
  return parent;
}

function getProperties(businessObject, propertyNames) {
  return reduce(propertyNames, function(result, key) {
    result[key] = businessObject.get(key);
    return result;
  }, {});
}


function setProperties(businessObject, properties) {
  forEach(properties, function(value, key) {
    businessObject.set(key, value);
  });
}


// api /////////////////////////////////////////////

/**
 * Updates a business object with a list of new properties
 *
 * @method  UpdateBusinessObjectHandler#execute
 *
 * @param {Object} context
 * @param {djs.model.Base} context.element the element which has a child business object updated
 * @param {moddle.businessObject} context.businessObject the businessObject to update
 * @param {Object} context.properties a list of properties to set on the businessObject
 *
 * @return {Array<djs.mode.Base>} the updated element
 */
UpdateBusinessObjectHandler.prototype.execute = function(context) {

  var element = context.element,
      businessObject = context.businessObject,
      rootElements = getRoot(businessObject).rootElements,
      referenceType = context.referenceType,
      referenceProperty = context.referenceProperty,
      changed = [ element ]; // this will not change any diagram-js elements

  if (!element) {
    throw new Error('element required');
  }

  if (!businessObject) {
    throw new Error('businessObject required');
  }

  var properties = context.properties,
      oldProperties = context.oldProperties || getProperties(businessObject, keys(properties));

  // check if there the update needs an external element for reference
  if (typeof referenceType !== 'undefined' && typeof referenceProperty !== 'undefined') {
    forEach(rootElements, function(rootElement) {
      if (is(rootElement, referenceType)) {
        if (rootElement.id === properties[referenceProperty]) {
          properties[referenceProperty] = rootElement;
        }
      }
    });
  }

  // update properties
  setProperties(businessObject, properties);

  // store old values
  context.oldProperties = oldProperties;
  context.changed = changed;

  // indicate changed on objects affected by the update
  return changed;
};

/**
 * Reverts the update
 *
 * @method  UpdateBusinessObjectHandler#revert
 *
 * @param {Object} context
 *
 * @return {djs.mode.Base} the updated element
 */
UpdateBusinessObjectHandler.prototype.revert = function(context) {

  var oldProperties = context.oldProperties,
      businessObject = context.businessObject;

  // update properties
  setProperties(businessObject, oldProperties);

  return context.changed;
};

},{"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522,"lodash/keys":539,"lodash/transform":551}],9:[function(require,module,exports){
'use strict';

var forEach = require('lodash/forEach');

/**
 * A handler that implements a BPMN 2.0 property update
 * for business object lists which are not represented in the
 * diagram.
 *
 * This is useful in the context of the properties panel in
 * order to update child elements of elements visible in
 * the diagram.
 *
 * Example: perform an update of a specific event definition
 * of an intermediate event.
 *
 * @class
 * @constructor
 */
function UpdateBusinessObjectListHandler(elementRegistry, bpmnFactory) {
  this._elementRegistry = elementRegistry;
  this._bpmnFactory = bpmnFactory;
}

UpdateBusinessObjectListHandler.$inject = [ 'elementRegistry', 'bpmnFactory' ];

module.exports = UpdateBusinessObjectListHandler;

function ensureNotNull(prop, name) {
  if (!prop) {
    throw new Error(name + 'required');
  }
  return prop;
}

// api /////////////////////////////////////////////

/**
 * Updates a element under a provided parent.
 */
UpdateBusinessObjectListHandler.prototype.execute = function(context) {

  var currentObject = ensureNotNull(context.currentObject, 'currentObject'),
      propertyName = ensureNotNull(context.propertyName, 'propertyName'),
      updatedObjectList = context.updatedObjectList,
      objectsToRemove = context.objectsToRemove || [],
      objectsToAdd = context.objectsToAdd || [],
      changed = [ context.element], // this will not change any diagram-js elements
      referencePropertyName;

  if (context.referencePropertyName) {
    referencePropertyName = context.referencePropertyName;
  }

  var objectList = currentObject[propertyName];
  // adjust array reference in the parent business object
  context.previousList = currentObject[propertyName];

  if (updatedObjectList) {
    currentObject[propertyName] = updatedObjectList;
  } else {
    var listCopy = [];
    // remove all objects which should be removed
    forEach(objectList, function(object) {
      if (objectsToRemove.indexOf(object) == -1) {
        listCopy.push(object);
      }
    });
    // add all objects which should be added
    listCopy = listCopy.concat(objectsToAdd);

    // set property to new list
    if (listCopy.length > 0 || !referencePropertyName) {

      // as long as there are elements in the list update the list
      currentObject[propertyName] = listCopy;
    } else if (referencePropertyName) {

      // remove the list when it is empty
      var parentObject = currentObject.$parent;
      parentObject.set(referencePropertyName, undefined);
    }
  }

  context.changed = changed;

  // indicate changed on objects affected by the update
  return changed;
};

/**
 * Reverts the update
 *
 * @method  CreateBusinessObjectListHandler#revert
 *
 * @param {Object} context
 *
 * @return {djs.mode.Base} the updated element
 */
UpdateBusinessObjectListHandler.prototype.revert = function(context) {

  var currentObject = context.currentObject,
      propertyName = context.propertyName,
      previousList = context.previousList,
      parentObject = currentObject.$parent;

  if (context.referencePropertyName) {
    parentObject.set(context.referencePropertyName, currentObject);
  }

  // remove new element
  currentObject.set(propertyName, previousList);

  return context.changed;
};

},{"lodash/forEach":522}],10:[function(require,module,exports){
'use strict';

var forEach = require('lodash/forEach');

var HANDLERS = {
  'properties-panel.update-businessobject': require('./UpdateBusinessObjectHandler'),
  'properties-panel.create-and-reference': require('./CreateAndReferenceHandler'),
  'properties-panel.create-businessobject-list': require('./CreateBusinessObjectListHandler'),
  'properties-panel.update-businessobject-list': require('./UpdateBusinessObjectListHandler'),
  'properties-panel.multi-command-executor': require('./MultiCommandHandler')
};


function CommandInitializer(eventBus, commandStack) {

  eventBus.on('diagram.init', function() {
    forEach(HANDLERS, function(handler, id) {
      commandStack.registerHandler(id, handler);
    });
  });
}

CommandInitializer.$inject = [ 'eventBus', 'commandStack' ];

module.exports = {
  __init__: [ CommandInitializer ]
};
},{"./CreateAndReferenceHandler":5,"./CreateBusinessObjectListHandler":6,"./MultiCommandHandler":7,"./UpdateBusinessObjectHandler":8,"./UpdateBusinessObjectListHandler":9,"lodash/forEach":522}],11:[function(require,module,exports){
'use strict';

var ElementHelper = {};
module.exports = ElementHelper;

/**
 * Creates a new element and set the parent to it
 *
 * @method ElementHelper#createElement
 *
 * @param {String} elementType of the new element
 * @param {Object} properties of the new element in key-value pairs
 * @param {moddle.object} parent of the new element
 * @param {BpmnFactory} factory which creates the new element
 *
 * @returns {djs.model.Base} element which is created
 */
ElementHelper.createElement = function(elementType, properties, parent, factory) {
  var element = factory.create(elementType, properties);
  element.$parent = parent;

  return element;
};

},{}],12:[function(require,module,exports){
module.exports = {
  __depends__: [
    require('./cmd'),
    require('diagram-js/lib/i18n/translate').default
  ],
  __init__: [ 'propertiesPanel' ],
  propertiesPanel: [ 'type', require('./PropertiesPanel') ]
};

},{"./PropertiesPanel":3,"./cmd":10,"diagram-js/lib/i18n/translate":337}],13:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BaseModeler;

var _inherits = _interopRequireDefault(require("inherits"));

var _ids = _interopRequireDefault(require("ids"));

var _BaseViewer = _interopRequireDefault(require("./BaseViewer"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A base modeler for BPMN 2.0 diagrams.
 *
 * Have a look at {@link Modeler} for a bundle that includes actual features.
 *
 * @param {Object} [options] configuration options to pass to the viewer
 * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
 * @param {string|number} [options.width] the width of the viewer
 * @param {string|number} [options.height] the height of the viewer
 * @param {Object} [options.moddleExtensions] extension packages to provide
 * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules
 * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules
 */
function BaseModeler(options) {
  _BaseViewer.default.call(this, options); // hook ID collection into the modeler


  this.on('import.parse.complete', function (event) {
    if (!event.error) {
      this._collectIds(event.definitions, event.elementsById);
    }
  }, this);
  this.on('diagram.destroy', function () {
    this.get('moddle').ids.clear();
  }, this);
}

(0, _inherits.default)(BaseModeler, _BaseViewer.default);
/**
 * Create a moddle instance, attaching ids to it.
 *
 * @param {Object} options
 */

BaseModeler.prototype._createModdle = function (options) {
  var moddle = _BaseViewer.default.prototype._createModdle.call(this, options); // attach ids to moddle to be able to track
  // and validated ids in the BPMN 2.0 XML document
  // tree


  moddle.ids = new _ids.default([32, 36, 1]);
  return moddle;
};
/**
 * Collect ids processed during parsing of the
 * definitions object.
 *
 * @param {ModdleElement} definitions
 * @param {Context} context
 */


BaseModeler.prototype._collectIds = function (definitions, elementsById) {
  var moddle = definitions.$model,
      ids = moddle.ids,
      id; // remove references from previous import

  ids.clear();

  for (id in elementsById) {
    ids.claim(id, elementsById[id]);
  }
};

},{"./BaseViewer":14,"ids":346,"inherits":347}],14:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BaseViewer;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _tinySvg = require("tiny-svg");

var _diagramJs = _interopRequireDefault(require("diagram-js"));

var _bpmnModdle = _interopRequireDefault(require("bpmn-moddle"));

var _inherits = _interopRequireDefault(require("inherits"));

var _Importer = require("./import/Importer");

var _CompatibilityUtil = require("./util/CompatibilityUtil");

var _PoweredByUtil = require("./util/PoweredByUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * The code in the <project-logo></project-logo> area
 * must not be changed.
 *
 * @see http://bpmn.io/license for more information.
 */

/**
 * A base viewer for BPMN 2.0 diagrams.
 *
 * Have a look at {@link Viewer}, {@link NavigatedViewer} or {@link Modeler} for
 * bundles that include actual features.
 *
 * @param {Object} [options] configuration options to pass to the viewer
 * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
 * @param {string|number} [options.width] the width of the viewer
 * @param {string|number} [options.height] the height of the viewer
 * @param {Object} [options.moddleExtensions] extension packages to provide
 * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules
 * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules
 */
function BaseViewer(options) {
  options = (0, _minDash.assign)({}, DEFAULT_OPTIONS, options);
  this._moddle = this._createModdle(options);
  this._container = this._createContainer(options);
  /* <project-logo> */

  addProjectLogo(this._container);
  /* </project-logo> */

  this._init(this._container, this._moddle, options);
}

(0, _inherits.default)(BaseViewer, _diagramJs.default);
/**
* The importXML result.
*
* @typedef {Object} ImportXMLResult
*
* @property {Array<string>} warnings
*/

/**
* The importXML error.
*
* @typedef {Error} ImportXMLError
*
* @property {Array<string>} warnings
*/

/**
 * Parse and render a BPMN 2.0 diagram.
 *
 * Once finished the viewer reports back the result to the
 * provided callback function with (err, warnings).
 *
 * ## Life-Cycle Events
 *
 * During import the viewer will fire life-cycle events:
 *
 *   * import.parse.start (about to read model from xml)
 *   * import.parse.complete (model read; may have worked or not)
 *   * import.render.start (graphical import start)
 *   * import.render.complete (graphical import finished)
 *   * import.done (everything done)
 *
 * You can use these events to hook into the life-cycle.
 *
 * @param {string} xml the BPMN 2.0 xml
 * @param {ModdleElement<BPMNDiagram>|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered)
 *
 * Returns {Promise<ImportXMLResult, ImportXMLError>}
 */

BaseViewer.prototype.importXML = (0, _CompatibilityUtil.wrapForCompatibility)(function importXML(xml, bpmnDiagram) {
  var self = this;

  function ParseCompleteEvent(data) {
    var event = self.get('eventBus').createEvent(data); // TODO(nikku): remove with future bpmn-js version

    Object.defineProperty(event, 'context', {
      enumerable: true,
      get: function () {
        console.warn(new Error('import.parse.complete <context> is deprecated ' + 'and will be removed in future library versions'));
        return {
          warnings: data.warnings,
          references: data.references,
          elementsById: data.elementsById
        };
      }
    });
    return event;
  }

  return new Promise(function (resolve, reject) {
    // hook in pre-parse listeners +
    // allow xml manipulation
    xml = self._emit('import.parse.start', {
      xml: xml
    }) || xml;

    self._moddle.fromXML(xml, 'bpmn:Definitions').then(function (result) {
      var definitions = result.rootElement;
      var references = result.references;
      var parseWarnings = result.warnings;
      var elementsById = result.elementsById; // hook in post parse listeners +
      // allow definitions manipulation

      definitions = self._emit('import.parse.complete', ParseCompleteEvent({
        error: null,
        definitions: definitions,
        elementsById: elementsById,
        references: references,
        warnings: parseWarnings
      })) || definitions;
      self.importDefinitions(definitions, bpmnDiagram).then(function (result) {
        var allWarnings = [].concat(parseWarnings, result.warnings || []);

        self._emit('import.done', {
          error: null,
          warnings: allWarnings
        });

        return resolve({
          warnings: allWarnings
        });
      }).catch(function (err) {
        var allWarnings = [].concat(parseWarnings, err.warnings || []);

        self._emit('import.done', {
          error: err,
          warnings: allWarnings
        });

        return reject(addWarningsToError(err, allWarnings));
      });
    }).catch(function (err) {
      self._emit('import.parse.complete', {
        error: err
      });

      err = checkValidationError(err);

      self._emit('import.done', {
        error: err,
        warnings: err.warnings
      });

      return reject(err);
    });
  });
});
/**
* The importDefinitions result.
*
* @typedef {Object} ImportDefinitionsResult
*
* @property {Array<string>} warnings
*/

/**
* The importDefinitions error.
*
* @typedef {Error} ImportDefinitionsError
*
* @property {Array<string>} warnings
*/

/**
 * Import parsed definitions and render a BPMN 2.0 diagram.
 *
 * Once finished the viewer reports back the result to the
 * provided callback function with (err, warnings).
 *
 * ## Life-Cycle Events
 *
 * During import the viewer will fire life-cycle events:
 *
 *   * import.render.start (graphical import start)
 *   * import.render.complete (graphical import finished)
 *
 * You can use these events to hook into the life-cycle.
 *
 * @param {ModdleElement<Definitions>} definitions parsed BPMN 2.0 definitions
 * @param {ModdleElement<BPMNDiagram>|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered)
 *
 * Returns {Promise<ImportDefinitionsResult, ImportDefinitionsError>}
 */

BaseViewer.prototype.importDefinitions = (0, _CompatibilityUtil.wrapForCompatibility)(function importDefinitions(definitions, bpmnDiagram) {
  var self = this;
  return new Promise(function (resolve, reject) {
    self._setDefinitions(definitions);

    self.open(bpmnDiagram).then(function (result) {
      var warnings = result.warnings;
      return resolve({
        warnings: warnings
      });
    }).catch(function (err) {
      return reject(err);
    });
  });
});
/**
 * The open result.
 *
 * @typedef {Object} OpenResult
 *
 * @property {Array<string>} warnings
 */

/**
* The open error.
*
* @typedef {Error} OpenError
*
* @property {Array<string>} warnings
*/

/**
 * Open diagram of previously imported XML.
 *
 * Once finished the viewer reports back the result to the
 * provided callback function with (err, warnings).
 *
 * ## Life-Cycle Events
 *
 * During switch the viewer will fire life-cycle events:
 *
 *   * import.render.start (graphical import start)
 *   * import.render.complete (graphical import finished)
 *
 * You can use these events to hook into the life-cycle.
 *
 * @param {string|ModdleElement<BPMNDiagram>} [bpmnDiagramOrId] id or the diagram to open
 *
 * Returns {Promise<OpenResult, OpenError>}
 */

BaseViewer.prototype.open = (0, _CompatibilityUtil.wrapForCompatibility)(function open(bpmnDiagramOrId) {
  var definitions = this._definitions;
  var bpmnDiagram = bpmnDiagramOrId;
  var self = this;
  return new Promise(function (resolve, reject) {
    if (!definitions) {
      var err1 = new Error('no XML imported');
      return reject(addWarningsToError(err1, []));
    }

    if (typeof bpmnDiagramOrId === 'string') {
      bpmnDiagram = findBPMNDiagram(definitions, bpmnDiagramOrId);

      if (!bpmnDiagram) {
        var err2 = new Error('BPMNDiagram <' + bpmnDiagramOrId + '> not found');
        return reject(addWarningsToError(err2, []));
      }
    } // clear existing rendered diagram
    // catch synchronous exceptions during #clear()


    try {
      self.clear();
    } catch (error) {
      return reject(addWarningsToError(error, []));
    } // perform graphical import


    (0, _Importer.importBpmnDiagram)(self, definitions, bpmnDiagram).then(function (result) {
      var warnings = result.warnings;
      return resolve({
        warnings: warnings
      });
    }).catch(function (err) {
      return reject(err);
    });
  });
});
/**
 * The saveXML result.
 *
 * @typedef {Object} SaveXMLResult
 *
 * @property {string} xml
 */

/**
 * Export the currently displayed BPMN 2.0 diagram as
 * a BPMN 2.0 XML document.
 *
 * ## Life-Cycle Events
 *
 * During XML saving the viewer will fire life-cycle events:
 *
 *   * saveXML.start (before serialization)
 *   * saveXML.serialized (after xml generation)
 *   * saveXML.done (everything done)
 *
 * You can use these events to hook into the life-cycle.
 *
 * @param {Object} [options] export options
 * @param {boolean} [options.format=false] output formatted XML
 * @param {boolean} [options.preamble=true] output preamble
 *
 * Returns {Promise<SaveXMLResult, Error>}
 */

BaseViewer.prototype.saveXML = (0, _CompatibilityUtil.wrapForCompatibility)(function saveXML(options) {
  options = options || {};
  var self = this;
  var definitions = this._definitions;
  return new Promise(function (resolve, reject) {
    if (!definitions) {
      var err = new Error('no definitions loaded');
      return reject(err);
    } // allow to fiddle around with definitions


    definitions = self._emit('saveXML.start', {
      definitions: definitions
    }) || definitions;

    self._moddle.toXML(definitions, options).then(function (result) {
      var xml = result.xml;

      try {
        xml = self._emit('saveXML.serialized', {
          error: null,
          xml: xml
        }) || xml;

        self._emit('saveXML.done', {
          error: null,
          xml: xml
        });
      } catch (e) {
        console.error('error in saveXML life-cycle listener', e);
      }

      return resolve({
        xml: xml
      });
    }).catch(function (err) {
      return reject(err);
    });
  });
});
/**
 * The saveSVG result.
 *
 * @typedef {Object} SaveSVGResult
 *
 * @property {string} svg
 */

/**
 * Export the currently displayed BPMN 2.0 diagram as
 * an SVG image.
 *
 * ## Life-Cycle Events
 *
 * During SVG saving the viewer will fire life-cycle events:
 *
 *   * saveSVG.start (before serialization)
 *   * saveSVG.done (everything done)
 *
 * You can use these events to hook into the life-cycle.
 *
 * @param {Object} [options]
 *
 * Returns {Promise<SaveSVGResult, Error>}
 */

BaseViewer.prototype.saveSVG = (0, _CompatibilityUtil.wrapForCompatibility)(function saveSVG(options) {
  options = options || {};
  var self = this;
  return new Promise(function (resolve, reject) {
    self._emit('saveSVG.start');

    var svg, err;

    try {
      var canvas = self.get('canvas');
      var contentNode = canvas.getDefaultLayer(),
          defsNode = (0, _minDom.query)('defs', canvas._svg);
      var contents = (0, _tinySvg.innerSVG)(contentNode),
          defs = defsNode ? '<defs>' + (0, _tinySvg.innerSVG)(defsNode) + '</defs>' : '';
      var bbox = contentNode.getBBox();
      svg = '<?xml version="1.0" encoding="utf-8"?>\n' + '<!-- created with bpmn-js / http://bpmn.io -->\n' + '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ' + 'width="' + bbox.width + '" height="' + bbox.height + '" ' + 'viewBox="' + bbox.x + ' ' + bbox.y + ' ' + bbox.width + ' ' + bbox.height + '" version="1.1">' + defs + contents + '</svg>';
    } catch (e) {
      err = e;
    }

    self._emit('saveSVG.done', {
      error: err,
      svg: svg
    });

    if (!err) {
      return resolve({
        svg: svg
      });
    }

    return reject(err);
  });
});
/**
 * Get a named diagram service.
 *
 * @example
 *
 * var elementRegistry = viewer.get('elementRegistry');
 * var startEventShape = elementRegistry.get('StartEvent_1');
 *
 * @param {string} name
 *
 * @return {Object} diagram service instance
 *
 * @method BaseViewer#get
 */

/**
 * Invoke a function in the context of this viewer.
 *
 * @example
 *
 * viewer.invoke(function(elementRegistry) {
 *   var startEventShape = elementRegistry.get('StartEvent_1');
 * });
 *
 * @param {Function} fn to be invoked
 *
 * @return {Object} the functions return value
 *
 * @method BaseViewer#invoke
 */

BaseViewer.prototype._setDefinitions = function (definitions) {
  this._definitions = definitions;
};

BaseViewer.prototype.getModules = function () {
  return this._modules;
};
/**
 * Remove all drawn elements from the viewer.
 *
 * After calling this method the viewer can still
 * be reused for opening another diagram.
 *
 * @method BaseViewer#clear
 */


BaseViewer.prototype.clear = function () {
  if (!this.getDefinitions()) {
    // no diagram to clear
    return;
  } // remove businessObject#di binding
  //
  // this is necessary, as we establish the bindings
  // in the BpmnTreeWalker (and assume none are given
  // on reimport)


  this.get('elementRegistry').forEach(function (element) {
    var bo = element.businessObject;

    if (bo && bo.di) {
      delete bo.di;
    }
  }); // remove drawn elements

  _diagramJs.default.prototype.clear.call(this);
};
/**
 * Destroy the viewer instance and remove all its
 * remainders from the document tree.
 */


BaseViewer.prototype.destroy = function () {
  // diagram destroy
  _diagramJs.default.prototype.destroy.call(this); // dom detach


  (0, _minDom.remove)(this._container);
};
/**
 * Register an event listener
 *
 * Remove a previously added listener via {@link #off(event, callback)}.
 *
 * @param {string} event
 * @param {number} [priority]
 * @param {Function} callback
 * @param {Object} [that]
 */


BaseViewer.prototype.on = function (event, priority, callback, target) {
  return this.get('eventBus').on(event, priority, callback, target);
};
/**
 * De-register an event listener
 *
 * @param {string} event
 * @param {Function} callback
 */


BaseViewer.prototype.off = function (event, callback) {
  this.get('eventBus').off(event, callback);
};

BaseViewer.prototype.attachTo = function (parentNode) {
  if (!parentNode) {
    throw new Error('parentNode required');
  } // ensure we detach from the
  // previous, old parent


  this.detach(); // unwrap jQuery if provided

  if (parentNode.get && parentNode.constructor.prototype.jquery) {
    parentNode = parentNode.get(0);
  }

  if (typeof parentNode === 'string') {
    parentNode = (0, _minDom.query)(parentNode);
  }

  parentNode.appendChild(this._container);

  this._emit('attach', {});

  this.get('canvas').resized();
};

BaseViewer.prototype.getDefinitions = function () {
  return this._definitions;
};

BaseViewer.prototype.detach = function () {
  var container = this._container,
      parentNode = container.parentNode;

  if (!parentNode) {
    return;
  }

  this._emit('detach', {});

  parentNode.removeChild(container);
};

BaseViewer.prototype._init = function (container, moddle, options) {
  var baseModules = options.modules || this.getModules(),
      additionalModules = options.additionalModules || [],
      staticModules = [{
    bpmnjs: ['value', this],
    moddle: ['value', moddle]
  }];
  var diagramModules = [].concat(staticModules, baseModules, additionalModules);
  var diagramOptions = (0, _minDash.assign)((0, _minDash.omit)(options, ['additionalModules']), {
    canvas: (0, _minDash.assign)({}, options.canvas, {
      container: container
    }),
    modules: diagramModules
  }); // invoke diagram constructor

  _diagramJs.default.call(this, diagramOptions);

  if (options && options.container) {
    this.attachTo(options.container);
  }
};
/**
 * Emit an event on the underlying {@link EventBus}
 *
 * @param  {string} type
 * @param  {Object} event
 *
 * @return {Object} event processing result (if any)
 */


BaseViewer.prototype._emit = function (type, event) {
  return this.get('eventBus').fire(type, event);
};

BaseViewer.prototype._createContainer = function (options) {
  var container = (0, _minDom.domify)('<div class="bjs-container"></div>');
  (0, _minDash.assign)(container.style, {
    width: ensureUnit(options.width),
    height: ensureUnit(options.height),
    position: options.position
  });
  return container;
};

BaseViewer.prototype._createModdle = function (options) {
  var moddleOptions = (0, _minDash.assign)({}, this._moddleExtensions, options.moddleExtensions);
  return new _bpmnModdle.default(moddleOptions);
};

BaseViewer.prototype._modules = []; // helpers ///////////////

function addWarningsToError(err, warningsAry) {
  err.warnings = warningsAry;
  return err;
}

function checkValidationError(err) {
  // check if we can help the user by indicating wrong BPMN 2.0 xml
  // (in case he or the exporting tool did not get that right)
  var pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/;
  var match = pattern.exec(err.message);

  if (match) {
    err.message = 'unparsable content <' + match[1] + '> detected; ' + 'this may indicate an invalid BPMN 2.0 diagram file' + match[2];
  }

  return err;
}

var DEFAULT_OPTIONS = {
  width: '100%',
  height: '100%',
  position: 'relative'
};
/**
 * Ensure the passed argument is a proper unit (defaulting to px)
 */

function ensureUnit(val) {
  return val + ((0, _minDash.isNumber)(val) ? 'px' : '');
}
/**
 * Find BPMNDiagram in definitions by ID
 *
 * @param {ModdleElement<Definitions>} definitions
 * @param {string} diagramId
 *
 * @return {ModdleElement<BPMNDiagram>|null}
 */


function findBPMNDiagram(definitions, diagramId) {
  if (!diagramId) {
    return null;
  }

  return (0, _minDash.find)(definitions.diagrams, function (element) {
    return element.id === diagramId;
  }) || null;
}
/* <project-logo> */


/**
 * Adds the project logo to the diagram container as
 * required by the bpmn.io license.
 *
 * @see http://bpmn.io/license
 *
 * @param {Element} container
 */
function addProjectLogo(container) {
  var img = _PoweredByUtil.BPMNIO_IMG;
  var linkMarkup = '<a href="http://bpmn.io" ' + 'target="_blank" ' + 'class="bjs-powered-by" ' + 'title="Powered by bpmn.io" ' + 'style="position: absolute; bottom: 15px; right: 15px; z-index: 100; ' + _PoweredByUtil.LINK_STYLES + '">' + img + '</a>';
  var linkElement = (0, _minDom.domify)(linkMarkup);
  container.appendChild(linkElement);

  _minDom.event.bind(linkElement, 'click', function (event) {
    (0, _PoweredByUtil.open)();
    event.preventDefault();
  });
}
/* </project-logo> */

},{"./import/Importer":135,"./util/CompatibilityUtil":138,"./util/PoweredByUtil":142,"bpmn-moddle":330,"diagram-js":143,"inherits":347,"min-dash":555,"min-dom":556,"tiny-svg":567}],15:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Modeler;

var _inherits = _interopRequireDefault(require("inherits"));

var _BaseModeler = _interopRequireDefault(require("./BaseModeler"));

var _Viewer = _interopRequireDefault(require("./Viewer"));

var _NavigatedViewer = _interopRequireDefault(require("./NavigatedViewer"));

var _keyboardMove = _interopRequireDefault(require("diagram-js/lib/navigation/keyboard-move"));

var _movecanvas = _interopRequireDefault(require("diagram-js/lib/navigation/movecanvas"));

var _touch = _interopRequireDefault(require("diagram-js/lib/navigation/touch"));

var _zoomscroll = _interopRequireDefault(require("diagram-js/lib/navigation/zoomscroll"));

var _alignElements = _interopRequireDefault(require("diagram-js/lib/features/align-elements"));

var _autoPlace = _interopRequireDefault(require("./features/auto-place"));

var _autoResize = _interopRequireDefault(require("./features/auto-resize"));

var _autoScroll = _interopRequireDefault(require("diagram-js/lib/features/auto-scroll"));

var _bendpoints = _interopRequireDefault(require("diagram-js/lib/features/bendpoints"));

var _connect = _interopRequireDefault(require("diagram-js/lib/features/connect"));

var _connectionPreview = _interopRequireDefault(require("diagram-js/lib/features/connection-preview"));

var _contextPad = _interopRequireDefault(require("./features/context-pad"));

var _copyPaste = _interopRequireDefault(require("./features/copy-paste"));

var _create = _interopRequireDefault(require("diagram-js/lib/features/create"));

var _distributeElements = _interopRequireDefault(require("./features/distribute-elements"));

var _editorActions = _interopRequireDefault(require("./features/editor-actions"));

var _gridSnapping = _interopRequireDefault(require("./features/grid-snapping"));

var _interactionEvents = _interopRequireDefault(require("./features/interaction-events"));

var _keyboard = _interopRequireDefault(require("./features/keyboard"));

var _keyboardMoveSelection = _interopRequireDefault(require("diagram-js/lib/features/keyboard-move-selection"));

var _labelEditing = _interopRequireDefault(require("./features/label-editing"));

var _modeling = _interopRequireDefault(require("./features/modeling"));

var _move = _interopRequireDefault(require("diagram-js/lib/features/move"));

var _palette = _interopRequireDefault(require("./features/palette"));

var _replacePreview = _interopRequireDefault(require("./features/replace-preview"));

var _resize = _interopRequireDefault(require("diagram-js/lib/features/resize"));

var _snapping = _interopRequireDefault(require("./features/snapping"));

var _search = _interopRequireDefault(require("./features/search"));

var _CompatibilityUtil = require("./util/CompatibilityUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var initialDiagram = '<?xml version="1.0" encoding="UTF-8"?>' + '<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' + 'xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" ' + 'xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" ' + 'xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" ' + 'targetNamespace="http://bpmn.io/schema/bpmn" ' + 'id="Definitions_1">' + '<bpmn:process id="Process_1" isExecutable="false">' + '<bpmn:startEvent id="StartEvent_1"/>' + '</bpmn:process>' + '<bpmndi:BPMNDiagram id="BPMNDiagram_1">' + '<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">' + '<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">' + '<dc:Bounds height="36.0" width="36.0" x="173.0" y="102.0"/>' + '</bpmndi:BPMNShape>' + '</bpmndi:BPMNPlane>' + '</bpmndi:BPMNDiagram>' + '</bpmn:definitions>';
/**
 * A modeler for BPMN 2.0 diagrams.
 *
 *
 * ## Extending the Modeler
 *
 * In order to extend the viewer pass extension modules to bootstrap via the
 * `additionalModules` option. An extension module is an object that exposes
 * named services.
 *
 * The following example depicts the integration of a simple
 * logging component that integrates with interaction events:
 *
 *
 * ```javascript
 *
 * // logging component
 * function InteractionLogger(eventBus) {
 *   eventBus.on('element.hover', function(event) {
 *     console.log()
 *   })
 * }
 *
 * InteractionLogger.$inject = [ 'eventBus' ]; // minification save
 *
 * // extension module
 * var extensionModule = {
 *   __init__: [ 'interactionLogger' ],
 *   interactionLogger: [ 'type', InteractionLogger ]
 * };
 *
 * // extend the viewer
 * var bpmnModeler = new Modeler({ additionalModules: [ extensionModule ] });
 * bpmnModeler.importXML(...);
 * ```
 *
 *
 * ## Customizing / Replacing Components
 *
 * You can replace individual diagram components by redefining them in override modules.
 * This works for all components, including those defined in the core.
 *
 * Pass in override modules via the `options.additionalModules` flag like this:
 *
 * ```javascript
 * function CustomContextPadProvider(contextPad) {
 *
 *   contextPad.registerProvider(this);
 *
 *   this.getContextPadEntries = function(element) {
 *     // no entries, effectively disable the context pad
 *     return {};
 *   };
 * }
 *
 * CustomContextPadProvider.$inject = [ 'contextPad' ];
 *
 * var overrideModule = {
 *   contextPadProvider: [ 'type', CustomContextPadProvider ]
 * };
 *
 * var bpmnModeler = new Modeler({ additionalModules: [ overrideModule ]});
 * ```
 *
 * @param {Object} [options] configuration options to pass to the viewer
 * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
 * @param {string|number} [options.width] the width of the viewer
 * @param {string|number} [options.height] the height of the viewer
 * @param {Object} [options.moddleExtensions] extension packages to provide
 * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules
 * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules
 */

function Modeler(options) {
  _BaseModeler.default.call(this, options);
}

(0, _inherits.default)(Modeler, _BaseModeler.default);
Modeler.Viewer = _Viewer.default;
Modeler.NavigatedViewer = _NavigatedViewer.default;
/**
* The createDiagram result.
*
* @typedef {Object} CreateDiagramResult
*
* @property {Array<string>} warnings
*/

/**
* The createDiagram error.
*
* @typedef {Error} CreateDiagramError
*
* @property {Array<string>} warnings
*/

/**
 * Create a new diagram to start modeling.
 *
 * Returns {Promise<CreateDiagramResult, CreateDiagramError>}
 */

Modeler.prototype.createDiagram = (0, _CompatibilityUtil.wrapForCompatibility)(function createDiagram() {
  return this.importXML(initialDiagram);
});
Modeler.prototype._interactionModules = [// non-modeling components
_keyboardMove.default, _movecanvas.default, _touch.default, _zoomscroll.default];
Modeler.prototype._modelingModules = [// modeling components
_alignElements.default, _autoPlace.default, _autoScroll.default, _autoResize.default, _bendpoints.default, _connect.default, _connectionPreview.default, _contextPad.default, _copyPaste.default, _create.default, _distributeElements.default, _editorActions.default, _gridSnapping.default, _interactionEvents.default, _keyboard.default, _keyboardMoveSelection.default, _labelEditing.default, _modeling.default, _move.default, _palette.default, _replacePreview.default, _resize.default, _snapping.default, _search.default]; // modules the modeler is composed of
//
// - viewer modules
// - interaction modules
// - modeling modules

Modeler.prototype._modules = [].concat(_Viewer.default.prototype._modules, Modeler.prototype._interactionModules, Modeler.prototype._modelingModules);

},{"./BaseModeler":13,"./NavigatedViewer":16,"./Viewer":17,"./features/auto-place":26,"./features/auto-resize":29,"./features/context-pad":31,"./features/copy-paste":34,"./features/distribute-elements":38,"./features/editor-actions":40,"./features/grid-snapping":46,"./features/interaction-events":48,"./features/keyboard":50,"./features/label-editing":55,"./features/modeling":110,"./features/palette":116,"./features/replace-preview":121,"./features/search":128,"./features/snapping":132,"./util/CompatibilityUtil":138,"diagram-js/lib/features/align-elements":159,"diagram-js/lib/features/auto-scroll":169,"diagram-js/lib/features/bendpoints":176,"diagram-js/lib/features/connect":183,"diagram-js/lib/features/connection-preview":185,"diagram-js/lib/features/create":192,"diagram-js/lib/features/keyboard-move-selection":213,"diagram-js/lib/features/move":251,"diagram-js/lib/features/resize":269,"diagram-js/lib/navigation/keyboard-move":304,"diagram-js/lib/navigation/movecanvas":306,"diagram-js/lib/navigation/touch":307,"diagram-js/lib/navigation/zoomscroll":310,"inherits":347}],16:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = NavigatedViewer;

var _inherits = _interopRequireDefault(require("inherits"));

var _Viewer = _interopRequireDefault(require("./Viewer"));

var _keyboardMove = _interopRequireDefault(require("diagram-js/lib/navigation/keyboard-move"));

var _movecanvas = _interopRequireDefault(require("diagram-js/lib/navigation/movecanvas"));

var _zoomscroll = _interopRequireDefault(require("diagram-js/lib/navigation/zoomscroll"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A viewer that includes mouse navigation facilities
 *
 * @param {Object} options
 */
function NavigatedViewer(options) {
  _Viewer.default.call(this, options);
}

(0, _inherits.default)(NavigatedViewer, _Viewer.default);
NavigatedViewer.prototype._navigationModules = [_keyboardMove.default, _movecanvas.default, _zoomscroll.default];
NavigatedViewer.prototype._modules = [].concat(_Viewer.default.prototype._modules, NavigatedViewer.prototype._navigationModules);

},{"./Viewer":17,"diagram-js/lib/navigation/keyboard-move":304,"diagram-js/lib/navigation/movecanvas":306,"diagram-js/lib/navigation/zoomscroll":310,"inherits":347}],17:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Viewer;

var _inherits = _interopRequireDefault(require("inherits"));

var _core = _interopRequireDefault(require("./core"));

var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate"));

var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection"));

var _overlays = _interopRequireDefault(require("diagram-js/lib/features/overlays"));

var _BaseViewer = _interopRequireDefault(require("./BaseViewer"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A viewer for BPMN 2.0 diagrams.
 *
 * Have a look at {@link NavigatedViewer} or {@link Modeler} for bundles that include
 * additional features.
 *
 *
 * ## Extending the Viewer
 *
 * In order to extend the viewer pass extension modules to bootstrap via the
 * `additionalModules` option. An extension module is an object that exposes
 * named services.
 *
 * The following example depicts the integration of a simple
 * logging component that integrates with interaction events:
 *
 *
 * ```javascript
 *
 * // logging component
 * function InteractionLogger(eventBus) {
 *   eventBus.on('element.hover', function(event) {
 *     console.log()
 *   })
 * }
 *
 * InteractionLogger.$inject = [ 'eventBus' ]; // minification save
 *
 * // extension module
 * var extensionModule = {
 *   __init__: [ 'interactionLogger' ],
 *   interactionLogger: [ 'type', InteractionLogger ]
 * };
 *
 * // extend the viewer
 * var bpmnViewer = new Viewer({ additionalModules: [ extensionModule ] });
 * bpmnViewer.importXML(...);
 * ```
 *
 * @param {Object} [options] configuration options to pass to the viewer
 * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
 * @param {string|number} [options.width] the width of the viewer
 * @param {string|number} [options.height] the height of the viewer
 * @param {Object} [options.moddleExtensions] extension packages to provide
 * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules
 * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules
 */
function Viewer(options) {
  _BaseViewer.default.call(this, options);
}

(0, _inherits.default)(Viewer, _BaseViewer.default); // modules the viewer is composed of

Viewer.prototype._modules = [_core.default, _translate.default, _selection.default, _overlays.default]; // default moddle extensions the viewer is composed of

Viewer.prototype._moddleExtensions = {};

},{"./BaseViewer":14,"./core":18,"diagram-js/lib/features/overlays":256,"diagram-js/lib/features/selection":278,"diagram-js/lib/i18n/translate":296,"inherits":347}],18:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _draw = _interopRequireDefault(require("../draw"));

var _import = _interopRequireDefault(require("../import"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_draw.default, _import.default]
};
exports.default = _default;

},{"../draw":23,"../import":137}],19:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.isTypedEvent = isTypedEvent;
exports.isThrowEvent = isThrowEvent;
exports.isCollection = isCollection;
exports.getDi = getDi;
exports.getSemantic = getSemantic;
exports.getFillColor = getFillColor;
exports.getStrokeColor = getStrokeColor;
exports.getCirclePath = getCirclePath;
exports.getRoundRectPath = getRoundRectPath;
exports.getDiamondPath = getDiamondPath;
exports.getRectPath = getRectPath;

var _minDash = require("min-dash");

var _RenderUtil = require("diagram-js/lib/util/RenderUtil");

// element utils //////////////////////

/**
 * Checks if eventDefinition of the given element matches with semantic type.
 *
 * @return {boolean} true if element is of the given semantic type
 */
function isTypedEvent(event, eventDefinitionType, filter) {
  function matches(definition, filter) {
    return (0, _minDash.every)(filter, function (val, key) {
      // we want a == conversion here, to be able to catch
      // undefined == false and friends

      /* jshint -W116 */
      return definition[key] == val;
    });
  }

  return (0, _minDash.some)(event.eventDefinitions, function (definition) {
    return definition.$type === eventDefinitionType && matches(event, filter);
  });
}

function isThrowEvent(event) {
  return event.$type === 'bpmn:IntermediateThrowEvent' || event.$type === 'bpmn:EndEvent';
}

function isCollection(element) {
  var dataObject = element.dataObjectRef;
  return element.isCollection || dataObject && dataObject.isCollection;
}

function getDi(element) {
  return element.businessObject.di;
}

function getSemantic(element) {
  return element.businessObject;
} // color access //////////////////////


function getFillColor(element, defaultColor) {
  return getDi(element).get('bioc:fill') || defaultColor || 'white';
}

function getStrokeColor(element, defaultColor) {
  return getDi(element).get('bioc:stroke') || defaultColor || 'black';
} // cropping path customizations //////////////////////


function getCirclePath(shape) {
  var cx = shape.x + shape.width / 2,
      cy = shape.y + shape.height / 2,
      radius = shape.width / 2;
  var circlePath = [['M', cx, cy], ['m', 0, -radius], ['a', radius, radius, 0, 1, 1, 0, 2 * radius], ['a', radius, radius, 0, 1, 1, 0, -2 * radius], ['z']];
  return (0, _RenderUtil.componentsToPath)(circlePath);
}

function getRoundRectPath(shape, borderRadius) {
  var x = shape.x,
      y = shape.y,
      width = shape.width,
      height = shape.height;
  var roundRectPath = [['M', x + borderRadius, y], ['l', width - borderRadius * 2, 0], ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, borderRadius], ['l', 0, height - borderRadius * 2], ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, borderRadius], ['l', borderRadius * 2 - width, 0], ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, -borderRadius], ['l', 0, borderRadius * 2 - height], ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, -borderRadius], ['z']];
  return (0, _RenderUtil.componentsToPath)(roundRectPath);
}

function getDiamondPath(shape) {
  var width = shape.width,
      height = shape.height,
      x = shape.x,
      y = shape.y,
      halfWidth = width / 2,
      halfHeight = height / 2;
  var diamondPath = [['M', x + halfWidth, y], ['l', halfWidth, halfHeight], ['l', -halfWidth, halfHeight], ['l', -halfWidth, -halfHeight], ['z']];
  return (0, _RenderUtil.componentsToPath)(diamondPath);
}

function getRectPath(shape) {
  var x = shape.x,
      y = shape.y,
      width = shape.width,
      height = shape.height;
  var rectPath = [['M', x, y], ['l', width, 0], ['l', 0, height], ['l', -width, 0], ['z']];
  return (0, _RenderUtil.componentsToPath)(rectPath);
}

},{"diagram-js/lib/util/RenderUtil":327,"min-dash":555}],20:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnRenderer;

var _inherits = _interopRequireDefault(require("inherits"));

var _minDash = require("min-dash");

var _BaseRenderer = _interopRequireDefault(require("diagram-js/lib/draw/BaseRenderer"));

var _DiUtil = require("../util/DiUtil");

var _LabelUtil = require("../features/label-editing/LabelUtil");

var _ModelUtil = require("../util/ModelUtil");

var _RenderUtil = require("diagram-js/lib/util/RenderUtil");

var _BpmnRenderUtil = require("./BpmnRenderUtil");

var _minDom = require("min-dom");

var _tinySvg = require("tiny-svg");

var _SvgTransformUtil = require("diagram-js/lib/util/SvgTransformUtil");

var _ids = _interopRequireDefault(require("ids"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var RENDERER_IDS = new _ids.default();
var TASK_BORDER_RADIUS = 10;
var INNER_OUTER_DIST = 3;
var DEFAULT_FILL_OPACITY = .95,
    HIGH_FILL_OPACITY = .35;

function BpmnRenderer(config, eventBus, styles, pathMap, canvas, textRenderer, priority) {
  _BaseRenderer.default.call(this, eventBus, priority);

  var defaultFillColor = config && config.defaultFillColor,
      defaultStrokeColor = config && config.defaultStrokeColor;
  var rendererId = RENDERER_IDS.next();
  var markers = {};
  var computeStyle = styles.computeStyle;

  function addMarker(id, options) {
    var attrs = (0, _minDash.assign)({
      fill: 'black',
      strokeWidth: 1,
      strokeLinecap: 'round',
      strokeDasharray: 'none'
    }, options.attrs);
    var ref = options.ref || {
      x: 0,
      y: 0
    };
    var scale = options.scale || 1; // fix for safari / chrome / firefox bug not correctly
    // resetting stroke dash array

    if (attrs.strokeDasharray === 'none') {
      attrs.strokeDasharray = [10000, 1];
    }

    var marker = (0, _tinySvg.create)('marker');
    (0, _tinySvg.attr)(options.element, attrs);
    (0, _tinySvg.append)(marker, options.element);
    (0, _tinySvg.attr)(marker, {
      id: id,
      viewBox: '0 0 20 20',
      refX: ref.x,
      refY: ref.y,
      markerWidth: 20 * scale,
      markerHeight: 20 * scale,
      orient: 'auto'
    });
    var defs = (0, _minDom.query)('defs', canvas._svg);

    if (!defs) {
      defs = (0, _tinySvg.create)('defs');
      (0, _tinySvg.append)(canvas._svg, defs);
    }

    (0, _tinySvg.append)(defs, marker);
    markers[id] = marker;
  }

  function colorEscape(str) {
    // only allow characters and numbers
    return str.replace(/[^0-9a-zA-z]+/g, '_');
  }

  function marker(type, fill, stroke) {
    var id = type + '-' + colorEscape(fill) + '-' + colorEscape(stroke) + '-' + rendererId;

    if (!markers[id]) {
      createMarker(id, type, fill, stroke);
    }

    return 'url(#' + id + ')';
  }

  function createMarker(id, type, fill, stroke) {
    if (type === 'sequenceflow-end') {
      var sequenceflowEnd = (0, _tinySvg.create)('path');
      (0, _tinySvg.attr)(sequenceflowEnd, {
        d: 'M 1 5 L 11 10 L 1 15 Z'
      });
      addMarker(id, {
        element: sequenceflowEnd,
        ref: {
          x: 11,
          y: 10
        },
        scale: 0.5,
        attrs: {
          fill: stroke,
          stroke: stroke
        }
      });
    }

    if (type === 'messageflow-start') {
      var messageflowStart = (0, _tinySvg.create)('circle');
      (0, _tinySvg.attr)(messageflowStart, {
        cx: 6,
        cy: 6,
        r: 3.5
      });
      addMarker(id, {
        element: messageflowStart,
        attrs: {
          fill: fill,
          stroke: stroke
        },
        ref: {
          x: 6,
          y: 6
        }
      });
    }

    if (type === 'messageflow-end') {
      var messageflowEnd = (0, _tinySvg.create)('path');
      (0, _tinySvg.attr)(messageflowEnd, {
        d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z'
      });
      addMarker(id, {
        element: messageflowEnd,
        attrs: {
          fill: fill,
          stroke: stroke,
          strokeLinecap: 'butt'
        },
        ref: {
          x: 8.5,
          y: 5
        }
      });
    }

    if (type === 'association-start') {
      var associationStart = (0, _tinySvg.create)('path');
      (0, _tinySvg.attr)(associationStart, {
        d: 'M 11 5 L 1 10 L 11 15'
      });
      addMarker(id, {
        element: associationStart,
        attrs: {
          fill: 'none',
          stroke: stroke,
          strokeWidth: 1.5
        },
        ref: {
          x: 1,
          y: 10
        },
        scale: 0.5
      });
    }

    if (type === 'association-end') {
      var associationEnd = (0, _tinySvg.create)('path');
      (0, _tinySvg.attr)(associationEnd, {
        d: 'M 1 5 L 11 10 L 1 15'
      });
      addMarker(id, {
        element: associationEnd,
        attrs: {
          fill: 'none',
          stroke: stroke,
          strokeWidth: 1.5
        },
        ref: {
          x: 12,
          y: 10
        },
        scale: 0.5
      });
    }

    if (type === 'conditional-flow-marker') {
      var conditionalflowMarker = (0, _tinySvg.create)('path');
      (0, _tinySvg.attr)(conditionalflowMarker, {
        d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z'
      });
      addMarker(id, {
        element: conditionalflowMarker,
        attrs: {
          fill: fill,
          stroke: stroke
        },
        ref: {
          x: -1,
          y: 10
        },
        scale: 0.5
      });
    }

    if (type === 'conditional-default-flow-marker') {
      var conditionaldefaultflowMarker = (0, _tinySvg.create)('path');
      (0, _tinySvg.attr)(conditionaldefaultflowMarker, {
        d: 'M 6 4 L 10 16'
      });
      addMarker(id, {
        element: conditionaldefaultflowMarker,
        attrs: {
          stroke: stroke
        },
        ref: {
          x: 0,
          y: 10
        },
        scale: 0.5
      });
    }
  }

  function drawCircle(parentGfx, width, height, offset, attrs) {
    if ((0, _minDash.isObject)(offset)) {
      attrs = offset;
      offset = 0;
    }

    offset = offset || 0;
    attrs = computeStyle(attrs, {
      stroke: 'black',
      strokeWidth: 2,
      fill: 'white'
    });

    if (attrs.fill === 'none') {
      delete attrs.fillOpacity;
    }

    var cx = width / 2,
        cy = height / 2;
    var circle = (0, _tinySvg.create)('circle');
    (0, _tinySvg.attr)(circle, {
      cx: cx,
      cy: cy,
      r: Math.round((width + height) / 4 - offset)
    });
    (0, _tinySvg.attr)(circle, attrs);
    (0, _tinySvg.append)(parentGfx, circle);
    return circle;
  }

  function drawRect(parentGfx, width, height, r, offset, attrs) {
    if ((0, _minDash.isObject)(offset)) {
      attrs = offset;
      offset = 0;
    }

    offset = offset || 0;
    attrs = computeStyle(attrs, {
      stroke: 'black',
      strokeWidth: 2,
      fill: 'white'
    });
    var rect = (0, _tinySvg.create)('rect');
    (0, _tinySvg.attr)(rect, {
      x: offset,
      y: offset,
      width: width - offset * 2,
      height: height - offset * 2,
      rx: r,
      ry: r
    });
    (0, _tinySvg.attr)(rect, attrs);
    (0, _tinySvg.append)(parentGfx, rect);
    return rect;
  }

  function drawDiamond(parentGfx, width, height, attrs) {
    var x_2 = width / 2;
    var y_2 = height / 2;
    var points = [{
      x: x_2,
      y: 0
    }, {
      x: width,
      y: y_2
    }, {
      x: x_2,
      y: height
    }, {
      x: 0,
      y: y_2
    }];
    var pointsString = points.map(function (point) {
      return point.x + ',' + point.y;
    }).join(' ');
    attrs = computeStyle(attrs, {
      stroke: 'black',
      strokeWidth: 2,
      fill: 'white'
    });
    var polygon = (0, _tinySvg.create)('polygon');
    (0, _tinySvg.attr)(polygon, {
      points: pointsString
    });
    (0, _tinySvg.attr)(polygon, attrs);
    (0, _tinySvg.append)(parentGfx, polygon);
    return polygon;
  }

  function drawLine(parentGfx, waypoints, attrs) {
    attrs = computeStyle(attrs, ['no-fill'], {
      stroke: 'black',
      strokeWidth: 2,
      fill: 'none'
    });
    var line = (0, _RenderUtil.createLine)(waypoints, attrs);
    (0, _tinySvg.append)(parentGfx, line);
    return line;
  }

  function drawPath(parentGfx, d, attrs) {
    attrs = computeStyle(attrs, ['no-fill'], {
      strokeWidth: 2,
      stroke: 'black'
    });
    var path = (0, _tinySvg.create)('path');
    (0, _tinySvg.attr)(path, {
      d: d
    });
    (0, _tinySvg.attr)(path, attrs);
    (0, _tinySvg.append)(parentGfx, path);
    return path;
  }

  function drawMarker(type, parentGfx, path, attrs) {
    return drawPath(parentGfx, path, (0, _minDash.assign)({
      'data-marker': type
    }, attrs));
  }

  function as(type) {
    return function (parentGfx, element) {
      return handlers[type](parentGfx, element);
    };
  }

  function renderer(type) {
    return handlers[type];
  }

  function renderEventContent(element, parentGfx) {
    var event = (0, _BpmnRenderUtil.getSemantic)(element);
    var isThrowing = (0, _BpmnRenderUtil.isThrowEvent)(event);

    if (event.eventDefinitions && event.eventDefinitions.length > 1) {
      if (event.parallelMultiple) {
        return renderer('bpmn:ParallelMultipleEventDefinition')(parentGfx, element, isThrowing);
      } else {
        return renderer('bpmn:MultipleEventDefinition')(parentGfx, element, isThrowing);
      }
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:MessageEventDefinition')) {
      return renderer('bpmn:MessageEventDefinition')(parentGfx, element, isThrowing);
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TimerEventDefinition')) {
      return renderer('bpmn:TimerEventDefinition')(parentGfx, element, isThrowing);
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:ConditionalEventDefinition')) {
      return renderer('bpmn:ConditionalEventDefinition')(parentGfx, element);
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:SignalEventDefinition')) {
      return renderer('bpmn:SignalEventDefinition')(parentGfx, element, isThrowing);
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:EscalationEventDefinition')) {
      return renderer('bpmn:EscalationEventDefinition')(parentGfx, element, isThrowing);
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:LinkEventDefinition')) {
      return renderer('bpmn:LinkEventDefinition')(parentGfx, element, isThrowing);
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:ErrorEventDefinition')) {
      return renderer('bpmn:ErrorEventDefinition')(parentGfx, element, isThrowing);
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CancelEventDefinition')) {
      return renderer('bpmn:CancelEventDefinition')(parentGfx, element, isThrowing);
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CompensateEventDefinition')) {
      return renderer('bpmn:CompensateEventDefinition')(parentGfx, element, isThrowing);
    }

    if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TerminateEventDefinition')) {
      return renderer('bpmn:TerminateEventDefinition')(parentGfx, element, isThrowing);
    }

    return null;
  }

  function renderLabel(parentGfx, label, options) {
    options = (0, _minDash.assign)({
      size: {
        width: 100
      }
    }, options);
    var text = textRenderer.createText(label || '', options);
    (0, _tinySvg.classes)(text).add('djs-label');
    (0, _tinySvg.append)(parentGfx, text);
    return text;
  }

  function renderEmbeddedLabel(parentGfx, element, align) {
    var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
    return renderLabel(parentGfx, semantic.name, {
      box: element,
      align: align,
      padding: 5,
      style: {
        fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      }
    });
  }

  function renderExternalLabel(parentGfx, element) {
    var box = {
      width: 90,
      height: 30,
      x: element.width / 2 + element.x,
      y: element.height / 2 + element.y
    };
    return renderLabel(parentGfx, (0, _LabelUtil.getLabel)(element), {
      box: box,
      fitBox: true,
      style: (0, _minDash.assign)({}, textRenderer.getExternalStyle(), {
        fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      })
    });
  }

  function renderLaneLabel(parentGfx, text, element) {
    var textBox = renderLabel(parentGfx, text, {
      box: {
        height: 30,
        width: element.height
      },
      align: 'center-middle',
      style: {
        fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      }
    });
    var top = -1 * element.height;
    (0, _SvgTransformUtil.transform)(textBox, 0, -top, 270);
  }

  function createPathFromConnection(connection) {
    var waypoints = connection.waypoints;
    var pathData = 'm  ' + waypoints[0].x + ',' + waypoints[0].y;

    for (var i = 1; i < waypoints.length; i++) {
      pathData += 'L' + waypoints[i].x + ',' + waypoints[i].y + ' ';
    }

    return pathData;
  }

  var handlers = this.handlers = {
    'bpmn:Event': function (parentGfx, element, attrs) {
      if (!('fillOpacity' in attrs)) {
        attrs.fillOpacity = DEFAULT_FILL_OPACITY;
      }

      return drawCircle(parentGfx, element.width, element.height, attrs);
    },
    'bpmn:StartEvent': function (parentGfx, element) {
      var attrs = {
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      };
      var semantic = (0, _BpmnRenderUtil.getSemantic)(element);

      if (!semantic.isInterrupting) {
        attrs = {
          strokeDasharray: '6',
          strokeLinecap: 'round',
          fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
          stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
        };
      }

      var circle = renderer('bpmn:Event')(parentGfx, element, attrs);
      renderEventContent(element, parentGfx);
      return circle;
    },
    'bpmn:MessageEventDefinition': function (parentGfx, element, isThrowing) {
      var pathData = pathMap.getScaledPath('EVENT_MESSAGE', {
        xScaleFactor: 0.9,
        yScaleFactor: 0.9,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: 0.235,
          my: 0.315
        }
      });
      var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) : (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor);
      var stroke = isThrowing ? (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor) : (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
      var messagePath = drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: fill,
        stroke: stroke
      });
      return messagePath;
    },
    'bpmn:TimerEventDefinition': function (parentGfx, element) {
      var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, {
        strokeWidth: 2,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', {
        xScaleFactor: 0.75,
        yScaleFactor: 0.75,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: 0.5,
          my: 0.5
        }
      });
      drawPath(parentGfx, pathData, {
        strokeWidth: 2,
        strokeLinecap: 'square',
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });

      for (var i = 0; i < 12; i++) {
        var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', {
          xScaleFactor: 0.75,
          yScaleFactor: 0.75,
          containerWidth: element.width,
          containerHeight: element.height,
          position: {
            mx: 0.5,
            my: 0.5
          }
        });
        var width = element.width / 2;
        var height = element.height / 2;
        drawPath(parentGfx, linePathData, {
          strokeWidth: 1,
          strokeLinecap: 'square',
          transform: 'rotate(' + i * 30 + ',' + height + ',' + width + ')',
          stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
        });
      }

      return circle;
    },
    'bpmn:EscalationEventDefinition': function (parentGfx, event, isThrowing) {
      var pathData = pathMap.getScaledPath('EVENT_ESCALATION', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: event.width,
        containerHeight: event.height,
        position: {
          mx: 0.5,
          my: 0.2
        }
      });
      var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
      return drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: fill,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
      });
    },
    'bpmn:ConditionalEventDefinition': function (parentGfx, event) {
      var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: event.width,
        containerHeight: event.height,
        position: {
          mx: 0.5,
          my: 0.222
        }
      });
      return drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
      });
    },
    'bpmn:LinkEventDefinition': function (parentGfx, event, isThrowing) {
      var pathData = pathMap.getScaledPath('EVENT_LINK', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: event.width,
        containerHeight: event.height,
        position: {
          mx: 0.57,
          my: 0.263
        }
      });
      var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
      return drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: fill,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
      });
    },
    'bpmn:ErrorEventDefinition': function (parentGfx, event, isThrowing) {
      var pathData = pathMap.getScaledPath('EVENT_ERROR', {
        xScaleFactor: 1.1,
        yScaleFactor: 1.1,
        containerWidth: event.width,
        containerHeight: event.height,
        position: {
          mx: 0.2,
          my: 0.722
        }
      });
      var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
      return drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: fill,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
      });
    },
    'bpmn:CancelEventDefinition': function (parentGfx, event, isThrowing) {
      var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', {
        xScaleFactor: 1.0,
        yScaleFactor: 1.0,
        containerWidth: event.width,
        containerHeight: event.height,
        position: {
          mx: 0.638,
          my: -0.055
        }
      });
      var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
      var path = drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: fill,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
      });
      (0, _SvgTransformUtil.rotate)(path, 45);
      return path;
    },
    'bpmn:CompensateEventDefinition': function (parentGfx, event, isThrowing) {
      var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: event.width,
        containerHeight: event.height,
        position: {
          mx: 0.22,
          my: 0.5
        }
      });
      var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
      return drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: fill,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
      });
    },
    'bpmn:SignalEventDefinition': function (parentGfx, event, isThrowing) {
      var pathData = pathMap.getScaledPath('EVENT_SIGNAL', {
        xScaleFactor: 0.9,
        yScaleFactor: 0.9,
        containerWidth: event.width,
        containerHeight: event.height,
        position: {
          mx: 0.5,
          my: 0.2
        }
      });
      var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
      return drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: fill,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
      });
    },
    'bpmn:MultipleEventDefinition': function (parentGfx, event, isThrowing) {
      var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', {
        xScaleFactor: 1.1,
        yScaleFactor: 1.1,
        containerWidth: event.width,
        containerHeight: event.height,
        position: {
          mx: 0.222,
          my: 0.36
        }
      });
      var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none';
      return drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: fill
      });
    },
    'bpmn:ParallelMultipleEventDefinition': function (parentGfx, event) {
      var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', {
        xScaleFactor: 1.2,
        yScaleFactor: 1.2,
        containerWidth: event.width,
        containerHeight: event.height,
        position: {
          mx: 0.458,
          my: 0.194
        }
      });
      return drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor)
      });
    },
    'bpmn:EndEvent': function (parentGfx, element) {
      var circle = renderer('bpmn:Event')(parentGfx, element, {
        strokeWidth: 4,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      renderEventContent(element, parentGfx, true);
      return circle;
    },
    'bpmn:TerminateEventDefinition': function (parentGfx, element) {
      var circle = drawCircle(parentGfx, element.width, element.height, 8, {
        strokeWidth: 4,
        fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return circle;
    },
    'bpmn:IntermediateEvent': function (parentGfx, element) {
      var outer = renderer('bpmn:Event')(parentGfx, element, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      /* inner */

      drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, 'none'),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      renderEventContent(element, parentGfx);
      return outer;
    },
    'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'),
    'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'),
    'bpmn:Activity': function (parentGfx, element, attrs) {
      attrs = attrs || {};

      if (!('fillOpacity' in attrs)) {
        attrs.fillOpacity = DEFAULT_FILL_OPACITY;
      }

      return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, attrs);
    },
    'bpmn:Task': function (parentGfx, element) {
      var attrs = {
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      };
      var rect = renderer('bpmn:Activity')(parentGfx, element, attrs);
      renderEmbeddedLabel(parentGfx, element, 'center-middle');
      attachTaskMarkers(parentGfx, element);
      return rect;
    },
    'bpmn:ServiceTask': function (parentGfx, element) {
      var task = renderer('bpmn:Task')(parentGfx, element);
      var pathDataBG = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
        abspos: {
          x: 12,
          y: 18
        }
      });
      /* service bg */

      drawPath(parentGfx, pathDataBG, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      var fillPathData = pathMap.getScaledPath('TASK_TYPE_SERVICE_FILL', {
        abspos: {
          x: 17.2,
          y: 18
        }
      });
      /* service fill */

      drawPath(parentGfx, fillPathData, {
        strokeWidth: 0,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor)
      });
      var pathData = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
        abspos: {
          x: 17,
          y: 22
        }
      });
      /* service */

      drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return task;
    },
    'bpmn:UserTask': function (parentGfx, element) {
      var task = renderer('bpmn:Task')(parentGfx, element);
      var x = 15;
      var y = 12;
      var pathData = pathMap.getScaledPath('TASK_TYPE_USER_1', {
        abspos: {
          x: x,
          y: y
        }
      });
      /* user path */

      drawPath(parentGfx, pathData, {
        strokeWidth: 0.5,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      var pathData2 = pathMap.getScaledPath('TASK_TYPE_USER_2', {
        abspos: {
          x: x,
          y: y
        }
      });
      /* user2 path */

      drawPath(parentGfx, pathData2, {
        strokeWidth: 0.5,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      var pathData3 = pathMap.getScaledPath('TASK_TYPE_USER_3', {
        abspos: {
          x: x,
          y: y
        }
      });
      /* user3 path */

      drawPath(parentGfx, pathData3, {
        strokeWidth: 0.5,
        fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return task;
    },
    'bpmn:ManualTask': function (parentGfx, element) {
      var task = renderer('bpmn:Task')(parentGfx, element);
      var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', {
        abspos: {
          x: 17,
          y: 15
        }
      });
      /* manual path */

      drawPath(parentGfx, pathData, {
        strokeWidth: 0.5,
        // 0.25,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return task;
    },
    'bpmn:SendTask': function (parentGfx, element) {
      var task = renderer('bpmn:Task')(parentGfx, element);
      var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: 21,
        containerHeight: 14,
        position: {
          mx: 0.285,
          my: 0.357
        }
      });
      /* send path */

      drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
        stroke: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor)
      });
      return task;
    },
    'bpmn:ReceiveTask': function (parentGfx, element) {
      var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
      var task = renderer('bpmn:Task')(parentGfx, element);
      var pathData;

      if (semantic.instantiate) {
        drawCircle(parentGfx, 28, 28, 20 * 0.22, {
          strokeWidth: 1
        });
        pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', {
          abspos: {
            x: 7.77,
            y: 9.52
          }
        });
      } else {
        pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
          xScaleFactor: 0.9,
          yScaleFactor: 0.9,
          containerWidth: 21,
          containerHeight: 14,
          position: {
            mx: 0.3,
            my: 0.4
          }
        });
      }
      /* receive path */


      drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return task;
    },
    'bpmn:ScriptTask': function (parentGfx, element) {
      var task = renderer('bpmn:Task')(parentGfx, element);
      var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', {
        abspos: {
          x: 15,
          y: 20
        }
      });
      /* script path */

      drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return task;
    },
    'bpmn:BusinessRuleTask': function (parentGfx, element) {
      var task = renderer('bpmn:Task')(parentGfx, element);
      var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', {
        abspos: {
          x: 8,
          y: 8
        }
      });
      var businessHeaderPath = drawPath(parentGfx, headerPathData);
      (0, _tinySvg.attr)(businessHeaderPath, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, '#aaaaaa'),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', {
        abspos: {
          x: 8,
          y: 8
        }
      });
      var businessPath = drawPath(parentGfx, headerData);
      (0, _tinySvg.attr)(businessPath, {
        strokeWidth: 1,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return task;
    },
    'bpmn:SubProcess': function (parentGfx, element, attrs) {
      attrs = (0, _minDash.assign)({
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      }, attrs);
      var rect = renderer('bpmn:Activity')(parentGfx, element, attrs);
      var expanded = (0, _DiUtil.isExpanded)(element);

      if ((0, _DiUtil.isEventSubProcess)(element)) {
        (0, _tinySvg.attr)(rect, {
          strokeDasharray: '1,2'
        });
      }

      renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle');

      if (expanded) {
        attachTaskMarkers(parentGfx, element);
      } else {
        attachTaskMarkers(parentGfx, element, ['SubProcessMarker']);
      }

      return rect;
    },
    'bpmn:AdHocSubProcess': function (parentGfx, element) {
      return renderer('bpmn:SubProcess')(parentGfx, element);
    },
    'bpmn:Transaction': function (parentGfx, element) {
      var outer = renderer('bpmn:SubProcess')(parentGfx, element);
      var innerAttrs = styles.style(['no-fill', 'no-events'], {
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      /* inner path */

      drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs);
      return outer;
    },
    'bpmn:CallActivity': function (parentGfx, element) {
      return renderer('bpmn:SubProcess')(parentGfx, element, {
        strokeWidth: 5
      });
    },
    'bpmn:Participant': function (parentGfx, element) {
      var attrs = {
        fillOpacity: DEFAULT_FILL_OPACITY,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      };
      var lane = renderer('bpmn:Lane')(parentGfx, element, attrs);
      var expandedPool = (0, _DiUtil.isExpanded)(element);

      if (expandedPool) {
        drawLine(parentGfx, [{
          x: 30,
          y: 0
        }, {
          x: 30,
          y: element.height
        }], {
          stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
        });
        var text = (0, _BpmnRenderUtil.getSemantic)(element).name;
        renderLaneLabel(parentGfx, text, element);
      } else {
        // Collapsed pool draw text inline
        var text2 = (0, _BpmnRenderUtil.getSemantic)(element).name;
        renderLabel(parentGfx, text2, {
          box: element,
          align: 'center-middle',
          style: {
            fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
          }
        });
      }

      var participantMultiplicity = !!(0, _BpmnRenderUtil.getSemantic)(element).participantMultiplicity;

      if (participantMultiplicity) {
        renderer('ParticipantMultiplicityMarker')(parentGfx, element);
      }

      return lane;
    },
    'bpmn:Lane': function (parentGfx, element, attrs) {
      var rect = drawRect(parentGfx, element.width, element.height, 0, (0, _minDash.assign)({
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        fillOpacity: HIGH_FILL_OPACITY,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      }, attrs));
      var semantic = (0, _BpmnRenderUtil.getSemantic)(element);

      if (semantic.$type === 'bpmn:Lane') {
        var text = semantic.name;
        renderLaneLabel(parentGfx, text, element);
      }

      return rect;
    },
    'bpmn:InclusiveGateway': function (parentGfx, element) {
      var diamond = renderer('bpmn:Gateway')(parentGfx, element);
      /* circle path */

      drawCircle(parentGfx, element.width, element.height, element.height * 0.24, {
        strokeWidth: 2.5,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return diamond;
    },
    'bpmn:ExclusiveGateway': function (parentGfx, element) {
      var diamond = renderer('bpmn:Gateway')(parentGfx, element);
      var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', {
        xScaleFactor: 0.4,
        yScaleFactor: 0.4,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: 0.32,
          my: 0.3
        }
      });

      if ((0, _BpmnRenderUtil.getDi)(element).isMarkerVisible) {
        drawPath(parentGfx, pathData, {
          strokeWidth: 1,
          fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
          stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
        });
      }

      return diamond;
    },
    'bpmn:ComplexGateway': function (parentGfx, element) {
      var diamond = renderer('bpmn:Gateway')(parentGfx, element);
      var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', {
        xScaleFactor: 0.5,
        yScaleFactor: 0.5,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: 0.46,
          my: 0.26
        }
      });
      /* complex path */

      drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return diamond;
    },
    'bpmn:ParallelGateway': function (parentGfx, element) {
      var diamond = renderer('bpmn:Gateway')(parentGfx, element);
      var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
        xScaleFactor: 0.6,
        yScaleFactor: 0.6,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: 0.46,
          my: 0.2
        }
      });
      /* parallel path */

      drawPath(parentGfx, pathData, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return diamond;
    },
    'bpmn:EventBasedGateway': function (parentGfx, element) {
      var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
      var diamond = renderer('bpmn:Gateway')(parentGfx, element);
      /* outer circle path */

      drawCircle(parentGfx, element.width, element.height, element.height * 0.20, {
        strokeWidth: 1,
        fill: 'none',
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      var type = semantic.eventGatewayType;
      var instantiate = !!semantic.instantiate;

      function drawEvent() {
        var pathData = pathMap.getScaledPath('GATEWAY_EVENT_BASED', {
          xScaleFactor: 0.18,
          yScaleFactor: 0.18,
          containerWidth: element.width,
          containerHeight: element.height,
          position: {
            mx: 0.36,
            my: 0.44
          }
        });
        var attrs = {
          strokeWidth: 2,
          fill: (0, _BpmnRenderUtil.getFillColor)(element, 'none'),
          stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
        };
        /* event path */

        drawPath(parentGfx, pathData, attrs);
      }

      if (type === 'Parallel') {
        var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
          xScaleFactor: 0.4,
          yScaleFactor: 0.4,
          containerWidth: element.width,
          containerHeight: element.height,
          position: {
            mx: 0.474,
            my: 0.296
          }
        });
        var parallelPath = drawPath(parentGfx, pathData);
        (0, _tinySvg.attr)(parallelPath, {
          strokeWidth: 1,
          fill: 'none'
        });
      } else if (type === 'Exclusive') {
        if (!instantiate) {
          var innerCircle = drawCircle(parentGfx, element.width, element.height, element.height * 0.26);
          (0, _tinySvg.attr)(innerCircle, {
            strokeWidth: 1,
            fill: 'none',
            stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
          });
        }

        drawEvent();
      }

      return diamond;
    },
    'bpmn:Gateway': function (parentGfx, element) {
      var attrs = {
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        fillOpacity: DEFAULT_FILL_OPACITY,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      };
      return drawDiamond(parentGfx, element.width, element.height, attrs);
    },
    'bpmn:SequenceFlow': function (parentGfx, element) {
      var pathData = createPathFromConnection(element);
      var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
          stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
      var attrs = {
        strokeLinejoin: 'round',
        markerEnd: marker('sequenceflow-end', fill, stroke),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      };
      var path = drawPath(parentGfx, pathData, attrs);
      var sequenceFlow = (0, _BpmnRenderUtil.getSemantic)(element);
      var source;

      if (element.source) {
        source = element.source.businessObject; // conditional flow marker

        if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Activity')) {
          (0, _tinySvg.attr)(path, {
            markerStart: marker('conditional-flow-marker', fill, stroke)
          });
        } // default marker


        if (source.default && (source.$instanceOf('bpmn:Gateway') || source.$instanceOf('bpmn:Activity')) && source.default === sequenceFlow) {
          (0, _tinySvg.attr)(path, {
            markerStart: marker('conditional-default-flow-marker', fill, stroke)
          });
        }
      }

      return path;
    },
    'bpmn:Association': function (parentGfx, element, attrs) {
      var semantic = (0, _BpmnRenderUtil.getSemantic)(element);
      var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
          stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
      attrs = (0, _minDash.assign)({
        strokeDasharray: '0.5, 5',
        strokeLinecap: 'round',
        strokeLinejoin: 'round',
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      }, attrs || {});

      if (semantic.associationDirection === 'One' || semantic.associationDirection === 'Both') {
        attrs.markerEnd = marker('association-end', fill, stroke);
      }

      if (semantic.associationDirection === 'Both') {
        attrs.markerStart = marker('association-start', fill, stroke);
      }

      return drawLine(parentGfx, element.waypoints, attrs);
    },
    'bpmn:DataInputAssociation': function (parentGfx, element) {
      var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
          stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
      return renderer('bpmn:Association')(parentGfx, element, {
        markerEnd: marker('association-end', fill, stroke)
      });
    },
    'bpmn:DataOutputAssociation': function (parentGfx, element) {
      var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
          stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
      return renderer('bpmn:Association')(parentGfx, element, {
        markerEnd: marker('association-end', fill, stroke)
      });
    },
    'bpmn:MessageFlow': function (parentGfx, element) {
      var semantic = (0, _BpmnRenderUtil.getSemantic)(element),
          di = (0, _BpmnRenderUtil.getDi)(element);
      var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
          stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor);
      var pathData = createPathFromConnection(element);
      var attrs = {
        markerEnd: marker('messageflow-end', fill, stroke),
        markerStart: marker('messageflow-start', fill, stroke),
        strokeDasharray: '10, 12',
        strokeLinecap: 'round',
        strokeLinejoin: 'round',
        strokeWidth: '1.5px',
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      };
      var path = drawPath(parentGfx, pathData, attrs);

      if (semantic.messageRef) {
        var midPoint = path.getPointAtLength(path.getTotalLength() / 2);
        var markerPathData = pathMap.getScaledPath('MESSAGE_FLOW_MARKER', {
          abspos: {
            x: midPoint.x,
            y: midPoint.y
          }
        });
        var messageAttrs = {
          strokeWidth: 1
        };

        if (di.messageVisibleKind === 'initiating') {
          messageAttrs.fill = 'white';
          messageAttrs.stroke = 'black';
        } else {
          messageAttrs.fill = '#888';
          messageAttrs.stroke = 'white';
        }

        drawPath(parentGfx, markerPathData, messageAttrs);
      }

      return path;
    },
    'bpmn:DataObject': function (parentGfx, element) {
      var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: 0.474,
          my: 0.296
        }
      });
      var elementObject = drawPath(parentGfx, pathData, {
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        fillOpacity: DEFAULT_FILL_OPACITY,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      var semantic = (0, _BpmnRenderUtil.getSemantic)(element);

      if ((0, _BpmnRenderUtil.isCollection)(semantic)) {
        renderDataItemCollection(parentGfx, element);
      }

      return elementObject;
    },
    'bpmn:DataObjectReference': as('bpmn:DataObject'),
    'bpmn:DataInput': function (parentGfx, element) {
      var arrowPathData = pathMap.getRawPath('DATA_ARROW'); // page

      var elementObject = renderer('bpmn:DataObject')(parentGfx, element);
      /* input arrow path */

      drawPath(parentGfx, arrowPathData, {
        strokeWidth: 1
      });
      return elementObject;
    },
    'bpmn:DataOutput': function (parentGfx, element) {
      var arrowPathData = pathMap.getRawPath('DATA_ARROW'); // page

      var elementObject = renderer('bpmn:DataObject')(parentGfx, element);
      /* output arrow path */

      drawPath(parentGfx, arrowPathData, {
        strokeWidth: 1,
        fill: 'black'
      });
      return elementObject;
    },
    'bpmn:DataStoreReference': function (parentGfx, element) {
      var DATA_STORE_PATH = pathMap.getScaledPath('DATA_STORE', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: 0,
          my: 0.133
        }
      });
      var elementStore = drawPath(parentGfx, DATA_STORE_PATH, {
        strokeWidth: 2,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        fillOpacity: DEFAULT_FILL_OPACITY,
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      return elementStore;
    },
    'bpmn:BoundaryEvent': function (parentGfx, element) {
      var semantic = (0, _BpmnRenderUtil.getSemantic)(element),
          cancel = semantic.cancelActivity;
      var attrs = {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      };

      if (!cancel) {
        attrs.strokeDasharray = '6';
        attrs.strokeLinecap = 'round';
      } // apply fillOpacity


      var outerAttrs = (0, _minDash.assign)({}, attrs, {
        fillOpacity: 1
      }); // apply no-fill

      var innerAttrs = (0, _minDash.assign)({}, attrs, {
        fill: 'none'
      });
      var outer = renderer('bpmn:Event')(parentGfx, element, outerAttrs);
      /* inner path */

      drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, innerAttrs);
      renderEventContent(element, parentGfx);
      return outer;
    },
    'bpmn:Group': function (parentGfx, element) {
      var group = drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, {
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
        strokeWidth: 1,
        strokeDasharray: '8,3,1,3',
        fill: 'none',
        pointerEvents: 'none'
      });
      return group;
    },
    'label': function (parentGfx, element) {
      return renderExternalLabel(parentGfx, element);
    },
    'bpmn:TextAnnotation': function (parentGfx, element) {
      var style = {
        'fill': 'none',
        'stroke': 'none'
      };
      var textElement = drawRect(parentGfx, element.width, element.height, 0, 0, style);
      var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: 0.0,
          my: 0.0
        }
      });
      drawPath(parentGfx, textPathData, {
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
      var text = (0, _BpmnRenderUtil.getSemantic)(element).text || '';
      renderLabel(parentGfx, text, {
        box: element,
        align: 'left-top',
        padding: 5,
        style: {
          fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
        }
      });
      return textElement;
    },
    'ParticipantMultiplicityMarker': function (parentGfx, element) {
      var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: element.width / 2 / element.width,
          my: (element.height - 15) / element.height
        }
      });
      drawMarker('participant-multiplicity', parentGfx, markerPath, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
    },
    'SubProcessMarker': function (parentGfx, element) {
      var markerRect = drawRect(parentGfx, 14, 14, 0, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      }); // Process marker is placed in the middle of the box
      // therefore fixed values can be used here

      (0, _SvgTransformUtil.translate)(markerRect, element.width / 2 - 7.5, element.height - 20);
      var markerPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', {
        xScaleFactor: 1.5,
        yScaleFactor: 1.5,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: (element.width / 2 - 7.5) / element.width,
          my: (element.height - 20) / element.height
        }
      });
      drawMarker('sub-process', parentGfx, markerPath, {
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
    },
    'ParallelMarker': function (parentGfx, element, position) {
      var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: (element.width / 2 + position.parallel) / element.width,
          my: (element.height - 20) / element.height
        }
      });
      drawMarker('parallel', parentGfx, markerPath, {
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
    },
    'SequentialMarker': function (parentGfx, element, position) {
      var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: (element.width / 2 + position.seq) / element.width,
          my: (element.height - 19) / element.height
        }
      });
      drawMarker('sequential', parentGfx, markerPath, {
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
    },
    'CompensationMarker': function (parentGfx, element, position) {
      var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: (element.width / 2 + position.compensation) / element.width,
          my: (element.height - 13) / element.height
        }
      });
      drawMarker('compensation', parentGfx, markerMath, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
    },
    'LoopMarker': function (parentGfx, element, position) {
      var markerPath = pathMap.getScaledPath('MARKER_LOOP', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: (element.width / 2 + position.loop) / element.width,
          my: (element.height - 7) / element.height
        }
      });
      drawMarker('loop', parentGfx, markerPath, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
        strokeLinecap: 'round',
        strokeMiterlimit: 0.5
      });
    },
    'AdhocMarker': function (parentGfx, element, position) {
      var markerPath = pathMap.getScaledPath('MARKER_ADHOC', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: (element.width / 2 + position.adhoc) / element.width,
          my: (element.height - 15) / element.height
        }
      });
      drawMarker('adhoc', parentGfx, markerPath, {
        strokeWidth: 1,
        fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor),
        stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor)
      });
    }
  };

  function attachTaskMarkers(parentGfx, element, taskMarkers) {
    var obj = (0, _BpmnRenderUtil.getSemantic)(element);
    var subprocess = taskMarkers && taskMarkers.indexOf('SubProcessMarker') !== -1;
    var position;

    if (subprocess) {
      position = {
        seq: -21,
        parallel: -22,
        compensation: -42,
        loop: -18,
        adhoc: 10
      };
    } else {
      position = {
        seq: -3,
        parallel: -6,
        compensation: -27,
        loop: 0,
        adhoc: 10
      };
    }

    (0, _minDash.forEach)(taskMarkers, function (marker) {
      renderer(marker)(parentGfx, element, position);
    });

    if (obj.isForCompensation) {
      renderer('CompensationMarker')(parentGfx, element, position);
    }

    if (obj.$type === 'bpmn:AdHocSubProcess') {
      renderer('AdhocMarker')(parentGfx, element, position);
    }

    var loopCharacteristics = obj.loopCharacteristics,
        isSequential = loopCharacteristics && loopCharacteristics.isSequential;

    if (loopCharacteristics) {
      if (isSequential === undefined) {
        renderer('LoopMarker')(parentGfx, element, position);
      }

      if (isSequential === false) {
        renderer('ParallelMarker')(parentGfx, element, position);
      }

      if (isSequential === true) {
        renderer('SequentialMarker')(parentGfx, element, position);
      }
    }
  }

  function renderDataItemCollection(parentGfx, element) {
    var yPosition = (element.height - 16) / element.height;
    var pathData = pathMap.getScaledPath('DATA_OBJECT_COLLECTION_PATH', {
      xScaleFactor: 1,
      yScaleFactor: 1,
      containerWidth: element.width,
      containerHeight: element.height,
      position: {
        mx: 0.451,
        my: yPosition
      }
    });
    /* collection path */

    drawPath(parentGfx, pathData, {
      strokeWidth: 2
    });
  } // extension API, use at your own risk


  this._drawPath = drawPath;
}

(0, _inherits.default)(BpmnRenderer, _BaseRenderer.default);
BpmnRenderer.$inject = ['config.bpmnRenderer', 'eventBus', 'styles', 'pathMap', 'canvas', 'textRenderer'];

BpmnRenderer.prototype.canRender = function (element) {
  return (0, _ModelUtil.is)(element, 'bpmn:BaseElement');
};

BpmnRenderer.prototype.drawShape = function (parentGfx, element) {
  var type = element.type;
  var h = this.handlers[type];
  /* jshint -W040 */

  return h(parentGfx, element);
};

BpmnRenderer.prototype.drawConnection = function (parentGfx, element) {
  var type = element.type;
  var h = this.handlers[type];
  /* jshint -W040 */

  return h(parentGfx, element);
};

BpmnRenderer.prototype.getShapePath = function (element) {
  if ((0, _ModelUtil.is)(element, 'bpmn:Event')) {
    return (0, _BpmnRenderUtil.getCirclePath)(element);
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:Activity')) {
    return (0, _BpmnRenderUtil.getRoundRectPath)(element, TASK_BORDER_RADIUS);
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:Gateway')) {
    return (0, _BpmnRenderUtil.getDiamondPath)(element);
  }

  return (0, _BpmnRenderUtil.getRectPath)(element);
};

},{"../features/label-editing/LabelUtil":53,"../util/DiUtil":139,"../util/ModelUtil":141,"./BpmnRenderUtil":19,"diagram-js/lib/draw/BaseRenderer":154,"diagram-js/lib/util/RenderUtil":327,"diagram-js/lib/util/SvgTransformUtil":328,"ids":346,"inherits":347,"min-dash":555,"min-dom":556,"tiny-svg":567}],21:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = PathMap;

/**
 * Map containing SVG paths needed by BpmnRenderer.
 */
function PathMap() {
  /**
   * Contains a map of path elements
   *
   * <h1>Path definition</h1>
   * A parameterized path is defined like this:
   * <pre>
   * 'GATEWAY_PARALLEL': {
   *   d: 'm {mx},{my} {e.x0},0 0,{e.x1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
          '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
   *   height: 17.5,
   *   width:  17.5,
   *   heightElements: [2.5, 7.5],
   *   widthElements: [2.5, 7.5]
   * }
   * </pre>
   * <p>It's important to specify a correct <b>height and width</b> for the path as the scaling
   * is based on the ratio between the specified height and width in this object and the
   * height and width that is set as scale target (Note x,y coordinates will be scaled with
   * individual ratios).</p>
   * <p>The '<b>heightElements</b>' and '<b>widthElements</b>' array must contain the values that will be scaled.
   * The scaling is based on the computed ratios.
   * Coordinates on the y axis should be in the <b>heightElement</b>'s array, they will be scaled using
   * the computed ratio coefficient.
   * In the parameterized path the scaled values can be accessed through the 'e' object in {} brackets.
   *   <ul>
   *    <li>The values for the y axis can be accessed in the path string using {e.y0}, {e.y1}, ....</li>
   *    <li>The values for the x axis can be accessed in the path string using {e.x0}, {e.x1}, ....</li>
   *   </ul>
   *   The numbers x0, x1 respectively y0, y1, ... map to the corresponding array index.
   * </p>
   */
  this.pathMap = {
    'EVENT_MESSAGE': {
      d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
      height: 36,
      width: 36,
      heightElements: [6, 14],
      widthElements: [10.5, 21]
    },
    'EVENT_SIGNAL': {
      d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x1},0 Z',
      height: 36,
      width: 36,
      heightElements: [18],
      widthElements: [10, 20]
    },
    'EVENT_ESCALATION': {
      d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x0},-{e.y1} l -{e.x0},{e.y1} Z',
      height: 36,
      width: 36,
      heightElements: [20, 7],
      widthElements: [8]
    },
    'EVENT_CONDITIONAL': {
      d: 'M {e.x0},{e.y0} l {e.x1},0 l 0,{e.y2} l -{e.x1},0 Z ' + 'M {e.x2},{e.y3} l {e.x0},0 ' + 'M {e.x2},{e.y4} l {e.x0},0 ' + 'M {e.x2},{e.y5} l {e.x0},0 ' + 'M {e.x2},{e.y6} l {e.x0},0 ' + 'M {e.x2},{e.y7} l {e.x0},0 ' + 'M {e.x2},{e.y8} l {e.x0},0 ',
      height: 36,
      width: 36,
      heightElements: [8.5, 14.5, 18, 11.5, 14.5, 17.5, 20.5, 23.5, 26.5],
      widthElements: [10.5, 14.5, 12.5]
    },
    'EVENT_LINK': {
      d: 'm {mx},{my} 0,{e.y0} -{e.x1},0 0,{e.y1} {e.x1},0 0,{e.y0} {e.x0},-{e.y2} -{e.x0},-{e.y2} z',
      height: 36,
      width: 36,
      heightElements: [4.4375, 6.75, 7.8125],
      widthElements: [9.84375, 13.5]
    },
    'EVENT_ERROR': {
      d: 'm {mx},{my} {e.x0},-{e.y0} {e.x1},-{e.y1} {e.x2},{e.y2} {e.x3},-{e.y3} -{e.x4},{e.y4} -{e.x5},-{e.y5} z',
      height: 36,
      width: 36,
      heightElements: [0.023, 8.737, 8.151, 16.564, 10.591, 8.714],
      widthElements: [0.085, 6.672, 6.97, 4.273, 5.337, 6.636]
    },
    'EVENT_CANCEL_45': {
      d: 'm {mx},{my} -{e.x1},0 0,{e.x0} {e.x1},0 0,{e.y1} {e.x0},0 ' + '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
      height: 36,
      width: 36,
      heightElements: [4.75, 8.5],
      widthElements: [4.75, 8.5]
    },
    'EVENT_COMPENSATION': {
      d: 'm {mx},{my} {e.x0},-{e.y0} 0,{e.y1} z m {e.x1},-{e.y2} {e.x2},-{e.y3} 0,{e.y1} -{e.x2},-{e.y3} z',
      height: 36,
      width: 36,
      heightElements: [6.5, 13, 0.4, 6.1],
      widthElements: [9, 9.3, 8.7]
    },
    'EVENT_TIMER_WH': {
      d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ',
      height: 36,
      width: 36,
      heightElements: [10, 2],
      widthElements: [3, 7]
    },
    'EVENT_TIMER_LINE': {
      d: 'M {mx},{my} ' + 'm {e.x0},{e.y0} l -{e.x1},{e.y1} ',
      height: 36,
      width: 36,
      heightElements: [10, 3],
      widthElements: [0, 0]
    },
    'EVENT_MULTIPLE': {
      d: 'm {mx},{my} {e.x1},-{e.y0} {e.x1},{e.y0} -{e.x0},{e.y1} -{e.x2},0 z',
      height: 36,
      width: 36,
      heightElements: [6.28099, 12.56199],
      widthElements: [3.1405, 9.42149, 12.56198]
    },
    'EVENT_PARALLEL_MULTIPLE': {
      d: 'm {mx},{my} {e.x0},0 0,{e.y1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' + '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
      height: 36,
      width: 36,
      heightElements: [2.56228, 7.68683],
      widthElements: [2.56228, 7.68683]
    },
    'GATEWAY_EXCLUSIVE': {
      d: 'm {mx},{my} {e.x0},{e.y0} {e.x1},{e.y0} {e.x2},0 {e.x4},{e.y2} ' + '{e.x4},{e.y1} {e.x2},0 {e.x1},{e.y3} {e.x0},{e.y3} ' + '{e.x3},0 {e.x5},{e.y1} {e.x5},{e.y2} {e.x3},0 z',
      height: 17.5,
      width: 17.5,
      heightElements: [8.5, 6.5312, -6.5312, -8.5],
      widthElements: [6.5, -6.5, 3, -3, 5, -5]
    },
    'GATEWAY_PARALLEL': {
      d: 'm {mx},{my} 0,{e.y1} -{e.x1},0 0,{e.y0} {e.x1},0 0,{e.y1} {e.x0},0 ' + '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
      height: 30,
      width: 30,
      heightElements: [5, 12.5],
      widthElements: [5, 12.5]
    },
    'GATEWAY_EVENT_BASED': {
      d: 'm {mx},{my} {e.x0},{e.y0} {e.x0},{e.y1} {e.x1},{e.y2} {e.x2},0 z',
      height: 11,
      width: 11,
      heightElements: [-6, 6, 12, -12],
      widthElements: [9, -3, -12]
    },
    'GATEWAY_COMPLEX': {
      d: 'm {mx},{my} 0,{e.y0} -{e.x0},-{e.y1} -{e.x1},{e.y2} {e.x0},{e.y1} -{e.x2},0 0,{e.y3} ' + '{e.x2},0  -{e.x0},{e.y1} l {e.x1},{e.y2} {e.x0},-{e.y1} 0,{e.y0} {e.x3},0 0,-{e.y0} {e.x0},{e.y1} ' + '{e.x1},-{e.y2} -{e.x0},-{e.y1} {e.x2},0 0,-{e.y3} -{e.x2},0 {e.x0},-{e.y1} -{e.x1},-{e.y2} ' + '-{e.x0},{e.y1} 0,-{e.y0} -{e.x3},0 z',
      height: 17.125,
      width: 17.125,
      heightElements: [4.875, 3.4375, 2.125, 3],
      widthElements: [3.4375, 2.125, 4.875, 3]
    },
    'DATA_OBJECT_PATH': {
      d: 'm 0,0 {e.x1},0 {e.x0},{e.y0} 0,{e.y1} -{e.x2},0 0,-{e.y2} {e.x1},0 0,{e.y0} {e.x0},0',
      height: 61,
      width: 51,
      heightElements: [10, 50, 60],
      widthElements: [10, 40, 50, 60]
    },
    'DATA_OBJECT_COLLECTION_PATH': {
      d: 'm {mx}, {my} ' + 'm  0 15  l 0 -15 ' + 'm  4 15  l 0 -15 ' + 'm  4 15  l 0 -15 ',
      height: 61,
      width: 51,
      heightElements: [12],
      widthElements: [1, 6, 12, 15]
    },
    'DATA_ARROW': {
      d: 'm 5,9 9,0 0,-3 5,5 -5,5 0,-3 -9,0 z',
      height: 61,
      width: 51,
      heightElements: [],
      widthElements: []
    },
    'DATA_STORE': {
      d: 'm  {mx},{my} ' + 'l  0,{e.y2} ' + 'c  {e.x0},{e.y1} {e.x1},{e.y1}  {e.x2},0 ' + 'l  0,-{e.y2} ' + 'c -{e.x0},-{e.y1} -{e.x1},-{e.y1} -{e.x2},0' + 'c  {e.x0},{e.y1} {e.x1},{e.y1}  {e.x2},0 ' + 'm  -{e.x2},{e.y0}' + 'c  {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0' + 'm  -{e.x2},{e.y0}' + 'c  {e.x0},{e.y1} {e.x1},{e.y1}  {e.x2},0',
      height: 61,
      width: 61,
      heightElements: [7, 10, 45],
      widthElements: [2, 58, 60]
    },
    'TEXT_ANNOTATION': {
      d: 'm {mx}, {my} m 10,0 l -10,0 l 0,{e.y0} l 10,0',
      height: 30,
      width: 10,
      heightElements: [30],
      widthElements: [10]
    },
    'MARKER_SUB_PROCESS': {
      d: 'm{mx},{my} m 7,2 l 0,10 m -5,-5 l 10,0',
      height: 10,
      width: 10,
      heightElements: [],
      widthElements: []
    },
    'MARKER_PARALLEL': {
      d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10',
      height: 10,
      width: 10,
      heightElements: [],
      widthElements: []
    },
    'MARKER_SEQUENTIAL': {
      d: 'm{mx},{my} m 0,3 l 10,0 m -10,3 l 10,0 m -10,3 l 10,0',
      height: 10,
      width: 10,
      heightElements: [],
      widthElements: []
    },
    'MARKER_COMPENSATION': {
      d: 'm {mx},{my} 7,-5 0,10 z m 7.1,-0.3 6.9,-4.7 0,10 -6.9,-4.7 z',
      height: 10,
      width: 21,
      heightElements: [],
      widthElements: []
    },
    'MARKER_LOOP': {
      d: 'm {mx},{my} c 3.526979,0 6.386161,-2.829858 6.386161,-6.320661 0,-3.490806 -2.859182,-6.320661 ' + '-6.386161,-6.320661 -3.526978,0 -6.38616,2.829855 -6.38616,6.320661 0,1.745402 ' + '0.714797,3.325567 1.870463,4.469381 0.577834,0.571908 1.265885,1.034728 2.029916,1.35457 ' + 'l -0.718163,-3.909793 m 0.718163,3.909793 -3.885211,0.802902',
      height: 13.9,
      width: 13.7,
      heightElements: [],
      widthElements: []
    },
    'MARKER_ADHOC': {
      d: 'm {mx},{my} m 0.84461,2.64411 c 1.05533,-1.23780996 2.64337,-2.07882 4.29653,-1.97997996 2.05163,0.0805 ' + '3.85579,1.15803 5.76082,1.79107 1.06385,0.34139996 2.24454,0.1438 3.18759,-0.43767 0.61743,-0.33642 ' + '1.2775,-0.64078 1.7542,-1.17511 0,0.56023 0,1.12046 0,1.6807 -0.98706,0.96237996 -2.29792,1.62393996 ' + '-3.6918,1.66181996 -1.24459,0.0927 -2.46671,-0.2491 -3.59505,-0.74812 -1.35789,-0.55965 ' + '-2.75133,-1.33436996 -4.27027,-1.18121996 -1.37741,0.14601 -2.41842,1.13685996 -3.44288,1.96782996 z',
      height: 4,
      width: 15,
      heightElements: [],
      widthElements: []
    },
    'TASK_TYPE_SEND': {
      d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
      height: 14,
      width: 21,
      heightElements: [6, 14],
      widthElements: [10.5, 21]
    },
    'TASK_TYPE_SCRIPT': {
      d: 'm {mx},{my} c 9.966553,-6.27276 -8.000926,-7.91932 2.968968,-14.938 l -8.802728,0 ' + 'c -10.969894,7.01868 6.997585,8.66524 -2.968967,14.938 z ' + 'm -7,-12 l 5,0 ' + 'm -4.5,3 l 4.5,0 ' + 'm -3,3 l 5,0' + 'm -4,3 l 5,0',
      height: 15,
      width: 12.6,
      heightElements: [6, 14],
      widthElements: [10.5, 21]
    },
    'TASK_TYPE_USER_1': {
      d: 'm {mx},{my} c 0.909,-0.845 1.594,-2.049 1.594,-3.385 0,-2.554 -1.805,-4.62199999 ' + '-4.357,-4.62199999 -2.55199998,0 -4.28799998,2.06799999 -4.28799998,4.62199999 0,1.348 ' + '0.974,2.562 1.89599998,3.405 -0.52899998,0.187 -5.669,2.097 -5.794,4.7560005 v 6.718 ' + 'h 17 v -6.718 c 0,-2.2980005 -5.5279996,-4.5950005 -6.0509996,-4.7760005 z' + 'm -8,6 l 0,5.5 m 11,0 l 0,-5'
    },
    'TASK_TYPE_USER_2': {
      d: 'm {mx},{my} m 2.162,1.009 c 0,2.4470005 -2.158,4.4310005 -4.821,4.4310005 ' + '-2.66499998,0 -4.822,-1.981 -4.822,-4.4310005 '
    },
    'TASK_TYPE_USER_3': {
      d: 'm {mx},{my} m -6.9,-3.80 c 0,0 2.25099998,-2.358 4.27399998,-1.177 2.024,1.181 4.221,1.537 ' + '4.124,0.965 -0.098,-0.57 -0.117,-3.79099999 -4.191,-4.13599999 -3.57499998,0.001 ' + '-4.20799998,3.36699999 -4.20699998,4.34799999 z'
    },
    'TASK_TYPE_MANUAL': {
      d: 'm {mx},{my} c 0.234,-0.01 5.604,0.008 8.029,0.004 0.808,0 1.271,-0.172 1.417,-0.752 0.227,-0.898 ' + '-0.334,-1.314 -1.338,-1.316 -2.467,-0.01 -7.886,-0.004 -8.108,-0.004 -0.014,-0.079 0.016,-0.533 0,-0.61 ' + '0.195,-0.042 8.507,0.006 9.616,0.002 0.877,-0.007 1.35,-0.438 1.353,-1.208 0.003,-0.768 -0.479,-1.09 ' + '-1.35,-1.091 -2.968,-0.002 -9.619,-0.013 -9.619,-0.013 v -0.591 c 0,0 5.052,-0.016 7.225,-0.016 ' + '0.888,-0.002 1.354,-0.416 1.351,-1.193 -0.006,-0.761 -0.492,-1.196 -1.361,-1.196 -3.473,-0.005 ' + '-10.86,-0.003 -11.0829995,-0.003 -0.022,-0.047 -0.045,-0.094 -0.069,-0.139 0.3939995,-0.319 ' + '2.0409995,-1.626 2.4149995,-2.017 0.469,-0.4870005 0.519,-1.1650005 0.162,-1.6040005 -0.414,-0.511 ' + '-0.973,-0.5 -1.48,-0.236 -1.4609995,0.764 -6.5999995,3.6430005 -7.7329995,4.2710005 -0.9,0.499 ' + '-1.516,1.253 -1.882,2.19 -0.37000002,0.95 -0.17,2.01 -0.166,2.979 0.004,0.718 -0.27300002,1.345 ' + '-0.055,2.063 0.629,2.087 2.425,3.312 4.859,3.318 4.6179995,0.014 9.2379995,-0.139 13.8569995,-0.158 ' + '0.755,-0.004 1.171,-0.301 1.182,-1.033 0.012,-0.754 -0.423,-0.969 -1.183,-0.973 -1.778,-0.01 ' + '-5.824,-0.004 -6.04,-0.004 10e-4,-0.084 0.003,-0.586 10e-4,-0.67 z'
    },
    'TASK_TYPE_INSTANTIATING_SEND': {
      d: 'm {mx},{my} l 0,8.4 l 12.6,0 l 0,-8.4 z l 6.3,3.6 l 6.3,-3.6'
    },
    'TASK_TYPE_SERVICE': {
      d: 'm {mx},{my} v -1.71335 c 0.352326,-0.0705 0.703932,-0.17838 1.047628,-0.32133 ' + '0.344416,-0.14465 0.665822,-0.32133 0.966377,-0.52145 l 1.19431,1.18005 1.567487,-1.57688 ' + '-1.195028,-1.18014 c 0.403376,-0.61394 0.683079,-1.29908 0.825447,-2.01824 l 1.622133,-0.01 ' + 'v -2.2196 l -1.636514,0.01 c -0.07333,-0.35153 -0.178319,-0.70024 -0.323564,-1.04372 ' + '-0.145244,-0.34406 -0.321407,-0.6644 -0.522735,-0.96217 l 1.131035,-1.13631 -1.583305,-1.56293 ' + '-1.129598,1.13589 c -0.614052,-0.40108 -1.302883,-0.68093 -2.022633,-0.82247 l 0.0093,-1.61852 ' + 'h -2.241173 l 0.0042,1.63124 c -0.353763,0.0736 -0.705369,0.17977 -1.049785,0.32371 -0.344415,0.14437 ' + '-0.665102,0.32092 -0.9635006,0.52046 l -1.1698628,-1.15823 -1.5667691,1.5792 1.1684265,1.15669 ' + 'c -0.4026573,0.61283 -0.68308,1.29797 -0.8247287,2.01713 l -1.6588041,0.003 v 2.22174 ' + 'l 1.6724648,-0.006 c 0.073327,0.35077 0.1797598,0.70243 0.3242851,1.04472 0.1452428,0.34448 ' + '0.3214064,0.6644 0.5227339,0.96066 l -1.1993431,1.19723 1.5840256,1.56011 1.1964668,-1.19348 ' + 'c 0.6140517,0.40346 1.3028827,0.68232 2.0233517,0.82331 l 7.19e-4,1.69892 h 2.226848 z ' + 'm 0.221462,-3.9957 c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' + '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' + '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
    },
    'TASK_TYPE_SERVICE_FILL': {
      d: 'm {mx},{my} c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' + '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' + '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
    },
    'TASK_TYPE_BUSINESS_RULE_HEADER': {
      d: 'm {mx},{my} 0,4 20,0 0,-4 z'
    },
    'TASK_TYPE_BUSINESS_RULE_MAIN': {
      d: 'm {mx},{my} 0,12 20,0 0,-12 z' + 'm 0,8 l 20,0 ' + 'm -13,-4 l 0,8'
    },
    'MESSAGE_FLOW_MARKER': {
      d: 'm {mx},{my} m -10.5 ,-7 l 0,14 l 21,0 l 0,-14 z l 10.5,6 l 10.5,-6'
    }
  };

  this.getRawPath = function getRawPath(pathId) {
    return this.pathMap[pathId].d;
  };
  /**
   * Scales the path to the given height and width.
   * <h1>Use case</h1>
   * <p>Use case is to scale the content of elements (event, gateways) based
   * on the element bounding box's size.
   * </p>
   * <h1>Why not transform</h1>
   * <p>Scaling a path with transform() will also scale the stroke and IE does not support
   * the option 'non-scaling-stroke' to prevent this.
   * Also there are use cases where only some parts of a path should be
   * scaled.</p>
   *
   * @param {string} pathId The ID of the path.
   * @param {Object} param <p>
   *   Example param object scales the path to 60% size of the container (data.width, data.height).
   *   <pre>
   *   {
   *     xScaleFactor: 0.6,
   *     yScaleFactor:0.6,
   *     containerWidth: data.width,
   *     containerHeight: data.height,
   *     position: {
   *       mx: 0.46,
   *       my: 0.2,
   *     }
   *   }
   *   </pre>
   *   <ul>
   *    <li>targetpathwidth = xScaleFactor * containerWidth</li>
   *    <li>targetpathheight = yScaleFactor * containerHeight</li>
   *    <li>Position is used to set the starting coordinate of the path. M is computed:
    *    <ul>
    *      <li>position.x * containerWidth</li>
    *      <li>position.y * containerHeight</li>
    *    </ul>
    *    Center of the container <pre> position: {
   *       mx: 0.5,
   *       my: 0.5,
   *     }</pre>
   *     Upper left corner of the container
   *     <pre> position: {
   *       mx: 0.0,
   *       my: 0.0,
   *     }</pre>
   *    </li>
   *   </ul>
   * </p>
   *
   */


  this.getScaledPath = function getScaledPath(pathId, param) {
    var rawPath = this.pathMap[pathId]; // positioning
    // compute the start point of the path

    var mx, my;

    if (param.abspos) {
      mx = param.abspos.x;
      my = param.abspos.y;
    } else {
      mx = param.containerWidth * param.position.mx;
      my = param.containerHeight * param.position.my;
    }

    var coordinates = {}; // map for the scaled coordinates

    if (param.position) {
      // path
      var heightRatio = param.containerHeight / rawPath.height * param.yScaleFactor;
      var widthRatio = param.containerWidth / rawPath.width * param.xScaleFactor; // Apply height ratio

      for (var heightIndex = 0; heightIndex < rawPath.heightElements.length; heightIndex++) {
        coordinates['y' + heightIndex] = rawPath.heightElements[heightIndex] * heightRatio;
      } // Apply width ratio


      for (var widthIndex = 0; widthIndex < rawPath.widthElements.length; widthIndex++) {
        coordinates['x' + widthIndex] = rawPath.widthElements[widthIndex] * widthRatio;
      }
    } // Apply value to raw path


    var path = format(rawPath.d, {
      mx: mx,
      my: my,
      e: coordinates
    });
    return path;
  };
} // helpers //////////////////////
// copied from https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js


var tokenRegex = /\{([^}]+)\}/g,
    objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g; // matches .xxxxx or ["xxxxx"] to run over object properties

function replacer(all, key, obj) {
  var res = obj;
  key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {
    name = name || quotedName;

    if (res) {
      if (name in res) {
        res = res[name];
      }

      typeof res == 'function' && isFunc && (res = res());
    }
  });
  res = (res == null || res == obj ? all : res) + '';
  return res;
}

function format(str, obj) {
  return String(str).replace(tokenRegex, function (all, key) {
    return replacer(all, key, obj);
  });
}

},{}],22:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = TextRenderer;

var _minDash = require("min-dash");

var _Text = _interopRequireDefault(require("diagram-js/lib/util/Text"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var DEFAULT_FONT_SIZE = 12;
var LINE_HEIGHT_RATIO = 1.2;
var MIN_TEXT_ANNOTATION_HEIGHT = 30;

function TextRenderer(config) {
  var defaultStyle = (0, _minDash.assign)({
    fontFamily: 'Arial, sans-serif',
    fontSize: DEFAULT_FONT_SIZE,
    fontWeight: 'normal',
    lineHeight: LINE_HEIGHT_RATIO
  }, config && config.defaultStyle || {});
  var fontSize = parseInt(defaultStyle.fontSize, 10) - 1;
  var externalStyle = (0, _minDash.assign)({}, defaultStyle, {
    fontSize: fontSize
  }, config && config.externalStyle || {});
  var textUtil = new _Text.default({
    style: defaultStyle
  });
  /**
   * Get the new bounds of an externally rendered,
   * layouted label.
   *
   * @param  {Bounds} bounds
   * @param  {string} text
   *
   * @return {Bounds}
   */

  this.getExternalLabelBounds = function (bounds, text) {
    var layoutedDimensions = textUtil.getDimensions(text, {
      box: {
        width: 90,
        height: 30,
        x: bounds.width / 2 + bounds.x,
        y: bounds.height / 2 + bounds.y
      },
      style: externalStyle
    }); // resize label shape to fit label text

    return {
      x: Math.round(bounds.x + bounds.width / 2 - layoutedDimensions.width / 2),
      y: Math.round(bounds.y),
      width: Math.ceil(layoutedDimensions.width),
      height: Math.ceil(layoutedDimensions.height)
    };
  };
  /**
   * Get the new bounds of text annotation.
   *
   * @param  {Bounds} bounds
   * @param  {string} text
   *
   * @return {Bounds}
   */


  this.getTextAnnotationBounds = function (bounds, text) {
    var layoutedDimensions = textUtil.getDimensions(text, {
      box: bounds,
      style: defaultStyle,
      align: 'left-top',
      padding: 5
    });
    return {
      x: bounds.x,
      y: bounds.y,
      width: bounds.width,
      height: Math.max(MIN_TEXT_ANNOTATION_HEIGHT, Math.round(layoutedDimensions.height))
    };
  };
  /**
   * Create a layouted text element.
   *
   * @param {string} text
   * @param {Object} [options]
   *
   * @return {SVGElement} rendered text
   */


  this.createText = function (text, options) {
    return textUtil.createText(text, options || {});
  };
  /**
   * Get default text style.
   */


  this.getDefaultStyle = function () {
    return defaultStyle;
  };
  /**
   * Get the external text style.
   */


  this.getExternalStyle = function () {
    return externalStyle;
  };
}

TextRenderer.$inject = ['config.textRenderer'];

},{"diagram-js/lib/util/Text":329,"min-dash":555}],23:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _BpmnRenderer = _interopRequireDefault(require("./BpmnRenderer"));

var _TextRenderer = _interopRequireDefault(require("./TextRenderer"));

var _PathMap = _interopRequireDefault(require("./PathMap"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['bpmnRenderer'],
  bpmnRenderer: ['type', _BpmnRenderer.default],
  textRenderer: ['type', _TextRenderer.default],
  pathMap: ['type', _PathMap.default]
};
exports.default = _default;

},{"./BpmnRenderer":20,"./PathMap":21,"./TextRenderer":22}],24:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AutoPlace;

var _BpmnAutoPlaceUtil = require("./BpmnAutoPlaceUtil");

/**
 * BPMN auto-place behavior.
 *
 * @param {EventBus} eventBus
 */
function AutoPlace(eventBus) {
  eventBus.on('autoPlace', function (context) {
    var shape = context.shape,
        source = context.source;
    return (0, _BpmnAutoPlaceUtil.getNewShapePosition)(source, shape);
  });
}

AutoPlace.$inject = ['eventBus'];

},{"./BpmnAutoPlaceUtil":25}],25:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getNewShapePosition = getNewShapePosition;
exports.getFlowNodePosition = getFlowNodePosition;
exports.getTextAnnotationPosition = getTextAnnotationPosition;
exports.getDataElementPosition = getDataElementPosition;

var _ModelUtil = require("../../util/ModelUtil");

var _ModelingUtil = require("../modeling/util/ModelingUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _AutoPlaceUtil = require("diagram-js/lib/features/auto-place/AutoPlaceUtil");

/**
 * Find the new position for the target element to
 * connect to source.
 *
 * @param  {djs.model.Shape} source
 * @param  {djs.model.Shape} element
 *
 * @return {Point}
 */
function getNewShapePosition(source, element) {
  if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
    return getTextAnnotationPosition(source, element);
  }

  if ((0, _ModelingUtil.isAny)(element, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) {
    return getDataElementPosition(source, element);
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:FlowNode')) {
    return getFlowNodePosition(source, element);
  }
}
/**
 * Always try to place element right of source;
 * compute actual distance from previous nodes in flow.
 */


function getFlowNodePosition(source, element) {
  var sourceTrbl = (0, _LayoutUtil.asTRBL)(source);
  var sourceMid = (0, _LayoutUtil.getMid)(source);
  var horizontalDistance = (0, _AutoPlaceUtil.getConnectedDistance)(source, {
    filter: function (connection) {
      return (0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow');
    }
  });
  var margin = 30,
      minDistance = 80,
      orientation = 'left';

  if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) {
    orientation = (0, _LayoutUtil.getOrientation)(source, source.host, -25);

    if (orientation.indexOf('top') !== -1) {
      margin *= -1;
    }
  }

  var position = {
    x: sourceTrbl.right + horizontalDistance + element.width / 2,
    y: sourceMid.y + getVerticalDistance(orientation, minDistance)
  };
  var nextPositionDirection = {
    y: {
      margin: margin,
      minDistance: minDistance
    }
  };
  return (0, _AutoPlaceUtil.findFreePosition)(source, element, position, (0, _AutoPlaceUtil.generateGetNextPosition)(nextPositionDirection));
}

function getVerticalDistance(orientation, minDistance) {
  if (orientation.indexOf('top') != -1) {
    return -1 * minDistance;
  } else if (orientation.indexOf('bottom') != -1) {
    return minDistance;
  } else {
    return 0;
  }
}
/**
 * Always try to place text annotations top right of source.
 */


function getTextAnnotationPosition(source, element) {
  var sourceTrbl = (0, _LayoutUtil.asTRBL)(source);
  var position = {
    x: sourceTrbl.right + element.width / 2,
    y: sourceTrbl.top - 50 - element.height / 2
  };
  var nextPositionDirection = {
    y: {
      margin: -30,
      minDistance: 20
    }
  };
  return (0, _AutoPlaceUtil.findFreePosition)(source, element, position, (0, _AutoPlaceUtil.generateGetNextPosition)(nextPositionDirection));
}
/**
 * Always put element bottom right of source.
 */


function getDataElementPosition(source, element) {
  var sourceTrbl = (0, _LayoutUtil.asTRBL)(source);
  var position = {
    x: sourceTrbl.right - 10 + element.width / 2,
    y: sourceTrbl.bottom + 40 + element.width / 2
  };
  var nextPositionDirection = {
    x: {
      margin: 30,
      minDistance: 30
    }
  };
  return (0, _AutoPlaceUtil.findFreePosition)(source, element, position, (0, _AutoPlaceUtil.generateGetNextPosition)(nextPositionDirection));
}

},{"../../util/ModelUtil":141,"../modeling/util/ModelingUtil":112,"diagram-js/lib/features/auto-place/AutoPlaceUtil":164,"diagram-js/lib/layout/LayoutUtil":300}],26:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _autoPlace = _interopRequireDefault(require("diagram-js/lib/features/auto-place"));

var _BpmnAutoPlace = _interopRequireDefault(require("./BpmnAutoPlace"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_autoPlace.default],
  __init__: ['bpmnAutoPlace'],
  bpmnAutoPlace: ['type', _BpmnAutoPlace.default]
};
exports.default = _default;

},{"./BpmnAutoPlace":24,"diagram-js/lib/features/auto-place":165}],27:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnAutoResize;

var _AutoResize = _interopRequireDefault(require("diagram-js/lib/features/auto-resize/AutoResize"));

var _inherits = _interopRequireDefault(require("inherits"));

var _ModelUtil = require("../../util/ModelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Sub class of the AutoResize module which implements a BPMN
 * specific resize function.
 */
function BpmnAutoResize(injector) {
  injector.invoke(_AutoResize.default, this);
}

BpmnAutoResize.$inject = ['injector'];
(0, _inherits.default)(BpmnAutoResize, _AutoResize.default);
/**
 * Resize shapes and lanes.
 *
 * @param {djs.model.Shape} target
 * @param {Bounds} newBounds
 * @param {Object} hints
 */

BpmnAutoResize.prototype.resize = function (target, newBounds, hints) {
  if ((0, _ModelUtil.is)(target, 'bpmn:Participant')) {
    this._modeling.resizeLane(target, newBounds, null, hints);
  } else {
    this._modeling.resizeShape(target, newBounds, null, hints);
  }
};

},{"../../util/ModelUtil":141,"diagram-js/lib/features/auto-resize/AutoResize":166,"inherits":347}],28:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnAutoResizeProvider;

var _ModelUtil = require("../../util/ModelUtil");

var _inherits = _interopRequireDefault(require("inherits"));

var _minDash = require("min-dash");

var _AutoResizeProvider = _interopRequireDefault(require("diagram-js/lib/features/auto-resize/AutoResizeProvider"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * This module is a provider for automatically resizing parent BPMN elements
 */
function BpmnAutoResizeProvider(eventBus, modeling) {
  _AutoResizeProvider.default.call(this, eventBus);

  this._modeling = modeling;
}

(0, _inherits.default)(BpmnAutoResizeProvider, _AutoResizeProvider.default);
BpmnAutoResizeProvider.$inject = ['eventBus', 'modeling'];
/**
 * Check if the given target can be expanded
 *
 * @param  {djs.model.Shape} target
 *
 * @return {boolean}
 */

BpmnAutoResizeProvider.prototype.canResize = function (elements, target) {
  if (!(0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _ModelUtil.is)(target, 'bpmn:Lane') && !(0, _ModelUtil.is)(target, 'bpmn:SubProcess')) {
    return false;
  }

  var canResize = true;
  (0, _minDash.forEach)(elements, function (element) {
    if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || element.labelTarget) {
      canResize = false;
      return;
    }
  });
  return canResize;
};

},{"../../util/ModelUtil":141,"diagram-js/lib/features/auto-resize/AutoResizeProvider":167,"inherits":347,"min-dash":555}],29:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _BpmnAutoResize = _interopRequireDefault(require("./BpmnAutoResize"));

var _BpmnAutoResizeProvider = _interopRequireDefault(require("./BpmnAutoResizeProvider"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['bpmnAutoResize', 'bpmnAutoResizeProvider'],
  bpmnAutoResize: ['type', _BpmnAutoResize.default],
  bpmnAutoResizeProvider: ['type', _BpmnAutoResizeProvider.default]
};
exports.default = _default;

},{"./BpmnAutoResize":27,"./BpmnAutoResizeProvider":28}],30:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ContextPadProvider;

var _minDash = require("min-dash");

var _ModelUtil = require("../../util/ModelUtil");

var _DiUtil = require("../../util/DiUtil");

var _ModelingUtil = require("../modeling/util/ModelingUtil");

var _LaneUtil = require("../modeling/util/LaneUtil");

var _Mouse = require("diagram-js/lib/util/Mouse");

/**
 * A provider for BPMN 2.0 elements context pad
 */
function ContextPadProvider(config, injector, eventBus, contextPad, modeling, elementFactory, connect, create, popupMenu, canvas, rules, translate) {
  config = config || {};
  contextPad.registerProvider(this);
  this._contextPad = contextPad;
  this._modeling = modeling;
  this._elementFactory = elementFactory;
  this._connect = connect;
  this._create = create;
  this._popupMenu = popupMenu;
  this._canvas = canvas;
  this._rules = rules;
  this._translate = translate;

  if (config.autoPlace !== false) {
    this._autoPlace = injector.get('autoPlace', false);
  }

  eventBus.on('create.end', 250, function (event) {
    var context = event.context,
        shape = context.shape;

    if (!(0, _Mouse.hasPrimaryModifier)(event) || !contextPad.isOpen(shape)) {
      return;
    }

    var entries = contextPad.getEntries(shape);

    if (entries.replace) {
      entries.replace.action.click(event, shape);
    }
  });
}

ContextPadProvider.$inject = ['config.contextPad', 'injector', 'eventBus', 'contextPad', 'modeling', 'elementFactory', 'connect', 'create', 'popupMenu', 'canvas', 'rules', 'translate'];

ContextPadProvider.prototype.getContextPadEntries = function (element) {
  var contextPad = this._contextPad,
      modeling = this._modeling,
      elementFactory = this._elementFactory,
      connect = this._connect,
      create = this._create,
      popupMenu = this._popupMenu,
      canvas = this._canvas,
      rules = this._rules,
      autoPlace = this._autoPlace,
      translate = this._translate;
  var actions = {};

  if (element.type === 'label') {
    return actions;
  }

  var businessObject = element.businessObject;

  function startConnect(event, element) {
    connect.start(event, element);
  }

  function removeElement(e) {
    modeling.removeElements([element]);
  }

  function getReplaceMenuPosition(element) {
    var Y_OFFSET = 5;
    var diagramContainer = canvas.getContainer(),
        pad = contextPad.getPad(element).html;
    var diagramRect = diagramContainer.getBoundingClientRect(),
        padRect = pad.getBoundingClientRect();
    var top = padRect.top - diagramRect.top;
    var left = padRect.left - diagramRect.left;
    var pos = {
      x: left,
      y: top + padRect.height + Y_OFFSET
    };
    return pos;
  }
  /**
   * Create an append action
   *
   * @param {string} type
   * @param {string} className
   * @param {string} [title]
   * @param {Object} [options]
   *
   * @return {Object} descriptor
   */


  function appendAction(type, className, title, options) {
    if (typeof title !== 'string') {
      options = title;
      title = translate('Append {type}', {
        type: type.replace(/^bpmn:/, '')
      });
    }

    function appendStart(event, element) {
      var shape = elementFactory.createShape((0, _minDash.assign)({
        type: type
      }, options));
      create.start(event, shape, {
        source: element
      });
    }

    var append = autoPlace ? function (event, element) {
      var shape = elementFactory.createShape((0, _minDash.assign)({
        type: type
      }, options));
      autoPlace.append(element, shape);
    } : appendStart;
    return {
      group: 'model',
      className: className,
      title: title,
      action: {
        dragstart: appendStart,
        click: append
      }
    };
  }

  function splitLaneHandler(count) {
    return function (event, element) {
      // actual split
      modeling.splitLane(element, count); // refresh context pad after split to
      // get rid of split icons

      contextPad.open(element, true);
    };
  }

  if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:Lane', 'bpmn:Participant']) && (0, _DiUtil.isExpanded)(businessObject)) {
    var childLanes = (0, _LaneUtil.getChildLanes)(element);
    (0, _minDash.assign)(actions, {
      'lane-insert-above': {
        group: 'lane-insert-above',
        className: 'bpmn-icon-lane-insert-above',
        title: translate('Add Lane above'),
        action: {
          click: function (event, element) {
            modeling.addLane(element, 'top');
          }
        }
      }
    });

    if (childLanes.length < 2) {
      if (element.height >= 120) {
        (0, _minDash.assign)(actions, {
          'lane-divide-two': {
            group: 'lane-divide',
            className: 'bpmn-icon-lane-divide-two',
            title: translate('Divide into two Lanes'),
            action: {
              click: splitLaneHandler(2)
            }
          }
        });
      }

      if (element.height >= 180) {
        (0, _minDash.assign)(actions, {
          'lane-divide-three': {
            group: 'lane-divide',
            className: 'bpmn-icon-lane-divide-three',
            title: translate('Divide into three Lanes'),
            action: {
              click: splitLaneHandler(3)
            }
          }
        });
      }
    }

    (0, _minDash.assign)(actions, {
      'lane-insert-below': {
        group: 'lane-insert-below',
        className: 'bpmn-icon-lane-insert-below',
        title: translate('Add Lane below'),
        action: {
          click: function (event, element) {
            modeling.addLane(element, 'bottom');
          }
        }
      }
    });
  }

  if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowNode')) {
    if ((0, _ModelUtil.is)(businessObject, 'bpmn:EventBasedGateway')) {
      (0, _minDash.assign)(actions, {
        'append.receive-task': appendAction('bpmn:ReceiveTask', 'bpmn-icon-receive-task', translate('Append ReceiveTask')),
        'append.message-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-message', translate('Append MessageIntermediateCatchEvent'), {
          eventDefinitionType: 'bpmn:MessageEventDefinition'
        }),
        'append.timer-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-timer', translate('Append TimerIntermediateCatchEvent'), {
          eventDefinitionType: 'bpmn:TimerEventDefinition'
        }),
        'append.condition-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-condition', translate('Append ConditionIntermediateCatchEvent'), {
          eventDefinitionType: 'bpmn:ConditionalEventDefinition'
        }),
        'append.signal-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-signal', translate('Append SignalIntermediateCatchEvent'), {
          eventDefinitionType: 'bpmn:SignalEventDefinition'
        })
      });
    } else if (isEventType(businessObject, 'bpmn:BoundaryEvent', 'bpmn:CompensateEventDefinition')) {
      (0, _minDash.assign)(actions, {
        'append.compensation-activity': appendAction('bpmn:Task', 'bpmn-icon-task', translate('Append compensation activity'), {
          isForCompensation: true
        })
      });
    } else if (!(0, _ModelUtil.is)(businessObject, 'bpmn:EndEvent') && !businessObject.isForCompensation && !isEventType(businessObject, 'bpmn:IntermediateThrowEvent', 'bpmn:LinkEventDefinition') && !(0, _DiUtil.isEventSubProcess)(businessObject)) {
      (0, _minDash.assign)(actions, {
        'append.end-event': appendAction('bpmn:EndEvent', 'bpmn-icon-end-event-none', translate('Append EndEvent')),
        'append.gateway': appendAction('bpmn:ExclusiveGateway', 'bpmn-icon-gateway-none', translate('Append Gateway')),
        'append.append-task': appendAction('bpmn:Task', 'bpmn-icon-task', translate('Append Task')),
        'append.intermediate-event': appendAction('bpmn:IntermediateThrowEvent', 'bpmn-icon-intermediate-event-none', translate('Append Intermediate/Boundary Event'))
      });
    }
  }

  if (!popupMenu.isEmpty(element, 'bpmn-replace')) {
    // Replace menu entry
    (0, _minDash.assign)(actions, {
      'replace': {
        group: 'edit',
        className: 'bpmn-icon-screw-wrench',
        title: translate('Change type'),
        action: {
          click: function (event, element) {
            var position = (0, _minDash.assign)(getReplaceMenuPosition(element), {
              cursor: {
                x: event.x,
                y: event.y
              }
            });
            popupMenu.open(element, 'bpmn-replace', position);
          }
        }
      }
    });
  }

  if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:FlowNode', 'bpmn:InteractionNode', 'bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) {
    (0, _minDash.assign)(actions, {
      'append.text-annotation': appendAction('bpmn:TextAnnotation', 'bpmn-icon-text-annotation'),
      'connect': {
        group: 'connect',
        className: 'bpmn-icon-connection-multi',
        title: translate('Connect using ' + (businessObject.isForCompensation ? '' : 'Sequence/MessageFlow or ') + 'Association'),
        action: {
          click: startConnect,
          dragstart: startConnect
        }
      }
    });
  }

  if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) {
    (0, _minDash.assign)(actions, {
      'connect': {
        group: 'connect',
        className: 'bpmn-icon-connection-multi',
        title: translate('Connect using DataInputAssociation'),
        action: {
          click: startConnect,
          dragstart: startConnect
        }
      }
    });
  }

  if ((0, _ModelUtil.is)(businessObject, 'bpmn:Group')) {
    (0, _minDash.assign)(actions, {
      'append.text-annotation': appendAction('bpmn:TextAnnotation', 'bpmn-icon-text-annotation')
    });
  } // delete element entry, only show if allowed by rules


  var deleteAllowed = rules.allowed('elements.delete', {
    elements: [element]
  });

  if ((0, _minDash.isArray)(deleteAllowed)) {
    // was the element returned as a deletion candidate?
    deleteAllowed = deleteAllowed[0] === element;
  }

  if (deleteAllowed) {
    (0, _minDash.assign)(actions, {
      'delete': {
        group: 'edit',
        className: 'bpmn-icon-trash',
        title: translate('Remove'),
        action: {
          click: removeElement
        }
      }
    });
  }

  return actions;
}; // helpers /////////


function isEventType(eventBo, type, definition) {
  var isType = eventBo.$instanceOf(type);
  var isDefinition = false;
  var definitions = eventBo.eventDefinitions || [];
  (0, _minDash.forEach)(definitions, function (def) {
    if (def.$type === definition) {
      isDefinition = true;
    }
  });
  return isType && isDefinition;
}

},{"../../util/DiUtil":139,"../../util/ModelUtil":141,"../modeling/util/LaneUtil":111,"../modeling/util/ModelingUtil":112,"diagram-js/lib/util/Mouse":323,"min-dash":555}],31:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _diagramJsDirectEditing = _interopRequireDefault(require("diagram-js-direct-editing"));

var _contextPad = _interopRequireDefault(require("diagram-js/lib/features/context-pad"));

var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection"));

var _connect = _interopRequireDefault(require("diagram-js/lib/features/connect"));

var _create = _interopRequireDefault(require("diagram-js/lib/features/create"));

var _popupMenu = _interopRequireDefault(require("../popup-menu"));

var _ContextPadProvider = _interopRequireDefault(require("./ContextPadProvider"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_diagramJsDirectEditing.default, _contextPad.default, _selection.default, _connect.default, _create.default, _popupMenu.default],
  __init__: ['contextPadProvider'],
  contextPadProvider: ['type', _ContextPadProvider.default]
};
exports.default = _default;

},{"../popup-menu":118,"./ContextPadProvider":30,"diagram-js-direct-editing":332,"diagram-js/lib/features/connect":183,"diagram-js/lib/features/context-pad":187,"diagram-js/lib/features/create":192,"diagram-js/lib/features/selection":278}],32:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnCopyPaste;

var _ModelUtil = require("../../util/ModelUtil");

var _minDash = require("min-dash");

function copyProperties(source, target, properties) {
  if (!(0, _minDash.isArray)(properties)) {
    properties = [properties];
  }

  (0, _minDash.forEach)(properties, function (property) {
    if (!(0, _minDash.isUndefined)(source[property])) {
      target[property] = source[property];
    }
  });
}

function removeProperties(element, properties) {
  if (!(0, _minDash.isArray)(properties)) {
    properties = [properties];
  }

  (0, _minDash.forEach)(properties, function (property) {
    if (element[property]) {
      delete element[property];
    }
  });
}

var LOW_PRIORITY = 750;

function BpmnCopyPaste(bpmnFactory, eventBus, moddleCopy) {
  eventBus.on('copyPaste.copyElement', LOW_PRIORITY, function (context) {
    var descriptor = context.descriptor,
        element = context.element;
    var businessObject = descriptor.oldBusinessObject = (0, _ModelUtil.getBusinessObject)(element);
    descriptor.type = element.type;
    copyProperties(businessObject, descriptor, 'name');
    descriptor.di = {}; // fill and stroke will be set to DI

    copyProperties(businessObject.di, descriptor.di, ['fill', 'stroke']);
    copyProperties(businessObject.di, descriptor, 'isExpanded');

    if (isLabel(descriptor)) {
      return descriptor;
    } // default sequence flow


    if (businessObject.default) {
      descriptor.default = businessObject.default.id;
    }
  });
  eventBus.on('moddleCopy.canCopyProperty', function (context) {
    var parent = context.parent,
        property = context.property,
        propertyName = context.propertyName,
        bpmnProcess;

    if (propertyName === 'processRef' && (0, _ModelUtil.is)(parent, 'bpmn:Participant') && (0, _ModelUtil.is)(property, 'bpmn:Process')) {
      bpmnProcess = bpmnFactory.create('bpmn:Process'); // return copy of process

      return moddleCopy.copyElement(property, bpmnProcess);
    }
  });
  var references;

  function resolveReferences(descriptor, cache) {
    var businessObject = (0, _ModelUtil.getBusinessObject)(descriptor); // default sequence flows

    if (descriptor.default) {
      // relationship cannot be resolved immediately
      references[descriptor.default] = {
        element: businessObject,
        property: 'default'
      };
    } // boundary events


    if (descriptor.host) {
      // relationship can be resolved immediately
      (0, _ModelUtil.getBusinessObject)(descriptor).attachedToRef = (0, _ModelUtil.getBusinessObject)(cache[descriptor.host]);
    }

    references = (0, _minDash.omit)(references, (0, _minDash.reduce)(references, function (array, reference, key) {
      var element = reference.element,
          property = reference.property;

      if (key === descriptor.id) {
        element[property] = businessObject;
        array.push(descriptor.id);
      }

      return array;
    }, []));
  }

  eventBus.on('copyPaste.pasteElements', function () {
    references = {};
  });
  eventBus.on('copyPaste.pasteElement', function (context) {
    var cache = context.cache,
        descriptor = context.descriptor,
        oldBusinessObject = descriptor.oldBusinessObject,
        newBusinessObject; // do NOT copy business object if external label

    if (isLabel(descriptor)) {
      descriptor.businessObject = (0, _ModelUtil.getBusinessObject)(cache[descriptor.labelTarget]);
      return;
    }

    newBusinessObject = bpmnFactory.create(oldBusinessObject.$type);
    descriptor.businessObject = moddleCopy.copyElement(oldBusinessObject, newBusinessObject); // resolve references e.g. default sequence flow

    resolveReferences(descriptor, cache);
    copyProperties(descriptor, newBusinessObject, ['isExpanded', 'name']);
    removeProperties(descriptor, 'oldBusinessObject');
  });
}

BpmnCopyPaste.$inject = ['bpmnFactory', 'eventBus', 'moddleCopy']; // helpers //////////

function isLabel(element) {
  return !!element.labelTarget;
}

},{"../../util/ModelUtil":141,"min-dash":555}],33:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ModdleCopy;
exports.getPropertyNames = getPropertyNames;

var _minDash = require("min-dash");

var DISALLOWED_PROPERTIES = ['artifacts', 'dataInputAssociations', 'dataOutputAssociations', 'default', 'flowElements', 'lanes', 'incoming', 'outgoing'];
/**
 * @typedef {Function} <moddleCopy.canCopyProperties> listener
 *
 * @param {Object} context
 * @param {Array<string>} context.propertyNames
 * @param {ModdleElement} context.sourceElement
 * @param {ModdleElement} context.targetElement
 *
 * @returns {Array<string>|boolean} - Return properties to be copied or false to disallow
 * copying.
 */

/**
 * @typedef {Function} <moddleCopy.canCopyProperty> listener
 *
 * @param {Object} context
 * @param {ModdleElement} context.parent
 * @param {*} context.property
 * @param {string} context.propertyName
 *
 * @returns {*|boolean} - Return copied property or false to disallow
 * copying.
 */

/**
 * @typedef {Function} <moddleCopy.canSetCopiedProperty> listener
 *
 * @param {Object} context
 * @param {ModdleElement} context.parent
 * @param {*} context.property
 * @param {string} context.propertyName
 *
 * @returns {boolean} - Return false to disallow
 * setting copied property.
 */

/**
 * Utility for copying model properties from source element to target element.
 *
 * @param {EventBus} eventBus
 * @param {BpmnFactory} bpmnFactory
 * @param {BpmnModdle} moddle
 */

function ModdleCopy(eventBus, bpmnFactory, moddle) {
  this._bpmnFactory = bpmnFactory;
  this._eventBus = eventBus;
  this._moddle = moddle; // copy extension elements last

  eventBus.on('moddleCopy.canCopyProperties', function (context) {
    var propertyNames = context.propertyNames;

    if (!propertyNames || !propertyNames.length) {
      return;
    }

    return (0, _minDash.sortBy)(propertyNames, function (propertyName) {
      return propertyName === 'extensionElements';
    });
  }); // default check whether property can be copied

  eventBus.on('moddleCopy.canCopyProperty', function (context) {
    var parent = context.parent,
        parentDescriptor = (0, _minDash.isObject)(parent) && parent.$descriptor,
        propertyName = context.propertyName;

    if (propertyName && DISALLOWED_PROPERTIES.indexOf(propertyName) !== -1) {
      // disallow copying property
      return false;
    }

    if (propertyName && parentDescriptor && !(0, _minDash.find)(parentDescriptor.properties, (0, _minDash.matchPattern)({
      name: propertyName
    }))) {
      // disallow copying property
      return false;
    }
  }); // do NOT allow to copy empty extension elements

  eventBus.on('moddleCopy.canSetCopiedProperty', function (context) {
    var property = context.property;

    if (is(property, 'bpmn:ExtensionElements') && (!property.values || !property.values.length)) {
      // disallow setting copied property
      return false;
    }
  });
}

ModdleCopy.$inject = ['eventBus', 'bpmnFactory', 'moddle'];
/**
 * Copy model properties of source element to target element.
 *
 * @param {ModdleElement} sourceElement
 * @param {ModdleElement} targetElement
 * @param {Array<string>} [propertyNames]
 *
 * @param {ModdleElement}
 */

ModdleCopy.prototype.copyElement = function (sourceElement, targetElement, propertyNames) {
  var self = this;

  if (propertyNames && !(0, _minDash.isArray)(propertyNames)) {
    propertyNames = [propertyNames];
  }

  propertyNames = propertyNames || getPropertyNames(sourceElement.$descriptor);

  var canCopyProperties = this._eventBus.fire('moddleCopy.canCopyProperties', {
    propertyNames: propertyNames,
    sourceElement: sourceElement,
    targetElement: targetElement
  });

  if (canCopyProperties === false) {
    return targetElement;
  }

  if ((0, _minDash.isArray)(canCopyProperties)) {
    propertyNames = canCopyProperties;
  } // copy properties


  (0, _minDash.forEach)(propertyNames, function (propertyName) {
    var sourceProperty;

    if ((0, _minDash.has)(sourceElement, propertyName)) {
      sourceProperty = sourceElement.get(propertyName);
    }

    var copiedProperty = self.copyProperty(sourceProperty, targetElement, propertyName);

    var canSetProperty = self._eventBus.fire('moddleCopy.canSetCopiedProperty', {
      parent: targetElement,
      property: copiedProperty,
      propertyName: propertyName
    });

    if (canSetProperty === false) {
      return;
    }

    if ((0, _minDash.isDefined)(copiedProperty)) {
      targetElement.set(propertyName, copiedProperty);
    }
  });
  return targetElement;
};
/**
 * Copy model property.
 *
 * @param {*} property
 * @param {ModdleElement} parent
 * @param {string} propertyName
 *
 * @returns {*}
 */


ModdleCopy.prototype.copyProperty = function (property, parent, propertyName) {
  var self = this; // allow others to copy property

  var copiedProperty = this._eventBus.fire('moddleCopy.canCopyProperty', {
    parent: parent,
    property: property,
    propertyName: propertyName
  }); // return if copying is NOT allowed


  if (copiedProperty === false) {
    return;
  }

  if (copiedProperty) {
    if ((0, _minDash.isObject)(copiedProperty) && copiedProperty.$type && !copiedProperty.$parent) {
      copiedProperty.$parent = parent;
    }

    return copiedProperty;
  }

  var propertyDescriptor = this._moddle.getPropertyDescriptor(parent, propertyName); // do NOT copy Ids and references


  if (propertyDescriptor.isId || propertyDescriptor.isReference) {
    return;
  } // copy arrays


  if ((0, _minDash.isArray)(property)) {
    return (0, _minDash.reduce)(property, function (childProperties, childProperty) {
      // recursion
      copiedProperty = self.copyProperty(childProperty, parent, propertyName); // copying might NOT be allowed

      if (copiedProperty) {
        copiedProperty.$parent = parent;
        return childProperties.concat(copiedProperty);
      }

      return childProperties;
    }, []);
  } // copy model elements


  if ((0, _minDash.isObject)(property) && property.$type) {
    if (this._moddle.getElementDescriptor(property).isGeneric) {
      return;
    }

    copiedProperty = self._bpmnFactory.create(property.$type);
    copiedProperty.$parent = parent; // recursion

    copiedProperty = self.copyElement(property, copiedProperty);
    return copiedProperty;
  } // copy primitive properties


  return property;
}; // helpers //////////


function getPropertyNames(descriptor, keepDefaultProperties) {
  return (0, _minDash.reduce)(descriptor.properties, function (properties, property) {
    if (keepDefaultProperties && property.default) {
      return properties;
    }

    return properties.concat(property.name);
  }, []);
}

function is(element, type) {
  return element && typeof element.$instanceOf === 'function' && element.$instanceOf(type);
}

},{"min-dash":555}],34:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _copyPaste = _interopRequireDefault(require("diagram-js/lib/features/copy-paste"));

var _BpmnCopyPaste = _interopRequireDefault(require("./BpmnCopyPaste"));

var _ModdleCopy = _interopRequireDefault(require("./ModdleCopy"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_copyPaste.default],
  __init__: ['bpmnCopyPaste', 'moddleCopy'],
  bpmnCopyPaste: ['type', _BpmnCopyPaste.default],
  moddleCopy: ['type', _ModdleCopy.default]
};
exports.default = _default;

},{"./BpmnCopyPaste":32,"./ModdleCopy":33,"diagram-js/lib/features/copy-paste":189}],35:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnDiOrdering;

var _BpmnRenderUtil = require("../../draw/BpmnRenderUtil");

var _ModelUtil = require("../../util/ModelUtil");

var _minDash = require("min-dash");

var _Elements = require("diagram-js/lib/util/Elements");

var HIGH_PRIORITY = 2000;

function BpmnDiOrdering(eventBus, canvas) {
  eventBus.on('saveXML.start', HIGH_PRIORITY, orderDi);

  function orderDi() {
    var root = canvas.getRootElement(),
        rootDi = (0, _ModelUtil.getBusinessObject)(root).di,
        elements,
        diElements;
    elements = (0, _Elements.selfAndAllChildren)([root], false); // only bpmndi:Shape and bpmndi:Edge can be direct children of bpmndi:Plane

    elements = (0, _minDash.filter)(elements, function (element) {
      return element !== root && !element.labelTarget;
    });
    diElements = (0, _minDash.map)(elements, _BpmnRenderUtil.getDi);
    rootDi.set('planeElement', diElements);
  }
}

BpmnDiOrdering.$inject = ['eventBus', 'canvas'];

},{"../../draw/BpmnRenderUtil":19,"../../util/ModelUtil":141,"diagram-js/lib/util/Elements":315,"min-dash":555}],36:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _BpmnDiOrdering = _interopRequireDefault(require("../di-ordering/BpmnDiOrdering"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['bpmnDiOrdering'],
  bpmnDiOrdering: ['type', _BpmnDiOrdering.default]
};
exports.default = _default;

},{"../di-ordering/BpmnDiOrdering":35}],37:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnDistributeElements;

var _minDash = require("min-dash");

var _ModelingUtil = require("../modeling/util/ModelingUtil");

/**
 * Registers element exclude filters for elements that
 * currently do not support distribution.
 */
function BpmnDistributeElements(distributeElements) {
  distributeElements.registerFilter(function (elements) {
    return (0, _minDash.filter)(elements, function (element) {
      var cannotDistribute = (0, _ModelingUtil.isAny)(element, ['bpmn:Association', 'bpmn:BoundaryEvent', 'bpmn:DataInputAssociation', 'bpmn:DataOutputAssociation', 'bpmn:Lane', 'bpmn:MessageFlow', 'bpmn:Participant', 'bpmn:SequenceFlow', 'bpmn:TextAnnotation']);
      return !(element.labelTarget || cannotDistribute);
    });
  });
}

BpmnDistributeElements.$inject = ['distributeElements'];

},{"../modeling/util/ModelingUtil":112,"min-dash":555}],38:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _distributeElements = _interopRequireDefault(require("diagram-js/lib/features/distribute-elements"));

var _BpmnDistributeElements = _interopRequireDefault(require("./BpmnDistributeElements"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_distributeElements.default],
  __init__: ['bpmnDistributeElements'],
  bpmnDistributeElements: ['type', _BpmnDistributeElements.default]
};
exports.default = _default;

},{"./BpmnDistributeElements":37,"diagram-js/lib/features/distribute-elements":194}],39:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnEditorActions;

var _inherits = _interopRequireDefault(require("inherits"));

var _EditorActions = _interopRequireDefault(require("diagram-js/lib/features/editor-actions/EditorActions"));

var _minDash = require("min-dash");

var _ModelUtil = require("../../util/ModelUtil");

var _Elements = require("diagram-js/lib/util/Elements");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Registers and executes BPMN specific editor actions.
 *
 * @param {Injector} injector
 */
function BpmnEditorActions(injector) {
  injector.invoke(_EditorActions.default, this);
}

(0, _inherits.default)(BpmnEditorActions, _EditorActions.default);
BpmnEditorActions.$inject = ['injector'];
/**
 * Register default actions.
 *
 * @param {Injector} injector
 */

BpmnEditorActions.prototype._registerDefaultActions = function (injector) {
  // (0) invoke super method
  _EditorActions.default.prototype._registerDefaultActions.call(this, injector); // (1) retrieve optional components to integrate with


  var canvas = injector.get('canvas', false);
  var elementRegistry = injector.get('elementRegistry', false);
  var selection = injector.get('selection', false);
  var spaceTool = injector.get('spaceTool', false);
  var lassoTool = injector.get('lassoTool', false);
  var handTool = injector.get('handTool', false);
  var globalConnect = injector.get('globalConnect', false);
  var distributeElements = injector.get('distributeElements', false);
  var alignElements = injector.get('alignElements', false);
  var directEditing = injector.get('directEditing', false);
  var searchPad = injector.get('searchPad', false);
  var modeling = injector.get('modeling', false); // (2) check components and register actions

  if (canvas && elementRegistry && selection) {
    this._registerAction('selectElements', function () {
      // select all elements except for the invisible
      // root element
      var rootElement = canvas.getRootElement();
      var elements = elementRegistry.filter(function (element) {
        return element !== rootElement;
      });
      selection.select(elements);
      return elements;
    });
  }

  if (spaceTool) {
    this._registerAction('spaceTool', function () {
      spaceTool.toggle();
    });
  }

  if (lassoTool) {
    this._registerAction('lassoTool', function () {
      lassoTool.toggle();
    });
  }

  if (handTool) {
    this._registerAction('handTool', function () {
      handTool.toggle();
    });
  }

  if (globalConnect) {
    this._registerAction('globalConnectTool', function () {
      globalConnect.toggle();
    });
  }

  if (selection && distributeElements) {
    this._registerAction('distributeElements', function (opts) {
      var currentSelection = selection.get(),
          type = opts.type;

      if (currentSelection.length) {
        distributeElements.trigger(currentSelection, type);
      }
    });
  }

  if (selection && alignElements) {
    this._registerAction('alignElements', function (opts) {
      var currentSelection = selection.get(),
          aligneableElements = [],
          type = opts.type;

      if (currentSelection.length) {
        aligneableElements = (0, _minDash.filter)(currentSelection, function (element) {
          return !(0, _ModelUtil.is)(element, 'bpmn:Lane');
        });
        alignElements.trigger(aligneableElements, type);
      }
    });
  }

  if (selection && modeling) {
    this._registerAction('setColor', function (opts) {
      var currentSelection = selection.get();

      if (currentSelection.length) {
        modeling.setColor(currentSelection, opts);
      }
    });
  }

  if (selection && directEditing) {
    this._registerAction('directEditing', function () {
      var currentSelection = selection.get();

      if (currentSelection.length) {
        directEditing.activate(currentSelection[0]);
      }
    });
  }

  if (searchPad) {
    this._registerAction('find', function () {
      searchPad.toggle();
    });
  }

  if (canvas && modeling) {
    this._registerAction('moveToOrigin', function () {
      var rootElement = canvas.getRootElement(),
          boundingBox,
          elements;

      if ((0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) {
        elements = elementRegistry.filter(function (element) {
          return (0, _ModelUtil.is)(element.parent, 'bpmn:Collaboration');
        });
      } else {
        elements = elementRegistry.filter(function (element) {
          return element !== rootElement && !(0, _ModelUtil.is)(element.parent, 'bpmn:SubProcess');
        });
      }

      boundingBox = (0, _Elements.getBBox)(elements);
      modeling.moveElements(elements, {
        x: -boundingBox.x,
        y: -boundingBox.y
      }, rootElement);
    });
  }
};

},{"../../util/ModelUtil":141,"diagram-js/lib/features/editor-actions/EditorActions":198,"diagram-js/lib/util/Elements":315,"inherits":347,"min-dash":555}],40:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _editorActions = _interopRequireDefault(require("diagram-js/lib/features/editor-actions"));

var _BpmnEditorActions = _interopRequireDefault(require("./BpmnEditorActions"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_editorActions.default],
  editorActions: ['type', _BpmnEditorActions.default]
};
exports.default = _default;

},{"./BpmnEditorActions":39,"diagram-js/lib/features/editor-actions":199}],41:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnGridSnapping;

var _ModelingUtil = require("../modeling/util/ModelingUtil");

function BpmnGridSnapping(eventBus) {
  eventBus.on(['create.init', 'shape.move.init'], function (event) {
    var context = event.context,
        shape = event.shape;

    if ((0, _ModelingUtil.isAny)(shape, ['bpmn:Participant', 'bpmn:SubProcess', 'bpmn:TextAnnotation'])) {
      if (!context.gridSnappingContext) {
        context.gridSnappingContext = {};
      }

      context.gridSnappingContext.snapLocation = 'top-left';
    }
  });
}

BpmnGridSnapping.$inject = ['eventBus'];

},{"../modeling/util/ModelingUtil":112}],42:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AutoPlaceBehavior;

var _BpmnAutoPlaceUtil = require("../../auto-place/BpmnAutoPlaceUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _ModelUtil = require("../../../util/ModelUtil");

var HIGH_PRIORITY = 2000;

function AutoPlaceBehavior(eventBus, gridSnapping) {
  eventBus.on('autoPlace', HIGH_PRIORITY, function (context) {
    var source = context.source,
        sourceMid = (0, _LayoutUtil.getMid)(source),
        shape = context.shape;
    var position = (0, _BpmnAutoPlaceUtil.getNewShapePosition)(source, shape);
    ['x', 'y'].forEach(function (axis) {
      var options = {}; // do not snap if x/y equal

      if (position[axis] === sourceMid[axis]) {
        return;
      }

      if (position[axis] > sourceMid[axis]) {
        options.min = position[axis];
      } else {
        options.max = position[axis];
      }

      if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) {
        if (isHorizontal(axis)) {
          options.offset = -shape.width / 2;
        } else {
          options.offset = -shape.height / 2;
        }
      }

      position[axis] = gridSnapping.snapValue(position[axis], options);
    }); // must be returned to be considered by auto place

    return position;
  });
}

AutoPlaceBehavior.$inject = ['eventBus', 'gridSnapping']; // helpers //////////

function isHorizontal(axis) {
  return axis === 'x';
}

},{"../../../util/ModelUtil":141,"../../auto-place/BpmnAutoPlaceUtil":25,"diagram-js/lib/layout/LayoutUtil":300}],43:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreateParticipantBehavior;

var _ModelUtil = require("../../../util/ModelUtil");

var HIGHER_PRIORITY = 1750;

function CreateParticipantBehavior(canvas, eventBus, gridSnapping) {
  eventBus.on(['create.start', 'shape.move.start'], HIGHER_PRIORITY, function (event) {
    var context = event.context,
        shape = context.shape,
        rootElement = canvas.getRootElement();

    if (!(0, _ModelUtil.is)(shape, 'bpmn:Participant') || !(0, _ModelUtil.is)(rootElement, 'bpmn:Process') || !rootElement.children.length) {
      return;
    }

    var createConstraints = context.createConstraints;

    if (!createConstraints) {
      return;
    }

    shape.width = gridSnapping.snapValue(shape.width, {
      min: shape.width
    });
    shape.height = gridSnapping.snapValue(shape.height, {
      min: shape.height
    });
  });
}

CreateParticipantBehavior.$inject = ['canvas', 'eventBus', 'gridSnapping'];

},{"../../../util/ModelUtil":141}],44:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = LayoutConnectionBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _Geometry = require("diagram-js/lib/util/Geometry");

var _minDash = require("min-dash");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var HIGH_PRIORITY = 3000;
/**
 * Snaps connections with Manhattan layout.
 */

function LayoutConnectionBehavior(eventBus, gridSnapping, modeling) {
  _CommandInterceptor.default.call(this, eventBus);

  this._gridSnapping = gridSnapping;
  var self = this;
  this.postExecuted(['connection.create', 'connection.layout'], HIGH_PRIORITY, function (event) {
    var context = event.context,
        connection = context.connection,
        hints = context.hints || {},
        waypoints = connection.waypoints;

    if (hints.connectionStart || hints.connectionEnd || hints.createElementsBehavior === false) {
      return;
    }

    if (!hasMiddleSegments(waypoints)) {
      return;
    }

    modeling.updateWaypoints(connection, self.snapMiddleSegments(waypoints));
  });
}

LayoutConnectionBehavior.$inject = ['eventBus', 'gridSnapping', 'modeling'];
(0, _inherits.default)(LayoutConnectionBehavior, _CommandInterceptor.default);
/**
 * Snap middle segments of a given connection.
 *
 * @param {Array<Point>} waypoints
 *
 * @returns {Array<Point>}
 */

LayoutConnectionBehavior.prototype.snapMiddleSegments = function (waypoints) {
  var gridSnapping = this._gridSnapping,
      snapped;
  waypoints = waypoints.slice();

  for (var i = 1; i < waypoints.length - 2; i++) {
    snapped = snapSegment(gridSnapping, waypoints[i], waypoints[i + 1]);
    waypoints[i] = snapped[0];
    waypoints[i + 1] = snapped[1];
  }

  return waypoints;
}; // helpers //////////

/**
 * Check whether a connection has a middle segments.
 *
 * @param {Array} waypoints
 *
 * @returns {boolean}
 */


function hasMiddleSegments(waypoints) {
  return waypoints.length > 3;
}
/**
 * Check whether an alignment is horizontal.
 *
 * @param {string} aligned
 *
 * @returns {boolean}
 */


function horizontallyAligned(aligned) {
  return aligned === 'h';
}
/**
 * Check whether an alignment is vertical.
 *
 * @param {string} aligned
 *
 * @returns {boolean}
 */


function verticallyAligned(aligned) {
  return aligned === 'v';
}
/**
 * Get middle segments from a given connection.
 *
 * @param {Array} waypoints
 *
 * @returns {Array}
 */


function snapSegment(gridSnapping, segmentStart, segmentEnd) {
  var aligned = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd);
  var snapped = {};

  if (horizontallyAligned(aligned)) {
    // snap horizontally
    snapped.y = gridSnapping.snapValue(segmentStart.y);
  }

  if (verticallyAligned(aligned)) {
    // snap vertically
    snapped.x = gridSnapping.snapValue(segmentStart.x);
  }

  if ('x' in snapped || 'y' in snapped) {
    segmentStart = (0, _minDash.assign)({}, segmentStart, snapped);
    segmentEnd = (0, _minDash.assign)({}, segmentEnd, snapped);
  }

  return [segmentStart, segmentEnd];
}

},{"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Geometry":318,"inherits":347,"min-dash":555}],45:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _AutoPlaceBehavior = _interopRequireDefault(require("./AutoPlaceBehavior"));

var _CreateParticipantBehavior = _interopRequireDefault(require("./CreateParticipantBehavior"));

var _LayoutConnectionBehavior = _interopRequireDefault(require("./LayoutConnectionBehavior"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['gridSnappingAutoPlaceBehavior', 'gridSnappingCreateParticipantBehavior', 'gridSnappingLayoutConnectionBehavior'],
  gridSnappingAutoPlaceBehavior: ['type', _AutoPlaceBehavior.default],
  gridSnappingCreateParticipantBehavior: ['type', _CreateParticipantBehavior.default],
  gridSnappingLayoutConnectionBehavior: ['type', _LayoutConnectionBehavior.default]
};
exports.default = _default;

},{"./AutoPlaceBehavior":42,"./CreateParticipantBehavior":43,"./LayoutConnectionBehavior":44}],46:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _BpmnGridSnapping = _interopRequireDefault(require("./BpmnGridSnapping"));

var _gridSnapping = _interopRequireDefault(require("diagram-js/lib/features/grid-snapping"));

var _behavior = _interopRequireDefault(require("./behavior"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_gridSnapping.default, _behavior.default],
  __init__: ['bpmnGridSnapping'],
  bpmnGridSnapping: ['type', _BpmnGridSnapping.default]
};
exports.default = _default;

},{"./BpmnGridSnapping":41,"./behavior":45,"diagram-js/lib/features/grid-snapping":207}],47:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnInteractionEvents;

var _ModelUtil = require("../../util/ModelUtil");

var _DiUtil = require("../../util/DiUtil");

var LABEL_WIDTH = 30,
    LABEL_HEIGHT = 30;
/**
 * BPMN-specific hit zones and interaction fixes.
 *
 * @param {EventBus} eventBus
 * @param {InteractionEvents} interactionEvents
 */

function BpmnInteractionEvents(eventBus, interactionEvents) {
  this._interactionEvents = interactionEvents;
  var self = this;
  eventBus.on(['interactionEvents.createHit', 'interactionEvents.updateHit'], function (context) {
    var element = context.element,
        gfx = context.gfx;

    if ((0, _ModelUtil.is)(element, 'bpmn:Lane')) {
      return self.createParticipantHit(element, gfx);
    } else if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) {
      if ((0, _DiUtil.isExpanded)(element)) {
        return self.createParticipantHit(element, gfx);
      } else {
        return self.createDefaultHit(element, gfx);
      }
    } else if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess')) {
      if ((0, _DiUtil.isExpanded)(element)) {
        return self.createSubProcessHit(element, gfx);
      } else {
        return self.createDefaultHit(element, gfx);
      }
    }
  });
}

BpmnInteractionEvents.$inject = ['eventBus', 'interactionEvents'];

BpmnInteractionEvents.prototype.createDefaultHit = function (element, gfx) {
  this._interactionEvents.removeHits(gfx);

  this._interactionEvents.createDefaultHit(element, gfx); // indicate that we created a hit


  return true;
};

BpmnInteractionEvents.prototype.createParticipantHit = function (element, gfx) {
  // remove existing hits
  this._interactionEvents.removeHits(gfx); // add outline hit


  this._interactionEvents.createBoxHit(gfx, 'click-stroke', {
    width: element.width,
    height: element.height
  }); // add label hit


  this._interactionEvents.createBoxHit(gfx, 'all', {
    width: LABEL_WIDTH,
    height: element.height
  }); // indicate that we created a hit


  return true;
};

BpmnInteractionEvents.prototype.createSubProcessHit = function (element, gfx) {
  // remove existing hits
  this._interactionEvents.removeHits(gfx); // add outline hit


  this._interactionEvents.createBoxHit(gfx, 'click-stroke', {
    width: element.width,
    height: element.height
  }); // add label hit


  this._interactionEvents.createBoxHit(gfx, 'all', {
    width: element.width,
    height: LABEL_HEIGHT
  }); // indicate that we created a hit


  return true;
};

},{"../../util/DiUtil":139,"../../util/ModelUtil":141}],48:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _BpmnInteractionEvents = _interopRequireDefault(require("./BpmnInteractionEvents"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['bpmnInteractionEvents'],
  bpmnInteractionEvents: ['type', _BpmnInteractionEvents.default]
};
exports.default = _default;

},{"./BpmnInteractionEvents":47}],49:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnKeyboardBindings;

var _inherits = _interopRequireDefault(require("inherits"));

var _KeyboardBindings = _interopRequireDefault(require("diagram-js/lib/features/keyboard/KeyboardBindings"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * BPMN 2.0 specific keyboard bindings.
 *
 * @param {Injector} injector
 */
function BpmnKeyboardBindings(injector) {
  injector.invoke(_KeyboardBindings.default, this);
}

(0, _inherits.default)(BpmnKeyboardBindings, _KeyboardBindings.default);
BpmnKeyboardBindings.$inject = ['injector'];
/**
 * Register available keyboard bindings.
 *
 * @param {Keyboard} keyboard
 * @param {EditorActions} editorActions
 */

BpmnKeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) {
  // inherit default bindings
  _KeyboardBindings.default.prototype.registerBindings.call(this, keyboard, editorActions);
  /**
   * Add keyboard binding if respective editor action
   * is registered.
   *
   * @param {string} action name
   * @param {Function} fn that implements the key binding
   */


  function addListener(action, fn) {
    if (editorActions.isRegistered(action)) {
      keyboard.addListener(fn);
    }
  } // select all elements
  // CTRL + A


  addListener('selectElements', function (context) {
    var event = context.keyEvent;

    if (keyboard.isKey(['a', 'A'], event) && keyboard.isCmd(event)) {
      editorActions.trigger('selectElements');
      return true;
    }
  }); // search labels
  // CTRL + F

  addListener('find', function (context) {
    var event = context.keyEvent;

    if (keyboard.isKey(['f', 'F'], event) && keyboard.isCmd(event)) {
      editorActions.trigger('find');
      return true;
    }
  }); // activate space tool
  // S

  addListener('spaceTool', function (context) {
    var event = context.keyEvent;

    if (keyboard.hasModifier(event)) {
      return;
    }

    if (keyboard.isKey(['s', 'S'], event)) {
      editorActions.trigger('spaceTool');
      return true;
    }
  }); // activate lasso tool
  // L

  addListener('lassoTool', function (context) {
    var event = context.keyEvent;

    if (keyboard.hasModifier(event)) {
      return;
    }

    if (keyboard.isKey(['l', 'L'], event)) {
      editorActions.trigger('lassoTool');
      return true;
    }
  }); // activate hand tool
  // H

  addListener('handTool', function (context) {
    var event = context.keyEvent;

    if (keyboard.hasModifier(event)) {
      return;
    }

    if (keyboard.isKey(['h', 'H'], event)) {
      editorActions.trigger('handTool');
      return true;
    }
  }); // activate global connect tool
  // C

  addListener('globalConnectTool', function (context) {
    var event = context.keyEvent;

    if (keyboard.hasModifier(event)) {
      return;
    }

    if (keyboard.isKey(['c', 'C'], event)) {
      editorActions.trigger('globalConnectTool');
      return true;
    }
  }); // activate direct editing
  // E

  addListener('directEditing', function (context) {
    var event = context.keyEvent;

    if (keyboard.hasModifier(event)) {
      return;
    }

    if (keyboard.isKey(['e', 'E'], event)) {
      editorActions.trigger('directEditing');
      return true;
    }
  });
};

},{"diagram-js/lib/features/keyboard/KeyboardBindings":215,"inherits":347}],50:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _keyboard = _interopRequireDefault(require("diagram-js/lib/features/keyboard"));

var _BpmnKeyboardBindings = _interopRequireDefault(require("./BpmnKeyboardBindings"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_keyboard.default],
  __init__: ['keyboardBindings'],
  keyboardBindings: ['type', _BpmnKeyboardBindings.default]
};
exports.default = _default;

},{"./BpmnKeyboardBindings":49,"diagram-js/lib/features/keyboard":217}],51:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = LabelEditingPreview;

var _tinySvg = require("tiny-svg");

var _ModelUtil = require("../../util/ModelUtil");

var _SvgTransformUtil = require("diagram-js/lib/util/SvgTransformUtil");

var MARKER_HIDDEN = 'djs-element-hidden',
    MARKER_LABEL_HIDDEN = 'djs-label-hidden';

function LabelEditingPreview(eventBus, canvas, elementRegistry, pathMap) {
  var self = this;
  var defaultLayer = canvas.getDefaultLayer();
  var element, absoluteElementBBox, gfx;
  eventBus.on('directEditing.activate', function (context) {
    var activeProvider = context.active;
    element = activeProvider.element.label || activeProvider.element; // text annotation

    if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
      absoluteElementBBox = canvas.getAbsoluteBBox(element);
      gfx = (0, _tinySvg.create)('g');
      var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: element.height,
        position: {
          mx: 0.0,
          my: 0.0
        }
      });
      var path = self.path = (0, _tinySvg.create)('path');
      (0, _tinySvg.attr)(path, {
        d: textPathData,
        strokeWidth: 2,
        stroke: getStrokeColor(element)
      });
      (0, _tinySvg.append)(gfx, path);
      (0, _tinySvg.append)(defaultLayer, gfx);
      (0, _SvgTransformUtil.translate)(gfx, element.x, element.y);
    }

    if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation') || element.labelTarget) {
      canvas.addMarker(element, MARKER_HIDDEN);
    } else if ((0, _ModelUtil.is)(element, 'bpmn:Task') || (0, _ModelUtil.is)(element, 'bpmn:CallActivity') || (0, _ModelUtil.is)(element, 'bpmn:SubProcess') || (0, _ModelUtil.is)(element, 'bpmn:Participant')) {
      canvas.addMarker(element, MARKER_LABEL_HIDDEN);
    }
  });
  eventBus.on('directEditing.resize', function (context) {
    // text annotation
    if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
      var height = context.height,
          dy = context.dy;
      var newElementHeight = Math.max(element.height / absoluteElementBBox.height * (height + dy), 0);
      var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
        xScaleFactor: 1,
        yScaleFactor: 1,
        containerWidth: element.width,
        containerHeight: newElementHeight,
        position: {
          mx: 0.0,
          my: 0.0
        }
      });
      (0, _tinySvg.attr)(self.path, {
        d: textPathData
      });
    }
  });
  eventBus.on(['directEditing.complete', 'directEditing.cancel'], function (context) {
    var activeProvider = context.active;

    if (activeProvider) {
      canvas.removeMarker(activeProvider.element.label || activeProvider.element, MARKER_HIDDEN);
      canvas.removeMarker(element, MARKER_LABEL_HIDDEN);
    }

    element = undefined;
    absoluteElementBBox = undefined;

    if (gfx) {
      (0, _tinySvg.remove)(gfx);
      gfx = undefined;
    }
  });
}

LabelEditingPreview.$inject = ['eventBus', 'canvas', 'elementRegistry', 'pathMap']; // helpers ///////////////////

function getStrokeColor(element, defaultColor) {
  var bo = (0, _ModelUtil.getBusinessObject)(element);
  return bo.di.get('stroke') || defaultColor || 'black';
}

},{"../../util/ModelUtil":141,"diagram-js/lib/util/SvgTransformUtil":328,"tiny-svg":567}],52:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = LabelEditingProvider;

var _minDash = require("min-dash");

var _LabelUtil = require("./LabelUtil");

var _ModelUtil = require("../../util/ModelUtil");

var _CategoryUtil = require("../modeling/behavior/util/CategoryUtil");

var _ModelingUtil = require("../modeling/util/ModelingUtil");

var _DiUtil = require("../../util/DiUtil");

var _LabelUtil2 = require("../../util/LabelUtil");

function LabelEditingProvider(eventBus, bpmnFactory, canvas, directEditing, modeling, resizeHandles, textRenderer) {
  this._bpmnFactory = bpmnFactory;
  this._canvas = canvas;
  this._modeling = modeling;
  this._textRenderer = textRenderer;
  directEditing.registerProvider(this); // listen to dblclick on non-root elements

  eventBus.on('element.dblclick', function (event) {
    activateDirectEdit(event.element, true);
  }); // complete on followup canvas operation

  eventBus.on(['autoPlace.start', 'canvas.viewbox.changing', 'drag.init', 'element.mousedown', 'popupMenu.open'], function (event) {
    if (directEditing.isActive()) {
      directEditing.complete();
    }
  }); // cancel on command stack changes

  eventBus.on(['commandStack.changed'], function (e) {
    if (directEditing.isActive()) {
      directEditing.cancel();
    }
  });
  eventBus.on('directEditing.activate', function (event) {
    resizeHandles.removeResizers();
  });
  eventBus.on('create.end', 500, function (event) {
    var context = event.context,
        element = context.shape,
        canExecute = event.context.canExecute,
        isTouch = event.isTouch; // TODO(nikku): we need to find a way to support the
    // direct editing on mobile devices; right now this will
    // break for desworkflowediting on mobile devices
    // as it breaks the user interaction workflow
    // TODO(nre): we should temporarily focus the edited element
    // here and release the focused viewport after the direct edit
    // operation is finished

    if (isTouch) {
      return;
    }

    if (!canExecute) {
      return;
    }

    if (context.hints && context.hints.createElementsBehavior === false) {
      return;
    }

    activateDirectEdit(element);
  });
  eventBus.on('autoPlace.end', 500, function (event) {
    activateDirectEdit(event.shape);
  });

  function activateDirectEdit(element, force) {
    if (force || (0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:TextAnnotation', 'bpmn:Group']) || isCollapsedSubProcess(element)) {
      directEditing.activate(element);
    }
  }
}

LabelEditingProvider.$inject = ['eventBus', 'bpmnFactory', 'canvas', 'directEditing', 'modeling', 'resizeHandles', 'textRenderer'];
/**
 * Activate direct editing for activities and text annotations.
 *
 * @param  {djs.model.Base} element
 *
 * @return {Object} an object with properties bounds (position and size), text and options
 */

LabelEditingProvider.prototype.activate = function (element) {
  // text
  var text = (0, _LabelUtil.getLabel)(element);

  if (text === undefined) {
    return;
  }

  var context = {
    text: text
  }; // bounds

  var bounds = this.getEditingBBox(element);
  (0, _minDash.assign)(context, bounds);
  var options = {}; // tasks

  if ((0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:Participant', 'bpmn:Lane', 'bpmn:CallActivity']) || isCollapsedSubProcess(element)) {
    (0, _minDash.assign)(options, {
      centerVertically: true
    });
  } // external labels


  if ((0, _LabelUtil2.isLabelExternal)(element)) {
    (0, _minDash.assign)(options, {
      autoResize: true
    });
  } // text annotations


  if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
    (0, _minDash.assign)(options, {
      resizable: true,
      autoResize: true
    });
  }

  (0, _minDash.assign)(context, {
    options: options
  });
  return context;
};
/**
 * Get the editing bounding box based on the element's size and position
 *
 * @param  {djs.model.Base} element
 *
 * @return {Object} an object containing information about position
 *                  and size (fixed or minimum and/or maximum)
 */


LabelEditingProvider.prototype.getEditingBBox = function (element) {
  var canvas = this._canvas;
  var target = element.label || element;
  var bbox = canvas.getAbsoluteBBox(target);
  var mid = {
    x: bbox.x + bbox.width / 2,
    y: bbox.y + bbox.height / 2
  }; // default position

  var bounds = {
    x: bbox.x,
    y: bbox.y
  };
  var zoom = canvas.zoom();

  var defaultStyle = this._textRenderer.getDefaultStyle(),
      externalStyle = this._textRenderer.getExternalStyle(); // take zoom into account


  var externalFontSize = externalStyle.fontSize * zoom,
      externalLineHeight = externalStyle.lineHeight,
      defaultFontSize = defaultStyle.fontSize * zoom,
      defaultLineHeight = defaultStyle.lineHeight;
  var style = {
    fontFamily: this._textRenderer.getDefaultStyle().fontFamily,
    fontWeight: this._textRenderer.getDefaultStyle().fontWeight
  }; // adjust for expanded pools AND lanes

  if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || isExpandedPool(element)) {
    (0, _minDash.assign)(bounds, {
      width: bbox.height,
      height: 30 * zoom,
      x: bbox.x - bbox.height / 2 + 15 * zoom,
      y: mid.y - 30 * zoom / 2
    });
    (0, _minDash.assign)(style, {
      fontSize: defaultFontSize + 'px',
      lineHeight: defaultLineHeight,
      paddingTop: 7 * zoom + 'px',
      paddingBottom: 7 * zoom + 'px',
      paddingLeft: 5 * zoom + 'px',
      paddingRight: 5 * zoom + 'px',
      transform: 'rotate(-90deg)'
    });
  } // internal labels for tasks and collapsed call activities,
  // sub processes and participants


  if ((0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:CallActivity']) || isCollapsedPool(element) || isCollapsedSubProcess(element)) {
    (0, _minDash.assign)(bounds, {
      width: bbox.width,
      height: bbox.height
    });
    (0, _minDash.assign)(style, {
      fontSize: defaultFontSize + 'px',
      lineHeight: defaultLineHeight,
      paddingTop: 7 * zoom + 'px',
      paddingBottom: 7 * zoom + 'px',
      paddingLeft: 5 * zoom + 'px',
      paddingRight: 5 * zoom + 'px'
    });
  } // internal labels for expanded sub processes


  if (isExpandedSubProcess(element)) {
    (0, _minDash.assign)(bounds, {
      width: bbox.width,
      x: bbox.x
    });
    (0, _minDash.assign)(style, {
      fontSize: defaultFontSize + 'px',
      lineHeight: defaultLineHeight,
      paddingTop: 7 * zoom + 'px',
      paddingBottom: 7 * zoom + 'px',
      paddingLeft: 5 * zoom + 'px',
      paddingRight: 5 * zoom + 'px'
    });
  }

  var width = 90 * zoom,
      paddingTop = 7 * zoom,
      paddingBottom = 4 * zoom; // external labels for events, data elements, gateways, groups and connections

  if (target.labelTarget) {
    (0, _minDash.assign)(bounds, {
      width: width,
      height: bbox.height + paddingTop + paddingBottom,
      x: mid.x - width / 2,
      y: bbox.y - paddingTop
    });
    (0, _minDash.assign)(style, {
      fontSize: externalFontSize + 'px',
      lineHeight: externalLineHeight,
      paddingTop: paddingTop + 'px',
      paddingBottom: paddingBottom + 'px'
    });
  } // external label not yet created


  if ((0, _LabelUtil2.isLabelExternal)(target) && !(0, _LabelUtil2.hasExternalLabel)(target) && !(0, _LabelUtil2.isLabel)(target)) {
    var externalLabelMid = (0, _LabelUtil2.getExternalLabelMid)(element);
    var absoluteBBox = canvas.getAbsoluteBBox({
      x: externalLabelMid.x,
      y: externalLabelMid.y,
      width: 0,
      height: 0
    });
    var height = externalFontSize + paddingTop + paddingBottom;
    (0, _minDash.assign)(bounds, {
      width: width,
      height: height,
      x: absoluteBBox.x - width / 2,
      y: absoluteBBox.y - height / 2
    });
    (0, _minDash.assign)(style, {
      fontSize: externalFontSize + 'px',
      lineHeight: externalLineHeight,
      paddingTop: paddingTop + 'px',
      paddingBottom: paddingBottom + 'px'
    });
  } // text annotations


  if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
    (0, _minDash.assign)(bounds, {
      width: bbox.width,
      height: bbox.height,
      minWidth: 30 * zoom,
      minHeight: 10 * zoom
    });
    (0, _minDash.assign)(style, {
      textAlign: 'left',
      paddingTop: 5 * zoom + 'px',
      paddingBottom: 7 * zoom + 'px',
      paddingLeft: 7 * zoom + 'px',
      paddingRight: 5 * zoom + 'px',
      fontSize: defaultFontSize + 'px',
      lineHeight: defaultLineHeight
    });
  }

  return {
    bounds: bounds,
    style: style
  };
};

LabelEditingProvider.prototype.update = function (element, newLabel, activeContextText, bounds) {
  var newBounds, bbox;

  if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
    bbox = this._canvas.getAbsoluteBBox(element);
    newBounds = {
      x: element.x,
      y: element.y,
      width: element.width / bbox.width * bounds.width,
      height: element.height / bbox.height * bounds.height
    };
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:Group')) {
    var businessObject = (0, _ModelUtil.getBusinessObject)(element); // initialize categoryValue if not existing

    if (!businessObject.categoryValueRef) {
      var rootElement = this._canvas.getRootElement(),
          definitions = (0, _ModelUtil.getBusinessObject)(rootElement).$parent;

      var categoryValue = (0, _CategoryUtil.createCategoryValue)(definitions, this._bpmnFactory);
      (0, _ModelUtil.getBusinessObject)(element).categoryValueRef = categoryValue;
    }
  }

  if (isEmptyText(newLabel)) {
    newLabel = null;
  }

  this._modeling.updateLabel(element, newLabel, newBounds);
}; // helpers //////////////////////


function isCollapsedSubProcess(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && !(0, _DiUtil.isExpanded)(element);
}

function isExpandedSubProcess(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element);
}

function isCollapsedPool(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(element);
}

function isExpandedPool(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:Participant') && (0, _DiUtil.isExpanded)(element);
}

function isEmptyText(label) {
  return !label || !label.trim();
}

},{"../../util/DiUtil":139,"../../util/LabelUtil":140,"../../util/ModelUtil":141,"../modeling/behavior/util/CategoryUtil":95,"../modeling/util/ModelingUtil":112,"./LabelUtil":53,"min-dash":555}],53:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getLabel = getLabel;
exports.setLabel = setLabel;

var _ModelUtil = require("../../util/ModelUtil");

function getLabelAttr(semantic) {
  if ((0, _ModelUtil.is)(semantic, 'bpmn:FlowElement') || (0, _ModelUtil.is)(semantic, 'bpmn:Participant') || (0, _ModelUtil.is)(semantic, 'bpmn:Lane') || (0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:MessageFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:DataInput') || (0, _ModelUtil.is)(semantic, 'bpmn:DataOutput')) {
    return 'name';
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:TextAnnotation')) {
    return 'text';
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:Group')) {
    return 'categoryValueRef';
  }
}

function getCategoryValue(semantic) {
  var categoryValueRef = semantic['categoryValueRef'];

  if (!categoryValueRef) {
    return '';
  }

  return categoryValueRef.value || '';
}

function getLabel(element) {
  var semantic = element.businessObject,
      attr = getLabelAttr(semantic);

  if (attr) {
    if (attr === 'categoryValueRef') {
      return getCategoryValue(semantic);
    }

    return semantic[attr] || '';
  }
}

function setLabel(element, text, isExternal) {
  var semantic = element.businessObject,
      attr = getLabelAttr(semantic);

  if (attr) {
    if (attr === 'categoryValueRef') {
      semantic['categoryValueRef'].value = text;
    } else {
      semantic[attr] = text;
    }
  }

  return element;
}

},{"../../util/ModelUtil":141}],54:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = UpdateLabelHandler;

var _LabelUtil = require("../LabelUtil");

var _LabelUtil2 = require("../../../util/LabelUtil");

var _ModelUtil = require("../../../util/ModelUtil");

var NULL_DIMENSIONS = {
  width: 0,
  height: 0
};
/**
 * A handler that updates the text of a BPMN element.
 */

function UpdateLabelHandler(modeling, textRenderer) {
  /**
   * Set the label and return the changed elements.
   *
   * Element parameter can be label itself or connection (i.e. sequence flow).
   *
   * @param {djs.model.Base} element
   * @param {string} text
   */
  function setText(element, text) {
    // external label if present
    var label = element.label || element;
    var labelTarget = element.labelTarget || element;
    (0, _LabelUtil.setLabel)(label, text, labelTarget !== label);
    return [label, labelTarget];
  }

  function preExecute(ctx) {
    var element = ctx.element,
        businessObject = element.businessObject,
        newLabel = ctx.newLabel;

    if (!(0, _LabelUtil2.isLabel)(element) && (0, _LabelUtil2.isLabelExternal)(element) && !(0, _LabelUtil2.hasExternalLabel)(element) && !isEmptyText(newLabel)) {
      // create label
      var paddingTop = 7;
      var labelCenter = (0, _LabelUtil2.getExternalLabelMid)(element);
      labelCenter = {
        x: labelCenter.x,
        y: labelCenter.y + paddingTop
      };
      modeling.createLabel(element, labelCenter, {
        id: businessObject.id + '_label',
        businessObject: businessObject
      });
    }
  }

  function execute(ctx) {
    ctx.oldLabel = (0, _LabelUtil.getLabel)(ctx.element);
    return setText(ctx.element, ctx.newLabel);
  }

  function revert(ctx) {
    return setText(ctx.element, ctx.oldLabel);
  }

  function postExecute(ctx) {
    var element = ctx.element,
        label = element.label || element,
        newLabel = ctx.newLabel,
        newBounds = ctx.newBounds,
        hints = ctx.hints || {}; // ignore internal labels for elements except text annotations

    if (!(0, _LabelUtil2.isLabel)(label) && !(0, _ModelUtil.is)(label, 'bpmn:TextAnnotation')) {
      return;
    }

    if ((0, _LabelUtil2.isLabel)(label) && isEmptyText(newLabel)) {
      if (hints.removeShape !== false) {
        modeling.removeShape(label, {
          unsetLabel: false
        });
      }

      return;
    }

    var text = (0, _LabelUtil.getLabel)(label); // resize element based on label _or_ pre-defined bounds

    if (typeof newBounds === 'undefined') {
      newBounds = textRenderer.getExternalLabelBounds(label, text);
    } // setting newBounds to false or _null_ will
    // disable the postExecute resize operation


    if (newBounds) {
      modeling.resizeShape(label, newBounds, NULL_DIMENSIONS);
    }
  } // API


  this.preExecute = preExecute;
  this.execute = execute;
  this.revert = revert;
  this.postExecute = postExecute;
}

UpdateLabelHandler.$inject = ['modeling', 'textRenderer']; // helpers ///////////////////////

function isEmptyText(label) {
  return !label || !label.trim();
}

},{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"../LabelUtil":53}],55:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _changeSupport = _interopRequireDefault(require("diagram-js/lib/features/change-support"));

var _resize = _interopRequireDefault(require("diagram-js/lib/features/resize"));

var _diagramJsDirectEditing = _interopRequireDefault(require("diagram-js-direct-editing"));

var _LabelEditingProvider = _interopRequireDefault(require("./LabelEditingProvider"));

var _LabelEditingPreview = _interopRequireDefault(require("./LabelEditingPreview"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_changeSupport.default, _resize.default, _diagramJsDirectEditing.default],
  __init__: ['labelEditingProvider', 'labelEditingPreview'],
  labelEditingProvider: ['type', _LabelEditingProvider.default],
  labelEditingPreview: ['type', _LabelEditingPreview.default]
};
exports.default = _default;

},{"./LabelEditingPreview":51,"./LabelEditingProvider":52,"diagram-js-direct-editing":332,"diagram-js/lib/features/change-support":178,"diagram-js/lib/features/resize":269}],56:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnFactory;

var _minDash = require("min-dash");

var _ModelingUtil = require("./util/ModelingUtil");

var _ModelUtil = require("../../util/ModelUtil");

function BpmnFactory(moddle) {
  this._model = moddle;
}

BpmnFactory.$inject = ['moddle'];

BpmnFactory.prototype._needsId = function (element) {
  return (0, _ModelingUtil.isAny)(element, ['bpmn:RootElement', 'bpmn:FlowElement', 'bpmn:MessageFlow', 'bpmn:DataAssociation', 'bpmn:Artifact', 'bpmn:Participant', 'bpmn:Lane', 'bpmn:LaneSet', 'bpmn:Process', 'bpmn:Collaboration', 'bpmndi:BPMNShape', 'bpmndi:BPMNEdge', 'bpmndi:BPMNDiagram', 'bpmndi:BPMNPlane', 'bpmn:Property', 'bpmn:CategoryValue']);
};

BpmnFactory.prototype._ensureId = function (element) {
  // generate semantic ids for elements
  // bpmn:SequenceFlow -> SequenceFlow_ID
  var prefix;

  if ((0, _ModelUtil.is)(element, 'bpmn:Activity')) {
    prefix = 'Activity';
  } else if ((0, _ModelUtil.is)(element, 'bpmn:Event')) {
    prefix = 'Event';
  } else if ((0, _ModelUtil.is)(element, 'bpmn:Gateway')) {
    prefix = 'Gateway';
  } else if ((0, _ModelingUtil.isAny)(element, ['bpmn:SequenceFlow', 'bpmn:MessageFlow'])) {
    prefix = 'Flow';
  } else {
    prefix = (element.$type || '').replace(/^[^:]*:/g, '');
  }

  prefix += '_';

  if (!element.id && this._needsId(element)) {
    element.id = this._model.ids.nextPrefixed(prefix, element);
  }
};

BpmnFactory.prototype.create = function (type, attrs) {
  var element = this._model.create(type, attrs || {});

  this._ensureId(element);

  return element;
};

BpmnFactory.prototype.createDiLabel = function () {
  return this.create('bpmndi:BPMNLabel', {
    bounds: this.createDiBounds()
  });
};

BpmnFactory.prototype.createDiShape = function (semantic, bounds, attrs) {
  return this.create('bpmndi:BPMNShape', (0, _minDash.assign)({
    bpmnElement: semantic,
    bounds: this.createDiBounds(bounds)
  }, attrs));
};

BpmnFactory.prototype.createDiBounds = function (bounds) {
  return this.create('dc:Bounds', bounds);
};

BpmnFactory.prototype.createDiWaypoints = function (waypoints) {
  var self = this;
  return (0, _minDash.map)(waypoints, function (pos) {
    return self.createDiWaypoint(pos);
  });
};

BpmnFactory.prototype.createDiWaypoint = function (point) {
  return this.create('dc:Point', (0, _minDash.pick)(point, ['x', 'y']));
};

BpmnFactory.prototype.createDiEdge = function (semantic, waypoints, attrs) {
  return this.create('bpmndi:BPMNEdge', (0, _minDash.assign)({
    bpmnElement: semantic
  }, attrs));
};

BpmnFactory.prototype.createDiPlane = function (semantic) {
  return this.create('bpmndi:BPMNPlane', {
    bpmnElement: semantic
  });
};

},{"../../util/ModelUtil":141,"./util/ModelingUtil":112,"min-dash":555}],57:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnLayouter;

var _inherits = _interopRequireDefault(require("inherits"));

var _minDash = require("min-dash");

var _BaseLayouter = _interopRequireDefault(require("diagram-js/lib/layout/BaseLayouter"));

var _ManhattanLayout = require("diagram-js/lib/layout/ManhattanLayout");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _DiUtil = require("../../util/DiUtil");

var _ModelUtil = require("../../util/ModelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var ATTACH_ORIENTATION_PADDING = -10,
    BOUNDARY_TO_HOST_THRESHOLD = 40;
var oppositeOrientationMapping = {
  'top': 'bottom',
  'top-right': 'bottom-left',
  'top-left': 'bottom-right',
  'right': 'left',
  'bottom': 'top',
  'bottom-right': 'top-left',
  'bottom-left': 'top-right',
  'left': 'right'
};
var orientationDirectionMapping = {
  top: 't',
  right: 'r',
  bottom: 'b',
  left: 'l'
};

function BpmnLayouter() {}

(0, _inherits.default)(BpmnLayouter, _BaseLayouter.default);

BpmnLayouter.prototype.layoutConnection = function (connection, hints) {
  if (!hints) {
    hints = {};
  }

  var source = hints.source || connection.source,
      target = hints.target || connection.target,
      waypoints = hints.waypoints || connection.waypoints,
      connectionStart = hints.connectionStart,
      connectionEnd = hints.connectionEnd;
  var manhattanOptions, updatedWaypoints;

  if (!connectionStart) {
    connectionStart = getConnectionDocking(waypoints && waypoints[0], source);
  }

  if (!connectionEnd) {
    connectionEnd = getConnectionDocking(waypoints && waypoints[waypoints.length - 1], target);
  } // TODO(nikku): support vertical modeling
  // and invert preferredLayouts accordingly


  if ((0, _ModelUtil.is)(connection, 'bpmn:Association') || (0, _ModelUtil.is)(connection, 'bpmn:DataAssociation')) {
    if (waypoints && !isCompensationAssociation(source, target)) {
      return [].concat([connectionStart], waypoints.slice(1, -1), [connectionEnd]);
    }
  }

  if ((0, _ModelUtil.is)(connection, 'bpmn:MessageFlow')) {
    manhattanOptions = getMessageFlowManhattanOptions(source, target);
  } else if ((0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow') || isCompensationAssociation(source, target)) {
    // layout all connection between flow elements h:h, except for
    // (1) outgoing of boundary events -> layout based on attach orientation and target orientation
    // (2) incoming/outgoing of gateways -> v:h for outgoing, h:v for incoming
    // (3) loops
    if (source === target) {
      manhattanOptions = {
        preferredLayouts: getLoopPreferredLayout(source, connection)
      };
    } else if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) {
      manhattanOptions = {
        preferredLayouts: getBoundaryEventPreferredLayouts(source, target, connectionEnd)
      };
    } else if (isExpandedSubProcess(source) || isExpandedSubProcess(target)) {
      manhattanOptions = getSubProcessManhattanOptions(source);
    } else if ((0, _ModelUtil.is)(source, 'bpmn:Gateway')) {
      manhattanOptions = {
        preferredLayouts: ['v:h']
      };
    } else if ((0, _ModelUtil.is)(target, 'bpmn:Gateway')) {
      manhattanOptions = {
        preferredLayouts: ['h:v']
      };
    } else {
      manhattanOptions = {
        preferredLayouts: ['h:h']
      };
    }
  }

  if (manhattanOptions) {
    manhattanOptions = (0, _minDash.assign)(manhattanOptions, hints);
    updatedWaypoints = (0, _ManhattanLayout.withoutRedundantPoints)((0, _ManhattanLayout.repairConnection)(source, target, connectionStart, connectionEnd, waypoints, manhattanOptions));
  }

  return updatedWaypoints || [connectionStart, connectionEnd];
}; // helpers //////////


function getAttachOrientation(attachedElement) {
  var hostElement = attachedElement.host;
  return (0, _LayoutUtil.getOrientation)((0, _LayoutUtil.getMid)(attachedElement), hostElement, ATTACH_ORIENTATION_PADDING);
}

function getMessageFlowManhattanOptions(source, target) {
  return {
    preferredLayouts: ['straight', 'v:v'],
    preserveDocking: getMessageFlowPreserveDocking(source, target)
  };
}

function getMessageFlowPreserveDocking(source, target) {
  // (1) docking element connected to participant has precedence
  if ((0, _ModelUtil.is)(target, 'bpmn:Participant')) {
    return 'source';
  }

  if ((0, _ModelUtil.is)(source, 'bpmn:Participant')) {
    return 'target';
  } // (2) docking element connected to expanded sub-process has precedence


  if (isExpandedSubProcess(target)) {
    return 'source';
  }

  if (isExpandedSubProcess(source)) {
    return 'target';
  } // (3) docking event has precedence


  if ((0, _ModelUtil.is)(target, 'bpmn:Event')) {
    return 'target';
  }

  if ((0, _ModelUtil.is)(source, 'bpmn:Event')) {
    return 'source';
  }

  return null;
}

function getSubProcessManhattanOptions(source) {
  return {
    preferredLayouts: ['straight', 'h:h'],
    preserveDocking: getSubProcessPreserveDocking(source)
  };
}

function getSubProcessPreserveDocking(source) {
  return isExpandedSubProcess(source) ? 'target' : 'source';
}

function getConnectionDocking(point, shape) {
  return point ? point.original || point : (0, _LayoutUtil.getMid)(shape);
}

function isCompensationAssociation(source, target) {
  return (0, _ModelUtil.is)(target, 'bpmn:Activity') && (0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent') && target.businessObject.isForCompensation;
}

function isExpandedSubProcess(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element);
}

function isSame(a, b) {
  return a === b;
}

function isAnyOrientation(orientation, orientations) {
  return orientations.indexOf(orientation) !== -1;
}

function getHorizontalOrientation(orientation) {
  var matches = /right|left/.exec(orientation);
  return matches && matches[0];
}

function getVerticalOrientation(orientation) {
  var matches = /top|bottom/.exec(orientation);
  return matches && matches[0];
}

function isOppositeOrientation(a, b) {
  return oppositeOrientationMapping[a] === b;
}

function isOppositeHorizontalOrientation(a, b) {
  var horizontalOrientation = getHorizontalOrientation(a);
  var oppositeHorizontalOrientation = oppositeOrientationMapping[horizontalOrientation];
  return b.indexOf(oppositeHorizontalOrientation) !== -1;
}

function isOppositeVerticalOrientation(a, b) {
  var verticalOrientation = getVerticalOrientation(a);
  var oppositeVerticalOrientation = oppositeOrientationMapping[verticalOrientation];
  return b.indexOf(oppositeVerticalOrientation) !== -1;
}

function isHorizontalOrientation(orientation) {
  return orientation === 'right' || orientation === 'left';
}

function getLoopPreferredLayout(source, connection) {
  var waypoints = connection.waypoints;
  var orientation = waypoints && waypoints.length && (0, _LayoutUtil.getOrientation)(waypoints[0], source);

  if (orientation === 'top') {
    return ['t:r'];
  } else if (orientation === 'right') {
    return ['r:b'];
  } else if (orientation === 'left') {
    return ['l:t'];
  }

  return ['b:l'];
}

function getBoundaryEventPreferredLayouts(source, target, end) {
  var sourceMid = (0, _LayoutUtil.getMid)(source),
      targetMid = (0, _LayoutUtil.getMid)(target),
      attachOrientation = getAttachOrientation(source),
      sourceLayout,
      targetLayout;
  var isLoop = isSame(source.host, target);
  var attachedToSide = isAnyOrientation(attachOrientation, ['top', 'right', 'bottom', 'left']);
  var targetOrientation = (0, _LayoutUtil.getOrientation)(targetMid, sourceMid, {
    x: source.width / 2 + target.width / 2,
    y: source.height / 2 + target.height / 2
  });

  if (isLoop) {
    return getBoundaryEventLoopLayout(attachOrientation, attachedToSide, source, target, end);
  } // source layout


  sourceLayout = getBoundaryEventSourceLayout(attachOrientation, targetOrientation, attachedToSide); // target layout

  targetLayout = getBoundaryEventTargetLayout(attachOrientation, targetOrientation, attachedToSide);
  return [sourceLayout + ':' + targetLayout];
}

function getBoundaryEventLoopLayout(attachOrientation, attachedToSide, source, target, end) {
  var orientation = attachedToSide ? attachOrientation : getVerticalOrientation(attachOrientation),
      sourceLayout = orientationDirectionMapping[orientation],
      targetLayout;

  if (attachedToSide) {
    if (isHorizontalOrientation(attachOrientation)) {
      targetLayout = shouldConnectToSameSide('y', source, target, end) ? 'h' : 'b';
    } else {
      targetLayout = shouldConnectToSameSide('x', source, target, end) ? 'v' : 'l';
    }
  } else {
    targetLayout = 'v';
  }

  return [sourceLayout + ':' + targetLayout];
}

function shouldConnectToSameSide(axis, source, target, end) {
  var threshold = BOUNDARY_TO_HOST_THRESHOLD;
  return !(areCloseOnAxis(axis, end, target, threshold) || areCloseOnAxis(axis, end, {
    x: target.x + target.width,
    y: target.y + target.height
  }, threshold) || areCloseOnAxis(axis, end, (0, _LayoutUtil.getMid)(source), threshold));
}

function areCloseOnAxis(axis, a, b, threshold) {
  return Math.abs(a[axis] - b[axis]) < threshold;
}

function getBoundaryEventSourceLayout(attachOrientation, targetOrientation, attachedToSide) {
  // attached to either top, right, bottom or left side
  if (attachedToSide) {
    return orientationDirectionMapping[attachOrientation];
  } // attached to either top-right, top-left, bottom-right or bottom-left corner
  // same vertical or opposite horizontal orientation


  if (isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) || isOppositeOrientation(getHorizontalOrientation(attachOrientation), getHorizontalOrientation(targetOrientation))) {
    return orientationDirectionMapping[getVerticalOrientation(attachOrientation)];
  } // fallback


  return orientationDirectionMapping[getHorizontalOrientation(attachOrientation)];
}

function getBoundaryEventTargetLayout(attachOrientation, targetOrientation, attachedToSide) {
  // attached to either top, right, bottom or left side
  if (attachedToSide) {
    if (isHorizontalOrientation(attachOrientation)) {
      // orientation is right or left
      // opposite horizontal orientation or same orientation
      if (isOppositeHorizontalOrientation(attachOrientation, targetOrientation) || isSame(attachOrientation, targetOrientation)) {
        return 'h';
      } // fallback


      return 'v';
    } else {
      // orientation is top or bottom
      // opposite vertical orientation or same orientation
      if (isOppositeVerticalOrientation(attachOrientation, targetOrientation) || isSame(attachOrientation, targetOrientation)) {
        return 'v';
      } // fallback


      return 'h';
    }
  } // attached to either top-right, top-left, bottom-right or bottom-left corner
  // orientation is right, left
  // or same vertical orientation but also right or left


  if (isHorizontalOrientation(targetOrientation) || isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) && getHorizontalOrientation(targetOrientation)) {
    return 'h';
  } else {
    return 'v';
  }
}

},{"../../util/DiUtil":139,"../../util/ModelUtil":141,"diagram-js/lib/layout/BaseLayouter":298,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/layout/ManhattanLayout":301,"inherits":347,"min-dash":555}],58:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnUpdater;

var _minDash = require("min-dash");

var _inherits = _interopRequireDefault(require("inherits"));

var _Collections = require("diagram-js/lib/util/Collections");

var _model = require("diagram-js/lib/model");

var _ModelUtil = require("../../util/ModelUtil");

var _ModelingUtil = require("./util/ModelingUtil");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A handler responsible for updating the underlying BPMN 2.0 XML + DI
 * once changes on the diagram happen
 */
function BpmnUpdater(eventBus, bpmnFactory, connectionDocking, translate) {
  _CommandInterceptor.default.call(this, eventBus);

  this._bpmnFactory = bpmnFactory;
  this._translate = translate;
  var self = this; // connection cropping //////////////////////
  // crop connection ends during create/update

  function cropConnection(e) {
    var context = e.context,
        hints = context.hints || {},
        connection;

    if (!context.cropped && hints.createElementsBehavior !== false) {
      connection = context.connection;
      connection.waypoints = connectionDocking.getCroppedWaypoints(connection);
      context.cropped = true;
    }
  }

  this.executed(['connection.layout', 'connection.create'], cropConnection);
  this.reverted(['connection.layout'], function (e) {
    delete e.context.cropped;
  }); // BPMN + DI update //////////////////////
  // update parent

  function updateParent(e) {
    var context = e.context;
    self.updateParent(context.shape || context.connection, context.oldParent);
  }

  function reverseUpdateParent(e) {
    var context = e.context;
    var element = context.shape || context.connection,
        // oldParent is the (old) new parent, because we are undoing
    oldParent = context.parent || context.newParent;
    self.updateParent(element, oldParent);
  }

  this.executed(['shape.move', 'shape.create', 'shape.delete', 'connection.create', 'connection.move', 'connection.delete'], ifBpmn(updateParent));
  this.reverted(['shape.move', 'shape.create', 'shape.delete', 'connection.create', 'connection.move', 'connection.delete'], ifBpmn(reverseUpdateParent));
  /*
   * ## Updating Parent
   *
   * When morphing a Process into a Collaboration or vice-versa,
   * make sure that both the *semantic* and *di* parent of each element
   * is updated.
   *
   */

  function updateRoot(event) {
    var context = event.context,
        oldRoot = context.oldRoot,
        children = oldRoot.children;
    (0, _minDash.forEach)(children, function (child) {
      if ((0, _ModelUtil.is)(child, 'bpmn:BaseElement')) {
        self.updateParent(child);
      }
    });
  }

  this.executed(['canvas.updateRoot'], updateRoot);
  this.reverted(['canvas.updateRoot'], updateRoot); // update bounds

  function updateBounds(e) {
    var shape = e.context.shape;

    if (!(0, _ModelUtil.is)(shape, 'bpmn:BaseElement')) {
      return;
    }

    self.updateBounds(shape);
  }

  this.executed(['shape.move', 'shape.create', 'shape.resize'], ifBpmn(function (event) {
    // exclude labels because they're handled separately during shape.changed
    if (event.context.shape.type === 'label') {
      return;
    }

    updateBounds(event);
  }));
  this.reverted(['shape.move', 'shape.create', 'shape.resize'], ifBpmn(function (event) {
    // exclude labels because they're handled separately during shape.changed
    if (event.context.shape.type === 'label') {
      return;
    }

    updateBounds(event);
  })); // Handle labels separately. This is necessary, because the label bounds have to be updated
  // every time its shape changes, not only on move, create and resize.

  eventBus.on('shape.changed', function (event) {
    if (event.element.type === 'label') {
      updateBounds({
        context: {
          shape: event.element
        }
      });
    }
  }); // attach / detach connection

  function updateConnection(e) {
    self.updateConnection(e.context);
  }

  this.executed(['connection.create', 'connection.move', 'connection.delete', 'connection.reconnect'], ifBpmn(updateConnection));
  this.reverted(['connection.create', 'connection.move', 'connection.delete', 'connection.reconnect'], ifBpmn(updateConnection)); // update waypoints

  function updateConnectionWaypoints(e) {
    self.updateConnectionWaypoints(e.context.connection);
  }

  this.executed(['connection.layout', 'connection.move', 'connection.updateWaypoints'], ifBpmn(updateConnectionWaypoints));
  this.reverted(['connection.layout', 'connection.move', 'connection.updateWaypoints'], ifBpmn(updateConnectionWaypoints)); // update conditional/default flows

  this.executed('connection.reconnect', ifBpmn(function (event) {
    var context = event.context,
        connection = context.connection,
        oldSource = context.oldSource,
        newSource = context.newSource,
        connectionBo = (0, _ModelUtil.getBusinessObject)(connection),
        oldSourceBo = (0, _ModelUtil.getBusinessObject)(oldSource),
        newSourceBo = (0, _ModelUtil.getBusinessObject)(newSource); // remove condition from connection on reconnect to new source
    // if new source can NOT have condional sequence flow

    if (connectionBo.conditionExpression && !(0, _ModelingUtil.isAny)(newSourceBo, ['bpmn:Activity', 'bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway'])) {
      context.oldConditionExpression = connectionBo.conditionExpression;
      delete connectionBo.conditionExpression;
    } // remove default from old source flow on reconnect to new source
    // if source changed


    if (oldSource !== newSource && oldSourceBo.default === connectionBo) {
      context.oldDefault = oldSourceBo.default;
      delete oldSourceBo.default;
    }
  }));
  this.reverted('connection.reconnect', ifBpmn(function (event) {
    var context = event.context,
        connection = context.connection,
        oldSource = context.oldSource,
        newSource = context.newSource,
        connectionBo = (0, _ModelUtil.getBusinessObject)(connection),
        oldSourceBo = (0, _ModelUtil.getBusinessObject)(oldSource),
        newSourceBo = (0, _ModelUtil.getBusinessObject)(newSource); // add condition to connection on revert reconnect to new source

    if (context.oldConditionExpression) {
      connectionBo.conditionExpression = context.oldConditionExpression;
    } // add default to old source on revert reconnect to new source


    if (context.oldDefault) {
      oldSourceBo.default = context.oldDefault;
      delete newSourceBo.default;
    }
  })); // update attachments

  function updateAttachment(e) {
    self.updateAttachment(e.context);
  }

  this.executed(['element.updateAttachment'], ifBpmn(updateAttachment));
  this.reverted(['element.updateAttachment'], ifBpmn(updateAttachment));
}

(0, _inherits.default)(BpmnUpdater, _CommandInterceptor.default);
BpmnUpdater.$inject = ['eventBus', 'bpmnFactory', 'connectionDocking', 'translate']; // implementation //////////////////////

BpmnUpdater.prototype.updateAttachment = function (context) {
  var shape = context.shape,
      businessObject = shape.businessObject,
      host = shape.host;
  businessObject.attachedToRef = host && host.businessObject;
};

BpmnUpdater.prototype.updateParent = function (element, oldParent) {
  // do not update BPMN 2.0 label parent
  if (element instanceof _model.Label) {
    return;
  } // data stores in collaborations are handled separately by DataStoreBehavior


  if ((0, _ModelUtil.is)(element, 'bpmn:DataStoreReference') && element.parent && (0, _ModelUtil.is)(element.parent, 'bpmn:Collaboration')) {
    return;
  }

  var parentShape = element.parent;
  var businessObject = element.businessObject,
      parentBusinessObject = parentShape && parentShape.businessObject,
      parentDi = parentBusinessObject && parentBusinessObject.di;

  if ((0, _ModelUtil.is)(element, 'bpmn:FlowNode')) {
    this.updateFlowNodeRefs(businessObject, parentBusinessObject, oldParent && oldParent.businessObject);
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:DataOutputAssociation')) {
    if (element.source) {
      parentBusinessObject = element.source.businessObject;
    } else {
      parentBusinessObject = null;
    }
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:DataInputAssociation')) {
    if (element.target) {
      parentBusinessObject = element.target.businessObject;
    } else {
      parentBusinessObject = null;
    }
  }

  this.updateSemanticParent(businessObject, parentBusinessObject);

  if ((0, _ModelUtil.is)(element, 'bpmn:DataObjectReference') && businessObject.dataObjectRef) {
    this.updateSemanticParent(businessObject.dataObjectRef, parentBusinessObject);
  }

  this.updateDiParent(businessObject.di, parentDi);
};

BpmnUpdater.prototype.updateBounds = function (shape) {
  var di = shape.businessObject.di;
  var target = shape instanceof _model.Label ? this._getLabel(di) : di;
  var bounds = target.bounds;

  if (!bounds) {
    bounds = this._bpmnFactory.createDiBounds();
    target.set('bounds', bounds);
  }

  (0, _minDash.assign)(bounds, {
    x: shape.x,
    y: shape.y,
    width: shape.width,
    height: shape.height
  });
};

BpmnUpdater.prototype.updateFlowNodeRefs = function (businessObject, newContainment, oldContainment) {
  if (oldContainment === newContainment) {
    return;
  }

  var oldRefs, newRefs;

  if ((0, _ModelUtil.is)(oldContainment, 'bpmn:Lane')) {
    oldRefs = oldContainment.get('flowNodeRef');
    (0, _Collections.remove)(oldRefs, businessObject);
  }

  if ((0, _ModelUtil.is)(newContainment, 'bpmn:Lane')) {
    newRefs = newContainment.get('flowNodeRef');
    (0, _Collections.add)(newRefs, businessObject);
  }
}; // update existing sourceElement and targetElement di information


BpmnUpdater.prototype.updateDiConnection = function (di, newSource, newTarget) {
  if (di.sourceElement && di.sourceElement.bpmnElement !== newSource) {
    di.sourceElement = newSource && newSource.di;
  }

  if (di.targetElement && di.targetElement.bpmnElement !== newTarget) {
    di.targetElement = newTarget && newTarget.di;
  }
};

BpmnUpdater.prototype.updateDiParent = function (di, parentDi) {
  if (parentDi && !(0, _ModelUtil.is)(parentDi, 'bpmndi:BPMNPlane')) {
    parentDi = parentDi.$parent;
  }

  if (di.$parent === parentDi) {
    return;
  }

  var planeElements = (parentDi || di.$parent).get('planeElement');

  if (parentDi) {
    planeElements.push(di);
    di.$parent = parentDi;
  } else {
    (0, _Collections.remove)(planeElements, di);
    di.$parent = null;
  }
};

function getDefinitions(element) {
  while (element && !(0, _ModelUtil.is)(element, 'bpmn:Definitions')) {
    element = element.$parent;
  }

  return element;
}

BpmnUpdater.prototype.getLaneSet = function (container) {
  var laneSet, laneSets; // bpmn:Lane

  if ((0, _ModelUtil.is)(container, 'bpmn:Lane')) {
    laneSet = container.childLaneSet;

    if (!laneSet) {
      laneSet = this._bpmnFactory.create('bpmn:LaneSet');
      container.childLaneSet = laneSet;
      laneSet.$parent = container;
    }

    return laneSet;
  } // bpmn:Participant


  if ((0, _ModelUtil.is)(container, 'bpmn:Participant')) {
    container = container.processRef;
  } // bpmn:FlowElementsContainer


  laneSets = container.get('laneSets');
  laneSet = laneSets[0];

  if (!laneSet) {
    laneSet = this._bpmnFactory.create('bpmn:LaneSet');
    laneSet.$parent = container;
    laneSets.push(laneSet);
  }

  return laneSet;
};

BpmnUpdater.prototype.updateSemanticParent = function (businessObject, newParent, visualParent) {
  var containment,
      translate = this._translate;

  if (businessObject.$parent === newParent) {
    return;
  }

  if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInput') || (0, _ModelUtil.is)(businessObject, 'bpmn:DataOutput')) {
    if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant') && 'processRef' in newParent) {
      newParent = newParent.processRef;
    } // already in correct ioSpecification


    if ('ioSpecification' in newParent && newParent.ioSpecification === businessObject.$parent) {
      return;
    }
  }

  if ((0, _ModelUtil.is)(businessObject, 'bpmn:Lane')) {
    if (newParent) {
      newParent = this.getLaneSet(newParent);
    }

    containment = 'lanes';
  } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowElement')) {
    if (newParent) {
      if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant')) {
        newParent = newParent.processRef;
      } else if ((0, _ModelUtil.is)(newParent, 'bpmn:Lane')) {
        do {
          // unwrap Lane -> LaneSet -> (Lane | FlowElementsContainer)
          newParent = newParent.$parent.$parent;
        } while ((0, _ModelUtil.is)(newParent, 'bpmn:Lane'));
      }
    }

    containment = 'flowElements';
  } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:Artifact')) {
    while (newParent && !(0, _ModelUtil.is)(newParent, 'bpmn:Process') && !(0, _ModelUtil.is)(newParent, 'bpmn:SubProcess') && !(0, _ModelUtil.is)(newParent, 'bpmn:Collaboration')) {
      if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant')) {
        newParent = newParent.processRef;
        break;
      } else {
        newParent = newParent.$parent;
      }
    }

    containment = 'artifacts';
  } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:MessageFlow')) {
    containment = 'messageFlows';
  } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:Participant')) {
    containment = 'participants'; // make sure the participants process is properly attached / detached
    // from the XML document

    var process = businessObject.processRef,
        definitions;

    if (process) {
      definitions = getDefinitions(businessObject.$parent || newParent);

      if (businessObject.$parent) {
        (0, _Collections.remove)(definitions.get('rootElements'), process);
        process.$parent = null;
      }

      if (newParent) {
        (0, _Collections.add)(definitions.get('rootElements'), process);
        process.$parent = definitions;
      }
    }
  } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataOutputAssociation')) {
    containment = 'dataOutputAssociations';
  } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInputAssociation')) {
    containment = 'dataInputAssociations';
  }

  if (!containment) {
    throw new Error(translate('no parent for {element} in {parent}', {
      element: businessObject.id,
      parent: newParent.id
    }));
  }

  var children;

  if (businessObject.$parent) {
    // remove from old parent
    children = businessObject.$parent.get(containment);
    (0, _Collections.remove)(children, businessObject);
  }

  if (!newParent) {
    businessObject.$parent = null;
  } else {
    // add to new parent
    children = newParent.get(containment);
    children.push(businessObject);
    businessObject.$parent = newParent;
  }

  if (visualParent) {
    var diChildren = visualParent.get(containment);
    (0, _Collections.remove)(children, businessObject);

    if (newParent) {
      if (!diChildren) {
        diChildren = [];
        newParent.set(containment, diChildren);
      }

      diChildren.push(businessObject);
    }
  }
};

BpmnUpdater.prototype.updateConnectionWaypoints = function (connection) {
  connection.businessObject.di.set('waypoint', this._bpmnFactory.createDiWaypoints(connection.waypoints));
};

BpmnUpdater.prototype.updateConnection = function (context) {
  var connection = context.connection,
      businessObject = (0, _ModelUtil.getBusinessObject)(connection),
      newSource = (0, _ModelUtil.getBusinessObject)(connection.source),
      newTarget = (0, _ModelUtil.getBusinessObject)(connection.target),
      visualParent;

  if (!(0, _ModelUtil.is)(businessObject, 'bpmn:DataAssociation')) {
    var inverseSet = (0, _ModelUtil.is)(businessObject, 'bpmn:SequenceFlow');

    if (businessObject.sourceRef !== newSource) {
      if (inverseSet) {
        (0, _Collections.remove)(businessObject.sourceRef && businessObject.sourceRef.get('outgoing'), businessObject);

        if (newSource && newSource.get('outgoing')) {
          newSource.get('outgoing').push(businessObject);
        }
      }

      businessObject.sourceRef = newSource;
    }

    if (businessObject.targetRef !== newTarget) {
      if (inverseSet) {
        (0, _Collections.remove)(businessObject.targetRef && businessObject.targetRef.get('incoming'), businessObject);

        if (newTarget && newTarget.get('incoming')) {
          newTarget.get('incoming').push(businessObject);
        }
      }

      businessObject.targetRef = newTarget;
    }
  } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInputAssociation')) {
    // handle obnoxious isMsome sourceRef
    businessObject.get('sourceRef')[0] = newSource;
    visualParent = context.parent || context.newParent || newTarget;
    this.updateSemanticParent(businessObject, newTarget, visualParent);
  } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataOutputAssociation')) {
    visualParent = context.parent || context.newParent || newSource;
    this.updateSemanticParent(businessObject, newSource, visualParent); // targetRef = new target

    businessObject.targetRef = newTarget;
  }

  this.updateConnectionWaypoints(connection);
  this.updateDiConnection(businessObject.di, newSource, newTarget);
}; // helpers //////////////////////


BpmnUpdater.prototype._getLabel = function (di) {
  if (!di.label) {
    di.label = this._bpmnFactory.createDiLabel();
  }

  return di.label;
};
/**
 * Make sure the event listener is only called
 * if the touched element is a BPMN element.
 *
 * @param  {Function} fn
 * @return {Function} guarded function
 */


function ifBpmn(fn) {
  return function (event) {
    var context = event.context,
        element = context.shape || context.connection;

    if ((0, _ModelUtil.is)(element, 'bpmn:BaseElement')) {
      fn(event);
    }
  };
}

},{"../../util/ModelUtil":141,"./util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/model":302,"diagram-js/lib/util/Collections":313,"inherits":347,"min-dash":555}],59:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ElementFactory;

var _minDash = require("min-dash");

var _inherits = _interopRequireDefault(require("inherits"));

var _ModelUtil = require("../../util/ModelUtil");

var _DiUtil = require("../../util/DiUtil");

var _ElementFactory = _interopRequireDefault(require("diagram-js/lib/core/ElementFactory"));

var _LabelUtil = require("../../util/LabelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A bpmn-aware factory for diagram-js shapes
 */
function ElementFactory(bpmnFactory, moddle, translate) {
  _ElementFactory.default.call(this);

  this._bpmnFactory = bpmnFactory;
  this._moddle = moddle;
  this._translate = translate;
}

(0, _inherits.default)(ElementFactory, _ElementFactory.default);
ElementFactory.$inject = ['bpmnFactory', 'moddle', 'translate'];
ElementFactory.prototype.baseCreate = _ElementFactory.default.prototype.create;

ElementFactory.prototype.create = function (elementType, attrs) {
  // no special magic for labels,
  // we assume their businessObjects have already been created
  // and wired via attrs
  if (elementType === 'label') {
    return this.baseCreate(elementType, (0, _minDash.assign)({
      type: 'label'
    }, _LabelUtil.DEFAULT_LABEL_SIZE, attrs));
  }

  return this.createBpmnElement(elementType, attrs);
};

ElementFactory.prototype.createBpmnElement = function (elementType, attrs) {
  var size,
      translate = this._translate;
  attrs = attrs || {};
  var businessObject = attrs.businessObject;

  if (!businessObject) {
    if (!attrs.type) {
      throw new Error(translate('no shape type specified'));
    }

    businessObject = this._bpmnFactory.create(attrs.type);
  }

  if (!businessObject.di) {
    if (elementType === 'root') {
      businessObject.di = this._bpmnFactory.createDiPlane(businessObject, [], {
        id: businessObject.id + '_di'
      });
    } else if (elementType === 'connection') {
      businessObject.di = this._bpmnFactory.createDiEdge(businessObject, [], {
        id: businessObject.id + '_di'
      });
    } else {
      businessObject.di = this._bpmnFactory.createDiShape(businessObject, {}, {
        id: businessObject.id + '_di'
      });
    }
  }

  if ((0, _ModelUtil.is)(businessObject, 'bpmn:Group')) {
    attrs = (0, _minDash.assign)({
      isFrame: true
    }, attrs);
  }

  if (attrs.di) {
    (0, _minDash.assign)(businessObject.di, attrs.di);
    delete attrs.di;
  }

  applyAttributes(businessObject, attrs, ['processRef', 'isInterrupting', 'associationDirection', 'isForCompensation']);

  if (attrs.isExpanded) {
    applyAttribute(businessObject.di, attrs, 'isExpanded');
  }

  if ((0, _ModelUtil.is)(businessObject, 'bpmn:ExclusiveGateway')) {
    businessObject.di.isMarkerVisible = true;
  }

  var eventDefinitions, newEventDefinition;

  if (attrs.eventDefinitionType) {
    eventDefinitions = businessObject.get('eventDefinitions') || [];
    newEventDefinition = this._bpmnFactory.create(attrs.eventDefinitionType, attrs.eventDefinitionAttrs);

    if (attrs.eventDefinitionType === 'bpmn:ConditionalEventDefinition') {
      newEventDefinition.condition = this._bpmnFactory.create('bpmn:FormalExpression');
    }

    eventDefinitions.push(newEventDefinition);
    newEventDefinition.$parent = businessObject;
    businessObject.eventDefinitions = eventDefinitions;
    delete attrs.eventDefinitionType;
  }

  size = this._getDefaultSize(businessObject);
  attrs = (0, _minDash.assign)({
    businessObject: businessObject,
    id: businessObject.id
  }, size, attrs);
  return this.baseCreate(elementType, attrs);
};

ElementFactory.prototype._getDefaultSize = function (semantic) {
  if ((0, _ModelUtil.is)(semantic, 'bpmn:SubProcess')) {
    if ((0, _DiUtil.isExpanded)(semantic)) {
      return {
        width: 350,
        height: 200
      };
    } else {
      return {
        width: 100,
        height: 80
      };
    }
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:Task')) {
    return {
      width: 100,
      height: 80
    };
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:Gateway')) {
    return {
      width: 50,
      height: 50
    };
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:Event')) {
    return {
      width: 36,
      height: 36
    };
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:Participant')) {
    if ((0, _DiUtil.isExpanded)(semantic)) {
      return {
        width: 600,
        height: 250
      };
    } else {
      return {
        width: 400,
        height: 60
      };
    }
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:Lane')) {
    return {
      width: 400,
      height: 100
    };
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:DataObjectReference')) {
    return {
      width: 36,
      height: 50
    };
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference')) {
    return {
      width: 50,
      height: 50
    };
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:TextAnnotation')) {
    return {
      width: 100,
      height: 30
    };
  }

  if ((0, _ModelUtil.is)(semantic, 'bpmn:Group')) {
    return {
      width: 300,
      height: 300
    };
  }

  return {
    width: 100,
    height: 80
  };
};
/**
 * Create participant.
 *
 * @param {boolean|Object} [attrs] attrs
 *
 * @returns {djs.model.Shape}
 */


ElementFactory.prototype.createParticipantShape = function (attrs) {
  if (!(0, _minDash.isObject)(attrs)) {
    attrs = {
      isExpanded: attrs
    };
  }

  attrs = (0, _minDash.assign)({
    type: 'bpmn:Participant'
  }, attrs || {}); // participants are expanded by default

  if (attrs.isExpanded !== false) {
    attrs.processRef = this._bpmnFactory.create('bpmn:Process');
  }

  return this.createShape(attrs);
}; // helpers //////////////////////

/**
 * Apply attributes from a map to the given element,
 * remove attribute from the map on application.
 *
 * @param {Base} element
 * @param {Object} attrs (in/out map of attributes)
 * @param {Array<string>} attributeNames name of attributes to apply
 */


function applyAttributes(element, attrs, attributeNames) {
  (0, _minDash.forEach)(attributeNames, function (property) {
    if (attrs[property] !== undefined) {
      applyAttribute(element, attrs, property);
    }
  });
}
/**
 * Apply named property to element and drain it from the attrs
 * collection.
 *
 * @param {Base} element
 * @param {Object} attrs (in/out map of attributes)
 * @param {string} attributeName to apply
 */


function applyAttribute(element, attrs, attributeName) {
  element[attributeName] = attrs[attributeName];
  delete attrs[attributeName];
}

},{"../../util/DiUtil":139,"../../util/LabelUtil":140,"../../util/ModelUtil":141,"diagram-js/lib/core/ElementFactory":149,"inherits":347,"min-dash":555}],60:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Modeling;

var _inherits = _interopRequireDefault(require("inherits"));

var _Modeling = _interopRequireDefault(require("diagram-js/lib/features/modeling/Modeling"));

var _UpdatePropertiesHandler = _interopRequireDefault(require("./cmd/UpdatePropertiesHandler"));

var _UpdateCanvasRootHandler = _interopRequireDefault(require("./cmd/UpdateCanvasRootHandler"));

var _AddLaneHandler = _interopRequireDefault(require("./cmd/AddLaneHandler"));

var _SplitLaneHandler = _interopRequireDefault(require("./cmd/SplitLaneHandler"));

var _ResizeLaneHandler = _interopRequireDefault(require("./cmd/ResizeLaneHandler"));

var _UpdateFlowNodeRefsHandler = _interopRequireDefault(require("./cmd/UpdateFlowNodeRefsHandler"));

var _IdClaimHandler = _interopRequireDefault(require("./cmd/IdClaimHandler"));

var _SetColorHandler = _interopRequireDefault(require("./cmd/SetColorHandler"));

var _UpdateLabelHandler = _interopRequireDefault(require("../label-editing/cmd/UpdateLabelHandler"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * BPMN 2.0 modeling features activator
 *
 * @param {EventBus} eventBus
 * @param {ElementFactory} elementFactory
 * @param {CommandStack} commandStack
 * @param {BpmnRules} bpmnRules
 */
function Modeling(eventBus, elementFactory, commandStack, bpmnRules) {
  _Modeling.default.call(this, eventBus, elementFactory, commandStack);

  this._bpmnRules = bpmnRules;
}

(0, _inherits.default)(Modeling, _Modeling.default);
Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack', 'bpmnRules'];

Modeling.prototype.getHandlers = function () {
  var handlers = _Modeling.default.prototype.getHandlers.call(this);

  handlers['element.updateProperties'] = _UpdatePropertiesHandler.default;
  handlers['canvas.updateRoot'] = _UpdateCanvasRootHandler.default;
  handlers['lane.add'] = _AddLaneHandler.default;
  handlers['lane.resize'] = _ResizeLaneHandler.default;
  handlers['lane.split'] = _SplitLaneHandler.default;
  handlers['lane.updateRefs'] = _UpdateFlowNodeRefsHandler.default;
  handlers['id.updateClaim'] = _IdClaimHandler.default;
  handlers['element.setColor'] = _SetColorHandler.default;
  handlers['element.updateLabel'] = _UpdateLabelHandler.default;
  return handlers;
};

Modeling.prototype.updateLabel = function (element, newLabel, newBounds, hints) {
  this._commandStack.execute('element.updateLabel', {
    element: element,
    newLabel: newLabel,
    newBounds: newBounds,
    hints: hints || {}
  });
};

Modeling.prototype.connect = function (source, target, attrs, hints) {
  var bpmnRules = this._bpmnRules;

  if (!attrs) {
    attrs = bpmnRules.canConnect(source, target);
  }

  if (!attrs) {
    return;
  }

  return this.createConnection(source, target, attrs, source.parent, hints);
};

Modeling.prototype.updateProperties = function (element, properties) {
  this._commandStack.execute('element.updateProperties', {
    element: element,
    properties: properties
  });
};

Modeling.prototype.resizeLane = function (laneShape, newBounds, balanced) {
  this._commandStack.execute('lane.resize', {
    shape: laneShape,
    newBounds: newBounds,
    balanced: balanced
  });
};

Modeling.prototype.addLane = function (targetLaneShape, location) {
  var context = {
    shape: targetLaneShape,
    location: location
  };

  this._commandStack.execute('lane.add', context);

  return context.newLane;
};

Modeling.prototype.splitLane = function (targetLane, count) {
  this._commandStack.execute('lane.split', {
    shape: targetLane,
    count: count
  });
};
/**
 * Transform the current diagram into a collaboration.
 *
 * @return {djs.model.Root} the new root element
 */


Modeling.prototype.makeCollaboration = function () {
  var collaborationElement = this._create('root', {
    type: 'bpmn:Collaboration'
  });

  var context = {
    newRoot: collaborationElement
  };

  this._commandStack.execute('canvas.updateRoot', context);

  return collaborationElement;
};

Modeling.prototype.updateLaneRefs = function (flowNodeShapes, laneShapes) {
  this._commandStack.execute('lane.updateRefs', {
    flowNodeShapes: flowNodeShapes,
    laneShapes: laneShapes
  });
};
/**
 * Transform the current diagram into a process.
 *
 * @return {djs.model.Root} the new root element
 */


Modeling.prototype.makeProcess = function () {
  var processElement = this._create('root', {
    type: 'bpmn:Process'
  });

  var context = {
    newRoot: processElement
  };

  this._commandStack.execute('canvas.updateRoot', context);
};

Modeling.prototype.claimId = function (id, moddleElement) {
  this._commandStack.execute('id.updateClaim', {
    id: id,
    element: moddleElement,
    claiming: true
  });
};

Modeling.prototype.unclaimId = function (id, moddleElement) {
  this._commandStack.execute('id.updateClaim', {
    id: id,
    element: moddleElement
  });
};

Modeling.prototype.setColor = function (elements, colors) {
  if (!elements.length) {
    elements = [elements];
  }

  this._commandStack.execute('element.setColor', {
    elements: elements,
    colors: colors
  });
};

},{"../label-editing/cmd/UpdateLabelHandler":54,"./cmd/AddLaneHandler":101,"./cmd/IdClaimHandler":102,"./cmd/ResizeLaneHandler":103,"./cmd/SetColorHandler":104,"./cmd/SplitLaneHandler":105,"./cmd/UpdateCanvasRootHandler":106,"./cmd/UpdateFlowNodeRefsHandler":107,"./cmd/UpdatePropertiesHandler":108,"diagram-js/lib/features/modeling/Modeling":222,"inherits":347}],61:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AdaptiveLabelPositioningBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _Math = require("diagram-js/lib/util/Math");

var _LabelUtil = require("../../../util/LabelUtil");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var ALIGNMENTS = ['top', 'bottom', 'left', 'right'];
var ELEMENT_LABEL_DISTANCE = 10;
/**
 * A component that makes sure that external labels are added
 * together with respective elements and properly updated (DI wise)
 * during move.
 *
 * @param {EventBus} eventBus
 * @param {Modeling} modeling
 */

function AdaptiveLabelPositioningBehavior(eventBus, modeling) {
  _CommandInterceptor.default.call(this, eventBus);

  this.postExecuted(['connection.create', 'connection.layout', 'connection.updateWaypoints'], function (event) {
    var context = event.context,
        connection = context.connection,
        source = connection.source,
        target = connection.target,
        hints = context.hints || {};

    if (hints.createElementsBehavior !== false) {
      checkLabelAdjustment(source);
      checkLabelAdjustment(target);
    }
  });
  this.postExecuted(['label.create'], function (event) {
    var context = event.context,
        shape = context.shape,
        hints = context.hints || {};

    if (hints.createElementsBehavior !== false) {
      checkLabelAdjustment(shape.labelTarget);
    }
  });
  this.postExecuted(['elements.create'], function (event) {
    var context = event.context,
        elements = context.elements,
        hints = context.hints || {};

    if (hints.createElementsBehavior !== false) {
      elements.forEach(function (element) {
        checkLabelAdjustment(element);
      });
    }
  });

  function checkLabelAdjustment(element) {
    // skip non-existing labels
    if (!(0, _LabelUtil.hasExternalLabel)(element)) {
      return;
    }

    var optimalPosition = getOptimalPosition(element); // no optimal position found

    if (!optimalPosition) {
      return;
    }

    adjustLabelPosition(element, optimalPosition);
  }

  function adjustLabelPosition(element, orientation) {
    var elementMid = (0, _LayoutUtil.getMid)(element),
        label = element.label,
        labelMid = (0, _LayoutUtil.getMid)(label); // ignore labels that are being created

    if (!label.parent) {
      return;
    }

    var elementTrbl = (0, _LayoutUtil.asTRBL)(element);
    var newLabelMid;

    switch (orientation) {
      case 'top':
        newLabelMid = {
          x: elementMid.x,
          y: elementTrbl.top - ELEMENT_LABEL_DISTANCE - label.height / 2
        };
        break;

      case 'left':
        newLabelMid = {
          x: elementTrbl.left - ELEMENT_LABEL_DISTANCE - label.width / 2,
          y: elementMid.y
        };
        break;

      case 'bottom':
        newLabelMid = {
          x: elementMid.x,
          y: elementTrbl.bottom + ELEMENT_LABEL_DISTANCE + label.height / 2
        };
        break;

      case 'right':
        newLabelMid = {
          x: elementTrbl.right + ELEMENT_LABEL_DISTANCE + label.width / 2,
          y: elementMid.y
        };
        break;
    }

    var delta = (0, _Math.substract)(newLabelMid, labelMid);
    modeling.moveShape(label, delta);
  }
}

(0, _inherits.default)(AdaptiveLabelPositioningBehavior, _CommandInterceptor.default);
AdaptiveLabelPositioningBehavior.$inject = ['eventBus', 'modeling']; // helpers //////////////////////

/**
 * Return alignments which are taken by a boundary's host element
 *
 * @param {Shape} element
 *
 * @return {Array<string>}
 */

function getTakenHostAlignments(element) {
  var hostElement = element.host,
      elementMid = (0, _LayoutUtil.getMid)(element),
      hostOrientation = (0, _LayoutUtil.getOrientation)(elementMid, hostElement);
  var freeAlignments; // check whether there is a multi-orientation, e.g. 'top-left'

  if (hostOrientation.indexOf('-') >= 0) {
    freeAlignments = hostOrientation.split('-');
  } else {
    freeAlignments = [hostOrientation];
  }

  var takenAlignments = ALIGNMENTS.filter(function (alignment) {
    return freeAlignments.indexOf(alignment) === -1;
  });
  return takenAlignments;
}
/**
 * Return alignments which are taken by related connections
 *
 * @param {Shape} element
 *
 * @return {Array<string>}
 */


function getTakenConnectionAlignments(element) {
  var elementMid = (0, _LayoutUtil.getMid)(element);
  var takenAlignments = [].concat(element.incoming.map(function (c) {
    return c.waypoints[c.waypoints.length - 2];
  }), element.outgoing.map(function (c) {
    return c.waypoints[1];
  })).map(function (point) {
    return getApproximateOrientation(elementMid, point);
  });
  return takenAlignments;
}
/**
 * Return the optimal label position around an element
 * or _undefined_, if none was found.
 *
 * @param  {Shape} element
 *
 * @return {string} positioning identifier
 */


function getOptimalPosition(element) {
  var labelMid = (0, _LayoutUtil.getMid)(element.label);
  var elementMid = (0, _LayoutUtil.getMid)(element);
  var labelOrientation = getApproximateOrientation(elementMid, labelMid);

  if (!isAligned(labelOrientation)) {
    return;
  }

  var takenAlignments = getTakenConnectionAlignments(element);

  if (element.host) {
    var takenHostAlignments = getTakenHostAlignments(element);
    takenAlignments = takenAlignments.concat(takenHostAlignments);
  }

  var freeAlignments = ALIGNMENTS.filter(function (alignment) {
    return takenAlignments.indexOf(alignment) === -1;
  }); // NOTHING TO DO; label already aligned a.O.K.

  if (freeAlignments.indexOf(labelOrientation) !== -1) {
    return;
  }

  return freeAlignments[0];
}

function getApproximateOrientation(p0, p1) {
  return (0, _LayoutUtil.getOrientation)(p1, p0, 5);
}

function isAligned(orientation) {
  return ALIGNMENTS.indexOf(orientation) !== -1;
}

},{"../../../util/LabelUtil":140,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Math":322,"inherits":347}],62:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AppendBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _ModelUtil = require("../../../util/ModelUtil");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function AppendBehavior(eventBus, elementFactory, bpmnRules) {
  _CommandInterceptor.default.call(this, eventBus); // assign correct shape position unless already set


  this.preExecute('shape.append', function (context) {
    var source = context.source,
        shape = context.shape;

    if (!context.position) {
      if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) {
        context.position = {
          x: source.x + source.width / 2 + 75,
          y: source.y - 50 - shape.height / 2
        };
      } else {
        context.position = {
          x: source.x + source.width + 80 + shape.width / 2,
          y: source.y + source.height / 2
        };
      }
    }
  }, true);
}

(0, _inherits.default)(AppendBehavior, _CommandInterceptor.default);
AppendBehavior.$inject = ['eventBus', 'elementFactory', 'bpmnRules'];

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],63:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AssociationBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _ModelUtil = require("../../../util/ModelUtil");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _minDash = require("min-dash");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function AssociationBehavior(injector, modeling) {
  injector.invoke(_CommandInterceptor.default, this);
  this.postExecute('shape.move', function (context) {
    var newParent = context.newParent,
        shape = context.shape;
    var associations = (0, _minDash.filter)(shape.incoming.concat(shape.outgoing), function (connection) {
      return (0, _ModelUtil.is)(connection, 'bpmn:Association');
    });
    (0, _minDash.forEach)(associations, function (association) {
      modeling.moveConnection(association, {
        x: 0,
        y: 0
      }, newParent);
    });
  }, true);
}

(0, _inherits.default)(AssociationBehavior, _CommandInterceptor.default);
AssociationBehavior.$inject = ['injector', 'modeling'];

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],64:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AttachEventBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _ModelingUtil = require("../util/ModelingUtil");

var _LabelUtil = require("../../../util/LabelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LOW_PRIORITY = 500;
/**
 * Replace intermediate event with boundary event when creating or moving results in attached event.
 */

function AttachEventBehavior(bpmnReplace, injector) {
  injector.invoke(_CommandInterceptor.default, this);
  this._bpmnReplace = bpmnReplace;
  var self = this;
  this.postExecuted('elements.create', LOW_PRIORITY, function (context) {
    var elements = context.elements;
    elements = elements.filter(function (shape) {
      var host = shape.host;
      return shouldReplace(shape, host);
    });

    if (elements.length !== 1) {
      return;
    }

    elements.map(function (element) {
      return elements.indexOf(element);
    }).forEach(function (index) {
      var host = elements[index];
      context.elements[index] = self.replaceShape(elements[index], host);
    });
  }, true);
  this.preExecute('elements.move', LOW_PRIORITY, function (context) {
    var shapes = context.shapes,
        host = context.newHost;

    if (shapes.length !== 1) {
      return;
    }

    var shape = shapes[0];

    if (shouldReplace(shape, host)) {
      context.shapes = [self.replaceShape(shape, host)];
    }
  }, true);
}

AttachEventBehavior.$inject = ['bpmnReplace', 'injector'];
(0, _inherits.default)(AttachEventBehavior, _CommandInterceptor.default);

AttachEventBehavior.prototype.replaceShape = function (shape, host) {
  var eventDefinition = getEventDefinition(shape);
  var boundaryEvent = {
    type: 'bpmn:BoundaryEvent',
    host: host
  };

  if (eventDefinition) {
    boundaryEvent.eventDefinitionType = eventDefinition.$type;
  }

  return this._bpmnReplace.replaceElement(shape, boundaryEvent, {
    layoutConnection: false
  });
}; // helpers //////////


function getEventDefinition(element) {
  var businessObject = (0, _ModelUtil.getBusinessObject)(element),
      eventDefinitions = businessObject.eventDefinitions;
  return eventDefinitions && eventDefinitions[0];
}

function shouldReplace(shape, host) {
  return !(0, _LabelUtil.isLabel)(shape) && (0, _ModelingUtil.isAny)(shape, ['bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent']) && !!host;
}

},{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],65:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BoundaryEventBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _minDash = require("min-dash");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * BPMN specific boundary event behavior
 */
function BoundaryEventBehavior(eventBus, modeling) {
  _CommandInterceptor.default.call(this, eventBus);

  function getBoundaryEvents(element) {
    return (0, _minDash.filter)(element.attachers, function (attacher) {
      return (0, _ModelUtil.is)(attacher, 'bpmn:BoundaryEvent');
    });
  } // remove after connecting to event-based gateway


  this.postExecute('connection.create', function (event) {
    var source = event.context.source,
        target = event.context.target,
        boundaryEvents = getBoundaryEvents(target);

    if ((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && (0, _ModelUtil.is)(target, 'bpmn:ReceiveTask') && boundaryEvents.length > 0) {
      modeling.removeElements(boundaryEvents);
    }
  }); // remove after replacing connected gateway with event-based gateway

  this.postExecute('connection.reconnect', function (event) {
    var oldSource = event.context.oldSource,
        newSource = event.context.newSource;

    if ((0, _ModelUtil.is)(oldSource, 'bpmn:Gateway') && (0, _ModelUtil.is)(newSource, 'bpmn:EventBasedGateway')) {
      (0, _minDash.forEach)(newSource.outgoing, function (connection) {
        var target = connection.target,
            attachedboundaryEvents = getBoundaryEvents(target);

        if ((0, _ModelUtil.is)(target, 'bpmn:ReceiveTask') && attachedboundaryEvents.length > 0) {
          modeling.removeElements(attachedboundaryEvents);
        }
      });
    }
  });
}

BoundaryEventBehavior.$inject = ['eventBus', 'modeling'];
(0, _inherits.default)(BoundaryEventBehavior, _CommandInterceptor.default);

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],66:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreateBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _ModelUtil = require("../../../util/ModelUtil");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelingUtil = require("../util/ModelingUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function CreateBehavior(injector) {
  injector.invoke(_CommandInterceptor.default, this);
  this.preExecute('shape.create', 1500, function (event) {
    var context = event.context,
        parent = context.parent,
        shape = context.shape;

    if ((0, _ModelUtil.is)(parent, 'bpmn:Lane') && !(0, _ModelUtil.is)(shape, 'bpmn:Lane')) {
      context.parent = (0, _ModelingUtil.getParent)(parent, 'bpmn:Participant');
    }
  });
}

CreateBehavior.$inject = ['injector'];
(0, _inherits.default)(CreateBehavior, _CommandInterceptor.default);

},{"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],67:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreateDataObjectBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * BPMN specific create data object behavior
 */
function CreateDataObjectBehavior(eventBus, bpmnFactory, moddle) {
  _CommandInterceptor.default.call(this, eventBus);

  this.preExecute('shape.create', function (event) {
    var context = event.context,
        shape = context.shape;

    if ((0, _ModelUtil.is)(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') {
      // create a DataObject every time a DataObjectReference is created
      var dataObject = bpmnFactory.create('bpmn:DataObject'); // set the reference to the DataObject

      shape.businessObject.dataObjectRef = dataObject;
    }
  });
}

CreateDataObjectBehavior.$inject = ['eventBus', 'bpmnFactory', 'moddle'];
(0, _inherits.default)(CreateDataObjectBehavior, _CommandInterceptor.default);

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],68:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreateParticipantBehavior;
exports.PARTICIPANT_BORDER_WIDTH = void 0;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _LabelUtil = require("../../../util/LabelUtil");

var _Elements = require("diagram-js/lib/util/Elements");

var _minDash = require("min-dash");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var HORIZONTAL_PARTICIPANT_PADDING = 20,
    VERTICAL_PARTICIPANT_PADDING = 20;
var PARTICIPANT_BORDER_WIDTH = 30;
exports.PARTICIPANT_BORDER_WIDTH = PARTICIPANT_BORDER_WIDTH;
var HIGH_PRIORITY = 2000;
/**
 * BPMN-specific behavior for creating participants.
 */

function CreateParticipantBehavior(canvas, eventBus, modeling) {
  _CommandInterceptor.default.call(this, eventBus); // fit participant


  eventBus.on(['create.start', 'shape.move.start'], HIGH_PRIORITY, function (event) {
    var context = event.context,
        shape = context.shape,
        rootElement = canvas.getRootElement();

    if (!(0, _ModelUtil.is)(shape, 'bpmn:Participant') || !(0, _ModelUtil.is)(rootElement, 'bpmn:Process') || !rootElement.children.length) {
      return;
    } // ignore connections, groups and labels


    var children = rootElement.children.filter(function (element) {
      return !(0, _ModelUtil.is)(element, 'bpmn:Group') && !(0, _LabelUtil.isLabel)(element) && !isConnection(element);
    }); // ensure for available children to calculate bounds

    if (!children.length) {
      return;
    }

    var childrenBBox = (0, _Elements.getBBox)(children);
    var participantBounds = getParticipantBounds(shape, childrenBBox); // assign width and height

    (0, _minDash.assign)(shape, participantBounds); // assign create constraints

    context.createConstraints = getParticipantCreateConstraints(shape, childrenBBox);
  }); // force hovering process when creating first participant

  eventBus.on('create.start', HIGH_PRIORITY, function (event) {
    var context = event.context,
        shape = context.shape,
        rootElement = canvas.getRootElement(),
        rootElementGfx = canvas.getGraphics(rootElement);

    function ensureHoveringProcess(event) {
      event.element = rootElement;
      event.gfx = rootElementGfx;
    }

    if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(rootElement, 'bpmn:Process')) {
      eventBus.on('element.hover', HIGH_PRIORITY, ensureHoveringProcess);
      eventBus.once('create.cleanup', function () {
        eventBus.off('element.hover', ensureHoveringProcess);
      });
    }
  });

  function ensureCollaboration(context) {
    var parent = context.parent,
        collaboration;
    var rootElement = canvas.getRootElement();

    if ((0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) {
      collaboration = rootElement;
    } else {
      // update root element by making collaboration
      collaboration = modeling.makeCollaboration(); // re-use process when creating first participant

      context.process = parent;
    }

    context.parent = collaboration;
  } // turn process into collaboration before adding participant


  this.preExecute('shape.create', function (context) {
    var parent = context.parent,
        shape = context.shape;

    if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(parent, 'bpmn:Process')) {
      ensureCollaboration(context);
    }
  }, true);
  this.execute('shape.create', function (context) {
    var process = context.process,
        shape = context.shape;

    if (process) {
      context.oldProcessRef = shape.businessObject.processRef; // re-use process when creating first participant

      shape.businessObject.processRef = process.businessObject;
    }
  }, true);
  this.revert('shape.create', function (context) {
    var process = context.process,
        shape = context.shape;

    if (process) {
      // re-use process when creating first participant
      shape.businessObject.processRef = context.oldProcessRef;
    }
  }, true);
  this.postExecute('shape.create', function (context) {
    var process = context.process,
        shape = context.shape;

    if (process) {
      // move children from process to participant
      var processChildren = process.children.slice();
      modeling.moveElements(processChildren, {
        x: 0,
        y: 0
      }, shape);
    }
  }, true); // turn process into collaboration when creating participants

  this.preExecute('elements.create', HIGH_PRIORITY, function (context) {
    var elements = context.elements,
        parent = context.parent,
        participant;
    var hasParticipants = findParticipant(elements);

    if (hasParticipants && (0, _ModelUtil.is)(parent, 'bpmn:Process')) {
      ensureCollaboration(context);
      participant = findParticipant(elements);
      context.oldProcessRef = participant.businessObject.processRef; // re-use process when creating first participant

      participant.businessObject.processRef = parent.businessObject;
    }
  }, true);
  this.revert('elements.create', function (context) {
    var elements = context.elements,
        process = context.process,
        participant;

    if (process) {
      participant = findParticipant(elements); // re-use process when creating first participant

      participant.businessObject.processRef = context.oldProcessRef;
    }
  }, true);
  this.postExecute('elements.create', function (context) {
    var elements = context.elements,
        process = context.process,
        participant;

    if (process) {
      participant = findParticipant(elements); // move children from process to first participant

      var processChildren = process.children.slice();
      modeling.moveElements(processChildren, {
        x: 0,
        y: 0
      }, participant);
    }
  }, true);
}

CreateParticipantBehavior.$inject = ['canvas', 'eventBus', 'modeling'];
(0, _inherits.default)(CreateParticipantBehavior, _CommandInterceptor.default); // helpers //////////

function getParticipantBounds(shape, childrenBBox) {
  childrenBBox = {
    width: childrenBBox.width + HORIZONTAL_PARTICIPANT_PADDING * 2 + PARTICIPANT_BORDER_WIDTH,
    height: childrenBBox.height + VERTICAL_PARTICIPANT_PADDING * 2
  };
  var width = Math.max(shape.width, childrenBBox.width),
      height = Math.max(shape.height, childrenBBox.height);
  return {
    x: -width / 2,
    y: -height / 2,
    width: width,
    height: height
  };
}

function getParticipantCreateConstraints(shape, childrenBBox) {
  childrenBBox = (0, _LayoutUtil.asTRBL)(childrenBBox);
  return {
    bottom: childrenBBox.top + shape.height / 2 - VERTICAL_PARTICIPANT_PADDING,
    left: childrenBBox.right - shape.width / 2 + HORIZONTAL_PARTICIPANT_PADDING,
    top: childrenBBox.bottom - shape.height / 2 + VERTICAL_PARTICIPANT_PADDING,
    right: childrenBBox.left + shape.width / 2 - HORIZONTAL_PARTICIPANT_PADDING - PARTICIPANT_BORDER_WIDTH
  };
}

function isConnection(element) {
  return !!element.waypoints;
}

function findParticipant(elements) {
  return (0, _minDash.find)(elements, function (element) {
    return (0, _ModelUtil.is)(element, 'bpmn:Participant');
  });
}

},{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Elements":315,"inherits":347,"min-dash":555}],69:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DataInputAssociationBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _Collections = require("diagram-js/lib/util/Collections");

var _minDash = require("min-dash");

var _ModelUtil = require("../../../util/ModelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var TARGET_REF_PLACEHOLDER_NAME = '__targetRef_placeholder';
/**
 * This behavior makes sure we always set a fake
 * DataInputAssociation#targetRef as demanded by the BPMN 2.0
 * XSD schema.
 *
 * The reference is set to a bpmn:Property{ name: '__targetRef_placeholder' }
 * which is created on the fly and cleaned up afterwards if not needed
 * anymore.
 *
 * @param {EventBus} eventBus
 * @param {BpmnFactory} bpmnFactory
 */

function DataInputAssociationBehavior(eventBus, bpmnFactory) {
  _CommandInterceptor.default.call(this, eventBus);

  this.executed(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnect'], ifDataInputAssociation(fixTargetRef));
  this.reverted(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnect'], ifDataInputAssociation(fixTargetRef));

  function usesTargetRef(element, targetRef, removedConnection) {
    var inputAssociations = element.get('dataInputAssociations');
    return (0, _minDash.find)(inputAssociations, function (association) {
      return association !== removedConnection && association.targetRef === targetRef;
    });
  }

  function getTargetRef(element, create) {
    var properties = element.get('properties');
    var targetRefProp = (0, _minDash.find)(properties, function (p) {
      return p.name === TARGET_REF_PLACEHOLDER_NAME;
    });

    if (!targetRefProp && create) {
      targetRefProp = bpmnFactory.create('bpmn:Property', {
        name: TARGET_REF_PLACEHOLDER_NAME
      });
      (0, _Collections.add)(properties, targetRefProp);
    }

    return targetRefProp;
  }

  function cleanupTargetRef(element, connection) {
    var targetRefProp = getTargetRef(element);

    if (!targetRefProp) {
      return;
    }

    if (!usesTargetRef(element, targetRefProp, connection)) {
      (0, _Collections.remove)(element.get('properties'), targetRefProp);
    }
  }
  /**
   * Make sure targetRef is set to a valid property or
   * `null` if the connection is detached.
   *
   * @param {Event} event
   */


  function fixTargetRef(event) {
    var context = event.context,
        connection = context.connection,
        connectionBo = connection.businessObject,
        target = connection.target,
        targetBo = target && target.businessObject,
        newTarget = context.newTarget,
        newTargetBo = newTarget && newTarget.businessObject,
        oldTarget = context.oldTarget || context.target,
        oldTargetBo = oldTarget && oldTarget.businessObject;
    var dataAssociation = connection.businessObject,
        targetRefProp;

    if (oldTargetBo && oldTargetBo !== targetBo) {
      cleanupTargetRef(oldTargetBo, connectionBo);
    }

    if (newTargetBo && newTargetBo !== targetBo) {
      cleanupTargetRef(newTargetBo, connectionBo);
    }

    if (targetBo) {
      targetRefProp = getTargetRef(targetBo, true);
      dataAssociation.targetRef = targetRefProp;
    } else {
      dataAssociation.targetRef = null;
    }
  }
}

DataInputAssociationBehavior.$inject = ['eventBus', 'bpmnFactory'];
(0, _inherits.default)(DataInputAssociationBehavior, _CommandInterceptor.default);
/**
 * Only call the given function when the event
 * touches a bpmn:DataInputAssociation.
 *
 * @param {Function} fn
 * @return {Function}
 */

function ifDataInputAssociation(fn) {
  return function (event) {
    var context = event.context,
        connection = context.connection;

    if ((0, _ModelUtil.is)(connection, 'bpmn:DataInputAssociation')) {
      return fn(event);
    }
  };
}

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Collections":313,"inherits":347,"min-dash":555}],70:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DataStoreBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _ModelingUtil = require("../util/ModelingUtil");

var _UpdateSemanticParentHandler = _interopRequireDefault(require("../cmd/UpdateSemanticParentHandler"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * BPMN specific data store behavior
 */
function DataStoreBehavior(canvas, commandStack, elementRegistry, eventBus) {
  _CommandInterceptor.default.call(this, eventBus);

  commandStack.registerHandler('dataStore.updateContainment', _UpdateSemanticParentHandler.default);

  function getFirstParticipant() {
    return elementRegistry.filter(function (element) {
      return (0, _ModelUtil.is)(element, 'bpmn:Participant');
    })[0];
  }

  function getDataStores(element) {
    return element.children.filter(function (child) {
      return (0, _ModelUtil.is)(child, 'bpmn:DataStoreReference') && !child.labelTarget;
    });
  }

  function updateDataStoreParent(dataStore, newDataStoreParent) {
    var dataStoreBo = dataStore.businessObject || dataStore;
    newDataStoreParent = newDataStoreParent || getFirstParticipant();

    if (newDataStoreParent) {
      var newDataStoreParentBo = newDataStoreParent.businessObject || newDataStoreParent;
      commandStack.execute('dataStore.updateContainment', {
        dataStoreBo: dataStoreBo,
        newSemanticParent: newDataStoreParentBo.processRef || newDataStoreParentBo,
        newDiParent: newDataStoreParentBo.di
      });
    }
  } // disable auto-resize for data stores


  this.preExecute('shape.create', function (event) {
    var context = event.context,
        shape = context.shape;

    if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label') {
      if (!context.hints) {
        context.hints = {};
      } // prevent auto resizing


      context.hints.autoResize = false;
    }
  }); // disable auto-resize for data stores

  this.preExecute('elements.move', function (event) {
    var context = event.context,
        shapes = context.shapes;
    var dataStoreReferences = shapes.filter(function (shape) {
      return (0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference');
    });

    if (dataStoreReferences.length) {
      if (!context.hints) {
        context.hints = {};
      } // prevent auto resizing for data store references


      context.hints.autoResize = shapes.filter(function (shape) {
        return !(0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference');
      });
    }
  }); // update parent on data store created

  this.postExecute('shape.create', function (event) {
    var context = event.context,
        shape = context.shape,
        parent = shape.parent;

    if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label' && (0, _ModelUtil.is)(parent, 'bpmn:Collaboration')) {
      updateDataStoreParent(shape);
    }
  }); // update parent on data store moved

  this.postExecute('shape.move', function (event) {
    var context = event.context,
        shape = context.shape,
        oldParent = context.oldParent,
        parent = shape.parent;

    if ((0, _ModelUtil.is)(oldParent, 'bpmn:Collaboration')) {
      // do nothing if not necessary
      return;
    }

    if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label' && (0, _ModelUtil.is)(parent, 'bpmn:Collaboration')) {
      var participant = (0, _ModelUtil.is)(oldParent, 'bpmn:Participant') ? oldParent : getAncestor(oldParent, 'bpmn:Participant');
      updateDataStoreParent(shape, participant);
    }
  }); // update data store parents on participant or subprocess deleted

  this.postExecute('shape.delete', function (event) {
    var context = event.context,
        shape = context.shape,
        rootElement = canvas.getRootElement();

    if ((0, _ModelingUtil.isAny)(shape, ['bpmn:Participant', 'bpmn:SubProcess']) && (0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) {
      getDataStores(rootElement).filter(function (dataStore) {
        return isDescendant(dataStore, shape);
      }).forEach(function (dataStore) {
        updateDataStoreParent(dataStore);
      });
    }
  }); // update data store parents on collaboration -> process

  this.postExecute('canvas.updateRoot', function (event) {
    var context = event.context,
        oldRoot = context.oldRoot,
        newRoot = context.newRoot;
    var dataStores = getDataStores(oldRoot);
    dataStores.forEach(function (dataStore) {
      if ((0, _ModelUtil.is)(newRoot, 'bpmn:Process')) {
        updateDataStoreParent(dataStore, newRoot);
      }
    });
  });
}

DataStoreBehavior.$inject = ['canvas', 'commandStack', 'elementRegistry', 'eventBus'];
(0, _inherits.default)(DataStoreBehavior, _CommandInterceptor.default); // helpers //////////

function isDescendant(descendant, ancestor) {
  var descendantBo = descendant.businessObject || descendant,
      ancestorBo = ancestor.businessObject || ancestor;

  while (descendantBo.$parent) {
    if (descendantBo.$parent === ancestorBo.processRef || ancestorBo) {
      return true;
    }

    descendantBo = descendantBo.$parent;
  }

  return false;
}

function getAncestor(element, type) {
  while (element.parent) {
    if ((0, _ModelUtil.is)(element.parent, type)) {
      return element.parent;
    }

    element = element.parent;
  }
}

},{"../../../util/ModelUtil":141,"../cmd/UpdateSemanticParentHandler":109,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],71:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DeleteLaneBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _LaneUtil = require("../util/LaneUtil");

var _Elements = require("diagram-js/lib/util/Elements");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LOW_PRIORITY = 500;
/**
 * BPMN specific delete lane behavior
 */

function DeleteLaneBehavior(eventBus, modeling, spaceTool) {
  _CommandInterceptor.default.call(this, eventBus);

  function compensateLaneDelete(shape, oldParent) {
    var siblings = (0, _LaneUtil.getChildLanes)(oldParent);
    var topAffected = [];
    var bottomAffected = [];
    (0, _Elements.eachElement)(siblings, function (element) {
      if (element.y > shape.y) {
        bottomAffected.push(element);
      } else {
        topAffected.push(element);
      }

      return element.children;
    });

    if (!siblings.length) {
      return;
    }

    var offset;

    if (bottomAffected.length && topAffected.length) {
      offset = shape.height / 2;
    } else {
      offset = shape.height;
    }

    var topAdjustments, bottomAdjustments;

    if (topAffected.length) {
      topAdjustments = spaceTool.calculateAdjustments(topAffected, 'y', offset, shape.y - 10);
      spaceTool.makeSpace(topAdjustments.movingShapes, topAdjustments.resizingShapes, {
        x: 0,
        y: offset
      }, 's');
    }

    if (bottomAffected.length) {
      bottomAdjustments = spaceTool.calculateAdjustments(bottomAffected, 'y', -offset, shape.y + shape.height + 10);
      spaceTool.makeSpace(bottomAdjustments.movingShapes, bottomAdjustments.resizingShapes, {
        x: 0,
        y: -offset
      }, 'n');
    }
  }
  /**
   * Adjust sizes of other lanes after lane deletion
   */


  this.postExecuted('shape.delete', LOW_PRIORITY, function (event) {
    var context = event.context,
        hints = context.hints,
        shape = context.shape,
        oldParent = context.oldParent; // only compensate lane deletes

    if (!(0, _ModelUtil.is)(shape, 'bpmn:Lane')) {
      return;
    } // compensate root deletes only


    if (hints && hints.nested) {
      return;
    }

    compensateLaneDelete(shape, oldParent);
  });
}

DeleteLaneBehavior.$inject = ['eventBus', 'modeling', 'spaceTool'];
(0, _inherits.default)(DeleteLaneBehavior, _CommandInterceptor.default);

},{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Elements":315,"inherits":347}],72:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DetachEventBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _LabelUtil = require("../../../util/LabelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LOW_PRIORITY = 500;
/**
 * Replace boundary event with intermediate event when creating or moving results in detached event.
 */

function DetachEventBehavior(bpmnReplace, injector) {
  injector.invoke(_CommandInterceptor.default, this);
  this._bpmnReplace = bpmnReplace;
  var self = this;
  this.postExecuted('elements.create', LOW_PRIORITY, function (context) {
    var elements = context.elements;
    elements.filter(function (shape) {
      var host = shape.host;
      return shouldReplace(shape, host);
    }).map(function (shape) {
      return elements.indexOf(shape);
    }).forEach(function (index) {
      context.elements[index] = self.replaceShape(elements[index]);
    });
  }, true);
  this.preExecute('elements.move', LOW_PRIORITY, function (context) {
    var shapes = context.shapes,
        newHost = context.newHost;
    shapes.forEach(function (shape, index) {
      var host = shape.host;

      if (shouldReplace(shape, includes(shapes, host) ? host : newHost)) {
        shapes[index] = self.replaceShape(shape);
      }
    });
  }, true);
}

DetachEventBehavior.$inject = ['bpmnReplace', 'injector'];
(0, _inherits.default)(DetachEventBehavior, _CommandInterceptor.default);

DetachEventBehavior.prototype.replaceShape = function (shape) {
  var eventDefinition = getEventDefinition(shape),
      intermediateEvent;

  if (eventDefinition) {
    intermediateEvent = {
      type: 'bpmn:IntermediateCatchEvent',
      eventDefinitionType: eventDefinition.$type
    };
  } else {
    intermediateEvent = {
      type: 'bpmn:IntermediateThrowEvent'
    };
  }

  return this._bpmnReplace.replaceElement(shape, intermediateEvent, {
    layoutConnection: false
  });
}; // helpers //////////


function getEventDefinition(element) {
  var businessObject = (0, _ModelUtil.getBusinessObject)(element),
      eventDefinitions = businessObject.eventDefinitions;
  return eventDefinitions && eventDefinitions[0];
}

function shouldReplace(shape, host) {
  return !(0, _LabelUtil.isLabel)(shape) && (0, _ModelUtil.is)(shape, 'bpmn:BoundaryEvent') && !host;
}

function includes(array, item) {
  return array.indexOf(item) !== -1;
}

},{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],73:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DropOnFlowBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _minDash = require("min-dash");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _LineIntersection = require("diagram-js/lib/util/LineIntersection");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function DropOnFlowBehavior(eventBus, bpmnRules, modeling) {
  _CommandInterceptor.default.call(this, eventBus);
  /**
   * Reconnect start / end of a connection after
   * dropping an element on a flow.
   */


  function insertShape(shape, targetFlow, positionOrBounds) {
    var waypoints = targetFlow.waypoints,
        waypointsBefore,
        waypointsAfter,
        dockingPoint,
        source,
        target,
        incomingConnection,
        outgoingConnection,
        oldOutgoing = shape.outgoing.slice(),
        oldIncoming = shape.incoming.slice();
    var mid;

    if ((0, _minDash.isNumber)(positionOrBounds.width)) {
      mid = (0, _LayoutUtil.getMid)(positionOrBounds);
    } else {
      mid = positionOrBounds;
    }

    var intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, mid);

    if (intersection) {
      waypointsBefore = waypoints.slice(0, intersection.index);
      waypointsAfter = waypoints.slice(intersection.index + (intersection.bendpoint ? 1 : 0)); // due to inaccuracy intersection might have been found

      if (!waypointsBefore.length || !waypointsAfter.length) {
        return;
      }

      dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : mid; // if last waypointBefore is inside shape's bounds, ignore docking point

      if (!isPointInsideBBox(shape, waypointsBefore[waypointsBefore.length - 1])) {
        waypointsBefore.push(copy(dockingPoint));
      } // if first waypointAfter is inside shape's bounds, ignore docking point


      if (!isPointInsideBBox(shape, waypointsAfter[0])) {
        waypointsAfter.unshift(copy(dockingPoint));
      }
    }

    source = targetFlow.source;
    target = targetFlow.target;

    if (bpmnRules.canConnect(source, shape, targetFlow)) {
      // reconnect source -> inserted shape
      modeling.reconnectEnd(targetFlow, shape, waypointsBefore || mid);
      incomingConnection = targetFlow;
    }

    if (bpmnRules.canConnect(shape, target, targetFlow)) {
      if (!incomingConnection) {
        // reconnect inserted shape -> end
        modeling.reconnectStart(targetFlow, shape, waypointsAfter || mid);
        outgoingConnection = targetFlow;
      } else {
        outgoingConnection = modeling.connect(shape, target, {
          type: targetFlow.type,
          waypoints: waypointsAfter
        });
      }
    }

    var duplicateConnections = [].concat(incomingConnection && (0, _minDash.filter)(oldIncoming, function (connection) {
      return connection.source === incomingConnection.source;
    }) || [], outgoingConnection && (0, _minDash.filter)(oldOutgoing, function (connection) {
      return connection.target === outgoingConnection.target;
    }) || []);

    if (duplicateConnections.length) {
      modeling.removeElements(duplicateConnections);
    }
  }

  this.preExecute('elements.move', function (context) {
    var newParent = context.newParent,
        shapes = context.shapes,
        delta = context.delta,
        shape = shapes[0];

    if (!shape || !newParent) {
      return;
    } // if the new parent is a connection,
    // change it to the new parent's parent


    if (newParent && newParent.waypoints) {
      context.newParent = newParent = newParent.parent;
    }

    var shapeMid = (0, _LayoutUtil.getMid)(shape);
    var newShapeMid = {
      x: shapeMid.x + delta.x,
      y: shapeMid.y + delta.y
    }; // find a connection which intersects with the
    // element's mid point

    var connection = (0, _minDash.find)(newParent.children, function (element) {
      var canInsert = bpmnRules.canInsert(shapes, element);
      return canInsert && (0, _LineIntersection.getApproxIntersection)(element.waypoints, newShapeMid);
    });

    if (connection) {
      context.targetFlow = connection;
      context.position = newShapeMid;
    }
  }, true);
  this.postExecuted('elements.move', function (context) {
    var shapes = context.shapes,
        targetFlow = context.targetFlow,
        position = context.position;

    if (targetFlow) {
      insertShape(shapes[0], targetFlow, position);
    }
  }, true);
  this.preExecute('shape.create', function (context) {
    var parent = context.parent,
        shape = context.shape;

    if (bpmnRules.canInsert(shape, parent)) {
      context.targetFlow = parent;
      context.parent = parent.parent;
    }
  }, true);
  this.postExecuted('shape.create', function (context) {
    var shape = context.shape,
        targetFlow = context.targetFlow,
        positionOrBounds = context.position;

    if (targetFlow) {
      insertShape(shape, targetFlow, positionOrBounds);
    }
  }, true);
}

(0, _inherits.default)(DropOnFlowBehavior, _CommandInterceptor.default);
DropOnFlowBehavior.$inject = ['eventBus', 'bpmnRules', 'modeling']; // helpers /////////////////////

function isPointInsideBBox(bbox, point) {
  var x = point.x,
      y = point.y;
  return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height;
}

function copy(obj) {
  return (0, _minDash.assign)({}, obj);
}

},{"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/LineIntersection":321,"inherits":347,"min-dash":555}],74:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = EventBasedGatewayBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function EventBasedGatewayBehavior(eventBus, modeling) {
  _CommandInterceptor.default.call(this, eventBus);
  /**
   * Remove existing sequence flows of event-based target before connecting
   * from event-based gateway.
   */


  this.preExecuted('connection.create', function (event) {
    var context = event.context,
        source = context.source,
        target = context.target,
        existingIncomingConnections = target.incoming.slice();

    if (context.hints && context.hints.createElementsBehavior === false) {
      return;
    }

    if ((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && target.incoming.length) {
      existingIncomingConnections.filter(isSequenceFlow).forEach(function (sequenceFlow) {
        modeling.removeConnection(sequenceFlow);
      });
    }
  });
  /**
   *  After replacing shape with event-based gateway, remove incoming sequence
   *  flows of event-based targets which do not belong to event-based gateway
   *  source.
   */

  this.preExecuted('shape.replace', function (event) {
    var newShape = event.context.newShape,
        newShapeTargets,
        newShapeTargetsIncomingSequenceFlows;

    if (!(0, _ModelUtil.is)(newShape, 'bpmn:EventBasedGateway')) {
      return;
    }

    newShapeTargets = newShape.outgoing.filter(isSequenceFlow).map(function (sequenceFlow) {
      return sequenceFlow.target;
    });
    newShapeTargetsIncomingSequenceFlows = newShapeTargets.reduce(function (sequenceFlows, target) {
      var incomingSequenceFlows = target.incoming.filter(isSequenceFlow);
      return sequenceFlows.concat(incomingSequenceFlows);
    }, []);
    newShapeTargetsIncomingSequenceFlows.forEach(function (sequenceFlow) {
      if (sequenceFlow.source !== newShape) {
        modeling.removeConnection(sequenceFlow);
      }
    });
  });
}

EventBasedGatewayBehavior.$inject = ['eventBus', 'modeling'];
(0, _inherits.default)(EventBasedGatewayBehavior, _CommandInterceptor.default); // helpers //////////////////////

function isSequenceFlow(connection) {
  return (0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow');
}

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],75:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = FixHoverBehavior;

var _LaneUtil = require("../util/LaneUtil");

var _ModelUtil = require("../../../util/ModelUtil");

var _ModelingUtil = require("../util/ModelingUtil");

var HIGH_PRIORITY = 1500;
var HIGHEST_PRIORITY = 2000;
/**
 * Correct hover targets in certain situations to improve diagram interaction.
 *
 * @param {ElementRegistry} elementRegistry
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 */

function FixHoverBehavior(elementRegistry, eventBus, canvas) {
  eventBus.on(['create.hover', 'create.move', 'create.end', 'shape.move.hover', 'shape.move.move', 'shape.move.end'], HIGH_PRIORITY, function (event) {
    var context = event.context,
        shape = context.shape || event.shape,
        hover = event.hover; // ensure elements are not dropped onto a bpmn:Lane but onto
    // the underlying bpmn:Participant

    if ((0, _ModelUtil.is)(hover, 'bpmn:Lane') && !(0, _ModelingUtil.isAny)(shape, ['bpmn:Lane', 'bpmn:Participant'])) {
      event.hover = (0, _LaneUtil.getLanesRoot)(hover);
      event.hoverGfx = elementRegistry.getGraphics(event.hover);
    }

    var rootElement = canvas.getRootElement(); // ensure bpmn:Group and label elements are dropped
    // always onto the root

    if (hover !== rootElement && (shape.labelTarget || (0, _ModelUtil.is)(shape, 'bpmn:Group'))) {
      event.hover = rootElement;
      event.hoverGfx = elementRegistry.getGraphics(event.hover);
    }
  });
  eventBus.on(['connect.hover', 'connect.out', 'connect.end', 'connect.cleanup', 'global-connect.hover', 'global-connect.out', 'global-connect.end', 'global-connect.cleanup'], HIGH_PRIORITY, function (event) {
    var hover = event.hover; // ensure connections start/end on bpmn:Participant,
    // not the underlying bpmn:Lane

    if ((0, _ModelUtil.is)(hover, 'bpmn:Lane')) {
      event.hover = (0, _LaneUtil.getLanesRoot)(hover) || hover;
      event.hoverGfx = elementRegistry.getGraphics(event.hover);
    }
  });
  eventBus.on(['bendpoint.move.hover'], HIGH_PRIORITY, function (event) {
    var context = event.context,
        hover = event.hover,
        type = context.type; // ensure reconnect start/end on bpmn:Participant,
    // not the underlying bpmn:Lane

    if ((0, _ModelUtil.is)(hover, 'bpmn:Lane') && /reconnect/.test(type)) {
      event.hover = (0, _LaneUtil.getLanesRoot)(hover) || hover;
      event.hoverGfx = elementRegistry.getGraphics(event.hover);
    }
  });
  eventBus.on(['connect.start'], HIGH_PRIORITY, function (event) {
    var context = event.context,
        start = context.start; // ensure connect start on bpmn:Participant,
    // not the underlying bpmn:Lane

    if ((0, _ModelUtil.is)(start, 'bpmn:Lane')) {
      context.start = (0, _LaneUtil.getLanesRoot)(start) || start;
    }
  }); // allow movement of participants from lanes

  eventBus.on('shape.move.start', HIGHEST_PRIORITY, function (event) {
    var shape = event.shape;

    if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) {
      event.shape = (0, _LaneUtil.getLanesRoot)(shape) || shape;
    }
  });
}

FixHoverBehavior.$inject = ['elementRegistry', 'eventBus', 'canvas'];

},{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"../util/ModelingUtil":112}],76:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = GroupBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _Collections = require("diagram-js/lib/util/Collections");

var _ModelUtil = require("../../../util/ModelUtil");

var _CategoryUtil = require("./util/CategoryUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var HIGH_PRIORITY = 2000;
/**
 * BPMN specific Group behavior
 */

function GroupBehavior(bpmnFactory, canvas, elementRegistry, eventBus, injector, moddleCopy) {
  injector.invoke(_CommandInterceptor.default, this);
  /**
   * Gets process definitions
   *
   * @return {ModdleElement} definitions
   */

  function getDefinitions() {
    var rootElement = canvas.getRootElement(),
        businessObject = (0, _ModelUtil.getBusinessObject)(rootElement);
    return businessObject.$parent;
  }
  /**
   * Removes a referenced category value for a given group shape
   *
   * @param {djs.model.Shape} shape
   */


  function removeReferencedCategoryValue(shape) {
    var businessObject = (0, _ModelUtil.getBusinessObject)(shape),
        categoryValue = businessObject.categoryValueRef;

    if (!categoryValue) {
      return;
    }

    var category = categoryValue.$parent;

    if (!categoryValue) {
      return;
    }

    (0, _Collections.remove)(category.categoryValue, categoryValue); // cleanup category if it is empty

    if (category && !category.categoryValue.length) {
      removeCategory(category);
    }
  }
  /**
   * Removes a given category from the definitions
   *
   * @param {ModdleElement} category
   */


  function removeCategory(category) {
    var definitions = getDefinitions();
    (0, _Collections.remove)(definitions.get('rootElements'), category);
  }
  /**
   * Returns all group element in the current registry
   *
   * @return {Array<djs.model.shape>} a list of group shapes
   */


  function getGroupElements() {
    return elementRegistry.filter(function (e) {
      return (0, _ModelUtil.is)(e, 'bpmn:Group');
    });
  }
  /**
   * Returns true if given categoryValue is referenced in one of the given elements
   *
   * @param {Array<djs.model.shape>} elements
   * @param {ModdleElement} categoryValue
   * @return {boolean}
   */


  function isReferenced(elements, categoryValue) {
    return elements.some(function (e) {
      var businessObject = (0, _ModelUtil.getBusinessObject)(e);
      return businessObject.categoryValueRef && businessObject.categoryValueRef === categoryValue;
    });
  }
  /**
   * remove referenced category + value when group was deleted
   */


  this.executed('shape.delete', function (event) {
    var context = event.context,
        shape = context.shape;

    if ((0, _ModelUtil.is)(shape, 'bpmn:Group')) {
      var businessObject = (0, _ModelUtil.getBusinessObject)(shape),
          categoryValueRef = businessObject.categoryValueRef,
          groupElements = getGroupElements();

      if (!isReferenced(groupElements, categoryValueRef)) {
        removeReferencedCategoryValue(shape);
      }
    }
  });
  /**
   * re-attach removed category
   */

  this.reverted('shape.delete', function (event) {
    var context = event.context,
        shape = context.shape;

    if ((0, _ModelUtil.is)(shape, 'bpmn:Group')) {
      var businessObject = (0, _ModelUtil.getBusinessObject)(shape),
          categoryValueRef = businessObject.categoryValueRef,
          definitions = getDefinitions(),
          category = categoryValueRef ? categoryValueRef.$parent : null;
      (0, _Collections.add)(category.get('categoryValue'), categoryValueRef);
      (0, _Collections.add)(definitions.get('rootElements'), category);
    }
  });
  /**
   * create new category + value when group was created
   */

  this.execute('shape.create', function (event) {
    var context = event.context,
        shape = context.shape,
        businessObject = (0, _ModelUtil.getBusinessObject)(shape);

    if ((0, _ModelUtil.is)(businessObject, 'bpmn:Group') && !businessObject.categoryValueRef) {
      var definitions = getDefinitions(),
          categoryValue = (0, _CategoryUtil.createCategoryValue)(definitions, bpmnFactory); // link the reference to the Group

      businessObject.categoryValueRef = categoryValue;
    }
  });
  this.revert('shape.create', function (event) {
    var context = event.context,
        shape = context.shape;

    if ((0, _ModelUtil.is)(shape, 'bpmn:Group')) {
      removeReferencedCategoryValue(shape);
      delete (0, _ModelUtil.getBusinessObject)(shape).categoryValueRef;
    }
  }); // copy bpmn:CategoryValue when copying element

  eventBus.on('moddleCopy.canCopyProperty', HIGH_PRIORITY, function (context) {
    var property = context.property,
        categoryValue;

    if ((0, _ModelUtil.is)(property, 'bpmn:CategoryValue')) {
      categoryValue = (0, _CategoryUtil.createCategoryValue)(getDefinitions(), bpmnFactory); // return copy of category

      return moddleCopy.copyElement(property, categoryValue);
    }
  });
}

GroupBehavior.$inject = ['bpmnFactory', 'canvas', 'elementRegistry', 'eventBus', 'injector', 'moddleCopy'];
(0, _inherits.default)(GroupBehavior, _CommandInterceptor.default);

},{"../../../util/ModelUtil":141,"./util/CategoryUtil":95,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Collections":313,"inherits":347}],77:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ImportDockingFix;

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _LineIntersect = _interopRequireDefault(require("./util/LineIntersect"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Fix broken dockings after DI imports.
 *
 * @param {EventBus} eventBus
 */
function ImportDockingFix(eventBus) {
  function adjustDocking(startPoint, nextPoint, elementMid) {
    var elementTop = {
      x: elementMid.x,
      y: elementMid.y - 50
    };
    var elementLeft = {
      x: elementMid.x - 50,
      y: elementMid.y
    };
    var verticalIntersect = (0, _LineIntersect.default)(startPoint, nextPoint, elementMid, elementTop),
        horizontalIntersect = (0, _LineIntersect.default)(startPoint, nextPoint, elementMid, elementLeft); // original is horizontal or vertical center cross intersection

    var centerIntersect;

    if (verticalIntersect && horizontalIntersect) {
      if (getDistance(verticalIntersect, elementMid) > getDistance(horizontalIntersect, elementMid)) {
        centerIntersect = horizontalIntersect;
      } else {
        centerIntersect = verticalIntersect;
      }
    } else {
      centerIntersect = verticalIntersect || horizontalIntersect;
    }

    startPoint.original = centerIntersect;
  }

  function fixDockings(connection) {
    var waypoints = connection.waypoints;
    adjustDocking(waypoints[0], waypoints[1], (0, _LayoutUtil.getMid)(connection.source));
    adjustDocking(waypoints[waypoints.length - 1], waypoints[waypoints.length - 2], (0, _LayoutUtil.getMid)(connection.target));
  }

  eventBus.on('bpmnElement.added', function (e) {
    var element = e.element;

    if (element.waypoints) {
      fixDockings(element);
    }
  });
}

ImportDockingFix.$inject = ['eventBus']; // helpers //////////////////////

function getDistance(p1, p2) {
  return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
}

},{"./util/LineIntersect":99,"diagram-js/lib/layout/LayoutUtil":300}],78:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = IsHorizontalFix;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _ModelingUtil = require("../util/ModelingUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A component that makes sure that each created or updated
 * Pool and Lane is assigned an isHorizontal property set to true.
 *
 * @param {EventBus} eventBus
 */
function IsHorizontalFix(eventBus) {
  _CommandInterceptor.default.call(this, eventBus);

  var elementTypesToUpdate = ['bpmn:Participant', 'bpmn:Lane'];
  this.executed(['shape.move', 'shape.create', 'shape.resize'], function (event) {
    var bo = (0, _ModelUtil.getBusinessObject)(event.context.shape);

    if ((0, _ModelingUtil.isAny)(bo, elementTypesToUpdate) && !bo.di.get('isHorizontal')) {
      // set attribute directly to avoid modeling#updateProperty side effects
      bo.di.set('isHorizontal', true);
    }
  });
}

IsHorizontalFix.$inject = ['eventBus'];
(0, _inherits.default)(IsHorizontalFix, _CommandInterceptor.default);

},{"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],79:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = LabelBehavior;
exports.getReferencePointDelta = getReferencePointDelta;
exports.getReferencePoint = getReferencePoint;
exports.asEdges = asEdges;

var _minDash = require("min-dash");

var _inherits = _interopRequireDefault(require("inherits"));

var _ModelUtil = require("../../../util/ModelUtil");

var _LabelUtil = require("../../../util/LabelUtil");

var _LabelUtil2 = require("../../label-editing/LabelUtil");

var _LabelLayoutUtil = require("./util/LabelLayoutUtil");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _AttachUtil = require("diagram-js/lib/util/AttachUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _PositionUtil = require("diagram-js/lib/util/PositionUtil");

var _GeometricUtil = require("./util/GeometricUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var DEFAULT_LABEL_DIMENSIONS = {
  width: 90,
  height: 20
};
var NAME_PROPERTY = 'name';
var TEXT_PROPERTY = 'text';
/**
 * A component that makes sure that external labels are added
 * together with respective elements and properly updated (DI wise)
 * during move.
 *
 * @param {EventBus} eventBus
 * @param {Modeling} modeling
 * @param {BpmnFactory} bpmnFactory
 * @param {TextRenderer} textRenderer
 */

function LabelBehavior(eventBus, modeling, bpmnFactory, textRenderer) {
  _CommandInterceptor.default.call(this, eventBus); // update label if name property was updated


  this.postExecute('element.updateProperties', function (e) {
    var context = e.context,
        element = context.element,
        properties = context.properties;

    if (NAME_PROPERTY in properties) {
      modeling.updateLabel(element, properties[NAME_PROPERTY]);
    }

    if (TEXT_PROPERTY in properties && (0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) {
      var newBounds = textRenderer.getTextAnnotationBounds({
        x: element.x,
        y: element.y,
        width: element.width,
        height: element.height
      }, properties[TEXT_PROPERTY] || '');
      modeling.updateLabel(element, properties.text, newBounds);
    }
  }); // create label shape after shape/connection was created

  this.postExecute(['shape.create', 'connection.create'], function (e) {
    var context = e.context,
        hints = context.hints || {};

    if (hints.createElementsBehavior === false) {
      return;
    }

    var element = context.shape || context.connection,
        businessObject = element.businessObject;

    if ((0, _LabelUtil.isLabel)(element) || !(0, _LabelUtil.isLabelExternal)(element)) {
      return;
    } // only create label if attribute available


    if (!(0, _LabelUtil2.getLabel)(element)) {
      return;
    }

    var labelCenter = (0, _LabelUtil.getExternalLabelMid)(element); // we don't care about x and y

    var labelDimensions = textRenderer.getExternalLabelBounds(DEFAULT_LABEL_DIMENSIONS, (0, _LabelUtil2.getLabel)(element));
    modeling.createLabel(element, labelCenter, {
      id: businessObject.id + '_label',
      businessObject: businessObject,
      width: labelDimensions.width,
      height: labelDimensions.height
    });
  }); // update label after label shape was deleted

  this.postExecute('shape.delete', function (event) {
    var context = event.context,
        labelTarget = context.labelTarget,
        hints = context.hints || {}; // check if label

    if (labelTarget && hints.unsetLabel !== false) {
      modeling.updateLabel(labelTarget, null, null, {
        removeShape: false
      });
    }
  }); // update di information on label creation

  this.postExecute(['label.create'], function (event) {
    var context = event.context,
        element = context.shape,
        businessObject,
        di; // we want to trigger on real labels only

    if (!element.labelTarget) {
      return;
    } // we want to trigger on BPMN elements only


    if (!(0, _ModelUtil.is)(element.labelTarget || element, 'bpmn:BaseElement')) {
      return;
    }

    businessObject = element.businessObject, di = businessObject.di;

    if (!di.label) {
      di.label = bpmnFactory.create('bpmndi:BPMNLabel', {
        bounds: bpmnFactory.create('dc:Bounds')
      });
    }

    (0, _minDash.assign)(di.label.bounds, {
      x: element.x,
      y: element.y,
      width: element.width,
      height: element.height
    });
  });

  function getVisibleLabelAdjustment(event) {
    var context = event.context,
        connection = context.connection,
        label = connection.label,
        hints = (0, _minDash.assign)({}, context.hints),
        newWaypoints = context.newWaypoints || connection.waypoints,
        oldWaypoints = context.oldWaypoints;

    if (typeof hints.startChanged === 'undefined') {
      hints.startChanged = !!hints.connectionStart;
    }

    if (typeof hints.endChanged === 'undefined') {
      hints.endChanged = !!hints.connectionEnd;
    }

    return (0, _LabelLayoutUtil.getLabelAdjustment)(label, newWaypoints, oldWaypoints, hints);
  }

  this.postExecute(['connection.layout', 'connection.updateWaypoints'], function (event) {
    var context = event.context,
        hints = context.hints || {};

    if (hints.labelBehavior === false) {
      return;
    }

    var connection = context.connection,
        label = connection.label,
        labelAdjustment; // handle missing label as well as the case
    // that the label parent does not exist (yet),
    // because it is being pasted / created via multi element create
    //
    // Cf. https://github.com/bpmn-io/bpmn-js/pull/1227

    if (!label || !label.parent) {
      return;
    }

    labelAdjustment = getVisibleLabelAdjustment(event);
    modeling.moveShape(label, labelAdjustment);
  }); // keep label position on shape replace

  this.postExecute(['shape.replace'], function (event) {
    var context = event.context,
        newShape = context.newShape,
        oldShape = context.oldShape;
    var businessObject = (0, _ModelUtil.getBusinessObject)(newShape);

    if (businessObject && (0, _LabelUtil.isLabelExternal)(businessObject) && oldShape.label && newShape.label) {
      newShape.label.x = oldShape.label.x;
      newShape.label.y = oldShape.label.y;
    }
  }); // move external label after resizing

  this.postExecute('shape.resize', function (event) {
    var context = event.context,
        shape = context.shape,
        newBounds = context.newBounds,
        oldBounds = context.oldBounds;

    if ((0, _LabelUtil.hasExternalLabel)(shape)) {
      var label = shape.label,
          labelMid = (0, _LayoutUtil.getMid)(label),
          edges = asEdges(oldBounds); // get nearest border point to label as reference point

      var referencePoint = getReferencePoint(labelMid, edges);
      var delta = getReferencePointDelta(referencePoint, oldBounds, newBounds);
      modeling.moveShape(label, delta);
    }
  });
}

(0, _inherits.default)(LabelBehavior, _CommandInterceptor.default);
LabelBehavior.$inject = ['eventBus', 'modeling', 'bpmnFactory', 'textRenderer']; // helpers //////////////////////

/**
 * Calculates a reference point delta relative to a new position
 * of a certain element's bounds
 *
 * @param {Point} point
 * @param {Bounds} oldBounds
 * @param {Bounds} newBounds
 *
 * @return {Delta} delta
 */

function getReferencePointDelta(referencePoint, oldBounds, newBounds) {
  var newReferencePoint = (0, _AttachUtil.getNewAttachPoint)(referencePoint, oldBounds, newBounds);
  return (0, _LayoutUtil.roundPoint)((0, _PositionUtil.delta)(newReferencePoint, referencePoint));
}
/**
 * Generates the nearest point (reference point) for a given point
 * onto given set of lines
 *
 * @param {Array<Point, Point>} lines
 * @param {Point} point
 *
 * @param {Point}
 */


function getReferencePoint(point, lines) {
  if (!lines.length) {
    return;
  }

  var nearestLine = getNearestLine(point, lines);
  return (0, _GeometricUtil.perpendicularFoot)(point, nearestLine);
}
/**
 * Convert the given bounds to a lines array containing all edges
 *
 * @param {Bounds|Point} bounds
 *
 * @return Array<Point>
 */


function asEdges(bounds) {
  return [[// top
  {
    x: bounds.x,
    y: bounds.y
  }, {
    x: bounds.x + (bounds.width || 0),
    y: bounds.y
  }], [// right
  {
    x: bounds.x + (bounds.width || 0),
    y: bounds.y
  }, {
    x: bounds.x + (bounds.width || 0),
    y: bounds.y + (bounds.height || 0)
  }], [// bottom
  {
    x: bounds.x,
    y: bounds.y + (bounds.height || 0)
  }, {
    x: bounds.x + (bounds.width || 0),
    y: bounds.y + (bounds.height || 0)
  }], [// left
  {
    x: bounds.x,
    y: bounds.y
  }, {
    x: bounds.x,
    y: bounds.y + (bounds.height || 0)
  }]];
}
/**
 * Returns the nearest line for a given point by distance
 * @param {Point} point
 * @param Array<Point> lines
 *
 * @return Array<Point>
 */


function getNearestLine(point, lines) {
  var distances = lines.map(function (l) {
    return {
      line: l,
      distance: (0, _GeometricUtil.getDistancePointLine)(point, l)
    };
  });
  var sorted = (0, _minDash.sortBy)(distances, 'distance');
  return sorted[0].line;
}

},{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"../../label-editing/LabelUtil":53,"./util/GeometricUtil":96,"./util/LabelLayoutUtil":97,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/AttachUtil":311,"diagram-js/lib/util/PositionUtil":325,"inherits":347,"min-dash":555}],80:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ModelingFeedback;

var _ModelUtil = require("../../../util/ModelUtil");

var COLLAB_ERR_MSG = 'flow elements must be children of pools/participants',
    PROCESS_ERR_MSG = 'participants cannot be pasted onto a non-empty process diagram';

function ModelingFeedback(eventBus, tooltips, translate) {
  function showError(position, message, timeout) {
    tooltips.add({
      position: {
        x: position.x + 5,
        y: position.y + 5
      },
      type: 'error',
      timeout: timeout || 2000,
      html: '<div>' + message + '</div>'
    });
  }

  eventBus.on(['shape.move.rejected', 'create.rejected'], function (event) {
    var context = event.context,
        shape = context.shape,
        target = context.target;

    if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration') && (0, _ModelUtil.is)(shape, 'bpmn:FlowNode')) {
      showError(event, translate(COLLAB_ERR_MSG));
    }
  });
  eventBus.on(['elements.paste.rejected'], function (event) {
    var context = event.context,
        position = context.position,
        target = context.target;

    if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration')) {
      showError(position, translate(COLLAB_ERR_MSG));
    }

    if ((0, _ModelUtil.is)(target, 'bpmn:Process')) {
      showError(position, translate(PROCESS_ERR_MSG), 3000);
    }
  });
}

ModelingFeedback.$inject = ['eventBus', 'tooltips', 'translate'];

},{"../../../util/ModelUtil":141}],81:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = RemoveElementBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _ModelUtil = require("../../../util/ModelUtil");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _LineIntersect = _interopRequireDefault(require("./util/LineIntersect"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function RemoveElementBehavior(eventBus, bpmnRules, modeling) {
  _CommandInterceptor.default.call(this, eventBus);
  /**
   * Combine sequence flows when deleting an element
   * if there is one incoming and one outgoing
   * sequence flow
   */


  this.preExecute('shape.delete', function (e) {
    var shape = e.context.shape; // only handle [a] -> [shape] -> [b] patterns

    if (shape.incoming.length !== 1 || shape.outgoing.length !== 1) {
      return;
    }

    var inConnection = shape.incoming[0],
        outConnection = shape.outgoing[0]; // only handle sequence flows

    if (!(0, _ModelUtil.is)(inConnection, 'bpmn:SequenceFlow') || !(0, _ModelUtil.is)(outConnection, 'bpmn:SequenceFlow')) {
      return;
    }

    if (bpmnRules.canConnect(inConnection.source, outConnection.target, inConnection)) {
      // compute new, combined waypoints
      var newWaypoints = getNewWaypoints(inConnection.waypoints, outConnection.waypoints);
      modeling.reconnectEnd(inConnection, outConnection.target, newWaypoints);
    }
  });
}

(0, _inherits.default)(RemoveElementBehavior, _CommandInterceptor.default);
RemoveElementBehavior.$inject = ['eventBus', 'bpmnRules', 'modeling']; // helpers //////////////////////

function getDocking(point) {
  return point.original || point;
}

function getNewWaypoints(inWaypoints, outWaypoints) {
  var intersection = (0, _LineIntersect.default)(getDocking(inWaypoints[inWaypoints.length - 2]), getDocking(inWaypoints[inWaypoints.length - 1]), getDocking(outWaypoints[1]), getDocking(outWaypoints[0]));

  if (intersection) {
    return [].concat(inWaypoints.slice(0, inWaypoints.length - 1), [intersection], outWaypoints.slice(1));
  } else {
    return [getDocking(inWaypoints[0]), getDocking(outWaypoints[outWaypoints.length - 1])];
  }
}

},{"../../../util/ModelUtil":141,"./util/LineIntersect":99,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],82:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = RemoveParticipantBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * BPMN specific remove behavior
 */
function RemoveParticipantBehavior(eventBus, modeling) {
  _CommandInterceptor.default.call(this, eventBus);
  /**
   * morph collaboration diagram into process diagram
   * after the last participant has been removed
   */


  this.preExecute('shape.delete', function (context) {
    var shape = context.shape,
        parent = shape.parent; // activate the behavior if the shape to be removed
    // is a participant

    if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
      context.collaborationRoot = parent;
    }
  }, true);
  this.postExecute('shape.delete', function (context) {
    var collaborationRoot = context.collaborationRoot;

    if (collaborationRoot && !collaborationRoot.businessObject.participants.length) {
      // replace empty collaboration with process diagram
      modeling.makeProcess();
    }
  }, true);
}

RemoveParticipantBehavior.$inject = ['eventBus', 'modeling'];
(0, _inherits.default)(RemoveParticipantBehavior, _CommandInterceptor.default);

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],83:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ReplaceConnectionBehavior;

var _minDash = require("min-dash");

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function ReplaceConnectionBehavior(eventBus, modeling, bpmnRules, injector) {
  _CommandInterceptor.default.call(this, eventBus);

  var dragging = injector.get('dragging', false);

  function fixConnection(connection) {
    var source = connection.source,
        target = connection.target,
        parent = connection.parent; // do not do anything if connection
    // is already deleted (may happen due to other
    // behaviors plugged-in before)

    if (!parent) {
      return;
    }

    var replacementType, remove;
    /**
     * Check if incoming or outgoing connections
     * can stay or could be substituted with an
     * appropriate replacement.
     *
     * This holds true for SequenceFlow <> MessageFlow.
     */

    if ((0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow')) {
      if (!bpmnRules.canConnectSequenceFlow(source, target)) {
        remove = true;
      }

      if (bpmnRules.canConnectMessageFlow(source, target)) {
        replacementType = 'bpmn:MessageFlow';
      }
    } // transform message flows into sequence flows, if possible


    if ((0, _ModelUtil.is)(connection, 'bpmn:MessageFlow')) {
      if (!bpmnRules.canConnectMessageFlow(source, target)) {
        remove = true;
      }

      if (bpmnRules.canConnectSequenceFlow(source, target)) {
        replacementType = 'bpmn:SequenceFlow';
      }
    }

    if ((0, _ModelUtil.is)(connection, 'bpmn:Association') && !bpmnRules.canConnectAssociation(source, target)) {
      remove = true;
    } // remove invalid connection,
    // unless it has been removed already


    if (remove) {
      modeling.removeConnection(connection);
    } // replace SequenceFlow <> MessageFlow


    if (replacementType) {
      modeling.connect(source, target, {
        type: replacementType,
        waypoints: connection.waypoints.slice()
      });
    }
  }

  function replaceReconnectedConnection(event) {
    var context = event.context,
        connection = context.connection,
        source = context.newSource || connection.source,
        target = context.newTarget || connection.target,
        allowed,
        replacement;
    allowed = bpmnRules.canConnect(source, target);

    if (!allowed || allowed.type === connection.type) {
      return;
    }

    replacement = modeling.connect(source, target, {
      type: allowed.type,
      waypoints: connection.waypoints.slice()
    }); // remove old connection

    modeling.removeConnection(connection); // replace connection in context to reconnect end/start

    context.connection = replacement;

    if (dragging) {
      cleanDraggingSelection(connection, replacement);
    }
  } // monkey-patch selection saved in dragging in order to re-select it when operation is finished


  function cleanDraggingSelection(oldConnection, newConnection) {
    var context = dragging.context(),
        previousSelection = context && context.payload.previousSelection,
        index; // do nothing if not dragging or no selection was present

    if (!previousSelection || !previousSelection.length) {
      return;
    }

    index = previousSelection.indexOf(oldConnection);

    if (index === -1) {
      return;
    }

    previousSelection.splice(index, 1, newConnection);
  } // lifecycle hooks


  this.postExecuted('elements.move', function (context) {
    var closure = context.closure,
        allConnections = closure.allConnections;
    (0, _minDash.forEach)(allConnections, fixConnection);
  }, true);
  this.preExecute('connection.reconnect', replaceReconnectedConnection);
  this.postExecuted('element.updateProperties', function (event) {
    var context = event.context,
        properties = context.properties,
        element = context.element,
        businessObject = element.businessObject,
        connection; // remove condition on change to default

    if (properties.default) {
      connection = (0, _minDash.find)(element.outgoing, (0, _minDash.matchPattern)({
        id: element.businessObject.default.id
      }));

      if (connection) {
        modeling.updateProperties(connection, {
          conditionExpression: undefined
        });
      }
    } // remove default from source on change to conditional


    if (properties.conditionExpression && businessObject.sourceRef.default === businessObject) {
      modeling.updateProperties(element.source, {
        default: undefined
      });
    }
  });
}

(0, _inherits.default)(ReplaceConnectionBehavior, _CommandInterceptor.default);
ReplaceConnectionBehavior.$inject = ['eventBus', 'modeling', 'bpmnRules', 'injector'];

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],84:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ReplaceElementBehaviour;

var _inherits = _interopRequireDefault(require("inherits"));

var _minDash = require("min-dash");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _DiUtil = require("../../../util/DiUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * BPMN-specific replace behavior.
 */
function ReplaceElementBehaviour(bpmnReplace, bpmnRules, elementRegistry, injector, modeling, selection) {
  injector.invoke(_CommandInterceptor.default, this);
  this._bpmnReplace = bpmnReplace;
  this._elementRegistry = elementRegistry;
  this._selection = selection; // replace elements on move

  this.postExecuted(['elements.move'], 500, function (event) {
    var context = event.context,
        target = context.newParent,
        newHost = context.newHost,
        elements = [];
    (0, _minDash.forEach)(context.closure.topLevel, function (topLevelElements) {
      if ((0, _DiUtil.isEventSubProcess)(topLevelElements)) {
        elements = elements.concat(topLevelElements.children);
      } else {
        elements = elements.concat(topLevelElements);
      }
    }); // set target to host if attaching

    if (elements.length === 1 && newHost) {
      target = newHost;
    }

    var canReplace = bpmnRules.canReplace(elements, target);

    if (canReplace) {
      this.replaceElements(elements, canReplace.replacements, newHost);
    }
  }, this); // update attachments on host replace

  this.postExecute(['shape.replace'], 1500, function (e) {
    var context = e.context,
        oldShape = context.oldShape,
        newShape = context.newShape,
        attachers = oldShape.attachers,
        canReplace;

    if (attachers && attachers.length) {
      canReplace = bpmnRules.canReplace(attachers, newShape);
      this.replaceElements(attachers, canReplace.replacements);
    }
  }, this); // keep ID on shape replace

  this.postExecuted(['shape.replace'], 1500, function (e) {
    var context = e.context,
        oldShape = context.oldShape,
        newShape = context.newShape;
    modeling.unclaimId(oldShape.businessObject.id, oldShape.businessObject);
    modeling.updateProperties(newShape, {
      id: oldShape.id
    });
  });
}

(0, _inherits.default)(ReplaceElementBehaviour, _CommandInterceptor.default);

ReplaceElementBehaviour.prototype.replaceElements = function (elements, newElements) {
  var elementRegistry = this._elementRegistry,
      bpmnReplace = this._bpmnReplace,
      selection = this._selection;
  (0, _minDash.forEach)(newElements, function (replacement) {
    var newElement = {
      type: replacement.newElementType
    };
    var oldElement = elementRegistry.get(replacement.oldElementId);
    var idx = elements.indexOf(oldElement);
    elements[idx] = bpmnReplace.replaceElement(oldElement, newElement, {
      select: false
    });
  });

  if (newElements) {
    selection.select(elements);
  }
};

ReplaceElementBehaviour.$inject = ['bpmnReplace', 'bpmnRules', 'elementRegistry', 'injector', 'modeling', 'selection'];

},{"../../../util/DiUtil":139,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],85:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ResizeBehavior;
exports.TEXT_ANNOTATION_MIN_DIMENSIONS = exports.SUB_PROCESS_MIN_DIMENSIONS = exports.PARTICIPANT_MIN_DIMENSIONS = exports.LANE_MIN_DIMENSIONS = void 0;

var _ModelUtil = require("../../../util/ModelUtil");

var _DiUtil = require("../../../util/DiUtil");

var _ResizeUtil = require("./util/ResizeUtil");

var HIGH_PRIORITY = 1500;
var LANE_MIN_DIMENSIONS = {
  width: 300,
  height: 60
};
exports.LANE_MIN_DIMENSIONS = LANE_MIN_DIMENSIONS;
var PARTICIPANT_MIN_DIMENSIONS = {
  width: 300,
  height: 150
};
exports.PARTICIPANT_MIN_DIMENSIONS = PARTICIPANT_MIN_DIMENSIONS;
var SUB_PROCESS_MIN_DIMENSIONS = {
  width: 140,
  height: 120
};
exports.SUB_PROCESS_MIN_DIMENSIONS = SUB_PROCESS_MIN_DIMENSIONS;
var TEXT_ANNOTATION_MIN_DIMENSIONS = {
  width: 50,
  height: 30
};
/**
 * Set minimum bounds/resize constraints on resize.
 *
 * @param {EventBus} eventBus
 */

exports.TEXT_ANNOTATION_MIN_DIMENSIONS = TEXT_ANNOTATION_MIN_DIMENSIONS;

function ResizeBehavior(eventBus) {
  eventBus.on('resize.start', HIGH_PRIORITY, function (event) {
    var context = event.context,
        shape = context.shape,
        direction = context.direction,
        balanced = context.balanced;

    if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
      context.resizeConstraints = (0, _ResizeUtil.getParticipantResizeConstraints)(shape, direction, balanced);
    }

    if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
      context.minDimensions = PARTICIPANT_MIN_DIMENSIONS;
    }

    if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(shape)) {
      context.minDimensions = SUB_PROCESS_MIN_DIMENSIONS;
    }

    if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) {
      context.minDimensions = TEXT_ANNOTATION_MIN_DIMENSIONS;
    }
  });
}

ResizeBehavior.$inject = ['eventBus'];

},{"../../../util/DiUtil":139,"../../../util/ModelUtil":141,"./util/ResizeUtil":100}],86:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ResizeLaneBehavior;

var _ModelUtil = require("../../../util/ModelUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _Mouse = require("diagram-js/lib/util/Mouse");

var SLIGHTLY_HIGHER_PRIORITY = 1001;
/**
 * Invoke {@link Modeling#resizeLane} instead of
 * {@link Modeling#resizeShape} when resizing a Lane
 * or Participant shape.
 */

function ResizeLaneBehavior(eventBus, modeling) {
  eventBus.on('resize.start', SLIGHTLY_HIGHER_PRIORITY + 500, function (event) {
    var context = event.context,
        shape = context.shape;

    if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
      // should we resize the opposite lane(s) in
      // order to compensate for the resize operation?
      context.balanced = !(0, _Mouse.hasPrimaryModifier)(event);
    }
  });
  /**
   * Intercept resize end and call resize lane function instead.
   */

  eventBus.on('resize.end', SLIGHTLY_HIGHER_PRIORITY, function (event) {
    var context = event.context,
        shape = context.shape,
        canExecute = context.canExecute,
        newBounds = context.newBounds;

    if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
      if (canExecute) {
        // ensure we have actual pixel values for new bounds
        // (important when zoom level was > 1 during move)
        newBounds = (0, _LayoutUtil.roundBounds)(newBounds); // perform the actual resize

        modeling.resizeLane(shape, newBounds, context.balanced);
      } // stop propagation


      return false;
    }
  });
}

ResizeLaneBehavior.$inject = ['eventBus', 'modeling'];

},{"../../../util/ModelUtil":141,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Mouse":323}],87:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = RootElementReferenceBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _minDash = require("min-dash");

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _Collections = require("diagram-js/lib/util/Collections");

var _ModelUtil = require("../../../util/ModelUtil");

var _ModelingUtil = require("../util/ModelingUtil");

var _DiUtil = require("../../../util/DiUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LOW_PRIORITY = 500;
/**
 * Add referenced root elements (error, escalation, message, signal) if they don't exist.
 * Copy referenced root elements on copy & paste.
 */

function RootElementReferenceBehavior(bpmnjs, eventBus, injector, moddleCopy, bpmnFactory) {
  injector.invoke(_CommandInterceptor.default, this);

  function canHaveRootElementReference(element) {
    return (0, _ModelingUtil.isAny)(element, ['bpmn:ReceiveTask', 'bpmn:SendTask']) || hasAnyEventDefinition(element, ['bpmn:ErrorEventDefinition', 'bpmn:EscalationEventDefinition', 'bpmn:MessageEventDefinition', 'bpmn:SignalEventDefinition']);
  }

  function hasRootElement(rootElement) {
    var definitions = bpmnjs.getDefinitions(),
        rootElements = definitions.get('rootElements');
    return !!(0, _minDash.find)(rootElements, (0, _minDash.matchPattern)({
      id: rootElement.id
    }));
  }

  function getRootElementReferencePropertyName(eventDefinition) {
    if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:ErrorEventDefinition')) {
      return 'errorRef';
    } else if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:EscalationEventDefinition')) {
      return 'escalationRef';
    } else if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:MessageEventDefinition')) {
      return 'messageRef';
    } else if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:SignalEventDefinition')) {
      return 'signalRef';
    }
  }

  function getRootElement(businessObject) {
    if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:ReceiveTask', 'bpmn:SendTask'])) {
      return businessObject.get('messageRef');
    }

    var eventDefinitions = businessObject.get('eventDefinitions'),
        eventDefinition = eventDefinitions[0];
    return eventDefinition.get(getRootElementReferencePropertyName(eventDefinition));
  }

  function setRootElement(businessObject, rootElement) {
    if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:ReceiveTask', 'bpmn:SendTask'])) {
      return businessObject.set('messageRef', rootElement);
    }

    var eventDefinitions = businessObject.get('eventDefinitions'),
        eventDefinition = eventDefinitions[0];
    return eventDefinition.set(getRootElementReferencePropertyName(eventDefinition), rootElement);
  } // create shape


  this.executed('shape.create', function (context) {
    var shape = context.shape;

    if (!canHaveRootElementReference(shape)) {
      return;
    }

    var businessObject = (0, _ModelUtil.getBusinessObject)(shape),
        rootElement = getRootElement(businessObject),
        rootElements;

    if (rootElement && !hasRootElement(rootElement)) {
      rootElements = bpmnjs.getDefinitions().get('rootElements'); // add root element

      (0, _Collections.add)(rootElements, rootElement);
      context.addedRootElement = rootElement;
    }
  }, true);
  this.reverted('shape.create', function (context) {
    var addedRootElement = context.addedRootElement;

    if (!addedRootElement) {
      return;
    }

    var rootElements = bpmnjs.getDefinitions().get('rootElements'); // remove root element

    (0, _Collections.remove)(rootElements, addedRootElement);
  }, true);
  eventBus.on('copyPaste.copyElement', function (context) {
    var descriptor = context.descriptor,
        element = context.element;

    if (!canHaveRootElementReference(element)) {
      return;
    }

    var businessObject = (0, _ModelUtil.getBusinessObject)(element),
        rootElement = getRootElement(businessObject);

    if (rootElement) {
      descriptor.referencedRootElement = rootElement;
    }
  });
  eventBus.on('copyPaste.pasteElement', LOW_PRIORITY, function (context) {
    var descriptor = context.descriptor,
        businessObject = descriptor.businessObject;

    if (!canHaveRootElementReference(businessObject)) {
      return;
    }

    var referencedRootElement = descriptor.referencedRootElement;

    if (!referencedRootElement) {
      return;
    }

    if (!hasRootElement(referencedRootElement)) {
      referencedRootElement = moddleCopy.copyElement(referencedRootElement, bpmnFactory.create(referencedRootElement.$type));
    }

    setRootElement(businessObject, referencedRootElement);
  });
}

RootElementReferenceBehavior.$inject = ['bpmnjs', 'eventBus', 'injector', 'moddleCopy', 'bpmnFactory'];
(0, _inherits.default)(RootElementReferenceBehavior, _CommandInterceptor.default); // helpers //////////

function hasAnyEventDefinition(element, types) {
  if (!(0, _minDash.isArray)(types)) {
    types = [types];
  }

  return (0, _minDash.some)(types, function (type) {
    return (0, _DiUtil.hasEventDefinition)(element, type);
  });
}

},{"../../../util/DiUtil":139,"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Collections":313,"inherits":347,"min-dash":555}],88:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SpaceToolBehavior;

var _minDash = require("min-dash");

var _ModelUtil = require("../../../util/ModelUtil");

var _DiUtil = require("../../../util/DiUtil");

var _ResizeBehavior = require("./ResizeBehavior");

var _LaneUtil = require("../util/LaneUtil");

var max = Math.max;

function SpaceToolBehavior(eventBus) {
  eventBus.on('spaceTool.getMinDimensions', function (context) {
    var shapes = context.shapes,
        axis = context.axis,
        start = context.start,
        minDimensions = {};
    (0, _minDash.forEach)(shapes, function (shape) {
      var id = shape.id;

      if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
        if (isHorizontal(axis)) {
          minDimensions[id] = _ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS;
        } else {
          minDimensions[id] = {
            width: _ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS.width,
            height: getParticipantMinHeight(shape, start)
          };
        }
      }

      if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(shape)) {
        minDimensions[id] = _ResizeBehavior.SUB_PROCESS_MIN_DIMENSIONS;
      }

      if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) {
        minDimensions[id] = _ResizeBehavior.TEXT_ANNOTATION_MIN_DIMENSIONS;
      }
    });
    return minDimensions;
  });
}

SpaceToolBehavior.$inject = ['eventBus']; // helpers //////////

function isHorizontal(axis) {
  return axis === 'x';
}
/**
 * Get minimum height for participant taking lanes into account.
 *
 * @param {<djs.model.Shape>} participant
 * @param {number} start
 *
 * @returns {Object}
 */


function getParticipantMinHeight(participant, start) {
  var lanesMinHeight;

  if (!hasChildLanes(participant)) {
    return _ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS.height;
  }

  lanesMinHeight = getLanesMinHeight(participant, start);
  return max(_ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS.height, lanesMinHeight);
}

function hasChildLanes(element) {
  return !!(0, _LaneUtil.getChildLanes)(element).length;
}

function getLanesMinHeight(participant, resizeStart) {
  var lanes = (0, _LaneUtil.getChildLanes)(participant),
      resizedLane; // find the nested lane which is currently resized

  resizedLane = findResizedLane(lanes, resizeStart); // resized lane cannot shrink below the minimum height
  // but remaining lanes' dimensions are kept intact

  return participant.height - resizedLane.height + _ResizeBehavior.LANE_MIN_DIMENSIONS.height;
}
/**
 * Find nested lane which is currently resized.
 *
 * @param {Array<djs.model.Shape>} lanes
 * @param {number} resizeStart
 */


function findResizedLane(lanes, resizeStart) {
  var i, lane, childLanes;

  for (i = 0; i < lanes.length; i++) {
    lane = lanes[i]; // resizing current lane or a lane nested

    if (resizeStart >= lane.y && resizeStart <= lane.y + lane.height) {
      childLanes = (0, _LaneUtil.getChildLanes)(lane); // a nested lane is resized

      if (childLanes.length) {
        return findResizedLane(childLanes, resizeStart);
      } // current lane is the resized one


      return lane;
    }
  }
}

},{"../../../util/DiUtil":139,"../../../util/ModelUtil":141,"../util/LaneUtil":111,"./ResizeBehavior":85,"min-dash":555}],89:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SubProcessStartEventBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _DiUtil = require("../../../util/DiUtil.js");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Add start event replacing element with expanded sub process.
 *
 * @param {Injector} injector
 * @param {Modeling} modeling
 */
function SubProcessStartEventBehavior(injector, modeling) {
  injector.invoke(_CommandInterceptor.default, this);
  this.postExecuted('shape.replace', function (event) {
    var oldShape = event.context.oldShape,
        newShape = event.context.newShape;

    if (!(0, _ModelUtil.is)(newShape, 'bpmn:SubProcess') || !(0, _ModelUtil.is)(oldShape, 'bpmn:Task') || !(0, _DiUtil.isExpanded)(newShape)) {
      return;
    }

    var position = getStartEventPosition(newShape);
    modeling.createShape({
      type: 'bpmn:StartEvent'
    }, position, newShape);
  });
}

SubProcessStartEventBehavior.$inject = ['injector', 'modeling'];
(0, _inherits.default)(SubProcessStartEventBehavior, _CommandInterceptor.default); // helpers //////////

function getStartEventPosition(shape) {
  return {
    x: shape.x + shape.width / 6,
    y: shape.y + shape.height / 2
  };
}

},{"../../../util/DiUtil.js":139,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],90:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ToggleElementCollapseBehaviour;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _ResizeUtil = require("diagram-js/lib/features/resize/ResizeUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LOW_PRIORITY = 500;

function ToggleElementCollapseBehaviour(eventBus, elementFactory, modeling, resize) {
  _CommandInterceptor.default.call(this, eventBus);

  function hideEmptyLabels(children) {
    if (children.length) {
      children.forEach(function (child) {
        if (child.type === 'label' && !child.businessObject.name) {
          child.hidden = true;
        }
      });
    }
  }

  function expandedBounds(shape, defaultSize) {
    var children = shape.children,
        newBounds = defaultSize,
        visibleElements,
        visibleBBox;
    visibleElements = filterVisible(children).concat([shape]);
    visibleBBox = (0, _ResizeUtil.computeChildrenBBox)(visibleElements);

    if (visibleBBox) {
      // center to visibleBBox with max(defaultSize, childrenBounds)
      newBounds.width = Math.max(visibleBBox.width, newBounds.width);
      newBounds.height = Math.max(visibleBBox.height, newBounds.height);
      newBounds.x = visibleBBox.x + (visibleBBox.width - newBounds.width) / 2;
      newBounds.y = visibleBBox.y + (visibleBBox.height - newBounds.height) / 2;
    } else {
      // center to collapsed shape with defaultSize
      newBounds.x = shape.x + (shape.width - newBounds.width) / 2;
      newBounds.y = shape.y + (shape.height - newBounds.height) / 2;
    }

    return newBounds;
  }

  function collapsedBounds(shape, defaultSize) {
    return {
      x: shape.x + (shape.width - defaultSize.width) / 2,
      y: shape.y + (shape.height - defaultSize.height) / 2,
      width: defaultSize.width,
      height: defaultSize.height
    };
  }

  this.executed(['shape.toggleCollapse'], LOW_PRIORITY, function (e) {
    var context = e.context,
        shape = context.shape;

    if (!(0, _ModelUtil.is)(shape, 'bpmn:SubProcess')) {
      return;
    }

    if (!shape.collapsed) {
      // all children got made visible through djs, hide empty labels
      hideEmptyLabels(shape.children); // remove collapsed marker

      (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = true;
    } else {
      // place collapsed marker
      (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = false;
    }
  });
  this.reverted(['shape.toggleCollapse'], LOW_PRIORITY, function (e) {
    var context = e.context;
    var shape = context.shape; // revert removing/placing collapsed marker

    if (!shape.collapsed) {
      (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = true;
    } else {
      (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = false;
    }
  });
  this.postExecuted(['shape.toggleCollapse'], LOW_PRIORITY, function (e) {
    var shape = e.context.shape,
        defaultSize = elementFactory._getDefaultSize(shape),
        newBounds;

    if (shape.collapsed) {
      // resize to default size of collapsed shapes
      newBounds = collapsedBounds(shape, defaultSize);
    } else {
      // resize to bounds of max(visible children, defaultSize)
      newBounds = expandedBounds(shape, defaultSize);
    }

    modeling.resizeShape(shape, newBounds, null, {
      autoResize: shape.collapsed ? false : 'nwse'
    });
  });
}

(0, _inherits.default)(ToggleElementCollapseBehaviour, _CommandInterceptor.default);
ToggleElementCollapseBehaviour.$inject = ['eventBus', 'elementFactory', 'modeling']; // helpers //////////////////////

function filterVisible(elements) {
  return elements.filter(function (e) {
    return !e.hidden;
  });
}

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/features/resize/ResizeUtil":268,"inherits":347}],91:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = UnclaimIdBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

var _DiUtil = require("../../../util/DiUtil");

var _LabelUtil = require("../../../util/LabelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Unclaims model IDs on element deletion.
 *
 * @param {Canvas} canvas
 * @param {Injector} injector
 * @param {Moddle} moddle
 * @param {Modeling} modeling
 */
function UnclaimIdBehavior(canvas, injector, moddle, modeling) {
  injector.invoke(_CommandInterceptor.default, this);
  this.preExecute('shape.delete', function (event) {
    var context = event.context,
        shape = context.shape,
        shapeBo = shape.businessObject;

    if ((0, _LabelUtil.isLabel)(shape)) {
      return;
    }

    if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _DiUtil.isExpanded)(shape)) {
      moddle.ids.unclaim(shapeBo.processRef.id);
    }

    modeling.unclaimId(shapeBo.id, shapeBo);
  });
  this.preExecute('connection.delete', function (event) {
    var context = event.context,
        connection = context.connection,
        connectionBo = connection.businessObject;
    modeling.unclaimId(connectionBo.id, connectionBo);
  });
  this.preExecute('canvas.updateRoot', function () {
    var rootElement = canvas.getRootElement(),
        rootElementBo = rootElement.businessObject;
    moddle.ids.unclaim(rootElementBo.id);
  });
}

(0, _inherits.default)(UnclaimIdBehavior, _CommandInterceptor.default);
UnclaimIdBehavior.$inject = ['canvas', 'injector', 'moddle', 'modeling'];

},{"../../../util/DiUtil":139,"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],92:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DeleteSequenceFlowBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A behavior that unsets the Default property of
 * sequence flow source on element delete, if the
 * removed element is the Gateway or Task's default flow.
 *
 * @param {EventBus} eventBus
 * @param {Modeling} modeling
 */
function DeleteSequenceFlowBehavior(eventBus, modeling) {
  _CommandInterceptor.default.call(this, eventBus);

  this.preExecute('connection.delete', function (event) {
    var context = event.context,
        connection = context.connection,
        source = connection.source;

    if (isDefaultFlow(connection, source)) {
      modeling.updateProperties(source, {
        'default': null
      });
    }
  });
}

(0, _inherits.default)(DeleteSequenceFlowBehavior, _CommandInterceptor.default);
DeleteSequenceFlowBehavior.$inject = ['eventBus', 'modeling']; // helpers //////////////////////

function isDefaultFlow(connection, source) {
  if (!(0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow')) {
    return false;
  }

  var sourceBo = (0, _ModelUtil.getBusinessObject)(source),
      sequenceFlow = (0, _ModelUtil.getBusinessObject)(connection);
  return sourceBo.get('default') === sequenceFlow;
}

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],93:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = UpdateFlowNodeRefsBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _ModelUtil = require("../../../util/ModelUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LOW_PRIORITY = 500,
    HIGH_PRIORITY = 5000;
/**
 * BPMN specific delete lane behavior
 */

function UpdateFlowNodeRefsBehavior(eventBus, modeling, translate) {
  _CommandInterceptor.default.call(this, eventBus);
  /**
   * Ok, this is it:
   *
   * We have to update the Lane#flowNodeRefs _and_
   * FlowNode#lanes with every FlowNode move/resize and
   * Lane move/resize.
   *
   * We want to group that stuff to recompute containments
   * as efficient as possible.
   *
   * Yea!
   */
  // the update context


  var context;

  function initContext() {
    context = context || new UpdateContext();
    context.enter();
    return context;
  }

  function getContext() {
    if (!context) {
      throw new Error(translate('out of bounds release'));
    }

    return context;
  }

  function releaseContext() {
    if (!context) {
      throw new Error(translate('out of bounds release'));
    }

    var triggerUpdate = context.leave();

    if (triggerUpdate) {
      modeling.updateLaneRefs(context.flowNodes, context.lanes);
      context = null;
    }

    return triggerUpdate;
  }

  var laneRefUpdateEvents = ['spaceTool', 'lane.add', 'lane.resize', 'lane.split', 'elements.create', 'elements.delete', 'elements.move', 'shape.create', 'shape.delete', 'shape.move', 'shape.resize']; // listen to a lot of stuff to group lane updates

  this.preExecute(laneRefUpdateEvents, HIGH_PRIORITY, function (event) {
    initContext();
  });
  this.postExecuted(laneRefUpdateEvents, LOW_PRIORITY, function (event) {
    releaseContext();
  }); // Mark flow nodes + lanes that need an update

  this.preExecute(['shape.create', 'shape.move', 'shape.delete', 'shape.resize'], function (event) {
    var context = event.context,
        shape = context.shape;
    var updateContext = getContext(); // no need to update labels

    if (shape.labelTarget) {
      return;
    }

    if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) {
      updateContext.addLane(shape);
    }

    if ((0, _ModelUtil.is)(shape, 'bpmn:FlowNode')) {
      updateContext.addFlowNode(shape);
    }
  });
}

UpdateFlowNodeRefsBehavior.$inject = ['eventBus', 'modeling', 'translate'];
(0, _inherits.default)(UpdateFlowNodeRefsBehavior, _CommandInterceptor.default);

function UpdateContext() {
  this.flowNodes = [];
  this.lanes = [];
  this.counter = 0;

  this.addLane = function (lane) {
    this.lanes.push(lane);
  };

  this.addFlowNode = function (flowNode) {
    this.flowNodes.push(flowNode);
  };

  this.enter = function () {
    this.counter++;
  };

  this.leave = function () {
    this.counter--;
    return !this.counter;
  };
}

},{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],94:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _AdaptiveLabelPositioningBehavior = _interopRequireDefault(require("./AdaptiveLabelPositioningBehavior"));

var _AppendBehavior = _interopRequireDefault(require("./AppendBehavior"));

var _AssociationBehavior = _interopRequireDefault(require("./AssociationBehavior"));

var _AttachEventBehavior = _interopRequireDefault(require("./AttachEventBehavior"));

var _BoundaryEventBehavior = _interopRequireDefault(require("./BoundaryEventBehavior"));

var _RootElementReferenceBehavior = _interopRequireDefault(require("./RootElementReferenceBehavior"));

var _CreateBehavior = _interopRequireDefault(require("./CreateBehavior"));

var _FixHoverBehavior = _interopRequireDefault(require("./FixHoverBehavior"));

var _CreateDataObjectBehavior = _interopRequireDefault(require("./CreateDataObjectBehavior"));

var _CreateParticipantBehavior = _interopRequireDefault(require("./CreateParticipantBehavior"));

var _DataInputAssociationBehavior = _interopRequireDefault(require("./DataInputAssociationBehavior"));

var _DataStoreBehavior = _interopRequireDefault(require("./DataStoreBehavior"));

var _DeleteLaneBehavior = _interopRequireDefault(require("./DeleteLaneBehavior"));

var _DetachEventBehavior = _interopRequireDefault(require("./DetachEventBehavior"));

var _DropOnFlowBehavior = _interopRequireDefault(require("./DropOnFlowBehavior"));

var _EventBasedGatewayBehavior = _interopRequireDefault(require("./EventBasedGatewayBehavior"));

var _GroupBehavior = _interopRequireDefault(require("./GroupBehavior"));

var _ImportDockingFix = _interopRequireDefault(require("./ImportDockingFix"));

var _IsHorizontalFix = _interopRequireDefault(require("./IsHorizontalFix"));

var _LabelBehavior = _interopRequireDefault(require("./LabelBehavior"));

var _ModelingFeedback = _interopRequireDefault(require("./ModelingFeedback"));

var _ReplaceConnectionBehavior = _interopRequireDefault(require("./ReplaceConnectionBehavior"));

var _RemoveParticipantBehavior = _interopRequireDefault(require("./RemoveParticipantBehavior"));

var _ReplaceElementBehaviour = _interopRequireDefault(require("./ReplaceElementBehaviour"));

var _ResizeBehavior = _interopRequireDefault(require("./ResizeBehavior"));

var _ResizeLaneBehavior = _interopRequireDefault(require("./ResizeLaneBehavior"));

var _RemoveElementBehavior = _interopRequireDefault(require("./RemoveElementBehavior"));

var _SpaceToolBehavior = _interopRequireDefault(require("./SpaceToolBehavior"));

var _SubProcessStartEventBehavior = _interopRequireDefault(require("./SubProcessStartEventBehavior"));

var _ToggleElementCollapseBehaviour = _interopRequireDefault(require("./ToggleElementCollapseBehaviour"));

var _UnclaimIdBehavior = _interopRequireDefault(require("./UnclaimIdBehavior"));

var _UpdateFlowNodeRefsBehavior = _interopRequireDefault(require("./UpdateFlowNodeRefsBehavior"));

var _UnsetDefaultFlowBehavior = _interopRequireDefault(require("./UnsetDefaultFlowBehavior"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['adaptiveLabelPositioningBehavior', 'appendBehavior', 'associationBehavior', 'attachEventBehavior', 'boundaryEventBehavior', 'rootElementReferenceBehavior', 'createBehavior', 'fixHoverBehavior', 'createDataObjectBehavior', 'createParticipantBehavior', 'dataStoreBehavior', 'dataInputAssociationBehavior', 'deleteLaneBehavior', 'detachEventBehavior', 'dropOnFlowBehavior', 'eventBasedGatewayBehavior', 'groupBehavior', 'importDockingFix', 'isHorizontalFix', 'labelBehavior', 'modelingFeedback', 'removeElementBehavior', 'removeParticipantBehavior', 'replaceConnectionBehavior', 'replaceElementBehaviour', 'resizeBehavior', 'resizeLaneBehavior', 'toggleElementCollapseBehaviour', 'spaceToolBehavior', 'subProcessStartEventBehavior', 'unclaimIdBehavior', 'unsetDefaultFlowBehavior', 'updateFlowNodeRefsBehavior'],
  adaptiveLabelPositioningBehavior: ['type', _AdaptiveLabelPositioningBehavior.default],
  appendBehavior: ['type', _AppendBehavior.default],
  associationBehavior: ['type', _AssociationBehavior.default],
  attachEventBehavior: ['type', _AttachEventBehavior.default],
  boundaryEventBehavior: ['type', _BoundaryEventBehavior.default],
  rootElementReferenceBehavior: ['type', _RootElementReferenceBehavior.default],
  createBehavior: ['type', _CreateBehavior.default],
  fixHoverBehavior: ['type', _FixHoverBehavior.default],
  createDataObjectBehavior: ['type', _CreateDataObjectBehavior.default],
  createParticipantBehavior: ['type', _CreateParticipantBehavior.default],
  dataInputAssociationBehavior: ['type', _DataInputAssociationBehavior.default],
  dataStoreBehavior: ['type', _DataStoreBehavior.default],
  deleteLaneBehavior: ['type', _DeleteLaneBehavior.default],
  detachEventBehavior: ['type', _DetachEventBehavior.default],
  dropOnFlowBehavior: ['type', _DropOnFlowBehavior.default],
  eventBasedGatewayBehavior: ['type', _EventBasedGatewayBehavior.default],
  groupBehavior: ['type', _GroupBehavior.default],
  importDockingFix: ['type', _ImportDockingFix.default],
  isHorizontalFix: ['type', _IsHorizontalFix.default],
  labelBehavior: ['type', _LabelBehavior.default],
  modelingFeedback: ['type', _ModelingFeedback.default],
  replaceConnectionBehavior: ['type', _ReplaceConnectionBehavior.default],
  removeParticipantBehavior: ['type', _RemoveParticipantBehavior.default],
  replaceElementBehaviour: ['type', _ReplaceElementBehaviour.default],
  resizeBehavior: ['type', _ResizeBehavior.default],
  resizeLaneBehavior: ['type', _ResizeLaneBehavior.default],
  removeElementBehavior: ['type', _RemoveElementBehavior.default],
  toggleElementCollapseBehaviour: ['type', _ToggleElementCollapseBehaviour.default],
  spaceToolBehavior: ['type', _SpaceToolBehavior.default],
  subProcessStartEventBehavior: ['type', _SubProcessStartEventBehavior.default],
  unclaimIdBehavior: ['type', _UnclaimIdBehavior.default],
  updateFlowNodeRefsBehavior: ['type', _UpdateFlowNodeRefsBehavior.default],
  unsetDefaultFlowBehavior: ['type', _UnsetDefaultFlowBehavior.default]
};
exports.default = _default;

},{"./AdaptiveLabelPositioningBehavior":61,"./AppendBehavior":62,"./AssociationBehavior":63,"./AttachEventBehavior":64,"./BoundaryEventBehavior":65,"./CreateBehavior":66,"./CreateDataObjectBehavior":67,"./CreateParticipantBehavior":68,"./DataInputAssociationBehavior":69,"./DataStoreBehavior":70,"./DeleteLaneBehavior":71,"./DetachEventBehavior":72,"./DropOnFlowBehavior":73,"./EventBasedGatewayBehavior":74,"./FixHoverBehavior":75,"./GroupBehavior":76,"./ImportDockingFix":77,"./IsHorizontalFix":78,"./LabelBehavior":79,"./ModelingFeedback":80,"./RemoveElementBehavior":81,"./RemoveParticipantBehavior":82,"./ReplaceConnectionBehavior":83,"./ReplaceElementBehaviour":84,"./ResizeBehavior":85,"./ResizeLaneBehavior":86,"./RootElementReferenceBehavior":87,"./SpaceToolBehavior":88,"./SubProcessStartEventBehavior":89,"./ToggleElementCollapseBehaviour":90,"./UnclaimIdBehavior":91,"./UnsetDefaultFlowBehavior":92,"./UpdateFlowNodeRefsBehavior":93}],95:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createCategoryValue = createCategoryValue;

var _Collections = require("diagram-js/lib/util/Collections");

var _ModelUtil = require("../../../../util/ModelUtil");

/**
 * Creates a new bpmn:CategoryValue inside a new bpmn:Category
 *
 * @param {ModdleElement} definitions
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement} categoryValue.
 */
function createCategoryValue(definitions, bpmnFactory) {
  var categoryValue = bpmnFactory.create('bpmn:CategoryValue'),
      category = bpmnFactory.create('bpmn:Category', {
    categoryValue: [categoryValue]
  }); // add to correct place

  (0, _Collections.add)(definitions.get('rootElements'), category);
  (0, _ModelUtil.getBusinessObject)(category).$parent = definitions;
  (0, _ModelUtil.getBusinessObject)(categoryValue).$parent = category;
  return categoryValue;
}

},{"../../../../util/ModelUtil":141,"diagram-js/lib/util/Collections":313}],96:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.vectorLength = vectorLength;
exports.getAngle = getAngle;
exports.rotateVector = rotateVector;
exports.perpendicularFoot = perpendicularFoot;
exports.getDistancePointLine = getDistancePointLine;
exports.getDistancePointPoint = getDistancePointPoint;

/**
 * Returns the length of a vector
 *
 * @param {Vector}
 * @return {Float}
 */
function vectorLength(v) {
  return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2));
}
/**
 * Calculates the angle between a line a the yAxis
 *
 * @param {Array}
 * @return {Float}
 */


function getAngle(line) {
  // return value is between 0, 180 and -180, -0
  // @janstuemmel: maybe replace return a/b with b/a
  return Math.atan((line[1].y - line[0].y) / (line[1].x - line[0].x));
}
/**
 * Rotates a vector by a given angle
 *
 * @param {Vector}
 * @param {Float} Angle in radians
 * @return {Vector}
 */


function rotateVector(vector, angle) {
  return !angle ? vector : {
    x: Math.cos(angle) * vector.x - Math.sin(angle) * vector.y,
    y: Math.sin(angle) * vector.x + Math.cos(angle) * vector.y
  };
}
/**
 * Solves a 2D equation system
 * a + r*b = c, where a,b,c are 2D vectors
 *
 * @param {Vector}
 * @param {Vector}
 * @param {Vector}
 * @return {Float}
 */


function solveLambaSystem(a, b, c) {
  // the 2d system
  var system = [{
    n: a[0] - c[0],
    lambda: b[0]
  }, {
    n: a[1] - c[1],
    lambda: b[1]
  }]; // solve

  var n = system[0].n * b[0] + system[1].n * b[1],
      l = system[0].lambda * b[0] + system[1].lambda * b[1];
  return -n / l;
}
/**
 * Position of perpendicular foot
 *
 * @param {Point}
 * @param [ {Point}, {Point} ] line defined through two points
 * @return {Point} the perpendicular foot position
 */


function perpendicularFoot(point, line) {
  var a = line[0],
      b = line[1]; // relative position of b from a

  var bd = {
    x: b.x - a.x,
    y: b.y - a.y
  }; // solve equation system to the parametrized vectors param real value

  var r = solveLambaSystem([a.x, a.y], [bd.x, bd.y], [point.x, point.y]);
  return {
    x: a.x + r * bd.x,
    y: a.y + r * bd.y
  };
}
/**
 * Calculates the distance between a point and a line
 *
 * @param {Point}
 * @param [ {Point}, {Point} ] line defined through two points
 * @return {Float} distance
 */


function getDistancePointLine(point, line) {
  var pfPoint = perpendicularFoot(point, line); // distance vector

  var connectionVector = {
    x: pfPoint.x - point.x,
    y: pfPoint.y - point.y
  };
  return vectorLength(connectionVector);
}
/**
 * Calculates the distance between two points
 *
 * @param {Point}
 * @param {Point}
 * @return {Float} distance
 */


function getDistancePointPoint(point1, point2) {
  return vectorLength({
    x: point1.x - point2.x,
    y: point1.y - point2.y
  });
}

},{}],97:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.findNewLabelLineStartIndex = findNewLabelLineStartIndex;
exports.getLabelAdjustment = getLabelAdjustment;

var _GeometricUtil = require("./GeometricUtil");

var _LineAttachmentUtil = require("./LineAttachmentUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

function findNewLabelLineStartIndex(oldWaypoints, newWaypoints, attachment, hints) {
  var index = attachment.segmentIndex;
  var offset = newWaypoints.length - oldWaypoints.length; // segmentMove happened

  if (hints.segmentMove) {
    var oldSegmentStartIndex = hints.segmentMove.segmentStartIndex,
        newSegmentStartIndex = hints.segmentMove.newSegmentStartIndex; // if label was on moved segment return new segment index

    if (index === oldSegmentStartIndex) {
      return newSegmentStartIndex;
    } // label is after new segment index


    if (index >= newSegmentStartIndex) {
      return index + offset < newSegmentStartIndex ? newSegmentStartIndex : index + offset;
    } // if label is before new segment index


    return index;
  } // bendpointMove happened


  if (hints.bendpointMove) {
    var insert = hints.bendpointMove.insert,
        bendpointIndex = hints.bendpointMove.bendpointIndex,
        newIndex; // waypoints length didnt change

    if (offset === 0) {
      return index;
    } // label behind new/removed bendpoint


    if (index >= bendpointIndex) {
      newIndex = insert ? index + 1 : index - 1;
    } // label before new/removed bendpoint


    if (index < bendpointIndex) {
      newIndex = index; // decide label should take right or left segment

      if (insert && attachment.type !== 'bendpoint' && bendpointIndex - 1 === index) {
        var rel = relativePositionMidWaypoint(newWaypoints, bendpointIndex);

        if (rel < attachment.relativeLocation) {
          newIndex++;
        }
      }
    }

    return newIndex;
  } // start/end changed


  if (offset === 0) {
    return index;
  }

  if (hints.connectionStart) {
    return index === 0 ? 0 : null;
  }

  if (hints.connectionEnd) {
    return index === oldWaypoints.length - 2 ? newWaypoints.length - 2 : null;
  } // if nothing fits, return null


  return null;
}
/**
 * Calculate the required adjustment (move delta) for the given label
 * after the connection waypoints got updated.
 *
 * @param {djs.model.Label} label
 * @param {Array<Point>} newWaypoints
 * @param {Array<Point>} oldWaypoints
 * @param {Object} hints
 *
 * @return {Point} delta
 */


function getLabelAdjustment(label, newWaypoints, oldWaypoints, hints) {
  var x = 0,
      y = 0;
  var labelPosition = getLabelMid(label); // get closest attachment

  var attachment = (0, _LineAttachmentUtil.getAttachment)(labelPosition, oldWaypoints),
      oldLabelLineIndex = attachment.segmentIndex,
      newLabelLineIndex = findNewLabelLineStartIndex(oldWaypoints, newWaypoints, attachment, hints);

  if (newLabelLineIndex === null) {
    return {
      x: x,
      y: y
    };
  } // should never happen
  // TODO(@janstuemmel): throw an error here when connectionSegmentMove is refactored


  if (newLabelLineIndex < 0 || newLabelLineIndex > newWaypoints.length - 2) {
    return {
      x: x,
      y: y
    };
  }

  var oldLabelLine = getLine(oldWaypoints, oldLabelLineIndex),
      newLabelLine = getLine(newWaypoints, newLabelLineIndex),
      oldFoot = attachment.position;
  var relativeFootPosition = getRelativeFootPosition(oldLabelLine, oldFoot),
      angleDelta = getAngleDelta(oldLabelLine, newLabelLine); // special rule if label on bendpoint

  if (attachment.type === 'bendpoint') {
    var offset = newWaypoints.length - oldWaypoints.length,
        oldBendpointIndex = attachment.bendpointIndex,
        oldBendpoint = oldWaypoints[oldBendpointIndex]; // bendpoint position hasn't changed, return same position

    if (newWaypoints.indexOf(oldBendpoint) !== -1) {
      return {
        x: x,
        y: y
      };
    } // new bendpoint and old bendpoint have same index, then just return the offset


    if (offset === 0) {
      var newBendpoint = newWaypoints[oldBendpointIndex];
      return {
        x: newBendpoint.x - attachment.position.x,
        y: newBendpoint.y - attachment.position.y
      };
    } // if bendpoints get removed


    if (offset < 0 && oldBendpointIndex !== 0 && oldBendpointIndex < oldWaypoints.length - 1) {
      relativeFootPosition = relativePositionMidWaypoint(oldWaypoints, oldBendpointIndex);
    }
  }

  var newFoot = {
    x: (newLabelLine[1].x - newLabelLine[0].x) * relativeFootPosition + newLabelLine[0].x,
    y: (newLabelLine[1].y - newLabelLine[0].y) * relativeFootPosition + newLabelLine[0].y
  }; // the rotated vector to label

  var newLabelVector = (0, _GeometricUtil.rotateVector)({
    x: labelPosition.x - oldFoot.x,
    y: labelPosition.y - oldFoot.y
  }, angleDelta); // the new relative position

  x = newFoot.x + newLabelVector.x - labelPosition.x;
  y = newFoot.y + newLabelVector.y - labelPosition.y;
  return (0, _LayoutUtil.roundPoint)({
    x: x,
    y: y
  });
} // HELPERS //////////////////////


function relativePositionMidWaypoint(waypoints, idx) {
  var distanceSegment1 = (0, _GeometricUtil.getDistancePointPoint)(waypoints[idx - 1], waypoints[idx]),
      distanceSegment2 = (0, _GeometricUtil.getDistancePointPoint)(waypoints[idx], waypoints[idx + 1]);
  var relativePosition = distanceSegment1 / (distanceSegment1 + distanceSegment2);
  return relativePosition;
}

function getLabelMid(label) {
  return {
    x: label.x + label.width / 2,
    y: label.y + label.height / 2
  };
}

function getAngleDelta(l1, l2) {
  var a1 = (0, _GeometricUtil.getAngle)(l1),
      a2 = (0, _GeometricUtil.getAngle)(l2);
  return a2 - a1;
}

function getLine(waypoints, idx) {
  return [waypoints[idx], waypoints[idx + 1]];
}

function getRelativeFootPosition(line, foot) {
  var length = (0, _GeometricUtil.getDistancePointPoint)(line[0], line[1]),
      lengthToFoot = (0, _GeometricUtil.getDistancePointPoint)(line[0], foot);
  return length === 0 ? 0 : lengthToFoot / length;
}

},{"./GeometricUtil":96,"./LineAttachmentUtil":98,"diagram-js/lib/layout/LayoutUtil":300}],98:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getAttachment = getAttachment;
var sqrt = Math.sqrt,
    min = Math.min,
    max = Math.max,
    abs = Math.abs;
/**
 * Calculate the square (power to two) of a number.
 *
 * @param {number} n
 *
 * @return {number}
 */

function sq(n) {
  return Math.pow(n, 2);
}
/**
 * Get distance between two points.
 *
 * @param {Point} p1
 * @param {Point} p2
 *
 * @return {number}
 */


function getDistance(p1, p2) {
  return sqrt(sq(p1.x - p2.x) + sq(p1.y - p2.y));
}
/**
 * Return the attachment of the given point on the specified line.
 *
 * The attachment is either a bendpoint (attached to the given point)
 * or segment (attached to a location on a line segment) attachment:
 *
 * ```javascript
 * var pointAttachment = {
 *   type: 'bendpoint',
 *   bendpointIndex: 3,
 *   position: { x: 10, y: 10 } // the attach point on the line
 * };
 *
 * var segmentAttachment = {
 *   type: 'segment',
 *   segmentIndex: 2,
 *   relativeLocation: 0.31, // attach point location between 0 (at start) and 1 (at end)
 *   position: { x: 10, y: 10 } // the attach point on the line
 * };
 * ```
 *
 * @param {Point} point
 * @param {Array<Point>} line
 *
 * @return {Object} attachment
 */


function getAttachment(point, line) {
  var idx = 0,
      segmentStart,
      segmentEnd,
      segmentStartDistance,
      segmentEndDistance,
      attachmentPosition,
      minDistance,
      intersections,
      attachment,
      attachmentDistance,
      closestAttachmentDistance,
      closestAttachment;

  for (idx = 0; idx < line.length - 1; idx++) {
    segmentStart = line[idx];
    segmentEnd = line[idx + 1];

    if (pointsEqual(segmentStart, segmentEnd)) {
      intersections = [segmentStart];
    } else {
      segmentStartDistance = getDistance(point, segmentStart);
      segmentEndDistance = getDistance(point, segmentEnd);
      minDistance = min(segmentStartDistance, segmentEndDistance);
      intersections = getCircleSegmentIntersections(segmentStart, segmentEnd, point, minDistance);
    }

    if (intersections.length < 1) {
      throw new Error('expected between [1, 2] circle -> line intersections');
    } // one intersection -> bendpoint attachment


    if (intersections.length === 1) {
      attachment = {
        type: 'bendpoint',
        position: intersections[0],
        segmentIndex: idx,
        bendpointIndex: pointsEqual(segmentStart, intersections[0]) ? idx : idx + 1
      };
    } // two intersections -> segment attachment


    if (intersections.length === 2) {
      attachmentPosition = mid(intersections[0], intersections[1]);
      attachment = {
        type: 'segment',
        position: attachmentPosition,
        segmentIndex: idx,
        relativeLocation: getDistance(segmentStart, attachmentPosition) / getDistance(segmentStart, segmentEnd)
      };
    }

    attachmentDistance = getDistance(attachment.position, point);

    if (!closestAttachment || closestAttachmentDistance > attachmentDistance) {
      closestAttachment = attachment;
      closestAttachmentDistance = attachmentDistance;
    }
  }

  return closestAttachment;
}
/**
 * Gets the intersection between a circle and a line segment.
 *
 * @param {Point} s1 segment start
 * @param {Point} s2 segment end
 * @param {Point} cc circle center
 * @param {number} cr circle radius
 *
 * @return {Array<Point>} intersections
 */


function getCircleSegmentIntersections(s1, s2, cc, cr) {
  var baX = s2.x - s1.x;
  var baY = s2.y - s1.y;
  var caX = cc.x - s1.x;
  var caY = cc.y - s1.y;
  var a = baX * baX + baY * baY;
  var bBy2 = baX * caX + baY * caY;
  var c = caX * caX + caY * caY - cr * cr;
  var pBy2 = bBy2 / a;
  var q = c / a;
  var disc = pBy2 * pBy2 - q; // check against negative value to work around
  // negative, very close to zero results (-4e-15)
  // being produced in some environments

  if (disc < 0 && disc > -0.000001) {
    disc = 0;
  }

  if (disc < 0) {
    return [];
  } // if disc == 0 ... dealt with later


  var tmpSqrt = sqrt(disc);
  var abScalingFactor1 = -pBy2 + tmpSqrt;
  var abScalingFactor2 = -pBy2 - tmpSqrt;
  var i1 = {
    x: s1.x - baX * abScalingFactor1,
    y: s1.y - baY * abScalingFactor1
  };

  if (disc === 0) {
    // abScalingFactor1 == abScalingFactor2
    return [i1];
  }

  var i2 = {
    x: s1.x - baX * abScalingFactor2,
    y: s1.y - baY * abScalingFactor2
  }; // return only points on line segment

  return [i1, i2].filter(function (p) {
    return isPointInSegment(p, s1, s2);
  });
}

function isPointInSegment(p, segmentStart, segmentEnd) {
  return fenced(p.x, segmentStart.x, segmentEnd.x) && fenced(p.y, segmentStart.y, segmentEnd.y);
}

function fenced(n, rangeStart, rangeEnd) {
  // use matching threshold to work around
  // precision errors in intersection computation
  return n >= min(rangeStart, rangeEnd) - EQUAL_THRESHOLD && n <= max(rangeStart, rangeEnd) + EQUAL_THRESHOLD;
}
/**
 * Calculate mid of two points.
 *
 * @param {Point} p1
 * @param {Point} p2
 *
 * @return {Point}
 */


function mid(p1, p2) {
  return {
    x: (p1.x + p2.x) / 2,
    y: (p1.y + p2.y) / 2
  };
}

var EQUAL_THRESHOLD = 0.1;

function pointsEqual(p1, p2) {
  return abs(p1.x - p2.x) <= EQUAL_THRESHOLD && abs(p1.y - p2.y) <= EQUAL_THRESHOLD;
}

},{}],99:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = lineIntersect;

/**
 * Returns the intersection between two line segments a and b.
 *
 * @param {Point} l1s
 * @param {Point} l1e
 * @param {Point} l2s
 * @param {Point} l2e
 *
 * @return {Point}
 */
function lineIntersect(l1s, l1e, l2s, l2e) {
  // if the lines intersect, the result contains the x and y of the
  // intersection (treating the lines as infinite) and booleans for
  // whether line segment 1 or line segment 2 contain the point
  var denominator, a, b, c, numerator;
  denominator = (l2e.y - l2s.y) * (l1e.x - l1s.x) - (l2e.x - l2s.x) * (l1e.y - l1s.y);

  if (denominator == 0) {
    return null;
  }

  a = l1s.y - l2s.y;
  b = l1s.x - l2s.x;
  numerator = (l2e.x - l2s.x) * a - (l2e.y - l2s.y) * b;
  c = numerator / denominator; // if we cast these lines infinitely in
  // both directions, they intersect here

  return {
    x: Math.round(l1s.x + c * (l1e.x - l1s.x)),
    y: Math.round(l1s.y + c * (l1e.y - l1s.y))
  };
}

},{}],100:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getParticipantResizeConstraints = getParticipantResizeConstraints;

var _ModelUtil = require("../../../../util/ModelUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _LaneUtil = require("../../../modeling/util/LaneUtil");

var _ResizeBehavior = require("../ResizeBehavior");

var abs = Math.abs,
    min = Math.min,
    max = Math.max;

function addToTrbl(trbl, attr, value, choice) {
  var current = trbl[attr]; // make sure to set the value if it does not exist
  // or apply the correct value by comparing against
  // choice(value, currentValue)

  trbl[attr] = current === undefined ? value : choice(value, current);
}

function addMin(trbl, attr, value) {
  return addToTrbl(trbl, attr, value, min);
}

function addMax(trbl, attr, value) {
  return addToTrbl(trbl, attr, value, max);
}

var LANE_RIGHT_PADDING = 20,
    LANE_LEFT_PADDING = 50,
    LANE_TOP_PADDING = 20,
    LANE_BOTTOM_PADDING = 20;

function getParticipantResizeConstraints(laneShape, resizeDirection, balanced) {
  var lanesRoot = (0, _LaneUtil.getLanesRoot)(laneShape);
  var isFirst = true,
      isLast = true; // max top/bottom size for lanes

  var allLanes = (0, _LaneUtil.collectLanes)(lanesRoot, [lanesRoot]);
  var laneTrbl = (0, _LayoutUtil.asTRBL)(laneShape);
  var maxTrbl = {},
      minTrbl = {};

  if (/e/.test(resizeDirection)) {
    minTrbl.right = laneTrbl.left + _ResizeBehavior.LANE_MIN_DIMENSIONS.width;
  } else if (/w/.test(resizeDirection)) {
    minTrbl.left = laneTrbl.right - _ResizeBehavior.LANE_MIN_DIMENSIONS.width;
  }

  allLanes.forEach(function (other) {
    var otherTrbl = (0, _LayoutUtil.asTRBL)(other);

    if (/n/.test(resizeDirection)) {
      if (otherTrbl.top < laneTrbl.top - 10) {
        isFirst = false;
      } // max top size (based on next element)


      if (balanced && abs(laneTrbl.top - otherTrbl.bottom) < 10) {
        addMax(maxTrbl, 'top', otherTrbl.top + _ResizeBehavior.LANE_MIN_DIMENSIONS.height);
      } // min top size (based on self or nested element)


      if (abs(laneTrbl.top - otherTrbl.top) < 5) {
        addMin(minTrbl, 'top', otherTrbl.bottom - _ResizeBehavior.LANE_MIN_DIMENSIONS.height);
      }
    }

    if (/s/.test(resizeDirection)) {
      if (otherTrbl.bottom > laneTrbl.bottom + 10) {
        isLast = false;
      } // max bottom size (based on previous element)


      if (balanced && abs(laneTrbl.bottom - otherTrbl.top) < 10) {
        addMin(maxTrbl, 'bottom', otherTrbl.bottom - _ResizeBehavior.LANE_MIN_DIMENSIONS.height);
      } // min bottom size (based on self or nested element)


      if (abs(laneTrbl.bottom - otherTrbl.bottom) < 5) {
        addMax(minTrbl, 'bottom', otherTrbl.top + _ResizeBehavior.LANE_MIN_DIMENSIONS.height);
      }
    }
  }); // max top/bottom/left/right size based on flow nodes

  var flowElements = lanesRoot.children.filter(function (s) {
    return !s.hidden && !s.waypoints && ((0, _ModelUtil.is)(s, 'bpmn:FlowElement') || (0, _ModelUtil.is)(s, 'bpmn:Artifact'));
  });
  flowElements.forEach(function (flowElement) {
    var flowElementTrbl = (0, _LayoutUtil.asTRBL)(flowElement);

    if (isFirst && /n/.test(resizeDirection)) {
      addMin(minTrbl, 'top', flowElementTrbl.top - LANE_TOP_PADDING);
    }

    if (/e/.test(resizeDirection)) {
      addMax(minTrbl, 'right', flowElementTrbl.right + LANE_RIGHT_PADDING);
    }

    if (isLast && /s/.test(resizeDirection)) {
      addMax(minTrbl, 'bottom', flowElementTrbl.bottom + LANE_BOTTOM_PADDING);
    }

    if (/w/.test(resizeDirection)) {
      addMin(minTrbl, 'left', flowElementTrbl.left - LANE_LEFT_PADDING);
    }
  });
  return {
    min: minTrbl,
    max: maxTrbl
  };
}

},{"../../../../util/ModelUtil":141,"../../../modeling/util/LaneUtil":111,"../ResizeBehavior":85,"diagram-js/lib/layout/LayoutUtil":300}],101:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AddLaneHandler;

var _minDash = require("min-dash");

var _Elements = require("diagram-js/lib/util/Elements");

var _LaneUtil = require("../util/LaneUtil");

/**
 * A handler that allows us to add a new lane
 * above or below an existing one.
 *
 * @param {Modeling} modeling
 * @param {SpaceTool} spaceTool
 */
function AddLaneHandler(modeling, spaceTool) {
  this._modeling = modeling;
  this._spaceTool = spaceTool;
}

AddLaneHandler.$inject = ['modeling', 'spaceTool'];

AddLaneHandler.prototype.preExecute = function (context) {
  var spaceTool = this._spaceTool,
      modeling = this._modeling;
  var shape = context.shape,
      location = context.location;
  var lanesRoot = (0, _LaneUtil.getLanesRoot)(shape);
  var isRoot = lanesRoot === shape,
      laneParent = isRoot ? shape : shape.parent;
  var existingChildLanes = (0, _LaneUtil.getChildLanes)(laneParent); // (0) add a lane if we currently got none and are adding to root

  if (!existingChildLanes.length) {
    modeling.createShape({
      type: 'bpmn:Lane'
    }, {
      x: shape.x + _LaneUtil.LANE_INDENTATION,
      y: shape.y,
      width: shape.width - _LaneUtil.LANE_INDENTATION,
      height: shape.height
    }, laneParent);
  } // (1) collect affected elements to create necessary space


  var allAffected = [];
  (0, _Elements.eachElement)(lanesRoot, function (element) {
    allAffected.push(element); // handle element labels in the diagram root

    if (element.label) {
      allAffected.push(element.label);
    }

    if (element === shape) {
      return [];
    }

    return (0, _minDash.filter)(element.children, function (c) {
      return c !== shape;
    });
  });
  var offset = location === 'top' ? -120 : 120,
      lanePosition = location === 'top' ? shape.y : shape.y + shape.height,
      spacePos = lanePosition + (location === 'top' ? 10 : -10),
      direction = location === 'top' ? 'n' : 's';
  var adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos);
  spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, {
    x: 0,
    y: offset
  }, direction, spacePos); // (2) create new lane at open space

  context.newLane = modeling.createShape({
    type: 'bpmn:Lane'
  }, {
    x: shape.x + (isRoot ? _LaneUtil.LANE_INDENTATION : 0),
    y: lanePosition - (location === 'top' ? 120 : 0),
    width: shape.width - (isRoot ? _LaneUtil.LANE_INDENTATION : 0),
    height: 120
  }, laneParent);
};

},{"../util/LaneUtil":111,"diagram-js/lib/util/Elements":315,"min-dash":555}],102:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = IdClaimHandler;

function IdClaimHandler(moddle) {
  this._moddle = moddle;
}

IdClaimHandler.$inject = ['moddle'];

IdClaimHandler.prototype.execute = function (context) {
  var ids = this._moddle.ids,
      id = context.id,
      element = context.element,
      claiming = context.claiming;

  if (claiming) {
    ids.claim(id, element);
  } else {
    ids.unclaim(id);
  }
};
/**
 * Command revert implementation.
 */


IdClaimHandler.prototype.revert = function (context) {
  var ids = this._moddle.ids,
      id = context.id,
      element = context.element,
      claiming = context.claiming;

  if (claiming) {
    ids.unclaim(id);
  } else {
    ids.claim(id, element);
  }
};

},{}],103:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ResizeLaneHandler;

var _ModelUtil = require("../../../util/ModelUtil");

var _LaneUtil = require("../util/LaneUtil");

var _Elements = require("diagram-js/lib/util/Elements");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _ResizeUtil = require("diagram-js/lib/features/resize/ResizeUtil");

/**
 * A handler that resizes a lane.
 *
 * @param {Modeling} modeling
 */
function ResizeLaneHandler(modeling, spaceTool) {
  this._modeling = modeling;
  this._spaceTool = spaceTool;
}

ResizeLaneHandler.$inject = ['modeling', 'spaceTool'];

ResizeLaneHandler.prototype.preExecute = function (context) {
  var shape = context.shape,
      newBounds = context.newBounds,
      balanced = context.balanced;

  if (balanced !== false) {
    this.resizeBalanced(shape, newBounds);
  } else {
    this.resizeSpace(shape, newBounds);
  }
};
/**
 * Resize balanced, adjusting next / previous lane sizes.
 *
 * @param {djs.model.Shape} shape
 * @param {Bounds} newBounds
 */


ResizeLaneHandler.prototype.resizeBalanced = function (shape, newBounds) {
  var modeling = this._modeling;
  var resizeNeeded = (0, _LaneUtil.computeLanesResize)(shape, newBounds); // resize the lane

  modeling.resizeShape(shape, newBounds); // resize other lanes as needed

  resizeNeeded.forEach(function (r) {
    modeling.resizeShape(r.shape, r.newBounds);
  });
};
/**
 * Resize, making actual space and moving below / above elements.
 *
 * @param {djs.model.Shape} shape
 * @param {Bounds} newBounds
 */


ResizeLaneHandler.prototype.resizeSpace = function (shape, newBounds) {
  var spaceTool = this._spaceTool;
  var shapeTrbl = (0, _LayoutUtil.asTRBL)(shape),
      newTrbl = (0, _LayoutUtil.asTRBL)(newBounds);
  var trblDiff = (0, _ResizeUtil.substractTRBL)(newTrbl, shapeTrbl);
  var lanesRoot = (0, _LaneUtil.getLanesRoot)(shape);
  var allAffected = [],
      allLanes = [];
  (0, _Elements.eachElement)(lanesRoot, function (element) {
    allAffected.push(element);

    if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || (0, _ModelUtil.is)(element, 'bpmn:Participant')) {
      allLanes.push(element);
    }

    return element.children;
  });
  var change, spacePos, direction, offset, adjustments;

  if (trblDiff.bottom || trblDiff.top) {
    change = trblDiff.bottom || trblDiff.top;
    spacePos = shape.y + (trblDiff.bottom ? shape.height : 0) + (trblDiff.bottom ? -10 : 10);
    direction = trblDiff.bottom ? 's' : 'n';
    offset = trblDiff.top > 0 || trblDiff.bottom < 0 ? -change : change;
    adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos);
    spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, {
      x: 0,
      y: change
    }, direction);
  }

  if (trblDiff.left || trblDiff.right) {
    change = trblDiff.right || trblDiff.left;
    spacePos = shape.x + (trblDiff.right ? shape.width : 0) + (trblDiff.right ? -10 : 100);
    direction = trblDiff.right ? 'e' : 'w';
    offset = trblDiff.left > 0 || trblDiff.right < 0 ? -change : change;
    adjustments = spaceTool.calculateAdjustments(allLanes, 'x', offset, spacePos);
    spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, {
      x: change,
      y: 0
    }, direction);
  }
};

},{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"diagram-js/lib/features/resize/ResizeUtil":268,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Elements":315}],104:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SetColorHandler;

var _minDash = require("min-dash");

var DEFAULT_COLORS = {
  fill: undefined,
  stroke: undefined
};

function SetColorHandler(commandStack) {
  this._commandStack = commandStack;
}

SetColorHandler.$inject = ['commandStack'];

SetColorHandler.prototype.postExecute = function (context) {
  var elements = context.elements,
      colors = context.colors || DEFAULT_COLORS;
  var self = this;
  var di = {};

  if ('fill' in colors) {
    (0, _minDash.assign)(di, {
      fill: colors.fill
    });
  }

  if ('stroke' in colors) {
    (0, _minDash.assign)(di, {
      stroke: colors.stroke
    });
  }

  (0, _minDash.forEach)(elements, function (element) {
    self._commandStack.execute('element.updateProperties', {
      element: element,
      properties: {
        di: di
      }
    });
  });
};

},{"min-dash":555}],105:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SplitLaneHandler;

var _LaneUtil = require("../util/LaneUtil");

/**
 * A handler that splits a lane into a number of sub-lanes,
 * creating new sub lanes, if necessary.
 *
 * @param {Modeling} modeling
 */
function SplitLaneHandler(modeling, translate) {
  this._modeling = modeling;
  this._translate = translate;
}

SplitLaneHandler.$inject = ['modeling', 'translate'];

SplitLaneHandler.prototype.preExecute = function (context) {
  var modeling = this._modeling,
      translate = this._translate;
  var shape = context.shape,
      newLanesCount = context.count;
  var childLanes = (0, _LaneUtil.getChildLanes)(shape),
      existingLanesCount = childLanes.length;

  if (existingLanesCount > newLanesCount) {
    throw new Error(translate('more than {count} child lanes', {
      count: newLanesCount
    }));
  }

  var newLanesHeight = Math.round(shape.height / newLanesCount); // Iterate from top to bottom in child lane order,
  // resizing existing lanes and creating new ones
  // so that they split the parent proportionally.
  //
  // Due to rounding related errors, the bottom lane
  // needs to take up all the remaining space.

  var laneY, laneHeight, laneBounds, newLaneAttrs, idx;

  for (idx = 0; idx < newLanesCount; idx++) {
    laneY = shape.y + idx * newLanesHeight; // if bottom lane

    if (idx === newLanesCount - 1) {
      laneHeight = shape.height - newLanesHeight * idx;
    } else {
      laneHeight = newLanesHeight;
    }

    laneBounds = {
      x: shape.x + _LaneUtil.LANE_INDENTATION,
      y: laneY,
      width: shape.width - _LaneUtil.LANE_INDENTATION,
      height: laneHeight
    };

    if (idx < existingLanesCount) {
      // resize existing lane
      modeling.resizeShape(childLanes[idx], laneBounds);
    } else {
      // create a new lane at position
      newLaneAttrs = {
        type: 'bpmn:Lane'
      };
      modeling.createShape(newLaneAttrs, laneBounds, shape);
    }
  }
};

},{"../util/LaneUtil":111}],106:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = UpdateCanvasRootHandler;

var _Collections = require("diagram-js/lib/util/Collections");

function UpdateCanvasRootHandler(canvas, modeling) {
  this._canvas = canvas;
  this._modeling = modeling;
}

UpdateCanvasRootHandler.$inject = ['canvas', 'modeling'];

UpdateCanvasRootHandler.prototype.execute = function (context) {
  var canvas = this._canvas;
  var newRoot = context.newRoot,
      newRootBusinessObject = newRoot.businessObject,
      oldRoot = canvas.getRootElement(),
      oldRootBusinessObject = oldRoot.businessObject,
      bpmnDefinitions = oldRootBusinessObject.$parent,
      diPlane = oldRootBusinessObject.di; // (1) replace process old <> new root

  canvas.setRootElement(newRoot, true); // (2) update root elements

  (0, _Collections.add)(bpmnDefinitions.rootElements, newRootBusinessObject);
  newRootBusinessObject.$parent = bpmnDefinitions;
  (0, _Collections.remove)(bpmnDefinitions.rootElements, oldRootBusinessObject);
  oldRootBusinessObject.$parent = null; // (3) wire di

  oldRootBusinessObject.di = null;
  diPlane.bpmnElement = newRootBusinessObject;
  newRootBusinessObject.di = diPlane;
  context.oldRoot = oldRoot; // TODO(nikku): return changed elements?
  // return [ newRoot, oldRoot ];
};

UpdateCanvasRootHandler.prototype.revert = function (context) {
  var canvas = this._canvas;
  var newRoot = context.newRoot,
      newRootBusinessObject = newRoot.businessObject,
      oldRoot = context.oldRoot,
      oldRootBusinessObject = oldRoot.businessObject,
      bpmnDefinitions = newRootBusinessObject.$parent,
      diPlane = newRootBusinessObject.di; // (1) replace process old <> new root

  canvas.setRootElement(oldRoot, true); // (2) update root elements

  (0, _Collections.remove)(bpmnDefinitions.rootElements, newRootBusinessObject);
  newRootBusinessObject.$parent = null;
  (0, _Collections.add)(bpmnDefinitions.rootElements, oldRootBusinessObject);
  oldRootBusinessObject.$parent = bpmnDefinitions; // (3) wire di

  newRootBusinessObject.di = null;
  diPlane.bpmnElement = oldRootBusinessObject;
  oldRootBusinessObject.di = diPlane; // TODO(nikku): return changed elements?
  // return [ newRoot, oldRoot ];
};

},{"diagram-js/lib/util/Collections":313}],107:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = UpdateFlowNodeRefsHandler;

var _LaneUtil = require("../util/LaneUtil");

var _ModelUtil = require("../../../util/ModelUtil");

var _Collections = require("diagram-js/lib/util/Collections");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var FLOW_NODE_REFS_ATTR = 'flowNodeRef',
    LANES_ATTR = 'lanes';
/**
 * A handler that updates lane refs on changed elements
 */

function UpdateFlowNodeRefsHandler(elementRegistry) {
  this._elementRegistry = elementRegistry;
}

UpdateFlowNodeRefsHandler.$inject = ['elementRegistry'];

UpdateFlowNodeRefsHandler.prototype.computeUpdates = function (flowNodeShapes, laneShapes) {
  var handledNodes = [];
  var updates = [];
  var participantCache = {};
  var allFlowNodeShapes = [];

  function isInLaneShape(element, laneShape) {
    var laneTrbl = (0, _LayoutUtil.asTRBL)(laneShape);
    var elementMid = {
      x: element.x + element.width / 2,
      y: element.y + element.height / 2
    };
    return elementMid.x > laneTrbl.left && elementMid.x < laneTrbl.right && elementMid.y > laneTrbl.top && elementMid.y < laneTrbl.bottom;
  }

  function addFlowNodeShape(flowNodeShape) {
    if (handledNodes.indexOf(flowNodeShape) === -1) {
      allFlowNodeShapes.push(flowNodeShape);
      handledNodes.push(flowNodeShape);
    }
  }

  function getAllLaneShapes(flowNodeShape) {
    var root = (0, _LaneUtil.getLanesRoot)(flowNodeShape);

    if (!participantCache[root.id]) {
      participantCache[root.id] = (0, _LaneUtil.collectLanes)(root);
    }

    return participantCache[root.id];
  }

  function getNewLanes(flowNodeShape) {
    if (!flowNodeShape.parent) {
      return [];
    }

    var allLaneShapes = getAllLaneShapes(flowNodeShape);
    return allLaneShapes.filter(function (l) {
      return isInLaneShape(flowNodeShape, l);
    }).map(function (shape) {
      return shape.businessObject;
    });
  }

  laneShapes.forEach(function (laneShape) {
    var root = (0, _LaneUtil.getLanesRoot)(laneShape);

    if (!root || handledNodes.indexOf(root) !== -1) {
      return;
    }

    var children = root.children.filter(function (c) {
      return (0, _ModelUtil.is)(c, 'bpmn:FlowNode');
    });
    children.forEach(addFlowNodeShape);
    handledNodes.push(root);
  });
  flowNodeShapes.forEach(addFlowNodeShape);
  allFlowNodeShapes.forEach(function (flowNodeShape) {
    var flowNode = flowNodeShape.businessObject;
    var lanes = flowNode.get(LANES_ATTR),
        remove = lanes.slice(),
        add = getNewLanes(flowNodeShape);
    updates.push({
      flowNode: flowNode,
      remove: remove,
      add: add
    });
  });
  laneShapes.forEach(function (laneShape) {
    var lane = laneShape.businessObject; // lane got removed XX-)

    if (!laneShape.parent) {
      lane.get(FLOW_NODE_REFS_ATTR).forEach(function (flowNode) {
        updates.push({
          flowNode: flowNode,
          remove: [lane],
          add: []
        });
      });
    }
  });
  return updates;
};

UpdateFlowNodeRefsHandler.prototype.execute = function (context) {
  var updates = context.updates;

  if (!updates) {
    updates = context.updates = this.computeUpdates(context.flowNodeShapes, context.laneShapes);
  }

  updates.forEach(function (update) {
    var flowNode = update.flowNode,
        lanes = flowNode.get(LANES_ATTR); // unwire old

    update.remove.forEach(function (oldLane) {
      (0, _Collections.remove)(lanes, oldLane);
      (0, _Collections.remove)(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode);
    }); // wire new

    update.add.forEach(function (newLane) {
      (0, _Collections.add)(lanes, newLane);
      (0, _Collections.add)(newLane.get(FLOW_NODE_REFS_ATTR), flowNode);
    });
  }); // TODO(nikku): return changed elements
  // return [ ... ];
};

UpdateFlowNodeRefsHandler.prototype.revert = function (context) {
  var updates = context.updates;
  updates.forEach(function (update) {
    var flowNode = update.flowNode,
        lanes = flowNode.get(LANES_ATTR); // unwire new

    update.add.forEach(function (newLane) {
      (0, _Collections.remove)(lanes, newLane);
      (0, _Collections.remove)(newLane.get(FLOW_NODE_REFS_ATTR), flowNode);
    }); // wire old

    update.remove.forEach(function (oldLane) {
      (0, _Collections.add)(lanes, oldLane);
      (0, _Collections.add)(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode);
    });
  }); // TODO(nikku): return changed elements
  // return [ ... ];
};

},{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Collections":313}],108:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = UpdatePropertiesHandler;

var _minDash = require("min-dash");

var _ModelUtil = require("../../../util/ModelUtil");

var DEFAULT_FLOW = 'default',
    ID = 'id',
    DI = 'di';
var NULL_DIMENSIONS = {
  width: 0,
  height: 0
};
/**
 * A handler that implements a BPMN 2.0 property update.
 *
 * This should be used to set simple properties on elements with
 * an underlying BPMN business object.
 *
 * Use respective diagram-js provided handlers if you would
 * like to perform automated modeling.
 */

function UpdatePropertiesHandler(elementRegistry, moddle, translate, modeling, textRenderer) {
  this._elementRegistry = elementRegistry;
  this._moddle = moddle;
  this._translate = translate;
  this._modeling = modeling;
  this._textRenderer = textRenderer;
}

UpdatePropertiesHandler.$inject = ['elementRegistry', 'moddle', 'translate', 'modeling', 'textRenderer']; // api //////////////////////

/**
 * Updates a BPMN element with a list of new properties
 *
 * @param {Object} context
 * @param {djs.model.Base} context.element the element to update
 * @param {Object} context.properties a list of properties to set on the element's
 *                                    businessObject (the BPMN model element)
 *
 * @return {Array<djs.model.Base>} the updated element
 */

UpdatePropertiesHandler.prototype.execute = function (context) {
  var element = context.element,
      changed = [element],
      translate = this._translate;

  if (!element) {
    throw new Error(translate('element required'));
  }

  var elementRegistry = this._elementRegistry,
      ids = this._moddle.ids;
  var businessObject = element.businessObject,
      properties = unwrapBusinessObjects(context.properties),
      oldProperties = context.oldProperties || getProperties(businessObject, properties);

  if (isIdChange(properties, businessObject)) {
    ids.unclaim(businessObject[ID]);
    elementRegistry.updateId(element, properties[ID]);
    ids.claim(properties[ID], businessObject);
  } // correctly indicate visual changes on default flow updates


  if (DEFAULT_FLOW in properties) {
    if (properties[DEFAULT_FLOW]) {
      changed.push(elementRegistry.get(properties[DEFAULT_FLOW].id));
    }

    if (businessObject[DEFAULT_FLOW]) {
      changed.push(elementRegistry.get(businessObject[DEFAULT_FLOW].id));
    }
  } // update properties


  setProperties(businessObject, properties); // store old values

  context.oldProperties = oldProperties;
  context.changed = changed; // indicate changed on objects affected by the update

  return changed;
};

UpdatePropertiesHandler.prototype.postExecute = function (context) {
  var element = context.element,
      label = element.label;
  var text = label && (0, _ModelUtil.getBusinessObject)(label).name;

  if (!text) {
    return;
  } // get layouted text bounds and resize external
  // external label accordingly


  var newLabelBounds = this._textRenderer.getExternalLabelBounds(label, text);

  this._modeling.resizeShape(label, newLabelBounds, NULL_DIMENSIONS);
};
/**
 * Reverts the update on a BPMN elements properties.
 *
 * @param  {Object} context
 *
 * @return {djs.model.Base} the updated element
 */


UpdatePropertiesHandler.prototype.revert = function (context) {
  var element = context.element,
      properties = context.properties,
      oldProperties = context.oldProperties,
      businessObject = element.businessObject,
      elementRegistry = this._elementRegistry,
      ids = this._moddle.ids; // update properties

  setProperties(businessObject, oldProperties);

  if (isIdChange(properties, businessObject)) {
    ids.unclaim(properties[ID]);
    elementRegistry.updateId(element, oldProperties[ID]);
    ids.claim(oldProperties[ID], businessObject);
  }

  return context.changed;
};

function isIdChange(properties, businessObject) {
  return ID in properties && properties[ID] !== businessObject[ID];
}

function getProperties(businessObject, properties) {
  var propertyNames = (0, _minDash.keys)(properties);
  return (0, _minDash.reduce)(propertyNames, function (result, key) {
    // handle DI separately
    if (key !== DI) {
      result[key] = businessObject.get(key);
    } else {
      result[key] = getDiProperties(businessObject.di, (0, _minDash.keys)(properties.di));
    }

    return result;
  }, {});
}

function getDiProperties(di, propertyNames) {
  return (0, _minDash.reduce)(propertyNames, function (result, key) {
    result[key] = di.get(key);
    return result;
  }, {});
}

function setProperties(businessObject, properties) {
  (0, _minDash.forEach)(properties, function (value, key) {
    if (key !== DI) {
      businessObject.set(key, value);
    } else {
      // only update, if businessObject.di exists
      if (businessObject.di) {
        setDiProperties(businessObject.di, value);
      }
    }
  });
}

function setDiProperties(di, properties) {
  (0, _minDash.forEach)(properties, function (value, key) {
    di.set(key, value);
  });
}

var referencePropertyNames = ['default'];
/**
 * Make sure we unwrap the actual business object
 * behind diagram element that may have been
 * passed as arguments.
 *
 * @param  {Object} properties
 *
 * @return {Object} unwrappedProps
 */

function unwrapBusinessObjects(properties) {
  var unwrappedProps = (0, _minDash.assign)({}, properties);
  referencePropertyNames.forEach(function (name) {
    if (name in properties) {
      unwrappedProps[name] = (0, _ModelUtil.getBusinessObject)(unwrappedProps[name]);
    }
  });
  return unwrappedProps;
}

},{"../../../util/ModelUtil":141,"min-dash":555}],109:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = UpdateSemanticParentHandler;

function UpdateSemanticParentHandler(bpmnUpdater) {
  this._bpmnUpdater = bpmnUpdater;
}

UpdateSemanticParentHandler.$inject = ['bpmnUpdater'];

UpdateSemanticParentHandler.prototype.execute = function (context) {
  var dataStoreBo = context.dataStoreBo,
      newSemanticParent = context.newSemanticParent,
      newDiParent = context.newDiParent;
  context.oldSemanticParent = dataStoreBo.$parent;
  context.oldDiParent = dataStoreBo.di.$parent; // update semantic parent

  this._bpmnUpdater.updateSemanticParent(dataStoreBo, newSemanticParent); // update DI parent


  this._bpmnUpdater.updateDiParent(dataStoreBo.di, newDiParent);
};

UpdateSemanticParentHandler.prototype.revert = function (context) {
  var dataStoreBo = context.dataStoreBo,
      oldSemanticParent = context.oldSemanticParent,
      oldDiParent = context.oldDiParent; // update semantic parent

  this._bpmnUpdater.updateSemanticParent(dataStoreBo, oldSemanticParent); // update DI parent


  this._bpmnUpdater.updateDiParent(dataStoreBo.di, oldDiParent);
};

},{}],110:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _behavior = _interopRequireDefault(require("./behavior"));

var _rules = _interopRequireDefault(require("../rules"));

var _diOrdering = _interopRequireDefault(require("../di-ordering"));

var _ordering = _interopRequireDefault(require("../ordering"));

var _replace = _interopRequireDefault(require("../replace"));

var _command = _interopRequireDefault(require("diagram-js/lib/command"));

var _tooltips = _interopRequireDefault(require("diagram-js/lib/features/tooltips"));

var _labelSupport = _interopRequireDefault(require("diagram-js/lib/features/label-support"));

var _attachSupport = _interopRequireDefault(require("diagram-js/lib/features/attach-support"));

var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection"));

var _changeSupport = _interopRequireDefault(require("diagram-js/lib/features/change-support"));

var _spaceTool = _interopRequireDefault(require("diagram-js/lib/features/space-tool"));

var _BpmnFactory = _interopRequireDefault(require("./BpmnFactory"));

var _BpmnUpdater = _interopRequireDefault(require("./BpmnUpdater"));

var _ElementFactory = _interopRequireDefault(require("./ElementFactory"));

var _Modeling = _interopRequireDefault(require("./Modeling"));

var _BpmnLayouter = _interopRequireDefault(require("./BpmnLayouter"));

var _CroppingConnectionDocking = _interopRequireDefault(require("diagram-js/lib/layout/CroppingConnectionDocking"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['modeling', 'bpmnUpdater'],
  __depends__: [_behavior.default, _rules.default, _diOrdering.default, _ordering.default, _replace.default, _command.default, _tooltips.default, _labelSupport.default, _attachSupport.default, _selection.default, _changeSupport.default, _spaceTool.default],
  bpmnFactory: ['type', _BpmnFactory.default],
  bpmnUpdater: ['type', _BpmnUpdater.default],
  elementFactory: ['type', _ElementFactory.default],
  modeling: ['type', _Modeling.default],
  layouter: ['type', _BpmnLayouter.default],
  connectionDocking: ['type', _CroppingConnectionDocking.default]
};
exports.default = _default;

},{"../di-ordering":36,"../ordering":114,"../replace":124,"../rules":126,"./BpmnFactory":56,"./BpmnLayouter":57,"./BpmnUpdater":58,"./ElementFactory":59,"./Modeling":60,"./behavior":94,"diagram-js/lib/command":147,"diagram-js/lib/features/attach-support":161,"diagram-js/lib/features/change-support":178,"diagram-js/lib/features/label-support":219,"diagram-js/lib/features/selection":278,"diagram-js/lib/features/space-tool":288,"diagram-js/lib/features/tooltips":292,"diagram-js/lib/layout/CroppingConnectionDocking":299}],111:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.collectLanes = collectLanes;
exports.getChildLanes = getChildLanes;
exports.getLanesRoot = getLanesRoot;
exports.computeLanesResize = computeLanesResize;
exports.LANE_INDENTATION = void 0;

var _ModelUtil = require("../../../util/ModelUtil");

var _ModelingUtil = require("./ModelingUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _ResizeUtil = require("diagram-js/lib/features/resize/ResizeUtil");

var abs = Math.abs;

function getTRBLResize(oldBounds, newBounds) {
  return (0, _ResizeUtil.substractTRBL)((0, _LayoutUtil.asTRBL)(newBounds), (0, _LayoutUtil.asTRBL)(oldBounds));
}

var LANE_PARENTS = ['bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess'];
var LANE_INDENTATION = 30;
/**
 * Collect all lane shapes in the given paren
 *
 * @param  {djs.model.Shape} shape
 * @param  {Array<djs.model.Base>} [collectedShapes]
 *
 * @return {Array<djs.model.Base>}
 */

exports.LANE_INDENTATION = LANE_INDENTATION;

function collectLanes(shape, collectedShapes) {
  collectedShapes = collectedShapes || [];
  shape.children.filter(function (s) {
    if ((0, _ModelUtil.is)(s, 'bpmn:Lane')) {
      collectLanes(s, collectedShapes);
      collectedShapes.push(s);
    }
  });
  return collectedShapes;
}
/**
 * Return the lane children of the given element.
 *
 * @param {djs.model.Shape} shape
 *
 * @return {Array<djs.model.Shape>}
 */


function getChildLanes(shape) {
  return shape.children.filter(function (c) {
    return (0, _ModelUtil.is)(c, 'bpmn:Lane');
  });
}
/**
 * Return the root element containing the given lane shape
 *
 * @param {djs.model.Shape} shape
 *
 * @return {djs.model.Shape}
 */


function getLanesRoot(shape) {
  return (0, _ModelingUtil.getParent)(shape, LANE_PARENTS) || shape;
}
/**
 * Compute the required resize operations for lanes
 * adjacent to the given shape, assuming it will be
 * resized to the given new bounds.
 *
 * @param {djs.model.Shape} shape
 * @param {Bounds} newBounds
 *
 * @return {Array<Object>}
 */


function computeLanesResize(shape, newBounds) {
  var rootElement = getLanesRoot(shape);
  var initialShapes = (0, _ModelUtil.is)(rootElement, 'bpmn:Process') ? [] : [rootElement];
  var allLanes = collectLanes(rootElement, initialShapes),
      shapeTrbl = (0, _LayoutUtil.asTRBL)(shape),
      shapeNewTrbl = (0, _LayoutUtil.asTRBL)(newBounds),
      trblResize = getTRBLResize(shape, newBounds),
      resizeNeeded = [];
  allLanes.forEach(function (other) {
    if (other === shape) {
      return;
    }

    var topResize = 0,
        rightResize = trblResize.right,
        bottomResize = 0,
        leftResize = trblResize.left;
    var otherTrbl = (0, _LayoutUtil.asTRBL)(other);

    if (trblResize.top) {
      if (abs(otherTrbl.bottom - shapeTrbl.top) < 10) {
        bottomResize = shapeNewTrbl.top - otherTrbl.bottom;
      }

      if (abs(otherTrbl.top - shapeTrbl.top) < 5) {
        topResize = shapeNewTrbl.top - otherTrbl.top;
      }
    }

    if (trblResize.bottom) {
      if (abs(otherTrbl.top - shapeTrbl.bottom) < 10) {
        topResize = shapeNewTrbl.bottom - otherTrbl.top;
      }

      if (abs(otherTrbl.bottom - shapeTrbl.bottom) < 5) {
        bottomResize = shapeNewTrbl.bottom - otherTrbl.bottom;
      }
    }

    if (topResize || rightResize || bottomResize || leftResize) {
      resizeNeeded.push({
        shape: other,
        newBounds: (0, _ResizeUtil.resizeTRBL)(other, {
          top: topResize,
          right: rightResize,
          bottom: bottomResize,
          left: leftResize
        })
      });
    }
  });
  return resizeNeeded;
}

},{"../../../util/ModelUtil":141,"./ModelingUtil":112,"diagram-js/lib/features/resize/ResizeUtil":268,"diagram-js/lib/layout/LayoutUtil":300}],112:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.isAny = isAny;
exports.getParent = getParent;

var _minDash = require("min-dash");

var _ModelUtil = require("../../../util/ModelUtil");

/**
 * Return true if element has any of the given types.
 *
 * @param {djs.model.Base} element
 * @param {Array<string>} types
 *
 * @return {boolean}
 */
function isAny(element, types) {
  return (0, _minDash.some)(types, function (t) {
    return (0, _ModelUtil.is)(element, t);
  });
}
/**
 * Return the parent of the element with any of the given types.
 *
 * @param {djs.model.Base} element
 * @param {string|Array<string>} anyType
 *
 * @return {djs.model.Base}
 */


function getParent(element, anyType) {
  if (typeof anyType === 'string') {
    anyType = [anyType];
  }

  while (element = element.parent) {
    if (isAny(element, anyType)) {
      return element;
    }
  }

  return null;
}

},{"../../../util/ModelUtil":141,"min-dash":555}],113:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnOrderingProvider;

var _inherits = _interopRequireDefault(require("inherits"));

var _OrderingProvider = _interopRequireDefault(require("diagram-js/lib/features/ordering/OrderingProvider"));

var _ModelingUtil = require("../modeling/util/ModelingUtil");

var _minDash = require("min-dash");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * a simple ordering provider that makes sure:
 *
 * (0) labels and groups are rendered always on top
 * (1) elements are ordered by a {level} property
 */
function BpmnOrderingProvider(eventBus, canvas, translate) {
  _OrderingProvider.default.call(this, eventBus);

  var orders = [{
    type: 'bpmn:SubProcess',
    order: {
      level: 6
    }
  }, {
    type: 'bpmn:SequenceFlow',
    order: {
      level: 3,
      containers: ['bpmn:Participant', 'bpmn:FlowElementsContainer']
    }
  }, // handle DataAssociation(s) like message flows and render them always on top
  {
    type: 'bpmn:DataAssociation',
    order: {
      level: 9,
      containers: ['bpmn:Collaboration', 'bpmn:Process']
    }
  }, {
    type: 'bpmn:MessageFlow',
    order: {
      level: 9,
      containers: ['bpmn:Collaboration']
    }
  }, {
    type: 'bpmn:Association',
    order: {
      level: 6,
      containers: ['bpmn:Participant', 'bpmn:FlowElementsContainer', 'bpmn:Collaboration']
    }
  }, {
    type: 'bpmn:BoundaryEvent',
    order: {
      level: 8
    }
  }, {
    type: 'bpmn:Group',
    order: {
      level: 10,
      containers: ['bpmn:Collaboration', 'bpmn:Process']
    }
  }, {
    type: 'bpmn:FlowElement',
    order: {
      level: 5
    }
  }, {
    type: 'bpmn:Participant',
    order: {
      level: -2
    }
  }, {
    type: 'bpmn:Lane',
    order: {
      level: -1
    }
  }];

  function computeOrder(element) {
    if (element.labelTarget) {
      return {
        level: 10
      };
    }

    var entry = (0, _minDash.find)(orders, function (o) {
      return (0, _ModelingUtil.isAny)(element, [o.type]);
    });
    return entry && entry.order || {
      level: 1
    };
  }

  function getOrder(element) {
    var order = element.order;

    if (!order) {
      element.order = order = computeOrder(element);
    }

    return order;
  }

  function findActualParent(element, newParent, containers) {
    var actualParent = newParent;

    while (actualParent) {
      if ((0, _ModelingUtil.isAny)(actualParent, containers)) {
        break;
      }

      actualParent = actualParent.parent;
    }

    if (!actualParent) {
      throw new Error(translate('no parent for {element} in {parent}', {
        element: element.id,
        parent: newParent.id
      }));
    }

    return actualParent;
  }

  this.getOrdering = function (element, newParent) {
    // render labels always on top
    if (element.labelTarget) {
      return {
        parent: canvas.getRootElement(),
        index: -1
      };
    }

    var elementOrder = getOrder(element);

    if (elementOrder.containers) {
      newParent = findActualParent(element, newParent, elementOrder.containers);
    }

    var currentIndex = newParent.children.indexOf(element);
    var insertIndex = (0, _minDash.findIndex)(newParent.children, function (child) {
      // do not compare with labels, they are created
      // in the wrong order (right after elements) during import and
      // mess up the positioning.
      if (!element.labelTarget && child.labelTarget) {
        return false;
      }

      return elementOrder.level < getOrder(child).level;
    }); // if the element is already in the child list at
    // a smaller index, we need to adjust the insert index.
    // this takes into account that the element is being removed
    // before being re-inserted

    if (insertIndex !== -1) {
      if (currentIndex !== -1 && currentIndex < insertIndex) {
        insertIndex -= 1;
      }
    }

    return {
      index: insertIndex,
      parent: newParent
    };
  };
}

BpmnOrderingProvider.$inject = ['eventBus', 'canvas', 'translate'];
(0, _inherits.default)(BpmnOrderingProvider, _OrderingProvider.default);

},{"../modeling/util/ModelingUtil":112,"diagram-js/lib/features/ordering/OrderingProvider":252,"inherits":347,"min-dash":555}],114:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate"));

var _BpmnOrderingProvider = _interopRequireDefault(require("./BpmnOrderingProvider"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_translate.default],
  __init__: ['bpmnOrderingProvider'],
  bpmnOrderingProvider: ['type', _BpmnOrderingProvider.default]
};
exports.default = _default;

},{"./BpmnOrderingProvider":113,"diagram-js/lib/i18n/translate":296}],115:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = PaletteProvider;

var _minDash = require("min-dash");

/**
 * A palette provider for BPMN 2.0 elements.
 */
function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect, translate) {
  this._palette = palette;
  this._create = create;
  this._elementFactory = elementFactory;
  this._spaceTool = spaceTool;
  this._lassoTool = lassoTool;
  this._handTool = handTool;
  this._globalConnect = globalConnect;
  this._translate = translate;
  palette.registerProvider(this);
}

PaletteProvider.$inject = ['palette', 'create', 'elementFactory', 'spaceTool', 'lassoTool', 'handTool', 'globalConnect', 'translate'];

PaletteProvider.prototype.getPaletteEntries = function (element) {
  var actions = {},
      create = this._create,
      elementFactory = this._elementFactory,
      spaceTool = this._spaceTool,
      lassoTool = this._lassoTool,
      handTool = this._handTool,
      globalConnect = this._globalConnect,
      translate = this._translate;

  function createAction(type, group, className, title, options) {
    function createListener(event) {
      var shape = elementFactory.createShape((0, _minDash.assign)({
        type: type
      }, options));

      if (options) {
        shape.businessObject.di.isExpanded = options.isExpanded;
      }

      create.start(event, shape);
    }

    var shortType = type.replace(/^bpmn:/, '');
    return {
      group: group,
      className: className,
      title: title || translate('Create {type}', {
        type: shortType
      }),
      action: {
        dragstart: createListener,
        click: createListener
      }
    };
  }

  function createSubprocess(event) {
    var subProcess = elementFactory.createShape({
      type: 'bpmn:SubProcess',
      x: 0,
      y: 0,
      isExpanded: true
    });
    var startEvent = elementFactory.createShape({
      type: 'bpmn:StartEvent',
      x: 40,
      y: 82,
      parent: subProcess
    });
    create.start(event, [subProcess, startEvent], {
      hints: {
        autoSelect: [startEvent]
      }
    });
  }

  function createParticipant(event) {
    create.start(event, elementFactory.createParticipantShape());
  }

  (0, _minDash.assign)(actions, {
    'hand-tool': {
      group: 'tools',
      className: 'bpmn-icon-hand-tool',
      title: translate('Activate the hand tool'),
      action: {
        click: function (event) {
          handTool.activateHand(event);
        }
      }
    },
    'lasso-tool': {
      group: 'tools',
      className: 'bpmn-icon-lasso-tool',
      title: translate('Activate the lasso tool'),
      action: {
        click: function (event) {
          lassoTool.activateSelection(event);
        }
      }
    },
    'space-tool': {
      group: 'tools',
      className: 'bpmn-icon-space-tool',
      title: translate('Activate the create/remove space tool'),
      action: {
        click: function (event) {
          spaceTool.activateSelection(event);
        }
      }
    },
    'global-connect-tool': {
      group: 'tools',
      className: 'bpmn-icon-connection-multi',
      title: translate('Activate the global connect tool'),
      action: {
        click: function (event) {
          globalConnect.toggle(event);
        }
      }
    },
    'tool-separator': {
      group: 'tools',
      separator: true
    },
    'create.start-event': createAction('bpmn:StartEvent', 'event', 'bpmn-icon-start-event-none', translate('Create StartEvent')),
    'create.intermediate-event': createAction('bpmn:IntermediateThrowEvent', 'event', 'bpmn-icon-intermediate-event-none', translate('Create Intermediate/Boundary Event')),
    'create.end-event': createAction('bpmn:EndEvent', 'event', 'bpmn-icon-end-event-none', translate('Create EndEvent')),
    'create.exclusive-gateway': createAction('bpmn:ExclusiveGateway', 'gateway', 'bpmn-icon-gateway-none', translate('Create Gateway')),
    'create.task': createAction('bpmn:Task', 'activity', 'bpmn-icon-task', translate('Create Task')),
    'create.data-object': createAction('bpmn:DataObjectReference', 'data-object', 'bpmn-icon-data-object', translate('Create DataObjectReference')),
    'create.data-store': createAction('bpmn:DataStoreReference', 'data-store', 'bpmn-icon-data-store', translate('Create DataStoreReference')),
    'create.subprocess-expanded': {
      group: 'activity',
      className: 'bpmn-icon-subprocess-expanded',
      title: translate('Create expanded SubProcess'),
      action: {
        dragstart: createSubprocess,
        click: createSubprocess
      }
    },
    'create.participant-expanded': {
      group: 'collaboration',
      className: 'bpmn-icon-participant',
      title: translate('Create Pool/Participant'),
      action: {
        dragstart: createParticipant,
        click: createParticipant
      }
    },
    'create.group': createAction('bpmn:Group', 'artifact', 'bpmn-icon-group', translate('Create Group'))
  });
  return actions;
};

},{"min-dash":555}],116:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _palette = _interopRequireDefault(require("diagram-js/lib/features/palette"));

var _create = _interopRequireDefault(require("diagram-js/lib/features/create"));

var _spaceTool = _interopRequireDefault(require("diagram-js/lib/features/space-tool"));

var _lassoTool = _interopRequireDefault(require("diagram-js/lib/features/lasso-tool"));

var _handTool = _interopRequireDefault(require("diagram-js/lib/features/hand-tool"));

var _globalConnect = _interopRequireDefault(require("diagram-js/lib/features/global-connect"));

var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate"));

var _PaletteProvider = _interopRequireDefault(require("./PaletteProvider"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_palette.default, _create.default, _spaceTool.default, _lassoTool.default, _handTool.default, _globalConnect.default, _translate.default],
  __init__: ['paletteProvider'],
  paletteProvider: ['type', _PaletteProvider.default]
};
exports.default = _default;

},{"./PaletteProvider":115,"diagram-js/lib/features/create":192,"diagram-js/lib/features/global-connect":201,"diagram-js/lib/features/hand-tool":209,"diagram-js/lib/features/lasso-tool":221,"diagram-js/lib/features/palette":258,"diagram-js/lib/features/space-tool":288,"diagram-js/lib/i18n/translate":296}],117:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ReplaceMenuProvider;

var _ModelUtil = require("../../util/ModelUtil");

var _DiUtil = require("../../util/DiUtil");

var _TypeUtil = require("./util/TypeUtil");

var _minDash = require("min-dash");

var replaceOptions = _interopRequireWildcard(require("../replace/ReplaceOptions"));

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

/**
 * This module is an element agnostic replace menu provider for the popup menu.
 */
function ReplaceMenuProvider(popupMenu, modeling, moddle, bpmnReplace, rules, translate) {
  this._popupMenu = popupMenu;
  this._modeling = modeling;
  this._moddle = moddle;
  this._bpmnReplace = bpmnReplace;
  this._rules = rules;
  this._translate = translate;
  this.register();
}

ReplaceMenuProvider.$inject = ['popupMenu', 'modeling', 'moddle', 'bpmnReplace', 'rules', 'translate'];
/**
 * Register replace menu provider in the popup menu
 */

ReplaceMenuProvider.prototype.register = function () {
  this._popupMenu.registerProvider('bpmn-replace', this);
};
/**
 * Get all entries from replaceOptions for the given element and apply filters
 * on them. Get for example only elements, which are different from the current one.
 *
 * @param {djs.model.Base} element
 *
 * @return {Array<Object>} a list of menu entry items
 */


ReplaceMenuProvider.prototype.getEntries = function (element) {
  var businessObject = element.businessObject;
  var rules = this._rules;
  var entries;

  if (!rules.allowed('shape.replace', {
    element: element
  })) {
    return [];
  }

  var differentType = (0, _TypeUtil.isDifferentType)(element); // start events outside sub processes

  if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && !(0, _ModelUtil.is)(businessObject.$parent, 'bpmn:SubProcess')) {
    entries = (0, _minDash.filter)(replaceOptions.START_EVENT, differentType);
    return this._createEntries(element, entries);
  } // expanded/collapsed pools


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:Participant')) {
    entries = (0, _minDash.filter)(replaceOptions.PARTICIPANT, function (entry) {
      return (0, _DiUtil.isExpanded)(businessObject) !== entry.target.isExpanded;
    });
    return this._createEntries(element, entries);
  } // start events inside event sub processes


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && (0, _DiUtil.isEventSubProcess)(businessObject.$parent)) {
    entries = (0, _minDash.filter)(replaceOptions.EVENT_SUB_PROCESS_START_EVENT, function (entry) {
      var target = entry.target;
      var isInterrupting = target.isInterrupting !== false;
      var isInterruptingEqual = (0, _ModelUtil.getBusinessObject)(element).isInterrupting === isInterrupting; // filters elements which types and event definition are equal but have have different interrupting types

      return differentType(entry) || !differentType(entry) && !isInterruptingEqual;
    });
    return this._createEntries(element, entries);
  } // start events inside sub processes


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && !(0, _DiUtil.isEventSubProcess)(businessObject.$parent) && (0, _ModelUtil.is)(businessObject.$parent, 'bpmn:SubProcess')) {
    entries = (0, _minDash.filter)(replaceOptions.START_EVENT_SUB_PROCESS, differentType);
    return this._createEntries(element, entries);
  } // end events


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:EndEvent')) {
    entries = (0, _minDash.filter)(replaceOptions.END_EVENT, function (entry) {
      var target = entry.target; // hide cancel end events outside transactions

      if (target.eventDefinitionType == 'bpmn:CancelEventDefinition' && !(0, _ModelUtil.is)(businessObject.$parent, 'bpmn:Transaction')) {
        return false;
      }

      return differentType(entry);
    });
    return this._createEntries(element, entries);
  } // boundary events


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:BoundaryEvent')) {
    entries = (0, _minDash.filter)(replaceOptions.BOUNDARY_EVENT, function (entry) {
      var target = entry.target;

      if (target.eventDefinition == 'bpmn:CancelEventDefinition' && !(0, _ModelUtil.is)(businessObject.attachedToRef, 'bpmn:Transaction')) {
        return false;
      }

      var cancelActivity = target.cancelActivity !== false;
      var isCancelActivityEqual = businessObject.cancelActivity == cancelActivity;
      return differentType(entry) || !differentType(entry) && !isCancelActivityEqual;
    });
    return this._createEntries(element, entries);
  } // intermediate events


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:IntermediateCatchEvent') || (0, _ModelUtil.is)(businessObject, 'bpmn:IntermediateThrowEvent')) {
    entries = (0, _minDash.filter)(replaceOptions.INTERMEDIATE_EVENT, differentType);
    return this._createEntries(element, entries);
  } // gateways


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:Gateway')) {
    entries = (0, _minDash.filter)(replaceOptions.GATEWAY, differentType);
    return this._createEntries(element, entries);
  } // transactions


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:Transaction')) {
    entries = (0, _minDash.filter)(replaceOptions.TRANSACTION, differentType);
    return this._createEntries(element, entries);
  } // expanded event sub processes


  if ((0, _DiUtil.isEventSubProcess)(businessObject) && (0, _DiUtil.isExpanded)(businessObject)) {
    entries = (0, _minDash.filter)(replaceOptions.EVENT_SUB_PROCESS, differentType);
    return this._createEntries(element, entries);
  } // expanded sub processes


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(businessObject)) {
    entries = (0, _minDash.filter)(replaceOptions.SUBPROCESS_EXPANDED, differentType);
    return this._createEntries(element, entries);
  } // collapsed ad hoc sub processes


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:AdHocSubProcess') && !(0, _DiUtil.isExpanded)(businessObject)) {
    entries = (0, _minDash.filter)(replaceOptions.TASK, function (entry) {
      var target = entry.target;
      var isTargetSubProcess = target.type === 'bpmn:SubProcess';
      var isTargetExpanded = target.isExpanded === true;
      return (0, _TypeUtil.isDifferentType)(element, target) && (!isTargetSubProcess || isTargetExpanded);
    });
    return this._createEntries(element, entries);
  } // sequence flows


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:SequenceFlow')) {
    return this._createSequenceFlowEntries(element, replaceOptions.SEQUENCE_FLOW);
  } // flow nodes


  if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowNode')) {
    entries = (0, _minDash.filter)(replaceOptions.TASK, differentType); // collapsed SubProcess can not be replaced with itself

    if ((0, _ModelUtil.is)(businessObject, 'bpmn:SubProcess') && !(0, _DiUtil.isExpanded)(businessObject)) {
      entries = (0, _minDash.filter)(entries, function (entry) {
        return entry.label !== 'Sub Process (collapsed)';
      });
    }

    return this._createEntries(element, entries);
  }

  return [];
};
/**
 * Get a list of header items for the given element. This includes buttons
 * for multi instance markers and for the ad hoc marker.
 *
 * @param {djs.model.Base} element
 *
 * @return {Array<Object>} a list of menu entry items
 */


ReplaceMenuProvider.prototype.getHeaderEntries = function (element) {
  var headerEntries = [];

  if ((0, _ModelUtil.is)(element, 'bpmn:Activity') && !(0, _DiUtil.isEventSubProcess)(element)) {
    headerEntries = headerEntries.concat(this._getLoopEntries(element));
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess') && !(0, _ModelUtil.is)(element, 'bpmn:Transaction') && !(0, _DiUtil.isEventSubProcess)(element)) {
    headerEntries.push(this._getAdHocEntry(element));
  }

  return headerEntries;
};
/**
 * Creates an array of menu entry objects for a given element and filters the replaceOptions
 * according to a filter function.
 *
 * @param  {djs.model.Base} element
 * @param  {Object} replaceOptions
 *
 * @return {Array<Object>} a list of menu items
 */


ReplaceMenuProvider.prototype._createEntries = function (element, replaceOptions) {
  var menuEntries = [];
  var self = this;
  (0, _minDash.forEach)(replaceOptions, function (definition) {
    var entry = self._createMenuEntry(definition, element);

    menuEntries.push(entry);
  });
  return menuEntries;
};
/**
 * Creates an array of menu entry objects for a given sequence flow.
 *
 * @param  {djs.model.Base} element
 * @param  {Object} replaceOptions

 * @return {Array<Object>} a list of menu items
 */


ReplaceMenuProvider.prototype._createSequenceFlowEntries = function (element, replaceOptions) {
  var businessObject = (0, _ModelUtil.getBusinessObject)(element);
  var menuEntries = [];
  var modeling = this._modeling,
      moddle = this._moddle;
  var self = this;
  (0, _minDash.forEach)(replaceOptions, function (entry) {
    switch (entry.actionName) {
      case 'replace-with-default-flow':
        if (businessObject.sourceRef.default !== businessObject && ((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ComplexGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity'))) {
          menuEntries.push(self._createMenuEntry(entry, element, function () {
            modeling.updateProperties(element.source, {
              default: businessObject
            });
          }));
        }

        break;

      case 'replace-with-conditional-flow':
        if (!businessObject.conditionExpression && (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity')) {
          menuEntries.push(self._createMenuEntry(entry, element, function () {
            var conditionExpression = moddle.create('bpmn:FormalExpression', {
              body: ''
            });
            modeling.updateProperties(element, {
              conditionExpression: conditionExpression
            });
          }));
        }

        break;

      default:
        // default flows
        if ((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity') && businessObject.conditionExpression) {
          return menuEntries.push(self._createMenuEntry(entry, element, function () {
            modeling.updateProperties(element, {
              conditionExpression: undefined
            });
          }));
        } // conditional flows


        if (((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ComplexGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity')) && businessObject.sourceRef.default === businessObject) {
          return menuEntries.push(self._createMenuEntry(entry, element, function () {
            modeling.updateProperties(element.source, {
              default: undefined
            });
          }));
        }

    }
  });
  return menuEntries;
};
/**
 * Creates and returns a single menu entry item.
 *
 * @param  {Object} definition a single replace options definition object
 * @param  {djs.model.Base} element
 * @param  {Function} [action] an action callback function which gets called when
 *                             the menu entry is being triggered.
 *
 * @return {Object} menu entry item
 */


ReplaceMenuProvider.prototype._createMenuEntry = function (definition, element, action) {
  var translate = this._translate;
  var replaceElement = this._bpmnReplace.replaceElement;

  var replaceAction = function () {
    return replaceElement(element, definition.target);
  };

  action = action || replaceAction;
  var menuEntry = {
    label: translate(definition.label),
    className: definition.className,
    id: definition.actionName,
    action: action
  };
  return menuEntry;
};
/**
 * Get a list of menu items containing buttons for multi instance markers
 *
 * @param  {djs.model.Base} element
 *
 * @return {Array<Object>} a list of menu items
 */


ReplaceMenuProvider.prototype._getLoopEntries = function (element) {
  var self = this;
  var translate = this._translate;

  function toggleLoopEntry(event, entry) {
    var loopCharacteristics;

    if (entry.active) {
      loopCharacteristics = undefined;
    } else {
      loopCharacteristics = self._moddle.create(entry.options.loopCharacteristics);

      if (entry.options.isSequential) {
        loopCharacteristics.isSequential = entry.options.isSequential;
      }
    }

    self._modeling.updateProperties(element, {
      loopCharacteristics: loopCharacteristics
    });
  }

  var businessObject = (0, _ModelUtil.getBusinessObject)(element),
      loopCharacteristics = businessObject.loopCharacteristics;
  var isSequential, isLoop, isParallel;

  if (loopCharacteristics) {
    isSequential = loopCharacteristics.isSequential;
    isLoop = loopCharacteristics.isSequential === undefined;
    isParallel = loopCharacteristics.isSequential !== undefined && !loopCharacteristics.isSequential;
  }

  var loopEntries = [{
    id: 'toggle-parallel-mi',
    className: 'bpmn-icon-parallel-mi-marker',
    title: translate('Parallel Multi Instance'),
    active: isParallel,
    action: toggleLoopEntry,
    options: {
      loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics',
      isSequential: false
    }
  }, {
    id: 'toggle-sequential-mi',
    className: 'bpmn-icon-sequential-mi-marker',
    title: translate('Sequential Multi Instance'),
    active: isSequential,
    action: toggleLoopEntry,
    options: {
      loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics',
      isSequential: true
    }
  }, {
    id: 'toggle-loop',
    className: 'bpmn-icon-loop-marker',
    title: translate('Loop'),
    active: isLoop,
    action: toggleLoopEntry,
    options: {
      loopCharacteristics: 'bpmn:StandardLoopCharacteristics'
    }
  }];
  return loopEntries;
};
/**
 * Get the menu items containing a button for the ad hoc marker
 *
 * @param  {djs.model.Base} element
 *
 * @return {Object} a menu item
 */


ReplaceMenuProvider.prototype._getAdHocEntry = function (element) {
  var translate = this._translate;
  var businessObject = (0, _ModelUtil.getBusinessObject)(element);
  var isAdHoc = (0, _ModelUtil.is)(businessObject, 'bpmn:AdHocSubProcess');
  var replaceElement = this._bpmnReplace.replaceElement;
  var adHocEntry = {
    id: 'toggle-adhoc',
    className: 'bpmn-icon-ad-hoc-marker',
    title: translate('Ad-hoc'),
    active: isAdHoc,
    action: function (event, entry) {
      if (isAdHoc) {
        return replaceElement(element, {
          type: 'bpmn:SubProcess'
        }, {
          autoResize: false,
          layoutConnection: false
        });
      } else {
        return replaceElement(element, {
          type: 'bpmn:AdHocSubProcess'
        }, {
          autoResize: false,
          layoutConnection: false
        });
      }
    }
  };
  return adHocEntry;
};

},{"../../util/DiUtil":139,"../../util/ModelUtil":141,"../replace/ReplaceOptions":123,"./util/TypeUtil":119,"min-dash":555}],118:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _popupMenu = _interopRequireDefault(require("diagram-js/lib/features/popup-menu"));

var _replace = _interopRequireDefault(require("../replace"));

var _ReplaceMenuProvider = _interopRequireDefault(require("./ReplaceMenuProvider"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_popupMenu.default, _replace.default],
  __init__: ['replaceMenuProvider'],
  replaceMenuProvider: ['type', _ReplaceMenuProvider.default]
};
exports.default = _default;

},{"../replace":124,"./ReplaceMenuProvider":117,"diagram-js/lib/features/popup-menu":260}],119:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.isDifferentType = isDifferentType;

var _ModelUtil = require("../../../util/ModelUtil");

var _DiUtil = require("../../../util/DiUtil");

/**
 * Returns true, if an element is from a different type
 * than a target definition. Takes into account the type,
 * event definition type and triggeredByEvent property.
 *
 * @param {djs.model.Base} element
 *
 * @return {boolean}
 */
function isDifferentType(element) {
  return function (entry) {
    var target = entry.target;
    var businessObject = (0, _ModelUtil.getBusinessObject)(element),
        eventDefinition = businessObject.eventDefinitions && businessObject.eventDefinitions[0];
    var isTypeEqual = businessObject.$type === target.type;
    var isEventDefinitionEqual = (eventDefinition && eventDefinition.$type) === target.eventDefinitionType;
    var isTriggeredByEventEqual = businessObject.triggeredByEvent === target.triggeredByEvent;
    var isExpandedEqual = target.isExpanded === undefined || target.isExpanded === (0, _DiUtil.isExpanded)(businessObject);
    return !isTypeEqual || !isEventDefinitionEqual || !isTriggeredByEventEqual || !isExpandedEqual;
  };
}

},{"../../../util/DiUtil":139,"../../../util/ModelUtil":141}],120:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnReplacePreview;

var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor"));

var _inherits = _interopRequireDefault(require("inherits"));

var _css = _interopRequireDefault(require("css.escape"));

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _tinySvg = require("tiny-svg");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LOW_PRIORITY = 250;

function BpmnReplacePreview(eventBus, elementRegistry, elementFactory, canvas, previewSupport) {
  _CommandInterceptor.default.call(this, eventBus);
  /**
   * Replace the visuals of all elements in the context which can be replaced
   *
   * @param  {Object} context
   */


  function replaceVisual(context) {
    var replacements = context.canExecute.replacements;
    (0, _minDash.forEach)(replacements, function (replacement) {
      var id = replacement.oldElementId;
      var newElement = {
        type: replacement.newElementType
      }; // if the visual of the element is already replaced

      if (context.visualReplacements[id]) {
        return;
      }

      var element = elementRegistry.get(id);
      (0, _minDash.assign)(newElement, {
        x: element.x,
        y: element.y
      }); // create a temporary shape

      var tempShape = elementFactory.createShape(newElement);
      canvas.addShape(tempShape, element.parent); // select the original SVG element related to the element and hide it

      var gfx = (0, _minDom.query)('[data-element-id="' + (0, _css.default)(element.id) + '"]', context.dragGroup);

      if (gfx) {
        (0, _tinySvg.attr)(gfx, {
          display: 'none'
        });
      } // clone the gfx of the temporary shape and add it to the drag group


      var dragger = previewSupport.addDragger(tempShape, context.dragGroup);
      context.visualReplacements[id] = dragger;
      canvas.removeShape(tempShape);
    });
  }
  /**
   * Restore the original visuals of the previously replaced elements
   *
   * @param  {Object} context
   */


  function restoreVisual(context) {
    var visualReplacements = context.visualReplacements;
    (0, _minDash.forEach)(visualReplacements, function (dragger, id) {
      var originalGfx = (0, _minDom.query)('[data-element-id="' + (0, _css.default)(id) + '"]', context.dragGroup);

      if (originalGfx) {
        (0, _tinySvg.attr)(originalGfx, {
          display: 'inline'
        });
      }

      dragger.remove();

      if (visualReplacements[id]) {
        delete visualReplacements[id];
      }
    });
  }

  eventBus.on('shape.move.move', LOW_PRIORITY, function (event) {
    var context = event.context,
        canExecute = context.canExecute;

    if (!context.visualReplacements) {
      context.visualReplacements = {};
    }

    if (canExecute && canExecute.replacements) {
      replaceVisual(context);
    } else {
      restoreVisual(context);
    }
  });
}

BpmnReplacePreview.$inject = ['eventBus', 'elementRegistry', 'elementFactory', 'canvas', 'previewSupport'];
(0, _inherits.default)(BpmnReplacePreview, _CommandInterceptor.default);

},{"css.escape":331,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555,"min-dom":556,"tiny-svg":567}],121:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _previewSupport = _interopRequireDefault(require("diagram-js/lib/features/preview-support"));

var _BpmnReplacePreview = _interopRequireDefault(require("./BpmnReplacePreview"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_previewSupport.default],
  __init__: ['bpmnReplacePreview'],
  bpmnReplacePreview: ['type', _BpmnReplacePreview.default]
};
exports.default = _default;

},{"./BpmnReplacePreview":120,"diagram-js/lib/features/preview-support":262}],122:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnReplace;

var _minDash = require("min-dash");

var _ModelUtil = require("../../util/ModelUtil");

var _ModelingUtil = require("../modeling/util/ModelingUtil");

var _DiUtil = require("../../util/DiUtil");

var _ModdleCopy = require("../copy-paste/ModdleCopy");

function copyProperties(source, target, properties) {
  if (!(0, _minDash.isArray)(properties)) {
    properties = [properties];
  }

  (0, _minDash.forEach)(properties, function (property) {
    if (!(0, _minDash.isUndefined)(source[property])) {
      target[property] = source[property];
    }
  });
}

var CUSTOM_PROPERTIES = ['cancelActivity', 'instantiate', 'eventGatewayType', 'triggeredByEvent', 'isInterrupting'];

function toggeling(element, target) {
  var oldCollapsed = element && (0, _minDash.has)(element, 'collapsed') ? element.collapsed : !(0, _DiUtil.isExpanded)(element);
  var targetCollapsed;

  if (target && ((0, _minDash.has)(target, 'collapsed') || (0, _minDash.has)(target, 'isExpanded'))) {
    // property is explicitly set so use it
    targetCollapsed = (0, _minDash.has)(target, 'collapsed') ? target.collapsed : !target.isExpanded;
  } else {
    // keep old state
    targetCollapsed = oldCollapsed;
  }

  if (oldCollapsed !== targetCollapsed) {
    element.collapsed = oldCollapsed;
    return true;
  }

  return false;
}
/**
 * This module takes care of replacing BPMN elements
 */


function BpmnReplace(bpmnFactory, elementFactory, moddleCopy, modeling, replace, selection) {
  /**
   * Prepares a new business object for the replacement element
   * and triggers the replace operation.
   *
   * @param  {djs.model.Base} element
   * @param  {Object} target
   * @param  {Object} [hints]
   *
   * @return {djs.model.Base} the newly created element
   */
  function replaceElement(element, target, hints) {
    hints = hints || {};
    var type = target.type,
        oldBusinessObject = element.businessObject;

    if (isSubProcess(oldBusinessObject)) {
      if (type === 'bpmn:SubProcess') {
        if (toggeling(element, target)) {
          // expanding or collapsing process
          modeling.toggleCollapse(element);
          return element;
        }
      }
    }

    var newBusinessObject = bpmnFactory.create(type);
    var newElement = {
      type: type,
      businessObject: newBusinessObject
    };
    var elementProps = (0, _ModdleCopy.getPropertyNames)(oldBusinessObject.$descriptor),
        newElementProps = (0, _ModdleCopy.getPropertyNames)(newBusinessObject.$descriptor, true),
        copyProps = intersection(elementProps, newElementProps); // initialize special properties defined in target definition

    (0, _minDash.assign)(newBusinessObject, (0, _minDash.pick)(target, CUSTOM_PROPERTIES));
    var properties = (0, _minDash.filter)(copyProps, function (propertyName) {
      // copying event definitions, unless we replace
      if (propertyName === 'eventDefinitions') {
        return hasEventDefinition(element, target.eventDefinitionType);
      } // retain loop characteristics if the target element
      // is not an event sub process


      if (propertyName === 'loopCharacteristics') {
        return !(0, _DiUtil.isEventSubProcess)(newBusinessObject);
      } // so the applied properties from 'target' don't get lost


      if (newBusinessObject.hasOwnProperty(propertyName)) {
        return false;
      }

      if (propertyName === 'processRef' && target.isExpanded === false) {
        return false;
      }

      if (propertyName === 'triggeredByEvent') {
        return false;
      }

      return true;
    });
    newBusinessObject = moddleCopy.copyElement(oldBusinessObject, newBusinessObject, properties); // initialize custom BPMN extensions

    if (target.eventDefinitionType) {
      // only initialize with new eventDefinition
      // if we did not set an event definition yet,
      // i.e. because we copied it
      if (!hasEventDefinition(newBusinessObject, target.eventDefinitionType)) {
        newElement.eventDefinitionType = target.eventDefinitionType;
        newElement.eventDefinitionAttrs = target.eventDefinitionAttrs;
      }
    }

    if ((0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Activity')) {
      if (isSubProcess(oldBusinessObject)) {
        // no toggeling, so keep old state
        newElement.isExpanded = (0, _DiUtil.isExpanded)(oldBusinessObject);
      } // else if property is explicitly set, use it
      else if (target && (0, _minDash.has)(target, 'isExpanded')) {
          newElement.isExpanded = target.isExpanded;
        } // TODO: need also to respect min/max Size
      // copy size, from an expanded subprocess to an expanded alternative subprocess
      // except bpmn:Task, because Task is always expanded


      if ((0, _DiUtil.isExpanded)(oldBusinessObject) && !(0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Task') && newElement.isExpanded) {
        newElement.width = element.width;
        newElement.height = element.height;
      }
    } // remove children if not expanding sub process


    if (isSubProcess(oldBusinessObject) && !isSubProcess(newBusinessObject)) {
      hints.moveChildren = false;
    } // transform collapsed/expanded pools


    if ((0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Participant')) {
      // create expanded pool
      if (target.isExpanded === true) {
        newBusinessObject.processRef = bpmnFactory.create('bpmn:Process');
      } else {
        // remove children when transforming to collapsed pool
        hints.moveChildren = false;
      } // apply same width and default height


      newElement.width = element.width;
      newElement.height = elementFactory._getDefaultSize(newBusinessObject).height;
    }

    newBusinessObject.name = oldBusinessObject.name; // retain default flow's reference between inclusive <-> exclusive gateways and activities

    if ((0, _ModelingUtil.isAny)(oldBusinessObject, ['bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:Activity']) && (0, _ModelingUtil.isAny)(newBusinessObject, ['bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:Activity'])) {
      newBusinessObject.default = oldBusinessObject.default;
    }

    if (target.host && !(0, _ModelUtil.is)(oldBusinessObject, 'bpmn:BoundaryEvent') && (0, _ModelUtil.is)(newBusinessObject, 'bpmn:BoundaryEvent')) {
      newElement.host = target.host;
    }

    newElement.di = {}; // fill and stroke will be set to DI

    copyProperties(oldBusinessObject.di, newElement.di, ['fill', 'stroke']);
    newElement = replace.replaceElement(element, newElement, hints);

    if (hints.select !== false) {
      selection.select(newElement);
    }

    return newElement;
  }

  this.replaceElement = replaceElement;
}

BpmnReplace.$inject = ['bpmnFactory', 'elementFactory', 'moddleCopy', 'modeling', 'replace', 'selection'];

function isSubProcess(bo) {
  return (0, _ModelUtil.is)(bo, 'bpmn:SubProcess');
}

function hasEventDefinition(element, type) {
  var bo = (0, _ModelUtil.getBusinessObject)(element);
  return type && bo.get('eventDefinitions').some(function (definition) {
    return (0, _ModelUtil.is)(definition, type);
  });
}
/**
 * Compute intersection between two arrays.
 */


function intersection(a1, a2) {
  return a1.filter(function (el) {
    return a2.indexOf(el) !== -1;
  });
}

},{"../../util/DiUtil":139,"../../util/ModelUtil":141,"../copy-paste/ModdleCopy":33,"../modeling/util/ModelingUtil":112,"min-dash":555}],123:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.PARTICIPANT = exports.SEQUENCE_FLOW = exports.EVENT_SUB_PROCESS_START_EVENT = exports.BOUNDARY_EVENT = exports.TASK = exports.EVENT_SUB_PROCESS = exports.TRANSACTION = exports.SUBPROCESS_EXPANDED = exports.GATEWAY = exports.END_EVENT = exports.INTERMEDIATE_EVENT = exports.START_EVENT_SUB_PROCESS = exports.START_EVENT = void 0;
var START_EVENT = [{
  label: 'Start Event',
  actionName: 'replace-with-none-start',
  className: 'bpmn-icon-start-event-none',
  target: {
    type: 'bpmn:StartEvent'
  }
}, {
  label: 'Intermediate Throw Event',
  actionName: 'replace-with-none-intermediate-throwing',
  className: 'bpmn-icon-intermediate-event-none',
  target: {
    type: 'bpmn:IntermediateThrowEvent'
  }
}, {
  label: 'End Event',
  actionName: 'replace-with-none-end',
  className: 'bpmn-icon-end-event-none',
  target: {
    type: 'bpmn:EndEvent'
  }
}, {
  label: 'Message Start Event',
  actionName: 'replace-with-message-start',
  className: 'bpmn-icon-start-event-message',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:MessageEventDefinition'
  }
}, {
  label: 'Timer Start Event',
  actionName: 'replace-with-timer-start',
  className: 'bpmn-icon-start-event-timer',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:TimerEventDefinition'
  }
}, {
  label: 'Conditional Start Event',
  actionName: 'replace-with-conditional-start',
  className: 'bpmn-icon-start-event-condition',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:ConditionalEventDefinition'
  }
}, {
  label: 'Signal Start Event',
  actionName: 'replace-with-signal-start',
  className: 'bpmn-icon-start-event-signal',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:SignalEventDefinition'
  }
}];
exports.START_EVENT = START_EVENT;
var START_EVENT_SUB_PROCESS = [{
  label: 'Start Event',
  actionName: 'replace-with-none-start',
  className: 'bpmn-icon-start-event-none',
  target: {
    type: 'bpmn:StartEvent'
  }
}, {
  label: 'Intermediate Throw Event',
  actionName: 'replace-with-none-intermediate-throwing',
  className: 'bpmn-icon-intermediate-event-none',
  target: {
    type: 'bpmn:IntermediateThrowEvent'
  }
}, {
  label: 'End Event',
  actionName: 'replace-with-none-end',
  className: 'bpmn-icon-end-event-none',
  target: {
    type: 'bpmn:EndEvent'
  }
}];
exports.START_EVENT_SUB_PROCESS = START_EVENT_SUB_PROCESS;
var INTERMEDIATE_EVENT = [{
  label: 'Start Event',
  actionName: 'replace-with-none-start',
  className: 'bpmn-icon-start-event-none',
  target: {
    type: 'bpmn:StartEvent'
  }
}, {
  label: 'Intermediate Throw Event',
  actionName: 'replace-with-none-intermediate-throw',
  className: 'bpmn-icon-intermediate-event-none',
  target: {
    type: 'bpmn:IntermediateThrowEvent'
  }
}, {
  label: 'End Event',
  actionName: 'replace-with-none-end',
  className: 'bpmn-icon-end-event-none',
  target: {
    type: 'bpmn:EndEvent'
  }
}, {
  label: 'Message Intermediate Catch Event',
  actionName: 'replace-with-message-intermediate-catch',
  className: 'bpmn-icon-intermediate-event-catch-message',
  target: {
    type: 'bpmn:IntermediateCatchEvent',
    eventDefinitionType: 'bpmn:MessageEventDefinition'
  }
}, {
  label: 'Message Intermediate Throw Event',
  actionName: 'replace-with-message-intermediate-throw',
  className: 'bpmn-icon-intermediate-event-throw-message',
  target: {
    type: 'bpmn:IntermediateThrowEvent',
    eventDefinitionType: 'bpmn:MessageEventDefinition'
  }
}, {
  label: 'Timer Intermediate Catch Event',
  actionName: 'replace-with-timer-intermediate-catch',
  className: 'bpmn-icon-intermediate-event-catch-timer',
  target: {
    type: 'bpmn:IntermediateCatchEvent',
    eventDefinitionType: 'bpmn:TimerEventDefinition'
  }
}, {
  label: 'Escalation Intermediate Throw Event',
  actionName: 'replace-with-escalation-intermediate-throw',
  className: 'bpmn-icon-intermediate-event-throw-escalation',
  target: {
    type: 'bpmn:IntermediateThrowEvent',
    eventDefinitionType: 'bpmn:EscalationEventDefinition'
  }
}, {
  label: 'Conditional Intermediate Catch Event',
  actionName: 'replace-with-conditional-intermediate-catch',
  className: 'bpmn-icon-intermediate-event-catch-condition',
  target: {
    type: 'bpmn:IntermediateCatchEvent',
    eventDefinitionType: 'bpmn:ConditionalEventDefinition'
  }
}, {
  label: 'Link Intermediate Catch Event',
  actionName: 'replace-with-link-intermediate-catch',
  className: 'bpmn-icon-intermediate-event-catch-link',
  target: {
    type: 'bpmn:IntermediateCatchEvent',
    eventDefinitionType: 'bpmn:LinkEventDefinition',
    eventDefinitionAttrs: {
      name: ''
    }
  }
}, {
  label: 'Link Intermediate Throw Event',
  actionName: 'replace-with-link-intermediate-throw',
  className: 'bpmn-icon-intermediate-event-throw-link',
  target: {
    type: 'bpmn:IntermediateThrowEvent',
    eventDefinitionType: 'bpmn:LinkEventDefinition',
    eventDefinitionAttrs: {
      name: ''
    }
  }
}, {
  label: 'Compensation Intermediate Throw Event',
  actionName: 'replace-with-compensation-intermediate-throw',
  className: 'bpmn-icon-intermediate-event-throw-compensation',
  target: {
    type: 'bpmn:IntermediateThrowEvent',
    eventDefinitionType: 'bpmn:CompensateEventDefinition'
  }
}, {
  label: 'Signal Intermediate Catch Event',
  actionName: 'replace-with-signal-intermediate-catch',
  className: 'bpmn-icon-intermediate-event-catch-signal',
  target: {
    type: 'bpmn:IntermediateCatchEvent',
    eventDefinitionType: 'bpmn:SignalEventDefinition'
  }
}, {
  label: 'Signal Intermediate Throw Event',
  actionName: 'replace-with-signal-intermediate-throw',
  className: 'bpmn-icon-intermediate-event-throw-signal',
  target: {
    type: 'bpmn:IntermediateThrowEvent',
    eventDefinitionType: 'bpmn:SignalEventDefinition'
  }
}];
exports.INTERMEDIATE_EVENT = INTERMEDIATE_EVENT;
var END_EVENT = [{
  label: 'Start Event',
  actionName: 'replace-with-none-start',
  className: 'bpmn-icon-start-event-none',
  target: {
    type: 'bpmn:StartEvent'
  }
}, {
  label: 'Intermediate Throw Event',
  actionName: 'replace-with-none-intermediate-throw',
  className: 'bpmn-icon-intermediate-event-none',
  target: {
    type: 'bpmn:IntermediateThrowEvent'
  }
}, {
  label: 'End Event',
  actionName: 'replace-with-none-end',
  className: 'bpmn-icon-end-event-none',
  target: {
    type: 'bpmn:EndEvent'
  }
}, {
  label: 'Message End Event',
  actionName: 'replace-with-message-end',
  className: 'bpmn-icon-end-event-message',
  target: {
    type: 'bpmn:EndEvent',
    eventDefinitionType: 'bpmn:MessageEventDefinition'
  }
}, {
  label: 'Escalation End Event',
  actionName: 'replace-with-escalation-end',
  className: 'bpmn-icon-end-event-escalation',
  target: {
    type: 'bpmn:EndEvent',
    eventDefinitionType: 'bpmn:EscalationEventDefinition'
  }
}, {
  label: 'Error End Event',
  actionName: 'replace-with-error-end',
  className: 'bpmn-icon-end-event-error',
  target: {
    type: 'bpmn:EndEvent',
    eventDefinitionType: 'bpmn:ErrorEventDefinition'
  }
}, {
  label: 'Cancel End Event',
  actionName: 'replace-with-cancel-end',
  className: 'bpmn-icon-end-event-cancel',
  target: {
    type: 'bpmn:EndEvent',
    eventDefinitionType: 'bpmn:CancelEventDefinition'
  }
}, {
  label: 'Compensation End Event',
  actionName: 'replace-with-compensation-end',
  className: 'bpmn-icon-end-event-compensation',
  target: {
    type: 'bpmn:EndEvent',
    eventDefinitionType: 'bpmn:CompensateEventDefinition'
  }
}, {
  label: 'Signal End Event',
  actionName: 'replace-with-signal-end',
  className: 'bpmn-icon-end-event-signal',
  target: {
    type: 'bpmn:EndEvent',
    eventDefinitionType: 'bpmn:SignalEventDefinition'
  }
}, {
  label: 'Terminate End Event',
  actionName: 'replace-with-terminate-end',
  className: 'bpmn-icon-end-event-terminate',
  target: {
    type: 'bpmn:EndEvent',
    eventDefinitionType: 'bpmn:TerminateEventDefinition'
  }
}];
exports.END_EVENT = END_EVENT;
var GATEWAY = [{
  label: 'Exclusive Gateway',
  actionName: 'replace-with-exclusive-gateway',
  className: 'bpmn-icon-gateway-xor',
  target: {
    type: 'bpmn:ExclusiveGateway'
  }
}, {
  label: 'Parallel Gateway',
  actionName: 'replace-with-parallel-gateway',
  className: 'bpmn-icon-gateway-parallel',
  target: {
    type: 'bpmn:ParallelGateway'
  }
}, {
  label: 'Inclusive Gateway',
  actionName: 'replace-with-inclusive-gateway',
  className: 'bpmn-icon-gateway-or',
  target: {
    type: 'bpmn:InclusiveGateway'
  }
}, {
  label: 'Complex Gateway',
  actionName: 'replace-with-complex-gateway',
  className: 'bpmn-icon-gateway-complex',
  target: {
    type: 'bpmn:ComplexGateway'
  }
}, {
  label: 'Event based Gateway',
  actionName: 'replace-with-event-based-gateway',
  className: 'bpmn-icon-gateway-eventbased',
  target: {
    type: 'bpmn:EventBasedGateway',
    instantiate: false,
    eventGatewayType: 'Exclusive'
  }
} // Gateways deactivated until https://github.com/bpmn-io/bpmn-js/issues/194
// {
//   label: 'Event based instantiating Gateway',
//   actionName: 'replace-with-exclusive-event-based-gateway',
//   className: 'bpmn-icon-exclusive-event-based',
//   target: {
//     type: 'bpmn:EventBasedGateway'
//   },
//   options: {
//     businessObject: { instantiate: true, eventGatewayType: 'Exclusive' }
//   }
// },
// {
//   label: 'Parallel Event based instantiating Gateway',
//   actionName: 'replace-with-parallel-event-based-instantiate-gateway',
//   className: 'bpmn-icon-parallel-event-based-instantiate-gateway',
//   target: {
//     type: 'bpmn:EventBasedGateway'
//   },
//   options: {
//     businessObject: { instantiate: true, eventGatewayType: 'Parallel' }
//   }
// }
];
exports.GATEWAY = GATEWAY;
var SUBPROCESS_EXPANDED = [{
  label: 'Transaction',
  actionName: 'replace-with-transaction',
  className: 'bpmn-icon-transaction',
  target: {
    type: 'bpmn:Transaction',
    isExpanded: true
  }
}, {
  label: 'Event Sub Process',
  actionName: 'replace-with-event-subprocess',
  className: 'bpmn-icon-event-subprocess-expanded',
  target: {
    type: 'bpmn:SubProcess',
    triggeredByEvent: true,
    isExpanded: true
  }
}, {
  label: 'Sub Process (collapsed)',
  actionName: 'replace-with-collapsed-subprocess',
  className: 'bpmn-icon-subprocess-collapsed',
  target: {
    type: 'bpmn:SubProcess',
    isExpanded: false
  }
}];
exports.SUBPROCESS_EXPANDED = SUBPROCESS_EXPANDED;
var TRANSACTION = [{
  label: 'Sub Process',
  actionName: 'replace-with-subprocess',
  className: 'bpmn-icon-subprocess-expanded',
  target: {
    type: 'bpmn:SubProcess',
    isExpanded: true
  }
}, {
  label: 'Event Sub Process',
  actionName: 'replace-with-event-subprocess',
  className: 'bpmn-icon-event-subprocess-expanded',
  target: {
    type: 'bpmn:SubProcess',
    triggeredByEvent: true,
    isExpanded: true
  }
}];
exports.TRANSACTION = TRANSACTION;
var EVENT_SUB_PROCESS = [{
  label: 'Sub Process',
  actionName: 'replace-with-subprocess',
  className: 'bpmn-icon-subprocess-expanded',
  target: {
    type: 'bpmn:SubProcess',
    isExpanded: true
  }
}, {
  label: 'Transaction',
  actionName: 'replace-with-transaction',
  className: 'bpmn-icon-transaction',
  target: {
    type: 'bpmn:Transaction',
    isExpanded: true
  }
}];
exports.EVENT_SUB_PROCESS = EVENT_SUB_PROCESS;
var TASK = [{
  label: 'Task',
  actionName: 'replace-with-task',
  className: 'bpmn-icon-task',
  target: {
    type: 'bpmn:Task'
  }
}, {
  label: 'Send Task',
  actionName: 'replace-with-send-task',
  className: 'bpmn-icon-send',
  target: {
    type: 'bpmn:SendTask'
  }
}, {
  label: 'Receive Task',
  actionName: 'replace-with-receive-task',
  className: 'bpmn-icon-receive',
  target: {
    type: 'bpmn:ReceiveTask'
  }
}, {
  label: 'User Task',
  actionName: 'replace-with-user-task',
  className: 'bpmn-icon-user',
  target: {
    type: 'bpmn:UserTask'
  }
}, {
  label: 'Manual Task',
  actionName: 'replace-with-manual-task',
  className: 'bpmn-icon-manual',
  target: {
    type: 'bpmn:ManualTask'
  }
}, {
  label: 'Business Rule Task',
  actionName: 'replace-with-rule-task',
  className: 'bpmn-icon-business-rule',
  target: {
    type: 'bpmn:BusinessRuleTask'
  }
}, {
  label: 'Service Task',
  actionName: 'replace-with-service-task',
  className: 'bpmn-icon-service',
  target: {
    type: 'bpmn:ServiceTask'
  }
}, {
  label: 'Script Task',
  actionName: 'replace-with-script-task',
  className: 'bpmn-icon-script',
  target: {
    type: 'bpmn:ScriptTask'
  }
}, {
  label: 'Call Activity',
  actionName: 'replace-with-call-activity',
  className: 'bpmn-icon-call-activity',
  target: {
    type: 'bpmn:CallActivity'
  }
}, {
  label: 'Sub Process (collapsed)',
  actionName: 'replace-with-collapsed-subprocess',
  className: 'bpmn-icon-subprocess-collapsed',
  target: {
    type: 'bpmn:SubProcess',
    isExpanded: false
  }
}, {
  label: 'Sub Process (expanded)',
  actionName: 'replace-with-expanded-subprocess',
  className: 'bpmn-icon-subprocess-expanded',
  target: {
    type: 'bpmn:SubProcess',
    isExpanded: true
  }
}];
exports.TASK = TASK;
var BOUNDARY_EVENT = [{
  label: 'Message Boundary Event',
  actionName: 'replace-with-message-boundary',
  className: 'bpmn-icon-intermediate-event-catch-message',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:MessageEventDefinition'
  }
}, {
  label: 'Timer Boundary Event',
  actionName: 'replace-with-timer-boundary',
  className: 'bpmn-icon-intermediate-event-catch-timer',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:TimerEventDefinition'
  }
}, {
  label: 'Escalation Boundary Event',
  actionName: 'replace-with-escalation-boundary',
  className: 'bpmn-icon-intermediate-event-catch-escalation',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:EscalationEventDefinition'
  }
}, {
  label: 'Conditional Boundary Event',
  actionName: 'replace-with-conditional-boundary',
  className: 'bpmn-icon-intermediate-event-catch-condition',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:ConditionalEventDefinition'
  }
}, {
  label: 'Error Boundary Event',
  actionName: 'replace-with-error-boundary',
  className: 'bpmn-icon-intermediate-event-catch-error',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:ErrorEventDefinition'
  }
}, {
  label: 'Cancel Boundary Event',
  actionName: 'replace-with-cancel-boundary',
  className: 'bpmn-icon-intermediate-event-catch-cancel',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:CancelEventDefinition'
  }
}, {
  label: 'Signal Boundary Event',
  actionName: 'replace-with-signal-boundary',
  className: 'bpmn-icon-intermediate-event-catch-signal',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:SignalEventDefinition'
  }
}, {
  label: 'Compensation Boundary Event',
  actionName: 'replace-with-compensation-boundary',
  className: 'bpmn-icon-intermediate-event-catch-compensation',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:CompensateEventDefinition'
  }
}, {
  label: 'Message Boundary Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-message-boundary',
  className: 'bpmn-icon-intermediate-event-catch-non-interrupting-message',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:MessageEventDefinition',
    cancelActivity: false
  }
}, {
  label: 'Timer Boundary Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-timer-boundary',
  className: 'bpmn-icon-intermediate-event-catch-non-interrupting-timer',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:TimerEventDefinition',
    cancelActivity: false
  }
}, {
  label: 'Escalation Boundary Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-escalation-boundary',
  className: 'bpmn-icon-intermediate-event-catch-non-interrupting-escalation',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:EscalationEventDefinition',
    cancelActivity: false
  }
}, {
  label: 'Conditional Boundary Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-conditional-boundary',
  className: 'bpmn-icon-intermediate-event-catch-non-interrupting-condition',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:ConditionalEventDefinition',
    cancelActivity: false
  }
}, {
  label: 'Signal Boundary Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-signal-boundary',
  className: 'bpmn-icon-intermediate-event-catch-non-interrupting-signal',
  target: {
    type: 'bpmn:BoundaryEvent',
    eventDefinitionType: 'bpmn:SignalEventDefinition',
    cancelActivity: false
  }
}];
exports.BOUNDARY_EVENT = BOUNDARY_EVENT;
var EVENT_SUB_PROCESS_START_EVENT = [{
  label: 'Message Start Event',
  actionName: 'replace-with-message-start',
  className: 'bpmn-icon-start-event-message',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:MessageEventDefinition'
  }
}, {
  label: 'Timer Start Event',
  actionName: 'replace-with-timer-start',
  className: 'bpmn-icon-start-event-timer',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:TimerEventDefinition'
  }
}, {
  label: 'Conditional Start Event',
  actionName: 'replace-with-conditional-start',
  className: 'bpmn-icon-start-event-condition',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:ConditionalEventDefinition'
  }
}, {
  label: 'Signal Start Event',
  actionName: 'replace-with-signal-start',
  className: 'bpmn-icon-start-event-signal',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:SignalEventDefinition'
  }
}, {
  label: 'Error Start Event',
  actionName: 'replace-with-error-start',
  className: 'bpmn-icon-start-event-error',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:ErrorEventDefinition'
  }
}, {
  label: 'Escalation Start Event',
  actionName: 'replace-with-escalation-start',
  className: 'bpmn-icon-start-event-escalation',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:EscalationEventDefinition'
  }
}, {
  label: 'Compensation Start Event',
  actionName: 'replace-with-compensation-start',
  className: 'bpmn-icon-start-event-compensation',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:CompensateEventDefinition'
  }
}, {
  label: 'Message Start Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-message-start',
  className: 'bpmn-icon-start-event-non-interrupting-message',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:MessageEventDefinition',
    isInterrupting: false
  }
}, {
  label: 'Timer Start Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-timer-start',
  className: 'bpmn-icon-start-event-non-interrupting-timer',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:TimerEventDefinition',
    isInterrupting: false
  }
}, {
  label: 'Conditional Start Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-conditional-start',
  className: 'bpmn-icon-start-event-non-interrupting-condition',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:ConditionalEventDefinition',
    isInterrupting: false
  }
}, {
  label: 'Signal Start Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-signal-start',
  className: 'bpmn-icon-start-event-non-interrupting-signal',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:SignalEventDefinition',
    isInterrupting: false
  }
}, {
  label: 'Escalation Start Event (non-interrupting)',
  actionName: 'replace-with-non-interrupting-escalation-start',
  className: 'bpmn-icon-start-event-non-interrupting-escalation',
  target: {
    type: 'bpmn:StartEvent',
    eventDefinitionType: 'bpmn:EscalationEventDefinition',
    isInterrupting: false
  }
}];
exports.EVENT_SUB_PROCESS_START_EVENT = EVENT_SUB_PROCESS_START_EVENT;
var SEQUENCE_FLOW = [{
  label: 'Sequence Flow',
  actionName: 'replace-with-sequence-flow',
  className: 'bpmn-icon-connection'
}, {
  label: 'Default Flow',
  actionName: 'replace-with-default-flow',
  className: 'bpmn-icon-default-flow'
}, {
  label: 'Conditional Flow',
  actionName: 'replace-with-conditional-flow',
  className: 'bpmn-icon-conditional-flow'
}];
exports.SEQUENCE_FLOW = SEQUENCE_FLOW;
var PARTICIPANT = [{
  label: 'Expanded Pool',
  actionName: 'replace-with-expanded-pool',
  className: 'bpmn-icon-participant',
  target: {
    type: 'bpmn:Participant',
    isExpanded: true
  }
}, {
  label: 'Collapsed Pool',
  actionName: 'replace-with-collapsed-pool',
  // TODO(@janstuemmel): maybe design new icon
  className: 'bpmn-icon-lane',
  target: {
    type: 'bpmn:Participant',
    isExpanded: false
  }
}];
exports.PARTICIPANT = PARTICIPANT;

},{}],124:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _copyPaste = _interopRequireDefault(require("../copy-paste"));

var _replace = _interopRequireDefault(require("diagram-js/lib/features/replace"));

var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection"));

var _BpmnReplace = _interopRequireDefault(require("./BpmnReplace"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_copyPaste.default, _replace.default, _selection.default],
  bpmnReplace: ['type', _BpmnReplace.default]
};
exports.default = _default;

},{"../copy-paste":34,"./BpmnReplace":122,"diagram-js/lib/features/replace":264,"diagram-js/lib/features/selection":278}],125:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnRules;

var _minDash = require("min-dash");

var _inherits = _interopRequireDefault(require("inherits"));

var _ModelUtil = require("../../util/ModelUtil");

var _ModelingUtil = require("../modeling/util/ModelingUtil");

var _LabelUtil = require("../../util/LabelUtil");

var _DiUtil = require("../../util/DiUtil");

var _RuleProvider = _interopRequireDefault(require("diagram-js/lib/features/rules/RuleProvider"));

var _BpmnSnappingUtil = require("../snapping/BpmnSnappingUtil");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * BPMN specific modeling rule
 */
function BpmnRules(eventBus) {
  _RuleProvider.default.call(this, eventBus);
}

(0, _inherits.default)(BpmnRules, _RuleProvider.default);
BpmnRules.$inject = ['eventBus'];

BpmnRules.prototype.init = function () {
  this.addRule('connection.start', function (context) {
    var source = context.source;
    return canStartConnection(source);
  });
  this.addRule('connection.create', function (context) {
    var source = context.source,
        target = context.target,
        hints = context.hints || {},
        targetParent = hints.targetParent,
        targetAttach = hints.targetAttach; // don't allow incoming connections on
    // newly created boundary events
    // to boundary events

    if (targetAttach) {
      return false;
    } // temporarily set target parent for scoping
    // checks to work


    if (targetParent) {
      target.parent = targetParent;
    }

    try {
      return canConnect(source, target);
    } finally {
      // unset temporary target parent
      if (targetParent) {
        target.parent = null;
      }
    }
  });
  this.addRule('connection.reconnect', function (context) {
    var connection = context.connection,
        source = context.source,
        target = context.target;
    return canConnect(source, target, connection);
  });
  this.addRule('connection.updateWaypoints', function (context) {
    return {
      type: context.connection.type
    };
  });
  this.addRule('shape.resize', function (context) {
    var shape = context.shape,
        newBounds = context.newBounds;
    return canResize(shape, newBounds);
  });
  this.addRule('elements.create', function (context) {
    var elements = context.elements,
        position = context.position,
        target = context.target;
    return (0, _minDash.every)(elements, function (element) {
      if (isConnection(element)) {
        return canConnect(element.source, element.target, element);
      }

      if (element.host) {
        return canAttach(element, element.host, null, position);
      }

      return canCreate(element, target, null, position);
    });
  });
  this.addRule('elements.move', function (context) {
    var target = context.target,
        shapes = context.shapes,
        position = context.position;
    return canAttach(shapes, target, null, position) || canReplace(shapes, target, position) || canMove(shapes, target, position) || canInsert(shapes, target, position);
  });
  this.addRule('shape.create', function (context) {
    return canCreate(context.shape, context.target, context.source, context.position);
  });
  this.addRule('shape.attach', function (context) {
    return canAttach(context.shape, context.target, null, context.position);
  });
  this.addRule('element.copy', function (context) {
    var element = context.element,
        elements = context.elements;
    return canCopy(elements, element);
  });
};

BpmnRules.prototype.canConnectMessageFlow = canConnectMessageFlow;
BpmnRules.prototype.canConnectSequenceFlow = canConnectSequenceFlow;
BpmnRules.prototype.canConnectDataAssociation = canConnectDataAssociation;
BpmnRules.prototype.canConnectAssociation = canConnectAssociation;
BpmnRules.prototype.canMove = canMove;
BpmnRules.prototype.canAttach = canAttach;
BpmnRules.prototype.canReplace = canReplace;
BpmnRules.prototype.canDrop = canDrop;
BpmnRules.prototype.canInsert = canInsert;
BpmnRules.prototype.canCreate = canCreate;
BpmnRules.prototype.canConnect = canConnect;
BpmnRules.prototype.canResize = canResize;
BpmnRules.prototype.canCopy = canCopy;
/**
 * Utility functions for rule checking
 */

/**
 * Checks if given element can be used for starting connection.
 *
 * @param  {Element} source
 * @return {boolean}
 */

function canStartConnection(element) {
  if (nonExistingOrLabel(element)) {
    return null;
  }

  return (0, _ModelingUtil.isAny)(element, ['bpmn:FlowNode', 'bpmn:InteractionNode', 'bpmn:DataObjectReference', 'bpmn:DataStoreReference', 'bpmn:Group']);
}

function nonExistingOrLabel(element) {
  return !element || (0, _LabelUtil.isLabel)(element);
}

function isSame(a, b) {
  return a === b;
}

function getOrganizationalParent(element) {
  do {
    if ((0, _ModelUtil.is)(element, 'bpmn:Process')) {
      return (0, _ModelUtil.getBusinessObject)(element);
    }

    if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) {
      return (0, _ModelUtil.getBusinessObject)(element).processRef || (0, _ModelUtil.getBusinessObject)(element);
    }
  } while (element = element.parent);
}

function isTextAnnotation(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:TextAnnotation');
}

function isGroup(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:Group') && !element.labelTarget;
}

function isCompensationBoundary(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && hasEventDefinition(element, 'bpmn:CompensateEventDefinition');
}

function isForCompensation(e) {
  return (0, _ModelUtil.getBusinessObject)(e).isForCompensation;
}

function isSameOrganization(a, b) {
  var parentA = getOrganizationalParent(a),
      parentB = getOrganizationalParent(b);
  return parentA === parentB;
}

function isMessageFlowSource(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:InteractionNode') && !(0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && (!(0, _ModelUtil.is)(element, 'bpmn:Event') || (0, _ModelUtil.is)(element, 'bpmn:ThrowEvent') && hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition'));
}

function isMessageFlowTarget(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:InteractionNode') && !isForCompensation(element) && (!(0, _ModelUtil.is)(element, 'bpmn:Event') || (0, _ModelUtil.is)(element, 'bpmn:CatchEvent') && hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition')) && !((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !hasEventDefinition(element, 'bpmn:MessageEventDefinition'));
}

function getScopeParent(element) {
  var parent = element;

  while (parent = parent.parent) {
    if ((0, _ModelUtil.is)(parent, 'bpmn:FlowElementsContainer')) {
      return (0, _ModelUtil.getBusinessObject)(parent);
    }

    if ((0, _ModelUtil.is)(parent, 'bpmn:Participant')) {
      return (0, _ModelUtil.getBusinessObject)(parent).processRef;
    }
  }

  return null;
}

function isSameScope(a, b) {
  var scopeParentA = getScopeParent(a),
      scopeParentB = getScopeParent(b);
  return scopeParentA === scopeParentB;
}

function hasEventDefinition(element, eventDefinition) {
  var bo = (0, _ModelUtil.getBusinessObject)(element);
  return !!(0, _minDash.find)(bo.eventDefinitions || [], function (definition) {
    return (0, _ModelUtil.is)(definition, eventDefinition);
  });
}

function hasEventDefinitionOrNone(element, eventDefinition) {
  var bo = (0, _ModelUtil.getBusinessObject)(element);
  return (bo.eventDefinitions || []).every(function (definition) {
    return (0, _ModelUtil.is)(definition, eventDefinition);
  });
}

function isSequenceFlowSource(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(element, 'bpmn:EndEvent') && !(0, _DiUtil.isEventSubProcess)(element) && !((0, _ModelUtil.is)(element, 'bpmn:IntermediateThrowEvent') && hasEventDefinition(element, 'bpmn:LinkEventDefinition')) && !isCompensationBoundary(element) && !isForCompensation(element);
}

function isSequenceFlowTarget(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(element, 'bpmn:StartEvent') && !(0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !(0, _DiUtil.isEventSubProcess)(element) && !((0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && hasEventDefinition(element, 'bpmn:LinkEventDefinition')) && !isForCompensation(element);
}

function isEventBasedTarget(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:ReceiveTask') || (0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && (hasEventDefinition(element, 'bpmn:MessageEventDefinition') || hasEventDefinition(element, 'bpmn:TimerEventDefinition') || hasEventDefinition(element, 'bpmn:ConditionalEventDefinition') || hasEventDefinition(element, 'bpmn:SignalEventDefinition'));
}

function isConnection(element) {
  return element.waypoints;
}

function getParents(element) {
  var parents = [];

  while (element) {
    element = element.parent;

    if (element) {
      parents.push(element);
    }
  }

  return parents;
}

function isParent(possibleParent, element) {
  var allParents = getParents(element);
  return allParents.indexOf(possibleParent) !== -1;
}

function canConnect(source, target, connection) {
  if (nonExistingOrLabel(source) || nonExistingOrLabel(target)) {
    return null;
  }

  if (!(0, _ModelUtil.is)(connection, 'bpmn:DataAssociation')) {
    if (canConnectMessageFlow(source, target)) {
      return {
        type: 'bpmn:MessageFlow'
      };
    }

    if (canConnectSequenceFlow(source, target)) {
      return {
        type: 'bpmn:SequenceFlow'
      };
    }
  }

  var connectDataAssociation = canConnectDataAssociation(source, target);

  if (connectDataAssociation) {
    return connectDataAssociation;
  }

  if (isCompensationBoundary(source) && isForCompensation(target)) {
    return {
      type: 'bpmn:Association',
      associationDirection: 'One'
    };
  }

  if (canConnectAssociation(source, target)) {
    return {
      type: 'bpmn:Association'
    };
  }

  return false;
}
/**
 * Can an element be dropped into the target element
 *
 * @return {boolean}
 */


function canDrop(element, target, position) {
  // can move labels and groups everywhere
  if ((0, _LabelUtil.isLabel)(element) || isGroup(element)) {
    return true;
  } // disallow to create elements on collapsed pools


  if ((0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(target)) {
    return false;
  } // allow to create new participants on
  // existing collaboration and process diagrams


  if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) {
    return (0, _ModelUtil.is)(target, 'bpmn:Process') || (0, _ModelUtil.is)(target, 'bpmn:Collaboration');
  } // allow moving DataInput / DataOutput within its original container only


  if ((0, _ModelingUtil.isAny)(element, ['bpmn:DataInput', 'bpmn:DataOutput'])) {
    if (element.parent) {
      return target === element.parent;
    }
  } // allow creating lanes on participants and other lanes only


  if ((0, _ModelUtil.is)(element, 'bpmn:Lane')) {
    return (0, _ModelUtil.is)(target, 'bpmn:Participant') || (0, _ModelUtil.is)(target, 'bpmn:Lane');
  } // disallow dropping boundary events which cannot replace with intermediate event


  if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !isDroppableBoundaryEvent(element)) {
    return false;
  } // drop flow elements onto flow element containers
  // and participants


  if ((0, _ModelUtil.is)(element, 'bpmn:FlowElement') && !(0, _ModelUtil.is)(element, 'bpmn:DataStoreReference')) {
    if ((0, _ModelUtil.is)(target, 'bpmn:FlowElementsContainer')) {
      return (0, _DiUtil.isExpanded)(target);
    }

    return (0, _ModelingUtil.isAny)(target, ['bpmn:Participant', 'bpmn:Lane']);
  } // account for the fact that data associations are always
  // rendered and moved to top (Process or Collaboration level)
  //
  // artifacts may be placed wherever, too


  if ((0, _ModelingUtil.isAny)(element, ['bpmn:Artifact', 'bpmn:DataAssociation', 'bpmn:DataStoreReference'])) {
    return (0, _ModelingUtil.isAny)(target, ['bpmn:Collaboration', 'bpmn:Lane', 'bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess']);
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:MessageFlow')) {
    return (0, _ModelUtil.is)(target, 'bpmn:Collaboration') || element.source.parent == target || element.target.parent == target;
  }

  return false;
}

function isDroppableBoundaryEvent(event) {
  return (0, _ModelUtil.getBusinessObject)(event).cancelActivity && (hasNoEventDefinition(event) || hasCommonBoundaryIntermediateEventDefinition(event));
}

function isBoundaryEvent(element) {
  return !(0, _LabelUtil.isLabel)(element) && (0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent');
}

function isLane(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:Lane');
}
/**
 * We treat IntermediateThrowEvents as boundary events during create,
 * this must be reflected in the rules.
 */


function isBoundaryCandidate(element) {
  if (isBoundaryEvent(element)) {
    return true;
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:IntermediateThrowEvent') && hasNoEventDefinition(element)) {
    return true;
  }

  return (0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && hasCommonBoundaryIntermediateEventDefinition(element);
}

function hasNoEventDefinition(element) {
  var bo = (0, _ModelUtil.getBusinessObject)(element);
  return bo && !(bo.eventDefinitions && bo.eventDefinitions.length);
}

function hasCommonBoundaryIntermediateEventDefinition(element) {
  return hasOneOfEventDefinitions(element, ['bpmn:MessageEventDefinition', 'bpmn:TimerEventDefinition', 'bpmn:SignalEventDefinition', 'bpmn:ConditionalEventDefinition']);
}

function hasOneOfEventDefinitions(element, eventDefinitions) {
  return eventDefinitions.some(function (definition) {
    return hasEventDefinition(element, definition);
  });
}

function isReceiveTaskAfterEventBasedGateway(element) {
  return (0, _ModelUtil.is)(element, 'bpmn:ReceiveTask') && (0, _minDash.find)(element.incoming, function (incoming) {
    return (0, _ModelUtil.is)(incoming.source, 'bpmn:EventBasedGateway');
  });
}

function canAttach(elements, target, source, position) {
  if (!Array.isArray(elements)) {
    elements = [elements];
  } // only (re-)attach one element at a time


  if (elements.length !== 1) {
    return false;
  }

  var element = elements[0]; // do not attach labels

  if ((0, _LabelUtil.isLabel)(element)) {
    return false;
  } // only handle boundary events


  if (!isBoundaryCandidate(element)) {
    return false;
  } // disallow drop on event sub processes


  if ((0, _DiUtil.isEventSubProcess)(target)) {
    return false;
  } // only allow drop on non compensation activities


  if (!(0, _ModelUtil.is)(target, 'bpmn:Activity') || isForCompensation(target)) {
    return false;
  } // only attach to subprocess border


  if (position && !(0, _BpmnSnappingUtil.getBoundaryAttachment)(position, target)) {
    return false;
  } // do not attach on receive tasks after event based gateways


  if (isReceiveTaskAfterEventBasedGateway(target)) {
    return false;
  }

  return 'attach';
}
/**
 * Defines how to replace elements for a given target.
 *
 * Returns an array containing all elements which will be replaced.
 *
 * @example
 *
 *  [{ id: 'IntermediateEvent_2',
 *     type: 'bpmn:StartEvent'
 *   },
 *   { id: 'IntermediateEvent_5',
 *     type: 'bpmn:EndEvent'
 *   }]
 *
 * @param  {Array} elements
 * @param  {Object} target
 *
 * @return {Object} an object containing all elements which have to be replaced
 */


function canReplace(elements, target, position) {
  if (!target) {
    return false;
  }

  var canExecute = {
    replacements: []
  };
  (0, _minDash.forEach)(elements, function (element) {
    if (!(0, _DiUtil.isEventSubProcess)(target)) {
      if ((0, _ModelUtil.is)(element, 'bpmn:StartEvent') && element.type !== 'label' && canDrop(element, target)) {
        // replace a non-interrupting start event by a blank interrupting start event
        // when the target is not an event sub process
        if (!(0, _DiUtil.isInterrupting)(element)) {
          canExecute.replacements.push({
            oldElementId: element.id,
            newElementType: 'bpmn:StartEvent'
          });
        } // replace an error/escalation/compensate start event by a blank interrupting start event
        // when the target is not an event sub process


        if ((0, _DiUtil.hasErrorEventDefinition)(element) || (0, _DiUtil.hasEscalationEventDefinition)(element) || (0, _DiUtil.hasCompensateEventDefinition)(element)) {
          canExecute.replacements.push({
            oldElementId: element.id,
            newElementType: 'bpmn:StartEvent'
          });
        } // replace a typed start event by a blank interrupting start event
        // when the target is a sub process but not an event sub process


        if (hasOneOfEventDefinitions(element, ['bpmn:MessageEventDefinition', 'bpmn:TimerEventDefinition', 'bpmn:SignalEventDefinition', 'bpmn:ConditionalEventDefinition']) && (0, _ModelUtil.is)(target, 'bpmn:SubProcess')) {
          canExecute.replacements.push({
            oldElementId: element.id,
            newElementType: 'bpmn:StartEvent'
          });
        }
      }
    }

    if (!(0, _ModelUtil.is)(target, 'bpmn:Transaction')) {
      if (hasEventDefinition(element, 'bpmn:CancelEventDefinition') && element.type !== 'label') {
        if ((0, _ModelUtil.is)(element, 'bpmn:EndEvent') && canDrop(element, target)) {
          canExecute.replacements.push({
            oldElementId: element.id,
            newElementType: 'bpmn:EndEvent'
          });
        }

        if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && canAttach(element, target, null, position)) {
          canExecute.replacements.push({
            oldElementId: element.id,
            newElementType: 'bpmn:BoundaryEvent'
          });
        }
      }
    }
  });
  return canExecute.replacements.length ? canExecute : false;
}

function canMove(elements, target) {
  // do not move selection containing lanes
  if ((0, _minDash.some)(elements, isLane)) {
    return false;
  } // allow default move check to start move operation


  if (!target) {
    return true;
  }

  return elements.every(function (element) {
    return canDrop(element, target);
  });
}

function canCreate(shape, target, source, position) {
  if (!target) {
    return false;
  }

  if ((0, _LabelUtil.isLabel)(shape) || isGroup(shape)) {
    return true;
  }

  if (isSame(source, target)) {
    return false;
  } // ensure we do not drop the element
  // into source


  if (source && isParent(source, target)) {
    return false;
  }

  return canDrop(shape, target, position) || canInsert(shape, target, position);
}

function canResize(shape, newBounds) {
  if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess')) {
    return (0, _DiUtil.isExpanded)(shape) && (!newBounds || newBounds.width >= 100 && newBounds.height >= 80);
  }

  if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) {
    return !newBounds || newBounds.width >= 130 && newBounds.height >= 60;
  }

  if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
    return !newBounds || newBounds.width >= 250 && newBounds.height >= 50;
  }

  if (isTextAnnotation(shape)) {
    return true;
  }

  if (isGroup(shape)) {
    return true;
  }

  return false;
}
/**
 * Check, whether one side of the relationship
 * is a text annotation.
 */


function isOneTextAnnotation(source, target) {
  var sourceTextAnnotation = isTextAnnotation(source),
      targetTextAnnotation = isTextAnnotation(target);
  return (sourceTextAnnotation || targetTextAnnotation) && sourceTextAnnotation !== targetTextAnnotation;
}

function canConnectAssociation(source, target) {
  // do not connect connections
  if (isConnection(source) || isConnection(target)) {
    return false;
  } // compensation boundary events are exception


  if (isCompensationBoundary(source) && isForCompensation(target)) {
    return true;
  } // don't connect parent <-> child


  if (isParent(target, source) || isParent(source, target)) {
    return false;
  } // allow connection of associations between <!TextAnnotation> and <TextAnnotation>


  if (isOneTextAnnotation(source, target)) {
    return true;
  } // can connect associations where we can connect
  // data associations, too (!)


  return !!canConnectDataAssociation(source, target);
}

function canConnectMessageFlow(source, target) {
  // during connect user might move mouse out of canvas
  // https://github.com/bpmn-io/bpmn-js/issues/1033
  if (getRootElement(source) && !getRootElement(target)) {
    return false;
  }

  return isMessageFlowSource(source) && isMessageFlowTarget(target) && !isSameOrganization(source, target);
}

function canConnectSequenceFlow(source, target) {
  if (isEventBasedTarget(target) && target.incoming.length > 0 && areOutgoingEventBasedGatewayConnections(target.incoming) && !(0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway')) {
    return false;
  }

  return isSequenceFlowSource(source) && isSequenceFlowTarget(target) && isSameScope(source, target) && !((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && !isEventBasedTarget(target));
}

function canConnectDataAssociation(source, target) {
  if ((0, _ModelingUtil.isAny)(source, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference']) && (0, _ModelingUtil.isAny)(target, ['bpmn:Activity', 'bpmn:ThrowEvent'])) {
    return {
      type: 'bpmn:DataInputAssociation'
    };
  }

  if ((0, _ModelingUtil.isAny)(target, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference']) && (0, _ModelingUtil.isAny)(source, ['bpmn:Activity', 'bpmn:CatchEvent'])) {
    return {
      type: 'bpmn:DataOutputAssociation'
    };
  }

  return false;
}

function canInsert(shape, flow, position) {
  if (!flow) {
    return false;
  }

  if (Array.isArray(shape)) {
    if (shape.length !== 1) {
      return false;
    }

    shape = shape[0];
  }

  if (flow.source === shape || flow.target === shape) {
    return false;
  } // return true if we can drop on the
  // underlying flow parent
  //
  // at this point we are not really able to talk
  // about connection rules (yet)


  return (0, _ModelingUtil.isAny)(flow, ['bpmn:SequenceFlow', 'bpmn:MessageFlow']) && !(0, _LabelUtil.isLabel)(flow) && (0, _ModelUtil.is)(shape, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(shape, 'bpmn:BoundaryEvent') && canDrop(shape, flow.parent, position);
}

function includes(elements, element) {
  return elements && element && elements.indexOf(element) !== -1;
}

function canCopy(elements, element) {
  if ((0, _LabelUtil.isLabel)(element)) {
    return true;
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:Lane') && !includes(elements, element.parent)) {
    return false;
  }

  return true;
}

function isOutgoingEventBasedGatewayConnection(connection) {
  if (connection && connection.source) {
    return (0, _ModelUtil.is)(connection.source, 'bpmn:EventBasedGateway');
  }
}

function areOutgoingEventBasedGatewayConnections(connections) {
  connections = connections || [];
  return connections.some(isOutgoingEventBasedGatewayConnection);
}

function getRootElement(element) {
  return (0, _ModelingUtil.getParent)(element, 'bpmn:Process') || (0, _ModelingUtil.getParent)(element, 'bpmn:Collaboration');
}

},{"../../util/DiUtil":139,"../../util/LabelUtil":140,"../../util/ModelUtil":141,"../modeling/util/ModelingUtil":112,"../snapping/BpmnSnappingUtil":131,"diagram-js/lib/features/rules/RuleProvider":270,"inherits":347,"min-dash":555}],126:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _rules = _interopRequireDefault(require("diagram-js/lib/features/rules"));

var _BpmnRules = _interopRequireDefault(require("./BpmnRules"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_rules.default],
  __init__: ['bpmnRules'],
  bpmnRules: ['type', _BpmnRules.default]
};
exports.default = _default;

},{"./BpmnRules":125,"diagram-js/lib/features/rules":272}],127:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnSearchProvider;

var _minDash = require("min-dash");

var _LabelUtil = require("../label-editing/LabelUtil");

/**
 * Provides ability to search through BPMN elements
 */
function BpmnSearchProvider(elementRegistry, searchPad, canvas) {
  this._elementRegistry = elementRegistry;
  this._canvas = canvas;
  searchPad.registerProvider(this);
}

BpmnSearchProvider.$inject = ['elementRegistry', 'searchPad', 'canvas'];
/**
 * Finds all elements that match given pattern
 *
 * <Result> :
 *  {
 *    primaryTokens: <Array<Token>>,
 *    secondaryTokens: <Array<Token>>,
 *    element: <Element>
 *  }
 *
 * <Token> :
 *  {
 *    normal|matched: <string>
 *  }
 *
 * @param  {string} pattern
 * @return {Array<Result>}
 */

BpmnSearchProvider.prototype.find = function (pattern) {
  var rootElement = this._canvas.getRootElement();

  var elements = this._elementRegistry.filter(function (element) {
    if (element.labelTarget) {
      return false;
    }

    return true;
  }); // do not include root element


  elements = (0, _minDash.filter)(elements, function (element) {
    return element !== rootElement;
  });
  elements = (0, _minDash.map)(elements, function (element) {
    return {
      primaryTokens: matchAndSplit((0, _LabelUtil.getLabel)(element), pattern),
      secondaryTokens: matchAndSplit(element.id, pattern),
      element: element
    };
  }); // exclude non-matched elements

  elements = (0, _minDash.filter)(elements, function (element) {
    return hasMatched(element.primaryTokens) || hasMatched(element.secondaryTokens);
  });
  elements = (0, _minDash.sortBy)(elements, function (element) {
    return (0, _LabelUtil.getLabel)(element.element) + element.element.id;
  });
  return elements;
};

function hasMatched(tokens) {
  var matched = (0, _minDash.filter)(tokens, function (t) {
    return !!t.matched;
  });
  return matched.length > 0;
}

function matchAndSplit(text, pattern) {
  var tokens = [],
      originalText = text;

  if (!text) {
    return tokens;
  }

  text = text.toLowerCase();
  pattern = pattern.toLowerCase();
  var i = text.indexOf(pattern);

  if (i > -1) {
    if (i !== 0) {
      tokens.push({
        normal: originalText.substr(0, i)
      });
    }

    tokens.push({
      matched: originalText.substr(i, pattern.length)
    });

    if (pattern.length + i < text.length) {
      tokens.push({
        normal: originalText.substr(pattern.length + i, text.length)
      });
    }
  } else {
    tokens.push({
      normal: originalText
    });
  }

  return tokens;
}

},{"../label-editing/LabelUtil":53,"min-dash":555}],128:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _searchPad = _interopRequireDefault(require("diagram-js/lib/features/search-pad"));

var _BpmnSearchProvider = _interopRequireDefault(require("./BpmnSearchProvider"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_searchPad.default],
  __init__: ['bpmnSearch'],
  bpmnSearch: ['type', _BpmnSearchProvider.default]
};
exports.default = _default;

},{"./BpmnSearchProvider":127,"diagram-js/lib/features/search-pad":274}],129:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnConnectSnapping;

var _SnapUtil = require("diagram-js/lib/features/snapping/SnapUtil");

var _KeyboardUtil = require("diagram-js/lib/features/keyboard/KeyboardUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _ModelUtil = require("../../util/ModelUtil");

var _ModelingUtil = require("../modeling/util/ModelingUtil");

var _minDash = require("min-dash");

var HIGHER_PRIORITY = 1250;
var BOUNDARY_TO_HOST_THRESHOLD = 40;
var TARGET_BOUNDS_PADDING = 20,
    TASK_BOUNDS_PADDING = 10;
var TARGET_CENTER_PADDING = 20;
var AXES = ['x', 'y'];
var abs = Math.abs;
/**
 * Snap during connect.
 *
 * @param {EventBus} eventBus
 */

function BpmnConnectSnapping(eventBus) {
  eventBus.on(['connect.hover', 'connect.move', 'connect.end'], HIGHER_PRIORITY, function (event) {
    var context = event.context,
        canExecute = context.canExecute,
        start = context.start,
        hover = context.hover,
        source = context.source,
        target = context.target; // do NOT snap on CMD

    if (event.originalEvent && (0, _KeyboardUtil.isCmd)(event.originalEvent)) {
      return;
    }

    if (!context.initialConnectionStart) {
      context.initialConnectionStart = context.connectionStart;
    } // snap hover


    if (canExecute && hover) {
      snapToShape(event, hover, getTargetBoundsPadding(hover));
    }

    if (hover && isAnyType(canExecute, ['bpmn:Association', 'bpmn:DataInputAssociation', 'bpmn:DataOutputAssociation', 'bpmn:SequenceFlow'])) {
      context.connectionStart = (0, _SnapUtil.mid)(start); // snap hover

      if ((0, _ModelingUtil.isAny)(hover, ['bpmn:Event', 'bpmn:Gateway'])) {
        snapToPosition(event, (0, _SnapUtil.mid)(hover));
      } // snap hover


      if ((0, _ModelingUtil.isAny)(hover, ['bpmn:Task', 'bpmn:SubProcess'])) {
        snapToTargetMid(event, hover);
      } // snap source and target


      if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent') && target === source.host) {
        snapBoundaryEventLoop(event);
      }
    } else if (isType(canExecute, 'bpmn:MessageFlow')) {
      if ((0, _ModelUtil.is)(start, 'bpmn:Event')) {
        // snap start
        context.connectionStart = (0, _SnapUtil.mid)(start);
      }

      if ((0, _ModelUtil.is)(hover, 'bpmn:Event')) {
        // snap hover
        snapToPosition(event, (0, _SnapUtil.mid)(hover));
      }
    } else {
      // un-snap source
      context.connectionStart = context.initialConnectionStart;
    }
  });
}

BpmnConnectSnapping.$inject = ['eventBus']; // helpers //////////
// snap to target if event in target

function snapToShape(event, target, padding) {
  AXES.forEach(function (axis) {
    var dimensionForAxis = getDimensionForAxis(axis, target);

    if (event[axis] < target[axis] + padding) {
      (0, _SnapUtil.setSnapped)(event, axis, target[axis] + padding);
    } else if (event[axis] > target[axis] + dimensionForAxis - padding) {
      (0, _SnapUtil.setSnapped)(event, axis, target[axis] + dimensionForAxis - padding);
    }
  });
} // snap to target mid if event in target mid


function snapToTargetMid(event, target) {
  var targetMid = (0, _SnapUtil.mid)(target);
  AXES.forEach(function (axis) {
    if (isMid(event, target, axis)) {
      (0, _SnapUtil.setSnapped)(event, axis, targetMid[axis]);
    }
  });
} // snap to prevent loop overlapping boundary event


function snapBoundaryEventLoop(event) {
  var context = event.context,
      source = context.source,
      target = context.target;

  if (isReverse(context)) {
    return;
  }

  var sourceMid = (0, _SnapUtil.mid)(source),
      orientation = (0, _LayoutUtil.getOrientation)(sourceMid, target, -10),
      axes = [];

  if (/top|bottom/.test(orientation)) {
    axes.push('x');
  }

  if (/left|right/.test(orientation)) {
    axes.push('y');
  }

  axes.forEach(function (axis) {
    var coordinate = event[axis],
        newCoordinate;

    if (abs(coordinate - sourceMid[axis]) < BOUNDARY_TO_HOST_THRESHOLD) {
      if (coordinate > sourceMid[axis]) {
        newCoordinate = sourceMid[axis] + BOUNDARY_TO_HOST_THRESHOLD;
      } else {
        newCoordinate = sourceMid[axis] - BOUNDARY_TO_HOST_THRESHOLD;
      }

      (0, _SnapUtil.setSnapped)(event, axis, newCoordinate);
    }
  });
}

function snapToPosition(event, position) {
  (0, _SnapUtil.setSnapped)(event, 'x', position.x);
  (0, _SnapUtil.setSnapped)(event, 'y', position.y);
}

function isType(attrs, type) {
  return attrs && attrs.type === type;
}

function isAnyType(attrs, types) {
  return (0, _minDash.some)(types, function (type) {
    return isType(attrs, type);
  });
}

function getDimensionForAxis(axis, element) {
  return axis === 'x' ? element.width : element.height;
}

function getTargetBoundsPadding(target) {
  if ((0, _ModelUtil.is)(target, 'bpmn:Task')) {
    return TASK_BOUNDS_PADDING;
  } else {
    return TARGET_BOUNDS_PADDING;
  }
}

function isMid(event, target, axis) {
  return event[axis] > target[axis] + TARGET_CENTER_PADDING && event[axis] < target[axis] + getDimensionForAxis(axis, target) - TARGET_CENTER_PADDING;
}

function isReverse(context) {
  var hover = context.hover,
      source = context.source;
  return hover && source && hover === source;
}

},{"../../util/ModelUtil":141,"../modeling/util/ModelingUtil":112,"diagram-js/lib/features/keyboard/KeyboardUtil":216,"diagram-js/lib/features/snapping/SnapUtil":282,"diagram-js/lib/layout/LayoutUtil":300,"min-dash":555}],130:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnCreateMoveSnapping;

var _inherits = _interopRequireDefault(require("inherits"));

var _CreateMoveSnapping = _interopRequireDefault(require("diagram-js/lib/features/snapping/CreateMoveSnapping"));

var _SnapUtil = require("diagram-js/lib/features/snapping/SnapUtil");

var _DiUtil = require("../../util/DiUtil");

var _ModelUtil = require("../../util/ModelUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _BpmnSnappingUtil = require("./BpmnSnappingUtil");

var _minDash = require("min-dash");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var HIGH_PRIORITY = 1500;
/**
 * Snap during create and move.
 *
 * @param {EventBus} eventBus
 * @param {Injector} injector
 */

function BpmnCreateMoveSnapping(eventBus, injector) {
  injector.invoke(_CreateMoveSnapping.default, this); // creating first participant

  eventBus.on(['create.move', 'create.end'], HIGH_PRIORITY, setSnappedIfConstrained); // snap boundary events

  eventBus.on(['create.move', 'create.end', 'shape.move.move', 'shape.move.end'], HIGH_PRIORITY, function (event) {
    var context = event.context,
        canExecute = context.canExecute,
        target = context.target;
    var canAttach = canExecute && (canExecute === 'attach' || canExecute.attach);

    if (canAttach && !(0, _SnapUtil.isSnapped)(event)) {
      snapBoundaryEvent(event, target);
    }
  });
}

(0, _inherits.default)(BpmnCreateMoveSnapping, _CreateMoveSnapping.default);
BpmnCreateMoveSnapping.$inject = ['eventBus', 'injector'];

BpmnCreateMoveSnapping.prototype.initSnap = function (event) {
  var snapContext = _CreateMoveSnapping.default.prototype.initSnap.call(this, event);

  var shape = event.shape;
  var isMove = !!this._elementRegistry.get(shape.id); // snap to docking points

  (0, _minDash.forEach)(shape.outgoing, function (connection) {
    var docking = connection.waypoints[0];
    docking = docking.original || docking;
    snapContext.setSnapOrigin(connection.id + '-docking', getDockingSnapOrigin(docking, isMove, event));
  });
  (0, _minDash.forEach)(shape.incoming, function (connection) {
    var docking = connection.waypoints[connection.waypoints.length - 1];
    docking = docking.original || docking;
    snapContext.setSnapOrigin(connection.id + '-docking', getDockingSnapOrigin(docking, isMove, event));
  });

  if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) {
    // snap to borders with higher priority
    snapContext.setSnapLocations(['top-left', 'bottom-right', 'mid']);
  }

  return snapContext;
};

BpmnCreateMoveSnapping.prototype.addSnapTargetPoints = function (snapPoints, shape, target) {
  _CreateMoveSnapping.default.prototype.addSnapTargetPoints.call(this, snapPoints, shape, target);

  var snapTargets = this.getSnapTargets(shape, target);
  (0, _minDash.forEach)(snapTargets, function (snapTarget) {
    // handle TRBL alignment
    //
    // * with container elements
    // * with text annotations
    if (isContainer(snapTarget) || areAll([shape, snapTarget], 'bpmn:TextAnnotation')) {
      snapPoints.add('top-left', (0, _SnapUtil.topLeft)(snapTarget));
      snapPoints.add('bottom-right', (0, _SnapUtil.bottomRight)(snapTarget));
    }
  });
  var elementRegistry = this._elementRegistry; // snap to docking points if not create mode

  (0, _minDash.forEach)(shape.incoming, function (connection) {
    if (elementRegistry.get(shape.id)) {
      if (!includes(snapTargets, connection.source)) {
        snapPoints.add('mid', (0, _LayoutUtil.getMid)(connection.source));
      }

      var docking = connection.waypoints[0];
      snapPoints.add(connection.id + '-docking', docking.original || docking);
    }
  });
  (0, _minDash.forEach)(shape.outgoing, function (connection) {
    if (elementRegistry.get(shape.id)) {
      if (!includes(snapTargets, connection.target)) {
        snapPoints.add('mid', (0, _LayoutUtil.getMid)(connection.target));
      }

      var docking = connection.waypoints[connection.waypoints.length - 1];
      snapPoints.add(connection.id + '-docking', docking.original || docking);
    }
  }); // add sequence flow parents as snap targets

  if ((0, _ModelUtil.is)(target, 'bpmn:SequenceFlow')) {
    snapPoints = this.addSnapTargetPoints(snapPoints, shape, target.parent);
  }

  return snapPoints;
};

BpmnCreateMoveSnapping.prototype.getSnapTargets = function (shape, target) {
  return _CreateMoveSnapping.default.prototype.getSnapTargets.call(this, shape, target).filter(function (snapTarget) {
    // do not snap to lanes
    return !(0, _ModelUtil.is)(snapTarget, 'bpmn:Lane');
  });
}; // helpers //////////


function snapBoundaryEvent(event, target) {
  var targetTRBL = (0, _LayoutUtil.asTRBL)(target);
  var direction = (0, _BpmnSnappingUtil.getBoundaryAttachment)(event, target);
  var context = event.context,
      shape = context.shape;
  var offset;

  if (shape.parent) {
    offset = {
      x: 0,
      y: 0
    };
  } else {
    offset = (0, _LayoutUtil.getMid)(shape);
  }

  if (/top/.test(direction)) {
    (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.top - offset.y);
  } else if (/bottom/.test(direction)) {
    (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.bottom - offset.y);
  }

  if (/left/.test(direction)) {
    (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.left - offset.x);
  } else if (/right/.test(direction)) {
    (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.right - offset.x);
  }
}

function areAll(elements, type) {
  return elements.every(function (el) {
    return (0, _ModelUtil.is)(el, type);
  });
}

function isContainer(element) {
  if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element)) {
    return true;
  }

  return (0, _ModelUtil.is)(element, 'bpmn:Participant');
}

function setSnappedIfConstrained(event) {
  var context = event.context,
      createConstraints = context.createConstraints;

  if (!createConstraints) {
    return;
  }

  var top = createConstraints.top,
      right = createConstraints.right,
      bottom = createConstraints.bottom,
      left = createConstraints.left;

  if (left && left >= event.x || right && right <= event.x) {
    (0, _SnapUtil.setSnapped)(event, 'x', event.x);
  }

  if (top && top >= event.y || bottom && bottom <= event.y) {
    (0, _SnapUtil.setSnapped)(event, 'y', event.y);
  }
}

function includes(array, value) {
  return array.indexOf(value) !== -1;
}

function getDockingSnapOrigin(docking, isMove, event) {
  return isMove ? {
    x: docking.x - event.x,
    y: docking.y - event.y
  } : {
    x: docking.x,
    y: docking.y
  };
}

},{"../../util/DiUtil":139,"../../util/ModelUtil":141,"./BpmnSnappingUtil":131,"diagram-js/lib/features/snapping/CreateMoveSnapping":279,"diagram-js/lib/features/snapping/SnapUtil":282,"diagram-js/lib/layout/LayoutUtil":300,"inherits":347,"min-dash":555}],131:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getBoundaryAttachment = getBoundaryAttachment;

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

function getBoundaryAttachment(position, targetBounds) {
  var orientation = (0, _LayoutUtil.getOrientation)(position, targetBounds, -15);

  if (orientation !== 'intersect') {
    return orientation;
  } else {
    return null;
  }
}

},{"diagram-js/lib/layout/LayoutUtil":300}],132:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _BpmnConnectSnapping = _interopRequireDefault(require("./BpmnConnectSnapping"));

var _BpmnCreateMoveSnapping = _interopRequireDefault(require("./BpmnCreateMoveSnapping"));

var _snapping = _interopRequireDefault(require("diagram-js/lib/features/snapping"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_snapping.default],
  __init__: ['connectSnapping', 'createMoveSnapping'],
  connectSnapping: ['type', _BpmnConnectSnapping.default],
  createMoveSnapping: ['type', _BpmnCreateMoveSnapping.default]
};
exports.default = _default;

},{"./BpmnConnectSnapping":129,"./BpmnCreateMoveSnapping":130,"diagram-js/lib/features/snapping":284}],133:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnImporter;

var _minDash = require("min-dash");

var _ModelUtil = require("../util/ModelUtil");

var _LabelUtil = require("../util/LabelUtil");

var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil");

var _DiUtil = require("../util/DiUtil");

var _LabelUtil2 = require("../features/label-editing/LabelUtil");

var _Util = require("./Util");

function elementData(semantic, attrs) {
  return (0, _minDash.assign)({
    id: semantic.id,
    type: semantic.$type,
    businessObject: semantic
  }, attrs);
}

function getWaypoints(bo, source, target) {
  var waypoints = bo.di.waypoint;

  if (!waypoints || waypoints.length < 2) {
    return [(0, _LayoutUtil.getMid)(source), (0, _LayoutUtil.getMid)(target)];
  }

  return waypoints.map(function (p) {
    return {
      x: p.x,
      y: p.y
    };
  });
}

function notYetDrawn(translate, semantic, refSemantic, property) {
  return new Error(translate('element {element} referenced by {referenced}#{property} not yet drawn', {
    element: (0, _Util.elementToString)(refSemantic),
    referenced: (0, _Util.elementToString)(semantic),
    property: property
  }));
}
/**
 * An importer that adds bpmn elements to the canvas
 *
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 * @param {ElementFactory} elementFactory
 * @param {ElementRegistry} elementRegistry
 * @param {Function} translate
 * @param {TextRenderer} textRenderer
 */


function BpmnImporter(eventBus, canvas, elementFactory, elementRegistry, translate, textRenderer) {
  this._eventBus = eventBus;
  this._canvas = canvas;
  this._elementFactory = elementFactory;
  this._elementRegistry = elementRegistry;
  this._translate = translate;
  this._textRenderer = textRenderer;
}

BpmnImporter.$inject = ['eventBus', 'canvas', 'elementFactory', 'elementRegistry', 'translate', 'textRenderer'];
/**
 * Add bpmn element (semantic) to the canvas onto the
 * specified parent shape.
 */

BpmnImporter.prototype.add = function (semantic, parentElement) {
  var di = semantic.di,
      element,
      translate = this._translate,
      hidden;
  var parentIndex; // ROOT ELEMENT
  // handle the special case that we deal with a
  // invisible root element (process or collaboration)

  if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNPlane')) {
    // add a virtual element (not being drawn)
    element = this._elementFactory.createRoot(elementData(semantic));

    this._canvas.setRootElement(element);
  } // SHAPE
  else if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNShape')) {
      var collapsed = !(0, _DiUtil.isExpanded)(semantic),
          isFrame = isFrameElement(semantic);
      hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
      var bounds = semantic.di.bounds;
      element = this._elementFactory.createShape(elementData(semantic, {
        collapsed: collapsed,
        hidden: hidden,
        x: Math.round(bounds.x),
        y: Math.round(bounds.y),
        width: Math.round(bounds.width),
        height: Math.round(bounds.height),
        isFrame: isFrame
      }));

      if ((0, _ModelUtil.is)(semantic, 'bpmn:BoundaryEvent')) {
        this._attachBoundary(semantic, element);
      } // insert lanes behind other flow nodes (cf. #727)


      if ((0, _ModelUtil.is)(semantic, 'bpmn:Lane')) {
        parentIndex = 0;
      }

      if ((0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference')) {
        // check whether data store is inside our outside of its semantic parent
        if (!isPointInsideBBox(parentElement, (0, _LayoutUtil.getMid)(bounds))) {
          parentElement = this._canvas.getRootElement();
        }
      }

      this._canvas.addShape(element, parentElement, parentIndex);
    } // CONNECTION
    else if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNEdge')) {
        var source = this._getSource(semantic),
            target = this._getTarget(semantic);

        hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
        element = this._elementFactory.createConnection(elementData(semantic, {
          hidden: hidden,
          source: source,
          target: target,
          waypoints: getWaypoints(semantic, source, target)
        }));

        if ((0, _ModelUtil.is)(semantic, 'bpmn:DataAssociation')) {
          // render always on top; this ensures DataAssociations
          // are rendered correctly across different "hacks" people
          // love to model such as cross participant / sub process
          // associations
          parentElement = null;
        } // insert sequence flows behind other flow nodes (cf. #727)


        if ((0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow')) {
          parentIndex = 0;
        }

        this._canvas.addConnection(element, parentElement, parentIndex);
      } else {
        throw new Error(translate('unknown di {di} for element {semantic}', {
          di: (0, _Util.elementToString)(di),
          semantic: (0, _Util.elementToString)(semantic)
        }));
      } // (optional) LABEL


  if ((0, _LabelUtil.isLabelExternal)(semantic) && (0, _LabelUtil2.getLabel)(element)) {
    this.addLabel(semantic, element);
  }

  this._eventBus.fire('bpmnElement.added', {
    element: element
  });

  return element;
};
/**
 * Attach the boundary element to the given host
 *
 * @param {ModdleElement} boundarySemantic
 * @param {djs.model.Base} boundaryElement
 */


BpmnImporter.prototype._attachBoundary = function (boundarySemantic, boundaryElement) {
  var translate = this._translate;
  var hostSemantic = boundarySemantic.attachedToRef;

  if (!hostSemantic) {
    throw new Error(translate('missing {semantic}#attachedToRef', {
      semantic: (0, _Util.elementToString)(boundarySemantic)
    }));
  }

  var host = this._elementRegistry.get(hostSemantic.id),
      attachers = host && host.attachers;

  if (!host) {
    throw notYetDrawn(translate, boundarySemantic, hostSemantic, 'attachedToRef');
  } // wire element.host <> host.attachers


  boundaryElement.host = host;

  if (!attachers) {
    host.attachers = attachers = [];
  }

  if (attachers.indexOf(boundaryElement) === -1) {
    attachers.push(boundaryElement);
  }
};
/**
 * add label for an element
 */


BpmnImporter.prototype.addLabel = function (semantic, element) {
  var bounds, text, label;
  bounds = (0, _LabelUtil.getExternalLabelBounds)(semantic, element);
  text = (0, _LabelUtil2.getLabel)(element);

  if (text) {
    // get corrected bounds from actual layouted text
    bounds = this._textRenderer.getExternalLabelBounds(bounds, text);
  }

  label = this._elementFactory.createLabel(elementData(semantic, {
    id: semantic.id + '_label',
    labelTarget: element,
    type: 'label',
    hidden: element.hidden || !(0, _LabelUtil2.getLabel)(element),
    x: Math.round(bounds.x),
    y: Math.round(bounds.y),
    width: Math.round(bounds.width),
    height: Math.round(bounds.height)
  }));
  return this._canvas.addShape(label, element.parent);
};
/**
 * Return the drawn connection end based on the given side.
 *
 * @throws {Error} if the end is not yet drawn
 */


BpmnImporter.prototype._getEnd = function (semantic, side) {
  var element,
      refSemantic,
      type = semantic.$type,
      translate = this._translate;
  refSemantic = semantic[side + 'Ref']; // handle mysterious isMany DataAssociation#sourceRef

  if (side === 'source' && type === 'bpmn:DataInputAssociation') {
    refSemantic = refSemantic && refSemantic[0];
  } // fix source / target for DataInputAssociation / DataOutputAssociation


  if (side === 'source' && type === 'bpmn:DataOutputAssociation' || side === 'target' && type === 'bpmn:DataInputAssociation') {
    refSemantic = semantic.$parent;
  }

  element = refSemantic && this._getElement(refSemantic);

  if (element) {
    return element;
  }

  if (refSemantic) {
    throw notYetDrawn(translate, semantic, refSemantic, side + 'Ref');
  } else {
    throw new Error(translate('{semantic}#{side} Ref not specified', {
      semantic: (0, _Util.elementToString)(semantic),
      side: side
    }));
  }
};

BpmnImporter.prototype._getSource = function (semantic) {
  return this._getEnd(semantic, 'source');
};

BpmnImporter.prototype._getTarget = function (semantic) {
  return this._getEnd(semantic, 'target');
};

BpmnImporter.prototype._getElement = function (semantic) {
  return this._elementRegistry.get(semantic.id);
}; // helpers ////////////////////


function isPointInsideBBox(bbox, point) {
  var x = point.x,
      y = point.y;
  return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height;
}

function isFrameElement(semantic) {
  return (0, _ModelUtil.is)(semantic, 'bpmn:Group');
}

},{"../features/label-editing/LabelUtil":53,"../util/DiUtil":139,"../util/LabelUtil":140,"../util/ModelUtil":141,"./Util":136,"diagram-js/lib/layout/LayoutUtil":300,"min-dash":555}],134:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BpmnTreeWalker;

var _minDash = require("min-dash");

var _objectRefs = _interopRequireDefault(require("object-refs"));

var _Util = require("./Util");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var diRefs = new _objectRefs.default({
  name: 'bpmnElement',
  enumerable: true
}, {
  name: 'di',
  configurable: true
});
/**
 * Returns true if an element has the given meta-model type
 *
 * @param  {ModdleElement}  element
 * @param  {string}         type
 *
 * @return {boolean}
 */

function is(element, type) {
  return element.$instanceOf(type);
}
/**
 * Find a suitable display candidate for definitions where the DI does not
 * correctly specify one.
 */


function findDisplayCandidate(definitions) {
  return (0, _minDash.find)(definitions.rootElements, function (e) {
    return is(e, 'bpmn:Process') || is(e, 'bpmn:Collaboration');
  });
}

function BpmnTreeWalker(handler, translate) {
  // list of containers already walked
  var handledElements = {}; // list of elements to handle deferred to ensure
  // prerequisites are drawn

  var deferred = []; // Helpers //////////////////////

  function contextual(fn, ctx) {
    return function (e) {
      fn(e, ctx);
    };
  }

  function handled(element) {
    handledElements[element.id] = element;
  }

  function isHandled(element) {
    return handledElements[element.id];
  }

  function visit(element, ctx) {
    var gfx = element.gfx; // avoid multiple rendering of elements

    if (gfx) {
      throw new Error(translate('already rendered {element}', {
        element: (0, _Util.elementToString)(element)
      }));
    } // call handler


    return handler.element(element, ctx);
  }

  function visitRoot(element, diagram) {
    return handler.root(element, diagram);
  }

  function visitIfDi(element, ctx) {
    try {
      var gfx = element.di && visit(element, ctx);
      handled(element);
      return gfx;
    } catch (e) {
      logError(e.message, {
        element: element,
        error: e
      });
      console.error(translate('failed to import {element}', {
        element: (0, _Util.elementToString)(element)
      }));
      console.error(e);
    }
  }

  function logError(message, context) {
    handler.error(message, context);
  } // DI handling //////////////////////


  function registerDi(di) {
    var bpmnElement = di.bpmnElement;

    if (bpmnElement) {
      if (bpmnElement.di) {
        logError(translate('multiple DI elements defined for {element}', {
          element: (0, _Util.elementToString)(bpmnElement)
        }), {
          element: bpmnElement
        });
      } else {
        diRefs.bind(bpmnElement, 'di');
        bpmnElement.di = di;
      }
    } else {
      logError(translate('no bpmnElement referenced in {element}', {
        element: (0, _Util.elementToString)(di)
      }), {
        element: di
      });
    }
  }

  function handleDiagram(diagram) {
    handlePlane(diagram.plane);
  }

  function handlePlane(plane) {
    registerDi(plane);
    (0, _minDash.forEach)(plane.planeElement, handlePlaneElement);
  }

  function handlePlaneElement(planeElement) {
    registerDi(planeElement);
  } // Semantic handling //////////////////////

  /**
   * Handle definitions and return the rendered diagram (if any)
   *
   * @param {ModdleElement} definitions to walk and import
   * @param {ModdleElement} [diagram] specific diagram to import and display
   *
   * @throws {Error} if no diagram to display could be found
   */


  function handleDefinitions(definitions, diagram) {
    // make sure we walk the correct bpmnElement
    var diagrams = definitions.diagrams;

    if (diagram && diagrams.indexOf(diagram) === -1) {
      throw new Error(translate('diagram not part of bpmn:Definitions'));
    }

    if (!diagram && diagrams && diagrams.length) {
      diagram = diagrams[0];
    } // no diagram -> nothing to import


    if (!diagram) {
      throw new Error(translate('no diagram to display'));
    } // load DI from selected diagram only


    handleDiagram(diagram);
    var plane = diagram.plane;

    if (!plane) {
      throw new Error(translate('no plane for {element}', {
        element: (0, _Util.elementToString)(diagram)
      }));
    }

    var rootElement = plane.bpmnElement; // ensure we default to a suitable display candidate (process or collaboration),
    // even if non is specified in DI

    if (!rootElement) {
      rootElement = findDisplayCandidate(definitions);

      if (!rootElement) {
        throw new Error(translate('no process or collaboration to display'));
      } else {
        logError(translate('correcting missing bpmnElement on {plane} to {rootElement}', {
          plane: (0, _Util.elementToString)(plane),
          rootElement: (0, _Util.elementToString)(rootElement)
        })); // correct DI on the fly

        plane.bpmnElement = rootElement;
        registerDi(plane);
      }
    }

    var ctx = visitRoot(rootElement, plane);

    if (is(rootElement, 'bpmn:Process')) {
      handleProcess(rootElement, ctx);
    } else if (is(rootElement, 'bpmn:Collaboration')) {
      handleCollaboration(rootElement, ctx); // force drawing of everything not yet drawn that is part of the target DI

      handleUnhandledProcesses(definitions.rootElements, ctx);
    } else {
      throw new Error(translate('unsupported bpmnElement for {plane}: {rootElement}', {
        plane: (0, _Util.elementToString)(plane),
        rootElement: (0, _Util.elementToString)(rootElement)
      }));
    } // handle all deferred elements


    handleDeferred(deferred);
  }

  function handleDeferred() {
    var fn; // drain deferred until empty

    while (deferred.length) {
      fn = deferred.shift();
      fn();
    }
  }

  function handleProcess(process, context) {
    handleFlowElementsContainer(process, context);
    handleIoSpecification(process.ioSpecification, context);
    handleArtifacts(process.artifacts, context); // log process handled

    handled(process);
  }

  function handleUnhandledProcesses(rootElements, ctx) {
    // walk through all processes that have not yet been drawn and draw them
    // if they contain lanes with DI information.
    // we do this to pass the free-floating lane test cases in the MIWG test suite
    var processes = (0, _minDash.filter)(rootElements, function (e) {
      return !isHandled(e) && is(e, 'bpmn:Process') && e.laneSets;
    });
    processes.forEach(contextual(handleProcess, ctx));
  }

  function handleMessageFlow(messageFlow, context) {
    visitIfDi(messageFlow, context);
  }

  function handleMessageFlows(messageFlows, context) {
    (0, _minDash.forEach)(messageFlows, contextual(handleMessageFlow, context));
  }

  function handleDataAssociation(association, context) {
    visitIfDi(association, context);
  }

  function handleDataInput(dataInput, context) {
    visitIfDi(dataInput, context);
  }

  function handleDataOutput(dataOutput, context) {
    visitIfDi(dataOutput, context);
  }

  function handleArtifact(artifact, context) {
    // bpmn:TextAnnotation
    // bpmn:Group
    // bpmn:Association
    visitIfDi(artifact, context);
  }

  function handleArtifacts(artifacts, context) {
    (0, _minDash.forEach)(artifacts, function (e) {
      if (is(e, 'bpmn:Association')) {
        deferred.push(function () {
          handleArtifact(e, context);
        });
      } else {
        handleArtifact(e, context);
      }
    });
  }

  function handleIoSpecification(ioSpecification, context) {
    if (!ioSpecification) {
      return;
    }

    (0, _minDash.forEach)(ioSpecification.dataInputs, contextual(handleDataInput, context));
    (0, _minDash.forEach)(ioSpecification.dataOutputs, contextual(handleDataOutput, context));
  }

  function handleSubProcess(subProcess, context) {
    handleFlowElementsContainer(subProcess, context);
    handleArtifacts(subProcess.artifacts, context);
  }

  function handleFlowNode(flowNode, context) {
    var childCtx = visitIfDi(flowNode, context);

    if (is(flowNode, 'bpmn:SubProcess')) {
      handleSubProcess(flowNode, childCtx || context);
    }

    if (is(flowNode, 'bpmn:Activity')) {
      handleIoSpecification(flowNode.ioSpecification, context);
    } // defer handling of associations
    // affected types:
    //
    //   * bpmn:Activity
    //   * bpmn:ThrowEvent
    //   * bpmn:CatchEvent
    //


    deferred.push(function () {
      (0, _minDash.forEach)(flowNode.dataInputAssociations, contextual(handleDataAssociation, context));
      (0, _minDash.forEach)(flowNode.dataOutputAssociations, contextual(handleDataAssociation, context));
    });
  }

  function handleSequenceFlow(sequenceFlow, context) {
    visitIfDi(sequenceFlow, context);
  }

  function handleDataElement(dataObject, context) {
    visitIfDi(dataObject, context);
  }

  function handleLane(lane, context) {
    deferred.push(function () {
      var newContext = visitIfDi(lane, context);

      if (lane.childLaneSet) {
        handleLaneSet(lane.childLaneSet, newContext || context);
      }

      wireFlowNodeRefs(lane);
    });
  }

  function handleLaneSet(laneSet, context) {
    (0, _minDash.forEach)(laneSet.lanes, contextual(handleLane, context));
  }

  function handleLaneSets(laneSets, context) {
    (0, _minDash.forEach)(laneSets, contextual(handleLaneSet, context));
  }

  function handleFlowElementsContainer(container, context) {
    handleFlowElements(container.flowElements, context);

    if (container.laneSets) {
      handleLaneSets(container.laneSets, context);
    }
  }

  function handleFlowElements(flowElements, context) {
    (0, _minDash.forEach)(flowElements, function (e) {
      if (is(e, 'bpmn:SequenceFlow')) {
        deferred.push(function () {
          handleSequenceFlow(e, context);
        });
      } else if (is(e, 'bpmn:BoundaryEvent')) {
        deferred.unshift(function () {
          handleFlowNode(e, context);
        });
      } else if (is(e, 'bpmn:FlowNode')) {
        handleFlowNode(e, context);
      } else if (is(e, 'bpmn:DataObject')) {// SKIP (assume correct referencing via DataObjectReference)
      } else if (is(e, 'bpmn:DataStoreReference')) {
        handleDataElement(e, context);
      } else if (is(e, 'bpmn:DataObjectReference')) {
        handleDataElement(e, context);
      } else {
        logError(translate('unrecognized flowElement {element} in context {context}', {
          element: (0, _Util.elementToString)(e),
          context: context ? (0, _Util.elementToString)(context.businessObject) : 'null'
        }), {
          element: e,
          context: context
        });
      }
    });
  }

  function handleParticipant(participant, context) {
    var newCtx = visitIfDi(participant, context);
    var process = participant.processRef;

    if (process) {
      handleProcess(process, newCtx || context);
    }
  }

  function handleCollaboration(collaboration) {
    (0, _minDash.forEach)(collaboration.participants, contextual(handleParticipant));
    handleArtifacts(collaboration.artifacts); // handle message flows latest in the process

    deferred.push(function () {
      handleMessageFlows(collaboration.messageFlows);
    });
  }

  function wireFlowNodeRefs(lane) {
    // wire the virtual flowNodeRefs <-> relationship
    (0, _minDash.forEach)(lane.flowNodeRef, function (flowNode) {
      var lanes = flowNode.get('lanes');

      if (lanes) {
        lanes.push(lane);
      }
    });
  } // API //////////////////////


  return {
    handleDeferred: handleDeferred,
    handleDefinitions: handleDefinitions,
    handleSubProcess: handleSubProcess,
    registerDi: registerDi
  };
}

},{"./Util":136,"min-dash":555,"object-refs":560}],135:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.importBpmnDiagram = importBpmnDiagram;

var _BpmnTreeWalker = _interopRequireDefault(require("./BpmnTreeWalker"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * The importBpmnDiagram result.
 *
 * @typedef {Object} ImportBPMNDiagramResult
 *
 * @property {Array<string>} warnings
 */

/**
* The importBpmnDiagram error.
*
* @typedef {Error} ImportBPMNDiagramError
*
* @property {Array<string>} warnings
*/

/**
 * Import the definitions into a diagram.
 *
 * Errors and warnings are reported through the specified callback.
 *
 * @param  {djs.Diagram} diagram
 * @param  {ModdleElement<Definitions>} definitions
 * @param  {ModdleElement<BPMNDiagram>} [bpmnDiagram] the diagram to be rendered
 * (if not provided, the first one will be rendered)
 *
 * Returns {Promise<ImportBPMNDiagramResult, ImportBPMNDiagramError>}
 */
function importBpmnDiagram(diagram, definitions, bpmnDiagram) {
  var importer, eventBus, translate;
  var error,
      warnings = [];
  /**
   * Walk the diagram semantically, importing (=drawing)
   * all elements you encounter.
   *
   * @param {ModdleElement<Definitions>} definitions
   * @param {ModdleElement<BPMNDiagram>} bpmnDiagram
   */

  function render(definitions, bpmnDiagram) {
    var visitor = {
      root: function (element) {
        return importer.add(element);
      },
      element: function (element, parentShape) {
        return importer.add(element, parentShape);
      },
      error: function (message, context) {
        warnings.push({
          message: message,
          context: context
        });
      }
    };
    var walker = new _BpmnTreeWalker.default(visitor, translate); // traverse BPMN 2.0 document model,
    // starting at definitions

    walker.handleDefinitions(definitions, bpmnDiagram);
  }

  return new Promise(function (resolve, reject) {
    try {
      importer = diagram.get('bpmnImporter');
      eventBus = diagram.get('eventBus');
      translate = diagram.get('translate');
      eventBus.fire('import.render.start', {
        definitions: definitions
      });
      render(definitions, bpmnDiagram);
      eventBus.fire('import.render.complete', {
        error: error,
        warnings: warnings
      });
      return resolve({
        warnings: warnings
      });
    } catch (e) {
      e.warnings = warnings;
      return reject(e);
    }
  });
}

},{"./BpmnTreeWalker":134}],136:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.elementToString = elementToString;

function elementToString(e) {
  if (!e) {
    return '<null>';
  }

  return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />';
}

},{}],137:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate"));

var _BpmnImporter = _interopRequireDefault(require("./BpmnImporter"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_translate.default],
  bpmnImporter: ['type', _BpmnImporter.default]
};
exports.default = _default;

},{"./BpmnImporter":133,"diagram-js/lib/i18n/translate":296}],138:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.wrapForCompatibility = wrapForCompatibility;

var _minDash = require("min-dash");

// TODO(nikku): remove with future bpmn-js version

/**
 * Wraps APIs to check:
 *
 * 1) If a callback is passed -> Warn users about callback deprecation.
 * 2) If Promise class is implemented in current environment.
 *
 * @private
 */
function wrapForCompatibility(api) {
  return function () {
    if (!window.Promise) {
      throw new Error('Promises is not supported in this environment. Please polyfill Promise.');
    }

    var argLen = arguments.length;

    if (argLen >= 1 && (0, _minDash.isFunction)(arguments[argLen - 1])) {
      var callback = arguments[argLen - 1];
      console.warn(new Error('Passing callbacks to ' + api.name + ' is deprecated and will be removed in a future major release. ' + 'Please switch to promises: https://bpmn.io/l/moving-to-promises.html'));
      var argsWithoutCallback = Array.prototype.slice.call(arguments, 0, -1);
      api.apply(this, argsWithoutCallback).then(function (result) {
        var firstKey = Object.keys(result)[0]; // The APIs we are wrapping all resolve a single item depending on the API.
        // For instance, importXML resolves { warnings } and saveXML returns { xml }.
        // That's why we can call the callback with the first item of result.

        return callback(null, result[firstKey]); // Passing a second paramter instead of catch because we don't want to
        // catch errors thrown by callback().
      }, function (err) {
        return callback(err, err.warnings);
      });
    } else {
      return api.apply(this, arguments);
    }
  };
}

},{"min-dash":555}],139:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.isExpanded = isExpanded;
exports.isInterrupting = isInterrupting;
exports.isEventSubProcess = isEventSubProcess;
exports.hasEventDefinition = hasEventDefinition;
exports.hasErrorEventDefinition = hasErrorEventDefinition;
exports.hasEscalationEventDefinition = hasEscalationEventDefinition;
exports.hasCompensateEventDefinition = hasCompensateEventDefinition;

var _ModelUtil = require("./ModelUtil");

var _minDash = require("min-dash");

function isExpanded(element) {
  if ((0, _ModelUtil.is)(element, 'bpmn:CallActivity')) {
    return false;
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess')) {
    return !!(0, _ModelUtil.getBusinessObject)(element).di.isExpanded;
  }

  if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) {
    return !!(0, _ModelUtil.getBusinessObject)(element).processRef;
  }

  return true;
}

function isInterrupting(element) {
  return element && (0, _ModelUtil.getBusinessObject)(element).isInterrupting !== false;
}

function isEventSubProcess(element) {
  return element && !!(0, _ModelUtil.getBusinessObject)(element).triggeredByEvent;
}

function hasEventDefinition(element, eventType) {
  var bo = (0, _ModelUtil.getBusinessObject)(element),
      hasEventDefinition = false;

  if (bo.eventDefinitions) {
    (0, _minDash.forEach)(bo.eventDefinitions, function (event) {
      if ((0, _ModelUtil.is)(event, eventType)) {
        hasEventDefinition = true;
      }
    });
  }

  return hasEventDefinition;
}

function hasErrorEventDefinition(element) {
  return hasEventDefinition(element, 'bpmn:ErrorEventDefinition');
}

function hasEscalationEventDefinition(element) {
  return hasEventDefinition(element, 'bpmn:EscalationEventDefinition');
}

function hasCompensateEventDefinition(element) {
  return hasEventDefinition(element, 'bpmn:CompensateEventDefinition');
}

},{"./ModelUtil":141,"min-dash":555}],140:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.isLabelExternal = isLabelExternal;
exports.hasExternalLabel = hasExternalLabel;
exports.getFlowLabelPosition = getFlowLabelPosition;
exports.getWaypointsMid = getWaypointsMid;
exports.getExternalLabelMid = getExternalLabelMid;
exports.getExternalLabelBounds = getExternalLabelBounds;
exports.isLabel = isLabel;
exports.FLOW_LABEL_INDENT = exports.DEFAULT_LABEL_SIZE = void 0;

var _minDash = require("min-dash");

var _ModelUtil = require("./ModelUtil");

var DEFAULT_LABEL_SIZE = {
  width: 90,
  height: 20
};
exports.DEFAULT_LABEL_SIZE = DEFAULT_LABEL_SIZE;
var FLOW_LABEL_INDENT = 15;
/**
 * Returns true if the given semantic has an external label
 *
 * @param {BpmnElement} semantic
 * @return {boolean} true if has label
 */

exports.FLOW_LABEL_INDENT = FLOW_LABEL_INDENT;

function isLabelExternal(semantic) {
  return (0, _ModelUtil.is)(semantic, 'bpmn:Event') || (0, _ModelUtil.is)(semantic, 'bpmn:Gateway') || (0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference') || (0, _ModelUtil.is)(semantic, 'bpmn:DataObjectReference') || (0, _ModelUtil.is)(semantic, 'bpmn:DataInput') || (0, _ModelUtil.is)(semantic, 'bpmn:DataOutput') || (0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:MessageFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:Group');
}
/**
 * Returns true if the given element has an external label
 *
 * @param {djs.model.shape} element
 * @return {boolean} true if has label
 */


function hasExternalLabel(element) {
  return isLabel(element.label);
}
/**
 * Get the position for sequence flow labels
 *
 * @param  {Array<Point>} waypoints
 * @return {Point} the label position
 */


function getFlowLabelPosition(waypoints) {
  // get the waypoints mid
  var mid = waypoints.length / 2 - 1;
  var first = waypoints[Math.floor(mid)];
  var second = waypoints[Math.ceil(mid + 0.01)]; // get position

  var position = getWaypointsMid(waypoints); // calculate angle

  var angle = Math.atan((second.y - first.y) / (second.x - first.x));
  var x = position.x,
      y = position.y;

  if (Math.abs(angle) < Math.PI / 2) {
    y -= FLOW_LABEL_INDENT;
  } else {
    x += FLOW_LABEL_INDENT;
  }

  return {
    x: x,
    y: y
  };
}
/**
 * Get the middle of a number of waypoints
 *
 * @param  {Array<Point>} waypoints
 * @return {Point} the mid point
 */


function getWaypointsMid(waypoints) {
  var mid = waypoints.length / 2 - 1;
  var first = waypoints[Math.floor(mid)];
  var second = waypoints[Math.ceil(mid + 0.01)];
  return {
    x: first.x + (second.x - first.x) / 2,
    y: first.y + (second.y - first.y) / 2
  };
}

function getExternalLabelMid(element) {
  if (element.waypoints) {
    return getFlowLabelPosition(element.waypoints);
  } else if ((0, _ModelUtil.is)(element, 'bpmn:Group')) {
    return {
      x: element.x + element.width / 2,
      y: element.y + DEFAULT_LABEL_SIZE.height / 2
    };
  } else {
    return {
      x: element.x + element.width / 2,
      y: element.y + element.height + DEFAULT_LABEL_SIZE.height / 2
    };
  }
}
/**
 * Returns the bounds of an elements label, parsed from the elements DI or
 * generated from its bounds.
 *
 * @param {BpmnElement} semantic
 * @param {djs.model.Base} element
 */


function getExternalLabelBounds(semantic, element) {
  var mid,
      size,
      bounds,
      di = semantic.di,
      label = di.label;

  if (label && label.bounds) {
    bounds = label.bounds;
    size = {
      width: Math.max(DEFAULT_LABEL_SIZE.width, bounds.width),
      height: bounds.height
    };
    mid = {
      x: bounds.x + bounds.width / 2,
      y: bounds.y + bounds.height / 2
    };
  } else {
    mid = getExternalLabelMid(element);
    size = DEFAULT_LABEL_SIZE;
  }

  return (0, _minDash.assign)({
    x: mid.x - size.width / 2,
    y: mid.y - size.height / 2
  }, size);
}

function isLabel(element) {
  return element && !!element.labelTarget;
}

},{"./ModelUtil":141,"min-dash":555}],141:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.is = is;
exports.getBusinessObject = getBusinessObject;

/**
 * Is an element of the given BPMN type?
 *
 * @param  {djs.model.Base|ModdleElement} element
 * @param  {string} type
 *
 * @return {boolean}
 */
function is(element, type) {
  var bo = getBusinessObject(element);
  return bo && typeof bo.$instanceOf === 'function' && bo.$instanceOf(type);
}
/**
 * Return the business object for a given element.
 *
 * @param  {djs.model.Base|ModdleElement} element
 *
 * @return {ModdleElement}
 */


function getBusinessObject(element) {
  return element && element.businessObject || element;
}

},{}],142:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.open = open;
exports.LINK_STYLES = exports.BPMNIO_IMG = void 0;

var _minDom = require("min-dom");

/**
 * This file must not be changed or exchanged.
 *
 * @see http://bpmn.io/license for more information.
 */
// inlined ../../resources/logo.svg
var BPMNIO_LOGO_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.02 5.57" width="53" height="21" style="vertical-align:middle"><path fill="currentColor" d="M1.88.92v.14c0 .41-.13.68-.4.8.33.14.46.44.46.86v.33c0 .61-.33.95-.95.95H0V0h.95c.65 0 .93.3.93.92zM.63.57v1.06h.24c.24 0 .38-.1.38-.43V.98c0-.28-.1-.4-.32-.4zm0 1.63v1.22h.36c.2 0 .32-.1.32-.39v-.35c0-.37-.12-.48-.4-.48H.63zM4.18.99v.52c0 .64-.31.98-.94.98h-.3V4h-.62V0h.92c.63 0 .94.35.94.99zM2.94.57v1.35h.3c.2 0 .3-.09.3-.37v-.6c0-.29-.1-.38-.3-.38h-.3zm2.89 2.27L6.25 0h.88v4h-.6V1.12L6.1 3.99h-.6l-.46-2.82v2.82h-.55V0h.87zM8.14 1.1V4h-.56V0h.79L9 2.4V0h.56v4h-.64zm2.49 2.29v.6h-.6v-.6zM12.12 1c0-.63.33-1 .95-1 .61 0 .95.37.95 1v2.04c0 .64-.34 1-.95 1-.62 0-.95-.37-.95-1zm.62 2.08c0 .28.13.39.33.39s.32-.1.32-.4V.98c0-.29-.12-.4-.32-.4s-.33.11-.33.4z"/><path fill="currentColor" d="M0 4.53h14.02v1.04H0zM11.08 0h.63v.62h-.63zm.63 4V1h-.63v2.98z"/></svg>';
var BPMNIO_IMG = BPMNIO_LOGO_SVG;
exports.BPMNIO_IMG = BPMNIO_IMG;

function css(attrs) {
  return attrs.join(';');
}

var LINK_STYLES = css(['color: #404040']);
exports.LINK_STYLES = LINK_STYLES;
var LIGHTBOX_STYLES = css(['z-index: 1001', 'position: fixed', 'top: 0', 'left: 0', 'right: 0', 'bottom: 0']);
var BACKDROP_STYLES = css(['width: 100%', 'height: 100%', 'background: rgba(40,40,40,0.2)']);
var NOTICE_STYLES = css(['position: absolute', 'left: 50%', 'top: 40%', 'transform: translate(-50%)', 'width: 260px', 'padding: 10px', 'background: white', 'box-shadow: 0 1px 4px rgba(0,0,0,0.3)', 'font-family: Helvetica, Arial, sans-serif', 'font-size: 14px', 'display: flex', 'line-height: 1.3']);
var LIGHTBOX_MARKUP = '<div class="bjs-powered-by-lightbox" style="' + LIGHTBOX_STYLES + '">' + '<div class="backdrop" style="' + BACKDROP_STYLES + '"></div>' + '<div class="notice" style="' + NOTICE_STYLES + '">' + '<a href="https://bpmn.io" target="_blank" rel="noopener" style="margin: 15px 20px 15px 10px; align-self: center;' + LINK_STYLES + '">' + BPMNIO_IMG + '</a>' + '<span>' + 'Web-based tooling for BPMN, DMN and CMMN diagrams ' + 'powered by <a href="https://bpmn.io" target="_blank" rel="noopener">bpmn.io</a>.' + '</span>' + '</div>' + '</div>';
var lightbox;

function open() {
  if (!lightbox) {
    lightbox = (0, _minDom.domify)(LIGHTBOX_MARKUP);

    _minDom.delegate.bind(lightbox, '.backdrop', 'click', function (event) {
      document.body.removeChild(lightbox);
    });
  }

  document.body.appendChild(lightbox);
}

},{"min-dom":556}],143:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
Object.defineProperty(exports, "default", {
  enumerable: true,
  get: function () {
    return _Diagram.default;
  }
});

var _Diagram = _interopRequireDefault(require("./lib/Diagram"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

},{"./lib/Diagram":144}],144:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Diagram;

var _didi = require("didi");

var _core = _interopRequireDefault(require("./core"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Bootstrap an injector from a list of modules, instantiating a number of default components
 *
 * @ignore
 * @param {Array<didi.Module>} bootstrapModules
 *
 * @return {didi.Injector} a injector to use to access the components
 */
function bootstrap(bootstrapModules) {
  var modules = [],
      components = [];

  function hasModule(m) {
    return modules.indexOf(m) >= 0;
  }

  function addModule(m) {
    modules.push(m);
  }

  function visit(m) {
    if (hasModule(m)) {
      return;
    }

    (m.__depends__ || []).forEach(visit);

    if (hasModule(m)) {
      return;
    }

    addModule(m);
    (m.__init__ || []).forEach(function (c) {
      components.push(c);
    });
  }

  bootstrapModules.forEach(visit);
  var injector = new _didi.Injector(modules);
  components.forEach(function (c) {
    try {
      // eagerly resolve component (fn or string)
      injector[typeof c === 'string' ? 'get' : 'invoke'](c);
    } catch (e) {
      console.error('Failed to instantiate component');
      console.error(e.stack);
      throw e;
    }
  });
  return injector;
}
/**
 * Creates an injector from passed options.
 *
 * @ignore
 * @param  {Object} options
 * @return {didi.Injector}
 */


function createInjector(options) {
  options = options || {};
  var configModule = {
    'config': ['value', options]
  };
  var modules = [configModule, _core.default].concat(options.modules || []);
  return bootstrap(modules);
}
/**
 * The main diagram-js entry point that bootstraps the diagram with the given
 * configuration.
 *
 * To register extensions with the diagram, pass them as Array<didi.Module> to the constructor.
 *
 * @class djs.Diagram
 * @memberOf djs
 * @constructor
 *
 * @example
 *
 * <caption>Creating a plug-in that logs whenever a shape is added to the canvas.</caption>
 *
 * // plug-in implemenentation
 * function MyLoggingPlugin(eventBus) {
 *   eventBus.on('shape.added', function(event) {
 *     console.log('shape ', event.shape, ' was added to the diagram');
 *   });
 * }
 *
 * // export as module
 * export default {
 *   __init__: [ 'myLoggingPlugin' ],
 *     myLoggingPlugin: [ 'type', MyLoggingPlugin ]
 * };
 *
 *
 * // instantiate the diagram with the new plug-in
 *
 * import MyLoggingModule from 'path-to-my-logging-plugin';
 *
 * var diagram = new Diagram({
 *   modules: [
 *     MyLoggingModule
 *   ]
 * });
 *
 * diagram.invoke([ 'canvas', function(canvas) {
 *   // add shape to drawing canvas
 *   canvas.addShape({ x: 10, y: 10 });
 * });
 *
 * // 'shape ... was added to the diagram' logged to console
 *
 * @param {Object} options
 * @param {Array<didi.Module>} [options.modules] external modules to instantiate with the diagram
 * @param {didi.Injector} [injector] an (optional) injector to bootstrap the diagram with
 */


function Diagram(options, injector) {
  // create injector unless explicitly specified
  this.injector = injector = injector || createInjector(options); // API

  /**
   * Resolves a diagram service
   *
   * @method Diagram#get
   *
   * @param {string} name the name of the diagram service to be retrieved
   * @param {boolean} [strict=true] if false, resolve missing services to null
   */

  this.get = injector.get;
  /**
   * Executes a function into which diagram services are injected
   *
   * @method Diagram#invoke
   *
   * @param {Function|Object[]} fn the function to resolve
   * @param {Object} locals a number of locals to use to resolve certain dependencies
   */

  this.invoke = injector.invoke; // init
  // indicate via event

  /**
   * An event indicating that all plug-ins are loaded.
   *
   * Use this event to fire other events to interested plug-ins
   *
   * @memberOf Diagram
   *
   * @event diagram.init
   *
   * @example
   *
   * eventBus.on('diagram.init', function() {
   *   eventBus.fire('my-custom-event', { foo: 'BAR' });
   * });
   *
   * @type {Object}
   */

  this.get('eventBus').fire('diagram.init');
}
/**
 * Destroys the diagram
 *
 * @method  Diagram#destroy
 */


Diagram.prototype.destroy = function () {
  this.get('eventBus').fire('diagram.destroy');
};
/**
 * Clear the diagram, removing all contents.
 */


Diagram.prototype.clear = function () {
  this.get('eventBus').fire('diagram.clear');
};

},{"./core":153,"didi":344}],145:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CommandInterceptor;

var _minDash = require("min-dash");

var DEFAULT_PRIORITY = 1000;
/**
 * A utility that can be used to plug-in into the command execution for
 * extension and/or validation.
 *
 * @param {EventBus} eventBus
 *
 * @example
 *
 * import inherits from 'inherits';
 *
 * import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
 *
 * function CommandLogger(eventBus) {
 *   CommandInterceptor.call(this, eventBus);
 *
 *   this.preExecute(function(event) {
 *     console.log('command pre-execute', event);
 *   });
 * }
 *
 * inherits(CommandLogger, CommandInterceptor);
 *
 */

function CommandInterceptor(eventBus) {
  this._eventBus = eventBus;
}

CommandInterceptor.$inject = ['eventBus'];

function unwrapEvent(fn, that) {
  return function (event) {
    return fn.call(that || null, event.context, event.command, event);
  };
}
/**
 * Register an interceptor for a command execution
 *
 * @param {string|Array<string>} [events] list of commands to register on
 * @param {string} [hook] command hook, i.e. preExecute, executed to listen on
 * @param {number} [priority] the priority on which to hook into the execution
 * @param {Function} handlerFn interceptor to be invoked with (event)
 * @param {boolean} unwrap if true, unwrap the event and pass (context, command, event) to the
 *                          listener instead
 * @param {Object} [that] Pass context (`this`) to the handler function
 */


CommandInterceptor.prototype.on = function (events, hook, priority, handlerFn, unwrap, that) {
  if ((0, _minDash.isFunction)(hook) || (0, _minDash.isNumber)(hook)) {
    that = unwrap;
    unwrap = handlerFn;
    handlerFn = priority;
    priority = hook;
    hook = null;
  }

  if ((0, _minDash.isFunction)(priority)) {
    that = unwrap;
    unwrap = handlerFn;
    handlerFn = priority;
    priority = DEFAULT_PRIORITY;
  }

  if ((0, _minDash.isObject)(unwrap)) {
    that = unwrap;
    unwrap = false;
  }

  if (!(0, _minDash.isFunction)(handlerFn)) {
    throw new Error('handlerFn must be a function');
  }

  if (!(0, _minDash.isArray)(events)) {
    events = [events];
  }

  var eventBus = this._eventBus;
  (0, _minDash.forEach)(events, function (event) {
    // concat commandStack(.event)?(.hook)?
    var fullEvent = ['commandStack', event, hook].filter(function (e) {
      return e;
    }).join('.');
    eventBus.on(fullEvent, priority, unwrap ? unwrapEvent(handlerFn, that) : handlerFn, that);
  });
};

var hooks = ['canExecute', 'preExecute', 'preExecuted', 'execute', 'executed', 'postExecute', 'postExecuted', 'revert', 'reverted'];
/*
 * Install hook shortcuts
 *
 * This will generate the CommandInterceptor#(preExecute|...|reverted) methods
 * which will in term forward to CommandInterceptor#on.
 */

(0, _minDash.forEach)(hooks, function (hook) {
  /**
   * {canExecute|preExecute|preExecuted|execute|executed|postExecute|postExecuted|revert|reverted}
   *
   * A named hook for plugging into the command execution
   *
   * @param {string|Array<string>} [events] list of commands to register on
   * @param {number} [priority] the priority on which to hook into the execution
   * @param {Function} handlerFn interceptor to be invoked with (event)
   * @param {boolean} [unwrap=false] if true, unwrap the event and pass (context, command, event) to the
   *                          listener instead
   * @param {Object} [that] Pass context (`this`) to the handler function
   */
  CommandInterceptor.prototype[hook] = function (events, priority, handlerFn, unwrap, that) {
    if ((0, _minDash.isFunction)(events) || (0, _minDash.isNumber)(events)) {
      that = unwrap;
      unwrap = handlerFn;
      handlerFn = priority;
      priority = events;
      events = null;
    }

    this.on(events, hook, priority, handlerFn, unwrap, that);
  };
});

},{"min-dash":555}],146:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CommandStack;

var _minDash = require("min-dash");

/**
 * A service that offers un- and redoable execution of commands.
 *
 * The command stack is responsible for executing modeling actions
 * in a un- and redoable manner. To do this it delegates the actual
 * command execution to {@link CommandHandler}s.
 *
 * Command handlers provide {@link CommandHandler#execute(ctx)} and
 * {@link CommandHandler#revert(ctx)} methods to un- and redo a command
 * identified by a command context.
 *
 *
 * ## Life-Cycle events
 *
 * In the process the command stack fires a number of life-cycle events
 * that other components to participate in the command execution.
 *
 *    * preExecute
 *    * preExecuted
 *    * execute
 *    * executed
 *    * postExecute
 *    * postExecuted
 *    * revert
 *    * reverted
 *
 * A special event is used for validating, whether a command can be
 * performed prior to its execution.
 *
 *    * canExecute
 *
 * Each of the events is fired as `commandStack.{eventName}` and
 * `commandStack.{commandName}.{eventName}`, respectively. This gives
 * components fine grained control on where to hook into.
 *
 * The event object fired transports `command`, the name of the
 * command and `context`, the command context.
 *
 *
 * ## Creating Command Handlers
 *
 * Command handlers should provide the {@link CommandHandler#execute(ctx)}
 * and {@link CommandHandler#revert(ctx)} methods to implement
 * redoing and undoing of a command.
 *
 * A command handler _must_ ensure undo is performed properly in order
 * not to break the undo chain. It must also return the shapes that
 * got changed during the `execute` and `revert` operations.
 *
 * Command handlers may execute other modeling operations (and thus
 * commands) in their `preExecute` and `postExecute` phases. The command
 * stack will properly group all commands together into a logical unit
 * that may be re- and undone atomically.
 *
 * Command handlers must not execute other commands from within their
 * core implementation (`execute`, `revert`).
 *
 *
 * ## Change Tracking
 *
 * During the execution of the CommandStack it will keep track of all
 * elements that have been touched during the command's execution.
 *
 * At the end of the CommandStack execution it will notify interested
 * components via an 'elements.changed' event with all the dirty
 * elements.
 *
 * The event can be picked up by components that are interested in the fact
 * that elements have been changed. One use case for this is updating
 * their graphical representation after moving / resizing or deletion.
 *
 * @see CommandHandler
 *
 * @param {EventBus} eventBus
 * @param {Injector} injector
 */
function CommandStack(eventBus, injector) {
  /**
   * A map of all registered command handlers.
   *
   * @type {Object}
   */
  this._handlerMap = {};
  /**
   * A stack containing all re/undoable actions on the diagram
   *
   * @type {Array<Object>}
   */

  this._stack = [];
  /**
   * The current index on the stack
   *
   * @type {number}
   */

  this._stackIdx = -1;
  /**
   * Current active commandStack execution
   *
   * @type {Object}
   */

  this._currentExecution = {
    actions: [],
    dirty: []
  };
  this._injector = injector;
  this._eventBus = eventBus;
  this._uid = 1;
  eventBus.on(['diagram.destroy', 'diagram.clear'], function () {
    this.clear(false);
  }, this);
}

CommandStack.$inject = ['eventBus', 'injector'];
/**
 * Execute a command
 *
 * @param {string} command the command to execute
 * @param {Object} context the environment to execute the command in
 */

CommandStack.prototype.execute = function (command, context) {
  if (!command) {
    throw new Error('command required');
  }

  var action = {
    command: command,
    context: context
  };

  this._pushAction(action);

  this._internalExecute(action);

  this._popAction(action);
};
/**
 * Ask whether a given command can be executed.
 *
 * Implementors may hook into the mechanism on two ways:
 *
 *   * in event listeners:
 *
 *     Users may prevent the execution via an event listener.
 *     It must prevent the default action for `commandStack.(<command>.)canExecute` events.
 *
 *   * in command handlers:
 *
 *     If the method {@link CommandHandler#canExecute} is implemented in a handler
 *     it will be called to figure out whether the execution is allowed.
 *
 * @param  {string} command the command to execute
 * @param  {Object} context the environment to execute the command in
 *
 * @return {boolean} true if the command can be executed
 */


CommandStack.prototype.canExecute = function (command, context) {
  var action = {
    command: command,
    context: context
  };

  var handler = this._getHandler(command);

  var result = this._fire(command, 'canExecute', action); // handler#canExecute will only be called if no listener
  // decided on a result already


  if (result === undefined) {
    if (!handler) {
      return false;
    }

    if (handler.canExecute) {
      result = handler.canExecute(context);
    }
  }

  return result;
};
/**
 * Clear the command stack, erasing all undo / redo history
 */


CommandStack.prototype.clear = function (emit) {
  this._stack.length = 0;
  this._stackIdx = -1;

  if (emit !== false) {
    this._fire('changed');
  }
};
/**
 * Undo last command(s)
 */


CommandStack.prototype.undo = function () {
  var action = this._getUndoAction(),
      next;

  if (action) {
    this._pushAction(action);

    while (action) {
      this._internalUndo(action);

      next = this._getUndoAction();

      if (!next || next.id !== action.id) {
        break;
      }

      action = next;
    }

    this._popAction();
  }
};
/**
 * Redo last command(s)
 */


CommandStack.prototype.redo = function () {
  var action = this._getRedoAction(),
      next;

  if (action) {
    this._pushAction(action);

    while (action) {
      this._internalExecute(action, true);

      next = this._getRedoAction();

      if (!next || next.id !== action.id) {
        break;
      }

      action = next;
    }

    this._popAction();
  }
};
/**
 * Register a handler instance with the command stack
 *
 * @param {string} command
 * @param {CommandHandler} handler
 */


CommandStack.prototype.register = function (command, handler) {
  this._setHandler(command, handler);
};
/**
 * Register a handler type with the command stack
 * by instantiating it and injecting its dependencies.
 *
 * @param {string} command
 * @param {Function} a constructor for a {@link CommandHandler}
 */


CommandStack.prototype.registerHandler = function (command, handlerCls) {
  if (!command || !handlerCls) {
    throw new Error('command and handlerCls must be defined');
  }

  var handler = this._injector.instantiate(handlerCls);

  this.register(command, handler);
};

CommandStack.prototype.canUndo = function () {
  return !!this._getUndoAction();
};

CommandStack.prototype.canRedo = function () {
  return !!this._getRedoAction();
}; // stack access  //////////////////////


CommandStack.prototype._getRedoAction = function () {
  return this._stack[this._stackIdx + 1];
};

CommandStack.prototype._getUndoAction = function () {
  return this._stack[this._stackIdx];
}; // internal functionality //////////////////////


CommandStack.prototype._internalUndo = function (action) {
  var self = this;
  var command = action.command,
      context = action.context;

  var handler = this._getHandler(command); // guard against illegal nested command stack invocations


  this._atomicDo(function () {
    self._fire(command, 'revert', action);

    if (handler.revert) {
      self._markDirty(handler.revert(context));
    }

    self._revertedAction(action);

    self._fire(command, 'reverted', action);
  });
};

CommandStack.prototype._fire = function (command, qualifier, event) {
  if (arguments.length < 3) {
    event = qualifier;
    qualifier = null;
  }

  var names = qualifier ? [command + '.' + qualifier, qualifier] : [command],
      i,
      name,
      result;
  event = this._eventBus.createEvent(event);

  for (i = 0; name = names[i]; i++) {
    result = this._eventBus.fire('commandStack.' + name, event);

    if (event.cancelBubble) {
      break;
    }
  }

  return result;
};

CommandStack.prototype._createId = function () {
  return this._uid++;
};

CommandStack.prototype._atomicDo = function (fn) {
  var execution = this._currentExecution;
  execution.atomic = true;

  try {
    fn();
  } finally {
    execution.atomic = false;
  }
};

CommandStack.prototype._internalExecute = function (action, redo) {
  var self = this;
  var command = action.command,
      context = action.context;

  var handler = this._getHandler(command);

  if (!handler) {
    throw new Error('no command handler registered for <' + command + '>');
  }

  this._pushAction(action);

  if (!redo) {
    this._fire(command, 'preExecute', action);

    if (handler.preExecute) {
      handler.preExecute(context);
    }

    this._fire(command, 'preExecuted', action);
  } // guard against illegal nested command stack invocations


  this._atomicDo(function () {
    self._fire(command, 'execute', action);

    if (handler.execute) {
      // actual execute + mark return results as dirty
      self._markDirty(handler.execute(context));
    } // log to stack


    self._executedAction(action, redo);

    self._fire(command, 'executed', action);
  });

  if (!redo) {
    this._fire(command, 'postExecute', action);

    if (handler.postExecute) {
      handler.postExecute(context);
    }

    this._fire(command, 'postExecuted', action);
  }

  this._popAction(action);
};

CommandStack.prototype._pushAction = function (action) {
  var execution = this._currentExecution,
      actions = execution.actions;
  var baseAction = actions[0];

  if (execution.atomic) {
    throw new Error('illegal invocation in <execute> or <revert> phase (action: ' + action.command + ')');
  }

  if (!action.id) {
    action.id = baseAction && baseAction.id || this._createId();
  }

  actions.push(action);
};

CommandStack.prototype._popAction = function () {
  var execution = this._currentExecution,
      actions = execution.actions,
      dirty = execution.dirty;
  actions.pop();

  if (!actions.length) {
    this._eventBus.fire('elements.changed', {
      elements: (0, _minDash.uniqueBy)('id', dirty.reverse())
    });

    dirty.length = 0;

    this._fire('changed');
  }
};

CommandStack.prototype._markDirty = function (elements) {
  var execution = this._currentExecution;

  if (!elements) {
    return;
  }

  elements = (0, _minDash.isArray)(elements) ? elements : [elements];
  execution.dirty = execution.dirty.concat(elements);
};

CommandStack.prototype._executedAction = function (action, redo) {
  var stackIdx = ++this._stackIdx;

  if (!redo) {
    this._stack.splice(stackIdx, this._stack.length, action);
  }
};

CommandStack.prototype._revertedAction = function (action) {
  this._stackIdx--;
};

CommandStack.prototype._getHandler = function (command) {
  return this._handlerMap[command];
};

CommandStack.prototype._setHandler = function (command, handler) {
  if (!command || !handler) {
    throw new Error('command and handler required');
  }

  if (this._handlerMap[command]) {
    throw new Error('overriding handler for command <' + command + '>');
  }

  this._handlerMap[command] = handler;
};

},{"min-dash":555}],147:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _CommandStack = _interopRequireDefault(require("./CommandStack"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  commandStack: ['type', _CommandStack.default]
};
exports.default = _default;

},{"./CommandStack":146}],148:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Canvas;

var _minDash = require("min-dash");

var _Collections = require("../util/Collections");

var _Elements = require("../util/Elements");

var _tinySvg = require("tiny-svg");

function round(number, resolution) {
  return Math.round(number * resolution) / resolution;
}

function ensurePx(number) {
  return (0, _minDash.isNumber)(number) ? number + 'px' : number;
}
/**
 * Creates a HTML container element for a SVG element with
 * the given configuration
 *
 * @param  {Object} options
 * @return {HTMLElement} the container element
 */


function createContainer(options) {
  options = (0, _minDash.assign)({}, {
    width: '100%',
    height: '100%'
  }, options);
  var container = options.container || document.body; // create a <div> around the svg element with the respective size
  // this way we can always get the correct container size
  // (this is impossible for <svg> elements at the moment)

  var parent = document.createElement('div');
  parent.setAttribute('class', 'djs-container');
  (0, _minDash.assign)(parent.style, {
    position: 'relative',
    overflow: 'hidden',
    width: ensurePx(options.width),
    height: ensurePx(options.height)
  });
  container.appendChild(parent);
  return parent;
}

function createGroup(parent, cls, childIndex) {
  var group = (0, _tinySvg.create)('g');
  (0, _tinySvg.classes)(group).add(cls);
  var index = childIndex !== undefined ? childIndex : parent.childNodes.length - 1; // must ensure second argument is node or _null_
  // cf. https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore

  parent.insertBefore(group, parent.childNodes[index] || null);
  return group;
}

var BASE_LAYER = 'base';
var REQUIRED_MODEL_ATTRS = {
  shape: ['x', 'y', 'width', 'height'],
  connection: ['waypoints']
};
/**
 * The main drawing canvas.
 *
 * @class
 * @constructor
 *
 * @emits Canvas#canvas.init
 *
 * @param {Object} config
 * @param {EventBus} eventBus
 * @param {GraphicsFactory} graphicsFactory
 * @param {ElementRegistry} elementRegistry
 */

function Canvas(config, eventBus, graphicsFactory, elementRegistry) {
  this._eventBus = eventBus;
  this._elementRegistry = elementRegistry;
  this._graphicsFactory = graphicsFactory;

  this._init(config || {});
}

Canvas.$inject = ['config.canvas', 'eventBus', 'graphicsFactory', 'elementRegistry'];

Canvas.prototype._init = function (config) {
  var eventBus = this._eventBus; // Creates a <svg> element that is wrapped into a <div>.
  // This way we are always able to correctly figure out the size of the svg element
  // by querying the parent node.
  //
  // (It is not possible to get the size of a svg element cross browser @ 2014-04-01)
  //
  // <div class="djs-container" style="width: {desired-width}, height: {desired-height}">
  //   <svg width="100%" height="100%">
  //    ...
  //   </svg>
  // </div>
  // html container

  var container = this._container = createContainer(config);
  var svg = this._svg = (0, _tinySvg.create)('svg');
  (0, _tinySvg.attr)(svg, {
    width: '100%',
    height: '100%'
  });
  (0, _tinySvg.append)(container, svg);
  var viewport = this._viewport = createGroup(svg, 'viewport');
  this._layers = {}; // debounce canvas.viewbox.changed events
  // for smoother diagram interaction

  if (config.deferUpdate !== false) {
    this._viewboxChanged = (0, _minDash.debounce)((0, _minDash.bind)(this._viewboxChanged, this), 300);
  }

  eventBus.on('diagram.init', function () {
    /**
     * An event indicating that the canvas is ready to be drawn on.
     *
     * @memberOf Canvas
     *
     * @event canvas.init
     *
     * @type {Object}
     * @property {SVGElement} svg the created svg element
     * @property {SVGElement} viewport the direct parent of diagram elements and shapes
     */
    eventBus.fire('canvas.init', {
      svg: svg,
      viewport: viewport
    });
  }, this); // reset viewbox on shape changes to
  // recompute the viewbox

  eventBus.on(['shape.added', 'connection.added', 'shape.removed', 'connection.removed', 'elements.changed'], function () {
    delete this._cachedViewbox;
  }, this);
  eventBus.on('diagram.destroy', 500, this._destroy, this);
  eventBus.on('diagram.clear', 500, this._clear, this);
};

Canvas.prototype._destroy = function (emit) {
  this._eventBus.fire('canvas.destroy', {
    svg: this._svg,
    viewport: this._viewport
  });

  var parent = this._container.parentNode;

  if (parent) {
    parent.removeChild(this._container);
  }

  delete this._svg;
  delete this._container;
  delete this._layers;
  delete this._rootElement;
  delete this._viewport;
};

Canvas.prototype._clear = function () {
  var self = this;

  var allElements = this._elementRegistry.getAll(); // remove all elements


  allElements.forEach(function (element) {
    var type = (0, _Elements.getType)(element);

    if (type === 'root') {
      self.setRootElement(null, true);
    } else {
      self._removeElement(element, type);
    }
  }); // force recomputation of view box

  delete this._cachedViewbox;
};
/**
 * Returns the default layer on which
 * all elements are drawn.
 *
 * @returns {SVGElement}
 */


Canvas.prototype.getDefaultLayer = function () {
  return this.getLayer(BASE_LAYER, 0);
};
/**
 * Returns a layer that is used to draw elements
 * or annotations on it.
 *
 * Non-existing layers retrieved through this method
 * will be created. During creation, the optional index
 * may be used to create layers below or above existing layers.
 * A layer with a certain index is always created above all
 * existing layers with the same index.
 *
 * @param {string} name
 * @param {number} index
 *
 * @returns {SVGElement}
 */


Canvas.prototype.getLayer = function (name, index) {
  if (!name) {
    throw new Error('must specify a name');
  }

  var layer = this._layers[name];

  if (!layer) {
    layer = this._layers[name] = this._createLayer(name, index);
  } // throw an error if layer creation / retrival is
  // requested on different index


  if (typeof index !== 'undefined' && layer.index !== index) {
    throw new Error('layer <' + name + '> already created at index <' + index + '>');
  }

  return layer.group;
};
/**
 * Creates a given layer and returns it.
 *
 * @param {string} name
 * @param {number} [index=0]
 *
 * @return {Object} layer descriptor with { index, group: SVGGroup }
 */


Canvas.prototype._createLayer = function (name, index) {
  if (!index) {
    index = 0;
  }

  var childIndex = (0, _minDash.reduce)(this._layers, function (childIndex, layer) {
    if (index >= layer.index) {
      childIndex++;
    }

    return childIndex;
  }, 0);
  return {
    group: createGroup(this._viewport, 'layer-' + name, childIndex),
    index: index
  };
};
/**
 * Returns the html element that encloses the
 * drawing canvas.
 *
 * @return {DOMNode}
 */


Canvas.prototype.getContainer = function () {
  return this._container;
}; // markers //////////////////////


Canvas.prototype._updateMarker = function (element, marker, add) {
  var container;

  if (!element.id) {
    element = this._elementRegistry.get(element);
  } // we need to access all


  container = this._elementRegistry._elements[element.id];

  if (!container) {
    return;
  }

  (0, _minDash.forEach)([container.gfx, container.secondaryGfx], function (gfx) {
    if (gfx) {
      // invoke either addClass or removeClass based on mode
      if (add) {
        (0, _tinySvg.classes)(gfx).add(marker);
      } else {
        (0, _tinySvg.classes)(gfx).remove(marker);
      }
    }
  });
  /**
   * An event indicating that a marker has been updated for an element
   *
   * @event element.marker.update
   * @type {Object}
   * @property {djs.model.Element} element the shape
   * @property {Object} gfx the graphical representation of the shape
   * @property {string} marker
   * @property {boolean} add true if the marker was added, false if it got removed
   */

  this._eventBus.fire('element.marker.update', {
    element: element,
    gfx: container.gfx,
    marker: marker,
    add: !!add
  });
};
/**
 * Adds a marker to an element (basically a css class).
 *
 * Fires the element.marker.update event, making it possible to
 * integrate extension into the marker life-cycle, too.
 *
 * @example
 * canvas.addMarker('foo', 'some-marker');
 *
 * var fooGfx = canvas.getGraphics('foo');
 *
 * fooGfx; // <g class="... some-marker"> ... </g>
 *
 * @param {string|djs.model.Base} element
 * @param {string} marker
 */


Canvas.prototype.addMarker = function (element, marker) {
  this._updateMarker(element, marker, true);
};
/**
 * Remove a marker from an element.
 *
 * Fires the element.marker.update event, making it possible to
 * integrate extension into the marker life-cycle, too.
 *
 * @param  {string|djs.model.Base} element
 * @param  {string} marker
 */


Canvas.prototype.removeMarker = function (element, marker) {
  this._updateMarker(element, marker, false);
};
/**
 * Check the existence of a marker on element.
 *
 * @param  {string|djs.model.Base} element
 * @param  {string} marker
 */


Canvas.prototype.hasMarker = function (element, marker) {
  if (!element.id) {
    element = this._elementRegistry.get(element);
  }

  var gfx = this.getGraphics(element);
  return (0, _tinySvg.classes)(gfx).has(marker);
};
/**
 * Toggles a marker on an element.
 *
 * Fires the element.marker.update event, making it possible to
 * integrate extension into the marker life-cycle, too.
 *
 * @param  {string|djs.model.Base} element
 * @param  {string} marker
 */


Canvas.prototype.toggleMarker = function (element, marker) {
  if (this.hasMarker(element, marker)) {
    this.removeMarker(element, marker);
  } else {
    this.addMarker(element, marker);
  }
};

Canvas.prototype.getRootElement = function () {
  if (!this._rootElement) {
    this.setRootElement({
      id: '__implicitroot',
      children: []
    });
  }

  return this._rootElement;
}; // root element handling //////////////////////

/**
 * Sets a given element as the new root element for the canvas
 * and returns the new root element.
 *
 * @param {Object|djs.model.Root} element
 * @param {boolean} [override] whether to override the current root element, if any
 *
 * @return {Object|djs.model.Root} new root element
 */


Canvas.prototype.setRootElement = function (element, override) {
  if (element) {
    this._ensureValid('root', element);
  }

  var currentRoot = this._rootElement,
      elementRegistry = this._elementRegistry,
      eventBus = this._eventBus;

  if (currentRoot) {
    if (!override) {
      throw new Error('rootElement already set, need to specify override');
    } // simulate element remove event sequence


    eventBus.fire('root.remove', {
      element: currentRoot
    });
    eventBus.fire('root.removed', {
      element: currentRoot
    });
    elementRegistry.remove(currentRoot);
  }

  if (element) {
    var gfx = this.getDefaultLayer(); // resemble element add event sequence

    eventBus.fire('root.add', {
      element: element
    });
    elementRegistry.add(element, gfx, this._svg);
    eventBus.fire('root.added', {
      element: element,
      gfx: gfx
    });
  }

  this._rootElement = element;
  return element;
}; // add functionality //////////////////////


Canvas.prototype._ensureValid = function (type, element) {
  if (!element.id) {
    throw new Error('element must have an id');
  }

  if (this._elementRegistry.get(element.id)) {
    throw new Error('element with id ' + element.id + ' already exists');
  }

  var requiredAttrs = REQUIRED_MODEL_ATTRS[type];
  var valid = (0, _minDash.every)(requiredAttrs, function (attr) {
    return typeof element[attr] !== 'undefined';
  });

  if (!valid) {
    throw new Error('must supply { ' + requiredAttrs.join(', ') + ' } with ' + type);
  }
};

Canvas.prototype._setParent = function (element, parent, parentIndex) {
  (0, _Collections.add)(parent.children, element, parentIndex);
  element.parent = parent;
};
/**
 * Adds an element to the canvas.
 *
 * This wires the parent <-> child relationship between the element and
 * a explicitly specified parent or an implicit root element.
 *
 * During add it emits the events
 *
 *  * <{type}.add> (element, parent)
 *  * <{type}.added> (element, gfx)
 *
 * Extensions may hook into these events to perform their magic.
 *
 * @param {string} type
 * @param {Object|djs.model.Base} element
 * @param {Object|djs.model.Base} [parent]
 * @param {number} [parentIndex]
 *
 * @return {Object|djs.model.Base} the added element
 */


Canvas.prototype._addElement = function (type, element, parent, parentIndex) {
  parent = parent || this.getRootElement();
  var eventBus = this._eventBus,
      graphicsFactory = this._graphicsFactory;

  this._ensureValid(type, element);

  eventBus.fire(type + '.add', {
    element: element,
    parent: parent
  });

  this._setParent(element, parent, parentIndex); // create graphics


  var gfx = graphicsFactory.create(type, element, parentIndex);

  this._elementRegistry.add(element, gfx); // update its visual


  graphicsFactory.update(type, element, gfx);
  eventBus.fire(type + '.added', {
    element: element,
    gfx: gfx
  });
  return element;
};
/**
 * Adds a shape to the canvas
 *
 * @param {Object|djs.model.Shape} shape to add to the diagram
 * @param {djs.model.Base} [parent]
 * @param {number} [parentIndex]
 *
 * @return {djs.model.Shape} the added shape
 */


Canvas.prototype.addShape = function (shape, parent, parentIndex) {
  return this._addElement('shape', shape, parent, parentIndex);
};
/**
 * Adds a connection to the canvas
 *
 * @param {Object|djs.model.Connection} connection to add to the diagram
 * @param {djs.model.Base} [parent]
 * @param {number} [parentIndex]
 *
 * @return {djs.model.Connection} the added connection
 */


Canvas.prototype.addConnection = function (connection, parent, parentIndex) {
  return this._addElement('connection', connection, parent, parentIndex);
};
/**
 * Internal remove element
 */


Canvas.prototype._removeElement = function (element, type) {
  var elementRegistry = this._elementRegistry,
      graphicsFactory = this._graphicsFactory,
      eventBus = this._eventBus;
  element = elementRegistry.get(element.id || element);

  if (!element) {
    // element was removed already
    return;
  }

  eventBus.fire(type + '.remove', {
    element: element
  });
  graphicsFactory.remove(element); // unset parent <-> child relationship

  (0, _Collections.remove)(element.parent && element.parent.children, element);
  element.parent = null;
  eventBus.fire(type + '.removed', {
    element: element
  });
  elementRegistry.remove(element);
  return element;
};
/**
 * Removes a shape from the canvas
 *
 * @param {string|djs.model.Shape} shape or shape id to be removed
 *
 * @return {djs.model.Shape} the removed shape
 */


Canvas.prototype.removeShape = function (shape) {
  /**
   * An event indicating that a shape is about to be removed from the canvas.
   *
   * @memberOf Canvas
   *
   * @event shape.remove
   * @type {Object}
   * @property {djs.model.Shape} element the shape descriptor
   * @property {Object} gfx the graphical representation of the shape
   */

  /**
   * An event indicating that a shape has been removed from the canvas.
   *
   * @memberOf Canvas
   *
   * @event shape.removed
   * @type {Object}
   * @property {djs.model.Shape} element the shape descriptor
   * @property {Object} gfx the graphical representation of the shape
   */
  return this._removeElement(shape, 'shape');
};
/**
 * Removes a connection from the canvas
 *
 * @param {string|djs.model.Connection} connection or connection id to be removed
 *
 * @return {djs.model.Connection} the removed connection
 */


Canvas.prototype.removeConnection = function (connection) {
  /**
   * An event indicating that a connection is about to be removed from the canvas.
   *
   * @memberOf Canvas
   *
   * @event connection.remove
   * @type {Object}
   * @property {djs.model.Connection} element the connection descriptor
   * @property {Object} gfx the graphical representation of the connection
   */

  /**
   * An event indicating that a connection has been removed from the canvas.
   *
   * @memberOf Canvas
   *
   * @event connection.removed
   * @type {Object}
   * @property {djs.model.Connection} element the connection descriptor
   * @property {Object} gfx the graphical representation of the connection
   */
  return this._removeElement(connection, 'connection');
};
/**
 * Return the graphical object underlaying a certain diagram element
 *
 * @param {string|djs.model.Base} element descriptor of the element
 * @param {boolean} [secondary=false] whether to return the secondary connected element
 *
 * @return {SVGElement}
 */


Canvas.prototype.getGraphics = function (element, secondary) {
  return this._elementRegistry.getGraphics(element, secondary);
};
/**
 * Perform a viewbox update via a given change function.
 *
 * @param {Function} changeFn
 */


Canvas.prototype._changeViewbox = function (changeFn) {
  // notify others of the upcoming viewbox change
  this._eventBus.fire('canvas.viewbox.changing'); // perform actual change


  changeFn.apply(this); // reset the cached viewbox so that
  // a new get operation on viewbox or zoom
  // triggers a viewbox re-computation

  this._cachedViewbox = null; // notify others of the change; this step
  // may or may not be debounced

  this._viewboxChanged();
};

Canvas.prototype._viewboxChanged = function () {
  this._eventBus.fire('canvas.viewbox.changed', {
    viewbox: this.viewbox()
  });
};
/**
 * Gets or sets the view box of the canvas, i.e. the
 * area that is currently displayed.
 *
 * The getter may return a cached viewbox (if it is currently
 * changing). To force a recomputation, pass `false` as the first argument.
 *
 * @example
 *
 * canvas.viewbox({ x: 100, y: 100, width: 500, height: 500 })
 *
 * // sets the visible area of the diagram to (100|100) -> (600|100)
 * // and and scales it according to the diagram width
 *
 * var viewbox = canvas.viewbox(); // pass `false` to force recomputing the box.
 *
 * console.log(viewbox);
 * // {
 * //   inner: Dimensions,
 * //   outer: Dimensions,
 * //   scale,
 * //   x, y,
 * //   width, height
 * // }
 *
 * // if the current diagram is zoomed and scrolled, you may reset it to the
 * // default zoom via this method, too:
 *
 * var zoomedAndScrolledViewbox = canvas.viewbox();
 *
 * canvas.viewbox({
 *   x: 0,
 *   y: 0,
 *   width: zoomedAndScrolledViewbox.outer.width,
 *   height: zoomedAndScrolledViewbox.outer.height
 * });
 *
 * @param  {Object} [box] the new view box to set
 * @param  {number} box.x the top left X coordinate of the canvas visible in view box
 * @param  {number} box.y the top left Y coordinate of the canvas visible in view box
 * @param  {number} box.width the visible width
 * @param  {number} box.height
 *
 * @return {Object} the current view box
 */


Canvas.prototype.viewbox = function (box) {
  if (box === undefined && this._cachedViewbox) {
    return this._cachedViewbox;
  }

  var viewport = this._viewport,
      innerBox,
      outerBox = this.getSize(),
      matrix,
      transform,
      scale,
      x,
      y;

  if (!box) {
    // compute the inner box based on the
    // diagrams default layer. This allows us to exclude
    // external components, such as overlays
    innerBox = this.getDefaultLayer().getBBox();
    transform = (0, _tinySvg.transform)(viewport);
    matrix = transform ? transform.matrix : (0, _tinySvg.createMatrix)();
    scale = round(matrix.a, 1000);
    x = round(-matrix.e || 0, 1000);
    y = round(-matrix.f || 0, 1000);
    box = this._cachedViewbox = {
      x: x ? x / scale : 0,
      y: y ? y / scale : 0,
      width: outerBox.width / scale,
      height: outerBox.height / scale,
      scale: scale,
      inner: {
        width: innerBox.width,
        height: innerBox.height,
        x: innerBox.x,
        y: innerBox.y
      },
      outer: outerBox
    };
    return box;
  } else {
    this._changeViewbox(function () {
      scale = Math.min(outerBox.width / box.width, outerBox.height / box.height);

      var matrix = this._svg.createSVGMatrix().scale(scale).translate(-box.x, -box.y);

      (0, _tinySvg.transform)(viewport, matrix);
    });
  }

  return box;
};
/**
 * Gets or sets the scroll of the canvas.
 *
 * @param {Object} [delta] the new scroll to apply.
 *
 * @param {number} [delta.dx]
 * @param {number} [delta.dy]
 */


Canvas.prototype.scroll = function (delta) {
  var node = this._viewport;
  var matrix = node.getCTM();

  if (delta) {
    this._changeViewbox(function () {
      delta = (0, _minDash.assign)({
        dx: 0,
        dy: 0
      }, delta || {});
      matrix = this._svg.createSVGMatrix().translate(delta.dx, delta.dy).multiply(matrix);
      setCTM(node, matrix);
    });
  }

  return {
    x: matrix.e,
    y: matrix.f
  };
};
/**
 * Gets or sets the current zoom of the canvas, optionally zooming
 * to the specified position.
 *
 * The getter may return a cached zoom level. Call it with `false` as
 * the first argument to force recomputation of the current level.
 *
 * @param {string|number} [newScale] the new zoom level, either a number, i.e. 0.9,
 *                                   or `fit-viewport` to adjust the size to fit the current viewport
 * @param {string|Point} [center] the reference point { x: .., y: ..} to zoom to, 'auto' to zoom into mid or null
 *
 * @return {number} the current scale
 */


Canvas.prototype.zoom = function (newScale, center) {
  if (!newScale) {
    return this.viewbox(newScale).scale;
  }

  if (newScale === 'fit-viewport') {
    return this._fitViewport(center);
  }

  var outer, matrix;

  this._changeViewbox(function () {
    if (typeof center !== 'object') {
      outer = this.viewbox().outer;
      center = {
        x: outer.width / 2,
        y: outer.height / 2
      };
    }

    matrix = this._setZoom(newScale, center);
  });

  return round(matrix.a, 1000);
};

function setCTM(node, m) {
  var mstr = 'matrix(' + m.a + ',' + m.b + ',' + m.c + ',' + m.d + ',' + m.e + ',' + m.f + ')';
  node.setAttribute('transform', mstr);
}

Canvas.prototype._fitViewport = function (center) {
  var vbox = this.viewbox(),
      outer = vbox.outer,
      inner = vbox.inner,
      newScale,
      newViewbox; // display the complete diagram without zooming in.
  // instead of relying on internal zoom, we perform a
  // hard reset on the canvas viewbox to realize this
  //
  // if diagram does not need to be zoomed in, we focus it around
  // the diagram origin instead

  if (inner.x >= 0 && inner.y >= 0 && inner.x + inner.width <= outer.width && inner.y + inner.height <= outer.height && !center) {
    newViewbox = {
      x: 0,
      y: 0,
      width: Math.max(inner.width + inner.x, outer.width),
      height: Math.max(inner.height + inner.y, outer.height)
    };
  } else {
    newScale = Math.min(1, outer.width / inner.width, outer.height / inner.height);
    newViewbox = {
      x: inner.x + (center ? inner.width / 2 - outer.width / newScale / 2 : 0),
      y: inner.y + (center ? inner.height / 2 - outer.height / newScale / 2 : 0),
      width: outer.width / newScale,
      height: outer.height / newScale
    };
  }

  this.viewbox(newViewbox);
  return this.viewbox(false).scale;
};

Canvas.prototype._setZoom = function (scale, center) {
  var svg = this._svg,
      viewport = this._viewport;
  var matrix = svg.createSVGMatrix();
  var point = svg.createSVGPoint();
  var centerPoint, originalPoint, currentMatrix, scaleMatrix, newMatrix;
  currentMatrix = viewport.getCTM();
  var currentScale = currentMatrix.a;

  if (center) {
    centerPoint = (0, _minDash.assign)(point, center); // revert applied viewport transformations

    originalPoint = centerPoint.matrixTransform(currentMatrix.inverse()); // create scale matrix

    scaleMatrix = matrix.translate(originalPoint.x, originalPoint.y).scale(1 / currentScale * scale).translate(-originalPoint.x, -originalPoint.y);
    newMatrix = currentMatrix.multiply(scaleMatrix);
  } else {
    newMatrix = matrix.scale(scale);
  }

  setCTM(this._viewport, newMatrix);
  return newMatrix;
};
/**
 * Returns the size of the canvas
 *
 * @return {Dimensions}
 */


Canvas.prototype.getSize = function () {
  return {
    width: this._container.clientWidth,
    height: this._container.clientHeight
  };
};
/**
 * Return the absolute bounding box for the given element
 *
 * The absolute bounding box may be used to display overlays in the
 * callers (browser) coordinate system rather than the zoomed in/out
 * canvas coordinates.
 *
 * @param  {ElementDescriptor} element
 * @return {Bounds} the absolute bounding box
 */


Canvas.prototype.getAbsoluteBBox = function (element) {
  var vbox = this.viewbox();
  var bbox; // connection
  // use svg bbox

  if (element.waypoints) {
    var gfx = this.getGraphics(element);
    bbox = gfx.getBBox();
  } // shapes
  // use data
  else {
      bbox = element;
    }

  var x = bbox.x * vbox.scale - vbox.x * vbox.scale;
  var y = bbox.y * vbox.scale - vbox.y * vbox.scale;
  var width = bbox.width * vbox.scale;
  var height = bbox.height * vbox.scale;
  return {
    x: x,
    y: y,
    width: width,
    height: height
  };
};
/**
 * Fires an event in order other modules can react to the
 * canvas resizing
 */


Canvas.prototype.resized = function () {
  // force recomputation of view box
  delete this._cachedViewbox;

  this._eventBus.fire('canvas.resized');
};

},{"../util/Collections":313,"../util/Elements":315,"min-dash":555,"tiny-svg":567}],149:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ElementFactory;

var _model = require("../model");

var _minDash = require("min-dash");

/**
 * A factory for diagram-js shapes
 */
function ElementFactory() {
  this._uid = 12;
}

ElementFactory.prototype.createRoot = function (attrs) {
  return this.create('root', attrs);
};

ElementFactory.prototype.createLabel = function (attrs) {
  return this.create('label', attrs);
};

ElementFactory.prototype.createShape = function (attrs) {
  return this.create('shape', attrs);
};

ElementFactory.prototype.createConnection = function (attrs) {
  return this.create('connection', attrs);
};
/**
 * Create a model element with the given type and
 * a number of pre-set attributes.
 *
 * @param  {string} type
 * @param  {Object} attrs
 * @return {djs.model.Base} the newly created model instance
 */


ElementFactory.prototype.create = function (type, attrs) {
  attrs = (0, _minDash.assign)({}, attrs || {});

  if (!attrs.id) {
    attrs.id = type + '_' + this._uid++;
  }

  return (0, _model.create)(type, attrs);
};

},{"../model":302,"min-dash":555}],150:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ElementRegistry;

var _tinySvg = require("tiny-svg");

var ELEMENT_ID = 'data-element-id';

/**
 * @class
 *
 * A registry that keeps track of all shapes in the diagram.
 */
function ElementRegistry(eventBus) {
  this._elements = {};
  this._eventBus = eventBus;
}

ElementRegistry.$inject = ['eventBus'];
/**
 * Register a pair of (element, gfx, (secondaryGfx)).
 *
 * @param {djs.model.Base} element
 * @param {SVGElement} gfx
 * @param {SVGElement} [secondaryGfx] optional other element to register, too
 */

ElementRegistry.prototype.add = function (element, gfx, secondaryGfx) {
  var id = element.id;

  this._validateId(id); // associate dom node with element


  (0, _tinySvg.attr)(gfx, ELEMENT_ID, id);

  if (secondaryGfx) {
    (0, _tinySvg.attr)(secondaryGfx, ELEMENT_ID, id);
  }

  this._elements[id] = {
    element: element,
    gfx: gfx,
    secondaryGfx: secondaryGfx
  };
};
/**
 * Removes an element from the registry.
 *
 * @param {djs.model.Base} element
 */


ElementRegistry.prototype.remove = function (element) {
  var elements = this._elements,
      id = element.id || element,
      container = id && elements[id];

  if (container) {
    // unset element id on gfx
    (0, _tinySvg.attr)(container.gfx, ELEMENT_ID, '');

    if (container.secondaryGfx) {
      (0, _tinySvg.attr)(container.secondaryGfx, ELEMENT_ID, '');
    }

    delete elements[id];
  }
};
/**
 * Update the id of an element
 *
 * @param {djs.model.Base} element
 * @param {string} newId
 */


ElementRegistry.prototype.updateId = function (element, newId) {
  this._validateId(newId);

  if (typeof element === 'string') {
    element = this.get(element);
  }

  this._eventBus.fire('element.updateId', {
    element: element,
    newId: newId
  });

  var gfx = this.getGraphics(element),
      secondaryGfx = this.getGraphics(element, true);
  this.remove(element);
  element.id = newId;
  this.add(element, gfx, secondaryGfx);
};
/**
 * Return the model element for a given id or graphics.
 *
 * @example
 *
 * elementRegistry.get('SomeElementId_1');
 * elementRegistry.get(gfx);
 *
 *
 * @param {string|SVGElement} filter for selecting the element
 *
 * @return {djs.model.Base}
 */


ElementRegistry.prototype.get = function (filter) {
  var id;

  if (typeof filter === 'string') {
    id = filter;
  } else {
    id = filter && (0, _tinySvg.attr)(filter, ELEMENT_ID);
  }

  var container = this._elements[id];
  return container && container.element;
};
/**
 * Return all elements that match a given filter function.
 *
 * @param {Function} fn
 *
 * @return {Array<djs.model.Base>}
 */


ElementRegistry.prototype.filter = function (fn) {
  var filtered = [];
  this.forEach(function (element, gfx) {
    if (fn(element, gfx)) {
      filtered.push(element);
    }
  });
  return filtered;
};
/**
 * Return the first element that satisfies the provided testing function.
 *
 * @param {Function} fn
 *
 * @return {djs.model.Base}
 */


ElementRegistry.prototype.find = function (fn) {
  var map = this._elements,
      keys = Object.keys(map);

  for (var i = 0; i < keys.length; i++) {
    var id = keys[i],
        container = map[id],
        element = container.element,
        gfx = container.gfx;

    if (fn(element, gfx)) {
      return element;
    }
  }
};
/**
 * Return all rendered model elements.
 *
 * @return {Array<djs.model.Base>}
 */


ElementRegistry.prototype.getAll = function () {
  return this.filter(function (e) {
    return e;
  });
};
/**
 * Iterate over all diagram elements.
 *
 * @param {Function} fn
 */


ElementRegistry.prototype.forEach = function (fn) {
  var map = this._elements;
  Object.keys(map).forEach(function (id) {
    var container = map[id],
        element = container.element,
        gfx = container.gfx;
    return fn(element, gfx);
  });
};
/**
 * Return the graphical representation of an element or its id.
 *
 * @example
 * elementRegistry.getGraphics('SomeElementId_1');
 * elementRegistry.getGraphics(rootElement); // <g ...>
 *
 * elementRegistry.getGraphics(rootElement, true); // <svg ...>
 *
 *
 * @param {string|djs.model.Base} filter
 * @param {boolean} [secondary=false] whether to return the secondary connected element
 *
 * @return {SVGElement}
 */


ElementRegistry.prototype.getGraphics = function (filter, secondary) {
  var id = filter.id || filter;
  var container = this._elements[id];
  return container && (secondary ? container.secondaryGfx : container.gfx);
};
/**
 * Validate the suitability of the given id and signals a problem
 * with an exception.
 *
 * @param {string} id
 *
 * @throws {Error} if id is empty or already assigned
 */


ElementRegistry.prototype._validateId = function (id) {
  if (!id) {
    throw new Error('element must have an id');
  }

  if (this._elements[id]) {
    throw new Error('element with id ' + id + ' already added');
  }
};

},{"tiny-svg":567}],151:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = EventBus;

var _minDash = require("min-dash");

var FN_REF = '__fn';
var DEFAULT_PRIORITY = 1000;
var slice = Array.prototype.slice;
/**
 * A general purpose event bus.
 *
 * This component is used to communicate across a diagram instance.
 * Other parts of a diagram can use it to listen to and broadcast events.
 *
 *
 * ## Registering for Events
 *
 * The event bus provides the {@link EventBus#on} and {@link EventBus#once}
 * methods to register for events. {@link EventBus#off} can be used to
 * remove event registrations. Listeners receive an instance of {@link Event}
 * as the first argument. It allows them to hook into the event execution.
 *
 * ```javascript
 *
 * // listen for event
 * eventBus.on('foo', function(event) {
 *
 *   // access event type
 *   event.type; // 'foo'
 *
 *   // stop propagation to other listeners
 *   event.stopPropagation();
 *
 *   // prevent event default
 *   event.preventDefault();
 * });
 *
 * // listen for event with custom payload
 * eventBus.on('bar', function(event, payload) {
 *   console.log(payload);
 * });
 *
 * // listen for event returning value
 * eventBus.on('foobar', function(event) {
 *
 *   // stop event propagation + prevent default
 *   return false;
 *
 *   // stop event propagation + return custom result
 *   return {
 *     complex: 'listening result'
 *   };
 * });
 *
 *
 * // listen with custom priority (default=1000, higher is better)
 * eventBus.on('priorityfoo', 1500, function(event) {
 *   console.log('invoked first!');
 * });
 *
 *
 * // listen for event and pass the context (`this`)
 * eventBus.on('foobar', function(event) {
 *   this.foo();
 * }, this);
 * ```
 *
 *
 * ## Emitting Events
 *
 * Events can be emitted via the event bus using {@link EventBus#fire}.
 *
 * ```javascript
 *
 * // false indicates that the default action
 * // was prevented by listeners
 * if (eventBus.fire('foo') === false) {
 *   console.log('default has been prevented!');
 * };
 *
 *
 * // custom args + return value listener
 * eventBus.on('sum', function(event, a, b) {
 *   return a + b;
 * });
 *
 * // you can pass custom arguments + retrieve result values.
 * var sum = eventBus.fire('sum', 1, 2);
 * console.log(sum); // 3
 * ```
 */

function EventBus() {
  this._listeners = {}; // cleanup on destroy on lowest priority to allow
  // message passing until the bitter end

  this.on('diagram.destroy', 1, this._destroy, this);
}
/**
 * Register an event listener for events with the given name.
 *
 * The callback will be invoked with `event, ...additionalArguments`
 * that have been passed to {@link EventBus#fire}.
 *
 * Returning false from a listener will prevent the events default action
 * (if any is specified). To stop an event from being processed further in
 * other listeners execute {@link Event#stopPropagation}.
 *
 * Returning anything but `undefined` from a listener will stop the listener propagation.
 *
 * @param {string|Array<string>} events
 * @param {number} [priority=1000] the priority in which this listener is called, larger is higher
 * @param {Function} callback
 * @param {Object} [that] Pass context (`this`) to the callback
 */


EventBus.prototype.on = function (events, priority, callback, that) {
  events = (0, _minDash.isArray)(events) ? events : [events];

  if ((0, _minDash.isFunction)(priority)) {
    that = callback;
    callback = priority;
    priority = DEFAULT_PRIORITY;
  }

  if (!(0, _minDash.isNumber)(priority)) {
    throw new Error('priority must be a number');
  }

  var actualCallback = callback;

  if (that) {
    actualCallback = (0, _minDash.bind)(callback, that); // make sure we remember and are able to remove
    // bound callbacks via {@link #off} using the original
    // callback

    actualCallback[FN_REF] = callback[FN_REF] || callback;
  }

  var self = this;
  events.forEach(function (e) {
    self._addListener(e, {
      priority: priority,
      callback: actualCallback,
      next: null
    });
  });
};
/**
 * Register an event listener that is executed only once.
 *
 * @param {string} event the event name to register for
 * @param {number} [priority=1000] the priority in which this listener is called, larger is higher
 * @param {Function} callback the callback to execute
 * @param {Object} [that] Pass context (`this`) to the callback
 */


EventBus.prototype.once = function (event, priority, callback, that) {
  var self = this;

  if ((0, _minDash.isFunction)(priority)) {
    that = callback;
    callback = priority;
    priority = DEFAULT_PRIORITY;
  }

  if (!(0, _minDash.isNumber)(priority)) {
    throw new Error('priority must be a number');
  }

  function wrappedCallback() {
    var result = callback.apply(that, arguments);
    self.off(event, wrappedCallback);
    return result;
  } // make sure we remember and are able to remove
  // bound callbacks via {@link #off} using the original
  // callback


  wrappedCallback[FN_REF] = callback;
  this.on(event, priority, wrappedCallback);
};
/**
 * Removes event listeners by event and callback.
 *
 * If no callback is given, all listeners for a given event name are being removed.
 *
 * @param {string|Array<string>} events
 * @param {Function} [callback]
 */


EventBus.prototype.off = function (events, callback) {
  events = (0, _minDash.isArray)(events) ? events : [events];
  var self = this;
  events.forEach(function (event) {
    self._removeListener(event, callback);
  });
};
/**
 * Create an EventBus event.
 *
 * @param {Object} data
 *
 * @return {Object} event, recognized by the eventBus
 */


EventBus.prototype.createEvent = function (data) {
  var event = new InternalEvent();
  event.init(data);
  return event;
};
/**
 * Fires a named event.
 *
 * @example
 *
 * // fire event by name
 * events.fire('foo');
 *
 * // fire event object with nested type
 * var event = { type: 'foo' };
 * events.fire(event);
 *
 * // fire event with explicit type
 * var event = { x: 10, y: 20 };
 * events.fire('element.moved', event);
 *
 * // pass additional arguments to the event
 * events.on('foo', function(event, bar) {
 *   alert(bar);
 * });
 *
 * events.fire({ type: 'foo' }, 'I am bar!');
 *
 * @param {string} [name] the optional event name
 * @param {Object} [event] the event object
 * @param {...Object} additional arguments to be passed to the callback functions
 *
 * @return {boolean} the events return value, if specified or false if the
 *                   default action was prevented by listeners
 */


EventBus.prototype.fire = function (type, data) {
  var event, firstListener, returnValue, args;
  args = slice.call(arguments);

  if (typeof type === 'object') {
    data = type;
    type = data.type;
  }

  if (!type) {
    throw new Error('no event type specified');
  }

  firstListener = this._listeners[type];

  if (!firstListener) {
    return;
  } // we make sure we fire instances of our home made
  // events here. We wrap them only once, though


  if (data instanceof InternalEvent) {
    // we are fine, we alread have an event
    event = data;
  } else {
    event = this.createEvent(data);
  } // ensure we pass the event as the first parameter


  args[0] = event; // original event type (in case we delegate)

  var originalType = event.type; // update event type before delegation

  if (type !== originalType) {
    event.type = type;
  }

  try {
    returnValue = this._invokeListeners(event, args, firstListener);
  } finally {
    // reset event type after delegation
    if (type !== originalType) {
      event.type = originalType;
    }
  } // set the return value to false if the event default
  // got prevented and no other return value exists


  if (returnValue === undefined && event.defaultPrevented) {
    returnValue = false;
  }

  return returnValue;
};

EventBus.prototype.handleError = function (error) {
  return this.fire('error', {
    error: error
  }) === false;
};

EventBus.prototype._destroy = function () {
  this._listeners = {};
};

EventBus.prototype._invokeListeners = function (event, args, listener) {
  var returnValue;

  while (listener) {
    // handle stopped propagation
    if (event.cancelBubble) {
      break;
    }

    returnValue = this._invokeListener(event, args, listener);
    listener = listener.next;
  }

  return returnValue;
};

EventBus.prototype._invokeListener = function (event, args, listener) {
  var returnValue;

  try {
    // returning false prevents the default action
    returnValue = invokeFunction(listener.callback, args); // stop propagation on return value

    if (returnValue !== undefined) {
      event.returnValue = returnValue;
      event.stopPropagation();
    } // prevent default on return false


    if (returnValue === false) {
      event.preventDefault();
    }
  } catch (e) {
    if (!this.handleError(e)) {
      console.error('unhandled error in event listener');
      console.error(e.stack);
      throw e;
    }
  }

  return returnValue;
};
/*
 * Add new listener with a certain priority to the list
 * of listeners (for the given event).
 *
 * The semantics of listener registration / listener execution are
 * first register, first serve: New listeners will always be inserted
 * after existing listeners with the same priority.
 *
 * Example: Inserting two listeners with priority 1000 and 1300
 *
 *    * before: [ 1500, 1500, 1000, 1000 ]
 *    * after: [ 1500, 1500, (new=1300), 1000, 1000, (new=1000) ]
 *
 * @param {string} event
 * @param {Object} listener { priority, callback }
 */


EventBus.prototype._addListener = function (event, newListener) {
  var listener = this._getListeners(event),
      previousListener; // no prior listeners


  if (!listener) {
    this._setListeners(event, newListener);

    return;
  } // ensure we order listeners by priority from
  // 0 (high) to n > 0 (low)


  while (listener) {
    if (listener.priority < newListener.priority) {
      newListener.next = listener;

      if (previousListener) {
        previousListener.next = newListener;
      } else {
        this._setListeners(event, newListener);
      }

      return;
    }

    previousListener = listener;
    listener = listener.next;
  } // add new listener to back


  previousListener.next = newListener;
};

EventBus.prototype._getListeners = function (name) {
  return this._listeners[name];
};

EventBus.prototype._setListeners = function (name, listener) {
  this._listeners[name] = listener;
};

EventBus.prototype._removeListener = function (event, callback) {
  var listener = this._getListeners(event),
      nextListener,
      previousListener,
      listenerCallback;

  if (!callback) {
    // clear listeners
    this._setListeners(event, null);

    return;
  }

  while (listener) {
    nextListener = listener.next;
    listenerCallback = listener.callback;

    if (listenerCallback === callback || listenerCallback[FN_REF] === callback) {
      if (previousListener) {
        previousListener.next = nextListener;
      } else {
        // new first listener
        this._setListeners(event, nextListener);
      }
    }

    previousListener = listener;
    listener = nextListener;
  }
};
/**
 * A event that is emitted via the event bus.
 */


function InternalEvent() {}

InternalEvent.prototype.stopPropagation = function () {
  this.cancelBubble = true;
};

InternalEvent.prototype.preventDefault = function () {
  this.defaultPrevented = true;
};

InternalEvent.prototype.init = function (data) {
  (0, _minDash.assign)(this, data || {});
};
/**
 * Invoke function. Be fast...
 *
 * @param {Function} fn
 * @param {Array<Object>} args
 *
 * @return {Any}
 */


function invokeFunction(fn, args) {
  return fn.apply(null, args);
}

},{"min-dash":555}],152:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = GraphicsFactory;

var _minDash = require("min-dash");

var _GraphicsUtil = require("../util/GraphicsUtil");

var _SvgTransformUtil = require("../util/SvgTransformUtil");

var _minDom = require("min-dom");

var _tinySvg = require("tiny-svg");

var _Elements = require("../util/Elements");

/**
 * A factory that creates graphical elements
 *
 * @param {EventBus} eventBus
 * @param {ElementRegistry} elementRegistry
 */
function GraphicsFactory(eventBus, elementRegistry) {
  this._eventBus = eventBus;
  this._elementRegistry = elementRegistry;
}

GraphicsFactory.$inject = ['eventBus', 'elementRegistry'];

GraphicsFactory.prototype._getChildrenContainer = function (element) {
  var gfx = this._elementRegistry.getGraphics(element);

  var childrenGfx; // root element

  if (!element.parent) {
    childrenGfx = gfx;
  } else {
    childrenGfx = (0, _GraphicsUtil.getChildren)(gfx);

    if (!childrenGfx) {
      childrenGfx = (0, _tinySvg.create)('g');
      (0, _tinySvg.classes)(childrenGfx).add('djs-children');
      (0, _tinySvg.append)(gfx.parentNode, childrenGfx);
    }
  }

  return childrenGfx;
};
/**
 * Clears the graphical representation of the element and returns the
 * cleared visual (the <g class="djs-visual" /> element).
 */


GraphicsFactory.prototype._clear = function (gfx) {
  var visual = (0, _GraphicsUtil.getVisual)(gfx);
  (0, _minDom.clear)(visual);
  return visual;
};
/**
 * Creates a gfx container for shapes and connections
 *
 * The layout is as follows:
 *
 * <g class="djs-group">
 *
 *   <!-- the gfx -->
 *   <g class="djs-element djs-(shape|connection|frame)">
 *     <g class="djs-visual">
 *       <!-- the renderer draws in here -->
 *     </g>
 *
 *     <!-- extensions (overlays, click box, ...) goes here
 *   </g>
 *
 *   <!-- the gfx child nodes -->
 *   <g class="djs-children"></g>
 * </g>
 *
 * @param {string} type the type of the element, i.e. shape | connection
 * @param {SVGElement} [childrenGfx]
 * @param {number} [parentIndex] position to create container in parent
 * @param {boolean} [isFrame] is frame element
 *
 * @return {SVGElement}
 */


GraphicsFactory.prototype._createContainer = function (type, childrenGfx, parentIndex, isFrame) {
  var outerGfx = (0, _tinySvg.create)('g');
  (0, _tinySvg.classes)(outerGfx).add('djs-group'); // insert node at position

  if (typeof parentIndex !== 'undefined') {
    prependTo(outerGfx, childrenGfx, childrenGfx.childNodes[parentIndex]);
  } else {
    (0, _tinySvg.append)(childrenGfx, outerGfx);
  }

  var gfx = (0, _tinySvg.create)('g');
  (0, _tinySvg.classes)(gfx).add('djs-element');
  (0, _tinySvg.classes)(gfx).add('djs-' + type);

  if (isFrame) {
    (0, _tinySvg.classes)(gfx).add('djs-frame');
  }

  (0, _tinySvg.append)(outerGfx, gfx); // create visual

  var visual = (0, _tinySvg.create)('g');
  (0, _tinySvg.classes)(visual).add('djs-visual');
  (0, _tinySvg.append)(gfx, visual);
  return gfx;
};

GraphicsFactory.prototype.create = function (type, element, parentIndex) {
  var childrenGfx = this._getChildrenContainer(element.parent);

  return this._createContainer(type, childrenGfx, parentIndex, (0, _Elements.isFrameElement)(element));
};

GraphicsFactory.prototype.updateContainments = function (elements) {
  var self = this,
      elementRegistry = this._elementRegistry,
      parents;
  parents = (0, _minDash.reduce)(elements, function (map, e) {
    if (e.parent) {
      map[e.parent.id] = e.parent;
    }

    return map;
  }, {}); // update all parents of changed and reorganized their children
  // in the correct order (as indicated in our model)

  (0, _minDash.forEach)(parents, function (parent) {
    var children = parent.children;

    if (!children) {
      return;
    }

    var childrenGfx = self._getChildrenContainer(parent);

    (0, _minDash.forEach)(children.slice().reverse(), function (child) {
      var childGfx = elementRegistry.getGraphics(child);
      prependTo(childGfx.parentNode, childrenGfx);
    });
  });
};

GraphicsFactory.prototype.drawShape = function (visual, element) {
  var eventBus = this._eventBus;
  return eventBus.fire('render.shape', {
    gfx: visual,
    element: element
  });
};

GraphicsFactory.prototype.getShapePath = function (element) {
  var eventBus = this._eventBus;
  return eventBus.fire('render.getShapePath', element);
};

GraphicsFactory.prototype.drawConnection = function (visual, element) {
  var eventBus = this._eventBus;
  return eventBus.fire('render.connection', {
    gfx: visual,
    element: element
  });
};

GraphicsFactory.prototype.getConnectionPath = function (waypoints) {
  var eventBus = this._eventBus;
  return eventBus.fire('render.getConnectionPath', waypoints);
};

GraphicsFactory.prototype.update = function (type, element, gfx) {
  // do NOT update root element
  if (!element.parent) {
    return;
  }

  var visual = this._clear(gfx); // redraw


  if (type === 'shape') {
    this.drawShape(visual, element); // update positioning

    (0, _SvgTransformUtil.translate)(gfx, element.x, element.y);
  } else if (type === 'connection') {
    this.drawConnection(visual, element);
  } else {
    throw new Error('unknown type: ' + type);
  }

  if (element.hidden) {
    (0, _tinySvg.attr)(gfx, 'display', 'none');
  } else {
    (0, _tinySvg.attr)(gfx, 'display', 'block');
  }
};

GraphicsFactory.prototype.remove = function (element) {
  var gfx = this._elementRegistry.getGraphics(element); // remove


  (0, _tinySvg.remove)(gfx.parentNode);
}; // helpers //////////


function prependTo(newNode, parentNode, siblingNode) {
  var node = siblingNode || parentNode.firstChild; // do not prepend node to itself to prevent IE from crashing
  // https://github.com/bpmn-io/bpmn-js/issues/746

  if (newNode === node) {
    return;
  }

  parentNode.insertBefore(newNode, node);
}

},{"../util/Elements":315,"../util/GraphicsUtil":319,"../util/SvgTransformUtil":328,"min-dash":555,"min-dom":556,"tiny-svg":567}],153:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _draw = _interopRequireDefault(require("../draw"));

var _Canvas = _interopRequireDefault(require("./Canvas"));

var _ElementRegistry = _interopRequireDefault(require("./ElementRegistry"));

var _ElementFactory = _interopRequireDefault(require("./ElementFactory"));

var _EventBus = _interopRequireDefault(require("./EventBus"));

var _GraphicsFactory = _interopRequireDefault(require("./GraphicsFactory"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_draw.default],
  __init__: ['canvas'],
  canvas: ['type', _Canvas.default],
  elementRegistry: ['type', _ElementRegistry.default],
  elementFactory: ['type', _ElementFactory.default],
  eventBus: ['type', _EventBus.default],
  graphicsFactory: ['type', _GraphicsFactory.default]
};
exports.default = _default;

},{"../draw":157,"./Canvas":148,"./ElementFactory":149,"./ElementRegistry":150,"./EventBus":151,"./GraphicsFactory":152}],154:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BaseRenderer;
var DEFAULT_RENDER_PRIORITY = 1000;
/**
 * The base implementation of shape and connection renderers.
 *
 * @param {EventBus} eventBus
 * @param {number} [renderPriority=1000]
 */

function BaseRenderer(eventBus, renderPriority) {
  var self = this;
  renderPriority = renderPriority || DEFAULT_RENDER_PRIORITY;
  eventBus.on(['render.shape', 'render.connection'], renderPriority, function (evt, context) {
    var type = evt.type,
        element = context.element,
        visuals = context.gfx;

    if (self.canRender(element)) {
      if (type === 'render.shape') {
        return self.drawShape(visuals, element);
      } else {
        return self.drawConnection(visuals, element);
      }
    }
  });
  eventBus.on(['render.getShapePath', 'render.getConnectionPath'], renderPriority, function (evt, element) {
    if (self.canRender(element)) {
      if (evt.type === 'render.getShapePath') {
        return self.getShapePath(element);
      } else {
        return self.getConnectionPath(element);
      }
    }
  });
}
/**
 * Should check whether *this* renderer can render
 * the element/connection.
 *
 * @param {element} element
 *
 * @returns {boolean}
 */


BaseRenderer.prototype.canRender = function () {};
/**
 * Provides the shape's snap svg element to be drawn on the `canvas`.
 *
 * @param {djs.Graphics} visuals
 * @param {Shape} shape
 *
 * @returns {Snap.svg} [returns a Snap.svg paper element ]
 */


BaseRenderer.prototype.drawShape = function () {};
/**
 * Provides the shape's snap svg element to be drawn on the `canvas`.
 *
 * @param {djs.Graphics} visuals
 * @param {Connection} connection
 *
 * @returns {Snap.svg} [returns a Snap.svg paper element ]
 */


BaseRenderer.prototype.drawConnection = function () {};
/**
 * Gets the SVG path of a shape that represents it's visual bounds.
 *
 * @param {Shape} shape
 *
 * @return {string} svg path
 */


BaseRenderer.prototype.getShapePath = function () {};
/**
 * Gets the SVG path of a connection that represents it's visual bounds.
 *
 * @param {Connection} connection
 *
 * @return {string} svg path
 */


BaseRenderer.prototype.getConnectionPath = function () {};

},{}],155:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DefaultRenderer;

var _inherits = _interopRequireDefault(require("inherits"));

var _BaseRenderer = _interopRequireDefault(require("./BaseRenderer"));

var _RenderUtil = require("../util/RenderUtil");

var _tinySvg = require("tiny-svg");

var _Elements = require("../util/Elements");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

// apply default renderer with lowest possible priority
// so that it only kicks in if noone else could render
var DEFAULT_RENDER_PRIORITY = 1;
/**
 * The default renderer used for shapes and connections.
 *
 * @param {EventBus} eventBus
 * @param {Styles} styles
 */

function DefaultRenderer(eventBus, styles) {
  //
  _BaseRenderer.default.call(this, eventBus, DEFAULT_RENDER_PRIORITY);

  this.CONNECTION_STYLE = styles.style(['no-fill'], {
    strokeWidth: 5,
    stroke: 'fuchsia'
  });
  this.SHAPE_STYLE = styles.style({
    fill: 'white',
    stroke: 'fuchsia',
    strokeWidth: 2
  });
  this.FRAME_STYLE = styles.style(['no-fill'], {
    stroke: 'fuchsia',
    strokeDasharray: 4,
    strokeWidth: 2
  });
}

(0, _inherits.default)(DefaultRenderer, _BaseRenderer.default);

DefaultRenderer.prototype.canRender = function () {
  return true;
};

DefaultRenderer.prototype.drawShape = function drawShape(visuals, element) {
  var rect = (0, _tinySvg.create)('rect');
  (0, _tinySvg.attr)(rect, {
    x: 0,
    y: 0,
    width: element.width || 0,
    height: element.height || 0
  });

  if ((0, _Elements.isFrameElement)(element)) {
    (0, _tinySvg.attr)(rect, this.FRAME_STYLE);
  } else {
    (0, _tinySvg.attr)(rect, this.SHAPE_STYLE);
  }

  (0, _tinySvg.append)(visuals, rect);
  return rect;
};

DefaultRenderer.prototype.drawConnection = function drawConnection(visuals, connection) {
  var line = (0, _RenderUtil.createLine)(connection.waypoints, this.CONNECTION_STYLE);
  (0, _tinySvg.append)(visuals, line);
  return line;
};

DefaultRenderer.prototype.getShapePath = function getShapePath(shape) {
  var x = shape.x,
      y = shape.y,
      width = shape.width,
      height = shape.height;
  var shapePath = [['M', x, y], ['l', width, 0], ['l', 0, height], ['l', -width, 0], ['z']];
  return (0, _RenderUtil.componentsToPath)(shapePath);
};

DefaultRenderer.prototype.getConnectionPath = function getConnectionPath(connection) {
  var waypoints = connection.waypoints;
  var idx,
      point,
      connectionPath = [];

  for (idx = 0; point = waypoints[idx]; idx++) {
    // take invisible docking into account
    // when creating the path
    point = point.original || point;
    connectionPath.push([idx === 0 ? 'M' : 'L', point.x, point.y]);
  }

  return (0, _RenderUtil.componentsToPath)(connectionPath);
};

DefaultRenderer.$inject = ['eventBus', 'styles'];

},{"../util/Elements":315,"../util/RenderUtil":327,"./BaseRenderer":154,"inherits":347,"tiny-svg":567}],156:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Styles;

var _minDash = require("min-dash");

/**
 * A component that manages shape styles
 */
function Styles() {
  var defaultTraits = {
    'no-fill': {
      fill: 'none'
    },
    'no-border': {
      strokeOpacity: 0.0
    },
    'no-events': {
      pointerEvents: 'none'
    }
  };
  var self = this;
  /**
   * Builds a style definition from a className, a list of traits and an object of additional attributes.
   *
   * @param  {string} className
   * @param  {Array<string>} traits
   * @param  {Object} additionalAttrs
   *
   * @return {Object} the style defintion
   */

  this.cls = function (className, traits, additionalAttrs) {
    var attrs = this.style(traits, additionalAttrs);
    return (0, _minDash.assign)(attrs, {
      'class': className
    });
  };
  /**
   * Builds a style definition from a list of traits and an object of additional attributes.
   *
   * @param  {Array<string>} traits
   * @param  {Object} additionalAttrs
   *
   * @return {Object} the style defintion
   */


  this.style = function (traits, additionalAttrs) {
    if (!(0, _minDash.isArray)(traits) && !additionalAttrs) {
      additionalAttrs = traits;
      traits = [];
    }

    var attrs = (0, _minDash.reduce)(traits, function (attrs, t) {
      return (0, _minDash.assign)(attrs, defaultTraits[t] || {});
    }, {});
    return additionalAttrs ? (0, _minDash.assign)(attrs, additionalAttrs) : attrs;
  };

  this.computeStyle = function (custom, traits, defaultStyles) {
    if (!(0, _minDash.isArray)(traits)) {
      defaultStyles = traits;
      traits = [];
    }

    return self.style(traits || [], (0, _minDash.assign)({}, defaultStyles, custom || {}));
  };
}

},{"min-dash":555}],157:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _DefaultRenderer = _interopRequireDefault(require("./DefaultRenderer"));

var _Styles = _interopRequireDefault(require("./Styles"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['defaultRenderer'],
  defaultRenderer: ['type', _DefaultRenderer.default],
  styles: ['type', _Styles.default]
};
exports.default = _default;

},{"./DefaultRenderer":155,"./Styles":156}],158:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AlignElements;

var _minDash = require("min-dash");

function last(arr) {
  return arr && arr[arr.length - 1];
}

function sortTopOrMiddle(element) {
  return element.y;
}

function sortLeftOrCenter(element) {
  return element.x;
}
/**
 * Sorting functions for different types of alignment
 *
 * @type {Object}
 *
 * @return {Function}
 */


var ALIGNMENT_SORTING = {
  left: sortLeftOrCenter,
  center: sortLeftOrCenter,
  right: function (element) {
    return element.x + element.width;
  },
  top: sortTopOrMiddle,
  middle: sortTopOrMiddle,
  bottom: function (element) {
    return element.y + element.height;
  }
};

function AlignElements(modeling) {
  this._modeling = modeling;
}

AlignElements.$inject = ['modeling'];
/**
 * Get the relevant "axis" and "dimension" related to the current type of alignment
 *
 * @param  {string} type left|right|center|top|bottom|middle
 *
 * @return {Object} { axis, dimension }
 */

AlignElements.prototype._getOrientationDetails = function (type) {
  var vertical = ['top', 'bottom', 'middle'],
      axis = 'x',
      dimension = 'width';

  if (vertical.indexOf(type) !== -1) {
    axis = 'y';
    dimension = 'height';
  }

  return {
    axis: axis,
    dimension: dimension
  };
};

AlignElements.prototype._isType = function (type, types) {
  return types.indexOf(type) !== -1;
};
/**
 * Get a point on the relevant axis where elements should align to
 *
 * @param  {string} type left|right|center|top|bottom|middle
 * @param  {Array} sortedElements
 *
 * @return {Object}
 */


AlignElements.prototype._alignmentPosition = function (type, sortedElements) {
  var orientation = this._getOrientationDetails(type),
      axis = orientation.axis,
      dimension = orientation.dimension,
      alignment = {},
      centers = {},
      hasSharedCenters = false,
      centeredElements,
      firstElement,
      lastElement;

  function getMiddleOrTop(first, last) {
    return Math.round((first[axis] + last[axis] + last[dimension]) / 2);
  }

  if (this._isType(type, ['left', 'top'])) {
    alignment[type] = sortedElements[0][axis];
  } else if (this._isType(type, ['right', 'bottom'])) {
    lastElement = last(sortedElements);
    alignment[type] = lastElement[axis] + lastElement[dimension];
  } else if (this._isType(type, ['center', 'middle'])) {
    // check if there is a center shared by more than one shape
    // if not, just take the middle of the range
    (0, _minDash.forEach)(sortedElements, function (element) {
      var center = element[axis] + Math.round(element[dimension] / 2);

      if (centers[center]) {
        centers[center].elements.push(element);
      } else {
        centers[center] = {
          elements: [element],
          center: center
        };
      }
    });
    centeredElements = (0, _minDash.sortBy)(centers, function (center) {
      if (center.elements.length > 1) {
        hasSharedCenters = true;
      }

      return center.elements.length;
    });

    if (hasSharedCenters) {
      alignment[type] = last(centeredElements).center;
      return alignment;
    }

    firstElement = sortedElements[0];
    sortedElements = (0, _minDash.sortBy)(sortedElements, function (element) {
      return element[axis] + element[dimension];
    });
    lastElement = last(sortedElements);
    alignment[type] = getMiddleOrTop(firstElement, lastElement);
  }

  return alignment;
};
/**
 * Executes the alignment of a selection of elements
 *
 * @param  {Array} elements [description]
 * @param  {string} type left|right|center|top|bottom|middle
 */


AlignElements.prototype.trigger = function (elements, type) {
  var modeling = this._modeling;
  var filteredElements = (0, _minDash.filter)(elements, function (element) {
    return !(element.waypoints || element.host || element.labelTarget);
  });
  var sortFn = ALIGNMENT_SORTING[type];
  var sortedElements = (0, _minDash.sortBy)(filteredElements, sortFn);

  var alignment = this._alignmentPosition(type, sortedElements);

  modeling.alignElements(sortedElements, alignment);
};

},{"min-dash":555}],159:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _AlignElements = _interopRequireDefault(require("./AlignElements"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['alignElements'],
  alignElements: ['type', _AlignElements.default]
};
exports.default = _default;

},{"./AlignElements":158}],160:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AttachSupport;

var _minDash = require("min-dash");

var _Removal = require("../../util/Removal");

var _AttachUtil = require("../../util/AttachUtil");

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LOW_PRIORITY = 251,
    HIGH_PRIORITY = 1401;
var MARKER_ATTACH = 'attach-ok';
/**
 * Adds the notion of attached elements to the modeler.
 *
 * Optionally depends on `diagram-js/lib/features/move` to render
 * the attached elements during move preview.
 *
 * Optionally depends on `diagram-js/lib/features/label-support`
 * to render attached labels during move preview.
 *
 * @param {didi.Injector} injector
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 * @param {Rules} rules
 * @param {Modeling} modeling
 */

function AttachSupport(injector, eventBus, canvas, rules, modeling) {
  _CommandInterceptor.default.call(this, eventBus);

  var movePreview = injector.get('movePreview', false); // remove all the attached elements from the shapes to be validated
  // add all the attached shapes to the overall list of moved shapes

  eventBus.on('shape.move.start', HIGH_PRIORITY, function (e) {
    var context = e.context,
        shapes = context.shapes,
        validatedShapes = context.validatedShapes;
    context.shapes = addAttached(shapes);
    context.validatedShapes = removeAttached(validatedShapes);
  }); // add attachers to the visual's group

  movePreview && eventBus.on('shape.move.start', LOW_PRIORITY, function (e) {
    var context = e.context,
        shapes = context.shapes,
        attachers = getAttachers(shapes);
    (0, _minDash.forEach)(attachers, function (attacher) {
      movePreview.makeDraggable(context, attacher, true);
      (0, _minDash.forEach)(attacher.labels, function (label) {
        movePreview.makeDraggable(context, label, true);
      });
    });
  }); // add attach-ok marker to current host

  movePreview && eventBus.on('shape.move.start', function (event) {
    var context = event.context,
        shapes = context.shapes;

    if (shapes.length !== 1) {
      return;
    }

    var shape = shapes[0];
    var host = shape.host;

    if (host) {
      canvas.addMarker(host, MARKER_ATTACH);
      eventBus.once(['shape.move.out', 'shape.move.cleanup'], function () {
        canvas.removeMarker(host, MARKER_ATTACH);
      });
    }
  }); // add all attachers to move closure

  this.preExecuted('elements.move', HIGH_PRIORITY, function (e) {
    var context = e.context,
        closure = context.closure,
        shapes = context.shapes,
        attachers = getAttachers(shapes);
    (0, _minDash.forEach)(attachers, function (attacher) {
      closure.add(attacher, closure.topLevel[attacher.host.id]);
    });
  }); // perform the attaching after shapes are done moving

  this.postExecuted('elements.move', function (e) {
    var context = e.context,
        shapes = context.shapes,
        newHost = context.newHost,
        attachers; // only single elements can be attached
    // multiply elements can be detached

    if (newHost && shapes.length !== 1) {
      return;
    }

    if (newHost) {
      attachers = shapes;
    } else {
      // find attachers moved without host
      attachers = (0, _minDash.filter)(shapes, function (shape) {
        var host = shape.host;
        return isAttacher(shape) && !includes(shapes, host);
      });
    }

    (0, _minDash.forEach)(attachers, function (attacher) {
      modeling.updateAttachment(attacher, newHost);
    });
  }); // ensure invalid attachment connections are removed

  this.postExecuted('elements.move', function (e) {
    var shapes = e.context.shapes;
    (0, _minDash.forEach)(shapes, function (shape) {
      (0, _minDash.forEach)(shape.attachers, function (attacher) {
        // remove invalid outgoing connections
        (0, _minDash.forEach)(attacher.outgoing.slice(), function (connection) {
          var allowed = rules.allowed('connection.reconnect', {
            connection: connection,
            source: connection.source,
            target: connection.target
          });

          if (!allowed) {
            modeling.removeConnection(connection);
          }
        }); // remove invalid incoming connections

        (0, _minDash.forEach)(attacher.incoming.slice(), function (connection) {
          var allowed = rules.allowed('connection.reconnect', {
            connection: connection,
            source: connection.source,
            target: connection.target
          });

          if (!allowed) {
            modeling.removeConnection(connection);
          }
        });
      });
    });
  });
  this.postExecute('shape.create', function (e) {
    var context = e.context,
        shape = context.shape,
        host = context.host;

    if (host) {
      modeling.updateAttachment(shape, host);
    }
  }); // update attachments if the host is replaced

  this.postExecute('shape.replace', function (e) {
    var context = e.context,
        oldShape = context.oldShape,
        newShape = context.newShape; // move the attachers to the new host

    (0, _Removal.saveClear)(oldShape.attachers, function (attacher) {
      var allowed = rules.allowed('elements.move', {
        target: newShape,
        shapes: [attacher]
      });

      if (allowed === 'attach') {
        modeling.updateAttachment(attacher, newShape);
      } else {
        modeling.removeShape(attacher);
      }
    }); // move attachers if new host has different size

    if (newShape.attachers.length) {
      (0, _minDash.forEach)(newShape.attachers, function (attacher) {
        var delta = (0, _AttachUtil.getNewAttachShapeDelta)(attacher, oldShape, newShape);
        modeling.moveShape(attacher, delta, attacher.parent);
      });
    }
  }); // move shape on host resize

  this.postExecute('shape.resize', function (event) {
    var context = event.context,
        shape = context.shape,
        oldBounds = context.oldBounds,
        newBounds = context.newBounds,
        attachers = shape.attachers,
        hints = context.hints || {};

    if (hints.attachSupport === false) {
      return;
    }

    (0, _minDash.forEach)(attachers, function (attacher) {
      var delta = (0, _AttachUtil.getNewAttachShapeDelta)(attacher, oldBounds, newBounds);
      modeling.moveShape(attacher, delta, attacher.parent);
      (0, _minDash.forEach)(attacher.labels, function (label) {
        modeling.moveShape(label, delta, label.parent);
      });
    });
  }); // remove attachments

  this.preExecute('shape.delete', function (event) {
    var shape = event.context.shape;
    (0, _Removal.saveClear)(shape.attachers, function (attacher) {
      modeling.removeShape(attacher);
    });

    if (shape.host) {
      modeling.updateAttachment(shape, null);
    }
  });
}

(0, _inherits.default)(AttachSupport, _CommandInterceptor.default);
AttachSupport.$inject = ['injector', 'eventBus', 'canvas', 'rules', 'modeling'];
/**
 * Return attachers of the given shapes
 *
 * @param {Array<djs.model.Base>} shapes
 * @return {Array<djs.model.Base>}
 */

function getAttachers(shapes) {
  return (0, _minDash.flatten)((0, _minDash.map)(shapes, function (s) {
    return s.attachers || [];
  }));
}
/**
 * Return a combined list of elements and
 * attachers.
 *
 * @param {Array<djs.model.Base>} elements
 * @return {Array<djs.model.Base>} filtered
 */


function addAttached(elements) {
  var attachers = getAttachers(elements);
  return (0, _minDash.unionBy)('id', elements, attachers);
}
/**
 * Return a filtered list of elements that do not
 * contain attached elements with hosts being part
 * of the selection.
 *
 * @param  {Array<djs.model.Base>} elements
 *
 * @return {Array<djs.model.Base>} filtered
 */


function removeAttached(elements) {
  var ids = (0, _minDash.groupBy)(elements, 'id');
  return (0, _minDash.filter)(elements, function (element) {
    while (element) {
      // host in selection
      if (element.host && ids[element.host.id]) {
        return false;
      }

      element = element.parent;
    }

    return true;
  });
}

function isAttacher(shape) {
  return !!shape.host;
}

function includes(array, item) {
  return array.indexOf(item) !== -1;
}

},{"../../command/CommandInterceptor":145,"../../util/AttachUtil":311,"../../util/Removal":326,"inherits":347,"min-dash":555}],161:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _rules = _interopRequireDefault(require("../rules"));

var _AttachSupport = _interopRequireDefault(require("./AttachSupport"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_rules.default],
  __init__: ['attachSupport'],
  attachSupport: ['type', _AttachSupport.default]
};
exports.default = _default;

},{"../rules":272,"./AttachSupport":160}],162:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AutoPlace;

var _LayoutUtil = require("../../layout/LayoutUtil");

var _AutoPlaceUtil = require("./AutoPlaceUtil");

var LOW_PRIORITY = 100;
/**
 * A service that places elements connected to existing ones
 * to an appropriate position in an _automated_ fashion.
 *
 * @param {EventBus} eventBus
 * @param {Modeling} modeling
 */

function AutoPlace(eventBus, modeling) {
  eventBus.on('autoPlace', LOW_PRIORITY, function (context) {
    var shape = context.shape,
        source = context.source;
    return getNewShapePosition(source, shape);
  });
  /**
   * Append shape to source at appropriate position.
   *
   * @param {djs.model.Shape} source
   * @param {djs.model.Shape} shape
   *
   * @return {djs.model.Shape} appended shape
   */

  this.append = function (source, shape, hints) {
    eventBus.fire('autoPlace.start', {
      source: source,
      shape: shape
    }); // allow others to provide the position

    var position = eventBus.fire('autoPlace', {
      source: source,
      shape: shape
    });
    var newShape = modeling.appendShape(source, shape, position, source.parent, hints);
    eventBus.fire('autoPlace.end', {
      source: source,
      shape: newShape
    });
    return newShape;
  };
}

AutoPlace.$inject = ['eventBus', 'modeling']; // helpers //////////

/**
 * Find the new position for the target element to
 * connect to source.
 *
 * @param  {djs.model.Shape} source
 * @param  {djs.model.Shape} element
 * @param  {Object} [hints]
 * @param  {Object} [hints.defaultDistance]
 *
 * @returns {Point}
 */

function getNewShapePosition(source, element, hints) {
  if (!hints) {
    hints = {};
  }

  var distance = hints.defaultDistance || _AutoPlaceUtil.DEFAULT_DISTANCE;
  var sourceMid = (0, _LayoutUtil.getMid)(source),
      sourceTrbl = (0, _LayoutUtil.asTRBL)(source); // simply put element right next to source

  return {
    x: sourceTrbl.right + distance + element.width / 2,
    y: sourceMid.y
  };
}

},{"../../layout/LayoutUtil":300,"./AutoPlaceUtil":164}],163:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AutoPlaceSelectionBehavior;

/**
 * Select element after auto placement.
 *
 * @param {EventBus} eventBus
 * @param {Selection} selection
 */
function AutoPlaceSelectionBehavior(eventBus, selection) {
  eventBus.on('autoPlace.end', 500, function (e) {
    selection.select(e.shape);
  });
}

AutoPlaceSelectionBehavior.$inject = ['eventBus', 'selection'];

},{}],164:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.findFreePosition = findFreePosition;
exports.generateGetNextPosition = generateGetNextPosition;
exports.getConnectedAtPosition = getConnectedAtPosition;
exports.getConnectedDistance = getConnectedDistance;
exports.DEFAULT_DISTANCE = void 0;

var _LayoutUtil = require("../../layout/LayoutUtil");

var _minDash = require("min-dash");

// padding to detect element placement
var PLACEMENT_DETECTION_PAD = 10;
var DEFAULT_DISTANCE = 50;
exports.DEFAULT_DISTANCE = DEFAULT_DISTANCE;
var DEFAULT_MAX_DISTANCE = 250;
/**
 * Get free position starting from given position.
 *
 * @param {djs.model.Shape} source
 * @param {djs.model.Shape} element
 * @param {Point} position
 * @param {Function} getNextPosition
 *
 * @return {Point}
 */

function findFreePosition(source, element, position, getNextPosition) {
  var connectedAtPosition;

  while (connectedAtPosition = getConnectedAtPosition(source, position, element)) {
    position = getNextPosition(element, position, connectedAtPosition);
  }

  return position;
}
/**
 * Returns function that returns next position.
 *
 * @param {Object} nextPositionDirection
 * @param {Object} [nextPositionDirection.x]
 * @param {Object} [nextPositionDirection.y]
 *
 * @returns {Function}
 */


function generateGetNextPosition(nextPositionDirection) {
  return function (element, previousPosition, connectedAtPosition) {
    var nextPosition = {
      x: previousPosition.x,
      y: previousPosition.y
    };
    ['x', 'y'].forEach(function (axis) {
      var nextPositionDirectionForAxis = nextPositionDirection[axis];

      if (!nextPositionDirectionForAxis) {
        return;
      }

      var dimension = axis === 'x' ? 'width' : 'height';
      var margin = nextPositionDirectionForAxis.margin,
          minDistance = nextPositionDirectionForAxis.minDistance;

      if (margin < 0) {
        nextPosition[axis] = Math.min(connectedAtPosition[axis] + margin - element[dimension] / 2, previousPosition[axis] - minDistance + margin);
      } else {
        nextPosition[axis] = Math.max(connectedAtPosition[axis] + connectedAtPosition[dimension] + margin + element[dimension] / 2, previousPosition[axis] + minDistance + margin);
      }
    });
    return nextPosition;
  };
}
/**
 * Return target at given position, if defined.
 *
 * This takes connected elements from host and attachers
 * into account, too.
 */


function getConnectedAtPosition(source, position, element) {
  var bounds = {
    x: position.x - element.width / 2,
    y: position.y - element.height / 2,
    width: element.width,
    height: element.height
  };
  var closure = getAutoPlaceClosure(source, element);
  return (0, _minDash.find)(closure, function (target) {
    if (target === element) {
      return false;
    }

    var orientation = (0, _LayoutUtil.getOrientation)(target, bounds, PLACEMENT_DETECTION_PAD);
    return orientation === 'intersect';
  });
}
/**
* Compute optimal distance between source and target based on existing connections to and from source.
* Assumes left-to-right and top-to-down modeling.
*
* @param {djs.model.Shape} source
* @param {Object} [hints]
* @param {number} [hints.defaultDistance]
* @param {string} [hints.direction]
* @param {Function} [hints.filter]
* @param {Function} [hints.getWeight]
* @param {number} [hints.maxDistance]
* @param {string} [hints.reference]
*
* @return {number}
*/


function getConnectedDistance(source, hints) {
  if (!hints) {
    hints = {};
  } // targets > sources by default


  function getDefaultWeight(connection) {
    return connection.source === source ? 1 : -1;
  }

  var defaultDistance = hints.defaultDistance || DEFAULT_DISTANCE,
      direction = hints.direction || 'e',
      filter = hints.filter,
      getWeight = hints.getWeight || getDefaultWeight,
      maxDistance = hints.maxDistance || DEFAULT_MAX_DISTANCE,
      reference = hints.reference || 'start';

  if (!filter) {
    filter = noneFilter;
  }

  function getDistance(a, b) {
    if (direction === 'n') {
      if (reference === 'start') {
        return (0, _LayoutUtil.asTRBL)(a).top - (0, _LayoutUtil.asTRBL)(b).bottom;
      } else if (reference === 'center') {
        return (0, _LayoutUtil.asTRBL)(a).top - (0, _LayoutUtil.getMid)(b).y;
      } else {
        return (0, _LayoutUtil.asTRBL)(a).top - (0, _LayoutUtil.asTRBL)(b).top;
      }
    } else if (direction === 'w') {
      if (reference === 'start') {
        return (0, _LayoutUtil.asTRBL)(a).left - (0, _LayoutUtil.asTRBL)(b).right;
      } else if (reference === 'center') {
        return (0, _LayoutUtil.asTRBL)(a).left - (0, _LayoutUtil.getMid)(b).x;
      } else {
        return (0, _LayoutUtil.asTRBL)(a).left - (0, _LayoutUtil.asTRBL)(b).left;
      }
    } else if (direction === 's') {
      if (reference === 'start') {
        return (0, _LayoutUtil.asTRBL)(b).top - (0, _LayoutUtil.asTRBL)(a).bottom;
      } else if (reference === 'center') {
        return (0, _LayoutUtil.getMid)(b).y - (0, _LayoutUtil.asTRBL)(a).bottom;
      } else {
        return (0, _LayoutUtil.asTRBL)(b).bottom - (0, _LayoutUtil.asTRBL)(a).bottom;
      }
    } else {
      if (reference === 'start') {
        return (0, _LayoutUtil.asTRBL)(b).left - (0, _LayoutUtil.asTRBL)(a).right;
      } else if (reference === 'center') {
        return (0, _LayoutUtil.getMid)(b).x - (0, _LayoutUtil.asTRBL)(a).right;
      } else {
        return (0, _LayoutUtil.asTRBL)(b).right - (0, _LayoutUtil.asTRBL)(a).right;
      }
    }
  }

  var sourcesDistances = source.incoming.filter(filter).map(function (connection) {
    var weight = getWeight(connection);
    var distance = weight < 0 ? getDistance(connection.source, source) : getDistance(source, connection.source);
    return {
      id: connection.source.id,
      distance: distance,
      weight: weight
    };
  });
  var targetsDistances = source.outgoing.filter(filter).map(function (connection) {
    var weight = getWeight(connection);
    var distance = weight > 0 ? getDistance(source, connection.target) : getDistance(connection.target, source);
    return {
      id: connection.target.id,
      distance: distance,
      weight: weight
    };
  });
  var distances = sourcesDistances.concat(targetsDistances).reduce(function (accumulator, currentValue) {
    accumulator[currentValue.id + '__weight_' + currentValue.weight] = currentValue;
    return accumulator;
  }, {});
  var distancesGrouped = (0, _minDash.reduce)(distances, function (accumulator, currentValue) {
    var distance = currentValue.distance,
        weight = currentValue.weight;

    if (distance < 0 || distance > maxDistance) {
      return accumulator;
    }

    if (!accumulator[String(distance)]) {
      accumulator[String(distance)] = 0;
    }

    accumulator[String(distance)] += 1 * weight;

    if (!accumulator.distance || accumulator[accumulator.distance] < accumulator[String(distance)]) {
      accumulator.distance = distance;
    }

    return accumulator;
  }, {});
  return distancesGrouped.distance || defaultDistance;
}
/**
 * Returns all connected elements around the given source.
 *
 * This includes:
 *
 *   - connected elements
 *   - host connected elements
 *   - attachers connected elements
 *
 * @param  {djs.model.Shape} source
 *
 * @return {Array<djs.model.Shape>}
 */


function getAutoPlaceClosure(source) {
  var allConnected = getConnected(source);

  if (source.host) {
    allConnected = allConnected.concat(getConnected(source.host));
  }

  if (source.attachers) {
    allConnected = allConnected.concat(source.attachers.reduce(function (shapes, attacher) {
      return shapes.concat(getConnected(attacher));
    }, []));
  }

  return allConnected;
}

function getConnected(element) {
  return getTargets(element).concat(getSources(element));
}

function getSources(shape) {
  return shape.incoming.map(function (connection) {
    return connection.source;
  });
}

function getTargets(shape) {
  return shape.outgoing.map(function (connection) {
    return connection.target;
  });
}

function noneFilter() {
  return true;
}

},{"../../layout/LayoutUtil":300,"min-dash":555}],165:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _AutoPlace = _interopRequireDefault(require("./AutoPlace"));

var _AutoPlaceSelectionBehavior = _interopRequireDefault(require("./AutoPlaceSelectionBehavior"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['autoPlaceSelectionBehavior'],
  autoPlace: ['type', _AutoPlace.default],
  autoPlaceSelectionBehavior: ['type', _AutoPlaceSelectionBehavior.default]
};
exports.default = _default;

},{"./AutoPlace":162,"./AutoPlaceSelectionBehavior":163}],166:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AutoResize;

var _inherits = _interopRequireDefault(require("inherits"));

var _Elements = require("../../util/Elements");

var _LayoutUtil = require("../../layout/LayoutUtil");

var _minDash = require("min-dash");

var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * An auto resize component that takes care of expanding a parent element
 * if child elements are created or moved close the parents edge.
 *
 * @param {EventBus} eventBus
 * @param {ElementRegistry} elementRegistry
 * @param {Modeling} modeling
 * @param {Rules} rules
 */
function AutoResize(eventBus, elementRegistry, modeling, rules) {
  _CommandInterceptor.default.call(this, eventBus);

  this._elementRegistry = elementRegistry;
  this._modeling = modeling;
  this._rules = rules;
  var self = this;
  this.postExecuted(['shape.create'], function (event) {
    var context = event.context,
        hints = context.hints || {},
        shape = context.shape,
        parent = context.parent || context.newParent;

    if (hints.autoResize === false) {
      return;
    }

    self._expand([shape], parent);
  });
  this.postExecuted(['elements.move'], function (event) {
    var context = event.context,
        elements = (0, _minDash.flatten)((0, _minDash.values)(context.closure.topLevel)),
        hints = context.hints;
    var autoResize = hints ? hints.autoResize : true;

    if (autoResize === false) {
      return;
    }

    var expandings = (0, _minDash.groupBy)(elements, function (element) {
      return element.parent.id;
    });
    (0, _minDash.forEach)(expandings, function (elements, parentId) {
      // optionally filter elements to be considered when resizing
      if ((0, _minDash.isArray)(autoResize)) {
        elements = elements.filter(function (element) {
          return (0, _minDash.find)(autoResize, (0, _minDash.matchPattern)({
            id: element.id
          }));
        });
      }

      self._expand(elements, parentId);
    });
  });
  this.postExecuted(['shape.toggleCollapse'], function (event) {
    var context = event.context,
        hints = context.hints,
        shape = context.shape;

    if (hints && hints.autoResize === false) {
      return;
    }

    if (shape.collapsed) {
      return;
    }

    self._expand(shape.children || [], shape);
  });
  this.postExecuted(['shape.resize'], function (event) {
    var context = event.context,
        hints = context.hints,
        shape = context.shape,
        parent = shape.parent;

    if (hints && hints.autoResize === false) {
      return;
    }

    if (parent) {
      self._expand([shape], parent);
    }
  });
}

AutoResize.$inject = ['eventBus', 'elementRegistry', 'modeling', 'rules'];
(0, _inherits.default)(AutoResize, _CommandInterceptor.default);
/**
 * Calculate the new bounds of the target shape, given
 * a number of elements have been moved or added into the parent.
 *
 * This method considers the current size, the added elements as well as
 * the provided padding for the new bounds.
 *
 * @param {Array<djs.model.Shape>} elements
 * @param {djs.model.Shape} target
 */

AutoResize.prototype._getOptimalBounds = function (elements, target) {
  var offset = this.getOffset(target),
      padding = this.getPadding(target);
  var elementsTrbl = (0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(elements)),
      targetTrbl = (0, _LayoutUtil.asTRBL)(target);
  var newTrbl = {};

  if (elementsTrbl.top - targetTrbl.top < padding.top) {
    newTrbl.top = elementsTrbl.top - offset.top;
  }

  if (elementsTrbl.left - targetTrbl.left < padding.left) {
    newTrbl.left = elementsTrbl.left - offset.left;
  }

  if (targetTrbl.right - elementsTrbl.right < padding.right) {
    newTrbl.right = elementsTrbl.right + offset.right;
  }

  if (targetTrbl.bottom - elementsTrbl.bottom < padding.bottom) {
    newTrbl.bottom = elementsTrbl.bottom + offset.bottom;
  }

  return (0, _LayoutUtil.asBounds)((0, _minDash.assign)({}, targetTrbl, newTrbl));
};
/**
 * Expand the target shape respecting rules, offset and padding
 *
 * @param {Array<djs.model.Shape>} elements
 * @param {djs.model.Shape|string} target|targetId
 */


AutoResize.prototype._expand = function (elements, target) {
  if (typeof target === 'string') {
    target = this._elementRegistry.get(target);
  }

  var allowed = this._rules.allowed('element.autoResize', {
    elements: elements,
    target: target
  });

  if (!allowed) {
    return;
  } // calculate the new bounds


  var newBounds = this._getOptimalBounds(elements, target);

  if (!boundsChanged(newBounds, target)) {
    return;
  }

  var resizeDirections = getResizeDirections((0, _minDash.pick)(target, ['x', 'y', 'width', 'height']), newBounds); // resize the parent shape

  this.resize(target, newBounds, {
    autoResize: resizeDirections
  });
  var parent = target.parent; // recursively expand parent elements

  if (parent) {
    this._expand([target], parent);
  }
};
/**
 * Get the amount to expand the given shape in each direction.
 *
 * @param {djs.model.Shape} shape
 *
 * @return {TRBL}
 */


AutoResize.prototype.getOffset = function (shape) {
  return {
    top: 60,
    bottom: 60,
    left: 100,
    right: 100
  };
};
/**
 * Get the activation threshold for each side for which
 * resize triggers.
 *
 * @param {djs.model.Shape} shape
 *
 * @return {TRBL}
 */


AutoResize.prototype.getPadding = function (shape) {
  return {
    top: 2,
    bottom: 2,
    left: 15,
    right: 15
  };
};
/**
 * Perform the actual resize operation.
 *
 * @param {djs.model.Shape} shape
 * @param {Bounds} newBounds
 * @param {Object} [hints]
 * @param {string} [hints.autoResize]
 */


AutoResize.prototype.resize = function (shape, newBounds, hints) {
  this._modeling.resizeShape(shape, newBounds, null, hints);
};

function boundsChanged(newBounds, oldBounds) {
  return newBounds.x !== oldBounds.x || newBounds.y !== oldBounds.y || newBounds.width !== oldBounds.width || newBounds.height !== oldBounds.height;
}
/**
 * Get directions of resize as {n|w|s|e} e.g. "nw".
 *
 * @param {Bounds} oldBounds
 * @param {Bounds} newBounds
 *
 * @returns {string} Resize directions as {n|w|s|e}.
 */


function getResizeDirections(oldBounds, newBounds) {
  var directions = '';
  oldBounds = (0, _LayoutUtil.asTRBL)(oldBounds);
  newBounds = (0, _LayoutUtil.asTRBL)(newBounds);

  if (oldBounds.top > newBounds.top) {
    directions = directions.concat('n');
  }

  if (oldBounds.right < newBounds.right) {
    directions = directions.concat('w');
  }

  if (oldBounds.bottom < newBounds.bottom) {
    directions = directions.concat('s');
  }

  if (oldBounds.left > newBounds.left) {
    directions = directions.concat('e');
  }

  return directions;
}

},{"../../command/CommandInterceptor":145,"../../layout/LayoutUtil":300,"../../util/Elements":315,"inherits":347,"min-dash":555}],167:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AutoResizeProvider;

var _RuleProvider = _interopRequireDefault(require("../rules/RuleProvider"));

var _inherits = _interopRequireDefault(require("inherits"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * This is a base rule provider for the element.autoResize rule.
 */
function AutoResizeProvider(eventBus) {
  _RuleProvider.default.call(this, eventBus);

  var self = this;
  this.addRule('element.autoResize', function (context) {
    return self.canResize(context.elements, context.target);
  });
}

AutoResizeProvider.$inject = ['eventBus'];
(0, _inherits.default)(AutoResizeProvider, _RuleProvider.default);
/**
 * Needs to be implemented by sub classes to allow actual auto resize
 *
 * @param  {Array<djs.model.Shape>} elements
 * @param  {djs.model.Shape} target
 *
 * @return {boolean}
 */

AutoResizeProvider.prototype.canResize = function (elements, target) {
  return false;
};

},{"../rules/RuleProvider":270,"inherits":347}],168:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AutoScroll;

var _minDash = require("min-dash");

var _Event = require("../../util/Event");

/**
 * Initiates canvas scrolling if current cursor point is close to a border.
 * Cancelled when current point moves back inside the scrolling borders
 * or cancelled manually.
 *
 * Default options :
 *   scrollThresholdIn: [ 20, 20, 20, 20 ],
 *   scrollThresholdOut: [ 0, 0, 0, 0 ],
 *   scrollRepeatTimeout: 15,
 *   scrollStep: 10
 *
 * Threshold order:
 *   [ left, top, right, bottom ]
 */
function AutoScroll(config, eventBus, canvas) {
  this._canvas = canvas;
  this._opts = (0, _minDash.assign)({
    scrollThresholdIn: [20, 20, 20, 20],
    scrollThresholdOut: [0, 0, 0, 0],
    scrollRepeatTimeout: 15,
    scrollStep: 10
  }, config);
  var self = this;
  eventBus.on('drag.move', function (e) {
    var point = self._toBorderPoint(e);

    self.startScroll(point);
  });
  eventBus.on(['drag.cleanup'], function () {
    self.stopScroll();
  });
}

AutoScroll.$inject = ['config.autoScroll', 'eventBus', 'canvas'];
/**
 * Starts scrolling loop.
 * Point is given in global scale in canvas container box plane.
 *
 * @param  {Object} point { x: X, y: Y }
 */

AutoScroll.prototype.startScroll = function (point) {
  var canvas = this._canvas;
  var opts = this._opts;
  var self = this;
  var clientRect = canvas.getContainer().getBoundingClientRect();
  var diff = [point.x, point.y, clientRect.width - point.x, clientRect.height - point.y];
  this.stopScroll();
  var dx = 0,
      dy = 0;

  for (var i = 0; i < 4; i++) {
    if (between(diff[i], opts.scrollThresholdOut[i], opts.scrollThresholdIn[i])) {
      if (i === 0) {
        dx = opts.scrollStep;
      } else if (i == 1) {
        dy = opts.scrollStep;
      } else if (i == 2) {
        dx = -opts.scrollStep;
      } else if (i == 3) {
        dy = -opts.scrollStep;
      }
    }
  }

  if (dx !== 0 || dy !== 0) {
    canvas.scroll({
      dx: dx,
      dy: dy
    });
    this._scrolling = setTimeout(function () {
      self.startScroll(point);
    }, opts.scrollRepeatTimeout);
  }
};

function between(val, start, end) {
  if (start < val && val < end) {
    return true;
  }

  return false;
}
/**
 * Stops scrolling loop.
 */


AutoScroll.prototype.stopScroll = function () {
  clearTimeout(this._scrolling);
};
/**
 * Overrides defaults options.
 *
 * @param  {Object} options
 */


AutoScroll.prototype.setOptions = function (options) {
  this._opts = (0, _minDash.assign)({}, this._opts, options);
};
/**
 * Converts event to a point in canvas container plane in global scale.
 *
 * @param  {Event} event
 * @return {Point}
 */


AutoScroll.prototype._toBorderPoint = function (event) {
  var clientRect = this._canvas._container.getBoundingClientRect();

  var globalPosition = (0, _Event.toPoint)(event.originalEvent);
  return {
    x: globalPosition.x - clientRect.left,
    y: globalPosition.y - clientRect.top
  };
};

},{"../../util/Event":317,"min-dash":555}],169:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _dragging = _interopRequireDefault(require("../dragging"));

var _AutoScroll = _interopRequireDefault(require("./AutoScroll"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_dragging.default],
  __init__: ['autoScroll'],
  autoScroll: ['type', _AutoScroll.default]
};
exports.default = _default;

},{"../dragging":197,"./AutoScroll":168}],170:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BendpointMove;
exports.isReverse = isReverse;

var _LayoutUtil = require("../../layout/LayoutUtil");

var round = Math.round;
var RECONNECT_START = 'reconnectStart',
    RECONNECT_END = 'reconnectEnd',
    UPDATE_WAYPOINTS = 'updateWaypoints';
/**
 * Move bendpoints through drag and drop to add/remove bendpoints or reconnect connection.
 */

function BendpointMove(injector, eventBus, canvas, dragging, rules, modeling) {
  this._injector = injector;

  this.start = function (event, connection, bendpointIndex, insert) {
    var gfx = canvas.getGraphics(connection),
        source = connection.source,
        target = connection.target,
        waypoints = connection.waypoints,
        type;

    if (!insert && bendpointIndex === 0) {
      type = RECONNECT_START;
    } else if (!insert && bendpointIndex === waypoints.length - 1) {
      type = RECONNECT_END;
    } else {
      type = UPDATE_WAYPOINTS;
    }

    var command = type === UPDATE_WAYPOINTS ? 'connection.updateWaypoints' : 'connection.reconnect';
    var allowed = rules.allowed(command, {
      connection: connection,
      source: source,
      target: target
    });

    if (allowed === false) {
      allowed = rules.allowed(command, {
        connection: connection,
        source: target,
        target: source
      });
    }

    if (allowed === false) {
      return;
    }

    dragging.init(event, 'bendpoint.move', {
      data: {
        connection: connection,
        connectionGfx: gfx,
        context: {
          allowed: allowed,
          bendpointIndex: bendpointIndex,
          connection: connection,
          source: source,
          target: target,
          insert: insert,
          type: type
        }
      }
    });
  };

  eventBus.on('bendpoint.move.hover', function (event) {
    var context = event.context,
        connection = context.connection,
        source = connection.source,
        target = connection.target,
        hover = event.hover,
        type = context.type; // cache hover state

    context.hover = hover;
    var allowed;

    if (!hover) {
      return;
    }

    var command = type === UPDATE_WAYPOINTS ? 'connection.updateWaypoints' : 'connection.reconnect';
    allowed = context.allowed = rules.allowed(command, {
      connection: connection,
      source: type === RECONNECT_START ? hover : source,
      target: type === RECONNECT_END ? hover : target
    });

    if (allowed) {
      context.source = type === RECONNECT_START ? hover : source;
      context.target = type === RECONNECT_END ? hover : target;
      return;
    }

    if (allowed === false) {
      allowed = context.allowed = rules.allowed(command, {
        connection: connection,
        source: type === RECONNECT_END ? hover : target,
        target: type === RECONNECT_START ? hover : source
      });
    }

    if (allowed) {
      context.source = type === RECONNECT_END ? hover : target;
      context.target = type === RECONNECT_START ? hover : source;
    }
  });
  eventBus.on(['bendpoint.move.out', 'bendpoint.move.cleanup'], function (event) {
    var context = event.context;
    context.hover = null;
    context.source = null;
    context.target = null;
    context.allowed = false;
  });
  eventBus.on('bendpoint.move.end', function (event) {
    var context = event.context,
        allowed = context.allowed,
        bendpointIndex = context.bendpointIndex,
        connection = context.connection,
        insert = context.insert,
        newWaypoints = connection.waypoints.slice(),
        source = context.source,
        target = context.target,
        type = context.type,
        hints = context.hints || {}; // ensure integer values (important if zoom level was > 1 during move)

    var docking = {
      x: round(event.x),
      y: round(event.y)
    };

    if (!allowed) {
      return false;
    }

    if (type === UPDATE_WAYPOINTS) {
      if (insert) {
        // insert new bendpoint
        newWaypoints.splice(bendpointIndex, 0, docking);
      } else {
        // swap previous waypoint with moved one
        newWaypoints[bendpointIndex] = docking;
      } // pass hints about actual moved bendpoint
      // useful for connection/label layout


      hints.bendpointMove = {
        insert: insert,
        bendpointIndex: bendpointIndex
      };
      newWaypoints = this.cropWaypoints(connection, newWaypoints);
      modeling.updateWaypoints(connection, (0, _LayoutUtil.filterRedundantWaypoints)(newWaypoints), hints);
    } else {
      if (type === RECONNECT_START) {
        hints.docking = 'source';

        if (isReverse(context)) {
          hints.docking = 'target';
          hints.newWaypoints = newWaypoints.reverse();
        }
      } else if (type === RECONNECT_END) {
        hints.docking = 'target';

        if (isReverse(context)) {
          hints.docking = 'source';
          hints.newWaypoints = newWaypoints.reverse();
        }
      }

      modeling.reconnect(connection, source, target, docking, hints);
    }
  }, this);
}

BendpointMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'rules', 'modeling'];

BendpointMove.prototype.cropWaypoints = function (connection, newWaypoints) {
  var connectionDocking = this._injector.get('connectionDocking', false);

  if (!connectionDocking) {
    return newWaypoints;
  }

  var waypoints = connection.waypoints;
  connection.waypoints = newWaypoints;
  connection.waypoints = connectionDocking.getCroppedWaypoints(connection);
  newWaypoints = connection.waypoints;
  connection.waypoints = waypoints;
  return newWaypoints;
}; // helpers //////////


function isReverse(context) {
  var hover = context.hover,
      source = context.source,
      target = context.target,
      type = context.type;

  if (type === RECONNECT_START) {
    return hover && target && hover === target && source !== target;
  }

  if (type === RECONNECT_END) {
    return hover && source && hover === source && source !== target;
  }
}

},{"../../layout/LayoutUtil":300}],171:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BendpointMovePreview;

var _tinySvg = require("tiny-svg");

var _BendpointUtil = require("./BendpointUtil");

var _SvgTransformUtil = require("../../util/SvgTransformUtil");

var _BendpointMove = require("./BendpointMove");

var RECONNECT_START = 'reconnectStart',
    RECONNECT_END = 'reconnectEnd',
    UPDATE_WAYPOINTS = 'updateWaypoints';
var MARKER_OK = 'connect-ok',
    MARKER_NOT_OK = 'connect-not-ok',
    MARKER_CONNECT_HOVER = 'connect-hover',
    MARKER_CONNECT_UPDATING = 'djs-updating',
    MARKER_ELEMENT_HIDDEN = 'djs-element-hidden';
var HIGH_PRIORITY = 1100;
/**
 * Preview connection while moving bendpoints.
 */

function BendpointMovePreview(bendpointMove, injector, eventBus, canvas) {
  this._injector = injector;
  var connectionPreview = injector.get('connectionPreview', false);
  eventBus.on('bendpoint.move.start', function (event) {
    var context = event.context,
        bendpointIndex = context.bendpointIndex,
        connection = context.connection,
        insert = context.insert,
        waypoints = connection.waypoints,
        newWaypoints = waypoints.slice();
    context.waypoints = waypoints;

    if (insert) {
      // insert placeholder for new bendpoint
      newWaypoints.splice(bendpointIndex, 0, {
        x: event.x,
        y: event.y
      });
    }

    connection.waypoints = newWaypoints; // add dragger gfx

    var draggerGfx = context.draggerGfx = (0, _BendpointUtil.addBendpoint)(canvas.getLayer('overlays'));
    (0, _tinySvg.classes)(draggerGfx).add('djs-dragging');
    canvas.addMarker(connection, MARKER_ELEMENT_HIDDEN);
    canvas.addMarker(connection, MARKER_CONNECT_UPDATING);
  });
  eventBus.on('bendpoint.move.hover', function (event) {
    var context = event.context,
        allowed = context.allowed,
        hover = context.hover,
        type = context.type;

    if (hover) {
      canvas.addMarker(hover, MARKER_CONNECT_HOVER);

      if (type === UPDATE_WAYPOINTS) {
        return;
      }

      if (allowed) {
        canvas.removeMarker(hover, MARKER_NOT_OK);
        canvas.addMarker(hover, MARKER_OK);
      } else if (allowed === false) {
        canvas.removeMarker(hover, MARKER_OK);
        canvas.addMarker(hover, MARKER_NOT_OK);
      }
    }
  });
  eventBus.on(['bendpoint.move.out', 'bendpoint.move.cleanup'], HIGH_PRIORITY, function (event) {
    var context = event.context,
        hover = context.hover,
        target = context.target;

    if (hover) {
      canvas.removeMarker(hover, MARKER_CONNECT_HOVER);
      canvas.removeMarker(hover, target ? MARKER_OK : MARKER_NOT_OK);
    }
  });
  eventBus.on('bendpoint.move.move', function (event) {
    var context = event.context,
        allowed = context.allowed,
        bendpointIndex = context.bendpointIndex,
        draggerGfx = context.draggerGfx,
        hover = context.hover,
        type = context.type,
        connection = context.connection,
        source = connection.source,
        target = connection.target,
        newWaypoints = connection.waypoints.slice(),
        bendpoint = {
      x: event.x,
      y: event.y
    },
        hints = context.hints || {},
        drawPreviewHints = {};

    if (connectionPreview) {
      if (hints.connectionStart) {
        drawPreviewHints.connectionStart = hints.connectionStart;
      }

      if (hints.connectionEnd) {
        drawPreviewHints.connectionEnd = hints.connectionEnd;
      }

      if (type === RECONNECT_START) {
        if ((0, _BendpointMove.isReverse)(context)) {
          drawPreviewHints.connectionEnd = drawPreviewHints.connectionEnd || bendpoint;
          drawPreviewHints.source = target;
          drawPreviewHints.target = hover || source;
          newWaypoints = newWaypoints.reverse();
        } else {
          drawPreviewHints.connectionStart = drawPreviewHints.connectionStart || bendpoint;
          drawPreviewHints.source = hover || source;
          drawPreviewHints.target = target;
        }
      } else if (type === RECONNECT_END) {
        if ((0, _BendpointMove.isReverse)(context)) {
          drawPreviewHints.connectionStart = drawPreviewHints.connectionStart || bendpoint;
          drawPreviewHints.source = hover || target;
          drawPreviewHints.target = source;
          newWaypoints = newWaypoints.reverse();
        } else {
          drawPreviewHints.connectionEnd = drawPreviewHints.connectionEnd || bendpoint;
          drawPreviewHints.source = source;
          drawPreviewHints.target = hover || target;
        }
      } else {
        drawPreviewHints.noCropping = true;
        drawPreviewHints.noLayout = true;
        newWaypoints[bendpointIndex] = bendpoint;
      }

      if (type === UPDATE_WAYPOINTS) {
        newWaypoints = bendpointMove.cropWaypoints(connection, newWaypoints);
      }

      drawPreviewHints.waypoints = newWaypoints;
      connectionPreview.drawPreview(context, allowed, drawPreviewHints);
    }

    (0, _SvgTransformUtil.translate)(draggerGfx, event.x, event.y);
  }, this);
  eventBus.on(['bendpoint.move.end', 'bendpoint.move.cancel'], HIGH_PRIORITY, function (event) {
    var context = event.context,
        connection = context.connection,
        draggerGfx = context.draggerGfx,
        hover = context.hover,
        target = context.target,
        waypoints = context.waypoints;
    connection.waypoints = waypoints; // remove dragger gfx

    (0, _tinySvg.remove)(draggerGfx);
    canvas.removeMarker(connection, MARKER_CONNECT_UPDATING);
    canvas.removeMarker(connection, MARKER_ELEMENT_HIDDEN);

    if (hover) {
      canvas.removeMarker(hover, MARKER_OK);
      canvas.removeMarker(hover, target ? MARKER_OK : MARKER_NOT_OK);
    }

    if (connectionPreview) {
      connectionPreview.cleanUp(context);
    }
  });
}

BendpointMovePreview.$inject = ['bendpointMove', 'injector', 'eventBus', 'canvas'];

},{"../../util/SvgTransformUtil":328,"./BendpointMove":170,"./BendpointUtil":173,"tiny-svg":567}],172:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BendpointSnapping;

var _minDash = require("min-dash");

var _SnapUtil = require("../snapping/SnapUtil");

var abs = Math.abs,
    round = Math.round;
var TOLERANCE = 10;

function BendpointSnapping(eventBus) {
  function snapTo(values, value) {
    if ((0, _minDash.isArray)(values)) {
      var i = values.length;

      while (i--) if (abs(values[i] - value) <= TOLERANCE) {
        return values[i];
      }
    } else {
      values = +values;
      var rem = value % values;

      if (rem < TOLERANCE) {
        return value - rem;
      }

      if (rem > values - TOLERANCE) {
        return value - rem + values;
      }
    }

    return value;
  }

  function mid(element) {
    if (element.width) {
      return {
        x: round(element.width / 2 + element.x),
        y: round(element.height / 2 + element.y)
      };
    }
  } // connection segment snapping //////////////////////


  function getConnectionSegmentSnaps(context) {
    var snapPoints = context.snapPoints,
        connection = context.connection,
        waypoints = connection.waypoints,
        segmentStart = context.segmentStart,
        segmentStartIndex = context.segmentStartIndex,
        segmentEnd = context.segmentEnd,
        segmentEndIndex = context.segmentEndIndex,
        axis = context.axis;

    if (snapPoints) {
      return snapPoints;
    }

    var referenceWaypoints = [waypoints[segmentStartIndex - 1], segmentStart, segmentEnd, waypoints[segmentEndIndex + 1]];

    if (segmentStartIndex < 2) {
      referenceWaypoints.unshift(mid(connection.source));
    }

    if (segmentEndIndex > waypoints.length - 3) {
      referenceWaypoints.unshift(mid(connection.target));
    }

    context.snapPoints = snapPoints = {
      horizontal: [],
      vertical: []
    };
    (0, _minDash.forEach)(referenceWaypoints, function (p) {
      // we snap on existing bendpoints only,
      // not placeholders that are inserted during add
      if (p) {
        p = p.original || p;

        if (axis === 'y') {
          snapPoints.horizontal.push(p.y);
        }

        if (axis === 'x') {
          snapPoints.vertical.push(p.x);
        }
      }
    });
    return snapPoints;
  }

  eventBus.on('connectionSegment.move.move', 1500, function (event) {
    var context = event.context,
        snapPoints = getConnectionSegmentSnaps(context),
        x = event.x,
        y = event.y,
        sx,
        sy;

    if (!snapPoints) {
      return;
    } // snap


    sx = snapTo(snapPoints.vertical, x);
    sy = snapTo(snapPoints.horizontal, y); // correction x/y

    var cx = x - sx,
        cy = y - sy; // update delta

    (0, _minDash.assign)(event, {
      dx: event.dx - cx,
      dy: event.dy - cy,
      x: sx,
      y: sy
    }); // only set snapped if actually snapped

    if (cx || snapPoints.vertical.indexOf(x) !== -1) {
      (0, _SnapUtil.setSnapped)(event, 'x', sx);
    }

    if (cy || snapPoints.horizontal.indexOf(y) !== -1) {
      (0, _SnapUtil.setSnapped)(event, 'y', sy);
    }
  }); // bendpoint snapping //////////////////////

  function getBendpointSnaps(context) {
    var snapPoints = context.snapPoints,
        waypoints = context.connection.waypoints,
        bendpointIndex = context.bendpointIndex;

    if (snapPoints) {
      return snapPoints;
    }

    var referenceWaypoints = [waypoints[bendpointIndex - 1], waypoints[bendpointIndex + 1]];
    context.snapPoints = snapPoints = {
      horizontal: [],
      vertical: []
    };
    (0, _minDash.forEach)(referenceWaypoints, function (p) {
      // we snap on existing bendpoints only,
      // not placeholders that are inserted during add
      if (p) {
        p = p.original || p;
        snapPoints.horizontal.push(p.y);
        snapPoints.vertical.push(p.x);
      }
    });
    return snapPoints;
  }

  eventBus.on(['bendpoint.move.move', 'bendpoint.move.end'], 1500, function (event) {
    var context = event.context,
        snapPoints = getBendpointSnaps(context),
        hover = context.hover,
        hoverMid = hover && mid(hover),
        x = event.x,
        y = event.y,
        sx,
        sy;

    if (!snapPoints) {
      return;
    } // snap to hover mid


    sx = snapTo(hoverMid ? snapPoints.vertical.concat([hoverMid.x]) : snapPoints.vertical, x);
    sy = snapTo(hoverMid ? snapPoints.horizontal.concat([hoverMid.y]) : snapPoints.horizontal, y); // correction x/y

    var cx = x - sx,
        cy = y - sy; // update delta

    (0, _minDash.assign)(event, {
      dx: event.dx - cx,
      dy: event.dy - cy,
      x: event.x - cx,
      y: event.y - cy
    }); // only set snapped if actually snapped

    if (cx || snapPoints.vertical.indexOf(x) !== -1) {
      (0, _SnapUtil.setSnapped)(event, 'x', sx);
    }

    if (cy || snapPoints.horizontal.indexOf(y) !== -1) {
      (0, _SnapUtil.setSnapped)(event, 'y', sy);
    }
  });
}

BendpointSnapping.$inject = ['eventBus'];

},{"../snapping/SnapUtil":282,"min-dash":555}],173:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.toCanvasCoordinates = toCanvasCoordinates;
exports.getConnectionIntersection = getConnectionIntersection;
exports.addBendpoint = addBendpoint;
exports.addSegmentDragger = addSegmentDragger;
exports.calculateSegmentMoveRegion = calculateSegmentMoveRegion;
exports.SEGMENT_DRAGGER_CLS = exports.BENDPOINT_CLS = void 0;

var _Event = require("../../util/Event");

var _Geometry = require("../../util/Geometry");

var _tinySvg = require("tiny-svg");

var _SvgTransformUtil = require("../../util/SvgTransformUtil");

var _LineIntersection = require("../../util/LineIntersection");

var BENDPOINT_CLS = 'djs-bendpoint';
exports.BENDPOINT_CLS = BENDPOINT_CLS;
var SEGMENT_DRAGGER_CLS = 'djs-segment-dragger';
exports.SEGMENT_DRAGGER_CLS = SEGMENT_DRAGGER_CLS;

function toCanvasCoordinates(canvas, event) {
  var position = (0, _Event.toPoint)(event),
      clientRect = canvas._container.getBoundingClientRect(),
      offset; // canvas relative position


  offset = {
    x: clientRect.left,
    y: clientRect.top
  }; // update actual event payload with canvas relative measures

  var viewbox = canvas.viewbox();
  return {
    x: viewbox.x + (position.x - offset.x) / viewbox.scale,
    y: viewbox.y + (position.y - offset.y) / viewbox.scale
  };
}

function getConnectionIntersection(canvas, waypoints, event) {
  var localPosition = toCanvasCoordinates(canvas, event),
      intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, localPosition);
  return intersection;
}

function addBendpoint(parentGfx, cls) {
  var groupGfx = (0, _tinySvg.create)('g');
  (0, _tinySvg.classes)(groupGfx).add(BENDPOINT_CLS);
  (0, _tinySvg.append)(parentGfx, groupGfx);
  var visual = (0, _tinySvg.create)('circle');
  (0, _tinySvg.attr)(visual, {
    cx: 0,
    cy: 0,
    r: 4
  });
  (0, _tinySvg.classes)(visual).add('djs-visual');
  (0, _tinySvg.append)(groupGfx, visual);
  var hit = (0, _tinySvg.create)('circle');
  (0, _tinySvg.attr)(hit, {
    cx: 0,
    cy: 0,
    r: 10
  });
  (0, _tinySvg.classes)(hit).add('djs-hit');
  (0, _tinySvg.append)(groupGfx, hit);

  if (cls) {
    (0, _tinySvg.classes)(groupGfx).add(cls);
  }

  return groupGfx;
}

function createParallelDragger(parentGfx, segmentStart, segmentEnd, alignment) {
  var draggerGfx = (0, _tinySvg.create)('g');
  (0, _tinySvg.append)(parentGfx, draggerGfx);
  var width = 14,
      height = 3,
      padding = 11,
      hitWidth = calculateHitWidth(segmentStart, segmentEnd, alignment),
      hitHeight = height + padding;
  var visual = (0, _tinySvg.create)('rect');
  (0, _tinySvg.attr)(visual, {
    x: -width / 2,
    y: -height / 2,
    width: width,
    height: height
  });
  (0, _tinySvg.classes)(visual).add('djs-visual');
  (0, _tinySvg.append)(draggerGfx, visual);
  var hit = (0, _tinySvg.create)('rect');
  (0, _tinySvg.attr)(hit, {
    x: -hitWidth / 2,
    y: -hitHeight / 2,
    width: hitWidth,
    height: hitHeight
  });
  (0, _tinySvg.classes)(hit).add('djs-hit');
  (0, _tinySvg.append)(draggerGfx, hit);
  (0, _SvgTransformUtil.rotate)(draggerGfx, alignment === 'v' ? 90 : 0, 0, 0);
  return draggerGfx;
}

function addSegmentDragger(parentGfx, segmentStart, segmentEnd) {
  var groupGfx = (0, _tinySvg.create)('g'),
      mid = (0, _Geometry.getMidPoint)(segmentStart, segmentEnd),
      alignment = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd);
  (0, _tinySvg.append)(parentGfx, groupGfx);
  createParallelDragger(groupGfx, segmentStart, segmentEnd, alignment);
  (0, _tinySvg.classes)(groupGfx).add(SEGMENT_DRAGGER_CLS);
  (0, _tinySvg.classes)(groupGfx).add(alignment === 'h' ? 'horizontal' : 'vertical');
  (0, _SvgTransformUtil.translate)(groupGfx, mid.x, mid.y);
  return groupGfx;
}
/**
 * Calculates region for segment move which is 2/3 of the full segment length
 * @param {number} segmentLength
 *
 * @return {number}
 */


function calculateSegmentMoveRegion(segmentLength) {
  return Math.abs(Math.round(segmentLength * 2 / 3));
} // helper //////////


function calculateHitWidth(segmentStart, segmentEnd, alignment) {
  var segmentLengthXAxis = segmentEnd.x - segmentStart.x,
      segmentLengthYAxis = segmentEnd.y - segmentStart.y;
  return alignment === 'h' ? calculateSegmentMoveRegion(segmentLengthXAxis) : calculateSegmentMoveRegion(segmentLengthYAxis);
}

},{"../../util/Event":317,"../../util/Geometry":318,"../../util/LineIntersection":321,"../../util/SvgTransformUtil":328,"tiny-svg":567}],174:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Bendpoints;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _BendpointUtil = require("./BendpointUtil");

var _EscapeUtil = require("../../util/EscapeUtil");

var _Geometry = require("../../util/Geometry");

var _tinySvg = require("tiny-svg");

var _SvgTransformUtil = require("../../util/SvgTransformUtil");

/**
 * A service that adds editable bendpoints to connections.
 */
function Bendpoints(eventBus, canvas, interactionEvents, bendpointMove, connectionSegmentMove) {
  /**
   * Returns true if intersection point is inside middle region of segment, adjusted by
   * optional threshold
   */
  function isIntersectionMiddle(intersection, waypoints, treshold) {
    var idx = intersection.index,
        p = intersection.point,
        p0,
        p1,
        mid,
        aligned,
        xDelta,
        yDelta;

    if (idx <= 0 || intersection.bendpoint) {
      return false;
    }

    p0 = waypoints[idx - 1];
    p1 = waypoints[idx];
    mid = (0, _Geometry.getMidPoint)(p0, p1), aligned = (0, _Geometry.pointsAligned)(p0, p1);
    xDelta = Math.abs(p.x - mid.x);
    yDelta = Math.abs(p.y - mid.y);
    return aligned && xDelta <= treshold && yDelta <= treshold;
  }
  /**
   * Calculates the threshold from a connection's middle which fits the two-third-region
   */


  function calculateIntersectionThreshold(connection, intersection) {
    var waypoints = connection.waypoints,
        relevantSegment,
        alignment,
        segmentLength,
        threshold;

    if (intersection.index <= 0 || intersection.bendpoint) {
      return null;
    } // segment relative to connection intersection


    relevantSegment = {
      start: waypoints[intersection.index - 1],
      end: waypoints[intersection.index]
    };
    alignment = (0, _Geometry.pointsAligned)(relevantSegment.start, relevantSegment.end);

    if (!alignment) {
      return null;
    }

    if (alignment === 'h') {
      segmentLength = relevantSegment.end.x - relevantSegment.start.x;
    } else {
      segmentLength = relevantSegment.end.y - relevantSegment.start.y;
    } // calculate threshold relative to 2/3 of segment length


    threshold = (0, _BendpointUtil.calculateSegmentMoveRegion)(segmentLength) / 2;
    return threshold;
  }

  function activateBendpointMove(event, connection) {
    var waypoints = connection.waypoints,
        intersection = (0, _BendpointUtil.getConnectionIntersection)(canvas, waypoints, event),
        threshold;

    if (!intersection) {
      return;
    }

    threshold = calculateIntersectionThreshold(connection, intersection);

    if (isIntersectionMiddle(intersection, waypoints, threshold)) {
      connectionSegmentMove.start(event, connection, intersection.index);
    } else {
      bendpointMove.start(event, connection, intersection.index, !intersection.bendpoint);
    } // we've handled the event


    return true;
  }

  function bindInteractionEvents(node, eventName, element) {
    _minDom.event.bind(node, eventName, function (event) {
      interactionEvents.triggerMouseEvent(eventName, event, element);
      event.stopPropagation();
    });
  }

  function getBendpointsContainer(element, create) {
    var layer = canvas.getLayer('overlays'),
        gfx = (0, _minDom.query)('.djs-bendpoints[data-element-id="' + (0, _EscapeUtil.escapeCSS)(element.id) + '"]', layer);

    if (!gfx && create) {
      gfx = (0, _tinySvg.create)('g');
      (0, _tinySvg.attr)(gfx, {
        'data-element-id': element.id
      });
      (0, _tinySvg.classes)(gfx).add('djs-bendpoints');
      (0, _tinySvg.append)(layer, gfx);
      bindInteractionEvents(gfx, 'mousedown', element);
      bindInteractionEvents(gfx, 'click', element);
      bindInteractionEvents(gfx, 'dblclick', element);
    }

    return gfx;
  }

  function getSegmentDragger(idx, parentGfx) {
    return (0, _minDom.query)('.djs-segment-dragger[data-segment-idx="' + idx + '"]', parentGfx);
  }

  function createBendpoints(gfx, connection) {
    connection.waypoints.forEach(function (p, idx) {
      var bendpoint = (0, _BendpointUtil.addBendpoint)(gfx);
      (0, _tinySvg.append)(gfx, bendpoint);
      (0, _SvgTransformUtil.translate)(bendpoint, p.x, p.y);
    }); // add floating bendpoint

    (0, _BendpointUtil.addBendpoint)(gfx, 'floating');
  }

  function createSegmentDraggers(gfx, connection) {
    var waypoints = connection.waypoints;
    var segmentStart, segmentEnd, segmentDraggerGfx;

    for (var i = 1; i < waypoints.length; i++) {
      segmentStart = waypoints[i - 1];
      segmentEnd = waypoints[i];

      if ((0, _Geometry.pointsAligned)(segmentStart, segmentEnd)) {
        segmentDraggerGfx = (0, _BendpointUtil.addSegmentDragger)(gfx, segmentStart, segmentEnd);
        (0, _tinySvg.attr)(segmentDraggerGfx, {
          'data-segment-idx': i
        });
        bindInteractionEvents(segmentDraggerGfx, 'mousemove', connection);
      }
    }
  }

  function clearBendpoints(gfx) {
    (0, _minDash.forEach)((0, _minDom.queryAll)('.' + _BendpointUtil.BENDPOINT_CLS, gfx), function (node) {
      (0, _tinySvg.remove)(node);
    });
  }

  function clearSegmentDraggers(gfx) {
    (0, _minDash.forEach)((0, _minDom.queryAll)('.' + _BendpointUtil.SEGMENT_DRAGGER_CLS, gfx), function (node) {
      (0, _tinySvg.remove)(node);
    });
  }

  function addHandles(connection) {
    var gfx = getBendpointsContainer(connection);

    if (!gfx) {
      gfx = getBendpointsContainer(connection, true);
      createBendpoints(gfx, connection);
      createSegmentDraggers(gfx, connection);
    }

    return gfx;
  }

  function updateHandles(connection) {
    var gfx = getBendpointsContainer(connection);

    if (gfx) {
      clearSegmentDraggers(gfx);
      clearBendpoints(gfx);
      createSegmentDraggers(gfx, connection);
      createBendpoints(gfx, connection);
    }
  }

  function updateFloatingBendpointPosition(parentGfx, intersection) {
    var floating = (0, _minDom.query)('.floating', parentGfx),
        point = intersection.point;

    if (!floating) {
      return;
    }

    (0, _SvgTransformUtil.translate)(floating, point.x, point.y);
  }

  function updateSegmentDraggerPosition(parentGfx, intersection, waypoints) {
    var draggerGfx = getSegmentDragger(intersection.index, parentGfx),
        segmentStart = waypoints[intersection.index - 1],
        segmentEnd = waypoints[intersection.index],
        point = intersection.point,
        mid = (0, _Geometry.getMidPoint)(segmentStart, segmentEnd),
        alignment = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd),
        draggerVisual,
        relativePosition;

    if (!draggerGfx) {
      return;
    }

    draggerVisual = getDraggerVisual(draggerGfx);
    relativePosition = {
      x: point.x - mid.x,
      y: point.y - mid.y
    };

    if (alignment === 'v') {
      // rotate position
      relativePosition = {
        x: relativePosition.y,
        y: relativePosition.x
      };
    }

    (0, _SvgTransformUtil.translate)(draggerVisual, relativePosition.x, relativePosition.y);
  }

  eventBus.on('connection.changed', function (event) {
    updateHandles(event.element);
  });
  eventBus.on('connection.remove', function (event) {
    var gfx = getBendpointsContainer(event.element);

    if (gfx) {
      (0, _tinySvg.remove)(gfx);
    }
  });
  eventBus.on('element.marker.update', function (event) {
    var element = event.element,
        bendpointsGfx;

    if (!element.waypoints) {
      return;
    }

    bendpointsGfx = addHandles(element);

    if (event.add) {
      (0, _tinySvg.classes)(bendpointsGfx).add(event.marker);
    } else {
      (0, _tinySvg.classes)(bendpointsGfx).remove(event.marker);
    }
  });
  eventBus.on('element.mousemove', function (event) {
    var element = event.element,
        waypoints = element.waypoints,
        bendpointsGfx,
        intersection;

    if (waypoints) {
      bendpointsGfx = getBendpointsContainer(element, true);
      intersection = (0, _BendpointUtil.getConnectionIntersection)(canvas, waypoints, event.originalEvent);

      if (!intersection) {
        return;
      }

      updateFloatingBendpointPosition(bendpointsGfx, intersection);

      if (!intersection.bendpoint) {
        updateSegmentDraggerPosition(bendpointsGfx, intersection, waypoints);
      }
    }
  });
  eventBus.on('element.mousedown', function (event) {
    var originalEvent = event.originalEvent,
        element = event.element;

    if (!element.waypoints) {
      return;
    }

    return activateBendpointMove(originalEvent, element);
  });
  eventBus.on('selection.changed', function (event) {
    var newSelection = event.newSelection,
        primary = newSelection[0];

    if (primary && primary.waypoints) {
      addHandles(primary);
    }
  });
  eventBus.on('element.hover', function (event) {
    var element = event.element;

    if (element.waypoints) {
      addHandles(element);
      interactionEvents.registerEvent(event.gfx, 'mousemove', 'element.mousemove');
    }
  });
  eventBus.on('element.out', function (event) {
    interactionEvents.unregisterEvent(event.gfx, 'mousemove', 'element.mousemove');
  }); // update bendpoint container data attribute on element ID change

  eventBus.on('element.updateId', function (context) {
    var element = context.element,
        newId = context.newId;

    if (element.waypoints) {
      var bendpointContainer = getBendpointsContainer(element);

      if (bendpointContainer) {
        (0, _tinySvg.attr)(bendpointContainer, {
          'data-element-id': newId
        });
      }
    }
  }); // API

  this.addHandles = addHandles;
  this.updateHandles = updateHandles;
  this.getBendpointsContainer = getBendpointsContainer;
  this.getSegmentDragger = getSegmentDragger;
}

Bendpoints.$inject = ['eventBus', 'canvas', 'interactionEvents', 'bendpointMove', 'connectionSegmentMove']; // helper /////////////

function getDraggerVisual(draggerGfx) {
  return (0, _minDom.query)('.djs-visual', draggerGfx);
}

},{"../../util/EscapeUtil":316,"../../util/Geometry":318,"../../util/SvgTransformUtil":328,"./BendpointUtil":173,"min-dash":555,"min-dom":556,"tiny-svg":567}],175:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ConnectionSegmentMove;

var _Geometry = require("../../util/Geometry");

var _BendpointUtil = require("./BendpointUtil");

var _LayoutUtil = require("../../layout/LayoutUtil");

var _tinySvg = require("tiny-svg");

var _SvgTransformUtil = require("../../util/SvgTransformUtil");

var MARKER_CONNECT_HOVER = 'connect-hover',
    MARKER_CONNECT_UPDATING = 'djs-updating';

function axisAdd(point, axis, delta) {
  return axisSet(point, axis, point[axis] + delta);
}

function axisSet(point, axis, value) {
  return {
    x: axis === 'x' ? value : point.x,
    y: axis === 'y' ? value : point.y
  };
}

function axisFenced(position, segmentStart, segmentEnd, axis) {
  var maxValue = Math.max(segmentStart[axis], segmentEnd[axis]),
      minValue = Math.min(segmentStart[axis], segmentEnd[axis]);
  var padding = 20;
  var fencedValue = Math.min(Math.max(minValue + padding, position[axis]), maxValue - padding);
  return axisSet(segmentStart, axis, fencedValue);
}

function flipAxis(axis) {
  return axis === 'x' ? 'y' : 'x';
}
/**
 * Get the docking point on the given element.
 *
 * Compute a reasonable docking, if non exists.
 *
 * @param  {Point} point
 * @param  {djs.model.Shape} referenceElement
 * @param  {string} moveAxis (x|y)
 *
 * @return {Point}
 */


function getDocking(point, referenceElement, moveAxis) {
  var referenceMid, inverseAxis;

  if (point.original) {
    return point.original;
  } else {
    referenceMid = (0, _LayoutUtil.getMid)(referenceElement);
    inverseAxis = flipAxis(moveAxis);
    return axisSet(point, inverseAxis, referenceMid[inverseAxis]);
  }
}
/**
 * A component that implements moving of bendpoints
 */


function ConnectionSegmentMove(injector, eventBus, canvas, dragging, graphicsFactory, modeling) {
  // optional connection docking integration
  var connectionDocking = injector.get('connectionDocking', false); // API

  this.start = function (event, connection, idx) {
    var context,
        gfx = canvas.getGraphics(connection),
        segmentStartIndex = idx - 1,
        segmentEndIndex = idx,
        waypoints = connection.waypoints,
        segmentStart = waypoints[segmentStartIndex],
        segmentEnd = waypoints[segmentEndIndex],
        intersection = (0, _BendpointUtil.getConnectionIntersection)(canvas, waypoints, event),
        direction,
        axis,
        dragPosition;
    direction = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd); // do not move diagonal connection

    if (!direction) {
      return;
    } // the axis where we are going to move things


    axis = direction === 'v' ? 'x' : 'y';

    if (segmentStartIndex === 0) {
      segmentStart = getDocking(segmentStart, connection.source, axis);
    }

    if (segmentEndIndex === waypoints.length - 1) {
      segmentEnd = getDocking(segmentEnd, connection.target, axis);
    }

    if (intersection) {
      dragPosition = intersection.point;
    } else {
      // set to segment center as default
      dragPosition = {
        x: (segmentStart.x + segmentEnd.x) / 2,
        y: (segmentStart.y + segmentEnd.y) / 2
      };
    }

    context = {
      connection: connection,
      segmentStartIndex: segmentStartIndex,
      segmentEndIndex: segmentEndIndex,
      segmentStart: segmentStart,
      segmentEnd: segmentEnd,
      axis: axis,
      dragPosition: dragPosition
    };
    dragging.init(event, dragPosition, 'connectionSegment.move', {
      cursor: axis === 'x' ? 'resize-ew' : 'resize-ns',
      data: {
        connection: connection,
        connectionGfx: gfx,
        context: context
      }
    });
  };
  /**
   * Crop connection if connection cropping is provided.
   *
   * @param {Connection} connection
   * @param {Array<Point>} newWaypoints
   *
   * @return {Array<Point>} cropped connection waypoints
   */


  function cropConnection(connection, newWaypoints) {
    // crop connection, if docking service is provided only
    if (!connectionDocking) {
      return newWaypoints;
    }

    var oldWaypoints = connection.waypoints,
        croppedWaypoints; // temporary set new waypoints

    connection.waypoints = newWaypoints;
    croppedWaypoints = connectionDocking.getCroppedWaypoints(connection); // restore old waypoints

    connection.waypoints = oldWaypoints;
    return croppedWaypoints;
  } // DRAGGING IMPLEMENTATION


  function redrawConnection(data) {
    graphicsFactory.update('connection', data.connection, data.connectionGfx);
  }

  function updateDragger(context, segmentOffset, event) {
    var newWaypoints = context.newWaypoints,
        segmentStartIndex = context.segmentStartIndex + segmentOffset,
        segmentStart = newWaypoints[segmentStartIndex],
        segmentEndIndex = context.segmentEndIndex + segmentOffset,
        segmentEnd = newWaypoints[segmentEndIndex],
        axis = flipAxis(context.axis); // make sure the dragger does not move
    // outside the connection

    var draggerPosition = axisFenced(event, segmentStart, segmentEnd, axis); // update dragger

    (0, _SvgTransformUtil.translate)(context.draggerGfx, draggerPosition.x, draggerPosition.y);
  }
  /**
   * Filter waypoints for redundant ones (i.e. on the same axis).
   * Returns the filtered waypoints and the offset related to the segment move.
   *
   * @param {Array<Point>} waypoints
   * @param {Integer} segmentStartIndex of moved segment start
   *
   * @return {Object} { filteredWaypoints, segmentOffset }
   */


  function filterRedundantWaypoints(waypoints, segmentStartIndex) {
    var segmentOffset = 0;
    var filteredWaypoints = waypoints.filter(function (r, idx) {
      if ((0, _Geometry.pointsOnLine)(waypoints[idx - 1], waypoints[idx + 1], r)) {
        // remove point and increment offset
        segmentOffset = idx <= segmentStartIndex ? segmentOffset - 1 : segmentOffset;
        return false;
      } // dont remove point


      return true;
    });
    return {
      waypoints: filteredWaypoints,
      segmentOffset: segmentOffset
    };
  }

  eventBus.on('connectionSegment.move.start', function (event) {
    var context = event.context,
        connection = event.connection,
        layer = canvas.getLayer('overlays');
    context.originalWaypoints = connection.waypoints.slice(); // add dragger gfx

    context.draggerGfx = (0, _BendpointUtil.addSegmentDragger)(layer, context.segmentStart, context.segmentEnd);
    (0, _tinySvg.classes)(context.draggerGfx).add('djs-dragging');
    canvas.addMarker(connection, MARKER_CONNECT_UPDATING);
  });
  eventBus.on('connectionSegment.move.move', function (event) {
    var context = event.context,
        connection = context.connection,
        segmentStartIndex = context.segmentStartIndex,
        segmentEndIndex = context.segmentEndIndex,
        segmentStart = context.segmentStart,
        segmentEnd = context.segmentEnd,
        axis = context.axis;
    var newWaypoints = context.originalWaypoints.slice(),
        newSegmentStart = axisAdd(segmentStart, axis, event['d' + axis]),
        newSegmentEnd = axisAdd(segmentEnd, axis, event['d' + axis]); // original waypoint count and added / removed
    // from start waypoint delta. We use the later
    // to retrieve the updated segmentStartIndex / segmentEndIndex

    var waypointCount = newWaypoints.length,
        segmentOffset = 0; // move segment start / end by axis delta

    newWaypoints[segmentStartIndex] = newSegmentStart;
    newWaypoints[segmentEndIndex] = newSegmentEnd;
    var sourceToSegmentOrientation, targetToSegmentOrientation; // handle first segment

    if (segmentStartIndex < 2) {
      sourceToSegmentOrientation = (0, _LayoutUtil.getOrientation)(connection.source, newSegmentStart); // first bendpoint, remove first segment if intersecting

      if (segmentStartIndex === 1) {
        if (sourceToSegmentOrientation === 'intersect') {
          newWaypoints.shift();
          newWaypoints[0] = newSegmentStart;
          segmentOffset--;
        }
      } // docking point, add segment if not intersecting anymore
      else {
          if (sourceToSegmentOrientation !== 'intersect') {
            newWaypoints.unshift(segmentStart);
            segmentOffset++;
          }
        }
    } // handle last segment


    if (segmentEndIndex > waypointCount - 3) {
      targetToSegmentOrientation = (0, _LayoutUtil.getOrientation)(connection.target, newSegmentEnd); // last bendpoint, remove last segment if intersecting

      if (segmentEndIndex === waypointCount - 2) {
        if (targetToSegmentOrientation === 'intersect') {
          newWaypoints.pop();
          newWaypoints[newWaypoints.length - 1] = newSegmentEnd;
        }
      } // last bendpoint, remove last segment if intersecting
      else {
          if (targetToSegmentOrientation !== 'intersect') {
            newWaypoints.push(segmentEnd);
          }
        }
    } // update connection waypoints


    context.newWaypoints = connection.waypoints = cropConnection(connection, newWaypoints); // update dragger position

    updateDragger(context, segmentOffset, event); // save segmentOffset in context

    context.newSegmentStartIndex = segmentStartIndex + segmentOffset; // redraw connection

    redrawConnection(event);
  });
  eventBus.on('connectionSegment.move.hover', function (event) {
    event.context.hover = event.hover;
    canvas.addMarker(event.hover, MARKER_CONNECT_HOVER);
  });
  eventBus.on(['connectionSegment.move.out', 'connectionSegment.move.cleanup'], function (event) {
    // remove connect marker
    // if it was added
    var hover = event.context.hover;

    if (hover) {
      canvas.removeMarker(hover, MARKER_CONNECT_HOVER);
    }
  });
  eventBus.on('connectionSegment.move.cleanup', function (event) {
    var context = event.context,
        connection = context.connection; // remove dragger gfx

    if (context.draggerGfx) {
      (0, _tinySvg.remove)(context.draggerGfx);
    }

    canvas.removeMarker(connection, MARKER_CONNECT_UPDATING);
  });
  eventBus.on(['connectionSegment.move.cancel', 'connectionSegment.move.end'], function (event) {
    var context = event.context,
        connection = context.connection;
    connection.waypoints = context.originalWaypoints;
    redrawConnection(event);
  });
  eventBus.on('connectionSegment.move.end', function (event) {
    var context = event.context,
        connection = context.connection,
        newWaypoints = context.newWaypoints,
        newSegmentStartIndex = context.newSegmentStartIndex; // ensure we have actual pixel values bendpoint
    // coordinates (important when zoom level was > 1 during move)

    newWaypoints = newWaypoints.map(function (p) {
      return {
        original: p.original,
        x: Math.round(p.x),
        y: Math.round(p.y)
      };
    }); // apply filter redunant waypoints

    var filtered = filterRedundantWaypoints(newWaypoints, newSegmentStartIndex); // get filtered waypoints

    var filteredWaypoints = filtered.waypoints,
        croppedWaypoints = cropConnection(connection, filteredWaypoints),
        segmentOffset = filtered.segmentOffset;
    var hints = {
      segmentMove: {
        segmentStartIndex: context.segmentStartIndex,
        newSegmentStartIndex: newSegmentStartIndex + segmentOffset
      }
    };
    modeling.updateWaypoints(connection, croppedWaypoints, hints);
  });
}

ConnectionSegmentMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'graphicsFactory', 'modeling'];

},{"../../layout/LayoutUtil":300,"../../util/Geometry":318,"../../util/SvgTransformUtil":328,"./BendpointUtil":173,"tiny-svg":567}],176:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _dragging = _interopRequireDefault(require("../dragging"));

var _rules = _interopRequireDefault(require("../rules"));

var _Bendpoints = _interopRequireDefault(require("./Bendpoints"));

var _BendpointMove = _interopRequireDefault(require("./BendpointMove"));

var _BendpointMovePreview = _interopRequireDefault(require("./BendpointMovePreview"));

var _ConnectionSegmentMove = _interopRequireDefault(require("./ConnectionSegmentMove"));

var _BendpointSnapping = _interopRequireDefault(require("./BendpointSnapping"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_dragging.default, _rules.default],
  __init__: ['bendpoints', 'bendpointSnapping', 'bendpointMovePreview'],
  bendpoints: ['type', _Bendpoints.default],
  bendpointMove: ['type', _BendpointMove.default],
  bendpointMovePreview: ['type', _BendpointMovePreview.default],
  connectionSegmentMove: ['type', _ConnectionSegmentMove.default],
  bendpointSnapping: ['type', _BendpointSnapping.default]
};
exports.default = _default;

},{"../dragging":197,"../rules":272,"./BendpointMove":170,"./BendpointMovePreview":171,"./BendpointSnapping":172,"./Bendpoints":174,"./ConnectionSegmentMove":175}],177:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ChangeSupport;

var _Elements = require("../../util/Elements");

/**
 * Adds change support to the diagram, including
 *
 * <ul>
 *   <li>redrawing shapes and connections on change</li>
 * </ul>
 *
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 * @param {ElementRegistry} elementRegistry
 * @param {GraphicsFactory} graphicsFactory
 */
function ChangeSupport(eventBus, canvas, elementRegistry, graphicsFactory) {
  // redraw shapes / connections on change
  eventBus.on('element.changed', function (event) {
    var element = event.element; // element might have been deleted and replaced by new element with same ID
    // thus check for parent of element except for root element

    if (element.parent || element === canvas.getRootElement()) {
      event.gfx = elementRegistry.getGraphics(element);
    } // shape + gfx may have been deleted


    if (!event.gfx) {
      return;
    }

    eventBus.fire((0, _Elements.getType)(element) + '.changed', event);
  });
  eventBus.on('elements.changed', function (event) {
    var elements = event.elements;
    elements.forEach(function (e) {
      eventBus.fire('element.changed', {
        element: e
      });
    });
    graphicsFactory.updateContainments(elements);
  });
  eventBus.on('shape.changed', function (event) {
    graphicsFactory.update('shape', event.element, event.gfx);
  });
  eventBus.on('connection.changed', function (event) {
    graphicsFactory.update('connection', event.element, event.gfx);
  });
}

ChangeSupport.$inject = ['eventBus', 'canvas', 'elementRegistry', 'graphicsFactory'];

},{"../../util/Elements":315}],178:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _ChangeSupport = _interopRequireDefault(require("./ChangeSupport"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['changeSupport'],
  changeSupport: ['type', _ChangeSupport.default]
};
exports.default = _default;

},{"./ChangeSupport":177}],179:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Clipboard;

/**
 * A clip board stub
 */
function Clipboard() {}

Clipboard.prototype.get = function () {
  return this._data;
};

Clipboard.prototype.set = function (data) {
  this._data = data;
};

Clipboard.prototype.clear = function () {
  var data = this._data;
  delete this._data;
  return data;
};

Clipboard.prototype.isEmpty = function () {
  return !this._data;
};

},{}],180:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _Clipboard = _interopRequireDefault(require("./Clipboard"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  clipboard: ['type', _Clipboard.default]
};
exports.default = _default;

},{"./Clipboard":179}],181:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Connect;
exports.isReverse = isReverse;

var _LayoutUtil = require("../../layout/LayoutUtil");

var _minDash = require("min-dash");

function Connect(eventBus, dragging, modeling, rules) {
  // rules
  function canConnect(source, target) {
    return rules.allowed('connection.create', {
      source: source,
      target: target
    });
  }

  function canConnectReverse(source, target) {
    return canConnect(target, source);
  } // event handlers


  eventBus.on('connect.hover', function (event) {
    var context = event.context,
        start = context.start,
        hover = event.hover,
        canExecute; // cache hover state

    context.hover = hover;
    canExecute = context.canExecute = canConnect(start, hover); // ignore hover

    if ((0, _minDash.isNil)(canExecute)) {
      return;
    }

    if (canExecute !== false) {
      context.source = start;
      context.target = hover;
      return;
    }

    canExecute = context.canExecute = canConnectReverse(start, hover); // ignore hover

    if ((0, _minDash.isNil)(canExecute)) {
      return;
    }

    if (canExecute !== false) {
      context.source = hover;
      context.target = start;
    }
  });
  eventBus.on(['connect.out', 'connect.cleanup'], function (event) {
    var context = event.context;
    context.hover = null;
    context.source = null;
    context.target = null;
    context.canExecute = false;
  });
  eventBus.on('connect.end', function (event) {
    var context = event.context,
        canExecute = context.canExecute,
        connectionStart = context.connectionStart,
        connectionEnd = {
      x: event.x,
      y: event.y
    },
        source = context.source,
        target = context.target;

    if (!canExecute) {
      return false;
    }

    var attrs = null,
        hints = {
      connectionStart: isReverse(context) ? connectionEnd : connectionStart,
      connectionEnd: isReverse(context) ? connectionStart : connectionEnd
    };

    if ((0, _minDash.isObject)(canExecute)) {
      attrs = canExecute;
    }

    modeling.connect(source, target, attrs, hints);
  }); // API

  /**
   * Start connect operation.
   *
   * @param {DOMEvent} event
   * @param {djs.model.Base} start
   * @param {Point} [connectionStart]
   * @param {boolean} [autoActivate=false]
   */

  this.start = function (event, start, connectionStart, autoActivate) {
    if (!(0, _minDash.isObject)(connectionStart)) {
      autoActivate = connectionStart;
      connectionStart = (0, _LayoutUtil.getMid)(start);
    }

    dragging.init(event, 'connect', {
      autoActivate: autoActivate,
      data: {
        shape: start,
        context: {
          start: start,
          connectionStart: connectionStart
        }
      }
    });
  };
}

Connect.$inject = ['eventBus', 'dragging', 'modeling', 'rules']; // helpers //////////

function isReverse(context) {
  var hover = context.hover,
      source = context.source,
      target = context.target;
  return hover && source && hover === source && source !== target;
}

},{"../../layout/LayoutUtil":300,"min-dash":555}],182:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ConnectPreview;

var _Connect = require("./Connect");

var HIGH_PRIORITY = 1100,
    LOW_PRIORITY = 900;
var MARKER_OK = 'connect-ok',
    MARKER_NOT_OK = 'connect-not-ok';
/**
 * Shows connection preview during connect.
 *
 * @param {didi.Injector} injector
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 */

function ConnectPreview(injector, eventBus, canvas) {
  var connectionPreview = injector.get('connectionPreview', false);
  connectionPreview && eventBus.on('connect.move', function (event) {
    var context = event.context,
        canConnect = context.canExecute,
        hover = context.hover,
        source = context.source,
        start = context.start,
        startPosition = context.startPosition,
        connectionStart = context.connectionStart,
        connectionEnd = context.connectionEnd,
        target = context.target;

    if (!connectionStart) {
      connectionStart = (0, _Connect.isReverse)(context) ? {
        x: event.x,
        y: event.y
      } : startPosition;
    }

    if (!connectionEnd) {
      connectionEnd = (0, _Connect.isReverse)(context) ? startPosition : {
        x: event.x,
        y: event.y
      };
    }

    connectionPreview.drawPreview(context, canConnect, {
      source: source || start,
      target: target || hover,
      connectionStart: connectionStart,
      connectionEnd: connectionEnd
    });
  });
  eventBus.on('connect.hover', LOW_PRIORITY, function (event) {
    var context = event.context,
        hover = event.hover,
        canExecute = context.canExecute; // ignore hover

    if (canExecute === null) {
      return;
    }

    canvas.addMarker(hover, canExecute ? MARKER_OK : MARKER_NOT_OK);
  });
  eventBus.on(['connect.out', 'connect.cleanup'], HIGH_PRIORITY, function (event) {
    var hover = event.hover;

    if (hover) {
      canvas.removeMarker(hover, MARKER_OK);
      canvas.removeMarker(hover, MARKER_NOT_OK);
    }
  });
  connectionPreview && eventBus.on('connect.cleanup', function (event) {
    connectionPreview.cleanUp(event.context);
  });
}

ConnectPreview.$inject = ['injector', 'eventBus', 'canvas'];

},{"./Connect":181}],183:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _selection = _interopRequireDefault(require("../selection"));

var _rules = _interopRequireDefault(require("../rules"));

var _dragging = _interopRequireDefault(require("../dragging"));

var _Connect = _interopRequireDefault(require("./Connect"));

var _ConnectPreview = _interopRequireDefault(require("./ConnectPreview"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_selection.default, _rules.default, _dragging.default],
  __init__: ['connectPreview'],
  connect: ['type', _Connect.default],
  connectPreview: ['type', _ConnectPreview.default]
};
exports.default = _default;

},{"../dragging":197,"../rules":272,"../selection":278,"./Connect":181,"./ConnectPreview":182}],184:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ConnectionPreview;

var _tinySvg = require("tiny-svg");

var _minDash = require("min-dash");

var _LayoutUtil = require("../../layout/LayoutUtil");

var MARKER_CONNECTION_PREVIEW = 'djs-connection-preview';
/**
 * Draws connection preview. Optionally, this can use layouter and connection docking to draw
 * better looking previews.
 *
 * @param {didi.Injector} injector
 * @param {Canvas} canvas
 * @param {GraphicsFactory} graphicsFactory
 * @param {ElementFactory} elementFactory
 */

function ConnectionPreview(injector, canvas, graphicsFactory, elementFactory) {
  this._canvas = canvas;
  this._graphicsFactory = graphicsFactory;
  this._elementFactory = elementFactory; // optional components

  this._connectionDocking = injector.get('connectionDocking', false);
  this._layouter = injector.get('layouter', false);
}

ConnectionPreview.$inject = ['injector', 'canvas', 'graphicsFactory', 'elementFactory'];
/**
 * Draw connection preview.
 *
 * Provide at least one of <source, connectionStart> and <target, connectionEnd> to create a preview.
 * In the clean up stage, call `connectionPreview#cleanUp` with the context to remove preview.
 *
 * @param {Object} context
 * @param {Object|boolean} canConnect
 * @param {Object} hints
 * @param {djs.model.shape} [hints.source] source element
 * @param {djs.model.shape} [hints.target] target element
 * @param {Point} [hints.connectionStart] connection preview start
 * @param {Point} [hints.connectionEnd] connection preview end
 * @param {Array<Point>} [hints.waypoints] provided waypoints for preview
 * @param {boolean} [hints.noLayout] true if preview should not be laid out
 * @param {boolean} [hints.noCropping] true if preview should not be cropped
 * @param {boolean} [hints.noNoop] true if simple connection should not be drawn
 */

ConnectionPreview.prototype.drawPreview = function (context, canConnect, hints) {
  hints = hints || {};
  var connectionPreviewGfx = context.connectionPreviewGfx,
      getConnection = context.getConnection,
      source = hints.source,
      target = hints.target,
      waypoints = hints.waypoints,
      connectionStart = hints.connectionStart,
      connectionEnd = hints.connectionEnd,
      noLayout = hints.noLayout,
      noCropping = hints.noCropping,
      noNoop = hints.noNoop,
      connection;
  var self = this;

  if (!connectionPreviewGfx) {
    connectionPreviewGfx = context.connectionPreviewGfx = this.createConnectionPreviewGfx();
  }

  (0, _tinySvg.clear)(connectionPreviewGfx);

  if (!getConnection) {
    getConnection = context.getConnection = cacheReturnValues(function (canConnect, source, target) {
      return self.getConnection(canConnect, source, target);
    });
  }

  if (canConnect) {
    connection = getConnection(canConnect, source, target);
  }

  if (!connection) {
    !noNoop && this.drawNoopPreview(connectionPreviewGfx, hints);
    return;
  }

  connection.waypoints = waypoints || []; // optional layout

  if (this._layouter && !noLayout) {
    connection.waypoints = this._layouter.layoutConnection(connection, {
      source: source,
      target: target,
      connectionStart: connectionStart,
      connectionEnd: connectionEnd,
      waypoints: hints.waypoints || connection.waypoints
    });
  } // fallback if no waypoints were provided nor created with layouter


  if (!connection.waypoints || !connection.waypoints.length) {
    connection.waypoints = [source ? (0, _LayoutUtil.getMid)(source) : connectionStart, target ? (0, _LayoutUtil.getMid)(target) : connectionEnd];
  } // optional cropping


  if (this._connectionDocking && (source || target) && !noCropping) {
    connection.waypoints = this._connectionDocking.getCroppedWaypoints(connection, source, target);
  }

  this._graphicsFactory.drawConnection(connectionPreviewGfx, connection);
};
/**
 * Draw simple connection between source and target or provided points.
 *
 * @param {SVGElement} connectionPreviewGfx container for the connection
 * @param {Object} hints
 * @param {djs.model.shape} [hints.source] source element
 * @param {djs.model.shape} [hints.target] target element
 * @param {Point} [hints.connectionStart] required if source is not provided
 * @param {Point} [hints.connectionEnd] required if target is not provided
 */


ConnectionPreview.prototype.drawNoopPreview = function (connectionPreviewGfx, hints) {
  var source = hints.source,
      target = hints.target,
      start = hints.connectionStart || (0, _LayoutUtil.getMid)(source),
      end = hints.connectionEnd || (0, _LayoutUtil.getMid)(target);
  var waypoints = this.cropWaypoints(start, end, source, target);
  var connection = this.createNoopConnection(waypoints[0], waypoints[1]);
  (0, _tinySvg.append)(connectionPreviewGfx, connection);
};
/**
 * Return cropped waypoints.
 *
 * @param {Point} start
 * @param {Point} end
 * @param {djs.model.shape} source
 * @param {djs.model.shape} target
 *
 * @returns {Array}
 */


ConnectionPreview.prototype.cropWaypoints = function (start, end, source, target) {
  var graphicsFactory = this._graphicsFactory,
      sourcePath = source && graphicsFactory.getShapePath(source),
      targetPath = target && graphicsFactory.getShapePath(target),
      connectionPath = graphicsFactory.getConnectionPath({
    waypoints: [start, end]
  });
  start = source && (0, _LayoutUtil.getElementLineIntersection)(sourcePath, connectionPath, true) || start;
  end = target && (0, _LayoutUtil.getElementLineIntersection)(targetPath, connectionPath, false) || end;
  return [start, end];
};
/**
 * Remove connection preview container if it exists.
 *
 * @param {Object} [context]
 * @param {SVGElement} [context.connectionPreviewGfx] preview container
 */


ConnectionPreview.prototype.cleanUp = function (context) {
  if (context && context.connectionPreviewGfx) {
    (0, _tinySvg.remove)(context.connectionPreviewGfx);
  }
};
/**
 * Get connection that connects source and target.
 *
 * @param {Object|boolean} canConnect
 *
 * @returns {djs.model.connection}
 */


ConnectionPreview.prototype.getConnection = function (canConnect) {
  var attrs = ensureConnectionAttrs(canConnect);
  return this._elementFactory.createConnection(attrs);
};
/**
 * Add and return preview graphics.
 *
 * @returns {SVGElement}
 */


ConnectionPreview.prototype.createConnectionPreviewGfx = function () {
  var gfx = (0, _tinySvg.create)('g');
  (0, _tinySvg.attr)(gfx, {
    pointerEvents: 'none'
  });
  (0, _tinySvg.classes)(gfx).add(MARKER_CONNECTION_PREVIEW);
  (0, _tinySvg.append)(this._canvas.getDefaultLayer(), gfx);
  return gfx;
};
/**
 * Create and return simple connection.
 *
 * @param {Point} start
 * @param {Point} end
 *
 * @returns {SVGElement}
 */


ConnectionPreview.prototype.createNoopConnection = function (start, end) {
  var connection = (0, _tinySvg.create)('polyline');
  (0, _tinySvg.attr)(connection, {
    'stroke': '#333',
    'strokeDasharray': [1],
    'strokeWidth': 2,
    'pointer-events': 'none'
  });
  (0, _tinySvg.attr)(connection, {
    'points': [start.x, start.y, end.x, end.y]
  });
  return connection;
}; // helpers //////////

/**
 * Returns function that returns cached return values referenced by stringified first argument.
 *
 * @param {Function} fn
 *
 * @return {Function}
 */


function cacheReturnValues(fn) {
  var returnValues = {};
  /**
   * Return cached return value referenced by stringified first argument.
   *
   * @returns {*}
   */

  return function (firstArgument) {
    var key = JSON.stringify(firstArgument);
    var returnValue = returnValues[key];

    if (!returnValue) {
      returnValue = returnValues[key] = fn.apply(null, arguments);
    }

    return returnValue;
  };
}
/**
 * Ensure connection attributes is object.
 *
 * @param {Object|boolean} canConnect
 *
 * @returns {Object}
 */


function ensureConnectionAttrs(canConnect) {
  if ((0, _minDash.isObject)(canConnect)) {
    return canConnect;
  } else {
    return {};
  }
}

},{"../../layout/LayoutUtil":300,"min-dash":555,"tiny-svg":567}],185:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _ConnectionPreview = _interopRequireDefault(require("./ConnectionPreview"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['connectionPreview'],
  connectionPreview: ['type', _ConnectionPreview.default]
};
exports.default = _default;

},{"./ConnectionPreview":184}],186:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ContextPad;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var entrySelector = '.entry';
var DEFAULT_PRIORITY = 1000;
/**
 * A context pad that displays element specific, contextual actions next
 * to a diagram element.
 *
 * @param {Object} config
 * @param {boolean|Object} [config.scale={ min: 1.0, max: 1.5 }]
 * @param {number} [config.scale.min]
 * @param {number} [config.scale.max]
 * @param {EventBus} eventBus
 * @param {Overlays} overlays
 */

function ContextPad(config, eventBus, overlays) {
  this._eventBus = eventBus;
  this._overlays = overlays;
  var scale = (0, _minDash.isDefined)(config && config.scale) ? config.scale : {
    min: 1,
    max: 1.5
  };
  this._overlaysConfig = {
    position: {
      right: -9,
      top: -6
    },
    scale: scale
  };
  this._current = null;

  this._init();
}

ContextPad.$inject = ['config.contextPad', 'eventBus', 'overlays'];
/**
 * Registers events needed for interaction with other components
 */

ContextPad.prototype._init = function () {
  var eventBus = this._eventBus;
  var self = this;
  eventBus.on('selection.changed', function (e) {
    var selection = e.newSelection;

    if (selection.length === 1) {
      self.open(selection[0]);
    } else {
      self.close();
    }
  });
  eventBus.on('elements.delete', function (event) {
    var elements = event.elements;
    (0, _minDash.forEach)(elements, function (e) {
      if (self.isOpen(e)) {
        self.close();
      }
    });
  });
  eventBus.on('element.changed', function (event) {
    var element = event.element,
        current = self._current; // force reopen if element for which we are currently opened changed

    if (current && current.element === element) {
      self.open(element, true);
    }
  });
};
/**
 * Register a provider with the context pad
 *
 * @param  {number} [priority=1000]
 * @param  {ContextPadProvider} provider
 *
 * @example
 * const contextPadProvider = {
  *   getContextPadEntries: function(element) {
  *     return function(entries) {
  *       return {
  *         ...entries,
  *         'entry-1': {
  *           label: 'My Entry',
  *           action: function() { alert("I have been clicked!"); }
  *         }
  *       };
  *     }
  *   }
  * };
  *
 * contextPad.registerProvider(800, contextPadProvider);
 */


ContextPad.prototype.registerProvider = function (priority, provider) {
  if (!provider) {
    provider = priority;
    priority = DEFAULT_PRIORITY;
  }

  this._eventBus.on('contextPad.getProviders', priority, function (event) {
    event.providers.push(provider);
  });
};
/**
 * Returns the context pad entries for a given element
 *
 * @param {djs.element.Base} element
 *
 * @return {Array<ContextPadEntryDescriptor>} list of entries
 */


ContextPad.prototype.getEntries = function (element) {
  var providers = this._getProviders();

  var entries = {}; // loop through all providers and their entries.
  // group entries by id so that overriding an entry is possible

  (0, _minDash.forEach)(providers, function (provider) {
    var entriesOrUpdater = provider.getContextPadEntries(element);

    if ((0, _minDash.isFunction)(entriesOrUpdater)) {
      entries = entriesOrUpdater(entries);
    } else {
      (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) {
        entries[id] = entry;
      });
    }
  });
  return entries;
};
/**
 * Trigger an action available on the opened context pad
 *
 * @param  {string} action
 * @param  {Event} event
 * @param  {boolean} [autoActivate=false]
 */


ContextPad.prototype.trigger = function (action, event, autoActivate) {
  var element = this._current.element,
      entries = this._current.entries,
      entry,
      handler,
      originalEvent,
      button = event.delegateTarget || event.target;

  if (!button) {
    return event.preventDefault();
  }

  entry = entries[(0, _minDom.attr)(button, 'data-action')];
  handler = entry.action;
  originalEvent = event.originalEvent || event; // simple action (via callback function)

  if ((0, _minDash.isFunction)(handler)) {
    if (action === 'click') {
      return handler(originalEvent, element, autoActivate);
    }
  } else {
    if (handler[action]) {
      return handler[action](originalEvent, element, autoActivate);
    }
  } // silence other actions


  event.preventDefault();
};
/**
 * Open the context pad for the given element
 *
 * @param {djs.model.Base} element
 * @param {boolean} force if true, force reopening the context pad
 */


ContextPad.prototype.open = function (element, force) {
  if (!force && this.isOpen(element)) {
    return;
  }

  this.close();

  this._updateAndOpen(element);
};

ContextPad.prototype._getProviders = function (id) {
  var event = this._eventBus.createEvent({
    type: 'contextPad.getProviders',
    providers: []
  });

  this._eventBus.fire(event);

  return event.providers;
};

ContextPad.prototype._updateAndOpen = function (element) {
  var entries = this.getEntries(element),
      pad = this.getPad(element),
      html = pad.html;
  (0, _minDash.forEach)(entries, function (entry, id) {
    var grouping = entry.group || 'default',
        control = (0, _minDom.domify)(entry.html || '<div class="entry" draggable="true"></div>'),
        container;
    (0, _minDom.attr)(control, 'data-action', id);
    container = (0, _minDom.query)('[data-group=' + grouping + ']', html);

    if (!container) {
      container = (0, _minDom.domify)('<div class="group" data-group="' + grouping + '"></div>');
      html.appendChild(container);
    }

    container.appendChild(control);

    if (entry.className) {
      addClasses(control, entry.className);
    }

    if (entry.title) {
      (0, _minDom.attr)(control, 'title', entry.title);
    }

    if (entry.imageUrl) {
      control.appendChild((0, _minDom.domify)('<img src="' + entry.imageUrl + '">'));
    }
  });
  (0, _minDom.classes)(html).add('open');
  this._current = {
    element: element,
    pad: pad,
    entries: entries
  };

  this._eventBus.fire('contextPad.open', {
    current: this._current
  });
};

ContextPad.prototype.getPad = function (element) {
  if (this.isOpen()) {
    return this._current.pad;
  }

  var self = this;
  var overlays = this._overlays;
  var html = (0, _minDom.domify)('<div class="djs-context-pad"></div>');
  var overlaysConfig = (0, _minDash.assign)({
    html: html
  }, this._overlaysConfig);

  _minDom.delegate.bind(html, entrySelector, 'click', function (event) {
    self.trigger('click', event);
  });

  _minDom.delegate.bind(html, entrySelector, 'dragstart', function (event) {
    self.trigger('dragstart', event);
  }); // stop propagation of mouse events


  _minDom.event.bind(html, 'mousedown', function (event) {
    event.stopPropagation();
  });

  this._overlayId = overlays.add(element, 'context-pad', overlaysConfig);
  var pad = overlays.get(this._overlayId);

  this._eventBus.fire('contextPad.create', {
    element: element,
    pad: pad
  });

  return pad;
};
/**
 * Close the context pad
 */


ContextPad.prototype.close = function () {
  if (!this.isOpen()) {
    return;
  }

  this._overlays.remove(this._overlayId);

  this._overlayId = null;

  this._eventBus.fire('contextPad.close', {
    current: this._current
  });

  this._current = null;
};
/**
 * Check if pad is open. If element is given, will check
 * if pad is opened with given element.
 *
 * @param {Element} element
 * @return {boolean}
 */


ContextPad.prototype.isOpen = function (element) {
  return !!this._current && (!element ? true : this._current.element === element);
}; // helpers //////////////////////


function addClasses(element, classNames) {
  var classes = (0, _minDom.classes)(element);
  var actualClassNames = (0, _minDash.isArray)(classNames) ? classNames : classNames.split(/\s+/g);
  actualClassNames.forEach(function (cls) {
    classes.add(cls);
  });
}

},{"min-dash":555,"min-dom":556}],187:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _interactionEvents = _interopRequireDefault(require("../interaction-events"));

var _overlays = _interopRequireDefault(require("../overlays"));

var _ContextPad = _interopRequireDefault(require("./ContextPad"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_interactionEvents.default, _overlays.default],
  contextPad: ['type', _ContextPad.default]
};
exports.default = _default;

},{"../interaction-events":211,"../overlays":256,"./ContextPad":186}],188:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CopyPaste;

var _minDash = require("min-dash");

var _Elements = require("../../util/Elements");

/**
 * @typedef {Function} <copyPaste.canCopyElements> listener
 *
 * @param {Object} context
 * @param {Array<djs.model.Base>} context.elements
 *
 * @returns {Array<djs.model.Base>|boolean} - Return elements to be copied or false to disallow
 * copying.
 */

/**
 * @typedef {Function} <copyPaste.copyElement> listener
 *
 * @param {Object} context
 * @param {Object} context.descriptor
 * @param {djs.model.Base} context.element
 * @param {Array<djs.model.Base>} context.elements
 */

/**
 * @typedef {Function} <copyPaste.elementsCopied> listener
 *
 * @param {Object} context
 * @param {Object} context.elements
 * @param {Object} context.tree
 */

/**
 * @typedef {Function} <copyPaste.pasteElement> listener
 *
 * @param {Object} context
 * @param {Object} context.cache - Already created elements.
 * @param {Object} context.descriptor
 */

/**
 * @typedef {Function} <copyPaste.pasteElements> listener
 *
 * @param {Object} context
 * @param {Object} context.hints - Add hints before pasting.
 */

/**
 * Copy and paste elements.
 *
 * @param {Canvas} canvas
 * @param {Create} create
 * @param {Clipboard} clipboard
 * @param {ElementFactory} elementFactory
 * @param {EventBus} eventBus
 * @param {Modeling} modeling
 * @param {Mouse} mouse
 * @param {Rules} rules
 */
function CopyPaste(canvas, create, clipboard, elementFactory, eventBus, modeling, mouse, rules) {
  this._canvas = canvas;
  this._create = create;
  this._clipboard = clipboard;
  this._elementFactory = elementFactory;
  this._eventBus = eventBus;
  this._modeling = modeling;
  this._mouse = mouse;
  this._rules = rules;
  eventBus.on('copyPaste.copyElement', function (context) {
    var descriptor = context.descriptor,
        element = context.element,
        elements = context.elements; // default priority (priority = 1)

    descriptor.priority = 1;
    descriptor.id = element.id;
    var parentCopied = (0, _minDash.find)(elements, function (e) {
      return e === element.parent;
    }); // do NOT reference parent if parent wasn't copied

    if (parentCopied) {
      descriptor.parent = element.parent.id;
    } // attachers (priority = 2)


    if (isAttacher(element)) {
      descriptor.priority = 2;
      descriptor.host = element.host.id;
    } // connections (priority = 3)


    if (isConnection(element)) {
      descriptor.priority = 3;
      descriptor.source = element.source.id;
      descriptor.target = element.target.id;
      descriptor.waypoints = copyWaypoints(element);
    } // labels (priority = 4)


    if (isLabel(element)) {
      descriptor.priority = 4;
      descriptor.labelTarget = element.labelTarget.id;
    }

    (0, _minDash.forEach)(['x', 'y', 'width', 'height'], function (property) {
      if ((0, _minDash.isNumber)(element[property])) {
        descriptor[property] = element[property];
      }
    });
    descriptor.hidden = element.hidden;
    descriptor.collapsed = element.collapsed;
  });
  eventBus.on('copyPaste.pasteElements', function (context) {
    var hints = context.hints;
    (0, _minDash.assign)(hints, {
      createElementsBehavior: false
    });
  });
}

CopyPaste.$inject = ['canvas', 'create', 'clipboard', 'elementFactory', 'eventBus', 'modeling', 'mouse', 'rules'];
/**
 * Copy elements.
 *
 * @param {Array<djs.model.Base>} elements
 *
 * @returns {Object}
 */

CopyPaste.prototype.copy = function (elements) {
  var allowed, tree;

  if (!(0, _minDash.isArray)(elements)) {
    elements = elements ? [elements] : [];
  }

  allowed = this._eventBus.fire('copyPaste.canCopyElements', {
    elements: elements
  });

  if (allowed === false) {
    tree = {};
  } else {
    tree = this.createTree((0, _minDash.isArray)(allowed) ? allowed : elements);
  } // we set an empty tree, selection of elements
  // to copy was empty.


  this._clipboard.set(tree);

  this._eventBus.fire('copyPaste.elementsCopied', {
    elements: elements,
    tree: tree
  });

  return tree;
};
/**
 * Paste elements.
 *
 * @param {Object} [context]
 * @param {djs.model.base} [context.element] - Parent.
 * @param {Point} [context.point] - Position.
 * @param {Object} [context.hints] - Hints.
 */


CopyPaste.prototype.paste = function (context) {
  var tree = this._clipboard.get();

  if (this._clipboard.isEmpty()) {
    return;
  }

  var hints = context && context.hints || {};

  this._eventBus.fire('copyPaste.pasteElements', {
    hints: hints
  });

  var elements = this._createElements(tree); // paste directly


  if (context && context.element && context.point) {
    return this._paste(elements, context.element, context.point, hints);
  }

  this._create.start(this._mouse.getLastMoveEvent(), elements, {
    hints: hints || {}
  });
};
/**
 * Paste elements directly.
 *
 * @param {Array<djs.model.Base>} elements
 * @param {djs.model.base} target
 * @param {Point} position
 * @param {Object} [hints]
 */


CopyPaste.prototype._paste = function (elements, target, position, hints) {
  // make sure each element has x and y
  (0, _minDash.forEach)(elements, function (element) {
    if (!(0, _minDash.isNumber)(element.x)) {
      element.x = 0;
    }

    if (!(0, _minDash.isNumber)(element.y)) {
      element.y = 0;
    }
  });
  var bbox = (0, _Elements.getBBox)(elements); // center elements around cursor

  (0, _minDash.forEach)(elements, function (element) {
    if (isConnection(element)) {
      element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint) {
        return {
          x: waypoint.x - bbox.x - bbox.width / 2,
          y: waypoint.y - bbox.y - bbox.height / 2
        };
      });
    }

    (0, _minDash.assign)(element, {
      x: element.x - bbox.x - bbox.width / 2,
      y: element.y - bbox.y - bbox.height / 2
    });
  });
  return this._modeling.createElements(elements, position, target, (0, _minDash.assign)({}, hints));
};
/**
 * Create elements from tree.
 */


CopyPaste.prototype._createElements = function (tree) {
  var self = this;
  var eventBus = this._eventBus;
  var cache = {};
  var elements = [];
  (0, _minDash.forEach)(tree, function (branch, depth) {
    depth = parseInt(depth, 10); // sort by priority

    branch = (0, _minDash.sortBy)(branch, 'priority');
    (0, _minDash.forEach)(branch, function (descriptor) {
      // remove priority
      var attrs = (0, _minDash.assign)({}, (0, _minDash.omit)(descriptor, ['priority']));

      if (cache[descriptor.parent]) {
        attrs.parent = cache[descriptor.parent];
      } else {
        delete attrs.parent;
      }

      eventBus.fire('copyPaste.pasteElement', {
        cache: cache,
        descriptor: attrs
      });
      var element;

      if (isConnection(attrs)) {
        attrs.source = cache[descriptor.source];
        attrs.target = cache[descriptor.target];
        element = cache[descriptor.id] = self.createConnection(attrs);
        elements.push(element);
        return;
      }

      if (isLabel(attrs)) {
        attrs.labelTarget = cache[attrs.labelTarget];
        element = cache[descriptor.id] = self.createLabel(attrs);
        elements.push(element);
        return;
      }

      if (attrs.host) {
        attrs.host = cache[attrs.host];
      }

      element = cache[descriptor.id] = self.createShape(attrs);
      elements.push(element);
    });
  });
  return elements;
};

CopyPaste.prototype.createConnection = function (attrs) {
  var connection = this._elementFactory.createConnection((0, _minDash.omit)(attrs, ['id']));

  return connection;
};

CopyPaste.prototype.createLabel = function (attrs) {
  var label = this._elementFactory.createLabel((0, _minDash.omit)(attrs, ['id']));

  return label;
};

CopyPaste.prototype.createShape = function (attrs) {
  var shape = this._elementFactory.createShape((0, _minDash.omit)(attrs, ['id']));

  return shape;
};
/**
 * Check wether element has relations to other elements e.g. attachers, labels and connections.
 *
 * @param  {Object} element
 * @param  {Array<djs.model.Base>} elements
 *
 * @returns {boolean}
 */


CopyPaste.prototype.hasRelations = function (element, elements) {
  var labelTarget, source, target;

  if (isConnection(element)) {
    source = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({
      id: element.source.id
    }));
    target = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({
      id: element.target.id
    }));

    if (!source || !target) {
      return false;
    }
  }

  if (isLabel(element)) {
    labelTarget = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({
      id: element.labelTarget.id
    }));

    if (!labelTarget) {
      return false;
    }
  }

  return true;
};
/**
 * Create a tree-like structure from elements.
 *
 * @example
 * tree: {
  *  0: [
  *    { id: 'Shape_1', priority: 1, ... },
  *    { id: 'Shape_2', priority: 1, ... },
  *    { id: 'Connection_1', source: 'Shape_1', target: 'Shape_2', priority: 3, ... },
  *    ...
  *  ],
  *  1: [
  *    { id: 'Shape_3', parent: 'Shape1', priority: 1, ... },
  *    ...
  *  ]
  * };
  *
  * @param  {Array<djs.model.base>} elements
  *
  * @return {Object}
  */


CopyPaste.prototype.createTree = function (elements) {
  var rules = this._rules,
      self = this;
  var tree = {},
      elementsData = [];
  var parents = (0, _Elements.getParents)(elements);

  function canCopy(element, elements) {
    return rules.allowed('element.copy', {
      element: element,
      elements: elements
    });
  }

  function addElementData(element, depth) {
    // (1) check wether element has already been added
    var foundElementData = (0, _minDash.find)(elementsData, function (elementsData) {
      return element === elementsData.element;
    }); // (2) add element if not already added

    if (!foundElementData) {
      elementsData.push({
        element: element,
        depth: depth
      });
      return;
    } // (3) update depth


    if (foundElementData.depth < depth) {
      elementsData = removeElementData(foundElementData, elementsData);
      elementsData.push({
        element: foundElementData.element,
        depth: depth
      });
    }
  }

  function removeElementData(elementData, elementsData) {
    var index = elementsData.indexOf(elementData);

    if (index !== -1) {
      elementsData.splice(index, 1);
    }

    return elementsData;
  } // (1) add elements


  (0, _Elements.eachElement)(parents, function (element, _index, depth) {
    // do NOT add external labels directly
    if (isLabel(element)) {
      return;
    } // always copy external labels


    (0, _minDash.forEach)(element.labels, function (label) {
      addElementData(label, depth);
    });

    function addRelatedElements(elements) {
      elements && elements.length && (0, _minDash.forEach)(elements, function (element) {
        // add external labels
        (0, _minDash.forEach)(element.labels, function (label) {
          addElementData(label, depth);
        });
        addElementData(element, depth);
      });
    }

    (0, _minDash.forEach)([element.attachers, element.incoming, element.outgoing], addRelatedElements);
    addElementData(element, depth);
    return element.children;
  });
  elements = (0, _minDash.map)(elementsData, function (elementData) {
    return elementData.element;
  }); // (2) copy elements

  elementsData = (0, _minDash.map)(elementsData, function (elementData) {
    elementData.descriptor = {};

    self._eventBus.fire('copyPaste.copyElement', {
      descriptor: elementData.descriptor,
      element: elementData.element,
      elements: elements
    });

    return elementData;
  }); // (3) sort elements by priority

  elementsData = (0, _minDash.sortBy)(elementsData, function (elementData) {
    return elementData.descriptor.priority;
  });
  elements = (0, _minDash.map)(elementsData, function (elementData) {
    return elementData.element;
  }); // (4) create tree

  (0, _minDash.forEach)(elementsData, function (elementData) {
    var depth = elementData.depth;

    if (!self.hasRelations(elementData.element, elements)) {
      removeElement(elementData.element, elements);
      return;
    }

    if (!canCopy(elementData.element, elements)) {
      removeElement(elementData.element, elements);
      return;
    }

    if (!tree[depth]) {
      tree[depth] = [];
    }

    tree[depth].push(elementData.descriptor);
  });
  return tree;
}; // helpers //////////


function isAttacher(element) {
  return !!element.host;
}

function isConnection(element) {
  return !!element.waypoints;
}

function isLabel(element) {
  return !!element.labelTarget;
}

function copyWaypoints(element) {
  return (0, _minDash.map)(element.waypoints, function (waypoint) {
    waypoint = copyWaypoint(waypoint);

    if (waypoint.original) {
      waypoint.original = copyWaypoint(waypoint.original);
    }

    return waypoint;
  });
}

function copyWaypoint(waypoint) {
  return (0, _minDash.assign)({}, waypoint);
}

function removeElement(element, elements) {
  var index = elements.indexOf(element);

  if (index === -1) {
    return elements;
  }

  return elements.splice(index, 1);
}

},{"../../util/Elements":315,"min-dash":555}],189:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _clipboard = _interopRequireDefault(require("../clipboard"));

var _create = _interopRequireDefault(require("../create"));

var _mouse = _interopRequireDefault(require("../mouse"));

var _rules = _interopRequireDefault(require("../rules"));

var _CopyPaste = _interopRequireDefault(require("./CopyPaste"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_clipboard.default, _create.default, _mouse.default, _rules.default],
  __init__: ['copyPaste'],
  copyPaste: ['type', _CopyPaste.default]
};
exports.default = _default;

},{"../clipboard":180,"../create":192,"../mouse":248,"../rules":272,"./CopyPaste":188}],190:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Create;

var _minDash = require("min-dash");

var _Elements = require("../../util/Elements");

var MARKER_OK = 'drop-ok',
    MARKER_NOT_OK = 'drop-not-ok',
    MARKER_ATTACH = 'attach-ok',
    MARKER_NEW_PARENT = 'new-parent';
var PREFIX = 'create';
var HIGH_PRIORITY = 2000;
/**
 * Create new elements through drag and drop.
 *
 * @param {Canvas} canvas
 * @param {Dragging} dragging
 * @param {EventBus} eventBus
 * @param {Modeling} modeling
 * @param {Rules} rules
 */

function Create(canvas, dragging, eventBus, modeling, rules) {
  // rules //////////

  /**
   * Check wether elements can be created.
   *
   * @param {Array<djs.model.Base>} elements
   * @param {djs.model.Base} target
   * @param {Point} position
   * @param {djs.model.Base} [source]
   *
   * @returns {boolean|null|Object}
   */
  function canCreate(elements, target, position, source, hints) {
    if (!target) {
      return false;
    } // ignore child elements and external labels


    elements = (0, _minDash.filter)(elements, function (element) {
      var labelTarget = element.labelTarget;
      return !element.parent && !(isLabel(element) && elements.indexOf(labelTarget) !== -1);
    });
    var shape = (0, _minDash.find)(elements, function (element) {
      return !isConnection(element);
    });
    var attach = false,
        connect = false,
        create = false; // (1) attaching single shapes

    if (isSingleShape(elements)) {
      attach = rules.allowed('shape.attach', {
        position: position,
        shape: shape,
        target: target
      });
    }

    if (!attach) {
      // (2) creating elements
      if (isSingleShape(elements)) {
        create = rules.allowed('shape.create', {
          position: position,
          shape: shape,
          source: source,
          target: target
        });
      } else {
        create = rules.allowed('elements.create', {
          elements: elements,
          position: position,
          target: target
        });
      }
    }

    var connectionTarget = hints.connectionTarget; // (3) appending single shapes

    if (create || attach) {
      if (shape && source) {
        connect = rules.allowed('connection.create', {
          source: connectionTarget === source ? shape : source,
          target: connectionTarget === source ? source : shape,
          hints: {
            targetParent: target,
            targetAttach: attach
          }
        });
      }

      return {
        attach: attach,
        connect: connect
      };
    } // ignore wether or not elements can be created


    if (create === null || attach === null) {
      return null;
    }

    return false;
  }

  function setMarker(element, marker) {
    [MARKER_ATTACH, MARKER_OK, MARKER_NOT_OK, MARKER_NEW_PARENT].forEach(function (m) {
      if (m === marker) {
        canvas.addMarker(element, m);
      } else {
        canvas.removeMarker(element, m);
      }
    });
  } // event handling //////////


  eventBus.on(['create.move', 'create.hover'], function (event) {
    var context = event.context,
        elements = context.elements,
        hover = event.hover,
        source = context.source,
        hints = context.hints || {};

    if (!hover) {
      context.canExecute = false;
      context.target = null;
      return;
    }

    ensureConstraints(event);
    var position = {
      x: event.x,
      y: event.y
    };
    var canExecute = context.canExecute = hover && canCreate(elements, hover, position, source, hints);

    if (hover && canExecute !== null) {
      context.target = hover;

      if (canExecute && canExecute.attach) {
        setMarker(hover, MARKER_ATTACH);
      } else {
        setMarker(hover, canExecute ? MARKER_NEW_PARENT : MARKER_NOT_OK);
      }
    }
  });
  eventBus.on(['create.end', 'create.out', 'create.cleanup'], function (event) {
    var hover = event.hover;

    if (hover) {
      setMarker(hover, null);
    }
  });
  eventBus.on('create.end', function (event) {
    var context = event.context,
        source = context.source,
        shape = context.shape,
        elements = context.elements,
        target = context.target,
        canExecute = context.canExecute,
        attach = canExecute && canExecute.attach,
        connect = canExecute && canExecute.connect,
        hints = context.hints || {};

    if (canExecute === false || !target) {
      return false;
    }

    ensureConstraints(event);
    var position = {
      x: event.x,
      y: event.y
    };

    if (connect) {
      shape = modeling.appendShape(source, shape, position, target, {
        attach: attach,
        connection: connect === true ? {} : connect,
        connectionTarget: hints.connectionTarget
      });
    } else {
      elements = modeling.createElements(elements, position, target, (0, _minDash.assign)({}, hints, {
        attach: attach
      })); // update shape

      shape = (0, _minDash.find)(elements, function (element) {
        return !isConnection(element);
      });
    } // update elements and shape


    (0, _minDash.assign)(context, {
      elements: elements,
      shape: shape
    });
    (0, _minDash.assign)(event, {
      elements: elements,
      shape: shape
    });
  });

  function cancel() {
    var context = dragging.context();

    if (context && context.prefix === PREFIX) {
      dragging.cancel();
    }
  } // cancel on <elements.changed> that is not result of <drag.end>


  eventBus.on('create.init', function () {
    eventBus.on('elements.changed', cancel);
    eventBus.once(['create.cancel', 'create.end'], HIGH_PRIORITY, function () {
      eventBus.off('elements.changed', cancel);
    });
  }); // API //////////

  this.start = function (event, elements, context) {
    if (!(0, _minDash.isArray)(elements)) {
      elements = [elements];
    }

    var shape = (0, _minDash.find)(elements, function (element) {
      return !isConnection(element);
    });

    if (!shape) {
      // at least one shape is required
      return;
    }

    context = (0, _minDash.assign)({
      elements: elements,
      hints: {},
      shape: shape
    }, context || {}); // make sure each element has x and y

    (0, _minDash.forEach)(elements, function (element) {
      if (!(0, _minDash.isNumber)(element.x)) {
        element.x = 0;
      }

      if (!(0, _minDash.isNumber)(element.y)) {
        element.y = 0;
      }
    });
    var bbox = (0, _Elements.getBBox)(elements); // center elements around cursor

    (0, _minDash.forEach)(elements, function (element) {
      if (isConnection(element)) {
        element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint) {
          return {
            x: waypoint.x - bbox.x - bbox.width / 2,
            y: waypoint.y - bbox.y - bbox.height / 2
          };
        });
      }

      (0, _minDash.assign)(element, {
        x: element.x - bbox.x - bbox.width / 2,
        y: element.y - bbox.y - bbox.height / 2
      });
    });
    dragging.init(event, PREFIX, {
      cursor: 'grabbing',
      autoActivate: true,
      data: {
        shape: shape,
        elements: elements,
        context: context
      }
    });
  };
}

Create.$inject = ['canvas', 'dragging', 'eventBus', 'modeling', 'rules']; // helpers //////////

function ensureConstraints(event) {
  var context = event.context,
      createConstraints = context.createConstraints;

  if (!createConstraints) {
    return;
  }

  if (createConstraints.left) {
    event.x = Math.max(event.x, createConstraints.left);
  }

  if (createConstraints.right) {
    event.x = Math.min(event.x, createConstraints.right);
  }

  if (createConstraints.top) {
    event.y = Math.max(event.y, createConstraints.top);
  }

  if (createConstraints.bottom) {
    event.y = Math.min(event.y, createConstraints.bottom);
  }
}

function isConnection(element) {
  return !!element.waypoints;
}

function isSingleShape(elements) {
  return elements && elements.length === 1 && !isConnection(elements[0]);
}

function isLabel(element) {
  return !!element.labelTarget;
}

},{"../../util/Elements":315,"min-dash":555}],191:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreatePreview;

var _SvgTransformUtil = require("../../util/SvgTransformUtil");

var _GraphicsUtil = require("../../util/GraphicsUtil");

var _tinySvg = require("tiny-svg");

var LOW_PRIORITY = 750;

function CreatePreview(canvas, eventBus, graphicsFactory, previewSupport, styles) {
  function createDragGroup(elements) {
    var dragGroup = (0, _tinySvg.create)('g');
    (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events']));
    var childrenGfx = (0, _tinySvg.create)('g');
    elements.forEach(function (element) {
      // create graphics
      var gfx;

      if (element.hidden) {
        return;
      }

      if (element.waypoints) {
        gfx = graphicsFactory._createContainer('connection', childrenGfx);
        graphicsFactory.drawConnection((0, _GraphicsUtil.getVisual)(gfx), element);
      } else {
        gfx = graphicsFactory._createContainer('shape', childrenGfx);
        graphicsFactory.drawShape((0, _GraphicsUtil.getVisual)(gfx), element);
        (0, _SvgTransformUtil.translate)(gfx, element.x, element.y);
      } // add preview


      previewSupport.addDragger(element, dragGroup, gfx);
    });
    return dragGroup;
  }

  eventBus.on('create.move', LOW_PRIORITY, function (event) {
    var hover = event.hover,
        context = event.context,
        elements = context.elements,
        dragGroup = context.dragGroup; // lazily create previews

    if (!dragGroup) {
      dragGroup = context.dragGroup = createDragGroup(elements);
    }

    var defaultLayer;

    if (hover) {
      if (!dragGroup.parentNode) {
        defaultLayer = canvas.getDefaultLayer();
        (0, _tinySvg.append)(defaultLayer, dragGroup);
      }

      (0, _SvgTransformUtil.translate)(dragGroup, event.x, event.y);
    } else {
      (0, _tinySvg.remove)(dragGroup);
    }
  });
  eventBus.on('create.cleanup', function (event) {
    var context = event.context,
        dragGroup = context.dragGroup;

    if (dragGroup) {
      (0, _tinySvg.remove)(dragGroup);
    }
  });
}

CreatePreview.$inject = ['canvas', 'eventBus', 'graphicsFactory', 'previewSupport', 'styles'];

},{"../../util/GraphicsUtil":319,"../../util/SvgTransformUtil":328,"tiny-svg":567}],192:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _dragging = _interopRequireDefault(require("../dragging"));

var _previewSupport = _interopRequireDefault(require("../preview-support"));

var _rules = _interopRequireDefault(require("../rules"));

var _selection = _interopRequireDefault(require("../selection"));

var _Create = _interopRequireDefault(require("./Create"));

var _CreatePreview = _interopRequireDefault(require("./CreatePreview"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_dragging.default, _previewSupport.default, _rules.default, _selection.default],
  __init__: ['create', 'createPreview'],
  create: ['type', _Create.default],
  createPreview: ['type', _CreatePreview.default]
};
exports.default = _default;

},{"../dragging":197,"../preview-support":262,"../rules":272,"../selection":278,"./Create":190,"./CreatePreview":191}],193:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DistributeElements;

var _minDash = require("min-dash");

var AXIS_DIMENSIONS = {
  horizontal: ['x', 'width'],
  vertical: ['y', 'height']
};
var THRESHOLD = 5;
/**
 * Groups and filters elements and then trigger even distribution.
 */

function DistributeElements(modeling) {
  this._modeling = modeling;
  this._filters = []; // register filter for filtering big elements

  this.registerFilter(function (elements, axis, dimension) {
    var elementsSize = 0,
        numOfShapes = 0,
        avgDimension;
    (0, _minDash.forEach)(elements, function (element) {
      if (element.waypoints || element.labelTarget) {
        return;
      }

      elementsSize += element[dimension];
      numOfShapes += 1;
    });
    avgDimension = Math.round(elementsSize / numOfShapes);
    return (0, _minDash.filter)(elements, function (element) {
      return element[dimension] < avgDimension + 50;
    });
  });
}

DistributeElements.$inject = ['modeling'];
/**
 * Registers filter functions that allow external parties to filter
 * out certain elements.
 *
 * @param  {Function} filterFn
 */

DistributeElements.prototype.registerFilter = function (filterFn) {
  if (typeof filterFn !== 'function') {
    throw new Error('the filter has to be a function');
  }

  this._filters.push(filterFn);
};
/**
 * Distributes the elements with a given orientation
 *
 * @param  {Array} elements    [description]
 * @param  {string} orientation [description]
 */


DistributeElements.prototype.trigger = function (elements, orientation) {
  var modeling = this._modeling;
  var groups, distributableElements;

  if (elements.length < 3) {
    return;
  }

  this._setOrientation(orientation);

  distributableElements = this._filterElements(elements);
  groups = this._createGroups(distributableElements); // nothing to distribute

  if (groups.length <= 2) {
    return;
  }

  modeling.distributeElements(groups, this._axis, this._dimension);
  return groups;
};
/**
 * Filters the elements with provided filters by external parties
 *
 * @param  {Array[Elements]} elements
 *
 * @return {Array[Elements]}
 */


DistributeElements.prototype._filterElements = function (elements) {
  var filters = this._filters,
      axis = this._axis,
      dimension = this._dimension,
      distributableElements = [].concat(elements);

  if (!filters.length) {
    return elements;
  }

  (0, _minDash.forEach)(filters, function (filterFn) {
    distributableElements = filterFn(distributableElements, axis, dimension);
  });
  return distributableElements;
};
/**
 * Create range (min, max) groups. Also tries to group elements
 * together that share the same range.
 *
 * @example
 * 	var distributableElements = [
 * 		{
 * 			range: {
 * 				min: 100,
 * 				max: 200
 * 			},
 * 			elements: [ { id: 'shape1', .. }]
 * 		}
 * 	]
 *
 * @param  {Array} elements
 *
 * @return {Array[Objects]}
 */


DistributeElements.prototype._createGroups = function (elements) {
  var rangeGroups = [],
      self = this,
      axis = this._axis,
      dimension = this._dimension;

  if (!axis) {
    throw new Error('must have a defined "axis" and "dimension"');
  } // sort by 'left->right' or 'top->bottom'


  var sortedElements = (0, _minDash.sortBy)(elements, axis);
  (0, _minDash.forEach)(sortedElements, function (element, idx) {
    var elementRange = self._findRange(element, axis, dimension),
        range;

    var previous = rangeGroups[rangeGroups.length - 1];

    if (previous && self._hasIntersection(previous.range, elementRange)) {
      rangeGroups[rangeGroups.length - 1].elements.push(element);
    } else {
      range = {
        range: elementRange,
        elements: [element]
      };
      rangeGroups.push(range);
    }
  });
  return rangeGroups;
};
/**
 * Maps a direction to the according axis and dimension
 *
 * @param  {string} direction 'horizontal' or 'vertical'
 */


DistributeElements.prototype._setOrientation = function (direction) {
  var orientation = AXIS_DIMENSIONS[direction];
  this._axis = orientation[0];
  this._dimension = orientation[1];
};
/**
 * Checks if the two ranges intercept each other
 *
 * @param  {Object} rangeA {min, max}
 * @param  {Object} rangeB {min, max}
 *
 * @return {boolean}
 */


DistributeElements.prototype._hasIntersection = function (rangeA, rangeB) {
  return Math.max(rangeA.min, rangeA.max) >= Math.min(rangeB.min, rangeB.max) && Math.min(rangeA.min, rangeA.max) <= Math.max(rangeB.min, rangeB.max);
};
/**
 * Returns the min and max values for an element
 *
 * @param  {[type]} element   [description]
 * @param  {[type]} axis      [description]
 * @param  {[type]} dimension [description]
 *
 * @return {[type]}           [description]
 */


DistributeElements.prototype._findRange = function (element) {
  var axis = element[this._axis],
      dimension = element[this._dimension];
  return {
    min: axis + THRESHOLD,
    max: axis + dimension - THRESHOLD
  };
};

},{"min-dash":555}],194:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _DistributeElements = _interopRequireDefault(require("./DistributeElements"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['distributeElements'],
  distributeElements: ['type', _DistributeElements.default]
};
exports.default = _default;

},{"./DistributeElements":193}],195:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Dragging;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _Event = require("../../util/Event");

var _Cursor = require("../../util/Cursor");

var _ClickTrap = require("../../util/ClickTrap");

var _PositionUtil = require("../../util/PositionUtil");

/* global TouchEvent */
var round = Math.round;
var DRAG_ACTIVE_CLS = 'djs-drag-active';

function preventDefault(event) {
  event.preventDefault();
}

function isTouchEvent(event) {
  // check for TouchEvent being available first
  // (i.e. not available on desktop Firefox)
  return typeof TouchEvent !== 'undefined' && event instanceof TouchEvent;
}

function getLength(point) {
  return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));
}
/**
 * A helper that fires canvas localized drag events and realizes
 * the general "drag-and-drop" look and feel.
 *
 * Calling {@link Dragging#activate} activates dragging on a canvas.
 *
 * It provides the following:
 *
 *   * emits life cycle events, namespaced with a prefix assigned
 *     during dragging activation
 *   * sets and restores the cursor
 *   * sets and restores the selection if elements still exist
 *   * ensures there can be only one drag operation active at a time
 *
 * Dragging may be canceled manually by calling {@link Dragging#cancel}
 * or by pressing ESC.
 *
 *
 * ## Life-cycle events
 *
 * Dragging can be in three different states, off, initialized
 * and active.
 *
 * (1) off: no dragging operation is in progress
 * (2) initialized: a new drag operation got initialized but not yet
 *                  started (i.e. because of no initial move)
 * (3) started: dragging is in progress
 *
 * Eventually dragging will be off again after a drag operation has
 * been ended or canceled via user click or ESC key press.
 *
 * To indicate transitions between these states dragging emits generic
 * life-cycle events with the `drag.` prefix _and_ events namespaced
 * to a prefix choosen by a user during drag initialization.
 *
 * The following events are emitted (appropriately prefixed) via
 * the {@link EventBus}.
 *
 * * `init`
 * * `start`
 * * `move`
 * * `end`
 * * `ended` (dragging already in off state)
 * * `cancel` (only if previously started)
 * * `canceled` (dragging already in off state, only if previously started)
 * * `cleanup`
 *
 *
 * @example
 *
 * function MyDragComponent(eventBus, dragging) {
 *
 *   eventBus.on('mydrag.start', function(event) {
 *     console.log('yes, we start dragging');
 *   });
 *
 *   eventBus.on('mydrag.move', function(event) {
 *     console.log('canvas local coordinates', event.x, event.y, event.dx, event.dy);
 *
 *     // local drag data is passed with the event
 *     event.context.foo; // "BAR"
 *
 *     // the original mouse event, too
 *     event.originalEvent; // MouseEvent(...)
 *   });
 *
 *   eventBus.on('element.click', function(event) {
 *     dragging.init(event, 'mydrag', {
 *       cursor: 'grabbing',
 *       data: {
 *         context: {
 *           foo: "BAR"
 *         }
 *       }
 *     });
 *   });
 * }
 */


function Dragging(eventBus, canvas, selection, elementRegistry) {
  var defaultOptions = {
    threshold: 5,
    trapClick: true
  }; // the currently active drag operation
  // dragging is active as soon as this context exists.
  //
  // it is visually _active_ only when a context.active flag is set to true.

  var context;
  /* convert a global event into local coordinates */

  function toLocalPoint(globalPosition) {
    var viewbox = canvas.viewbox();

    var clientRect = canvas._container.getBoundingClientRect();

    return {
      x: viewbox.x + (globalPosition.x - clientRect.left) / viewbox.scale,
      y: viewbox.y + (globalPosition.y - clientRect.top) / viewbox.scale
    };
  } // helpers


  function fire(type, dragContext) {
    dragContext = dragContext || context;
    var event = eventBus.createEvent((0, _minDash.assign)({}, dragContext.payload, dragContext.data, {
      isTouch: dragContext.isTouch
    })); // default integration

    if (eventBus.fire('drag.' + type, event) === false) {
      return false;
    }

    return eventBus.fire(dragContext.prefix + '.' + type, event);
  }

  function restoreSelection(previousSelection) {
    var existingSelection = previousSelection.filter(function (element) {
      return elementRegistry.get(element.id);
    });
    existingSelection.length && selection.select(existingSelection);
  } // event listeners


  function move(event, activate) {
    var payload = context.payload,
        displacement = context.displacement;
    var globalStart = context.globalStart,
        globalCurrent = (0, _Event.toPoint)(event),
        globalDelta = (0, _PositionUtil.delta)(globalCurrent, globalStart);
    var localStart = context.localStart,
        localCurrent = toLocalPoint(globalCurrent),
        localDelta = (0, _PositionUtil.delta)(localCurrent, localStart); // activate context explicitly or once threshold is reached

    if (!context.active && (activate || getLength(globalDelta) > context.threshold)) {
      // fire start event with original
      // starting coordinates
      (0, _minDash.assign)(payload, {
        x: round(localStart.x + displacement.x),
        y: round(localStart.y + displacement.y),
        dx: 0,
        dy: 0
      }, {
        originalEvent: event
      });

      if (false === fire('start')) {
        return cancel();
      }

      context.active = true; // unset selection and remember old selection
      // the previous (old) selection will always passed
      // with the event via the event.previousSelection property

      if (!context.keepSelection) {
        payload.previousSelection = selection.get();
        selection.select(null);
      } // allow custom cursor


      if (context.cursor) {
        (0, _Cursor.set)(context.cursor);
      } // indicate dragging via marker on root element


      canvas.addMarker(canvas.getRootElement(), DRAG_ACTIVE_CLS);
    }

    (0, _Event.stopPropagation)(event);

    if (context.active) {
      // update payload with actual coordinates
      (0, _minDash.assign)(payload, {
        x: round(localCurrent.x + displacement.x),
        y: round(localCurrent.y + displacement.y),
        dx: round(localDelta.x),
        dy: round(localDelta.y)
      }, {
        originalEvent: event
      }); // emit move event

      fire('move');
    }
  }

  function end(event) {
    var previousContext,
        returnValue = true;

    if (context.active) {
      if (event) {
        context.payload.originalEvent = event; // suppress original event (click, ...)
        // because we just ended a drag operation

        (0, _Event.stopPropagation)(event);
      } // implementations may stop restoring the
      // original state (selections, ...) by preventing the
      // end events default action


      returnValue = fire('end');
    }

    if (returnValue === false) {
      fire('rejected');
    }

    previousContext = cleanup(returnValue !== true); // last event to be fired when all drag operations are done
    // at this point in time no drag operation is in progress anymore

    fire('ended', previousContext);
  } // cancel active drag operation if the user presses
  // the ESC key on the keyboard


  function checkCancel(event) {
    if (event.which === 27) {
      preventDefault(event);
      cancel();
    }
  } // prevent ghost click that might occur after a finished
  // drag and drop session


  function trapClickAndEnd(event) {
    var untrap; // trap the click in case we are part of an active
    // drag operation. This will effectively prevent
    // the ghost click that cannot be canceled otherwise.

    if (context.active) {
      untrap = (0, _ClickTrap.install)(eventBus); // remove trap after minimal delay

      setTimeout(untrap, 400); // prevent default action (click)

      preventDefault(event);
    }

    end(event);
  }

  function trapTouch(event) {
    move(event);
  } // update the drag events hover (djs.model.Base) and hoverGfx (Snap<SVGElement>)
  // properties during hover and out and fire {prefix}.hover and {prefix}.out properties
  // respectively


  function hover(event) {
    var payload = context.payload;
    payload.hoverGfx = event.gfx;
    payload.hover = event.element;
    fire('hover');
  }

  function out(event) {
    fire('out');
    var payload = context.payload;
    payload.hoverGfx = null;
    payload.hover = null;
  } // life-cycle methods


  function cancel(restore) {
    var previousContext;

    if (!context) {
      return;
    }

    var wasActive = context.active;

    if (wasActive) {
      fire('cancel');
    }

    previousContext = cleanup(restore);

    if (wasActive) {
      // last event to be fired when all drag operations are done
      // at this point in time no drag operation is in progress anymore
      fire('canceled', previousContext);
    }
  }

  function cleanup(restore) {
    var previousContext, endDrag;
    fire('cleanup'); // reset cursor

    (0, _Cursor.unset)();

    if (context.trapClick) {
      endDrag = trapClickAndEnd;
    } else {
      endDrag = end;
    } // reset dom listeners


    _minDom.event.unbind(document, 'mousemove', move);

    _minDom.event.unbind(document, 'dragstart', preventDefault);

    _minDom.event.unbind(document, 'selectstart', preventDefault);

    _minDom.event.unbind(document, 'mousedown', endDrag, true);

    _minDom.event.unbind(document, 'mouseup', endDrag, true);

    _minDom.event.unbind(document, 'keyup', checkCancel);

    _minDom.event.unbind(document, 'touchstart', trapTouch, true);

    _minDom.event.unbind(document, 'touchcancel', cancel, true);

    _minDom.event.unbind(document, 'touchmove', move, true);

    _minDom.event.unbind(document, 'touchend', end, true);

    eventBus.off('element.hover', hover);
    eventBus.off('element.out', out); // remove drag marker on root element

    canvas.removeMarker(canvas.getRootElement(), DRAG_ACTIVE_CLS); // restore selection, unless it has changed

    var previousSelection = context.payload.previousSelection;

    if (restore !== false && previousSelection && !selection.get().length) {
      restoreSelection(previousSelection);
    }

    previousContext = context;
    context = null;
    return previousContext;
  }
  /**
   * Initialize a drag operation.
   *
   * If `localPosition` is given, drag events will be emitted
   * relative to it.
   *
   * @param {MouseEvent|TouchEvent} [event]
   * @param {Point} [localPosition] actual diagram local position this drag operation should start at
   * @param {string} prefix
   * @param {Object} [options]
   */


  function init(event, relativeTo, prefix, options) {
    // only one drag operation may be active, at a time
    if (context) {
      cancel(false);
    }

    if (typeof relativeTo === 'string') {
      options = prefix;
      prefix = relativeTo;
      relativeTo = null;
    }

    options = (0, _minDash.assign)({}, defaultOptions, options || {});
    var data = options.data || {},
        originalEvent,
        globalStart,
        localStart,
        endDrag,
        isTouch;

    if (options.trapClick) {
      endDrag = trapClickAndEnd;
    } else {
      endDrag = end;
    }

    if (event) {
      originalEvent = (0, _Event.getOriginal)(event) || event;
      globalStart = (0, _Event.toPoint)(event);
      (0, _Event.stopPropagation)(event); // prevent default browser dragging behavior

      if (originalEvent.type === 'dragstart') {
        preventDefault(originalEvent);
      }
    } else {
      originalEvent = null;
      globalStart = {
        x: 0,
        y: 0
      };
    }

    localStart = toLocalPoint(globalStart);

    if (!relativeTo) {
      relativeTo = localStart;
    }

    isTouch = isTouchEvent(originalEvent);
    context = (0, _minDash.assign)({
      prefix: prefix,
      data: data,
      payload: {},
      globalStart: globalStart,
      displacement: (0, _PositionUtil.delta)(relativeTo, localStart),
      localStart: localStart,
      isTouch: isTouch
    }, options); // skip dom registration if trigger
    // is set to manual (during testing)

    if (!options.manual) {
      // add dom listeners
      if (isTouch) {
        _minDom.event.bind(document, 'touchstart', trapTouch, true);

        _minDom.event.bind(document, 'touchcancel', cancel, true);

        _minDom.event.bind(document, 'touchmove', move, true);

        _minDom.event.bind(document, 'touchend', end, true);
      } else {
        // assume we use the mouse to interact per default
        _minDom.event.bind(document, 'mousemove', move); // prevent default browser drag and text selection behavior


        _minDom.event.bind(document, 'dragstart', preventDefault);

        _minDom.event.bind(document, 'selectstart', preventDefault);

        _minDom.event.bind(document, 'mousedown', endDrag, true);

        _minDom.event.bind(document, 'mouseup', endDrag, true);
      }

      _minDom.event.bind(document, 'keyup', checkCancel);

      eventBus.on('element.hover', hover);
      eventBus.on('element.out', out);
    }

    fire('init');

    if (options.autoActivate) {
      move(event, true);
    }
  } // cancel on diagram destruction


  eventBus.on('diagram.destroy', cancel); // API

  this.init = init;
  this.move = move;
  this.hover = hover;
  this.out = out;
  this.end = end;
  this.cancel = cancel; // for introspection

  this.context = function () {
    return context;
  };

  this.setOptions = function (options) {
    (0, _minDash.assign)(defaultOptions, options);
  };
}

Dragging.$inject = ['eventBus', 'canvas', 'selection', 'elementRegistry'];

},{"../../util/ClickTrap":312,"../../util/Cursor":314,"../../util/Event":317,"../../util/PositionUtil":325,"min-dash":555,"min-dom":556}],196:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = HoverFix;

var _minDom = require("min-dom");

var _Event = require("../../util/Event");

var HIGH_PRIORITY = 1500;
/**
 * Browsers may swallow certain events (hover, out ...) if users are to
 * fast with the mouse.
 *
 * @see http://stackoverflow.com/questions/7448468/why-cant-i-reliably-capture-a-mouseout-event
 *
 * The fix implemented in this component ensure that we
 *
 * 1) have a hover state after a successful drag.move event
 * 2) have an out event when dragging leaves an element
 *
 * @param {EventBus} eventBus
 * @param {Dragging} dragging
 * @param {ElementRegistry} elementRegistry
 */

function HoverFix(eventBus, dragging, elementRegistry) {
  var self = this;
  /**
   * Make sure we are god damn hovering!
   *
   * @param {Event} dragging event
   */

  function ensureHover(event) {
    if (event.hover) {
      return;
    }

    var originalEvent = event.originalEvent;

    var gfx = self._findTargetGfx(originalEvent);

    var element = gfx && elementRegistry.get(gfx);

    if (gfx && element) {
      // 1) cancel current mousemove
      event.stopPropagation(); // 2) emit fake hover for new target

      dragging.hover({
        element: element,
        gfx: gfx
      }); // 3) re-trigger move event

      dragging.move(originalEvent);
    }
  }
  /**
   * We wait for a specific sequence of events before
   * emitting a fake drag.hover event.
   *
   * Event Sequence:
   *
   * drag.start
   * drag.move >> ensure we are hovering
   */


  eventBus.on('drag.start', function (event) {
    eventBus.once('drag.move', HIGH_PRIORITY, function (event) {
      ensureHover(event);
    });
  });
  /**
   * We make sure that drag.out is always fired, even if the
   * browser swallows an element.out event.
   *
   * Event sequence:
   *
   * drag.hover
   * (element.out >> sometimes swallowed)
   * element.hover >> ensure we fired drag.out
   */

  eventBus.on('drag.init', function () {
    var hover, hoverGfx;

    function setDragHover(event) {
      hover = event.hover;
      hoverGfx = event.hoverGfx;
    }

    function unsetHover() {
      hover = null;
      hoverGfx = null;
    }

    function ensureOut() {
      if (!hover) {
        return;
      }

      var element = hover,
          gfx = hoverGfx;
      hover = null;
      hoverGfx = null; // emit synthetic out event

      dragging.out({
        element: element,
        gfx: gfx
      });
    }

    eventBus.on('drag.hover', setDragHover);
    eventBus.on('element.out', unsetHover);
    eventBus.on('element.hover', HIGH_PRIORITY, ensureOut);
    eventBus.once('drag.cleanup', function () {
      eventBus.off('drag.hover', setDragHover);
      eventBus.off('element.out', unsetHover);
      eventBus.off('element.hover', ensureOut);
    });
  });

  this._findTargetGfx = function (event) {
    var position, target;

    if (!(event instanceof MouseEvent)) {
      return;
    }

    position = (0, _Event.toPoint)(event); // damn expensive operation, ouch!

    target = document.elementFromPoint(position.x, position.y);
    return getGfx(target);
  };
}

HoverFix.$inject = ['eventBus', 'dragging', 'elementRegistry']; // helpers /////////////////////

function getGfx(target) {
  return (0, _minDom.closest)(target, 'svg, .djs-element', true);
}

},{"../../util/Event":317,"min-dom":556}],197:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _selection = _interopRequireDefault(require("../selection"));

var _Dragging = _interopRequireDefault(require("./Dragging"));

var _HoverFix = _interopRequireDefault(require("./HoverFix"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['hoverFix'],
  __depends__: [_selection.default],
  dragging: ['type', _Dragging.default],
  hoverFix: ['type', _HoverFix.default]
};
exports.default = _default;

},{"../selection":278,"./Dragging":195,"./HoverFix":196}],198:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = EditorActions;

var _minDash = require("min-dash");

var NOT_REGISTERED_ERROR = 'is not a registered action',
    IS_REGISTERED_ERROR = 'is already registered';
/**
 * An interface that provides access to modeling actions by decoupling
 * the one who requests the action to be triggered and the trigger itself.
 *
 * It's possible to add new actions by registering them with ´registerAction´
 * and likewise unregister existing ones with ´unregisterAction´.
 *
 *
 * ## Life-Cycle and configuration
 *
 * The editor actions will wait for diagram initialization before
 * registering default actions _and_ firing an `editorActions.init` event.
 *
 * Interested parties may listen to the `editorActions.init` event with
 * low priority to check, which actions got registered. Other components
 * may use the event to register their own actions via `registerAction`.
 *
 * @param {EventBus} eventBus
 * @param {Injector} injector
 */

function EditorActions(eventBus, injector) {
  // initialize actions
  this._actions = {};
  var self = this;
  eventBus.on('diagram.init', function () {
    // all diagram modules got loaded; check which ones
    // are available and register the respective default actions
    self._registerDefaultActions(injector); // ask interested parties to register available editor
    // actions on diagram initialization


    eventBus.fire('editorActions.init', {
      editorActions: self
    });
  });
}

EditorActions.$inject = ['eventBus', 'injector'];
/**
 * Register default actions.
 *
 * @param {Injector} injector
 */

EditorActions.prototype._registerDefaultActions = function (injector) {
  // (1) retrieve optional components to integrate with
  var commandStack = injector.get('commandStack', false);
  var modeling = injector.get('modeling', false);
  var selection = injector.get('selection', false);
  var zoomScroll = injector.get('zoomScroll', false);
  var copyPaste = injector.get('copyPaste', false);
  var canvas = injector.get('canvas', false);
  var rules = injector.get('rules', false);
  var keyboardMove = injector.get('keyboardMove', false);
  var keyboardMoveSelection = injector.get('keyboardMoveSelection', false); // (2) check components and register actions

  if (commandStack) {
    this.register('undo', function () {
      commandStack.undo();
    });
    this.register('redo', function () {
      commandStack.redo();
    });
  }

  if (copyPaste && selection) {
    this.register('copy', function () {
      var selectedElements = selection.get();
      copyPaste.copy(selectedElements);
    });
  }

  if (copyPaste) {
    this.register('paste', function () {
      copyPaste.paste();
    });
  }

  if (zoomScroll) {
    this.register('stepZoom', function (opts) {
      zoomScroll.stepZoom(opts.value);
    });
  }

  if (canvas) {
    this.register('zoom', function (opts) {
      canvas.zoom(opts.value);
    });
  }

  if (modeling && selection && rules) {
    this.register('removeSelection', function () {
      var selectedElements = selection.get();

      if (!selectedElements.length) {
        return;
      }

      var allowed = rules.allowed('elements.delete', {
        elements: selectedElements
      }),
          removableElements;

      if (allowed === false) {
        return;
      } else if ((0, _minDash.isArray)(allowed)) {
        removableElements = allowed;
      } else {
        removableElements = selectedElements;
      }

      if (removableElements.length) {
        modeling.removeElements(removableElements.slice());
      }
    });
  }

  if (keyboardMove) {
    this.register('moveCanvas', function (opts) {
      keyboardMove.moveCanvas(opts);
    });
  }

  if (keyboardMoveSelection) {
    this.register('moveSelection', function (opts) {
      keyboardMoveSelection.moveSelection(opts.direction, opts.accelerated);
    });
  }
};
/**
 * Triggers a registered action
 *
 * @param  {string} action
 * @param  {Object} opts
 *
 * @return {Unknown} Returns what the registered listener returns
 */


EditorActions.prototype.trigger = function (action, opts) {
  if (!this._actions[action]) {
    throw error(action, NOT_REGISTERED_ERROR);
  }

  return this._actions[action](opts);
};
/**
 * Registers a collections of actions.
 * The key of the object will be the name of the action.
 *
 * @example
 * ´´´
 * var actions = {
 *   spaceTool: function() {
 *     spaceTool.activateSelection();
 *   },
 *   lassoTool: function() {
 *     lassoTool.activateSelection();
 *   }
 * ];
 *
 * editorActions.register(actions);
 *
 * editorActions.isRegistered('spaceTool'); // true
 * ´´´
 *
 * @param  {Object} actions
 */


EditorActions.prototype.register = function (actions, listener) {
  var self = this;

  if (typeof actions === 'string') {
    return this._registerAction(actions, listener);
  }

  (0, _minDash.forEach)(actions, function (listener, action) {
    self._registerAction(action, listener);
  });
};
/**
 * Registers a listener to an action key
 *
 * @param  {string} action
 * @param  {Function} listener
 */


EditorActions.prototype._registerAction = function (action, listener) {
  if (this.isRegistered(action)) {
    throw error(action, IS_REGISTERED_ERROR);
  }

  this._actions[action] = listener;
};
/**
 * Unregister an existing action
 *
 * @param {string} action
 */


EditorActions.prototype.unregister = function (action) {
  if (!this.isRegistered(action)) {
    throw error(action, NOT_REGISTERED_ERROR);
  }

  this._actions[action] = undefined;
};
/**
 * Returns the number of actions that are currently registered
 *
 * @return {number}
 */


EditorActions.prototype.getActions = function () {
  return Object.keys(this._actions);
};
/**
 * Checks wether the given action is registered
 *
 * @param {string} action
 *
 * @return {boolean}
 */


EditorActions.prototype.isRegistered = function (action) {
  return !!this._actions[action];
};

function error(action, message) {
  return new Error(action + ' ' + message);
}

},{"min-dash":555}],199:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _EditorActions = _interopRequireDefault(require("./EditorActions"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['editorActions'],
  editorActions: ['type', _EditorActions.default]
};
exports.default = _default;

},{"./EditorActions":198}],200:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = GlobalConnect;
var MARKER_OK = 'connect-ok',
    MARKER_NOT_OK = 'connect-not-ok';
/**
 * @class
 * @constructor
 *
 * @param {EventBus} eventBus
 * @param {Dragging} dragging
 * @param {Connect} connect
 * @param {Canvas} canvas
 * @param {ToolManager} toolManager
 * @param {Rules} rules
 */

function GlobalConnect(eventBus, dragging, connect, canvas, toolManager, rules) {
  var self = this;
  this._dragging = dragging;
  this._rules = rules;
  toolManager.registerTool('global-connect', {
    tool: 'global-connect',
    dragging: 'global-connect.drag'
  });
  eventBus.on('global-connect.hover', function (event) {
    var context = event.context,
        startTarget = event.hover;
    var canStartConnect = context.canStartConnect = self.canStartConnect(startTarget); // simply ignore hover

    if (canStartConnect === null) {
      return;
    }

    context.startTarget = startTarget;
    canvas.addMarker(startTarget, canStartConnect ? MARKER_OK : MARKER_NOT_OK);
  });
  eventBus.on(['global-connect.out', 'global-connect.cleanup'], function (event) {
    var startTarget = event.context.startTarget,
        canStartConnect = event.context.canStartConnect;

    if (startTarget) {
      canvas.removeMarker(startTarget, canStartConnect ? MARKER_OK : MARKER_NOT_OK);
    }
  });
  eventBus.on(['global-connect.ended'], function (event) {
    var context = event.context,
        startTarget = context.startTarget,
        startPosition = {
      x: event.x,
      y: event.y
    };
    var canStartConnect = self.canStartConnect(startTarget);

    if (!canStartConnect) {
      return;
    }

    eventBus.once('element.out', function () {
      eventBus.once(['connect.ended', 'connect.canceled'], function () {
        eventBus.fire('global-connect.drag.ended');
      });
      connect.start(null, startTarget, startPosition);
    });
    return false;
  });
}

GlobalConnect.$inject = ['eventBus', 'dragging', 'connect', 'canvas', 'toolManager', 'rules'];
/**
 * Initiates tool activity.
 */

GlobalConnect.prototype.start = function (event) {
  this._dragging.init(event, 'global-connect', {
    trapClick: false,
    data: {
      context: {}
    }
  });
};

GlobalConnect.prototype.toggle = function () {
  if (this.isActive()) {
    this._dragging.cancel();
  } else {
    this.start();
  }
};

GlobalConnect.prototype.isActive = function () {
  var context = this._dragging.context();

  return context && /^global-connect/.test(context.prefix);
};
/**
 * Check if source shape can initiate connection.
 *
 * @param  {Shape} startTarget
 * @return {boolean}
 */


GlobalConnect.prototype.canStartConnect = function (startTarget) {
  return this._rules.allowed('connection.start', {
    source: startTarget
  });
};

},{}],201:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _connect = _interopRequireDefault(require("../connect"));

var _rules = _interopRequireDefault(require("../rules"));

var _dragging = _interopRequireDefault(require("../dragging"));

var _toolManager = _interopRequireDefault(require("../tool-manager"));

var _GlobalConnect = _interopRequireDefault(require("./GlobalConnect"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_connect.default, _rules.default, _dragging.default, _toolManager.default],
  globalConnect: ['type', _GlobalConnect.default]
};
exports.default = _default;

},{"../connect":183,"../dragging":197,"../rules":272,"../tool-manager":290,"./GlobalConnect":200}],202:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = GridSnapping;

var _SnapUtil = require("../snapping/SnapUtil");

var _KeyboardUtil = require("../keyboard/KeyboardUtil");

var _minDash = require("min-dash");

var _GridUtil = require("./GridUtil");

var LOWER_PRIORITY = 1200;
var LOW_PRIORITY = 800;
/**
 * Basic grid snapping that covers connecting, creating, moving, resizing shapes, moving bendpoints
 * and connection segments.
 */

function GridSnapping(elementRegistry, eventBus, config) {
  var active = !config || config.active !== false;
  this._eventBus = eventBus;
  var self = this;
  eventBus.on('diagram.init', LOW_PRIORITY, function () {
    self.setActive(active);
  });
  eventBus.on(['create.move', 'create.end', 'bendpoint.move.move', 'bendpoint.move.end', 'connect.move', 'connect.end', 'connectionSegment.move.move', 'connectionSegment.move.end', 'resize.move', 'resize.end', 'shape.move.move', 'shape.move.end'], LOWER_PRIORITY, function (event) {
    var originalEvent = event.originalEvent;

    if (!self.active || originalEvent && (0, _KeyboardUtil.isCmd)(originalEvent)) {
      return;
    }

    var context = event.context,
        gridSnappingContext = context.gridSnappingContext;

    if (!gridSnappingContext) {
      gridSnappingContext = context.gridSnappingContext = {};
    }

    ['x', 'y'].forEach(function (axis) {
      var options = {}; // allow snapping with offset

      var snapOffset = getSnapOffset(event, axis, elementRegistry);

      if (snapOffset) {
        options.offset = snapOffset;
      } // allow snapping with min and max


      var snapConstraints = getSnapConstraints(event, axis);

      if (snapConstraints) {
        (0, _minDash.assign)(options, snapConstraints);
      }

      if (!(0, _SnapUtil.isSnapped)(event, axis)) {
        self.snapEvent(event, axis, options);
      }
    });
  });
}
/**
 * Snap an events x or y with optional min, max and offset.
 *
 * @param {Object} event
 * @param {string} axis
 * @param {number} [options.min]
 * @param {number} [options.max]
 * @param {number} [options.offset]
 */


GridSnapping.prototype.snapEvent = function (event, axis, options) {
  var snappedValue = this.snapValue(event[axis], options);
  (0, _SnapUtil.setSnapped)(event, axis, snappedValue);
};
/**
 * Expose grid spacing for third parties (i.e. extensions).
 *
 * @return {number} spacing of grid dots
 */


GridSnapping.prototype.getGridSpacing = function () {
  return _GridUtil.SPACING;
};
/**
 * Snap value with optional min, max and offset.
 *
 * @param {number} value
 * @param {Object} options
 * @param {number} [options.min]
 * @param {number} [options.max]
 * @param {number} [options.offset]
 */


GridSnapping.prototype.snapValue = function (value, options) {
  var offset = 0;

  if (options && options.offset) {
    offset = options.offset;
  }

  value += offset;
  value = (0, _GridUtil.quantize)(value, _GridUtil.SPACING);
  var min, max;

  if (options && options.min) {
    min = options.min;

    if ((0, _minDash.isNumber)(min)) {
      min = (0, _GridUtil.quantize)(min + offset, _GridUtil.SPACING, 'ceil');
      value = Math.max(value, min);
    }
  }

  if (options && options.max) {
    max = options.max;

    if ((0, _minDash.isNumber)(max)) {
      max = (0, _GridUtil.quantize)(max + offset, _GridUtil.SPACING, 'floor');
      value = Math.min(value, max);
    }
  }

  value -= offset;
  return value;
};

GridSnapping.prototype.isActive = function () {
  return this.active;
};

GridSnapping.prototype.setActive = function (active) {
  this.active = active;

  this._eventBus.fire('gridSnapping.toggle', {
    active: active
  });
};

GridSnapping.prototype.toggleActive = function () {
  this.setActive(!this.active);
};

GridSnapping.$inject = ['elementRegistry', 'eventBus', 'config.gridSnapping']; // helpers //////////

/**
 * Get minimum and maximum snap constraints.
 * Constraints are cached.
 *
 * @param {Object} event
 * @param {Object} event.context
 * @param {string} axis
 *
 * @returns {boolean|Object}
 */

function getSnapConstraints(event, axis) {
  var context = event.context,
      createConstraints = context.createConstraints,
      resizeConstraints = context.resizeConstraints || {},
      gridSnappingContext = context.gridSnappingContext,
      snapConstraints = gridSnappingContext.snapConstraints; // cache snap constraints

  if (snapConstraints && snapConstraints[axis]) {
    return snapConstraints[axis];
  }

  if (!snapConstraints) {
    snapConstraints = gridSnappingContext.snapConstraints = {};
  }

  if (!snapConstraints[axis]) {
    snapConstraints[axis] = {};
  }

  var direction = context.direction; // create

  if (createConstraints) {
    if (isHorizontal(axis)) {
      snapConstraints.x.min = createConstraints.left;
      snapConstraints.x.max = createConstraints.right;
    } else {
      snapConstraints.y.min = createConstraints.top;
      snapConstraints.y.max = createConstraints.bottom;
    }
  } // resize


  var minResizeConstraints = resizeConstraints.min,
      maxResizeConstraints = resizeConstraints.max;

  if (minResizeConstraints) {
    if (isHorizontal(axis)) {
      if (isWest(direction)) {
        snapConstraints.x.max = minResizeConstraints.left;
      } else {
        snapConstraints.x.min = minResizeConstraints.right;
      }
    } else {
      if (isNorth(direction)) {
        snapConstraints.y.max = minResizeConstraints.top;
      } else {
        snapConstraints.y.min = minResizeConstraints.bottom;
      }
    }
  }

  if (maxResizeConstraints) {
    if (isHorizontal(axis)) {
      if (isWest(direction)) {
        snapConstraints.x.min = maxResizeConstraints.left;
      } else {
        snapConstraints.x.max = maxResizeConstraints.right;
      }
    } else {
      if (isNorth(direction)) {
        snapConstraints.y.min = maxResizeConstraints.top;
      } else {
        snapConstraints.y.max = maxResizeConstraints.bottom;
      }
    }
  }

  return snapConstraints[axis];
}
/**
 * Get snap offset.
 * Offset is cached.
 *
 * @param {Object} event
 * @param {string} axis
 * @param {ElementRegistry} elementRegistry
 *
 * @returns {number}
 */


function getSnapOffset(event, axis, elementRegistry) {
  var context = event.context,
      shape = event.shape,
      gridSnappingContext = context.gridSnappingContext,
      snapLocation = gridSnappingContext.snapLocation,
      snapOffset = gridSnappingContext.snapOffset; // cache snap offset

  if (snapOffset && (0, _minDash.isNumber)(snapOffset[axis])) {
    return snapOffset[axis];
  }

  if (!snapOffset) {
    snapOffset = gridSnappingContext.snapOffset = {};
  }

  if (!(0, _minDash.isNumber)(snapOffset[axis])) {
    snapOffset[axis] = 0;
  }

  if (!shape) {
    return snapOffset[axis];
  }

  if (!elementRegistry.get(shape.id)) {
    if (isHorizontal(axis)) {
      snapOffset[axis] += shape[axis] + shape.width / 2;
    } else {
      snapOffset[axis] += shape[axis] + shape.height / 2;
    }
  }

  if (!snapLocation) {
    return snapOffset[axis];
  }

  if (axis === 'x') {
    if (/left/.test(snapLocation)) {
      snapOffset[axis] -= shape.width / 2;
    } else if (/right/.test(snapLocation)) {
      snapOffset[axis] += shape.width / 2;
    }
  } else {
    if (/top/.test(snapLocation)) {
      snapOffset[axis] -= shape.height / 2;
    } else if (/bottom/.test(snapLocation)) {
      snapOffset[axis] += shape.height / 2;
    }
  }

  return snapOffset[axis];
}

function isHorizontal(axis) {
  return axis === 'x';
}

function isNorth(direction) {
  return direction.indexOf('n') !== -1;
}

function isWest(direction) {
  return direction.indexOf('w') !== -1;
}

},{"../keyboard/KeyboardUtil":216,"../snapping/SnapUtil":282,"./GridUtil":203,"min-dash":555}],203:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.quantize = quantize;
exports.SPACING = void 0;
var SPACING = 10;
exports.SPACING = SPACING;

function quantize(value, quantum, fn) {
  if (!fn) {
    fn = 'round';
  }

  return Math[fn](value / quantum) * quantum;
}

},{}],204:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ResizeBehavior;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("../../../command/CommandInterceptor"));

var _minDash = require("min-dash");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Integrates resizing with grid snapping.
 */
function ResizeBehavior(eventBus, gridSnapping) {
  _CommandInterceptor.default.call(this, eventBus);

  this._gridSnapping = gridSnapping;
  var self = this;
  this.preExecute('shape.resize', function (event) {
    var context = event.context,
        hints = context.hints || {},
        autoResize = hints.autoResize;

    if (!autoResize) {
      return;
    }

    var shape = context.shape,
        newBounds = context.newBounds;

    if ((0, _minDash.isString)(autoResize)) {
      context.newBounds = self.snapComplex(newBounds, autoResize);
    } else {
      context.newBounds = self.snapSimple(shape, newBounds);
    }
  });
}

ResizeBehavior.$inject = ['eventBus', 'gridSnapping', 'modeling'];
(0, _inherits.default)(ResizeBehavior, _CommandInterceptor.default);
/**
 * Snap width and height in relation to center.
 *
 * @param {djs.model.shape} shape
 * @param {Bounds} newBounds
 *
 * @returns {Bounds} Snapped bounds.
 */

ResizeBehavior.prototype.snapSimple = function (shape, newBounds) {
  var gridSnapping = this._gridSnapping;
  newBounds.width = gridSnapping.snapValue(newBounds.width, {
    min: newBounds.width
  });
  newBounds.height = gridSnapping.snapValue(newBounds.height, {
    min: newBounds.height
  });
  newBounds.x = shape.x + shape.width / 2 - newBounds.width / 2;
  newBounds.y = shape.y + shape.height / 2 - newBounds.height / 2;
  return newBounds;
};
/**
 * Snap x, y, width and height according to given directions.
 *
 * @param {Bounds} newBounds
 * @param {string} directions - Directions as {n|w|s|e}.
 *
 * @returns {Bounds} Snapped bounds.
 */


ResizeBehavior.prototype.snapComplex = function (newBounds, directions) {
  if (/w|e/.test(directions)) {
    newBounds = this.snapHorizontally(newBounds, directions);
  }

  if (/n|s/.test(directions)) {
    newBounds = this.snapVertically(newBounds, directions);
  }

  return newBounds;
};
/**
 * Snap in one or both directions horizontally.
 *
 * @param {Bounds} newBounds
 * @param {string} directions - Directions as {n|w|s|e}.
 *
 * @returns {Bounds} Snapped bounds.
 */


ResizeBehavior.prototype.snapHorizontally = function (newBounds, directions) {
  var gridSnapping = this._gridSnapping,
      west = /w/.test(directions),
      east = /e/.test(directions);
  var snappedNewBounds = {};
  snappedNewBounds.width = gridSnapping.snapValue(newBounds.width, {
    min: newBounds.width
  });

  if (east) {
    // handle <we>
    if (west) {
      snappedNewBounds.x = gridSnapping.snapValue(newBounds.x, {
        max: newBounds.x
      });
      snappedNewBounds.width += gridSnapping.snapValue(newBounds.x - snappedNewBounds.x, {
        min: newBounds.x - snappedNewBounds.x
      });
    } // handle <e>
    else {
        newBounds.x = newBounds.x + newBounds.width - snappedNewBounds.width;
      }
  } // assign snapped x and width


  (0, _minDash.assign)(newBounds, snappedNewBounds);
  return newBounds;
};
/**
 * Snap in one or both directions vertically.
 *
 * @param {Bounds} newBounds
 * @param {string} directions - Directions as {n|w|s|e}.
 *
 * @returns {Bounds} Snapped bounds.
 */


ResizeBehavior.prototype.snapVertically = function (newBounds, directions) {
  var gridSnapping = this._gridSnapping,
      north = /n/.test(directions),
      south = /s/.test(directions);
  var snappedNewBounds = {};
  snappedNewBounds.height = gridSnapping.snapValue(newBounds.height, {
    min: newBounds.height
  });

  if (north) {
    // handle <ns>
    if (south) {
      snappedNewBounds.y = gridSnapping.snapValue(newBounds.y, {
        max: newBounds.y
      });
      snappedNewBounds.height += gridSnapping.snapValue(newBounds.y - snappedNewBounds.y, {
        min: newBounds.y - snappedNewBounds.y
      });
    } // handle <n>
    else {
        newBounds.y = newBounds.y + newBounds.height - snappedNewBounds.height;
      }
  } // assign snapped y and height


  (0, _minDash.assign)(newBounds, snappedNewBounds);
  return newBounds;
};

},{"../../../command/CommandInterceptor":145,"inherits":347,"min-dash":555}],205:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SpaceToolBehavior;
var HIGH_PRIORITY = 2000;
/**
 * Integrates space tool with grid snapping.
 */

function SpaceToolBehavior(eventBus, gridSnapping) {
  eventBus.on(['spaceTool.move', 'spaceTool.end'], HIGH_PRIORITY, function (event) {
    var context = event.context;

    if (!context.initialized) {
      return;
    }

    var axis = context.axis;
    var snapped;

    if (axis === 'x') {
      // snap delta x to multiple of 10
      snapped = gridSnapping.snapValue(event.dx);
      event.x = event.x + snapped - event.dx;
      event.dx = snapped;
    } else {
      // snap delta y to multiple of 10
      snapped = gridSnapping.snapValue(event.dy);
      event.y = event.y + snapped - event.dy;
      event.dy = snapped;
    }
  });
}

SpaceToolBehavior.$inject = ['eventBus', 'gridSnapping'];

},{}],206:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _ResizeBehavior = _interopRequireDefault(require("./ResizeBehavior"));

var _SpaceToolBehavior = _interopRequireDefault(require("./SpaceToolBehavior"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['gridSnappingResizeBehavior', 'gridSnappingSpaceToolBehavior'],
  gridSnappingResizeBehavior: ['type', _ResizeBehavior.default],
  gridSnappingSpaceToolBehavior: ['type', _SpaceToolBehavior.default]
};
exports.default = _default;

},{"./ResizeBehavior":204,"./SpaceToolBehavior":205}],207:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _GridSnapping = _interopRequireDefault(require("./GridSnapping"));

var _behavior = _interopRequireDefault(require("./behavior"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_behavior.default],
  __init__: ['gridSnapping'],
  gridSnapping: ['type', _GridSnapping.default]
};
exports.default = _default;

},{"./GridSnapping":202,"./behavior":206}],208:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = HandTool;

var _Mouse = require("../../util/Mouse");

var _KeyboardUtil = require("../../features/keyboard/KeyboardUtil");

var HIGH_PRIORITY = 1500;
var HAND_CURSOR = 'grab';

function HandTool(eventBus, canvas, dragging, injector, toolManager) {
  this._dragging = dragging;
  var self = this,
      keyboard = injector.get('keyboard', false);
  toolManager.registerTool('hand', {
    tool: 'hand',
    dragging: 'hand.move'
  });
  eventBus.on('element.mousedown', HIGH_PRIORITY, function (event) {
    if ((0, _Mouse.hasPrimaryModifier)(event)) {
      this.activateMove(event.originalEvent);
      return false;
    }
  }, this);
  keyboard && keyboard.addListener(HIGH_PRIORITY, function (e) {
    if (!isSpace(e.keyEvent)) {
      return;
    }

    if (self.isActive()) {
      return;
    }

    function activateMove(event) {
      self.activateMove(event);
      window.removeEventListener('mousemove', activateMove);
    }

    window.addEventListener('mousemove', activateMove);

    function deactivateMove(e) {
      if (!isSpace(e.keyEvent)) {
        return;
      }

      window.removeEventListener('mousemove', activateMove);
      keyboard.removeListener(deactivateMove, 'keyboard.keyup');
      dragging.cancel();
    }

    keyboard.addListener(HIGH_PRIORITY, deactivateMove, 'keyboard.keyup');
  }, 'keyboard.keydown');
  eventBus.on('hand.end', function (event) {
    var target = event.originalEvent.target; // only reactive on diagram click
    // on some occasions, event.hover is not set and we have to check if the target is an svg

    if (!event.hover && !(target instanceof SVGElement)) {
      return false;
    }

    eventBus.once('hand.ended', function () {
      this.activateMove(event.originalEvent, {
        reactivate: true
      });
    }, this);
  }, this);
  eventBus.on('hand.move.move', function (event) {
    var scale = canvas.viewbox().scale;
    canvas.scroll({
      dx: event.dx * scale,
      dy: event.dy * scale
    });
  });
  eventBus.on('hand.move.end', function (event) {
    var context = event.context,
        reactivate = context.reactivate; // Don't reactivate if the user is using the keyboard keybinding

    if (!(0, _Mouse.hasPrimaryModifier)(event) && reactivate) {
      eventBus.once('hand.move.ended', function (event) {
        this.activateHand(event.originalEvent, true, true);
      }, this);
    }

    return false;
  }, this);
}

HandTool.$inject = ['eventBus', 'canvas', 'dragging', 'injector', 'toolManager'];

HandTool.prototype.activateMove = function (event, autoActivate, context) {
  if (typeof autoActivate === 'object') {
    context = autoActivate;
    autoActivate = false;
  }

  this._dragging.init(event, 'hand.move', {
    autoActivate: autoActivate,
    cursor: HAND_CURSOR,
    data: {
      context: context || {}
    }
  });
};

HandTool.prototype.activateHand = function (event, autoActivate, reactivate) {
  this._dragging.init(event, 'hand', {
    trapClick: false,
    autoActivate: autoActivate,
    cursor: HAND_CURSOR,
    data: {
      context: {
        reactivate: reactivate
      }
    }
  });
};

HandTool.prototype.toggle = function () {
  if (this.isActive()) {
    this._dragging.cancel();
  } else {
    this.activateHand();
  }
};

HandTool.prototype.isActive = function () {
  var context = this._dragging.context();

  if (context) {
    return /^(hand|hand\.move)$/.test(context.prefix);
  }

  return false;
}; // helpers //////////


function isSpace(keyEvent) {
  return (0, _KeyboardUtil.isKey)(' ', keyEvent);
}

},{"../../features/keyboard/KeyboardUtil":216,"../../util/Mouse":323}],209:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _toolManager = _interopRequireDefault(require("../tool-manager"));

var _HandTool = _interopRequireDefault(require("./HandTool"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_toolManager.default],
  __init__: ['handTool'],
  handTool: ['type', _HandTool.default]
};
exports.default = _default;

},{"../tool-manager":290,"./HandTool":208}],210:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = InteractionEvents;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _Mouse = require("../../util/Mouse");

var _tinySvg = require("tiny-svg");

var _RenderUtil = require("../../util/RenderUtil");

function allowAll(e) {
  return true;
}

var LOW_PRIORITY = 500;
/**
 * A plugin that provides interaction events for diagram elements.
 *
 * It emits the following events:
 *
 *   * element.click
 *   * element.contextmenu
 *   * element.dblclick
 *   * element.hover
 *   * element.mousedown
 *   * element.mousemove
 *   * element.mouseup
 *   * element.out
 *
 * Each event is a tuple { element, gfx, originalEvent }.
 *
 * Canceling the event via Event#preventDefault()
 * prevents the original DOM operation.
 *
 * @param {EventBus} eventBus
 */

function InteractionEvents(eventBus, elementRegistry, styles) {
  var self = this;
  /**
   * Fire an interaction event.
   *
   * @param {string} type local event name, e.g. element.click.
   * @param {DOMEvent} event native event
   * @param {djs.model.Base} [element] the diagram element to emit the event on;
   *                                   defaults to the event target
   */

  function fire(type, event, element) {
    if (isIgnored(type, event)) {
      return;
    }

    var target, gfx, returnValue;

    if (!element) {
      target = event.delegateTarget || event.target;

      if (target) {
        gfx = target;
        element = elementRegistry.get(gfx);
      }
    } else {
      gfx = elementRegistry.getGraphics(element);
    }

    if (!gfx || !element) {
      return;
    }

    returnValue = eventBus.fire(type, {
      element: element,
      gfx: gfx,
      originalEvent: event
    });

    if (returnValue === false) {
      event.stopPropagation();
      event.preventDefault();
    }
  } // TODO(nikku): document this


  var handlers = {};

  function mouseHandler(localEventName) {
    return handlers[localEventName];
  }

  function isIgnored(localEventName, event) {
    var filter = ignoredFilters[localEventName] || _Mouse.isPrimaryButton; // only react on left mouse button interactions
    // except for interaction events that are enabled
    // for secundary mouse button

    return !filter(event);
  }

  var bindings = {
    click: 'element.click',
    contextmenu: 'element.contextmenu',
    dblclick: 'element.dblclick',
    mousedown: 'element.mousedown',
    mousemove: 'element.mousemove',
    mouseover: 'element.hover',
    mouseout: 'element.out',
    mouseup: 'element.mouseup'
  };
  var ignoredFilters = {
    'element.contextmenu': allowAll
  }; // manual event trigger //////////

  /**
   * Trigger an interaction event (based on a native dom event)
   * on the target shape or connection.
   *
   * @param {string} eventName the name of the triggered DOM event
   * @param {MouseEvent} event
   * @param {djs.model.Base} targetElement
   */

  function triggerMouseEvent(eventName, event, targetElement) {
    // i.e. element.mousedown...
    var localEventName = bindings[eventName];

    if (!localEventName) {
      throw new Error('unmapped DOM event name <' + eventName + '>');
    }

    return fire(localEventName, event, targetElement);
  }

  var ELEMENT_SELECTOR = 'svg, .djs-element'; // event handling ///////

  function registerEvent(node, event, localEvent, ignoredFilter) {
    var handler = handlers[localEvent] = function (event) {
      fire(localEvent, event);
    };

    if (ignoredFilter) {
      ignoredFilters[localEvent] = ignoredFilter;
    }

    handler.$delegate = _minDom.delegate.bind(node, ELEMENT_SELECTOR, event, handler);
  }

  function unregisterEvent(node, event, localEvent) {
    var handler = mouseHandler(localEvent);

    if (!handler) {
      return;
    }

    _minDom.delegate.unbind(node, event, handler.$delegate);
  }

  function registerEvents(svg) {
    (0, _minDash.forEach)(bindings, function (val, key) {
      registerEvent(svg, key, val);
    });
  }

  function unregisterEvents(svg) {
    (0, _minDash.forEach)(bindings, function (val, key) {
      unregisterEvent(svg, key, val);
    });
  }

  eventBus.on('canvas.destroy', function (event) {
    unregisterEvents(event.svg);
  });
  eventBus.on('canvas.init', function (event) {
    registerEvents(event.svg);
  }); // hit box updating ////////////////

  eventBus.on(['shape.added', 'connection.added'], function (event) {
    var element = event.element,
        gfx = event.gfx;
    eventBus.fire('interactionEvents.createHit', {
      element: element,
      gfx: gfx
    });
  }); // Update djs-hit on change.
  // A low priortity is necessary, because djs-hit of labels has to be updated
  // after the label bounds have been updated in the renderer.

  eventBus.on(['shape.changed', 'connection.changed'], LOW_PRIORITY, function (event) {
    var element = event.element,
        gfx = event.gfx;
    eventBus.fire('interactionEvents.updateHit', {
      element: element,
      gfx: gfx
    });
  });
  eventBus.on('interactionEvents.createHit', LOW_PRIORITY, function (event) {
    var element = event.element,
        gfx = event.gfx;
    self.createDefaultHit(element, gfx);
  });
  eventBus.on('interactionEvents.updateHit', function (event) {
    var element = event.element,
        gfx = event.gfx;
    self.updateDefaultHit(element, gfx);
  }); // hit styles ////////////

  var STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-stroke');
  var CLICK_STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-click-stroke');
  var ALL_HIT_STYLE = createHitStyle('djs-hit djs-hit-all');
  var HIT_TYPES = {
    'all': ALL_HIT_STYLE,
    'click-stroke': CLICK_STROKE_HIT_STYLE,
    'stroke': STROKE_HIT_STYLE
  };

  function createHitStyle(classNames, attrs) {
    attrs = (0, _minDash.assign)({
      stroke: 'white',
      strokeWidth: 15
    }, attrs || {});
    return styles.cls(classNames, ['no-fill', 'no-border'], attrs);
  } // style helpers ///////////////


  function applyStyle(hit, type) {
    var attrs = HIT_TYPES[type];

    if (!attrs) {
      throw new Error('invalid hit type <' + type + '>');
    }

    (0, _tinySvg.attr)(hit, attrs);
    return hit;
  }

  function appendHit(gfx, hit) {
    (0, _tinySvg.append)(gfx, hit);
  } // API

  /**
   * Remove hints on the given graphics.
   *
   * @param {SVGElement} gfx
   */


  this.removeHits = function (gfx) {
    var hits = (0, _minDom.queryAll)('.djs-hit', gfx);
    (0, _minDash.forEach)(hits, _tinySvg.remove);
  };
  /**
   * Create default hit for the given element.
   *
   * @param {djs.model.Base} element
   * @param {SVGElement} gfx
   *
   * @return {SVGElement} created hit
   */


  this.createDefaultHit = function (element, gfx) {
    var waypoints = element.waypoints,
        isFrame = element.isFrame,
        boxType;

    if (waypoints) {
      return this.createWaypointsHit(gfx, waypoints);
    } else {
      boxType = isFrame ? 'stroke' : 'all';
      return this.createBoxHit(gfx, boxType, {
        width: element.width,
        height: element.height
      });
    }
  };
  /**
   * Create hits for the given waypoints.
   *
   * @param {SVGElement} gfx
   * @param {Array<Point>} waypoints
   *
   * @return {SVGElement}
   */


  this.createWaypointsHit = function (gfx, waypoints) {
    var hit = (0, _RenderUtil.createLine)(waypoints);
    applyStyle(hit, 'stroke');
    appendHit(gfx, hit);
    return hit;
  };
  /**
   * Create hits for a box.
   *
   * @param {SVGElement} gfx
   * @param {string} hitType
   * @param {Object} attrs
   *
   * @return {SVGElement}
   */


  this.createBoxHit = function (gfx, type, attrs) {
    attrs = (0, _minDash.assign)({
      x: 0,
      y: 0
    }, attrs);
    var hit = (0, _tinySvg.create)('rect');
    applyStyle(hit, type);
    (0, _tinySvg.attr)(hit, attrs);
    appendHit(gfx, hit);
    return hit;
  };
  /**
   * Update default hit of the element.
   *
   * @param  {djs.model.Base} element
   * @param  {SVGElement} gfx
   *
   * @return {SVGElement} updated hit
   */


  this.updateDefaultHit = function (element, gfx) {
    var hit = (0, _minDom.query)('.djs-hit', gfx);

    if (!hit) {
      return;
    }

    if (element.waypoints) {
      (0, _RenderUtil.updateLine)(hit, element.waypoints);
    } else {
      (0, _tinySvg.attr)(hit, {
        width: element.width,
        height: element.height
      });
    }

    return hit;
  };

  this.fire = fire;
  this.triggerMouseEvent = triggerMouseEvent;
  this.mouseHandler = mouseHandler;
  this.registerEvent = registerEvent;
  this.unregisterEvent = unregisterEvent;
}

InteractionEvents.$inject = ['eventBus', 'elementRegistry', 'styles'];
/**
 * An event indicating that the mouse hovered over an element
 *
 * @event element.hover
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has left an element
 *
 * @event element.out
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has clicked an element
 *
 * @event element.click
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has double clicked an element
 *
 * @event element.dblclick
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has gone down on an element.
 *
 * @event element.mousedown
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has gone up on an element.
 *
 * @event element.mouseup
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the context menu action is triggered
 * via mouse or touch controls.
 *
 * @event element.contextmenu
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

},{"../../util/Mouse":323,"../../util/RenderUtil":327,"min-dash":555,"min-dom":556,"tiny-svg":567}],211:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _InteractionEvents = _interopRequireDefault(require("./InteractionEvents"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['interactionEvents'],
  interactionEvents: ['type', _InteractionEvents.default]
};
exports.default = _default;

},{"./InteractionEvents":210}],212:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = KeyboardMoveSelection;

var _minDash = require("min-dash");

var DEFAULT_CONFIG = {
  moveSpeed: 1,
  moveSpeedAccelerated: 10
};
var HIGHER_PRIORITY = 1500;
var LEFT = 'left';
var UP = 'up';
var RIGHT = 'right';
var DOWN = 'down';
var KEY_TO_DIRECTION = {
  ArrowLeft: LEFT,
  Left: LEFT,
  ArrowUp: UP,
  Up: UP,
  ArrowRight: RIGHT,
  Right: RIGHT,
  ArrowDown: DOWN,
  Down: DOWN
};
var DIRECTIONS_DELTA = {
  left: function (speed) {
    return {
      x: -speed,
      y: 0
    };
  },
  up: function (speed) {
    return {
      x: 0,
      y: -speed
    };
  },
  right: function (speed) {
    return {
      x: speed,
      y: 0
    };
  },
  down: function (speed) {
    return {
      x: 0,
      y: speed
    };
  }
};
/**
 * Enables to move selection with keyboard arrows.
 * Use with Shift for modified speed (default=1, with Shift=10).
 * Pressed Cmd/Ctrl turns the feature off.
 *
 * @param {Object} config
 * @param {number} [config.moveSpeed=1]
 * @param {number} [config.moveSpeedAccelerated=10]
 * @param {Keyboard} keyboard
 * @param {Modeling} modeling
 * @param {Selection} selection
 */

function KeyboardMoveSelection(config, keyboard, modeling, rules, selection) {
  var self = this;
  this._config = (0, _minDash.assign)({}, DEFAULT_CONFIG, config || {});
  keyboard.addListener(HIGHER_PRIORITY, function (event) {
    var keyEvent = event.keyEvent;
    var direction = KEY_TO_DIRECTION[keyEvent.key];

    if (!direction) {
      return;
    }

    if (keyboard.isCmd(keyEvent)) {
      return;
    }

    var accelerated = keyboard.isShift(keyEvent);
    self.moveSelection(direction, accelerated);
    return true;
  });
  /**
   * Move selected elements in the given direction,
   * optionally specifying accelerated movement.
   *
   * @param {string} direction
   * @param {boolean} [accelerated=false]
   */

  this.moveSelection = function (direction, accelerated) {
    var selectedElements = selection.get();

    if (!selectedElements.length) {
      return;
    }

    var speed = this._config[accelerated ? 'moveSpeedAccelerated' : 'moveSpeed'];
    var delta = DIRECTIONS_DELTA[direction](speed);
    var canMove = rules.allowed('elements.move', {
      shapes: selectedElements
    });

    if (canMove) {
      modeling.moveElements(selectedElements, delta);
    }
  };
}

KeyboardMoveSelection.$inject = ['config.keyboardMoveSelection', 'keyboard', 'modeling', 'rules', 'selection'];

},{"min-dash":555}],213:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _keyboard = _interopRequireDefault(require("../keyboard"));

var _selection = _interopRequireDefault(require("../selection"));

var _KeyboardMoveSelection = _interopRequireDefault(require("./KeyboardMoveSelection"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_keyboard.default, _selection.default],
  __init__: ['keyboardMoveSelection'],
  keyboardMoveSelection: ['type', _KeyboardMoveSelection.default]
};
exports.default = _default;

},{"../keyboard":217,"../selection":278,"./KeyboardMoveSelection":212}],214:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Keyboard;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _KeyboardUtil = require("./KeyboardUtil");

var KEYDOWN_EVENT = 'keyboard.keydown',
    KEYUP_EVENT = 'keyboard.keyup';
var DEFAULT_PRIORITY = 1000;
/**
 * A keyboard abstraction that may be activated and
 * deactivated by users at will, consuming key events
 * and triggering diagram actions.
 *
 * For keys pressed down, keyboard fires `keyboard.keydown` event.
 * The event context contains one field which is `KeyboardEvent` event.
 *
 * The implementation fires the following key events that allow
 * other components to hook into key handling:
 *
 *  - keyboard.bind
 *  - keyboard.unbind
 *  - keyboard.init
 *  - keyboard.destroy
 *
 * All events contain one field which is node.
 *
 * A default binding for the keyboard may be specified via the
 * `keyboard.bindTo` configuration option.
 *
 * @param {Config} config
 * @param {EventBus} eventBus
 */

function Keyboard(config, eventBus) {
  var self = this;
  this._config = config || {};
  this._eventBus = eventBus;
  this._keydownHandler = this._keydownHandler.bind(this);
  this._keyupHandler = this._keyupHandler.bind(this); // properly clean dom registrations

  eventBus.on('diagram.destroy', function () {
    self._fire('destroy');

    self.unbind();
  });
  eventBus.on('diagram.init', function () {
    self._fire('init');
  });
  eventBus.on('attach', function () {
    if (config && config.bindTo) {
      self.bind(config.bindTo);
    }
  });
  eventBus.on('detach', function () {
    self.unbind();
  });
}

Keyboard.$inject = ['config.keyboard', 'eventBus'];

Keyboard.prototype._keydownHandler = function (event) {
  this._keyHandler(event, KEYDOWN_EVENT);
};

Keyboard.prototype._keyupHandler = function (event) {
  this._keyHandler(event, KEYUP_EVENT);
};

Keyboard.prototype._keyHandler = function (event, type) {
  var target = event.target,
      eventBusResult;

  if (isInput(target)) {
    return;
  }

  var context = {
    keyEvent: event
  };
  eventBusResult = this._eventBus.fire(type || KEYDOWN_EVENT, context);

  if (eventBusResult) {
    event.preventDefault();
  }
};

Keyboard.prototype.bind = function (node) {
  // make sure that the keyboard is only bound once to the DOM
  this.unbind();
  this._node = node; // bind key events

  _minDom.event.bind(node, 'keydown', this._keydownHandler, true);

  _minDom.event.bind(node, 'keyup', this._keyupHandler, true);

  this._fire('bind');
};

Keyboard.prototype.getBinding = function () {
  return this._node;
};

Keyboard.prototype.unbind = function () {
  var node = this._node;

  if (node) {
    this._fire('unbind'); // unbind key events


    _minDom.event.unbind(node, 'keydown', this._keydownHandler, true);

    _minDom.event.unbind(node, 'keyup', this._keyupHandler, true);
  }

  this._node = null;
};

Keyboard.prototype._fire = function (event) {
  this._eventBus.fire('keyboard.' + event, {
    node: this._node
  });
};
/**
 * Add a listener function that is notified with `KeyboardEvent` whenever
 * the keyboard is bound and the user presses a key. If no priority is
 * provided, the default value of 1000 is used.
 *
 * @param {number} [priority]
 * @param {Function} listener
 * @param {string} type
 */


Keyboard.prototype.addListener = function (priority, listener, type) {
  if ((0, _minDash.isFunction)(priority)) {
    type = listener;
    listener = priority;
    priority = DEFAULT_PRIORITY;
  }

  this._eventBus.on(type || KEYDOWN_EVENT, priority, listener);
};

Keyboard.prototype.removeListener = function (listener, type) {
  this._eventBus.off(type || KEYDOWN_EVENT, listener);
};

Keyboard.prototype.hasModifier = _KeyboardUtil.hasModifier;
Keyboard.prototype.isCmd = _KeyboardUtil.isCmd;
Keyboard.prototype.isShift = _KeyboardUtil.isShift;
Keyboard.prototype.isKey = _KeyboardUtil.isKey; // helpers ///////

function isInput(target) {
  return target && ((0, _minDom.matches)(target, 'input, textarea') || target.contentEditable === 'true');
}

},{"./KeyboardUtil":216,"min-dash":555,"min-dom":556}],215:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = KeyboardBindings;
exports.KEYS_UNDO = exports.KEYS_REDO = exports.KEYS_PASTE = exports.KEYS_COPY = exports.KEYCODE_Z = exports.KEYCODE_Y = exports.KEYCODE_V = exports.KEYCODE_C = void 0;

var _KeyboardUtil = require("./KeyboardUtil");

var LOW_PRIORITY = 500;
var KEYCODE_C = 67;
exports.KEYCODE_C = KEYCODE_C;
var KEYCODE_V = 86;
exports.KEYCODE_V = KEYCODE_V;
var KEYCODE_Y = 89;
exports.KEYCODE_Y = KEYCODE_Y;
var KEYCODE_Z = 90;
exports.KEYCODE_Z = KEYCODE_Z;
var KEYS_COPY = ['c', 'C', KEYCODE_C];
exports.KEYS_COPY = KEYS_COPY;
var KEYS_PASTE = ['v', 'V', KEYCODE_V];
exports.KEYS_PASTE = KEYS_PASTE;
var KEYS_REDO = ['y', 'Y', KEYCODE_Y];
exports.KEYS_REDO = KEYS_REDO;
var KEYS_UNDO = ['z', 'Z', KEYCODE_Z];
/**
 * Adds default keyboard bindings.
 *
 * This does not pull in any features will bind only actions that
 * have previously been registered against the editorActions component.
 *
 * @param {EventBus} eventBus
 * @param {Keyboard} keyboard
 */

exports.KEYS_UNDO = KEYS_UNDO;

function KeyboardBindings(eventBus, keyboard) {
  var self = this;
  eventBus.on('editorActions.init', LOW_PRIORITY, function (event) {
    var editorActions = event.editorActions;
    self.registerBindings(keyboard, editorActions);
  });
}

KeyboardBindings.$inject = ['eventBus', 'keyboard'];
/**
 * Register available keyboard bindings.
 *
 * @param {Keyboard} keyboard
 * @param {EditorActions} editorActions
 */

KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) {
  /**
   * Add keyboard binding if respective editor action
   * is registered.
   *
   * @param {string} action name
   * @param {Function} fn that implements the key binding
   */
  function addListener(action, fn) {
    if (editorActions.isRegistered(action)) {
      keyboard.addListener(fn);
    }
  } // undo
  // (CTRL|CMD) + Z


  addListener('undo', function (context) {
    var event = context.keyEvent;

    if ((0, _KeyboardUtil.isCmd)(event) && !(0, _KeyboardUtil.isShift)(event) && (0, _KeyboardUtil.isKey)(KEYS_UNDO, event)) {
      editorActions.trigger('undo');
      return true;
    }
  }); // redo
  // CTRL + Y
  // CMD + SHIFT + Z

  addListener('redo', function (context) {
    var event = context.keyEvent;

    if ((0, _KeyboardUtil.isCmd)(event) && ((0, _KeyboardUtil.isKey)(KEYS_REDO, event) || (0, _KeyboardUtil.isKey)(KEYS_UNDO, event) && (0, _KeyboardUtil.isShift)(event))) {
      editorActions.trigger('redo');
      return true;
    }
  }); // copy
  // CTRL/CMD + C

  addListener('copy', function (context) {
    var event = context.keyEvent;

    if ((0, _KeyboardUtil.isCmd)(event) && (0, _KeyboardUtil.isKey)(KEYS_COPY, event)) {
      editorActions.trigger('copy');
      return true;
    }
  }); // paste
  // CTRL/CMD + V

  addListener('paste', function (context) {
    var event = context.keyEvent;

    if ((0, _KeyboardUtil.isCmd)(event) && (0, _KeyboardUtil.isKey)(KEYS_PASTE, event)) {
      editorActions.trigger('paste');
      return true;
    }
  }); // zoom in one step
  // CTRL/CMD + +

  addListener('stepZoom', function (context) {
    var event = context.keyEvent;

    if ((0, _KeyboardUtil.isKey)(['+', 'Add'], event) && (0, _KeyboardUtil.isCmd)(event)) {
      editorActions.trigger('stepZoom', {
        value: 1
      });
      return true;
    }
  }); // zoom out one step
  // CTRL + -

  addListener('stepZoom', function (context) {
    var event = context.keyEvent;

    if ((0, _KeyboardUtil.isKey)(['-', 'Subtract'], event) && (0, _KeyboardUtil.isCmd)(event)) {
      editorActions.trigger('stepZoom', {
        value: -1
      });
      return true;
    }
  }); // zoom to the default level
  // CTRL + 0

  addListener('zoom', function (context) {
    var event = context.keyEvent;

    if ((0, _KeyboardUtil.isKey)('0', event) && (0, _KeyboardUtil.isCmd)(event)) {
      editorActions.trigger('zoom', {
        value: 1
      });
      return true;
    }
  }); // delete selected element
  // DEL

  addListener('removeSelection', function (context) {
    var event = context.keyEvent;

    if ((0, _KeyboardUtil.isKey)(['Backspace', 'Delete', 'Del'], event)) {
      editorActions.trigger('removeSelection');
      return true;
    }
  });
};

},{"./KeyboardUtil":216}],216:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.hasModifier = hasModifier;
exports.isCmd = isCmd;
exports.isKey = isKey;
exports.isShift = isShift;

var _minDash = require("min-dash");

/**
 * Returns true if event was triggered with any modifier
 * @param {KeyboardEvent} event
 */
function hasModifier(event) {
  return event.ctrlKey || event.metaKey || event.shiftKey || event.altKey;
}
/**
 * @param {KeyboardEvent} event
 */


function isCmd(event) {
  // ensure we don't react to AltGr
  // (mapped to CTRL + ALT)
  if (event.altKey) {
    return false;
  }

  return event.ctrlKey || event.metaKey;
}
/**
 * Checks if key pressed is one of provided keys.
 *
 * @param {string|Array<string>} keys
 * @param {KeyboardEvent} event
 */


function isKey(keys, event) {
  keys = (0, _minDash.isArray)(keys) ? keys : [keys];
  return keys.indexOf(event.key) !== -1 || keys.indexOf(event.keyCode) !== -1;
}
/**
 * @param {KeyboardEvent} event
 */


function isShift(event) {
  return event.shiftKey;
}

},{"min-dash":555}],217:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _Keyboard = _interopRequireDefault(require("./Keyboard"));

var _KeyboardBindings = _interopRequireDefault(require("./KeyboardBindings"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['keyboard', 'keyboardBindings'],
  keyboard: ['type', _Keyboard.default],
  keyboardBindings: ['type', _KeyboardBindings.default]
};
exports.default = _default;

},{"./Keyboard":214,"./KeyboardBindings":215}],218:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = LabelSupport;

var _minDash = require("min-dash");

var _inherits = _interopRequireDefault(require("inherits"));

var _Collections = require("../../util/Collections");

var _Removal = require("../../util/Removal");

var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var LOW_PRIORITY = 250,
    HIGH_PRIORITY = 1400;

/**
 * A handler that makes sure labels are properly moved with
 * their label targets.
 *
 * @param {didi.Injector} injector
 * @param {EventBus} eventBus
 * @param {Modeling} modeling
 */
function LabelSupport(injector, eventBus, modeling) {
  _CommandInterceptor.default.call(this, eventBus);

  var movePreview = injector.get('movePreview', false); // remove labels from the collection that are being
  // moved with other elements anyway

  eventBus.on('shape.move.start', HIGH_PRIORITY, function (e) {
    var context = e.context,
        shapes = context.shapes,
        validatedShapes = context.validatedShapes;
    context.shapes = removeLabels(shapes);
    context.validatedShapes = removeLabels(validatedShapes);
  }); // add labels to visual's group

  movePreview && eventBus.on('shape.move.start', LOW_PRIORITY, function (e) {
    var context = e.context,
        shapes = context.shapes;
    var labels = [];
    (0, _minDash.forEach)(shapes, function (element) {
      (0, _minDash.forEach)(element.labels, function (label) {
        if (!label.hidden && context.shapes.indexOf(label) === -1) {
          labels.push(label);
        }

        if (element.labelTarget) {
          labels.push(element);
        }
      });
    });
    (0, _minDash.forEach)(labels, function (label) {
      movePreview.makeDraggable(context, label, true);
    });
  }); // add all labels to move closure

  this.preExecuted('elements.move', HIGH_PRIORITY, function (e) {
    var context = e.context,
        closure = context.closure,
        enclosedElements = closure.enclosedElements;
    var enclosedLabels = []; // find labels that are not part of
    // move closure yet and add them

    (0, _minDash.forEach)(enclosedElements, function (element) {
      (0, _minDash.forEach)(element.labels, function (label) {
        if (!enclosedElements[label.id]) {
          enclosedLabels.push(label);
        }
      });
    });
    closure.addAll(enclosedLabels);
  });
  this.preExecute(['connection.delete', 'shape.delete'], function (e) {
    var context = e.context,
        element = context.connection || context.shape;
    (0, _Removal.saveClear)(element.labels, function (label) {
      modeling.removeShape(label, {
        nested: true
      });
    });
  });
  this.execute('shape.delete', function (e) {
    var context = e.context,
        shape = context.shape,
        labelTarget = shape.labelTarget; // unset labelTarget

    if (labelTarget) {
      context.labelTargetIndex = (0, _Collections.indexOf)(labelTarget.labels, shape);
      context.labelTarget = labelTarget;
      shape.labelTarget = null;
    }
  });
  this.revert('shape.delete', function (e) {
    var context = e.context,
        shape = context.shape,
        labelTarget = context.labelTarget,
        labelTargetIndex = context.labelTargetIndex; // restore labelTarget

    if (labelTarget) {
      (0, _Collections.add)(labelTarget.labels, shape, labelTargetIndex);
      shape.labelTarget = labelTarget;
    }
  });
}

(0, _inherits.default)(LabelSupport, _CommandInterceptor.default);
LabelSupport.$inject = ['injector', 'eventBus', 'modeling'];
/**
 * Return a filtered list of elements that do not
 * contain attached elements with hosts being part
 * of the selection.
 *
 * @param  {Array<djs.model.Base>} elements
 *
 * @return {Array<djs.model.Base>} filtered
 */

function removeLabels(elements) {
  return (0, _minDash.filter)(elements, function (element) {
    // filter out labels that are move together
    // with their label targets
    return elements.indexOf(element.labelTarget) === -1;
  });
}

},{"../../command/CommandInterceptor":145,"../../util/Collections":313,"../../util/Removal":326,"inherits":347,"min-dash":555}],219:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _LabelSupport = _interopRequireDefault(require("./LabelSupport"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['labelSupport'],
  labelSupport: ['type', _LabelSupport.default]
};
exports.default = _default;

},{"./LabelSupport":218}],220:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = LassoTool;

var _minDash = require("min-dash");

var _Elements = require("../../util/Elements");

var _Mouse = require("../../util/Mouse");

var _tinySvg = require("tiny-svg");

var LASSO_TOOL_CURSOR = 'crosshair';

function LassoTool(eventBus, canvas, dragging, elementRegistry, selection, toolManager) {
  this._selection = selection;
  this._dragging = dragging;
  var self = this; // lasso visuals implementation

  /**
  * A helper that realizes the selection box visual
  */

  var visuals = {
    create: function (context) {
      var container = canvas.getDefaultLayer(),
          frame;
      frame = context.frame = (0, _tinySvg.create)('rect');
      (0, _tinySvg.attr)(frame, {
        class: 'djs-lasso-overlay',
        width: 1,
        height: 1,
        x: 0,
        y: 0
      });
      (0, _tinySvg.append)(container, frame);
    },
    update: function (context) {
      var frame = context.frame,
          bbox = context.bbox;
      (0, _tinySvg.attr)(frame, {
        x: bbox.x,
        y: bbox.y,
        width: bbox.width,
        height: bbox.height
      });
    },
    remove: function (context) {
      if (context.frame) {
        (0, _tinySvg.remove)(context.frame);
      }
    }
  };
  toolManager.registerTool('lasso', {
    tool: 'lasso.selection',
    dragging: 'lasso'
  });
  eventBus.on('lasso.selection.end', function (event) {
    var target = event.originalEvent.target; // only reactive on diagram click
    // on some occasions, event.hover is not set and we have to check if the target is an svg

    if (!event.hover && !(target instanceof SVGElement)) {
      return;
    }

    eventBus.once('lasso.selection.ended', function () {
      self.activateLasso(event.originalEvent, true);
    });
  }); // lasso interaction implementation

  eventBus.on('lasso.end', function (event) {
    var bbox = toBBox(event);
    var elements = elementRegistry.filter(function (element) {
      return element;
    });
    self.select(elements, bbox);
  });
  eventBus.on('lasso.start', function (event) {
    var context = event.context;
    context.bbox = toBBox(event);
    visuals.create(context);
  });
  eventBus.on('lasso.move', function (event) {
    var context = event.context;
    context.bbox = toBBox(event);
    visuals.update(context);
  });
  eventBus.on('lasso.cleanup', function (event) {
    var context = event.context;
    visuals.remove(context);
  }); // event integration

  eventBus.on('element.mousedown', 1500, function (event) {
    if ((0, _Mouse.hasSecondaryModifier)(event)) {
      self.activateLasso(event.originalEvent); // we've handled the event

      return true;
    }
  });
}

LassoTool.$inject = ['eventBus', 'canvas', 'dragging', 'elementRegistry', 'selection', 'toolManager'];

LassoTool.prototype.activateLasso = function (event, autoActivate) {
  this._dragging.init(event, 'lasso', {
    autoActivate: autoActivate,
    cursor: LASSO_TOOL_CURSOR,
    data: {
      context: {}
    }
  });
};

LassoTool.prototype.activateSelection = function (event) {
  this._dragging.init(event, 'lasso.selection', {
    trapClick: false,
    cursor: LASSO_TOOL_CURSOR,
    data: {
      context: {}
    }
  });
};

LassoTool.prototype.select = function (elements, bbox) {
  var selectedElements = (0, _Elements.getEnclosedElements)(elements, bbox);

  this._selection.select((0, _minDash.values)(selectedElements));
};

LassoTool.prototype.toggle = function () {
  if (this.isActive()) {
    this._dragging.cancel();
  } else {
    this.activateSelection();
  }
};

LassoTool.prototype.isActive = function () {
  var context = this._dragging.context();

  return context && /^lasso/.test(context.prefix);
};

function toBBox(event) {
  var start = {
    x: event.x - event.dx,
    y: event.y - event.dy
  };
  var end = {
    x: event.x,
    y: event.y
  };
  var bbox;

  if (start.x <= end.x && start.y < end.y || start.x < end.x && start.y <= end.y) {
    bbox = {
      x: start.x,
      y: start.y,
      width: end.x - start.x,
      height: end.y - start.y
    };
  } else if (start.x >= end.x && start.y < end.y || start.x > end.x && start.y <= end.y) {
    bbox = {
      x: end.x,
      y: start.y,
      width: start.x - end.x,
      height: end.y - start.y
    };
  } else if (start.x <= end.x && start.y > end.y || start.x < end.x && start.y >= end.y) {
    bbox = {
      x: start.x,
      y: end.y,
      width: end.x - start.x,
      height: start.y - end.y
    };
  } else if (start.x >= end.x && start.y > end.y || start.x > end.x && start.y >= end.y) {
    bbox = {
      x: end.x,
      y: end.y,
      width: start.x - end.x,
      height: start.y - end.y
    };
  } else {
    bbox = {
      x: end.x,
      y: end.y,
      width: 0,
      height: 0
    };
  }

  return bbox;
}

},{"../../util/Elements":315,"../../util/Mouse":323,"min-dash":555,"tiny-svg":567}],221:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _toolManager = _interopRequireDefault(require("../tool-manager"));

var _LassoTool = _interopRequireDefault(require("./LassoTool"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_toolManager.default],
  __init__: ['lassoTool'],
  lassoTool: ['type', _LassoTool.default]
};
exports.default = _default;

},{"../tool-manager":290,"./LassoTool":220}],222:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Modeling;

var _minDash = require("min-dash");

var _model = require("../../model");

var _AlignElementsHandler = _interopRequireDefault(require("./cmd/AlignElementsHandler"));

var _AppendShapeHandler = _interopRequireDefault(require("./cmd/AppendShapeHandler"));

var _CreateConnectionHandler = _interopRequireDefault(require("./cmd/CreateConnectionHandler"));

var _CreateElementsHandler = _interopRequireDefault(require("./cmd/CreateElementsHandler"));

var _CreateLabelHandler = _interopRequireDefault(require("./cmd/CreateLabelHandler"));

var _CreateShapeHandler = _interopRequireDefault(require("./cmd/CreateShapeHandler"));

var _DeleteConnectionHandler = _interopRequireDefault(require("./cmd/DeleteConnectionHandler"));

var _DeleteElementsHandler = _interopRequireDefault(require("./cmd/DeleteElementsHandler"));

var _DeleteShapeHandler = _interopRequireDefault(require("./cmd/DeleteShapeHandler"));

var _DistributeElementsHandler = _interopRequireDefault(require("./cmd/DistributeElementsHandler"));

var _LayoutConnectionHandler = _interopRequireDefault(require("./cmd/LayoutConnectionHandler"));

var _MoveConnectionHandler = _interopRequireDefault(require("./cmd/MoveConnectionHandler"));

var _MoveElementsHandler = _interopRequireDefault(require("./cmd/MoveElementsHandler"));

var _MoveShapeHandler = _interopRequireDefault(require("./cmd/MoveShapeHandler"));

var _ReconnectConnectionHandler = _interopRequireDefault(require("./cmd/ReconnectConnectionHandler"));

var _ReplaceShapeHandler = _interopRequireDefault(require("./cmd/ReplaceShapeHandler"));

var _ResizeShapeHandler = _interopRequireDefault(require("./cmd/ResizeShapeHandler"));

var _SpaceToolHandler = _interopRequireDefault(require("./cmd/SpaceToolHandler"));

var _ToggleShapeCollapseHandler = _interopRequireDefault(require("./cmd/ToggleShapeCollapseHandler"));

var _UpdateAttachmentHandler = _interopRequireDefault(require("./cmd/UpdateAttachmentHandler"));

var _UpdateWaypointsHandler = _interopRequireDefault(require("./cmd/UpdateWaypointsHandler"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * The basic modeling entry point.
 *
 * @param {EventBus} eventBus
 * @param {ElementFactory} elementFactory
 * @param {CommandStack} commandStack
 */
function Modeling(eventBus, elementFactory, commandStack) {
  this._eventBus = eventBus;
  this._elementFactory = elementFactory;
  this._commandStack = commandStack;
  var self = this;
  eventBus.on('diagram.init', function () {
    // register modeling handlers
    self.registerHandlers(commandStack);
  });
}

Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack'];

Modeling.prototype.getHandlers = function () {
  return {
    'shape.append': _AppendShapeHandler.default,
    'shape.create': _CreateShapeHandler.default,
    'shape.delete': _DeleteShapeHandler.default,
    'shape.move': _MoveShapeHandler.default,
    'shape.resize': _ResizeShapeHandler.default,
    'shape.replace': _ReplaceShapeHandler.default,
    'shape.toggleCollapse': _ToggleShapeCollapseHandler.default,
    'spaceTool': _SpaceToolHandler.default,
    'label.create': _CreateLabelHandler.default,
    'connection.create': _CreateConnectionHandler.default,
    'connection.delete': _DeleteConnectionHandler.default,
    'connection.move': _MoveConnectionHandler.default,
    'connection.layout': _LayoutConnectionHandler.default,
    'connection.updateWaypoints': _UpdateWaypointsHandler.default,
    'connection.reconnect': _ReconnectConnectionHandler.default,
    'elements.create': _CreateElementsHandler.default,
    'elements.move': _MoveElementsHandler.default,
    'elements.delete': _DeleteElementsHandler.default,
    'elements.distribute': _DistributeElementsHandler.default,
    'elements.align': _AlignElementsHandler.default,
    'element.updateAttachment': _UpdateAttachmentHandler.default
  };
};
/**
 * Register handlers with the command stack
 *
 * @param {CommandStack} commandStack
 */


Modeling.prototype.registerHandlers = function (commandStack) {
  (0, _minDash.forEach)(this.getHandlers(), function (handler, id) {
    commandStack.registerHandler(id, handler);
  });
}; // modeling helpers //////////////////////


Modeling.prototype.moveShape = function (shape, delta, newParent, newParentIndex, hints) {
  if (typeof newParentIndex === 'object') {
    hints = newParentIndex;
    newParentIndex = null;
  }

  var context = {
    shape: shape,
    delta: delta,
    newParent: newParent,
    newParentIndex: newParentIndex,
    hints: hints || {}
  };

  this._commandStack.execute('shape.move', context);
};
/**
 * Update the attachment of the given shape.
 *
 * @param {djs.mode.Base} shape
 * @param {djs.model.Base} [newHost]
 */


Modeling.prototype.updateAttachment = function (shape, newHost) {
  var context = {
    shape: shape,
    newHost: newHost
  };

  this._commandStack.execute('element.updateAttachment', context);
};
/**
 * Move a number of shapes to a new target, either setting it as
 * the new parent or attaching it.
 *
 * @param {Array<djs.mode.Base>} shapes
 * @param {Point} delta
 * @param {djs.model.Base} [target]
 * @param {Object} [hints]
 * @param {boolean} [hints.attach=false]
 */


Modeling.prototype.moveElements = function (shapes, delta, target, hints) {
  hints = hints || {};
  var attach = hints.attach;
  var newParent = target,
      newHost;

  if (attach === true) {
    newHost = target;
    newParent = target.parent;
  } else if (attach === false) {
    newHost = null;
  }

  var context = {
    shapes: shapes,
    delta: delta,
    newParent: newParent,
    newHost: newHost,
    hints: hints
  };

  this._commandStack.execute('elements.move', context);
};

Modeling.prototype.moveConnection = function (connection, delta, newParent, newParentIndex, hints) {
  if (typeof newParentIndex === 'object') {
    hints = newParentIndex;
    newParentIndex = undefined;
  }

  var context = {
    connection: connection,
    delta: delta,
    newParent: newParent,
    newParentIndex: newParentIndex,
    hints: hints || {}
  };

  this._commandStack.execute('connection.move', context);
};

Modeling.prototype.layoutConnection = function (connection, hints) {
  var context = {
    connection: connection,
    hints: hints || {}
  };

  this._commandStack.execute('connection.layout', context);
};
/**
 * Create connection.
 *
 * @param {djs.model.Base} source
 * @param {djs.model.Base} target
 * @param {number} [parentIndex]
 * @param {Object|djs.model.Connection} connection
 * @param {djs.model.Base} parent
 * @param {Object} hints
 *
 * @return {djs.model.Connection} the created connection.
 */


Modeling.prototype.createConnection = function (source, target, parentIndex, connection, parent, hints) {
  if (typeof parentIndex === 'object') {
    hints = parent;
    parent = connection;
    connection = parentIndex;
    parentIndex = undefined;
  }

  connection = this._create('connection', connection);
  var context = {
    source: source,
    target: target,
    parent: parent,
    parentIndex: parentIndex,
    connection: connection,
    hints: hints
  };

  this._commandStack.execute('connection.create', context);

  return context.connection;
};
/**
 * Create a shape at the specified position.
 *
 * @param {djs.model.Shape|Object} shape
 * @param {Point} position
 * @param {djs.model.Shape|djs.model.Root} target
 * @param {number} [parentIndex] position in parents children list
 * @param {Object} [hints]
 * @param {boolean} [hints.attach] whether to attach to target or become a child
 *
 * @return {djs.model.Shape} the created shape
 */


Modeling.prototype.createShape = function (shape, position, target, parentIndex, hints) {
  if (typeof parentIndex !== 'number') {
    hints = parentIndex;
    parentIndex = undefined;
  }

  hints = hints || {};
  var attach = hints.attach,
      parent,
      host;
  shape = this._create('shape', shape);

  if (attach) {
    parent = target.parent;
    host = target;
  } else {
    parent = target;
  }

  var context = {
    position: position,
    shape: shape,
    parent: parent,
    parentIndex: parentIndex,
    host: host,
    hints: hints
  };

  this._commandStack.execute('shape.create', context);

  return context.shape;
};

Modeling.prototype.createElements = function (elements, position, parent, parentIndex, hints) {
  if (!(0, _minDash.isArray)(elements)) {
    elements = [elements];
  }

  if (typeof parentIndex !== 'number') {
    hints = parentIndex;
    parentIndex = undefined;
  }

  hints = hints || {};
  var context = {
    position: position,
    elements: elements,
    parent: parent,
    parentIndex: parentIndex,
    hints: hints
  };

  this._commandStack.execute('elements.create', context);

  return context.elements;
};

Modeling.prototype.createLabel = function (labelTarget, position, label, parent) {
  label = this._create('label', label);
  var context = {
    labelTarget: labelTarget,
    position: position,
    parent: parent || labelTarget.parent,
    shape: label
  };

  this._commandStack.execute('label.create', context);

  return context.shape;
};
/**
 * Append shape to given source, drawing a connection
 * between source and the newly created shape.
 *
 * @param {djs.model.Shape} source
 * @param {djs.model.Shape|Object} shape
 * @param {Point} position
 * @param {djs.model.Shape} target
 * @param {Object} [hints]
 * @param {boolean} [hints.attach]
 * @param {djs.model.Connection|Object} [hints.connection]
 * @param {djs.model.Base} [hints.connectionParent]
 *
 * @return {djs.model.Shape} the newly created shape
 */


Modeling.prototype.appendShape = function (source, shape, position, target, hints) {
  hints = hints || {};
  shape = this._create('shape', shape);
  var context = {
    source: source,
    position: position,
    target: target,
    shape: shape,
    connection: hints.connection,
    connectionParent: hints.connectionParent,
    hints: hints
  };

  this._commandStack.execute('shape.append', context);

  return context.shape;
};

Modeling.prototype.removeElements = function (elements) {
  var context = {
    elements: elements
  };

  this._commandStack.execute('elements.delete', context);
};

Modeling.prototype.distributeElements = function (groups, axis, dimension) {
  var context = {
    groups: groups,
    axis: axis,
    dimension: dimension
  };

  this._commandStack.execute('elements.distribute', context);
};

Modeling.prototype.removeShape = function (shape, hints) {
  var context = {
    shape: shape,
    hints: hints || {}
  };

  this._commandStack.execute('shape.delete', context);
};

Modeling.prototype.removeConnection = function (connection, hints) {
  var context = {
    connection: connection,
    hints: hints || {}
  };

  this._commandStack.execute('connection.delete', context);
};

Modeling.prototype.replaceShape = function (oldShape, newShape, hints) {
  var context = {
    oldShape: oldShape,
    newData: newShape,
    hints: hints || {}
  };

  this._commandStack.execute('shape.replace', context);

  return context.newShape;
};

Modeling.prototype.alignElements = function (elements, alignment) {
  var context = {
    elements: elements,
    alignment: alignment
  };

  this._commandStack.execute('elements.align', context);
};

Modeling.prototype.resizeShape = function (shape, newBounds, minBounds, hints) {
  var context = {
    shape: shape,
    newBounds: newBounds,
    minBounds: minBounds,
    hints: hints
  };

  this._commandStack.execute('shape.resize', context);
};

Modeling.prototype.createSpace = function (movingShapes, resizingShapes, delta, direction, start) {
  var context = {
    delta: delta,
    direction: direction,
    movingShapes: movingShapes,
    resizingShapes: resizingShapes,
    start: start
  };

  this._commandStack.execute('spaceTool', context);
};

Modeling.prototype.updateWaypoints = function (connection, newWaypoints, hints) {
  var context = {
    connection: connection,
    newWaypoints: newWaypoints,
    hints: hints || {}
  };

  this._commandStack.execute('connection.updateWaypoints', context);
};

Modeling.prototype.reconnect = function (connection, source, target, dockingOrPoints, hints) {
  var context = {
    connection: connection,
    newSource: source,
    newTarget: target,
    dockingOrPoints: dockingOrPoints,
    hints: hints || {}
  };

  this._commandStack.execute('connection.reconnect', context);
};

Modeling.prototype.reconnectStart = function (connection, newSource, dockingOrPoints, hints) {
  if (!hints) {
    hints = {};
  }

  this.reconnect(connection, newSource, connection.target, dockingOrPoints, (0, _minDash.assign)(hints, {
    docking: 'source'
  }));
};

Modeling.prototype.reconnectEnd = function (connection, newTarget, dockingOrPoints, hints) {
  if (!hints) {
    hints = {};
  }

  this.reconnect(connection, connection.source, newTarget, dockingOrPoints, (0, _minDash.assign)(hints, {
    docking: 'target'
  }));
};

Modeling.prototype.connect = function (source, target, attrs, hints) {
  return this.createConnection(source, target, attrs || {}, source.parent, hints);
};

Modeling.prototype._create = function (type, attrs) {
  if (attrs instanceof _model.Base) {
    return attrs;
  } else {
    return this._elementFactory.create(type, attrs);
  }
};

Modeling.prototype.toggleCollapse = function (shape, hints) {
  var context = {
    shape: shape,
    hints: hints || {}
  };

  this._commandStack.execute('shape.toggleCollapse', context);
};

},{"../../model":302,"./cmd/AlignElementsHandler":223,"./cmd/AppendShapeHandler":224,"./cmd/CreateConnectionHandler":225,"./cmd/CreateElementsHandler":226,"./cmd/CreateLabelHandler":227,"./cmd/CreateShapeHandler":228,"./cmd/DeleteConnectionHandler":229,"./cmd/DeleteElementsHandler":230,"./cmd/DeleteShapeHandler":231,"./cmd/DistributeElementsHandler":232,"./cmd/LayoutConnectionHandler":233,"./cmd/MoveConnectionHandler":234,"./cmd/MoveElementsHandler":235,"./cmd/MoveShapeHandler":236,"./cmd/ReconnectConnectionHandler":237,"./cmd/ReplaceShapeHandler":238,"./cmd/ResizeShapeHandler":239,"./cmd/SpaceToolHandler":240,"./cmd/ToggleShapeCollapseHandler":241,"./cmd/UpdateAttachmentHandler":242,"./cmd/UpdateWaypointsHandler":243,"min-dash":555}],223:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AlignElements;

var _minDash = require("min-dash");

/**
 * A handler that align elements in a certain way.
 *
 */
function AlignElements(modeling, canvas) {
  this._modeling = modeling;
  this._canvas = canvas;
}

AlignElements.$inject = ['modeling', 'canvas'];

AlignElements.prototype.preExecute = function (context) {
  var modeling = this._modeling;
  var elements = context.elements,
      alignment = context.alignment;
  (0, _minDash.forEach)(elements, function (element) {
    var delta = {
      x: 0,
      y: 0
    };

    if (alignment.left) {
      delta.x = alignment.left - element.x;
    } else if (alignment.right) {
      delta.x = alignment.right - element.width - element.x;
    } else if (alignment.center) {
      delta.x = alignment.center - Math.round(element.width / 2) - element.x;
    } else if (alignment.top) {
      delta.y = alignment.top - element.y;
    } else if (alignment.bottom) {
      delta.y = alignment.bottom - element.height - element.y;
    } else if (alignment.middle) {
      delta.y = alignment.middle - Math.round(element.height / 2) - element.y;
    }

    modeling.moveElements([element], delta, element.parent);
  });
};

AlignElements.prototype.postExecute = function (context) {};

},{"min-dash":555}],224:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = AppendShapeHandler;

var _minDash = require("min-dash");

/**
 * A handler that implements reversible appending of shapes
 * to a source shape.
 *
 * @param {canvas} Canvas
 * @param {elementFactory} ElementFactory
 * @param {modeling} Modeling
 */
function AppendShapeHandler(modeling) {
  this._modeling = modeling;
}

AppendShapeHandler.$inject = ['modeling']; // api //////////////////////

/**
 * Creates a new shape
 *
 * @param {Object} context
 * @param {ElementDescriptor} context.shape the new shape
 * @param {ElementDescriptor} context.source the source object
 * @param {ElementDescriptor} context.parent the parent object
 * @param {Point} context.position position of the new element
 */

AppendShapeHandler.prototype.preExecute = function (context) {
  var source = context.source;

  if (!source) {
    throw new Error('source required');
  }

  var target = context.target || source.parent,
      shape = context.shape,
      hints = context.hints || {};
  shape = context.shape = this._modeling.createShape(shape, context.position, target, {
    attach: hints.attach
  });
  context.shape = shape;
};

AppendShapeHandler.prototype.postExecute = function (context) {
  var hints = context.hints || {};

  if (!existsConnection(context.source, context.shape)) {
    // create connection
    if (hints.connectionTarget === context.source) {
      this._modeling.connect(context.shape, context.source, context.connection);
    } else {
      this._modeling.connect(context.source, context.shape, context.connection);
    }
  }
};

function existsConnection(source, target) {
  return (0, _minDash.some)(source.outgoing, function (c) {
    return c.target === target;
  });
}

},{"min-dash":555}],225:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreateConnectionHandler;

function CreateConnectionHandler(canvas, layouter) {
  this._canvas = canvas;
  this._layouter = layouter;
}

CreateConnectionHandler.$inject = ['canvas', 'layouter']; // api //////////////////////

/**
 * Appends a shape to a target shape
 *
 * @param {Object} context
 * @param {djs.element.Base} context.source the source object
 * @param {djs.element.Base} context.target the parent object
 * @param {Point} context.position position of the new element
 */

CreateConnectionHandler.prototype.execute = function (context) {
  var connection = context.connection,
      source = context.source,
      target = context.target,
      parent = context.parent,
      parentIndex = context.parentIndex,
      hints = context.hints;

  if (!source || !target) {
    throw new Error('source and target required');
  }

  if (!parent) {
    throw new Error('parent required');
  }

  connection.source = source;
  connection.target = target;

  if (!connection.waypoints) {
    connection.waypoints = this._layouter.layoutConnection(connection, hints);
  } // add connection


  this._canvas.addConnection(connection, parent, parentIndex);

  return connection;
};

CreateConnectionHandler.prototype.revert = function (context) {
  var connection = context.connection;

  this._canvas.removeConnection(connection);

  connection.source = null;
  connection.target = null;
  return connection;
};

},{}],226:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreateElementsHandler;

var _minDash = require("min-dash");

var _Elements = require("../../../util/Elements");

var round = Math.round;

function CreateElementsHandler(modeling) {
  this._modeling = modeling;
}

CreateElementsHandler.$inject = ['modeling'];

CreateElementsHandler.prototype.preExecute = function (context) {
  var elements = context.elements,
      parent = context.parent,
      parentIndex = context.parentIndex,
      position = context.position,
      hints = context.hints;
  var modeling = this._modeling; // make sure each element has x and y

  (0, _minDash.forEach)(elements, function (element) {
    if (!(0, _minDash.isNumber)(element.x)) {
      element.x = 0;
    }

    if (!(0, _minDash.isNumber)(element.y)) {
      element.y = 0;
    }
  });
  var bbox = (0, _Elements.getBBox)(elements); // center elements around position

  (0, _minDash.forEach)(elements, function (element) {
    if (isConnection(element)) {
      element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint) {
        return {
          x: round(waypoint.x - bbox.x - bbox.width / 2 + position.x),
          y: round(waypoint.y - bbox.y - bbox.height / 2 + position.y)
        };
      });
    }

    (0, _minDash.assign)(element, {
      x: round(element.x - bbox.x - bbox.width / 2 + position.x),
      y: round(element.y - bbox.y - bbox.height / 2 + position.y)
    });
  });
  var parents = (0, _Elements.getParents)(elements);
  var cache = {};
  (0, _minDash.forEach)(elements, function (element) {
    if (isConnection(element)) {
      cache[element.id] = (0, _minDash.isNumber)(parentIndex) ? modeling.createConnection(cache[element.source.id], cache[element.target.id], parentIndex, element, element.parent || parent, hints) : modeling.createConnection(cache[element.source.id], cache[element.target.id], element, element.parent || parent, hints);
      return;
    }

    var createShapeHints = (0, _minDash.assign)({}, hints);

    if (parents.indexOf(element) === -1) {
      createShapeHints.autoResize = false;
    }

    cache[element.id] = (0, _minDash.isNumber)(parentIndex) ? modeling.createShape(element, (0, _minDash.pick)(element, ['x', 'y', 'width', 'height']), element.parent || parent, parentIndex, createShapeHints) : modeling.createShape(element, (0, _minDash.pick)(element, ['x', 'y', 'width', 'height']), element.parent || parent, createShapeHints);
  });
  context.elements = (0, _minDash.values)(cache);
}; // helpers //////////


function isConnection(element) {
  return !!element.waypoints;
}

},{"../../../util/Elements":315,"min-dash":555}],227:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreateLabelHandler;

var _inherits = _interopRequireDefault(require("inherits"));

var _CreateShapeHandler = _interopRequireDefault(require("./CreateShapeHandler"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A handler that attaches a label to a given target shape.
 *
 * @param {Canvas} canvas
 */
function CreateLabelHandler(canvas) {
  _CreateShapeHandler.default.call(this, canvas);
}

(0, _inherits.default)(CreateLabelHandler, _CreateShapeHandler.default);
CreateLabelHandler.$inject = ['canvas']; // api //////////////////////

var originalExecute = _CreateShapeHandler.default.prototype.execute;
/**
 * Appends a label to a target shape.
 *
 * @method CreateLabelHandler#execute
 *
 * @param {Object} context
 * @param {ElementDescriptor} context.target the element the label is attached to
 * @param {ElementDescriptor} context.parent the parent object
 * @param {Point} context.position position of the new element
 */

CreateLabelHandler.prototype.execute = function (context) {
  var label = context.shape;
  ensureValidDimensions(label);
  label.labelTarget = context.labelTarget;
  return originalExecute.call(this, context);
};

var originalRevert = _CreateShapeHandler.default.prototype.revert;
/**
 * Undo append by removing the shape
 */

CreateLabelHandler.prototype.revert = function (context) {
  context.shape.labelTarget = null;
  return originalRevert.call(this, context);
}; // helpers //////////////////////


function ensureValidDimensions(label) {
  // make sure a label has valid { width, height } dimensions
  ['width', 'height'].forEach(function (prop) {
    if (typeof label[prop] === 'undefined') {
      label[prop] = 0;
    }
  });
}

},{"./CreateShapeHandler":228,"inherits":347}],228:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreateShapeHandler;

var _minDash = require("min-dash");

var round = Math.round;
/**
 * A handler that implements reversible addition of shapes.
 *
 * @param {canvas} Canvas
 */

function CreateShapeHandler(canvas) {
  this._canvas = canvas;
}

CreateShapeHandler.$inject = ['canvas']; // api //////////////////////

/**
 * Appends a shape to a target shape
 *
 * @param {Object} context
 * @param {djs.model.Base} context.parent the parent object
 * @param {Point} context.position position of the new element
 */

CreateShapeHandler.prototype.execute = function (context) {
  var shape = context.shape,
      positionOrBounds = context.position,
      parent = context.parent,
      parentIndex = context.parentIndex;

  if (!parent) {
    throw new Error('parent required');
  }

  if (!positionOrBounds) {
    throw new Error('position required');
  } // (1) add at event center position _or_ at given bounds


  if (positionOrBounds.width !== undefined) {
    (0, _minDash.assign)(shape, positionOrBounds);
  } else {
    (0, _minDash.assign)(shape, {
      x: positionOrBounds.x - round(shape.width / 2),
      y: positionOrBounds.y - round(shape.height / 2)
    });
  } // (2) add to canvas


  this._canvas.addShape(shape, parent, parentIndex);

  return shape;
};
/**
 * Undo append by removing the shape
 */


CreateShapeHandler.prototype.revert = function (context) {
  var shape = context.shape; // (3) remove form canvas

  this._canvas.removeShape(shape);

  return shape;
};

},{"min-dash":555}],229:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DeleteConnectionHandler;

var _Collections = require("../../../util/Collections");

/**
 * A handler that implements reversible deletion of Connections.
 */
function DeleteConnectionHandler(canvas, modeling) {
  this._canvas = canvas;
  this._modeling = modeling;
}

DeleteConnectionHandler.$inject = ['canvas', 'modeling'];

DeleteConnectionHandler.prototype.execute = function (context) {
  var connection = context.connection,
      parent = connection.parent;
  context.parent = parent; // remember containment

  context.parentIndex = (0, _Collections.indexOf)(parent.children, connection);
  context.source = connection.source;
  context.target = connection.target;

  this._canvas.removeConnection(connection);

  connection.source = null;
  connection.target = null;
  return connection;
};
/**
 * Command revert implementation.
 */


DeleteConnectionHandler.prototype.revert = function (context) {
  var connection = context.connection,
      parent = context.parent,
      parentIndex = context.parentIndex;
  connection.source = context.source;
  connection.target = context.target; // restore containment

  (0, _Collections.add)(parent.children, connection, parentIndex);

  this._canvas.addConnection(connection, parent);

  return connection;
};

},{"../../../util/Collections":313}],230:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DeleteElementsHandler;

var _minDash = require("min-dash");

function DeleteElementsHandler(modeling, elementRegistry) {
  this._modeling = modeling;
  this._elementRegistry = elementRegistry;
}

DeleteElementsHandler.$inject = ['modeling', 'elementRegistry'];

DeleteElementsHandler.prototype.postExecute = function (context) {
  var modeling = this._modeling,
      elementRegistry = this._elementRegistry,
      elements = context.elements;
  (0, _minDash.forEach)(elements, function (element) {
    // element may have been removed with previous
    // remove operations already (e.g. in case of nesting)
    if (!elementRegistry.get(element.id)) {
      return;
    }

    if (element.waypoints) {
      modeling.removeConnection(element);
    } else {
      modeling.removeShape(element);
    }
  });
};

},{"min-dash":555}],231:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DeleteShapeHandler;

var _Collections = require("../../../util/Collections");

var _Removal = require("../../../util/Removal");

/**
 * A handler that implements reversible deletion of shapes.
 *
 */
function DeleteShapeHandler(canvas, modeling) {
  this._canvas = canvas;
  this._modeling = modeling;
}

DeleteShapeHandler.$inject = ['canvas', 'modeling'];
/**
 * - Remove connections
 * - Remove all direct children
 */

DeleteShapeHandler.prototype.preExecute = function (context) {
  var modeling = this._modeling;
  var shape = context.shape; // remove connections

  (0, _Removal.saveClear)(shape.incoming, function (connection) {
    // To make sure that the connection isn't removed twice
    // For example if a container is removed
    modeling.removeConnection(connection, {
      nested: true
    });
  });
  (0, _Removal.saveClear)(shape.outgoing, function (connection) {
    modeling.removeConnection(connection, {
      nested: true
    });
  }); // remove child shapes and connections

  (0, _Removal.saveClear)(shape.children, function (child) {
    if (isConnection(child)) {
      modeling.removeConnection(child, {
        nested: true
      });
    } else {
      modeling.removeShape(child, {
        nested: true
      });
    }
  });
};
/**
 * Remove shape and remember the parent
 */


DeleteShapeHandler.prototype.execute = function (context) {
  var canvas = this._canvas;
  var shape = context.shape,
      oldParent = shape.parent;
  context.oldParent = oldParent; // remove containment

  context.oldParentIndex = (0, _Collections.indexOf)(oldParent.children, shape); // remove shape

  canvas.removeShape(shape);
  return shape;
};
/**
 * Command revert implementation
 */


DeleteShapeHandler.prototype.revert = function (context) {
  var canvas = this._canvas;
  var shape = context.shape,
      oldParent = context.oldParent,
      oldParentIndex = context.oldParentIndex; // restore containment

  (0, _Collections.add)(oldParent.children, shape, oldParentIndex);
  canvas.addShape(shape, oldParent);
  return shape;
};

function isConnection(element) {
  return element.waypoints;
}

},{"../../../util/Collections":313,"../../../util/Removal":326}],232:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DistributeElements;

var _minDash = require("min-dash");

/**
 * A handler that distributes elements evenly.
 */
function DistributeElements(modeling) {
  this._modeling = modeling;
}

DistributeElements.$inject = ['modeling'];
var OFF_AXIS = {
  x: 'y',
  y: 'x'
};

DistributeElements.prototype.preExecute = function (context) {
  var modeling = this._modeling;
  var groups = context.groups,
      axis = context.axis,
      dimension = context.dimension;

  function updateRange(group, element) {
    group.range.min = Math.min(element[axis], group.range.min);
    group.range.max = Math.max(element[axis] + element[dimension], group.range.max);
  }

  function center(element) {
    return element[axis] + element[dimension] / 2;
  }

  function lastIdx(arr) {
    return arr.length - 1;
  }

  function rangeDiff(range) {
    return range.max - range.min;
  }

  function centerElement(refCenter, element) {
    var delta = {
      y: 0
    };
    delta[axis] = refCenter - center(element);

    if (delta[axis]) {
      delta[OFF_AXIS[axis]] = 0;
      modeling.moveElements([element], delta, element.parent);
    }
  }

  var firstGroup = groups[0],
      lastGroupIdx = lastIdx(groups),
      lastGroup = groups[lastGroupIdx];
  var margin,
      spaceInBetween,
      groupsSize = 0; // the size of each range

  (0, _minDash.forEach)(groups, function (group, idx) {
    var sortedElements, refElem, refCenter;

    if (group.elements.length < 2) {
      if (idx && idx !== groups.length - 1) {
        updateRange(group, group.elements[0]);
        groupsSize += rangeDiff(group.range);
      }

      return;
    }

    sortedElements = (0, _minDash.sortBy)(group.elements, axis);
    refElem = sortedElements[0];

    if (idx === lastGroupIdx) {
      refElem = sortedElements[lastIdx(sortedElements)];
    }

    refCenter = center(refElem); // wanna update the ranges after the shapes have been centered

    group.range = null;
    (0, _minDash.forEach)(sortedElements, function (element) {
      centerElement(refCenter, element);

      if (group.range === null) {
        group.range = {
          min: element[axis],
          max: element[axis] + element[dimension]
        };
        return;
      } // update group's range after centering the range elements


      updateRange(group, element);
    });

    if (idx && idx !== groups.length - 1) {
      groupsSize += rangeDiff(group.range);
    }
  });
  spaceInBetween = Math.abs(lastGroup.range.min - firstGroup.range.max);
  margin = Math.round((spaceInBetween - groupsSize) / (groups.length - 1));

  if (margin < groups.length - 1) {
    return;
  }

  (0, _minDash.forEach)(groups, function (group, groupIdx) {
    var delta = {},
        prevGroup;

    if (group === firstGroup || group === lastGroup) {
      return;
    }

    prevGroup = groups[groupIdx - 1];
    group.range.max = 0;
    (0, _minDash.forEach)(group.elements, function (element, idx) {
      delta[OFF_AXIS[axis]] = 0;
      delta[axis] = prevGroup.range.max - element[axis] + margin;

      if (group.range.min !== element[axis]) {
        delta[axis] += element[axis] - group.range.min;
      }

      if (delta[axis]) {
        modeling.moveElements([element], delta, element.parent);
      }

      group.range.max = Math.max(element[axis] + element[dimension], idx ? group.range.max : 0);
    });
  });
};

DistributeElements.prototype.postExecute = function (context) {};

},{"min-dash":555}],233:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = LayoutConnectionHandler;

var _minDash = require("min-dash");

/**
 * A handler that implements reversible moving of shapes.
 */
function LayoutConnectionHandler(layouter, canvas) {
  this._layouter = layouter;
  this._canvas = canvas;
}

LayoutConnectionHandler.$inject = ['layouter', 'canvas'];

LayoutConnectionHandler.prototype.execute = function (context) {
  var connection = context.connection;
  var oldWaypoints = connection.waypoints;
  (0, _minDash.assign)(context, {
    oldWaypoints: oldWaypoints
  });
  connection.waypoints = this._layouter.layoutConnection(connection, context.hints);
  return connection;
};

LayoutConnectionHandler.prototype.revert = function (context) {
  var connection = context.connection;
  connection.waypoints = context.oldWaypoints;
  return connection;
};

},{"min-dash":555}],234:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = MoveConnectionHandler;

var _minDash = require("min-dash");

var _Collections = require("../../../util/Collections");

/**
 * A handler that implements reversible moving of connections.
 *
 * The handler differs from the layout connection handler in a sense
 * that it preserves the connection layout.
 */
function MoveConnectionHandler() {}

MoveConnectionHandler.prototype.execute = function (context) {
  var connection = context.connection,
      delta = context.delta;
  var newParent = context.newParent || connection.parent,
      newParentIndex = context.newParentIndex,
      oldParent = connection.parent; // save old parent in context

  context.oldParent = oldParent;
  context.oldParentIndex = (0, _Collections.remove)(oldParent.children, connection); // add to new parent at position

  (0, _Collections.add)(newParent.children, connection, newParentIndex); // update parent

  connection.parent = newParent; // update waypoint positions

  (0, _minDash.forEach)(connection.waypoints, function (p) {
    p.x += delta.x;
    p.y += delta.y;

    if (p.original) {
      p.original.x += delta.x;
      p.original.y += delta.y;
    }
  });
  return connection;
};

MoveConnectionHandler.prototype.revert = function (context) {
  var connection = context.connection,
      newParent = connection.parent,
      oldParent = context.oldParent,
      oldParentIndex = context.oldParentIndex,
      delta = context.delta; // remove from newParent

  (0, _Collections.remove)(newParent.children, connection); // restore previous location in old parent

  (0, _Collections.add)(oldParent.children, connection, oldParentIndex); // restore parent

  connection.parent = oldParent; // revert to old waypoint positions

  (0, _minDash.forEach)(connection.waypoints, function (p) {
    p.x -= delta.x;
    p.y -= delta.y;

    if (p.original) {
      p.original.x -= delta.x;
      p.original.y -= delta.y;
    }
  });
  return connection;
};

},{"../../../util/Collections":313,"min-dash":555}],235:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = MoveElementsHandler;

var _MoveHelper = _interopRequireDefault(require("./helper/MoveHelper"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A handler that implements reversible moving of shapes.
 */
function MoveElementsHandler(modeling) {
  this._helper = new _MoveHelper.default(modeling);
}

MoveElementsHandler.$inject = ['modeling'];

MoveElementsHandler.prototype.preExecute = function (context) {
  context.closure = this._helper.getClosure(context.shapes);
};

MoveElementsHandler.prototype.postExecute = function (context) {
  var hints = context.hints,
      primaryShape;

  if (hints && hints.primaryShape) {
    primaryShape = hints.primaryShape;
    hints.oldParent = primaryShape.parent;
  }

  this._helper.moveClosure(context.closure, context.delta, context.newParent, context.newHost, primaryShape);
};

},{"./helper/MoveHelper":246}],236:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = MoveShapeHandler;

var _minDash = require("min-dash");

var _MoveHelper = _interopRequireDefault(require("./helper/MoveHelper"));

var _Collections = require("../../../util/Collections");

var _AnchorsHelper = require("./helper/AnchorsHelper");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A handler that implements reversible moving of shapes.
 */
function MoveShapeHandler(modeling) {
  this._modeling = modeling;
  this._helper = new _MoveHelper.default(modeling);
}

MoveShapeHandler.$inject = ['modeling'];

MoveShapeHandler.prototype.execute = function (context) {
  var shape = context.shape,
      delta = context.delta,
      newParent = context.newParent || shape.parent,
      newParentIndex = context.newParentIndex,
      oldParent = shape.parent;
  context.oldBounds = (0, _minDash.pick)(shape, ['x', 'y', 'width', 'height']); // save old parent in context

  context.oldParent = oldParent;
  context.oldParentIndex = (0, _Collections.remove)(oldParent.children, shape); // add to new parent at position

  (0, _Collections.add)(newParent.children, shape, newParentIndex); // update shape parent + position

  (0, _minDash.assign)(shape, {
    parent: newParent,
    x: shape.x + delta.x,
    y: shape.y + delta.y
  });
  return shape;
};

MoveShapeHandler.prototype.postExecute = function (context) {
  var shape = context.shape,
      delta = context.delta,
      hints = context.hints;
  var modeling = this._modeling;

  if (hints.layout !== false) {
    (0, _minDash.forEach)(shape.incoming, function (c) {
      modeling.layoutConnection(c, {
        connectionEnd: (0, _AnchorsHelper.getMovedTargetAnchor)(c, shape, delta)
      });
    });
    (0, _minDash.forEach)(shape.outgoing, function (c) {
      modeling.layoutConnection(c, {
        connectionStart: (0, _AnchorsHelper.getMovedSourceAnchor)(c, shape, delta)
      });
    });
  }

  if (hints.recurse !== false) {
    this.moveChildren(context);
  }
};

MoveShapeHandler.prototype.revert = function (context) {
  var shape = context.shape,
      oldParent = context.oldParent,
      oldParentIndex = context.oldParentIndex,
      delta = context.delta; // restore previous location in old parent

  (0, _Collections.add)(oldParent.children, shape, oldParentIndex); // revert to old position and parent

  (0, _minDash.assign)(shape, {
    parent: oldParent,
    x: shape.x - delta.x,
    y: shape.y - delta.y
  });
  return shape;
};

MoveShapeHandler.prototype.moveChildren = function (context) {
  var delta = context.delta,
      shape = context.shape;

  this._helper.moveRecursive(shape.children, delta, null);
};

MoveShapeHandler.prototype.getNewParent = function (context) {
  return context.newParent || context.shape.parent;
};

},{"../../../util/Collections":313,"./helper/AnchorsHelper":244,"./helper/MoveHelper":246,"min-dash":555}],237:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ReconnectConnectionHandler;

var _minDash = require("min-dash");

/**
 * Reconnect connection handler
 */
function ReconnectConnectionHandler(modeling) {
  this._modeling = modeling;
}

ReconnectConnectionHandler.$inject = ['modeling'];

ReconnectConnectionHandler.prototype.execute = function (context) {
  var newSource = context.newSource,
      newTarget = context.newTarget,
      connection = context.connection,
      dockingOrPoints = context.dockingOrPoints;

  if (!newSource && !newTarget) {
    throw new Error('newSource or newTarget required');
  }

  if ((0, _minDash.isArray)(dockingOrPoints)) {
    context.oldWaypoints = connection.waypoints;
    connection.waypoints = dockingOrPoints;
  }

  if (newSource) {
    context.oldSource = connection.source;
    connection.source = newSource;
  }

  if (newTarget) {
    context.oldTarget = connection.target;
    connection.target = newTarget;
  }

  return connection;
};

ReconnectConnectionHandler.prototype.postExecute = function (context) {
  var connection = context.connection,
      newSource = context.newSource,
      newTarget = context.newTarget,
      dockingOrPoints = context.dockingOrPoints,
      hints = context.hints || {};
  var layoutConnectionHints = {};

  if (hints.connectionStart) {
    layoutConnectionHints.connectionStart = hints.connectionStart;
  }

  if (hints.connectionEnd) {
    layoutConnectionHints.connectionEnd = hints.connectionEnd;
  }

  if (hints.layoutConnection === false) {
    return;
  }

  if (newSource && (!newTarget || hints.docking === 'source')) {
    layoutConnectionHints.connectionStart = layoutConnectionHints.connectionStart || getDocking((0, _minDash.isArray)(dockingOrPoints) ? dockingOrPoints[0] : dockingOrPoints);
  }

  if (newTarget && (!newSource || hints.docking === 'target')) {
    layoutConnectionHints.connectionEnd = layoutConnectionHints.connectionEnd || getDocking((0, _minDash.isArray)(dockingOrPoints) ? dockingOrPoints[dockingOrPoints.length - 1] : dockingOrPoints);
  }

  if (hints.newWaypoints) {
    layoutConnectionHints.waypoints = hints.newWaypoints;
  }

  this._modeling.layoutConnection(connection, layoutConnectionHints);
};

ReconnectConnectionHandler.prototype.revert = function (context) {
  var oldSource = context.oldSource,
      oldTarget = context.oldTarget,
      oldWaypoints = context.oldWaypoints,
      connection = context.connection;

  if (oldSource) {
    connection.source = oldSource;
  }

  if (oldTarget) {
    connection.target = oldTarget;
  }

  if (oldWaypoints) {
    connection.waypoints = oldWaypoints;
  }

  return connection;
}; // helpers //////////


function getDocking(point) {
  return point.original || point;
}

},{"min-dash":555}],238:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ReplaceShapeHandler;

var _minDash = require("min-dash");

var _AnchorsHelper = require("./helper/AnchorsHelper");

/**
 * Replace shape by adding new shape and removing old shape. Incoming and outgoing connections will
 * be kept if possible.
 *
 * @class
 * @constructor
 *
 * @param {Modeling} modeling
 * @param {Rules} rules
 */
function ReplaceShapeHandler(modeling, rules) {
  this._modeling = modeling;
  this._rules = rules;
}

ReplaceShapeHandler.$inject = ['modeling', 'rules'];
/**
 * Add new shape.
 *
 * @param {Object} context
 * @param {djs.model.Shape} context.oldShape
 * @param {Object} context.newData
 * @param {string} context.newData.type
 * @param {number} context.newData.x
 * @param {number} context.newData.y
 * @param {Object} [hints]
 */

ReplaceShapeHandler.prototype.preExecute = function (context) {
  var self = this,
      modeling = this._modeling,
      rules = this._rules;
  var oldShape = context.oldShape,
      newData = context.newData,
      hints = context.hints || {},
      newShape;

  function canReconnect(source, target, connection) {
    return rules.allowed('connection.reconnect', {
      connection: connection,
      source: source,
      target: target
    });
  } // (1) add new shape at given position


  var position = {
    x: newData.x,
    y: newData.y
  };
  var oldBounds = {
    x: oldShape.x,
    y: oldShape.y,
    width: oldShape.width,
    height: oldShape.height
  };
  newShape = context.newShape = context.newShape || self.createShape(newData, position, oldShape.parent, hints); // (2) update host

  if (oldShape.host) {
    modeling.updateAttachment(newShape, oldShape.host);
  } // (3) adopt all children from old shape


  var children;

  if (hints.moveChildren !== false) {
    children = oldShape.children.slice();
    modeling.moveElements(children, {
      x: 0,
      y: 0
    }, newShape, hints);
  } // (4) reconnect connections to new shape if possible


  var incoming = oldShape.incoming.slice(),
      outgoing = oldShape.outgoing.slice();
  (0, _minDash.forEach)(incoming, function (connection) {
    var source = connection.source,
        allowed = canReconnect(source, newShape, connection);

    if (allowed) {
      self.reconnectEnd(connection, newShape, (0, _AnchorsHelper.getResizedTargetAnchor)(connection, newShape, oldBounds), hints);
    }
  });
  (0, _minDash.forEach)(outgoing, function (connection) {
    var target = connection.target,
        allowed = canReconnect(newShape, target, connection);

    if (allowed) {
      self.reconnectStart(connection, newShape, (0, _AnchorsHelper.getResizedSourceAnchor)(connection, newShape, oldBounds), hints);
    }
  });
};
/**
 * Remove old shape.
 */


ReplaceShapeHandler.prototype.postExecute = function (context) {
  var oldShape = context.oldShape;

  this._modeling.removeShape(oldShape);
};

ReplaceShapeHandler.prototype.execute = function (context) {};

ReplaceShapeHandler.prototype.revert = function (context) {};

ReplaceShapeHandler.prototype.createShape = function (shape, position, target, hints) {
  return this._modeling.createShape(shape, position, target, hints);
};

ReplaceShapeHandler.prototype.reconnectStart = function (connection, newSource, dockingPoint, hints) {
  this._modeling.reconnectStart(connection, newSource, dockingPoint, hints);
};

ReplaceShapeHandler.prototype.reconnectEnd = function (connection, newTarget, dockingPoint, hints) {
  this._modeling.reconnectEnd(connection, newTarget, dockingPoint, hints);
};

},{"./helper/AnchorsHelper":244,"min-dash":555}],239:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ResizeShapeHandler;

var _minDash = require("min-dash");

var _AnchorsHelper = require("./helper/AnchorsHelper");

/**
 * A handler that implements reversible resizing of shapes.
 *
 * @param {Modeling} modeling
 */
function ResizeShapeHandler(modeling) {
  this._modeling = modeling;
}

ResizeShapeHandler.$inject = ['modeling'];
/**
 * {
 *   shape: {....}
 *   newBounds: {
 *     width:  20,
 *     height: 40,
 *     x:       5,
 *     y:      10
 *   }
 *
 * }
 */

ResizeShapeHandler.prototype.execute = function (context) {
  var shape = context.shape,
      newBounds = context.newBounds,
      minBounds = context.minBounds;

  if (newBounds.x === undefined || newBounds.y === undefined || newBounds.width === undefined || newBounds.height === undefined) {
    throw new Error('newBounds must have {x, y, width, height} properties');
  }

  if (minBounds && (newBounds.width < minBounds.width || newBounds.height < minBounds.height)) {
    throw new Error('width and height cannot be less than minimum height and width');
  } else if (!minBounds && newBounds.width < 10 || newBounds.height < 10) {
    throw new Error('width and height cannot be less than 10px');
  } // save old bbox in context


  context.oldBounds = {
    width: shape.width,
    height: shape.height,
    x: shape.x,
    y: shape.y
  }; // update shape

  (0, _minDash.assign)(shape, {
    width: newBounds.width,
    height: newBounds.height,
    x: newBounds.x,
    y: newBounds.y
  });
  return shape;
};

ResizeShapeHandler.prototype.postExecute = function (context) {
  var modeling = this._modeling;
  var shape = context.shape,
      oldBounds = context.oldBounds,
      hints = context.hints || {};

  if (hints.layout === false) {
    return;
  }

  (0, _minDash.forEach)(shape.incoming, function (c) {
    modeling.layoutConnection(c, {
      connectionEnd: (0, _AnchorsHelper.getResizedTargetAnchor)(c, shape, oldBounds)
    });
  });
  (0, _minDash.forEach)(shape.outgoing, function (c) {
    modeling.layoutConnection(c, {
      connectionStart: (0, _AnchorsHelper.getResizedSourceAnchor)(c, shape, oldBounds)
    });
  });
};

ResizeShapeHandler.prototype.revert = function (context) {
  var shape = context.shape,
      oldBounds = context.oldBounds; // restore previous bbox

  (0, _minDash.assign)(shape, {
    width: oldBounds.width,
    height: oldBounds.height,
    x: oldBounds.x,
    y: oldBounds.y
  });
  return shape;
};

},{"./helper/AnchorsHelper":244,"min-dash":555}],240:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SpaceToolHandler;

var _minDash = require("min-dash");

var _SpaceUtil = require("../../space-tool/SpaceUtil");

var _AnchorsHelper = require("./helper/AnchorsHelper");

/**
 * Add or remove space by moving and resizing shapes and updating connection waypoints.
 */
function SpaceToolHandler(modeling) {
  this._modeling = modeling;
}

SpaceToolHandler.$inject = ['modeling'];

SpaceToolHandler.prototype.preExecute = function (context) {
  var delta = context.delta,
      direction = context.direction,
      movingShapes = context.movingShapes,
      resizingShapes = context.resizingShapes,
      start = context.start,
      oldBounds = {}; // (1) move shapes

  this.moveShapes(movingShapes, delta); // (2a) save old bounds of resized shapes

  (0, _minDash.forEach)(resizingShapes, function (shape) {
    oldBounds[shape.id] = getBounds(shape);
  }); // (2b) resize shapes

  this.resizeShapes(resizingShapes, delta, direction); // (3) update connection waypoints

  this.updateConnectionWaypoints((0, _SpaceUtil.getWaypointsUpdatingConnections)(movingShapes, resizingShapes), delta, direction, start, movingShapes, resizingShapes, oldBounds);
};

SpaceToolHandler.prototype.execute = function () {};

SpaceToolHandler.prototype.revert = function () {};

SpaceToolHandler.prototype.moveShapes = function (shapes, delta) {
  var self = this;
  (0, _minDash.forEach)(shapes, function (element) {
    self._modeling.moveShape(element, delta, null, {
      autoResize: false,
      layout: false,
      recurse: false
    });
  });
};

SpaceToolHandler.prototype.resizeShapes = function (shapes, delta, direction) {
  var self = this;
  (0, _minDash.forEach)(shapes, function (shape) {
    var newBounds = (0, _SpaceUtil.resizeBounds)(shape, direction, delta);

    self._modeling.resizeShape(shape, newBounds, null, {
      attachSupport: false,
      autoResize: false,
      layout: false
    });
  });
};
/**
 * Update connections waypoints according to the rules:
 *   1. Both source and target are moved/resized => move waypoints by the delta
 *   2. Only one of source and target is moved/resized => re-layout connection with moved start/end
 */


SpaceToolHandler.prototype.updateConnectionWaypoints = function (connections, delta, direction, start, movingShapes, resizingShapes, oldBounds) {
  var self = this,
      affectedShapes = movingShapes.concat(resizingShapes);
  (0, _minDash.forEach)(connections, function (connection) {
    var source = connection.source,
        target = connection.target,
        waypoints = copyWaypoints(connection),
        axis = getAxisFromDirection(direction),
        layoutHints = {
      labelBehavior: false
    };

    if (includes(affectedShapes, source) && includes(affectedShapes, target)) {
      // move waypoints
      waypoints = (0, _minDash.map)(waypoints, function (waypoint) {
        if (shouldMoveWaypoint(waypoint, start, direction)) {
          // move waypoint
          waypoint[axis] = waypoint[axis] + delta[axis];
        }

        if (waypoint.original && shouldMoveWaypoint(waypoint.original, start, direction)) {
          // move waypoint original
          waypoint.original[axis] = waypoint.original[axis] + delta[axis];
        }

        return waypoint;
      });

      self._modeling.updateWaypoints(connection, waypoints, {
        labelBehavior: false
      });
    } else if (includes(affectedShapes, source) || includes(affectedShapes, target)) {
      // re-layout connection with moved start/end
      if (includes(movingShapes, source)) {
        layoutHints.connectionStart = (0, _AnchorsHelper.getMovedSourceAnchor)(connection, source, delta);
      } else if (includes(movingShapes, target)) {
        layoutHints.connectionEnd = (0, _AnchorsHelper.getMovedTargetAnchor)(connection, target, delta);
      } else if (includes(resizingShapes, source)) {
        layoutHints.connectionStart = (0, _AnchorsHelper.getResizedSourceAnchor)(connection, source, oldBounds[source.id]);
      } else if (includes(resizingShapes, target)) {
        layoutHints.connectionEnd = (0, _AnchorsHelper.getResizedTargetAnchor)(connection, target, oldBounds[target.id]);
      }

      self._modeling.layoutConnection(connection, layoutHints);
    }
  });
}; // helpers //////////


function copyWaypoint(waypoint) {
  return (0, _minDash.assign)({}, waypoint);
}

function copyWaypoints(connection) {
  return (0, _minDash.map)(connection.waypoints, function (waypoint) {
    waypoint = copyWaypoint(waypoint);

    if (waypoint.original) {
      waypoint.original = copyWaypoint(waypoint.original);
    }

    return waypoint;
  });
}

function getAxisFromDirection(direction) {
  switch (direction) {
    case 'n':
      return 'y';

    case 'w':
      return 'x';

    case 's':
      return 'y';

    case 'e':
      return 'x';
  }
}

function shouldMoveWaypoint(waypoint, start, direction) {
  var relevantAxis = getAxisFromDirection(direction);

  if (/e|s/.test(direction)) {
    return waypoint[relevantAxis] > start;
  } else if (/n|w/.test(direction)) {
    return waypoint[relevantAxis] < start;
  }
}

function includes(array, item) {
  return array.indexOf(item) !== -1;
}

function getBounds(shape) {
  return {
    x: shape.x,
    y: shape.y,
    height: shape.height,
    width: shape.width
  };
}

},{"../../space-tool/SpaceUtil":287,"./helper/AnchorsHelper":244,"min-dash":555}],241:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ToggleShapeCollapseHandler;

var _minDash = require("min-dash");

/**
 * A handler that toggles the collapsed state of an element
 * and the visibility of all its children.
 *
 * @param {Modeling} modeling
 */
function ToggleShapeCollapseHandler(modeling) {
  this._modeling = modeling;
}

ToggleShapeCollapseHandler.$inject = ['modeling'];

ToggleShapeCollapseHandler.prototype.execute = function (context) {
  var shape = context.shape,
      children = shape.children; // recursively remember previous visibility of children

  context.oldChildrenVisibility = getElementsVisibilityRecursive(children); // toggle state

  shape.collapsed = !shape.collapsed; // recursively hide/show children

  var result = setHiddenRecursive(children, shape.collapsed);
  return [shape].concat(result);
};

ToggleShapeCollapseHandler.prototype.revert = function (context) {
  var shape = context.shape,
      oldChildrenVisibility = context.oldChildrenVisibility;
  var children = shape.children; // recursively set old visability of children

  var result = restoreVisibilityRecursive(children, oldChildrenVisibility); // retoggle state

  shape.collapsed = !shape.collapsed;
  return [shape].concat(result);
}; // helpers //////////////////////

/**
 * Return a map { elementId -> hiddenState}.
 *
 * @param {Array<djs.model.Shape>} elements
 *
 * @return {Object}
 */


function getElementsVisibilityRecursive(elements) {
  var result = {};
  (0, _minDash.forEach)(elements, function (element) {
    result[element.id] = element.hidden;

    if (element.children) {
      result = (0, _minDash.assign)({}, result, getElementsVisibilityRecursive(element.children));
    }
  });
  return result;
}

function setHiddenRecursive(elements, newHidden) {
  var result = [];
  (0, _minDash.forEach)(elements, function (element) {
    element.hidden = newHidden;
    result = result.concat(element);

    if (element.children) {
      result = result.concat(setHiddenRecursive(element.children, element.collapsed || newHidden));
    }
  });
  return result;
}

function restoreVisibilityRecursive(elements, lastState) {
  var result = [];
  (0, _minDash.forEach)(elements, function (element) {
    element.hidden = lastState[element.id];
    result = result.concat(element);

    if (element.children) {
      result = result.concat(restoreVisibilityRecursive(element.children, lastState));
    }
  });
  return result;
}

},{"min-dash":555}],242:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = UpdateAttachmentHandler;

var _Collections = require("../../../util/Collections");

/**
 * A handler that implements reversible attaching/detaching of shapes.
 */
function UpdateAttachmentHandler(modeling) {
  this._modeling = modeling;
}

UpdateAttachmentHandler.$inject = ['modeling'];

UpdateAttachmentHandler.prototype.execute = function (context) {
  var shape = context.shape,
      newHost = context.newHost,
      oldHost = shape.host; // (0) detach from old host

  context.oldHost = oldHost;
  context.attacherIdx = removeAttacher(oldHost, shape); // (1) attach to new host

  addAttacher(newHost, shape); // (2) update host

  shape.host = newHost;
  return shape;
};

UpdateAttachmentHandler.prototype.revert = function (context) {
  var shape = context.shape,
      newHost = context.newHost,
      oldHost = context.oldHost,
      attacherIdx = context.attacherIdx; // (2) update host

  shape.host = oldHost; // (1) attach to new host

  removeAttacher(newHost, shape); // (0) detach from old host

  addAttacher(oldHost, shape, attacherIdx);
  return shape;
};

function removeAttacher(host, attacher) {
  // remove attacher from host
  return (0, _Collections.remove)(host && host.attachers, attacher);
}

function addAttacher(host, attacher, idx) {
  if (!host) {
    return;
  }

  var attachers = host.attachers;

  if (!attachers) {
    host.attachers = attachers = [];
  }

  (0, _Collections.add)(attachers, attacher, idx);
}

},{"../../../util/Collections":313}],243:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = UpdateWaypointsHandler;

function UpdateWaypointsHandler() {}

UpdateWaypointsHandler.prototype.execute = function (context) {
  var connection = context.connection,
      newWaypoints = context.newWaypoints;
  context.oldWaypoints = connection.waypoints;
  connection.waypoints = newWaypoints;
  return connection;
};

UpdateWaypointsHandler.prototype.revert = function (context) {
  var connection = context.connection,
      oldWaypoints = context.oldWaypoints;
  connection.waypoints = oldWaypoints;
  return connection;
};

},{}],244:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getResizedSourceAnchor = getResizedSourceAnchor;
exports.getResizedTargetAnchor = getResizedTargetAnchor;
exports.getMovedSourceAnchor = getMovedSourceAnchor;
exports.getMovedTargetAnchor = getMovedTargetAnchor;

var _AttachUtil = require("../../../../util/AttachUtil");

var _LayoutUtil = require("../../../../layout/LayoutUtil");

var _minDash = require("min-dash");

function getResizedSourceAnchor(connection, shape, oldBounds) {
  var waypoints = safeGetWaypoints(connection),
      waypointsInsideNewBounds = getWaypointsInsideBounds(waypoints, shape),
      oldAnchor = waypoints[0]; // new anchor is the last waypoint enclosed be resized source

  if (waypointsInsideNewBounds.length) {
    return waypointsInsideNewBounds[waypointsInsideNewBounds.length - 1];
  }

  return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape);
}

function getResizedTargetAnchor(connection, shape, oldBounds) {
  var waypoints = safeGetWaypoints(connection),
      waypointsInsideNewBounds = getWaypointsInsideBounds(waypoints, shape),
      oldAnchor = waypoints[waypoints.length - 1]; // new anchor is the first waypoint enclosed be resized target

  if (waypointsInsideNewBounds.length) {
    return waypointsInsideNewBounds[0];
  }

  return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape);
}

function getMovedSourceAnchor(connection, source, moveDelta) {
  var waypoints = safeGetWaypoints(connection),
      oldBounds = subtract(source, moveDelta),
      oldAnchor = waypoints[0];
  return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, source);
}

function getMovedTargetAnchor(connection, target, moveDelta) {
  var waypoints = safeGetWaypoints(connection),
      oldBounds = subtract(target, moveDelta),
      oldAnchor = waypoints[waypoints.length - 1];
  return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, target);
} // helpers //////////////////////


function subtract(bounds, delta) {
  return {
    x: bounds.x - delta.x,
    y: bounds.y - delta.y,
    width: bounds.width,
    height: bounds.height
  };
}
/**
 * Return waypoints of given connection; throw if non exists (should not happen!!).
 *
 * @param {Connection} connection
 *
 * @return {Array<Point>}
 */


function safeGetWaypoints(connection) {
  var waypoints = connection.waypoints;

  if (!waypoints.length) {
    throw new Error('connection#' + connection.id + ': no waypoints');
  }

  return waypoints;
}

function getWaypointsInsideBounds(waypoints, bounds) {
  var originalWaypoints = (0, _minDash.map)(waypoints, getOriginal);
  return (0, _minDash.filter)(originalWaypoints, function (waypoint) {
    return isInsideBounds(waypoint, bounds);
  });
}
/**
 * Checks if point is inside bounds, incl. edges.
 *
 * @param {Point} point
 * @param {Bounds} bounds
 */


function isInsideBounds(point, bounds) {
  return (0, _LayoutUtil.getOrientation)(bounds, point, 1) === 'intersect';
}

function getOriginal(point) {
  return point.original || point;
}

},{"../../../../layout/LayoutUtil":300,"../../../../util/AttachUtil":311,"min-dash":555}],245:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = MoveClosure;

var _minDash = require("min-dash");

var _Elements = require("../../../../util/Elements");

function MoveClosure() {
  this.allShapes = {};
  this.allConnections = {};
  this.enclosedElements = {};
  this.enclosedConnections = {};
  this.topLevel = {};
}

MoveClosure.prototype.add = function (element, isTopLevel) {
  return this.addAll([element], isTopLevel);
};

MoveClosure.prototype.addAll = function (elements, isTopLevel) {
  var newClosure = (0, _Elements.getClosure)(elements, !!isTopLevel, this);
  (0, _minDash.assign)(this, newClosure);
  return this;
};

},{"../../../../util/Elements":315,"min-dash":555}],246:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = MoveHelper;

var _minDash = require("min-dash");

var _AnchorsHelper = require("./AnchorsHelper");

var _MoveClosure = _interopRequireDefault(require("./MoveClosure"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A helper that is able to carry out serialized move
 * operations on multiple elements.
 *
 * @param {Modeling} modeling
 */
function MoveHelper(modeling) {
  this._modeling = modeling;
}
/**
 * Move the specified elements and all children by the given delta.
 *
 * This moves all enclosed connections, too and layouts all affected
 * external connections.
 *
 * @param  {Array<djs.model.Base>} elements
 * @param  {Point} delta
 * @param  {djs.model.Base} newParent applied to the first level of shapes
 *
 * @return {Array<djs.model.Base>} list of touched elements
 */


MoveHelper.prototype.moveRecursive = function (elements, delta, newParent) {
  if (!elements) {
    return [];
  } else {
    return this.moveClosure(this.getClosure(elements), delta, newParent);
  }
};
/**
 * Move the given closure of elmements.
 *
 * @param {Object} closure
 * @param {Point} delta
 * @param {djs.model.Base} [newParent]
 * @param {djs.model.Base} [newHost]
 */


MoveHelper.prototype.moveClosure = function (closure, delta, newParent, newHost, primaryShape) {
  var modeling = this._modeling;
  var allShapes = closure.allShapes,
      allConnections = closure.allConnections,
      enclosedConnections = closure.enclosedConnections,
      topLevel = closure.topLevel,
      keepParent = false;

  if (primaryShape && primaryShape.parent === newParent) {
    keepParent = true;
  } // move all shapes


  (0, _minDash.forEach)(allShapes, function (shape) {
    // move the element according to the given delta
    modeling.moveShape(shape, delta, topLevel[shape.id] && !keepParent && newParent, {
      recurse: false,
      layout: false
    });
  }); // move all child connections / layout external connections

  (0, _minDash.forEach)(allConnections, function (c) {
    var sourceMoved = !!allShapes[c.source.id],
        targetMoved = !!allShapes[c.target.id];

    if (enclosedConnections[c.id] && sourceMoved && targetMoved) {
      modeling.moveConnection(c, delta, topLevel[c.id] && !keepParent && newParent);
    } else {
      modeling.layoutConnection(c, {
        connectionStart: sourceMoved && (0, _AnchorsHelper.getMovedSourceAnchor)(c, c.source, delta),
        connectionEnd: targetMoved && (0, _AnchorsHelper.getMovedTargetAnchor)(c, c.target, delta)
      });
    }
  });
};
/**
 * Returns the closure for the selected elements
 *
 * @param  {Array<djs.model.Base>} elements
 * @return {MoveClosure} closure
 */


MoveHelper.prototype.getClosure = function (elements) {
  return new _MoveClosure.default().addAll(elements, true);
};

},{"./AnchorsHelper":244,"./MoveClosure":245,"min-dash":555}],247:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Mouse;
exports.createMoveEvent = createMoveEvent;

function Mouse(eventBus) {
  var self = this;
  this._lastMoveEvent = null;

  function setLastMoveEvent(mousemoveEvent) {
    self._lastMoveEvent = mousemoveEvent;
  }

  eventBus.on('canvas.init', function (context) {
    var svg = self._svg = context.svg;
    svg.addEventListener('mousemove', setLastMoveEvent);
  });
  eventBus.on('canvas.destroy', function () {
    self._lastMouseEvent = null;

    self._svg.removeEventListener('mousemove', setLastMoveEvent);
  });
}

Mouse.$inject = ['eventBus'];

Mouse.prototype.getLastMoveEvent = function () {
  return this._lastMoveEvent || createMoveEvent(0, 0);
}; // helpers //////////


function createMoveEvent(x, y) {
  var event = document.createEvent('MouseEvent');
  var screenX = x,
      screenY = y,
      clientX = x,
      clientY = y;

  if (event.initMouseEvent) {
    event.initMouseEvent('mousemove', true, true, window, 0, screenX, screenY, clientX, clientY, false, false, false, false, 0, null);
  }

  return event;
}

},{}],248:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _Mouse = _interopRequireDefault(require("./Mouse"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['mouse'],
  mouse: ['type', _Mouse.default]
};
exports.default = _default;

},{"./Mouse":247}],249:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = MoveEvents;

var _minDash = require("min-dash");

var _Event = require("../../util/Event");

var LOW_PRIORITY = 500,
    MEDIUM_PRIORITY = 1250,
    HIGH_PRIORITY = 1500;
var round = Math.round;

function mid(element) {
  return {
    x: element.x + round(element.width / 2),
    y: element.y + round(element.height / 2)
  };
}
/**
 * A plugin that makes shapes draggable / droppable.
 *
 * @param {EventBus} eventBus
 * @param {Dragging} dragging
 * @param {Modeling} modeling
 * @param {Selection} selection
 * @param {Rules} rules
 */


function MoveEvents(eventBus, dragging, modeling, selection, rules) {
  // rules
  function canMove(shapes, delta, position, target) {
    return rules.allowed('elements.move', {
      shapes: shapes,
      delta: delta,
      position: position,
      target: target
    });
  } // move events
  // assign a high priority to this handler to setup the environment
  // others may hook up later, e.g. at default priority and modify
  // the move environment.
  //
  // This sets up the context with
  //
  // * shape: the primary shape being moved
  // * shapes: a list of shapes to be moved
  // * validatedShapes: a list of shapes that are being checked
  //                    against the rules before and during move
  //


  eventBus.on('shape.move.start', HIGH_PRIORITY, function (event) {
    var context = event.context,
        shape = event.shape,
        shapes = selection.get().slice(); // move only single shape if the dragged element
    // is not part of the current selection

    if (shapes.indexOf(shape) === -1) {
      shapes = [shape];
    } // ensure we remove nested elements in the collection
    // and add attachers for a proper dragger


    shapes = removeNested(shapes); // attach shapes to drag context

    (0, _minDash.assign)(context, {
      shapes: shapes,
      validatedShapes: shapes,
      shape: shape
    });
  }); // assign a high priority to this handler to setup the environment
  // others may hook up later, e.g. at default priority and modify
  // the move environment
  //

  eventBus.on('shape.move.start', MEDIUM_PRIORITY, function (event) {
    var context = event.context,
        validatedShapes = context.validatedShapes,
        canExecute;
    canExecute = context.canExecute = canMove(validatedShapes); // check if we can move the elements

    if (!canExecute) {
      return false;
    }
  }); // assign a low priority to this handler
  // to let others modify the move event before we update
  // the context
  //

  eventBus.on('shape.move.move', LOW_PRIORITY, function (event) {
    var context = event.context,
        validatedShapes = context.validatedShapes,
        hover = event.hover,
        delta = {
      x: event.dx,
      y: event.dy
    },
        position = {
      x: event.x,
      y: event.y
    },
        canExecute; // check if we can move the elements

    canExecute = canMove(validatedShapes, delta, position, hover);
    context.delta = delta;
    context.canExecute = canExecute; // simply ignore move over

    if (canExecute === null) {
      context.target = null;
      return;
    }

    context.target = hover;
  });
  eventBus.on('shape.move.end', function (event) {
    var context = event.context;
    var delta = context.delta,
        canExecute = context.canExecute,
        isAttach = canExecute === 'attach',
        shapes = context.shapes;

    if (canExecute === false) {
      return false;
    } // ensure we have actual pixel values deltas
    // (important when zoom level was > 1 during move)


    delta.x = round(delta.x);
    delta.y = round(delta.y);

    if (delta.x === 0 && delta.y === 0) {
      // didn't move
      return;
    }

    modeling.moveElements(shapes, delta, context.target, {
      primaryShape: context.shape,
      attach: isAttach
    });
  }); // move activation

  eventBus.on('element.mousedown', function (event) {
    var originalEvent = (0, _Event.getOriginal)(event);

    if (!originalEvent) {
      throw new Error('must supply DOM mousedown event');
    }

    return start(originalEvent, event.element);
  });
  /**
   * Start move.
   *
   * @param {MouseEvent} event
   * @param {djs.model.Shape} shape
   * @param {boolean} [activate]
   * @param {Object} [context]
   */

  function start(event, element, activate, context) {
    if ((0, _minDash.isObject)(activate)) {
      context = activate;
      activate = false;
    } // do not move connections or the root element


    if (element.waypoints || !element.parent) {
      return;
    }

    var referencePoint = mid(element);
    dragging.init(event, referencePoint, 'shape.move', {
      cursor: 'grabbing',
      autoActivate: activate,
      data: {
        shape: element,
        context: context || {}
      }
    }); // we've handled the event

    return true;
  } // API


  this.start = start;
}

MoveEvents.$inject = ['eventBus', 'dragging', 'modeling', 'selection', 'rules'];
/**
 * Return a filtered list of elements that do not contain
 * those nested into others.
 *
 * @param  {Array<djs.model.Base>} elements
 *
 * @return {Array<djs.model.Base>} filtered
 */

function removeNested(elements) {
  var ids = (0, _minDash.groupBy)(elements, 'id');
  return (0, _minDash.filter)(elements, function (element) {
    while (element = element.parent) {
      // parent in selection
      if (ids[element.id]) {
        return false;
      }
    }

    return true;
  });
}

},{"../../util/Event":317,"min-dash":555}],250:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = MovePreview;

var _minDash = require("min-dash");

var _Elements = require("../../util/Elements");

var _tinySvg = require("tiny-svg");

var _SvgTransformUtil = require("../../util/SvgTransformUtil");

var LOW_PRIORITY = 499;
var MARKER_DRAGGING = 'djs-dragging',
    MARKER_OK = 'drop-ok',
    MARKER_NOT_OK = 'drop-not-ok',
    MARKER_NEW_PARENT = 'new-parent',
    MARKER_ATTACH = 'attach-ok';
/**
 * Provides previews for moving shapes when moving.
 *
 * @param {EventBus} eventBus
 * @param {ElementRegistry} elementRegistry
 * @param {Canvas} canvas
 * @param {Styles} styles
 */

function MovePreview(eventBus, canvas, styles, previewSupport) {
  function getVisualDragShapes(shapes) {
    var elements = getAllDraggedElements(shapes);
    var filteredElements = removeEdges(elements);
    return filteredElements;
  }

  function getAllDraggedElements(shapes) {
    var allShapes = (0, _Elements.selfAndAllChildren)(shapes, true);
    var allConnections = (0, _minDash.map)(allShapes, function (shape) {
      return (shape.incoming || []).concat(shape.outgoing || []);
    });
    return (0, _minDash.flatten)(allShapes.concat(allConnections));
  }
  /**
   * Sets drop marker on an element.
   */


  function setMarker(element, marker) {
    [MARKER_ATTACH, MARKER_OK, MARKER_NOT_OK, MARKER_NEW_PARENT].forEach(function (m) {
      if (m === marker) {
        canvas.addMarker(element, m);
      } else {
        canvas.removeMarker(element, m);
      }
    });
  }
  /**
   * Make an element draggable.
   *
   * @param {Object} context
   * @param {djs.model.Base} element
   * @param {boolean} addMarker
   */


  function makeDraggable(context, element, addMarker) {
    previewSupport.addDragger(element, context.dragGroup);

    if (addMarker) {
      canvas.addMarker(element, MARKER_DRAGGING);
    }

    if (context.allDraggedElements) {
      context.allDraggedElements.push(element);
    } else {
      context.allDraggedElements = [element];
    }
  } // assign a low priority to this handler
  // to let others modify the move context before
  // we draw things


  eventBus.on('shape.move.start', LOW_PRIORITY, function (event) {
    var context = event.context,
        dragShapes = context.shapes,
        allDraggedElements = context.allDraggedElements;
    var visuallyDraggedShapes = getVisualDragShapes(dragShapes);

    if (!context.dragGroup) {
      var dragGroup = (0, _tinySvg.create)('g');
      (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events']));
      var defaultLayer = canvas.getDefaultLayer();
      (0, _tinySvg.append)(defaultLayer, dragGroup);
      context.dragGroup = dragGroup;
    } // add previews


    visuallyDraggedShapes.forEach(function (shape) {
      previewSupport.addDragger(shape, context.dragGroup);
    }); // cache all dragged elements / gfx
    // so that we can quickly undo their state changes later

    if (!allDraggedElements) {
      allDraggedElements = getAllDraggedElements(dragShapes);
    } else {
      allDraggedElements = (0, _minDash.flatten)([allDraggedElements, getAllDraggedElements(dragShapes)]);
    } // add dragging marker


    (0, _minDash.forEach)(allDraggedElements, function (e) {
      canvas.addMarker(e, MARKER_DRAGGING);
    });
    context.allDraggedElements = allDraggedElements; // determine, if any of the dragged elements have different parents

    context.differentParents = haveDifferentParents(dragShapes);
  }); // update previews

  eventBus.on('shape.move.move', LOW_PRIORITY, function (event) {
    var context = event.context,
        dragGroup = context.dragGroup,
        target = context.target,
        parent = context.shape.parent,
        canExecute = context.canExecute;

    if (target) {
      if (canExecute === 'attach') {
        setMarker(target, MARKER_ATTACH);
      } else if (context.canExecute && target && target.id !== parent.id) {
        setMarker(target, MARKER_NEW_PARENT);
      } else {
        setMarker(target, context.canExecute ? MARKER_OK : MARKER_NOT_OK);
      }
    }

    (0, _SvgTransformUtil.translate)(dragGroup, event.dx, event.dy);
  });
  eventBus.on(['shape.move.out', 'shape.move.cleanup'], function (event) {
    var context = event.context,
        target = context.target;

    if (target) {
      setMarker(target, null);
    }
  }); // remove previews

  eventBus.on('shape.move.cleanup', function (event) {
    var context = event.context,
        allDraggedElements = context.allDraggedElements,
        dragGroup = context.dragGroup; // remove dragging marker

    (0, _minDash.forEach)(allDraggedElements, function (e) {
      canvas.removeMarker(e, MARKER_DRAGGING);
    });

    if (dragGroup) {
      (0, _tinySvg.remove)(dragGroup);
    }
  }); // API //////////////////////

  /**
   * Make an element draggable.
   *
   * @param {Object} context
   * @param {djs.model.Base} element
   * @param {boolean} addMarker
   */

  this.makeDraggable = makeDraggable;
}

MovePreview.$inject = ['eventBus', 'canvas', 'styles', 'previewSupport']; // helpers //////////////////////

/**
 * returns elements minus all connections
 * where source or target is not elements
 */

function removeEdges(elements) {
  var filteredElements = (0, _minDash.filter)(elements, function (element) {
    if (!isConnection(element)) {
      return true;
    } else {
      return (0, _minDash.find)(elements, (0, _minDash.matchPattern)({
        id: element.source.id
      })) && (0, _minDash.find)(elements, (0, _minDash.matchPattern)({
        id: element.target.id
      }));
    }
  });
  return filteredElements;
}

function haveDifferentParents(elements) {
  return (0, _minDash.size)((0, _minDash.groupBy)(elements, function (e) {
    return e.parent && e.parent.id;
  })) !== 1;
}
/**
 * Checks if an element is a connection.
 */


function isConnection(element) {
  return element.waypoints;
}

},{"../../util/Elements":315,"../../util/SvgTransformUtil":328,"min-dash":555,"tiny-svg":567}],251:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _interactionEvents = _interopRequireDefault(require("../interaction-events"));

var _selection = _interopRequireDefault(require("../selection"));

var _outline = _interopRequireDefault(require("../outline"));

var _rules = _interopRequireDefault(require("../rules"));

var _dragging = _interopRequireDefault(require("../dragging"));

var _previewSupport = _interopRequireDefault(require("../preview-support"));

var _Move = _interopRequireDefault(require("./Move"));

var _MovePreview = _interopRequireDefault(require("./MovePreview"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_interactionEvents.default, _selection.default, _outline.default, _rules.default, _dragging.default, _previewSupport.default],
  __init__: ['move', 'movePreview'],
  move: ['type', _Move.default],
  movePreview: ['type', _MovePreview.default]
};
exports.default = _default;

},{"../dragging":197,"../interaction-events":211,"../outline":254,"../preview-support":262,"../rules":272,"../selection":278,"./Move":249,"./MovePreview":250}],252:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = OrderingProvider;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * An abstract provider that allows modelers to implement a custom
 * ordering of diagram elements on the canvas.
 *
 * It makes sure that the order is always preserved during element
 * creation and move operations.
 *
 * In order to use this behavior, inherit from it and override
 * the method {@link OrderingProvider#getOrdering}.
 *
 * @example
 *
 * ```javascript
 * function CustomOrderingProvider(eventBus) {
 *   OrderingProvider.call(this, eventBus);
 *
 *   this.getOrdering = function(element, newParent) {
 *     // always insert elements at the front
 *     // when moving
 *     return {
 *       index: 0,
 *       parent: newParent
 *     };
 *   };
 * }
 * ```
 *
 * @param {EventBus} eventBus
 */
function OrderingProvider(eventBus) {
  _CommandInterceptor.default.call(this, eventBus);

  var self = this;
  this.preExecute(['shape.create', 'connection.create'], function (event) {
    var context = event.context,
        element = context.shape || context.connection,
        parent = context.parent;
    var ordering = self.getOrdering(element, parent);

    if (ordering) {
      if (ordering.parent !== undefined) {
        context.parent = ordering.parent;
      }

      context.parentIndex = ordering.index;
    }
  });
  this.preExecute(['shape.move', 'connection.move'], function (event) {
    var context = event.context,
        element = context.shape || context.connection,
        parent = context.newParent || element.parent;
    var ordering = self.getOrdering(element, parent);

    if (ordering) {
      if (ordering.parent !== undefined) {
        context.newParent = ordering.parent;
      }

      context.newParentIndex = ordering.index;
    }
  });
}
/**
 * Return a custom ordering of the element, both in terms
 * of parent element and index in the new parent.
 *
 * Implementors of this method must return an object with
 * `parent` _and_ `index` in it.
 *
 * @param {djs.model.Base} element
 * @param {djs.model.Shape} newParent
 *
 * @return {Object} ordering descriptor
 */


OrderingProvider.prototype.getOrdering = function (element, newParent) {
  return null;
};

(0, _inherits.default)(OrderingProvider, _CommandInterceptor.default);

},{"../../command/CommandInterceptor":145,"inherits":347}],253:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Outline;

var _Elements = require("../../util/Elements");

var _tinySvg = require("tiny-svg");

var _minDom = require("min-dom");

var _minDash = require("min-dash");

var LOW_PRIORITY = 500;

/**
 * @class
 *
 * A plugin that adds an outline to shapes and connections that may be activated and styled
 * via CSS classes.
 *
 * @param {EventBus} eventBus
 * @param {Styles} styles
 * @param {ElementRegistry} elementRegistry
 */
function Outline(eventBus, styles, elementRegistry) {
  this.offset = 6;
  var OUTLINE_STYLE = styles.cls('djs-outline', ['no-fill']);
  var self = this;

  function createOutline(gfx, bounds) {
    var outline = (0, _tinySvg.create)('rect');
    (0, _tinySvg.attr)(outline, (0, _minDash.assign)({
      x: 10,
      y: 10,
      width: 100,
      height: 100
    }, OUTLINE_STYLE));
    (0, _tinySvg.append)(gfx, outline);
    return outline;
  } // A low priortity is necessary, because outlines of labels have to be updated
  // after the label bounds have been updated in the renderer.


  eventBus.on(['shape.added', 'shape.changed'], LOW_PRIORITY, function (event) {
    var element = event.element,
        gfx = event.gfx;
    var outline = (0, _minDom.query)('.djs-outline', gfx);

    if (!outline) {
      outline = createOutline(gfx, element);
    }

    self.updateShapeOutline(outline, element);
  });
  eventBus.on(['connection.added', 'connection.changed'], function (event) {
    var element = event.element,
        gfx = event.gfx;
    var outline = (0, _minDom.query)('.djs-outline', gfx);

    if (!outline) {
      outline = createOutline(gfx, element);
    }

    self.updateConnectionOutline(outline, element);
  });
}
/**
 * Updates the outline of a shape respecting the dimension of the
 * element and an outline offset.
 *
 * @param  {SVGElement} outline
 * @param  {djs.model.Base} element
 */


Outline.prototype.updateShapeOutline = function (outline, element) {
  (0, _tinySvg.attr)(outline, {
    x: -this.offset,
    y: -this.offset,
    width: element.width + this.offset * 2,
    height: element.height + this.offset * 2
  });
};
/**
 * Updates the outline of a connection respecting the bounding box of
 * the connection and an outline offset.
 *
 * @param  {SVGElement} outline
 * @param  {djs.model.Base} element
 */


Outline.prototype.updateConnectionOutline = function (outline, connection) {
  var bbox = (0, _Elements.getBBox)(connection);
  (0, _tinySvg.attr)(outline, {
    x: bbox.x - this.offset,
    y: bbox.y - this.offset,
    width: bbox.width + this.offset * 2,
    height: bbox.height + this.offset * 2
  });
};

Outline.$inject = ['eventBus', 'styles', 'elementRegistry'];

},{"../../util/Elements":315,"min-dash":555,"min-dom":556,"tiny-svg":567}],254:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _Outline = _interopRequireDefault(require("./Outline"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['outline'],
  outline: ['type', _Outline.default]
};
exports.default = _default;

},{"./Outline":253}],255:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Overlays;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _Elements = require("../../util/Elements");

var _IdGenerator = _interopRequireDefault(require("../../util/IdGenerator"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

// document wide unique overlay ids
var ids = new _IdGenerator.default('ov');
var LOW_PRIORITY = 500;
/**
 * A service that allows users to attach overlays to diagram elements.
 *
 * The overlay service will take care of overlay positioning during updates.
 *
 * @example
 *
 * // add a pink badge on the top left of the shape
 * overlays.add(someShape, {
 *   position: {
 *     top: -5,
 *     left: -5
 *   },
 *   html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
 * });
 *
 * // or add via shape id
 *
 * overlays.add('some-element-id', {
 *   position: {
 *     top: -5,
 *     left: -5
 *   }
 *   html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
 * });
 *
 * // or add with optional type
 *
 * overlays.add(someShape, 'badge', {
 *   position: {
 *     top: -5,
 *     left: -5
 *   }
 *   html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
 * });
 *
 *
 * // remove an overlay
 *
 * var id = overlays.add(...);
 * overlays.remove(id);
 *
 *
 * You may configure overlay defaults during tool by providing a `config` module
 * with `overlays.defaults` as an entry:
 *
 * {
 *   overlays: {
 *     defaults: {
 *       show: {
 *         minZoom: 0.7,
 *         maxZoom: 5.0
 *       },
 *       scale: {
 *         min: 1
 *       }
 *     }
 * }
 *
 * @param {Object} config
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 * @param {ElementRegistry} elementRegistry
 */

function Overlays(config, eventBus, canvas, elementRegistry) {
  this._eventBus = eventBus;
  this._canvas = canvas;
  this._elementRegistry = elementRegistry;
  this._ids = ids;
  this._overlayDefaults = (0, _minDash.assign)({
    // no show constraints
    show: null,
    // always scale
    scale: true
  }, config && config.defaults);
  /**
   * Mapping overlayId -> overlay
   */

  this._overlays = {};
  /**
   * Mapping elementId -> overlay container
   */

  this._overlayContainers = []; // root html element for all overlays

  this._overlayRoot = createRoot(canvas.getContainer());

  this._init();
}

Overlays.$inject = ['config.overlays', 'eventBus', 'canvas', 'elementRegistry'];
/**
 * Returns the overlay with the specified id or a list of overlays
 * for an element with a given type.
 *
 * @example
 *
 * // return the single overlay with the given id
 * overlays.get('some-id');
 *
 * // return all overlays for the shape
 * overlays.get({ element: someShape });
 *
 * // return all overlays on shape with type 'badge'
 * overlays.get({ element: someShape, type: 'badge' });
 *
 * // shape can also be specified as id
 * overlays.get({ element: 'element-id', type: 'badge' });
 *
 *
 * @param {Object} search
 * @param {string} [search.id]
 * @param {string|djs.model.Base} [search.element]
 * @param {string} [search.type]
 *
 * @return {Object|Array<Object>} the overlay(s)
 */

Overlays.prototype.get = function (search) {
  if ((0, _minDash.isString)(search)) {
    search = {
      id: search
    };
  }

  if ((0, _minDash.isString)(search.element)) {
    search.element = this._elementRegistry.get(search.element);
  }

  if (search.element) {
    var container = this._getOverlayContainer(search.element, true); // return a list of overlays when searching by element (+type)


    if (container) {
      return search.type ? (0, _minDash.filter)(container.overlays, (0, _minDash.matchPattern)({
        type: search.type
      })) : container.overlays.slice();
    } else {
      return [];
    }
  } else if (search.type) {
    return (0, _minDash.filter)(this._overlays, (0, _minDash.matchPattern)({
      type: search.type
    }));
  } else {
    // return single element when searching by id
    return search.id ? this._overlays[search.id] : null;
  }
};
/**
 * Adds a HTML overlay to an element.
 *
 * @param {string|djs.model.Base}   element   attach overlay to this shape
 * @param {string}                  [type]    optional type to assign to the overlay
 * @param {Object}                  overlay   the overlay configuration
 *
 * @param {string|DOMElement}       overlay.html                 html element to use as an overlay
 * @param {Object}                  [overlay.show]               show configuration
 * @param {number}                  [overlay.show.minZoom]       minimal zoom level to show the overlay
 * @param {number}                  [overlay.show.maxZoom]       maximum zoom level to show the overlay
 * @param {Object}                  overlay.position             where to attach the overlay
 * @param {number}                  [overlay.position.left]      relative to element bbox left attachment
 * @param {number}                  [overlay.position.top]       relative to element bbox top attachment
 * @param {number}                  [overlay.position.bottom]    relative to element bbox bottom attachment
 * @param {number}                  [overlay.position.right]     relative to element bbox right attachment
 * @param {boolean|Object}          [overlay.scale=true]         false to preserve the same size regardless of
 *                                                               diagram zoom
 * @param {number}                  [overlay.scale.min]
 * @param {number}                  [overlay.scale.max]
 *
 * @return {string}                 id that may be used to reference the overlay for update or removal
 */


Overlays.prototype.add = function (element, type, overlay) {
  if ((0, _minDash.isObject)(type)) {
    overlay = type;
    type = null;
  }

  if (!element.id) {
    element = this._elementRegistry.get(element);
  }

  if (!overlay.position) {
    throw new Error('must specifiy overlay position');
  }

  if (!overlay.html) {
    throw new Error('must specifiy overlay html');
  }

  if (!element) {
    throw new Error('invalid element specified');
  }

  var id = this._ids.next();

  overlay = (0, _minDash.assign)({}, this._overlayDefaults, overlay, {
    id: id,
    type: type,
    element: element,
    html: overlay.html
  });

  this._addOverlay(overlay);

  return id;
};
/**
 * Remove an overlay with the given id or all overlays matching the given filter.
 *
 * @see Overlays#get for filter options.
 *
 * @param {string} [id]
 * @param {Object} [filter]
 */


Overlays.prototype.remove = function (filter) {
  var overlays = this.get(filter) || [];

  if (!(0, _minDash.isArray)(overlays)) {
    overlays = [overlays];
  }

  var self = this;
  (0, _minDash.forEach)(overlays, function (overlay) {
    var container = self._getOverlayContainer(overlay.element, true);

    if (overlay) {
      (0, _minDom.remove)(overlay.html);
      (0, _minDom.remove)(overlay.htmlContainer);
      delete overlay.htmlContainer;
      delete overlay.element;
      delete self._overlays[overlay.id];
    }

    if (container) {
      var idx = container.overlays.indexOf(overlay);

      if (idx !== -1) {
        container.overlays.splice(idx, 1);
      }
    }
  });
};

Overlays.prototype.show = function () {
  setVisible(this._overlayRoot);
};

Overlays.prototype.hide = function () {
  setVisible(this._overlayRoot, false);
};

Overlays.prototype.clear = function () {
  this._overlays = {};
  this._overlayContainers = [];
  (0, _minDom.clear)(this._overlayRoot);
};

Overlays.prototype._updateOverlayContainer = function (container) {
  var element = container.element,
      html = container.html; // update container left,top according to the elements x,y coordinates
  // this ensures we can attach child elements relative to this container

  var x = element.x,
      y = element.y;

  if (element.waypoints) {
    var bbox = (0, _Elements.getBBox)(element);
    x = bbox.x;
    y = bbox.y;
  }

  setPosition(html, x, y);
  (0, _minDom.attr)(container.html, 'data-container-id', element.id);
};

Overlays.prototype._updateOverlay = function (overlay) {
  var position = overlay.position,
      htmlContainer = overlay.htmlContainer,
      element = overlay.element; // update overlay html relative to shape because
  // it is already positioned on the element
  // update relative

  var left = position.left,
      top = position.top;

  if (position.right !== undefined) {
    var width;

    if (element.waypoints) {
      width = (0, _Elements.getBBox)(element).width;
    } else {
      width = element.width;
    }

    left = position.right * -1 + width;
  }

  if (position.bottom !== undefined) {
    var height;

    if (element.waypoints) {
      height = (0, _Elements.getBBox)(element).height;
    } else {
      height = element.height;
    }

    top = position.bottom * -1 + height;
  }

  setPosition(htmlContainer, left || 0, top || 0);
};

Overlays.prototype._createOverlayContainer = function (element) {
  var html = (0, _minDom.domify)('<div class="djs-overlays" style="position: absolute" />');

  this._overlayRoot.appendChild(html);

  var container = {
    html: html,
    element: element,
    overlays: []
  };

  this._updateOverlayContainer(container);

  this._overlayContainers.push(container);

  return container;
};

Overlays.prototype._updateRoot = function (viewbox) {
  var scale = viewbox.scale || 1;
  var matrix = 'matrix(' + [scale, 0, 0, scale, -1 * viewbox.x * scale, -1 * viewbox.y * scale].join(',') + ')';
  setTransform(this._overlayRoot, matrix);
};

Overlays.prototype._getOverlayContainer = function (element, raw) {
  var container = (0, _minDash.find)(this._overlayContainers, function (c) {
    return c.element === element;
  });

  if (!container && !raw) {
    return this._createOverlayContainer(element);
  }

  return container;
};

Overlays.prototype._addOverlay = function (overlay) {
  var id = overlay.id,
      element = overlay.element,
      html = overlay.html,
      htmlContainer,
      overlayContainer; // unwrap jquery (for those who need it)

  if (html.get && html.constructor.prototype.jquery) {
    html = html.get(0);
  } // create proper html elements from
  // overlay HTML strings


  if ((0, _minDash.isString)(html)) {
    html = (0, _minDom.domify)(html);
  }

  overlayContainer = this._getOverlayContainer(element);
  htmlContainer = (0, _minDom.domify)('<div class="djs-overlay" data-overlay-id="' + id + '" style="position: absolute">');
  htmlContainer.appendChild(html);

  if (overlay.type) {
    (0, _minDom.classes)(htmlContainer).add('djs-overlay-' + overlay.type);
  }

  overlay.htmlContainer = htmlContainer;
  overlayContainer.overlays.push(overlay);
  overlayContainer.html.appendChild(htmlContainer);
  this._overlays[id] = overlay;

  this._updateOverlay(overlay);

  this._updateOverlayVisibilty(overlay, this._canvas.viewbox());
};

Overlays.prototype._updateOverlayVisibilty = function (overlay, viewbox) {
  var show = overlay.show,
      minZoom = show && show.minZoom,
      maxZoom = show && show.maxZoom,
      htmlContainer = overlay.htmlContainer,
      visible = true;

  if (show) {
    if ((0, _minDash.isDefined)(minZoom) && minZoom > viewbox.scale || (0, _minDash.isDefined)(maxZoom) && maxZoom < viewbox.scale) {
      visible = false;
    }

    setVisible(htmlContainer, visible);
  }

  this._updateOverlayScale(overlay, viewbox);
};

Overlays.prototype._updateOverlayScale = function (overlay, viewbox) {
  var shouldScale = overlay.scale,
      minScale,
      maxScale,
      htmlContainer = overlay.htmlContainer;
  var scale,
      transform = '';

  if (shouldScale !== true) {
    if (shouldScale === false) {
      minScale = 1;
      maxScale = 1;
    } else {
      minScale = shouldScale.min;
      maxScale = shouldScale.max;
    }

    if ((0, _minDash.isDefined)(minScale) && viewbox.scale < minScale) {
      scale = (1 / viewbox.scale || 1) * minScale;
    }

    if ((0, _minDash.isDefined)(maxScale) && viewbox.scale > maxScale) {
      scale = (1 / viewbox.scale || 1) * maxScale;
    }
  }

  if ((0, _minDash.isDefined)(scale)) {
    transform = 'scale(' + scale + ',' + scale + ')';
  }

  setTransform(htmlContainer, transform);
};

Overlays.prototype._updateOverlaysVisibilty = function (viewbox) {
  var self = this;
  (0, _minDash.forEach)(this._overlays, function (overlay) {
    self._updateOverlayVisibilty(overlay, viewbox);
  });
};

Overlays.prototype._init = function () {
  var eventBus = this._eventBus;
  var self = this; // scroll/zoom integration

  function updateViewbox(viewbox) {
    self._updateRoot(viewbox);

    self._updateOverlaysVisibilty(viewbox);

    self.show();
  }

  eventBus.on('canvas.viewbox.changing', function (event) {
    self.hide();
  });
  eventBus.on('canvas.viewbox.changed', function (event) {
    updateViewbox(event.viewbox);
  }); // remove integration

  eventBus.on(['shape.remove', 'connection.remove'], function (e) {
    var element = e.element;
    var overlays = self.get({
      element: element
    });
    (0, _minDash.forEach)(overlays, function (o) {
      self.remove(o.id);
    });

    var container = self._getOverlayContainer(element);

    if (container) {
      (0, _minDom.remove)(container.html);

      var i = self._overlayContainers.indexOf(container);

      if (i !== -1) {
        self._overlayContainers.splice(i, 1);
      }
    }
  }); // move integration

  eventBus.on('element.changed', LOW_PRIORITY, function (e) {
    var element = e.element;

    var container = self._getOverlayContainer(element, true);

    if (container) {
      (0, _minDash.forEach)(container.overlays, function (overlay) {
        self._updateOverlay(overlay);
      });

      self._updateOverlayContainer(container);
    }
  }); // marker integration, simply add them on the overlays as classes, too.

  eventBus.on('element.marker.update', function (e) {
    var container = self._getOverlayContainer(e.element, true);

    if (container) {
      (0, _minDom.classes)(container.html)[e.add ? 'add' : 'remove'](e.marker);
    }
  }); // clear overlays with diagram

  eventBus.on('diagram.clear', this.clear, this);
}; // helpers /////////////////////////////


function createRoot(parentNode) {
  var root = (0, _minDom.domify)('<div class="djs-overlay-container" style="position: absolute; width: 0; height: 0;" />');
  parentNode.insertBefore(root, parentNode.firstChild);
  return root;
}

function setPosition(el, x, y) {
  (0, _minDash.assign)(el.style, {
    left: x + 'px',
    top: y + 'px'
  });
}

function setVisible(el, visible) {
  el.style.display = visible === false ? 'none' : '';
}

function setTransform(el, transform) {
  el.style['transform-origin'] = 'top left';
  ['', '-ms-', '-webkit-'].forEach(function (prefix) {
    el.style[prefix + 'transform'] = transform;
  });
}

},{"../../util/Elements":315,"../../util/IdGenerator":320,"min-dash":555,"min-dom":556}],256:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _Overlays = _interopRequireDefault(require("./Overlays"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['overlays'],
  overlays: ['type', _Overlays.default]
};
exports.default = _default;

},{"./Overlays":255}],257:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Palette;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var TOGGLE_SELECTOR = '.djs-palette-toggle',
    ENTRY_SELECTOR = '.entry',
    ELEMENT_SELECTOR = TOGGLE_SELECTOR + ', ' + ENTRY_SELECTOR;
var PALETTE_OPEN_CLS = 'open',
    PALETTE_TWO_COLUMN_CLS = 'two-column';
var DEFAULT_PRIORITY = 1000;
/**
 * A palette containing modeling elements.
 */

function Palette(eventBus, canvas) {
  this._eventBus = eventBus;
  this._canvas = canvas;
  var self = this;
  eventBus.on('tool-manager.update', function (event) {
    var tool = event.tool;
    self.updateToolHighlight(tool);
  });
  eventBus.on('i18n.changed', function () {
    self._update();
  });
  eventBus.on('diagram.init', function () {
    self._diagramInitialized = true;

    self._rebuild();
  });
}

Palette.$inject = ['eventBus', 'canvas'];
/**
 * Register a provider with the palette
 *
 * @param  {number} [priority=1000]
 * @param  {PaletteProvider} provider
 *
 * @example
 * const paletteProvider = {
 *   getPaletteEntries: function() {
 *     return function(entries) {
 *       return {
 *         ...entries,
 *         'entry-1': {
 *           label: 'My Entry',
 *           action: function() { alert("I have been clicked!"); }
 *         }
 *       };
 *     }
 *   }
 * };
 *
 * palette.registerProvider(800, paletteProvider);
 */

Palette.prototype.registerProvider = function (priority, provider) {
  if (!provider) {
    provider = priority;
    priority = DEFAULT_PRIORITY;
  }

  this._eventBus.on('palette.getProviders', priority, function (event) {
    event.providers.push(provider);
  });

  this._rebuild();
};
/**
 * Returns the palette entries
 *
 * @return {Object<string, PaletteEntryDescriptor>} map of entries
 */


Palette.prototype.getEntries = function () {
  var providers = this._getProviders();

  return providers.reduce(addPaletteEntries, {});
};

Palette.prototype._rebuild = function () {
  if (!this._diagramInitialized) {
    return;
  }

  var providers = this._getProviders();

  if (!providers.length) {
    return;
  }

  if (!this._container) {
    this._init();
  }

  this._update();
};
/**
 * Initialize
 */


Palette.prototype._init = function () {
  var self = this;
  var eventBus = this._eventBus;

  var parentContainer = this._getParentContainer();

  var container = this._container = (0, _minDom.domify)(Palette.HTML_MARKUP);
  parentContainer.appendChild(container);

  _minDom.delegate.bind(container, ELEMENT_SELECTOR, 'click', function (event) {
    var target = event.delegateTarget;

    if ((0, _minDom.matches)(target, TOGGLE_SELECTOR)) {
      return self.toggle();
    }

    self.trigger('click', event);
  }); // prevent drag propagation


  _minDom.event.bind(container, 'mousedown', function (event) {
    event.stopPropagation();
  }); // prevent drag propagation


  _minDom.delegate.bind(container, ENTRY_SELECTOR, 'dragstart', function (event) {
    self.trigger('dragstart', event);
  });

  eventBus.on('canvas.resized', this._layoutChanged, this);
  eventBus.fire('palette.create', {
    container: container
  });
};

Palette.prototype._getProviders = function (id) {
  var event = this._eventBus.createEvent({
    type: 'palette.getProviders',
    providers: []
  });

  this._eventBus.fire(event);

  return event.providers;
};
/**
 * Update palette state.
 *
 * @param  {Object} [state] { open, twoColumn }
 */


Palette.prototype._toggleState = function (state) {
  state = state || {};

  var parent = this._getParentContainer(),
      container = this._container;

  var eventBus = this._eventBus;
  var twoColumn;
  var cls = (0, _minDom.classes)(container);

  if ('twoColumn' in state) {
    twoColumn = state.twoColumn;
  } else {
    twoColumn = this._needsCollapse(parent.clientHeight, this._entries || {});
  } // always update two column


  cls.toggle(PALETTE_TWO_COLUMN_CLS, twoColumn);

  if ('open' in state) {
    cls.toggle(PALETTE_OPEN_CLS, state.open);
  }

  eventBus.fire('palette.changed', {
    twoColumn: twoColumn,
    open: this.isOpen()
  });
};

Palette.prototype._update = function () {
  var entriesContainer = (0, _minDom.query)('.djs-palette-entries', this._container),
      entries = this._entries = this.getEntries();
  (0, _minDom.clear)(entriesContainer);
  (0, _minDash.forEach)(entries, function (entry, id) {
    var grouping = entry.group || 'default';
    var container = (0, _minDom.query)('[data-group=' + grouping + ']', entriesContainer);

    if (!container) {
      container = (0, _minDom.domify)('<div class="group" data-group="' + grouping + '"></div>');
      entriesContainer.appendChild(container);
    }

    var html = entry.html || (entry.separator ? '<hr class="separator" />' : '<div class="entry" draggable="true"></div>');
    var control = (0, _minDom.domify)(html);
    container.appendChild(control);

    if (!entry.separator) {
      (0, _minDom.attr)(control, 'data-action', id);

      if (entry.title) {
        (0, _minDom.attr)(control, 'title', entry.title);
      }

      if (entry.className) {
        addClasses(control, entry.className);
      }

      if (entry.imageUrl) {
        control.appendChild((0, _minDom.domify)('<img src="' + entry.imageUrl + '">'));
      }
    }
  }); // open after update

  this.open();
};
/**
 * Trigger an action available on the palette
 *
 * @param  {string} action
 * @param  {Event} event
 */


Palette.prototype.trigger = function (action, event, autoActivate) {
  var entries = this._entries,
      entry,
      handler,
      originalEvent,
      button = event.delegateTarget || event.target;

  if (!button) {
    return event.preventDefault();
  }

  entry = entries[(0, _minDom.attr)(button, 'data-action')]; // when user clicks on the palette and not on an action

  if (!entry) {
    return;
  }

  handler = entry.action;
  originalEvent = event.originalEvent || event; // simple action (via callback function)

  if ((0, _minDash.isFunction)(handler)) {
    if (action === 'click') {
      handler(originalEvent, autoActivate);
    }
  } else {
    if (handler[action]) {
      handler[action](originalEvent, autoActivate);
    }
  } // silence other actions


  event.preventDefault();
};

Palette.prototype._layoutChanged = function () {
  this._toggleState({});
};
/**
 * Do we need to collapse to two columns?
 *
 * @param {number} availableHeight
 * @param {Object} entries
 *
 * @return {boolean}
 */


Palette.prototype._needsCollapse = function (availableHeight, entries) {
  // top margin + bottom toggle + bottom margin
  // implementors must override this method if they
  // change the palette styles
  var margin = 20 + 10 + 20;
  var entriesHeight = Object.keys(entries).length * 46;
  return availableHeight < entriesHeight + margin;
};
/**
 * Close the palette
 */


Palette.prototype.close = function () {
  this._toggleState({
    open: false,
    twoColumn: false
  });
};
/**
 * Open the palette
 */


Palette.prototype.open = function () {
  this._toggleState({
    open: true
  });
};

Palette.prototype.toggle = function (open) {
  if (this.isOpen()) {
    this.close();
  } else {
    this.open();
  }
};

Palette.prototype.isActiveTool = function (tool) {
  return tool && this._activeTool === tool;
};

Palette.prototype.updateToolHighlight = function (name) {
  var entriesContainer, toolsContainer;

  if (!this._toolsContainer) {
    entriesContainer = (0, _minDom.query)('.djs-palette-entries', this._container);
    this._toolsContainer = (0, _minDom.query)('[data-group=tools]', entriesContainer);
  }

  toolsContainer = this._toolsContainer;
  (0, _minDash.forEach)(toolsContainer.children, function (tool) {
    var actionName = tool.getAttribute('data-action');

    if (!actionName) {
      return;
    }

    var toolClasses = (0, _minDom.classes)(tool);
    actionName = actionName.replace('-tool', '');

    if (toolClasses.contains('entry') && actionName === name) {
      toolClasses.add('highlighted-entry');
    } else {
      toolClasses.remove('highlighted-entry');
    }
  });
};
/**
 * Return true if the palette is opened.
 *
 * @example
 *
 * palette.open();
 *
 * if (palette.isOpen()) {
 *   // yes, we are open
 * }
 *
 * @return {boolean} true if palette is opened
 */


Palette.prototype.isOpen = function () {
  return (0, _minDom.classes)(this._container).has(PALETTE_OPEN_CLS);
};
/**
 * Get container the palette lives in.
 *
 * @return {Element}
 */


Palette.prototype._getParentContainer = function () {
  return this._canvas.getContainer();
};
/* markup definition */


Palette.HTML_MARKUP = '<div class="djs-palette">' + '<div class="djs-palette-entries"></div>' + '<div class="djs-palette-toggle"></div>' + '</div>'; // helpers //////////////////////

function addClasses(element, classNames) {
  var classes = (0, _minDom.classes)(element);
  var actualClassNames = (0, _minDash.isArray)(classNames) ? classNames : classNames.split(/\s+/g);
  actualClassNames.forEach(function (cls) {
    classes.add(cls);
  });
}

function addPaletteEntries(entries, provider) {
  var entriesOrUpdater = provider.getPaletteEntries();

  if ((0, _minDash.isFunction)(entriesOrUpdater)) {
    return entriesOrUpdater(entries);
  }

  (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) {
    entries[id] = entry;
  });
  return entries;
}

},{"min-dash":555,"min-dom":556}],258:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _Palette = _interopRequireDefault(require("./Palette"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['palette'],
  palette: ['type', _Palette.default]
};
exports.default = _default;

},{"./Palette":257}],259:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = PopupMenu;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var DATA_REF = 'data-id';
var CLOSE_EVENTS = ['contextPad.close', 'canvas.viewbox.changing', 'commandStack.changed'];
var DEFAULT_PRIORITY = 1000;
/**
 * A popup menu that can be used to display a list of actions anywhere in the canvas.
 *
 * @param {Object} config
 * @param {boolean|Object} [config.scale={ min: 1.0, max: 1.5 }]
 * @param {number} [config.scale.min]
 * @param {number} [config.scale.max]
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 *
 * @class
 * @constructor
 */

function PopupMenu(config, eventBus, canvas) {
  var scale = (0, _minDash.isDefined)(config && config.scale) ? config.scale : {
    min: 1,
    max: 1.5
  };
  this._config = {
    scale: scale
  };
  this._eventBus = eventBus;
  this._canvas = canvas;
  this._providers = {};
  this._current = {};
}

PopupMenu.$inject = ['config.popupMenu', 'eventBus', 'canvas'];
/**
 * Registers a popup menu provider
 *
 * @param  {string} id
 * @param {number} [priority=1000]
 * @param  {Object} provider
 *
 * @example
 * const popupMenuProvider = {
 *   getPopupMenuEntries: function(element) {
 *     return {
 *       'entry-1': {
 *         label: 'My Entry',
 *         action: function() { alert("I have been clicked!"); }
 *       }
 *     }
 *   }
 * };
 *
 * popupMenu.registerProvider('myMenuID', popupMenuProvider);
 */

PopupMenu.prototype.registerProvider = function (id, priority, provider) {
  if (!provider) {
    provider = priority;
    priority = DEFAULT_PRIORITY;
  }

  this._eventBus.on('popupMenu.getProviders.' + id, priority, function (event) {
    event.providers.push(provider);
  });
};
/**
 * Determine if the popup menu has entries.
 *
 * @return {boolean} true if empty
 */


PopupMenu.prototype.isEmpty = function (element, providerId) {
  if (!element) {
    throw new Error('element parameter is missing');
  }

  if (!providerId) {
    throw new Error('providerId parameter is missing');
  }

  var providers = this._getProviders(providerId);

  if (!providers) {
    return true;
  }

  var entries = this._getEntries(element, providers),
      headerEntries = this._getHeaderEntries(element, providers);

  var hasEntries = (0, _minDash.size)(entries) > 0,
      hasHeaderEntries = headerEntries && (0, _minDash.size)(headerEntries) > 0;
  return !hasEntries && !hasHeaderEntries;
};
/**
 * Create entries and open popup menu at given position
 *
 * @param  {Object} element
 * @param  {string} id provider id
 * @param  {Object} position
 *
 * @return {Object} popup menu instance
 */


PopupMenu.prototype.open = function (element, id, position) {
  var providers = this._getProviders(id);

  if (!element) {
    throw new Error('Element is missing');
  }

  if (!providers || !providers.length) {
    throw new Error('No registered providers for: ' + id);
  }

  if (!position) {
    throw new Error('the position argument is missing');
  }

  if (this.isOpen()) {
    this.close();
  }

  this._emit('open');

  var current = this._current = {
    className: id,
    element: element,
    position: position
  };

  var entries = this._getEntries(element, providers),
      headerEntries = this._getHeaderEntries(element, providers);

  current.entries = (0, _minDash.assign)({}, entries, headerEntries);
  current.container = this._createContainer();

  if ((0, _minDash.size)(headerEntries)) {
    current.container.appendChild(this._createEntries(headerEntries, 'djs-popup-header'));
  }

  if ((0, _minDash.size)(entries)) {
    current.container.appendChild(this._createEntries(entries, 'djs-popup-body'));
  }

  var canvas = this._canvas,
      parent = canvas.getContainer();

  this._attachContainer(current.container, parent, position.cursor);

  this._bindAutoClose();
};
/**
 * Removes the popup menu and unbinds the event handlers.
 */


PopupMenu.prototype.close = function () {
  if (!this.isOpen()) {
    return;
  }

  this._emit('close');

  this._unbindAutoClose();

  (0, _minDom.remove)(this._current.container);
  this._current.container = null;
};
/**
 * Determine if an open popup menu exist.
 *
 * @return {boolean} true if open
 */


PopupMenu.prototype.isOpen = function () {
  return !!this._current.container;
};
/**
 * Trigger an action associated with an entry.
 *
 * @param {Object} event
 *
 * @return the result of the action callback, if any
 */


PopupMenu.prototype.trigger = function (event) {
  // silence other actions
  event.preventDefault();
  var element = event.delegateTarget || event.target,
      entryId = (0, _minDom.attr)(element, DATA_REF);

  var entry = this._getEntry(entryId);

  if (entry.action) {
    return entry.action.call(null, event, entry);
  }
};

PopupMenu.prototype._getProviders = function (id) {
  var event = this._eventBus.createEvent({
    type: 'popupMenu.getProviders.' + id,
    providers: []
  });

  this._eventBus.fire(event);

  return event.providers;
};

PopupMenu.prototype._getEntries = function (element, providers) {
  var entries = {};
  (0, _minDash.forEach)(providers, function (provider) {
    // handle legacy method
    if (!provider.getPopupMenuEntries) {
      (0, _minDash.forEach)(provider.getEntries(element), function (entry) {
        var id = entry.id;

        if (!id) {
          throw new Error('every entry must have the id property set');
        }

        entries[id] = (0, _minDash.omit)(entry, ['id']);
      });
      return;
    }

    var entriesOrUpdater = provider.getPopupMenuEntries(element);

    if ((0, _minDash.isFunction)(entriesOrUpdater)) {
      entries = entriesOrUpdater(entries);
    } else {
      (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) {
        entries[id] = entry;
      });
    }
  });
  return entries;
};

PopupMenu.prototype._getHeaderEntries = function (element, providers) {
  var entries = {};
  (0, _minDash.forEach)(providers, function (provider) {
    // handle legacy method
    if (!provider.getPopupMenuHeaderEntries) {
      if (!provider.getHeaderEntries) {
        return;
      }

      (0, _minDash.forEach)(provider.getHeaderEntries(element), function (entry) {
        var id = entry.id;

        if (!id) {
          throw new Error('every entry must have the id property set');
        }

        entries[id] = (0, _minDash.omit)(entry, ['id']);
      });
      return;
    }

    var entriesOrUpdater = provider.getPopupMenuHeaderEntries(element);

    if ((0, _minDash.isFunction)(entriesOrUpdater)) {
      entries = entriesOrUpdater(entries);
    } else {
      (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) {
        entries[id] = entry;
      });
    }
  });
  return entries;
};
/**
 * Gets an entry instance (either entry or headerEntry) by id.
 *
 * @param  {string} entryId
 *
 * @return {Object} entry instance
 */


PopupMenu.prototype._getEntry = function (entryId) {
  var entry = this._current.entries[entryId];

  if (!entry) {
    throw new Error('entry not found');
  }

  return entry;
};

PopupMenu.prototype._emit = function (eventName) {
  this._eventBus.fire('popupMenu.' + eventName);
};
/**
 * Creates the popup menu container.
 *
 * @return {Object} a DOM container
 */


PopupMenu.prototype._createContainer = function () {
  var container = (0, _minDom.domify)('<div class="djs-popup">'),
      position = this._current.position,
      className = this._current.className;
  (0, _minDash.assign)(container.style, {
    position: 'absolute',
    left: position.x + 'px',
    top: position.y + 'px',
    visibility: 'hidden'
  });
  (0, _minDom.classes)(container).add(className);
  return container;
};
/**
 * Attaches the container to the DOM.
 *
 * @param {Object} container
 * @param {Object} parent
 */


PopupMenu.prototype._attachContainer = function (container, parent, cursor) {
  var self = this; // Event handler

  _minDom.delegate.bind(container, '.entry', 'click', function (event) {
    self.trigger(event);
  });

  this._updateScale(container); // Attach to DOM


  parent.appendChild(container);

  if (cursor) {
    this._assureIsInbounds(container, cursor);
  }
};
/**
 * Updates popup style.transform with respect to the config and zoom level.
 *
 * @method _updateScale
 *
 * @param {Object} container
 */


PopupMenu.prototype._updateScale = function (container) {
  var zoom = this._canvas.zoom();

  var scaleConfig = this._config.scale,
      minScale,
      maxScale,
      scale = zoom;

  if (scaleConfig !== true) {
    if (scaleConfig === false) {
      minScale = 1;
      maxScale = 1;
    } else {
      minScale = scaleConfig.min;
      maxScale = scaleConfig.max;
    }

    if ((0, _minDash.isDefined)(minScale) && zoom < minScale) {
      scale = minScale;
    }

    if ((0, _minDash.isDefined)(maxScale) && zoom > maxScale) {
      scale = maxScale;
    }
  }

  setTransform(container, 'scale(' + scale + ')');
};
/**
 * Make sure that the menu is always fully shown
 *
 * @method function
 *
 * @param  {Object} container
 * @param  {Position} cursor {x, y}
 */


PopupMenu.prototype._assureIsInbounds = function (container, cursor) {
  var canvas = this._canvas,
      clientRect = canvas._container.getBoundingClientRect();

  var containerX = container.offsetLeft,
      containerY = container.offsetTop,
      containerWidth = container.scrollWidth,
      containerHeight = container.scrollHeight,
      overAxis = {},
      left,
      top;
  var cursorPosition = {
    x: cursor.x - clientRect.left,
    y: cursor.y - clientRect.top
  };

  if (containerX + containerWidth > clientRect.width) {
    overAxis.x = true;
  }

  if (containerY + containerHeight > clientRect.height) {
    overAxis.y = true;
  }

  if (overAxis.x && overAxis.y) {
    left = cursorPosition.x - containerWidth + 'px';
    top = cursorPosition.y - containerHeight + 'px';
  } else if (overAxis.x) {
    left = cursorPosition.x - containerWidth + 'px';
    top = cursorPosition.y + 'px';
  } else if (overAxis.y && cursorPosition.y < containerHeight) {
    left = cursorPosition.x + 'px';
    top = 10 + 'px';
  } else if (overAxis.y) {
    left = cursorPosition.x + 'px';
    top = cursorPosition.y - containerHeight + 'px';
  }

  (0, _minDash.assign)(container.style, {
    left: left,
    top: top
  }, {
    visibility: 'visible',
    'z-index': 1000
  });
};
/**
 * Creates a list of entries and returns them as a DOM container.
 *
 * @param {Array<Object>} entries an array of entry objects
 * @param {string} className the class name of the entry container
 *
 * @return {Object} a DOM container
 */


PopupMenu.prototype._createEntries = function (entries, className) {
  var entriesContainer = (0, _minDom.domify)('<div>'),
      self = this;
  (0, _minDom.classes)(entriesContainer).add(className);
  (0, _minDash.forEach)(entries, function (entry, id) {
    var entryContainer = self._createEntry(entry, id);

    entriesContainer.appendChild(entryContainer);
  });
  return entriesContainer;
};
/**
 * Creates a single entry and returns it as a DOM container.
 *
 * @param  {Object} entry
 *
 * @return {Object} a DOM container
 */


PopupMenu.prototype._createEntry = function (entry, id) {
  var entryContainer = (0, _minDom.domify)('<div>'),
      entryClasses = (0, _minDom.classes)(entryContainer);
  entryClasses.add('entry');

  if (entry.className) {
    entry.className.split(' ').forEach(function (className) {
      entryClasses.add(className);
    });
  }

  (0, _minDom.attr)(entryContainer, DATA_REF, id);

  if (entry.label) {
    var label = (0, _minDom.domify)('<span>');
    label.textContent = entry.label;
    entryContainer.appendChild(label);
  }

  if (entry.imageUrl) {
    entryContainer.appendChild((0, _minDom.domify)('<img src="' + entry.imageUrl + '" />'));
  }

  if (entry.active === true) {
    entryClasses.add('active');
  }

  if (entry.disabled === true) {
    entryClasses.add('disabled');
  }

  if (entry.title) {
    entryContainer.title = entry.title;
  }

  return entryContainer;
};
/**
 * Set up listener to close popup automatically on certain events.
 */


PopupMenu.prototype._bindAutoClose = function () {
  this._eventBus.once(CLOSE_EVENTS, this.close, this);
};
/**
 * Remove the auto-closing listener.
 */


PopupMenu.prototype._unbindAutoClose = function () {
  this._eventBus.off(CLOSE_EVENTS, this.close, this);
}; // helpers /////////////////////////////


function setTransform(element, transform) {
  element.style['transform-origin'] = 'top left';
  ['', '-ms-', '-webkit-'].forEach(function (prefix) {
    element.style[prefix + 'transform'] = transform;
  });
}

},{"min-dash":555,"min-dom":556}],260:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _PopupMenu = _interopRequireDefault(require("./PopupMenu"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['popupMenu'],
  popupMenu: ['type', _PopupMenu.default]
};
exports.default = _default;

},{"./PopupMenu":259}],261:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = PreviewSupport;

var _minDash = require("min-dash");

var _tinySvg = require("tiny-svg");

var _minDom = require("min-dom");

var _GraphicsUtil = require("../../util/GraphicsUtil");

var MARKER_TYPES = ['marker-start', 'marker-mid', 'marker-end'];
var NODES_CAN_HAVE_MARKER = ['circle', 'ellipse', 'line', 'path', 'polygon', 'polyline', 'rect'];
/**
 * Adds support for previews of moving/resizing elements.
 */

function PreviewSupport(elementRegistry, eventBus, canvas, styles) {
  this._elementRegistry = elementRegistry;
  this._canvas = canvas;
  this._styles = styles;
  this._clonedMarkers = {};
  var self = this;
  eventBus.on('drag.cleanup', function () {
    (0, _minDash.forEach)(self._clonedMarkers, function (clonedMarker) {
      (0, _tinySvg.remove)(clonedMarker);
    });
    self._clonedMarkers = {};
  });
}

PreviewSupport.$inject = ['elementRegistry', 'eventBus', 'canvas', 'styles'];
/**
 * Returns graphics of an element.
 *
 * @param {djs.model.Base} element
 *
 * @return {SVGElement}
 */

PreviewSupport.prototype.getGfx = function (element) {
  return this._elementRegistry.getGraphics(element);
};
/**
 * Adds a move preview of a given shape to a given svg group.
 *
 * @param {djs.model.Base} element
 * @param {SVGElement} group
 * @param {SVGElement} [gfx]
 *
 * @return {SVGElement} dragger
 */


PreviewSupport.prototype.addDragger = function (element, group, gfx) {
  gfx = gfx || this.getGfx(element);
  var dragger = (0, _tinySvg.clone)(gfx);
  var bbox = gfx.getBoundingClientRect();

  this._cloneMarkers((0, _GraphicsUtil.getVisual)(dragger));

  (0, _tinySvg.attr)(dragger, this._styles.cls('djs-dragger', [], {
    x: bbox.top,
    y: bbox.left
  }));
  (0, _tinySvg.append)(group, dragger);
  return dragger;
};
/**
 * Adds a resize preview of a given shape to a given svg group.
 *
 * @param {djs.model.Base} element
 * @param {SVGElement} group
 *
 * @return {SVGElement} frame
 */


PreviewSupport.prototype.addFrame = function (shape, group) {
  var frame = (0, _tinySvg.create)('rect', {
    class: 'djs-resize-overlay',
    width: shape.width,
    height: shape.height,
    x: shape.x,
    y: shape.y
  });
  (0, _tinySvg.append)(group, frame);
  return frame;
};
/**
 * Clone all markers referenced by a node and its child nodes.
 *
 * @param {SVGElement} gfx
 */


PreviewSupport.prototype._cloneMarkers = function (gfx) {
  var self = this;

  if (gfx.childNodes) {
    // TODO: use forEach once we drop PhantomJS
    for (var i = 0; i < gfx.childNodes.length; i++) {
      // recursively clone markers of child nodes
      self._cloneMarkers(gfx.childNodes[i]);
    }
  }

  if (!canHaveMarker(gfx)) {
    return;
  }

  MARKER_TYPES.forEach(function (markerType) {
    if ((0, _tinySvg.attr)(gfx, markerType)) {
      var marker = getMarker(gfx, markerType, self._canvas.getContainer());

      self._cloneMarker(gfx, marker, markerType);
    }
  });
};
/**
 * Clone marker referenced by an element.
 *
 * @param {SVGElement} gfx
 * @param {SVGElement} marker
 * @param {string} markerType
 */


PreviewSupport.prototype._cloneMarker = function (gfx, marker, markerType) {
  var markerId = marker.id;
  var clonedMarker = this._clonedMarkers[markerId];

  if (!clonedMarker) {
    clonedMarker = (0, _tinySvg.clone)(marker);
    var clonedMarkerId = markerId + '-clone';
    clonedMarker.id = clonedMarkerId;
    (0, _tinySvg.classes)(clonedMarker).add('djs-dragger').add('djs-dragger-marker');
    this._clonedMarkers[markerId] = clonedMarker;
    var defs = (0, _minDom.query)('defs', this._canvas._svg);

    if (!defs) {
      defs = (0, _tinySvg.create)('defs');
      (0, _tinySvg.append)(this._canvas._svg, defs);
    }

    (0, _tinySvg.append)(defs, clonedMarker);
  }

  var reference = idToReference(this._clonedMarkers[markerId].id);
  (0, _tinySvg.attr)(gfx, markerType, reference);
}; // helpers //////////

/**
 * Get marker of given type referenced by node.
 *
 * @param {Node} node
 * @param {string} markerType
 * @param {Node} [parentNode]
 *
 * @param {Node}
 */


function getMarker(node, markerType, parentNode) {
  var id = referenceToId((0, _tinySvg.attr)(node, markerType));
  return (0, _minDom.query)('marker#' + id, parentNode || document);
}
/**
 * Get ID of fragment within current document from its functional IRI reference.
 * References may use single or double quotes.
 *
 * @param {string} reference
 *
 * @returns {string}
 */


function referenceToId(reference) {
  return reference.match(/url\(['"]?#([^'"]*)['"]?\)/)[1];
}
/**
 * Get functional IRI reference for given ID of fragment within current document.
 *
 * @param {string} id
 *
 * @returns {string}
 */


function idToReference(id) {
  return 'url(#' + id + ')';
}
/**
 * Check wether node type can have marker attributes.
 *
 * @param {Node} node
 *
 * @returns {boolean}
 */


function canHaveMarker(node) {
  return NODES_CAN_HAVE_MARKER.indexOf(node.nodeName) !== -1;
}

},{"../../util/GraphicsUtil":319,"min-dash":555,"min-dom":556,"tiny-svg":567}],262:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _PreviewSupport = _interopRequireDefault(require("./PreviewSupport"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['previewSupport'],
  previewSupport: ['type', _PreviewSupport.default]
};
exports.default = _default;

},{"./PreviewSupport":261}],263:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Replace;

var _minDash = require("min-dash");

var round = Math.round;
/**
 * Service that allow replacing of elements.
 */

function Replace(modeling) {
  this._modeling = modeling;
}

Replace.$inject = ['modeling'];
/**
 * @param {Element} oldElement - Element to be replaced
 * @param {Object}  newElementData - Containing information about the new element,
 *                                   for example the new bounds and type.
 * @param {Object}  options - Custom options that will be attached to the context. It can be used to inject data
 *                            that is needed in the command chain. For example it could be used in
 *                            eventbus.on('commandStack.shape.replace.postExecute') to change shape attributes after
 *                            shape creation.
 */

Replace.prototype.replaceElement = function (oldElement, newElementData, options) {
  if (oldElement.waypoints) {
    // TODO(nikku): we do not replace connections, yet
    return null;
  }

  var modeling = this._modeling;
  var width = newElementData.width || oldElement.width,
      height = newElementData.height || oldElement.height,
      x = newElementData.x || oldElement.x,
      y = newElementData.y || oldElement.y,
      centerX = round(x + width / 2),
      centerY = round(y + height / 2); // modeling API requires center coordinates,
  // account for that when handling shape bounds

  return modeling.replaceShape(oldElement, (0, _minDash.assign)({}, newElementData, {
    x: centerX,
    y: centerY,
    width: width,
    height: height
  }), options);
};

},{"min-dash":555}],264:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _Replace = _interopRequireDefault(require("./Replace"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['replace'],
  replace: ['type', _Replace.default]
};
exports.default = _default;

},{"./Replace":263}],265:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Resize;
exports.getReferencePoint = getReferencePoint;

var _minDash = require("min-dash");

var _ResizeUtil = require("./ResizeUtil");

var _LayoutUtil = require("../../layout/LayoutUtil");

var DEFAULT_MIN_WIDTH = 10;
/**
 * A component that provides resizing of shapes on the canvas.
 *
 * The following components are part of shape resize:
 *
 *  * adding resize handles,
 *  * creating a visual during resize
 *  * checking resize rules
 *  * committing a change once finished
 *
 *
 * ## Customizing
 *
 * It's possible to customize the resizing behaviour by intercepting 'resize.start'
 * and providing the following parameters through the 'context':
 *
 *   * minDimensions ({ width, height }): minimum shape dimensions
 *
 *   * childrenBoxPadding ({ left, top, bottom, right } || number):
 *     gap between the minimum bounding box and the container
 *
 * f.ex:
 *
 * ```javascript
 * eventBus.on('resize.start', 1500, function(event) {
 *   var context = event.context,
 *
 *  context.minDimensions = { width: 140, height: 120 };
 *
 *  // Passing general padding
 *  context.childrenBoxPadding = 30;
 *
 *  // Passing padding to a specific side
 *  context.childrenBoxPadding.left = 20;
 * });
 * ```
 */

function Resize(eventBus, rules, modeling, dragging) {
  this._dragging = dragging;
  this._rules = rules;
  var self = this;
  /**
   * Handle resize move by specified delta.
   *
   * @param {Object} context
   * @param {Point} delta
   */

  function handleMove(context, delta) {
    var shape = context.shape,
        direction = context.direction,
        resizeConstraints = context.resizeConstraints,
        newBounds;
    context.delta = delta;
    newBounds = (0, _ResizeUtil.resizeBounds)(shape, direction, delta); // ensure constraints during resize

    context.newBounds = (0, _ResizeUtil.ensureConstraints)(newBounds, resizeConstraints); // update + cache executable state

    context.canExecute = self.canResize(context);
  }
  /**
   * Handle resize start.
   *
   * @param  {Object} context
   */


  function handleStart(context) {
    var resizeConstraints = context.resizeConstraints,
        // evaluate minBounds for backwards compatibility
    minBounds = context.minBounds;

    if (resizeConstraints !== undefined) {
      return;
    }

    if (minBounds === undefined) {
      minBounds = self.computeMinResizeBox(context);
    }

    context.resizeConstraints = {
      min: (0, _LayoutUtil.asTRBL)(minBounds)
    };
  }
  /**
   * Handle resize end.
   *
   * @param  {Object} context
   */


  function handleEnd(context) {
    var shape = context.shape,
        canExecute = context.canExecute,
        newBounds = context.newBounds;

    if (canExecute) {
      // ensure we have actual pixel values for new bounds
      // (important when zoom level was > 1 during move)
      newBounds = (0, _LayoutUtil.roundBounds)(newBounds);

      if (!boundsChanged(shape, newBounds)) {
        // no resize necessary
        return;
      } // perform the actual resize


      modeling.resizeShape(shape, newBounds);
    }
  }

  eventBus.on('resize.start', function (event) {
    handleStart(event.context);
  });
  eventBus.on('resize.move', function (event) {
    var delta = {
      x: event.dx,
      y: event.dy
    };
    handleMove(event.context, delta);
  });
  eventBus.on('resize.end', function (event) {
    handleEnd(event.context);
  });
}

Resize.prototype.canResize = function (context) {
  var rules = this._rules;
  var ctx = (0, _minDash.pick)(context, ['newBounds', 'shape', 'delta', 'direction']);
  return rules.allowed('shape.resize', ctx);
};
/**
 * Activate a resize operation.
 *
 * You may specify additional contextual information and must specify a
 * resize direction during activation of the resize event.
 *
 * @param {MouseEvent} event
 * @param {djs.model.Shape} shape
 * @param {Object|string} contextOrDirection
 */


Resize.prototype.activate = function (event, shape, contextOrDirection) {
  var dragging = this._dragging,
      context,
      direction;

  if (typeof contextOrDirection === 'string') {
    contextOrDirection = {
      direction: contextOrDirection
    };
  }

  context = (0, _minDash.assign)({
    shape: shape
  }, contextOrDirection);
  direction = context.direction;

  if (!direction) {
    throw new Error('must provide a direction (n|w|s|e|nw|se|ne|sw)');
  }

  dragging.init(event, getReferencePoint(shape, direction), 'resize', {
    autoActivate: true,
    cursor: getCursor(direction),
    data: {
      shape: shape,
      context: context
    }
  });
};

Resize.prototype.computeMinResizeBox = function (context) {
  var shape = context.shape,
      direction = context.direction,
      minDimensions,
      childrenBounds;
  minDimensions = context.minDimensions || {
    width: DEFAULT_MIN_WIDTH,
    height: DEFAULT_MIN_WIDTH
  }; // get children bounds

  childrenBounds = (0, _ResizeUtil.computeChildrenBBox)(shape, context.childrenBoxPadding); // get correct minimum bounds from given resize direction
  // basically ensures that the minBounds is max(childrenBounds, minDimensions)

  return (0, _ResizeUtil.getMinResizeBounds)(direction, shape, minDimensions, childrenBounds);
};

Resize.$inject = ['eventBus', 'rules', 'modeling', 'dragging']; // helpers //////////

function boundsChanged(shape, newBounds) {
  return shape.x !== newBounds.x || shape.y !== newBounds.y || shape.width !== newBounds.width || shape.height !== newBounds.height;
}

function getReferencePoint(shape, direction) {
  var mid = (0, _LayoutUtil.getMid)(shape),
      trbl = (0, _LayoutUtil.asTRBL)(shape);
  var referencePoint = {
    x: mid.x,
    y: mid.y
  };

  if (direction.indexOf('n') !== -1) {
    referencePoint.y = trbl.top;
  } else if (direction.indexOf('s') !== -1) {
    referencePoint.y = trbl.bottom;
  }

  if (direction.indexOf('e') !== -1) {
    referencePoint.x = trbl.right;
  } else if (direction.indexOf('w') !== -1) {
    referencePoint.x = trbl.left;
  }

  return referencePoint;
}

function getCursor(direction) {
  var prefix = 'resize-';

  if (direction === 'n' || direction === 's') {
    return prefix + 'ns';
  } else if (direction === 'e' || direction === 'w') {
    return prefix + 'ew';
  } else if (direction === 'nw' || direction === 'se') {
    return prefix + 'nwse';
  } else {
    return prefix + 'nesw';
  }
}

},{"../../layout/LayoutUtil":300,"./ResizeUtil":268,"min-dash":555}],266:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ResizeHandles;

var _minDash = require("min-dash");

var _tinySvg = require("tiny-svg");

var _minDom = require("min-dom");

var _Mouse = require("../../util/Mouse");

var _SvgTransformUtil = require("../../util/SvgTransformUtil");

var _Resize = require("./Resize");

var HANDLE_OFFSET = -6,
    HANDLE_SIZE = 4,
    HANDLE_HIT_SIZE = 20;
var CLS_RESIZER = 'djs-resizer';
var directions = ['n', 'w', 's', 'e', 'nw', 'ne', 'se', 'sw'];
/**
 * This component is responsible for adding resize handles.
 *
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 * @param {Selection} selection
 * @param {Resize} resize
 */

function ResizeHandles(eventBus, canvas, selection, resize) {
  this._resize = resize;
  this._canvas = canvas;
  var self = this;
  eventBus.on('selection.changed', function (e) {
    var newSelection = e.newSelection; // remove old selection markers

    self.removeResizers(); // add new selection markers ONLY if single selection

    if (newSelection.length === 1) {
      (0, _minDash.forEach)(newSelection, (0, _minDash.bind)(self.addResizer, self));
    }
  });
  eventBus.on('shape.changed', function (e) {
    var shape = e.element;

    if (selection.isSelected(shape)) {
      self.removeResizers();
      self.addResizer(shape);
    }
  });
}

ResizeHandles.prototype.makeDraggable = function (element, gfx, direction) {
  var resize = this._resize;

  function startResize(event) {
    // only trigger on left mouse button
    if ((0, _Mouse.isPrimaryButton)(event)) {
      resize.activate(event, element, direction);
    }
  }

  _minDom.event.bind(gfx, 'mousedown', startResize);

  _minDom.event.bind(gfx, 'touchstart', startResize);
};

ResizeHandles.prototype._createResizer = function (element, x, y, direction) {
  var resizersParent = this._getResizersParent();

  var offset = getHandleOffset(direction);
  var group = (0, _tinySvg.create)('g');
  (0, _tinySvg.classes)(group).add(CLS_RESIZER);
  (0, _tinySvg.classes)(group).add(CLS_RESIZER + '-' + element.id);
  (0, _tinySvg.classes)(group).add(CLS_RESIZER + '-' + direction);
  (0, _tinySvg.append)(resizersParent, group);
  var visual = (0, _tinySvg.create)('rect');
  (0, _tinySvg.attr)(visual, {
    x: -HANDLE_SIZE / 2 + offset.x,
    y: -HANDLE_SIZE / 2 + offset.y,
    width: HANDLE_SIZE,
    height: HANDLE_SIZE
  });
  (0, _tinySvg.classes)(visual).add(CLS_RESIZER + '-visual');
  (0, _tinySvg.append)(group, visual);
  var hit = (0, _tinySvg.create)('rect');
  (0, _tinySvg.attr)(hit, {
    x: -HANDLE_HIT_SIZE / 2 + offset.x,
    y: -HANDLE_HIT_SIZE / 2 + offset.y,
    width: HANDLE_HIT_SIZE,
    height: HANDLE_HIT_SIZE
  });
  (0, _tinySvg.classes)(hit).add(CLS_RESIZER + '-hit');
  (0, _tinySvg.append)(group, hit);
  (0, _SvgTransformUtil.transform)(group, x, y);
  return group;
};

ResizeHandles.prototype.createResizer = function (element, direction) {
  var point = (0, _Resize.getReferencePoint)(element, direction);

  var resizer = this._createResizer(element, point.x, point.y, direction);

  this.makeDraggable(element, resizer, direction);
}; // resize handles implementation ///////////////////////////////

/**
 * Add resizers for a given element.
 *
 * @param {djs.model.Shape} shape
 */


ResizeHandles.prototype.addResizer = function (shape) {
  var self = this;
  var resize = this._resize;

  if (!resize.canResize({
    shape: shape
  })) {
    return;
  }

  (0, _minDash.forEach)(directions, function (direction) {
    self.createResizer(shape, direction);
  });
};
/**
 * Remove all resizers
 */


ResizeHandles.prototype.removeResizers = function () {
  var resizersParent = this._getResizersParent();

  (0, _tinySvg.clear)(resizersParent);
};

ResizeHandles.prototype._getResizersParent = function () {
  return this._canvas.getLayer('resizers');
};

ResizeHandles.$inject = ['eventBus', 'canvas', 'selection', 'resize']; // helpers //////////

function getHandleOffset(direction) {
  var offset = {
    x: 0,
    y: 0
  };

  if (direction.indexOf('e') !== -1) {
    offset.x = -HANDLE_OFFSET;
  } else if (direction.indexOf('w') !== -1) {
    offset.x = HANDLE_OFFSET;
  }

  if (direction.indexOf('s') !== -1) {
    offset.y = -HANDLE_OFFSET;
  } else if (direction.indexOf('n') !== -1) {
    offset.y = HANDLE_OFFSET;
  }

  return offset;
}

},{"../../util/Mouse":323,"../../util/SvgTransformUtil":328,"./Resize":265,"min-dash":555,"min-dom":556,"tiny-svg":567}],267:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ResizePreview;

var _tinySvg = require("tiny-svg");

var MARKER_RESIZING = 'djs-resizing',
    MARKER_RESIZE_NOT_OK = 'resize-not-ok';
var LOW_PRIORITY = 500;

/**
 * Provides previews for resizing shapes when resizing.
 *
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 * @param {PreviewSupport} previewSupport
 */
function ResizePreview(eventBus, canvas, previewSupport) {
  /**
   * Update resizer frame.
   *
   * @param {Object} context
   */
  function updateFrame(context) {
    var shape = context.shape,
        bounds = context.newBounds,
        frame = context.frame;

    if (!frame) {
      frame = context.frame = previewSupport.addFrame(shape, canvas.getDefaultLayer());
      canvas.addMarker(shape, MARKER_RESIZING);
    }

    if (bounds.width > 5) {
      (0, _tinySvg.attr)(frame, {
        x: bounds.x,
        width: bounds.width
      });
    }

    if (bounds.height > 5) {
      (0, _tinySvg.attr)(frame, {
        y: bounds.y,
        height: bounds.height
      });
    }

    if (context.canExecute) {
      (0, _tinySvg.classes)(frame).remove(MARKER_RESIZE_NOT_OK);
    } else {
      (0, _tinySvg.classes)(frame).add(MARKER_RESIZE_NOT_OK);
    }
  }
  /**
   * Remove resizer frame.
   *
   * @param {Object} context
   */


  function removeFrame(context) {
    var shape = context.shape,
        frame = context.frame;

    if (frame) {
      (0, _tinySvg.remove)(context.frame);
    }

    canvas.removeMarker(shape, MARKER_RESIZING);
  } // add and update previews


  eventBus.on('resize.move', LOW_PRIORITY, function (event) {
    updateFrame(event.context);
  }); // remove previews

  eventBus.on('resize.cleanup', function (event) {
    removeFrame(event.context);
  });
}

ResizePreview.$inject = ['eventBus', 'canvas', 'previewSupport'];

},{"tiny-svg":567}],268:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.substractTRBL = substractTRBL;
exports.resizeBounds = resizeBounds;
exports.resizeTRBL = resizeTRBL;
exports.reattachPoint = reattachPoint;
exports.ensureConstraints = ensureConstraints;
exports.getMinResizeBounds = getMinResizeBounds;
exports.addPadding = addPadding;
exports.computeChildrenBBox = computeChildrenBBox;

var _minDash = require("min-dash");

var _Elements = require("../../util/Elements");

var _LayoutUtil = require("../../layout/LayoutUtil");

var max = Math.max,
    min = Math.min;
var DEFAULT_CHILD_BOX_PADDING = 20;

/**
 * Substract a TRBL from another
 *
 * @param  {TRBL} trblA
 * @param  {TRBL} trblB
 *
 * @return {TRBL}
 */
function substractTRBL(trblA, trblB) {
  return {
    top: trblA.top - trblB.top,
    right: trblA.right - trblB.right,
    bottom: trblA.bottom - trblB.bottom,
    left: trblA.left - trblB.left
  };
}
/**
 * Resize the given bounds by the specified delta from a given anchor point.
 *
 * @param {Bounds} bounds the bounding box that should be resized
 * @param {string} direction in which the element is resized (nw, ne, se, sw)
 * @param {Point} delta of the resize operation
 *
 * @return {Bounds} resized bounding box
 */


function resizeBounds(bounds, direction, delta) {
  var dx = delta.x,
      dy = delta.y;
  var newBounds = {
    x: bounds.x,
    y: bounds.y,
    width: bounds.width,
    height: bounds.height
  };

  if (direction.indexOf('n') !== -1) {
    newBounds.y = bounds.y + dy;
    newBounds.height = bounds.height - dy;
  } else if (direction.indexOf('s') !== -1) {
    newBounds.height = bounds.height + dy;
  }

  if (direction.indexOf('e') !== -1) {
    newBounds.width = bounds.width + dx;
  } else if (direction.indexOf('w') !== -1) {
    newBounds.x = bounds.x + dx;
    newBounds.width = bounds.width - dx;
  }

  return newBounds;
}
/**
 * Resize the given bounds by applying the passed
 * { top, right, bottom, left } delta.
 *
 * @param {Bounds} bounds
 * @param {TRBL} trblResize
 *
 * @return {Bounds}
 */


function resizeTRBL(bounds, resize) {
  return {
    x: bounds.x + (resize.left || 0),
    y: bounds.y + (resize.top || 0),
    width: bounds.width - (resize.left || 0) + (resize.right || 0),
    height: bounds.height - (resize.top || 0) + (resize.bottom || 0)
  };
}

function reattachPoint(bounds, newBounds, point) {
  var sx = bounds.width / newBounds.width,
      sy = bounds.height / newBounds.height;
  return {
    x: Math.round(newBounds.x + newBounds.width / 2) - Math.floor((bounds.x + bounds.width / 2 - point.x) / sx),
    y: Math.round(newBounds.y + newBounds.height / 2) - Math.floor((bounds.y + bounds.height / 2 - point.y) / sy)
  };
}

function applyConstraints(attr, trbl, resizeConstraints) {
  var value = trbl[attr],
      minValue = resizeConstraints.min && resizeConstraints.min[attr],
      maxValue = resizeConstraints.max && resizeConstraints.max[attr];

  if ((0, _minDash.isNumber)(minValue)) {
    value = (/top|left/.test(attr) ? min : max)(value, minValue);
  }

  if ((0, _minDash.isNumber)(maxValue)) {
    value = (/top|left/.test(attr) ? max : min)(value, maxValue);
  }

  return value;
}

function ensureConstraints(currentBounds, resizeConstraints) {
  if (!resizeConstraints) {
    return currentBounds;
  }

  var currentTrbl = (0, _LayoutUtil.asTRBL)(currentBounds);
  return (0, _LayoutUtil.asBounds)({
    top: applyConstraints('top', currentTrbl, resizeConstraints),
    right: applyConstraints('right', currentTrbl, resizeConstraints),
    bottom: applyConstraints('bottom', currentTrbl, resizeConstraints),
    left: applyConstraints('left', currentTrbl, resizeConstraints)
  });
}

function getMinResizeBounds(direction, currentBounds, minDimensions, childrenBounds) {
  var currentBox = (0, _LayoutUtil.asTRBL)(currentBounds);
  var minBox = {
    top: /n/.test(direction) ? currentBox.bottom - minDimensions.height : currentBox.top,
    left: /w/.test(direction) ? currentBox.right - minDimensions.width : currentBox.left,
    bottom: /s/.test(direction) ? currentBox.top + minDimensions.height : currentBox.bottom,
    right: /e/.test(direction) ? currentBox.left + minDimensions.width : currentBox.right
  };
  var childrenBox = childrenBounds ? (0, _LayoutUtil.asTRBL)(childrenBounds) : minBox;
  var combinedBox = {
    top: min(minBox.top, childrenBox.top),
    left: min(minBox.left, childrenBox.left),
    bottom: max(minBox.bottom, childrenBox.bottom),
    right: max(minBox.right, childrenBox.right)
  };
  return (0, _LayoutUtil.asBounds)(combinedBox);
}

function asPadding(mayBePadding, defaultValue) {
  if (typeof mayBePadding !== 'undefined') {
    return mayBePadding;
  } else {
    return DEFAULT_CHILD_BOX_PADDING;
  }
}

function addPadding(bbox, padding) {
  var left, right, top, bottom;

  if (typeof padding === 'object') {
    left = asPadding(padding.left);
    right = asPadding(padding.right);
    top = asPadding(padding.top);
    bottom = asPadding(padding.bottom);
  } else {
    left = right = top = bottom = asPadding(padding);
  }

  return {
    x: bbox.x - left,
    y: bbox.y - top,
    width: bbox.width + left + right,
    height: bbox.height + top + bottom
  };
}
/**
 * Is the given element part of the resize
 * targets min boundary box?
 *
 * This is the default implementation which excludes
 * connections and labels.
 *
 * @param {djs.model.Base} element
 */


function isBBoxChild(element) {
  // exclude connections
  if (element.waypoints) {
    return false;
  } // exclude labels


  if (element.type === 'label') {
    return false;
  }

  return true;
}
/**
 * Return children bounding computed from a shapes children
 * or a list of prefiltered children.
 *
 * @param  {djs.model.Shape|Array<djs.model.Shape>} shapeOrChildren
 * @param  {number|Object} padding
 *
 * @return {Bounds}
 */


function computeChildrenBBox(shapeOrChildren, padding) {
  var elements; // compute based on shape

  if (shapeOrChildren.length === undefined) {
    // grab all the children that are part of the
    // parents children box
    elements = (0, _minDash.filter)(shapeOrChildren.children, isBBoxChild);
  } else {
    elements = shapeOrChildren;
  }

  if (elements.length) {
    return addPadding((0, _Elements.getBBox)(elements), padding);
  }
}

},{"../../layout/LayoutUtil":300,"../../util/Elements":315,"min-dash":555}],269:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _rules = _interopRequireDefault(require("../rules"));

var _dragging = _interopRequireDefault(require("../dragging"));

var _previewSupport = _interopRequireDefault(require("../preview-support"));

var _Resize = _interopRequireDefault(require("./Resize"));

var _ResizePreview = _interopRequireDefault(require("./ResizePreview"));

var _ResizeHandles = _interopRequireDefault(require("./ResizeHandles"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_rules.default, _dragging.default, _previewSupport.default],
  __init__: ['resize', 'resizePreview', 'resizeHandles'],
  resize: ['type', _Resize.default],
  resizePreview: ['type', _ResizePreview.default],
  resizeHandles: ['type', _ResizeHandles.default]
};
exports.default = _default;

},{"../dragging":197,"../preview-support":262,"../rules":272,"./Resize":265,"./ResizeHandles":266,"./ResizePreview":267}],270:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = RuleProvider;

var _inherits = _interopRequireDefault(require("inherits"));

var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A basic provider that may be extended to implement modeling rules.
 *
 * Extensions should implement the init method to actually add their custom
 * modeling checks. Checks may be added via the #addRule(action, fn) method.
 *
 * @param {EventBus} eventBus
 */
function RuleProvider(eventBus) {
  _CommandInterceptor.default.call(this, eventBus);

  this.init();
}

RuleProvider.$inject = ['eventBus'];
(0, _inherits.default)(RuleProvider, _CommandInterceptor.default);
/**
 * Adds a modeling rule for the given action, implemented through
 * a callback function.
 *
 * The function will receive the modeling specific action context
 * to perform its check. It must return `false` to disallow the
 * action from happening or `true` to allow the action.
 *
 * A rule provider may pass over the evaluation to lower priority
 * rules by returning return nothing (or <code>undefined</code>).
 *
 * @example
 *
 * ResizableRules.prototype.init = function() {
 *
 *   \/**
 *    * Return `true`, `false` or nothing to denote
 *    * _allowed_, _not allowed_ and _continue evaluating_.
 *    *\/
 *   this.addRule('shape.resize', function(context) {
 *
 *     var shape = context.shape;
 *
 *     if (!context.newBounds) {
 *       // check general resizability
 *       if (!shape.resizable) {
 *         return false;
 *       }
 *
 *       // not returning anything (read: undefined)
 *       // will continue the evaluation of other rules
 *       // (with lower priority)
 *       return;
 *     } else {
 *       // element must have minimum size of 10*10 points
 *       return context.newBounds.width > 10 && context.newBounds.height > 10;
 *     }
 *   });
 * };
 *
 * @param {string|Array<string>} actions the identifier for the modeling action to check
 * @param {number} [priority] the priority at which this rule is being applied
 * @param {Function} fn the callback function that performs the actual check
 */

RuleProvider.prototype.addRule = function (actions, priority, fn) {
  var self = this;

  if (typeof actions === 'string') {
    actions = [actions];
  }

  actions.forEach(function (action) {
    self.canExecute(action, priority, function (context, action, event) {
      return fn(context);
    }, true);
  });
};
/**
 * Implement this method to add new rules during provider initialization.
 */


RuleProvider.prototype.init = function () {};

},{"../../command/CommandInterceptor":145,"inherits":347}],271:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Rules;

/**
 * A service that provides rules for certain diagram actions.
 *
 * The default implementation will hook into the {@link CommandStack}
 * to perform the actual rule evaluation. Make sure to provide the
 * `commandStack` service with this module if you plan to use it.
 *
 * Together with this implementation you may use the {@link RuleProvider}
 * to implement your own rule checkers.
 *
 * This module is ment to be easily replaced, thus the tiny foot print.
 *
 * @param {Injector} injector
 */
function Rules(injector) {
  this._commandStack = injector.get('commandStack', false);
}

Rules.$inject = ['injector'];
/**
 * Returns whether or not a given modeling action can be executed
 * in the specified context.
 *
 * This implementation will respond with allow unless anyone
 * objects.
 *
 * @param {string} action the action to be checked
 * @param {Object} [context] the context to check the action in
 *
 * @return {boolean} returns true, false or null depending on whether the
 *                   operation is allowed, not allowed or should be ignored.
 */

Rules.prototype.allowed = function (action, context) {
  var allowed = true;
  var commandStack = this._commandStack;

  if (commandStack) {
    allowed = commandStack.canExecute(action, context);
  } // map undefined to true, i.e. no rules


  return allowed === undefined ? true : allowed;
};

},{}],272:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _Rules = _interopRequireDefault(require("./Rules"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['rules'],
  rules: ['type', _Rules.default]
};
exports.default = _default;

},{"./Rules":271}],273:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SearchPad;

var _minDom = require("min-dom");

var _Elements = require("../../util/Elements");

var _EscapeUtil = require("../../util/EscapeUtil");

/**
 * Provides searching infrastructure
 */
function SearchPad(canvas, eventBus, overlays, selection) {
  this._open = false;
  this._results = [];
  this._eventMaps = [];
  this._canvas = canvas;
  this._eventBus = eventBus;
  this._overlays = overlays;
  this._selection = selection; // setup elements

  this._container = (0, _minDom.domify)(SearchPad.BOX_HTML);
  this._searchInput = (0, _minDom.query)(SearchPad.INPUT_SELECTOR, this._container);
  this._resultsContainer = (0, _minDom.query)(SearchPad.RESULTS_CONTAINER_SELECTOR, this._container); // attach search pad

  this._canvas.getContainer().appendChild(this._container); // cleanup on destroy


  eventBus.on(['canvas.destroy', 'diagram.destroy'], this.close, this);
}

SearchPad.$inject = ['canvas', 'eventBus', 'overlays', 'selection'];
/**
 * Binds and keeps track of all event listereners
 */

SearchPad.prototype._bindEvents = function () {
  var self = this;

  function listen(el, selector, type, fn) {
    self._eventMaps.push({
      el: el,
      type: type,
      listener: _minDom.delegate.bind(el, selector, type, fn)
    });
  } // close search on clicking anywhere outside


  listen(document, 'html', 'click', function (e) {
    self.close();
  }); // stop event from propagating and closing search
  // focus on input

  listen(this._container, SearchPad.INPUT_SELECTOR, 'click', function (e) {
    e.stopPropagation();
    e.delegateTarget.focus();
  }); // preselect result on hover

  listen(this._container, SearchPad.RESULT_SELECTOR, 'mouseover', function (e) {
    e.stopPropagation();

    self._scrollToNode(e.delegateTarget);

    self._preselect(e.delegateTarget);
  }); // selects desired result on mouse click

  listen(this._container, SearchPad.RESULT_SELECTOR, 'click', function (e) {
    e.stopPropagation();

    self._select(e.delegateTarget);
  }); // prevent cursor in input from going left and right when using up/down to
  // navigate results

  listen(this._container, SearchPad.INPUT_SELECTOR, 'keydown', function (e) {
    // up
    if (e.keyCode === 38) {
      e.preventDefault();
    } // down


    if (e.keyCode === 40) {
      e.preventDefault();
    }
  }); // handle keyboard input

  listen(this._container, SearchPad.INPUT_SELECTOR, 'keyup', function (e) {
    // escape
    if (e.keyCode === 27) {
      return self.close();
    } // enter


    if (e.keyCode === 13) {
      var selected = self._getCurrentResult();

      return selected ? self._select(selected) : self.close();
    } // up


    if (e.keyCode === 38) {
      return self._scrollToDirection(true);
    } // down


    if (e.keyCode === 40) {
      return self._scrollToDirection();
    } // left && right
    // do not search while navigating text input


    if (e.keyCode === 37 || e.keyCode === 39) {
      return;
    } // anything else


    self._search(e.delegateTarget.value);
  });
};
/**
 * Unbinds all previously established listeners
 */


SearchPad.prototype._unbindEvents = function () {
  this._eventMaps.forEach(function (m) {
    _minDom.delegate.unbind(m.el, m.type, m.listener);
  });
};
/**
 * Performs a search for the given pattern.
 *
 * @param  {string} pattern
 */


SearchPad.prototype._search = function (pattern) {
  var self = this;

  this._clearResults(); // do not search on empty query


  if (!pattern || pattern === '') {
    return;
  }

  var searchResults = this._searchProvider.find(pattern);

  if (!searchResults.length) {
    return;
  } // append new results


  searchResults.forEach(function (result) {
    var id = result.element.id;

    var node = self._createResultNode(result, id);

    self._results[id] = {
      element: result.element,
      node: node
    };
  }); // preselect first result

  var node = (0, _minDom.query)(SearchPad.RESULT_SELECTOR, this._resultsContainer);

  this._scrollToNode(node);

  this._preselect(node);
};
/**
 * Navigate to the previous/next result. Defaults to next result.
 * @param  {boolean} previous
 */


SearchPad.prototype._scrollToDirection = function (previous) {
  var selected = this._getCurrentResult();

  if (!selected) {
    return;
  }

  var node = previous ? selected.previousElementSibling : selected.nextElementSibling;

  if (node) {
    this._scrollToNode(node);

    this._preselect(node);
  }
};
/**
 * Scroll to the node if it is not visible.
 *
 * @param  {Element} node
 */


SearchPad.prototype._scrollToNode = function (node) {
  if (!node || node === this._getCurrentResult()) {
    return;
  }

  var nodeOffset = node.offsetTop;
  var containerScroll = this._resultsContainer.scrollTop;
  var bottomScroll = nodeOffset - this._resultsContainer.clientHeight + node.clientHeight;

  if (nodeOffset < containerScroll) {
    this._resultsContainer.scrollTop = nodeOffset;
  } else if (containerScroll < bottomScroll) {
    this._resultsContainer.scrollTop = bottomScroll;
  }
};
/**
 * Clears all results data.
 */


SearchPad.prototype._clearResults = function () {
  (0, _minDom.clear)(this._resultsContainer);
  this._results = [];

  this._resetOverlay();

  this._eventBus.fire('searchPad.cleared');
};
/**
 * Get currently selected result.
 *
 * @return {Element}
 */


SearchPad.prototype._getCurrentResult = function () {
  return (0, _minDom.query)(SearchPad.RESULT_SELECTED_SELECTOR, this._resultsContainer);
};
/**
 * Create result DOM element within results container
 * that corresponds to a search result.
 *
 * 'result' : one of the elements returned by SearchProvider
 * 'id' : id attribute value to assign to the new DOM node
 * return : created DOM element
 *
 * @param  {SearchResult} result
 * @param  {string} id
 * @return {Element}
 */


SearchPad.prototype._createResultNode = function (result, id) {
  var node = (0, _minDom.domify)(SearchPad.RESULT_HTML); // create only if available

  if (result.primaryTokens.length > 0) {
    createInnerTextNode(node, result.primaryTokens, SearchPad.RESULT_PRIMARY_HTML);
  } // secondary tokens (represent element ID) are allways available


  createInnerTextNode(node, result.secondaryTokens, SearchPad.RESULT_SECONDARY_HTML);
  (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE, id);

  this._resultsContainer.appendChild(node);

  return node;
};
/**
 * Register search element provider.
 *
 * SearchProvider.find - provides search function over own elements
 *  (pattern) => [{ text: <String>, element: <Element>}, ...]
 *
 * @param  {SearchProvider} provider
 */


SearchPad.prototype.registerProvider = function (provider) {
  this._searchProvider = provider;
};
/**
 * Open search pad.
 */


SearchPad.prototype.open = function () {
  if (!this._searchProvider) {
    throw new Error('no search provider registered');
  }

  if (this.isOpen()) {
    return;
  }

  this._bindEvents();

  this._open = true;
  (0, _minDom.classes)(this._container).add('open');

  this._searchInput.focus();

  this._eventBus.fire('searchPad.opened');
};
/**
 * Close search pad.
 */


SearchPad.prototype.close = function () {
  if (!this.isOpen()) {
    return;
  }

  this._unbindEvents();

  this._open = false;
  (0, _minDom.classes)(this._container).remove('open');

  this._clearResults();

  this._searchInput.value = '';

  this._searchInput.blur();

  this._resetOverlay();

  this._eventBus.fire('searchPad.closed');
};
/**
 * Toggles search pad on/off.
 */


SearchPad.prototype.toggle = function () {
  this.isOpen() ? this.close() : this.open();
};
/**
 * Report state of search pad.
 */


SearchPad.prototype.isOpen = function () {
  return this._open;
};
/**
 * Preselect result entry.
 *
 * @param  {Element} element
 */


SearchPad.prototype._preselect = function (node) {
  var selectedNode = this._getCurrentResult(); // already selected


  if (node === selectedNode) {
    return;
  } // removing preselection from current node


  if (selectedNode) {
    (0, _minDom.classes)(selectedNode).remove(SearchPad.RESULT_SELECTED_CLASS);
  }

  var id = (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE);
  var element = this._results[id].element;
  (0, _minDom.classes)(node).add(SearchPad.RESULT_SELECTED_CLASS);

  this._resetOverlay(element);

  this._centerViewbox(element);

  this._selection.select(element);

  this._eventBus.fire('searchPad.preselected', element);
};
/**
 * Select result node.
 *
 * @param  {Element} element
 */


SearchPad.prototype._select = function (node) {
  var id = (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE);
  var element = this._results[id].element;
  this.close();

  this._resetOverlay();

  this._centerViewbox(element);

  this._selection.select(element);

  this._eventBus.fire('searchPad.selected', element);
};
/**
 * Center viewbox on the element middle point.
 *
 * @param  {Element} element
 */


SearchPad.prototype._centerViewbox = function (element) {
  var viewbox = this._canvas.viewbox();

  var box = (0, _Elements.getBBox)(element);
  var newViewbox = {
    x: box.x + box.width / 2 - viewbox.outer.width / 2,
    y: box.y + box.height / 2 - viewbox.outer.height / 2,
    width: viewbox.outer.width,
    height: viewbox.outer.height
  };

  this._canvas.viewbox(newViewbox);

  this._canvas.zoom(viewbox.scale);
};
/**
 * Reset overlay removes and, optionally, set
 * overlay to a new element.
 *
 * @param  {Element} element
 */


SearchPad.prototype._resetOverlay = function (element) {
  if (this._overlayId) {
    this._overlays.remove(this._overlayId);
  }

  if (element) {
    var box = (0, _Elements.getBBox)(element);
    var overlay = constructOverlay(box);
    this._overlayId = this._overlays.add(element, overlay);
  }
};
/**
 * Construct overlay object for the given bounding box.
 *
 * @param  {BoundingBox} box
 * @return {Object}
 */


function constructOverlay(box) {
  var offset = 6;
  var w = box.width + offset * 2;
  var h = box.height + offset * 2;
  var styles = ['width: ' + w + 'px', 'height: ' + h + 'px'].join('; ');
  return {
    position: {
      bottom: h - offset,
      right: w - offset
    },
    show: true,
    html: '<div style="' + styles + '" class="' + SearchPad.OVERLAY_CLASS + '"></div>'
  };
}
/**
 * Creates and appends child node from result tokens and HTML template.
 *
 * @param  {Element} node
 * @param  {Array<Object>} tokens
 * @param  {string} template
 */


function createInnerTextNode(parentNode, tokens, template) {
  var text = createHtmlText(tokens);
  var childNode = (0, _minDom.domify)(template);
  childNode.innerHTML = text;
  parentNode.appendChild(childNode);
}
/**
 * Create internal HTML markup from result tokens.
 * Caters for highlighting pattern matched tokens.
 *
 * @param  {Array<Object>} tokens
 * @return {string}
 */


function createHtmlText(tokens) {
  var htmlText = '';
  tokens.forEach(function (t) {
    if (t.matched) {
      htmlText += '<strong class="' + SearchPad.RESULT_HIGHLIGHT_CLASS + '">' + (0, _EscapeUtil.escapeHTML)(t.matched) + '</strong>';
    } else {
      htmlText += (0, _EscapeUtil.escapeHTML)(t.normal);
    }
  });
  return htmlText !== '' ? htmlText : null;
}
/**
 * CONSTANTS
 */


SearchPad.CONTAINER_SELECTOR = '.djs-search-container';
SearchPad.INPUT_SELECTOR = '.djs-search-input input';
SearchPad.RESULTS_CONTAINER_SELECTOR = '.djs-search-results';
SearchPad.RESULT_SELECTOR = '.djs-search-result';
SearchPad.RESULT_SELECTED_CLASS = 'djs-search-result-selected';
SearchPad.RESULT_SELECTED_SELECTOR = '.' + SearchPad.RESULT_SELECTED_CLASS;
SearchPad.RESULT_ID_ATTRIBUTE = 'data-result-id';
SearchPad.RESULT_HIGHLIGHT_CLASS = 'djs-search-highlight';
SearchPad.OVERLAY_CLASS = 'djs-search-overlay';
SearchPad.BOX_HTML = '<div class="djs-search-container djs-draggable djs-scrollable">' + '<div class="djs-search-input">' + '<input type="text"/>' + '</div>' + '<div class="djs-search-results"></div>' + '</div>';
SearchPad.RESULT_HTML = '<div class="djs-search-result"></div>';
SearchPad.RESULT_PRIMARY_HTML = '<div class="djs-search-result-primary"></div>';
SearchPad.RESULT_SECONDARY_HTML = '<p class="djs-search-result-secondary"></p>';

},{"../../util/Elements":315,"../../util/EscapeUtil":316,"min-dom":556}],274:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _overlays = _interopRequireDefault(require("../overlays"));

var _selection = _interopRequireDefault(require("../selection"));

var _SearchPad = _interopRequireDefault(require("./SearchPad"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_overlays.default, _selection.default],
  searchPad: ['type', _SearchPad.default]
};
exports.default = _default;

},{"../overlays":256,"../selection":278,"./SearchPad":273}],275:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Selection;

var _minDash = require("min-dash");

/**
 * A service that offers the current selection in a diagram.
 * Offers the api to control the selection, too.
 *
 * @class
 *
 * @param {EventBus} eventBus the event bus
 */
function Selection(eventBus) {
  this._eventBus = eventBus;
  this._selectedElements = [];
  var self = this;
  eventBus.on(['shape.remove', 'connection.remove'], function (e) {
    var element = e.element;
    self.deselect(element);
  });
  eventBus.on(['diagram.clear'], function (e) {
    self.select(null);
  });
}

Selection.$inject = ['eventBus'];

Selection.prototype.deselect = function (element) {
  var selectedElements = this._selectedElements;
  var idx = selectedElements.indexOf(element);

  if (idx !== -1) {
    var oldSelection = selectedElements.slice();
    selectedElements.splice(idx, 1);

    this._eventBus.fire('selection.changed', {
      oldSelection: oldSelection,
      newSelection: selectedElements
    });
  }
};

Selection.prototype.get = function () {
  return this._selectedElements;
};

Selection.prototype.isSelected = function (element) {
  return this._selectedElements.indexOf(element) !== -1;
};
/**
 * This method selects one or more elements on the diagram.
 *
 * By passing an additional add parameter you can decide whether or not the element(s)
 * should be added to the already existing selection or not.
 *
 * @method Selection#select
 *
 * @param  {Object|Object[]} elements element or array of elements to be selected
 * @param  {boolean} [add] whether the element(s) should be appended to the current selection, defaults to false
 */


Selection.prototype.select = function (elements, add) {
  var selectedElements = this._selectedElements,
      oldSelection = selectedElements.slice();

  if (!(0, _minDash.isArray)(elements)) {
    elements = elements ? [elements] : [];
  } // selection may be cleared by passing an empty array or null
  // to the method


  if (add) {
    (0, _minDash.forEach)(elements, function (element) {
      if (selectedElements.indexOf(element) !== -1) {
        // already selected
        return;
      } else {
        selectedElements.push(element);
      }
    });
  } else {
    this._selectedElements = selectedElements = elements.slice();
  }

  this._eventBus.fire('selection.changed', {
    oldSelection: oldSelection,
    newSelection: selectedElements
  });
};

},{"min-dash":555}],276:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SelectionBehavior;

var _Mouse = require("../../util/Mouse");

var _minDash = require("min-dash");

function SelectionBehavior(eventBus, selection, canvas, elementRegistry) {
  // Select elements on create
  eventBus.on('create.end', 500, function (event) {
    var context = event.context,
        canExecute = context.canExecute,
        elements = context.elements,
        hints = context.hints || {},
        autoSelect = hints.autoSelect;

    if (canExecute) {
      if (autoSelect === false) {
        // Select no elements
        return;
      }

      if ((0, _minDash.isArray)(autoSelect)) {
        selection.select(autoSelect);
      } else {
        // Select all elements by default
        selection.select(elements.filter(isShown));
      }
    }
  }); // Select connection targets on connect

  eventBus.on('connect.end', 500, function (event) {
    var context = event.context,
        canExecute = context.canExecute,
        hover = context.hover;

    if (canExecute && hover) {
      selection.select(hover);
    }
  }); // Select shapes on move

  eventBus.on('shape.move.end', 500, function (event) {
    var previousSelection = event.previousSelection || [];
    var shape = elementRegistry.get(event.context.shape.id); // Always select main shape on move

    var isSelected = (0, _minDash.find)(previousSelection, function (selectedShape) {
      return shape.id === selectedShape.id;
    });

    if (!isSelected) {
      selection.select(shape);
    }
  }); // Select elements on click

  eventBus.on('element.click', function (event) {
    var element = event.element;

    if (element === canvas.getRootElement()) {
      element = null;
    }

    var isSelected = selection.isSelected(element),
        isMultiSelect = selection.get().length > 1; // Add to selection if CTRL or SHIFT pressed

    var add = (0, _Mouse.hasPrimaryModifier)(event) || (0, _Mouse.hasSecondaryModifier)(event);

    if (isSelected && isMultiSelect) {
      if (add) {
        // Deselect element
        return selection.deselect(element);
      } else {
        // Select element only
        return selection.select(element);
      }
    } else if (!isSelected) {
      // Select element
      selection.select(element, add);
    } else {
      // Deselect element
      selection.deselect(element);
    }
  });
}

SelectionBehavior.$inject = ['eventBus', 'selection', 'canvas', 'elementRegistry'];

function isShown(element) {
  return !element.hidden;
}

},{"../../util/Mouse":323,"min-dash":555}],277:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SelectionVisuals;

var _minDash = require("min-dash");

var MARKER_HOVER = 'hover',
    MARKER_SELECTED = 'selected';
/**
 * A plugin that adds a visible selection UI to shapes and connections
 * by appending the <code>hover</code> and <code>selected</code> classes to them.
 *
 * @class
 *
 * Makes elements selectable, too.
 *
 * @param {EventBus} events
 * @param {SelectionService} selection
 * @param {Canvas} canvas
 */

function SelectionVisuals(events, canvas, selection, styles) {
  this._multiSelectionBox = null;

  function addMarker(e, cls) {
    canvas.addMarker(e, cls);
  }

  function removeMarker(e, cls) {
    canvas.removeMarker(e, cls);
  }

  events.on('element.hover', function (event) {
    addMarker(event.element, MARKER_HOVER);
  });
  events.on('element.out', function (event) {
    removeMarker(event.element, MARKER_HOVER);
  });
  events.on('selection.changed', function (event) {
    function deselect(s) {
      removeMarker(s, MARKER_SELECTED);
    }

    function select(s) {
      addMarker(s, MARKER_SELECTED);
    }

    var oldSelection = event.oldSelection,
        newSelection = event.newSelection;
    (0, _minDash.forEach)(oldSelection, function (e) {
      if (newSelection.indexOf(e) === -1) {
        deselect(e);
      }
    });
    (0, _minDash.forEach)(newSelection, function (e) {
      if (oldSelection.indexOf(e) === -1) {
        select(e);
      }
    });
  });
}

SelectionVisuals.$inject = ['eventBus', 'canvas', 'selection', 'styles'];

},{"min-dash":555}],278:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _interactionEvents = _interopRequireDefault(require("../interaction-events"));

var _outline = _interopRequireDefault(require("../outline"));

var _Selection = _interopRequireDefault(require("./Selection"));

var _SelectionVisuals = _interopRequireDefault(require("./SelectionVisuals"));

var _SelectionBehavior = _interopRequireDefault(require("./SelectionBehavior"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['selectionVisuals', 'selectionBehavior'],
  __depends__: [_interactionEvents.default, _outline.default],
  selection: ['type', _Selection.default],
  selectionVisuals: ['type', _SelectionVisuals.default],
  selectionBehavior: ['type', _SelectionBehavior.default]
};
exports.default = _default;

},{"../interaction-events":211,"../outline":254,"./Selection":275,"./SelectionBehavior":276,"./SelectionVisuals":277}],279:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CreateMoveSnapping;

var _SnapContext = _interopRequireDefault(require("./SnapContext"));

var _SnapUtil = require("./SnapUtil");

var _KeyboardUtil = require("../keyboard/KeyboardUtil");

var _minDash = require("min-dash");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var HIGHER_PRIORITY = 1250;
/**
 * Snap during create and move.
 *
 * @param {EventBus} elementRegistry
 * @param {EventBus} eventBus
 * @param {Snapping} snapping
 */

function CreateMoveSnapping(elementRegistry, eventBus, snapping) {
  var self = this;
  this._elementRegistry = elementRegistry;
  eventBus.on(['create.start', 'shape.move.start'], function (event) {
    self.initSnap(event);
  });
  eventBus.on(['create.move', 'create.end', 'shape.move.move', 'shape.move.end'], HIGHER_PRIORITY, function (event) {
    var context = event.context,
        shape = context.shape,
        snapContext = context.snapContext,
        target = context.target;

    if (event.originalEvent && (0, _KeyboardUtil.isCmd)(event.originalEvent)) {
      return;
    }

    if ((0, _SnapUtil.isSnapped)(event) || !target) {
      return;
    }

    var snapPoints = snapContext.pointsForTarget(target);

    if (!snapPoints.initialized) {
      snapPoints = self.addSnapTargetPoints(snapPoints, shape, target);
      snapPoints.initialized = true;
    }

    snapping.snap(event, snapPoints);
  });
  eventBus.on(['create.cleanup', 'shape.move.cleanup'], function () {
    snapping.hide();
  });
}

CreateMoveSnapping.$inject = ['elementRegistry', 'eventBus', 'snapping'];

CreateMoveSnapping.prototype.initSnap = function (event) {
  var elementRegistry = this._elementRegistry;
  var context = event.context,
      shape = context.shape,
      snapContext = context.snapContext;

  if (!snapContext) {
    snapContext = context.snapContext = new _SnapContext.default();
  }

  var shapeMid;

  if (elementRegistry.get(shape.id)) {
    // move
    shapeMid = (0, _SnapUtil.mid)(shape, event);
  } else {
    // create
    shapeMid = {
      x: event.x + (0, _SnapUtil.mid)(shape).x,
      y: event.y + (0, _SnapUtil.mid)(shape).y
    };
  }

  var shapeTopLeft = {
    x: shapeMid.x - shape.width / 2,
    y: shapeMid.y - shape.height / 2
  },
      shapeBottomRight = {
    x: shapeMid.x + shape.width / 2,
    y: shapeMid.y + shape.height / 2
  };
  snapContext.setSnapOrigin('mid', {
    x: shapeMid.x - event.x,
    y: shapeMid.y - event.y
  }); // snap labels to mid only

  if (isLabel(shape)) {
    return snapContext;
  }

  snapContext.setSnapOrigin('top-left', {
    x: shapeTopLeft.x - event.x,
    y: shapeTopLeft.y - event.y
  });
  snapContext.setSnapOrigin('bottom-right', {
    x: shapeBottomRight.x - event.x,
    y: shapeBottomRight.y - event.y
  });
  return snapContext;
};

CreateMoveSnapping.prototype.addSnapTargetPoints = function (snapPoints, shape, target) {
  var snapTargets = this.getSnapTargets(shape, target);
  (0, _minDash.forEach)(snapTargets, function (snapTarget) {
    // handle labels
    if (isLabel(snapTarget)) {
      if (isLabel(shape)) {
        snapPoints.add('mid', (0, _SnapUtil.mid)(snapTarget));
      }

      return;
    } // handle connections


    if (isConnection(snapTarget)) {
      // ignore single segment connections
      if (snapTarget.waypoints.length < 3) {
        return;
      } // ignore first and last waypoint


      var waypoints = snapTarget.waypoints.slice(1, -1);
      (0, _minDash.forEach)(waypoints, function (waypoint) {
        snapPoints.add('mid', waypoint);
      });
      return;
    } // handle shapes


    snapPoints.add('mid', (0, _SnapUtil.mid)(snapTarget));
  });

  if (!(0, _minDash.isNumber)(shape.x) || !(0, _minDash.isNumber)(shape.y)) {
    return snapPoints;
  } // snap to original position when moving


  if (this._elementRegistry.get(shape.id)) {
    snapPoints.add('mid', (0, _SnapUtil.mid)(shape));
  }

  return snapPoints;
};

CreateMoveSnapping.prototype.getSnapTargets = function (shape, target) {
  return (0, _SnapUtil.getChildren)(target).filter(function (child) {
    return !isHidden(child);
  });
}; // helpers //////////


function isConnection(element) {
  return !!element.waypoints;
}

function isHidden(element) {
  return !!element.hidden;
}

function isLabel(element) {
  return !!element.labelTarget;
}

},{"../keyboard/KeyboardUtil":216,"./SnapContext":281,"./SnapUtil":282,"min-dash":555}],280:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ResizeSnapping;

var _SnapContext = _interopRequireDefault(require("./SnapContext"));

var _SnapUtil = require("./SnapUtil");

var _KeyboardUtil = require("../keyboard/KeyboardUtil");

var _LayoutUtil = require("../../layout/LayoutUtil");

var _minDash = require("min-dash");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var HIGHER_PRIORITY = 1250;
/**
 * Snap during resize.
 *
 * @param {EventBus} eventBus
 * @param {Snapping} snapping
 */

function ResizeSnapping(eventBus, snapping) {
  var self = this;
  eventBus.on(['resize.start'], function (event) {
    self.initSnap(event);
  });
  eventBus.on(['resize.move', 'resize.end'], HIGHER_PRIORITY, function (event) {
    var context = event.context,
        shape = context.shape,
        parent = shape.parent,
        direction = context.direction,
        snapContext = context.snapContext;

    if (event.originalEvent && (0, _KeyboardUtil.isCmd)(event.originalEvent)) {
      return;
    }

    if ((0, _SnapUtil.isSnapped)(event)) {
      return;
    }

    var snapPoints = snapContext.pointsForTarget(parent);

    if (!snapPoints.initialized) {
      snapPoints = self.addSnapTargetPoints(snapPoints, shape, parent, direction);
      snapPoints.initialized = true;
    }

    if (isHorizontal(direction)) {
      (0, _SnapUtil.setSnapped)(event, 'x', event.x);
    }

    if (isVertical(direction)) {
      (0, _SnapUtil.setSnapped)(event, 'y', event.y);
    }

    snapping.snap(event, snapPoints);
  });
  eventBus.on(['resize.cleanup'], function () {
    snapping.hide();
  });
}

ResizeSnapping.prototype.initSnap = function (event) {
  var context = event.context,
      shape = context.shape,
      direction = context.direction,
      snapContext = context.snapContext;

  if (!snapContext) {
    snapContext = context.snapContext = new _SnapContext.default();
  }

  var snapOrigin = getSnapOrigin(shape, direction);
  snapContext.setSnapOrigin('corner', {
    x: snapOrigin.x - event.x,
    y: snapOrigin.y - event.y
  });
  return snapContext;
};

ResizeSnapping.prototype.addSnapTargetPoints = function (snapPoints, shape, target, direction) {
  var snapTargets = this.getSnapTargets(shape, target);
  (0, _minDash.forEach)(snapTargets, function (snapTarget) {
    snapPoints.add('corner', (0, _SnapUtil.bottomRight)(snapTarget));
    snapPoints.add('corner', (0, _SnapUtil.topLeft)(snapTarget));
  });
  snapPoints.add('corner', getSnapOrigin(shape, direction));
  return snapPoints;
};

ResizeSnapping.$inject = ['eventBus', 'snapping'];

ResizeSnapping.prototype.getSnapTargets = function (shape, target) {
  return (0, _SnapUtil.getChildren)(target).filter(function (child) {
    return !isAttached(child, shape) && !isConnection(child) && !isHidden(child) && !isLabel(child);
  });
}; // helpers //////////


function getSnapOrigin(shape, direction) {
  var mid = (0, _LayoutUtil.getMid)(shape),
      trbl = (0, _LayoutUtil.asTRBL)(shape);
  var snapOrigin = {
    x: mid.x,
    y: mid.y
  };

  if (direction.indexOf('n') !== -1) {
    snapOrigin.y = trbl.top;
  } else if (direction.indexOf('s') !== -1) {
    snapOrigin.y = trbl.bottom;
  }

  if (direction.indexOf('e') !== -1) {
    snapOrigin.x = trbl.right;
  } else if (direction.indexOf('w') !== -1) {
    snapOrigin.x = trbl.left;
  }

  return snapOrigin;
}

function isAttached(element, host) {
  return element.host === host;
}

function isConnection(element) {
  return !!element.waypoints;
}

function isHidden(element) {
  return !!element.hidden;
}

function isLabel(element) {
  return !!element.labelTarget;
}

function isHorizontal(direction) {
  return direction === 'n' || direction === 's';
}

function isVertical(direction) {
  return direction === 'e' || direction === 'w';
}

},{"../../layout/LayoutUtil":300,"../keyboard/KeyboardUtil":216,"./SnapContext":281,"./SnapUtil":282,"min-dash":555}],281:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SnapContext;
exports.SnapPoints = SnapPoints;

var _minDash = require("min-dash");

var _SnapUtil = require("./SnapUtil");

/**
 * A snap context, containing the (possibly incomplete)
 * mappings of drop targets (to identify the snapping)
 * to computed snap points.
 */
function SnapContext() {
  /**
   * Map<String, SnapPoints> mapping drop targets to
   * a list of possible snappings.
   *
   * @type {Object}
   */
  this._targets = {};
  /**
   * Map<String, Point> initial positioning of element
   * regarding various snap directions.
   *
   * @type {Object}
   */

  this._snapOrigins = {};
  /**
   * List of snap locations
   *
   * @type {Array<string>}
   */

  this._snapLocations = [];
  /**
   * Map<String, Array<Point>> of default snapping locations
   *
   * @type {Object}
   */

  this._defaultSnaps = {};
}

SnapContext.prototype.getSnapOrigin = function (snapLocation) {
  return this._snapOrigins[snapLocation];
};

SnapContext.prototype.setSnapOrigin = function (snapLocation, initialValue) {
  this._snapOrigins[snapLocation] = initialValue;

  if (this._snapLocations.indexOf(snapLocation) === -1) {
    this._snapLocations.push(snapLocation);
  }
};

SnapContext.prototype.addDefaultSnap = function (type, point) {
  var snapValues = this._defaultSnaps[type];

  if (!snapValues) {
    snapValues = this._defaultSnaps[type] = [];
  }

  snapValues.push(point);
};
/**
 * Return a number of initialized snaps, i.e. snap locations such as
 * top-left, mid, bottom-right and so forth.
 *
 * @return {Array<string>} snapLocations
 */


SnapContext.prototype.getSnapLocations = function () {
  return this._snapLocations;
};
/**
 * Set the snap locations for this context.
 *
 * The order of locations determines precedence.
 *
 * @param {Array<string>} snapLocations
 */


SnapContext.prototype.setSnapLocations = function (snapLocations) {
  this._snapLocations = snapLocations;
};
/**
 * Get snap points for a given target
 *
 * @param {Element|string} target
 */


SnapContext.prototype.pointsForTarget = function (target) {
  var targetId = target.id || target;
  var snapPoints = this._targets[targetId];

  if (!snapPoints) {
    snapPoints = this._targets[targetId] = new SnapPoints();
    snapPoints.initDefaults(this._defaultSnaps);
  }

  return snapPoints;
};
/**
 * Creates the snap points and initializes them with the
 * given default values.
 *
 * @param {Object<string, Array<Point>>} [defaultPoints]
 */


function SnapPoints(defaultSnaps) {
  /**
   * Map<String, Map<(x|y), Array<number>>> mapping snap locations,
   * i.e. top-left, bottom-right, center to actual snap values.
   *
   * @type {Object}
   */
  this._snapValues = {};
}

SnapPoints.prototype.add = function (snapLocation, point) {
  var snapValues = this._snapValues[snapLocation];

  if (!snapValues) {
    snapValues = this._snapValues[snapLocation] = {
      x: [],
      y: []
    };
  }

  if (snapValues.x.indexOf(point.x) === -1) {
    snapValues.x.push(point.x);
  }

  if (snapValues.y.indexOf(point.y) === -1) {
    snapValues.y.push(point.y);
  }
};

SnapPoints.prototype.snap = function (point, snapLocation, axis, tolerance) {
  var snappingValues = this._snapValues[snapLocation];
  return snappingValues && (0, _SnapUtil.snapTo)(point[axis], snappingValues[axis], tolerance);
};
/**
 * Initialize a number of default snapping points.
 *
 * @param  {Object} defaultSnaps
 */


SnapPoints.prototype.initDefaults = function (defaultSnaps) {
  var self = this;
  (0, _minDash.forEach)(defaultSnaps || {}, function (snapPoints, snapLocation) {
    (0, _minDash.forEach)(snapPoints, function (point) {
      self.add(snapLocation, point);
    });
  });
};

},{"./SnapUtil":282,"min-dash":555}],282:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.snapTo = snapTo;
exports.topLeft = topLeft;
exports.topRight = topRight;
exports.bottomLeft = bottomLeft;
exports.bottomRight = bottomRight;
exports.mid = mid;
exports.isSnapped = isSnapped;
exports.setSnapped = setSnapped;
exports.getChildren = getChildren;
var abs = Math.abs,
    round = Math.round;
/**
 * Snap value to a collection of reference values.
 *
 * @param  {number} value
 * @param  {Array<number>} values
 * @param  {number} [tolerance=10]
 *
 * @return {number} the value we snapped to or null, if none snapped
 */

function snapTo(value, values, tolerance) {
  tolerance = tolerance === undefined ? 10 : tolerance;
  var idx, snapValue;

  for (idx = 0; idx < values.length; idx++) {
    snapValue = values[idx];

    if (abs(snapValue - value) <= tolerance) {
      return snapValue;
    }
  }
}

function topLeft(bounds) {
  return {
    x: bounds.x,
    y: bounds.y
  };
}

function topRight(bounds) {
  return {
    x: bounds.x + bounds.width,
    y: bounds.y
  };
}

function bottomLeft(bounds) {
  return {
    x: bounds.x,
    y: bounds.y + bounds.height
  };
}

function bottomRight(bounds) {
  return {
    x: bounds.x + bounds.width,
    y: bounds.y + bounds.height
  };
}

function mid(bounds, defaultValue) {
  if (!bounds || isNaN(bounds.x) || isNaN(bounds.y)) {
    return defaultValue;
  }

  return {
    x: round(bounds.x + bounds.width / 2),
    y: round(bounds.y + bounds.height / 2)
  };
}
/**
 * Retrieve the snap state of the given event.
 *
 * @param  {Event} event
 * @param  {string} axis
 *
 * @return {boolean} the snapped state
 *
 */


function isSnapped(event, axis) {
  var snapped = event.snapped;

  if (!snapped) {
    return false;
  }

  if (typeof axis === 'string') {
    return snapped[axis];
  }

  return snapped.x && snapped.y;
}
/**
 * Set the given event as snapped.
 *
 * This method may change the x and/or y position of the shape
 * from the given event!
 *
 * @param {Event} event
 * @param {string} axis
 * @param {number|boolean} value
 *
 * @return {number} old value
 */


function setSnapped(event, axis, value) {
  if (typeof axis !== 'string') {
    throw new Error('axis must be in [x, y]');
  }

  if (typeof value !== 'number' && value !== false) {
    throw new Error('value must be Number or false');
  }

  var delta,
      previousValue = event[axis];
  var snapped = event.snapped = event.snapped || {};

  if (value === false) {
    snapped[axis] = false;
  } else {
    snapped[axis] = true;
    delta = value - previousValue;
    event[axis] += delta;
    event['d' + axis] += delta;
  }

  return previousValue;
}
/**
 * Get children of a shape.
 *
 * @param {djs.model.Shape} parent
 *
 * @returns {Array<djs.model.Shape|djs.model.Connection>}
 */


function getChildren(parent) {
  return parent.children || [];
}

},{}],283:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Snapping;
exports.SNAP_LINE_HIDE_DELAY = void 0;

var _minDash = require("min-dash");

var _SnapUtil = require("./SnapUtil");

var _tinySvg = require("tiny-svg");

var SNAP_TOLERANCE = 7;
var SNAP_LINE_HIDE_DELAY = 1000;
/**
 * Generic snapping feature.
 *
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 */

exports.SNAP_LINE_HIDE_DELAY = SNAP_LINE_HIDE_DELAY;

function Snapping(canvas) {
  this._canvas = canvas; // delay hide by 1000 seconds since last snap

  this._asyncHide = (0, _minDash.debounce)((0, _minDash.bind)(this.hide, this), SNAP_LINE_HIDE_DELAY);
}

Snapping.$inject = ['canvas'];
/**
 * Snap an event to given snap points.
 *
 * @param {Event} event
 * @param {SnapPoints} snapPoints
 */

Snapping.prototype.snap = function (event, snapPoints) {
  var context = event.context,
      snapContext = context.snapContext,
      snapLocations = snapContext.getSnapLocations();
  var snapping = {
    x: (0, _SnapUtil.isSnapped)(event, 'x'),
    y: (0, _SnapUtil.isSnapped)(event, 'y')
  };
  (0, _minDash.forEach)(snapLocations, function (location) {
    var snapOrigin = snapContext.getSnapOrigin(location);
    var snapCurrent = {
      x: event.x + snapOrigin.x,
      y: event.y + snapOrigin.y
    }; // snap both axis if not snapped already

    (0, _minDash.forEach)(['x', 'y'], function (axis) {
      var locationSnapping;

      if (!snapping[axis]) {
        locationSnapping = snapPoints.snap(snapCurrent, location, axis, SNAP_TOLERANCE);

        if (locationSnapping !== undefined) {
          snapping[axis] = {
            value: locationSnapping,
            originValue: locationSnapping - snapOrigin[axis]
          };
        }
      }
    }); // no need to continue snapping

    if (snapping.x && snapping.y) {
      return false;
    }
  }); // show snap lines

  this.showSnapLine('vertical', snapping.x && snapping.x.value);
  this.showSnapLine('horizontal', snapping.y && snapping.y.value); // snap event

  (0, _minDash.forEach)(['x', 'y'], function (axis) {
    var axisSnapping = snapping[axis];

    if ((0, _minDash.isObject)(axisSnapping)) {
      (0, _SnapUtil.setSnapped)(event, axis, axisSnapping.originValue);
    }
  });
};

Snapping.prototype._createLine = function (orientation) {
  var root = this._canvas.getLayer('snap');

  var line = (0, _tinySvg.create)('path');
  (0, _tinySvg.attr)(line, {
    d: 'M0,0 L0,0'
  });
  (0, _tinySvg.classes)(line).add('djs-snap-line');
  (0, _tinySvg.append)(root, line);
  return {
    update: function (position) {
      if (!(0, _minDash.isNumber)(position)) {
        (0, _tinySvg.attr)(line, {
          display: 'none'
        });
      } else {
        if (orientation === 'horizontal') {
          (0, _tinySvg.attr)(line, {
            d: 'M-100000,' + position + ' L+100000,' + position,
            display: ''
          });
        } else {
          (0, _tinySvg.attr)(line, {
            d: 'M ' + position + ',-100000 L ' + position + ', +100000',
            display: ''
          });
        }
      }
    }
  };
};

Snapping.prototype._createSnapLines = function () {
  this._snapLines = {
    horizontal: this._createLine('horizontal'),
    vertical: this._createLine('vertical')
  };
};

Snapping.prototype.showSnapLine = function (orientation, position) {
  var line = this.getSnapLine(orientation);

  if (line) {
    line.update(position);
  }

  this._asyncHide();
};

Snapping.prototype.getSnapLine = function (orientation) {
  if (!this._snapLines) {
    this._createSnapLines();
  }

  return this._snapLines[orientation];
};

Snapping.prototype.hide = function () {
  (0, _minDash.forEach)(this._snapLines, function (snapLine) {
    snapLine.update();
  });
};

},{"./SnapUtil":282,"min-dash":555,"tiny-svg":567}],284:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _CreateMoveSnapping = _interopRequireDefault(require("./CreateMoveSnapping"));

var _ResizeSnapping = _interopRequireDefault(require("./ResizeSnapping"));

var _Snapping = _interopRequireDefault(require("./Snapping"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['createMoveSnapping', 'resizeSnapping', 'snapping'],
  createMoveSnapping: ['type', _CreateMoveSnapping.default],
  resizeSnapping: ['type', _ResizeSnapping.default],
  snapping: ['type', _Snapping.default]
};
exports.default = _default;

},{"./CreateMoveSnapping":279,"./ResizeSnapping":280,"./Snapping":283}],285:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SpaceTool;

var _minDash = require("min-dash");

var _LayoutUtil = require("../../layout/LayoutUtil");

var _Elements = require("../../util/Elements");

var _SpaceUtil = require("./SpaceUtil");

var _Mouse = require("../../util/Mouse");

var _Cursor = require("../../util/Cursor");

var abs = Math.abs,
    round = Math.round;
var AXIS_TO_DIMENSION = {
  x: 'width',
  y: 'height'
};
var CURSOR_CROSSHAIR = 'crosshair';
var DIRECTION_TO_TRBL = {
  n: 'top',
  w: 'left',
  s: 'bottom',
  e: 'right'
};
var HIGH_PRIORITY = 1500;
var DIRECTION_TO_OPPOSITE = {
  n: 's',
  w: 'e',
  s: 'n',
  e: 'w'
};
var PADDING = 20;
/**
 * Add or remove space by moving and resizing elements.
 *
 * @param {Canvas} canvas
 * @param {Dragging} dragging
 * @param {EventBus} eventBus
 * @param {Modeling} modeling
 * @param {Rules} rules
 * @param {toolManager} toolManager
 */

function SpaceTool(canvas, dragging, eventBus, modeling, rules, toolManager) {
  this._canvas = canvas;
  this._dragging = dragging;
  this._eventBus = eventBus;
  this._modeling = modeling;
  this._rules = rules;
  this._toolManager = toolManager;
  var self = this;
  toolManager.registerTool('space', {
    tool: 'spaceTool.selection',
    dragging: 'spaceTool'
  });
  eventBus.on('spaceTool.selection.end', function (event) {
    eventBus.once('spaceTool.selection.ended', function () {
      self.activateMakeSpace(event.originalEvent);
    });
  });
  eventBus.on('spaceTool.move', HIGH_PRIORITY, function (event) {
    var context = event.context,
        initialized = context.initialized;

    if (!initialized) {
      initialized = context.initialized = self.init(event, context);
    }

    if (initialized) {
      ensureConstraints(event);
    }
  });
  eventBus.on('spaceTool.end', function (event) {
    var context = event.context,
        axis = context.axis,
        direction = context.direction,
        movingShapes = context.movingShapes,
        resizingShapes = context.resizingShapes,
        start = context.start;

    if (!context.initialized) {
      return;
    }

    ensureConstraints(event);
    var delta = {
      x: 0,
      y: 0
    };
    delta[axis] = round(event['d' + axis]);
    self.makeSpace(movingShapes, resizingShapes, delta, direction, start);
    eventBus.once('spaceTool.ended', function (event) {
      // activate space tool selection after make space
      self.activateSelection(event.originalEvent, true, true);
    });
  });
}

SpaceTool.$inject = ['canvas', 'dragging', 'eventBus', 'modeling', 'rules', 'toolManager'];
/**
 * Activate space tool selection.
 *
 * @param {Object} event
 * @param {boolean} autoActivate
 */

SpaceTool.prototype.activateSelection = function (event, autoActivate, reactivate) {
  this._dragging.init(event, 'spaceTool.selection', {
    autoActivate: autoActivate,
    cursor: CURSOR_CROSSHAIR,
    data: {
      context: {
        reactivate: reactivate
      }
    },
    trapClick: false
  });
};
/**
 * Activate space tool make space.
 *
 * @param  {MouseEvent} event
 */


SpaceTool.prototype.activateMakeSpace = function (event) {
  this._dragging.init(event, 'spaceTool', {
    autoActivate: true,
    cursor: CURSOR_CROSSHAIR,
    data: {
      context: {}
    }
  });
};
/**
 * Make space.
 *
 * @param  {Array<djs.model.Shape>} movingShapes
 * @param  {Array<djs.model.Shape>} resizingShapes
 * @param  {Object} delta
 * @param  {number} delta.x
 * @param  {number} delta.y
 * @param  {string} direction
 * @param  {number} start
 */


SpaceTool.prototype.makeSpace = function (movingShapes, resizingShapes, delta, direction, start) {
  return this._modeling.createSpace(movingShapes, resizingShapes, delta, direction, start);
};
/**
 * Initialize make space and return true if that was successful.
 *
 * @param {Object} event
 * @param {Object} context
 *
 * @return {boolean}
 */


SpaceTool.prototype.init = function (event, context) {
  var axis = abs(event.dx) > abs(event.dy) ? 'x' : 'y',
      delta = event['d' + axis],
      start = event[axis] - delta;

  if (abs(delta) < 5) {
    return false;
  } // invert delta to remove space when moving left


  if (delta < 0) {
    delta *= -1;
  } // invert delta to add/remove space when removing/adding space if modifier key is pressed


  if ((0, _Mouse.hasPrimaryModifier)(event)) {
    delta *= -1;
  }

  var direction = (0, _SpaceUtil.getDirection)(axis, delta);

  var root = this._canvas.getRootElement();

  var children = (0, _Elements.selfAndAllChildren)(root, true);
  var elements = this.calculateAdjustments(children, axis, delta, start);

  var minDimensions = this._eventBus.fire('spaceTool.getMinDimensions', {
    axis: axis,
    direction: direction,
    shapes: elements.resizingShapes,
    start: start
  });

  var spaceToolConstraints = getSpaceToolConstraints(elements, axis, direction, start, minDimensions);
  (0, _minDash.assign)(context, elements, {
    axis: axis,
    direction: direction,
    spaceToolConstraints: spaceToolConstraints,
    start: start
  });
  (0, _Cursor.set)('resize-' + (axis === 'x' ? 'ew' : 'ns'));
  return true;
};
/**
 * Get elements to be moved and resized.
 *
 * @param  {Array<djs.model.Shape>} elements
 * @param  {string} axis
 * @param  {number} delta
 * @param  {number} start
 *
 * @return {Object}
 */


SpaceTool.prototype.calculateAdjustments = function (elements, axis, delta, start) {
  var rules = this._rules;
  var movingShapes = [],
      resizingShapes = [];
  (0, _minDash.forEach)(elements, function (element) {
    if (!element.parent || isConnection(element)) {
      return;
    }

    var shapeStart = element[axis],
        shapeEnd = shapeStart + element[AXIS_TO_DIMENSION[axis]]; // shape to be moved

    if (delta > 0 && shapeStart > start || delta < 0 && shapeEnd < start) {
      return movingShapes.push(element);
    } // shape to be resized


    if (shapeStart < start && shapeEnd > start && rules.allowed('shape.resize', {
      shape: element
    })) {
      return resizingShapes.push(element);
    }
  });
  return {
    movingShapes: movingShapes,
    resizingShapes: resizingShapes
  };
};

SpaceTool.prototype.toggle = function () {
  if (this.isActive()) {
    this._dragging.cancel();
  } else {
    this.activateSelection();
  }
};

SpaceTool.prototype.isActive = function () {
  var context = this._dragging.context();

  return context && /^spaceTool/.test(context.prefix);
}; // helpers //////////


function addPadding(trbl) {
  return {
    top: trbl.top - PADDING,
    right: trbl.right + PADDING,
    bottom: trbl.bottom + PADDING,
    left: trbl.left - PADDING
  };
}

function ensureConstraints(event) {
  var context = event.context,
      spaceToolConstraints = context.spaceToolConstraints;

  if (!spaceToolConstraints) {
    return;
  }

  var x, y;

  if ((0, _minDash.isNumber)(spaceToolConstraints.left)) {
    x = Math.max(event.x, spaceToolConstraints.left);
    event.dx = event.dx + x - event.x;
    event.x = x;
  }

  if ((0, _minDash.isNumber)(spaceToolConstraints.right)) {
    x = Math.min(event.x, spaceToolConstraints.right);
    event.dx = event.dx + x - event.x;
    event.x = x;
  }

  if ((0, _minDash.isNumber)(spaceToolConstraints.top)) {
    y = Math.max(event.y, spaceToolConstraints.top);
    event.dy = event.dy + y - event.y;
    event.y = y;
  }

  if ((0, _minDash.isNumber)(spaceToolConstraints.bottom)) {
    y = Math.min(event.y, spaceToolConstraints.bottom);
    event.dy = event.dy + y - event.y;
    event.y = y;
  }
}

function getSpaceToolConstraints(elements, axis, direction, start, minDimensions) {
  var movingShapes = elements.movingShapes,
      resizingShapes = elements.resizingShapes;

  if (!resizingShapes.length) {
    return;
  }

  var spaceToolConstraints = {},
      min,
      max;
  (0, _minDash.forEach)(resizingShapes, function (resizingShape) {
    var resizingShapeBBox = (0, _LayoutUtil.asTRBL)(resizingShape); // find children that are not moving or resizing

    var nonMovingResizingChildren = (0, _minDash.filter)(resizingShape.children, function (child) {
      return !isConnection(child) && !isLabel(child) && !includes(movingShapes, child) && !includes(resizingShapes, child);
    }); // find children that are moving

    var movingChildren = (0, _minDash.filter)(resizingShape.children, function (child) {
      return !isConnection(child) && !isLabel(child) && includes(movingShapes, child);
    });
    var minOrMax, nonMovingResizingChildrenBBox, movingChildrenBBox;

    if (nonMovingResizingChildren.length) {
      nonMovingResizingChildrenBBox = addPadding((0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(nonMovingResizingChildren)));
      minOrMax = start - resizingShapeBBox[DIRECTION_TO_TRBL[direction]] + nonMovingResizingChildrenBBox[DIRECTION_TO_TRBL[direction]];

      if (direction === 'n') {
        spaceToolConstraints.bottom = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax;
      } else if (direction === 'w') {
        spaceToolConstraints.right = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax;
      } else if (direction === 's') {
        spaceToolConstraints.top = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax;
      } else if (direction === 'e') {
        spaceToolConstraints.left = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax;
      }
    }

    if (movingChildren.length) {
      movingChildrenBBox = addPadding((0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(movingChildren)));
      minOrMax = start - movingChildrenBBox[DIRECTION_TO_TRBL[DIRECTION_TO_OPPOSITE[direction]]] + resizingShapeBBox[DIRECTION_TO_TRBL[DIRECTION_TO_OPPOSITE[direction]]];

      if (direction === 'n') {
        spaceToolConstraints.bottom = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax;
      } else if (direction === 'w') {
        spaceToolConstraints.right = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax;
      } else if (direction === 's') {
        spaceToolConstraints.top = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax;
      } else if (direction === 'e') {
        spaceToolConstraints.left = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax;
      }
    }

    var resizingShapeMinDimensions = minDimensions && minDimensions[resizingShape.id];

    if (resizingShapeMinDimensions) {
      if (direction === 'n') {
        minOrMax = start + resizingShape[AXIS_TO_DIMENSION[axis]] - resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]];
        spaceToolConstraints.bottom = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax;
      } else if (direction === 'w') {
        minOrMax = start + resizingShape[AXIS_TO_DIMENSION[axis]] - resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]];
        spaceToolConstraints.right = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax;
      } else if (direction === 's') {
        minOrMax = start - resizingShape[AXIS_TO_DIMENSION[axis]] + resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]];
        spaceToolConstraints.top = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax;
      } else if (direction === 'e') {
        minOrMax = start - resizingShape[AXIS_TO_DIMENSION[axis]] + resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]];
        spaceToolConstraints.left = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax;
      }
    }
  });
  return spaceToolConstraints;
}

function includes(array, item) {
  return array.indexOf(item) !== -1;
}

function isConnection(element) {
  return !!element.waypoints;
}

function isLabel(element) {
  return !!element.labelTarget;
}

},{"../../layout/LayoutUtil":300,"../../util/Cursor":314,"../../util/Elements":315,"../../util/Mouse":323,"./SpaceUtil":287,"min-dash":555}],286:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = SpaceToolPreview;

var _minDash = require("min-dash");

var _tinySvg = require("tiny-svg");

var _SvgTransformUtil = require("../../util/SvgTransformUtil");

var MARKER_DRAGGING = 'djs-dragging',
    MARKER_RESIZING = 'djs-resizing';
var LOW_PRIORITY = 250;
var max = Math.max;
/**
 * Provides previews for selecting/moving/resizing shapes when creating/removing space.
 *
 * @param {EventBus} eventBus
 * @param {ElementRegistry} elementRegistry
 * @param {Canvas} canvas
 * @param {Styles} styles
 */

function SpaceToolPreview(eventBus, elementRegistry, canvas, styles, previewSupport) {
  function addPreviewGfx(collection, dragGroup) {
    (0, _minDash.forEach)(collection, function (element) {
      previewSupport.addDragger(element, dragGroup);
      canvas.addMarker(element, MARKER_DRAGGING);
    });
  } // add crosshair


  eventBus.on('spaceTool.selection.start', function (event) {
    var space = canvas.getLayer('space'),
        context = event.context;
    var orientation = {
      x: 'M 0,-10000 L 0,10000',
      y: 'M -10000,0 L 10000,0'
    };
    var crosshairGroup = (0, _tinySvg.create)('g');
    (0, _tinySvg.attr)(crosshairGroup, styles.cls('djs-crosshair-group', ['no-events']));
    (0, _tinySvg.append)(space, crosshairGroup); // horizontal path

    var pathX = (0, _tinySvg.create)('path');
    (0, _tinySvg.attr)(pathX, 'd', orientation.x);
    (0, _tinySvg.classes)(pathX).add('djs-crosshair');
    (0, _tinySvg.append)(crosshairGroup, pathX); // vertical path

    var pathY = (0, _tinySvg.create)('path');
    (0, _tinySvg.attr)(pathY, 'd', orientation.y);
    (0, _tinySvg.classes)(pathY).add('djs-crosshair');
    (0, _tinySvg.append)(crosshairGroup, pathY);
    context.crosshairGroup = crosshairGroup;
  }); // update crosshair

  eventBus.on('spaceTool.selection.move', function (event) {
    var crosshairGroup = event.context.crosshairGroup;
    (0, _SvgTransformUtil.translate)(crosshairGroup, event.x, event.y);
  }); // remove crosshair

  eventBus.on('spaceTool.selection.cleanup', function (event) {
    var context = event.context,
        crosshairGroup = context.crosshairGroup;

    if (crosshairGroup) {
      (0, _tinySvg.remove)(crosshairGroup);
    }
  }); // add and update move/resize previews

  eventBus.on('spaceTool.move', LOW_PRIORITY, function (event) {
    var context = event.context,
        line = context.line,
        axis = context.axis,
        movingShapes = context.movingShapes,
        resizingShapes = context.resizingShapes;

    if (!context.initialized) {
      return;
    }

    if (!context.dragGroup) {
      var spaceLayer = canvas.getLayer('space');
      line = (0, _tinySvg.create)('path');
      (0, _tinySvg.attr)(line, 'd', 'M0,0 L0,0');
      (0, _tinySvg.classes)(line).add('djs-crosshair');
      (0, _tinySvg.append)(spaceLayer, line);
      context.line = line;
      var dragGroup = (0, _tinySvg.create)('g');
      (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events']));
      (0, _tinySvg.append)(canvas.getDefaultLayer(), dragGroup); // shapes

      addPreviewGfx(movingShapes, dragGroup); // connections

      var movingConnections = context.movingConnections = elementRegistry.filter(function (element) {
        var sourceIsMoving = false;
        (0, _minDash.forEach)(movingShapes, function (shape) {
          (0, _minDash.forEach)(shape.outgoing, function (connection) {
            if (element === connection) {
              sourceIsMoving = true;
            }
          });
        });
        var targetIsMoving = false;
        (0, _minDash.forEach)(movingShapes, function (shape) {
          (0, _minDash.forEach)(shape.incoming, function (connection) {
            if (element === connection) {
              targetIsMoving = true;
            }
          });
        });
        var sourceIsResizing = false;
        (0, _minDash.forEach)(resizingShapes, function (shape) {
          (0, _minDash.forEach)(shape.outgoing, function (connection) {
            if (element === connection) {
              sourceIsResizing = true;
            }
          });
        });
        var targetIsResizing = false;
        (0, _minDash.forEach)(resizingShapes, function (shape) {
          (0, _minDash.forEach)(shape.incoming, function (connection) {
            if (element === connection) {
              targetIsResizing = true;
            }
          });
        });
        return isConnection(element) && (sourceIsMoving || sourceIsResizing) && (targetIsMoving || targetIsResizing);
      });
      addPreviewGfx(movingConnections, dragGroup);
      context.dragGroup = dragGroup;
    }

    if (!context.frameGroup) {
      var frameGroup = (0, _tinySvg.create)('g');
      (0, _tinySvg.attr)(frameGroup, styles.cls('djs-frame-group', ['no-events']));
      (0, _tinySvg.append)(canvas.getDefaultLayer(), frameGroup);
      var frames = [];
      (0, _minDash.forEach)(resizingShapes, function (shape) {
        var frame = previewSupport.addFrame(shape, frameGroup);
        var initialBounds = frame.getBBox();
        frames.push({
          element: frame,
          initialBounds: initialBounds
        });
        canvas.addMarker(shape, MARKER_RESIZING);
      });
      context.frameGroup = frameGroup;
      context.frames = frames;
    }

    var orientation = {
      x: 'M' + event.x + ', -10000 L' + event.x + ', 10000',
      y: 'M -10000, ' + event.y + ' L 10000, ' + event.y
    };
    (0, _tinySvg.attr)(line, {
      d: orientation[axis]
    });
    var opposite = {
      x: 'y',
      y: 'x'
    };
    var delta = {
      x: event.dx,
      y: event.dy
    };
    delta[opposite[context.axis]] = 0; // update move previews

    (0, _SvgTransformUtil.translate)(context.dragGroup, delta.x, delta.y); // update resize previews

    (0, _minDash.forEach)(context.frames, function (frame) {
      var element = frame.element,
          initialBounds = frame.initialBounds,
          width,
          height;

      if (context.direction === 'e') {
        (0, _tinySvg.attr)(element, {
          width: max(initialBounds.width + delta.x, 5)
        });
      } else {
        width = max(initialBounds.width - delta.x, 5);
        (0, _tinySvg.attr)(element, {
          width: width,
          x: initialBounds.x + initialBounds.width - width
        });
      }

      if (context.direction === 's') {
        (0, _tinySvg.attr)(element, {
          height: max(initialBounds.height + delta.y, 5)
        });
      } else {
        height = max(initialBounds.height - delta.y, 5);
        (0, _tinySvg.attr)(element, {
          height: height,
          y: initialBounds.y + initialBounds.height - height
        });
      }
    });
  }); // remove move/resize previews

  eventBus.on('spaceTool.cleanup', function (event) {
    var context = event.context,
        movingShapes = context.movingShapes,
        movingConnections = context.movingConnections,
        resizingShapes = context.resizingShapes,
        line = context.line,
        dragGroup = context.dragGroup,
        frameGroup = context.frameGroup; // moving shapes

    (0, _minDash.forEach)(movingShapes, function (shape) {
      canvas.removeMarker(shape, MARKER_DRAGGING);
    }); // moving connections

    (0, _minDash.forEach)(movingConnections, function (connection) {
      canvas.removeMarker(connection, MARKER_DRAGGING);
    });

    if (dragGroup) {
      (0, _tinySvg.remove)(line);
      (0, _tinySvg.remove)(dragGroup);
    }

    (0, _minDash.forEach)(resizingShapes, function (shape) {
      canvas.removeMarker(shape, MARKER_RESIZING);
    });

    if (frameGroup) {
      (0, _tinySvg.remove)(frameGroup);
    }
  });
}

SpaceToolPreview.$inject = ['eventBus', 'elementRegistry', 'canvas', 'styles', 'previewSupport']; // helpers //////////////////////

/**
 * Checks if an element is a connection.
 */

function isConnection(element) {
  return element.waypoints;
}

},{"../../util/SvgTransformUtil":328,"min-dash":555,"tiny-svg":567}],287:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getDirection = getDirection;
exports.getWaypointsUpdatingConnections = getWaypointsUpdatingConnections;
exports.resizeBounds = resizeBounds;

var _minDash = require("min-dash");

/**
 * Return direction given axis and delta.
 *
 * @param {string} axis
 * @param {number} delta
 *
 * @return {string}
 */
function getDirection(axis, delta) {
  if (axis === 'x') {
    if (delta > 0) {
      return 'e';
    }

    if (delta < 0) {
      return 'w';
    }
  }

  if (axis === 'y') {
    if (delta > 0) {
      return 's';
    }

    if (delta < 0) {
      return 'n';
    }
  }

  return null;
}
/**
 * Returns connections whose waypoints are to be updated. Waypoints are to be updated if start
 * or end is to be moved or resized.
 *
 * @param {Array<djs.model.Shape} movingShapes
 * @param {Array<djs.model.Shape} resizingShapes
 *
 * @returns {Array<djs.model.Connection>}
 */


function getWaypointsUpdatingConnections(movingShapes, resizingShapes) {
  var waypointsUpdatingConnections = [];
  (0, _minDash.forEach)(movingShapes.concat(resizingShapes), function (shape) {
    var incoming = shape.incoming,
        outgoing = shape.outgoing;
    (0, _minDash.forEach)(incoming.concat(outgoing), function (connection) {
      var source = connection.source,
          target = connection.target;

      if (includes(movingShapes, source) || includes(movingShapes, target) || includes(resizingShapes, source) || includes(resizingShapes, target)) {
        if (!includes(waypointsUpdatingConnections, connection)) {
          waypointsUpdatingConnections.push(connection);
        }
      }
    });
  });
  return waypointsUpdatingConnections;
}

function includes(array, item) {
  return array.indexOf(item) !== -1;
}
/**
 * Resize bounds.
 *
 * @param {Object} bounds
 * @param {number} bounds.x
 * @param {number} bounds.y
 * @param {number} bounds.width
 * @param {number} bounds.height
 * @param {string} direction
 * @param {Object} delta
 * @param {number} delta.x
 * @param {number} delta.y
 *
 * @return {Object}
 */


function resizeBounds(bounds, direction, delta) {
  var x = bounds.x,
      y = bounds.y,
      width = bounds.width,
      height = bounds.height,
      dx = delta.x,
      dy = delta.y;

  switch (direction) {
    case 'n':
      return {
        x: x,
        y: y + dy,
        width: width,
        height: height - dy
      };

    case 's':
      return {
        x: x,
        y: y,
        width: width,
        height: height + dy
      };

    case 'w':
      return {
        x: x + dx,
        y: y,
        width: width - dx,
        height: height
      };

    case 'e':
      return {
        x: x,
        y: y,
        width: width + dx,
        height: height
      };

    default:
      throw new Error('unknown direction: ' + direction);
  }
}

},{"min-dash":555}],288:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _dragging = _interopRequireDefault(require("../dragging"));

var _rules = _interopRequireDefault(require("../rules"));

var _toolManager = _interopRequireDefault(require("../tool-manager"));

var _previewSupport = _interopRequireDefault(require("../preview-support"));

var _SpaceTool = _interopRequireDefault(require("./SpaceTool"));

var _SpaceToolPreview = _interopRequireDefault(require("./SpaceToolPreview"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['spaceToolPreview'],
  __depends__: [_dragging.default, _rules.default, _toolManager.default, _previewSupport.default],
  spaceTool: ['type', _SpaceTool.default],
  spaceToolPreview: ['type', _SpaceToolPreview.default]
};
exports.default = _default;

},{"../dragging":197,"../preview-support":262,"../rules":272,"../tool-manager":290,"./SpaceTool":285,"./SpaceToolPreview":286}],289:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ToolManager;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var LOW_PRIORITY = 250;
/**
 * The tool manager acts as middle-man between the available tool's and the Palette,
 * it takes care of making sure that the correct active state is set.
 *
 * @param  {Object}    eventBus
 * @param  {Object}    dragging
 */

function ToolManager(eventBus, dragging) {
  this._eventBus = eventBus;
  this._dragging = dragging;
  this._tools = [];
  this._active = null;
}

ToolManager.$inject = ['eventBus', 'dragging'];

ToolManager.prototype.registerTool = function (name, events) {
  var tools = this._tools;

  if (!events) {
    throw new Error('A tool has to be registered with it\'s "events"');
  }

  tools.push(name);
  this.bindEvents(name, events);
};

ToolManager.prototype.isActive = function (tool) {
  return tool && this._active === tool;
};

ToolManager.prototype.length = function (tool) {
  return this._tools.length;
};

ToolManager.prototype.setActive = function (tool) {
  var eventBus = this._eventBus;

  if (this._active !== tool) {
    this._active = tool;
    eventBus.fire('tool-manager.update', {
      tool: tool
    });
  }
};

ToolManager.prototype.bindEvents = function (name, events) {
  var eventBus = this._eventBus,
      dragging = this._dragging;
  var eventsToRegister = [];
  eventBus.on(events.tool + '.init', function (event) {
    var context = event.context; // Active tools that want to reactivate themselves must do this explicitly

    if (!context.reactivate && this.isActive(name)) {
      this.setActive(null);
      dragging.cancel();
      return;
    }

    this.setActive(name);
  }, this); // Todo[ricardo]: add test cases

  (0, _minDash.forEach)(events, function (event) {
    eventsToRegister.push(event + '.ended');
    eventsToRegister.push(event + '.canceled');
  });
  eventBus.on(eventsToRegister, LOW_PRIORITY, function (event) {
    var originalEvent = event.originalEvent; // We defer the de-activation of the tool to the .activate phase,
    // so we're able to check if we want to toggle off the current
    // active tool or switch to a new one

    if (!this._active) {
      return;
    }

    if (originalEvent && (0, _minDom.closest)(originalEvent.target, '.group[data-group="tools"]')) {
      return;
    }

    this.setActive(null);
  }, this);
};

},{"min-dash":555,"min-dom":556}],290:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _dragging = _interopRequireDefault(require("../dragging"));

var _ToolManager = _interopRequireDefault(require("./ToolManager"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_dragging.default],
  __init__: ['toolManager'],
  toolManager: ['type', _ToolManager.default]
};
exports.default = _default;

},{"../dragging":197,"./ToolManager":289}],291:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Tooltips;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _IdGenerator = _interopRequireDefault(require("../../util/IdGenerator"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

// document wide unique tooltip ids
var ids = new _IdGenerator.default('tt');

function createRoot(parentNode) {
  var root = (0, _minDom.domify)('<div class="djs-tooltip-container" style="position: absolute; width: 0; height: 0;" />');
  parentNode.insertBefore(root, parentNode.firstChild);
  return root;
}

function setPosition(el, x, y) {
  (0, _minDash.assign)(el.style, {
    left: x + 'px',
    top: y + 'px'
  });
}

function setVisible(el, visible) {
  el.style.display = visible === false ? 'none' : '';
}

var tooltipClass = 'djs-tooltip',
    tooltipSelector = '.' + tooltipClass;
/**
 * A service that allows users to render tool tips on the diagram.
 *
 * The tooltip service will take care of updating the tooltip positioning
 * during navigation + zooming.
 *
 * @example
 *
 * ```javascript
 *
 * // add a pink badge on the top left of the shape
 * tooltips.add({
 *   position: {
 *     x: 50,
 *     y: 100
 *   },
 *   html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
 * });
 *
 * // or with optional life span
 * tooltips.add({
 *   position: {
 *     top: -5,
 *     left: -5
 *   },
 *   html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>',
 *   ttl: 2000
 * });
 *
 * // remove a tool tip
 * var id = tooltips.add(...);
 * tooltips.remove(id);
 * ```
 *
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 */

function Tooltips(eventBus, canvas) {
  this._eventBus = eventBus;
  this._canvas = canvas;
  this._ids = ids;
  this._tooltipDefaults = {
    show: {
      minZoom: 0.7,
      maxZoom: 5.0
    }
  };
  /**
   * Mapping tooltipId -> tooltip
   */

  this._tooltips = {}; // root html element for all tooltips

  this._tooltipRoot = createRoot(canvas.getContainer());
  var self = this;

  _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mousedown', function (event) {
    event.stopPropagation();
  });

  _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mouseover', function (event) {
    self.trigger('mouseover', event);
  });

  _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mouseout', function (event) {
    self.trigger('mouseout', event);
  });

  this._init();
}

Tooltips.$inject = ['eventBus', 'canvas'];
/**
 * Adds a HTML tooltip to the diagram
 *
 * @param {Object}               tooltip   the tooltip configuration
 *
 * @param {string|DOMElement}    tooltip.html                 html element to use as an tooltip
 * @param {Object}               [tooltip.show]               show configuration
 * @param {number}               [tooltip.show.minZoom]       minimal zoom level to show the tooltip
 * @param {number}               [tooltip.show.maxZoom]       maximum zoom level to show the tooltip
 * @param {Object}               tooltip.position             where to attach the tooltip
 * @param {number}               [tooltip.position.left]      relative to element bbox left attachment
 * @param {number}               [tooltip.position.top]       relative to element bbox top attachment
 * @param {number}               [tooltip.position.bottom]    relative to element bbox bottom attachment
 * @param {number}               [tooltip.position.right]     relative to element bbox right attachment
 * @param {number}               [tooltip.timeout=-1]
 *
 * @return {string}              id that may be used to reference the tooltip for update or removal
 */

Tooltips.prototype.add = function (tooltip) {
  if (!tooltip.position) {
    throw new Error('must specifiy tooltip position');
  }

  if (!tooltip.html) {
    throw new Error('must specifiy tooltip html');
  }

  var id = this._ids.next();

  tooltip = (0, _minDash.assign)({}, this._tooltipDefaults, tooltip, {
    id: id
  });

  this._addTooltip(tooltip);

  if (tooltip.timeout) {
    this.setTimeout(tooltip);
  }

  return id;
};

Tooltips.prototype.trigger = function (action, event) {
  var node = event.delegateTarget || event.target;
  var tooltip = this.get((0, _minDom.attr)(node, 'data-tooltip-id'));

  if (!tooltip) {
    return;
  }

  if (action === 'mouseover' && tooltip.timeout) {
    this.clearTimeout(tooltip);
  }

  if (action === 'mouseout' && tooltip.timeout) {
    // cut timeout after mouse out
    tooltip.timeout = 1000;
    this.setTimeout(tooltip);
  }
};
/**
 * Get a tooltip with the given id
 *
 * @param {string} id
 */


Tooltips.prototype.get = function (id) {
  if (typeof id !== 'string') {
    id = id.id;
  }

  return this._tooltips[id];
};

Tooltips.prototype.clearTimeout = function (tooltip) {
  tooltip = this.get(tooltip);

  if (!tooltip) {
    return;
  }

  var removeTimer = tooltip.removeTimer;

  if (removeTimer) {
    clearTimeout(removeTimer);
    tooltip.removeTimer = null;
  }
};

Tooltips.prototype.setTimeout = function (tooltip) {
  tooltip = this.get(tooltip);

  if (!tooltip) {
    return;
  }

  this.clearTimeout(tooltip);
  var self = this;
  tooltip.removeTimer = setTimeout(function () {
    self.remove(tooltip);
  }, tooltip.timeout);
};
/**
 * Remove an tooltip with the given id
 *
 * @param {string} id
 */


Tooltips.prototype.remove = function (id) {
  var tooltip = this.get(id);

  if (tooltip) {
    (0, _minDom.remove)(tooltip.html);
    (0, _minDom.remove)(tooltip.htmlContainer);
    delete tooltip.htmlContainer;
    delete this._tooltips[tooltip.id];
  }
};

Tooltips.prototype.show = function () {
  setVisible(this._tooltipRoot);
};

Tooltips.prototype.hide = function () {
  setVisible(this._tooltipRoot, false);
};

Tooltips.prototype._updateRoot = function (viewbox) {
  var a = viewbox.scale || 1;
  var d = viewbox.scale || 1;
  var matrix = 'matrix(' + a + ',0,0,' + d + ',' + -1 * viewbox.x * a + ',' + -1 * viewbox.y * d + ')';
  this._tooltipRoot.style.transform = matrix;
  this._tooltipRoot.style['-ms-transform'] = matrix;
};

Tooltips.prototype._addTooltip = function (tooltip) {
  var id = tooltip.id,
      html = tooltip.html,
      htmlContainer,
      tooltipRoot = this._tooltipRoot; // unwrap jquery (for those who need it)

  if (html.get && html.constructor.prototype.jquery) {
    html = html.get(0);
  } // create proper html elements from
  // tooltip HTML strings


  if ((0, _minDash.isString)(html)) {
    html = (0, _minDom.domify)(html);
  }

  htmlContainer = (0, _minDom.domify)('<div data-tooltip-id="' + id + '" class="' + tooltipClass + '" style="position: absolute">');
  htmlContainer.appendChild(html);

  if (tooltip.type) {
    (0, _minDom.classes)(htmlContainer).add('djs-tooltip-' + tooltip.type);
  }

  if (tooltip.className) {
    (0, _minDom.classes)(htmlContainer).add(tooltip.className);
  }

  tooltip.htmlContainer = htmlContainer;
  tooltipRoot.appendChild(htmlContainer);
  this._tooltips[id] = tooltip;

  this._updateTooltip(tooltip);
};

Tooltips.prototype._updateTooltip = function (tooltip) {
  var position = tooltip.position,
      htmlContainer = tooltip.htmlContainer; // update overlay html based on tooltip x, y

  setPosition(htmlContainer, position.x, position.y);
};

Tooltips.prototype._updateTooltipVisibilty = function (viewbox) {
  (0, _minDash.forEach)(this._tooltips, function (tooltip) {
    var show = tooltip.show,
        htmlContainer = tooltip.htmlContainer,
        visible = true;

    if (show) {
      if (show.minZoom > viewbox.scale || show.maxZoom < viewbox.scale) {
        visible = false;
      }

      setVisible(htmlContainer, visible);
    }
  });
};

Tooltips.prototype._init = function () {
  var self = this; // scroll/zoom integration

  function updateViewbox(viewbox) {
    self._updateRoot(viewbox);

    self._updateTooltipVisibilty(viewbox);

    self.show();
  }

  this._eventBus.on('canvas.viewbox.changing', function (event) {
    self.hide();
  });

  this._eventBus.on('canvas.viewbox.changed', function (event) {
    updateViewbox(event.viewbox);
  });
};

},{"../../util/IdGenerator":320,"min-dash":555,"min-dom":556}],292:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _Tooltips = _interopRequireDefault(require("./Tooltips"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['tooltips'],
  tooltips: ['type', _Tooltips.default]
};
exports.default = _default;

},{"./Tooltips":291}],293:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = TouchFix;

var _tinySvg = require("tiny-svg");

function TouchFix(canvas, eventBus) {
  var self = this;
  eventBus.on('canvas.init', function (e) {
    self.addBBoxMarker(e.svg);
  });
}

TouchFix.$inject = ['canvas', 'eventBus'];
/**
 * Safari mobile (iOS 7) does not fire touchstart event in <SVG> element
 * if there is no shape between 0,0 and viewport elements origin.
 *
 * So touchstart event is only fired when the <g class="viewport"> element was hit.
 * Putting an element over and below the 'viewport' fixes that behavior.
 */

TouchFix.prototype.addBBoxMarker = function (svg) {
  var markerStyle = {
    fill: 'none',
    class: 'outer-bound-marker'
  };
  var rect1 = (0, _tinySvg.create)('rect');
  (0, _tinySvg.attr)(rect1, {
    x: -10000,
    y: 10000,
    width: 10,
    height: 10
  });
  (0, _tinySvg.attr)(rect1, markerStyle);
  (0, _tinySvg.append)(svg, rect1);
  var rect2 = (0, _tinySvg.create)('rect');
  (0, _tinySvg.attr)(rect2, {
    x: 10000,
    y: 10000,
    width: 10,
    height: 10
  });
  (0, _tinySvg.attr)(rect2, markerStyle);
  (0, _tinySvg.append)(svg, rect2);
};

},{"tiny-svg":567}],294:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = TouchInteractionEvents;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _hammerjs = _interopRequireDefault(require("hammerjs"));

var _Event = require("../../util/Event");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var MIN_ZOOM = 0.2,
    MAX_ZOOM = 4;
var mouseEvents = ['mousedown', 'mouseup', 'mouseover', 'mouseout', 'click', 'dblclick'];

function log() {// console.log.apply(console, arguments);
}

function get(service, injector) {
  return injector.get(service, false);
}

function stopEvent(event) {
  event.preventDefault();

  if (typeof event.stopPropagation === 'function') {
    event.stopPropagation();
  } else if (event.srcEvent && typeof event.srcEvent.stopPropagation === 'function') {
    // iPhone & iPad
    event.srcEvent.stopPropagation();
  }

  if (typeof event.stopImmediatePropagation === 'function') {
    event.stopImmediatePropagation();
  }
}

function createTouchRecognizer(node) {
  function stopMouse(event) {
    (0, _minDash.forEach)(mouseEvents, function (e) {
      _minDom.event.bind(node, e, stopEvent, true);
    });
  }

  function allowMouse(event) {
    setTimeout(function () {
      (0, _minDash.forEach)(mouseEvents, function (e) {
        _minDom.event.unbind(node, e, stopEvent, true);
      });
    }, 500);
  }

  _minDom.event.bind(node, 'touchstart', stopMouse, true);

  _minDom.event.bind(node, 'touchend', allowMouse, true);

  _minDom.event.bind(node, 'touchcancel', allowMouse, true); // A touch event recognizer that handles
  // touch events only (we know, we can already handle
  // mouse events out of the box)


  var recognizer = new _hammerjs.default.Manager(node, {
    inputClass: _hammerjs.default.TouchInput,
    recognizers: [],
    domEvents: true
  });
  var tap = new _hammerjs.default.Tap();
  var pan = new _hammerjs.default.Pan({
    threshold: 10
  });
  var press = new _hammerjs.default.Press();
  var pinch = new _hammerjs.default.Pinch();
  var doubleTap = new _hammerjs.default.Tap({
    event: 'doubletap',
    taps: 2
  });
  pinch.requireFailure(pan);
  pinch.requireFailure(press);
  recognizer.add([pan, press, pinch, doubleTap, tap]);

  recognizer.reset = function (force) {
    var recognizers = this.recognizers,
        session = this.session;

    if (session.stopped) {
      return;
    }

    log('recognizer', 'stop');
    recognizer.stop(force);
    setTimeout(function () {
      var i, r;
      log('recognizer', 'reset');

      for (i = 0; r = recognizers[i]; i++) {
        r.reset();
        r.state = 8; // FAILED STATE
      }

      session.curRecognizer = null;
    }, 0);
  };

  recognizer.on('hammer.input', function (event) {
    if (event.srcEvent.defaultPrevented) {
      recognizer.reset(true);
    }
  });
  return recognizer;
}
/**
 * A plugin that provides touch events for elements.
 *
 * @param {EventBus} eventBus
 * @param {InteractionEvents} interactionEvents
 */


function TouchInteractionEvents(injector, canvas, eventBus, elementRegistry, interactionEvents) {
  // optional integrations
  var dragging = get('dragging', injector),
      move = get('move', injector),
      contextPad = get('contextPad', injector),
      palette = get('palette', injector); // the touch recognizer

  var recognizer;

  function handler(type) {
    return function (event) {
      log('element', type, event);
      interactionEvents.fire(type, event);
    };
  }

  function getGfx(target) {
    var node = (0, _minDom.closest)(target, 'svg, .djs-element', true);
    return node;
  }

  function initEvents(svg) {
    // touch recognizer
    recognizer = createTouchRecognizer(svg);
    recognizer.on('doubletap', handler('element.dblclick'));
    recognizer.on('tap', handler('element.click'));

    function startGrabCanvas(event) {
      log('canvas', 'grab start');
      var lx = 0,
          ly = 0;

      function update(e) {
        var dx = e.deltaX - lx,
            dy = e.deltaY - ly;
        canvas.scroll({
          dx: dx,
          dy: dy
        });
        lx = e.deltaX;
        ly = e.deltaY;
      }

      function end(e) {
        recognizer.off('panmove', update);
        recognizer.off('panend', end);
        recognizer.off('pancancel', end);
        log('canvas', 'grab end');
      }

      recognizer.on('panmove', update);
      recognizer.on('panend', end);
      recognizer.on('pancancel', end);
    }

    function startGrab(event) {
      var gfx = getGfx(event.target),
          element = gfx && elementRegistry.get(gfx); // recognizer

      if (move && canvas.getRootElement() !== element) {
        log('element', 'move start', element, event, true);
        return move.start(event, element, true);
      } else {
        startGrabCanvas(event);
      }
    }

    function startZoom(e) {
      log('canvas', 'zoom start');
      var zoom = canvas.zoom(),
          mid = e.center;

      function update(e) {
        var ratio = 1 - (1 - e.scale) / 1.50,
            newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, ratio * zoom));
        canvas.zoom(newZoom, mid);
        stopEvent(e);
      }

      function end(e) {
        recognizer.off('pinchmove', update);
        recognizer.off('pinchend', end);
        recognizer.off('pinchcancel', end);
        recognizer.reset(true);
        log('canvas', 'zoom end');
      }

      recognizer.on('pinchmove', update);
      recognizer.on('pinchend', end);
      recognizer.on('pinchcancel', end);
    }

    recognizer.on('panstart', startGrab);
    recognizer.on('press', startGrab);
    recognizer.on('pinchstart', startZoom);
  }

  if (dragging) {
    // simulate hover during dragging
    eventBus.on('drag.move', function (event) {
      var originalEvent = event.originalEvent;

      if (!originalEvent || originalEvent instanceof MouseEvent) {
        return;
      }

      var position = (0, _Event.toPoint)(originalEvent); // this gets really expensive ...

      var node = document.elementFromPoint(position.x, position.y),
          gfx = getGfx(node),
          element = gfx && elementRegistry.get(gfx);

      if (element !== event.hover) {
        if (event.hover) {
          dragging.out(event);
        }

        if (element) {
          dragging.hover({
            element: element,
            gfx: gfx
          });
          event.hover = element;
          event.hoverGfx = gfx;
        }
      }
    });
  }

  if (contextPad) {
    eventBus.on('contextPad.create', function (event) {
      var node = event.pad.html; // touch recognizer

      var padRecognizer = createTouchRecognizer(node);
      padRecognizer.on('panstart', function (event) {
        log('context-pad', 'panstart', event);
        contextPad.trigger('dragstart', event, true);
      });
      padRecognizer.on('press', function (event) {
        log('context-pad', 'press', event);
        contextPad.trigger('dragstart', event, true);
      });
      padRecognizer.on('tap', function (event) {
        log('context-pad', 'tap', event);
        contextPad.trigger('click', event);
      });
    });
  }

  if (palette) {
    eventBus.on('palette.create', function (event) {
      var node = event.container; // touch recognizer

      var padRecognizer = createTouchRecognizer(node);
      padRecognizer.on('panstart', function (event) {
        log('palette', 'panstart', event);
        palette.trigger('dragstart', event, true);
      });
      padRecognizer.on('press', function (event) {
        log('palette', 'press', event);
        palette.trigger('dragstart', event, true);
      });
      padRecognizer.on('tap', function (event) {
        log('palette', 'tap', event);
        palette.trigger('click', event);
      });
    });
  }

  eventBus.on('canvas.init', function (event) {
    initEvents(event.svg);
  });
}

TouchInteractionEvents.$inject = ['injector', 'canvas', 'eventBus', 'elementRegistry', 'interactionEvents', 'touchFix'];

},{"../../util/Event":317,"hammerjs":345,"min-dash":555,"min-dom":556}],295:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _interactionEvents = _interopRequireDefault(require("../interaction-events"));

var _TouchInteractionEvents = _interopRequireDefault(require("./TouchInteractionEvents"));

var _TouchFix = _interopRequireDefault(require("./TouchFix"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_interactionEvents.default],
  __init__: ['touchInteractionEvents'],
  touchInteractionEvents: ['type', _TouchInteractionEvents.default],
  touchFix: ['type', _TouchFix.default]
};
exports.default = _default;

},{"../interaction-events":211,"./TouchFix":293,"./TouchInteractionEvents":294}],296:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _translate = _interopRequireDefault(require("./translate"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  translate: ['value', _translate.default]
};
exports.default = _default;

},{"./translate":297}],297:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = translate;

/**
 * A simple translation stub to be used for multi-language support
 * in diagrams. Can be easily replaced with a more sophisticated
 * solution.
 *
 * @example
 *
 * // use it inside any diagram component by injecting `translate`.
 *
 * function MyService(translate) {
 *   alert(translate('HELLO {you}', { you: 'You!' }));
 * }
 *
 * @param {string} template to interpolate
 * @param {Object} [replacements] a map with substitutes
 *
 * @return {string} the translated string
 */
function translate(template, replacements) {
  replacements = replacements || {};
  return template.replace(/{([^}]+)}/g, function (_, key) {
    return replacements[key] || '{' + key + '}';
  });
}

},{}],298:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = BaseLayouter;

var _LayoutUtil = require("./LayoutUtil");

/**
 * A base connection layouter implementation
 * that layouts the connection by directly connecting
 * mid(source) + mid(target).
 */
function BaseLayouter() {}
/**
 * Return the new layouted waypoints for the given connection.
 *
 * The connection passed is still unchanged; you may figure out about
 * the new connection start / end via the layout hints provided.
 *
 * @param {djs.model.Connection} connection
 * @param {Object} [hints]
 * @param {Point} [hints.connectionStart]
 * @param {Point} [hints.connectionEnd]
 * @param {Point} [hints.source]
 * @param {Point} [hints.target]
 *
 * @return {Array<Point>} the layouted connection waypoints
 */


BaseLayouter.prototype.layoutConnection = function (connection, hints) {
  hints = hints || {};
  return [hints.connectionStart || (0, _LayoutUtil.getMid)(hints.source || connection.source), hints.connectionEnd || (0, _LayoutUtil.getMid)(hints.target || connection.target)];
};

},{"./LayoutUtil":300}],299:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = CroppingConnectionDocking;

var _minDash = require("min-dash");

var _LayoutUtil = require("./LayoutUtil");

function dockingToPoint(docking) {
  // use the dockings actual point and
  // retain the original docking
  return (0, _minDash.assign)({
    original: docking.point.original || docking.point
  }, docking.actual);
}
/**
 * A {@link ConnectionDocking} that crops connection waypoints based on
 * the path(s) of the connection source and target.
 *
 * @param {djs.core.ElementRegistry} elementRegistry
 */


function CroppingConnectionDocking(elementRegistry, graphicsFactory) {
  this._elementRegistry = elementRegistry;
  this._graphicsFactory = graphicsFactory;
}

CroppingConnectionDocking.$inject = ['elementRegistry', 'graphicsFactory'];
/**
 * @inheritDoc ConnectionDocking#getCroppedWaypoints
 */

CroppingConnectionDocking.prototype.getCroppedWaypoints = function (connection, source, target) {
  source = source || connection.source;
  target = target || connection.target;
  var sourceDocking = this.getDockingPoint(connection, source, true),
      targetDocking = this.getDockingPoint(connection, target);
  var croppedWaypoints = connection.waypoints.slice(sourceDocking.idx + 1, targetDocking.idx);
  croppedWaypoints.unshift(dockingToPoint(sourceDocking));
  croppedWaypoints.push(dockingToPoint(targetDocking));
  return croppedWaypoints;
};
/**
 * Return the connection docking point on the specified shape
 *
 * @inheritDoc ConnectionDocking#getDockingPoint
 */


CroppingConnectionDocking.prototype.getDockingPoint = function (connection, shape, dockStart) {
  var waypoints = connection.waypoints,
      dockingIdx,
      dockingPoint,
      croppedPoint;
  dockingIdx = dockStart ? 0 : waypoints.length - 1;
  dockingPoint = waypoints[dockingIdx];
  croppedPoint = this._getIntersection(shape, connection, dockStart);
  return {
    point: dockingPoint,
    actual: croppedPoint || dockingPoint,
    idx: dockingIdx
  };
}; // helpers //////////////////////


CroppingConnectionDocking.prototype._getIntersection = function (shape, connection, takeFirst) {
  var shapePath = this._getShapePath(shape),
      connectionPath = this._getConnectionPath(connection);

  return (0, _LayoutUtil.getElementLineIntersection)(shapePath, connectionPath, takeFirst);
};

CroppingConnectionDocking.prototype._getConnectionPath = function (connection) {
  return this._graphicsFactory.getConnectionPath(connection);
};

CroppingConnectionDocking.prototype._getShapePath = function (shape) {
  return this._graphicsFactory.getShapePath(shape);
};

CroppingConnectionDocking.prototype._getGfx = function (element) {
  return this._elementRegistry.getGraphics(element);
};

},{"./LayoutUtil":300,"min-dash":555}],300:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.roundBounds = roundBounds;
exports.roundPoint = roundPoint;
exports.asTRBL = asTRBL;
exports.asBounds = asBounds;
exports.getMid = getMid;
exports.getOrientation = getOrientation;
exports.getElementLineIntersection = getElementLineIntersection;
exports.getIntersections = getIntersections;
exports.filterRedundantWaypoints = filterRedundantWaypoints;

var _minDash = require("min-dash");

var _Geometry = require("../util/Geometry");

var _pathIntersection = _interopRequireDefault(require("path-intersection"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function roundBounds(bounds) {
  return {
    x: Math.round(bounds.x),
    y: Math.round(bounds.y),
    width: Math.round(bounds.width),
    height: Math.round(bounds.height)
  };
}

function roundPoint(point) {
  return {
    x: Math.round(point.x),
    y: Math.round(point.y)
  };
}
/**
 * Convert the given bounds to a { top, left, bottom, right } descriptor.
 *
 * @param {Bounds|Point} bounds
 *
 * @return {Object}
 */


function asTRBL(bounds) {
  return {
    top: bounds.y,
    right: bounds.x + (bounds.width || 0),
    bottom: bounds.y + (bounds.height || 0),
    left: bounds.x
  };
}
/**
 * Convert a { top, left, bottom, right } to an objects bounds.
 *
 * @param {Object} trbl
 *
 * @return {Bounds}
 */


function asBounds(trbl) {
  return {
    x: trbl.left,
    y: trbl.top,
    width: trbl.right - trbl.left,
    height: trbl.bottom - trbl.top
  };
}
/**
 * Get the mid of the given bounds or point.
 *
 * @param {Bounds|Point} bounds
 *
 * @return {Point}
 */


function getMid(bounds) {
  return roundPoint({
    x: bounds.x + (bounds.width || 0) / 2,
    y: bounds.y + (bounds.height || 0) / 2
  });
} // orientation utils //////////////////////

/**
 * Get orientation of the given rectangle with respect to
 * the reference rectangle.
 *
 * A padding (positive or negative) may be passed to influence
 * horizontal / vertical orientation and intersection.
 *
 * @param {Bounds} rect
 * @param {Bounds} reference
 * @param {Point|number} padding
 *
 * @return {string} the orientation; one of top, top-left, left, ..., bottom, right or intersect.
 */


function getOrientation(rect, reference, padding) {
  padding = padding || 0; // make sure we can use an object, too
  // for individual { x, y } padding

  if (!(0, _minDash.isObject)(padding)) {
    padding = {
      x: padding,
      y: padding
    };
  }

  var rectOrientation = asTRBL(rect),
      referenceOrientation = asTRBL(reference);
  var top = rectOrientation.bottom + padding.y <= referenceOrientation.top,
      right = rectOrientation.left - padding.x >= referenceOrientation.right,
      bottom = rectOrientation.top - padding.y >= referenceOrientation.bottom,
      left = rectOrientation.right + padding.x <= referenceOrientation.left;
  var vertical = top ? 'top' : bottom ? 'bottom' : null,
      horizontal = left ? 'left' : right ? 'right' : null;

  if (horizontal && vertical) {
    return vertical + '-' + horizontal;
  } else {
    return horizontal || vertical || 'intersect';
  }
} // intersection utils //////////////////////

/**
 * Get intersection between an element and a line path.
 *
 * @param {PathDef} elementPath
 * @param {PathDef} linePath
 * @param {boolean} cropStart crop from start or end
 *
 * @return {Point}
 */


function getElementLineIntersection(elementPath, linePath, cropStart) {
  var intersections = getIntersections(elementPath, linePath); // recognize intersections
  // only one -> choose
  // two close together -> choose first
  // two or more distinct -> pull out appropriate one
  // none -> ok (fallback to point itself)

  if (intersections.length === 1) {
    return roundPoint(intersections[0]);
  } else if (intersections.length === 2 && (0, _Geometry.pointDistance)(intersections[0], intersections[1]) < 1) {
    return roundPoint(intersections[0]);
  } else if (intersections.length > 1) {
    // sort by intersections based on connection segment +
    // distance from start
    intersections = (0, _minDash.sortBy)(intersections, function (i) {
      var distance = Math.floor(i.t2 * 100) || 1;
      distance = 100 - distance;
      distance = (distance < 10 ? '0' : '') + distance; // create a sort string that makes sure we sort
      // line segment ASC + line segment position DESC (for cropStart)
      // line segment ASC + line segment position ASC (for cropEnd)

      return i.segment2 + '#' + distance;
    });
    return roundPoint(intersections[cropStart ? 0 : intersections.length - 1]);
  }

  return null;
}

function getIntersections(a, b) {
  return (0, _pathIntersection.default)(a, b);
}

function filterRedundantWaypoints(waypoints) {
  // alter copy of waypoints, not original
  waypoints = waypoints.slice();
  var idx = 0,
      point,
      previousPoint,
      nextPoint;

  while (waypoints[idx]) {
    point = waypoints[idx];
    previousPoint = waypoints[idx - 1];
    nextPoint = waypoints[idx + 1];

    if ((0, _Geometry.pointDistance)(point, nextPoint) === 0 || (0, _Geometry.pointsOnLine)(previousPoint, nextPoint, point)) {
      // remove point, if overlapping with {nextPoint}
      // or on line with {previousPoint} -> {point} -> {nextPoint}
      waypoints.splice(idx, 1);
    } else {
      idx++;
    }
  }

  return waypoints;
}

},{"../util/Geometry":318,"min-dash":555,"path-intersection":563}],301:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.connectPoints = connectPoints;
exports.connectRectangles = connectRectangles;
exports.repairConnection = repairConnection;
exports.tryLayoutStraight = tryLayoutStraight;
exports.withoutRedundantPoints = withoutRedundantPoints;

var _minDash = require("min-dash");

var _LayoutUtil = require("./LayoutUtil");

var _Geometry = require("../util/Geometry");

var MIN_SEGMENT_LENGTH = 20,
    POINT_ORIENTATION_PADDING = 5;
var round = Math.round;
var INTERSECTION_THRESHOLD = 20,
    ORIENTATION_THRESHOLD = {
  'h:h': 20,
  'v:v': 20,
  'h:v': -10,
  'v:h': -10
};

function needsTurn(orientation, startDirection) {
  return !{
    t: /top/,
    r: /right/,
    b: /bottom/,
    l: /left/,
    h: /./,
    v: /./
  }[startDirection].test(orientation);
}

function canLayoutStraight(direction, targetOrientation) {
  return {
    t: /top/,
    r: /right/,
    b: /bottom/,
    l: /left/,
    h: /left|right/,
    v: /top|bottom/
  }[direction].test(targetOrientation);
}

function getSegmentBendpoints(a, b, directions) {
  var orientation = (0, _LayoutUtil.getOrientation)(b, a, POINT_ORIENTATION_PADDING);
  var startDirection = directions.split(':')[0];
  var xmid = round((b.x - a.x) / 2 + a.x),
      ymid = round((b.y - a.y) / 2 + a.y);
  var segmentEnd, segmentDirections;
  var layoutStraight = canLayoutStraight(startDirection, orientation),
      layoutHorizontal = /h|r|l/.test(startDirection),
      layoutTurn = false;
  var turnNextDirections = false;

  if (layoutStraight) {
    segmentEnd = layoutHorizontal ? {
      x: xmid,
      y: a.y
    } : {
      x: a.x,
      y: ymid
    };
    segmentDirections = layoutHorizontal ? 'h:h' : 'v:v';
  } else {
    layoutTurn = needsTurn(orientation, startDirection);
    segmentDirections = layoutHorizontal ? 'h:v' : 'v:h';

    if (layoutTurn) {
      if (layoutHorizontal) {
        turnNextDirections = ymid === a.y;
        segmentEnd = {
          x: a.x + MIN_SEGMENT_LENGTH * (/l/.test(startDirection) ? -1 : 1),
          y: turnNextDirections ? ymid + MIN_SEGMENT_LENGTH : ymid
        };
      } else {
        turnNextDirections = xmid === a.x;
        segmentEnd = {
          x: turnNextDirections ? xmid + MIN_SEGMENT_LENGTH : xmid,
          y: a.y + MIN_SEGMENT_LENGTH * (/t/.test(startDirection) ? -1 : 1)
        };
      }
    } else {
      segmentEnd = {
        x: xmid,
        y: ymid
      };
    }
  }

  return {
    waypoints: getBendpoints(a, segmentEnd, segmentDirections).concat(segmentEnd),
    directions: segmentDirections,
    turnNextDirections: turnNextDirections
  };
}

function getStartSegment(a, b, directions) {
  return getSegmentBendpoints(a, b, directions);
}

function getEndSegment(a, b, directions) {
  var invertedSegment = getSegmentBendpoints(b, a, invertDirections(directions));
  return {
    waypoints: invertedSegment.waypoints.slice().reverse(),
    directions: invertDirections(invertedSegment.directions),
    turnNextDirections: invertedSegment.turnNextDirections
  };
}

function getMidSegment(startSegment, endSegment) {
  var startDirection = startSegment.directions.split(':')[1],
      endDirection = endSegment.directions.split(':')[0];

  if (startSegment.turnNextDirections) {
    startDirection = startDirection == 'h' ? 'v' : 'h';
  }

  if (endSegment.turnNextDirections) {
    endDirection = endDirection == 'h' ? 'v' : 'h';
  }

  var directions = startDirection + ':' + endDirection;
  var bendpoints = getBendpoints(startSegment.waypoints[startSegment.waypoints.length - 1], endSegment.waypoints[0], directions);
  return {
    waypoints: bendpoints,
    directions: directions
  };
}

function invertDirections(directions) {
  return directions.split(':').reverse().join(':');
}
/**
 * Handle simple layouts with maximum two bendpoints.
 */


function getSimpleBendpoints(a, b, directions) {
  var xmid = round((b.x - a.x) / 2 + a.x),
      ymid = round((b.y - a.y) / 2 + a.y); // one point, right or left from a

  if (directions === 'h:v') {
    return [{
      x: b.x,
      y: a.y
    }];
  } // one point, above or below a


  if (directions === 'v:h') {
    return [{
      x: a.x,
      y: b.y
    }];
  } // vertical segment between a and b


  if (directions === 'h:h') {
    return [{
      x: xmid,
      y: a.y
    }, {
      x: xmid,
      y: b.y
    }];
  } // horizontal segment between a and b


  if (directions === 'v:v') {
    return [{
      x: a.x,
      y: ymid
    }, {
      x: b.x,
      y: ymid
    }];
  }

  throw new Error('invalid directions: can only handle varians of [hv]:[hv]');
}
/**
 * Returns the mid points for a manhattan connection between two points.
 *
 * @example h:h (horizontal:horizontal)
 *
 * [a]----[x]
 *         |
 *        [x]----[b]
 *
 * @example h:v (horizontal:vertical)
 *
 * [a]----[x]
 *         |
 *        [b]
 *
 * @example h:r (horizontal:right)
 *
 * [a]----[x]
 *         |
 *    [b]-[x]
 *
 * @param  {Point} a
 * @param  {Point} b
 * @param  {string} directions
 *
 * @return {Array<Point>}
 */


function getBendpoints(a, b, directions) {
  directions = directions || 'h:h';

  if (!isValidDirections(directions)) {
    throw new Error('unknown directions: <' + directions + '>: ' + 'must be specified as <start>:<end> ' + 'with start/end in { h,v,t,r,b,l }');
  } // compute explicit directions, involving trbl dockings
  // using a three segmented layouting algorithm


  if (isExplicitDirections(directions)) {
    var startSegment = getStartSegment(a, b, directions),
        endSegment = getEndSegment(a, b, directions),
        midSegment = getMidSegment(startSegment, endSegment);
    return [].concat(startSegment.waypoints, midSegment.waypoints, endSegment.waypoints);
  } // handle simple [hv]:[hv] cases that can be easily computed


  return getSimpleBendpoints(a, b, directions);
}
/**
 * Create a connection between the two points according
 * to the manhattan layout (only horizontal and vertical) edges.
 *
 * @param {Point} a
 * @param {Point} b
 *
 * @param {string} [directions='h:h'] specifies manhattan directions for each point as {adirection}:{bdirection}.
                   A directionfor a point is either `h` (horizontal) or `v` (vertical)
 *
 * @return {Array<Point>}
 */


function connectPoints(a, b, directions) {
  var points = getBendpoints(a, b, directions);
  points.unshift(a);
  points.push(b);
  return withoutRedundantPoints(points);
}
/**
 * Connect two rectangles using a manhattan layouted connection.
 *
 * @param {Bounds} source source rectangle
 * @param {Bounds} target target rectangle
 * @param {Point} [start] source docking
 * @param {Point} [end] target docking
 *
 * @param {Object} [hints]
 * @param {string} [hints.preserveDocking=source] preserve docking on selected side
 * @param {Array<string>} [hints.preferredLayouts]
 * @param {Point|boolean} [hints.connectionStart] whether the start changed
 * @param {Point|boolean} [hints.connectionEnd] whether the end changed
 *
 * @return {Array<Point>} connection points
 */


function connectRectangles(source, target, start, end, hints) {
  var preferredLayouts = hints && hints.preferredLayouts || [];
  var preferredLayout = (0, _minDash.without)(preferredLayouts, 'straight')[0] || 'h:h';
  var threshold = ORIENTATION_THRESHOLD[preferredLayout] || 0;
  var orientation = (0, _LayoutUtil.getOrientation)(source, target, threshold);
  var directions = getDirections(orientation, preferredLayout);
  start = start || (0, _LayoutUtil.getMid)(source);
  end = end || (0, _LayoutUtil.getMid)(target);
  var directionSplit = directions.split(':'); // compute actual docking points for start / end
  // this ensures we properly layout only parts of the
  // connection that lies in between the two rectangles

  var startDocking = getDockingPoint(start, source, directionSplit[0], invertOrientation(orientation)),
      endDocking = getDockingPoint(end, target, directionSplit[1], orientation);
  return connectPoints(startDocking, endDocking, directions);
}
/**
 * Repair the connection between two rectangles, of which one has been updated.
 *
 * @param {Bounds} source
 * @param {Bounds} target
 * @param {Point} [start]
 * @param {Point} [end]
 * @param {Array<Point>} [waypoints]
 * @param {Object} [hints]
 * @param {Array<string>} [hints.preferredLayouts] list of preferred layouts
 * @param {boolean} [hints.connectionStart]
 * @param {boolean} [hints.connectionEnd]
 *
 * @return {Array<Point>} repaired waypoints
 */


function repairConnection(source, target, start, end, waypoints, hints) {
  if ((0, _minDash.isArray)(start)) {
    waypoints = start;
    hints = end;
    start = (0, _LayoutUtil.getMid)(source);
    end = (0, _LayoutUtil.getMid)(target);
  }

  hints = (0, _minDash.assign)({
    preferredLayouts: []
  }, hints);
  waypoints = waypoints || [];
  var preferredLayouts = hints.preferredLayouts,
      preferStraight = preferredLayouts.indexOf('straight') !== -1,
      repairedWaypoints; // just layout non-existing or simple connections
  // attempt to render straight lines, if required
  // attempt to layout a straight line

  repairedWaypoints = preferStraight && tryLayoutStraight(source, target, start, end, hints);

  if (repairedWaypoints) {
    return repairedWaypoints;
  } // try to layout from end


  repairedWaypoints = hints.connectionEnd && tryRepairConnectionEnd(target, source, end, waypoints);

  if (repairedWaypoints) {
    return repairedWaypoints;
  } // try to layout from start


  repairedWaypoints = hints.connectionStart && tryRepairConnectionStart(source, target, start, waypoints);

  if (repairedWaypoints) {
    return repairedWaypoints;
  } // or whether nothing seems to have changed


  if (!hints.connectionStart && !hints.connectionEnd && waypoints && waypoints.length) {
    return waypoints;
  } // simply reconnect if nothing else worked


  return connectRectangles(source, target, start, end, hints);
}

function inRange(a, start, end) {
  return a >= start && a <= end;
}

function isInRange(axis, a, b) {
  var size = {
    x: 'width',
    y: 'height'
  };
  return inRange(a[axis], b[axis], b[axis] + b[size[axis]]);
}
/**
 * Layout a straight connection
 *
 * @param {Bounds} source
 * @param {Bounds} target
 * @param {Point} start
 * @param {Point} end
 * @param {Object} [hints]
 *
 * @return {Array<Point>|null} waypoints if straight layout worked
 */


function tryLayoutStraight(source, target, start, end, hints) {
  var axis = {},
      primaryAxis,
      orientation;
  orientation = (0, _LayoutUtil.getOrientation)(source, target); // only layout a straight connection if shapes are
  // horizontally or vertically aligned

  if (!/^(top|bottom|left|right)$/.test(orientation)) {
    return null;
  }

  if (/top|bottom/.test(orientation)) {
    primaryAxis = 'x';
  }

  if (/left|right/.test(orientation)) {
    primaryAxis = 'y';
  }

  if (hints.preserveDocking === 'target') {
    if (!isInRange(primaryAxis, end, source)) {
      return null;
    }

    axis[primaryAxis] = end[primaryAxis];
    return [{
      x: axis.x !== undefined ? axis.x : start.x,
      y: axis.y !== undefined ? axis.y : start.y,
      original: {
        x: axis.x !== undefined ? axis.x : start.x,
        y: axis.y !== undefined ? axis.y : start.y
      }
    }, {
      x: end.x,
      y: end.y
    }];
  } else {
    if (!isInRange(primaryAxis, start, target)) {
      return null;
    }

    axis[primaryAxis] = start[primaryAxis];
    return [{
      x: start.x,
      y: start.y
    }, {
      x: axis.x !== undefined ? axis.x : end.x,
      y: axis.y !== undefined ? axis.y : end.y,
      original: {
        x: axis.x !== undefined ? axis.x : end.x,
        y: axis.y !== undefined ? axis.y : end.y
      }
    }];
  }
}
/**
 * Repair a connection from start.
 *
 * @param {Bounds} moved
 * @param {Bounds} other
 * @param {Point} newDocking
 * @param {Array<Point>} points originalPoints from moved to other
 *
 * @return {Array<Point>|null} the repaired points between the two rectangles
 */


function tryRepairConnectionStart(moved, other, newDocking, points) {
  return _tryRepairConnectionSide(moved, other, newDocking, points);
}
/**
 * Repair a connection from end.
 *
 * @param {Bounds} moved
 * @param {Bounds} other
 * @param {Point} newDocking
 * @param {Array<Point>} points originalPoints from moved to other
 *
 * @return {Array<Point>|null} the repaired points between the two rectangles
 */


function tryRepairConnectionEnd(moved, other, newDocking, points) {
  var waypoints = points.slice().reverse();
  waypoints = _tryRepairConnectionSide(moved, other, newDocking, waypoints);
  return waypoints ? waypoints.reverse() : null;
}
/**
 * Repair a connection from one side that moved.
 *
 * @param {Bounds} moved
 * @param {Bounds} other
 * @param {Point} newDocking
 * @param {Array<Point>} points originalPoints from moved to other
 *
 * @return {Array<Point>} the repaired points between the two rectangles
 */


function _tryRepairConnectionSide(moved, other, newDocking, points) {
  function needsRelayout(points) {
    if (points.length < 3) {
      return true;
    }

    if (points.length > 4) {
      return false;
    } // relayout if two points overlap
    // this is most likely due to


    return !!(0, _minDash.find)(points, function (p, idx) {
      var q = points[idx - 1];
      return q && (0, _Geometry.pointDistance)(p, q) < 3;
    });
  }

  function repairBendpoint(candidate, oldPeer, newPeer) {
    var alignment = (0, _Geometry.pointsAligned)(oldPeer, candidate);

    switch (alignment) {
      case 'v':
        // repair horizontal alignment
        return {
          x: newPeer.x,
          y: candidate.y
        };

      case 'h':
        // repair vertical alignment
        return {
          x: candidate.x,
          y: newPeer.y
        };
    }

    return {
      x: candidate.x,
      y: candidate.y
    };
  }

  function removeOverlapping(points, a, b) {
    var i;

    for (i = points.length - 2; i !== 0; i--) {
      // intersects (?) break, remove all bendpoints up to this one and relayout
      if ((0, _Geometry.pointInRect)(points[i], a, INTERSECTION_THRESHOLD) || (0, _Geometry.pointInRect)(points[i], b, INTERSECTION_THRESHOLD)) {
        // return sliced old connection
        return points.slice(i);
      }
    }

    return points;
  } // (0) only repair what has layoutable bendpoints
  // (1) if only one bendpoint and on shape moved onto other shapes axis
  //     (horizontally / vertically), relayout


  if (needsRelayout(points)) {
    return null;
  }

  var oldDocking = points[0],
      newPoints = points.slice(),
      slicedPoints; // (2) repair only last line segment and only if it was layouted before

  newPoints[0] = newDocking;
  newPoints[1] = repairBendpoint(newPoints[1], oldDocking, newDocking); // (3) if shape intersects with any bendpoint after repair,
  //     remove all segments up to this bendpoint and repair from there

  slicedPoints = removeOverlapping(newPoints, moved, other);

  if (slicedPoints !== newPoints) {
    newPoints = _tryRepairConnectionSide(moved, other, newDocking, slicedPoints);
  } // (4) do NOT repair if repaired bendpoints are aligned


  if (newPoints && (0, _Geometry.pointsAligned)(newPoints)) {
    return null;
  }

  return newPoints;
}
/**
 * Returns the manhattan directions connecting two rectangles
 * with the given orientation.
 *
 * Will always return the default layout, if it is specific
 * regarding sides already (trbl).
 *
 * @example
 *
 * getDirections('top'); // -> 'v:v'
 * getDirections('intersect'); // -> 't:t'
 *
 * getDirections('top-right', 'v:h'); // -> 'v:h'
 * getDirections('top-right', 'h:h'); // -> 'h:h'
 *
 *
 * @param {string} orientation
 * @param {string} defaultLayout
 *
 * @return {string}
 */


function getDirections(orientation, defaultLayout) {
  // don't override specific trbl directions
  if (isExplicitDirections(defaultLayout)) {
    return defaultLayout;
  }

  switch (orientation) {
    case 'intersect':
      return 't:t';

    case 'top':
    case 'bottom':
      return 'v:v';

    case 'left':
    case 'right':
      return 'h:h';
    // 'top-left'
    // 'top-right'
    // 'bottom-left'
    // 'bottom-right'

    default:
      return defaultLayout;
  }
}

function isValidDirections(directions) {
  return directions && /^h|v|t|r|b|l:h|v|t|r|b|l$/.test(directions);
}

function isExplicitDirections(directions) {
  return directions && /t|r|b|l/.test(directions);
}

function invertOrientation(orientation) {
  return {
    'top': 'bottom',
    'bottom': 'top',
    'left': 'right',
    'right': 'left',
    'top-left': 'bottom-right',
    'bottom-right': 'top-left',
    'top-right': 'bottom-left',
    'bottom-left': 'top-right'
  }[orientation];
}

function getDockingPoint(point, rectangle, dockingDirection, targetOrientation) {
  // ensure we end up with a specific docking direction
  // based on the targetOrientation, if <h|v> is being passed
  if (dockingDirection === 'h') {
    dockingDirection = /left/.test(targetOrientation) ? 'l' : 'r';
  }

  if (dockingDirection === 'v') {
    dockingDirection = /top/.test(targetOrientation) ? 't' : 'b';
  }

  if (dockingDirection === 't') {
    return {
      original: point,
      x: point.x,
      y: rectangle.y
    };
  }

  if (dockingDirection === 'r') {
    return {
      original: point,
      x: rectangle.x + rectangle.width,
      y: point.y
    };
  }

  if (dockingDirection === 'b') {
    return {
      original: point,
      x: point.x,
      y: rectangle.y + rectangle.height
    };
  }

  if (dockingDirection === 'l') {
    return {
      original: point,
      x: rectangle.x,
      y: point.y
    };
  }

  throw new Error('unexpected dockingDirection: <' + dockingDirection + '>');
}
/**
 * Return list of waypoints with redundant ones filtered out.
 *
 * @example
 *
 * Original points:
 *
 *   [x] ----- [x] ------ [x]
 *                         |
 *                        [x] ----- [x] - [x]
 *
 * Filtered:
 *
 *   [x] ---------------- [x]
 *                         |
 *                        [x] ----------- [x]
 *
 * @param  {Array<Point>} waypoints
 *
 * @return {Array<Point>}
 */


function withoutRedundantPoints(waypoints) {
  return waypoints.reduce(function (points, p, idx) {
    var previous = points[points.length - 1],
        next = waypoints[idx + 1];

    if (!(0, _Geometry.pointsOnLine)(previous, next, p, 0)) {
      points.push(p);
    }

    return points;
  }, []);
}

},{"../util/Geometry":318,"./LayoutUtil":300,"min-dash":555}],302:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Base = Base;
exports.Shape = Shape;
exports.Root = Root;
exports.Label = Label;
exports.Connection = Connection;
exports.create = create;

var _minDash = require("min-dash");

var _inherits = _interopRequireDefault(require("inherits"));

var _objectRefs = _interopRequireDefault(require("object-refs"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var parentRefs = new _objectRefs.default({
  name: 'children',
  enumerable: true,
  collection: true
}, {
  name: 'parent'
}),
    labelRefs = new _objectRefs.default({
  name: 'labels',
  enumerable: true,
  collection: true
}, {
  name: 'labelTarget'
}),
    attacherRefs = new _objectRefs.default({
  name: 'attachers',
  collection: true
}, {
  name: 'host'
}),
    outgoingRefs = new _objectRefs.default({
  name: 'outgoing',
  collection: true
}, {
  name: 'source'
}),
    incomingRefs = new _objectRefs.default({
  name: 'incoming',
  collection: true
}, {
  name: 'target'
});
/**
 * @namespace djs.model
 */

/**
 * @memberOf djs.model
 */

/**
 * The basic graphical representation
 *
 * @class
 *
 * @abstract
 */

function Base() {
  /**
   * The object that backs up the shape
   *
   * @name Base#businessObject
   * @type Object
   */
  Object.defineProperty(this, 'businessObject', {
    writable: true
  });
  /**
   * Single label support, will mapped to multi label array
   *
   * @name Base#label
   * @type Object
   */

  Object.defineProperty(this, 'label', {
    get: function () {
      return this.labels[0];
    },
    set: function (newLabel) {
      var label = this.label,
          labels = this.labels;

      if (!newLabel && label) {
        labels.remove(label);
      } else {
        labels.add(newLabel, 0);
      }
    }
  });
  /**
   * The parent shape
   *
   * @name Base#parent
   * @type Shape
   */

  parentRefs.bind(this, 'parent');
  /**
   * The list of labels
   *
   * @name Base#labels
   * @type Label
   */

  labelRefs.bind(this, 'labels');
  /**
   * The list of outgoing connections
   *
   * @name Base#outgoing
   * @type Array<Connection>
   */

  outgoingRefs.bind(this, 'outgoing');
  /**
   * The list of incoming connections
   *
   * @name Base#incoming
   * @type Array<Connection>
   */

  incomingRefs.bind(this, 'incoming');
}
/**
 * A graphical object
 *
 * @class
 * @constructor
 *
 * @extends Base
 */


function Shape() {
  Base.call(this);
  /**
   * Indicates frame shapes
   *
   * @name Shape#isFrame
   * @type boolean
   */

  /**
   * The list of children
   *
   * @name Shape#children
   * @type Array<Base>
   */

  parentRefs.bind(this, 'children');
  /**
   * @name Shape#host
   * @type Shape
   */

  attacherRefs.bind(this, 'host');
  /**
   * @name Shape#attachers
   * @type Shape
   */

  attacherRefs.bind(this, 'attachers');
}

(0, _inherits.default)(Shape, Base);
/**
 * A root graphical object
 *
 * @class
 * @constructor
 *
 * @extends Shape
 */

function Root() {
  Shape.call(this);
}

(0, _inherits.default)(Root, Shape);
/**
 * A label for an element
 *
 * @class
 * @constructor
 *
 * @extends Shape
 */

function Label() {
  Shape.call(this);
  /**
   * The labeled element
   *
   * @name Label#labelTarget
   * @type Base
   */

  labelRefs.bind(this, 'labelTarget');
}

(0, _inherits.default)(Label, Shape);
/**
 * A connection between two elements
 *
 * @class
 * @constructor
 *
 * @extends Base
 */

function Connection() {
  Base.call(this);
  /**
   * The element this connection originates from
   *
   * @name Connection#source
   * @type Base
   */

  outgoingRefs.bind(this, 'source');
  /**
   * The element this connection points to
   *
   * @name Connection#target
   * @type Base
   */

  incomingRefs.bind(this, 'target');
}

(0, _inherits.default)(Connection, Base);
var types = {
  connection: Connection,
  shape: Shape,
  label: Label,
  root: Root
};
/**
 * Creates a new model element of the specified type
 *
 * @method create
 *
 * @example
 *
 * var shape1 = Model.create('shape', { x: 10, y: 10, width: 100, height: 100 });
 * var shape2 = Model.create('shape', { x: 210, y: 210, width: 100, height: 100 });
 *
 * var connection = Model.create('connection', { waypoints: [ { x: 110, y: 55 }, {x: 210, y: 55 } ] });
 *
 * @param  {string} type lower-cased model name
 * @param  {Object} attrs attributes to initialize the new model instance with
 *
 * @return {Base} the new model instance
 */

function create(type, attrs) {
  var Type = types[type];

  if (!Type) {
    throw new Error('unknown type: <' + type + '>');
  }

  return (0, _minDash.assign)(new Type(), attrs);
}

},{"inherits":347,"min-dash":555,"object-refs":560}],303:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = KeyboardMove;

var _minDash = require("min-dash");

var DEFAULT_CONFIG = {
  moveSpeed: 50,
  moveSpeedAccelerated: 200
};
/**
 * A feature that allows users to move the canvas using the keyboard.
 *
 * @param {Object} config
 * @param {number} [config.moveSpeed=50]
 * @param {number} [config.moveSpeedAccelerated=200]
 * @param {Keyboard} keyboard
 * @param {Canvas} canvas
 */

function KeyboardMove(config, keyboard, canvas) {
  var self = this;
  this._config = (0, _minDash.assign)({}, DEFAULT_CONFIG, config || {});
  keyboard.addListener(arrowsListener);

  function arrowsListener(context) {
    var event = context.keyEvent,
        config = self._config;

    if (!keyboard.isCmd(event)) {
      return;
    }

    if (keyboard.isKey(['ArrowLeft', 'Left', 'ArrowUp', 'Up', 'ArrowDown', 'Down', 'ArrowRight', 'Right'], event)) {
      var speed = keyboard.isShift(event) ? config.moveSpeedAccelerated : config.moveSpeed;
      var direction;

      switch (event.key) {
        case 'ArrowLeft':
        case 'Left':
          direction = 'left';
          break;

        case 'ArrowUp':
        case 'Up':
          direction = 'up';
          break;

        case 'ArrowRight':
        case 'Right':
          direction = 'right';
          break;

        case 'ArrowDown':
        case 'Down':
          direction = 'down';
          break;
      }

      self.moveCanvas({
        speed: speed,
        direction: direction
      });
      return true;
    }
  }

  this.moveCanvas = function (opts) {
    var dx = 0,
        dy = 0,
        speed = opts.speed;
    var actualSpeed = speed / Math.min(Math.sqrt(canvas.viewbox().scale), 1);

    switch (opts.direction) {
      case 'left':
        // Left
        dx = actualSpeed;
        break;

      case 'up':
        // Up
        dy = actualSpeed;
        break;

      case 'right':
        // Right
        dx = -actualSpeed;
        break;

      case 'down':
        // Down
        dy = -actualSpeed;
        break;
    }

    canvas.scroll({
      dx: dx,
      dy: dy
    });
  };
}

KeyboardMove.$inject = ['config.keyboardMove', 'keyboard', 'canvas'];

},{"min-dash":555}],304:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _keyboard = _interopRequireDefault(require("../../features/keyboard"));

var _KeyboardMove = _interopRequireDefault(require("./KeyboardMove"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_keyboard.default],
  __init__: ['keyboardMove'],
  keyboardMove: ['type', _KeyboardMove.default]
};
exports.default = _default;

},{"../../features/keyboard":217,"./KeyboardMove":303}],305:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = MoveCanvas;

var _Cursor = require("../../util/Cursor");

var _ClickTrap = require("../../util/ClickTrap");

var _PositionUtil = require("../../util/PositionUtil");

var _minDom = require("min-dom");

var _Event = require("../../util/Event");

var THRESHOLD = 15;
/**
 * Move the canvas via mouse.
 *
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 */

function MoveCanvas(eventBus, canvas) {
  var context; // listen for move on element mouse down;
  // allow others to hook into the event before us though
  // (dragging / element moving will do this)

  eventBus.on('element.mousedown', 500, function (e) {
    return handleStart(e.originalEvent);
  });

  function handleMove(event) {
    var start = context.start,
        position = (0, _Event.toPoint)(event),
        delta = (0, _PositionUtil.delta)(position, start);

    if (!context.dragging && length(delta) > THRESHOLD) {
      context.dragging = true;
      (0, _ClickTrap.install)(eventBus);
      (0, _Cursor.set)('grab');
    }

    if (context.dragging) {
      var lastPosition = context.last || context.start;
      delta = (0, _PositionUtil.delta)(position, lastPosition);
      canvas.scroll({
        dx: delta.x,
        dy: delta.y
      });
      context.last = position;
    } // prevent select


    event.preventDefault();
  }

  function handleEnd(event) {
    _minDom.event.unbind(document, 'mousemove', handleMove);

    _minDom.event.unbind(document, 'mouseup', handleEnd);

    context = null;
    (0, _Cursor.unset)();
  }

  function handleStart(event) {
    // event is already handled by '.djs-draggable'
    if ((0, _minDom.closest)(event.target, '.djs-draggable')) {
      return;
    } // reject non-left left mouse button or modifier key


    if (event.button || event.ctrlKey || event.shiftKey || event.altKey) {
      return;
    }

    context = {
      start: (0, _Event.toPoint)(event)
    };

    _minDom.event.bind(document, 'mousemove', handleMove);

    _minDom.event.bind(document, 'mouseup', handleEnd); // we've handled the event


    return true;
  }
}

MoveCanvas.$inject = ['eventBus', 'canvas']; // helpers ///////

function length(point) {
  return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));
}

},{"../../util/ClickTrap":312,"../../util/Cursor":314,"../../util/Event":317,"../../util/PositionUtil":325,"min-dom":556}],306:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _MoveCanvas = _interopRequireDefault(require("./MoveCanvas"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['moveCanvas'],
  moveCanvas: ['type', _MoveCanvas.default]
};
exports.default = _default;

},{"./MoveCanvas":305}],307:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _touch = _interopRequireDefault(require("../../features/touch"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_touch.default]
};
exports.default = _default;

},{"../../features/touch":295}],308:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = ZoomScroll;

var _minDom = require("min-dom");

var _ZoomUtil = require("./ZoomUtil");

var _Math = require("../../util/Math");

var _minDash = require("min-dash");

var sign = Math.sign || function (n) {
  return n >= 0 ? 1 : -1;
};

var RANGE = {
  min: 0.2,
  max: 4
},
    NUM_STEPS = 10;
var DELTA_THRESHOLD = 0.1;
var DEFAULT_SCALE = 0.75;
/**
 * An implementation of zooming and scrolling within the
 * {@link Canvas} via the mouse wheel.
 *
 * Mouse wheel zooming / scrolling may be disabled using
 * the {@link toggle(enabled)} method.
 *
 * @param {Object} [config]
 * @param {boolean} [config.enabled=true] default enabled state
 * @param {number} [config.scale=.75] scroll sensivity
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 */

function ZoomScroll(config, eventBus, canvas) {
  config = config || {};
  this._enabled = false;
  this._canvas = canvas;
  this._container = canvas._container;
  this._handleWheel = (0, _minDash.bind)(this._handleWheel, this);
  this._totalDelta = 0;
  this._scale = config.scale || DEFAULT_SCALE;
  var self = this;
  eventBus.on('canvas.init', function (e) {
    self._init(config.enabled !== false);
  });
}

ZoomScroll.$inject = ['config.zoomScroll', 'eventBus', 'canvas'];

ZoomScroll.prototype.scroll = function scroll(delta) {
  this._canvas.scroll(delta);
};

ZoomScroll.prototype.reset = function reset() {
  this._canvas.zoom('fit-viewport');
};
/**
 * Zoom depending on delta.
 *
 * @param {number} delta
 * @param {Object} position
 */


ZoomScroll.prototype.zoom = function zoom(delta, position) {
  // zoom with half the step size of stepZoom
  var stepSize = (0, _ZoomUtil.getStepSize)(RANGE, NUM_STEPS * 2); // add until threshold reached

  this._totalDelta += delta;

  if (Math.abs(this._totalDelta) > DELTA_THRESHOLD) {
    this._zoom(delta, position, stepSize); // reset


    this._totalDelta = 0;
  }
};

ZoomScroll.prototype._handleWheel = function handleWheel(event) {
  // event is already handled by '.djs-scrollable'
  if ((0, _minDom.closest)(event.target, '.djs-scrollable', true)) {
    return;
  }

  var element = this._container;
  event.preventDefault(); // pinch to zoom is mapped to wheel + ctrlKey = true
  // in modern browsers (!)

  var isZoom = event.ctrlKey;
  var isHorizontalScroll = event.shiftKey;
  var factor = -1 * this._scale,
      delta;

  if (isZoom) {
    factor *= event.deltaMode === 0 ? 0.020 : 0.32;
  } else {
    factor *= event.deltaMode === 0 ? 1.0 : 16.0;
  }

  if (isZoom) {
    var elementRect = element.getBoundingClientRect();
    var offset = {
      x: event.clientX - elementRect.left,
      y: event.clientY - elementRect.top
    };
    delta = Math.sqrt(Math.pow(event.deltaY, 2) + Math.pow(event.deltaX, 2)) * sign(event.deltaY) * factor; // zoom in relative to diagram {x,y} coordinates

    this.zoom(delta, offset);
  } else {
    if (isHorizontalScroll) {
      delta = {
        dx: factor * event.deltaY,
        dy: 0
      };
    } else {
      delta = {
        dx: factor * event.deltaX,
        dy: factor * event.deltaY
      };
    }

    this.scroll(delta);
  }
};
/**
 * Zoom with fixed step size.
 *
 * @param {number} delta - Zoom delta (1 for zooming in, -1 for out).
 * @param {Object} position
 */


ZoomScroll.prototype.stepZoom = function stepZoom(delta, position) {
  var stepSize = (0, _ZoomUtil.getStepSize)(RANGE, NUM_STEPS);

  this._zoom(delta, position, stepSize);
};
/**
 * Zoom in/out given a step size.
 *
 * @param {number} delta
 * @param {Object} position
 * @param {number} stepSize
 */


ZoomScroll.prototype._zoom = function (delta, position, stepSize) {
  var canvas = this._canvas;
  var direction = delta > 0 ? 1 : -1;
  var currentLinearZoomLevel = (0, _Math.log10)(canvas.zoom()); // snap to a proximate zoom step

  var newLinearZoomLevel = Math.round(currentLinearZoomLevel / stepSize) * stepSize; // increase or decrease one zoom step in the given direction

  newLinearZoomLevel += stepSize * direction; // calculate the absolute logarithmic zoom level based on the linear zoom level
  // (e.g. 2 for an absolute x2 zoom)

  var newLogZoomLevel = Math.pow(10, newLinearZoomLevel);
  canvas.zoom((0, _ZoomUtil.cap)(RANGE, newLogZoomLevel), position);
};
/**
 * Toggle the zoom scroll ability via mouse wheel.
 *
 * @param  {boolean} [newEnabled] new enabled state
 */


ZoomScroll.prototype.toggle = function toggle(newEnabled) {
  var element = this._container;
  var handleWheel = this._handleWheel;
  var oldEnabled = this._enabled;

  if (typeof newEnabled === 'undefined') {
    newEnabled = !oldEnabled;
  } // only react on actual changes


  if (oldEnabled !== newEnabled) {
    // add or remove wheel listener based on
    // changed enabled state
    _minDom.event[newEnabled ? 'bind' : 'unbind'](element, 'wheel', handleWheel, false);
  }

  this._enabled = newEnabled;
  return newEnabled;
};

ZoomScroll.prototype._init = function (newEnabled) {
  this.toggle(newEnabled);
};

},{"../../util/Math":322,"./ZoomUtil":309,"min-dash":555,"min-dom":556}],309:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getStepSize = getStepSize;
exports.cap = cap;

var _Math = require("../../util/Math");

/**
 * Get step size for given range and number of steps.
 *
 * @param {Object} range
 * @param {number} range.min
 * @param {number} range.max
 */
function getStepSize(range, steps) {
  var minLinearRange = (0, _Math.log10)(range.min),
      maxLinearRange = (0, _Math.log10)(range.max);
  var absoluteLinearRange = Math.abs(minLinearRange) + Math.abs(maxLinearRange);
  return absoluteLinearRange / steps;
}

function cap(range, scale) {
  return Math.max(range.min, Math.min(range.max, scale));
}

},{"../../util/Math":322}],310:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _ZoomScroll = _interopRequireDefault(require("./ZoomScroll"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['zoomScroll'],
  zoomScroll: ['type', _ZoomScroll.default]
};
exports.default = _default;

},{"./ZoomScroll":308}],311:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getNewAttachPoint = getNewAttachPoint;
exports.getNewAttachShapeDelta = getNewAttachShapeDelta;

var _LayoutUtil = require("../layout/LayoutUtil");

var _PositionUtil = require("./PositionUtil");

/**
 * Calculates the absolute point relative to the new element's position
 *
 * @param {point} point [absolute]
 * @param {bounds} oldBounds
 * @param {bounds} newBounds
 *
 * @return {point} point [absolute]
 */
function getNewAttachPoint(point, oldBounds, newBounds) {
  var oldCenter = (0, _PositionUtil.center)(oldBounds),
      newCenter = (0, _PositionUtil.center)(newBounds),
      oldDelta = (0, _PositionUtil.delta)(point, oldCenter);
  var newDelta = {
    x: oldDelta.x * (newBounds.width / oldBounds.width),
    y: oldDelta.y * (newBounds.height / oldBounds.height)
  };
  return (0, _LayoutUtil.roundPoint)({
    x: newCenter.x + newDelta.x,
    y: newCenter.y + newDelta.y
  });
}
/**
 * Calculates the shape's delta relative to a new position
 * of a certain element's bounds
 *
 * @param {djs.model.Shape} point [absolute]
 * @param {bounds} oldBounds
 * @param {bounds} newBounds
 *
 * @return {delta} delta
 */


function getNewAttachShapeDelta(shape, oldBounds, newBounds) {
  var shapeCenter = (0, _PositionUtil.center)(shape),
      oldCenter = (0, _PositionUtil.center)(oldBounds),
      newCenter = (0, _PositionUtil.center)(newBounds),
      shapeDelta = (0, _PositionUtil.delta)(shape, shapeCenter),
      oldCenterDelta = (0, _PositionUtil.delta)(shapeCenter, oldCenter),
      stickyPositionDelta = getStickyPositionDelta(shapeCenter, oldBounds, newBounds);

  if (stickyPositionDelta) {
    return stickyPositionDelta;
  }

  var newCenterDelta = {
    x: oldCenterDelta.x * (newBounds.width / oldBounds.width),
    y: oldCenterDelta.y * (newBounds.height / oldBounds.height)
  };
  var newShapeCenter = {
    x: newCenter.x + newCenterDelta.x,
    y: newCenter.y + newCenterDelta.y
  };
  return (0, _LayoutUtil.roundPoint)({
    x: newShapeCenter.x + shapeDelta.x - shape.x,
    y: newShapeCenter.y + shapeDelta.y - shape.y
  });
}

function getStickyPositionDelta(oldShapeCenter, oldBounds, newBounds) {
  var oldTRBL = (0, _LayoutUtil.asTRBL)(oldBounds),
      newTRBL = (0, _LayoutUtil.asTRBL)(newBounds);

  if (isMoved(oldTRBL, newTRBL)) {
    return null;
  }

  var oldOrientation = (0, _LayoutUtil.getOrientation)(oldBounds, oldShapeCenter),
      stickyPositionDelta,
      newShapeCenter,
      newOrientation;

  if (oldOrientation === 'top') {
    stickyPositionDelta = {
      x: 0,
      y: newTRBL.bottom - oldTRBL.bottom
    };
  } else if (oldOrientation === 'bottom') {
    stickyPositionDelta = {
      x: 0,
      y: newTRBL.top - oldTRBL.top
    };
  } else if (oldOrientation === 'right') {
    stickyPositionDelta = {
      x: newTRBL.left - oldTRBL.left,
      y: 0
    };
  } else if (oldOrientation === 'left') {
    stickyPositionDelta = {
      x: newTRBL.right - oldTRBL.right,
      y: 0
    };
  } else {
    // fallback to proportional movement for corner-placed attachments
    return null;
  }

  newShapeCenter = {
    x: oldShapeCenter.x + stickyPositionDelta.x,
    y: oldShapeCenter.y + stickyPositionDelta.y
  };
  newOrientation = (0, _LayoutUtil.getOrientation)(newBounds, newShapeCenter);

  if (newOrientation !== oldOrientation) {
    // fallback to proportional movement if orientation would otherwise change
    return null;
  }

  return stickyPositionDelta;
}

function isMoved(oldTRBL, newTRBL) {
  return isHorizontallyMoved(oldTRBL, newTRBL) || isVerticallyMoved(oldTRBL, newTRBL);
}

function isHorizontallyMoved(oldTRBL, newTRBL) {
  return oldTRBL.right !== newTRBL.right && oldTRBL.left !== newTRBL.left;
}

function isVerticallyMoved(oldTRBL, newTRBL) {
  return oldTRBL.top !== newTRBL.top && oldTRBL.bottom !== newTRBL.bottom;
}

},{"../layout/LayoutUtil":300,"./PositionUtil":325}],312:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.install = install;
var TRAP_PRIORITY = 5000;
/**
 * Installs a click trap that prevents a ghost click following a dragging operation.
 *
 * @return {Function} a function to immediately remove the installed trap.
 */

function install(eventBus, eventName) {
  eventName = eventName || 'element.click';

  function trap() {
    return false;
  }

  eventBus.once(eventName, TRAP_PRIORITY, trap);
  return function () {
    eventBus.off(eventName, trap);
  };
}

},{}],313:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.remove = remove;
exports.add = add;
exports.indexOf = indexOf;

/**
 * Failsafe remove an element from a collection
 *
 * @param  {Array<Object>} [collection]
 * @param  {Object} [element]
 *
 * @return {number} the previous index of the element
 */
function remove(collection, element) {
  if (!collection || !element) {
    return -1;
  }

  var idx = collection.indexOf(element);

  if (idx !== -1) {
    collection.splice(idx, 1);
  }

  return idx;
}
/**
 * Fail save add an element to the given connection, ensuring
 * it does not yet exist.
 *
 * @param {Array<Object>} collection
 * @param {Object} element
 * @param {number} idx
 */


function add(collection, element, idx) {
  if (!collection || !element) {
    return;
  }

  if (typeof idx !== 'number') {
    idx = -1;
  }

  var currentIdx = collection.indexOf(element);

  if (currentIdx !== -1) {
    if (currentIdx === idx) {
      // nothing to do, position has not changed
      return;
    } else {
      if (idx !== -1) {
        // remove from current position
        collection.splice(currentIdx, 1);
      } else {
        // already exists in collection
        return;
      }
    }
  }

  if (idx !== -1) {
    // insert at specified position
    collection.splice(idx, 0, element);
  } else {
    // push to end
    collection.push(element);
  }
}
/**
 * Fail save get the index of an element in a collection.
 *
 * @param {Array<Object>} collection
 * @param {Object} element
 *
 * @return {number} the index or -1 if collection or element do
 *                  not exist or the element is not contained.
 */


function indexOf(collection, element) {
  if (!collection || !element) {
    return -1;
  }

  return collection.indexOf(element);
}

},{}],314:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.set = set;
exports.unset = unset;
exports.has = has;

var _minDom = require("min-dom");

var CURSOR_CLS_PATTERN = /^djs-cursor-.*$/;

function set(mode) {
  var classes = (0, _minDom.classes)(document.body);
  classes.removeMatching(CURSOR_CLS_PATTERN);

  if (mode) {
    classes.add('djs-cursor-' + mode);
  }
}

function unset() {
  set(null);
}

function has(mode) {
  var classes = (0, _minDom.classes)(document.body);
  return classes.has('djs-cursor-' + mode);
}

},{"min-dom":556}],315:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getParents = getParents;
exports.add = add;
exports.eachElement = eachElement;
exports.selfAndChildren = selfAndChildren;
exports.selfAndDirectChildren = selfAndDirectChildren;
exports.selfAndAllChildren = selfAndAllChildren;
exports.getClosure = getClosure;
exports.getBBox = getBBox;
exports.getEnclosedElements = getEnclosedElements;
exports.getType = getType;
exports.isFrameElement = isFrameElement;

var _minDash = require("min-dash");

/**
 * Get parent elements.
 *
 * @param {Array<djs.model.base>} elements
 *
 * @returns {Array<djs.model.Base>}
 */
function getParents(elements) {
  // find elements that are not children of any other elements
  return (0, _minDash.filter)(elements, function (element) {
    return !(0, _minDash.find)(elements, function (e) {
      return e !== element && getParent(element, e);
    });
  });
}

function getParent(element, parent) {
  if (!parent) {
    return;
  }

  if (element === parent) {
    return parent;
  }

  if (!element.parent) {
    return;
  }

  return getParent(element.parent, parent);
}
/**
 * Adds an element to a collection and returns true if the
 * element was added.
 *
 * @param {Array<Object>} elements
 * @param {Object} e
 * @param {boolean} unique
 */


function add(elements, e, unique) {
  var canAdd = !unique || elements.indexOf(e) === -1;

  if (canAdd) {
    elements.push(e);
  }

  return canAdd;
}
/**
 * Iterate over each element in a collection, calling the iterator function `fn`
 * with (element, index, recursionDepth).
 *
 * Recurse into all elements that are returned by `fn`.
 *
 * @param  {Object|Array<Object>} elements
 * @param  {Function} fn iterator function called with (element, index, recursionDepth)
 * @param  {number} [depth] maximum recursion depth
 */


function eachElement(elements, fn, depth) {
  depth = depth || 0;

  if (!(0, _minDash.isArray)(elements)) {
    elements = [elements];
  }

  (0, _minDash.forEach)(elements, function (s, i) {
    var filter = fn(s, i, depth);

    if ((0, _minDash.isArray)(filter) && filter.length) {
      eachElement(filter, fn, depth + 1);
    }
  });
}
/**
 * Collects self + child elements up to a given depth from a list of elements.
 *
 * @param  {djs.model.Base|Array<djs.model.Base>} elements the elements to select the children from
 * @param  {boolean} unique whether to return a unique result set (no duplicates)
 * @param  {number} maxDepth the depth to search through or -1 for infinite
 *
 * @return {Array<djs.model.Base>} found elements
 */


function selfAndChildren(elements, unique, maxDepth) {
  var result = [],
      processedChildren = [];
  eachElement(elements, function (element, i, depth) {
    add(result, element, unique);
    var children = element.children; // max traversal depth not reached yet

    if (maxDepth === -1 || depth < maxDepth) {
      // children exist && children not yet processed
      if (children && add(processedChildren, children, unique)) {
        return children;
      }
    }
  });
  return result;
}
/**
 * Return self + direct children for a number of elements
 *
 * @param  {Array<djs.model.Base>} elements to query
 * @param  {boolean} allowDuplicates to allow duplicates in the result set
 *
 * @return {Array<djs.model.Base>} the collected elements
 */


function selfAndDirectChildren(elements, allowDuplicates) {
  return selfAndChildren(elements, !allowDuplicates, 1);
}
/**
 * Return self + ALL children for a number of elements
 *
 * @param  {Array<djs.model.Base>} elements to query
 * @param  {boolean} allowDuplicates to allow duplicates in the result set
 *
 * @return {Array<djs.model.Base>} the collected elements
 */


function selfAndAllChildren(elements, allowDuplicates) {
  return selfAndChildren(elements, !allowDuplicates, -1);
}
/**
 * Gets the the closure for all selected elements,
 * their enclosed children and connections.
 *
 * @param {Array<djs.model.Base>} elements
 * @param {boolean} [isTopLevel=true]
 * @param {Object} [existingClosure]
 *
 * @return {Object} newClosure
 */


function getClosure(elements, isTopLevel, closure) {
  if ((0, _minDash.isUndefined)(isTopLevel)) {
    isTopLevel = true;
  }

  if ((0, _minDash.isObject)(isTopLevel)) {
    closure = isTopLevel;
    isTopLevel = true;
  }

  closure = closure || {};
  var allShapes = copyObject(closure.allShapes),
      allConnections = copyObject(closure.allConnections),
      enclosedElements = copyObject(closure.enclosedElements),
      enclosedConnections = copyObject(closure.enclosedConnections);
  var topLevel = copyObject(closure.topLevel, isTopLevel && (0, _minDash.groupBy)(elements, function (e) {
    return e.id;
  }));

  function handleConnection(c) {
    if (topLevel[c.source.id] && topLevel[c.target.id]) {
      topLevel[c.id] = [c];
    } // not enclosed as a child, but maybe logically
    // (connecting two moved elements?)


    if (allShapes[c.source.id] && allShapes[c.target.id]) {
      enclosedConnections[c.id] = enclosedElements[c.id] = c;
    }

    allConnections[c.id] = c;
  }

  function handleElement(element) {
    enclosedElements[element.id] = element;

    if (element.waypoints) {
      // remember connection
      enclosedConnections[element.id] = allConnections[element.id] = element;
    } else {
      // remember shape
      allShapes[element.id] = element; // remember all connections

      (0, _minDash.forEach)(element.incoming, handleConnection);
      (0, _minDash.forEach)(element.outgoing, handleConnection); // recurse into children

      return element.children;
    }
  }

  eachElement(elements, handleElement);
  return {
    allShapes: allShapes,
    allConnections: allConnections,
    topLevel: topLevel,
    enclosedConnections: enclosedConnections,
    enclosedElements: enclosedElements
  };
}
/**
 * Returns the surrounding bbox for all elements in
 * the array or the element primitive.
 *
 * @param {Array<djs.model.Shape>|djs.model.Shape} elements
 * @param {boolean} stopRecursion
 */


function getBBox(elements, stopRecursion) {
  stopRecursion = !!stopRecursion;

  if (!(0, _minDash.isArray)(elements)) {
    elements = [elements];
  }

  var minX, minY, maxX, maxY;
  (0, _minDash.forEach)(elements, function (element) {
    // If element is a connection the bbox must be computed first
    var bbox = element;

    if (element.waypoints && !stopRecursion) {
      bbox = getBBox(element.waypoints, true);
    }

    var x = bbox.x,
        y = bbox.y,
        height = bbox.height || 0,
        width = bbox.width || 0;

    if (x < minX || minX === undefined) {
      minX = x;
    }

    if (y < minY || minY === undefined) {
      minY = y;
    }

    if (x + width > maxX || maxX === undefined) {
      maxX = x + width;
    }

    if (y + height > maxY || maxY === undefined) {
      maxY = y + height;
    }
  });
  return {
    x: minX,
    y: minY,
    height: maxY - minY,
    width: maxX - minX
  };
}
/**
 * Returns all elements that are enclosed from the bounding box.
 *
 *   * If bbox.(width|height) is not specified the method returns
 *     all elements with element.x/y > bbox.x/y
 *   * If only bbox.x or bbox.y is specified, method return all elements with
 *     e.x > bbox.x or e.y > bbox.y
 *
 * @param {Array<djs.model.Shape>} elements List of Elements to search through
 * @param {djs.model.Shape} bbox the enclosing bbox.
 *
 * @return {Array<djs.model.Shape>} enclosed elements
 */


function getEnclosedElements(elements, bbox) {
  var filteredElements = {};
  (0, _minDash.forEach)(elements, function (element) {
    var e = element;

    if (e.waypoints) {
      e = getBBox(e);
    }

    if (!(0, _minDash.isNumber)(bbox.y) && e.x > bbox.x) {
      filteredElements[element.id] = element;
    }

    if (!(0, _minDash.isNumber)(bbox.x) && e.y > bbox.y) {
      filteredElements[element.id] = element;
    }

    if (e.x > bbox.x && e.y > bbox.y) {
      if ((0, _minDash.isNumber)(bbox.width) && (0, _minDash.isNumber)(bbox.height) && e.width + e.x < bbox.width + bbox.x && e.height + e.y < bbox.height + bbox.y) {
        filteredElements[element.id] = element;
      } else if (!(0, _minDash.isNumber)(bbox.width) || !(0, _minDash.isNumber)(bbox.height)) {
        filteredElements[element.id] = element;
      }
    }
  });
  return filteredElements;
}

function getType(element) {
  if ('waypoints' in element) {
    return 'connection';
  }

  if ('x' in element) {
    return 'shape';
  }

  return 'root';
}

function isFrameElement(element) {
  return !!(element && element.isFrame);
} // helpers ///////////////////////////////


function copyObject(src1, src2) {
  return (0, _minDash.assign)({}, src1 || {}, src2 || {});
}

},{"min-dash":555}],316:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.escapeHTML = escapeHTML;
Object.defineProperty(exports, "escapeCSS", {
  enumerable: true,
  get: function () {
    return _css.default;
  }
});

var _css = _interopRequireDefault(require("css.escape"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var HTML_ESCAPE_MAP = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  '\'': '&#39;'
};

function escapeHTML(str) {
  str = '' + str;
  return str && str.replace(/[&<>"']/g, function (match) {
    return HTML_ESCAPE_MAP[match];
  });
}

},{"css.escape":331}],317:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getOriginal = getOriginal;
exports.stopPropagation = stopPropagation;
exports.toPoint = toPoint;

function __stopPropagation(event) {
  if (!event || typeof event.stopPropagation !== 'function') {
    return;
  }

  event.stopPropagation();
}

function getOriginal(event) {
  return event.originalEvent || event.srcEvent;
}

function stopPropagation(event, immediate) {
  __stopPropagation(event, immediate);

  __stopPropagation(getOriginal(event), immediate);
}

function toPoint(event) {
  if (event.pointers && event.pointers.length) {
    event = event.pointers[0];
  }

  if (event.touches && event.touches.length) {
    event = event.touches[0];
  }

  return event ? {
    x: event.clientX,
    y: event.clientY
  } : null;
}

},{}],318:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.pointDistance = pointDistance;
exports.pointsOnLine = pointsOnLine;
exports.pointsAligned = pointsAligned;
exports.pointsAlignedHorizontally = pointsAlignedHorizontally;
exports.pointsAlignedVertically = pointsAlignedVertically;
exports.pointInRect = pointInRect;
exports.getMidPoint = getMidPoint;

var _minDash = require("min-dash");

/**
 * Computes the distance between two points
 *
 * @param  {Point}  p
 * @param  {Point}  q
 *
 * @return {number}  distance
 */
function pointDistance(a, b) {
  if (!a || !b) {
    return -1;
  }

  return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
}
/**
 * Returns true if the point r is on the line between p and q
 *
 * @param  {Point}  p
 * @param  {Point}  q
 * @param  {Point}  r
 * @param  {number} [accuracy=5] accuracy for points on line check (lower is better)
 *
 * @return {boolean}
 */


function pointsOnLine(p, q, r, accuracy) {
  if (typeof accuracy === 'undefined') {
    accuracy = 5;
  }

  if (!p || !q || !r) {
    return false;
  }

  var val = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x),
      dist = pointDistance(p, q); // @see http://stackoverflow.com/a/907491/412190

  return Math.abs(val / dist) <= accuracy;
}

var ALIGNED_THRESHOLD = 2;
/**
 * Check whether two points are horizontally or vertically aligned.
 *
 * @param {Array<Point>|Point}
 * @param {Point}
 *
 * @return {string|boolean}
 */

function pointsAligned(a, b) {
  var points;

  if ((0, _minDash.isArray)(a)) {
    points = a;
  } else {
    points = [a, b];
  }

  if (pointsAlignedHorizontally(points)) {
    return 'h';
  }

  if (pointsAlignedVertically(points)) {
    return 'v';
  }

  return false;
}

function pointsAlignedHorizontally(a, b) {
  var points;

  if ((0, _minDash.isArray)(a)) {
    points = a;
  } else {
    points = [a, b];
  }

  var firstPoint = points.slice().shift();
  return (0, _minDash.every)(points, function (point) {
    return Math.abs(firstPoint.y - point.y) <= ALIGNED_THRESHOLD;
  });
}

function pointsAlignedVertically(a, b) {
  var points;

  if ((0, _minDash.isArray)(a)) {
    points = a;
  } else {
    points = [a, b];
  }

  var firstPoint = points.slice().shift();
  return (0, _minDash.every)(points, function (point) {
    return Math.abs(firstPoint.x - point.x) <= ALIGNED_THRESHOLD;
  });
}
/**
 * Returns true if the point p is inside the rectangle rect
 *
 * @param  {Point}  p
 * @param  {Rect} rect
 * @param  {number} tolerance
 *
 * @return {boolean}
 */


function pointInRect(p, rect, tolerance) {
  tolerance = tolerance || 0;
  return p.x > rect.x - tolerance && p.y > rect.y - tolerance && p.x < rect.x + rect.width + tolerance && p.y < rect.y + rect.height + tolerance;
}
/**
 * Returns a point in the middle of points p and q
 *
 * @param  {Point}  p
 * @param  {Point}  q
 *
 * @return {Point} middle point
 */


function getMidPoint(p, q) {
  return {
    x: Math.round(p.x + (q.x - p.x) / 2.0),
    y: Math.round(p.y + (q.y - p.y) / 2.0)
  };
}

},{"min-dash":555}],319:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getVisual = getVisual;
exports.getChildren = getChildren;

/**
 * SVGs for elements are generated by the {@link GraphicsFactory}.
 *
 * This utility gives quick access to the important semantic
 * parts of an element.
 */

/**
 * Returns the visual part of a diagram element
 *
 * @param {Snap<SVGElement>} gfx
 *
 * @return {Snap<SVGElement>}
 */
function getVisual(gfx) {
  return gfx.childNodes[0];
}
/**
 * Returns the children for a given diagram element.
 *
 * @param {Snap<SVGElement>} gfx
 * @return {Snap<SVGElement>}
 */


function getChildren(gfx) {
  return gfx.parentNode.childNodes[1];
}

},{}],320:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = IdGenerator;

/**
 * Util that provides unique IDs.
 *
 * @class djs.util.IdGenerator
 * @constructor
 * @memberOf djs.util
 *
 * The ids can be customized via a given prefix and contain a random value to avoid collisions.
 *
 * @param {string} prefix a prefix to prepend to generated ids (for better readability)
 */
function IdGenerator(prefix) {
  this._counter = 0;
  this._prefix = (prefix ? prefix + '-' : '') + Math.floor(Math.random() * 1000000000) + '-';
}
/**
 * Returns a next unique ID.
 *
 * @method djs.util.IdGenerator#next
 *
 * @returns {string} the id
 */


IdGenerator.prototype.next = function () {
  return this._prefix + ++this._counter;
};

},{}],321:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getApproxIntersection = getApproxIntersection;

var _Geometry = require("./Geometry");

var _pathIntersection = _interopRequireDefault(require("path-intersection"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var round = Math.round,
    max = Math.max;

function circlePath(center, r) {
  var x = center.x,
      y = center.y;
  return [['M', x, y], ['m', 0, -r], ['a', r, r, 0, 1, 1, 0, 2 * r], ['a', r, r, 0, 1, 1, 0, -2 * r], ['z']];
}

function linePath(points) {
  var segments = [];
  points.forEach(function (p, idx) {
    segments.push([idx === 0 ? 'M' : 'L', p.x, p.y]);
  });
  return segments;
}

var INTERSECTION_THRESHOLD = 10;

function getBendpointIntersection(waypoints, reference) {
  var i, w;

  for (i = 0; w = waypoints[i]; i++) {
    if ((0, _Geometry.pointDistance)(w, reference) <= INTERSECTION_THRESHOLD) {
      return {
        point: waypoints[i],
        bendpoint: true,
        index: i
      };
    }
  }

  return null;
}

function getPathIntersection(waypoints, reference) {
  var intersections = (0, _pathIntersection.default)(circlePath(reference, INTERSECTION_THRESHOLD), linePath(waypoints));
  var a = intersections[0],
      b = intersections[intersections.length - 1],
      idx;

  if (!a) {
    // no intersection
    return null;
  }

  if (a !== b) {
    if (a.segment2 !== b.segment2) {
      // we use the bendpoint in between both segments
      // as the intersection point
      idx = max(a.segment2, b.segment2) - 1;
      return {
        point: waypoints[idx],
        bendpoint: true,
        index: idx
      };
    }

    return {
      point: {
        x: round(a.x + b.x) / 2,
        y: round(a.y + b.y) / 2
      },
      index: a.segment2
    };
  }

  return {
    point: {
      x: round(a.x),
      y: round(a.y)
    },
    index: a.segment2
  };
}
/**
 * Returns the closest point on the connection towards a given reference point.
 *
 * @param  {Array<Point>} waypoints
 * @param  {Point} reference
 *
 * @return {Object} intersection data (segment, point)
 */


function getApproxIntersection(waypoints, reference) {
  return getBendpointIntersection(waypoints, reference) || getPathIntersection(waypoints, reference);
}

},{"./Geometry":318,"path-intersection":563}],322:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.log10 = log10;
Object.defineProperty(exports, "substract", {
  enumerable: true,
  get: function () {
    return _PositionUtil.delta;
  }
});

var _PositionUtil = require("./PositionUtil");

/**
 * Get the logarithm of x with base 10
 * @param  {Integer} value
 */
function log10(x) {
  return Math.log(x) / Math.log(10);
}

},{"./PositionUtil":325}],323:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.isPrimaryButton = isPrimaryButton;
exports.hasPrimaryModifier = hasPrimaryModifier;
exports.hasSecondaryModifier = hasSecondaryModifier;
Object.defineProperty(exports, "isMac", {
  enumerable: true,
  get: function () {
    return _Platform.isMac;
  }
});

var _Event = require("./Event");

var _Platform = require("./Platform");

function isPrimaryButton(event) {
  // button === 0 -> left áka primary mouse button
  return !((0, _Event.getOriginal)(event) || event).button;
}

function hasPrimaryModifier(event) {
  var originalEvent = (0, _Event.getOriginal)(event) || event;

  if (!isPrimaryButton(event)) {
    return false;
  } // Use alt as primary modifier key for mac OS


  if ((0, _Platform.isMac)()) {
    return originalEvent.metaKey;
  } else {
    return originalEvent.ctrlKey;
  }
}

function hasSecondaryModifier(event) {
  var originalEvent = (0, _Event.getOriginal)(event) || event;
  return isPrimaryButton(event) && originalEvent.shiftKey;
}

},{"./Event":317,"./Platform":324}],324:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.isMac = isMac;

function isMac() {
  return /mac/i.test(navigator.platform);
}

},{}],325:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.center = center;
exports.delta = delta;

function center(bounds) {
  return {
    x: bounds.x + bounds.width / 2,
    y: bounds.y + bounds.height / 2
  };
}

function delta(a, b) {
  return {
    x: a.x - b.x,
    y: a.y - b.y
  };
}

},{}],326:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.saveClear = saveClear;

/**
 * Remove from the beginning of a collection until it is empty.
 *
 * This is a null-safe operation that ensures elements
 * are being removed from the given collection until the
 * collection is empty.
 *
 * The implementation deals with the fact that a remove operation
 * may touch, i.e. remove multiple elements in the collection
 * at a time.
 *
 * @param {Array<Object>} [collection]
 * @param {Function} removeFn
 *
 * @return {Array<Object>} the cleared collection
 */
function saveClear(collection, removeFn) {
  if (typeof removeFn !== 'function') {
    throw new Error('removeFn iterator must be a function');
  }

  if (!collection) {
    return;
  }

  var e;

  while (e = collection[0]) {
    removeFn(e);
  }

  return collection;
}

},{}],327:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.componentsToPath = componentsToPath;
exports.toSVGPoints = toSVGPoints;
exports.createLine = createLine;
exports.updateLine = updateLine;

var _tinySvg = require("tiny-svg");

function componentsToPath(elements) {
  return elements.join(',').replace(/,?([A-z]),?/g, '$1');
}

function toSVGPoints(points) {
  var result = '';

  for (var i = 0, p; p = points[i]; i++) {
    result += p.x + ',' + p.y + ' ';
  }

  return result;
}

function createLine(points, attrs) {
  var line = (0, _tinySvg.create)('polyline');
  (0, _tinySvg.attr)(line, {
    points: toSVGPoints(points)
  });

  if (attrs) {
    (0, _tinySvg.attr)(line, attrs);
  }

  return line;
}

function updateLine(gfx, points) {
  (0, _tinySvg.attr)(gfx, {
    points: toSVGPoints(points)
  });
  return gfx;
}

},{"tiny-svg":567}],328:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.transform = transform;
exports.translate = translate;
exports.rotate = rotate;
exports.scale = scale;

var _tinySvg = require("tiny-svg");

/**
 * @param {<SVGElement>} element
 * @param {number} x
 * @param {number} y
 * @param {number} angle
 * @param {number} amount
 */
function transform(gfx, x, y, angle, amount) {
  var translate = (0, _tinySvg.createTransform)();
  translate.setTranslate(x, y);
  var rotate = (0, _tinySvg.createTransform)();
  rotate.setRotate(angle || 0, 0, 0);
  var scale = (0, _tinySvg.createTransform)();
  scale.setScale(amount || 1, amount || 1);
  (0, _tinySvg.transform)(gfx, [translate, rotate, scale]);
}
/**
 * @param {SVGElement} element
 * @param {number} x
 * @param {number} y
 */


function translate(gfx, x, y) {
  var translate = (0, _tinySvg.createTransform)();
  translate.setTranslate(x, y);
  (0, _tinySvg.transform)(gfx, translate);
}
/**
 * @param {SVGElement} element
 * @param {number} angle
 */


function rotate(gfx, angle) {
  var rotate = (0, _tinySvg.createTransform)();
  rotate.setRotate(angle, 0, 0);
  (0, _tinySvg.transform)(gfx, rotate);
}
/**
 * @param {SVGElement} element
 * @param {number} amount
 */


function scale(gfx, amount) {
  var scale = (0, _tinySvg.createTransform)();
  scale.setScale(amount, amount);
  (0, _tinySvg.transform)(gfx, scale);
}

},{"tiny-svg":567}],329:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = Text;

var _minDash = require("min-dash");

var _tinySvg = require("tiny-svg");

var DEFAULT_BOX_PADDING = 0;
var DEFAULT_LABEL_SIZE = {
  width: 150,
  height: 50
};

function parseAlign(align) {
  var parts = align.split('-');
  return {
    horizontal: parts[0] || 'center',
    vertical: parts[1] || 'top'
  };
}

function parsePadding(padding) {
  if ((0, _minDash.isObject)(padding)) {
    return (0, _minDash.assign)({
      top: 0,
      left: 0,
      right: 0,
      bottom: 0
    }, padding);
  } else {
    return {
      top: padding,
      left: padding,
      right: padding,
      bottom: padding
    };
  }
}

function getTextBBox(text, fakeText) {
  fakeText.textContent = text;
  var textBBox;

  try {
    var bbox,
        emptyLine = text === ''; // add dummy text, when line is empty to
    // determine correct height

    fakeText.textContent = emptyLine ? 'dummy' : text;
    textBBox = fakeText.getBBox(); // take text rendering related horizontal
    // padding into account

    bbox = {
      width: textBBox.width + textBBox.x * 2,
      height: textBBox.height
    };

    if (emptyLine) {
      // correct width
      bbox.width = 0;
    }

    return bbox;
  } catch (e) {
    return {
      width: 0,
      height: 0
    };
  }
}
/**
 * Layout the next line and return the layouted element.
 *
 * Alters the lines passed.
 *
 * @param  {Array<string>} lines
 * @return {Object} the line descriptor, an object { width, height, text }
 */


function layoutNext(lines, maxWidth, fakeText) {
  var originalLine = lines.shift(),
      fitLine = originalLine;
  var textBBox;

  for (;;) {
    textBBox = getTextBBox(fitLine, fakeText);
    textBBox.width = fitLine ? textBBox.width : 0; // try to fit

    if (fitLine === ' ' || fitLine === '' || textBBox.width < Math.round(maxWidth) || fitLine.length < 2) {
      return fit(lines, fitLine, originalLine, textBBox);
    }

    fitLine = shortenLine(fitLine, textBBox.width, maxWidth);
  }
}

function fit(lines, fitLine, originalLine, textBBox) {
  if (fitLine.length < originalLine.length) {
    var remainder = originalLine.slice(fitLine.length).trim();
    lines.unshift(remainder);
  }

  return {
    width: textBBox.width,
    height: textBBox.height,
    text: fitLine
  };
}
/**
 * Shortens a line based on spacing and hyphens.
 * Returns the shortened result on success.
 *
 * @param  {string} line
 * @param  {number} maxLength the maximum characters of the string
 * @return {string} the shortened string
 */


function semanticShorten(line, maxLength) {
  var parts = line.split(/(\s|-)/g),
      part,
      shortenedParts = [],
      length = 0; // try to shorten via spaces + hyphens

  if (parts.length > 1) {
    while (part = parts.shift()) {
      if (part.length + length < maxLength) {
        shortenedParts.push(part);
        length += part.length;
      } else {
        // remove previous part, too if hyphen does not fit anymore
        if (part === '-') {
          shortenedParts.pop();
        }

        break;
      }
    }
  }

  return shortenedParts.join('');
}

function shortenLine(line, width, maxWidth) {
  var length = Math.max(line.length * (maxWidth / width), 1); // try to shorten semantically (i.e. based on spaces and hyphens)

  var shortenedLine = semanticShorten(line, length);

  if (!shortenedLine) {
    // force shorten by cutting the long word
    shortenedLine = line.slice(0, Math.max(Math.round(length - 1), 1));
  }

  return shortenedLine;
}

function getHelperSvg() {
  var helperSvg = document.getElementById('helper-svg');

  if (!helperSvg) {
    helperSvg = (0, _tinySvg.create)('svg');
    (0, _tinySvg.attr)(helperSvg, {
      id: 'helper-svg',
      width: 0,
      height: 0,
      style: 'visibility: hidden; position: fixed'
    });
    document.body.appendChild(helperSvg);
  }

  return helperSvg;
}
/**
 * Creates a new label utility
 *
 * @param {Object} config
 * @param {Dimensions} config.size
 * @param {number} config.padding
 * @param {Object} config.style
 * @param {string} config.align
 */


function Text(config) {
  this._config = (0, _minDash.assign)({}, {
    size: DEFAULT_LABEL_SIZE,
    padding: DEFAULT_BOX_PADDING,
    style: {},
    align: 'center-top'
  }, config || {});
}
/**
 * Returns the layouted text as an SVG element.
 *
 * @param {string} text
 * @param {Object} options
 *
 * @return {SVGElement}
 */


Text.prototype.createText = function (text, options) {
  return this.layoutText(text, options).element;
};
/**
 * Returns a labels layouted dimensions.
 *
 * @param {string} text to layout
 * @param {Object} options
 *
 * @return {Dimensions}
 */


Text.prototype.getDimensions = function (text, options) {
  return this.layoutText(text, options).dimensions;
};
/**
 * Creates and returns a label and its bounding box.
 *
 * @method Text#createText
 *
 * @param {string} text the text to render on the label
 * @param {Object} options
 * @param {string} options.align how to align in the bounding box.
 *                               Any of { 'center-middle', 'center-top' },
 *                               defaults to 'center-top'.
 * @param {string} options.style style to be applied to the text
 * @param {boolean} options.fitBox indicates if box will be recalculated to
 *                                 fit text
 *
 * @return {Object} { element, dimensions }
 */


Text.prototype.layoutText = function (text, options) {
  var box = (0, _minDash.assign)({}, this._config.size, options.box),
      style = (0, _minDash.assign)({}, this._config.style, options.style),
      align = parseAlign(options.align || this._config.align),
      padding = parsePadding(options.padding !== undefined ? options.padding : this._config.padding),
      fitBox = options.fitBox || false;
  var lineHeight = getLineHeight(style);
  var lines = text.split(/\r?\n/g),
      layouted = [];
  var maxWidth = box.width - padding.left - padding.right; // ensure correct rendering by attaching helper text node to invisible SVG

  var helperText = (0, _tinySvg.create)('text');
  (0, _tinySvg.attr)(helperText, {
    x: 0,
    y: 0
  });
  (0, _tinySvg.attr)(helperText, style);
  var helperSvg = getHelperSvg();
  (0, _tinySvg.append)(helperSvg, helperText);

  while (lines.length) {
    layouted.push(layoutNext(lines, maxWidth, helperText));
  }

  if (align.vertical === 'middle') {
    padding.top = padding.bottom = 0;
  }

  var totalHeight = (0, _minDash.reduce)(layouted, function (sum, line, idx) {
    return sum + (lineHeight || line.height);
  }, 0) + padding.top + padding.bottom;
  var maxLineWidth = (0, _minDash.reduce)(layouted, function (sum, line, idx) {
    return line.width > sum ? line.width : sum;
  }, 0); // the y position of the next line

  var y = padding.top;

  if (align.vertical === 'middle') {
    y += (box.height - totalHeight) / 2;
  } // magic number initial offset


  y -= (lineHeight || layouted[0].height) / 4;
  var textElement = (0, _tinySvg.create)('text');
  (0, _tinySvg.attr)(textElement, style); // layout each line taking into account that parent
  // shape might resize to fit text size

  (0, _minDash.forEach)(layouted, function (line) {
    var x;
    y += lineHeight || line.height;

    switch (align.horizontal) {
      case 'left':
        x = padding.left;
        break;

      case 'right':
        x = (fitBox ? maxLineWidth : maxWidth) - padding.right - line.width;
        break;

      default:
        // aka center
        x = Math.max(((fitBox ? maxLineWidth : maxWidth) - line.width) / 2 + padding.left, 0);
    }

    var tspan = (0, _tinySvg.create)('tspan');
    (0, _tinySvg.attr)(tspan, {
      x: x,
      y: y
    });
    tspan.textContent = line.text;
    (0, _tinySvg.append)(textElement, tspan);
  });
  (0, _tinySvg.remove)(helperText);
  var dimensions = {
    width: maxLineWidth,
    height: totalHeight
  };
  return {
    dimensions: dimensions,
    element: textElement
  };
};

function getLineHeight(style) {
  if ('fontSize' in style && 'lineHeight' in style) {
    return style.lineHeight * parseInt(style.fontSize, 10);
  }
}

},{"min-dash":555,"tiny-svg":567}],330:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _minDash = require("min-dash");

var _moddle = require("moddle");

var _moddleXml = require("moddle-xml");

/**
 * A sub class of {@link Moddle} with support for import and export of BPMN 2.0 xml files.
 *
 * @class BpmnModdle
 * @extends Moddle
 *
 * @param {Object|Array} packages to use for instantiating the model
 * @param {Object} [options] additional options to pass over
 */
function BpmnModdle(packages, options) {
  _moddle.Moddle.call(this, packages, options);
}

BpmnModdle.prototype = Object.create(_moddle.Moddle.prototype);
/**
 * The fromXML result.
 *
 * @typedef {Object} ParseResult
 *
 * @property {ModdleElement} rootElement
 * @property {Array<Object>} references
 * @property {Array<Error>} warnings
 * @property {Object} elementsById - a mapping containing each ID -> ModdleElement
 */

/**
 * The fromXML error.
 *
 * @typedef {Error} ParseError
 *
 * @property {Array<Error>} warnings
 */

/**
 * Instantiates a BPMN model tree from a given xml string.
 *
 * @param {String}   xmlStr
 * @param {String}   [typeName='bpmn:Definitions'] name of the root element
 * @param {Object}   [options]  options to pass to the underlying reader
 *
 * @returns {Promise<ParseResult, ParseError>}
 */

BpmnModdle.prototype.fromXML = function (xmlStr, typeName, options) {
  if (!(0, _minDash.isString)(typeName)) {
    options = typeName;
    typeName = 'bpmn:Definitions';
  }

  var reader = new _moddleXml.Reader((0, _minDash.assign)({
    model: this,
    lax: true
  }, options));
  var rootHandler = reader.handler(typeName);
  return reader.fromXML(xmlStr, rootHandler);
};
/**
 * The toXML result.
 *
 * @typedef {Object} SerializationResult
 *
 * @property {String} xml
 */

/**
 * Serializes a BPMN 2.0 object tree to XML.
 *
 * @param {String}   element    the root element, typically an instance of `bpmn:Definitions`
 * @param {Object}   [options]  to pass to the underlying writer
 *
 * @returns {Promise<SerializationResult, Error>}
 */


BpmnModdle.prototype.toXML = function (element, options) {
  var writer = new _moddleXml.Writer(options);
  return new Promise(function (resolve, reject) {
    try {
      var result = writer.toXML(element);
      return resolve({
        xml: result
      });
    } catch (err) {
      return reject(err);
    }
  });
};

var name = "BPMN20";
var uri = "http://www.omg.org/spec/BPMN/20100524/MODEL";
var prefix = "bpmn";
var associations = [];
var types = [{
  name: "Interface",
  superClass: ["RootElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "operations",
    type: "Operation",
    isMany: true
  }, {
    name: "implementationRef",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "Operation",
  superClass: ["BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "inMessageRef",
    type: "Message",
    isReference: true
  }, {
    name: "outMessageRef",
    type: "Message",
    isReference: true
  }, {
    name: "errorRef",
    type: "Error",
    isMany: true,
    isReference: true
  }, {
    name: "implementationRef",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "EndPoint",
  superClass: ["RootElement"]
}, {
  name: "Auditing",
  superClass: ["BaseElement"]
}, {
  name: "GlobalTask",
  superClass: ["CallableElement"],
  properties: [{
    name: "resources",
    type: "ResourceRole",
    isMany: true
  }]
}, {
  name: "Monitoring",
  superClass: ["BaseElement"]
}, {
  name: "Performer",
  superClass: ["ResourceRole"]
}, {
  name: "Process",
  superClass: ["FlowElementsContainer", "CallableElement"],
  properties: [{
    name: "processType",
    type: "ProcessType",
    isAttr: true
  }, {
    name: "isClosed",
    isAttr: true,
    type: "Boolean"
  }, {
    name: "auditing",
    type: "Auditing"
  }, {
    name: "monitoring",
    type: "Monitoring"
  }, {
    name: "properties",
    type: "Property",
    isMany: true
  }, {
    name: "laneSets",
    isMany: true,
    replaces: "FlowElementsContainer#laneSets",
    type: "LaneSet"
  }, {
    name: "flowElements",
    isMany: true,
    replaces: "FlowElementsContainer#flowElements",
    type: "FlowElement"
  }, {
    name: "artifacts",
    type: "Artifact",
    isMany: true
  }, {
    name: "resources",
    type: "ResourceRole",
    isMany: true
  }, {
    name: "correlationSubscriptions",
    type: "CorrelationSubscription",
    isMany: true
  }, {
    name: "supports",
    type: "Process",
    isMany: true,
    isReference: true
  }, {
    name: "definitionalCollaborationRef",
    type: "Collaboration",
    isAttr: true,
    isReference: true
  }, {
    name: "isExecutable",
    isAttr: true,
    type: "Boolean"
  }]
}, {
  name: "LaneSet",
  superClass: ["BaseElement"],
  properties: [{
    name: "lanes",
    type: "Lane",
    isMany: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "Lane",
  superClass: ["BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "partitionElementRef",
    type: "BaseElement",
    isAttr: true,
    isReference: true
  }, {
    name: "partitionElement",
    type: "BaseElement"
  }, {
    name: "flowNodeRef",
    type: "FlowNode",
    isMany: true,
    isReference: true
  }, {
    name: "childLaneSet",
    type: "LaneSet",
    xml: {
      serialize: "xsi:type"
    }
  }]
}, {
  name: "GlobalManualTask",
  superClass: ["GlobalTask"]
}, {
  name: "ManualTask",
  superClass: ["Task"]
}, {
  name: "UserTask",
  superClass: ["Task"],
  properties: [{
    name: "renderings",
    type: "Rendering",
    isMany: true
  }, {
    name: "implementation",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "Rendering",
  superClass: ["BaseElement"]
}, {
  name: "HumanPerformer",
  superClass: ["Performer"]
}, {
  name: "PotentialOwner",
  superClass: ["HumanPerformer"]
}, {
  name: "GlobalUserTask",
  superClass: ["GlobalTask"],
  properties: [{
    name: "implementation",
    isAttr: true,
    type: "String"
  }, {
    name: "renderings",
    type: "Rendering",
    isMany: true
  }]
}, {
  name: "Gateway",
  isAbstract: true,
  superClass: ["FlowNode"],
  properties: [{
    name: "gatewayDirection",
    type: "GatewayDirection",
    "default": "Unspecified",
    isAttr: true
  }]
}, {
  name: "EventBasedGateway",
  superClass: ["Gateway"],
  properties: [{
    name: "instantiate",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "eventGatewayType",
    type: "EventBasedGatewayType",
    isAttr: true,
    "default": "Exclusive"
  }]
}, {
  name: "ComplexGateway",
  superClass: ["Gateway"],
  properties: [{
    name: "activationCondition",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "default",
    type: "SequenceFlow",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ExclusiveGateway",
  superClass: ["Gateway"],
  properties: [{
    name: "default",
    type: "SequenceFlow",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "InclusiveGateway",
  superClass: ["Gateway"],
  properties: [{
    name: "default",
    type: "SequenceFlow",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ParallelGateway",
  superClass: ["Gateway"]
}, {
  name: "RootElement",
  isAbstract: true,
  superClass: ["BaseElement"]
}, {
  name: "Relationship",
  superClass: ["BaseElement"],
  properties: [{
    name: "type",
    isAttr: true,
    type: "String"
  }, {
    name: "direction",
    type: "RelationshipDirection",
    isAttr: true
  }, {
    name: "source",
    isMany: true,
    isReference: true,
    type: "Element"
  }, {
    name: "target",
    isMany: true,
    isReference: true,
    type: "Element"
  }]
}, {
  name: "BaseElement",
  isAbstract: true,
  properties: [{
    name: "id",
    isAttr: true,
    type: "String",
    isId: true
  }, {
    name: "documentation",
    type: "Documentation",
    isMany: true
  }, {
    name: "extensionDefinitions",
    type: "ExtensionDefinition",
    isMany: true,
    isReference: true
  }, {
    name: "extensionElements",
    type: "ExtensionElements"
  }]
}, {
  name: "Extension",
  properties: [{
    name: "mustUnderstand",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "definition",
    type: "ExtensionDefinition",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ExtensionDefinition",
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "extensionAttributeDefinitions",
    type: "ExtensionAttributeDefinition",
    isMany: true
  }]
}, {
  name: "ExtensionAttributeDefinition",
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "type",
    isAttr: true,
    type: "String"
  }, {
    name: "isReference",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "extensionDefinition",
    type: "ExtensionDefinition",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ExtensionElements",
  properties: [{
    name: "valueRef",
    isAttr: true,
    isReference: true,
    type: "Element"
  }, {
    name: "values",
    type: "Element",
    isMany: true
  }, {
    name: "extensionAttributeDefinition",
    type: "ExtensionAttributeDefinition",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "Documentation",
  superClass: ["BaseElement"],
  properties: [{
    name: "text",
    type: "String",
    isBody: true
  }, {
    name: "textFormat",
    "default": "text/plain",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "Event",
  isAbstract: true,
  superClass: ["FlowNode", "InteractionNode"],
  properties: [{
    name: "properties",
    type: "Property",
    isMany: true
  }]
}, {
  name: "IntermediateCatchEvent",
  superClass: ["CatchEvent"]
}, {
  name: "IntermediateThrowEvent",
  superClass: ["ThrowEvent"]
}, {
  name: "EndEvent",
  superClass: ["ThrowEvent"]
}, {
  name: "StartEvent",
  superClass: ["CatchEvent"],
  properties: [{
    name: "isInterrupting",
    "default": true,
    isAttr: true,
    type: "Boolean"
  }]
}, {
  name: "ThrowEvent",
  isAbstract: true,
  superClass: ["Event"],
  properties: [{
    name: "dataInputs",
    type: "DataInput",
    isMany: true
  }, {
    name: "dataInputAssociations",
    type: "DataInputAssociation",
    isMany: true
  }, {
    name: "inputSet",
    type: "InputSet"
  }, {
    name: "eventDefinitions",
    type: "EventDefinition",
    isMany: true
  }, {
    name: "eventDefinitionRef",
    type: "EventDefinition",
    isMany: true,
    isReference: true
  }]
}, {
  name: "CatchEvent",
  isAbstract: true,
  superClass: ["Event"],
  properties: [{
    name: "parallelMultiple",
    isAttr: true,
    type: "Boolean",
    "default": false
  }, {
    name: "dataOutputs",
    type: "DataOutput",
    isMany: true
  }, {
    name: "dataOutputAssociations",
    type: "DataOutputAssociation",
    isMany: true
  }, {
    name: "outputSet",
    type: "OutputSet"
  }, {
    name: "eventDefinitions",
    type: "EventDefinition",
    isMany: true
  }, {
    name: "eventDefinitionRef",
    type: "EventDefinition",
    isMany: true,
    isReference: true
  }]
}, {
  name: "BoundaryEvent",
  superClass: ["CatchEvent"],
  properties: [{
    name: "cancelActivity",
    "default": true,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "attachedToRef",
    type: "Activity",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "EventDefinition",
  isAbstract: true,
  superClass: ["RootElement"]
}, {
  name: "CancelEventDefinition",
  superClass: ["EventDefinition"]
}, {
  name: "ErrorEventDefinition",
  superClass: ["EventDefinition"],
  properties: [{
    name: "errorRef",
    type: "Error",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "TerminateEventDefinition",
  superClass: ["EventDefinition"]
}, {
  name: "EscalationEventDefinition",
  superClass: ["EventDefinition"],
  properties: [{
    name: "escalationRef",
    type: "Escalation",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "Escalation",
  properties: [{
    name: "structureRef",
    type: "ItemDefinition",
    isAttr: true,
    isReference: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "escalationCode",
    isAttr: true,
    type: "String"
  }],
  superClass: ["RootElement"]
}, {
  name: "CompensateEventDefinition",
  superClass: ["EventDefinition"],
  properties: [{
    name: "waitForCompletion",
    isAttr: true,
    type: "Boolean",
    "default": true
  }, {
    name: "activityRef",
    type: "Activity",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "TimerEventDefinition",
  superClass: ["EventDefinition"],
  properties: [{
    name: "timeDate",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "timeCycle",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "timeDuration",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }]
}, {
  name: "LinkEventDefinition",
  superClass: ["EventDefinition"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "target",
    type: "LinkEventDefinition",
    isAttr: true,
    isReference: true
  }, {
    name: "source",
    type: "LinkEventDefinition",
    isMany: true,
    isReference: true
  }]
}, {
  name: "MessageEventDefinition",
  superClass: ["EventDefinition"],
  properties: [{
    name: "messageRef",
    type: "Message",
    isAttr: true,
    isReference: true
  }, {
    name: "operationRef",
    type: "Operation",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ConditionalEventDefinition",
  superClass: ["EventDefinition"],
  properties: [{
    name: "condition",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }]
}, {
  name: "SignalEventDefinition",
  superClass: ["EventDefinition"],
  properties: [{
    name: "signalRef",
    type: "Signal",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "Signal",
  superClass: ["RootElement"],
  properties: [{
    name: "structureRef",
    type: "ItemDefinition",
    isAttr: true,
    isReference: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "ImplicitThrowEvent",
  superClass: ["ThrowEvent"]
}, {
  name: "DataState",
  superClass: ["BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "ItemAwareElement",
  superClass: ["BaseElement"],
  properties: [{
    name: "itemSubjectRef",
    type: "ItemDefinition",
    isAttr: true,
    isReference: true
  }, {
    name: "dataState",
    type: "DataState"
  }]
}, {
  name: "DataAssociation",
  superClass: ["BaseElement"],
  properties: [{
    name: "sourceRef",
    type: "ItemAwareElement",
    isMany: true,
    isReference: true
  }, {
    name: "targetRef",
    type: "ItemAwareElement",
    isReference: true
  }, {
    name: "transformation",
    type: "FormalExpression",
    xml: {
      serialize: "property"
    }
  }, {
    name: "assignment",
    type: "Assignment",
    isMany: true
  }]
}, {
  name: "DataInput",
  superClass: ["ItemAwareElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "isCollection",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "inputSetRef",
    type: "InputSet",
    isMany: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "inputSetWithOptional",
    type: "InputSet",
    isMany: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "inputSetWithWhileExecuting",
    type: "InputSet",
    isMany: true,
    isVirtual: true,
    isReference: true
  }]
}, {
  name: "DataOutput",
  superClass: ["ItemAwareElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "isCollection",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "outputSetRef",
    type: "OutputSet",
    isMany: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "outputSetWithOptional",
    type: "OutputSet",
    isMany: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "outputSetWithWhileExecuting",
    type: "OutputSet",
    isMany: true,
    isVirtual: true,
    isReference: true
  }]
}, {
  name: "InputSet",
  superClass: ["BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "dataInputRefs",
    type: "DataInput",
    isMany: true,
    isReference: true
  }, {
    name: "optionalInputRefs",
    type: "DataInput",
    isMany: true,
    isReference: true
  }, {
    name: "whileExecutingInputRefs",
    type: "DataInput",
    isMany: true,
    isReference: true
  }, {
    name: "outputSetRefs",
    type: "OutputSet",
    isMany: true,
    isReference: true
  }]
}, {
  name: "OutputSet",
  superClass: ["BaseElement"],
  properties: [{
    name: "dataOutputRefs",
    type: "DataOutput",
    isMany: true,
    isReference: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "inputSetRefs",
    type: "InputSet",
    isMany: true,
    isReference: true
  }, {
    name: "optionalOutputRefs",
    type: "DataOutput",
    isMany: true,
    isReference: true
  }, {
    name: "whileExecutingOutputRefs",
    type: "DataOutput",
    isMany: true,
    isReference: true
  }]
}, {
  name: "Property",
  superClass: ["ItemAwareElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "DataInputAssociation",
  superClass: ["DataAssociation"]
}, {
  name: "DataOutputAssociation",
  superClass: ["DataAssociation"]
}, {
  name: "InputOutputSpecification",
  superClass: ["BaseElement"],
  properties: [{
    name: "dataInputs",
    type: "DataInput",
    isMany: true
  }, {
    name: "dataOutputs",
    type: "DataOutput",
    isMany: true
  }, {
    name: "inputSets",
    type: "InputSet",
    isMany: true
  }, {
    name: "outputSets",
    type: "OutputSet",
    isMany: true
  }]
}, {
  name: "DataObject",
  superClass: ["FlowElement", "ItemAwareElement"],
  properties: [{
    name: "isCollection",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }]
}, {
  name: "InputOutputBinding",
  properties: [{
    name: "inputDataRef",
    type: "InputSet",
    isAttr: true,
    isReference: true
  }, {
    name: "outputDataRef",
    type: "OutputSet",
    isAttr: true,
    isReference: true
  }, {
    name: "operationRef",
    type: "Operation",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "Assignment",
  superClass: ["BaseElement"],
  properties: [{
    name: "from",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "to",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }]
}, {
  name: "DataStore",
  superClass: ["RootElement", "ItemAwareElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "capacity",
    isAttr: true,
    type: "Integer"
  }, {
    name: "isUnlimited",
    "default": true,
    isAttr: true,
    type: "Boolean"
  }]
}, {
  name: "DataStoreReference",
  superClass: ["ItemAwareElement", "FlowElement"],
  properties: [{
    name: "dataStoreRef",
    type: "DataStore",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "DataObjectReference",
  superClass: ["ItemAwareElement", "FlowElement"],
  properties: [{
    name: "dataObjectRef",
    type: "DataObject",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ConversationLink",
  superClass: ["BaseElement"],
  properties: [{
    name: "sourceRef",
    type: "InteractionNode",
    isAttr: true,
    isReference: true
  }, {
    name: "targetRef",
    type: "InteractionNode",
    isAttr: true,
    isReference: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "ConversationAssociation",
  superClass: ["BaseElement"],
  properties: [{
    name: "innerConversationNodeRef",
    type: "ConversationNode",
    isAttr: true,
    isReference: true
  }, {
    name: "outerConversationNodeRef",
    type: "ConversationNode",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "CallConversation",
  superClass: ["ConversationNode"],
  properties: [{
    name: "calledCollaborationRef",
    type: "Collaboration",
    isAttr: true,
    isReference: true
  }, {
    name: "participantAssociations",
    type: "ParticipantAssociation",
    isMany: true
  }]
}, {
  name: "Conversation",
  superClass: ["ConversationNode"]
}, {
  name: "SubConversation",
  superClass: ["ConversationNode"],
  properties: [{
    name: "conversationNodes",
    type: "ConversationNode",
    isMany: true
  }]
}, {
  name: "ConversationNode",
  isAbstract: true,
  superClass: ["InteractionNode", "BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "participantRef",
    type: "Participant",
    isMany: true,
    isReference: true
  }, {
    name: "messageFlowRefs",
    type: "MessageFlow",
    isMany: true,
    isReference: true
  }, {
    name: "correlationKeys",
    type: "CorrelationKey",
    isMany: true
  }]
}, {
  name: "GlobalConversation",
  superClass: ["Collaboration"]
}, {
  name: "PartnerEntity",
  superClass: ["RootElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "participantRef",
    type: "Participant",
    isMany: true,
    isReference: true
  }]
}, {
  name: "PartnerRole",
  superClass: ["RootElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "participantRef",
    type: "Participant",
    isMany: true,
    isReference: true
  }]
}, {
  name: "CorrelationProperty",
  superClass: ["RootElement"],
  properties: [{
    name: "correlationPropertyRetrievalExpression",
    type: "CorrelationPropertyRetrievalExpression",
    isMany: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "type",
    type: "ItemDefinition",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "Error",
  superClass: ["RootElement"],
  properties: [{
    name: "structureRef",
    type: "ItemDefinition",
    isAttr: true,
    isReference: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "errorCode",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "CorrelationKey",
  superClass: ["BaseElement"],
  properties: [{
    name: "correlationPropertyRef",
    type: "CorrelationProperty",
    isMany: true,
    isReference: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "Expression",
  superClass: ["BaseElement"],
  isAbstract: false,
  properties: [{
    name: "body",
    isBody: true,
    type: "String"
  }]
}, {
  name: "FormalExpression",
  superClass: ["Expression"],
  properties: [{
    name: "language",
    isAttr: true,
    type: "String"
  }, {
    name: "evaluatesToTypeRef",
    type: "ItemDefinition",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "Message",
  superClass: ["RootElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "itemRef",
    type: "ItemDefinition",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ItemDefinition",
  superClass: ["RootElement"],
  properties: [{
    name: "itemKind",
    type: "ItemKind",
    isAttr: true
  }, {
    name: "structureRef",
    isAttr: true,
    type: "String"
  }, {
    name: "isCollection",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "import",
    type: "Import",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "FlowElement",
  isAbstract: true,
  superClass: ["BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "auditing",
    type: "Auditing"
  }, {
    name: "monitoring",
    type: "Monitoring"
  }, {
    name: "categoryValueRef",
    type: "CategoryValue",
    isMany: true,
    isReference: true
  }]
}, {
  name: "SequenceFlow",
  superClass: ["FlowElement"],
  properties: [{
    name: "isImmediate",
    isAttr: true,
    type: "Boolean"
  }, {
    name: "conditionExpression",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "sourceRef",
    type: "FlowNode",
    isAttr: true,
    isReference: true
  }, {
    name: "targetRef",
    type: "FlowNode",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "FlowElementsContainer",
  isAbstract: true,
  superClass: ["BaseElement"],
  properties: [{
    name: "laneSets",
    type: "LaneSet",
    isMany: true
  }, {
    name: "flowElements",
    type: "FlowElement",
    isMany: true
  }]
}, {
  name: "CallableElement",
  isAbstract: true,
  superClass: ["RootElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "ioSpecification",
    type: "InputOutputSpecification",
    xml: {
      serialize: "property"
    }
  }, {
    name: "supportedInterfaceRef",
    type: "Interface",
    isMany: true,
    isReference: true
  }, {
    name: "ioBinding",
    type: "InputOutputBinding",
    isMany: true,
    xml: {
      serialize: "property"
    }
  }]
}, {
  name: "FlowNode",
  isAbstract: true,
  superClass: ["FlowElement"],
  properties: [{
    name: "incoming",
    type: "SequenceFlow",
    isMany: true,
    isReference: true
  }, {
    name: "outgoing",
    type: "SequenceFlow",
    isMany: true,
    isReference: true
  }, {
    name: "lanes",
    type: "Lane",
    isMany: true,
    isVirtual: true,
    isReference: true
  }]
}, {
  name: "CorrelationPropertyRetrievalExpression",
  superClass: ["BaseElement"],
  properties: [{
    name: "messagePath",
    type: "FormalExpression"
  }, {
    name: "messageRef",
    type: "Message",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "CorrelationPropertyBinding",
  superClass: ["BaseElement"],
  properties: [{
    name: "dataPath",
    type: "FormalExpression"
  }, {
    name: "correlationPropertyRef",
    type: "CorrelationProperty",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "Resource",
  superClass: ["RootElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "resourceParameters",
    type: "ResourceParameter",
    isMany: true
  }]
}, {
  name: "ResourceParameter",
  superClass: ["BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "isRequired",
    isAttr: true,
    type: "Boolean"
  }, {
    name: "type",
    type: "ItemDefinition",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "CorrelationSubscription",
  superClass: ["BaseElement"],
  properties: [{
    name: "correlationKeyRef",
    type: "CorrelationKey",
    isAttr: true,
    isReference: true
  }, {
    name: "correlationPropertyBinding",
    type: "CorrelationPropertyBinding",
    isMany: true
  }]
}, {
  name: "MessageFlow",
  superClass: ["BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "sourceRef",
    type: "InteractionNode",
    isAttr: true,
    isReference: true
  }, {
    name: "targetRef",
    type: "InteractionNode",
    isAttr: true,
    isReference: true
  }, {
    name: "messageRef",
    type: "Message",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "MessageFlowAssociation",
  superClass: ["BaseElement"],
  properties: [{
    name: "innerMessageFlowRef",
    type: "MessageFlow",
    isAttr: true,
    isReference: true
  }, {
    name: "outerMessageFlowRef",
    type: "MessageFlow",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "InteractionNode",
  isAbstract: true,
  properties: [{
    name: "incomingConversationLinks",
    type: "ConversationLink",
    isMany: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "outgoingConversationLinks",
    type: "ConversationLink",
    isMany: true,
    isVirtual: true,
    isReference: true
  }]
}, {
  name: "Participant",
  superClass: ["InteractionNode", "BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "interfaceRef",
    type: "Interface",
    isMany: true,
    isReference: true
  }, {
    name: "participantMultiplicity",
    type: "ParticipantMultiplicity"
  }, {
    name: "endPointRefs",
    type: "EndPoint",
    isMany: true,
    isReference: true
  }, {
    name: "processRef",
    type: "Process",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ParticipantAssociation",
  superClass: ["BaseElement"],
  properties: [{
    name: "innerParticipantRef",
    type: "Participant",
    isAttr: true,
    isReference: true
  }, {
    name: "outerParticipantRef",
    type: "Participant",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ParticipantMultiplicity",
  properties: [{
    name: "minimum",
    "default": 0,
    isAttr: true,
    type: "Integer"
  }, {
    name: "maximum",
    "default": 1,
    isAttr: true,
    type: "Integer"
  }],
  superClass: ["BaseElement"]
}, {
  name: "Collaboration",
  superClass: ["RootElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "isClosed",
    isAttr: true,
    type: "Boolean"
  }, {
    name: "participants",
    type: "Participant",
    isMany: true
  }, {
    name: "messageFlows",
    type: "MessageFlow",
    isMany: true
  }, {
    name: "artifacts",
    type: "Artifact",
    isMany: true
  }, {
    name: "conversations",
    type: "ConversationNode",
    isMany: true
  }, {
    name: "conversationAssociations",
    type: "ConversationAssociation"
  }, {
    name: "participantAssociations",
    type: "ParticipantAssociation",
    isMany: true
  }, {
    name: "messageFlowAssociations",
    type: "MessageFlowAssociation",
    isMany: true
  }, {
    name: "correlationKeys",
    type: "CorrelationKey",
    isMany: true
  }, {
    name: "choreographyRef",
    type: "Choreography",
    isMany: true,
    isReference: true
  }, {
    name: "conversationLinks",
    type: "ConversationLink",
    isMany: true
  }]
}, {
  name: "ChoreographyActivity",
  isAbstract: true,
  superClass: ["FlowNode"],
  properties: [{
    name: "participantRef",
    type: "Participant",
    isMany: true,
    isReference: true
  }, {
    name: "initiatingParticipantRef",
    type: "Participant",
    isAttr: true,
    isReference: true
  }, {
    name: "correlationKeys",
    type: "CorrelationKey",
    isMany: true
  }, {
    name: "loopType",
    type: "ChoreographyLoopType",
    "default": "None",
    isAttr: true
  }]
}, {
  name: "CallChoreography",
  superClass: ["ChoreographyActivity"],
  properties: [{
    name: "calledChoreographyRef",
    type: "Choreography",
    isAttr: true,
    isReference: true
  }, {
    name: "participantAssociations",
    type: "ParticipantAssociation",
    isMany: true
  }]
}, {
  name: "SubChoreography",
  superClass: ["ChoreographyActivity", "FlowElementsContainer"],
  properties: [{
    name: "artifacts",
    type: "Artifact",
    isMany: true
  }]
}, {
  name: "ChoreographyTask",
  superClass: ["ChoreographyActivity"],
  properties: [{
    name: "messageFlowRef",
    type: "MessageFlow",
    isMany: true,
    isReference: true
  }]
}, {
  name: "Choreography",
  superClass: ["Collaboration", "FlowElementsContainer"]
}, {
  name: "GlobalChoreographyTask",
  superClass: ["Choreography"],
  properties: [{
    name: "initiatingParticipantRef",
    type: "Participant",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "TextAnnotation",
  superClass: ["Artifact"],
  properties: [{
    name: "text",
    type: "String"
  }, {
    name: "textFormat",
    "default": "text/plain",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "Group",
  superClass: ["Artifact"],
  properties: [{
    name: "categoryValueRef",
    type: "CategoryValue",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "Association",
  superClass: ["Artifact"],
  properties: [{
    name: "associationDirection",
    type: "AssociationDirection",
    isAttr: true
  }, {
    name: "sourceRef",
    type: "BaseElement",
    isAttr: true,
    isReference: true
  }, {
    name: "targetRef",
    type: "BaseElement",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "Category",
  superClass: ["RootElement"],
  properties: [{
    name: "categoryValue",
    type: "CategoryValue",
    isMany: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "Artifact",
  isAbstract: true,
  superClass: ["BaseElement"]
}, {
  name: "CategoryValue",
  superClass: ["BaseElement"],
  properties: [{
    name: "categorizedFlowElements",
    type: "FlowElement",
    isMany: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "value",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "Activity",
  isAbstract: true,
  superClass: ["FlowNode"],
  properties: [{
    name: "isForCompensation",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "default",
    type: "SequenceFlow",
    isAttr: true,
    isReference: true
  }, {
    name: "ioSpecification",
    type: "InputOutputSpecification",
    xml: {
      serialize: "property"
    }
  }, {
    name: "boundaryEventRefs",
    type: "BoundaryEvent",
    isMany: true,
    isReference: true
  }, {
    name: "properties",
    type: "Property",
    isMany: true
  }, {
    name: "dataInputAssociations",
    type: "DataInputAssociation",
    isMany: true
  }, {
    name: "dataOutputAssociations",
    type: "DataOutputAssociation",
    isMany: true
  }, {
    name: "startQuantity",
    "default": 1,
    isAttr: true,
    type: "Integer"
  }, {
    name: "resources",
    type: "ResourceRole",
    isMany: true
  }, {
    name: "completionQuantity",
    "default": 1,
    isAttr: true,
    type: "Integer"
  }, {
    name: "loopCharacteristics",
    type: "LoopCharacteristics"
  }]
}, {
  name: "ServiceTask",
  superClass: ["Task"],
  properties: [{
    name: "implementation",
    isAttr: true,
    type: "String"
  }, {
    name: "operationRef",
    type: "Operation",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "SubProcess",
  superClass: ["Activity", "FlowElementsContainer", "InteractionNode"],
  properties: [{
    name: "triggeredByEvent",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "artifacts",
    type: "Artifact",
    isMany: true
  }]
}, {
  name: "LoopCharacteristics",
  isAbstract: true,
  superClass: ["BaseElement"]
}, {
  name: "MultiInstanceLoopCharacteristics",
  superClass: ["LoopCharacteristics"],
  properties: [{
    name: "isSequential",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "behavior",
    type: "MultiInstanceBehavior",
    "default": "All",
    isAttr: true
  }, {
    name: "loopCardinality",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "loopDataInputRef",
    type: "ItemAwareElement",
    isReference: true
  }, {
    name: "loopDataOutputRef",
    type: "ItemAwareElement",
    isReference: true
  }, {
    name: "inputDataItem",
    type: "DataInput",
    xml: {
      serialize: "property"
    }
  }, {
    name: "outputDataItem",
    type: "DataOutput",
    xml: {
      serialize: "property"
    }
  }, {
    name: "complexBehaviorDefinition",
    type: "ComplexBehaviorDefinition",
    isMany: true
  }, {
    name: "completionCondition",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "oneBehaviorEventRef",
    type: "EventDefinition",
    isAttr: true,
    isReference: true
  }, {
    name: "noneBehaviorEventRef",
    type: "EventDefinition",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "StandardLoopCharacteristics",
  superClass: ["LoopCharacteristics"],
  properties: [{
    name: "testBefore",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "loopCondition",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "loopMaximum",
    type: "Integer",
    isAttr: true
  }]
}, {
  name: "CallActivity",
  superClass: ["Activity"],
  properties: [{
    name: "calledElement",
    type: "String",
    isAttr: true
  }]
}, {
  name: "Task",
  superClass: ["Activity", "InteractionNode"]
}, {
  name: "SendTask",
  superClass: ["Task"],
  properties: [{
    name: "implementation",
    isAttr: true,
    type: "String"
  }, {
    name: "operationRef",
    type: "Operation",
    isAttr: true,
    isReference: true
  }, {
    name: "messageRef",
    type: "Message",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ReceiveTask",
  superClass: ["Task"],
  properties: [{
    name: "implementation",
    isAttr: true,
    type: "String"
  }, {
    name: "instantiate",
    "default": false,
    isAttr: true,
    type: "Boolean"
  }, {
    name: "operationRef",
    type: "Operation",
    isAttr: true,
    isReference: true
  }, {
    name: "messageRef",
    type: "Message",
    isAttr: true,
    isReference: true
  }]
}, {
  name: "ScriptTask",
  superClass: ["Task"],
  properties: [{
    name: "scriptFormat",
    isAttr: true,
    type: "String"
  }, {
    name: "script",
    type: "String"
  }]
}, {
  name: "BusinessRuleTask",
  superClass: ["Task"],
  properties: [{
    name: "implementation",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "AdHocSubProcess",
  superClass: ["SubProcess"],
  properties: [{
    name: "completionCondition",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "ordering",
    type: "AdHocOrdering",
    isAttr: true
  }, {
    name: "cancelRemainingInstances",
    "default": true,
    isAttr: true,
    type: "Boolean"
  }]
}, {
  name: "Transaction",
  superClass: ["SubProcess"],
  properties: [{
    name: "protocol",
    isAttr: true,
    type: "String"
  }, {
    name: "method",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "GlobalScriptTask",
  superClass: ["GlobalTask"],
  properties: [{
    name: "scriptLanguage",
    isAttr: true,
    type: "String"
  }, {
    name: "script",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "GlobalBusinessRuleTask",
  superClass: ["GlobalTask"],
  properties: [{
    name: "implementation",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "ComplexBehaviorDefinition",
  superClass: ["BaseElement"],
  properties: [{
    name: "condition",
    type: "FormalExpression"
  }, {
    name: "event",
    type: "ImplicitThrowEvent"
  }]
}, {
  name: "ResourceRole",
  superClass: ["BaseElement"],
  properties: [{
    name: "resourceRef",
    type: "Resource",
    isReference: true
  }, {
    name: "resourceParameterBindings",
    type: "ResourceParameterBinding",
    isMany: true
  }, {
    name: "resourceAssignmentExpression",
    type: "ResourceAssignmentExpression"
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "ResourceParameterBinding",
  properties: [{
    name: "expression",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }, {
    name: "parameterRef",
    type: "ResourceParameter",
    isAttr: true,
    isReference: true
  }],
  superClass: ["BaseElement"]
}, {
  name: "ResourceAssignmentExpression",
  properties: [{
    name: "expression",
    type: "Expression",
    xml: {
      serialize: "xsi:type"
    }
  }],
  superClass: ["BaseElement"]
}, {
  name: "Import",
  properties: [{
    name: "importType",
    isAttr: true,
    type: "String"
  }, {
    name: "location",
    isAttr: true,
    type: "String"
  }, {
    name: "namespace",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "Definitions",
  superClass: ["BaseElement"],
  properties: [{
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "targetNamespace",
    isAttr: true,
    type: "String"
  }, {
    name: "expressionLanguage",
    "default": "http://www.w3.org/1999/XPath",
    isAttr: true,
    type: "String"
  }, {
    name: "typeLanguage",
    "default": "http://www.w3.org/2001/XMLSchema",
    isAttr: true,
    type: "String"
  }, {
    name: "imports",
    type: "Import",
    isMany: true
  }, {
    name: "extensions",
    type: "Extension",
    isMany: true
  }, {
    name: "rootElements",
    type: "RootElement",
    isMany: true
  }, {
    name: "diagrams",
    isMany: true,
    type: "bpmndi:BPMNDiagram"
  }, {
    name: "exporter",
    isAttr: true,
    type: "String"
  }, {
    name: "relationships",
    type: "Relationship",
    isMany: true
  }, {
    name: "exporterVersion",
    isAttr: true,
    type: "String"
  }]
}];
var enumerations = [{
  name: "ProcessType",
  literalValues: [{
    name: "None"
  }, {
    name: "Public"
  }, {
    name: "Private"
  }]
}, {
  name: "GatewayDirection",
  literalValues: [{
    name: "Unspecified"
  }, {
    name: "Converging"
  }, {
    name: "Diverging"
  }, {
    name: "Mixed"
  }]
}, {
  name: "EventBasedGatewayType",
  literalValues: [{
    name: "Parallel"
  }, {
    name: "Exclusive"
  }]
}, {
  name: "RelationshipDirection",
  literalValues: [{
    name: "None"
  }, {
    name: "Forward"
  }, {
    name: "Backward"
  }, {
    name: "Both"
  }]
}, {
  name: "ItemKind",
  literalValues: [{
    name: "Physical"
  }, {
    name: "Information"
  }]
}, {
  name: "ChoreographyLoopType",
  literalValues: [{
    name: "None"
  }, {
    name: "Standard"
  }, {
    name: "MultiInstanceSequential"
  }, {
    name: "MultiInstanceParallel"
  }]
}, {
  name: "AssociationDirection",
  literalValues: [{
    name: "None"
  }, {
    name: "One"
  }, {
    name: "Both"
  }]
}, {
  name: "MultiInstanceBehavior",
  literalValues: [{
    name: "None"
  }, {
    name: "One"
  }, {
    name: "All"
  }, {
    name: "Complex"
  }]
}, {
  name: "AdHocOrdering",
  literalValues: [{
    name: "Parallel"
  }, {
    name: "Sequential"
  }]
}];
var xml = {
  tagAlias: "lowerCase",
  typePrefix: "t"
};
var BpmnPackage = {
  name: name,
  uri: uri,
  prefix: prefix,
  associations: associations,
  types: types,
  enumerations: enumerations,
  xml: xml
};
var name$1 = "BPMNDI";
var uri$1 = "http://www.omg.org/spec/BPMN/20100524/DI";
var prefix$1 = "bpmndi";
var types$1 = [{
  name: "BPMNDiagram",
  properties: [{
    name: "plane",
    type: "BPMNPlane",
    redefines: "di:Diagram#rootElement"
  }, {
    name: "labelStyle",
    type: "BPMNLabelStyle",
    isMany: true
  }],
  superClass: ["di:Diagram"]
}, {
  name: "BPMNPlane",
  properties: [{
    name: "bpmnElement",
    isAttr: true,
    isReference: true,
    type: "bpmn:BaseElement",
    redefines: "di:DiagramElement#modelElement"
  }],
  superClass: ["di:Plane"]
}, {
  name: "BPMNShape",
  properties: [{
    name: "bpmnElement",
    isAttr: true,
    isReference: true,
    type: "bpmn:BaseElement",
    redefines: "di:DiagramElement#modelElement"
  }, {
    name: "isHorizontal",
    isAttr: true,
    type: "Boolean"
  }, {
    name: "isExpanded",
    isAttr: true,
    type: "Boolean"
  }, {
    name: "isMarkerVisible",
    isAttr: true,
    type: "Boolean"
  }, {
    name: "label",
    type: "BPMNLabel"
  }, {
    name: "isMessageVisible",
    isAttr: true,
    type: "Boolean"
  }, {
    name: "participantBandKind",
    type: "ParticipantBandKind",
    isAttr: true
  }, {
    name: "choreographyActivityShape",
    type: "BPMNShape",
    isAttr: true,
    isReference: true
  }],
  superClass: ["di:LabeledShape"]
}, {
  name: "BPMNEdge",
  properties: [{
    name: "label",
    type: "BPMNLabel"
  }, {
    name: "bpmnElement",
    isAttr: true,
    isReference: true,
    type: "bpmn:BaseElement",
    redefines: "di:DiagramElement#modelElement"
  }, {
    name: "sourceElement",
    isAttr: true,
    isReference: true,
    type: "di:DiagramElement",
    redefines: "di:Edge#source"
  }, {
    name: "targetElement",
    isAttr: true,
    isReference: true,
    type: "di:DiagramElement",
    redefines: "di:Edge#target"
  }, {
    name: "messageVisibleKind",
    type: "MessageVisibleKind",
    isAttr: true,
    "default": "initiating"
  }],
  superClass: ["di:LabeledEdge"]
}, {
  name: "BPMNLabel",
  properties: [{
    name: "labelStyle",
    type: "BPMNLabelStyle",
    isAttr: true,
    isReference: true,
    redefines: "di:DiagramElement#style"
  }],
  superClass: ["di:Label"]
}, {
  name: "BPMNLabelStyle",
  properties: [{
    name: "font",
    type: "dc:Font"
  }],
  superClass: ["di:Style"]
}];
var enumerations$1 = [{
  name: "ParticipantBandKind",
  literalValues: [{
    name: "top_initiating"
  }, {
    name: "middle_initiating"
  }, {
    name: "bottom_initiating"
  }, {
    name: "top_non_initiating"
  }, {
    name: "middle_non_initiating"
  }, {
    name: "bottom_non_initiating"
  }]
}, {
  name: "MessageVisibleKind",
  literalValues: [{
    name: "initiating"
  }, {
    name: "non_initiating"
  }]
}];
var associations$1 = [];
var BpmnDiPackage = {
  name: name$1,
  uri: uri$1,
  prefix: prefix$1,
  types: types$1,
  enumerations: enumerations$1,
  associations: associations$1
};
var name$2 = "DC";
var uri$2 = "http://www.omg.org/spec/DD/20100524/DC";
var prefix$2 = "dc";
var types$2 = [{
  name: "Boolean"
}, {
  name: "Integer"
}, {
  name: "Real"
}, {
  name: "String"
}, {
  name: "Font",
  properties: [{
    name: "name",
    type: "String",
    isAttr: true
  }, {
    name: "size",
    type: "Real",
    isAttr: true
  }, {
    name: "isBold",
    type: "Boolean",
    isAttr: true
  }, {
    name: "isItalic",
    type: "Boolean",
    isAttr: true
  }, {
    name: "isUnderline",
    type: "Boolean",
    isAttr: true
  }, {
    name: "isStrikeThrough",
    type: "Boolean",
    isAttr: true
  }]
}, {
  name: "Point",
  properties: [{
    name: "x",
    type: "Real",
    "default": "0",
    isAttr: true
  }, {
    name: "y",
    type: "Real",
    "default": "0",
    isAttr: true
  }]
}, {
  name: "Bounds",
  properties: [{
    name: "x",
    type: "Real",
    "default": "0",
    isAttr: true
  }, {
    name: "y",
    type: "Real",
    "default": "0",
    isAttr: true
  }, {
    name: "width",
    type: "Real",
    isAttr: true
  }, {
    name: "height",
    type: "Real",
    isAttr: true
  }]
}];
var associations$2 = [];
var DcPackage = {
  name: name$2,
  uri: uri$2,
  prefix: prefix$2,
  types: types$2,
  associations: associations$2
};
var name$3 = "DI";
var uri$3 = "http://www.omg.org/spec/DD/20100524/DI";
var prefix$3 = "di";
var types$3 = [{
  name: "DiagramElement",
  isAbstract: true,
  properties: [{
    name: "id",
    isAttr: true,
    isId: true,
    type: "String"
  }, {
    name: "extension",
    type: "Extension"
  }, {
    name: "owningDiagram",
    type: "Diagram",
    isReadOnly: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "owningElement",
    type: "DiagramElement",
    isReadOnly: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "modelElement",
    isReadOnly: true,
    isVirtual: true,
    isReference: true,
    type: "Element"
  }, {
    name: "style",
    type: "Style",
    isReadOnly: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "ownedElement",
    type: "DiagramElement",
    isReadOnly: true,
    isMany: true,
    isVirtual: true
  }]
}, {
  name: "Node",
  isAbstract: true,
  superClass: ["DiagramElement"]
}, {
  name: "Edge",
  isAbstract: true,
  superClass: ["DiagramElement"],
  properties: [{
    name: "source",
    type: "DiagramElement",
    isReadOnly: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "target",
    type: "DiagramElement",
    isReadOnly: true,
    isVirtual: true,
    isReference: true
  }, {
    name: "waypoint",
    isUnique: false,
    isMany: true,
    type: "dc:Point",
    xml: {
      serialize: "xsi:type"
    }
  }]
}, {
  name: "Diagram",
  isAbstract: true,
  properties: [{
    name: "id",
    isAttr: true,
    isId: true,
    type: "String"
  }, {
    name: "rootElement",
    type: "DiagramElement",
    isReadOnly: true,
    isVirtual: true
  }, {
    name: "name",
    isAttr: true,
    type: "String"
  }, {
    name: "documentation",
    isAttr: true,
    type: "String"
  }, {
    name: "resolution",
    isAttr: true,
    type: "Real"
  }, {
    name: "ownedStyle",
    type: "Style",
    isReadOnly: true,
    isMany: true,
    isVirtual: true
  }]
}, {
  name: "Shape",
  isAbstract: true,
  superClass: ["Node"],
  properties: [{
    name: "bounds",
    type: "dc:Bounds"
  }]
}, {
  name: "Plane",
  isAbstract: true,
  superClass: ["Node"],
  properties: [{
    name: "planeElement",
    type: "DiagramElement",
    subsettedProperty: "DiagramElement-ownedElement",
    isMany: true
  }]
}, {
  name: "LabeledEdge",
  isAbstract: true,
  superClass: ["Edge"],
  properties: [{
    name: "ownedLabel",
    type: "Label",
    isReadOnly: true,
    subsettedProperty: "DiagramElement-ownedElement",
    isMany: true,
    isVirtual: true
  }]
}, {
  name: "LabeledShape",
  isAbstract: true,
  superClass: ["Shape"],
  properties: [{
    name: "ownedLabel",
    type: "Label",
    isReadOnly: true,
    subsettedProperty: "DiagramElement-ownedElement",
    isMany: true,
    isVirtual: true
  }]
}, {
  name: "Label",
  isAbstract: true,
  superClass: ["Node"],
  properties: [{
    name: "bounds",
    type: "dc:Bounds"
  }]
}, {
  name: "Style",
  isAbstract: true,
  properties: [{
    name: "id",
    isAttr: true,
    isId: true,
    type: "String"
  }]
}, {
  name: "Extension",
  properties: [{
    name: "values",
    isMany: true,
    type: "Element"
  }]
}];
var associations$3 = [];
var xml$1 = {
  tagAlias: "lowerCase"
};
var DiPackage = {
  name: name$3,
  uri: uri$3,
  prefix: prefix$3,
  types: types$3,
  associations: associations$3,
  xml: xml$1
};
var name$4 = "bpmn.io colors for BPMN";
var uri$4 = "http://bpmn.io/schema/bpmn/biocolor/1.0";
var prefix$4 = "bioc";
var types$4 = [{
  name: "ColoredShape",
  "extends": ["bpmndi:BPMNShape"],
  properties: [{
    name: "stroke",
    isAttr: true,
    type: "String"
  }, {
    name: "fill",
    isAttr: true,
    type: "String"
  }]
}, {
  name: "ColoredEdge",
  "extends": ["bpmndi:BPMNEdge"],
  properties: [{
    name: "stroke",
    isAttr: true,
    type: "String"
  }, {
    name: "fill",
    isAttr: true,
    type: "String"
  }]
}];
var enumerations$2 = [];
var associations$4 = [];
var BiocPackage = {
  name: name$4,
  uri: uri$4,
  prefix: prefix$4,
  types: types$4,
  enumerations: enumerations$2,
  associations: associations$4
};
var packages = {
  bpmn: BpmnPackage,
  bpmndi: BpmnDiPackage,
  dc: DcPackage,
  di: DiPackage,
  bioc: BiocPackage
};

function simple(additionalPackages, options) {
  var pks = (0, _minDash.assign)({}, packages, additionalPackages);
  return new BpmnModdle(pks, options);
}

var _default = simple;
exports.default = _default;

},{"min-dash":555,"moddle":559,"moddle-xml":558}],331:[function(require,module,exports){
(function (global){(function (){
/*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */
;(function(root, factory) {
	// https://github.com/umdjs/umd/blob/master/returnExports.js
	if (typeof exports == 'object') {
		// For Node.js.
		module.exports = factory(root);
	} else if (typeof define == 'function' && define.amd) {
		// For AMD. Register as an anonymous module.
		define([], factory.bind(root, root));
	} else {
		// For browser globals (not exposing the function separately).
		factory(root);
	}
}(typeof global != 'undefined' ? global : this, function(root) {

	if (root.CSS && root.CSS.escape) {
		return root.CSS.escape;
	}

	// https://drafts.csswg.org/cssom/#serialize-an-identifier
	var cssEscape = function(value) {
		if (arguments.length == 0) {
			throw new TypeError('`CSS.escape` requires an argument.');
		}
		var string = String(value);
		var length = string.length;
		var index = -1;
		var codeUnit;
		var result = '';
		var firstCodeUnit = string.charCodeAt(0);
		while (++index < length) {
			codeUnit = string.charCodeAt(index);
			// Note: there’s no need to special-case astral symbols, surrogate
			// pairs, or lone surrogates.

			// If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
			// (U+FFFD).
			if (codeUnit == 0x0000) {
				result += '\uFFFD';
				continue;
			}

			if (
				// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
				// U+007F, […]
				(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
				// If the character is the first character and is in the range [0-9]
				// (U+0030 to U+0039), […]
				(index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
				// If the character is the second character and is in the range [0-9]
				// (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
				(
					index == 1 &&
					codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
					firstCodeUnit == 0x002D
				)
			) {
				// https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
				result += '\\' + codeUnit.toString(16) + ' ';
				continue;
			}

			if (
				// If the character is the first character and is a `-` (U+002D), and
				// there is no second character, […]
				index == 0 &&
				length == 1 &&
				codeUnit == 0x002D
			) {
				result += '\\' + string.charAt(index);
				continue;
			}

			// If the character is not handled by one of the above rules and is
			// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
			// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
			// U+005A), or [a-z] (U+0061 to U+007A), […]
			if (
				codeUnit >= 0x0080 ||
				codeUnit == 0x002D ||
				codeUnit == 0x005F ||
				codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
				codeUnit >= 0x0041 && codeUnit <= 0x005A ||
				codeUnit >= 0x0061 && codeUnit <= 0x007A
			) {
				// the character itself
				result += string.charAt(index);
				continue;
			}

			// Otherwise, the escaped character.
			// https://drafts.csswg.org/cssom/#escape-a-character
			result += '\\' + string.charAt(index);

		}
		return result;
	};

	if (!root.CSS) {
		root.CSS = {};
	}

	root.CSS.escape = cssEscape;
	return cssEscape;

}));

}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],332:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _interactionEvents = _interopRequireDefault(require("diagram-js/lib/features/interaction-events"));

var _DirectEditing = _interopRequireDefault(require("./lib/DirectEditing"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __depends__: [_interactionEvents.default],
  __init__: ['directEditing'],
  directEditing: ['type', _DirectEditing.default]
};
exports.default = _default;

},{"./lib/DirectEditing":333,"diagram-js/lib/features/interaction-events":336}],333:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = DirectEditing;

var _minDash = require("min-dash");

var _TextBox = _interopRequireDefault(require("./TextBox"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * A direct editing component that allows users
 * to edit an elements text directly in the diagram
 *
 * @param {EventBus} eventBus the event bus
 */
function DirectEditing(eventBus, canvas) {
  this._eventBus = eventBus;
  this._providers = [];
  this._textbox = new _TextBox.default({
    container: canvas.getContainer(),
    keyHandler: (0, _minDash.bind)(this._handleKey, this),
    resizeHandler: (0, _minDash.bind)(this._handleResize, this)
  });
}

DirectEditing.$inject = ['eventBus', 'canvas'];
/**
 * Register a direct editing provider

 * @param {Object} provider the provider, must expose an #activate(element) method that returns
 *                          an activation context ({ bounds: {x, y, width, height }, text }) if
 *                          direct editing is available for the given element.
 *                          Additionally the provider must expose a #update(element, value) method
 *                          to receive direct editing updates.
 */

DirectEditing.prototype.registerProvider = function (provider) {
  this._providers.push(provider);
};
/**
 * Returns true if direct editing is currently active
 *
 * @return {Boolean}
 */


DirectEditing.prototype.isActive = function () {
  return !!this._active;
};
/**
 * Cancel direct editing, if it is currently active
 */


DirectEditing.prototype.cancel = function () {
  if (!this._active) {
    return;
  }

  this._fire('cancel');

  this.close();
};

DirectEditing.prototype._fire = function (event, context) {
  this._eventBus.fire('directEditing.' + event, context || {
    active: this._active
  });
};

DirectEditing.prototype.close = function () {
  this._textbox.destroy();

  this._fire('deactivate');

  this._active = null;
  this.resizable = undefined;
};

DirectEditing.prototype.complete = function () {
  var active = this._active;

  if (!active) {
    return;
  }

  var containerBounds,
      previousBounds = active.context.bounds,
      newBounds = this.$textbox.getBoundingClientRect(),
      newText = this.getValue(),
      previousText = active.context.text;

  if (newText !== previousText || newBounds.height !== previousBounds.height || newBounds.width !== previousBounds.width) {
    containerBounds = this._textbox.container.getBoundingClientRect();
    active.provider.update(active.element, newText, active.context.text, {
      x: newBounds.left - containerBounds.left,
      y: newBounds.top - containerBounds.top,
      width: newBounds.width,
      height: newBounds.height
    });
  }

  this._fire('complete');

  this.close();
};

DirectEditing.prototype.getValue = function () {
  return this._textbox.getValue();
};

DirectEditing.prototype._handleKey = function (e) {
  // stop bubble
  e.stopPropagation();
  var key = e.keyCode || e.charCode; // ESC

  if (key === 27) {
    e.preventDefault();
    return this.cancel();
  } // Enter


  if (key === 13 && !e.shiftKey) {
    e.preventDefault();
    return this.complete();
  }
};

DirectEditing.prototype._handleResize = function (event) {
  this._fire('resize', event);
};
/**
 * Activate direct editing on the given element
 *
 * @param {Object} ElementDescriptor the descriptor for a shape or connection
 * @return {Boolean} true if the activation was possible
 */


DirectEditing.prototype.activate = function (element) {
  if (this.isActive()) {
    this.cancel();
  } // the direct editing context


  var context;
  var provider = (0, _minDash.find)(this._providers, function (p) {
    return (context = p.activate(element)) ? p : null;
  }); // check if activation took place

  if (context) {
    this.$textbox = this._textbox.create(context.bounds, context.style, context.text, context.options);
    this._active = {
      element: element,
      context: context,
      provider: provider
    };

    if (context.options && context.options.resizable) {
      this.resizable = true;
    }

    this._fire('activate');
  }

  return !!context;
};

},{"./TextBox":334,"min-dash":555}],334:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = TextBox;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var min = Math.min,
    max = Math.max;

function preventDefault(e) {
  e.preventDefault();
}

function stopPropagation(e) {
  e.stopPropagation();
}

function isTextNode(node) {
  return node.nodeType === Node.TEXT_NODE;
}

function toArray(nodeList) {
  return [].slice.call(nodeList);
}
/**
 * Initializes a container for a content editable div.
 *
 * Structure:
 *
 * container
 *   parent
 *     content
 *     resize-handle
 *
 * @param {object} options
 * @param {DOMElement} options.container The DOM element to append the contentContainer to
 * @param {Function} options.keyHandler Handler for key events
 * @param {Function} options.resizeHandler Handler for resize events
 */


function TextBox(options) {
  this.container = options.container;
  this.parent = (0, _minDom.domify)('<div class="djs-direct-editing-parent">' + '<div class="djs-direct-editing-content" contenteditable="true"></div>' + '</div>');
  this.content = (0, _minDom.query)('[contenteditable]', this.parent);

  this.keyHandler = options.keyHandler || function () {};

  this.resizeHandler = options.resizeHandler || function () {};

  this.autoResize = (0, _minDash.bind)(this.autoResize, this);
  this.handlePaste = (0, _minDash.bind)(this.handlePaste, this);
}
/**
 * Create a text box with the given position, size, style and text content
 *
 * @param {Object} bounds
 * @param {Number} bounds.x absolute x position
 * @param {Number} bounds.y absolute y position
 * @param {Number} [bounds.width] fixed width value
 * @param {Number} [bounds.height] fixed height value
 * @param {Number} [bounds.maxWidth] maximum width value
 * @param {Number} [bounds.maxHeight] maximum height value
 * @param {Number} [bounds.minWidth] minimum width value
 * @param {Number} [bounds.minHeight] minimum height value
 * @param {Object} [style]
 * @param {String} value text content
 *
 * @return {DOMElement} The created content DOM element
 */


TextBox.prototype.create = function (bounds, style, value, options) {
  var self = this;
  var parent = this.parent,
      content = this.content,
      container = this.container;
  options = this.options = options || {};
  style = this.style = style || {};
  var parentStyle = (0, _minDash.pick)(style, ['width', 'height', 'maxWidth', 'maxHeight', 'minWidth', 'minHeight', 'left', 'top', 'backgroundColor', 'position', 'overflow', 'border', 'wordWrap', 'textAlign', 'outline', 'transform']);
  (0, _minDash.assign)(parent.style, {
    width: bounds.width + 'px',
    height: bounds.height + 'px',
    maxWidth: bounds.maxWidth + 'px',
    maxHeight: bounds.maxHeight + 'px',
    minWidth: bounds.minWidth + 'px',
    minHeight: bounds.minHeight + 'px',
    left: bounds.x + 'px',
    top: bounds.y + 'px',
    backgroundColor: '#ffffff',
    position: 'absolute',
    overflow: 'visible',
    border: '1px solid #ccc',
    boxSizing: 'border-box',
    wordWrap: 'normal',
    textAlign: 'center',
    outline: 'none'
  }, parentStyle);
  var contentStyle = (0, _minDash.pick)(style, ['fontFamily', 'fontSize', 'fontWeight', 'lineHeight', 'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft']);
  (0, _minDash.assign)(content.style, {
    boxSizing: 'border-box',
    width: '100%',
    outline: 'none',
    wordWrap: 'break-word'
  }, contentStyle);

  if (options.centerVertically) {
    (0, _minDash.assign)(content.style, {
      position: 'absolute',
      top: '50%',
      transform: 'translate(0, -50%)'
    }, contentStyle);
  }

  content.innerText = value;

  _minDom.event.bind(content, 'keydown', this.keyHandler);

  _minDom.event.bind(content, 'mousedown', stopPropagation);

  _minDom.event.bind(content, 'paste', self.handlePaste);

  if (options.autoResize) {
    _minDom.event.bind(content, 'input', this.autoResize);
  }

  if (options.resizable) {
    this.resizable(style);
  }

  container.appendChild(parent); // set selection to end of text

  this.setSelection(content.lastChild, content.lastChild && content.lastChild.length);
  return parent;
};
/**
 * Intercept paste events to remove formatting from pasted text.
 */


TextBox.prototype.handlePaste = function (e) {
  var options = this.options,
      style = this.style;
  e.preventDefault();
  var text;

  if (e.clipboardData) {
    // Chrome, Firefox, Safari
    text = e.clipboardData.getData('text/plain');
  } else {
    // Internet Explorer
    text = window.clipboardData.getData('Text');
  }

  this.insertText(text);

  if (options.autoResize) {
    var hasResized = this.autoResize(style);

    if (hasResized) {
      this.resizeHandler(hasResized);
    }
  }
};

TextBox.prototype.insertText = function (text) {
  // insertText command not supported by Internet Explorer
  var success = document.execCommand('insertText', false, text);

  if (success) {
    return;
  }

  this._insertTextIE(text);
};

TextBox.prototype._insertTextIE = function (text) {
  // Internet Explorer
  var range = this.getSelection(),
      startContainer = range.startContainer,
      endContainer = range.endContainer,
      startOffset = range.startOffset,
      endOffset = range.endOffset,
      commonAncestorContainer = range.commonAncestorContainer;
  var childNodesArray = toArray(commonAncestorContainer.childNodes);
  var container, offset;

  if (isTextNode(commonAncestorContainer)) {
    var containerTextContent = startContainer.textContent;
    startContainer.textContent = containerTextContent.substring(0, startOffset) + text + containerTextContent.substring(endOffset);
    container = startContainer;
    offset = startOffset + text.length;
  } else if (startContainer === this.content && endContainer === this.content) {
    var textNode = document.createTextNode(text);
    this.content.insertBefore(textNode, childNodesArray[startOffset]);
    container = textNode;
    offset = textNode.textContent.length;
  } else {
    var startContainerChildIndex = childNodesArray.indexOf(startContainer),
        endContainerChildIndex = childNodesArray.indexOf(endContainer);
    childNodesArray.forEach(function (childNode, index) {
      if (index === startContainerChildIndex) {
        childNode.textContent = startContainer.textContent.substring(0, startOffset) + text + endContainer.textContent.substring(endOffset);
      } else if (index > startContainerChildIndex && index <= endContainerChildIndex) {
        (0, _minDom.remove)(childNode);
      }
    });
    container = startContainer;
    offset = startOffset + text.length;
  }

  if (container && offset !== undefined) {
    // is necessary in Internet Explorer
    setTimeout(function () {
      self.setSelection(container, offset);
    });
  }
};
/**
 * Automatically resize element vertically to fit its content.
 */


TextBox.prototype.autoResize = function () {
  var parent = this.parent,
      content = this.content;
  var fontSize = parseInt(this.style.fontSize) || 12;

  if (content.scrollHeight > parent.offsetHeight || content.scrollHeight < parent.offsetHeight - fontSize) {
    var bounds = parent.getBoundingClientRect();
    var height = content.scrollHeight;
    parent.style.height = height + 'px';
    this.resizeHandler({
      width: bounds.width,
      height: bounds.height,
      dx: 0,
      dy: height - bounds.height
    });
  }
};
/**
 * Make an element resizable by adding a resize handle.
 */


TextBox.prototype.resizable = function () {
  var self = this;
  var parent = this.parent,
      resizeHandle = this.resizeHandle;
  var minWidth = parseInt(this.style.minWidth) || 0,
      minHeight = parseInt(this.style.minHeight) || 0,
      maxWidth = parseInt(this.style.maxWidth) || Infinity,
      maxHeight = parseInt(this.style.maxHeight) || Infinity;

  if (!resizeHandle) {
    resizeHandle = this.resizeHandle = (0, _minDom.domify)('<div class="djs-direct-editing-resize-handle"></div>');
    var startX, startY, startWidth, startHeight;

    var onMouseDown = function (e) {
      preventDefault(e);
      stopPropagation(e);
      startX = e.clientX;
      startY = e.clientY;
      var bounds = parent.getBoundingClientRect();
      startWidth = bounds.width;
      startHeight = bounds.height;

      _minDom.event.bind(document, 'mousemove', onMouseMove);

      _minDom.event.bind(document, 'mouseup', onMouseUp);
    };

    var onMouseMove = function (e) {
      preventDefault(e);
      stopPropagation(e);
      var newWidth = min(max(startWidth + e.clientX - startX, minWidth), maxWidth);
      var newHeight = min(max(startHeight + e.clientY - startY, minHeight), maxHeight);
      parent.style.width = newWidth + 'px';
      parent.style.height = newHeight + 'px';
      self.resizeHandler({
        width: startWidth,
        height: startHeight,
        dx: e.clientX - startX,
        dy: e.clientY - startY
      });
    };

    var onMouseUp = function (e) {
      preventDefault(e);
      stopPropagation(e);

      _minDom.event.unbind(document, 'mousemove', onMouseMove, false);

      _minDom.event.unbind(document, 'mouseup', onMouseUp, false);
    };

    _minDom.event.bind(resizeHandle, 'mousedown', onMouseDown);
  }

  (0, _minDash.assign)(resizeHandle.style, {
    position: 'absolute',
    bottom: '0px',
    right: '0px',
    cursor: 'nwse-resize',
    width: '0',
    height: '0',
    borderTop: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid transparent',
    borderRight: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid #ccc',
    borderBottom: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid #ccc',
    borderLeft: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid transparent'
  });
  parent.appendChild(resizeHandle);
};
/**
 * Clear content and style of the textbox, unbind listeners and
 * reset CSS style.
 */


TextBox.prototype.destroy = function () {
  var parent = this.parent,
      content = this.content,
      resizeHandle = this.resizeHandle; // clear content

  content.innerText = ''; // clear styles

  parent.removeAttribute('style');
  content.removeAttribute('style');

  _minDom.event.unbind(content, 'keydown', this.keyHandler);

  _minDom.event.unbind(content, 'mousedown', stopPropagation);

  _minDom.event.unbind(content, 'input', this.autoResize);

  _minDom.event.unbind(content, 'paste', this.handlePaste);

  if (resizeHandle) {
    resizeHandle.removeAttribute('style');
    (0, _minDom.remove)(resizeHandle);
  }

  (0, _minDom.remove)(parent);
};

TextBox.prototype.getValue = function () {
  return this.content.innerText.trim();
};

TextBox.prototype.getSelection = function () {
  var selection = window.getSelection(),
      range = selection.getRangeAt(0);
  return range;
};

TextBox.prototype.setSelection = function (container, offset) {
  var range = document.createRange();

  if (container === null) {
    range.selectNodeContents(this.content);
  } else {
    range.setStart(container, offset);
    range.setEnd(container, offset);
  }

  var selection = window.getSelection();
  selection.removeAllRanges();
  selection.addRange(range);
};

},{"min-dash":555,"min-dom":556}],335:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = InteractionEvents;

var _minDash = require("min-dash");

var _minDom = require("min-dom");

var _Mouse = require("../../util/Mouse");

var _tinySvg = require("tiny-svg");

var _RenderUtil = require("../../util/RenderUtil");

function allowAll(e) {
  return true;
}

var LOW_PRIORITY = 500;
/**
 * A plugin that provides interaction events for diagram elements.
 *
 * It emits the following events:
 *
 *   * element.click
 *   * element.contextmenu
 *   * element.dblclick
 *   * element.hover
 *   * element.mousedown
 *   * element.mousemove
 *   * element.mouseup
 *   * element.out
 *
 * Each event is a tuple { element, gfx, originalEvent }.
 *
 * Canceling the event via Event#preventDefault()
 * prevents the original DOM operation.
 *
 * @param {EventBus} eventBus
 */

function InteractionEvents(eventBus, elementRegistry, styles) {
  var self = this;
  /**
   * Fire an interaction event.
   *
   * @param {String} type local event name, e.g. element.click.
   * @param {DOMEvent} event native event
   * @param {djs.model.Base} [element] the diagram element to emit the event on;
   *                                   defaults to the event target
   */

  function fire(type, event, element) {
    if (isIgnored(type, event)) {
      return;
    }

    var target, gfx, returnValue;

    if (!element) {
      target = event.delegateTarget || event.target;

      if (target) {
        gfx = target;
        element = elementRegistry.get(gfx);
      }
    } else {
      gfx = elementRegistry.getGraphics(element);
    }

    if (!gfx || !element) {
      return;
    }

    returnValue = eventBus.fire(type, {
      element: element,
      gfx: gfx,
      originalEvent: event
    });

    if (returnValue === false) {
      event.stopPropagation();
      event.preventDefault();
    }
  } // TODO(nikku): document this


  var handlers = {};

  function mouseHandler(localEventName) {
    return handlers[localEventName];
  }

  function isIgnored(localEventName, event) {
    var filter = ignoredFilters[localEventName] || _Mouse.isPrimaryButton; // only react on left mouse button interactions
    // except for interaction events that are enabled
    // for secundary mouse button

    return !filter(event);
  }

  var bindings = {
    click: 'element.click',
    contextmenu: 'element.contextmenu',
    dblclick: 'element.dblclick',
    mousedown: 'element.mousedown',
    mousemove: 'element.mousemove',
    mouseover: 'element.hover',
    mouseout: 'element.out',
    mouseup: 'element.mouseup'
  };
  var ignoredFilters = {
    'element.contextmenu': allowAll
  }; // manual event trigger //////////

  /**
   * Trigger an interaction event (based on a native dom event)
   * on the target shape or connection.
   *
   * @param {String} eventName the name of the triggered DOM event
   * @param {MouseEvent} event
   * @param {djs.model.Base} targetElement
   */

  function triggerMouseEvent(eventName, event, targetElement) {
    // i.e. element.mousedown...
    var localEventName = bindings[eventName];

    if (!localEventName) {
      throw new Error('unmapped DOM event name <' + eventName + '>');
    }

    return fire(localEventName, event, targetElement);
  }

  var ELEMENT_SELECTOR = 'svg, .djs-element'; // event handling ///////

  function registerEvent(node, event, localEvent, ignoredFilter) {
    var handler = handlers[localEvent] = function (event) {
      fire(localEvent, event);
    };

    if (ignoredFilter) {
      ignoredFilters[localEvent] = ignoredFilter;
    }

    handler.$delegate = _minDom.delegate.bind(node, ELEMENT_SELECTOR, event, handler);
  }

  function unregisterEvent(node, event, localEvent) {
    var handler = mouseHandler(localEvent);

    if (!handler) {
      return;
    }

    _minDom.delegate.unbind(node, event, handler.$delegate);
  }

  function registerEvents(svg) {
    (0, _minDash.forEach)(bindings, function (val, key) {
      registerEvent(svg, key, val);
    });
  }

  function unregisterEvents(svg) {
    (0, _minDash.forEach)(bindings, function (val, key) {
      unregisterEvent(svg, key, val);
    });
  }

  eventBus.on('canvas.destroy', function (event) {
    unregisterEvents(event.svg);
  });
  eventBus.on('canvas.init', function (event) {
    registerEvents(event.svg);
  }); // hit box updating ////////////////

  eventBus.on(['shape.added', 'connection.added'], function (event) {
    var element = event.element,
        gfx = event.gfx;
    eventBus.fire('interactionEvents.createHit', {
      element: element,
      gfx: gfx
    });
  }); // Update djs-hit on change.
  // A low priortity is necessary, because djs-hit of labels has to be updated
  // after the label bounds have been updated in the renderer.

  eventBus.on(['shape.changed', 'connection.changed'], LOW_PRIORITY, function (event) {
    var element = event.element,
        gfx = event.gfx;
    eventBus.fire('interactionEvents.updateHit', {
      element: element,
      gfx: gfx
    });
  });
  eventBus.on('interactionEvents.createHit', LOW_PRIORITY, function (event) {
    var element = event.element,
        gfx = event.gfx;
    self.createDefaultHit(element, gfx);
  });
  eventBus.on('interactionEvents.updateHit', function (event) {
    var element = event.element,
        gfx = event.gfx;
    self.updateDefaultHit(element, gfx);
  }); // hit styles ////////////

  var STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-stroke');
  var CLICK_STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-click-stroke');
  var ALL_HIT_STYLE = createHitStyle('djs-hit djs-hit-all');
  var HIT_TYPES = {
    'all': ALL_HIT_STYLE,
    'click-stroke': CLICK_STROKE_HIT_STYLE,
    'stroke': STROKE_HIT_STYLE
  };

  function createHitStyle(classNames, attrs) {
    attrs = (0, _minDash.assign)({
      stroke: 'white',
      strokeWidth: 15
    }, attrs || {});
    return styles.cls(classNames, ['no-fill', 'no-border'], attrs);
  } // style helpers ///////////////


  function applyStyle(hit, type) {
    var attrs = HIT_TYPES[type];

    if (!attrs) {
      throw new Error('invalid hit type <' + type + '>');
    }

    (0, _tinySvg.attr)(hit, attrs);
    return hit;
  }

  function appendHit(gfx, hit) {
    (0, _tinySvg.append)(gfx, hit);
  } // API

  /**
   * Remove hints on the given graphics.
   *
   * @param {SVGElement} gfx
   */


  this.removeHits = function (gfx) {
    var hits = (0, _minDom.queryAll)('.djs-hit', gfx);
    (0, _minDash.forEach)(hits, _tinySvg.remove);
  };
  /**
   * Create default hit for the given element.
   *
   * @param {djs.model.Base} element
   * @param {SVGElement} gfx
   *
   * @return {SVGElement} created hit
   */


  this.createDefaultHit = function (element, gfx) {
    var waypoints = element.waypoints,
        isFrame = element.isFrame,
        boxType;

    if (waypoints) {
      return this.createWaypointsHit(gfx, waypoints);
    } else {
      boxType = isFrame ? 'stroke' : 'all';
      return this.createBoxHit(gfx, boxType, {
        width: element.width,
        height: element.height
      });
    }
  };
  /**
   * Create hits for the given waypoints.
   *
   * @param {SVGElement} gfx
   * @param {Array<Point>} waypoints
   *
   * @return {SVGElement}
   */


  this.createWaypointsHit = function (gfx, waypoints) {
    var hit = (0, _RenderUtil.createLine)(waypoints);
    applyStyle(hit, 'stroke');
    appendHit(gfx, hit);
    return hit;
  };
  /**
   * Create hits for a box.
   *
   * @param {SVGElement} gfx
   * @param {String} hitType
   * @param {Object} attrs
   *
   * @return {SVGElement}
   */


  this.createBoxHit = function (gfx, type, attrs) {
    attrs = (0, _minDash.assign)({
      x: 0,
      y: 0
    }, attrs);
    var hit = (0, _tinySvg.create)('rect');
    applyStyle(hit, type);
    (0, _tinySvg.attr)(hit, attrs);
    appendHit(gfx, hit);
    return hit;
  };
  /**
   * Update default hit of the element.
   *
   * @param  {djs.model.Base} element
   * @param  {SVGElement} gfx
   *
   * @return {SVGElement} updated hit
   */


  this.updateDefaultHit = function (element, gfx) {
    var hit = (0, _minDom.query)('.djs-hit', gfx);

    if (!hit) {
      return;
    }

    if (element.waypoints) {
      (0, _RenderUtil.updateLine)(hit, element.waypoints);
    } else {
      (0, _tinySvg.attr)(hit, {
        width: element.width,
        height: element.height
      });
    }

    return hit;
  };

  this.fire = fire;
  this.triggerMouseEvent = triggerMouseEvent;
  this.mouseHandler = mouseHandler;
  this.registerEvent = registerEvent;
  this.unregisterEvent = unregisterEvent;
}

InteractionEvents.$inject = ['eventBus', 'elementRegistry', 'styles'];
/**
 * An event indicating that the mouse hovered over an element
 *
 * @event element.hover
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has left an element
 *
 * @event element.out
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has clicked an element
 *
 * @event element.click
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has double clicked an element
 *
 * @event element.dblclick
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has gone down on an element.
 *
 * @event element.mousedown
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the mouse has gone up on an element.
 *
 * @event element.mouseup
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

/**
 * An event indicating that the context menu action is triggered
 * via mouse or touch controls.
 *
 * @event element.contextmenu
 *
 * @type {Object}
 * @property {djs.model.Base} element
 * @property {SVGElement} gfx
 * @property {Event} originalEvent
 */

},{"../../util/Mouse":341,"../../util/RenderUtil":343,"min-dash":555,"min-dom":556,"tiny-svg":567}],336:[function(require,module,exports){
arguments[4][211][0].apply(exports,arguments)
},{"./InteractionEvents":335,"dup":211}],337:[function(require,module,exports){
arguments[4][296][0].apply(exports,arguments)
},{"./translate":338,"dup":296}],338:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = translate;

/**
 * A simple translation stub to be used for multi-language support
 * in diagrams. Can be easily replaced with a more sophisticated
 * solution.
 *
 * @example
 *
 * // use it inside any diagram component by injecting `translate`.
 *
 * function MyService(translate) {
 *   alert(translate('HELLO {you}', { you: 'You!' }));
 * }
 *
 * @param {String} template to interpolate
 * @param {Object} [replacements] a map with substitutes
 *
 * @return {String} the translated string
 */
function translate(template, replacements) {
  replacements = replacements || {};
  return template.replace(/{([^}]+)}/g, function (_, key) {
    return replacements[key] || '{' + key + '}';
  });
}

},{}],339:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.remove = remove;
exports.add = add;
exports.indexOf = indexOf;

/**
 * Failsafe remove an element from a collection
 *
 * @param  {Array<Object>} [collection]
 * @param  {Object} [element]
 *
 * @return {Number} the previous index of the element
 */
function remove(collection, element) {
  if (!collection || !element) {
    return -1;
  }

  var idx = collection.indexOf(element);

  if (idx !== -1) {
    collection.splice(idx, 1);
  }

  return idx;
}
/**
 * Fail save add an element to the given connection, ensuring
 * it does not yet exist.
 *
 * @param {Array<Object>} collection
 * @param {Object} element
 * @param {Number} idx
 */


function add(collection, element, idx) {
  if (!collection || !element) {
    return;
  }

  if (typeof idx !== 'number') {
    idx = -1;
  }

  var currentIdx = collection.indexOf(element);

  if (currentIdx !== -1) {
    if (currentIdx === idx) {
      // nothing to do, position has not changed
      return;
    } else {
      if (idx !== -1) {
        // remove from current position
        collection.splice(currentIdx, 1);
      } else {
        // already exists in collection
        return;
      }
    }
  }

  if (idx !== -1) {
    // insert at specified position
    collection.splice(idx, 0, element);
  } else {
    // push to end
    collection.push(element);
  }
}
/**
 * Fail save get the index of an element in a collection.
 *
 * @param {Array<Object>} collection
 * @param {Object} element
 *
 * @return {Number} the index or -1 if collection or element do
 *                  not exist or the element is not contained.
 */


function indexOf(collection, element) {
  if (!collection || !element) {
    return -1;
  }

  return collection.indexOf(element);
}

},{}],340:[function(require,module,exports){
arguments[4][317][0].apply(exports,arguments)
},{"dup":317}],341:[function(require,module,exports){
arguments[4][323][0].apply(exports,arguments)
},{"./Event":340,"./Platform":342,"dup":323}],342:[function(require,module,exports){
arguments[4][324][0].apply(exports,arguments)
},{"dup":324}],343:[function(require,module,exports){
arguments[4][327][0].apply(exports,arguments)
},{"dup":327,"tiny-svg":567}],344:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.annotate = annotate;
exports.Module = Module;
exports.Injector = Injector;
var CLASS_PATTERN = /^class /;

function isClass(fn) {
  return CLASS_PATTERN.test(fn.toString());
}

function isArray(obj) {
  return Object.prototype.toString.call(obj) === '[object Array]';
}

function annotate() {
  var args = Array.prototype.slice.call(arguments);

  if (args.length === 1 && isArray(args[0])) {
    args = args[0];
  }

  var fn = args.pop();
  fn.$inject = args;
  return fn;
} // Current limitations:
// - can't put into "function arg" comments
// function /* (no parenthesis like this) */ (){}
// function abc( /* xx (no parenthesis like this) */ a, b) {}
//
// Just put the comment before function or inside:
// /* (((this is fine))) */ function(a, b) {}
// function abc(a) { /* (((this is fine))) */}
//
// - can't reliably auto-annotate constructor; we'll match the
// first constructor(...) pattern found which may be the one
// of a nested class, too.


var CONSTRUCTOR_ARGS = /constructor\s*[^(]*\(\s*([^)]*)\)/m;
var FN_ARGS = /^function\s*[^(]*\(\s*([^)]*)\)/m;
var FN_ARG = /\/\*([^*]*)\*\//m;

function parse(fn) {
  if (typeof fn !== 'function') {
    throw new Error('Cannot annotate "' + fn + '". Expected a function!');
  }

  var match = fn.toString().match(isClass(fn) ? CONSTRUCTOR_ARGS : FN_ARGS); // may parse class without constructor

  if (!match) {
    return [];
  }

  return match[1] && match[1].split(',').map(function (arg) {
    match = arg.match(FN_ARG);
    return match ? match[1].trim() : arg.trim();
  }) || [];
}

function Module() {
  var providers = [];

  this.factory = function (name, factory) {
    providers.push([name, 'factory', factory]);
    return this;
  };

  this.value = function (name, value) {
    providers.push([name, 'value', value]);
    return this;
  };

  this.type = function (name, type) {
    providers.push([name, 'type', type]);
    return this;
  };

  this.forEach = function (iterator) {
    providers.forEach(iterator);
  };
}

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  return typeof obj;
} : function (obj) {
  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};

function _toConsumableArray(arr) {
  if (Array.isArray(arr)) {
    for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
      arr2[i] = arr[i];
    }

    return arr2;
  } else {
    return Array.from(arr);
  }
}

function Injector(modules, parent) {
  parent = parent || {
    get: function get(name, strict) {
      currentlyResolving.push(name);

      if (strict === false) {
        return null;
      } else {
        throw error('No provider for "' + name + '"!');
      }
    }
  };
  var currentlyResolving = [];
  var providers = this._providers = Object.create(parent._providers || null);
  var instances = this._instances = Object.create(null);
  var self = instances.injector = this;

  var error = function error(msg) {
    var stack = currentlyResolving.join(' -> ');
    currentlyResolving.length = 0;
    return new Error(stack ? msg + ' (Resolving: ' + stack + ')' : msg);
  };
  /**
   * Return a named service.
   *
   * @param {String} name
   * @param {Boolean} [strict=true] if false, resolve missing services to null
   *
   * @return {Object}
   */


  var get = function get(name, strict) {
    if (!providers[name] && name.indexOf('.') !== -1) {
      var parts = name.split('.');
      var pivot = get(parts.shift());

      while (parts.length) {
        pivot = pivot[parts.shift()];
      }

      return pivot;
    }

    if (hasProp(instances, name)) {
      return instances[name];
    }

    if (hasProp(providers, name)) {
      if (currentlyResolving.indexOf(name) !== -1) {
        currentlyResolving.push(name);
        throw error('Cannot resolve circular dependency!');
      }

      currentlyResolving.push(name);
      instances[name] = providers[name][0](providers[name][1]);
      currentlyResolving.pop();
      return instances[name];
    }

    return parent.get(name, strict);
  };

  var fnDef = function fnDef(fn) {
    var locals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

    if (typeof fn !== 'function') {
      if (isArray(fn)) {
        fn = annotate(fn.slice());
      } else {
        throw new Error('Cannot invoke "' + fn + '". Expected a function!');
      }
    }

    var inject = fn.$inject || parse(fn);
    var dependencies = inject.map(function (dep) {
      if (hasProp(locals, dep)) {
        return locals[dep];
      } else {
        return get(dep);
      }
    });
    return {
      fn: fn,
      dependencies: dependencies
    };
  };

  var instantiate = function instantiate(Type) {
    var _fnDef = fnDef(Type),
        dependencies = _fnDef.dependencies,
        fn = _fnDef.fn;

    return new (Function.prototype.bind.apply(fn, [null].concat(_toConsumableArray(dependencies))))();
  };

  var invoke = function invoke(func, context, locals) {
    var _fnDef2 = fnDef(func, locals),
        dependencies = _fnDef2.dependencies,
        fn = _fnDef2.fn;

    return fn.call.apply(fn, [context].concat(_toConsumableArray(dependencies)));
  };

  var createPrivateInjectorFactory = function createPrivateInjectorFactory(privateChildInjector) {
    return annotate(function (key) {
      return privateChildInjector.get(key);
    });
  };

  var createChild = function createChild(modules, forceNewInstances) {
    if (forceNewInstances && forceNewInstances.length) {
      var fromParentModule = Object.create(null);
      var matchedScopes = Object.create(null);
      var privateInjectorsCache = [];
      var privateChildInjectors = [];
      var privateChildFactories = [];
      var provider;
      var cacheIdx;
      var privateChildInjector;
      var privateChildInjectorFactory;

      for (var name in providers) {
        provider = providers[name];

        if (forceNewInstances.indexOf(name) !== -1) {
          if (provider[2] === 'private') {
            cacheIdx = privateInjectorsCache.indexOf(provider[3]);

            if (cacheIdx === -1) {
              privateChildInjector = provider[3].createChild([], forceNewInstances);
              privateChildInjectorFactory = createPrivateInjectorFactory(privateChildInjector);
              privateInjectorsCache.push(provider[3]);
              privateChildInjectors.push(privateChildInjector);
              privateChildFactories.push(privateChildInjectorFactory);
              fromParentModule[name] = [privateChildInjectorFactory, name, 'private', privateChildInjector];
            } else {
              fromParentModule[name] = [privateChildFactories[cacheIdx], name, 'private', privateChildInjectors[cacheIdx]];
            }
          } else {
            fromParentModule[name] = [provider[2], provider[1]];
          }

          matchedScopes[name] = true;
        }

        if ((provider[2] === 'factory' || provider[2] === 'type') && provider[1].$scope) {
          /* jshint -W083 */
          forceNewInstances.forEach(function (scope) {
            if (provider[1].$scope.indexOf(scope) !== -1) {
              fromParentModule[name] = [provider[2], provider[1]];
              matchedScopes[scope] = true;
            }
          });
        }
      }

      forceNewInstances.forEach(function (scope) {
        if (!matchedScopes[scope]) {
          throw new Error('No provider for "' + scope + '". Cannot use provider from the parent!');
        }
      });
      modules.unshift(fromParentModule);
    }

    return new Injector(modules, self);
  };

  var factoryMap = {
    factory: invoke,
    type: instantiate,
    value: function value(_value) {
      return _value;
    }
  };
  modules.forEach(function (module) {
    function arrayUnwrap(type, value) {
      if (type !== 'value' && isArray(value)) {
        value = annotate(value.slice());
      }

      return value;
    } // TODO(vojta): handle wrong inputs (modules)


    if (module instanceof Module) {
      module.forEach(function (provider) {
        var name = provider[0];
        var type = provider[1];
        var value = provider[2];
        providers[name] = [factoryMap[type], arrayUnwrap(type, value), type];
      });
    } else if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
      if (module.__exports__) {
        var clonedModule = Object.keys(module).reduce(function (m, key) {
          if (key.substring(0, 2) !== '__') {
            m[key] = module[key];
          }

          return m;
        }, Object.create(null));
        var privateInjector = new Injector((module.__modules__ || []).concat([clonedModule]), self);
        var getFromPrivateInjector = annotate(function (key) {
          return privateInjector.get(key);
        });

        module.__exports__.forEach(function (key) {
          providers[key] = [getFromPrivateInjector, key, 'private', privateInjector];
        });
      } else {
        Object.keys(module).forEach(function (name) {
          if (module[name][2] === 'private') {
            providers[name] = module[name];
            return;
          }

          var type = module[name][0];
          var value = module[name][1];
          providers[name] = [factoryMap[type], arrayUnwrap(type, value), type];
        });
      }
    }
  }); // public API

  this.get = get;
  this.invoke = invoke;
  this.instantiate = instantiate;
  this.createChild = createChild;
} // helpers /////////////////


function hasProp(obj, prop) {
  return Object.hasOwnProperty.call(obj, prop);
}

},{}],345:[function(require,module,exports){
/*! Hammer.JS - v2.0.7 - 2016-04-22
 * http://hammerjs.github.io/
 *
 * Copyright (c) 2016 Jorik Tangelder;
 * Licensed under the MIT license */
(function(window, document, exportName, undefined) {
  'use strict';

var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
var TEST_ELEMENT = document.createElement('div');

var TYPE_FUNCTION = 'function';

var round = Math.round;
var abs = Math.abs;
var now = Date.now;

/**
 * set a timeout with a given scope
 * @param {Function} fn
 * @param {Number} timeout
 * @param {Object} context
 * @returns {number}
 */
function setTimeoutContext(fn, timeout, context) {
    return setTimeout(bindFn(fn, context), timeout);
}

/**
 * if the argument is an array, we want to execute the fn on each entry
 * if it aint an array we don't want to do a thing.
 * this is used by all the methods that accept a single and array argument.
 * @param {*|Array} arg
 * @param {String} fn
 * @param {Object} [context]
 * @returns {Boolean}
 */
function invokeArrayArg(arg, fn, context) {
    if (Array.isArray(arg)) {
        each(arg, context[fn], context);
        return true;
    }
    return false;
}

/**
 * walk objects and arrays
 * @param {Object} obj
 * @param {Function} iterator
 * @param {Object} context
 */
function each(obj, iterator, context) {
    var i;

    if (!obj) {
        return;
    }

    if (obj.forEach) {
        obj.forEach(iterator, context);
    } else if (obj.length !== undefined) {
        i = 0;
        while (i < obj.length) {
            iterator.call(context, obj[i], i, obj);
            i++;
        }
    } else {
        for (i in obj) {
            obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
        }
    }
}

/**
 * wrap a method with a deprecation warning and stack trace
 * @param {Function} method
 * @param {String} name
 * @param {String} message
 * @returns {Function} A new function wrapping the supplied method.
 */
function deprecate(method, name, message) {
    var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n';
    return function() {
        var e = new Error('get-stack-trace');
        var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '')
            .replace(/^\s+at\s+/gm, '')
            .replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';

        var log = window.console && (window.console.warn || window.console.log);
        if (log) {
            log.call(window.console, deprecationMessage, stack);
        }
        return method.apply(this, arguments);
    };
}

/**
 * extend object.
 * means that properties in dest will be overwritten by the ones in src.
 * @param {Object} target
 * @param {...Object} objects_to_assign
 * @returns {Object} target
 */
var assign;
if (typeof Object.assign !== 'function') {
    assign = function assign(target) {
        if (target === undefined || target === null) {
            throw new TypeError('Cannot convert undefined or null to object');
        }

        var output = Object(target);
        for (var index = 1; index < arguments.length; index++) {
            var source = arguments[index];
            if (source !== undefined && source !== null) {
                for (var nextKey in source) {
                    if (source.hasOwnProperty(nextKey)) {
                        output[nextKey] = source[nextKey];
                    }
                }
            }
        }
        return output;
    };
} else {
    assign = Object.assign;
}

/**
 * extend object.
 * means that properties in dest will be overwritten by the ones in src.
 * @param {Object} dest
 * @param {Object} src
 * @param {Boolean} [merge=false]
 * @returns {Object} dest
 */
var extend = deprecate(function extend(dest, src, merge) {
    var keys = Object.keys(src);
    var i = 0;
    while (i < keys.length) {
        if (!merge || (merge && dest[keys[i]] === undefined)) {
            dest[keys[i]] = src[keys[i]];
        }
        i++;
    }
    return dest;
}, 'extend', 'Use `assign`.');

/**
 * merge the values from src in the dest.
 * means that properties that exist in dest will not be overwritten by src
 * @param {Object} dest
 * @param {Object} src
 * @returns {Object} dest
 */
var merge = deprecate(function merge(dest, src) {
    return extend(dest, src, true);
}, 'merge', 'Use `assign`.');

/**
 * simple class inheritance
 * @param {Function} child
 * @param {Function} base
 * @param {Object} [properties]
 */
function inherit(child, base, properties) {
    var baseP = base.prototype,
        childP;

    childP = child.prototype = Object.create(baseP);
    childP.constructor = child;
    childP._super = baseP;

    if (properties) {
        assign(childP, properties);
    }
}

/**
 * simple function bind
 * @param {Function} fn
 * @param {Object} context
 * @returns {Function}
 */
function bindFn(fn, context) {
    return function boundFn() {
        return fn.apply(context, arguments);
    };
}

/**
 * let a boolean value also be a function that must return a boolean
 * this first item in args will be used as the context
 * @param {Boolean|Function} val
 * @param {Array} [args]
 * @returns {Boolean}
 */
function boolOrFn(val, args) {
    if (typeof val == TYPE_FUNCTION) {
        return val.apply(args ? args[0] || undefined : undefined, args);
    }
    return val;
}

/**
 * use the val2 when val1 is undefined
 * @param {*} val1
 * @param {*} val2
 * @returns {*}
 */
function ifUndefined(val1, val2) {
    return (val1 === undefined) ? val2 : val1;
}

/**
 * addEventListener with multiple events at once
 * @param {EventTarget} target
 * @param {String} types
 * @param {Function} handler
 */
function addEventListeners(target, types, handler) {
    each(splitStr(types), function(type) {
        target.addEventListener(type, handler, false);
    });
}

/**
 * removeEventListener with multiple events at once
 * @param {EventTarget} target
 * @param {String} types
 * @param {Function} handler
 */
function removeEventListeners(target, types, handler) {
    each(splitStr(types), function(type) {
        target.removeEventListener(type, handler, false);
    });
}

/**
 * find if a node is in the given parent
 * @method hasParent
 * @param {HTMLElement} node
 * @param {HTMLElement} parent
 * @return {Boolean} found
 */
function hasParent(node, parent) {
    while (node) {
        if (node == parent) {
            return true;
        }
        node = node.parentNode;
    }
    return false;
}

/**
 * small indexOf wrapper
 * @param {String} str
 * @param {String} find
 * @returns {Boolean} found
 */
function inStr(str, find) {
    return str.indexOf(find) > -1;
}

/**
 * split string on whitespace
 * @param {String} str
 * @returns {Array} words
 */
function splitStr(str) {
    return str.trim().split(/\s+/g);
}

/**
 * find if a array contains the object using indexOf or a simple polyFill
 * @param {Array} src
 * @param {String} find
 * @param {String} [findByKey]
 * @return {Boolean|Number} false when not found, or the index
 */
function inArray(src, find, findByKey) {
    if (src.indexOf && !findByKey) {
        return src.indexOf(find);
    } else {
        var i = 0;
        while (i < src.length) {
            if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {
                return i;
            }
            i++;
        }
        return -1;
    }
}

/**
 * convert array-like objects to real arrays
 * @param {Object} obj
 * @returns {Array}
 */
function toArray(obj) {
    return Array.prototype.slice.call(obj, 0);
}

/**
 * unique array with objects based on a key (like 'id') or just by the array's value
 * @param {Array} src [{id:1},{id:2},{id:1}]
 * @param {String} [key]
 * @param {Boolean} [sort=False]
 * @returns {Array} [{id:1},{id:2}]
 */
function uniqueArray(src, key, sort) {
    var results = [];
    var values = [];
    var i = 0;

    while (i < src.length) {
        var val = key ? src[i][key] : src[i];
        if (inArray(values, val) < 0) {
            results.push(src[i]);
        }
        values[i] = val;
        i++;
    }

    if (sort) {
        if (!key) {
            results = results.sort();
        } else {
            results = results.sort(function sortUniqueArray(a, b) {
                return a[key] > b[key];
            });
        }
    }

    return results;
}

/**
 * get the prefixed property
 * @param {Object} obj
 * @param {String} property
 * @returns {String|Undefined} prefixed
 */
function prefixed(obj, property) {
    var prefix, prop;
    var camelProp = property[0].toUpperCase() + property.slice(1);

    var i = 0;
    while (i < VENDOR_PREFIXES.length) {
        prefix = VENDOR_PREFIXES[i];
        prop = (prefix) ? prefix + camelProp : property;

        if (prop in obj) {
            return prop;
        }
        i++;
    }
    return undefined;
}

/**
 * get a unique id
 * @returns {number} uniqueId
 */
var _uniqueId = 1;
function uniqueId() {
    return _uniqueId++;
}

/**
 * get the window object of an element
 * @param {HTMLElement} element
 * @returns {DocumentView|Window}
 */
function getWindowForElement(element) {
    var doc = element.ownerDocument || element;
    return (doc.defaultView || doc.parentWindow || window);
}

var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;

var SUPPORT_TOUCH = ('ontouchstart' in window);
var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;
var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);

var INPUT_TYPE_TOUCH = 'touch';
var INPUT_TYPE_PEN = 'pen';
var INPUT_TYPE_MOUSE = 'mouse';
var INPUT_TYPE_KINECT = 'kinect';

var COMPUTE_INTERVAL = 25;

var INPUT_START = 1;
var INPUT_MOVE = 2;
var INPUT_END = 4;
var INPUT_CANCEL = 8;

var DIRECTION_NONE = 1;
var DIRECTION_LEFT = 2;
var DIRECTION_RIGHT = 4;
var DIRECTION_UP = 8;
var DIRECTION_DOWN = 16;

var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;

var PROPS_XY = ['x', 'y'];
var PROPS_CLIENT_XY = ['clientX', 'clientY'];

/**
 * create new input type manager
 * @param {Manager} manager
 * @param {Function} callback
 * @returns {Input}
 * @constructor
 */
function Input(manager, callback) {
    var self = this;
    this.manager = manager;
    this.callback = callback;
    this.element = manager.element;
    this.target = manager.options.inputTarget;

    // smaller wrapper around the handler, for the scope and the enabled state of the manager,
    // so when disabled the input events are completely bypassed.
    this.domHandler = function(ev) {
        if (boolOrFn(manager.options.enable, [manager])) {
            self.handler(ev);
        }
    };

    this.init();

}

Input.prototype = {
    /**
     * should handle the inputEvent data and trigger the callback
     * @virtual
     */
    handler: function() { },

    /**
     * bind the events
     */
    init: function() {
        this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
        this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
        this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
    },

    /**
     * unbind the events
     */
    destroy: function() {
        this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
        this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
        this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
    }
};

/**
 * create new input type manager
 * called by the Manager constructor
 * @param {Hammer} manager
 * @returns {Input}
 */
function createInputInstance(manager) {
    var Type;
    var inputClass = manager.options.inputClass;

    if (inputClass) {
        Type = inputClass;
    } else if (SUPPORT_POINTER_EVENTS) {
        Type = PointerEventInput;
    } else if (SUPPORT_ONLY_TOUCH) {
        Type = TouchInput;
    } else if (!SUPPORT_TOUCH) {
        Type = MouseInput;
    } else {
        Type = TouchMouseInput;
    }
    return new (Type)(manager, inputHandler);
}

/**
 * handle input events
 * @param {Manager} manager
 * @param {String} eventType
 * @param {Object} input
 */
function inputHandler(manager, eventType, input) {
    var pointersLen = input.pointers.length;
    var changedPointersLen = input.changedPointers.length;
    var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));
    var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));

    input.isFirst = !!isFirst;
    input.isFinal = !!isFinal;

    if (isFirst) {
        manager.session = {};
    }

    // source event is the normalized value of the domEvents
    // like 'touchstart, mouseup, pointerdown'
    input.eventType = eventType;

    // compute scale, rotation etc
    computeInputData(manager, input);

    // emit secret event
    manager.emit('hammer.input', input);

    manager.recognize(input);
    manager.session.prevInput = input;
}

/**
 * extend the data with some usable properties like scale, rotate, velocity etc
 * @param {Object} manager
 * @param {Object} input
 */
function computeInputData(manager, input) {
    var session = manager.session;
    var pointers = input.pointers;
    var pointersLength = pointers.length;

    // store the first input to calculate the distance and direction
    if (!session.firstInput) {
        session.firstInput = simpleCloneInputData(input);
    }

    // to compute scale and rotation we need to store the multiple touches
    if (pointersLength > 1 && !session.firstMultiple) {
        session.firstMultiple = simpleCloneInputData(input);
    } else if (pointersLength === 1) {
        session.firstMultiple = false;
    }

    var firstInput = session.firstInput;
    var firstMultiple = session.firstMultiple;
    var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;

    var center = input.center = getCenter(pointers);
    input.timeStamp = now();
    input.deltaTime = input.timeStamp - firstInput.timeStamp;

    input.angle = getAngle(offsetCenter, center);
    input.distance = getDistance(offsetCenter, center);

    computeDeltaXY(session, input);
    input.offsetDirection = getDirection(input.deltaX, input.deltaY);

    var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
    input.overallVelocityX = overallVelocity.x;
    input.overallVelocityY = overallVelocity.y;
    input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;

    input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
    input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;

    input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >
        session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);

    computeIntervalInputData(session, input);

    // find the correct target
    var target = manager.element;
    if (hasParent(input.srcEvent.target, target)) {
        target = input.srcEvent.target;
    }
    input.target = target;
}

function computeDeltaXY(session, input) {
    var center = input.center;
    var offset = session.offsetDelta || {};
    var prevDelta = session.prevDelta || {};
    var prevInput = session.prevInput || {};

    if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
        prevDelta = session.prevDelta = {
            x: prevInput.deltaX || 0,
            y: prevInput.deltaY || 0
        };

        offset = session.offsetDelta = {
            x: center.x,
            y: center.y
        };
    }

    input.deltaX = prevDelta.x + (center.x - offset.x);
    input.deltaY = prevDelta.y + (center.y - offset.y);
}

/**
 * velocity is calculated every x ms
 * @param {Object} session
 * @param {Object} input
 */
function computeIntervalInputData(session, input) {
    var last = session.lastInterval || input,
        deltaTime = input.timeStamp - last.timeStamp,
        velocity, velocityX, velocityY, direction;

    if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
        var deltaX = input.deltaX - last.deltaX;
        var deltaY = input.deltaY - last.deltaY;

        var v = getVelocity(deltaTime, deltaX, deltaY);
        velocityX = v.x;
        velocityY = v.y;
        velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
        direction = getDirection(deltaX, deltaY);

        session.lastInterval = input;
    } else {
        // use latest velocity info if it doesn't overtake a minimum period
        velocity = last.velocity;
        velocityX = last.velocityX;
        velocityY = last.velocityY;
        direction = last.direction;
    }

    input.velocity = velocity;
    input.velocityX = velocityX;
    input.velocityY = velocityY;
    input.direction = direction;
}

/**
 * create a simple clone from the input used for storage of firstInput and firstMultiple
 * @param {Object} input
 * @returns {Object} clonedInputData
 */
function simpleCloneInputData(input) {
    // make a simple copy of the pointers because we will get a reference if we don't
    // we only need clientXY for the calculations
    var pointers = [];
    var i = 0;
    while (i < input.pointers.length) {
        pointers[i] = {
            clientX: round(input.pointers[i].clientX),
            clientY: round(input.pointers[i].clientY)
        };
        i++;
    }

    return {
        timeStamp: now(),
        pointers: pointers,
        center: getCenter(pointers),
        deltaX: input.deltaX,
        deltaY: input.deltaY
    };
}

/**
 * get the center of all the pointers
 * @param {Array} pointers
 * @return {Object} center contains `x` and `y` properties
 */
function getCenter(pointers) {
    var pointersLength = pointers.length;

    // no need to loop when only one touch
    if (pointersLength === 1) {
        return {
            x: round(pointers[0].clientX),
            y: round(pointers[0].clientY)
        };
    }

    var x = 0, y = 0, i = 0;
    while (i < pointersLength) {
        x += pointers[i].clientX;
        y += pointers[i].clientY;
        i++;
    }

    return {
        x: round(x / pointersLength),
        y: round(y / pointersLength)
    };
}

/**
 * calculate the velocity between two points. unit is in px per ms.
 * @param {Number} deltaTime
 * @param {Number} x
 * @param {Number} y
 * @return {Object} velocity `x` and `y`
 */
function getVelocity(deltaTime, x, y) {
    return {
        x: x / deltaTime || 0,
        y: y / deltaTime || 0
    };
}

/**
 * get the direction between two points
 * @param {Number} x
 * @param {Number} y
 * @return {Number} direction
 */
function getDirection(x, y) {
    if (x === y) {
        return DIRECTION_NONE;
    }

    if (abs(x) >= abs(y)) {
        return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
    }
    return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
}

/**
 * calculate the absolute distance between two points
 * @param {Object} p1 {x, y}
 * @param {Object} p2 {x, y}
 * @param {Array} [props] containing x and y keys
 * @return {Number} distance
 */
function getDistance(p1, p2, props) {
    if (!props) {
        props = PROPS_XY;
    }
    var x = p2[props[0]] - p1[props[0]],
        y = p2[props[1]] - p1[props[1]];

    return Math.sqrt((x * x) + (y * y));
}

/**
 * calculate the angle between two coordinates
 * @param {Object} p1
 * @param {Object} p2
 * @param {Array} [props] containing x and y keys
 * @return {Number} angle
 */
function getAngle(p1, p2, props) {
    if (!props) {
        props = PROPS_XY;
    }
    var x = p2[props[0]] - p1[props[0]],
        y = p2[props[1]] - p1[props[1]];
    return Math.atan2(y, x) * 180 / Math.PI;
}

/**
 * calculate the rotation degrees between two pointersets
 * @param {Array} start array of pointers
 * @param {Array} end array of pointers
 * @return {Number} rotation
 */
function getRotation(start, end) {
    return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
}

/**
 * calculate the scale factor between two pointersets
 * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
 * @param {Array} start array of pointers
 * @param {Array} end array of pointers
 * @return {Number} scale
 */
function getScale(start, end) {
    return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
}

var MOUSE_INPUT_MAP = {
    mousedown: INPUT_START,
    mousemove: INPUT_MOVE,
    mouseup: INPUT_END
};

var MOUSE_ELEMENT_EVENTS = 'mousedown';
var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';

/**
 * Mouse events input
 * @constructor
 * @extends Input
 */
function MouseInput() {
    this.evEl = MOUSE_ELEMENT_EVENTS;
    this.evWin = MOUSE_WINDOW_EVENTS;

    this.pressed = false; // mousedown state

    Input.apply(this, arguments);
}

inherit(MouseInput, Input, {
    /**
     * handle mouse events
     * @param {Object} ev
     */
    handler: function MEhandler(ev) {
        var eventType = MOUSE_INPUT_MAP[ev.type];

        // on start we want to have the left mouse button down
        if (eventType & INPUT_START && ev.button === 0) {
            this.pressed = true;
        }

        if (eventType & INPUT_MOVE && ev.which !== 1) {
            eventType = INPUT_END;
        }

        // mouse must be down
        if (!this.pressed) {
            return;
        }

        if (eventType & INPUT_END) {
            this.pressed = false;
        }

        this.callback(this.manager, eventType, {
            pointers: [ev],
            changedPointers: [ev],
            pointerType: INPUT_TYPE_MOUSE,
            srcEvent: ev
        });
    }
});

var POINTER_INPUT_MAP = {
    pointerdown: INPUT_START,
    pointermove: INPUT_MOVE,
    pointerup: INPUT_END,
    pointercancel: INPUT_CANCEL,
    pointerout: INPUT_CANCEL
};

// in IE10 the pointer types is defined as an enum
var IE10_POINTER_TYPE_ENUM = {
    2: INPUT_TYPE_TOUCH,
    3: INPUT_TYPE_PEN,
    4: INPUT_TYPE_MOUSE,
    5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
};

var POINTER_ELEMENT_EVENTS = 'pointerdown';
var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';

// IE10 has prefixed support, and case-sensitive
if (window.MSPointerEvent && !window.PointerEvent) {
    POINTER_ELEMENT_EVENTS = 'MSPointerDown';
    POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
}

/**
 * Pointer events input
 * @constructor
 * @extends Input
 */
function PointerEventInput() {
    this.evEl = POINTER_ELEMENT_EVENTS;
    this.evWin = POINTER_WINDOW_EVENTS;

    Input.apply(this, arguments);

    this.store = (this.manager.session.pointerEvents = []);
}

inherit(PointerEventInput, Input, {
    /**
     * handle mouse events
     * @param {Object} ev
     */
    handler: function PEhandler(ev) {
        var store = this.store;
        var removePointer = false;

        var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
        var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
        var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;

        var isTouch = (pointerType == INPUT_TYPE_TOUCH);

        // get index of the event in the store
        var storeIndex = inArray(store, ev.pointerId, 'pointerId');

        // start and mouse must be down
        if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
            if (storeIndex < 0) {
                store.push(ev);
                storeIndex = store.length - 1;
            }
        } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
            removePointer = true;
        }

        // it not found, so the pointer hasn't been down (so it's probably a hover)
        if (storeIndex < 0) {
            return;
        }

        // update the event in the store
        store[storeIndex] = ev;

        this.callback(this.manager, eventType, {
            pointers: store,
            changedPointers: [ev],
            pointerType: pointerType,
            srcEvent: ev
        });

        if (removePointer) {
            // remove from the store
            store.splice(storeIndex, 1);
        }
    }
});

var SINGLE_TOUCH_INPUT_MAP = {
    touchstart: INPUT_START,
    touchmove: INPUT_MOVE,
    touchend: INPUT_END,
    touchcancel: INPUT_CANCEL
};

var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';

/**
 * Touch events input
 * @constructor
 * @extends Input
 */
function SingleTouchInput() {
    this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
    this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
    this.started = false;

    Input.apply(this, arguments);
}

inherit(SingleTouchInput, Input, {
    handler: function TEhandler(ev) {
        var type = SINGLE_TOUCH_INPUT_MAP[ev.type];

        // should we handle the touch events?
        if (type === INPUT_START) {
            this.started = true;
        }

        if (!this.started) {
            return;
        }

        var touches = normalizeSingleTouches.call(this, ev, type);

        // when done, reset the started state
        if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
            this.started = false;
        }

        this.callback(this.manager, type, {
            pointers: touches[0],
            changedPointers: touches[1],
            pointerType: INPUT_TYPE_TOUCH,
            srcEvent: ev
        });
    }
});

/**
 * @this {TouchInput}
 * @param {Object} ev
 * @param {Number} type flag
 * @returns {undefined|Array} [all, changed]
 */
function normalizeSingleTouches(ev, type) {
    var all = toArray(ev.touches);
    var changed = toArray(ev.changedTouches);

    if (type & (INPUT_END | INPUT_CANCEL)) {
        all = uniqueArray(all.concat(changed), 'identifier', true);
    }

    return [all, changed];
}

var TOUCH_INPUT_MAP = {
    touchstart: INPUT_START,
    touchmove: INPUT_MOVE,
    touchend: INPUT_END,
    touchcancel: INPUT_CANCEL
};

var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';

/**
 * Multi-user touch events input
 * @constructor
 * @extends Input
 */
function TouchInput() {
    this.evTarget = TOUCH_TARGET_EVENTS;
    this.targetIds = {};

    Input.apply(this, arguments);
}

inherit(TouchInput, Input, {
    handler: function MTEhandler(ev) {
        var type = TOUCH_INPUT_MAP[ev.type];
        var touches = getTouches.call(this, ev, type);
        if (!touches) {
            return;
        }

        this.callback(this.manager, type, {
            pointers: touches[0],
            changedPointers: touches[1],
            pointerType: INPUT_TYPE_TOUCH,
            srcEvent: ev
        });
    }
});

/**
 * @this {TouchInput}
 * @param {Object} ev
 * @param {Number} type flag
 * @returns {undefined|Array} [all, changed]
 */
function getTouches(ev, type) {
    var allTouches = toArray(ev.touches);
    var targetIds = this.targetIds;

    // when there is only one touch, the process can be simplified
    if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
        targetIds[allTouches[0].identifier] = true;
        return [allTouches, allTouches];
    }

    var i,
        targetTouches,
        changedTouches = toArray(ev.changedTouches),
        changedTargetTouches = [],
        target = this.target;

    // get target touches from touches
    targetTouches = allTouches.filter(function(touch) {
        return hasParent(touch.target, target);
    });

    // collect touches
    if (type === INPUT_START) {
        i = 0;
        while (i < targetTouches.length) {
            targetIds[targetTouches[i].identifier] = true;
            i++;
        }
    }

    // filter changed touches to only contain touches that exist in the collected target ids
    i = 0;
    while (i < changedTouches.length) {
        if (targetIds[changedTouches[i].identifier]) {
            changedTargetTouches.push(changedTouches[i]);
        }

        // cleanup removed touches
        if (type & (INPUT_END | INPUT_CANCEL)) {
            delete targetIds[changedTouches[i].identifier];
        }
        i++;
    }

    if (!changedTargetTouches.length) {
        return;
    }

    return [
        // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
        uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),
        changedTargetTouches
    ];
}

/**
 * Combined touch and mouse input
 *
 * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
 * This because touch devices also emit mouse events while doing a touch.
 *
 * @constructor
 * @extends Input
 */

var DEDUP_TIMEOUT = 2500;
var DEDUP_DISTANCE = 25;

function TouchMouseInput() {
    Input.apply(this, arguments);

    var handler = bindFn(this.handler, this);
    this.touch = new TouchInput(this.manager, handler);
    this.mouse = new MouseInput(this.manager, handler);

    this.primaryTouch = null;
    this.lastTouches = [];
}

inherit(TouchMouseInput, Input, {
    /**
     * handle mouse and touch events
     * @param {Hammer} manager
     * @param {String} inputEvent
     * @param {Object} inputData
     */
    handler: function TMEhandler(manager, inputEvent, inputData) {
        var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH),
            isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);

        if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
            return;
        }

        // when we're in a touch event, record touches to  de-dupe synthetic mouse event
        if (isTouch) {
            recordTouches.call(this, inputEvent, inputData);
        } else if (isMouse && isSyntheticEvent.call(this, inputData)) {
            return;
        }

        this.callback(manager, inputEvent, inputData);
    },

    /**
     * remove the event listeners
     */
    destroy: function destroy() {
        this.touch.destroy();
        this.mouse.destroy();
    }
});

function recordTouches(eventType, eventData) {
    if (eventType & INPUT_START) {
        this.primaryTouch = eventData.changedPointers[0].identifier;
        setLastTouch.call(this, eventData);
    } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
        setLastTouch.call(this, eventData);
    }
}

function setLastTouch(eventData) {
    var touch = eventData.changedPointers[0];

    if (touch.identifier === this.primaryTouch) {
        var lastTouch = {x: touch.clientX, y: touch.clientY};
        this.lastTouches.push(lastTouch);
        var lts = this.lastTouches;
        var removeLastTouch = function() {
            var i = lts.indexOf(lastTouch);
            if (i > -1) {
                lts.splice(i, 1);
            }
        };
        setTimeout(removeLastTouch, DEDUP_TIMEOUT);
    }
}

function isSyntheticEvent(eventData) {
    var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;
    for (var i = 0; i < this.lastTouches.length; i++) {
        var t = this.lastTouches[i];
        var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);
        if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
            return true;
        }
    }
    return false;
}

var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;

// magical touchAction value
var TOUCH_ACTION_COMPUTE = 'compute';
var TOUCH_ACTION_AUTO = 'auto';
var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
var TOUCH_ACTION_NONE = 'none';
var TOUCH_ACTION_PAN_X = 'pan-x';
var TOUCH_ACTION_PAN_Y = 'pan-y';
var TOUCH_ACTION_MAP = getTouchActionProps();

/**
 * Touch Action
 * sets the touchAction property or uses the js alternative
 * @param {Manager} manager
 * @param {String} value
 * @constructor
 */
function TouchAction(manager, value) {
    this.manager = manager;
    this.set(value);
}

TouchAction.prototype = {
    /**
     * set the touchAction value on the element or enable the polyfill
     * @param {String} value
     */
    set: function(value) {
        // find out the touch-action by the event handlers
        if (value == TOUCH_ACTION_COMPUTE) {
            value = this.compute();
        }

        if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
            this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
        }
        this.actions = value.toLowerCase().trim();
    },

    /**
     * just re-set the touchAction value
     */
    update: function() {
        this.set(this.manager.options.touchAction);
    },

    /**
     * compute the value for the touchAction property based on the recognizer's settings
     * @returns {String} value
     */
    compute: function() {
        var actions = [];
        each(this.manager.recognizers, function(recognizer) {
            if (boolOrFn(recognizer.options.enable, [recognizer])) {
                actions = actions.concat(recognizer.getTouchAction());
            }
        });
        return cleanTouchActions(actions.join(' '));
    },

    /**
     * this method is called on each input cycle and provides the preventing of the browser behavior
     * @param {Object} input
     */
    preventDefaults: function(input) {
        var srcEvent = input.srcEvent;
        var direction = input.offsetDirection;

        // if the touch action did prevented once this session
        if (this.manager.session.prevented) {
            srcEvent.preventDefault();
            return;
        }

        var actions = this.actions;
        var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
        var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
        var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];

        if (hasNone) {
            //do not prevent defaults if this is a tap gesture

            var isTapPointer = input.pointers.length === 1;
            var isTapMovement = input.distance < 2;
            var isTapTouchTime = input.deltaTime < 250;

            if (isTapPointer && isTapMovement && isTapTouchTime) {
                return;
            }
        }

        if (hasPanX && hasPanY) {
            // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
            return;
        }

        if (hasNone ||
            (hasPanY && direction & DIRECTION_HORIZONTAL) ||
            (hasPanX && direction & DIRECTION_VERTICAL)) {
            return this.preventSrc(srcEvent);
        }
    },

    /**
     * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
     * @param {Object} srcEvent
     */
    preventSrc: function(srcEvent) {
        this.manager.session.prevented = true;
        srcEvent.preventDefault();
    }
};

/**
 * when the touchActions are collected they are not a valid value, so we need to clean things up. *
 * @param {String} actions
 * @returns {*}
 */
function cleanTouchActions(actions) {
    // none
    if (inStr(actions, TOUCH_ACTION_NONE)) {
        return TOUCH_ACTION_NONE;
    }

    var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
    var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);

    // if both pan-x and pan-y are set (different recognizers
    // for different directions, e.g. horizontal pan but vertical swipe?)
    // we need none (as otherwise with pan-x pan-y combined none of these
    // recognizers will work, since the browser would handle all panning
    if (hasPanX && hasPanY) {
        return TOUCH_ACTION_NONE;
    }

    // pan-x OR pan-y
    if (hasPanX || hasPanY) {
        return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
    }

    // manipulation
    if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
        return TOUCH_ACTION_MANIPULATION;
    }

    return TOUCH_ACTION_AUTO;
}

function getTouchActionProps() {
    if (!NATIVE_TOUCH_ACTION) {
        return false;
    }
    var touchMap = {};
    var cssSupports = window.CSS && window.CSS.supports;
    ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function(val) {

        // If css.supports is not supported but there is native touch-action assume it supports
        // all values. This is the case for IE 10 and 11.
        touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;
    });
    return touchMap;
}

/**
 * Recognizer flow explained; *
 * All recognizers have the initial state of POSSIBLE when a input session starts.
 * The definition of a input session is from the first input until the last input, with all it's movement in it. *
 * Example session for mouse-input: mousedown -> mousemove -> mouseup
 *
 * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
 * which determines with state it should be.
 *
 * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
 * POSSIBLE to give it another change on the next cycle.
 *
 *               Possible
 *                  |
 *            +-----+---------------+
 *            |                     |
 *      +-----+-----+               |
 *      |           |               |
 *   Failed      Cancelled          |
 *                          +-------+------+
 *                          |              |
 *                      Recognized       Began
 *                                         |
 *                                      Changed
 *                                         |
 *                                  Ended/Recognized
 */
var STATE_POSSIBLE = 1;
var STATE_BEGAN = 2;
var STATE_CHANGED = 4;
var STATE_ENDED = 8;
var STATE_RECOGNIZED = STATE_ENDED;
var STATE_CANCELLED = 16;
var STATE_FAILED = 32;

/**
 * Recognizer
 * Every recognizer needs to extend from this class.
 * @constructor
 * @param {Object} options
 */
function Recognizer(options) {
    this.options = assign({}, this.defaults, options || {});

    this.id = uniqueId();

    this.manager = null;

    // default is enable true
    this.options.enable = ifUndefined(this.options.enable, true);

    this.state = STATE_POSSIBLE;

    this.simultaneous = {};
    this.requireFail = [];
}

Recognizer.prototype = {
    /**
     * @virtual
     * @type {Object}
     */
    defaults: {},

    /**
     * set options
     * @param {Object} options
     * @return {Recognizer}
     */
    set: function(options) {
        assign(this.options, options);

        // also update the touchAction, in case something changed about the directions/enabled state
        this.manager && this.manager.touchAction.update();
        return this;
    },

    /**
     * recognize simultaneous with an other recognizer.
     * @param {Recognizer} otherRecognizer
     * @returns {Recognizer} this
     */
    recognizeWith: function(otherRecognizer) {
        if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
            return this;
        }

        var simultaneous = this.simultaneous;
        otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
        if (!simultaneous[otherRecognizer.id]) {
            simultaneous[otherRecognizer.id] = otherRecognizer;
            otherRecognizer.recognizeWith(this);
        }
        return this;
    },

    /**
     * drop the simultaneous link. it doesnt remove the link on the other recognizer.
     * @param {Recognizer} otherRecognizer
     * @returns {Recognizer} this
     */
    dropRecognizeWith: function(otherRecognizer) {
        if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
            return this;
        }

        otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
        delete this.simultaneous[otherRecognizer.id];
        return this;
    },

    /**
     * recognizer can only run when an other is failing
     * @param {Recognizer} otherRecognizer
     * @returns {Recognizer} this
     */
    requireFailure: function(otherRecognizer) {
        if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
            return this;
        }

        var requireFail = this.requireFail;
        otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
        if (inArray(requireFail, otherRecognizer) === -1) {
            requireFail.push(otherRecognizer);
            otherRecognizer.requireFailure(this);
        }
        return this;
    },

    /**
     * drop the requireFailure link. it does not remove the link on the other recognizer.
     * @param {Recognizer} otherRecognizer
     * @returns {Recognizer} this
     */
    dropRequireFailure: function(otherRecognizer) {
        if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
            return this;
        }

        otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
        var index = inArray(this.requireFail, otherRecognizer);
        if (index > -1) {
            this.requireFail.splice(index, 1);
        }
        return this;
    },

    /**
     * has require failures boolean
     * @returns {boolean}
     */
    hasRequireFailures: function() {
        return this.requireFail.length > 0;
    },

    /**
     * if the recognizer can recognize simultaneous with an other recognizer
     * @param {Recognizer} otherRecognizer
     * @returns {Boolean}
     */
    canRecognizeWith: function(otherRecognizer) {
        return !!this.simultaneous[otherRecognizer.id];
    },

    /**
     * You should use `tryEmit` instead of `emit` directly to check
     * that all the needed recognizers has failed before emitting.
     * @param {Object} input
     */
    emit: function(input) {
        var self = this;
        var state = this.state;

        function emit(event) {
            self.manager.emit(event, input);
        }

        // 'panstart' and 'panmove'
        if (state < STATE_ENDED) {
            emit(self.options.event + stateStr(state));
        }

        emit(self.options.event); // simple 'eventName' events

        if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)
            emit(input.additionalEvent);
        }

        // panend and pancancel
        if (state >= STATE_ENDED) {
            emit(self.options.event + stateStr(state));
        }
    },

    /**
     * Check that all the require failure recognizers has failed,
     * if true, it emits a gesture event,
     * otherwise, setup the state to FAILED.
     * @param {Object} input
     */
    tryEmit: function(input) {
        if (this.canEmit()) {
            return this.emit(input);
        }
        // it's failing anyway
        this.state = STATE_FAILED;
    },

    /**
     * can we emit?
     * @returns {boolean}
     */
    canEmit: function() {
        var i = 0;
        while (i < this.requireFail.length) {
            if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
                return false;
            }
            i++;
        }
        return true;
    },

    /**
     * update the recognizer
     * @param {Object} inputData
     */
    recognize: function(inputData) {
        // make a new copy of the inputData
        // so we can change the inputData without messing up the other recognizers
        var inputDataClone = assign({}, inputData);

        // is is enabled and allow recognizing?
        if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
            this.reset();
            this.state = STATE_FAILED;
            return;
        }

        // reset when we've reached the end
        if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
            this.state = STATE_POSSIBLE;
        }

        this.state = this.process(inputDataClone);

        // the recognizer has recognized a gesture
        // so trigger an event
        if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
            this.tryEmit(inputDataClone);
        }
    },

    /**
     * return the state of the recognizer
     * the actual recognizing happens in this method
     * @virtual
     * @param {Object} inputData
     * @returns {Const} STATE
     */
    process: function(inputData) { }, // jshint ignore:line

    /**
     * return the preferred touch-action
     * @virtual
     * @returns {Array}
     */
    getTouchAction: function() { },

    /**
     * called when the gesture isn't allowed to recognize
     * like when another is being recognized or it is disabled
     * @virtual
     */
    reset: function() { }
};

/**
 * get a usable string, used as event postfix
 * @param {Const} state
 * @returns {String} state
 */
function stateStr(state) {
    if (state & STATE_CANCELLED) {
        return 'cancel';
    } else if (state & STATE_ENDED) {
        return 'end';
    } else if (state & STATE_CHANGED) {
        return 'move';
    } else if (state & STATE_BEGAN) {
        return 'start';
    }
    return '';
}

/**
 * direction cons to string
 * @param {Const} direction
 * @returns {String}
 */
function directionStr(direction) {
    if (direction == DIRECTION_DOWN) {
        return 'down';
    } else if (direction == DIRECTION_UP) {
        return 'up';
    } else if (direction == DIRECTION_LEFT) {
        return 'left';
    } else if (direction == DIRECTION_RIGHT) {
        return 'right';
    }
    return '';
}

/**
 * get a recognizer by name if it is bound to a manager
 * @param {Recognizer|String} otherRecognizer
 * @param {Recognizer} recognizer
 * @returns {Recognizer}
 */
function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
    var manager = recognizer.manager;
    if (manager) {
        return manager.get(otherRecognizer);
    }
    return otherRecognizer;
}

/**
 * This recognizer is just used as a base for the simple attribute recognizers.
 * @constructor
 * @extends Recognizer
 */
function AttrRecognizer() {
    Recognizer.apply(this, arguments);
}

inherit(AttrRecognizer, Recognizer, {
    /**
     * @namespace
     * @memberof AttrRecognizer
     */
    defaults: {
        /**
         * @type {Number}
         * @default 1
         */
        pointers: 1
    },

    /**
     * Used to check if it the recognizer receives valid input, like input.distance > 10.
     * @memberof AttrRecognizer
     * @param {Object} input
     * @returns {Boolean} recognized
     */
    attrTest: function(input) {
        var optionPointers = this.options.pointers;
        return optionPointers === 0 || input.pointers.length === optionPointers;
    },

    /**
     * Process the input and return the state for the recognizer
     * @memberof AttrRecognizer
     * @param {Object} input
     * @returns {*} State
     */
    process: function(input) {
        var state = this.state;
        var eventType = input.eventType;

        var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
        var isValid = this.attrTest(input);

        // on cancel input and we've recognized before, return STATE_CANCELLED
        if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
            return state | STATE_CANCELLED;
        } else if (isRecognized || isValid) {
            if (eventType & INPUT_END) {
                return state | STATE_ENDED;
            } else if (!(state & STATE_BEGAN)) {
                return STATE_BEGAN;
            }
            return state | STATE_CHANGED;
        }
        return STATE_FAILED;
    }
});

/**
 * Pan
 * Recognized when the pointer is down and moved in the allowed direction.
 * @constructor
 * @extends AttrRecognizer
 */
function PanRecognizer() {
    AttrRecognizer.apply(this, arguments);

    this.pX = null;
    this.pY = null;
}

inherit(PanRecognizer, AttrRecognizer, {
    /**
     * @namespace
     * @memberof PanRecognizer
     */
    defaults: {
        event: 'pan',
        threshold: 10,
        pointers: 1,
        direction: DIRECTION_ALL
    },

    getTouchAction: function() {
        var direction = this.options.direction;
        var actions = [];
        if (direction & DIRECTION_HORIZONTAL) {
            actions.push(TOUCH_ACTION_PAN_Y);
        }
        if (direction & DIRECTION_VERTICAL) {
            actions.push(TOUCH_ACTION_PAN_X);
        }
        return actions;
    },

    directionTest: function(input) {
        var options = this.options;
        var hasMoved = true;
        var distance = input.distance;
        var direction = input.direction;
        var x = input.deltaX;
        var y = input.deltaY;

        // lock to axis?
        if (!(direction & options.direction)) {
            if (options.direction & DIRECTION_HORIZONTAL) {
                direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;
                hasMoved = x != this.pX;
                distance = Math.abs(input.deltaX);
            } else {
                direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;
                hasMoved = y != this.pY;
                distance = Math.abs(input.deltaY);
            }
        }
        input.direction = direction;
        return hasMoved && distance > options.threshold && direction & options.direction;
    },

    attrTest: function(input) {
        return AttrRecognizer.prototype.attrTest.call(this, input) &&
            (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));
    },

    emit: function(input) {

        this.pX = input.deltaX;
        this.pY = input.deltaY;

        var direction = directionStr(input.direction);

        if (direction) {
            input.additionalEvent = this.options.event + direction;
        }
        this._super.emit.call(this, input);
    }
});

/**
 * Pinch
 * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
 * @constructor
 * @extends AttrRecognizer
 */
function PinchRecognizer() {
    AttrRecognizer.apply(this, arguments);
}

inherit(PinchRecognizer, AttrRecognizer, {
    /**
     * @namespace
     * @memberof PinchRecognizer
     */
    defaults: {
        event: 'pinch',
        threshold: 0,
        pointers: 2
    },

    getTouchAction: function() {
        return [TOUCH_ACTION_NONE];
    },

    attrTest: function(input) {
        return this._super.attrTest.call(this, input) &&
            (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
    },

    emit: function(input) {
        if (input.scale !== 1) {
            var inOut = input.scale < 1 ? 'in' : 'out';
            input.additionalEvent = this.options.event + inOut;
        }
        this._super.emit.call(this, input);
    }
});

/**
 * Press
 * Recognized when the pointer is down for x ms without any movement.
 * @constructor
 * @extends Recognizer
 */
function PressRecognizer() {
    Recognizer.apply(this, arguments);

    this._timer = null;
    this._input = null;
}

inherit(PressRecognizer, Recognizer, {
    /**
     * @namespace
     * @memberof PressRecognizer
     */
    defaults: {
        event: 'press',
        pointers: 1,
        time: 251, // minimal time of the pointer to be pressed
        threshold: 9 // a minimal movement is ok, but keep it low
    },

    getTouchAction: function() {
        return [TOUCH_ACTION_AUTO];
    },

    process: function(input) {
        var options = this.options;
        var validPointers = input.pointers.length === options.pointers;
        var validMovement = input.distance < options.threshold;
        var validTime = input.deltaTime > options.time;

        this._input = input;

        // we only allow little movement
        // and we've reached an end event, so a tap is possible
        if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {
            this.reset();
        } else if (input.eventType & INPUT_START) {
            this.reset();
            this._timer = setTimeoutContext(function() {
                this.state = STATE_RECOGNIZED;
                this.tryEmit();
            }, options.time, this);
        } else if (input.eventType & INPUT_END) {
            return STATE_RECOGNIZED;
        }
        return STATE_FAILED;
    },

    reset: function() {
        clearTimeout(this._timer);
    },

    emit: function(input) {
        if (this.state !== STATE_RECOGNIZED) {
            return;
        }

        if (input && (input.eventType & INPUT_END)) {
            this.manager.emit(this.options.event + 'up', input);
        } else {
            this._input.timeStamp = now();
            this.manager.emit(this.options.event, this._input);
        }
    }
});

/**
 * Rotate
 * Recognized when two or more pointer are moving in a circular motion.
 * @constructor
 * @extends AttrRecognizer
 */
function RotateRecognizer() {
    AttrRecognizer.apply(this, arguments);
}

inherit(RotateRecognizer, AttrRecognizer, {
    /**
     * @namespace
     * @memberof RotateRecognizer
     */
    defaults: {
        event: 'rotate',
        threshold: 0,
        pointers: 2
    },

    getTouchAction: function() {
        return [TOUCH_ACTION_NONE];
    },

    attrTest: function(input) {
        return this._super.attrTest.call(this, input) &&
            (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
    }
});

/**
 * Swipe
 * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
 * @constructor
 * @extends AttrRecognizer
 */
function SwipeRecognizer() {
    AttrRecognizer.apply(this, arguments);
}

inherit(SwipeRecognizer, AttrRecognizer, {
    /**
     * @namespace
     * @memberof SwipeRecognizer
     */
    defaults: {
        event: 'swipe',
        threshold: 10,
        velocity: 0.3,
        direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
        pointers: 1
    },

    getTouchAction: function() {
        return PanRecognizer.prototype.getTouchAction.call(this);
    },

    attrTest: function(input) {
        var direction = this.options.direction;
        var velocity;

        if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
            velocity = input.overallVelocity;
        } else if (direction & DIRECTION_HORIZONTAL) {
            velocity = input.overallVelocityX;
        } else if (direction & DIRECTION_VERTICAL) {
            velocity = input.overallVelocityY;
        }

        return this._super.attrTest.call(this, input) &&
            direction & input.offsetDirection &&
            input.distance > this.options.threshold &&
            input.maxPointers == this.options.pointers &&
            abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
    },

    emit: function(input) {
        var direction = directionStr(input.offsetDirection);
        if (direction) {
            this.manager.emit(this.options.event + direction, input);
        }

        this.manager.emit(this.options.event, input);
    }
});

/**
 * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
 * between the given interval and position. The delay option can be used to recognize multi-taps without firing
 * a single tap.
 *
 * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
 * multi-taps being recognized.
 * @constructor
 * @extends Recognizer
 */
function TapRecognizer() {
    Recognizer.apply(this, arguments);

    // previous time and center,
    // used for tap counting
    this.pTime = false;
    this.pCenter = false;

    this._timer = null;
    this._input = null;
    this.count = 0;
}

inherit(TapRecognizer, Recognizer, {
    /**
     * @namespace
     * @memberof PinchRecognizer
     */
    defaults: {
        event: 'tap',
        pointers: 1,
        taps: 1,
        interval: 300, // max time between the multi-tap taps
        time: 250, // max time of the pointer to be down (like finger on the screen)
        threshold: 9, // a minimal movement is ok, but keep it low
        posThreshold: 10 // a multi-tap can be a bit off the initial position
    },

    getTouchAction: function() {
        return [TOUCH_ACTION_MANIPULATION];
    },

    process: function(input) {
        var options = this.options;

        var validPointers = input.pointers.length === options.pointers;
        var validMovement = input.distance < options.threshold;
        var validTouchTime = input.deltaTime < options.time;

        this.reset();

        if ((input.eventType & INPUT_START) && (this.count === 0)) {
            return this.failTimeout();
        }

        // we only allow little movement
        // and we've reached an end event, so a tap is possible
        if (validMovement && validTouchTime && validPointers) {
            if (input.eventType != INPUT_END) {
                return this.failTimeout();
            }

            var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
            var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;

            this.pTime = input.timeStamp;
            this.pCenter = input.center;

            if (!validMultiTap || !validInterval) {
                this.count = 1;
            } else {
                this.count += 1;
            }

            this._input = input;

            // if tap count matches we have recognized it,
            // else it has began recognizing...
            var tapCount = this.count % options.taps;
            if (tapCount === 0) {
                // no failing requirements, immediately trigger the tap event
                // or wait as long as the multitap interval to trigger
                if (!this.hasRequireFailures()) {
                    return STATE_RECOGNIZED;
                } else {
                    this._timer = setTimeoutContext(function() {
                        this.state = STATE_RECOGNIZED;
                        this.tryEmit();
                    }, options.interval, this);
                    return STATE_BEGAN;
                }
            }
        }
        return STATE_FAILED;
    },

    failTimeout: function() {
        this._timer = setTimeoutContext(function() {
            this.state = STATE_FAILED;
        }, this.options.interval, this);
        return STATE_FAILED;
    },

    reset: function() {
        clearTimeout(this._timer);
    },

    emit: function() {
        if (this.state == STATE_RECOGNIZED) {
            this._input.tapCount = this.count;
            this.manager.emit(this.options.event, this._input);
        }
    }
});

/**
 * Simple way to create a manager with a default set of recognizers.
 * @param {HTMLElement} element
 * @param {Object} [options]
 * @constructor
 */
function Hammer(element, options) {
    options = options || {};
    options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
    return new Manager(element, options);
}

/**
 * @const {string}
 */
Hammer.VERSION = '2.0.7';

/**
 * default settings
 * @namespace
 */
Hammer.defaults = {
    /**
     * set if DOM events are being triggered.
     * But this is slower and unused by simple implementations, so disabled by default.
     * @type {Boolean}
     * @default false
     */
    domEvents: false,

    /**
     * The value for the touchAction property/fallback.
     * When set to `compute` it will magically set the correct value based on the added recognizers.
     * @type {String}
     * @default compute
     */
    touchAction: TOUCH_ACTION_COMPUTE,

    /**
     * @type {Boolean}
     * @default true
     */
    enable: true,

    /**
     * EXPERIMENTAL FEATURE -- can be removed/changed
     * Change the parent input target element.
     * If Null, then it is being set the to main element.
     * @type {Null|EventTarget}
     * @default null
     */
    inputTarget: null,

    /**
     * force an input class
     * @type {Null|Function}
     * @default null
     */
    inputClass: null,

    /**
     * Default recognizer setup when calling `Hammer()`
     * When creating a new Manager these will be skipped.
     * @type {Array}
     */
    preset: [
        // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
        [RotateRecognizer, {enable: false}],
        [PinchRecognizer, {enable: false}, ['rotate']],
        [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],
        [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],
        [TapRecognizer],
        [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],
        [PressRecognizer]
    ],

    /**
     * Some CSS properties can be used to improve the working of Hammer.
     * Add them to this method and they will be set when creating a new Manager.
     * @namespace
     */
    cssProps: {
        /**
         * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
         * @type {String}
         * @default 'none'
         */
        userSelect: 'none',

        /**
         * Disable the Windows Phone grippers when pressing an element.
         * @type {String}
         * @default 'none'
         */
        touchSelect: 'none',

        /**
         * Disables the default callout shown when you touch and hold a touch target.
         * On iOS, when you touch and hold a touch target such as a link, Safari displays
         * a callout containing information about the link. This property allows you to disable that callout.
         * @type {String}
         * @default 'none'
         */
        touchCallout: 'none',

        /**
         * Specifies whether zooming is enabled. Used by IE10>
         * @type {String}
         * @default 'none'
         */
        contentZooming: 'none',

        /**
         * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
         * @type {String}
         * @default 'none'
         */
        userDrag: 'none',

        /**
         * Overrides the highlight color shown when the user taps a link or a JavaScript
         * clickable element in iOS. This property obeys the alpha value, if specified.
         * @type {String}
         * @default 'rgba(0,0,0,0)'
         */
        tapHighlightColor: 'rgba(0,0,0,0)'
    }
};

var STOP = 1;
var FORCED_STOP = 2;

/**
 * Manager
 * @param {HTMLElement} element
 * @param {Object} [options]
 * @constructor
 */
function Manager(element, options) {
    this.options = assign({}, Hammer.defaults, options || {});

    this.options.inputTarget = this.options.inputTarget || element;

    this.handlers = {};
    this.session = {};
    this.recognizers = [];
    this.oldCssProps = {};

    this.element = element;
    this.input = createInputInstance(this);
    this.touchAction = new TouchAction(this, this.options.touchAction);

    toggleCssProps(this, true);

    each(this.options.recognizers, function(item) {
        var recognizer = this.add(new (item[0])(item[1]));
        item[2] && recognizer.recognizeWith(item[2]);
        item[3] && recognizer.requireFailure(item[3]);
    }, this);
}

Manager.prototype = {
    /**
     * set options
     * @param {Object} options
     * @returns {Manager}
     */
    set: function(options) {
        assign(this.options, options);

        // Options that need a little more setup
        if (options.touchAction) {
            this.touchAction.update();
        }
        if (options.inputTarget) {
            // Clean up existing event listeners and reinitialize
            this.input.destroy();
            this.input.target = options.inputTarget;
            this.input.init();
        }
        return this;
    },

    /**
     * stop recognizing for this session.
     * This session will be discarded, when a new [input]start event is fired.
     * When forced, the recognizer cycle is stopped immediately.
     * @param {Boolean} [force]
     */
    stop: function(force) {
        this.session.stopped = force ? FORCED_STOP : STOP;
    },

    /**
     * run the recognizers!
     * called by the inputHandler function on every movement of the pointers (touches)
     * it walks through all the recognizers and tries to detect the gesture that is being made
     * @param {Object} inputData
     */
    recognize: function(inputData) {
        var session = this.session;
        if (session.stopped) {
            return;
        }

        // run the touch-action polyfill
        this.touchAction.preventDefaults(inputData);

        var recognizer;
        var recognizers = this.recognizers;

        // this holds the recognizer that is being recognized.
        // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
        // if no recognizer is detecting a thing, it is set to `null`
        var curRecognizer = session.curRecognizer;

        // reset when the last recognizer is recognized
        // or when we're in a new session
        if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
            curRecognizer = session.curRecognizer = null;
        }

        var i = 0;
        while (i < recognizers.length) {
            recognizer = recognizers[i];

            // find out if we are allowed try to recognize the input for this one.
            // 1.   allow if the session is NOT forced stopped (see the .stop() method)
            // 2.   allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
            //      that is being recognized.
            // 3.   allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
            //      this can be setup with the `recognizeWith()` method on the recognizer.
            if (session.stopped !== FORCED_STOP && ( // 1
                    !curRecognizer || recognizer == curRecognizer || // 2
                    recognizer.canRecognizeWith(curRecognizer))) { // 3
                recognizer.recognize(inputData);
            } else {
                recognizer.reset();
            }

            // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
            // current active recognizer. but only if we don't already have an active recognizer
            if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
                curRecognizer = session.curRecognizer = recognizer;
            }
            i++;
        }
    },

    /**
     * get a recognizer by its event name.
     * @param {Recognizer|String} recognizer
     * @returns {Recognizer|Null}
     */
    get: function(recognizer) {
        if (recognizer instanceof Recognizer) {
            return recognizer;
        }

        var recognizers = this.recognizers;
        for (var i = 0; i < recognizers.length; i++) {
            if (recognizers[i].options.event == recognizer) {
                return recognizers[i];
            }
        }
        return null;
    },

    /**
     * add a recognizer to the manager
     * existing recognizers with the same event name will be removed
     * @param {Recognizer} recognizer
     * @returns {Recognizer|Manager}
     */
    add: function(recognizer) {
        if (invokeArrayArg(recognizer, 'add', this)) {
            return this;
        }

        // remove existing
        var existing = this.get(recognizer.options.event);
        if (existing) {
            this.remove(existing);
        }

        this.recognizers.push(recognizer);
        recognizer.manager = this;

        this.touchAction.update();
        return recognizer;
    },

    /**
     * remove a recognizer by name or instance
     * @param {Recognizer|String} recognizer
     * @returns {Manager}
     */
    remove: function(recognizer) {
        if (invokeArrayArg(recognizer, 'remove', this)) {
            return this;
        }

        recognizer = this.get(recognizer);

        // let's make sure this recognizer exists
        if (recognizer) {
            var recognizers = this.recognizers;
            var index = inArray(recognizers, recognizer);

            if (index !== -1) {
                recognizers.splice(index, 1);
                this.touchAction.update();
            }
        }

        return this;
    },

    /**
     * bind event
     * @param {String} events
     * @param {Function} handler
     * @returns {EventEmitter} this
     */
    on: function(events, handler) {
        if (events === undefined) {
            return;
        }
        if (handler === undefined) {
            return;
        }

        var handlers = this.handlers;
        each(splitStr(events), function(event) {
            handlers[event] = handlers[event] || [];
            handlers[event].push(handler);
        });
        return this;
    },

    /**
     * unbind event, leave emit blank to remove all handlers
     * @param {String} events
     * @param {Function} [handler]
     * @returns {EventEmitter} this
     */
    off: function(events, handler) {
        if (events === undefined) {
            return;
        }

        var handlers = this.handlers;
        each(splitStr(events), function(event) {
            if (!handler) {
                delete handlers[event];
            } else {
                handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
            }
        });
        return this;
    },

    /**
     * emit event to the listeners
     * @param {String} event
     * @param {Object} data
     */
    emit: function(event, data) {
        // we also want to trigger dom events
        if (this.options.domEvents) {
            triggerDomEvent(event, data);
        }

        // no handlers, so skip it all
        var handlers = this.handlers[event] && this.handlers[event].slice();
        if (!handlers || !handlers.length) {
            return;
        }

        data.type = event;
        data.preventDefault = function() {
            data.srcEvent.preventDefault();
        };

        var i = 0;
        while (i < handlers.length) {
            handlers[i](data);
            i++;
        }
    },

    /**
     * destroy the manager and unbinds all events
     * it doesn't unbind dom events, that is the user own responsibility
     */
    destroy: function() {
        this.element && toggleCssProps(this, false);

        this.handlers = {};
        this.session = {};
        this.input.destroy();
        this.element = null;
    }
};

/**
 * add/remove the css properties as defined in manager.options.cssProps
 * @param {Manager} manager
 * @param {Boolean} add
 */
function toggleCssProps(manager, add) {
    var element = manager.element;
    if (!element.style) {
        return;
    }
    var prop;
    each(manager.options.cssProps, function(value, name) {
        prop = prefixed(element.style, name);
        if (add) {
            manager.oldCssProps[prop] = element.style[prop];
            element.style[prop] = value;
        } else {
            element.style[prop] = manager.oldCssProps[prop] || '';
        }
    });
    if (!add) {
        manager.oldCssProps = {};
    }
}

/**
 * trigger dom event
 * @param {String} event
 * @param {Object} data
 */
function triggerDomEvent(event, data) {
    var gestureEvent = document.createEvent('Event');
    gestureEvent.initEvent(event, true, true);
    gestureEvent.gesture = data;
    data.target.dispatchEvent(gestureEvent);
}

assign(Hammer, {
    INPUT_START: INPUT_START,
    INPUT_MOVE: INPUT_MOVE,
    INPUT_END: INPUT_END,
    INPUT_CANCEL: INPUT_CANCEL,

    STATE_POSSIBLE: STATE_POSSIBLE,
    STATE_BEGAN: STATE_BEGAN,
    STATE_CHANGED: STATE_CHANGED,
    STATE_ENDED: STATE_ENDED,
    STATE_RECOGNIZED: STATE_RECOGNIZED,
    STATE_CANCELLED: STATE_CANCELLED,
    STATE_FAILED: STATE_FAILED,

    DIRECTION_NONE: DIRECTION_NONE,
    DIRECTION_LEFT: DIRECTION_LEFT,
    DIRECTION_RIGHT: DIRECTION_RIGHT,
    DIRECTION_UP: DIRECTION_UP,
    DIRECTION_DOWN: DIRECTION_DOWN,
    DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
    DIRECTION_VERTICAL: DIRECTION_VERTICAL,
    DIRECTION_ALL: DIRECTION_ALL,

    Manager: Manager,
    Input: Input,
    TouchAction: TouchAction,

    TouchInput: TouchInput,
    MouseInput: MouseInput,
    PointerEventInput: PointerEventInput,
    TouchMouseInput: TouchMouseInput,
    SingleTouchInput: SingleTouchInput,

    Recognizer: Recognizer,
    AttrRecognizer: AttrRecognizer,
    Tap: TapRecognizer,
    Pan: PanRecognizer,
    Swipe: SwipeRecognizer,
    Pinch: PinchRecognizer,
    Rotate: RotateRecognizer,
    Press: PressRecognizer,

    on: addEventListeners,
    off: removeEventListeners,
    each: each,
    merge: merge,
    extend: extend,
    assign: assign,
    inherit: inherit,
    bindFn: bindFn,
    prefixed: prefixed
});

// this prevents errors when Hammer is loaded in the presence of an AMD
//  style loader but by script tag, not by the loader.
var freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line
freeGlobal.Hammer = Hammer;

if (typeof define === 'function' && define.amd) {
    define(function() {
        return Hammer;
    });
} else if (typeof module != 'undefined' && module.exports) {
    module.exports = Hammer;
} else {
    window[exportName] = Hammer;
}

})(window, document, 'Hammer');

},{}],346:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

function createCommonjsModule(fn, module) {
  return module = {
    exports: {}
  }, fn(module, module.exports), module.exports;
}

var hat_1 = createCommonjsModule(function (module) {
  var hat = module.exports = function (bits, base) {
    if (!base) base = 16;
    if (bits === undefined) bits = 128;
    if (bits <= 0) return '0';
    var digits = Math.log(Math.pow(2, bits)) / Math.log(base);

    for (var i = 2; digits === Infinity; i *= 2) {
      digits = Math.log(Math.pow(2, bits / i)) / Math.log(base) * i;
    }

    var rem = digits - Math.floor(digits);
    var res = '';

    for (var i = 0; i < Math.floor(digits); i++) {
      var x = Math.floor(Math.random() * base).toString(base);
      res = x + res;
    }

    if (rem) {
      var b = Math.pow(base, rem);
      var x = Math.floor(Math.random() * b).toString(base);
      res = x + res;
    }

    var parsed = parseInt(res, base);

    if (parsed !== Infinity && parsed >= Math.pow(2, bits)) {
      return hat(bits, base);
    } else return res;
  };

  hat.rack = function (bits, base, expandBy) {
    var fn = function (data) {
      var iters = 0;

      do {
        if (iters++ > 10) {
          if (expandBy) bits += expandBy;else throw new Error('too many ID collisions, use more bits');
        }

        var id = hat(bits, base);
      } while (Object.hasOwnProperty.call(hats, id));

      hats[id] = data;
      return id;
    };

    var hats = fn.hats = {};

    fn.get = function (id) {
      return fn.hats[id];
    };

    fn.set = function (id, value) {
      fn.hats[id] = value;
      return fn;
    };

    fn.bits = bits || 128;
    fn.base = base || 16;
    return fn;
  };
});
/**
 * Create a new id generator / cache instance.
 *
 * You may optionally provide a seed that is used internally.
 *
 * @param {Seed} seed
 */

function Ids(seed) {
  if (!(this instanceof Ids)) {
    return new Ids(seed);
  }

  seed = seed || [128, 36, 1];
  this._seed = seed.length ? hat_1.rack(seed[0], seed[1], seed[2]) : seed;
}
/**
 * Generate a next id.
 *
 * @param {Object} [element] element to bind the id to
 *
 * @return {String} id
 */


Ids.prototype.next = function (element) {
  return this._seed(element || true);
};
/**
 * Generate a next id with a given prefix.
 *
 * @param {Object} [element] element to bind the id to
 *
 * @return {String} id
 */


Ids.prototype.nextPrefixed = function (prefix, element) {
  var id;

  do {
    id = prefix + this.next(true);
  } while (this.assigned(id)); // claim {prefix}{random}


  this.claim(id, element); // return

  return id;
};
/**
 * Manually claim an existing id.
 *
 * @param {String} id
 * @param {String} [element] element the id is claimed by
 */


Ids.prototype.claim = function (id, element) {
  this._seed.set(id, element || true);
};
/**
 * Returns true if the given id has already been assigned.
 *
 * @param  {String} id
 * @return {Boolean}
 */


Ids.prototype.assigned = function (id) {
  return this._seed.get(id) || false;
};
/**
 * Unclaim an id.
 *
 * @param  {String} id the id to unclaim
 */


Ids.prototype.unclaim = function (id) {
  delete this._seed.hats[id];
};
/**
 * Clear all claimed ids.
 */


Ids.prototype.clear = function () {
  var hats = this._seed.hats,
      id;

  for (id in hats) {
    this.unclaim(id);
  }
};

var _default = Ids;
exports.default = _default;

},{}],347:[function(require,module,exports){
if (typeof Object.create === 'function') {
  // implementation from standard node.js 'util' module
  module.exports = function inherits(ctor, superCtor) {
    if (superCtor) {
      ctor.super_ = superCtor
      ctor.prototype = Object.create(superCtor.prototype, {
        constructor: {
          value: ctor,
          enumerable: false,
          writable: true,
          configurable: true
        }
      })
    }
  };
} else {
  // old school shim for old browsers
  module.exports = function inherits(ctor, superCtor) {
    if (superCtor) {
      ctor.super_ = superCtor
      var TempCtor = function () {}
      TempCtor.prototype = superCtor.prototype
      ctor.prototype = new TempCtor()
      ctor.prototype.constructor = ctor
    }
  }
}

},{}],348:[function(require,module,exports){
/*!
 * jQuery JavaScript Library v3.5.1
 * https://jquery.com/
 *
 * Includes Sizzle.js
 * https://sizzlejs.com/
 *
 * Copyright JS Foundation and other contributors
 * Released under the MIT license
 * https://jquery.org/license
 *
 * Date: 2020-05-04T22:49Z
 */
( function( global, factory ) {

	"use strict";

	if ( typeof module === "object" && typeof module.exports === "object" ) {

		// For CommonJS and CommonJS-like environments where a proper `window`
		// is present, execute the factory and get jQuery.
		// For environments that do not have a `window` with a `document`
		// (such as Node.js), expose a factory as module.exports.
		// This accentuates the need for the creation of a real `window`.
		// e.g. var jQuery = require("jquery")(window);
		// See ticket #14549 for more info.
		module.exports = global.document ?
			factory( global, true ) :
			function( w ) {
				if ( !w.document ) {
					throw new Error( "jQuery requires a window with a document" );
				}
				return factory( w );
			};
	} else {
		factory( global );
	}

// Pass this if window is not defined yet
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {

// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
// enough that all such attempts are guarded in a try block.
"use strict";

var arr = [];

var getProto = Object.getPrototypeOf;

var slice = arr.slice;

var flat = arr.flat ? function( array ) {
	return arr.flat.call( array );
} : function( array ) {
	return arr.concat.apply( [], array );
};


var push = arr.push;

var indexOf = arr.indexOf;

var class2type = {};

var toString = class2type.toString;

var hasOwn = class2type.hasOwnProperty;

var fnToString = hasOwn.toString;

var ObjectFunctionString = fnToString.call( Object );

var support = {};

var isFunction = function isFunction( obj ) {

      // Support: Chrome <=57, Firefox <=52
      // In some browsers, typeof returns "function" for HTML <object> elements
      // (i.e., `typeof document.createElement( "object" ) === "function"`).
      // We don't want to classify *any* DOM node as a function.
      return typeof obj === "function" && typeof obj.nodeType !== "number";
  };


var isWindow = function isWindow( obj ) {
		return obj != null && obj === obj.window;
	};


var document = window.document;



	var preservedScriptAttributes = {
		type: true,
		src: true,
		nonce: true,
		noModule: true
	};

	function DOMEval( code, node, doc ) {
		doc = doc || document;

		var i, val,
			script = doc.createElement( "script" );

		script.text = code;
		if ( node ) {
			for ( i in preservedScriptAttributes ) {

				// Support: Firefox 64+, Edge 18+
				// Some browsers don't support the "nonce" property on scripts.
				// On the other hand, just using `getAttribute` is not enough as
				// the `nonce` attribute is reset to an empty string whenever it
				// becomes browsing-context connected.
				// See https://github.com/whatwg/html/issues/2369
				// See https://html.spec.whatwg.org/#nonce-attributes
				// The `node.getAttribute` check was added for the sake of
				// `jQuery.globalEval` so that it can fake a nonce-containing node
				// via an object.
				val = node[ i ] || node.getAttribute && node.getAttribute( i );
				if ( val ) {
					script.setAttribute( i, val );
				}
			}
		}
		doc.head.appendChild( script ).parentNode.removeChild( script );
	}


function toType( obj ) {
	if ( obj == null ) {
		return obj + "";
	}

	// Support: Android <=2.3 only (functionish RegExp)
	return typeof obj === "object" || typeof obj === "function" ?
		class2type[ toString.call( obj ) ] || "object" :
		typeof obj;
}
/* global Symbol */
// Defining this global in .eslintrc.json would create a danger of using the global
// unguarded in another place, it seems safer to define global only for this module



var
	version = "3.5.1",

	// Define a local copy of jQuery
	jQuery = function( selector, context ) {

		// The jQuery object is actually just the init constructor 'enhanced'
		// Need init if jQuery is called (just allow error to be thrown if not included)
		return new jQuery.fn.init( selector, context );
	};

jQuery.fn = jQuery.prototype = {

	// The current version of jQuery being used
	jquery: version,

	constructor: jQuery,

	// The default length of a jQuery object is 0
	length: 0,

	toArray: function() {
		return slice.call( this );
	},

	// Get the Nth element in the matched element set OR
	// Get the whole matched element set as a clean array
	get: function( num ) {

		// Return all the elements in a clean array
		if ( num == null ) {
			return slice.call( this );
		}

		// Return just the one element from the set
		return num < 0 ? this[ num + this.length ] : this[ num ];
	},

	// Take an array of elements and push it onto the stack
	// (returning the new matched element set)
	pushStack: function( elems ) {

		// Build a new jQuery matched element set
		var ret = jQuery.merge( this.constructor(), elems );

		// Add the old object onto the stack (as a reference)
		ret.prevObject = this;

		// Return the newly-formed element set
		return ret;
	},

	// Execute a callback for every element in the matched set.
	each: function( callback ) {
		return jQuery.each( this, callback );
	},

	map: function( callback ) {
		return this.pushStack( jQuery.map( this, function( elem, i ) {
			return callback.call( elem, i, elem );
		} ) );
	},

	slice: function() {
		return this.pushStack( slice.apply( this, arguments ) );
	},

	first: function() {
		return this.eq( 0 );
	},

	last: function() {
		return this.eq( -1 );
	},

	even: function() {
		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
			return ( i + 1 ) % 2;
		} ) );
	},

	odd: function() {
		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
			return i % 2;
		} ) );
	},

	eq: function( i ) {
		var len = this.length,
			j = +i + ( i < 0 ? len : 0 );
		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
	},

	end: function() {
		return this.prevObject || this.constructor();
	},

	// For internal use only.
	// Behaves like an Array's method, not like a jQuery method.
	push: push,
	sort: arr.sort,
	splice: arr.splice
};

jQuery.extend = jQuery.fn.extend = function() {
	var options, name, src, copy, copyIsArray, clone,
		target = arguments[ 0 ] || {},
		i = 1,
		length = arguments.length,
		deep = false;

	// Handle a deep copy situation
	if ( typeof target === "boolean" ) {
		deep = target;

		// Skip the boolean and the target
		target = arguments[ i ] || {};
		i++;
	}

	// Handle case when target is a string or something (possible in deep copy)
	if ( typeof target !== "object" && !isFunction( target ) ) {
		target = {};
	}

	// Extend jQuery itself if only one argument is passed
	if ( i === length ) {
		target = this;
		i--;
	}

	for ( ; i < length; i++ ) {

		// Only deal with non-null/undefined values
		if ( ( options = arguments[ i ] ) != null ) {

			// Extend the base object
			for ( name in options ) {
				copy = options[ name ];

				// Prevent Object.prototype pollution
				// Prevent never-ending loop
				if ( name === "__proto__" || target === copy ) {
					continue;
				}

				// Recurse if we're merging plain objects or arrays
				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
					( copyIsArray = Array.isArray( copy ) ) ) ) {
					src = target[ name ];

					// Ensure proper type for the source value
					if ( copyIsArray && !Array.isArray( src ) ) {
						clone = [];
					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
						clone = {};
					} else {
						clone = src;
					}
					copyIsArray = false;

					// Never move original objects, clone them
					target[ name ] = jQuery.extend( deep, clone, copy );

				// Don't bring in undefined values
				} else if ( copy !== undefined ) {
					target[ name ] = copy;
				}
			}
		}
	}

	// Return the modified object
	return target;
};

jQuery.extend( {

	// Unique for each copy of jQuery on the page
	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),

	// Assume jQuery is ready without the ready module
	isReady: true,

	error: function( msg ) {
		throw new Error( msg );
	},

	noop: function() {},

	isPlainObject: function( obj ) {
		var proto, Ctor;

		// Detect obvious negatives
		// Use toString instead of jQuery.type to catch host objects
		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
			return false;
		}

		proto = getProto( obj );

		// Objects with no prototype (e.g., `Object.create( null )`) are plain
		if ( !proto ) {
			return true;
		}

		// Objects with prototype are plain iff they were constructed by a global Object function
		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
	},

	isEmptyObject: function( obj ) {
		var name;

		for ( name in obj ) {
			return false;
		}
		return true;
	},

	// Evaluates a script in a provided context; falls back to the global one
	// if not specified.
	globalEval: function( code, options, doc ) {
		DOMEval( code, { nonce: options && options.nonce }, doc );
	},

	each: function( obj, callback ) {
		var length, i = 0;

		if ( isArrayLike( obj ) ) {
			length = obj.length;
			for ( ; i < length; i++ ) {
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
					break;
				}
			}
		} else {
			for ( i in obj ) {
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
					break;
				}
			}
		}

		return obj;
	},

	// results is for internal usage only
	makeArray: function( arr, results ) {
		var ret = results || [];

		if ( arr != null ) {
			if ( isArrayLike( Object( arr ) ) ) {
				jQuery.merge( ret,
					typeof arr === "string" ?
					[ arr ] : arr
				);
			} else {
				push.call( ret, arr );
			}
		}

		return ret;
	},

	inArray: function( elem, arr, i ) {
		return arr == null ? -1 : indexOf.call( arr, elem, i );
	},

	// Support: Android <=4.0 only, PhantomJS 1 only
	// push.apply(_, arraylike) throws on ancient WebKit
	merge: function( first, second ) {
		var len = +second.length,
			j = 0,
			i = first.length;

		for ( ; j < len; j++ ) {
			first[ i++ ] = second[ j ];
		}

		first.length = i;

		return first;
	},

	grep: function( elems, callback, invert ) {
		var callbackInverse,
			matches = [],
			i = 0,
			length = elems.length,
			callbackExpect = !invert;

		// Go through the array, only saving the items
		// that pass the validator function
		for ( ; i < length; i++ ) {
			callbackInverse = !callback( elems[ i ], i );
			if ( callbackInverse !== callbackExpect ) {
				matches.push( elems[ i ] );
			}
		}

		return matches;
	},

	// arg is for internal usage only
	map: function( elems, callback, arg ) {
		var length, value,
			i = 0,
			ret = [];

		// Go through the array, translating each of the items to their new values
		if ( isArrayLike( elems ) ) {
			length = elems.length;
			for ( ; i < length; i++ ) {
				value = callback( elems[ i ], i, arg );

				if ( value != null ) {
					ret.push( value );
				}
			}

		// Go through every key on the object,
		} else {
			for ( i in elems ) {
				value = callback( elems[ i ], i, arg );

				if ( value != null ) {
					ret.push( value );
				}
			}
		}

		// Flatten any nested arrays
		return flat( ret );
	},

	// A global GUID counter for objects
	guid: 1,

	// jQuery.support is not used in Core but other projects attach their
	// properties to it so it needs to exist.
	support: support
} );

if ( typeof Symbol === "function" ) {
	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
}

// Populate the class2type map
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
function( _i, name ) {
	class2type[ "[object " + name + "]" ] = name.toLowerCase();
} );

function isArrayLike( obj ) {

	// Support: real iOS 8.2 only (not reproducible in simulator)
	// `in` check used to prevent JIT error (gh-2145)
	// hasOwn isn't used here due to false negatives
	// regarding Nodelist length in IE
	var length = !!obj && "length" in obj && obj.length,
		type = toType( obj );

	if ( isFunction( obj ) || isWindow( obj ) ) {
		return false;
	}

	return type === "array" || length === 0 ||
		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}
var Sizzle =
/*!
 * Sizzle CSS Selector Engine v2.3.5
 * https://sizzlejs.com/
 *
 * Copyright JS Foundation and other contributors
 * Released under the MIT license
 * https://js.foundation/
 *
 * Date: 2020-03-14
 */
( function( window ) {
var i,
	support,
	Expr,
	getText,
	isXML,
	tokenize,
	compile,
	select,
	outermostContext,
	sortInput,
	hasDuplicate,

	// Local document vars
	setDocument,
	document,
	docElem,
	documentIsHTML,
	rbuggyQSA,
	rbuggyMatches,
	matches,
	contains,

	// Instance-specific data
	expando = "sizzle" + 1 * new Date(),
	preferredDoc = window.document,
	dirruns = 0,
	done = 0,
	classCache = createCache(),
	tokenCache = createCache(),
	compilerCache = createCache(),
	nonnativeSelectorCache = createCache(),
	sortOrder = function( a, b ) {
		if ( a === b ) {
			hasDuplicate = true;
		}
		return 0;
	},

	// Instance methods
	hasOwn = ( {} ).hasOwnProperty,
	arr = [],
	pop = arr.pop,
	pushNative = arr.push,
	push = arr.push,
	slice = arr.slice,

	// Use a stripped-down indexOf as it's faster than native
	// https://jsperf.com/thor-indexof-vs-for/5
	indexOf = function( list, elem ) {
		var i = 0,
			len = list.length;
		for ( ; i < len; i++ ) {
			if ( list[ i ] === elem ) {
				return i;
			}
		}
		return -1;
	},

	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
		"ismap|loop|multiple|open|readonly|required|scoped",

	// Regular expressions

	// http://www.w3.org/TR/css3-selectors/#whitespace
	whitespace = "[\\x20\\t\\r\\n\\f]",

	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
	identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",

	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +

		// Operator (capture 2)
		"*([*^$|!~]?=)" + whitespace +

		// "Attribute values must be CSS identifiers [capture 5]
		// or strings [capture 3 or capture 4]"
		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
		whitespace + "*\\]",

	pseudos = ":(" + identifier + ")(?:\\((" +

		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
		// 1. quoted (capture 3; capture 4 or capture 5)
		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +

		// 2. simple (capture 6)
		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +

		// 3. anything else (capture 2)
		".*" +
		")\\)|)",

	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
	rwhitespace = new RegExp( whitespace + "+", "g" ),
	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
		whitespace + "+$", "g" ),

	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
		"*" ),
	rdescend = new RegExp( whitespace + "|>" ),

	rpseudo = new RegExp( pseudos ),
	ridentifier = new RegExp( "^" + identifier + "$" ),

	matchExpr = {
		"ID": new RegExp( "^#(" + identifier + ")" ),
		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
		"ATTR": new RegExp( "^" + attributes ),
		"PSEUDO": new RegExp( "^" + pseudos ),
		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
			whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
			whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),

		// For use in libraries implementing .is()
		// We use this for POS matching in `select`
		"needsContext": new RegExp( "^" + whitespace +
			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
			"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
	},

	rhtml = /HTML$/i,
	rinputs = /^(?:input|select|textarea|button)$/i,
	rheader = /^h\d$/i,

	rnative = /^[^{]+\{\s*\[native \w/,

	// Easily-parseable/retrievable ID or TAG or CLASS selectors
	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

	rsibling = /[+~]/,

	// CSS escapes
	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
	funescape = function( escape, nonHex ) {
		var high = "0x" + escape.slice( 1 ) - 0x10000;

		return nonHex ?

			// Strip the backslash prefix from a non-hex escape sequence
			nonHex :

			// Replace a hexadecimal escape sequence with the encoded Unicode code point
			// Support: IE <=11+
			// For values outside the Basic Multilingual Plane (BMP), manually construct a
			// surrogate pair
			high < 0 ?
				String.fromCharCode( high + 0x10000 ) :
				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
	},

	// CSS string/identifier serialization
	// https://drafts.csswg.org/cssom/#common-serializing-idioms
	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
	fcssescape = function( ch, asCodePoint ) {
		if ( asCodePoint ) {

			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
			if ( ch === "\0" ) {
				return "\uFFFD";
			}

			// Control characters and (dependent upon position) numbers get escaped as code points
			return ch.slice( 0, -1 ) + "\\" +
				ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
		}

		// Other potentially-special ASCII characters get backslash-escaped
		return "\\" + ch;
	},

	// Used for iframes
	// See setDocument()
	// Removing the function wrapper causes a "Permission Denied"
	// error in IE
	unloadHandler = function() {
		setDocument();
	},

	inDisabledFieldset = addCombinator(
		function( elem ) {
			return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
		},
		{ dir: "parentNode", next: "legend" }
	);

// Optimize for push.apply( _, NodeList )
try {
	push.apply(
		( arr = slice.call( preferredDoc.childNodes ) ),
		preferredDoc.childNodes
	);

	// Support: Android<4.0
	// Detect silently failing push.apply
	// eslint-disable-next-line no-unused-expressions
	arr[ preferredDoc.childNodes.length ].nodeType;
} catch ( e ) {
	push = { apply: arr.length ?

		// Leverage slice if possible
		function( target, els ) {
			pushNative.apply( target, slice.call( els ) );
		} :

		// Support: IE<9
		// Otherwise append directly
		function( target, els ) {
			var j = target.length,
				i = 0;

			// Can't trust NodeList.length
			while ( ( target[ j++ ] = els[ i++ ] ) ) {}
			target.length = j - 1;
		}
	};
}

function Sizzle( selector, context, results, seed ) {
	var m, i, elem, nid, match, groups, newSelector,
		newContext = context && context.ownerDocument,

		// nodeType defaults to 9, since context defaults to document
		nodeType = context ? context.nodeType : 9;

	results = results || [];

	// Return early from calls with invalid selector or context
	if ( typeof selector !== "string" || !selector ||
		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {

		return results;
	}

	// Try to shortcut find operations (as opposed to filters) in HTML documents
	if ( !seed ) {
		setDocument( context );
		context = context || document;

		if ( documentIsHTML ) {

			// If the selector is sufficiently simple, try using a "get*By*" DOM method
			// (excepting DocumentFragment context, where the methods don't exist)
			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {

				// ID selector
				if ( ( m = match[ 1 ] ) ) {

					// Document context
					if ( nodeType === 9 ) {
						if ( ( elem = context.getElementById( m ) ) ) {

							// Support: IE, Opera, Webkit
							// TODO: identify versions
							// getElementById can match elements by name instead of ID
							if ( elem.id === m ) {
								results.push( elem );
								return results;
							}
						} else {
							return results;
						}

					// Element context
					} else {

						// Support: IE, Opera, Webkit
						// TODO: identify versions
						// getElementById can match elements by name instead of ID
						if ( newContext && ( elem = newContext.getElementById( m ) ) &&
							contains( context, elem ) &&
							elem.id === m ) {

							results.push( elem );
							return results;
						}
					}

				// Type selector
				} else if ( match[ 2 ] ) {
					push.apply( results, context.getElementsByTagName( selector ) );
					return results;

				// Class selector
				} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
					context.getElementsByClassName ) {

					push.apply( results, context.getElementsByClassName( m ) );
					return results;
				}
			}

			// Take advantage of querySelectorAll
			if ( support.qsa &&
				!nonnativeSelectorCache[ selector + " " ] &&
				( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&

				// Support: IE 8 only
				// Exclude object elements
				( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {

				newSelector = selector;
				newContext = context;

				// qSA considers elements outside a scoping root when evaluating child or
				// descendant combinators, which is not what we want.
				// In such cases, we work around the behavior by prefixing every selector in the
				// list with an ID selector referencing the scope context.
				// The technique has to be used as well when a leading combinator is used
				// as such selectors are not recognized by querySelectorAll.
				// Thanks to Andrew Dupont for this technique.
				if ( nodeType === 1 &&
					( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {

					// Expand context for sibling selectors
					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
						context;

					// We can use :scope instead of the ID hack if the browser
					// supports it & if we're not changing the context.
					if ( newContext !== context || !support.scope ) {

						// Capture the context ID, setting it first if necessary
						if ( ( nid = context.getAttribute( "id" ) ) ) {
							nid = nid.replace( rcssescape, fcssescape );
						} else {
							context.setAttribute( "id", ( nid = expando ) );
						}
					}

					// Prefix every selector in the list
					groups = tokenize( selector );
					i = groups.length;
					while ( i-- ) {
						groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
							toSelector( groups[ i ] );
					}
					newSelector = groups.join( "," );
				}

				try {
					push.apply( results,
						newContext.querySelectorAll( newSelector )
					);
					return results;
				} catch ( qsaError ) {
					nonnativeSelectorCache( selector, true );
				} finally {
					if ( nid === expando ) {
						context.removeAttribute( "id" );
					}
				}
			}
		}
	}

	// All others
	return select( selector.replace( rtrim, "$1" ), context, results, seed );
}

/**
 * Create key-value caches of limited size
 * @returns {function(string, object)} Returns the Object data after storing it on itself with
 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
 *	deleting the oldest entry
 */
function createCache() {
	var keys = [];

	function cache( key, value ) {

		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
		if ( keys.push( key + " " ) > Expr.cacheLength ) {

			// Only keep the most recent entries
			delete cache[ keys.shift() ];
		}
		return ( cache[ key + " " ] = value );
	}
	return cache;
}

/**
 * Mark a function for special use by Sizzle
 * @param {Function} fn The function to mark
 */
function markFunction( fn ) {
	fn[ expando ] = true;
	return fn;
}

/**
 * Support testing using an element
 * @param {Function} fn Passed the created element and returns a boolean result
 */
function assert( fn ) {
	var el = document.createElement( "fieldset" );

	try {
		return !!fn( el );
	} catch ( e ) {
		return false;
	} finally {

		// Remove from its parent by default
		if ( el.parentNode ) {
			el.parentNode.removeChild( el );
		}

		// release memory in IE
		el = null;
	}
}

/**
 * Adds the same handler for all of the specified attrs
 * @param {String} attrs Pipe-separated list of attributes
 * @param {Function} handler The method that will be applied
 */
function addHandle( attrs, handler ) {
	var arr = attrs.split( "|" ),
		i = arr.length;

	while ( i-- ) {
		Expr.attrHandle[ arr[ i ] ] = handler;
	}
}

/**
 * Checks document order of two siblings
 * @param {Element} a
 * @param {Element} b
 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
 */
function siblingCheck( a, b ) {
	var cur = b && a,
		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
			a.sourceIndex - b.sourceIndex;

	// Use IE sourceIndex if available on both nodes
	if ( diff ) {
		return diff;
	}

	// Check if b follows a
	if ( cur ) {
		while ( ( cur = cur.nextSibling ) ) {
			if ( cur === b ) {
				return -1;
			}
		}
	}

	return a ? 1 : -1;
}

/**
 * Returns a function to use in pseudos for input types
 * @param {String} type
 */
function createInputPseudo( type ) {
	return function( elem ) {
		var name = elem.nodeName.toLowerCase();
		return name === "input" && elem.type === type;
	};
}

/**
 * Returns a function to use in pseudos for buttons
 * @param {String} type
 */
function createButtonPseudo( type ) {
	return function( elem ) {
		var name = elem.nodeName.toLowerCase();
		return ( name === "input" || name === "button" ) && elem.type === type;
	};
}

/**
 * Returns a function to use in pseudos for :enabled/:disabled
 * @param {Boolean} disabled true for :disabled; false for :enabled
 */
function createDisabledPseudo( disabled ) {

	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
	return function( elem ) {

		// Only certain elements can match :enabled or :disabled
		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
		if ( "form" in elem ) {

			// Check for inherited disabledness on relevant non-disabled elements:
			// * listed form-associated elements in a disabled fieldset
			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
			// * option elements in a disabled optgroup
			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
			// All such elements have a "form" property.
			if ( elem.parentNode && elem.disabled === false ) {

				// Option elements defer to a parent optgroup if present
				if ( "label" in elem ) {
					if ( "label" in elem.parentNode ) {
						return elem.parentNode.disabled === disabled;
					} else {
						return elem.disabled === disabled;
					}
				}

				// Support: IE 6 - 11
				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
				return elem.isDisabled === disabled ||

					// Where there is no isDisabled, check manually
					/* jshint -W018 */
					elem.isDisabled !== !disabled &&
					inDisabledFieldset( elem ) === disabled;
			}

			return elem.disabled === disabled;

		// Try to winnow out elements that can't be disabled before trusting the disabled property.
		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
		// even exist on them, let alone have a boolean value.
		} else if ( "label" in elem ) {
			return elem.disabled === disabled;
		}

		// Remaining elements are neither :enabled nor :disabled
		return false;
	};
}

/**
 * Returns a function to use in pseudos for positionals
 * @param {Function} fn
 */
function createPositionalPseudo( fn ) {
	return markFunction( function( argument ) {
		argument = +argument;
		return markFunction( function( seed, matches ) {
			var j,
				matchIndexes = fn( [], seed.length, argument ),
				i = matchIndexes.length;

			// Match elements found at the specified indexes
			while ( i-- ) {
				if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
					seed[ j ] = !( matches[ j ] = seed[ j ] );
				}
			}
		} );
	} );
}

/**
 * Checks a node for validity as a Sizzle context
 * @param {Element|Object=} context
 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
 */
function testContext( context ) {
	return context && typeof context.getElementsByTagName !== "undefined" && context;
}

// Expose support vars for convenience
support = Sizzle.support = {};

/**
 * Detects XML nodes
 * @param {Element|Object} elem An element or a document
 * @returns {Boolean} True iff elem is a non-HTML XML node
 */
isXML = Sizzle.isXML = function( elem ) {
	var namespace = elem.namespaceURI,
		docElem = ( elem.ownerDocument || elem ).documentElement;

	// Support: IE <=8
	// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
	// https://bugs.jquery.com/ticket/4833
	return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
};

/**
 * Sets document-related variables once based on the current document
 * @param {Element|Object} [doc] An element or document object to use to set the document
 * @returns {Object} Returns the current document
 */
setDocument = Sizzle.setDocument = function( node ) {
	var hasCompare, subWindow,
		doc = node ? node.ownerDocument || node : preferredDoc;

	// Return early if doc is invalid or already selected
	// Support: IE 11+, Edge 17 - 18+
	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	// two documents; shallow comparisons work.
	// eslint-disable-next-line eqeqeq
	if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
		return document;
	}

	// Update global variables
	document = doc;
	docElem = document.documentElement;
	documentIsHTML = !isXML( document );

	// Support: IE 9 - 11+, Edge 12 - 18+
	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
	// Support: IE 11+, Edge 17 - 18+
	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	// two documents; shallow comparisons work.
	// eslint-disable-next-line eqeqeq
	if ( preferredDoc != document &&
		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {

		// Support: IE 11, Edge
		if ( subWindow.addEventListener ) {
			subWindow.addEventListener( "unload", unloadHandler, false );

		// Support: IE 9 - 10 only
		} else if ( subWindow.attachEvent ) {
			subWindow.attachEvent( "onunload", unloadHandler );
		}
	}

	// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
	// Safari 4 - 5 only, Opera <=11.6 - 12.x only
	// IE/Edge & older browsers don't support the :scope pseudo-class.
	// Support: Safari 6.0 only
	// Safari 6.0 supports :scope but it's an alias of :root there.
	support.scope = assert( function( el ) {
		docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
		return typeof el.querySelectorAll !== "undefined" &&
			!el.querySelectorAll( ":scope fieldset div" ).length;
	} );

	/* Attributes
	---------------------------------------------------------------------- */

	// Support: IE<8
	// Verify that getAttribute really returns attributes and not properties
	// (excepting IE8 booleans)
	support.attributes = assert( function( el ) {
		el.className = "i";
		return !el.getAttribute( "className" );
	} );

	/* getElement(s)By*
	---------------------------------------------------------------------- */

	// Check if getElementsByTagName("*") returns only elements
	support.getElementsByTagName = assert( function( el ) {
		el.appendChild( document.createComment( "" ) );
		return !el.getElementsByTagName( "*" ).length;
	} );

	// Support: IE<9
	support.getElementsByClassName = rnative.test( document.getElementsByClassName );

	// Support: IE<10
	// Check if getElementById returns elements by name
	// The broken getElementById methods don't pick up programmatically-set names,
	// so use a roundabout getElementsByName test
	support.getById = assert( function( el ) {
		docElem.appendChild( el ).id = expando;
		return !document.getElementsByName || !document.getElementsByName( expando ).length;
	} );

	// ID filter and find
	if ( support.getById ) {
		Expr.filter[ "ID" ] = function( id ) {
			var attrId = id.replace( runescape, funescape );
			return function( elem ) {
				return elem.getAttribute( "id" ) === attrId;
			};
		};
		Expr.find[ "ID" ] = function( id, context ) {
			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
				var elem = context.getElementById( id );
				return elem ? [ elem ] : [];
			}
		};
	} else {
		Expr.filter[ "ID" ] =  function( id ) {
			var attrId = id.replace( runescape, funescape );
			return function( elem ) {
				var node = typeof elem.getAttributeNode !== "undefined" &&
					elem.getAttributeNode( "id" );
				return node && node.value === attrId;
			};
		};

		// Support: IE 6 - 7 only
		// getElementById is not reliable as a find shortcut
		Expr.find[ "ID" ] = function( id, context ) {
			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
				var node, i, elems,
					elem = context.getElementById( id );

				if ( elem ) {

					// Verify the id attribute
					node = elem.getAttributeNode( "id" );
					if ( node && node.value === id ) {
						return [ elem ];
					}

					// Fall back on getElementsByName
					elems = context.getElementsByName( id );
					i = 0;
					while ( ( elem = elems[ i++ ] ) ) {
						node = elem.getAttributeNode( "id" );
						if ( node && node.value === id ) {
							return [ elem ];
						}
					}
				}

				return [];
			}
		};
	}

	// Tag
	Expr.find[ "TAG" ] = support.getElementsByTagName ?
		function( tag, context ) {
			if ( typeof context.getElementsByTagName !== "undefined" ) {
				return context.getElementsByTagName( tag );

			// DocumentFragment nodes don't have gEBTN
			} else if ( support.qsa ) {
				return context.querySelectorAll( tag );
			}
		} :

		function( tag, context ) {
			var elem,
				tmp = [],
				i = 0,

				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
				results = context.getElementsByTagName( tag );

			// Filter out possible comments
			if ( tag === "*" ) {
				while ( ( elem = results[ i++ ] ) ) {
					if ( elem.nodeType === 1 ) {
						tmp.push( elem );
					}
				}

				return tmp;
			}
			return results;
		};

	// Class
	Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
			return context.getElementsByClassName( className );
		}
	};

	/* QSA/matchesSelector
	---------------------------------------------------------------------- */

	// QSA and matchesSelector support

	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
	rbuggyMatches = [];

	// qSa(:focus) reports false when true (Chrome 21)
	// We allow this because of a bug in IE8/9 that throws an error
	// whenever `document.activeElement` is accessed on an iframe
	// So, we allow :focus to pass through QSA all the time to avoid the IE error
	// See https://bugs.jquery.com/ticket/13378
	rbuggyQSA = [];

	if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {

		// Build QSA regex
		// Regex strategy adopted from Diego Perini
		assert( function( el ) {

			var input;

			// Select is set to empty string on purpose
			// This is to test IE's treatment of not explicitly
			// setting a boolean content attribute,
			// since its presence should be enough
			// https://bugs.jquery.com/ticket/12359
			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
				"<option selected=''></option></select>";

			// Support: IE8, Opera 11-12.16
			// Nothing should be selected when empty strings follow ^= or $= or *=
			// The test attribute must be unknown in Opera but "safe" for WinRT
			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
			if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
			}

			// Support: IE8
			// Boolean attributes and "value" are not treated correctly
			if ( !el.querySelectorAll( "[selected]" ).length ) {
				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
			}

			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
				rbuggyQSA.push( "~=" );
			}

			// Support: IE 11+, Edge 15 - 18+
			// IE 11/Edge don't find elements on a `[name='']` query in some cases.
			// Adding a temporary attribute to the document before the selection works
			// around the issue.
			// Interestingly, IE 10 & older don't seem to have the issue.
			input = document.createElement( "input" );
			input.setAttribute( "name", "" );
			el.appendChild( input );
			if ( !el.querySelectorAll( "[name='']" ).length ) {
				rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
					whitespace + "*(?:''|\"\")" );
			}

			// Webkit/Opera - :checked should return selected option elements
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
			// IE8 throws error here and will not see later tests
			if ( !el.querySelectorAll( ":checked" ).length ) {
				rbuggyQSA.push( ":checked" );
			}

			// Support: Safari 8+, iOS 8+
			// https://bugs.webkit.org/show_bug.cgi?id=136851
			// In-page `selector#id sibling-combinator selector` fails
			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
				rbuggyQSA.push( ".#.+[+~]" );
			}

			// Support: Firefox <=3.6 - 5 only
			// Old Firefox doesn't throw on a badly-escaped identifier.
			el.querySelectorAll( "\\\f" );
			rbuggyQSA.push( "[\\r\\n\\f]" );
		} );

		assert( function( el ) {
			el.innerHTML = "<a href='' disabled='disabled'></a>" +
				"<select disabled='disabled'><option/></select>";

			// Support: Windows 8 Native Apps
			// The type and name attributes are restricted during .innerHTML assignment
			var input = document.createElement( "input" );
			input.setAttribute( "type", "hidden" );
			el.appendChild( input ).setAttribute( "name", "D" );

			// Support: IE8
			// Enforce case-sensitivity of name attribute
			if ( el.querySelectorAll( "[name=d]" ).length ) {
				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
			}

			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
			// IE8 throws error here and will not see later tests
			if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
				rbuggyQSA.push( ":enabled", ":disabled" );
			}

			// Support: IE9-11+
			// IE's :disabled selector does not pick up the children of disabled fieldsets
			docElem.appendChild( el ).disabled = true;
			if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
				rbuggyQSA.push( ":enabled", ":disabled" );
			}

			// Support: Opera 10 - 11 only
			// Opera 10-11 does not throw on post-comma invalid pseudos
			el.querySelectorAll( "*,:x" );
			rbuggyQSA.push( ",.*:" );
		} );
	}

	if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
		docElem.webkitMatchesSelector ||
		docElem.mozMatchesSelector ||
		docElem.oMatchesSelector ||
		docElem.msMatchesSelector ) ) ) ) {

		assert( function( el ) {

			// Check to see if it's possible to do matchesSelector
			// on a disconnected node (IE 9)
			support.disconnectedMatch = matches.call( el, "*" );

			// This should fail with an exception
			// Gecko does not error, returns false instead
			matches.call( el, "[s!='']:x" );
			rbuggyMatches.push( "!=", pseudos );
		} );
	}

	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );

	/* Contains
	---------------------------------------------------------------------- */
	hasCompare = rnative.test( docElem.compareDocumentPosition );

	// Element contains another
	// Purposefully self-exclusive
	// As in, an element does not contain itself
	contains = hasCompare || rnative.test( docElem.contains ) ?
		function( a, b ) {
			var adown = a.nodeType === 9 ? a.documentElement : a,
				bup = b && b.parentNode;
			return a === bup || !!( bup && bup.nodeType === 1 && (
				adown.contains ?
					adown.contains( bup ) :
					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
			) );
		} :
		function( a, b ) {
			if ( b ) {
				while ( ( b = b.parentNode ) ) {
					if ( b === a ) {
						return true;
					}
				}
			}
			return false;
		};

	/* Sorting
	---------------------------------------------------------------------- */

	// Document order sorting
	sortOrder = hasCompare ?
	function( a, b ) {

		// Flag for duplicate removal
		if ( a === b ) {
			hasDuplicate = true;
			return 0;
		}

		// Sort on method existence if only one input has compareDocumentPosition
		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
		if ( compare ) {
			return compare;
		}

		// Calculate position if both inputs belong to the same document
		// Support: IE 11+, Edge 17 - 18+
		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
		// two documents; shallow comparisons work.
		// eslint-disable-next-line eqeqeq
		compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
			a.compareDocumentPosition( b ) :

			// Otherwise we know they are disconnected
			1;

		// Disconnected nodes
		if ( compare & 1 ||
			( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {

			// Choose the first element that is related to our preferred document
			// Support: IE 11+, Edge 17 - 18+
			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
			// two documents; shallow comparisons work.
			// eslint-disable-next-line eqeqeq
			if ( a == document || a.ownerDocument == preferredDoc &&
				contains( preferredDoc, a ) ) {
				return -1;
			}

			// Support: IE 11+, Edge 17 - 18+
			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
			// two documents; shallow comparisons work.
			// eslint-disable-next-line eqeqeq
			if ( b == document || b.ownerDocument == preferredDoc &&
				contains( preferredDoc, b ) ) {
				return 1;
			}

			// Maintain original order
			return sortInput ?
				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
				0;
		}

		return compare & 4 ? -1 : 1;
	} :
	function( a, b ) {

		// Exit early if the nodes are identical
		if ( a === b ) {
			hasDuplicate = true;
			return 0;
		}

		var cur,
			i = 0,
			aup = a.parentNode,
			bup = b.parentNode,
			ap = [ a ],
			bp = [ b ];

		// Parentless nodes are either documents or disconnected
		if ( !aup || !bup ) {

			// Support: IE 11+, Edge 17 - 18+
			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
			// two documents; shallow comparisons work.
			/* eslint-disable eqeqeq */
			return a == document ? -1 :
				b == document ? 1 :
				/* eslint-enable eqeqeq */
				aup ? -1 :
				bup ? 1 :
				sortInput ?
				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
				0;

		// If the nodes are siblings, we can do a quick check
		} else if ( aup === bup ) {
			return siblingCheck( a, b );
		}

		// Otherwise we need full lists of their ancestors for comparison
		cur = a;
		while ( ( cur = cur.parentNode ) ) {
			ap.unshift( cur );
		}
		cur = b;
		while ( ( cur = cur.parentNode ) ) {
			bp.unshift( cur );
		}

		// Walk down the tree looking for a discrepancy
		while ( ap[ i ] === bp[ i ] ) {
			i++;
		}

		return i ?

			// Do a sibling check if the nodes have a common ancestor
			siblingCheck( ap[ i ], bp[ i ] ) :

			// Otherwise nodes in our document sort first
			// Support: IE 11+, Edge 17 - 18+
			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
			// two documents; shallow comparisons work.
			/* eslint-disable eqeqeq */
			ap[ i ] == preferredDoc ? -1 :
			bp[ i ] == preferredDoc ? 1 :
			/* eslint-enable eqeqeq */
			0;
	};

	return document;
};

Sizzle.matches = function( expr, elements ) {
	return Sizzle( expr, null, null, elements );
};

Sizzle.matchesSelector = function( elem, expr ) {
	setDocument( elem );

	if ( support.matchesSelector && documentIsHTML &&
		!nonnativeSelectorCache[ expr + " " ] &&
		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {

		try {
			var ret = matches.call( elem, expr );

			// IE 9's matchesSelector returns false on disconnected nodes
			if ( ret || support.disconnectedMatch ||

				// As well, disconnected nodes are said to be in a document
				// fragment in IE 9
				elem.document && elem.document.nodeType !== 11 ) {
				return ret;
			}
		} catch ( e ) {
			nonnativeSelectorCache( expr, true );
		}
	}

	return Sizzle( expr, document, null, [ elem ] ).length > 0;
};

Sizzle.contains = function( context, elem ) {

	// Set document vars if needed
	// Support: IE 11+, Edge 17 - 18+
	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	// two documents; shallow comparisons work.
	// eslint-disable-next-line eqeqeq
	if ( ( context.ownerDocument || context ) != document ) {
		setDocument( context );
	}
	return contains( context, elem );
};

Sizzle.attr = function( elem, name ) {

	// Set document vars if needed
	// Support: IE 11+, Edge 17 - 18+
	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	// two documents; shallow comparisons work.
	// eslint-disable-next-line eqeqeq
	if ( ( elem.ownerDocument || elem ) != document ) {
		setDocument( elem );
	}

	var fn = Expr.attrHandle[ name.toLowerCase() ],

		// Don't get fooled by Object.prototype properties (jQuery #13807)
		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
			fn( elem, name, !documentIsHTML ) :
			undefined;

	return val !== undefined ?
		val :
		support.attributes || !documentIsHTML ?
			elem.getAttribute( name ) :
			( val = elem.getAttributeNode( name ) ) && val.specified ?
				val.value :
				null;
};

Sizzle.escape = function( sel ) {
	return ( sel + "" ).replace( rcssescape, fcssescape );
};

Sizzle.error = function( msg ) {
	throw new Error( "Syntax error, unrecognized expression: " + msg );
};

/**
 * Document sorting and removing duplicates
 * @param {ArrayLike} results
 */
Sizzle.uniqueSort = function( results ) {
	var elem,
		duplicates = [],
		j = 0,
		i = 0;

	// Unless we *know* we can detect duplicates, assume their presence
	hasDuplicate = !support.detectDuplicates;
	sortInput = !support.sortStable && results.slice( 0 );
	results.sort( sortOrder );

	if ( hasDuplicate ) {
		while ( ( elem = results[ i++ ] ) ) {
			if ( elem === results[ i ] ) {
				j = duplicates.push( i );
			}
		}
		while ( j-- ) {
			results.splice( duplicates[ j ], 1 );
		}
	}

	// Clear input after sorting to release objects
	// See https://github.com/jquery/sizzle/pull/225
	sortInput = null;

	return results;
};

/**
 * Utility function for retrieving the text value of an array of DOM nodes
 * @param {Array|Element} elem
 */
getText = Sizzle.getText = function( elem ) {
	var node,
		ret = "",
		i = 0,
		nodeType = elem.nodeType;

	if ( !nodeType ) {

		// If no nodeType, this is expected to be an array
		while ( ( node = elem[ i++ ] ) ) {

			// Do not traverse comment nodes
			ret += getText( node );
		}
	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {

		// Use textContent for elements
		// innerText usage removed for consistency of new lines (jQuery #11153)
		if ( typeof elem.textContent === "string" ) {
			return elem.textContent;
		} else {

			// Traverse its children
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
				ret += getText( elem );
			}
		}
	} else if ( nodeType === 3 || nodeType === 4 ) {
		return elem.nodeValue;
	}

	// Do not include comment or processing instruction nodes

	return ret;
};

Expr = Sizzle.selectors = {

	// Can be adjusted by the user
	cacheLength: 50,

	createPseudo: markFunction,

	match: matchExpr,

	attrHandle: {},

	find: {},

	relative: {
		">": { dir: "parentNode", first: true },
		" ": { dir: "parentNode" },
		"+": { dir: "previousSibling", first: true },
		"~": { dir: "previousSibling" }
	},

	preFilter: {
		"ATTR": function( match ) {
			match[ 1 ] = match[ 1 ].replace( runescape, funescape );

			// Move the given value to match[3] whether quoted or unquoted
			match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
				match[ 5 ] || "" ).replace( runescape, funescape );

			if ( match[ 2 ] === "~=" ) {
				match[ 3 ] = " " + match[ 3 ] + " ";
			}

			return match.slice( 0, 4 );
		},

		"CHILD": function( match ) {

			/* matches from matchExpr["CHILD"]
				1 type (only|nth|...)
				2 what (child|of-type)
				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
				4 xn-component of xn+y argument ([+-]?\d*n|)
				5 sign of xn-component
				6 x of xn-component
				7 sign of y-component
				8 y of y-component
			*/
			match[ 1 ] = match[ 1 ].toLowerCase();

			if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {

				// nth-* requires argument
				if ( !match[ 3 ] ) {
					Sizzle.error( match[ 0 ] );
				}

				// numeric x and y parameters for Expr.filter.CHILD
				// remember that false/true cast respectively to 0/1
				match[ 4 ] = +( match[ 4 ] ?
					match[ 5 ] + ( match[ 6 ] || 1 ) :
					2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
				match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );

				// other types prohibit arguments
			} else if ( match[ 3 ] ) {
				Sizzle.error( match[ 0 ] );
			}

			return match;
		},

		"PSEUDO": function( match ) {
			var excess,
				unquoted = !match[ 6 ] && match[ 2 ];

			if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
				return null;
			}

			// Accept quoted arguments as-is
			if ( match[ 3 ] ) {
				match[ 2 ] = match[ 4 ] || match[ 5 ] || "";

			// Strip excess characters from unquoted arguments
			} else if ( unquoted && rpseudo.test( unquoted ) &&

				// Get excess from tokenize (recursively)
				( excess = tokenize( unquoted, true ) ) &&

				// advance to the next closing parenthesis
				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {

				// excess is a negative index
				match[ 0 ] = match[ 0 ].slice( 0, excess );
				match[ 2 ] = unquoted.slice( 0, excess );
			}

			// Return only captures needed by the pseudo filter method (type and argument)
			return match.slice( 0, 3 );
		}
	},

	filter: {

		"TAG": function( nodeNameSelector ) {
			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
			return nodeNameSelector === "*" ?
				function() {
					return true;
				} :
				function( elem ) {
					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
				};
		},

		"CLASS": function( className ) {
			var pattern = classCache[ className + " " ];

			return pattern ||
				( pattern = new RegExp( "(^|" + whitespace +
					")" + className + "(" + whitespace + "|$)" ) ) && classCache(
						className, function( elem ) {
							return pattern.test(
								typeof elem.className === "string" && elem.className ||
								typeof elem.getAttribute !== "undefined" &&
									elem.getAttribute( "class" ) ||
								""
							);
				} );
		},

		"ATTR": function( name, operator, check ) {
			return function( elem ) {
				var result = Sizzle.attr( elem, name );

				if ( result == null ) {
					return operator === "!=";
				}
				if ( !operator ) {
					return true;
				}

				result += "";

				/* eslint-disable max-len */

				return operator === "=" ? result === check :
					operator === "!=" ? result !== check :
					operator === "^=" ? check && result.indexOf( check ) === 0 :
					operator === "*=" ? check && result.indexOf( check ) > -1 :
					operator === "$=" ? check && result.slice( -check.length ) === check :
					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
					false;
				/* eslint-enable max-len */

			};
		},

		"CHILD": function( type, what, _argument, first, last ) {
			var simple = type.slice( 0, 3 ) !== "nth",
				forward = type.slice( -4 ) !== "last",
				ofType = what === "of-type";

			return first === 1 && last === 0 ?

				// Shortcut for :nth-*(n)
				function( elem ) {
					return !!elem.parentNode;
				} :

				function( elem, _context, xml ) {
					var cache, uniqueCache, outerCache, node, nodeIndex, start,
						dir = simple !== forward ? "nextSibling" : "previousSibling",
						parent = elem.parentNode,
						name = ofType && elem.nodeName.toLowerCase(),
						useCache = !xml && !ofType,
						diff = false;

					if ( parent ) {

						// :(first|last|only)-(child|of-type)
						if ( simple ) {
							while ( dir ) {
								node = elem;
								while ( ( node = node[ dir ] ) ) {
									if ( ofType ?
										node.nodeName.toLowerCase() === name :
										node.nodeType === 1 ) {

										return false;
									}
								}

								// Reverse direction for :only-* (if we haven't yet done so)
								start = dir = type === "only" && !start && "nextSibling";
							}
							return true;
						}

						start = [ forward ? parent.firstChild : parent.lastChild ];

						// non-xml :nth-child(...) stores cache data on `parent`
						if ( forward && useCache ) {

							// Seek `elem` from a previously-cached index

							// ...in a gzip-friendly way
							node = parent;
							outerCache = node[ expando ] || ( node[ expando ] = {} );

							// Support: IE <9 only
							// Defend against cloned attroperties (jQuery gh-1709)
							uniqueCache = outerCache[ node.uniqueID ] ||
								( outerCache[ node.uniqueID ] = {} );

							cache = uniqueCache[ type ] || [];
							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
							diff = nodeIndex && cache[ 2 ];
							node = nodeIndex && parent.childNodes[ nodeIndex ];

							while ( ( node = ++nodeIndex && node && node[ dir ] ||

								// Fallback to seeking `elem` from the start
								( diff = nodeIndex = 0 ) || start.pop() ) ) {

								// When found, cache indexes on `parent` and break
								if ( node.nodeType === 1 && ++diff && node === elem ) {
									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
									break;
								}
							}

						} else {

							// Use previously-cached element index if available
							if ( useCache ) {

								// ...in a gzip-friendly way
								node = elem;
								outerCache = node[ expando ] || ( node[ expando ] = {} );

								// Support: IE <9 only
								// Defend against cloned attroperties (jQuery gh-1709)
								uniqueCache = outerCache[ node.uniqueID ] ||
									( outerCache[ node.uniqueID ] = {} );

								cache = uniqueCache[ type ] || [];
								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
								diff = nodeIndex;
							}

							// xml :nth-child(...)
							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
							if ( diff === false ) {

								// Use the same loop as above to seek `elem` from the start
								while ( ( node = ++nodeIndex && node && node[ dir ] ||
									( diff = nodeIndex = 0 ) || start.pop() ) ) {

									if ( ( ofType ?
										node.nodeName.toLowerCase() === name :
										node.nodeType === 1 ) &&
										++diff ) {

										// Cache the index of each encountered element
										if ( useCache ) {
											outerCache = node[ expando ] ||
												( node[ expando ] = {} );

											// Support: IE <9 only
											// Defend against cloned attroperties (jQuery gh-1709)
											uniqueCache = outerCache[ node.uniqueID ] ||
												( outerCache[ node.uniqueID ] = {} );

											uniqueCache[ type ] = [ dirruns, diff ];
										}

										if ( node === elem ) {
											break;
										}
									}
								}
							}
						}

						// Incorporate the offset, then check against cycle size
						diff -= last;
						return diff === first || ( diff % first === 0 && diff / first >= 0 );
					}
				};
		},

		"PSEUDO": function( pseudo, argument ) {

			// pseudo-class names are case-insensitive
			// http://www.w3.org/TR/selectors/#pseudo-classes
			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
			// Remember that setFilters inherits from pseudos
			var args,
				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
					Sizzle.error( "unsupported pseudo: " + pseudo );

			// The user may use createPseudo to indicate that
			// arguments are needed to create the filter function
			// just as Sizzle does
			if ( fn[ expando ] ) {
				return fn( argument );
			}

			// But maintain support for old signatures
			if ( fn.length > 1 ) {
				args = [ pseudo, pseudo, "", argument ];
				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
					markFunction( function( seed, matches ) {
						var idx,
							matched = fn( seed, argument ),
							i = matched.length;
						while ( i-- ) {
							idx = indexOf( seed, matched[ i ] );
							seed[ idx ] = !( matches[ idx ] = matched[ i ] );
						}
					} ) :
					function( elem ) {
						return fn( elem, 0, args );
					};
			}

			return fn;
		}
	},

	pseudos: {

		// Potentially complex pseudos
		"not": markFunction( function( selector ) {

			// Trim the selector passed to compile
			// to avoid treating leading and trailing
			// spaces as combinators
			var input = [],
				results = [],
				matcher = compile( selector.replace( rtrim, "$1" ) );

			return matcher[ expando ] ?
				markFunction( function( seed, matches, _context, xml ) {
					var elem,
						unmatched = matcher( seed, null, xml, [] ),
						i = seed.length;

					// Match elements unmatched by `matcher`
					while ( i-- ) {
						if ( ( elem = unmatched[ i ] ) ) {
							seed[ i ] = !( matches[ i ] = elem );
						}
					}
				} ) :
				function( elem, _context, xml ) {
					input[ 0 ] = elem;
					matcher( input, null, xml, results );

					// Don't keep the element (issue #299)
					input[ 0 ] = null;
					return !results.pop();
				};
		} ),

		"has": markFunction( function( selector ) {
			return function( elem ) {
				return Sizzle( selector, elem ).length > 0;
			};
		} ),

		"contains": markFunction( function( text ) {
			text = text.replace( runescape, funescape );
			return function( elem ) {
				return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
			};
		} ),

		// "Whether an element is represented by a :lang() selector
		// is based solely on the element's language value
		// being equal to the identifier C,
		// or beginning with the identifier C immediately followed by "-".
		// The matching of C against the element's language value is performed case-insensitively.
		// The identifier C does not have to be a valid language name."
		// http://www.w3.org/TR/selectors/#lang-pseudo
		"lang": markFunction( function( lang ) {

			// lang value must be a valid identifier
			if ( !ridentifier.test( lang || "" ) ) {
				Sizzle.error( "unsupported lang: " + lang );
			}
			lang = lang.replace( runescape, funescape ).toLowerCase();
			return function( elem ) {
				var elemLang;
				do {
					if ( ( elemLang = documentIsHTML ?
						elem.lang :
						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {

						elemLang = elemLang.toLowerCase();
						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
					}
				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
				return false;
			};
		} ),

		// Miscellaneous
		"target": function( elem ) {
			var hash = window.location && window.location.hash;
			return hash && hash.slice( 1 ) === elem.id;
		},

		"root": function( elem ) {
			return elem === docElem;
		},

		"focus": function( elem ) {
			return elem === document.activeElement &&
				( !document.hasFocus || document.hasFocus() ) &&
				!!( elem.type || elem.href || ~elem.tabIndex );
		},

		// Boolean properties
		"enabled": createDisabledPseudo( false ),
		"disabled": createDisabledPseudo( true ),

		"checked": function( elem ) {

			// In CSS3, :checked should return both checked and selected elements
			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
			var nodeName = elem.nodeName.toLowerCase();
			return ( nodeName === "input" && !!elem.checked ) ||
				( nodeName === "option" && !!elem.selected );
		},

		"selected": function( elem ) {

			// Accessing this property makes selected-by-default
			// options in Safari work properly
			if ( elem.parentNode ) {
				// eslint-disable-next-line no-unused-expressions
				elem.parentNode.selectedIndex;
			}

			return elem.selected === true;
		},

		// Contents
		"empty": function( elem ) {

			// http://www.w3.org/TR/selectors/#empty-pseudo
			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
			//   but not by others (comment: 8; processing instruction: 7; etc.)
			// nodeType < 6 works because attributes (2) do not appear as children
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
				if ( elem.nodeType < 6 ) {
					return false;
				}
			}
			return true;
		},

		"parent": function( elem ) {
			return !Expr.pseudos[ "empty" ]( elem );
		},

		// Element/input types
		"header": function( elem ) {
			return rheader.test( elem.nodeName );
		},

		"input": function( elem ) {
			return rinputs.test( elem.nodeName );
		},

		"button": function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return name === "input" && elem.type === "button" || name === "button";
		},

		"text": function( elem ) {
			var attr;
			return elem.nodeName.toLowerCase() === "input" &&
				elem.type === "text" &&

				// Support: IE<8
				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
				( ( attr = elem.getAttribute( "type" ) ) == null ||
					attr.toLowerCase() === "text" );
		},

		// Position-in-collection
		"first": createPositionalPseudo( function() {
			return [ 0 ];
		} ),

		"last": createPositionalPseudo( function( _matchIndexes, length ) {
			return [ length - 1 ];
		} ),

		"eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
			return [ argument < 0 ? argument + length : argument ];
		} ),

		"even": createPositionalPseudo( function( matchIndexes, length ) {
			var i = 0;
			for ( ; i < length; i += 2 ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		} ),

		"odd": createPositionalPseudo( function( matchIndexes, length ) {
			var i = 1;
			for ( ; i < length; i += 2 ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		} ),

		"lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
			var i = argument < 0 ?
				argument + length :
				argument > length ?
					length :
					argument;
			for ( ; --i >= 0; ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		} ),

		"gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
			var i = argument < 0 ? argument + length : argument;
			for ( ; ++i < length; ) {
				matchIndexes.push( i );
			}
			return matchIndexes;
		} )
	}
};

Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];

// Add button/input type pseudos
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
	Expr.pseudos[ i ] = createInputPseudo( i );
}
for ( i in { submit: true, reset: true } ) {
	Expr.pseudos[ i ] = createButtonPseudo( i );
}

// Easy API for creating new setFilters
function setFilters() {}
setFilters.prototype = Expr.filters = Expr.pseudos;
Expr.setFilters = new setFilters();

tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
	var matched, match, tokens, type,
		soFar, groups, preFilters,
		cached = tokenCache[ selector + " " ];

	if ( cached ) {
		return parseOnly ? 0 : cached.slice( 0 );
	}

	soFar = selector;
	groups = [];
	preFilters = Expr.preFilter;

	while ( soFar ) {

		// Comma and first run
		if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
			if ( match ) {

				// Don't consume trailing commas as valid
				soFar = soFar.slice( match[ 0 ].length ) || soFar;
			}
			groups.push( ( tokens = [] ) );
		}

		matched = false;

		// Combinators
		if ( ( match = rcombinators.exec( soFar ) ) ) {
			matched = match.shift();
			tokens.push( {
				value: matched,

				// Cast descendant combinators to space
				type: match[ 0 ].replace( rtrim, " " )
			} );
			soFar = soFar.slice( matched.length );
		}

		// Filters
		for ( type in Expr.filter ) {
			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
				( match = preFilters[ type ]( match ) ) ) ) {
				matched = match.shift();
				tokens.push( {
					value: matched,
					type: type,
					matches: match
				} );
				soFar = soFar.slice( matched.length );
			}
		}

		if ( !matched ) {
			break;
		}
	}

	// Return the length of the invalid excess
	// if we're just parsing
	// Otherwise, throw an error or return tokens
	return parseOnly ?
		soFar.length :
		soFar ?
			Sizzle.error( selector ) :

			// Cache the tokens
			tokenCache( selector, groups ).slice( 0 );
};

function toSelector( tokens ) {
	var i = 0,
		len = tokens.length,
		selector = "";
	for ( ; i < len; i++ ) {
		selector += tokens[ i ].value;
	}
	return selector;
}

function addCombinator( matcher, combinator, base ) {
	var dir = combinator.dir,
		skip = combinator.next,
		key = skip || dir,
		checkNonElements = base && key === "parentNode",
		doneName = done++;

	return combinator.first ?

		// Check against closest ancestor/preceding element
		function( elem, context, xml ) {
			while ( ( elem = elem[ dir ] ) ) {
				if ( elem.nodeType === 1 || checkNonElements ) {
					return matcher( elem, context, xml );
				}
			}
			return false;
		} :

		// Check against all ancestor/preceding elements
		function( elem, context, xml ) {
			var oldCache, uniqueCache, outerCache,
				newCache = [ dirruns, doneName ];

			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
			if ( xml ) {
				while ( ( elem = elem[ dir ] ) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						if ( matcher( elem, context, xml ) ) {
							return true;
						}
					}
				}
			} else {
				while ( ( elem = elem[ dir ] ) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						outerCache = elem[ expando ] || ( elem[ expando ] = {} );

						// Support: IE <9 only
						// Defend against cloned attroperties (jQuery gh-1709)
						uniqueCache = outerCache[ elem.uniqueID ] ||
							( outerCache[ elem.uniqueID ] = {} );

						if ( skip && skip === elem.nodeName.toLowerCase() ) {
							elem = elem[ dir ] || elem;
						} else if ( ( oldCache = uniqueCache[ key ] ) &&
							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {

							// Assign to newCache so results back-propagate to previous elements
							return ( newCache[ 2 ] = oldCache[ 2 ] );
						} else {

							// Reuse newcache so results back-propagate to previous elements
							uniqueCache[ key ] = newCache;

							// A match means we're done; a fail means we have to keep checking
							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
								return true;
							}
						}
					}
				}
			}
			return false;
		};
}

function elementMatcher( matchers ) {
	return matchers.length > 1 ?
		function( elem, context, xml ) {
			var i = matchers.length;
			while ( i-- ) {
				if ( !matchers[ i ]( elem, context, xml ) ) {
					return false;
				}
			}
			return true;
		} :
		matchers[ 0 ];
}

function multipleContexts( selector, contexts, results ) {
	var i = 0,
		len = contexts.length;
	for ( ; i < len; i++ ) {
		Sizzle( selector, contexts[ i ], results );
	}
	return results;
}

function condense( unmatched, map, filter, context, xml ) {
	var elem,
		newUnmatched = [],
		i = 0,
		len = unmatched.length,
		mapped = map != null;

	for ( ; i < len; i++ ) {
		if ( ( elem = unmatched[ i ] ) ) {
			if ( !filter || filter( elem, context, xml ) ) {
				newUnmatched.push( elem );
				if ( mapped ) {
					map.push( i );
				}
			}
		}
	}

	return newUnmatched;
}

function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
	if ( postFilter && !postFilter[ expando ] ) {
		postFilter = setMatcher( postFilter );
	}
	if ( postFinder && !postFinder[ expando ] ) {
		postFinder = setMatcher( postFinder, postSelector );
	}
	return markFunction( function( seed, results, context, xml ) {
		var temp, i, elem,
			preMap = [],
			postMap = [],
			preexisting = results.length,

			// Get initial elements from seed or context
			elems = seed || multipleContexts(
				selector || "*",
				context.nodeType ? [ context ] : context,
				[]
			),

			// Prefilter to get matcher input, preserving a map for seed-results synchronization
			matcherIn = preFilter && ( seed || !selector ) ?
				condense( elems, preMap, preFilter, context, xml ) :
				elems,

			matcherOut = matcher ?

				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?

					// ...intermediate processing is necessary
					[] :

					// ...otherwise use results directly
					results :
				matcherIn;

		// Find primary matches
		if ( matcher ) {
			matcher( matcherIn, matcherOut, context, xml );
		}

		// Apply postFilter
		if ( postFilter ) {
			temp = condense( matcherOut, postMap );
			postFilter( temp, [], context, xml );

			// Un-match failing elements by moving them back to matcherIn
			i = temp.length;
			while ( i-- ) {
				if ( ( elem = temp[ i ] ) ) {
					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
				}
			}
		}

		if ( seed ) {
			if ( postFinder || preFilter ) {
				if ( postFinder ) {

					// Get the final matcherOut by condensing this intermediate into postFinder contexts
					temp = [];
					i = matcherOut.length;
					while ( i-- ) {
						if ( ( elem = matcherOut[ i ] ) ) {

							// Restore matcherIn since elem is not yet a final match
							temp.push( ( matcherIn[ i ] = elem ) );
						}
					}
					postFinder( null, ( matcherOut = [] ), temp, xml );
				}

				// Move matched elements from seed to results to keep them synchronized
				i = matcherOut.length;
				while ( i-- ) {
					if ( ( elem = matcherOut[ i ] ) &&
						( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {

						seed[ temp ] = !( results[ temp ] = elem );
					}
				}
			}

		// Add elements to results, through postFinder if defined
		} else {
			matcherOut = condense(
				matcherOut === results ?
					matcherOut.splice( preexisting, matcherOut.length ) :
					matcherOut
			);
			if ( postFinder ) {
				postFinder( null, results, matcherOut, xml );
			} else {
				push.apply( results, matcherOut );
			}
		}
	} );
}

function matcherFromTokens( tokens ) {
	var checkContext, matcher, j,
		len = tokens.length,
		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
		implicitRelative = leadingRelative || Expr.relative[ " " ],
		i = leadingRelative ? 1 : 0,

		// The foundational matcher ensures that elements are reachable from top-level context(s)
		matchContext = addCombinator( function( elem ) {
			return elem === checkContext;
		}, implicitRelative, true ),
		matchAnyContext = addCombinator( function( elem ) {
			return indexOf( checkContext, elem ) > -1;
		}, implicitRelative, true ),
		matchers = [ function( elem, context, xml ) {
			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
				( checkContext = context ).nodeType ?
					matchContext( elem, context, xml ) :
					matchAnyContext( elem, context, xml ) );

			// Avoid hanging onto element (issue #299)
			checkContext = null;
			return ret;
		} ];

	for ( ; i < len; i++ ) {
		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
		} else {
			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );

			// Return special upon seeing a positional matcher
			if ( matcher[ expando ] ) {

				// Find the next relative operator (if any) for proper handling
				j = ++i;
				for ( ; j < len; j++ ) {
					if ( Expr.relative[ tokens[ j ].type ] ) {
						break;
					}
				}
				return setMatcher(
					i > 1 && elementMatcher( matchers ),
					i > 1 && toSelector(

					// If the preceding token was a descendant combinator, insert an implicit any-element `*`
					tokens
						.slice( 0, i - 1 )
						.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
					).replace( rtrim, "$1" ),
					matcher,
					i < j && matcherFromTokens( tokens.slice( i, j ) ),
					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
					j < len && toSelector( tokens )
				);
			}
			matchers.push( matcher );
		}
	}

	return elementMatcher( matchers );
}

function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
	var bySet = setMatchers.length > 0,
		byElement = elementMatchers.length > 0,
		superMatcher = function( seed, context, xml, results, outermost ) {
			var elem, j, matcher,
				matchedCount = 0,
				i = "0",
				unmatched = seed && [],
				setMatched = [],
				contextBackup = outermostContext,

				// We must always have either seed elements or outermost context
				elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),

				// Use integer dirruns iff this is the outermost matcher
				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
				len = elems.length;

			if ( outermost ) {

				// Support: IE 11+, Edge 17 - 18+
				// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
				// two documents; shallow comparisons work.
				// eslint-disable-next-line eqeqeq
				outermostContext = context == document || context || outermost;
			}

			// Add elements passing elementMatchers directly to results
			// Support: IE<9, Safari
			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
				if ( byElement && elem ) {
					j = 0;

					// Support: IE 11+, Edge 17 - 18+
					// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
					// two documents; shallow comparisons work.
					// eslint-disable-next-line eqeqeq
					if ( !context && elem.ownerDocument != document ) {
						setDocument( elem );
						xml = !documentIsHTML;
					}
					while ( ( matcher = elementMatchers[ j++ ] ) ) {
						if ( matcher( elem, context || document, xml ) ) {
							results.push( elem );
							break;
						}
					}
					if ( outermost ) {
						dirruns = dirrunsUnique;
					}
				}

				// Track unmatched elements for set filters
				if ( bySet ) {

					// They will have gone through all possible matchers
					if ( ( elem = !matcher && elem ) ) {
						matchedCount--;
					}

					// Lengthen the array for every element, matched or not
					if ( seed ) {
						unmatched.push( elem );
					}
				}
			}

			// `i` is now the count of elements visited above, and adding it to `matchedCount`
			// makes the latter nonnegative.
			matchedCount += i;

			// Apply set filters to unmatched elements
			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
			// no element matchers and no seed.
			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
			// numerically zero.
			if ( bySet && i !== matchedCount ) {
				j = 0;
				while ( ( matcher = setMatchers[ j++ ] ) ) {
					matcher( unmatched, setMatched, context, xml );
				}

				if ( seed ) {

					// Reintegrate element matches to eliminate the need for sorting
					if ( matchedCount > 0 ) {
						while ( i-- ) {
							if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
								setMatched[ i ] = pop.call( results );
							}
						}
					}

					// Discard index placeholder values to get only actual matches
					setMatched = condense( setMatched );
				}

				// Add matches to results
				push.apply( results, setMatched );

				// Seedless set matches succeeding multiple successful matchers stipulate sorting
				if ( outermost && !seed && setMatched.length > 0 &&
					( matchedCount + setMatchers.length ) > 1 ) {

					Sizzle.uniqueSort( results );
				}
			}

			// Override manipulation of globals by nested matchers
			if ( outermost ) {
				dirruns = dirrunsUnique;
				outermostContext = contextBackup;
			}

			return unmatched;
		};

	return bySet ?
		markFunction( superMatcher ) :
		superMatcher;
}

compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
	var i,
		setMatchers = [],
		elementMatchers = [],
		cached = compilerCache[ selector + " " ];

	if ( !cached ) {

		// Generate a function of recursive functions that can be used to check each element
		if ( !match ) {
			match = tokenize( selector );
		}
		i = match.length;
		while ( i-- ) {
			cached = matcherFromTokens( match[ i ] );
			if ( cached[ expando ] ) {
				setMatchers.push( cached );
			} else {
				elementMatchers.push( cached );
			}
		}

		// Cache the compiled function
		cached = compilerCache(
			selector,
			matcherFromGroupMatchers( elementMatchers, setMatchers )
		);

		// Save selector and tokenization
		cached.selector = selector;
	}
	return cached;
};

/**
 * A low-level selection function that works with Sizzle's compiled
 *  selector functions
 * @param {String|Function} selector A selector or a pre-compiled
 *  selector function built with Sizzle.compile
 * @param {Element} context
 * @param {Array} [results]
 * @param {Array} [seed] A set of elements to match against
 */
select = Sizzle.select = function( selector, context, results, seed ) {
	var i, tokens, token, type, find,
		compiled = typeof selector === "function" && selector,
		match = !seed && tokenize( ( selector = compiled.selector || selector ) );

	results = results || [];

	// Try to minimize operations if there is only one selector in the list and no seed
	// (the latter of which guarantees us context)
	if ( match.length === 1 ) {

		// Reduce context if the leading compound selector is an ID
		tokens = match[ 0 ] = match[ 0 ].slice( 0 );
		if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
			context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {

			context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
				.replace( runescape, funescape ), context ) || [] )[ 0 ];
			if ( !context ) {
				return results;

			// Precompiled matchers will still verify ancestry, so step up a level
			} else if ( compiled ) {
				context = context.parentNode;
			}

			selector = selector.slice( tokens.shift().value.length );
		}

		// Fetch a seed set for right-to-left matching
		i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
		while ( i-- ) {
			token = tokens[ i ];

			// Abort if we hit a combinator
			if ( Expr.relative[ ( type = token.type ) ] ) {
				break;
			}
			if ( ( find = Expr.find[ type ] ) ) {

				// Search, expanding context for leading sibling combinators
				if ( ( seed = find(
					token.matches[ 0 ].replace( runescape, funescape ),
					rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
						context
				) ) ) {

					// If seed is empty or no tokens remain, we can return early
					tokens.splice( i, 1 );
					selector = seed.length && toSelector( tokens );
					if ( !selector ) {
						push.apply( results, seed );
						return results;
					}

					break;
				}
			}
		}
	}

	// Compile and execute a filtering function if one is not provided
	// Provide `match` to avoid retokenization if we modified the selector above
	( compiled || compile( selector, match ) )(
		seed,
		context,
		!documentIsHTML,
		results,
		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
	);
	return results;
};

// One-time assignments

// Sort stability
support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;

// Support: Chrome 14-35+
// Always assume duplicates if they aren't passed to the comparison function
support.detectDuplicates = !!hasDuplicate;

// Initialize against the default document
setDocument();

// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
// Detached nodes confoundingly follow *each other*
support.sortDetached = assert( function( el ) {

	// Should return 1, but returns 4 (following)
	return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
} );

// Support: IE<8
// Prevent attribute/property "interpolation"
// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
if ( !assert( function( el ) {
	el.innerHTML = "<a href='#'></a>";
	return el.firstChild.getAttribute( "href" ) === "#";
} ) ) {
	addHandle( "type|href|height|width", function( elem, name, isXML ) {
		if ( !isXML ) {
			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
		}
	} );
}

// Support: IE<9
// Use defaultValue in place of getAttribute("value")
if ( !support.attributes || !assert( function( el ) {
	el.innerHTML = "<input/>";
	el.firstChild.setAttribute( "value", "" );
	return el.firstChild.getAttribute( "value" ) === "";
} ) ) {
	addHandle( "value", function( elem, _name, isXML ) {
		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
			return elem.defaultValue;
		}
	} );
}

// Support: IE<9
// Use getAttributeNode to fetch booleans when getAttribute lies
if ( !assert( function( el ) {
	return el.getAttribute( "disabled" ) == null;
} ) ) {
	addHandle( booleans, function( elem, name, isXML ) {
		var val;
		if ( !isXML ) {
			return elem[ name ] === true ? name.toLowerCase() :
				( val = elem.getAttributeNode( name ) ) && val.specified ?
					val.value :
					null;
		}
	} );
}

return Sizzle;

} )( window );



jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;

// Deprecated
jQuery.expr[ ":" ] = jQuery.expr.pseudos;
jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
jQuery.escapeSelector = Sizzle.escape;




var dir = function( elem, dir, until ) {
	var matched = [],
		truncate = until !== undefined;

	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
		if ( elem.nodeType === 1 ) {
			if ( truncate && jQuery( elem ).is( until ) ) {
				break;
			}
			matched.push( elem );
		}
	}
	return matched;
};


var siblings = function( n, elem ) {
	var matched = [];

	for ( ; n; n = n.nextSibling ) {
		if ( n.nodeType === 1 && n !== elem ) {
			matched.push( n );
		}
	}

	return matched;
};


var rneedsContext = jQuery.expr.match.needsContext;



function nodeName( elem, name ) {

  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();

};
var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );



// Implement the identical functionality for filter and not
function winnow( elements, qualifier, not ) {
	if ( isFunction( qualifier ) ) {
		return jQuery.grep( elements, function( elem, i ) {
			return !!qualifier.call( elem, i, elem ) !== not;
		} );
	}

	// Single element
	if ( qualifier.nodeType ) {
		return jQuery.grep( elements, function( elem ) {
			return ( elem === qualifier ) !== not;
		} );
	}

	// Arraylike of elements (jQuery, arguments, Array)
	if ( typeof qualifier !== "string" ) {
		return jQuery.grep( elements, function( elem ) {
			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
		} );
	}

	// Filtered directly for both simple and complex selectors
	return jQuery.filter( qualifier, elements, not );
}

jQuery.filter = function( expr, elems, not ) {
	var elem = elems[ 0 ];

	if ( not ) {
		expr = ":not(" + expr + ")";
	}

	if ( elems.length === 1 && elem.nodeType === 1 ) {
		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
	}

	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
		return elem.nodeType === 1;
	} ) );
};

jQuery.fn.extend( {
	find: function( selector ) {
		var i, ret,
			len = this.length,
			self = this;

		if ( typeof selector !== "string" ) {
			return this.pushStack( jQuery( selector ).filter( function() {
				for ( i = 0; i < len; i++ ) {
					if ( jQuery.contains( self[ i ], this ) ) {
						return true;
					}
				}
			} ) );
		}

		ret = this.pushStack( [] );

		for ( i = 0; i < len; i++ ) {
			jQuery.find( selector, self[ i ], ret );
		}

		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
	},
	filter: function( selector ) {
		return this.pushStack( winnow( this, selector || [], false ) );
	},
	not: function( selector ) {
		return this.pushStack( winnow( this, selector || [], true ) );
	},
	is: function( selector ) {
		return !!winnow(
			this,

			// If this is a positional/relative selector, check membership in the returned set
			// so $("p:first").is("p:last") won't return true for a doc with two "p".
			typeof selector === "string" && rneedsContext.test( selector ) ?
				jQuery( selector ) :
				selector || [],
			false
		).length;
	}
} );


// Initialize a jQuery object


// A central reference to the root jQuery(document)
var rootjQuery,

	// A simple way to check for HTML strings
	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
	// Strict HTML recognition (#11290: must start with <)
	// Shortcut simple #id case for speed
	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,

	init = jQuery.fn.init = function( selector, context, root ) {
		var match, elem;

		// HANDLE: $(""), $(null), $(undefined), $(false)
		if ( !selector ) {
			return this;
		}

		// Method init() accepts an alternate rootjQuery
		// so migrate can support jQuery.sub (gh-2101)
		root = root || rootjQuery;

		// Handle HTML strings
		if ( typeof selector === "string" ) {
			if ( selector[ 0 ] === "<" &&
				selector[ selector.length - 1 ] === ">" &&
				selector.length >= 3 ) {

				// Assume that strings that start and end with <> are HTML and skip the regex check
				match = [ null, selector, null ];

			} else {
				match = rquickExpr.exec( selector );
			}

			// Match html or make sure no context is specified for #id
			if ( match && ( match[ 1 ] || !context ) ) {

				// HANDLE: $(html) -> $(array)
				if ( match[ 1 ] ) {
					context = context instanceof jQuery ? context[ 0 ] : context;

					// Option to run scripts is true for back-compat
					// Intentionally let the error be thrown if parseHTML is not present
					jQuery.merge( this, jQuery.parseHTML(
						match[ 1 ],
						context && context.nodeType ? context.ownerDocument || context : document,
						true
					) );

					// HANDLE: $(html, props)
					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
						for ( match in context ) {

							// Properties of context are called as methods if possible
							if ( isFunction( this[ match ] ) ) {
								this[ match ]( context[ match ] );

							// ...and otherwise set as attributes
							} else {
								this.attr( match, context[ match ] );
							}
						}
					}

					return this;

				// HANDLE: $(#id)
				} else {
					elem = document.getElementById( match[ 2 ] );

					if ( elem ) {

						// Inject the element directly into the jQuery object
						this[ 0 ] = elem;
						this.length = 1;
					}
					return this;
				}

			// HANDLE: $(expr, $(...))
			} else if ( !context || context.jquery ) {
				return ( context || root ).find( selector );

			// HANDLE: $(expr, context)
			// (which is just equivalent to: $(context).find(expr)
			} else {
				return this.constructor( context ).find( selector );
			}

		// HANDLE: $(DOMElement)
		} else if ( selector.nodeType ) {
			this[ 0 ] = selector;
			this.length = 1;
			return this;

		// HANDLE: $(function)
		// Shortcut for document ready
		} else if ( isFunction( selector ) ) {
			return root.ready !== undefined ?
				root.ready( selector ) :

				// Execute immediately if ready is not present
				selector( jQuery );
		}

		return jQuery.makeArray( selector, this );
	};

// Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;

// Initialize central reference
rootjQuery = jQuery( document );


var rparentsprev = /^(?:parents|prev(?:Until|All))/,

	// Methods guaranteed to produce a unique set when starting from a unique set
	guaranteedUnique = {
		children: true,
		contents: true,
		next: true,
		prev: true
	};

jQuery.fn.extend( {
	has: function( target ) {
		var targets = jQuery( target, this ),
			l = targets.length;

		return this.filter( function() {
			var i = 0;
			for ( ; i < l; i++ ) {
				if ( jQuery.contains( this, targets[ i ] ) ) {
					return true;
				}
			}
		} );
	},

	closest: function( selectors, context ) {
		var cur,
			i = 0,
			l = this.length,
			matched = [],
			targets = typeof selectors !== "string" && jQuery( selectors );

		// Positional selectors never match, since there's no _selection_ context
		if ( !rneedsContext.test( selectors ) ) {
			for ( ; i < l; i++ ) {
				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {

					// Always skip document fragments
					if ( cur.nodeType < 11 && ( targets ?
						targets.index( cur ) > -1 :

						// Don't pass non-elements to Sizzle
						cur.nodeType === 1 &&
							jQuery.find.matchesSelector( cur, selectors ) ) ) {

						matched.push( cur );
						break;
					}
				}
			}
		}

		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
	},

	// Determine the position of an element within the set
	index: function( elem ) {

		// No argument, return index in parent
		if ( !elem ) {
			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
		}

		// Index in selector
		if ( typeof elem === "string" ) {
			return indexOf.call( jQuery( elem ), this[ 0 ] );
		}

		// Locate the position of the desired element
		return indexOf.call( this,

			// If it receives a jQuery object, the first element is used
			elem.jquery ? elem[ 0 ] : elem
		);
	},

	add: function( selector, context ) {
		return this.pushStack(
			jQuery.uniqueSort(
				jQuery.merge( this.get(), jQuery( selector, context ) )
			)
		);
	},

	addBack: function( selector ) {
		return this.add( selector == null ?
			this.prevObject : this.prevObject.filter( selector )
		);
	}
} );

function sibling( cur, dir ) {
	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
	return cur;
}

jQuery.each( {
	parent: function( elem ) {
		var parent = elem.parentNode;
		return parent && parent.nodeType !== 11 ? parent : null;
	},
	parents: function( elem ) {
		return dir( elem, "parentNode" );
	},
	parentsUntil: function( elem, _i, until ) {
		return dir( elem, "parentNode", until );
	},
	next: function( elem ) {
		return sibling( elem, "nextSibling" );
	},
	prev: function( elem ) {
		return sibling( elem, "previousSibling" );
	},
	nextAll: function( elem ) {
		return dir( elem, "nextSibling" );
	},
	prevAll: function( elem ) {
		return dir( elem, "previousSibling" );
	},
	nextUntil: function( elem, _i, until ) {
		return dir( elem, "nextSibling", until );
	},
	prevUntil: function( elem, _i, until ) {
		return dir( elem, "previousSibling", until );
	},
	siblings: function( elem ) {
		return siblings( ( elem.parentNode || {} ).firstChild, elem );
	},
	children: function( elem ) {
		return siblings( elem.firstChild );
	},
	contents: function( elem ) {
		if ( elem.contentDocument != null &&

			// Support: IE 11+
			// <object> elements with no `data` attribute has an object
			// `contentDocument` with a `null` prototype.
			getProto( elem.contentDocument ) ) {

			return elem.contentDocument;
		}

		// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
		// Treat the template element as a regular one in browsers that
		// don't support it.
		if ( nodeName( elem, "template" ) ) {
			elem = elem.content || elem;
		}

		return jQuery.merge( [], elem.childNodes );
	}
}, function( name, fn ) {
	jQuery.fn[ name ] = function( until, selector ) {
		var matched = jQuery.map( this, fn, until );

		if ( name.slice( -5 ) !== "Until" ) {
			selector = until;
		}

		if ( selector && typeof selector === "string" ) {
			matched = jQuery.filter( selector, matched );
		}

		if ( this.length > 1 ) {

			// Remove duplicates
			if ( !guaranteedUnique[ name ] ) {
				jQuery.uniqueSort( matched );
			}

			// Reverse order for parents* and prev-derivatives
			if ( rparentsprev.test( name ) ) {
				matched.reverse();
			}
		}

		return this.pushStack( matched );
	};
} );
var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );



// Convert String-formatted options into Object-formatted ones
function createOptions( options ) {
	var object = {};
	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
		object[ flag ] = true;
	} );
	return object;
}

/*
 * Create a callback list using the following parameters:
 *
 *	options: an optional list of space-separated options that will change how
 *			the callback list behaves or a more traditional option object
 *
 * By default a callback list will act like an event callback list and can be
 * "fired" multiple times.
 *
 * Possible options:
 *
 *	once:			will ensure the callback list can only be fired once (like a Deferred)
 *
 *	memory:			will keep track of previous values and will call any callback added
 *					after the list has been fired right away with the latest "memorized"
 *					values (like a Deferred)
 *
 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
 *
 *	stopOnFalse:	interrupt callings when a callback returns false
 *
 */
jQuery.Callbacks = function( options ) {

	// Convert options from String-formatted to Object-formatted if needed
	// (we check in cache first)
	options = typeof options === "string" ?
		createOptions( options ) :
		jQuery.extend( {}, options );

	var // Flag to know if list is currently firing
		firing,

		// Last fire value for non-forgettable lists
		memory,

		// Flag to know if list was already fired
		fired,

		// Flag to prevent firing
		locked,

		// Actual callback list
		list = [],

		// Queue of execution data for repeatable lists
		queue = [],

		// Index of currently firing callback (modified by add/remove as needed)
		firingIndex = -1,

		// Fire callbacks
		fire = function() {

			// Enforce single-firing
			locked = locked || options.once;

			// Execute callbacks for all pending executions,
			// respecting firingIndex overrides and runtime changes
			fired = firing = true;
			for ( ; queue.length; firingIndex = -1 ) {
				memory = queue.shift();
				while ( ++firingIndex < list.length ) {

					// Run callback and check for early termination
					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
						options.stopOnFalse ) {

						// Jump to end and forget the data so .add doesn't re-fire
						firingIndex = list.length;
						memory = false;
					}
				}
			}

			// Forget the data if we're done with it
			if ( !options.memory ) {
				memory = false;
			}

			firing = false;

			// Clean up if we're done firing for good
			if ( locked ) {

				// Keep an empty list if we have data for future add calls
				if ( memory ) {
					list = [];

				// Otherwise, this object is spent
				} else {
					list = "";
				}
			}
		},

		// Actual Callbacks object
		self = {

			// Add a callback or a collection of callbacks to the list
			add: function() {
				if ( list ) {

					// If we have memory from a past run, we should fire after adding
					if ( memory && !firing ) {
						firingIndex = list.length - 1;
						queue.push( memory );
					}

					( function add( args ) {
						jQuery.each( args, function( _, arg ) {
							if ( isFunction( arg ) ) {
								if ( !options.unique || !self.has( arg ) ) {
									list.push( arg );
								}
							} else if ( arg && arg.length && toType( arg ) !== "string" ) {

								// Inspect recursively
								add( arg );
							}
						} );
					} )( arguments );

					if ( memory && !firing ) {
						fire();
					}
				}
				return this;
			},

			// Remove a callback from the list
			remove: function() {
				jQuery.each( arguments, function( _, arg ) {
					var index;
					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
						list.splice( index, 1 );

						// Handle firing indexes
						if ( index <= firingIndex ) {
							firingIndex--;
						}
					}
				} );
				return this;
			},

			// Check if a given callback is in the list.
			// If no argument is given, return whether or not list has callbacks attached.
			has: function( fn ) {
				return fn ?
					jQuery.inArray( fn, list ) > -1 :
					list.length > 0;
			},

			// Remove all callbacks from the list
			empty: function() {
				if ( list ) {
					list = [];
				}
				return this;
			},

			// Disable .fire and .add
			// Abort any current/pending executions
			// Clear all callbacks and values
			disable: function() {
				locked = queue = [];
				list = memory = "";
				return this;
			},
			disabled: function() {
				return !list;
			},

			// Disable .fire
			// Also disable .add unless we have memory (since it would have no effect)
			// Abort any pending executions
			lock: function() {
				locked = queue = [];
				if ( !memory && !firing ) {
					list = memory = "";
				}
				return this;
			},
			locked: function() {
				return !!locked;
			},

			// Call all callbacks with the given context and arguments
			fireWith: function( context, args ) {
				if ( !locked ) {
					args = args || [];
					args = [ context, args.slice ? args.slice() : args ];
					queue.push( args );
					if ( !firing ) {
						fire();
					}
				}
				return this;
			},

			// Call all the callbacks with the given arguments
			fire: function() {
				self.fireWith( this, arguments );
				return this;
			},

			// To know if the callbacks have already been called at least once
			fired: function() {
				return !!fired;
			}
		};

	return self;
};


function Identity( v ) {
	return v;
}
function Thrower( ex ) {
	throw ex;
}

function adoptValue( value, resolve, reject, noValue ) {
	var method;

	try {

		// Check for promise aspect first to privilege synchronous behavior
		if ( value && isFunction( ( method = value.promise ) ) ) {
			method.call( value ).done( resolve ).fail( reject );

		// Other thenables
		} else if ( value && isFunction( ( method = value.then ) ) ) {
			method.call( value, resolve, reject );

		// Other non-thenables
		} else {

			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
			// * false: [ value ].slice( 0 ) => resolve( value )
			// * true: [ value ].slice( 1 ) => resolve()
			resolve.apply( undefined, [ value ].slice( noValue ) );
		}

	// For Promises/A+, convert exceptions into rejections
	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
	// Deferred#then to conditionally suppress rejection.
	} catch ( value ) {

		// Support: Android 4.0 only
		// Strict mode functions invoked without .call/.apply get global-object context
		reject.apply( undefined, [ value ] );
	}
}

jQuery.extend( {

	Deferred: function( func ) {
		var tuples = [

				// action, add listener, callbacks,
				// ... .then handlers, argument index, [final state]
				[ "notify", "progress", jQuery.Callbacks( "memory" ),
					jQuery.Callbacks( "memory" ), 2 ],
				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
			],
			state = "pending",
			promise = {
				state: function() {
					return state;
				},
				always: function() {
					deferred.done( arguments ).fail( arguments );
					return this;
				},
				"catch": function( fn ) {
					return promise.then( null, fn );
				},

				// Keep pipe for back-compat
				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
					var fns = arguments;

					return jQuery.Deferred( function( newDefer ) {
						jQuery.each( tuples, function( _i, tuple ) {

							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];

							// deferred.progress(function() { bind to newDefer or newDefer.notify })
							// deferred.done(function() { bind to newDefer or newDefer.resolve })
							// deferred.fail(function() { bind to newDefer or newDefer.reject })
							deferred[ tuple[ 1 ] ]( function() {
								var returned = fn && fn.apply( this, arguments );
								if ( returned && isFunction( returned.promise ) ) {
									returned.promise()
										.progress( newDefer.notify )
										.done( newDefer.resolve )
										.fail( newDefer.reject );
								} else {
									newDefer[ tuple[ 0 ] + "With" ](
										this,
										fn ? [ returned ] : arguments
									);
								}
							} );
						} );
						fns = null;
					} ).promise();
				},
				then: function( onFulfilled, onRejected, onProgress ) {
					var maxDepth = 0;
					function resolve( depth, deferred, handler, special ) {
						return function() {
							var that = this,
								args = arguments,
								mightThrow = function() {
									var returned, then;

									// Support: Promises/A+ section 2.3.3.3.3
									// https://promisesaplus.com/#point-59
									// Ignore double-resolution attempts
									if ( depth < maxDepth ) {
										return;
									}

									returned = handler.apply( that, args );

									// Support: Promises/A+ section 2.3.1
									// https://promisesaplus.com/#point-48
									if ( returned === deferred.promise() ) {
										throw new TypeError( "Thenable self-resolution" );
									}

									// Support: Promises/A+ sections 2.3.3.1, 3.5
									// https://promisesaplus.com/#point-54
									// https://promisesaplus.com/#point-75
									// Retrieve `then` only once
									then = returned &&

										// Support: Promises/A+ section 2.3.4
										// https://promisesaplus.com/#point-64
										// Only check objects and functions for thenability
										( typeof returned === "object" ||
											typeof returned === "function" ) &&
										returned.then;

									// Handle a returned thenable
									if ( isFunction( then ) ) {

										// Special processors (notify) just wait for resolution
										if ( special ) {
											then.call(
												returned,
												resolve( maxDepth, deferred, Identity, special ),
												resolve( maxDepth, deferred, Thrower, special )
											);

										// Normal processors (resolve) also hook into progress
										} else {

											// ...and disregard older resolution values
											maxDepth++;

											then.call(
												returned,
												resolve( maxDepth, deferred, Identity, special ),
												resolve( maxDepth, deferred, Thrower, special ),
												resolve( maxDepth, deferred, Identity,
													deferred.notifyWith )
											);
										}

									// Handle all other returned values
									} else {

										// Only substitute handlers pass on context
										// and multiple values (non-spec behavior)
										if ( handler !== Identity ) {
											that = undefined;
											args = [ returned ];
										}

										// Process the value(s)
										// Default process is resolve
										( special || deferred.resolveWith )( that, args );
									}
								},

								// Only normal processors (resolve) catch and reject exceptions
								process = special ?
									mightThrow :
									function() {
										try {
											mightThrow();
										} catch ( e ) {

											if ( jQuery.Deferred.exceptionHook ) {
												jQuery.Deferred.exceptionHook( e,
													process.stackTrace );
											}

											// Support: Promises/A+ section 2.3.3.3.4.1
											// https://promisesaplus.com/#point-61
											// Ignore post-resolution exceptions
											if ( depth + 1 >= maxDepth ) {

												// Only substitute handlers pass on context
												// and multiple values (non-spec behavior)
												if ( handler !== Thrower ) {
													that = undefined;
													args = [ e ];
												}

												deferred.rejectWith( that, args );
											}
										}
									};

							// Support: Promises/A+ section 2.3.3.3.1
							// https://promisesaplus.com/#point-57
							// Re-resolve promises immediately to dodge false rejection from
							// subsequent errors
							if ( depth ) {
								process();
							} else {

								// Call an optional hook to record the stack, in case of exception
								// since it's otherwise lost when execution goes async
								if ( jQuery.Deferred.getStackHook ) {
									process.stackTrace = jQuery.Deferred.getStackHook();
								}
								window.setTimeout( process );
							}
						};
					}

					return jQuery.Deferred( function( newDefer ) {

						// progress_handlers.add( ... )
						tuples[ 0 ][ 3 ].add(
							resolve(
								0,
								newDefer,
								isFunction( onProgress ) ?
									onProgress :
									Identity,
								newDefer.notifyWith
							)
						);

						// fulfilled_handlers.add( ... )
						tuples[ 1 ][ 3 ].add(
							resolve(
								0,
								newDefer,
								isFunction( onFulfilled ) ?
									onFulfilled :
									Identity
							)
						);

						// rejected_handlers.add( ... )
						tuples[ 2 ][ 3 ].add(
							resolve(
								0,
								newDefer,
								isFunction( onRejected ) ?
									onRejected :
									Thrower
							)
						);
					} ).promise();
				},

				// Get a promise for this deferred
				// If obj is provided, the promise aspect is added to the object
				promise: function( obj ) {
					return obj != null ? jQuery.extend( obj, promise ) : promise;
				}
			},
			deferred = {};

		// Add list-specific methods
		jQuery.each( tuples, function( i, tuple ) {
			var list = tuple[ 2 ],
				stateString = tuple[ 5 ];

			// promise.progress = list.add
			// promise.done = list.add
			// promise.fail = list.add
			promise[ tuple[ 1 ] ] = list.add;

			// Handle state
			if ( stateString ) {
				list.add(
					function() {

						// state = "resolved" (i.e., fulfilled)
						// state = "rejected"
						state = stateString;
					},

					// rejected_callbacks.disable
					// fulfilled_callbacks.disable
					tuples[ 3 - i ][ 2 ].disable,

					// rejected_handlers.disable
					// fulfilled_handlers.disable
					tuples[ 3 - i ][ 3 ].disable,

					// progress_callbacks.lock
					tuples[ 0 ][ 2 ].lock,

					// progress_handlers.lock
					tuples[ 0 ][ 3 ].lock
				);
			}

			// progress_handlers.fire
			// fulfilled_handlers.fire
			// rejected_handlers.fire
			list.add( tuple[ 3 ].fire );

			// deferred.notify = function() { deferred.notifyWith(...) }
			// deferred.resolve = function() { deferred.resolveWith(...) }
			// deferred.reject = function() { deferred.rejectWith(...) }
			deferred[ tuple[ 0 ] ] = function() {
				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
				return this;
			};

			// deferred.notifyWith = list.fireWith
			// deferred.resolveWith = list.fireWith
			// deferred.rejectWith = list.fireWith
			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
		} );

		// Make the deferred a promise
		promise.promise( deferred );

		// Call given func if any
		if ( func ) {
			func.call( deferred, deferred );
		}

		// All done!
		return deferred;
	},

	// Deferred helper
	when: function( singleValue ) {
		var

			// count of uncompleted subordinates
			remaining = arguments.length,

			// count of unprocessed arguments
			i = remaining,

			// subordinate fulfillment data
			resolveContexts = Array( i ),
			resolveValues = slice.call( arguments ),

			// the master Deferred
			master = jQuery.Deferred(),

			// subordinate callback factory
			updateFunc = function( i ) {
				return function( value ) {
					resolveContexts[ i ] = this;
					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
					if ( !( --remaining ) ) {
						master.resolveWith( resolveContexts, resolveValues );
					}
				};
			};

		// Single- and empty arguments are adopted like Promise.resolve
		if ( remaining <= 1 ) {
			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
				!remaining );

			// Use .then() to unwrap secondary thenables (cf. gh-3000)
			if ( master.state() === "pending" ||
				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {

				return master.then();
			}
		}

		// Multiple arguments are aggregated like Promise.all array elements
		while ( i-- ) {
			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
		}

		return master.promise();
	}
} );


// These usually indicate a programmer mistake during development,
// warn about them ASAP rather than swallowing them by default.
var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;

jQuery.Deferred.exceptionHook = function( error, stack ) {

	// Support: IE 8 - 9 only
	// Console exists when dev tools are open, which can happen at any time
	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
	}
};




jQuery.readyException = function( error ) {
	window.setTimeout( function() {
		throw error;
	} );
};




// The deferred used on DOM ready
var readyList = jQuery.Deferred();

jQuery.fn.ready = function( fn ) {

	readyList
		.then( fn )

		// Wrap jQuery.readyException in a function so that the lookup
		// happens at the time of error handling instead of callback
		// registration.
		.catch( function( error ) {
			jQuery.readyException( error );
		} );

	return this;
};

jQuery.extend( {

	// Is the DOM ready to be used? Set to true once it occurs.
	isReady: false,

	// A counter to track how many items to wait for before
	// the ready event fires. See #6781
	readyWait: 1,

	// Handle when the DOM is ready
	ready: function( wait ) {

		// Abort if there are pending holds or we're already ready
		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
			return;
		}

		// Remember that the DOM is ready
		jQuery.isReady = true;

		// If a normal DOM Ready event fired, decrement, and wait if need be
		if ( wait !== true && --jQuery.readyWait > 0 ) {
			return;
		}

		// If there are functions bound, to execute
		readyList.resolveWith( document, [ jQuery ] );
	}
} );

jQuery.ready.then = readyList.then;

// The ready event handler and self cleanup method
function completed() {
	document.removeEventListener( "DOMContentLoaded", completed );
	window.removeEventListener( "load", completed );
	jQuery.ready();
}

// Catch cases where $(document).ready() is called
// after the browser event has already occurred.
// Support: IE <=9 - 10 only
// Older IE sometimes signals "interactive" too soon
if ( document.readyState === "complete" ||
	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {

	// Handle it asynchronously to allow scripts the opportunity to delay ready
	window.setTimeout( jQuery.ready );

} else {

	// Use the handy event callback
	document.addEventListener( "DOMContentLoaded", completed );

	// A fallback to window.onload, that will always work
	window.addEventListener( "load", completed );
}




// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
	var i = 0,
		len = elems.length,
		bulk = key == null;

	// Sets many values
	if ( toType( key ) === "object" ) {
		chainable = true;
		for ( i in key ) {
			access( elems, fn, i, key[ i ], true, emptyGet, raw );
		}

	// Sets one value
	} else if ( value !== undefined ) {
		chainable = true;

		if ( !isFunction( value ) ) {
			raw = true;
		}

		if ( bulk ) {

			// Bulk operations run against the entire set
			if ( raw ) {
				fn.call( elems, value );
				fn = null;

			// ...except when executing function values
			} else {
				bulk = fn;
				fn = function( elem, _key, value ) {
					return bulk.call( jQuery( elem ), value );
				};
			}
		}

		if ( fn ) {
			for ( ; i < len; i++ ) {
				fn(
					elems[ i ], key, raw ?
					value :
					value.call( elems[ i ], i, fn( elems[ i ], key ) )
				);
			}
		}
	}

	if ( chainable ) {
		return elems;
	}

	// Gets
	if ( bulk ) {
		return fn.call( elems );
	}

	return len ? fn( elems[ 0 ], key ) : emptyGet;
};


// Matches dashed string for camelizing
var rmsPrefix = /^-ms-/,
	rdashAlpha = /-([a-z])/g;

// Used by camelCase as callback to replace()
function fcamelCase( _all, letter ) {
	return letter.toUpperCase();
}

// Convert dashed to camelCase; used by the css and data modules
// Support: IE <=9 - 11, Edge 12 - 15
// Microsoft forgot to hump their vendor prefix (#9572)
function camelCase( string ) {
	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
}
var acceptData = function( owner ) {

	// Accepts only:
	//  - Node
	//    - Node.ELEMENT_NODE
	//    - Node.DOCUMENT_NODE
	//  - Object
	//    - Any
	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
};




function Data() {
	this.expando = jQuery.expando + Data.uid++;
}

Data.uid = 1;

Data.prototype = {

	cache: function( owner ) {

		// Check if the owner object already has a cache
		var value = owner[ this.expando ];

		// If not, create one
		if ( !value ) {
			value = {};

			// We can accept data for non-element nodes in modern browsers,
			// but we should not, see #8335.
			// Always return an empty object.
			if ( acceptData( owner ) ) {

				// If it is a node unlikely to be stringify-ed or looped over
				// use plain assignment
				if ( owner.nodeType ) {
					owner[ this.expando ] = value;

				// Otherwise secure it in a non-enumerable property
				// configurable must be true to allow the property to be
				// deleted when data is removed
				} else {
					Object.defineProperty( owner, this.expando, {
						value: value,
						configurable: true
					} );
				}
			}
		}

		return value;
	},
	set: function( owner, data, value ) {
		var prop,
			cache = this.cache( owner );

		// Handle: [ owner, key, value ] args
		// Always use camelCase key (gh-2257)
		if ( typeof data === "string" ) {
			cache[ camelCase( data ) ] = value;

		// Handle: [ owner, { properties } ] args
		} else {

			// Copy the properties one-by-one to the cache object
			for ( prop in data ) {
				cache[ camelCase( prop ) ] = data[ prop ];
			}
		}
		return cache;
	},
	get: function( owner, key ) {
		return key === undefined ?
			this.cache( owner ) :

			// Always use camelCase key (gh-2257)
			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
	},
	access: function( owner, key, value ) {

		// In cases where either:
		//
		//   1. No key was specified
		//   2. A string key was specified, but no value provided
		//
		// Take the "read" path and allow the get method to determine
		// which value to return, respectively either:
		//
		//   1. The entire cache object
		//   2. The data stored at the key
		//
		if ( key === undefined ||
				( ( key && typeof key === "string" ) && value === undefined ) ) {

			return this.get( owner, key );
		}

		// When the key is not a string, or both a key and value
		// are specified, set or extend (existing objects) with either:
		//
		//   1. An object of properties
		//   2. A key and value
		//
		this.set( owner, key, value );

		// Since the "set" path can have two possible entry points
		// return the expected data based on which path was taken[*]
		return value !== undefined ? value : key;
	},
	remove: function( owner, key ) {
		var i,
			cache = owner[ this.expando ];

		if ( cache === undefined ) {
			return;
		}

		if ( key !== undefined ) {

			// Support array or space separated string of keys
			if ( Array.isArray( key ) ) {

				// If key is an array of keys...
				// We always set camelCase keys, so remove that.
				key = key.map( camelCase );
			} else {
				key = camelCase( key );

				// If a key with the spaces exists, use it.
				// Otherwise, create an array by matching non-whitespace
				key = key in cache ?
					[ key ] :
					( key.match( rnothtmlwhite ) || [] );
			}

			i = key.length;

			while ( i-- ) {
				delete cache[ key[ i ] ];
			}
		}

		// Remove the expando if there's no more data
		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {

			// Support: Chrome <=35 - 45
			// Webkit & Blink performance suffers when deleting properties
			// from DOM nodes, so set to undefined instead
			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
			if ( owner.nodeType ) {
				owner[ this.expando ] = undefined;
			} else {
				delete owner[ this.expando ];
			}
		}
	},
	hasData: function( owner ) {
		var cache = owner[ this.expando ];
		return cache !== undefined && !jQuery.isEmptyObject( cache );
	}
};
var dataPriv = new Data();

var dataUser = new Data();



//	Implementation Summary
//
//	1. Enforce API surface and semantic compatibility with 1.9.x branch
//	2. Improve the module's maintainability by reducing the storage
//		paths to a single mechanism.
//	3. Use the same single mechanism to support "private" and "user" data.
//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
//	5. Avoid exposing implementation details on user objects (eg. expando properties)
//	6. Provide a clear path for implementation upgrade to WeakMap in 2014

var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
	rmultiDash = /[A-Z]/g;

function getData( data ) {
	if ( data === "true" ) {
		return true;
	}

	if ( data === "false" ) {
		return false;
	}

	if ( data === "null" ) {
		return null;
	}

	// Only convert to a number if it doesn't change the string
	if ( data === +data + "" ) {
		return +data;
	}

	if ( rbrace.test( data ) ) {
		return JSON.parse( data );
	}

	return data;
}

function dataAttr( elem, key, data ) {
	var name;

	// If nothing was found internally, try to fetch any
	// data from the HTML5 data-* attribute
	if ( data === undefined && elem.nodeType === 1 ) {
		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
		data = elem.getAttribute( name );

		if ( typeof data === "string" ) {
			try {
				data = getData( data );
			} catch ( e ) {}

			// Make sure we set the data so it isn't changed later
			dataUser.set( elem, key, data );
		} else {
			data = undefined;
		}
	}
	return data;
}

jQuery.extend( {
	hasData: function( elem ) {
		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
	},

	data: function( elem, name, data ) {
		return dataUser.access( elem, name, data );
	},

	removeData: function( elem, name ) {
		dataUser.remove( elem, name );
	},

	// TODO: Now that all calls to _data and _removeData have been replaced
	// with direct calls to dataPriv methods, these can be deprecated.
	_data: function( elem, name, data ) {
		return dataPriv.access( elem, name, data );
	},

	_removeData: function( elem, name ) {
		dataPriv.remove( elem, name );
	}
} );

jQuery.fn.extend( {
	data: function( key, value ) {
		var i, name, data,
			elem = this[ 0 ],
			attrs = elem && elem.attributes;

		// Gets all values
		if ( key === undefined ) {
			if ( this.length ) {
				data = dataUser.get( elem );

				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
					i = attrs.length;
					while ( i-- ) {

						// Support: IE 11 only
						// The attrs elements can be null (#14894)
						if ( attrs[ i ] ) {
							name = attrs[ i ].name;
							if ( name.indexOf( "data-" ) === 0 ) {
								name = camelCase( name.slice( 5 ) );
								dataAttr( elem, name, data[ name ] );
							}
						}
					}
					dataPriv.set( elem, "hasDataAttrs", true );
				}
			}

			return data;
		}

		// Sets multiple values
		if ( typeof key === "object" ) {
			return this.each( function() {
				dataUser.set( this, key );
			} );
		}

		return access( this, function( value ) {
			var data;

			// The calling jQuery object (element matches) is not empty
			// (and therefore has an element appears at this[ 0 ]) and the
			// `value` parameter was not undefined. An empty jQuery object
			// will result in `undefined` for elem = this[ 0 ] which will
			// throw an exception if an attempt to read a data cache is made.
			if ( elem && value === undefined ) {

				// Attempt to get data from the cache
				// The key will always be camelCased in Data
				data = dataUser.get( elem, key );
				if ( data !== undefined ) {
					return data;
				}

				// Attempt to "discover" the data in
				// HTML5 custom data-* attrs
				data = dataAttr( elem, key );
				if ( data !== undefined ) {
					return data;
				}

				// We tried really hard, but the data doesn't exist.
				return;
			}

			// Set the data...
			this.each( function() {

				// We always store the camelCased key
				dataUser.set( this, key, value );
			} );
		}, null, value, arguments.length > 1, null, true );
	},

	removeData: function( key ) {
		return this.each( function() {
			dataUser.remove( this, key );
		} );
	}
} );


jQuery.extend( {
	queue: function( elem, type, data ) {
		var queue;

		if ( elem ) {
			type = ( type || "fx" ) + "queue";
			queue = dataPriv.get( elem, type );

			// Speed up dequeue by getting out quickly if this is just a lookup
			if ( data ) {
				if ( !queue || Array.isArray( data ) ) {
					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
				} else {
					queue.push( data );
				}
			}
			return queue || [];
		}
	},

	dequeue: function( elem, type ) {
		type = type || "fx";

		var queue = jQuery.queue( elem, type ),
			startLength = queue.length,
			fn = queue.shift(),
			hooks = jQuery._queueHooks( elem, type ),
			next = function() {
				jQuery.dequeue( elem, type );
			};

		// If the fx queue is dequeued, always remove the progress sentinel
		if ( fn === "inprogress" ) {
			fn = queue.shift();
			startLength--;
		}

		if ( fn ) {

			// Add a progress sentinel to prevent the fx queue from being
			// automatically dequeued
			if ( type === "fx" ) {
				queue.unshift( "inprogress" );
			}

			// Clear up the last queue stop function
			delete hooks.stop;
			fn.call( elem, next, hooks );
		}

		if ( !startLength && hooks ) {
			hooks.empty.fire();
		}
	},

	// Not public - generate a queueHooks object, or return the current one
	_queueHooks: function( elem, type ) {
		var key = type + "queueHooks";
		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
			empty: jQuery.Callbacks( "once memory" ).add( function() {
				dataPriv.remove( elem, [ type + "queue", key ] );
			} )
		} );
	}
} );

jQuery.fn.extend( {
	queue: function( type, data ) {
		var setter = 2;

		if ( typeof type !== "string" ) {
			data = type;
			type = "fx";
			setter--;
		}

		if ( arguments.length < setter ) {
			return jQuery.queue( this[ 0 ], type );
		}

		return data === undefined ?
			this :
			this.each( function() {
				var queue = jQuery.queue( this, type, data );

				// Ensure a hooks for this queue
				jQuery._queueHooks( this, type );

				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
					jQuery.dequeue( this, type );
				}
			} );
	},
	dequeue: function( type ) {
		return this.each( function() {
			jQuery.dequeue( this, type );
		} );
	},
	clearQueue: function( type ) {
		return this.queue( type || "fx", [] );
	},

	// Get a promise resolved when queues of a certain type
	// are emptied (fx is the type by default)
	promise: function( type, obj ) {
		var tmp,
			count = 1,
			defer = jQuery.Deferred(),
			elements = this,
			i = this.length,
			resolve = function() {
				if ( !( --count ) ) {
					defer.resolveWith( elements, [ elements ] );
				}
			};

		if ( typeof type !== "string" ) {
			obj = type;
			type = undefined;
		}
		type = type || "fx";

		while ( i-- ) {
			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
			if ( tmp && tmp.empty ) {
				count++;
				tmp.empty.add( resolve );
			}
		}
		resolve();
		return defer.promise( obj );
	}
} );
var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;

var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );


var cssExpand = [ "Top", "Right", "Bottom", "Left" ];

var documentElement = document.documentElement;



	var isAttached = function( elem ) {
			return jQuery.contains( elem.ownerDocument, elem );
		},
		composed = { composed: true };

	// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
	// Check attachment across shadow DOM boundaries when possible (gh-3504)
	// Support: iOS 10.0-10.2 only
	// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
	// leading to errors. We need to check for `getRootNode`.
	if ( documentElement.getRootNode ) {
		isAttached = function( elem ) {
			return jQuery.contains( elem.ownerDocument, elem ) ||
				elem.getRootNode( composed ) === elem.ownerDocument;
		};
	}
var isHiddenWithinTree = function( elem, el ) {

		// isHiddenWithinTree might be called from jQuery#filter function;
		// in that case, element will be second argument
		elem = el || elem;

		// Inline style trumps all
		return elem.style.display === "none" ||
			elem.style.display === "" &&

			// Otherwise, check computed style
			// Support: Firefox <=43 - 45
			// Disconnected elements can have computed display: none, so first confirm that elem is
			// in the document.
			isAttached( elem ) &&

			jQuery.css( elem, "display" ) === "none";
	};



function adjustCSS( elem, prop, valueParts, tween ) {
	var adjusted, scale,
		maxIterations = 20,
		currentValue = tween ?
			function() {
				return tween.cur();
			} :
			function() {
				return jQuery.css( elem, prop, "" );
			},
		initial = currentValue(),
		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),

		// Starting value computation is required for potential unit mismatches
		initialInUnit = elem.nodeType &&
			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
			rcssNum.exec( jQuery.css( elem, prop ) );

	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {

		// Support: Firefox <=54
		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
		initial = initial / 2;

		// Trust units reported by jQuery.css
		unit = unit || initialInUnit[ 3 ];

		// Iteratively approximate from a nonzero starting point
		initialInUnit = +initial || 1;

		while ( maxIterations-- ) {

			// Evaluate and update our best guess (doubling guesses that zero out).
			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
			jQuery.style( elem, prop, initialInUnit + unit );
			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
				maxIterations = 0;
			}
			initialInUnit = initialInUnit / scale;

		}

		initialInUnit = initialInUnit * 2;
		jQuery.style( elem, prop, initialInUnit + unit );

		// Make sure we update the tween properties later on
		valueParts = valueParts || [];
	}

	if ( valueParts ) {
		initialInUnit = +initialInUnit || +initial || 0;

		// Apply relative offset (+=/-=) if specified
		adjusted = valueParts[ 1 ] ?
			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
			+valueParts[ 2 ];
		if ( tween ) {
			tween.unit = unit;
			tween.start = initialInUnit;
			tween.end = adjusted;
		}
	}
	return adjusted;
}


var defaultDisplayMap = {};

function getDefaultDisplay( elem ) {
	var temp,
		doc = elem.ownerDocument,
		nodeName = elem.nodeName,
		display = defaultDisplayMap[ nodeName ];

	if ( display ) {
		return display;
	}

	temp = doc.body.appendChild( doc.createElement( nodeName ) );
	display = jQuery.css( temp, "display" );

	temp.parentNode.removeChild( temp );

	if ( display === "none" ) {
		display = "block";
	}
	defaultDisplayMap[ nodeName ] = display;

	return display;
}

function showHide( elements, show ) {
	var display, elem,
		values = [],
		index = 0,
		length = elements.length;

	// Determine new display value for elements that need to change
	for ( ; index < length; index++ ) {
		elem = elements[ index ];
		if ( !elem.style ) {
			continue;
		}

		display = elem.style.display;
		if ( show ) {

			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
			// check is required in this first loop unless we have a nonempty display value (either
			// inline or about-to-be-restored)
			if ( display === "none" ) {
				values[ index ] = dataPriv.get( elem, "display" ) || null;
				if ( !values[ index ] ) {
					elem.style.display = "";
				}
			}
			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
				values[ index ] = getDefaultDisplay( elem );
			}
		} else {
			if ( display !== "none" ) {
				values[ index ] = "none";

				// Remember what we're overwriting
				dataPriv.set( elem, "display", display );
			}
		}
	}

	// Set the display of the elements in a second loop to avoid constant reflow
	for ( index = 0; index < length; index++ ) {
		if ( values[ index ] != null ) {
			elements[ index ].style.display = values[ index ];
		}
	}

	return elements;
}

jQuery.fn.extend( {
	show: function() {
		return showHide( this, true );
	},
	hide: function() {
		return showHide( this );
	},
	toggle: function( state ) {
		if ( typeof state === "boolean" ) {
			return state ? this.show() : this.hide();
		}

		return this.each( function() {
			if ( isHiddenWithinTree( this ) ) {
				jQuery( this ).show();
			} else {
				jQuery( this ).hide();
			}
		} );
	}
} );
var rcheckableType = ( /^(?:checkbox|radio)$/i );

var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );

var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );



( function() {
	var fragment = document.createDocumentFragment(),
		div = fragment.appendChild( document.createElement( "div" ) ),
		input = document.createElement( "input" );

	// Support: Android 4.0 - 4.3 only
	// Check state lost if the name is set (#11217)
	// Support: Windows Web Apps (WWA)
	// `name` and `type` must use .setAttribute for WWA (#14901)
	input.setAttribute( "type", "radio" );
	input.setAttribute( "checked", "checked" );
	input.setAttribute( "name", "t" );

	div.appendChild( input );

	// Support: Android <=4.1 only
	// Older WebKit doesn't clone checked state correctly in fragments
	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;

	// Support: IE <=11 only
	// Make sure textarea (and checkbox) defaultValue is properly cloned
	div.innerHTML = "<textarea>x</textarea>";
	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;

	// Support: IE <=9 only
	// IE <=9 replaces <option> tags with their contents when inserted outside of
	// the select element.
	div.innerHTML = "<option></option>";
	support.option = !!div.lastChild;
} )();


// We have to close these tags to support XHTML (#13200)
var wrapMap = {

	// XHTML parsers do not magically insert elements in the
	// same way that tag soup parsers do. So we cannot shorten
	// this by omitting <tbody> or other required elements.
	thead: [ 1, "<table>", "</table>" ],
	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],

	_default: [ 0, "", "" ]
};

wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;

// Support: IE <=9 only
if ( !support.option ) {
	wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
}


function getAll( context, tag ) {

	// Support: IE <=9 - 11 only
	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
	var ret;

	if ( typeof context.getElementsByTagName !== "undefined" ) {
		ret = context.getElementsByTagName( tag || "*" );

	} else if ( typeof context.querySelectorAll !== "undefined" ) {
		ret = context.querySelectorAll( tag || "*" );

	} else {
		ret = [];
	}

	if ( tag === undefined || tag && nodeName( context, tag ) ) {
		return jQuery.merge( [ context ], ret );
	}

	return ret;
}


// Mark scripts as having already been evaluated
function setGlobalEval( elems, refElements ) {
	var i = 0,
		l = elems.length;

	for ( ; i < l; i++ ) {
		dataPriv.set(
			elems[ i ],
			"globalEval",
			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
		);
	}
}


var rhtml = /<|&#?\w+;/;

function buildFragment( elems, context, scripts, selection, ignored ) {
	var elem, tmp, tag, wrap, attached, j,
		fragment = context.createDocumentFragment(),
		nodes = [],
		i = 0,
		l = elems.length;

	for ( ; i < l; i++ ) {
		elem = elems[ i ];

		if ( elem || elem === 0 ) {

			// Add nodes directly
			if ( toType( elem ) === "object" ) {

				// Support: Android <=4.0 only, PhantomJS 1 only
				// push.apply(_, arraylike) throws on ancient WebKit
				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );

			// Convert non-html into a text node
			} else if ( !rhtml.test( elem ) ) {
				nodes.push( context.createTextNode( elem ) );

			// Convert html into DOM nodes
			} else {
				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );

				// Deserialize a standard representation
				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
				wrap = wrapMap[ tag ] || wrapMap._default;
				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];

				// Descend through wrappers to the right content
				j = wrap[ 0 ];
				while ( j-- ) {
					tmp = tmp.lastChild;
				}

				// Support: Android <=4.0 only, PhantomJS 1 only
				// push.apply(_, arraylike) throws on ancient WebKit
				jQuery.merge( nodes, tmp.childNodes );

				// Remember the top-level container
				tmp = fragment.firstChild;

				// Ensure the created nodes are orphaned (#12392)
				tmp.textContent = "";
			}
		}
	}

	// Remove wrapper from fragment
	fragment.textContent = "";

	i = 0;
	while ( ( elem = nodes[ i++ ] ) ) {

		// Skip elements already in the context collection (trac-4087)
		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
			if ( ignored ) {
				ignored.push( elem );
			}
			continue;
		}

		attached = isAttached( elem );

		// Append to fragment
		tmp = getAll( fragment.appendChild( elem ), "script" );

		// Preserve script evaluation history
		if ( attached ) {
			setGlobalEval( tmp );
		}

		// Capture executables
		if ( scripts ) {
			j = 0;
			while ( ( elem = tmp[ j++ ] ) ) {
				if ( rscriptType.test( elem.type || "" ) ) {
					scripts.push( elem );
				}
			}
		}
	}

	return fragment;
}


var
	rkeyEvent = /^key/,
	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;

function returnTrue() {
	return true;
}

function returnFalse() {
	return false;
}

// Support: IE <=9 - 11+
// focus() and blur() are asynchronous, except when they are no-op.
// So expect focus to be synchronous when the element is already active,
// and blur to be synchronous when the element is not already active.
// (focus and blur are always synchronous in other supported browsers,
// this just defines when we can count on it).
function expectSync( elem, type ) {
	return ( elem === safeActiveElement() ) === ( type === "focus" );
}

// Support: IE <=9 only
// Accessing document.activeElement can throw unexpectedly
// https://bugs.jquery.com/ticket/13393
function safeActiveElement() {
	try {
		return document.activeElement;
	} catch ( err ) { }
}

function on( elem, types, selector, data, fn, one ) {
	var origFn, type;

	// Types can be a map of types/handlers
	if ( typeof types === "object" ) {

		// ( types-Object, selector, data )
		if ( typeof selector !== "string" ) {

			// ( types-Object, data )
			data = data || selector;
			selector = undefined;
		}
		for ( type in types ) {
			on( elem, type, selector, data, types[ type ], one );
		}
		return elem;
	}

	if ( data == null && fn == null ) {

		// ( types, fn )
		fn = selector;
		data = selector = undefined;
	} else if ( fn == null ) {
		if ( typeof selector === "string" ) {

			// ( types, selector, fn )
			fn = data;
			data = undefined;
		} else {

			// ( types, data, fn )
			fn = data;
			data = selector;
			selector = undefined;
		}
	}
	if ( fn === false ) {
		fn = returnFalse;
	} else if ( !fn ) {
		return elem;
	}

	if ( one === 1 ) {
		origFn = fn;
		fn = function( event ) {

			// Can use an empty set, since event contains the info
			jQuery().off( event );
			return origFn.apply( this, arguments );
		};

		// Use same guid so caller can remove using origFn
		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
	}
	return elem.each( function() {
		jQuery.event.add( this, types, fn, data, selector );
	} );
}

/*
 * Helper functions for managing events -- not part of the public interface.
 * Props to Dean Edwards' addEvent library for many of the ideas.
 */
jQuery.event = {

	global: {},

	add: function( elem, types, handler, data, selector ) {

		var handleObjIn, eventHandle, tmp,
			events, t, handleObj,
			special, handlers, type, namespaces, origType,
			elemData = dataPriv.get( elem );

		// Only attach events to objects that accept data
		if ( !acceptData( elem ) ) {
			return;
		}

		// Caller can pass in an object of custom data in lieu of the handler
		if ( handler.handler ) {
			handleObjIn = handler;
			handler = handleObjIn.handler;
			selector = handleObjIn.selector;
		}

		// Ensure that invalid selectors throw exceptions at attach time
		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
		if ( selector ) {
			jQuery.find.matchesSelector( documentElement, selector );
		}

		// Make sure that the handler has a unique ID, used to find/remove it later
		if ( !handler.guid ) {
			handler.guid = jQuery.guid++;
		}

		// Init the element's event structure and main handler, if this is the first
		if ( !( events = elemData.events ) ) {
			events = elemData.events = Object.create( null );
		}
		if ( !( eventHandle = elemData.handle ) ) {
			eventHandle = elemData.handle = function( e ) {

				// Discard the second event of a jQuery.event.trigger() and
				// when an event is called after a page has unloaded
				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
			};
		}

		// Handle multiple events separated by a space
		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
		t = types.length;
		while ( t-- ) {
			tmp = rtypenamespace.exec( types[ t ] ) || [];
			type = origType = tmp[ 1 ];
			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();

			// There *must* be a type, no attaching namespace-only handlers
			if ( !type ) {
				continue;
			}

			// If event changes its type, use the special event handlers for the changed type
			special = jQuery.event.special[ type ] || {};

			// If selector defined, determine special event api type, otherwise given type
			type = ( selector ? special.delegateType : special.bindType ) || type;

			// Update special based on newly reset type
			special = jQuery.event.special[ type ] || {};

			// handleObj is passed to all event handlers
			handleObj = jQuery.extend( {
				type: type,
				origType: origType,
				data: data,
				handler: handler,
				guid: handler.guid,
				selector: selector,
				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
				namespace: namespaces.join( "." )
			}, handleObjIn );

			// Init the event handler queue if we're the first
			if ( !( handlers = events[ type ] ) ) {
				handlers = events[ type ] = [];
				handlers.delegateCount = 0;

				// Only use addEventListener if the special events handler returns false
				if ( !special.setup ||
					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {

					if ( elem.addEventListener ) {
						elem.addEventListener( type, eventHandle );
					}
				}
			}

			if ( special.add ) {
				special.add.call( elem, handleObj );

				if ( !handleObj.handler.guid ) {
					handleObj.handler.guid = handler.guid;
				}
			}

			// Add to the element's handler list, delegates in front
			if ( selector ) {
				handlers.splice( handlers.delegateCount++, 0, handleObj );
			} else {
				handlers.push( handleObj );
			}

			// Keep track of which events have ever been used, for event optimization
			jQuery.event.global[ type ] = true;
		}

	},

	// Detach an event or set of events from an element
	remove: function( elem, types, handler, selector, mappedTypes ) {

		var j, origCount, tmp,
			events, t, handleObj,
			special, handlers, type, namespaces, origType,
			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );

		if ( !elemData || !( events = elemData.events ) ) {
			return;
		}

		// Once for each type.namespace in types; type may be omitted
		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
		t = types.length;
		while ( t-- ) {
			tmp = rtypenamespace.exec( types[ t ] ) || [];
			type = origType = tmp[ 1 ];
			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();

			// Unbind all events (on this namespace, if provided) for the element
			if ( !type ) {
				for ( type in events ) {
					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
				}
				continue;
			}

			special = jQuery.event.special[ type ] || {};
			type = ( selector ? special.delegateType : special.bindType ) || type;
			handlers = events[ type ] || [];
			tmp = tmp[ 2 ] &&
				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );

			// Remove matching events
			origCount = j = handlers.length;
			while ( j-- ) {
				handleObj = handlers[ j ];

				if ( ( mappedTypes || origType === handleObj.origType ) &&
					( !handler || handler.guid === handleObj.guid ) &&
					( !tmp || tmp.test( handleObj.namespace ) ) &&
					( !selector || selector === handleObj.selector ||
						selector === "**" && handleObj.selector ) ) {
					handlers.splice( j, 1 );

					if ( handleObj.selector ) {
						handlers.delegateCount--;
					}
					if ( special.remove ) {
						special.remove.call( elem, handleObj );
					}
				}
			}

			// Remove generic event handler if we removed something and no more handlers exist
			// (avoids potential for endless recursion during removal of special event handlers)
			if ( origCount && !handlers.length ) {
				if ( !special.teardown ||
					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {

					jQuery.removeEvent( elem, type, elemData.handle );
				}

				delete events[ type ];
			}
		}

		// Remove data and the expando if it's no longer used
		if ( jQuery.isEmptyObject( events ) ) {
			dataPriv.remove( elem, "handle events" );
		}
	},

	dispatch: function( nativeEvent ) {

		var i, j, ret, matched, handleObj, handlerQueue,
			args = new Array( arguments.length ),

			// Make a writable jQuery.Event from the native event object
			event = jQuery.event.fix( nativeEvent ),

			handlers = (
					dataPriv.get( this, "events" ) || Object.create( null )
				)[ event.type ] || [],
			special = jQuery.event.special[ event.type ] || {};

		// Use the fix-ed jQuery.Event rather than the (read-only) native event
		args[ 0 ] = event;

		for ( i = 1; i < arguments.length; i++ ) {
			args[ i ] = arguments[ i ];
		}

		event.delegateTarget = this;

		// Call the preDispatch hook for the mapped type, and let it bail if desired
		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
			return;
		}

		// Determine handlers
		handlerQueue = jQuery.event.handlers.call( this, event, handlers );

		// Run delegates first; they may want to stop propagation beneath us
		i = 0;
		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
			event.currentTarget = matched.elem;

			j = 0;
			while ( ( handleObj = matched.handlers[ j++ ] ) &&
				!event.isImmediatePropagationStopped() ) {

				// If the event is namespaced, then each handler is only invoked if it is
				// specially universal or its namespaces are a superset of the event's.
				if ( !event.rnamespace || handleObj.namespace === false ||
					event.rnamespace.test( handleObj.namespace ) ) {

					event.handleObj = handleObj;
					event.data = handleObj.data;

					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
						handleObj.handler ).apply( matched.elem, args );

					if ( ret !== undefined ) {
						if ( ( event.result = ret ) === false ) {
							event.preventDefault();
							event.stopPropagation();
						}
					}
				}
			}
		}

		// Call the postDispatch hook for the mapped type
		if ( special.postDispatch ) {
			special.postDispatch.call( this, event );
		}

		return event.result;
	},

	handlers: function( event, handlers ) {
		var i, handleObj, sel, matchedHandlers, matchedSelectors,
			handlerQueue = [],
			delegateCount = handlers.delegateCount,
			cur = event.target;

		// Find delegate handlers
		if ( delegateCount &&

			// Support: IE <=9
			// Black-hole SVG <use> instance trees (trac-13180)
			cur.nodeType &&

			// Support: Firefox <=42
			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
			// Support: IE 11 only
			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
			!( event.type === "click" && event.button >= 1 ) ) {

			for ( ; cur !== this; cur = cur.parentNode || this ) {

				// Don't check non-elements (#13208)
				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
					matchedHandlers = [];
					matchedSelectors = {};
					for ( i = 0; i < delegateCount; i++ ) {
						handleObj = handlers[ i ];

						// Don't conflict with Object.prototype properties (#13203)
						sel = handleObj.selector + " ";

						if ( matchedSelectors[ sel ] === undefined ) {
							matchedSelectors[ sel ] = handleObj.needsContext ?
								jQuery( sel, this ).index( cur ) > -1 :
								jQuery.find( sel, this, null, [ cur ] ).length;
						}
						if ( matchedSelectors[ sel ] ) {
							matchedHandlers.push( handleObj );
						}
					}
					if ( matchedHandlers.length ) {
						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
					}
				}
			}
		}

		// Add the remaining (directly-bound) handlers
		cur = this;
		if ( delegateCount < handlers.length ) {
			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
		}

		return handlerQueue;
	},

	addProp: function( name, hook ) {
		Object.defineProperty( jQuery.Event.prototype, name, {
			enumerable: true,
			configurable: true,

			get: isFunction( hook ) ?
				function() {
					if ( this.originalEvent ) {
							return hook( this.originalEvent );
					}
				} :
				function() {
					if ( this.originalEvent ) {
							return this.originalEvent[ name ];
					}
				},

			set: function( value ) {
				Object.defineProperty( this, name, {
					enumerable: true,
					configurable: true,
					writable: true,
					value: value
				} );
			}
		} );
	},

	fix: function( originalEvent ) {
		return originalEvent[ jQuery.expando ] ?
			originalEvent :
			new jQuery.Event( originalEvent );
	},

	special: {
		load: {

			// Prevent triggered image.load events from bubbling to window.load
			noBubble: true
		},
		click: {

			// Utilize native event to ensure correct state for checkable inputs
			setup: function( data ) {

				// For mutual compressibility with _default, replace `this` access with a local var.
				// `|| data` is dead code meant only to preserve the variable through minification.
				var el = this || data;

				// Claim the first handler
				if ( rcheckableType.test( el.type ) &&
					el.click && nodeName( el, "input" ) ) {

					// dataPriv.set( el, "click", ... )
					leverageNative( el, "click", returnTrue );
				}

				// Return false to allow normal processing in the caller
				return false;
			},
			trigger: function( data ) {

				// For mutual compressibility with _default, replace `this` access with a local var.
				// `|| data` is dead code meant only to preserve the variable through minification.
				var el = this || data;

				// Force setup before triggering a click
				if ( rcheckableType.test( el.type ) &&
					el.click && nodeName( el, "input" ) ) {

					leverageNative( el, "click" );
				}

				// Return non-false to allow normal event-path propagation
				return true;
			},

			// For cross-browser consistency, suppress native .click() on links
			// Also prevent it if we're currently inside a leveraged native-event stack
			_default: function( event ) {
				var target = event.target;
				return rcheckableType.test( target.type ) &&
					target.click && nodeName( target, "input" ) &&
					dataPriv.get( target, "click" ) ||
					nodeName( target, "a" );
			}
		},

		beforeunload: {
			postDispatch: function( event ) {

				// Support: Firefox 20+
				// Firefox doesn't alert if the returnValue field is not set.
				if ( event.result !== undefined && event.originalEvent ) {
					event.originalEvent.returnValue = event.result;
				}
			}
		}
	}
};

// Ensure the presence of an event listener that handles manually-triggered
// synthetic events by interrupting progress until reinvoked in response to
// *native* events that it fires directly, ensuring that state changes have
// already occurred before other listeners are invoked.
function leverageNative( el, type, expectSync ) {

	// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
	if ( !expectSync ) {
		if ( dataPriv.get( el, type ) === undefined ) {
			jQuery.event.add( el, type, returnTrue );
		}
		return;
	}

	// Register the controller as a special universal handler for all event namespaces
	dataPriv.set( el, type, false );
	jQuery.event.add( el, type, {
		namespace: false,
		handler: function( event ) {
			var notAsync, result,
				saved = dataPriv.get( this, type );

			if ( ( event.isTrigger & 1 ) && this[ type ] ) {

				// Interrupt processing of the outer synthetic .trigger()ed event
				// Saved data should be false in such cases, but might be a leftover capture object
				// from an async native handler (gh-4350)
				if ( !saved.length ) {

					// Store arguments for use when handling the inner native event
					// There will always be at least one argument (an event object), so this array
					// will not be confused with a leftover capture object.
					saved = slice.call( arguments );
					dataPriv.set( this, type, saved );

					// Trigger the native event and capture its result
					// Support: IE <=9 - 11+
					// focus() and blur() are asynchronous
					notAsync = expectSync( this, type );
					this[ type ]();
					result = dataPriv.get( this, type );
					if ( saved !== result || notAsync ) {
						dataPriv.set( this, type, false );
					} else {
						result = {};
					}
					if ( saved !== result ) {

						// Cancel the outer synthetic event
						event.stopImmediatePropagation();
						event.preventDefault();
						return result.value;
					}

				// If this is an inner synthetic event for an event with a bubbling surrogate
				// (focus or blur), assume that the surrogate already propagated from triggering the
				// native event and prevent that from happening again here.
				// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
				// bubbling surrogate propagates *after* the non-bubbling base), but that seems
				// less bad than duplication.
				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
					event.stopPropagation();
				}

			// If this is a native event triggered above, everything is now in order
			// Fire an inner synthetic event with the original arguments
			} else if ( saved.length ) {

				// ...and capture the result
				dataPriv.set( this, type, {
					value: jQuery.event.trigger(

						// Support: IE <=9 - 11+
						// Extend with the prototype to reset the above stopImmediatePropagation()
						jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
						saved.slice( 1 ),
						this
					)
				} );

				// Abort handling of the native event
				event.stopImmediatePropagation();
			}
		}
	} );
}

jQuery.removeEvent = function( elem, type, handle ) {

	// This "if" is needed for plain objects
	if ( elem.removeEventListener ) {
		elem.removeEventListener( type, handle );
	}
};

jQuery.Event = function( src, props ) {

	// Allow instantiation without the 'new' keyword
	if ( !( this instanceof jQuery.Event ) ) {
		return new jQuery.Event( src, props );
	}

	// Event object
	if ( src && src.type ) {
		this.originalEvent = src;
		this.type = src.type;

		// Events bubbling up the document may have been marked as prevented
		// by a handler lower down the tree; reflect the correct value.
		this.isDefaultPrevented = src.defaultPrevented ||
				src.defaultPrevented === undefined &&

				// Support: Android <=2.3 only
				src.returnValue === false ?
			returnTrue :
			returnFalse;

		// Create target properties
		// Support: Safari <=6 - 7 only
		// Target should not be a text node (#504, #13143)
		this.target = ( src.target && src.target.nodeType === 3 ) ?
			src.target.parentNode :
			src.target;

		this.currentTarget = src.currentTarget;
		this.relatedTarget = src.relatedTarget;

	// Event type
	} else {
		this.type = src;
	}

	// Put explicitly provided properties onto the event object
	if ( props ) {
		jQuery.extend( this, props );
	}

	// Create a timestamp if incoming event doesn't have one
	this.timeStamp = src && src.timeStamp || Date.now();

	// Mark it as fixed
	this[ jQuery.expando ] = true;
};

// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery.Event.prototype = {
	constructor: jQuery.Event,
	isDefaultPrevented: returnFalse,
	isPropagationStopped: returnFalse,
	isImmediatePropagationStopped: returnFalse,
	isSimulated: false,

	preventDefault: function() {
		var e = this.originalEvent;

		this.isDefaultPrevented = returnTrue;

		if ( e && !this.isSimulated ) {
			e.preventDefault();
		}
	},
	stopPropagation: function() {
		var e = this.originalEvent;

		this.isPropagationStopped = returnTrue;

		if ( e && !this.isSimulated ) {
			e.stopPropagation();
		}
	},
	stopImmediatePropagation: function() {
		var e = this.originalEvent;

		this.isImmediatePropagationStopped = returnTrue;

		if ( e && !this.isSimulated ) {
			e.stopImmediatePropagation();
		}

		this.stopPropagation();
	}
};

// Includes all common event props including KeyEvent and MouseEvent specific props
jQuery.each( {
	altKey: true,
	bubbles: true,
	cancelable: true,
	changedTouches: true,
	ctrlKey: true,
	detail: true,
	eventPhase: true,
	metaKey: true,
	pageX: true,
	pageY: true,
	shiftKey: true,
	view: true,
	"char": true,
	code: true,
	charCode: true,
	key: true,
	keyCode: true,
	button: true,
	buttons: true,
	clientX: true,
	clientY: true,
	offsetX: true,
	offsetY: true,
	pointerId: true,
	pointerType: true,
	screenX: true,
	screenY: true,
	targetTouches: true,
	toElement: true,
	touches: true,

	which: function( event ) {
		var button = event.button;

		// Add which for key events
		if ( event.which == null && rkeyEvent.test( event.type ) ) {
			return event.charCode != null ? event.charCode : event.keyCode;
		}

		// Add which for click: 1 === left; 2 === middle; 3 === right
		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
			if ( button & 1 ) {
				return 1;
			}

			if ( button & 2 ) {
				return 3;
			}

			if ( button & 4 ) {
				return 2;
			}

			return 0;
		}

		return event.which;
	}
}, jQuery.event.addProp );

jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
	jQuery.event.special[ type ] = {

		// Utilize native event if possible so blur/focus sequence is correct
		setup: function() {

			// Claim the first handler
			// dataPriv.set( this, "focus", ... )
			// dataPriv.set( this, "blur", ... )
			leverageNative( this, type, expectSync );

			// Return false to allow normal processing in the caller
			return false;
		},
		trigger: function() {

			// Force setup before trigger
			leverageNative( this, type );

			// Return non-false to allow normal event-path propagation
			return true;
		},

		delegateType: delegateType
	};
} );

// Create mouseenter/leave events using mouseover/out and event-time checks
// so that event delegation works in jQuery.
// Do the same for pointerenter/pointerleave and pointerover/pointerout
//
// Support: Safari 7 only
// Safari sends mouseenter too often; see:
// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
// for the description of the bug (it existed in older Chrome versions as well).
jQuery.each( {
	mouseenter: "mouseover",
	mouseleave: "mouseout",
	pointerenter: "pointerover",
	pointerleave: "pointerout"
}, function( orig, fix ) {
	jQuery.event.special[ orig ] = {
		delegateType: fix,
		bindType: fix,

		handle: function( event ) {
			var ret,
				target = this,
				related = event.relatedTarget,
				handleObj = event.handleObj;

			// For mouseenter/leave call the handler if related is outside the target.
			// NB: No relatedTarget if the mouse left/entered the browser window
			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
				event.type = handleObj.origType;
				ret = handleObj.handler.apply( this, arguments );
				event.type = fix;
			}
			return ret;
		}
	};
} );

jQuery.fn.extend( {

	on: function( types, selector, data, fn ) {
		return on( this, types, selector, data, fn );
	},
	one: function( types, selector, data, fn ) {
		return on( this, types, selector, data, fn, 1 );
	},
	off: function( types, selector, fn ) {
		var handleObj, type;
		if ( types && types.preventDefault && types.handleObj ) {

			// ( event )  dispatched jQuery.Event
			handleObj = types.handleObj;
			jQuery( types.delegateTarget ).off(
				handleObj.namespace ?
					handleObj.origType + "." + handleObj.namespace :
					handleObj.origType,
				handleObj.selector,
				handleObj.handler
			);
			return this;
		}
		if ( typeof types === "object" ) {

			// ( types-object [, selector] )
			for ( type in types ) {
				this.off( type, selector, types[ type ] );
			}
			return this;
		}
		if ( selector === false || typeof selector === "function" ) {

			// ( types [, fn] )
			fn = selector;
			selector = undefined;
		}
		if ( fn === false ) {
			fn = returnFalse;
		}
		return this.each( function() {
			jQuery.event.remove( this, types, fn, selector );
		} );
	}
} );


var

	// Support: IE <=10 - 11, Edge 12 - 13 only
	// In IE/Edge using regex groups here causes severe slowdowns.
	// See https://connect.microsoft.com/IE/feedback/details/1736512/
	rnoInnerhtml = /<script|<style|<link/i,

	// checked="checked" or checked
	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;

// Prefer a tbody over its parent table for containing new rows
function manipulationTarget( elem, content ) {
	if ( nodeName( elem, "table" ) &&
		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {

		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
	}

	return elem;
}

// Replace/restore the type attribute of script elements for safe DOM manipulation
function disableScript( elem ) {
	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
	return elem;
}
function restoreScript( elem ) {
	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
		elem.type = elem.type.slice( 5 );
	} else {
		elem.removeAttribute( "type" );
	}

	return elem;
}

function cloneCopyEvent( src, dest ) {
	var i, l, type, pdataOld, udataOld, udataCur, events;

	if ( dest.nodeType !== 1 ) {
		return;
	}

	// 1. Copy private data: events, handlers, etc.
	if ( dataPriv.hasData( src ) ) {
		pdataOld = dataPriv.get( src );
		events = pdataOld.events;

		if ( events ) {
			dataPriv.remove( dest, "handle events" );

			for ( type in events ) {
				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
					jQuery.event.add( dest, type, events[ type ][ i ] );
				}
			}
		}
	}

	// 2. Copy user data
	if ( dataUser.hasData( src ) ) {
		udataOld = dataUser.access( src );
		udataCur = jQuery.extend( {}, udataOld );

		dataUser.set( dest, udataCur );
	}
}

// Fix IE bugs, see support tests
function fixInput( src, dest ) {
	var nodeName = dest.nodeName.toLowerCase();

	// Fails to persist the checked state of a cloned checkbox or radio button.
	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
		dest.checked = src.checked;

	// Fails to return the selected option to the default selected state when cloning options
	} else if ( nodeName === "input" || nodeName === "textarea" ) {
		dest.defaultValue = src.defaultValue;
	}
}

function domManip( collection, args, callback, ignored ) {

	// Flatten any nested arrays
	args = flat( args );

	var fragment, first, scripts, hasScripts, node, doc,
		i = 0,
		l = collection.length,
		iNoClone = l - 1,
		value = args[ 0 ],
		valueIsFunction = isFunction( value );

	// We can't cloneNode fragments that contain checked, in WebKit
	if ( valueIsFunction ||
			( l > 1 && typeof value === "string" &&
				!support.checkClone && rchecked.test( value ) ) ) {
		return collection.each( function( index ) {
			var self = collection.eq( index );
			if ( valueIsFunction ) {
				args[ 0 ] = value.call( this, index, self.html() );
			}
			domManip( self, args, callback, ignored );
		} );
	}

	if ( l ) {
		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
		first = fragment.firstChild;

		if ( fragment.childNodes.length === 1 ) {
			fragment = first;
		}

		// Require either new content or an interest in ignored elements to invoke the callback
		if ( first || ignored ) {
			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
			hasScripts = scripts.length;

			// Use the original fragment for the last item
			// instead of the first because it can end up
			// being emptied incorrectly in certain situations (#8070).
			for ( ; i < l; i++ ) {
				node = fragment;

				if ( i !== iNoClone ) {
					node = jQuery.clone( node, true, true );

					// Keep references to cloned scripts for later restoration
					if ( hasScripts ) {

						// Support: Android <=4.0 only, PhantomJS 1 only
						// push.apply(_, arraylike) throws on ancient WebKit
						jQuery.merge( scripts, getAll( node, "script" ) );
					}
				}

				callback.call( collection[ i ], node, i );
			}

			if ( hasScripts ) {
				doc = scripts[ scripts.length - 1 ].ownerDocument;

				// Reenable scripts
				jQuery.map( scripts, restoreScript );

				// Evaluate executable scripts on first document insertion
				for ( i = 0; i < hasScripts; i++ ) {
					node = scripts[ i ];
					if ( rscriptType.test( node.type || "" ) &&
						!dataPriv.access( node, "globalEval" ) &&
						jQuery.contains( doc, node ) ) {

						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {

							// Optional AJAX dependency, but won't run scripts if not present
							if ( jQuery._evalUrl && !node.noModule ) {
								jQuery._evalUrl( node.src, {
									nonce: node.nonce || node.getAttribute( "nonce" )
								}, doc );
							}
						} else {
							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
						}
					}
				}
			}
		}
	}

	return collection;
}

function remove( elem, selector, keepData ) {
	var node,
		nodes = selector ? jQuery.filter( selector, elem ) : elem,
		i = 0;

	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
		if ( !keepData && node.nodeType === 1 ) {
			jQuery.cleanData( getAll( node ) );
		}

		if ( node.parentNode ) {
			if ( keepData && isAttached( node ) ) {
				setGlobalEval( getAll( node, "script" ) );
			}
			node.parentNode.removeChild( node );
		}
	}

	return elem;
}

jQuery.extend( {
	htmlPrefilter: function( html ) {
		return html;
	},

	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
		var i, l, srcElements, destElements,
			clone = elem.cloneNode( true ),
			inPage = isAttached( elem );

		// Fix IE cloning issues
		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
				!jQuery.isXMLDoc( elem ) ) {

			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
			destElements = getAll( clone );
			srcElements = getAll( elem );

			for ( i = 0, l = srcElements.length; i < l; i++ ) {
				fixInput( srcElements[ i ], destElements[ i ] );
			}
		}

		// Copy the events from the original to the clone
		if ( dataAndEvents ) {
			if ( deepDataAndEvents ) {
				srcElements = srcElements || getAll( elem );
				destElements = destElements || getAll( clone );

				for ( i = 0, l = srcElements.length; i < l; i++ ) {
					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
				}
			} else {
				cloneCopyEvent( elem, clone );
			}
		}

		// Preserve script evaluation history
		destElements = getAll( clone, "script" );
		if ( destElements.length > 0 ) {
			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
		}

		// Return the cloned set
		return clone;
	},

	cleanData: function( elems ) {
		var data, elem, type,
			special = jQuery.event.special,
			i = 0;

		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
			if ( acceptData( elem ) ) {
				if ( ( data = elem[ dataPriv.expando ] ) ) {
					if ( data.events ) {
						for ( type in data.events ) {
							if ( special[ type ] ) {
								jQuery.event.remove( elem, type );

							// This is a shortcut to avoid jQuery.event.remove's overhead
							} else {
								jQuery.removeEvent( elem, type, data.handle );
							}
						}
					}

					// Support: Chrome <=35 - 45+
					// Assign undefined instead of using delete, see Data#remove
					elem[ dataPriv.expando ] = undefined;
				}
				if ( elem[ dataUser.expando ] ) {

					// Support: Chrome <=35 - 45+
					// Assign undefined instead of using delete, see Data#remove
					elem[ dataUser.expando ] = undefined;
				}
			}
		}
	}
} );

jQuery.fn.extend( {
	detach: function( selector ) {
		return remove( this, selector, true );
	},

	remove: function( selector ) {
		return remove( this, selector );
	},

	text: function( value ) {
		return access( this, function( value ) {
			return value === undefined ?
				jQuery.text( this ) :
				this.empty().each( function() {
					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
						this.textContent = value;
					}
				} );
		}, null, value, arguments.length );
	},

	append: function() {
		return domManip( this, arguments, function( elem ) {
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
				var target = manipulationTarget( this, elem );
				target.appendChild( elem );
			}
		} );
	},

	prepend: function() {
		return domManip( this, arguments, function( elem ) {
			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
				var target = manipulationTarget( this, elem );
				target.insertBefore( elem, target.firstChild );
			}
		} );
	},

	before: function() {
		return domManip( this, arguments, function( elem ) {
			if ( this.parentNode ) {
				this.parentNode.insertBefore( elem, this );
			}
		} );
	},

	after: function() {
		return domManip( this, arguments, function( elem ) {
			if ( this.parentNode ) {
				this.parentNode.insertBefore( elem, this.nextSibling );
			}
		} );
	},

	empty: function() {
		var elem,
			i = 0;

		for ( ; ( elem = this[ i ] ) != null; i++ ) {
			if ( elem.nodeType === 1 ) {

				// Prevent memory leaks
				jQuery.cleanData( getAll( elem, false ) );

				// Remove any remaining nodes
				elem.textContent = "";
			}
		}

		return this;
	},

	clone: function( dataAndEvents, deepDataAndEvents ) {
		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

		return this.map( function() {
			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
		} );
	},

	html: function( value ) {
		return access( this, function( value ) {
			var elem = this[ 0 ] || {},
				i = 0,
				l = this.length;

			if ( value === undefined && elem.nodeType === 1 ) {
				return elem.innerHTML;
			}

			// See if we can take a shortcut and just use innerHTML
			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {

				value = jQuery.htmlPrefilter( value );

				try {
					for ( ; i < l; i++ ) {
						elem = this[ i ] || {};

						// Remove element nodes and prevent memory leaks
						if ( elem.nodeType === 1 ) {
							jQuery.cleanData( getAll( elem, false ) );
							elem.innerHTML = value;
						}
					}

					elem = 0;

				// If using innerHTML throws an exception, use the fallback method
				} catch ( e ) {}
			}

			if ( elem ) {
				this.empty().append( value );
			}
		}, null, value, arguments.length );
	},

	replaceWith: function() {
		var ignored = [];

		// Make the changes, replacing each non-ignored context element with the new content
		return domManip( this, arguments, function( elem ) {
			var parent = this.parentNode;

			if ( jQuery.inArray( this, ignored ) < 0 ) {
				jQuery.cleanData( getAll( this ) );
				if ( parent ) {
					parent.replaceChild( elem, this );
				}
			}

		// Force callback invocation
		}, ignored );
	}
} );

jQuery.each( {
	appendTo: "append",
	prependTo: "prepend",
	insertBefore: "before",
	insertAfter: "after",
	replaceAll: "replaceWith"
}, function( name, original ) {
	jQuery.fn[ name ] = function( selector ) {
		var elems,
			ret = [],
			insert = jQuery( selector ),
			last = insert.length - 1,
			i = 0;

		for ( ; i <= last; i++ ) {
			elems = i === last ? this : this.clone( true );
			jQuery( insert[ i ] )[ original ]( elems );

			// Support: Android <=4.0 only, PhantomJS 1 only
			// .get() because push.apply(_, arraylike) throws on ancient WebKit
			push.apply( ret, elems.get() );
		}

		return this.pushStack( ret );
	};
} );
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );

var getStyles = function( elem ) {

		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
		// IE throws on elements created in popups
		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
		var view = elem.ownerDocument.defaultView;

		if ( !view || !view.opener ) {
			view = window;
		}

		return view.getComputedStyle( elem );
	};

var swap = function( elem, options, callback ) {
	var ret, name,
		old = {};

	// Remember the old values, and insert the new ones
	for ( name in options ) {
		old[ name ] = elem.style[ name ];
		elem.style[ name ] = options[ name ];
	}

	ret = callback.call( elem );

	// Revert the old values
	for ( name in options ) {
		elem.style[ name ] = old[ name ];
	}

	return ret;
};


var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );



( function() {

	// Executing both pixelPosition & boxSizingReliable tests require only one layout
	// so they're executed at the same time to save the second computation.
	function computeStyleTests() {

		// This is a singleton, we need to execute it only once
		if ( !div ) {
			return;
		}

		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
			"margin-top:1px;padding:0;border:0";
		div.style.cssText =
			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
			"margin:auto;border:1px;padding:1px;" +
			"width:60%;top:1%";
		documentElement.appendChild( container ).appendChild( div );

		var divStyle = window.getComputedStyle( div );
		pixelPositionVal = divStyle.top !== "1%";

		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;

		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
		// Some styles come back with percentage values, even though they shouldn't
		div.style.right = "60%";
		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;

		// Support: IE 9 - 11 only
		// Detect misreporting of content dimensions for box-sizing:border-box elements
		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;

		// Support: IE 9 only
		// Detect overflow:scroll screwiness (gh-3699)
		// Support: Chrome <=64
		// Don't get tricked when zoom affects offsetWidth (gh-4029)
		div.style.position = "absolute";
		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;

		documentElement.removeChild( container );

		// Nullify the div so it wouldn't be stored in the memory and
		// it will also be a sign that checks already performed
		div = null;
	}

	function roundPixelMeasures( measure ) {
		return Math.round( parseFloat( measure ) );
	}

	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
		reliableTrDimensionsVal, reliableMarginLeftVal,
		container = document.createElement( "div" ),
		div = document.createElement( "div" );

	// Finish early in limited (non-browser) environments
	if ( !div.style ) {
		return;
	}

	// Support: IE <=9 - 11 only
	// Style of cloned element affects source element cloned (#8908)
	div.style.backgroundClip = "content-box";
	div.cloneNode( true ).style.backgroundClip = "";
	support.clearCloneStyle = div.style.backgroundClip === "content-box";

	jQuery.extend( support, {
		boxSizingReliable: function() {
			computeStyleTests();
			return boxSizingReliableVal;
		},
		pixelBoxStyles: function() {
			computeStyleTests();
			return pixelBoxStylesVal;
		},
		pixelPosition: function() {
			computeStyleTests();
			return pixelPositionVal;
		},
		reliableMarginLeft: function() {
			computeStyleTests();
			return reliableMarginLeftVal;
		},
		scrollboxSize: function() {
			computeStyleTests();
			return scrollboxSizeVal;
		},

		// Support: IE 9 - 11+, Edge 15 - 18+
		// IE/Edge misreport `getComputedStyle` of table rows with width/height
		// set in CSS while `offset*` properties report correct values.
		// Behavior in IE 9 is more subtle than in newer versions & it passes
		// some versions of this test; make sure not to make it pass there!
		reliableTrDimensions: function() {
			var table, tr, trChild, trStyle;
			if ( reliableTrDimensionsVal == null ) {
				table = document.createElement( "table" );
				tr = document.createElement( "tr" );
				trChild = document.createElement( "div" );

				table.style.cssText = "position:absolute;left:-11111px";
				tr.style.height = "1px";
				trChild.style.height = "9px";

				documentElement
					.appendChild( table )
					.appendChild( tr )
					.appendChild( trChild );

				trStyle = window.getComputedStyle( tr );
				reliableTrDimensionsVal = parseInt( trStyle.height ) > 3;

				documentElement.removeChild( table );
			}
			return reliableTrDimensionsVal;
		}
	} );
} )();


function curCSS( elem, name, computed ) {
	var width, minWidth, maxWidth, ret,

		// Support: Firefox 51+
		// Retrieving style before computed somehow
		// fixes an issue with getting wrong values
		// on detached elements
		style = elem.style;

	computed = computed || getStyles( elem );

	// getPropertyValue is needed for:
	//   .css('filter') (IE 9 only, #12537)
	//   .css('--customProperty) (#3144)
	if ( computed ) {
		ret = computed.getPropertyValue( name ) || computed[ name ];

		if ( ret === "" && !isAttached( elem ) ) {
			ret = jQuery.style( elem, name );
		}

		// A tribute to the "awesome hack by Dean Edwards"
		// Android Browser returns percentage for some values,
		// but width seems to be reliably pixels.
		// This is against the CSSOM draft spec:
		// https://drafts.csswg.org/cssom/#resolved-values
		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {

			// Remember the original values
			width = style.width;
			minWidth = style.minWidth;
			maxWidth = style.maxWidth;

			// Put in the new values to get a computed value out
			style.minWidth = style.maxWidth = style.width = ret;
			ret = computed.width;

			// Revert the changed values
			style.width = width;
			style.minWidth = minWidth;
			style.maxWidth = maxWidth;
		}
	}

	return ret !== undefined ?

		// Support: IE <=9 - 11 only
		// IE returns zIndex value as an integer.
		ret + "" :
		ret;
}


function addGetHookIf( conditionFn, hookFn ) {

	// Define the hook, we'll check on the first run if it's really needed.
	return {
		get: function() {
			if ( conditionFn() ) {

				// Hook not needed (or it's not possible to use it due
				// to missing dependency), remove it.
				delete this.get;
				return;
			}

			// Hook needed; redefine it so that the support test is not executed again.
			return ( this.get = hookFn ).apply( this, arguments );
		}
	};
}


var cssPrefixes = [ "Webkit", "Moz", "ms" ],
	emptyStyle = document.createElement( "div" ).style,
	vendorProps = {};

// Return a vendor-prefixed property or undefined
function vendorPropName( name ) {

	// Check for vendor prefixed names
	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
		i = cssPrefixes.length;

	while ( i-- ) {
		name = cssPrefixes[ i ] + capName;
		if ( name in emptyStyle ) {
			return name;
		}
	}
}

// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
function finalPropName( name ) {
	var final = jQuery.cssProps[ name ] || vendorProps[ name ];

	if ( final ) {
		return final;
	}
	if ( name in emptyStyle ) {
		return name;
	}
	return vendorProps[ name ] = vendorPropName( name ) || name;
}


var

	// Swappable if display is none or starts with table
	// except "table", "table-cell", or "table-caption"
	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
	rcustomProp = /^--/,
	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
	cssNormalTransform = {
		letterSpacing: "0",
		fontWeight: "400"
	};

function setPositiveNumber( _elem, value, subtract ) {

	// Any relative (+/-) values have already been
	// normalized at this point
	var matches = rcssNum.exec( value );
	return matches ?

		// Guard against undefined "subtract", e.g., when used as in cssHooks
		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
		value;
}

function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
	var i = dimension === "width" ? 1 : 0,
		extra = 0,
		delta = 0;

	// Adjustment may not be necessary
	if ( box === ( isBorderBox ? "border" : "content" ) ) {
		return 0;
	}

	for ( ; i < 4; i += 2 ) {

		// Both box models exclude margin
		if ( box === "margin" ) {
			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
		}

		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
		if ( !isBorderBox ) {

			// Add padding
			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );

			// For "border" or "margin", add border
			if ( box !== "padding" ) {
				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );

			// But still keep track of it otherwise
			} else {
				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
			}

		// If we get here with a border-box (content + padding + border), we're seeking "content" or
		// "padding" or "margin"
		} else {

			// For "content", subtract padding
			if ( box === "content" ) {
				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
			}

			// For "content" or "padding", subtract border
			if ( box !== "margin" ) {
				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
			}
		}
	}

	// Account for positive content-box scroll gutter when requested by providing computedVal
	if ( !isBorderBox && computedVal >= 0 ) {

		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
		// Assuming integer scroll gutter, subtract the rest and round down
		delta += Math.max( 0, Math.ceil(
			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
			computedVal -
			delta -
			extra -
			0.5

		// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
		// Use an explicit zero to avoid NaN (gh-3964)
		) ) || 0;
	}

	return delta;
}

function getWidthOrHeight( elem, dimension, extra ) {

	// Start with computed style
	var styles = getStyles( elem ),

		// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
		// Fake content-box until we know it's needed to know the true value.
		boxSizingNeeded = !support.boxSizingReliable() || extra,
		isBorderBox = boxSizingNeeded &&
			jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
		valueIsBorderBox = isBorderBox,

		val = curCSS( elem, dimension, styles ),
		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );

	// Support: Firefox <=54
	// Return a confounding non-pixel value or feign ignorance, as appropriate.
	if ( rnumnonpx.test( val ) ) {
		if ( !extra ) {
			return val;
		}
		val = "auto";
	}


	// Support: IE 9 - 11 only
	// Use offsetWidth/offsetHeight for when box sizing is unreliable.
	// In those cases, the computed value can be trusted to be border-box.
	if ( ( !support.boxSizingReliable() && isBorderBox ||

		// Support: IE 10 - 11+, Edge 15 - 18+
		// IE/Edge misreport `getComputedStyle` of table rows with width/height
		// set in CSS while `offset*` properties report correct values.
		// Interestingly, in some cases IE 9 doesn't suffer from this issue.
		!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||

		// Fall back to offsetWidth/offsetHeight when value is "auto"
		// This happens for inline elements with no explicit setting (gh-3571)
		val === "auto" ||

		// Support: Android <=4.1 - 4.3 only
		// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&

		// Make sure the element is visible & connected
		elem.getClientRects().length ) {

		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";

		// Where available, offsetWidth/offsetHeight approximate border box dimensions.
		// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
		// retrieved value as a content box dimension.
		valueIsBorderBox = offsetProp in elem;
		if ( valueIsBorderBox ) {
			val = elem[ offsetProp ];
		}
	}

	// Normalize "" and auto
	val = parseFloat( val ) || 0;

	// Adjust for the element's box model
	return ( val +
		boxModelAdjustment(
			elem,
			dimension,
			extra || ( isBorderBox ? "border" : "content" ),
			valueIsBorderBox,
			styles,

			// Provide the current computed size to request scroll gutter calculation (gh-3589)
			val
		)
	) + "px";
}

jQuery.extend( {

	// Add in style property hooks for overriding the default
	// behavior of getting and setting a style property
	cssHooks: {
		opacity: {
			get: function( elem, computed ) {
				if ( computed ) {

					// We should always get a number back from opacity
					var ret = curCSS( elem, "opacity" );
					return ret === "" ? "1" : ret;
				}
			}
		}
	},

	// Don't automatically add "px" to these possibly-unitless properties
	cssNumber: {
		"animationIterationCount": true,
		"columnCount": true,
		"fillOpacity": true,
		"flexGrow": true,
		"flexShrink": true,
		"fontWeight": true,
		"gridArea": true,
		"gridColumn": true,
		"gridColumnEnd": true,
		"gridColumnStart": true,
		"gridRow": true,
		"gridRowEnd": true,
		"gridRowStart": true,
		"lineHeight": true,
		"opacity": true,
		"order": true,
		"orphans": true,
		"widows": true,
		"zIndex": true,
		"zoom": true
	},

	// Add in properties whose names you wish to fix before
	// setting or getting the value
	cssProps: {},

	// Get and set the style property on a DOM Node
	style: function( elem, name, value, extra ) {

		// Don't set styles on text and comment nodes
		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
			return;
		}

		// Make sure that we're working with the right name
		var ret, type, hooks,
			origName = camelCase( name ),
			isCustomProp = rcustomProp.test( name ),
			style = elem.style;

		// Make sure that we're working with the right name. We don't
		// want to query the value if it is a CSS custom property
		// since they are user-defined.
		if ( !isCustomProp ) {
			name = finalPropName( origName );
		}

		// Gets hook for the prefixed version, then unprefixed version
		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];

		// Check if we're setting a value
		if ( value !== undefined ) {
			type = typeof value;

			// Convert "+=" or "-=" to relative numbers (#7345)
			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
				value = adjustCSS( elem, name, ret );

				// Fixes bug #9237
				type = "number";
			}

			// Make sure that null and NaN values aren't set (#7116)
			if ( value == null || value !== value ) {
				return;
			}

			// If a number was passed in, add the unit (except for certain CSS properties)
			// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
			// "px" to a few hardcoded values.
			if ( type === "number" && !isCustomProp ) {
				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
			}

			// background-* props affect original clone's values
			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
				style[ name ] = "inherit";
			}

			// If a hook was provided, use that value, otherwise just set the specified value
			if ( !hooks || !( "set" in hooks ) ||
				( value = hooks.set( elem, value, extra ) ) !== undefined ) {

				if ( isCustomProp ) {
					style.setProperty( name, value );
				} else {
					style[ name ] = value;
				}
			}

		} else {

			// If a hook was provided get the non-computed value from there
			if ( hooks && "get" in hooks &&
				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {

				return ret;
			}

			// Otherwise just get the value from the style object
			return style[ name ];
		}
	},

	css: function( elem, name, extra, styles ) {
		var val, num, hooks,
			origName = camelCase( name ),
			isCustomProp = rcustomProp.test( name );

		// Make sure that we're working with the right name. We don't
		// want to modify the value if it is a CSS custom property
		// since they are user-defined.
		if ( !isCustomProp ) {
			name = finalPropName( origName );
		}

		// Try prefixed name followed by the unprefixed name
		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];

		// If a hook was provided get the computed value from there
		if ( hooks && "get" in hooks ) {
			val = hooks.get( elem, true, extra );
		}

		// Otherwise, if a way to get the computed value exists, use that
		if ( val === undefined ) {
			val = curCSS( elem, name, styles );
		}

		// Convert "normal" to computed value
		if ( val === "normal" && name in cssNormalTransform ) {
			val = cssNormalTransform[ name ];
		}

		// Make numeric if forced or a qualifier was provided and val looks numeric
		if ( extra === "" || extra ) {
			num = parseFloat( val );
			return extra === true || isFinite( num ) ? num || 0 : val;
		}

		return val;
	}
} );

jQuery.each( [ "height", "width" ], function( _i, dimension ) {
	jQuery.cssHooks[ dimension ] = {
		get: function( elem, computed, extra ) {
			if ( computed ) {

				// Certain elements can have dimension info if we invisibly show them
				// but it must have a current display style that would benefit
				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&

					// Support: Safari 8+
					// Table columns in Safari have non-zero offsetWidth & zero
					// getBoundingClientRect().width unless display is changed.
					// Support: IE <=11 only
					// Running getBoundingClientRect on a disconnected node
					// in IE throws an error.
					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
						swap( elem, cssShow, function() {
							return getWidthOrHeight( elem, dimension, extra );
						} ) :
						getWidthOrHeight( elem, dimension, extra );
			}
		},

		set: function( elem, value, extra ) {
			var matches,
				styles = getStyles( elem ),

				// Only read styles.position if the test has a chance to fail
				// to avoid forcing a reflow.
				scrollboxSizeBuggy = !support.scrollboxSize() &&
					styles.position === "absolute",

				// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
				boxSizingNeeded = scrollboxSizeBuggy || extra,
				isBorderBox = boxSizingNeeded &&
					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
				subtract = extra ?
					boxModelAdjustment(
						elem,
						dimension,
						extra,
						isBorderBox,
						styles
					) :
					0;

			// Account for unreliable border-box dimensions by comparing offset* to computed and
			// faking a content-box to get border and padding (gh-3699)
			if ( isBorderBox && scrollboxSizeBuggy ) {
				subtract -= Math.ceil(
					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
					parseFloat( styles[ dimension ] ) -
					boxModelAdjustment( elem, dimension, "border", false, styles ) -
					0.5
				);
			}

			// Convert to pixels if value adjustment is needed
			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
				( matches[ 3 ] || "px" ) !== "px" ) {

				elem.style[ dimension ] = value;
				value = jQuery.css( elem, dimension );
			}

			return setPositiveNumber( elem, value, subtract );
		}
	};
} );

jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
	function( elem, computed ) {
		if ( computed ) {
			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
				elem.getBoundingClientRect().left -
					swap( elem, { marginLeft: 0 }, function() {
						return elem.getBoundingClientRect().left;
					} )
				) + "px";
		}
	}
);

// These hooks are used by animate to expand properties
jQuery.each( {
	margin: "",
	padding: "",
	border: "Width"
}, function( prefix, suffix ) {
	jQuery.cssHooks[ prefix + suffix ] = {
		expand: function( value ) {
			var i = 0,
				expanded = {},

				// Assumes a single number if not a string
				parts = typeof value === "string" ? value.split( " " ) : [ value ];

			for ( ; i < 4; i++ ) {
				expanded[ prefix + cssExpand[ i ] + suffix ] =
					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
			}

			return expanded;
		}
	};

	if ( prefix !== "margin" ) {
		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
	}
} );

jQuery.fn.extend( {
	css: function( name, value ) {
		return access( this, function( elem, name, value ) {
			var styles, len,
				map = {},
				i = 0;

			if ( Array.isArray( name ) ) {
				styles = getStyles( elem );
				len = name.length;

				for ( ; i < len; i++ ) {
					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
				}

				return map;
			}

			return value !== undefined ?
				jQuery.style( elem, name, value ) :
				jQuery.css( elem, name );
		}, name, value, arguments.length > 1 );
	}
} );


function Tween( elem, options, prop, end, easing ) {
	return new Tween.prototype.init( elem, options, prop, end, easing );
}
jQuery.Tween = Tween;

Tween.prototype = {
	constructor: Tween,
	init: function( elem, options, prop, end, easing, unit ) {
		this.elem = elem;
		this.prop = prop;
		this.easing = easing || jQuery.easing._default;
		this.options = options;
		this.start = this.now = this.cur();
		this.end = end;
		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
	},
	cur: function() {
		var hooks = Tween.propHooks[ this.prop ];

		return hooks && hooks.get ?
			hooks.get( this ) :
			Tween.propHooks._default.get( this );
	},
	run: function( percent ) {
		var eased,
			hooks = Tween.propHooks[ this.prop ];

		if ( this.options.duration ) {
			this.pos = eased = jQuery.easing[ this.easing ](
				percent, this.options.duration * percent, 0, 1, this.options.duration
			);
		} else {
			this.pos = eased = percent;
		}
		this.now = ( this.end - this.start ) * eased + this.start;

		if ( this.options.step ) {
			this.options.step.call( this.elem, this.now, this );
		}

		if ( hooks && hooks.set ) {
			hooks.set( this );
		} else {
			Tween.propHooks._default.set( this );
		}
		return this;
	}
};

Tween.prototype.init.prototype = Tween.prototype;

Tween.propHooks = {
	_default: {
		get: function( tween ) {
			var result;

			// Use a property on the element directly when it is not a DOM element,
			// or when there is no matching style property that exists.
			if ( tween.elem.nodeType !== 1 ||
				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
				return tween.elem[ tween.prop ];
			}

			// Passing an empty string as a 3rd parameter to .css will automatically
			// attempt a parseFloat and fallback to a string if the parse fails.
			// Simple values such as "10px" are parsed to Float;
			// complex values such as "rotate(1rad)" are returned as-is.
			result = jQuery.css( tween.elem, tween.prop, "" );

			// Empty strings, null, undefined and "auto" are converted to 0.
			return !result || result === "auto" ? 0 : result;
		},
		set: function( tween ) {

			// Use step hook for back compat.
			// Use cssHook if its there.
			// Use .style if available and use plain properties where available.
			if ( jQuery.fx.step[ tween.prop ] ) {
				jQuery.fx.step[ tween.prop ]( tween );
			} else if ( tween.elem.nodeType === 1 && (
					jQuery.cssHooks[ tween.prop ] ||
					tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
			} else {
				tween.elem[ tween.prop ] = tween.now;
			}
		}
	}
};

// Support: IE <=9 only
// Panic based approach to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
	set: function( tween ) {
		if ( tween.elem.nodeType && tween.elem.parentNode ) {
			tween.elem[ tween.prop ] = tween.now;
		}
	}
};

jQuery.easing = {
	linear: function( p ) {
		return p;
	},
	swing: function( p ) {
		return 0.5 - Math.cos( p * Math.PI ) / 2;
	},
	_default: "swing"
};

jQuery.fx = Tween.prototype.init;

// Back compat <1.8 extension point
jQuery.fx.step = {};




var
	fxNow, inProgress,
	rfxtypes = /^(?:toggle|show|hide)$/,
	rrun = /queueHooks$/;

function schedule() {
	if ( inProgress ) {
		if ( document.hidden === false && window.requestAnimationFrame ) {
			window.requestAnimationFrame( schedule );
		} else {
			window.setTimeout( schedule, jQuery.fx.interval );
		}

		jQuery.fx.tick();
	}
}

// Animations created synchronously will run synchronously
function createFxNow() {
	window.setTimeout( function() {
		fxNow = undefined;
	} );
	return ( fxNow = Date.now() );
}

// Generate parameters to create a standard animation
function genFx( type, includeWidth ) {
	var which,
		i = 0,
		attrs = { height: type };

	// If we include width, step value is 1 to do all cssExpand values,
	// otherwise step value is 2 to skip over Left and Right
	includeWidth = includeWidth ? 1 : 0;
	for ( ; i < 4; i += 2 - includeWidth ) {
		which = cssExpand[ i ];
		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
	}

	if ( includeWidth ) {
		attrs.opacity = attrs.width = type;
	}

	return attrs;
}

function createTween( value, prop, animation ) {
	var tween,
		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
		index = 0,
		length = collection.length;
	for ( ; index < length; index++ ) {
		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {

			// We're done with this property
			return tween;
		}
	}
}

function defaultPrefilter( elem, props, opts ) {
	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
		isBox = "width" in props || "height" in props,
		anim = this,
		orig = {},
		style = elem.style,
		hidden = elem.nodeType && isHiddenWithinTree( elem ),
		dataShow = dataPriv.get( elem, "fxshow" );

	// Queue-skipping animations hijack the fx hooks
	if ( !opts.queue ) {
		hooks = jQuery._queueHooks( elem, "fx" );
		if ( hooks.unqueued == null ) {
			hooks.unqueued = 0;
			oldfire = hooks.empty.fire;
			hooks.empty.fire = function() {
				if ( !hooks.unqueued ) {
					oldfire();
				}
			};
		}
		hooks.unqueued++;

		anim.always( function() {

			// Ensure the complete handler is called before this completes
			anim.always( function() {
				hooks.unqueued--;
				if ( !jQuery.queue( elem, "fx" ).length ) {
					hooks.empty.fire();
				}
			} );
		} );
	}

	// Detect show/hide animations
	for ( prop in props ) {
		value = props[ prop ];
		if ( rfxtypes.test( value ) ) {
			delete props[ prop ];
			toggle = toggle || value === "toggle";
			if ( value === ( hidden ? "hide" : "show" ) ) {

				// Pretend to be hidden if this is a "show" and
				// there is still data from a stopped show/hide
				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
					hidden = true;

				// Ignore all other no-op show/hide data
				} else {
					continue;
				}
			}
			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
		}
	}

	// Bail out if this is a no-op like .hide().hide()
	propTween = !jQuery.isEmptyObject( props );
	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
		return;
	}

	// Restrict "overflow" and "display" styles during box animations
	if ( isBox && elem.nodeType === 1 ) {

		// Support: IE <=9 - 11, Edge 12 - 15
		// Record all 3 overflow attributes because IE does not infer the shorthand
		// from identically-valued overflowX and overflowY and Edge just mirrors
		// the overflowX value there.
		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];

		// Identify a display type, preferring old show/hide data over the CSS cascade
		restoreDisplay = dataShow && dataShow.display;
		if ( restoreDisplay == null ) {
			restoreDisplay = dataPriv.get( elem, "display" );
		}
		display = jQuery.css( elem, "display" );
		if ( display === "none" ) {
			if ( restoreDisplay ) {
				display = restoreDisplay;
			} else {

				// Get nonempty value(s) by temporarily forcing visibility
				showHide( [ elem ], true );
				restoreDisplay = elem.style.display || restoreDisplay;
				display = jQuery.css( elem, "display" );
				showHide( [ elem ] );
			}
		}

		// Animate inline elements as inline-block
		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
			if ( jQuery.css( elem, "float" ) === "none" ) {

				// Restore the original display value at the end of pure show/hide animations
				if ( !propTween ) {
					anim.done( function() {
						style.display = restoreDisplay;
					} );
					if ( restoreDisplay == null ) {
						display = style.display;
						restoreDisplay = display === "none" ? "" : display;
					}
				}
				style.display = "inline-block";
			}
		}
	}

	if ( opts.overflow ) {
		style.overflow = "hidden";
		anim.always( function() {
			style.overflow = opts.overflow[ 0 ];
			style.overflowX = opts.overflow[ 1 ];
			style.overflowY = opts.overflow[ 2 ];
		} );
	}

	// Implement show/hide animations
	propTween = false;
	for ( prop in orig ) {

		// General show/hide setup for this element animation
		if ( !propTween ) {
			if ( dataShow ) {
				if ( "hidden" in dataShow ) {
					hidden = dataShow.hidden;
				}
			} else {
				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
			}

			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
			if ( toggle ) {
				dataShow.hidden = !hidden;
			}

			// Show elements before animating them
			if ( hidden ) {
				showHide( [ elem ], true );
			}

			/* eslint-disable no-loop-func */

			anim.done( function() {

			/* eslint-enable no-loop-func */

				// The final step of a "hide" animation is actually hiding the element
				if ( !hidden ) {
					showHide( [ elem ] );
				}
				dataPriv.remove( elem, "fxshow" );
				for ( prop in orig ) {
					jQuery.style( elem, prop, orig[ prop ] );
				}
			} );
		}

		// Per-property setup
		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
		if ( !( prop in dataShow ) ) {
			dataShow[ prop ] = propTween.start;
			if ( hidden ) {
				propTween.end = propTween.start;
				propTween.start = 0;
			}
		}
	}
}

function propFilter( props, specialEasing ) {
	var index, name, easing, value, hooks;

	// camelCase, specialEasing and expand cssHook pass
	for ( index in props ) {
		name = camelCase( index );
		easing = specialEasing[ name ];
		value = props[ index ];
		if ( Array.isArray( value ) ) {
			easing = value[ 1 ];
			value = props[ index ] = value[ 0 ];
		}

		if ( index !== name ) {
			props[ name ] = value;
			delete props[ index ];
		}

		hooks = jQuery.cssHooks[ name ];
		if ( hooks && "expand" in hooks ) {
			value = hooks.expand( value );
			delete props[ name ];

			// Not quite $.extend, this won't overwrite existing keys.
			// Reusing 'index' because we have the correct "name"
			for ( index in value ) {
				if ( !( index in props ) ) {
					props[ index ] = value[ index ];
					specialEasing[ index ] = easing;
				}
			}
		} else {
			specialEasing[ name ] = easing;
		}
	}
}

function Animation( elem, properties, options ) {
	var result,
		stopped,
		index = 0,
		length = Animation.prefilters.length,
		deferred = jQuery.Deferred().always( function() {

			// Don't match elem in the :animated selector
			delete tick.elem;
		} ),
		tick = function() {
			if ( stopped ) {
				return false;
			}
			var currentTime = fxNow || createFxNow(),
				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),

				// Support: Android 2.3 only
				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
				temp = remaining / animation.duration || 0,
				percent = 1 - temp,
				index = 0,
				length = animation.tweens.length;

			for ( ; index < length; index++ ) {
				animation.tweens[ index ].run( percent );
			}

			deferred.notifyWith( elem, [ animation, percent, remaining ] );

			// If there's more to do, yield
			if ( percent < 1 && length ) {
				return remaining;
			}

			// If this was an empty animation, synthesize a final progress notification
			if ( !length ) {
				deferred.notifyWith( elem, [ animation, 1, 0 ] );
			}

			// Resolve the animation and report its conclusion
			deferred.resolveWith( elem, [ animation ] );
			return false;
		},
		animation = deferred.promise( {
			elem: elem,
			props: jQuery.extend( {}, properties ),
			opts: jQuery.extend( true, {
				specialEasing: {},
				easing: jQuery.easing._default
			}, options ),
			originalProperties: properties,
			originalOptions: options,
			startTime: fxNow || createFxNow(),
			duration: options.duration,
			tweens: [],
			createTween: function( prop, end ) {
				var tween = jQuery.Tween( elem, animation.opts, prop, end,
						animation.opts.specialEasing[ prop ] || animation.opts.easing );
				animation.tweens.push( tween );
				return tween;
			},
			stop: function( gotoEnd ) {
				var index = 0,

					// If we are going to the end, we want to run all the tweens
					// otherwise we skip this part
					length = gotoEnd ? animation.tweens.length : 0;
				if ( stopped ) {
					return this;
				}
				stopped = true;
				for ( ; index < length; index++ ) {
					animation.tweens[ index ].run( 1 );
				}

				// Resolve when we played the last frame; otherwise, reject
				if ( gotoEnd ) {
					deferred.notifyWith( elem, [ animation, 1, 0 ] );
					deferred.resolveWith( elem, [ animation, gotoEnd ] );
				} else {
					deferred.rejectWith( elem, [ animation, gotoEnd ] );
				}
				return this;
			}
		} ),
		props = animation.props;

	propFilter( props, animation.opts.specialEasing );

	for ( ; index < length; index++ ) {
		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
		if ( result ) {
			if ( isFunction( result.stop ) ) {
				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
					result.stop.bind( result );
			}
			return result;
		}
	}

	jQuery.map( props, createTween, animation );

	if ( isFunction( animation.opts.start ) ) {
		animation.opts.start.call( elem, animation );
	}

	// Attach callbacks from options
	animation
		.progress( animation.opts.progress )
		.done( animation.opts.done, animation.opts.complete )
		.fail( animation.opts.fail )
		.always( animation.opts.always );

	jQuery.fx.timer(
		jQuery.extend( tick, {
			elem: elem,
			anim: animation,
			queue: animation.opts.queue
		} )
	);

	return animation;
}

jQuery.Animation = jQuery.extend( Animation, {

	tweeners: {
		"*": [ function( prop, value ) {
			var tween = this.createTween( prop, value );
			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
			return tween;
		} ]
	},

	tweener: function( props, callback ) {
		if ( isFunction( props ) ) {
			callback = props;
			props = [ "*" ];
		} else {
			props = props.match( rnothtmlwhite );
		}

		var prop,
			index = 0,
			length = props.length;

		for ( ; index < length; index++ ) {
			prop = props[ index ];
			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
			Animation.tweeners[ prop ].unshift( callback );
		}
	},

	prefilters: [ defaultPrefilter ],

	prefilter: function( callback, prepend ) {
		if ( prepend ) {
			Animation.prefilters.unshift( callback );
		} else {
			Animation.prefilters.push( callback );
		}
	}
} );

jQuery.speed = function( speed, easing, fn ) {
	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
		complete: fn || !fn && easing ||
			isFunction( speed ) && speed,
		duration: speed,
		easing: fn && easing || easing && !isFunction( easing ) && easing
	};

	// Go to the end state if fx are off
	if ( jQuery.fx.off ) {
		opt.duration = 0;

	} else {
		if ( typeof opt.duration !== "number" ) {
			if ( opt.duration in jQuery.fx.speeds ) {
				opt.duration = jQuery.fx.speeds[ opt.duration ];

			} else {
				opt.duration = jQuery.fx.speeds._default;
			}
		}
	}

	// Normalize opt.queue - true/undefined/null -> "fx"
	if ( opt.queue == null || opt.queue === true ) {
		opt.queue = "fx";
	}

	// Queueing
	opt.old = opt.complete;

	opt.complete = function() {
		if ( isFunction( opt.old ) ) {
			opt.old.call( this );
		}

		if ( opt.queue ) {
			jQuery.dequeue( this, opt.queue );
		}
	};

	return opt;
};

jQuery.fn.extend( {
	fadeTo: function( speed, to, easing, callback ) {

		// Show any hidden elements after setting opacity to 0
		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()

			// Animate to the value specified
			.end().animate( { opacity: to }, speed, easing, callback );
	},
	animate: function( prop, speed, easing, callback ) {
		var empty = jQuery.isEmptyObject( prop ),
			optall = jQuery.speed( speed, easing, callback ),
			doAnimation = function() {

				// Operate on a copy of prop so per-property easing won't be lost
				var anim = Animation( this, jQuery.extend( {}, prop ), optall );

				// Empty animations, or finishing resolves immediately
				if ( empty || dataPriv.get( this, "finish" ) ) {
					anim.stop( true );
				}
			};
			doAnimation.finish = doAnimation;

		return empty || optall.queue === false ?
			this.each( doAnimation ) :
			this.queue( optall.queue, doAnimation );
	},
	stop: function( type, clearQueue, gotoEnd ) {
		var stopQueue = function( hooks ) {
			var stop = hooks.stop;
			delete hooks.stop;
			stop( gotoEnd );
		};

		if ( typeof type !== "string" ) {
			gotoEnd = clearQueue;
			clearQueue = type;
			type = undefined;
		}
		if ( clearQueue ) {
			this.queue( type || "fx", [] );
		}

		return this.each( function() {
			var dequeue = true,
				index = type != null && type + "queueHooks",
				timers = jQuery.timers,
				data = dataPriv.get( this );

			if ( index ) {
				if ( data[ index ] && data[ index ].stop ) {
					stopQueue( data[ index ] );
				}
			} else {
				for ( index in data ) {
					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
						stopQueue( data[ index ] );
					}
				}
			}

			for ( index = timers.length; index--; ) {
				if ( timers[ index ].elem === this &&
					( type == null || timers[ index ].queue === type ) ) {

					timers[ index ].anim.stop( gotoEnd );
					dequeue = false;
					timers.splice( index, 1 );
				}
			}

			// Start the next in the queue if the last step wasn't forced.
			// Timers currently will call their complete callbacks, which
			// will dequeue but only if they were gotoEnd.
			if ( dequeue || !gotoEnd ) {
				jQuery.dequeue( this, type );
			}
		} );
	},
	finish: function( type ) {
		if ( type !== false ) {
			type = type || "fx";
		}
		return this.each( function() {
			var index,
				data = dataPriv.get( this ),
				queue = data[ type + "queue" ],
				hooks = data[ type + "queueHooks" ],
				timers = jQuery.timers,
				length = queue ? queue.length : 0;

			// Enable finishing flag on private data
			data.finish = true;

			// Empty the queue first
			jQuery.queue( this, type, [] );

			if ( hooks && hooks.stop ) {
				hooks.stop.call( this, true );
			}

			// Look for any active animations, and finish them
			for ( index = timers.length; index--; ) {
				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
					timers[ index ].anim.stop( true );
					timers.splice( index, 1 );
				}
			}

			// Look for any animations in the old queue and finish them
			for ( index = 0; index < length; index++ ) {
				if ( queue[ index ] && queue[ index ].finish ) {
					queue[ index ].finish.call( this );
				}
			}

			// Turn off finishing flag
			delete data.finish;
		} );
	}
} );

jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
	var cssFn = jQuery.fn[ name ];
	jQuery.fn[ name ] = function( speed, easing, callback ) {
		return speed == null || typeof speed === "boolean" ?
			cssFn.apply( this, arguments ) :
			this.animate( genFx( name, true ), speed, easing, callback );
	};
} );

// Generate shortcuts for custom animations
jQuery.each( {
	slideDown: genFx( "show" ),
	slideUp: genFx( "hide" ),
	slideToggle: genFx( "toggle" ),
	fadeIn: { opacity: "show" },
	fadeOut: { opacity: "hide" },
	fadeToggle: { opacity: "toggle" }
}, function( name, props ) {
	jQuery.fn[ name ] = function( speed, easing, callback ) {
		return this.animate( props, speed, easing, callback );
	};
} );

jQuery.timers = [];
jQuery.fx.tick = function() {
	var timer,
		i = 0,
		timers = jQuery.timers;

	fxNow = Date.now();

	for ( ; i < timers.length; i++ ) {
		timer = timers[ i ];

		// Run the timer and safely remove it when done (allowing for external removal)
		if ( !timer() && timers[ i ] === timer ) {
			timers.splice( i--, 1 );
		}
	}

	if ( !timers.length ) {
		jQuery.fx.stop();
	}
	fxNow = undefined;
};

jQuery.fx.timer = function( timer ) {
	jQuery.timers.push( timer );
	jQuery.fx.start();
};

jQuery.fx.interval = 13;
jQuery.fx.start = function() {
	if ( inProgress ) {
		return;
	}

	inProgress = true;
	schedule();
};

jQuery.fx.stop = function() {
	inProgress = null;
};

jQuery.fx.speeds = {
	slow: 600,
	fast: 200,

	// Default speed
	_default: 400
};


// Based off of the plugin by Clint Helfers, with permission.
// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
jQuery.fn.delay = function( time, type ) {
	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
	type = type || "fx";

	return this.queue( type, function( next, hooks ) {
		var timeout = window.setTimeout( next, time );
		hooks.stop = function() {
			window.clearTimeout( timeout );
		};
	} );
};


( function() {
	var input = document.createElement( "input" ),
		select = document.createElement( "select" ),
		opt = select.appendChild( document.createElement( "option" ) );

	input.type = "checkbox";

	// Support: Android <=4.3 only
	// Default value for a checkbox should be "on"
	support.checkOn = input.value !== "";

	// Support: IE <=11 only
	// Must access selectedIndex to make default options select
	support.optSelected = opt.selected;

	// Support: IE <=11 only
	// An input loses its value after becoming a radio
	input = document.createElement( "input" );
	input.value = "t";
	input.type = "radio";
	support.radioValue = input.value === "t";
} )();


var boolHook,
	attrHandle = jQuery.expr.attrHandle;

jQuery.fn.extend( {
	attr: function( name, value ) {
		return access( this, jQuery.attr, name, value, arguments.length > 1 );
	},

	removeAttr: function( name ) {
		return this.each( function() {
			jQuery.removeAttr( this, name );
		} );
	}
} );

jQuery.extend( {
	attr: function( elem, name, value ) {
		var ret, hooks,
			nType = elem.nodeType;

		// Don't get/set attributes on text, comment and attribute nodes
		if ( nType === 3 || nType === 8 || nType === 2 ) {
			return;
		}

		// Fallback to prop when attributes are not supported
		if ( typeof elem.getAttribute === "undefined" ) {
			return jQuery.prop( elem, name, value );
		}

		// Attribute hooks are determined by the lowercase version
		// Grab necessary hook if one is defined
		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
		}

		if ( value !== undefined ) {
			if ( value === null ) {
				jQuery.removeAttr( elem, name );
				return;
			}

			if ( hooks && "set" in hooks &&
				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
				return ret;
			}

			elem.setAttribute( name, value + "" );
			return value;
		}

		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
			return ret;
		}

		ret = jQuery.find.attr( elem, name );

		// Non-existent attributes return null, we normalize to undefined
		return ret == null ? undefined : ret;
	},

	attrHooks: {
		type: {
			set: function( elem, value ) {
				if ( !support.radioValue && value === "radio" &&
					nodeName( elem, "input" ) ) {
					var val = elem.value;
					elem.setAttribute( "type", value );
					if ( val ) {
						elem.value = val;
					}
					return value;
				}
			}
		}
	},

	removeAttr: function( elem, value ) {
		var name,
			i = 0,

			// Attribute names can contain non-HTML whitespace characters
			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
			attrNames = value && value.match( rnothtmlwhite );

		if ( attrNames && elem.nodeType === 1 ) {
			while ( ( name = attrNames[ i++ ] ) ) {
				elem.removeAttribute( name );
			}
		}
	}
} );

// Hooks for boolean attributes
boolHook = {
	set: function( elem, value, name ) {
		if ( value === false ) {

			// Remove boolean attributes when set to false
			jQuery.removeAttr( elem, name );
		} else {
			elem.setAttribute( name, name );
		}
		return name;
	}
};

jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
	var getter = attrHandle[ name ] || jQuery.find.attr;

	attrHandle[ name ] = function( elem, name, isXML ) {
		var ret, handle,
			lowercaseName = name.toLowerCase();

		if ( !isXML ) {

			// Avoid an infinite loop by temporarily removing this function from the getter
			handle = attrHandle[ lowercaseName ];
			attrHandle[ lowercaseName ] = ret;
			ret = getter( elem, name, isXML ) != null ?
				lowercaseName :
				null;
			attrHandle[ lowercaseName ] = handle;
		}
		return ret;
	};
} );




var rfocusable = /^(?:input|select|textarea|button)$/i,
	rclickable = /^(?:a|area)$/i;

jQuery.fn.extend( {
	prop: function( name, value ) {
		return access( this, jQuery.prop, name, value, arguments.length > 1 );
	},

	removeProp: function( name ) {
		return this.each( function() {
			delete this[ jQuery.propFix[ name ] || name ];
		} );
	}
} );

jQuery.extend( {
	prop: function( elem, name, value ) {
		var ret, hooks,
			nType = elem.nodeType;

		// Don't get/set properties on text, comment and attribute nodes
		if ( nType === 3 || nType === 8 || nType === 2 ) {
			return;
		}

		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {

			// Fix name and attach hooks
			name = jQuery.propFix[ name ] || name;
			hooks = jQuery.propHooks[ name ];
		}

		if ( value !== undefined ) {
			if ( hooks && "set" in hooks &&
				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
				return ret;
			}

			return ( elem[ name ] = value );
		}

		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
			return ret;
		}

		return elem[ name ];
	},

	propHooks: {
		tabIndex: {
			get: function( elem ) {

				// Support: IE <=9 - 11 only
				// elem.tabIndex doesn't always return the
				// correct value when it hasn't been explicitly set
				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
				// Use proper attribute retrieval(#12072)
				var tabindex = jQuery.find.attr( elem, "tabindex" );

				if ( tabindex ) {
					return parseInt( tabindex, 10 );
				}

				if (
					rfocusable.test( elem.nodeName ) ||
					rclickable.test( elem.nodeName ) &&
					elem.href
				) {
					return 0;
				}

				return -1;
			}
		}
	},

	propFix: {
		"for": "htmlFor",
		"class": "className"
	}
} );

// Support: IE <=11 only
// Accessing the selectedIndex property
// forces the browser to respect setting selected
// on the option
// The getter ensures a default option is selected
// when in an optgroup
// eslint rule "no-unused-expressions" is disabled for this code
// since it considers such accessions noop
if ( !support.optSelected ) {
	jQuery.propHooks.selected = {
		get: function( elem ) {

			/* eslint no-unused-expressions: "off" */

			var parent = elem.parentNode;
			if ( parent && parent.parentNode ) {
				parent.parentNode.selectedIndex;
			}
			return null;
		},
		set: function( elem ) {

			/* eslint no-unused-expressions: "off" */

			var parent = elem.parentNode;
			if ( parent ) {
				parent.selectedIndex;

				if ( parent.parentNode ) {
					parent.parentNode.selectedIndex;
				}
			}
		}
	};
}

jQuery.each( [
	"tabIndex",
	"readOnly",
	"maxLength",
	"cellSpacing",
	"cellPadding",
	"rowSpan",
	"colSpan",
	"useMap",
	"frameBorder",
	"contentEditable"
], function() {
	jQuery.propFix[ this.toLowerCase() ] = this;
} );




	// Strip and collapse whitespace according to HTML spec
	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
	function stripAndCollapse( value ) {
		var tokens = value.match( rnothtmlwhite ) || [];
		return tokens.join( " " );
	}


function getClass( elem ) {
	return elem.getAttribute && elem.getAttribute( "class" ) || "";
}

function classesToArray( value ) {
	if ( Array.isArray( value ) ) {
		return value;
	}
	if ( typeof value === "string" ) {
		return value.match( rnothtmlwhite ) || [];
	}
	return [];
}

jQuery.fn.extend( {
	addClass: function( value ) {
		var classes, elem, cur, curValue, clazz, j, finalValue,
			i = 0;

		if ( isFunction( value ) ) {
			return this.each( function( j ) {
				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
			} );
		}

		classes = classesToArray( value );

		if ( classes.length ) {
			while ( ( elem = this[ i++ ] ) ) {
				curValue = getClass( elem );
				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );

				if ( cur ) {
					j = 0;
					while ( ( clazz = classes[ j++ ] ) ) {
						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
							cur += clazz + " ";
						}
					}

					// Only assign if different to avoid unneeded rendering.
					finalValue = stripAndCollapse( cur );
					if ( curValue !== finalValue ) {
						elem.setAttribute( "class", finalValue );
					}
				}
			}
		}

		return this;
	},

	removeClass: function( value ) {
		var classes, elem, cur, curValue, clazz, j, finalValue,
			i = 0;

		if ( isFunction( value ) ) {
			return this.each( function( j ) {
				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
			} );
		}

		if ( !arguments.length ) {
			return this.attr( "class", "" );
		}

		classes = classesToArray( value );

		if ( classes.length ) {
			while ( ( elem = this[ i++ ] ) ) {
				curValue = getClass( elem );

				// This expression is here for better compressibility (see addClass)
				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );

				if ( cur ) {
					j = 0;
					while ( ( clazz = classes[ j++ ] ) ) {

						// Remove *all* instances
						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
							cur = cur.replace( " " + clazz + " ", " " );
						}
					}

					// Only assign if different to avoid unneeded rendering.
					finalValue = stripAndCollapse( cur );
					if ( curValue !== finalValue ) {
						elem.setAttribute( "class", finalValue );
					}
				}
			}
		}

		return this;
	},

	toggleClass: function( value, stateVal ) {
		var type = typeof value,
			isValidValue = type === "string" || Array.isArray( value );

		if ( typeof stateVal === "boolean" && isValidValue ) {
			return stateVal ? this.addClass( value ) : this.removeClass( value );
		}

		if ( isFunction( value ) ) {
			return this.each( function( i ) {
				jQuery( this ).toggleClass(
					value.call( this, i, getClass( this ), stateVal ),
					stateVal
				);
			} );
		}

		return this.each( function() {
			var className, i, self, classNames;

			if ( isValidValue ) {

				// Toggle individual class names
				i = 0;
				self = jQuery( this );
				classNames = classesToArray( value );

				while ( ( className = classNames[ i++ ] ) ) {

					// Check each className given, space separated list
					if ( self.hasClass( className ) ) {
						self.removeClass( className );
					} else {
						self.addClass( className );
					}
				}

			// Toggle whole class name
			} else if ( value === undefined || type === "boolean" ) {
				className = getClass( this );
				if ( className ) {

					// Store className if set
					dataPriv.set( this, "__className__", className );
				}

				// If the element has a class name or if we're passed `false`,
				// then remove the whole classname (if there was one, the above saved it).
				// Otherwise bring back whatever was previously saved (if anything),
				// falling back to the empty string if nothing was stored.
				if ( this.setAttribute ) {
					this.setAttribute( "class",
						className || value === false ?
						"" :
						dataPriv.get( this, "__className__" ) || ""
					);
				}
			}
		} );
	},

	hasClass: function( selector ) {
		var className, elem,
			i = 0;

		className = " " + selector + " ";
		while ( ( elem = this[ i++ ] ) ) {
			if ( elem.nodeType === 1 &&
				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
					return true;
			}
		}

		return false;
	}
} );




var rreturn = /\r/g;

jQuery.fn.extend( {
	val: function( value ) {
		var hooks, ret, valueIsFunction,
			elem = this[ 0 ];

		if ( !arguments.length ) {
			if ( elem ) {
				hooks = jQuery.valHooks[ elem.type ] ||
					jQuery.valHooks[ elem.nodeName.toLowerCase() ];

				if ( hooks &&
					"get" in hooks &&
					( ret = hooks.get( elem, "value" ) ) !== undefined
				) {
					return ret;
				}

				ret = elem.value;

				// Handle most common string cases
				if ( typeof ret === "string" ) {
					return ret.replace( rreturn, "" );
				}

				// Handle cases where value is null/undef or number
				return ret == null ? "" : ret;
			}

			return;
		}

		valueIsFunction = isFunction( value );

		return this.each( function( i ) {
			var val;

			if ( this.nodeType !== 1 ) {
				return;
			}

			if ( valueIsFunction ) {
				val = value.call( this, i, jQuery( this ).val() );
			} else {
				val = value;
			}

			// Treat null/undefined as ""; convert numbers to string
			if ( val == null ) {
				val = "";

			} else if ( typeof val === "number" ) {
				val += "";

			} else if ( Array.isArray( val ) ) {
				val = jQuery.map( val, function( value ) {
					return value == null ? "" : value + "";
				} );
			}

			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];

			// If set returns undefined, fall back to normal setting
			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
				this.value = val;
			}
		} );
	}
} );

jQuery.extend( {
	valHooks: {
		option: {
			get: function( elem ) {

				var val = jQuery.find.attr( elem, "value" );
				return val != null ?
					val :

					// Support: IE <=10 - 11 only
					// option.text throws exceptions (#14686, #14858)
					// Strip and collapse whitespace
					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
					stripAndCollapse( jQuery.text( elem ) );
			}
		},
		select: {
			get: function( elem ) {
				var value, option, i,
					options = elem.options,
					index = elem.selectedIndex,
					one = elem.type === "select-one",
					values = one ? null : [],
					max = one ? index + 1 : options.length;

				if ( index < 0 ) {
					i = max;

				} else {
					i = one ? index : 0;
				}

				// Loop through all the selected options
				for ( ; i < max; i++ ) {
					option = options[ i ];

					// Support: IE <=9 only
					// IE8-9 doesn't update selected after form reset (#2551)
					if ( ( option.selected || i === index ) &&

							// Don't return options that are disabled or in a disabled optgroup
							!option.disabled &&
							( !option.parentNode.disabled ||
								!nodeName( option.parentNode, "optgroup" ) ) ) {

						// Get the specific value for the option
						value = jQuery( option ).val();

						// We don't need an array for one selects
						if ( one ) {
							return value;
						}

						// Multi-Selects return an array
						values.push( value );
					}
				}

				return values;
			},

			set: function( elem, value ) {
				var optionSet, option,
					options = elem.options,
					values = jQuery.makeArray( value ),
					i = options.length;

				while ( i-- ) {
					option = options[ i ];

					/* eslint-disable no-cond-assign */

					if ( option.selected =
						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
					) {
						optionSet = true;
					}

					/* eslint-enable no-cond-assign */
				}

				// Force browsers to behave consistently when non-matching value is set
				if ( !optionSet ) {
					elem.selectedIndex = -1;
				}
				return values;
			}
		}
	}
} );

// Radios and checkboxes getter/setter
jQuery.each( [ "radio", "checkbox" ], function() {
	jQuery.valHooks[ this ] = {
		set: function( elem, value ) {
			if ( Array.isArray( value ) ) {
				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
			}
		}
	};
	if ( !support.checkOn ) {
		jQuery.valHooks[ this ].get = function( elem ) {
			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
		};
	}
} );




// Return jQuery for attributes-only inclusion


support.focusin = "onfocusin" in window;


var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
	stopPropagationCallback = function( e ) {
		e.stopPropagation();
	};

jQuery.extend( jQuery.event, {

	trigger: function( event, data, elem, onlyHandlers ) {

		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
			eventPath = [ elem || document ],
			type = hasOwn.call( event, "type" ) ? event.type : event,
			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];

		cur = lastElement = tmp = elem = elem || document;

		// Don't do events on text and comment nodes
		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
			return;
		}

		// focus/blur morphs to focusin/out; ensure we're not firing them right now
		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
			return;
		}

		if ( type.indexOf( "." ) > -1 ) {

			// Namespaced trigger; create a regexp to match event type in handle()
			namespaces = type.split( "." );
			type = namespaces.shift();
			namespaces.sort();
		}
		ontype = type.indexOf( ":" ) < 0 && "on" + type;

		// Caller can pass in a jQuery.Event object, Object, or just an event type string
		event = event[ jQuery.expando ] ?
			event :
			new jQuery.Event( type, typeof event === "object" && event );

		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
		event.isTrigger = onlyHandlers ? 2 : 3;
		event.namespace = namespaces.join( "." );
		event.rnamespace = event.namespace ?
			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
			null;

		// Clean up the event in case it is being reused
		event.result = undefined;
		if ( !event.target ) {
			event.target = elem;
		}

		// Clone any incoming data and prepend the event, creating the handler arg list
		data = data == null ?
			[ event ] :
			jQuery.makeArray( data, [ event ] );

		// Allow special events to draw outside the lines
		special = jQuery.event.special[ type ] || {};
		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
			return;
		}

		// Determine event propagation path in advance, per W3C events spec (#9951)
		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {

			bubbleType = special.delegateType || type;
			if ( !rfocusMorph.test( bubbleType + type ) ) {
				cur = cur.parentNode;
			}
			for ( ; cur; cur = cur.parentNode ) {
				eventPath.push( cur );
				tmp = cur;
			}

			// Only add window if we got to document (e.g., not plain obj or detached DOM)
			if ( tmp === ( elem.ownerDocument || document ) ) {
				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
			}
		}

		// Fire handlers on the event path
		i = 0;
		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
			lastElement = cur;
			event.type = i > 1 ?
				bubbleType :
				special.bindType || type;

			// jQuery handler
			handle = (
					dataPriv.get( cur, "events" ) || Object.create( null )
				)[ event.type ] &&
				dataPriv.get( cur, "handle" );
			if ( handle ) {
				handle.apply( cur, data );
			}

			// Native handler
			handle = ontype && cur[ ontype ];
			if ( handle && handle.apply && acceptData( cur ) ) {
				event.result = handle.apply( cur, data );
				if ( event.result === false ) {
					event.preventDefault();
				}
			}
		}
		event.type = type;

		// If nobody prevented the default action, do it now
		if ( !onlyHandlers && !event.isDefaultPrevented() ) {

			if ( ( !special._default ||
				special._default.apply( eventPath.pop(), data ) === false ) &&
				acceptData( elem ) ) {

				// Call a native DOM method on the target with the same name as the event.
				// Don't do default actions on window, that's where global variables be (#6170)
				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {

					// Don't re-trigger an onFOO event when we call its FOO() method
					tmp = elem[ ontype ];

					if ( tmp ) {
						elem[ ontype ] = null;
					}

					// Prevent re-triggering of the same event, since we already bubbled it above
					jQuery.event.triggered = type;

					if ( event.isPropagationStopped() ) {
						lastElement.addEventListener( type, stopPropagationCallback );
					}

					elem[ type ]();

					if ( event.isPropagationStopped() ) {
						lastElement.removeEventListener( type, stopPropagationCallback );
					}

					jQuery.event.triggered = undefined;

					if ( tmp ) {
						elem[ ontype ] = tmp;
					}
				}
			}
		}

		return event.result;
	},

	// Piggyback on a donor event to simulate a different one
	// Used only for `focus(in | out)` events
	simulate: function( type, elem, event ) {
		var e = jQuery.extend(
			new jQuery.Event(),
			event,
			{
				type: type,
				isSimulated: true
			}
		);

		jQuery.event.trigger( e, null, elem );
	}

} );

jQuery.fn.extend( {

	trigger: function( type, data ) {
		return this.each( function() {
			jQuery.event.trigger( type, data, this );
		} );
	},
	triggerHandler: function( type, data ) {
		var elem = this[ 0 ];
		if ( elem ) {
			return jQuery.event.trigger( type, data, elem, true );
		}
	}
} );


// Support: Firefox <=44
// Firefox doesn't have focus(in | out) events
// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
//
// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
// focus(in | out) events fire after focus & blur events,
// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
if ( !support.focusin ) {
	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {

		// Attach a single capturing handler on the document while someone wants focusin/focusout
		var handler = function( event ) {
			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
		};

		jQuery.event.special[ fix ] = {
			setup: function() {

				// Handle: regular nodes (via `this.ownerDocument`), window
				// (via `this.document`) & document (via `this`).
				var doc = this.ownerDocument || this.document || this,
					attaches = dataPriv.access( doc, fix );

				if ( !attaches ) {
					doc.addEventListener( orig, handler, true );
				}
				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
			},
			teardown: function() {
				var doc = this.ownerDocument || this.document || this,
					attaches = dataPriv.access( doc, fix ) - 1;

				if ( !attaches ) {
					doc.removeEventListener( orig, handler, true );
					dataPriv.remove( doc, fix );

				} else {
					dataPriv.access( doc, fix, attaches );
				}
			}
		};
	} );
}
var location = window.location;

var nonce = { guid: Date.now() };

var rquery = ( /\?/ );



// Cross-browser xml parsing
jQuery.parseXML = function( data ) {
	var xml;
	if ( !data || typeof data !== "string" ) {
		return null;
	}

	// Support: IE 9 - 11 only
	// IE throws on parseFromString with invalid input.
	try {
		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
	} catch ( e ) {
		xml = undefined;
	}

	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
		jQuery.error( "Invalid XML: " + data );
	}
	return xml;
};


var
	rbracket = /\[\]$/,
	rCRLF = /\r?\n/g,
	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
	rsubmittable = /^(?:input|select|textarea|keygen)/i;

function buildParams( prefix, obj, traditional, add ) {
	var name;

	if ( Array.isArray( obj ) ) {

		// Serialize array item.
		jQuery.each( obj, function( i, v ) {
			if ( traditional || rbracket.test( prefix ) ) {

				// Treat each array item as a scalar.
				add( prefix, v );

			} else {

				// Item is non-scalar (array or object), encode its numeric index.
				buildParams(
					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
					v,
					traditional,
					add
				);
			}
		} );

	} else if ( !traditional && toType( obj ) === "object" ) {

		// Serialize object item.
		for ( name in obj ) {
			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
		}

	} else {

		// Serialize scalar item.
		add( prefix, obj );
	}
}

// Serialize an array of form elements or a set of
// key/values into a query string
jQuery.param = function( a, traditional ) {
	var prefix,
		s = [],
		add = function( key, valueOrFunction ) {

			// If value is a function, invoke it and use its return value
			var value = isFunction( valueOrFunction ) ?
				valueOrFunction() :
				valueOrFunction;

			s[ s.length ] = encodeURIComponent( key ) + "=" +
				encodeURIComponent( value == null ? "" : value );
		};

	if ( a == null ) {
		return "";
	}

	// If an array was passed in, assume that it is an array of form elements.
	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {

		// Serialize the form elements
		jQuery.each( a, function() {
			add( this.name, this.value );
		} );

	} else {

		// If traditional, encode the "old" way (the way 1.3.2 or older
		// did it), otherwise encode params recursively.
		for ( prefix in a ) {
			buildParams( prefix, a[ prefix ], traditional, add );
		}
	}

	// Return the resulting serialization
	return s.join( "&" );
};

jQuery.fn.extend( {
	serialize: function() {
		return jQuery.param( this.serializeArray() );
	},
	serializeArray: function() {
		return this.map( function() {

			// Can add propHook for "elements" to filter or add form elements
			var elements = jQuery.prop( this, "elements" );
			return elements ? jQuery.makeArray( elements ) : this;
		} )
		.filter( function() {
			var type = this.type;

			// Use .is( ":disabled" ) so that fieldset[disabled] works
			return this.name && !jQuery( this ).is( ":disabled" ) &&
				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
				( this.checked || !rcheckableType.test( type ) );
		} )
		.map( function( _i, elem ) {
			var val = jQuery( this ).val();

			if ( val == null ) {
				return null;
			}

			if ( Array.isArray( val ) ) {
				return jQuery.map( val, function( val ) {
					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
				} );
			}

			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
		} ).get();
	}
} );


var
	r20 = /%20/g,
	rhash = /#.*$/,
	rantiCache = /([?&])_=[^&]*/,
	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,

	// #7653, #8125, #8152: local protocol detection
	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
	rnoContent = /^(?:GET|HEAD)$/,
	rprotocol = /^\/\//,

	/* Prefilters
	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
	 * 2) These are called:
	 *    - BEFORE asking for a transport
	 *    - AFTER param serialization (s.data is a string if s.processData is true)
	 * 3) key is the dataType
	 * 4) the catchall symbol "*" can be used
	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
	 */
	prefilters = {},

	/* Transports bindings
	 * 1) key is the dataType
	 * 2) the catchall symbol "*" can be used
	 * 3) selection will start with transport dataType and THEN go to "*" if needed
	 */
	transports = {},

	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
	allTypes = "*/".concat( "*" ),

	// Anchor tag for parsing the document origin
	originAnchor = document.createElement( "a" );
	originAnchor.href = location.href;

// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
function addToPrefiltersOrTransports( structure ) {

	// dataTypeExpression is optional and defaults to "*"
	return function( dataTypeExpression, func ) {

		if ( typeof dataTypeExpression !== "string" ) {
			func = dataTypeExpression;
			dataTypeExpression = "*";
		}

		var dataType,
			i = 0,
			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];

		if ( isFunction( func ) ) {

			// For each dataType in the dataTypeExpression
			while ( ( dataType = dataTypes[ i++ ] ) ) {

				// Prepend if requested
				if ( dataType[ 0 ] === "+" ) {
					dataType = dataType.slice( 1 ) || "*";
					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );

				// Otherwise append
				} else {
					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
				}
			}
		}
	};
}

// Base inspection function for prefilters and transports
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {

	var inspected = {},
		seekingTransport = ( structure === transports );

	function inspect( dataType ) {
		var selected;
		inspected[ dataType ] = true;
		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
			if ( typeof dataTypeOrTransport === "string" &&
				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {

				options.dataTypes.unshift( dataTypeOrTransport );
				inspect( dataTypeOrTransport );
				return false;
			} else if ( seekingTransport ) {
				return !( selected = dataTypeOrTransport );
			}
		} );
		return selected;
	}

	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
}

// A special extend for ajax options
// that takes "flat" options (not to be deep extended)
// Fixes #9887
function ajaxExtend( target, src ) {
	var key, deep,
		flatOptions = jQuery.ajaxSettings.flatOptions || {};

	for ( key in src ) {
		if ( src[ key ] !== undefined ) {
			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
		}
	}
	if ( deep ) {
		jQuery.extend( true, target, deep );
	}

	return target;
}

/* Handles responses to an ajax request:
 * - finds the right dataType (mediates between content-type and expected dataType)
 * - returns the corresponding response
 */
function ajaxHandleResponses( s, jqXHR, responses ) {

	var ct, type, finalDataType, firstDataType,
		contents = s.contents,
		dataTypes = s.dataTypes;

	// Remove auto dataType and get content-type in the process
	while ( dataTypes[ 0 ] === "*" ) {
		dataTypes.shift();
		if ( ct === undefined ) {
			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
		}
	}

	// Check if we're dealing with a known content-type
	if ( ct ) {
		for ( type in contents ) {
			if ( contents[ type ] && contents[ type ].test( ct ) ) {
				dataTypes.unshift( type );
				break;
			}
		}
	}

	// Check to see if we have a response for the expected dataType
	if ( dataTypes[ 0 ] in responses ) {
		finalDataType = dataTypes[ 0 ];
	} else {

		// Try convertible dataTypes
		for ( type in responses ) {
			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
				finalDataType = type;
				break;
			}
			if ( !firstDataType ) {
				firstDataType = type;
			}
		}

		// Or just use first one
		finalDataType = finalDataType || firstDataType;
	}

	// If we found a dataType
	// We add the dataType to the list if needed
	// and return the corresponding response
	if ( finalDataType ) {
		if ( finalDataType !== dataTypes[ 0 ] ) {
			dataTypes.unshift( finalDataType );
		}
		return responses[ finalDataType ];
	}
}

/* Chain conversions given the request and the original response
 * Also sets the responseXXX fields on the jqXHR instance
 */
function ajaxConvert( s, response, jqXHR, isSuccess ) {
	var conv2, current, conv, tmp, prev,
		converters = {},

		// Work with a copy of dataTypes in case we need to modify it for conversion
		dataTypes = s.dataTypes.slice();

	// Create converters map with lowercased keys
	if ( dataTypes[ 1 ] ) {
		for ( conv in s.converters ) {
			converters[ conv.toLowerCase() ] = s.converters[ conv ];
		}
	}

	current = dataTypes.shift();

	// Convert to each sequential dataType
	while ( current ) {

		if ( s.responseFields[ current ] ) {
			jqXHR[ s.responseFields[ current ] ] = response;
		}

		// Apply the dataFilter if provided
		if ( !prev && isSuccess && s.dataFilter ) {
			response = s.dataFilter( response, s.dataType );
		}

		prev = current;
		current = dataTypes.shift();

		if ( current ) {

			// There's only work to do if current dataType is non-auto
			if ( current === "*" ) {

				current = prev;

			// Convert response if prev dataType is non-auto and differs from current
			} else if ( prev !== "*" && prev !== current ) {

				// Seek a direct converter
				conv = converters[ prev + " " + current ] || converters[ "* " + current ];

				// If none found, seek a pair
				if ( !conv ) {
					for ( conv2 in converters ) {

						// If conv2 outputs current
						tmp = conv2.split( " " );
						if ( tmp[ 1 ] === current ) {

							// If prev can be converted to accepted input
							conv = converters[ prev + " " + tmp[ 0 ] ] ||
								converters[ "* " + tmp[ 0 ] ];
							if ( conv ) {

								// Condense equivalence converters
								if ( conv === true ) {
									conv = converters[ conv2 ];

								// Otherwise, insert the intermediate dataType
								} else if ( converters[ conv2 ] !== true ) {
									current = tmp[ 0 ];
									dataTypes.unshift( tmp[ 1 ] );
								}
								break;
							}
						}
					}
				}

				// Apply converter (if not an equivalence)
				if ( conv !== true ) {

					// Unless errors are allowed to bubble, catch and return them
					if ( conv && s.throws ) {
						response = conv( response );
					} else {
						try {
							response = conv( response );
						} catch ( e ) {
							return {
								state: "parsererror",
								error: conv ? e : "No conversion from " + prev + " to " + current
							};
						}
					}
				}
			}
		}
	}

	return { state: "success", data: response };
}

jQuery.extend( {

	// Counter for holding the number of active queries
	active: 0,

	// Last-Modified header cache for next request
	lastModified: {},
	etag: {},

	ajaxSettings: {
		url: location.href,
		type: "GET",
		isLocal: rlocalProtocol.test( location.protocol ),
		global: true,
		processData: true,
		async: true,
		contentType: "application/x-www-form-urlencoded; charset=UTF-8",

		/*
		timeout: 0,
		data: null,
		dataType: null,
		username: null,
		password: null,
		cache: null,
		throws: false,
		traditional: false,
		headers: {},
		*/

		accepts: {
			"*": allTypes,
			text: "text/plain",
			html: "text/html",
			xml: "application/xml, text/xml",
			json: "application/json, text/javascript"
		},

		contents: {
			xml: /\bxml\b/,
			html: /\bhtml/,
			json: /\bjson\b/
		},

		responseFields: {
			xml: "responseXML",
			text: "responseText",
			json: "responseJSON"
		},

		// Data converters
		// Keys separate source (or catchall "*") and destination types with a single space
		converters: {

			// Convert anything to text
			"* text": String,

			// Text to html (true = no transformation)
			"text html": true,

			// Evaluate text as a json expression
			"text json": JSON.parse,

			// Parse text as xml
			"text xml": jQuery.parseXML
		},

		// For options that shouldn't be deep extended:
		// you can add your own custom options here if
		// and when you create one that shouldn't be
		// deep extended (see ajaxExtend)
		flatOptions: {
			url: true,
			context: true
		}
	},

	// Creates a full fledged settings object into target
	// with both ajaxSettings and settings fields.
	// If target is omitted, writes into ajaxSettings.
	ajaxSetup: function( target, settings ) {
		return settings ?

			// Building a settings object
			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :

			// Extending ajaxSettings
			ajaxExtend( jQuery.ajaxSettings, target );
	},

	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
	ajaxTransport: addToPrefiltersOrTransports( transports ),

	// Main method
	ajax: function( url, options ) {

		// If url is an object, simulate pre-1.5 signature
		if ( typeof url === "object" ) {
			options = url;
			url = undefined;
		}

		// Force options to be an object
		options = options || {};

		var transport,

			// URL without anti-cache param
			cacheURL,

			// Response headers
			responseHeadersString,
			responseHeaders,

			// timeout handle
			timeoutTimer,

			// Url cleanup var
			urlAnchor,

			// Request state (becomes false upon send and true upon completion)
			completed,

			// To know if global events are to be dispatched
			fireGlobals,

			// Loop variable
			i,

			// uncached part of the url
			uncached,

			// Create the final options object
			s = jQuery.ajaxSetup( {}, options ),

			// Callbacks context
			callbackContext = s.context || s,

			// Context for global events is callbackContext if it is a DOM node or jQuery collection
			globalEventContext = s.context &&
				( callbackContext.nodeType || callbackContext.jquery ) ?
					jQuery( callbackContext ) :
					jQuery.event,

			// Deferreds
			deferred = jQuery.Deferred(),
			completeDeferred = jQuery.Callbacks( "once memory" ),

			// Status-dependent callbacks
			statusCode = s.statusCode || {},

			// Headers (they are sent all at once)
			requestHeaders = {},
			requestHeadersNames = {},

			// Default abort message
			strAbort = "canceled",

			// Fake xhr
			jqXHR = {
				readyState: 0,

				// Builds headers hashtable if needed
				getResponseHeader: function( key ) {
					var match;
					if ( completed ) {
						if ( !responseHeaders ) {
							responseHeaders = {};
							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
										.concat( match[ 2 ] );
							}
						}
						match = responseHeaders[ key.toLowerCase() + " " ];
					}
					return match == null ? null : match.join( ", " );
				},

				// Raw string
				getAllResponseHeaders: function() {
					return completed ? responseHeadersString : null;
				},

				// Caches the header
				setRequestHeader: function( name, value ) {
					if ( completed == null ) {
						name = requestHeadersNames[ name.toLowerCase() ] =
							requestHeadersNames[ name.toLowerCase() ] || name;
						requestHeaders[ name ] = value;
					}
					return this;
				},

				// Overrides response content-type header
				overrideMimeType: function( type ) {
					if ( completed == null ) {
						s.mimeType = type;
					}
					return this;
				},

				// Status-dependent callbacks
				statusCode: function( map ) {
					var code;
					if ( map ) {
						if ( completed ) {

							// Execute the appropriate callbacks
							jqXHR.always( map[ jqXHR.status ] );
						} else {

							// Lazy-add the new callbacks in a way that preserves old ones
							for ( code in map ) {
								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
							}
						}
					}
					return this;
				},

				// Cancel the request
				abort: function( statusText ) {
					var finalText = statusText || strAbort;
					if ( transport ) {
						transport.abort( finalText );
					}
					done( 0, finalText );
					return this;
				}
			};

		// Attach deferreds
		deferred.promise( jqXHR );

		// Add protocol if not provided (prefilters might expect it)
		// Handle falsy url in the settings object (#10093: consistency with old signature)
		// We also use the url parameter if available
		s.url = ( ( url || s.url || location.href ) + "" )
			.replace( rprotocol, location.protocol + "//" );

		// Alias method option to type as per ticket #12004
		s.type = options.method || options.type || s.method || s.type;

		// Extract dataTypes list
		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];

		// A cross-domain request is in order when the origin doesn't match the current origin.
		if ( s.crossDomain == null ) {
			urlAnchor = document.createElement( "a" );

			// Support: IE <=8 - 11, Edge 12 - 15
			// IE throws exception on accessing the href property if url is malformed,
			// e.g. http://example.com:80x/
			try {
				urlAnchor.href = s.url;

				// Support: IE <=8 - 11 only
				// Anchor's host property isn't correctly set when s.url is relative
				urlAnchor.href = urlAnchor.href;
				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
					urlAnchor.protocol + "//" + urlAnchor.host;
			} catch ( e ) {

				// If there is an error parsing the URL, assume it is crossDomain,
				// it can be rejected by the transport if it is invalid
				s.crossDomain = true;
			}
		}

		// Convert data if not already a string
		if ( s.data && s.processData && typeof s.data !== "string" ) {
			s.data = jQuery.param( s.data, s.traditional );
		}

		// Apply prefilters
		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );

		// If request was aborted inside a prefilter, stop there
		if ( completed ) {
			return jqXHR;
		}

		// We can fire global events as of now if asked to
		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
		fireGlobals = jQuery.event && s.global;

		// Watch for a new set of requests
		if ( fireGlobals && jQuery.active++ === 0 ) {
			jQuery.event.trigger( "ajaxStart" );
		}

		// Uppercase the type
		s.type = s.type.toUpperCase();

		// Determine if request has content
		s.hasContent = !rnoContent.test( s.type );

		// Save the URL in case we're toying with the If-Modified-Since
		// and/or If-None-Match header later on
		// Remove hash to simplify url manipulation
		cacheURL = s.url.replace( rhash, "" );

		// More options handling for requests with no content
		if ( !s.hasContent ) {

			// Remember the hash so we can put it back
			uncached = s.url.slice( cacheURL.length );

			// If data is available and should be processed, append data to url
			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;

				// #9682: remove data so that it's not used in an eventual retry
				delete s.data;
			}

			// Add or update anti-cache param if needed
			if ( s.cache === false ) {
				cacheURL = cacheURL.replace( rantiCache, "$1" );
				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
					uncached;
			}

			// Put hash and anti-cache on the URL that will be requested (gh-1732)
			s.url = cacheURL + uncached;

		// Change '%20' to '+' if this is encoded form body content (gh-2658)
		} else if ( s.data && s.processData &&
			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
			s.data = s.data.replace( r20, "+" );
		}

		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
		if ( s.ifModified ) {
			if ( jQuery.lastModified[ cacheURL ] ) {
				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
			}
			if ( jQuery.etag[ cacheURL ] ) {
				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
			}
		}

		// Set the correct header, if data is being sent
		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
			jqXHR.setRequestHeader( "Content-Type", s.contentType );
		}

		// Set the Accepts header for the server, depending on the dataType
		jqXHR.setRequestHeader(
			"Accept",
			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
				s.accepts[ s.dataTypes[ 0 ] ] +
					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
				s.accepts[ "*" ]
		);

		// Check for headers option
		for ( i in s.headers ) {
			jqXHR.setRequestHeader( i, s.headers[ i ] );
		}

		// Allow custom headers/mimetypes and early abort
		if ( s.beforeSend &&
			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {

			// Abort if not done already and return
			return jqXHR.abort();
		}

		// Aborting is no longer a cancellation
		strAbort = "abort";

		// Install callbacks on deferreds
		completeDeferred.add( s.complete );
		jqXHR.done( s.success );
		jqXHR.fail( s.error );

		// Get transport
		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );

		// If no transport, we auto-abort
		if ( !transport ) {
			done( -1, "No Transport" );
		} else {
			jqXHR.readyState = 1;

			// Send global event
			if ( fireGlobals ) {
				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
			}

			// If request was aborted inside ajaxSend, stop there
			if ( completed ) {
				return jqXHR;
			}

			// Timeout
			if ( s.async && s.timeout > 0 ) {
				timeoutTimer = window.setTimeout( function() {
					jqXHR.abort( "timeout" );
				}, s.timeout );
			}

			try {
				completed = false;
				transport.send( requestHeaders, done );
			} catch ( e ) {

				// Rethrow post-completion exceptions
				if ( completed ) {
					throw e;
				}

				// Propagate others as results
				done( -1, e );
			}
		}

		// Callback for when everything is done
		function done( status, nativeStatusText, responses, headers ) {
			var isSuccess, success, error, response, modified,
				statusText = nativeStatusText;

			// Ignore repeat invocations
			if ( completed ) {
				return;
			}

			completed = true;

			// Clear timeout if it exists
			if ( timeoutTimer ) {
				window.clearTimeout( timeoutTimer );
			}

			// Dereference transport for early garbage collection
			// (no matter how long the jqXHR object will be used)
			transport = undefined;

			// Cache response headers
			responseHeadersString = headers || "";

			// Set readyState
			jqXHR.readyState = status > 0 ? 4 : 0;

			// Determine if successful
			isSuccess = status >= 200 && status < 300 || status === 304;

			// Get response data
			if ( responses ) {
				response = ajaxHandleResponses( s, jqXHR, responses );
			}

			// Use a noop converter for missing script
			if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) {
				s.converters[ "text script" ] = function() {};
			}

			// Convert no matter what (that way responseXXX fields are always set)
			response = ajaxConvert( s, response, jqXHR, isSuccess );

			// If successful, handle type chaining
			if ( isSuccess ) {

				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
				if ( s.ifModified ) {
					modified = jqXHR.getResponseHeader( "Last-Modified" );
					if ( modified ) {
						jQuery.lastModified[ cacheURL ] = modified;
					}
					modified = jqXHR.getResponseHeader( "etag" );
					if ( modified ) {
						jQuery.etag[ cacheURL ] = modified;
					}
				}

				// if no content
				if ( status === 204 || s.type === "HEAD" ) {
					statusText = "nocontent";

				// if not modified
				} else if ( status === 304 ) {
					statusText = "notmodified";

				// If we have data, let's convert it
				} else {
					statusText = response.state;
					success = response.data;
					error = response.error;
					isSuccess = !error;
				}
			} else {

				// Extract error from statusText and normalize for non-aborts
				error = statusText;
				if ( status || !statusText ) {
					statusText = "error";
					if ( status < 0 ) {
						status = 0;
					}
				}
			}

			// Set data for the fake xhr object
			jqXHR.status = status;
			jqXHR.statusText = ( nativeStatusText || statusText ) + "";

			// Success/Error
			if ( isSuccess ) {
				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
			} else {
				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
			}

			// Status-dependent callbacks
			jqXHR.statusCode( statusCode );
			statusCode = undefined;

			if ( fireGlobals ) {
				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
					[ jqXHR, s, isSuccess ? success : error ] );
			}

			// Complete
			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );

			if ( fireGlobals ) {
				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );

				// Handle the global AJAX counter
				if ( !( --jQuery.active ) ) {
					jQuery.event.trigger( "ajaxStop" );
				}
			}
		}

		return jqXHR;
	},

	getJSON: function( url, data, callback ) {
		return jQuery.get( url, data, callback, "json" );
	},

	getScript: function( url, callback ) {
		return jQuery.get( url, undefined, callback, "script" );
	}
} );

jQuery.each( [ "get", "post" ], function( _i, method ) {
	jQuery[ method ] = function( url, data, callback, type ) {

		// Shift arguments if data argument was omitted
		if ( isFunction( data ) ) {
			type = type || callback;
			callback = data;
			data = undefined;
		}

		// The url can be an options object (which then must have .url)
		return jQuery.ajax( jQuery.extend( {
			url: url,
			type: method,
			dataType: type,
			data: data,
			success: callback
		}, jQuery.isPlainObject( url ) && url ) );
	};
} );

jQuery.ajaxPrefilter( function( s ) {
	var i;
	for ( i in s.headers ) {
		if ( i.toLowerCase() === "content-type" ) {
			s.contentType = s.headers[ i ] || "";
		}
	}
} );


jQuery._evalUrl = function( url, options, doc ) {
	return jQuery.ajax( {
		url: url,

		// Make this explicit, since user can override this through ajaxSetup (#11264)
		type: "GET",
		dataType: "script",
		cache: true,
		async: false,
		global: false,

		// Only evaluate the response if it is successful (gh-4126)
		// dataFilter is not invoked for failure responses, so using it instead
		// of the default converter is kludgy but it works.
		converters: {
			"text script": function() {}
		},
		dataFilter: function( response ) {
			jQuery.globalEval( response, options, doc );
		}
	} );
};


jQuery.fn.extend( {
	wrapAll: function( html ) {
		var wrap;

		if ( this[ 0 ] ) {
			if ( isFunction( html ) ) {
				html = html.call( this[ 0 ] );
			}

			// The elements to wrap the target around
			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );

			if ( this[ 0 ].parentNode ) {
				wrap.insertBefore( this[ 0 ] );
			}

			wrap.map( function() {
				var elem = this;

				while ( elem.firstElementChild ) {
					elem = elem.firstElementChild;
				}

				return elem;
			} ).append( this );
		}

		return this;
	},

	wrapInner: function( html ) {
		if ( isFunction( html ) ) {
			return this.each( function( i ) {
				jQuery( this ).wrapInner( html.call( this, i ) );
			} );
		}

		return this.each( function() {
			var self = jQuery( this ),
				contents = self.contents();

			if ( contents.length ) {
				contents.wrapAll( html );

			} else {
				self.append( html );
			}
		} );
	},

	wrap: function( html ) {
		var htmlIsFunction = isFunction( html );

		return this.each( function( i ) {
			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
		} );
	},

	unwrap: function( selector ) {
		this.parent( selector ).not( "body" ).each( function() {
			jQuery( this ).replaceWith( this.childNodes );
		} );
		return this;
	}
} );


jQuery.expr.pseudos.hidden = function( elem ) {
	return !jQuery.expr.pseudos.visible( elem );
};
jQuery.expr.pseudos.visible = function( elem ) {
	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};




jQuery.ajaxSettings.xhr = function() {
	try {
		return new window.XMLHttpRequest();
	} catch ( e ) {}
};

var xhrSuccessStatus = {

		// File protocol always yields status code 0, assume 200
		0: 200,

		// Support: IE <=9 only
		// #1450: sometimes IE returns 1223 when it should be 204
		1223: 204
	},
	xhrSupported = jQuery.ajaxSettings.xhr();

support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
support.ajax = xhrSupported = !!xhrSupported;

jQuery.ajaxTransport( function( options ) {
	var callback, errorCallback;

	// Cross domain only allowed if supported through XMLHttpRequest
	if ( support.cors || xhrSupported && !options.crossDomain ) {
		return {
			send: function( headers, complete ) {
				var i,
					xhr = options.xhr();

				xhr.open(
					options.type,
					options.url,
					options.async,
					options.username,
					options.password
				);

				// Apply custom fields if provided
				if ( options.xhrFields ) {
					for ( i in options.xhrFields ) {
						xhr[ i ] = options.xhrFields[ i ];
					}
				}

				// Override mime type if needed
				if ( options.mimeType && xhr.overrideMimeType ) {
					xhr.overrideMimeType( options.mimeType );
				}

				// X-Requested-With header
				// For cross-domain requests, seeing as conditions for a preflight are
				// akin to a jigsaw puzzle, we simply never set it to be sure.
				// (it can always be set on a per-request basis or even using ajaxSetup)
				// For same-domain requests, won't change header if already provided.
				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
					headers[ "X-Requested-With" ] = "XMLHttpRequest";
				}

				// Set headers
				for ( i in headers ) {
					xhr.setRequestHeader( i, headers[ i ] );
				}

				// Callback
				callback = function( type ) {
					return function() {
						if ( callback ) {
							callback = errorCallback = xhr.onload =
								xhr.onerror = xhr.onabort = xhr.ontimeout =
									xhr.onreadystatechange = null;

							if ( type === "abort" ) {
								xhr.abort();
							} else if ( type === "error" ) {

								// Support: IE <=9 only
								// On a manual native abort, IE9 throws
								// errors on any property access that is not readyState
								if ( typeof xhr.status !== "number" ) {
									complete( 0, "error" );
								} else {
									complete(

										// File: protocol always yields status 0; see #8605, #14207
										xhr.status,
										xhr.statusText
									);
								}
							} else {
								complete(
									xhrSuccessStatus[ xhr.status ] || xhr.status,
									xhr.statusText,

									// Support: IE <=9 only
									// IE9 has no XHR2 but throws on binary (trac-11426)
									// For XHR2 non-text, let the caller handle it (gh-2498)
									( xhr.responseType || "text" ) !== "text"  ||
									typeof xhr.responseText !== "string" ?
										{ binary: xhr.response } :
										{ text: xhr.responseText },
									xhr.getAllResponseHeaders()
								);
							}
						}
					};
				};

				// Listen to events
				xhr.onload = callback();
				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );

				// Support: IE 9 only
				// Use onreadystatechange to replace onabort
				// to handle uncaught aborts
				if ( xhr.onabort !== undefined ) {
					xhr.onabort = errorCallback;
				} else {
					xhr.onreadystatechange = function() {

						// Check readyState before timeout as it changes
						if ( xhr.readyState === 4 ) {

							// Allow onerror to be called first,
							// but that will not handle a native abort
							// Also, save errorCallback to a variable
							// as xhr.onerror cannot be accessed
							window.setTimeout( function() {
								if ( callback ) {
									errorCallback();
								}
							} );
						}
					};
				}

				// Create the abort callback
				callback = callback( "abort" );

				try {

					// Do send the request (this may raise an exception)
					xhr.send( options.hasContent && options.data || null );
				} catch ( e ) {

					// #14683: Only rethrow if this hasn't been notified as an error yet
					if ( callback ) {
						throw e;
					}
				}
			},

			abort: function() {
				if ( callback ) {
					callback();
				}
			}
		};
	}
} );




// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
jQuery.ajaxPrefilter( function( s ) {
	if ( s.crossDomain ) {
		s.contents.script = false;
	}
} );

// Install script dataType
jQuery.ajaxSetup( {
	accepts: {
		script: "text/javascript, application/javascript, " +
			"application/ecmascript, application/x-ecmascript"
	},
	contents: {
		script: /\b(?:java|ecma)script\b/
	},
	converters: {
		"text script": function( text ) {
			jQuery.globalEval( text );
			return text;
		}
	}
} );

// Handle cache's special case and crossDomain
jQuery.ajaxPrefilter( "script", function( s ) {
	if ( s.cache === undefined ) {
		s.cache = false;
	}
	if ( s.crossDomain ) {
		s.type = "GET";
	}
} );

// Bind script tag hack transport
jQuery.ajaxTransport( "script", function( s ) {

	// This transport only deals with cross domain or forced-by-attrs requests
	if ( s.crossDomain || s.scriptAttrs ) {
		var script, callback;
		return {
			send: function( _, complete ) {
				script = jQuery( "<script>" )
					.attr( s.scriptAttrs || {} )
					.prop( { charset: s.scriptCharset, src: s.url } )
					.on( "load error", callback = function( evt ) {
						script.remove();
						callback = null;
						if ( evt ) {
							complete( evt.type === "error" ? 404 : 200, evt.type );
						}
					} );

				// Use native DOM manipulation to avoid our domManip AJAX trickery
				document.head.appendChild( script[ 0 ] );
			},
			abort: function() {
				if ( callback ) {
					callback();
				}
			}
		};
	}
} );




var oldCallbacks = [],
	rjsonp = /(=)\?(?=&|$)|\?\?/;

// Default jsonp settings
jQuery.ajaxSetup( {
	jsonp: "callback",
	jsonpCallback: function() {
		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
		this[ callback ] = true;
		return callback;
	}
} );

// Detect, normalize options and install callbacks for jsonp requests
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {

	var callbackName, overwritten, responseContainer,
		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
			"url" :
			typeof s.data === "string" &&
				( s.contentType || "" )
					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
				rjsonp.test( s.data ) && "data"
		);

	// Handle iff the expected data type is "jsonp" or we have a parameter to set
	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {

		// Get callback name, remembering preexisting value associated with it
		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
			s.jsonpCallback() :
			s.jsonpCallback;

		// Insert callback into url or form data
		if ( jsonProp ) {
			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
		} else if ( s.jsonp !== false ) {
			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
		}

		// Use data converter to retrieve json after script execution
		s.converters[ "script json" ] = function() {
			if ( !responseContainer ) {
				jQuery.error( callbackName + " was not called" );
			}
			return responseContainer[ 0 ];
		};

		// Force json dataType
		s.dataTypes[ 0 ] = "json";

		// Install callback
		overwritten = window[ callbackName ];
		window[ callbackName ] = function() {
			responseContainer = arguments;
		};

		// Clean-up function (fires after converters)
		jqXHR.always( function() {

			// If previous value didn't exist - remove it
			if ( overwritten === undefined ) {
				jQuery( window ).removeProp( callbackName );

			// Otherwise restore preexisting value
			} else {
				window[ callbackName ] = overwritten;
			}

			// Save back as free
			if ( s[ callbackName ] ) {

				// Make sure that re-using the options doesn't screw things around
				s.jsonpCallback = originalSettings.jsonpCallback;

				// Save the callback name for future use
				oldCallbacks.push( callbackName );
			}

			// Call if it was a function and we have a response
			if ( responseContainer && isFunction( overwritten ) ) {
				overwritten( responseContainer[ 0 ] );
			}

			responseContainer = overwritten = undefined;
		} );

		// Delegate to script
		return "script";
	}
} );




// Support: Safari 8 only
// In Safari 8 documents created via document.implementation.createHTMLDocument
// collapse sibling forms: the second one becomes a child of the first one.
// Because of that, this security measure has to be disabled in Safari 8.
// https://bugs.webkit.org/show_bug.cgi?id=137337
support.createHTMLDocument = ( function() {
	var body = document.implementation.createHTMLDocument( "" ).body;
	body.innerHTML = "<form></form><form></form>";
	return body.childNodes.length === 2;
} )();


// Argument "data" should be string of html
// context (optional): If specified, the fragment will be created in this context,
// defaults to document
// keepScripts (optional): If true, will include scripts passed in the html string
jQuery.parseHTML = function( data, context, keepScripts ) {
	if ( typeof data !== "string" ) {
		return [];
	}
	if ( typeof context === "boolean" ) {
		keepScripts = context;
		context = false;
	}

	var base, parsed, scripts;

	if ( !context ) {

		// Stop scripts or inline event handlers from being executed immediately
		// by using document.implementation
		if ( support.createHTMLDocument ) {
			context = document.implementation.createHTMLDocument( "" );

			// Set the base href for the created document
			// so any parsed elements with URLs
			// are based on the document's URL (gh-2965)
			base = context.createElement( "base" );
			base.href = document.location.href;
			context.head.appendChild( base );
		} else {
			context = document;
		}
	}

	parsed = rsingleTag.exec( data );
	scripts = !keepScripts && [];

	// Single tag
	if ( parsed ) {
		return [ context.createElement( parsed[ 1 ] ) ];
	}

	parsed = buildFragment( [ data ], context, scripts );

	if ( scripts && scripts.length ) {
		jQuery( scripts ).remove();
	}

	return jQuery.merge( [], parsed.childNodes );
};


/**
 * Load a url into a page
 */
jQuery.fn.load = function( url, params, callback ) {
	var selector, type, response,
		self = this,
		off = url.indexOf( " " );

	if ( off > -1 ) {
		selector = stripAndCollapse( url.slice( off ) );
		url = url.slice( 0, off );
	}

	// If it's a function
	if ( isFunction( params ) ) {

		// We assume that it's the callback
		callback = params;
		params = undefined;

	// Otherwise, build a param string
	} else if ( params && typeof params === "object" ) {
		type = "POST";
	}

	// If we have elements to modify, make the request
	if ( self.length > 0 ) {
		jQuery.ajax( {
			url: url,

			// If "type" variable is undefined, then "GET" method will be used.
			// Make value of this field explicit since
			// user can override it through ajaxSetup method
			type: type || "GET",
			dataType: "html",
			data: params
		} ).done( function( responseText ) {

			// Save response for use in complete callback
			response = arguments;

			self.html( selector ?

				// If a selector was specified, locate the right elements in a dummy div
				// Exclude scripts to avoid IE 'Permission Denied' errors
				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :

				// Otherwise use the full result
				responseText );

		// If the request succeeds, this function gets "data", "status", "jqXHR"
		// but they are ignored because response was set above.
		// If it fails, this function gets "jqXHR", "status", "error"
		} ).always( callback && function( jqXHR, status ) {
			self.each( function() {
				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
			} );
		} );
	}

	return this;
};




jQuery.expr.pseudos.animated = function( elem ) {
	return jQuery.grep( jQuery.timers, function( fn ) {
		return elem === fn.elem;
	} ).length;
};




jQuery.offset = {
	setOffset: function( elem, options, i ) {
		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
			position = jQuery.css( elem, "position" ),
			curElem = jQuery( elem ),
			props = {};

		// Set position first, in-case top/left are set even on static elem
		if ( position === "static" ) {
			elem.style.position = "relative";
		}

		curOffset = curElem.offset();
		curCSSTop = jQuery.css( elem, "top" );
		curCSSLeft = jQuery.css( elem, "left" );
		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;

		// Need to be able to calculate position if either
		// top or left is auto and position is either absolute or fixed
		if ( calculatePosition ) {
			curPosition = curElem.position();
			curTop = curPosition.top;
			curLeft = curPosition.left;

		} else {
			curTop = parseFloat( curCSSTop ) || 0;
			curLeft = parseFloat( curCSSLeft ) || 0;
		}

		if ( isFunction( options ) ) {

			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
		}

		if ( options.top != null ) {
			props.top = ( options.top - curOffset.top ) + curTop;
		}
		if ( options.left != null ) {
			props.left = ( options.left - curOffset.left ) + curLeft;
		}

		if ( "using" in options ) {
			options.using.call( elem, props );

		} else {
			if ( typeof props.top === "number" ) {
				props.top += "px";
			}
			if ( typeof props.left === "number" ) {
				props.left += "px";
			}
			curElem.css( props );
		}
	}
};

jQuery.fn.extend( {

	// offset() relates an element's border box to the document origin
	offset: function( options ) {

		// Preserve chaining for setter
		if ( arguments.length ) {
			return options === undefined ?
				this :
				this.each( function( i ) {
					jQuery.offset.setOffset( this, options, i );
				} );
		}

		var rect, win,
			elem = this[ 0 ];

		if ( !elem ) {
			return;
		}

		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
		// Support: IE <=11 only
		// Running getBoundingClientRect on a
		// disconnected node in IE throws an error
		if ( !elem.getClientRects().length ) {
			return { top: 0, left: 0 };
		}

		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
		rect = elem.getBoundingClientRect();
		win = elem.ownerDocument.defaultView;
		return {
			top: rect.top + win.pageYOffset,
			left: rect.left + win.pageXOffset
		};
	},

	// position() relates an element's margin box to its offset parent's padding box
	// This corresponds to the behavior of CSS absolute positioning
	position: function() {
		if ( !this[ 0 ] ) {
			return;
		}

		var offsetParent, offset, doc,
			elem = this[ 0 ],
			parentOffset = { top: 0, left: 0 };

		// position:fixed elements are offset from the viewport, which itself always has zero offset
		if ( jQuery.css( elem, "position" ) === "fixed" ) {

			// Assume position:fixed implies availability of getBoundingClientRect
			offset = elem.getBoundingClientRect();

		} else {
			offset = this.offset();

			// Account for the *real* offset parent, which can be the document or its root element
			// when a statically positioned element is identified
			doc = elem.ownerDocument;
			offsetParent = elem.offsetParent || doc.documentElement;
			while ( offsetParent &&
				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
				jQuery.css( offsetParent, "position" ) === "static" ) {

				offsetParent = offsetParent.parentNode;
			}
			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {

				// Incorporate borders into its offset, since they are outside its content origin
				parentOffset = jQuery( offsetParent ).offset();
				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
			}
		}

		// Subtract parent offsets and element margins
		return {
			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
		};
	},

	// This method will return documentElement in the following cases:
	// 1) For the element inside the iframe without offsetParent, this method will return
	//    documentElement of the parent window
	// 2) For the hidden or detached element
	// 3) For body or html element, i.e. in case of the html node - it will return itself
	//
	// but those exceptions were never presented as a real life use-cases
	// and might be considered as more preferable results.
	//
	// This logic, however, is not guaranteed and can change at any point in the future
	offsetParent: function() {
		return this.map( function() {
			var offsetParent = this.offsetParent;

			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
				offsetParent = offsetParent.offsetParent;
			}

			return offsetParent || documentElement;
		} );
	}
} );

// Create scrollLeft and scrollTop methods
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
	var top = "pageYOffset" === prop;

	jQuery.fn[ method ] = function( val ) {
		return access( this, function( elem, method, val ) {

			// Coalesce documents and windows
			var win;
			if ( isWindow( elem ) ) {
				win = elem;
			} else if ( elem.nodeType === 9 ) {
				win = elem.defaultView;
			}

			if ( val === undefined ) {
				return win ? win[ prop ] : elem[ method ];
			}

			if ( win ) {
				win.scrollTo(
					!top ? val : win.pageXOffset,
					top ? val : win.pageYOffset
				);

			} else {
				elem[ method ] = val;
			}
		}, method, val, arguments.length );
	};
} );

// Support: Safari <=7 - 9.1, Chrome <=37 - 49
// Add the top/left cssHooks using jQuery.fn.position
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
// getComputedStyle returns percent when specified for top/left/bottom/right;
// rather than make the css module depend on the offset module, just check for it here
jQuery.each( [ "top", "left" ], function( _i, prop ) {
	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
		function( elem, computed ) {
			if ( computed ) {
				computed = curCSS( elem, prop );

				// If curCSS returns percentage, fallback to offset
				return rnumnonpx.test( computed ) ?
					jQuery( elem ).position()[ prop ] + "px" :
					computed;
			}
		}
	);
} );


// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
		function( defaultExtra, funcName ) {

		// Margin is only for outerHeight, outerWidth
		jQuery.fn[ funcName ] = function( margin, value ) {
			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );

			return access( this, function( elem, type, value ) {
				var doc;

				if ( isWindow( elem ) ) {

					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
					return funcName.indexOf( "outer" ) === 0 ?
						elem[ "inner" + name ] :
						elem.document.documentElement[ "client" + name ];
				}

				// Get document width or height
				if ( elem.nodeType === 9 ) {
					doc = elem.documentElement;

					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
					// whichever is greatest
					return Math.max(
						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
						elem.body[ "offset" + name ], doc[ "offset" + name ],
						doc[ "client" + name ]
					);
				}

				return value === undefined ?

					// Get width or height on the element, requesting but not forcing parseFloat
					jQuery.css( elem, type, extra ) :

					// Set width or height on the element
					jQuery.style( elem, type, value, extra );
			}, type, chainable ? margin : undefined, chainable );
		};
	} );
} );


jQuery.each( [
	"ajaxStart",
	"ajaxStop",
	"ajaxComplete",
	"ajaxError",
	"ajaxSuccess",
	"ajaxSend"
], function( _i, type ) {
	jQuery.fn[ type ] = function( fn ) {
		return this.on( type, fn );
	};
} );




jQuery.fn.extend( {

	bind: function( types, data, fn ) {
		return this.on( types, null, data, fn );
	},
	unbind: function( types, fn ) {
		return this.off( types, null, fn );
	},

	delegate: function( selector, types, data, fn ) {
		return this.on( types, selector, data, fn );
	},
	undelegate: function( selector, types, fn ) {

		// ( namespace ) or ( selector, types [, fn] )
		return arguments.length === 1 ?
			this.off( selector, "**" ) :
			this.off( types, selector || "**", fn );
	},

	hover: function( fnOver, fnOut ) {
		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
	}
} );

jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
	function( _i, name ) {

		// Handle event binding
		jQuery.fn[ name ] = function( data, fn ) {
			return arguments.length > 0 ?
				this.on( name, null, data, fn ) :
				this.trigger( name );
		};
	} );




// Support: Android <=4.0 only
// Make sure we trim BOM and NBSP
var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;

// Bind a function to a context, optionally partially applying any
// arguments.
// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
// However, it is not slated for removal any time soon
jQuery.proxy = function( fn, context ) {
	var tmp, args, proxy;

	if ( typeof context === "string" ) {
		tmp = fn[ context ];
		context = fn;
		fn = tmp;
	}

	// Quick check to determine if target is callable, in the spec
	// this throws a TypeError, but we will just return undefined.
	if ( !isFunction( fn ) ) {
		return undefined;
	}

	// Simulated bind
	args = slice.call( arguments, 2 );
	proxy = function() {
		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
	};

	// Set the guid of unique handler to the same of original handler, so it can be removed
	proxy.guid = fn.guid = fn.guid || jQuery.guid++;

	return proxy;
};

jQuery.holdReady = function( hold ) {
	if ( hold ) {
		jQuery.readyWait++;
	} else {
		jQuery.ready( true );
	}
};
jQuery.isArray = Array.isArray;
jQuery.parseJSON = JSON.parse;
jQuery.nodeName = nodeName;
jQuery.isFunction = isFunction;
jQuery.isWindow = isWindow;
jQuery.camelCase = camelCase;
jQuery.type = toType;

jQuery.now = Date.now;

jQuery.isNumeric = function( obj ) {

	// As of jQuery 3.0, isNumeric is limited to
	// strings and numbers (primitives or objects)
	// that can be coerced to finite numbers (gh-2662)
	var type = jQuery.type( obj );
	return ( type === "number" || type === "string" ) &&

		// parseFloat NaNs numeric-cast false positives ("")
		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
		// subtraction forces infinities to NaN
		!isNaN( obj - parseFloat( obj ) );
};

jQuery.trim = function( text ) {
	return text == null ?
		"" :
		( text + "" ).replace( rtrim, "" );
};



// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.

// Note that for maximum portability, libraries that are not jQuery should
// declare themselves as anonymous modules, and avoid setting a global if an
// AMD loader is present. jQuery is a special case. For more information, see
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

if ( typeof define === "function" && define.amd ) {
	define( "jquery", [], function() {
		return jQuery;
	} );
}




var

	// Map over jQuery in case of overwrite
	_jQuery = window.jQuery,

	// Map over the $ in case of overwrite
	_$ = window.$;

jQuery.noConflict = function( deep ) {
	if ( window.$ === jQuery ) {
		window.$ = _$;
	}

	if ( deep && window.jQuery === jQuery ) {
		window.jQuery = _jQuery;
	}

	return jQuery;
};

// Expose jQuery and $ identifiers, even in AMD
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566)
if ( typeof noGlobal === "undefined" ) {
	window.jQuery = window.$ = jQuery;
}




return jQuery;
} );

},{}],349:[function(require,module,exports){
var getNative = require('./_getNative'),
    root = require('./_root');

/* Built-in method references that are verified to be native. */
var DataView = getNative(root, 'DataView');

module.exports = DataView;

},{"./_getNative":447,"./_root":494}],350:[function(require,module,exports){
var hashClear = require('./_hashClear'),
    hashDelete = require('./_hashDelete'),
    hashGet = require('./_hashGet'),
    hashHas = require('./_hashHas'),
    hashSet = require('./_hashSet');

/**
 * Creates a hash object.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */
function Hash(entries) {
  var index = -1,
      length = entries == null ? 0 : entries.length;

  this.clear();
  while (++index < length) {
    var entry = entries[index];
    this.set(entry[0], entry[1]);
  }
}

// Add methods to `Hash`.
Hash.prototype.clear = hashClear;
Hash.prototype['delete'] = hashDelete;
Hash.prototype.get = hashGet;
Hash.prototype.has = hashHas;
Hash.prototype.set = hashSet;

module.exports = Hash;

},{"./_hashClear":455,"./_hashDelete":456,"./_hashGet":457,"./_hashHas":458,"./_hashSet":459}],351:[function(require,module,exports){
var baseCreate = require('./_baseCreate'),
    baseLodash = require('./_baseLodash');

/** Used as references for the maximum length and index of an array. */
var MAX_ARRAY_LENGTH = 4294967295;

/**
 * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
 *
 * @private
 * @constructor
 * @param {*} value The value to wrap.
 */
function LazyWrapper(value) {
  this.__wrapped__ = value;
  this.__actions__ = [];
  this.__dir__ = 1;
  this.__filtered__ = false;
  this.__iteratees__ = [];
  this.__takeCount__ = MAX_ARRAY_LENGTH;
  this.__views__ = [];
}

// Ensure `LazyWrapper` is an instance of `baseLodash`.
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
LazyWrapper.prototype.constructor = LazyWrapper;

module.exports = LazyWrapper;

},{"./_baseCreate":377,"./_baseLodash":399}],352:[function(require,module,exports){
var listCacheClear = require('./_listCacheClear'),
    listCacheDelete = require('./_listCacheDelete'),
    listCacheGet = require('./_listCacheGet'),
    listCacheHas = require('./_listCacheHas'),
    listCacheSet = require('./_listCacheSet');

/**
 * Creates an list cache object.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */
function ListCache(entries) {
  var index = -1,
      length = entries == null ? 0 : entries.length;

  this.clear();
  while (++index < length) {
    var entry = entries[index];
    this.set(entry[0], entry[1]);
  }
}

// Add methods to `ListCache`.
ListCache.prototype.clear = listCacheClear;
ListCache.prototype['delete'] = listCacheDelete;
ListCache.prototype.get = listCacheGet;
ListCache.prototype.has = listCacheHas;
ListCache.prototype.set = listCacheSet;

module.exports = ListCache;

},{"./_listCacheClear":470,"./_listCacheDelete":471,"./_listCacheGet":472,"./_listCacheHas":473,"./_listCacheSet":474}],353:[function(require,module,exports){
var baseCreate = require('./_baseCreate'),
    baseLodash = require('./_baseLodash');

/**
 * The base constructor for creating `lodash` wrapper objects.
 *
 * @private
 * @param {*} value The value to wrap.
 * @param {boolean} [chainAll] Enable explicit method chain sequences.
 */
function LodashWrapper(value, chainAll) {
  this.__wrapped__ = value;
  this.__actions__ = [];
  this.__chain__ = !!chainAll;
  this.__index__ = 0;
  this.__values__ = undefined;
}

LodashWrapper.prototype = baseCreate(baseLodash.prototype);
LodashWrapper.prototype.constructor = LodashWrapper;

module.exports = LodashWrapper;

},{"./_baseCreate":377,"./_baseLodash":399}],354:[function(require,module,exports){
var getNative = require('./_getNative'),
    root = require('./_root');

/* Built-in method references that are verified to be native. */
var Map = getNative(root, 'Map');

module.exports = Map;

},{"./_getNative":447,"./_root":494}],355:[function(require,module,exports){
var mapCacheClear = require('./_mapCacheClear'),
    mapCacheDelete = require('./_mapCacheDelete'),
    mapCacheGet = require('./_mapCacheGet'),
    mapCacheHas = require('./_mapCacheHas'),
    mapCacheSet = require('./_mapCacheSet');

/**
 * Creates a map cache object to store key-value pairs.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */
function MapCache(entries) {
  var index = -1,
      length = entries == null ? 0 : entries.length;

  this.clear();
  while (++index < length) {
    var entry = entries[index];
    this.set(entry[0], entry[1]);
  }
}

// Add methods to `MapCache`.
MapCache.prototype.clear = mapCacheClear;
MapCache.prototype['delete'] = mapCacheDelete;
MapCache.prototype.get = mapCacheGet;
MapCache.prototype.has = mapCacheHas;
MapCache.prototype.set = mapCacheSet;

module.exports = MapCache;

},{"./_mapCacheClear":475,"./_mapCacheDelete":476,"./_mapCacheGet":477,"./_mapCacheHas":478,"./_mapCacheSet":479}],356:[function(require,module,exports){
var getNative = require('./_getNative'),
    root = require('./_root');

/* Built-in method references that are verified to be native. */
var Promise = getNative(root, 'Promise');

module.exports = Promise;

},{"./_getNative":447,"./_root":494}],357:[function(require,module,exports){
var getNative = require('./_getNative'),
    root = require('./_root');

/* Built-in method references that are verified to be native. */
var Set = getNative(root, 'Set');

module.exports = Set;

},{"./_getNative":447,"./_root":494}],358:[function(require,module,exports){
var MapCache = require('./_MapCache'),
    setCacheAdd = require('./_setCacheAdd'),
    setCacheHas = require('./_setCacheHas');

/**
 *
 * Creates an array cache object to store unique values.
 *
 * @private
 * @constructor
 * @param {Array} [values] The values to cache.
 */
function SetCache(values) {
  var index = -1,
      length = values == null ? 0 : values.length;

  this.__data__ = new MapCache;
  while (++index < length) {
    this.add(values[index]);
  }
}

// Add methods to `SetCache`.
SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
SetCache.prototype.has = setCacheHas;

module.exports = SetCache;

},{"./_MapCache":355,"./_setCacheAdd":495,"./_setCacheHas":496}],359:[function(require,module,exports){
var ListCache = require('./_ListCache'),
    stackClear = require('./_stackClear'),
    stackDelete = require('./_stackDelete'),
    stackGet = require('./_stackGet'),
    stackHas = require('./_stackHas'),
    stackSet = require('./_stackSet');

/**
 * Creates a stack cache object to store key-value pairs.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */
function Stack(entries) {
  var data = this.__data__ = new ListCache(entries);
  this.size = data.size;
}

// Add methods to `Stack`.
Stack.prototype.clear = stackClear;
Stack.prototype['delete'] = stackDelete;
Stack.prototype.get = stackGet;
Stack.prototype.has = stackHas;
Stack.prototype.set = stackSet;

module.exports = Stack;

},{"./_ListCache":352,"./_stackClear":502,"./_stackDelete":503,"./_stackGet":504,"./_stackHas":505,"./_stackSet":506}],360:[function(require,module,exports){
var root = require('./_root');

/** Built-in value references. */
var Symbol = root.Symbol;

module.exports = Symbol;

},{"./_root":494}],361:[function(require,module,exports){
var root = require('./_root');

/** Built-in value references. */
var Uint8Array = root.Uint8Array;

module.exports = Uint8Array;

},{"./_root":494}],362:[function(require,module,exports){
var getNative = require('./_getNative'),
    root = require('./_root');

/* Built-in method references that are verified to be native. */
var WeakMap = getNative(root, 'WeakMap');

module.exports = WeakMap;

},{"./_getNative":447,"./_root":494}],363:[function(require,module,exports){
/**
 * A faster alternative to `Function#apply`, this function invokes `func`
 * with the `this` binding of `thisArg` and the arguments of `args`.
 *
 * @private
 * @param {Function} func The function to invoke.
 * @param {*} thisArg The `this` binding of `func`.
 * @param {Array} args The arguments to invoke `func` with.
 * @returns {*} Returns the result of `func`.
 */
function apply(func, thisArg, args) {
  switch (args.length) {
    case 0: return func.call(thisArg);
    case 1: return func.call(thisArg, args[0]);
    case 2: return func.call(thisArg, args[0], args[1]);
    case 3: return func.call(thisArg, args[0], args[1], args[2]);
  }
  return func.apply(thisArg, args);
}

module.exports = apply;

},{}],364:[function(require,module,exports){
/**
 * A specialized version of `baseAggregator` for arrays.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} setter The function to set `accumulator` values.
 * @param {Function} iteratee The iteratee to transform keys.
 * @param {Object} accumulator The initial aggregated object.
 * @returns {Function} Returns `accumulator`.
 */
function arrayAggregator(array, setter, iteratee, accumulator) {
  var index = -1,
      length = array == null ? 0 : array.length;

  while (++index < length) {
    var value = array[index];
    setter(accumulator, value, iteratee(value), array);
  }
  return accumulator;
}

module.exports = arrayAggregator;

},{}],365:[function(require,module,exports){
/**
 * A specialized version of `_.forEach` for arrays without support for
 * iteratee shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns `array`.
 */
function arrayEach(array, iteratee) {
  var index = -1,
      length = array == null ? 0 : array.length;

  while (++index < length) {
    if (iteratee(array[index], index, array) === false) {
      break;
    }
  }
  return array;
}

module.exports = arrayEach;

},{}],366:[function(require,module,exports){
/**
 * A specialized version of `_.filter` for arrays without support for
 * iteratee shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} predicate The function invoked per iteration.
 * @returns {Array} Returns the new filtered array.
 */
function arrayFilter(array, predicate) {
  var index = -1,
      length = array == null ? 0 : array.length,
      resIndex = 0,
      result = [];

  while (++index < length) {
    var value = array[index];
    if (predicate(value, index, array)) {
      result[resIndex++] = value;
    }
  }
  return result;
}

module.exports = arrayFilter;

},{}],367:[function(require,module,exports){
var baseIndexOf = require('./_baseIndexOf');

/**
 * A specialized version of `_.includes` for arrays without support for
 * specifying an index to search from.
 *
 * @private
 * @param {Array} [array] The array to inspect.
 * @param {*} target The value to search for.
 * @returns {boolean} Returns `true` if `target` is found, else `false`.
 */
function arrayIncludes(array, value) {
  var length = array == null ? 0 : array.length;
  return !!length && baseIndexOf(array, value, 0) > -1;
}

module.exports = arrayIncludes;

},{"./_baseIndexOf":389}],368:[function(require,module,exports){
/**
 * This function is like `arrayIncludes` except that it accepts a comparator.
 *
 * @private
 * @param {Array} [array] The array to inspect.
 * @param {*} target The value to search for.
 * @param {Function} comparator The comparator invoked per element.
 * @returns {boolean} Returns `true` if `target` is found, else `false`.
 */
function arrayIncludesWith(array, value, comparator) {
  var index = -1,
      length = array == null ? 0 : array.length;

  while (++index < length) {
    if (comparator(value, array[index])) {
      return true;
    }
  }
  return false;
}

module.exports = arrayIncludesWith;

},{}],369:[function(require,module,exports){
var baseTimes = require('./_baseTimes'),
    isArguments = require('./isArguments'),
    isArray = require('./isArray'),
    isBuffer = require('./isBuffer'),
    isIndex = require('./_isIndex'),
    isTypedArray = require('./isTypedArray');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Creates an array of the enumerable property names of the array-like `value`.
 *
 * @private
 * @param {*} value The value to query.
 * @param {boolean} inherited Specify returning inherited property names.
 * @returns {Array} Returns the array of property names.
 */
function arrayLikeKeys(value, inherited) {
  var isArr = isArray(value),
      isArg = !isArr && isArguments(value),
      isBuff = !isArr && !isArg && isBuffer(value),
      isType = !isArr && !isArg && !isBuff && isTypedArray(value),
      skipIndexes = isArr || isArg || isBuff || isType,
      result = skipIndexes ? baseTimes(value.length, String) : [],
      length = result.length;

  for (var key in value) {
    if ((inherited || hasOwnProperty.call(value, key)) &&
        !(skipIndexes && (
           // Safari 9 has enumerable `arguments.length` in strict mode.
           key == 'length' ||
           // Node.js 0.10 has enumerable non-index properties on buffers.
           (isBuff && (key == 'offset' || key == 'parent')) ||
           // PhantomJS 2 has enumerable non-index properties on typed arrays.
           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
           // Skip index properties.
           isIndex(key, length)
        ))) {
      result.push(key);
    }
  }
  return result;
}

module.exports = arrayLikeKeys;

},{"./_baseTimes":408,"./_isIndex":462,"./isArguments":526,"./isArray":527,"./isBuffer":530,"./isTypedArray":537}],370:[function(require,module,exports){
/**
 * A specialized version of `_.map` for arrays without support for iteratee
 * shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the new mapped array.
 */
function arrayMap(array, iteratee) {
  var index = -1,
      length = array == null ? 0 : array.length,
      result = Array(length);

  while (++index < length) {
    result[index] = iteratee(array[index], index, array);
  }
  return result;
}

module.exports = arrayMap;

},{}],371:[function(require,module,exports){
/**
 * Appends the elements of `values` to `array`.
 *
 * @private
 * @param {Array} array The array to modify.
 * @param {Array} values The values to append.
 * @returns {Array} Returns `array`.
 */
function arrayPush(array, values) {
  var index = -1,
      length = values.length,
      offset = array.length;

  while (++index < length) {
    array[offset + index] = values[index];
  }
  return array;
}

module.exports = arrayPush;

},{}],372:[function(require,module,exports){
/**
 * A specialized version of `_.some` for arrays without support for iteratee
 * shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} predicate The function invoked per iteration.
 * @returns {boolean} Returns `true` if any element passes the predicate check,
 *  else `false`.
 */
function arraySome(array, predicate) {
  var index = -1,
      length = array == null ? 0 : array.length;

  while (++index < length) {
    if (predicate(array[index], index, array)) {
      return true;
    }
  }
  return false;
}

module.exports = arraySome;

},{}],373:[function(require,module,exports){
var baseAssignValue = require('./_baseAssignValue'),
    eq = require('./eq');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Assigns `value` to `key` of `object` if the existing value is not equivalent
 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * for equality comparisons.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */
function assignValue(object, key, value) {
  var objValue = object[key];
  if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
      (value === undefined && !(key in object))) {
    baseAssignValue(object, key, value);
  }
}

module.exports = assignValue;

},{"./_baseAssignValue":376,"./eq":517}],374:[function(require,module,exports){
var eq = require('./eq');

/**
 * Gets the index at which the `key` is found in `array` of key-value pairs.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} key The key to search for.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */
function assocIndexOf(array, key) {
  var length = array.length;
  while (length--) {
    if (eq(array[length][0], key)) {
      return length;
    }
  }
  return -1;
}

module.exports = assocIndexOf;

},{"./eq":517}],375:[function(require,module,exports){
var baseEach = require('./_baseEach');

/**
 * Aggregates elements of `collection` on `accumulator` with keys transformed
 * by `iteratee` and values set by `setter`.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} setter The function to set `accumulator` values.
 * @param {Function} iteratee The iteratee to transform keys.
 * @param {Object} accumulator The initial aggregated object.
 * @returns {Function} Returns `accumulator`.
 */
function baseAggregator(collection, setter, iteratee, accumulator) {
  baseEach(collection, function(value, key, collection) {
    setter(accumulator, value, iteratee(value), collection);
  });
  return accumulator;
}

module.exports = baseAggregator;

},{"./_baseEach":379}],376:[function(require,module,exports){
var defineProperty = require('./_defineProperty');

/**
 * The base implementation of `assignValue` and `assignMergeValue` without
 * value checks.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */
function baseAssignValue(object, key, value) {
  if (key == '__proto__' && defineProperty) {
    defineProperty(object, key, {
      'configurable': true,
      'enumerable': true,
      'value': value,
      'writable': true
    });
  } else {
    object[key] = value;
  }
}

module.exports = baseAssignValue;

},{"./_defineProperty":436}],377:[function(require,module,exports){
var isObject = require('./isObject');

/** Built-in value references. */
var objectCreate = Object.create;

/**
 * The base implementation of `_.create` without support for assigning
 * properties to the created object.
 *
 * @private
 * @param {Object} proto The object to inherit from.
 * @returns {Object} Returns the new object.
 */
var baseCreate = (function() {
  function object() {}
  return function(proto) {
    if (!isObject(proto)) {
      return {};
    }
    if (objectCreate) {
      return objectCreate(proto);
    }
    object.prototype = proto;
    var result = new object;
    object.prototype = undefined;
    return result;
  };
}());

module.exports = baseCreate;

},{"./isObject":534}],378:[function(require,module,exports){
var SetCache = require('./_SetCache'),
    arrayIncludes = require('./_arrayIncludes'),
    arrayIncludesWith = require('./_arrayIncludesWith'),
    arrayMap = require('./_arrayMap'),
    baseUnary = require('./_baseUnary'),
    cacheHas = require('./_cacheHas');

/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;

/**
 * The base implementation of methods like `_.difference` without support
 * for excluding multiple arrays or iteratee shorthands.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {Array} values The values to exclude.
 * @param {Function} [iteratee] The iteratee invoked per element.
 * @param {Function} [comparator] The comparator invoked per element.
 * @returns {Array} Returns the new array of filtered values.
 */
function baseDifference(array, values, iteratee, comparator) {
  var index = -1,
      includes = arrayIncludes,
      isCommon = true,
      length = array.length,
      result = [],
      valuesLength = values.length;

  if (!length) {
    return result;
  }
  if (iteratee) {
    values = arrayMap(values, baseUnary(iteratee));
  }
  if (comparator) {
    includes = arrayIncludesWith;
    isCommon = false;
  }
  else if (values.length >= LARGE_ARRAY_SIZE) {
    includes = cacheHas;
    isCommon = false;
    values = new SetCache(values);
  }
  outer:
  while (++index < length) {
    var value = array[index],
        computed = iteratee == null ? value : iteratee(value);

    value = (comparator || value !== 0) ? value : 0;
    if (isCommon && computed === computed) {
      var valuesIndex = valuesLength;
      while (valuesIndex--) {
        if (values[valuesIndex] === computed) {
          continue outer;
        }
      }
      result.push(value);
    }
    else if (!includes(values, computed, comparator)) {
      result.push(value);
    }
  }
  return result;
}

module.exports = baseDifference;

},{"./_SetCache":358,"./_arrayIncludes":367,"./_arrayIncludesWith":368,"./_arrayMap":370,"./_baseUnary":410,"./_cacheHas":414}],379:[function(require,module,exports){
var baseForOwn = require('./_baseForOwn'),
    createBaseEach = require('./_createBaseEach');

/**
 * The base implementation of `_.forEach` without support for iteratee shorthands.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array|Object} Returns `collection`.
 */
var baseEach = createBaseEach(baseForOwn);

module.exports = baseEach;

},{"./_baseForOwn":384,"./_createBaseEach":425}],380:[function(require,module,exports){
var baseEach = require('./_baseEach');

/**
 * The base implementation of `_.filter` without support for iteratee shorthands.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} predicate The function invoked per iteration.
 * @returns {Array} Returns the new filtered array.
 */
function baseFilter(collection, predicate) {
  var result = [];
  baseEach(collection, function(value, index, collection) {
    if (predicate(value, index, collection)) {
      result.push(value);
    }
  });
  return result;
}

module.exports = baseFilter;

},{"./_baseEach":379}],381:[function(require,module,exports){
/**
 * The base implementation of `_.findIndex` and `_.findLastIndex` without
 * support for iteratee shorthands.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {Function} predicate The function invoked per iteration.
 * @param {number} fromIndex The index to search from.
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */
function baseFindIndex(array, predicate, fromIndex, fromRight) {
  var length = array.length,
      index = fromIndex + (fromRight ? 1 : -1);

  while ((fromRight ? index-- : ++index < length)) {
    if (predicate(array[index], index, array)) {
      return index;
    }
  }
  return -1;
}

module.exports = baseFindIndex;

},{}],382:[function(require,module,exports){
var arrayPush = require('./_arrayPush'),
    isFlattenable = require('./_isFlattenable');

/**
 * The base implementation of `_.flatten` with support for restricting flattening.
 *
 * @private
 * @param {Array} array The array to flatten.
 * @param {number} depth The maximum recursion depth.
 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
 * @param {Array} [result=[]] The initial result value.
 * @returns {Array} Returns the new flattened array.
 */
function baseFlatten(array, depth, predicate, isStrict, result) {
  var index = -1,
      length = array.length;

  predicate || (predicate = isFlattenable);
  result || (result = []);

  while (++index < length) {
    var value = array[index];
    if (depth > 0 && predicate(value)) {
      if (depth > 1) {
        // Recursively flatten arrays (susceptible to call stack limits).
        baseFlatten(value, depth - 1, predicate, isStrict, result);
      } else {
        arrayPush(result, value);
      }
    } else if (!isStrict) {
      result[result.length] = value;
    }
  }
  return result;
}

module.exports = baseFlatten;

},{"./_arrayPush":371,"./_isFlattenable":461}],383:[function(require,module,exports){
var createBaseFor = require('./_createBaseFor');

/**
 * The base implementation of `baseForOwn` which iterates over `object`
 * properties returned by `keysFunc` and invokes `iteratee` for each property.
 * Iteratee functions may exit iteration early by explicitly returning `false`.
 *
 * @private
 * @param {Object} object The object to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {Function} keysFunc The function to get the keys of `object`.
 * @returns {Object} Returns `object`.
 */
var baseFor = createBaseFor();

module.exports = baseFor;

},{"./_createBaseFor":426}],384:[function(require,module,exports){
var baseFor = require('./_baseFor'),
    keys = require('./keys');

/**
 * The base implementation of `_.forOwn` without support for iteratee shorthands.
 *
 * @private
 * @param {Object} object The object to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Object} Returns `object`.
 */
function baseForOwn(object, iteratee) {
  return object && baseFor(object, iteratee, keys);
}

module.exports = baseForOwn;

},{"./_baseFor":383,"./keys":539}],385:[function(require,module,exports){
var castPath = require('./_castPath'),
    toKey = require('./_toKey');

/**
 * The base implementation of `_.get` without support for default values.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array|string} path The path of the property to get.
 * @returns {*} Returns the resolved value.
 */
function baseGet(object, path) {
  path = castPath(path, object);

  var index = 0,
      length = path.length;

  while (object != null && index < length) {
    object = object[toKey(path[index++])];
  }
  return (index && index == length) ? object : undefined;
}

module.exports = baseGet;

},{"./_castPath":416,"./_toKey":509}],386:[function(require,module,exports){
var arrayPush = require('./_arrayPush'),
    isArray = require('./isArray');

/**
 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
 * symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Function} keysFunc The function to get the keys of `object`.
 * @param {Function} symbolsFunc The function to get the symbols of `object`.
 * @returns {Array} Returns the array of property names and symbols.
 */
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  var result = keysFunc(object);
  return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
}

module.exports = baseGetAllKeys;

},{"./_arrayPush":371,"./isArray":527}],387:[function(require,module,exports){
var Symbol = require('./_Symbol'),
    getRawTag = require('./_getRawTag'),
    objectToString = require('./_objectToString');

/** `Object#toString` result references. */
var nullTag = '[object Null]',
    undefinedTag = '[object Undefined]';

/** Built-in value references. */
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;

/**
 * The base implementation of `getTag` without fallbacks for buggy environments.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */
function baseGetTag(value) {
  if (value == null) {
    return value === undefined ? undefinedTag : nullTag;
  }
  return (symToStringTag && symToStringTag in Object(value))
    ? getRawTag(value)
    : objectToString(value);
}

module.exports = baseGetTag;

},{"./_Symbol":360,"./_getRawTag":449,"./_objectToString":488}],388:[function(require,module,exports){
/**
 * The base implementation of `_.hasIn` without support for deep paths.
 *
 * @private
 * @param {Object} [object] The object to query.
 * @param {Array|string} key The key to check.
 * @returns {boolean} Returns `true` if `key` exists, else `false`.
 */
function baseHasIn(object, key) {
  return object != null && key in Object(object);
}

module.exports = baseHasIn;

},{}],389:[function(require,module,exports){
var baseFindIndex = require('./_baseFindIndex'),
    baseIsNaN = require('./_baseIsNaN'),
    strictIndexOf = require('./_strictIndexOf');

/**
 * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} value The value to search for.
 * @param {number} fromIndex The index to search from.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */
function baseIndexOf(array, value, fromIndex) {
  return value === value
    ? strictIndexOf(array, value, fromIndex)
    : baseFindIndex(array, baseIsNaN, fromIndex);
}

module.exports = baseIndexOf;

},{"./_baseFindIndex":381,"./_baseIsNaN":394,"./_strictIndexOf":507}],390:[function(require,module,exports){
var baseGetTag = require('./_baseGetTag'),
    isObjectLike = require('./isObjectLike');

/** `Object#toString` result references. */
var argsTag = '[object Arguments]';

/**
 * The base implementation of `_.isArguments`.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
 */
function baseIsArguments(value) {
  return isObjectLike(value) && baseGetTag(value) == argsTag;
}

module.exports = baseIsArguments;

},{"./_baseGetTag":387,"./isObjectLike":535}],391:[function(require,module,exports){
var baseIsEqualDeep = require('./_baseIsEqualDeep'),
    isObjectLike = require('./isObjectLike');

/**
 * The base implementation of `_.isEqual` which supports partial comparisons
 * and tracks traversed objects.
 *
 * @private
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @param {boolean} bitmask The bitmask flags.
 *  1 - Unordered comparison
 *  2 - Partial comparison
 * @param {Function} [customizer] The function to customize comparisons.
 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
 */
function baseIsEqual(value, other, bitmask, customizer, stack) {
  if (value === other) {
    return true;
  }
  if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
    return value !== value && other !== other;
  }
  return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
}

module.exports = baseIsEqual;

},{"./_baseIsEqualDeep":392,"./isObjectLike":535}],392:[function(require,module,exports){
var Stack = require('./_Stack'),
    equalArrays = require('./_equalArrays'),
    equalByTag = require('./_equalByTag'),
    equalObjects = require('./_equalObjects'),
    getTag = require('./_getTag'),
    isArray = require('./isArray'),
    isBuffer = require('./isBuffer'),
    isTypedArray = require('./isTypedArray');

/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG = 1;

/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
    arrayTag = '[object Array]',
    objectTag = '[object Object]';

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * A specialized version of `baseIsEqual` for arrays and objects which performs
 * deep comparisons and tracks traversed objects enabling objects with circular
 * references to be compared.
 *
 * @private
 * @param {Object} object The object to compare.
 * @param {Object} other The other object to compare.
 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
 * @param {Function} customizer The function to customize comparisons.
 * @param {Function} equalFunc The function to determine equivalents of values.
 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 */
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
  var objIsArr = isArray(object),
      othIsArr = isArray(other),
      objTag = objIsArr ? arrayTag : getTag(object),
      othTag = othIsArr ? arrayTag : getTag(other);

  objTag = objTag == argsTag ? objectTag : objTag;
  othTag = othTag == argsTag ? objectTag : othTag;

  var objIsObj = objTag == objectTag,
      othIsObj = othTag == objectTag,
      isSameTag = objTag == othTag;

  if (isSameTag && isBuffer(object)) {
    if (!isBuffer(other)) {
      return false;
    }
    objIsArr = true;
    objIsObj = false;
  }
  if (isSameTag && !objIsObj) {
    stack || (stack = new Stack);
    return (objIsArr || isTypedArray(object))
      ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
      : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
  }
  if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
    var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
        othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');

    if (objIsWrapped || othIsWrapped) {
      var objUnwrapped = objIsWrapped ? object.value() : object,
          othUnwrapped = othIsWrapped ? other.value() : other;

      stack || (stack = new Stack);
      return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
    }
  }
  if (!isSameTag) {
    return false;
  }
  stack || (stack = new Stack);
  return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
}

module.exports = baseIsEqualDeep;

},{"./_Stack":359,"./_equalArrays":437,"./_equalByTag":438,"./_equalObjects":439,"./_getTag":451,"./isArray":527,"./isBuffer":530,"./isTypedArray":537}],393:[function(require,module,exports){
var Stack = require('./_Stack'),
    baseIsEqual = require('./_baseIsEqual');

/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG = 1,
    COMPARE_UNORDERED_FLAG = 2;

/**
 * The base implementation of `_.isMatch` without support for iteratee shorthands.
 *
 * @private
 * @param {Object} object The object to inspect.
 * @param {Object} source The object of property values to match.
 * @param {Array} matchData The property names, values, and compare flags to match.
 * @param {Function} [customizer] The function to customize comparisons.
 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
 */
function baseIsMatch(object, source, matchData, customizer) {
  var index = matchData.length,
      length = index,
      noCustomizer = !customizer;

  if (object == null) {
    return !length;
  }
  object = Object(object);
  while (index--) {
    var data = matchData[index];
    if ((noCustomizer && data[2])
          ? data[1] !== object[data[0]]
          : !(data[0] in object)
        ) {
      return false;
    }
  }
  while (++index < length) {
    data = matchData[index];
    var key = data[0],
        objValue = object[key],
        srcValue = data[1];

    if (noCustomizer && data[2]) {
      if (objValue === undefined && !(key in object)) {
        return false;
      }
    } else {
      var stack = new Stack;
      if (customizer) {
        var result = customizer(objValue, srcValue, key, object, source, stack);
      }
      if (!(result === undefined
            ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
            : result
          )) {
        return false;
      }
    }
  }
  return true;
}

module.exports = baseIsMatch;

},{"./_Stack":359,"./_baseIsEqual":391}],394:[function(require,module,exports){
/**
 * The base implementation of `_.isNaN` without support for number objects.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
 */
function baseIsNaN(value) {
  return value !== value;
}

module.exports = baseIsNaN;

},{}],395:[function(require,module,exports){
var isFunction = require('./isFunction'),
    isMasked = require('./_isMasked'),
    isObject = require('./isObject'),
    toSource = require('./_toSource');

/**
 * Used to match `RegExp`
 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
 */
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;

/** Used to detect host constructors (Safari). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;

/** Used for built-in method references. */
var funcProto = Function.prototype,
    objectProto = Object.prototype;

/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);

/**
 * The base implementation of `_.isNative` without bad shim checks.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a native function,
 *  else `false`.
 */
function baseIsNative(value) {
  if (!isObject(value) || isMasked(value)) {
    return false;
  }
  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
  return pattern.test(toSource(value));
}

module.exports = baseIsNative;

},{"./_isMasked":467,"./_toSource":510,"./isFunction":532,"./isObject":534}],396:[function(require,module,exports){
var baseGetTag = require('./_baseGetTag'),
    isLength = require('./isLength'),
    isObjectLike = require('./isObjectLike');

/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
    arrayTag = '[object Array]',
    boolTag = '[object Boolean]',
    dateTag = '[object Date]',
    errorTag = '[object Error]',
    funcTag = '[object Function]',
    mapTag = '[object Map]',
    numberTag = '[object Number]',
    objectTag = '[object Object]',
    regexpTag = '[object RegExp]',
    setTag = '[object Set]',
    stringTag = '[object String]',
    weakMapTag = '[object WeakMap]';

var arrayBufferTag = '[object ArrayBuffer]',
    dataViewTag = '[object DataView]',
    float32Tag = '[object Float32Array]',
    float64Tag = '[object Float64Array]',
    int8Tag = '[object Int8Array]',
    int16Tag = '[object Int16Array]',
    int32Tag = '[object Int32Array]',
    uint8Tag = '[object Uint8Array]',
    uint8ClampedTag = '[object Uint8ClampedArray]',
    uint16Tag = '[object Uint16Array]',
    uint32Tag = '[object Uint32Array]';

/** Used to identify `toStringTag` values of typed arrays. */
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
typedArrayTags[errorTag] = typedArrayTags[funcTag] =
typedArrayTags[mapTag] = typedArrayTags[numberTag] =
typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
typedArrayTags[setTag] = typedArrayTags[stringTag] =
typedArrayTags[weakMapTag] = false;

/**
 * The base implementation of `_.isTypedArray` without Node.js optimizations.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
 */
function baseIsTypedArray(value) {
  return isObjectLike(value) &&
    isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
}

module.exports = baseIsTypedArray;

},{"./_baseGetTag":387,"./isLength":533,"./isObjectLike":535}],397:[function(require,module,exports){
var baseMatches = require('./_baseMatches'),
    baseMatchesProperty = require('./_baseMatchesProperty'),
    identity = require('./identity'),
    isArray = require('./isArray'),
    property = require('./property');

/**
 * The base implementation of `_.iteratee`.
 *
 * @private
 * @param {*} [value=_.identity] The value to convert to an iteratee.
 * @returns {Function} Returns the iteratee.
 */
function baseIteratee(value) {
  // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
  // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
  if (typeof value == 'function') {
    return value;
  }
  if (value == null) {
    return identity;
  }
  if (typeof value == 'object') {
    return isArray(value)
      ? baseMatchesProperty(value[0], value[1])
      : baseMatches(value);
  }
  return property(value);
}

module.exports = baseIteratee;

},{"./_baseMatches":401,"./_baseMatchesProperty":402,"./identity":525,"./isArray":527,"./property":544}],398:[function(require,module,exports){
var isPrototype = require('./_isPrototype'),
    nativeKeys = require('./_nativeKeys');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */
function baseKeys(object) {
  if (!isPrototype(object)) {
    return nativeKeys(object);
  }
  var result = [];
  for (var key in Object(object)) {
    if (hasOwnProperty.call(object, key) && key != 'constructor') {
      result.push(key);
    }
  }
  return result;
}

module.exports = baseKeys;

},{"./_isPrototype":468,"./_nativeKeys":486}],399:[function(require,module,exports){
/**
 * The function whose prototype chain sequence wrappers inherit from.
 *
 * @private
 */
function baseLodash() {
  // No operation performed.
}

module.exports = baseLodash;

},{}],400:[function(require,module,exports){
var baseEach = require('./_baseEach'),
    isArrayLike = require('./isArrayLike');

/**
 * The base implementation of `_.map` without support for iteratee shorthands.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the new mapped array.
 */
function baseMap(collection, iteratee) {
  var index = -1,
      result = isArrayLike(collection) ? Array(collection.length) : [];

  baseEach(collection, function(value, key, collection) {
    result[++index] = iteratee(value, key, collection);
  });
  return result;
}

module.exports = baseMap;

},{"./_baseEach":379,"./isArrayLike":528}],401:[function(require,module,exports){
var baseIsMatch = require('./_baseIsMatch'),
    getMatchData = require('./_getMatchData'),
    matchesStrictComparable = require('./_matchesStrictComparable');

/**
 * The base implementation of `_.matches` which doesn't clone `source`.
 *
 * @private
 * @param {Object} source The object of property values to match.
 * @returns {Function} Returns the new spec function.
 */
function baseMatches(source) {
  var matchData = getMatchData(source);
  if (matchData.length == 1 && matchData[0][2]) {
    return matchesStrictComparable(matchData[0][0], matchData[0][1]);
  }
  return function(object) {
    return object === source || baseIsMatch(object, source, matchData);
  };
}

module.exports = baseMatches;

},{"./_baseIsMatch":393,"./_getMatchData":446,"./_matchesStrictComparable":481}],402:[function(require,module,exports){
var baseIsEqual = require('./_baseIsEqual'),
    get = require('./get'),
    hasIn = require('./hasIn'),
    isKey = require('./_isKey'),
    isStrictComparable = require('./_isStrictComparable'),
    matchesStrictComparable = require('./_matchesStrictComparable'),
    toKey = require('./_toKey');

/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG = 1,
    COMPARE_UNORDERED_FLAG = 2;

/**
 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
 *
 * @private
 * @param {string} path The path of the property to get.
 * @param {*} srcValue The value to match.
 * @returns {Function} Returns the new spec function.
 */
function baseMatchesProperty(path, srcValue) {
  if (isKey(path) && isStrictComparable(srcValue)) {
    return matchesStrictComparable(toKey(path), srcValue);
  }
  return function(object) {
    var objValue = get(object, path);
    return (objValue === undefined && objValue === srcValue)
      ? hasIn(object, path)
      : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
  };
}

module.exports = baseMatchesProperty;

},{"./_baseIsEqual":391,"./_isKey":464,"./_isStrictComparable":469,"./_matchesStrictComparable":481,"./_toKey":509,"./get":523,"./hasIn":524}],403:[function(require,module,exports){
/**
 * The base implementation of `_.property` without support for deep paths.
 *
 * @private
 * @param {string} key The key of the property to get.
 * @returns {Function} Returns the new accessor function.
 */
function baseProperty(key) {
  return function(object) {
    return object == null ? undefined : object[key];
  };
}

module.exports = baseProperty;

},{}],404:[function(require,module,exports){
var baseGet = require('./_baseGet');

/**
 * A specialized version of `baseProperty` which supports deep paths.
 *
 * @private
 * @param {Array|string} path The path of the property to get.
 * @returns {Function} Returns the new accessor function.
 */
function basePropertyDeep(path) {
  return function(object) {
    return baseGet(object, path);
  };
}

module.exports = basePropertyDeep;

},{"./_baseGet":385}],405:[function(require,module,exports){
var identity = require('./identity'),
    overRest = require('./_overRest'),
    setToString = require('./_setToString');

/**
 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
 *
 * @private
 * @param {Function} func The function to apply a rest parameter to.
 * @param {number} [start=func.length-1] The start position of the rest parameter.
 * @returns {Function} Returns the new function.
 */
function baseRest(func, start) {
  return setToString(overRest(func, start, identity), func + '');
}

module.exports = baseRest;

},{"./_overRest":490,"./_setToString":499,"./identity":525}],406:[function(require,module,exports){
var identity = require('./identity'),
    metaMap = require('./_metaMap');

/**
 * The base implementation of `setData` without support for hot loop shorting.
 *
 * @private
 * @param {Function} func The function to associate metadata with.
 * @param {*} data The metadata.
 * @returns {Function} Returns `func`.
 */
var baseSetData = !metaMap ? identity : function(func, data) {
  metaMap.set(func, data);
  return func;
};

module.exports = baseSetData;

},{"./_metaMap":484,"./identity":525}],407:[function(require,module,exports){
var constant = require('./constant'),
    defineProperty = require('./_defineProperty'),
    identity = require('./identity');

/**
 * The base implementation of `setToString` without support for hot loop shorting.
 *
 * @private
 * @param {Function} func The function to modify.
 * @param {Function} string The `toString` result.
 * @returns {Function} Returns `func`.
 */
var baseSetToString = !defineProperty ? identity : function(func, string) {
  return defineProperty(func, 'toString', {
    'configurable': true,
    'enumerable': false,
    'value': constant(string),
    'writable': true
  });
};

module.exports = baseSetToString;

},{"./_defineProperty":436,"./constant":515,"./identity":525}],408:[function(require,module,exports){
/**
 * The base implementation of `_.times` without support for iteratee shorthands
 * or max array length checks.
 *
 * @private
 * @param {number} n The number of times to invoke `iteratee`.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the array of results.
 */
function baseTimes(n, iteratee) {
  var index = -1,
      result = Array(n);

  while (++index < n) {
    result[index] = iteratee(index);
  }
  return result;
}

module.exports = baseTimes;

},{}],409:[function(require,module,exports){
var Symbol = require('./_Symbol'),
    arrayMap = require('./_arrayMap'),
    isArray = require('./isArray'),
    isSymbol = require('./isSymbol');

/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;

/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol ? Symbol.prototype : undefined,
    symbolToString = symbolProto ? symbolProto.toString : undefined;

/**
 * The base implementation of `_.toString` which doesn't convert nullish
 * values to empty strings.
 *
 * @private
 * @param {*} value The value to process.
 * @returns {string} Returns the string.
 */
function baseToString(value) {
  // Exit early for strings to avoid a performance hit in some environments.
  if (typeof value == 'string') {
    return value;
  }
  if (isArray(value)) {
    // Recursively convert values (susceptible to call stack limits).
    return arrayMap(value, baseToString) + '';
  }
  if (isSymbol(value)) {
    return symbolToString ? symbolToString.call(value) : '';
  }
  var result = (value + '');
  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}

module.exports = baseToString;

},{"./_Symbol":360,"./_arrayMap":370,"./isArray":527,"./isSymbol":536}],410:[function(require,module,exports){
/**
 * The base implementation of `_.unary` without support for storing metadata.
 *
 * @private
 * @param {Function} func The function to cap arguments for.
 * @returns {Function} Returns the new capped function.
 */
function baseUnary(func) {
  return function(value) {
    return func(value);
  };
}

module.exports = baseUnary;

},{}],411:[function(require,module,exports){
var SetCache = require('./_SetCache'),
    arrayIncludes = require('./_arrayIncludes'),
    arrayIncludesWith = require('./_arrayIncludesWith'),
    cacheHas = require('./_cacheHas'),
    createSet = require('./_createSet'),
    setToArray = require('./_setToArray');

/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;

/**
 * The base implementation of `_.uniqBy` without support for iteratee shorthands.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {Function} [iteratee] The iteratee invoked per element.
 * @param {Function} [comparator] The comparator invoked per element.
 * @returns {Array} Returns the new duplicate free array.
 */
function baseUniq(array, iteratee, comparator) {
  var index = -1,
      includes = arrayIncludes,
      length = array.length,
      isCommon = true,
      result = [],
      seen = result;

  if (comparator) {
    isCommon = false;
    includes = arrayIncludesWith;
  }
  else if (length >= LARGE_ARRAY_SIZE) {
    var set = iteratee ? null : createSet(array);
    if (set) {
      return setToArray(set);
    }
    isCommon = false;
    includes = cacheHas;
    seen = new SetCache;
  }
  else {
    seen = iteratee ? [] : result;
  }
  outer:
  while (++index < length) {
    var value = array[index],
        computed = iteratee ? iteratee(value) : value;

    value = (comparator || value !== 0) ? value : 0;
    if (isCommon && computed === computed) {
      var seenIndex = seen.length;
      while (seenIndex--) {
        if (seen[seenIndex] === computed) {
          continue outer;
        }
      }
      if (iteratee) {
        seen.push(computed);
      }
      result.push(value);
    }
    else if (!includes(seen, computed, comparator)) {
      if (seen !== result) {
        seen.push(computed);
      }
      result.push(value);
    }
  }
  return result;
}

module.exports = baseUniq;

},{"./_SetCache":358,"./_arrayIncludes":367,"./_arrayIncludesWith":368,"./_cacheHas":414,"./_createSet":434,"./_setToArray":498}],412:[function(require,module,exports){
var arrayMap = require('./_arrayMap');

/**
 * The base implementation of `_.values` and `_.valuesIn` which creates an
 * array of `object` property values corresponding to the property names
 * of `props`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array} props The property names to get values for.
 * @returns {Object} Returns the array of property values.
 */
function baseValues(object, props) {
  return arrayMap(props, function(key) {
    return object[key];
  });
}

module.exports = baseValues;

},{"./_arrayMap":370}],413:[function(require,module,exports){
var baseDifference = require('./_baseDifference'),
    baseFlatten = require('./_baseFlatten'),
    baseUniq = require('./_baseUniq');

/**
 * The base implementation of methods like `_.xor`, without support for
 * iteratee shorthands, that accepts an array of arrays to inspect.
 *
 * @private
 * @param {Array} arrays The arrays to inspect.
 * @param {Function} [iteratee] The iteratee invoked per element.
 * @param {Function} [comparator] The comparator invoked per element.
 * @returns {Array} Returns the new array of values.
 */
function baseXor(arrays, iteratee, comparator) {
  var length = arrays.length;
  if (length < 2) {
    return length ? baseUniq(arrays[0]) : [];
  }
  var index = -1,
      result = Array(length);

  while (++index < length) {
    var array = arrays[index],
        othIndex = -1;

    while (++othIndex < length) {
      if (othIndex != index) {
        result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
      }
    }
  }
  return baseUniq(baseFlatten(result, 1), iteratee, comparator);
}

module.exports = baseXor;

},{"./_baseDifference":378,"./_baseFlatten":382,"./_baseUniq":411}],414:[function(require,module,exports){
/**
 * Checks if a `cache` value for `key` exists.
 *
 * @private
 * @param {Object} cache The cache to query.
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */
function cacheHas(cache, key) {
  return cache.has(key);
}

module.exports = cacheHas;

},{}],415:[function(require,module,exports){
var identity = require('./identity');

/**
 * Casts `value` to `identity` if it's not a function.
 *
 * @private
 * @param {*} value The value to inspect.
 * @returns {Function} Returns cast function.
 */
function castFunction(value) {
  return typeof value == 'function' ? value : identity;
}

module.exports = castFunction;

},{"./identity":525}],416:[function(require,module,exports){
var isArray = require('./isArray'),
    isKey = require('./_isKey'),
    stringToPath = require('./_stringToPath'),
    toString = require('./toString');

/**
 * Casts `value` to a path array if it's not one.
 *
 * @private
 * @param {*} value The value to inspect.
 * @param {Object} [object] The object to query keys on.
 * @returns {Array} Returns the cast property path array.
 */
function castPath(value, object) {
  if (isArray(value)) {
    return value;
  }
  return isKey(value, object) ? [value] : stringToPath(toString(value));
}

module.exports = castPath;

},{"./_isKey":464,"./_stringToPath":508,"./isArray":527,"./toString":550}],417:[function(require,module,exports){
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;

/**
 * Creates an array that is the composition of partially applied arguments,
 * placeholders, and provided arguments into a single array of arguments.
 *
 * @private
 * @param {Array} args The provided arguments.
 * @param {Array} partials The arguments to prepend to those provided.
 * @param {Array} holders The `partials` placeholder indexes.
 * @params {boolean} [isCurried] Specify composing for a curried function.
 * @returns {Array} Returns the new array of composed arguments.
 */
function composeArgs(args, partials, holders, isCurried) {
  var argsIndex = -1,
      argsLength = args.length,
      holdersLength = holders.length,
      leftIndex = -1,
      leftLength = partials.length,
      rangeLength = nativeMax(argsLength - holdersLength, 0),
      result = Array(leftLength + rangeLength),
      isUncurried = !isCurried;

  while (++leftIndex < leftLength) {
    result[leftIndex] = partials[leftIndex];
  }
  while (++argsIndex < holdersLength) {
    if (isUncurried || argsIndex < argsLength) {
      result[holders[argsIndex]] = args[argsIndex];
    }
  }
  while (rangeLength--) {
    result[leftIndex++] = args[argsIndex++];
  }
  return result;
}

module.exports = composeArgs;

},{}],418:[function(require,module,exports){
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;

/**
 * This function is like `composeArgs` except that the arguments composition
 * is tailored for `_.partialRight`.
 *
 * @private
 * @param {Array} args The provided arguments.
 * @param {Array} partials The arguments to append to those provided.
 * @param {Array} holders The `partials` placeholder indexes.
 * @params {boolean} [isCurried] Specify composing for a curried function.
 * @returns {Array} Returns the new array of composed arguments.
 */
function composeArgsRight(args, partials, holders, isCurried) {
  var argsIndex = -1,
      argsLength = args.length,
      holdersIndex = -1,
      holdersLength = holders.length,
      rightIndex = -1,
      rightLength = partials.length,
      rangeLength = nativeMax(argsLength - holdersLength, 0),
      result = Array(rangeLength + rightLength),
      isUncurried = !isCurried;

  while (++argsIndex < rangeLength) {
    result[argsIndex] = args[argsIndex];
  }
  var offset = argsIndex;
  while (++rightIndex < rightLength) {
    result[offset + rightIndex] = partials[rightIndex];
  }
  while (++holdersIndex < holdersLength) {
    if (isUncurried || argsIndex < argsLength) {
      result[offset + holders[holdersIndex]] = args[argsIndex++];
    }
  }
  return result;
}

module.exports = composeArgsRight;

},{}],419:[function(require,module,exports){
/**
 * Copies the values of `source` to `array`.
 *
 * @private
 * @param {Array} source The array to copy values from.
 * @param {Array} [array=[]] The array to copy values to.
 * @returns {Array} Returns `array`.
 */
function copyArray(source, array) {
  var index = -1,
      length = source.length;

  array || (array = Array(length));
  while (++index < length) {
    array[index] = source[index];
  }
  return array;
}

module.exports = copyArray;

},{}],420:[function(require,module,exports){
var assignValue = require('./_assignValue'),
    baseAssignValue = require('./_baseAssignValue');

/**
 * Copies properties of `source` to `object`.
 *
 * @private
 * @param {Object} source The object to copy properties from.
 * @param {Array} props The property identifiers to copy.
 * @param {Object} [object={}] The object to copy properties to.
 * @param {Function} [customizer] The function to customize copied values.
 * @returns {Object} Returns `object`.
 */
function copyObject(source, props, object, customizer) {
  var isNew = !object;
  object || (object = {});

  var index = -1,
      length = props.length;

  while (++index < length) {
    var key = props[index];

    var newValue = customizer
      ? customizer(object[key], source[key], key, object, source)
      : undefined;

    if (newValue === undefined) {
      newValue = source[key];
    }
    if (isNew) {
      baseAssignValue(object, key, newValue);
    } else {
      assignValue(object, key, newValue);
    }
  }
  return object;
}

module.exports = copyObject;

},{"./_assignValue":373,"./_baseAssignValue":376}],421:[function(require,module,exports){
var root = require('./_root');

/** Used to detect overreaching core-js shims. */
var coreJsData = root['__core-js_shared__'];

module.exports = coreJsData;

},{"./_root":494}],422:[function(require,module,exports){
/**
 * Gets the number of `placeholder` occurrences in `array`.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} placeholder The placeholder to search for.
 * @returns {number} Returns the placeholder count.
 */
function countHolders(array, placeholder) {
  var length = array.length,
      result = 0;

  while (length--) {
    if (array[length] === placeholder) {
      ++result;
    }
  }
  return result;
}

module.exports = countHolders;

},{}],423:[function(require,module,exports){
var arrayAggregator = require('./_arrayAggregator'),
    baseAggregator = require('./_baseAggregator'),
    baseIteratee = require('./_baseIteratee'),
    isArray = require('./isArray');

/**
 * Creates a function like `_.groupBy`.
 *
 * @private
 * @param {Function} setter The function to set accumulator values.
 * @param {Function} [initializer] The accumulator object initializer.
 * @returns {Function} Returns the new aggregator function.
 */
function createAggregator(setter, initializer) {
  return function(collection, iteratee) {
    var func = isArray(collection) ? arrayAggregator : baseAggregator,
        accumulator = initializer ? initializer() : {};

    return func(collection, setter, baseIteratee(iteratee, 2), accumulator);
  };
}

module.exports = createAggregator;

},{"./_arrayAggregator":364,"./_baseAggregator":375,"./_baseIteratee":397,"./isArray":527}],424:[function(require,module,exports){
var baseRest = require('./_baseRest'),
    isIterateeCall = require('./_isIterateeCall');

/**
 * Creates a function like `_.assign`.
 *
 * @private
 * @param {Function} assigner The function to assign values.
 * @returns {Function} Returns the new assigner function.
 */
function createAssigner(assigner) {
  return baseRest(function(object, sources) {
    var index = -1,
        length = sources.length,
        customizer = length > 1 ? sources[length - 1] : undefined,
        guard = length > 2 ? sources[2] : undefined;

    customizer = (assigner.length > 3 && typeof customizer == 'function')
      ? (length--, customizer)
      : undefined;

    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
      customizer = length < 3 ? undefined : customizer;
      length = 1;
    }
    object = Object(object);
    while (++index < length) {
      var source = sources[index];
      if (source) {
        assigner(object, source, index, customizer);
      }
    }
    return object;
  });
}

module.exports = createAssigner;

},{"./_baseRest":405,"./_isIterateeCall":463}],425:[function(require,module,exports){
var isArrayLike = require('./isArrayLike');

/**
 * Creates a `baseEach` or `baseEachRight` function.
 *
 * @private
 * @param {Function} eachFunc The function to iterate over a collection.
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Function} Returns the new base function.
 */
function createBaseEach(eachFunc, fromRight) {
  return function(collection, iteratee) {
    if (collection == null) {
      return collection;
    }
    if (!isArrayLike(collection)) {
      return eachFunc(collection, iteratee);
    }
    var length = collection.length,
        index = fromRight ? length : -1,
        iterable = Object(collection);

    while ((fromRight ? index-- : ++index < length)) {
      if (iteratee(iterable[index], index, iterable) === false) {
        break;
      }
    }
    return collection;
  };
}

module.exports = createBaseEach;

},{"./isArrayLike":528}],426:[function(require,module,exports){
/**
 * Creates a base function for methods like `_.forIn` and `_.forOwn`.
 *
 * @private
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Function} Returns the new base function.
 */
function createBaseFor(fromRight) {
  return function(object, iteratee, keysFunc) {
    var index = -1,
        iterable = Object(object),
        props = keysFunc(object),
        length = props.length;

    while (length--) {
      var key = props[fromRight ? length : ++index];
      if (iteratee(iterable[key], key, iterable) === false) {
        break;
      }
    }
    return object;
  };
}

module.exports = createBaseFor;

},{}],427:[function(require,module,exports){
var createCtor = require('./_createCtor'),
    root = require('./_root');

/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1;

/**
 * Creates a function that wraps `func` to invoke it with the optional `this`
 * binding of `thisArg`.
 *
 * @private
 * @param {Function} func The function to wrap.
 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
 * @param {*} [thisArg] The `this` binding of `func`.
 * @returns {Function} Returns the new wrapped function.
 */
function createBind(func, bitmask, thisArg) {
  var isBind = bitmask & WRAP_BIND_FLAG,
      Ctor = createCtor(func);

  function wrapper() {
    var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
    return fn.apply(isBind ? thisArg : this, arguments);
  }
  return wrapper;
}

module.exports = createBind;

},{"./_createCtor":428,"./_root":494}],428:[function(require,module,exports){
var baseCreate = require('./_baseCreate'),
    isObject = require('./isObject');

/**
 * Creates a function that produces an instance of `Ctor` regardless of
 * whether it was invoked as part of a `new` expression or by `call` or `apply`.
 *
 * @private
 * @param {Function} Ctor The constructor to wrap.
 * @returns {Function} Returns the new wrapped function.
 */
function createCtor(Ctor) {
  return function() {
    // Use a `switch` statement to work with class constructors. See
    // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
    // for more details.
    var args = arguments;
    switch (args.length) {
      case 0: return new Ctor;
      case 1: return new Ctor(args[0]);
      case 2: return new Ctor(args[0], args[1]);
      case 3: return new Ctor(args[0], args[1], args[2]);
      case 4: return new Ctor(args[0], args[1], args[2], args[3]);
      case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
      case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
      case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
    }
    var thisBinding = baseCreate(Ctor.prototype),
        result = Ctor.apply(thisBinding, args);

    // Mimic the constructor's `return` behavior.
    // See https://es5.github.io/#x13.2.2 for more details.
    return isObject(result) ? result : thisBinding;
  };
}

module.exports = createCtor;

},{"./_baseCreate":377,"./isObject":534}],429:[function(require,module,exports){
var apply = require('./_apply'),
    createCtor = require('./_createCtor'),
    createHybrid = require('./_createHybrid'),
    createRecurry = require('./_createRecurry'),
    getHolder = require('./_getHolder'),
    replaceHolders = require('./_replaceHolders'),
    root = require('./_root');

/**
 * Creates a function that wraps `func` to enable currying.
 *
 * @private
 * @param {Function} func The function to wrap.
 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
 * @param {number} arity The arity of `func`.
 * @returns {Function} Returns the new wrapped function.
 */
function createCurry(func, bitmask, arity) {
  var Ctor = createCtor(func);

  function wrapper() {
    var length = arguments.length,
        args = Array(length),
        index = length,
        placeholder = getHolder(wrapper);

    while (index--) {
      args[index] = arguments[index];
    }
    var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
      ? []
      : replaceHolders(args, placeholder);

    length -= holders.length;
    if (length < arity) {
      return createRecurry(
        func, bitmask, createHybrid, wrapper.placeholder, undefined,
        args, holders, undefined, undefined, arity - length);
    }
    var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
    return apply(fn, this, args);
  }
  return wrapper;
}

module.exports = createCurry;

},{"./_apply":363,"./_createCtor":428,"./_createHybrid":431,"./_createRecurry":433,"./_getHolder":444,"./_replaceHolders":493,"./_root":494}],430:[function(require,module,exports){
var baseIteratee = require('./_baseIteratee'),
    isArrayLike = require('./isArrayLike'),
    keys = require('./keys');

/**
 * Creates a `_.find` or `_.findLast` function.
 *
 * @private
 * @param {Function} findIndexFunc The function to find the collection index.
 * @returns {Function} Returns the new find function.
 */
function createFind(findIndexFunc) {
  return function(collection, predicate, fromIndex) {
    var iterable = Object(collection);
    if (!isArrayLike(collection)) {
      var iteratee = baseIteratee(predicate, 3);
      collection = keys(collection);
      predicate = function(key) { return iteratee(iterable[key], key, iterable); };
    }
    var index = findIndexFunc(collection, predicate, fromIndex);
    return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
  };
}

module.exports = createFind;

},{"./_baseIteratee":397,"./isArrayLike":528,"./keys":539}],431:[function(require,module,exports){
var composeArgs = require('./_composeArgs'),
    composeArgsRight = require('./_composeArgsRight'),
    countHolders = require('./_countHolders'),
    createCtor = require('./_createCtor'),
    createRecurry = require('./_createRecurry'),
    getHolder = require('./_getHolder'),
    reorder = require('./_reorder'),
    replaceHolders = require('./_replaceHolders'),
    root = require('./_root');

/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1,
    WRAP_BIND_KEY_FLAG = 2,
    WRAP_CURRY_FLAG = 8,
    WRAP_CURRY_RIGHT_FLAG = 16,
    WRAP_ARY_FLAG = 128,
    WRAP_FLIP_FLAG = 512;

/**
 * Creates a function that wraps `func` to invoke it with optional `this`
 * binding of `thisArg`, partial application, and currying.
 *
 * @private
 * @param {Function|string} func The function or method name to wrap.
 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
 * @param {*} [thisArg] The `this` binding of `func`.
 * @param {Array} [partials] The arguments to prepend to those provided to
 *  the new function.
 * @param {Array} [holders] The `partials` placeholder indexes.
 * @param {Array} [partialsRight] The arguments to append to those provided
 *  to the new function.
 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
 * @param {Array} [argPos] The argument positions of the new function.
 * @param {number} [ary] The arity cap of `func`.
 * @param {number} [arity] The arity of `func`.
 * @returns {Function} Returns the new wrapped function.
 */
function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
  var isAry = bitmask & WRAP_ARY_FLAG,
      isBind = bitmask & WRAP_BIND_FLAG,
      isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
      isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
      isFlip = bitmask & WRAP_FLIP_FLAG,
      Ctor = isBindKey ? undefined : createCtor(func);

  function wrapper() {
    var length = arguments.length,
        args = Array(length),
        index = length;

    while (index--) {
      args[index] = arguments[index];
    }
    if (isCurried) {
      var placeholder = getHolder(wrapper),
          holdersCount = countHolders(args, placeholder);
    }
    if (partials) {
      args = composeArgs(args, partials, holders, isCurried);
    }
    if (partialsRight) {
      args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
    }
    length -= holdersCount;
    if (isCurried && length < arity) {
      var newHolders = replaceHolders(args, placeholder);
      return createRecurry(
        func, bitmask, createHybrid, wrapper.placeholder, thisArg,
        args, newHolders, argPos, ary, arity - length
      );
    }
    var thisBinding = isBind ? thisArg : this,
        fn = isBindKey ? thisBinding[func] : func;

    length = args.length;
    if (argPos) {
      args = reorder(args, argPos);
    } else if (isFlip && length > 1) {
      args.reverse();
    }
    if (isAry && ary < length) {
      args.length = ary;
    }
    if (this && this !== root && this instanceof wrapper) {
      fn = Ctor || createCtor(fn);
    }
    return fn.apply(thisBinding, args);
  }
  return wrapper;
}

module.exports = createHybrid;

},{"./_composeArgs":417,"./_composeArgsRight":418,"./_countHolders":422,"./_createCtor":428,"./_createRecurry":433,"./_getHolder":444,"./_reorder":492,"./_replaceHolders":493,"./_root":494}],432:[function(require,module,exports){
var apply = require('./_apply'),
    createCtor = require('./_createCtor'),
    root = require('./_root');

/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1;

/**
 * Creates a function that wraps `func` to invoke it with the `this` binding
 * of `thisArg` and `partials` prepended to the arguments it receives.
 *
 * @private
 * @param {Function} func The function to wrap.
 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
 * @param {*} thisArg The `this` binding of `func`.
 * @param {Array} partials The arguments to prepend to those provided to
 *  the new function.
 * @returns {Function} Returns the new wrapped function.
 */
function createPartial(func, bitmask, thisArg, partials) {
  var isBind = bitmask & WRAP_BIND_FLAG,
      Ctor = createCtor(func);

  function wrapper() {
    var argsIndex = -1,
        argsLength = arguments.length,
        leftIndex = -1,
        leftLength = partials.length,
        args = Array(leftLength + argsLength),
        fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;

    while (++leftIndex < leftLength) {
      args[leftIndex] = partials[leftIndex];
    }
    while (argsLength--) {
      args[leftIndex++] = arguments[++argsIndex];
    }
    return apply(fn, isBind ? thisArg : this, args);
  }
  return wrapper;
}

module.exports = createPartial;

},{"./_apply":363,"./_createCtor":428,"./_root":494}],433:[function(require,module,exports){
var isLaziable = require('./_isLaziable'),
    setData = require('./_setData'),
    setWrapToString = require('./_setWrapToString');

/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1,
    WRAP_BIND_KEY_FLAG = 2,
    WRAP_CURRY_BOUND_FLAG = 4,
    WRAP_CURRY_FLAG = 8,
    WRAP_PARTIAL_FLAG = 32,
    WRAP_PARTIAL_RIGHT_FLAG = 64;

/**
 * Creates a function that wraps `func` to continue currying.
 *
 * @private
 * @param {Function} func The function to wrap.
 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
 * @param {Function} wrapFunc The function to create the `func` wrapper.
 * @param {*} placeholder The placeholder value.
 * @param {*} [thisArg] The `this` binding of `func`.
 * @param {Array} [partials] The arguments to prepend to those provided to
 *  the new function.
 * @param {Array} [holders] The `partials` placeholder indexes.
 * @param {Array} [argPos] The argument positions of the new function.
 * @param {number} [ary] The arity cap of `func`.
 * @param {number} [arity] The arity of `func`.
 * @returns {Function} Returns the new wrapped function.
 */
function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
  var isCurry = bitmask & WRAP_CURRY_FLAG,
      newHolders = isCurry ? holders : undefined,
      newHoldersRight = isCurry ? undefined : holders,
      newPartials = isCurry ? partials : undefined,
      newPartialsRight = isCurry ? undefined : partials;

  bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
  bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);

  if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
    bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
  }
  var newData = [
    func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
    newHoldersRight, argPos, ary, arity
  ];

  var result = wrapFunc.apply(undefined, newData);
  if (isLaziable(func)) {
    setData(result, newData);
  }
  result.placeholder = placeholder;
  return setWrapToString(result, func, bitmask);
}

module.exports = createRecurry;

},{"./_isLaziable":466,"./_setData":497,"./_setWrapToString":500}],434:[function(require,module,exports){
var Set = require('./_Set'),
    noop = require('./noop'),
    setToArray = require('./_setToArray');

/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;

/**
 * Creates a set object of `values`.
 *
 * @private
 * @param {Array} values The values to add to the set.
 * @returns {Object} Returns the new set.
 */
var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
  return new Set(values);
};

module.exports = createSet;

},{"./_Set":357,"./_setToArray":498,"./noop":542}],435:[function(require,module,exports){
var baseSetData = require('./_baseSetData'),
    createBind = require('./_createBind'),
    createCurry = require('./_createCurry'),
    createHybrid = require('./_createHybrid'),
    createPartial = require('./_createPartial'),
    getData = require('./_getData'),
    mergeData = require('./_mergeData'),
    setData = require('./_setData'),
    setWrapToString = require('./_setWrapToString'),
    toInteger = require('./toInteger');

/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';

/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1,
    WRAP_BIND_KEY_FLAG = 2,
    WRAP_CURRY_FLAG = 8,
    WRAP_CURRY_RIGHT_FLAG = 16,
    WRAP_PARTIAL_FLAG = 32,
    WRAP_PARTIAL_RIGHT_FLAG = 64;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;

/**
 * Creates a function that either curries or invokes `func` with optional
 * `this` binding and partially applied arguments.
 *
 * @private
 * @param {Function|string} func The function or method name to wrap.
 * @param {number} bitmask The bitmask flags.
 *    1 - `_.bind`
 *    2 - `_.bindKey`
 *    4 - `_.curry` or `_.curryRight` of a bound function
 *    8 - `_.curry`
 *   16 - `_.curryRight`
 *   32 - `_.partial`
 *   64 - `_.partialRight`
 *  128 - `_.rearg`
 *  256 - `_.ary`
 *  512 - `_.flip`
 * @param {*} [thisArg] The `this` binding of `func`.
 * @param {Array} [partials] The arguments to be partially applied.
 * @param {Array} [holders] The `partials` placeholder indexes.
 * @param {Array} [argPos] The argument positions of the new function.
 * @param {number} [ary] The arity cap of `func`.
 * @param {number} [arity] The arity of `func`.
 * @returns {Function} Returns the new wrapped function.
 */
function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
  var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
  if (!isBindKey && typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  var length = partials ? partials.length : 0;
  if (!length) {
    bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
    partials = holders = undefined;
  }
  ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
  arity = arity === undefined ? arity : toInteger(arity);
  length -= holders ? holders.length : 0;

  if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
    var partialsRight = partials,
        holdersRight = holders;

    partials = holders = undefined;
  }
  var data = isBindKey ? undefined : getData(func);

  var newData = [
    func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
    argPos, ary, arity
  ];

  if (data) {
    mergeData(newData, data);
  }
  func = newData[0];
  bitmask = newData[1];
  thisArg = newData[2];
  partials = newData[3];
  holders = newData[4];
  arity = newData[9] = newData[9] === undefined
    ? (isBindKey ? 0 : func.length)
    : nativeMax(newData[9] - length, 0);

  if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
    bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
  }
  if (!bitmask || bitmask == WRAP_BIND_FLAG) {
    var result = createBind(func, bitmask, thisArg);
  } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
    result = createCurry(func, bitmask, arity);
  } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
    result = createPartial(func, bitmask, thisArg, partials);
  } else {
    result = createHybrid.apply(undefined, newData);
  }
  var setter = data ? baseSetData : setData;
  return setWrapToString(setter(result, newData), func, bitmask);
}

module.exports = createWrap;

},{"./_baseSetData":406,"./_createBind":427,"./_createCurry":429,"./_createHybrid":431,"./_createPartial":432,"./_getData":442,"./_mergeData":483,"./_setData":497,"./_setWrapToString":500,"./toInteger":548}],436:[function(require,module,exports){
var getNative = require('./_getNative');

var defineProperty = (function() {
  try {
    var func = getNative(Object, 'defineProperty');
    func({}, '', {});
    return func;
  } catch (e) {}
}());

module.exports = defineProperty;

},{"./_getNative":447}],437:[function(require,module,exports){
var SetCache = require('./_SetCache'),
    arraySome = require('./_arraySome'),
    cacheHas = require('./_cacheHas');

/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG = 1,
    COMPARE_UNORDERED_FLAG = 2;

/**
 * A specialized version of `baseIsEqualDeep` for arrays with support for
 * partial deep comparisons.
 *
 * @private
 * @param {Array} array The array to compare.
 * @param {Array} other The other array to compare.
 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
 * @param {Function} customizer The function to customize comparisons.
 * @param {Function} equalFunc The function to determine equivalents of values.
 * @param {Object} stack Tracks traversed `array` and `other` objects.
 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
 */
function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
      arrLength = array.length,
      othLength = other.length;

  if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
    return false;
  }
  // Check that cyclic values are equal.
  var arrStacked = stack.get(array);
  var othStacked = stack.get(other);
  if (arrStacked && othStacked) {
    return arrStacked == other && othStacked == array;
  }
  var index = -1,
      result = true,
      seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;

  stack.set(array, other);
  stack.set(other, array);

  // Ignore non-index properties.
  while (++index < arrLength) {
    var arrValue = array[index],
        othValue = other[index];

    if (customizer) {
      var compared = isPartial
        ? customizer(othValue, arrValue, index, other, array, stack)
        : customizer(arrValue, othValue, index, array, other, stack);
    }
    if (compared !== undefined) {
      if (compared) {
        continue;
      }
      result = false;
      break;
    }
    // Recursively compare arrays (susceptible to call stack limits).
    if (seen) {
      if (!arraySome(other, function(othValue, othIndex) {
            if (!cacheHas(seen, othIndex) &&
                (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
              return seen.push(othIndex);
            }
          })) {
        result = false;
        break;
      }
    } else if (!(
          arrValue === othValue ||
            equalFunc(arrValue, othValue, bitmask, customizer, stack)
        )) {
      result = false;
      break;
    }
  }
  stack['delete'](array);
  stack['delete'](other);
  return result;
}

module.exports = equalArrays;

},{"./_SetCache":358,"./_arraySome":372,"./_cacheHas":414}],438:[function(require,module,exports){
var Symbol = require('./_Symbol'),
    Uint8Array = require('./_Uint8Array'),
    eq = require('./eq'),
    equalArrays = require('./_equalArrays'),
    mapToArray = require('./_mapToArray'),
    setToArray = require('./_setToArray');

/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG = 1,
    COMPARE_UNORDERED_FLAG = 2;

/** `Object#toString` result references. */
var boolTag = '[object Boolean]',
    dateTag = '[object Date]',
    errorTag = '[object Error]',
    mapTag = '[object Map]',
    numberTag = '[object Number]',
    regexpTag = '[object RegExp]',
    setTag = '[object Set]',
    stringTag = '[object String]',
    symbolTag = '[object Symbol]';

var arrayBufferTag = '[object ArrayBuffer]',
    dataViewTag = '[object DataView]';

/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol ? Symbol.prototype : undefined,
    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;

/**
 * A specialized version of `baseIsEqualDeep` for comparing objects of
 * the same `toStringTag`.
 *
 * **Note:** This function only supports comparing values with tags of
 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
 *
 * @private
 * @param {Object} object The object to compare.
 * @param {Object} other The other object to compare.
 * @param {string} tag The `toStringTag` of the objects to compare.
 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
 * @param {Function} customizer The function to customize comparisons.
 * @param {Function} equalFunc The function to determine equivalents of values.
 * @param {Object} stack Tracks traversed `object` and `other` objects.
 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 */
function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
  switch (tag) {
    case dataViewTag:
      if ((object.byteLength != other.byteLength) ||
          (object.byteOffset != other.byteOffset)) {
        return false;
      }
      object = object.buffer;
      other = other.buffer;

    case arrayBufferTag:
      if ((object.byteLength != other.byteLength) ||
          !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
        return false;
      }
      return true;

    case boolTag:
    case dateTag:
    case numberTag:
      // Coerce booleans to `1` or `0` and dates to milliseconds.
      // Invalid dates are coerced to `NaN`.
      return eq(+object, +other);

    case errorTag:
      return object.name == other.name && object.message == other.message;

    case regexpTag:
    case stringTag:
      // Coerce regexes to strings and treat strings, primitives and objects,
      // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
      // for more details.
      return object == (other + '');

    case mapTag:
      var convert = mapToArray;

    case setTag:
      var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
      convert || (convert = setToArray);

      if (object.size != other.size && !isPartial) {
        return false;
      }
      // Assume cyclic values are equal.
      var stacked = stack.get(object);
      if (stacked) {
        return stacked == other;
      }
      bitmask |= COMPARE_UNORDERED_FLAG;

      // Recursively compare objects (susceptible to call stack limits).
      stack.set(object, other);
      var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
      stack['delete'](object);
      return result;

    case symbolTag:
      if (symbolValueOf) {
        return symbolValueOf.call(object) == symbolValueOf.call(other);
      }
  }
  return false;
}

module.exports = equalByTag;

},{"./_Symbol":360,"./_Uint8Array":361,"./_equalArrays":437,"./_mapToArray":480,"./_setToArray":498,"./eq":517}],439:[function(require,module,exports){
var getAllKeys = require('./_getAllKeys');

/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG = 1;

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * A specialized version of `baseIsEqualDeep` for objects with support for
 * partial deep comparisons.
 *
 * @private
 * @param {Object} object The object to compare.
 * @param {Object} other The other object to compare.
 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
 * @param {Function} customizer The function to customize comparisons.
 * @param {Function} equalFunc The function to determine equivalents of values.
 * @param {Object} stack Tracks traversed `object` and `other` objects.
 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 */
function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
      objProps = getAllKeys(object),
      objLength = objProps.length,
      othProps = getAllKeys(other),
      othLength = othProps.length;

  if (objLength != othLength && !isPartial) {
    return false;
  }
  var index = objLength;
  while (index--) {
    var key = objProps[index];
    if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
      return false;
    }
  }
  // Check that cyclic values are equal.
  var objStacked = stack.get(object);
  var othStacked = stack.get(other);
  if (objStacked && othStacked) {
    return objStacked == other && othStacked == object;
  }
  var result = true;
  stack.set(object, other);
  stack.set(other, object);

  var skipCtor = isPartial;
  while (++index < objLength) {
    key = objProps[index];
    var objValue = object[key],
        othValue = other[key];

    if (customizer) {
      var compared = isPartial
        ? customizer(othValue, objValue, key, other, object, stack)
        : customizer(objValue, othValue, key, object, other, stack);
    }
    // Recursively compare objects (susceptible to call stack limits).
    if (!(compared === undefined
          ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
          : compared
        )) {
      result = false;
      break;
    }
    skipCtor || (skipCtor = key == 'constructor');
  }
  if (result && !skipCtor) {
    var objCtor = object.constructor,
        othCtor = other.constructor;

    // Non `Object` object instances with different constructors are not equal.
    if (objCtor != othCtor &&
        ('constructor' in object && 'constructor' in other) &&
        !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
          typeof othCtor == 'function' && othCtor instanceof othCtor)) {
      result = false;
    }
  }
  stack['delete'](object);
  stack['delete'](other);
  return result;
}

module.exports = equalObjects;

},{"./_getAllKeys":441}],440:[function(require,module,exports){
(function (global){(function (){
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;

module.exports = freeGlobal;

}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],441:[function(require,module,exports){
var baseGetAllKeys = require('./_baseGetAllKeys'),
    getSymbols = require('./_getSymbols'),
    keys = require('./keys');

/**
 * Creates an array of own enumerable property names and symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names and symbols.
 */
function getAllKeys(object) {
  return baseGetAllKeys(object, keys, getSymbols);
}

module.exports = getAllKeys;

},{"./_baseGetAllKeys":386,"./_getSymbols":450,"./keys":539}],442:[function(require,module,exports){
var metaMap = require('./_metaMap'),
    noop = require('./noop');

/**
 * Gets metadata for `func`.
 *
 * @private
 * @param {Function} func The function to query.
 * @returns {*} Returns the metadata for `func`.
 */
var getData = !metaMap ? noop : function(func) {
  return metaMap.get(func);
};

module.exports = getData;

},{"./_metaMap":484,"./noop":542}],443:[function(require,module,exports){
var realNames = require('./_realNames');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Gets the name of `func`.
 *
 * @private
 * @param {Function} func The function to query.
 * @returns {string} Returns the function name.
 */
function getFuncName(func) {
  var result = (func.name + ''),
      array = realNames[result],
      length = hasOwnProperty.call(realNames, result) ? array.length : 0;

  while (length--) {
    var data = array[length],
        otherFunc = data.func;
    if (otherFunc == null || otherFunc == func) {
      return data.name;
    }
  }
  return result;
}

module.exports = getFuncName;

},{"./_realNames":491}],444:[function(require,module,exports){
/**
 * Gets the argument placeholder value for `func`.
 *
 * @private
 * @param {Function} func The function to inspect.
 * @returns {*} Returns the placeholder value.
 */
function getHolder(func) {
  var object = func;
  return object.placeholder;
}

module.exports = getHolder;

},{}],445:[function(require,module,exports){
var isKeyable = require('./_isKeyable');

/**
 * Gets the data for `map`.
 *
 * @private
 * @param {Object} map The map to query.
 * @param {string} key The reference key.
 * @returns {*} Returns the map data.
 */
function getMapData(map, key) {
  var data = map.__data__;
  return isKeyable(key)
    ? data[typeof key == 'string' ? 'string' : 'hash']
    : data.map;
}

module.exports = getMapData;

},{"./_isKeyable":465}],446:[function(require,module,exports){
var isStrictComparable = require('./_isStrictComparable'),
    keys = require('./keys');

/**
 * Gets the property names, values, and compare flags of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the match data of `object`.
 */
function getMatchData(object) {
  var result = keys(object),
      length = result.length;

  while (length--) {
    var key = result[length],
        value = object[key];

    result[length] = [key, value, isStrictComparable(value)];
  }
  return result;
}

module.exports = getMatchData;

},{"./_isStrictComparable":469,"./keys":539}],447:[function(require,module,exports){
var baseIsNative = require('./_baseIsNative'),
    getValue = require('./_getValue');

/**
 * Gets the native function at `key` of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {string} key The key of the method to get.
 * @returns {*} Returns the function if it's native, else `undefined`.
 */
function getNative(object, key) {
  var value = getValue(object, key);
  return baseIsNative(value) ? value : undefined;
}

module.exports = getNative;

},{"./_baseIsNative":395,"./_getValue":452}],448:[function(require,module,exports){
var overArg = require('./_overArg');

/** Built-in value references. */
var getPrototype = overArg(Object.getPrototypeOf, Object);

module.exports = getPrototype;

},{"./_overArg":489}],449:[function(require,module,exports){
var Symbol = require('./_Symbol');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */
var nativeObjectToString = objectProto.toString;

/** Built-in value references. */
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;

/**
 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the raw `toStringTag`.
 */
function getRawTag(value) {
  var isOwn = hasOwnProperty.call(value, symToStringTag),
      tag = value[symToStringTag];

  try {
    value[symToStringTag] = undefined;
    var unmasked = true;
  } catch (e) {}

  var result = nativeObjectToString.call(value);
  if (unmasked) {
    if (isOwn) {
      value[symToStringTag] = tag;
    } else {
      delete value[symToStringTag];
    }
  }
  return result;
}

module.exports = getRawTag;

},{"./_Symbol":360}],450:[function(require,module,exports){
var arrayFilter = require('./_arrayFilter'),
    stubArray = require('./stubArray');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Built-in value references. */
var propertyIsEnumerable = objectProto.propertyIsEnumerable;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeGetSymbols = Object.getOwnPropertySymbols;

/**
 * Creates an array of the own enumerable symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of symbols.
 */
var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
  if (object == null) {
    return [];
  }
  object = Object(object);
  return arrayFilter(nativeGetSymbols(object), function(symbol) {
    return propertyIsEnumerable.call(object, symbol);
  });
};

module.exports = getSymbols;

},{"./_arrayFilter":366,"./stubArray":545}],451:[function(require,module,exports){
var DataView = require('./_DataView'),
    Map = require('./_Map'),
    Promise = require('./_Promise'),
    Set = require('./_Set'),
    WeakMap = require('./_WeakMap'),
    baseGetTag = require('./_baseGetTag'),
    toSource = require('./_toSource');

/** `Object#toString` result references. */
var mapTag = '[object Map]',
    objectTag = '[object Object]',
    promiseTag = '[object Promise]',
    setTag = '[object Set]',
    weakMapTag = '[object WeakMap]';

var dataViewTag = '[object DataView]';

/** Used to detect maps, sets, and weakmaps. */
var dataViewCtorString = toSource(DataView),
    mapCtorString = toSource(Map),
    promiseCtorString = toSource(Promise),
    setCtorString = toSource(Set),
    weakMapCtorString = toSource(WeakMap);

/**
 * Gets the `toStringTag` of `value`.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */
var getTag = baseGetTag;

// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
    (Map && getTag(new Map) != mapTag) ||
    (Promise && getTag(Promise.resolve()) != promiseTag) ||
    (Set && getTag(new Set) != setTag) ||
    (WeakMap && getTag(new WeakMap) != weakMapTag)) {
  getTag = function(value) {
    var result = baseGetTag(value),
        Ctor = result == objectTag ? value.constructor : undefined,
        ctorString = Ctor ? toSource(Ctor) : '';

    if (ctorString) {
      switch (ctorString) {
        case dataViewCtorString: return dataViewTag;
        case mapCtorString: return mapTag;
        case promiseCtorString: return promiseTag;
        case setCtorString: return setTag;
        case weakMapCtorString: return weakMapTag;
      }
    }
    return result;
  };
}

module.exports = getTag;

},{"./_DataView":349,"./_Map":354,"./_Promise":356,"./_Set":357,"./_WeakMap":362,"./_baseGetTag":387,"./_toSource":510}],452:[function(require,module,exports){
/**
 * Gets the value at `key` of `object`.
 *
 * @private
 * @param {Object} [object] The object to query.
 * @param {string} key The key of the property to get.
 * @returns {*} Returns the property value.
 */
function getValue(object, key) {
  return object == null ? undefined : object[key];
}

module.exports = getValue;

},{}],453:[function(require,module,exports){
/** Used to match wrap detail comments. */
var reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
    reSplitDetails = /,? & /;

/**
 * Extracts wrapper details from the `source` body comment.
 *
 * @private
 * @param {string} source The source to inspect.
 * @returns {Array} Returns the wrapper details.
 */
function getWrapDetails(source) {
  var match = source.match(reWrapDetails);
  return match ? match[1].split(reSplitDetails) : [];
}

module.exports = getWrapDetails;

},{}],454:[function(require,module,exports){
var castPath = require('./_castPath'),
    isArguments = require('./isArguments'),
    isArray = require('./isArray'),
    isIndex = require('./_isIndex'),
    isLength = require('./isLength'),
    toKey = require('./_toKey');

/**
 * Checks if `path` exists on `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array|string} path The path to check.
 * @param {Function} hasFunc The function to check properties.
 * @returns {boolean} Returns `true` if `path` exists, else `false`.
 */
function hasPath(object, path, hasFunc) {
  path = castPath(path, object);

  var index = -1,
      length = path.length,
      result = false;

  while (++index < length) {
    var key = toKey(path[index]);
    if (!(result = object != null && hasFunc(object, key))) {
      break;
    }
    object = object[key];
  }
  if (result || ++index != length) {
    return result;
  }
  length = object == null ? 0 : object.length;
  return !!length && isLength(length) && isIndex(key, length) &&
    (isArray(object) || isArguments(object));
}

module.exports = hasPath;

},{"./_castPath":416,"./_isIndex":462,"./_toKey":509,"./isArguments":526,"./isArray":527,"./isLength":533}],455:[function(require,module,exports){
var nativeCreate = require('./_nativeCreate');

/**
 * Removes all key-value entries from the hash.
 *
 * @private
 * @name clear
 * @memberOf Hash
 */
function hashClear() {
  this.__data__ = nativeCreate ? nativeCreate(null) : {};
  this.size = 0;
}

module.exports = hashClear;

},{"./_nativeCreate":485}],456:[function(require,module,exports){
/**
 * Removes `key` and its value from the hash.
 *
 * @private
 * @name delete
 * @memberOf Hash
 * @param {Object} hash The hash to modify.
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */
function hashDelete(key) {
  var result = this.has(key) && delete this.__data__[key];
  this.size -= result ? 1 : 0;
  return result;
}

module.exports = hashDelete;

},{}],457:[function(require,module,exports){
var nativeCreate = require('./_nativeCreate');

/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Gets the hash value for `key`.
 *
 * @private
 * @name get
 * @memberOf Hash
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */
function hashGet(key) {
  var data = this.__data__;
  if (nativeCreate) {
    var result = data[key];
    return result === HASH_UNDEFINED ? undefined : result;
  }
  return hasOwnProperty.call(data, key) ? data[key] : undefined;
}

module.exports = hashGet;

},{"./_nativeCreate":485}],458:[function(require,module,exports){
var nativeCreate = require('./_nativeCreate');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Checks if a hash value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf Hash
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */
function hashHas(key) {
  var data = this.__data__;
  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
}

module.exports = hashHas;

},{"./_nativeCreate":485}],459:[function(require,module,exports){
var nativeCreate = require('./_nativeCreate');

/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';

/**
 * Sets the hash `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf Hash
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the hash instance.
 */
function hashSet(key, value) {
  var data = this.__data__;
  this.size += this.has(key) ? 0 : 1;
  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
  return this;
}

module.exports = hashSet;

},{"./_nativeCreate":485}],460:[function(require,module,exports){
/** Used to match wrap detail comments. */
var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/;

/**
 * Inserts wrapper `details` in a comment at the top of the `source` body.
 *
 * @private
 * @param {string} source The source to modify.
 * @returns {Array} details The details to insert.
 * @returns {string} Returns the modified source.
 */
function insertWrapDetails(source, details) {
  var length = details.length;
  if (!length) {
    return source;
  }
  var lastIndex = length - 1;
  details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
  details = details.join(length > 2 ? ', ' : ' ');
  return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
}

module.exports = insertWrapDetails;

},{}],461:[function(require,module,exports){
var Symbol = require('./_Symbol'),
    isArguments = require('./isArguments'),
    isArray = require('./isArray');

/** Built-in value references. */
var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;

/**
 * Checks if `value` is a flattenable `arguments` object or array.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
 */
function isFlattenable(value) {
  return isArray(value) || isArguments(value) ||
    !!(spreadableSymbol && value && value[spreadableSymbol]);
}

module.exports = isFlattenable;

},{"./_Symbol":360,"./isArguments":526,"./isArray":527}],462:[function(require,module,exports){
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;

/** Used to detect unsigned integer values. */
var reIsUint = /^(?:0|[1-9]\d*)$/;

/**
 * Checks if `value` is a valid array-like index.
 *
 * @private
 * @param {*} value The value to check.
 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
 */
function isIndex(value, length) {
  var type = typeof value;
  length = length == null ? MAX_SAFE_INTEGER : length;

  return !!length &&
    (type == 'number' ||
      (type != 'symbol' && reIsUint.test(value))) &&
        (value > -1 && value % 1 == 0 && value < length);
}

module.exports = isIndex;

},{}],463:[function(require,module,exports){
var eq = require('./eq'),
    isArrayLike = require('./isArrayLike'),
    isIndex = require('./_isIndex'),
    isObject = require('./isObject');

/**
 * Checks if the given arguments are from an iteratee call.
 *
 * @private
 * @param {*} value The potential iteratee value argument.
 * @param {*} index The potential iteratee index or key argument.
 * @param {*} object The potential iteratee object argument.
 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
 *  else `false`.
 */
function isIterateeCall(value, index, object) {
  if (!isObject(object)) {
    return false;
  }
  var type = typeof index;
  if (type == 'number'
        ? (isArrayLike(object) && isIndex(index, object.length))
        : (type == 'string' && index in object)
      ) {
    return eq(object[index], value);
  }
  return false;
}

module.exports = isIterateeCall;

},{"./_isIndex":462,"./eq":517,"./isArrayLike":528,"./isObject":534}],464:[function(require,module,exports){
var isArray = require('./isArray'),
    isSymbol = require('./isSymbol');

/** Used to match property names within property paths. */
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
    reIsPlainProp = /^\w*$/;

/**
 * Checks if `value` is a property name and not a property path.
 *
 * @private
 * @param {*} value The value to check.
 * @param {Object} [object] The object to query keys on.
 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
 */
function isKey(value, object) {
  if (isArray(value)) {
    return false;
  }
  var type = typeof value;
  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
      value == null || isSymbol(value)) {
    return true;
  }
  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
    (object != null && value in Object(object));
}

module.exports = isKey;

},{"./isArray":527,"./isSymbol":536}],465:[function(require,module,exports){
/**
 * Checks if `value` is suitable for use as unique object key.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
 */
function isKeyable(value) {
  var type = typeof value;
  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
    ? (value !== '__proto__')
    : (value === null);
}

module.exports = isKeyable;

},{}],466:[function(require,module,exports){
var LazyWrapper = require('./_LazyWrapper'),
    getData = require('./_getData'),
    getFuncName = require('./_getFuncName'),
    lodash = require('./wrapperLodash');

/**
 * Checks if `func` has a lazy counterpart.
 *
 * @private
 * @param {Function} func The function to check.
 * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
 *  else `false`.
 */
function isLaziable(func) {
  var funcName = getFuncName(func),
      other = lodash[funcName];

  if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
    return false;
  }
  if (func === other) {
    return true;
  }
  var data = getData(other);
  return !!data && func === data[0];
}

module.exports = isLaziable;

},{"./_LazyWrapper":351,"./_getData":442,"./_getFuncName":443,"./wrapperLodash":553}],467:[function(require,module,exports){
var coreJsData = require('./_coreJsData');

/** Used to detect methods masquerading as native. */
var maskSrcKey = (function() {
  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
  return uid ? ('Symbol(src)_1.' + uid) : '';
}());

/**
 * Checks if `func` has its source masked.
 *
 * @private
 * @param {Function} func The function to check.
 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
 */
function isMasked(func) {
  return !!maskSrcKey && (maskSrcKey in func);
}

module.exports = isMasked;

},{"./_coreJsData":421}],468:[function(require,module,exports){
/** Used for built-in method references. */
var objectProto = Object.prototype;

/**
 * Checks if `value` is likely a prototype object.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
 */
function isPrototype(value) {
  var Ctor = value && value.constructor,
      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;

  return value === proto;
}

module.exports = isPrototype;

},{}],469:[function(require,module,exports){
var isObject = require('./isObject');

/**
 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` if suitable for strict
 *  equality comparisons, else `false`.
 */
function isStrictComparable(value) {
  return value === value && !isObject(value);
}

module.exports = isStrictComparable;

},{"./isObject":534}],470:[function(require,module,exports){
/**
 * Removes all key-value entries from the list cache.
 *
 * @private
 * @name clear
 * @memberOf ListCache
 */
function listCacheClear() {
  this.__data__ = [];
  this.size = 0;
}

module.exports = listCacheClear;

},{}],471:[function(require,module,exports){
var assocIndexOf = require('./_assocIndexOf');

/** Used for built-in method references. */
var arrayProto = Array.prototype;

/** Built-in value references. */
var splice = arrayProto.splice;

/**
 * Removes `key` and its value from the list cache.
 *
 * @private
 * @name delete
 * @memberOf ListCache
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */
function listCacheDelete(key) {
  var data = this.__data__,
      index = assocIndexOf(data, key);

  if (index < 0) {
    return false;
  }
  var lastIndex = data.length - 1;
  if (index == lastIndex) {
    data.pop();
  } else {
    splice.call(data, index, 1);
  }
  --this.size;
  return true;
}

module.exports = listCacheDelete;

},{"./_assocIndexOf":374}],472:[function(require,module,exports){
var assocIndexOf = require('./_assocIndexOf');

/**
 * Gets the list cache value for `key`.
 *
 * @private
 * @name get
 * @memberOf ListCache
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */
function listCacheGet(key) {
  var data = this.__data__,
      index = assocIndexOf(data, key);

  return index < 0 ? undefined : data[index][1];
}

module.exports = listCacheGet;

},{"./_assocIndexOf":374}],473:[function(require,module,exports){
var assocIndexOf = require('./_assocIndexOf');

/**
 * Checks if a list cache value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf ListCache
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */
function listCacheHas(key) {
  return assocIndexOf(this.__data__, key) > -1;
}

module.exports = listCacheHas;

},{"./_assocIndexOf":374}],474:[function(require,module,exports){
var assocIndexOf = require('./_assocIndexOf');

/**
 * Sets the list cache `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf ListCache
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the list cache instance.
 */
function listCacheSet(key, value) {
  var data = this.__data__,
      index = assocIndexOf(data, key);

  if (index < 0) {
    ++this.size;
    data.push([key, value]);
  } else {
    data[index][1] = value;
  }
  return this;
}

module.exports = listCacheSet;

},{"./_assocIndexOf":374}],475:[function(require,module,exports){
var Hash = require('./_Hash'),
    ListCache = require('./_ListCache'),
    Map = require('./_Map');

/**
 * Removes all key-value entries from the map.
 *
 * @private
 * @name clear
 * @memberOf MapCache
 */
function mapCacheClear() {
  this.size = 0;
  this.__data__ = {
    'hash': new Hash,
    'map': new (Map || ListCache),
    'string': new Hash
  };
}

module.exports = mapCacheClear;

},{"./_Hash":350,"./_ListCache":352,"./_Map":354}],476:[function(require,module,exports){
var getMapData = require('./_getMapData');

/**
 * Removes `key` and its value from the map.
 *
 * @private
 * @name delete
 * @memberOf MapCache
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */
function mapCacheDelete(key) {
  var result = getMapData(this, key)['delete'](key);
  this.size -= result ? 1 : 0;
  return result;
}

module.exports = mapCacheDelete;

},{"./_getMapData":445}],477:[function(require,module,exports){
var getMapData = require('./_getMapData');

/**
 * Gets the map value for `key`.
 *
 * @private
 * @name get
 * @memberOf MapCache
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */
function mapCacheGet(key) {
  return getMapData(this, key).get(key);
}

module.exports = mapCacheGet;

},{"./_getMapData":445}],478:[function(require,module,exports){
var getMapData = require('./_getMapData');

/**
 * Checks if a map value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf MapCache
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */
function mapCacheHas(key) {
  return getMapData(this, key).has(key);
}

module.exports = mapCacheHas;

},{"./_getMapData":445}],479:[function(require,module,exports){
var getMapData = require('./_getMapData');

/**
 * Sets the map `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf MapCache
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the map cache instance.
 */
function mapCacheSet(key, value) {
  var data = getMapData(this, key),
      size = data.size;

  data.set(key, value);
  this.size += data.size == size ? 0 : 1;
  return this;
}

module.exports = mapCacheSet;

},{"./_getMapData":445}],480:[function(require,module,exports){
/**
 * Converts `map` to its key-value pairs.
 *
 * @private
 * @param {Object} map The map to convert.
 * @returns {Array} Returns the key-value pairs.
 */
function mapToArray(map) {
  var index = -1,
      result = Array(map.size);

  map.forEach(function(value, key) {
    result[++index] = [key, value];
  });
  return result;
}

module.exports = mapToArray;

},{}],481:[function(require,module,exports){
/**
 * A specialized version of `matchesProperty` for source values suitable
 * for strict equality comparisons, i.e. `===`.
 *
 * @private
 * @param {string} key The key of the property to get.
 * @param {*} srcValue The value to match.
 * @returns {Function} Returns the new spec function.
 */
function matchesStrictComparable(key, srcValue) {
  return function(object) {
    if (object == null) {
      return false;
    }
    return object[key] === srcValue &&
      (srcValue !== undefined || (key in Object(object)));
  };
}

module.exports = matchesStrictComparable;

},{}],482:[function(require,module,exports){
var memoize = require('./memoize');

/** Used as the maximum memoize cache size. */
var MAX_MEMOIZE_SIZE = 500;

/**
 * A specialized version of `_.memoize` which clears the memoized function's
 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
 *
 * @private
 * @param {Function} func The function to have its output memoized.
 * @returns {Function} Returns the new memoized function.
 */
function memoizeCapped(func) {
  var result = memoize(func, function(key) {
    if (cache.size === MAX_MEMOIZE_SIZE) {
      cache.clear();
    }
    return key;
  });

  var cache = result.cache;
  return result;
}

module.exports = memoizeCapped;

},{"./memoize":541}],483:[function(require,module,exports){
var composeArgs = require('./_composeArgs'),
    composeArgsRight = require('./_composeArgsRight'),
    replaceHolders = require('./_replaceHolders');

/** Used as the internal argument placeholder. */
var PLACEHOLDER = '__lodash_placeholder__';

/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1,
    WRAP_BIND_KEY_FLAG = 2,
    WRAP_CURRY_BOUND_FLAG = 4,
    WRAP_CURRY_FLAG = 8,
    WRAP_ARY_FLAG = 128,
    WRAP_REARG_FLAG = 256;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;

/**
 * Merges the function metadata of `source` into `data`.
 *
 * Merging metadata reduces the number of wrappers used to invoke a function.
 * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
 * may be applied regardless of execution order. Methods like `_.ary` and
 * `_.rearg` modify function arguments, making the order in which they are
 * executed important, preventing the merging of metadata. However, we make
 * an exception for a safe combined case where curried functions have `_.ary`
 * and or `_.rearg` applied.
 *
 * @private
 * @param {Array} data The destination metadata.
 * @param {Array} source The source metadata.
 * @returns {Array} Returns `data`.
 */
function mergeData(data, source) {
  var bitmask = data[1],
      srcBitmask = source[1],
      newBitmask = bitmask | srcBitmask,
      isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);

  var isCombo =
    ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
    ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
    ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));

  // Exit early if metadata can't be merged.
  if (!(isCommon || isCombo)) {
    return data;
  }
  // Use source `thisArg` if available.
  if (srcBitmask & WRAP_BIND_FLAG) {
    data[2] = source[2];
    // Set when currying a bound function.
    newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
  }
  // Compose partial arguments.
  var value = source[3];
  if (value) {
    var partials = data[3];
    data[3] = partials ? composeArgs(partials, value, source[4]) : value;
    data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
  }
  // Compose partial right arguments.
  value = source[5];
  if (value) {
    partials = data[5];
    data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
    data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
  }
  // Use source `argPos` if available.
  value = source[7];
  if (value) {
    data[7] = value;
  }
  // Use source `ary` if it's smaller.
  if (srcBitmask & WRAP_ARY_FLAG) {
    data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
  }
  // Use source `arity` if one is not provided.
  if (data[9] == null) {
    data[9] = source[9];
  }
  // Use source `func` and merge bitmasks.
  data[0] = source[0];
  data[1] = newBitmask;

  return data;
}

module.exports = mergeData;

},{"./_composeArgs":417,"./_composeArgsRight":418,"./_replaceHolders":493}],484:[function(require,module,exports){
var WeakMap = require('./_WeakMap');

/** Used to store function metadata. */
var metaMap = WeakMap && new WeakMap;

module.exports = metaMap;

},{"./_WeakMap":362}],485:[function(require,module,exports){
var getNative = require('./_getNative');

/* Built-in method references that are verified to be native. */
var nativeCreate = getNative(Object, 'create');

module.exports = nativeCreate;

},{"./_getNative":447}],486:[function(require,module,exports){
var overArg = require('./_overArg');

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeKeys = overArg(Object.keys, Object);

module.exports = nativeKeys;

},{"./_overArg":489}],487:[function(require,module,exports){
var freeGlobal = require('./_freeGlobal');

/** Detect free variable `exports`. */
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;

/** Detect free variable `module`. */
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;

/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;

/** Detect free variable `process` from Node.js. */
var freeProcess = moduleExports && freeGlobal.process;

/** Used to access faster Node.js helpers. */
var nodeUtil = (function() {
  try {
    // Use `util.types` for Node.js 10+.
    var types = freeModule && freeModule.require && freeModule.require('util').types;

    if (types) {
      return types;
    }

    // Legacy `process.binding('util')` for Node.js < 10.
    return freeProcess && freeProcess.binding && freeProcess.binding('util');
  } catch (e) {}
}());

module.exports = nodeUtil;

},{"./_freeGlobal":440}],488:[function(require,module,exports){
/** Used for built-in method references. */
var objectProto = Object.prototype;

/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */
var nativeObjectToString = objectProto.toString;

/**
 * Converts `value` to a string using `Object.prototype.toString`.
 *
 * @private
 * @param {*} value The value to convert.
 * @returns {string} Returns the converted string.
 */
function objectToString(value) {
  return nativeObjectToString.call(value);
}

module.exports = objectToString;

},{}],489:[function(require,module,exports){
/**
 * Creates a unary function that invokes `func` with its argument transformed.
 *
 * @private
 * @param {Function} func The function to wrap.
 * @param {Function} transform The argument transform.
 * @returns {Function} Returns the new function.
 */
function overArg(func, transform) {
  return function(arg) {
    return func(transform(arg));
  };
}

module.exports = overArg;

},{}],490:[function(require,module,exports){
var apply = require('./_apply');

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;

/**
 * A specialized version of `baseRest` which transforms the rest array.
 *
 * @private
 * @param {Function} func The function to apply a rest parameter to.
 * @param {number} [start=func.length-1] The start position of the rest parameter.
 * @param {Function} transform The rest array transform.
 * @returns {Function} Returns the new function.
 */
function overRest(func, start, transform) {
  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
  return function() {
    var args = arguments,
        index = -1,
        length = nativeMax(args.length - start, 0),
        array = Array(length);

    while (++index < length) {
      array[index] = args[start + index];
    }
    index = -1;
    var otherArgs = Array(start + 1);
    while (++index < start) {
      otherArgs[index] = args[index];
    }
    otherArgs[start] = transform(array);
    return apply(func, this, otherArgs);
  };
}

module.exports = overRest;

},{"./_apply":363}],491:[function(require,module,exports){
/** Used to lookup unminified function names. */
var realNames = {};

module.exports = realNames;

},{}],492:[function(require,module,exports){
var copyArray = require('./_copyArray'),
    isIndex = require('./_isIndex');

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;

/**
 * Reorder `array` according to the specified indexes where the element at
 * the first index is assigned as the first element, the element at
 * the second index is assigned as the second element, and so on.
 *
 * @private
 * @param {Array} array The array to reorder.
 * @param {Array} indexes The arranged array indexes.
 * @returns {Array} Returns `array`.
 */
function reorder(array, indexes) {
  var arrLength = array.length,
      length = nativeMin(indexes.length, arrLength),
      oldArray = copyArray(array);

  while (length--) {
    var index = indexes[length];
    array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
  }
  return array;
}

module.exports = reorder;

},{"./_copyArray":419,"./_isIndex":462}],493:[function(require,module,exports){
/** Used as the internal argument placeholder. */
var PLACEHOLDER = '__lodash_placeholder__';

/**
 * Replaces all `placeholder` elements in `array` with an internal placeholder
 * and returns an array of their indexes.
 *
 * @private
 * @param {Array} array The array to modify.
 * @param {*} placeholder The placeholder to replace.
 * @returns {Array} Returns the new array of placeholder indexes.
 */
function replaceHolders(array, placeholder) {
  var index = -1,
      length = array.length,
      resIndex = 0,
      result = [];

  while (++index < length) {
    var value = array[index];
    if (value === placeholder || value === PLACEHOLDER) {
      array[index] = PLACEHOLDER;
      result[resIndex++] = index;
    }
  }
  return result;
}

module.exports = replaceHolders;

},{}],494:[function(require,module,exports){
var freeGlobal = require('./_freeGlobal');

/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();

module.exports = root;

},{"./_freeGlobal":440}],495:[function(require,module,exports){
/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';

/**
 * Adds `value` to the array cache.
 *
 * @private
 * @name add
 * @memberOf SetCache
 * @alias push
 * @param {*} value The value to cache.
 * @returns {Object} Returns the cache instance.
 */
function setCacheAdd(value) {
  this.__data__.set(value, HASH_UNDEFINED);
  return this;
}

module.exports = setCacheAdd;

},{}],496:[function(require,module,exports){
/**
 * Checks if `value` is in the array cache.
 *
 * @private
 * @name has
 * @memberOf SetCache
 * @param {*} value The value to search for.
 * @returns {number} Returns `true` if `value` is found, else `false`.
 */
function setCacheHas(value) {
  return this.__data__.has(value);
}

module.exports = setCacheHas;

},{}],497:[function(require,module,exports){
var baseSetData = require('./_baseSetData'),
    shortOut = require('./_shortOut');

/**
 * Sets metadata for `func`.
 *
 * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
 * period of time, it will trip its breaker and transition to an identity
 * function to avoid garbage collection pauses in V8. See
 * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
 * for more details.
 *
 * @private
 * @param {Function} func The function to associate metadata with.
 * @param {*} data The metadata.
 * @returns {Function} Returns `func`.
 */
var setData = shortOut(baseSetData);

module.exports = setData;

},{"./_baseSetData":406,"./_shortOut":501}],498:[function(require,module,exports){
/**
 * Converts `set` to an array of its values.
 *
 * @private
 * @param {Object} set The set to convert.
 * @returns {Array} Returns the values.
 */
function setToArray(set) {
  var index = -1,
      result = Array(set.size);

  set.forEach(function(value) {
    result[++index] = value;
  });
  return result;
}

module.exports = setToArray;

},{}],499:[function(require,module,exports){
var baseSetToString = require('./_baseSetToString'),
    shortOut = require('./_shortOut');

/**
 * Sets the `toString` method of `func` to return `string`.
 *
 * @private
 * @param {Function} func The function to modify.
 * @param {Function} string The `toString` result.
 * @returns {Function} Returns `func`.
 */
var setToString = shortOut(baseSetToString);

module.exports = setToString;

},{"./_baseSetToString":407,"./_shortOut":501}],500:[function(require,module,exports){
var getWrapDetails = require('./_getWrapDetails'),
    insertWrapDetails = require('./_insertWrapDetails'),
    setToString = require('./_setToString'),
    updateWrapDetails = require('./_updateWrapDetails');

/**
 * Sets the `toString` method of `wrapper` to mimic the source of `reference`
 * with wrapper details in a comment at the top of the source body.
 *
 * @private
 * @param {Function} wrapper The function to modify.
 * @param {Function} reference The reference function.
 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
 * @returns {Function} Returns `wrapper`.
 */
function setWrapToString(wrapper, reference, bitmask) {
  var source = (reference + '');
  return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
}

module.exports = setWrapToString;

},{"./_getWrapDetails":453,"./_insertWrapDetails":460,"./_setToString":499,"./_updateWrapDetails":511}],501:[function(require,module,exports){
/** Used to detect hot functions by number of calls within a span of milliseconds. */
var HOT_COUNT = 800,
    HOT_SPAN = 16;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeNow = Date.now;

/**
 * Creates a function that'll short out and invoke `identity` instead
 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
 * milliseconds.
 *
 * @private
 * @param {Function} func The function to restrict.
 * @returns {Function} Returns the new shortable function.
 */
function shortOut(func) {
  var count = 0,
      lastCalled = 0;

  return function() {
    var stamp = nativeNow(),
        remaining = HOT_SPAN - (stamp - lastCalled);

    lastCalled = stamp;
    if (remaining > 0) {
      if (++count >= HOT_COUNT) {
        return arguments[0];
      }
    } else {
      count = 0;
    }
    return func.apply(undefined, arguments);
  };
}

module.exports = shortOut;

},{}],502:[function(require,module,exports){
var ListCache = require('./_ListCache');

/**
 * Removes all key-value entries from the stack.
 *
 * @private
 * @name clear
 * @memberOf Stack
 */
function stackClear() {
  this.__data__ = new ListCache;
  this.size = 0;
}

module.exports = stackClear;

},{"./_ListCache":352}],503:[function(require,module,exports){
/**
 * Removes `key` and its value from the stack.
 *
 * @private
 * @name delete
 * @memberOf Stack
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */
function stackDelete(key) {
  var data = this.__data__,
      result = data['delete'](key);

  this.size = data.size;
  return result;
}

module.exports = stackDelete;

},{}],504:[function(require,module,exports){
/**
 * Gets the stack value for `key`.
 *
 * @private
 * @name get
 * @memberOf Stack
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */
function stackGet(key) {
  return this.__data__.get(key);
}

module.exports = stackGet;

},{}],505:[function(require,module,exports){
/**
 * Checks if a stack value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf Stack
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */
function stackHas(key) {
  return this.__data__.has(key);
}

module.exports = stackHas;

},{}],506:[function(require,module,exports){
var ListCache = require('./_ListCache'),
    Map = require('./_Map'),
    MapCache = require('./_MapCache');

/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;

/**
 * Sets the stack `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf Stack
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the stack cache instance.
 */
function stackSet(key, value) {
  var data = this.__data__;
  if (data instanceof ListCache) {
    var pairs = data.__data__;
    if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
      pairs.push([key, value]);
      this.size = ++data.size;
      return this;
    }
    data = this.__data__ = new MapCache(pairs);
  }
  data.set(key, value);
  this.size = data.size;
  return this;
}

module.exports = stackSet;

},{"./_ListCache":352,"./_Map":354,"./_MapCache":355}],507:[function(require,module,exports){
/**
 * A specialized version of `_.indexOf` which performs strict equality
 * comparisons of values, i.e. `===`.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} value The value to search for.
 * @param {number} fromIndex The index to search from.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */
function strictIndexOf(array, value, fromIndex) {
  var index = fromIndex - 1,
      length = array.length;

  while (++index < length) {
    if (array[index] === value) {
      return index;
    }
  }
  return -1;
}

module.exports = strictIndexOf;

},{}],508:[function(require,module,exports){
var memoizeCapped = require('./_memoizeCapped');

/** Used to match property names within property paths. */
var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;

/** Used to match backslashes in property paths. */
var reEscapeChar = /\\(\\)?/g;

/**
 * Converts `string` to a property path array.
 *
 * @private
 * @param {string} string The string to convert.
 * @returns {Array} Returns the property path array.
 */
var stringToPath = memoizeCapped(function(string) {
  var result = [];
  if (string.charCodeAt(0) === 46 /* . */) {
    result.push('');
  }
  string.replace(rePropName, function(match, number, quote, subString) {
    result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
  });
  return result;
});

module.exports = stringToPath;

},{"./_memoizeCapped":482}],509:[function(require,module,exports){
var isSymbol = require('./isSymbol');

/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;

/**
 * Converts `value` to a string key if it's not a string or symbol.
 *
 * @private
 * @param {*} value The value to inspect.
 * @returns {string|symbol} Returns the key.
 */
function toKey(value) {
  if (typeof value == 'string' || isSymbol(value)) {
    return value;
  }
  var result = (value + '');
  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}

module.exports = toKey;

},{"./isSymbol":536}],510:[function(require,module,exports){
/** Used for built-in method references. */
var funcProto = Function.prototype;

/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;

/**
 * Converts `func` to its source code.
 *
 * @private
 * @param {Function} func The function to convert.
 * @returns {string} Returns the source code.
 */
function toSource(func) {
  if (func != null) {
    try {
      return funcToString.call(func);
    } catch (e) {}
    try {
      return (func + '');
    } catch (e) {}
  }
  return '';
}

module.exports = toSource;

},{}],511:[function(require,module,exports){
var arrayEach = require('./_arrayEach'),
    arrayIncludes = require('./_arrayIncludes');

/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1,
    WRAP_BIND_KEY_FLAG = 2,
    WRAP_CURRY_FLAG = 8,
    WRAP_CURRY_RIGHT_FLAG = 16,
    WRAP_PARTIAL_FLAG = 32,
    WRAP_PARTIAL_RIGHT_FLAG = 64,
    WRAP_ARY_FLAG = 128,
    WRAP_REARG_FLAG = 256,
    WRAP_FLIP_FLAG = 512;

/** Used to associate wrap methods with their bit flags. */
var wrapFlags = [
  ['ary', WRAP_ARY_FLAG],
  ['bind', WRAP_BIND_FLAG],
  ['bindKey', WRAP_BIND_KEY_FLAG],
  ['curry', WRAP_CURRY_FLAG],
  ['curryRight', WRAP_CURRY_RIGHT_FLAG],
  ['flip', WRAP_FLIP_FLAG],
  ['partial', WRAP_PARTIAL_FLAG],
  ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
  ['rearg', WRAP_REARG_FLAG]
];

/**
 * Updates wrapper `details` based on `bitmask` flags.
 *
 * @private
 * @returns {Array} details The details to modify.
 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
 * @returns {Array} Returns `details`.
 */
function updateWrapDetails(details, bitmask) {
  arrayEach(wrapFlags, function(pair) {
    var value = '_.' + pair[0];
    if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
      details.push(value);
    }
  });
  return details.sort();
}

module.exports = updateWrapDetails;

},{"./_arrayEach":365,"./_arrayIncludes":367}],512:[function(require,module,exports){
var LazyWrapper = require('./_LazyWrapper'),
    LodashWrapper = require('./_LodashWrapper'),
    copyArray = require('./_copyArray');

/**
 * Creates a clone of `wrapper`.
 *
 * @private
 * @param {Object} wrapper The wrapper to clone.
 * @returns {Object} Returns the cloned wrapper.
 */
function wrapperClone(wrapper) {
  if (wrapper instanceof LazyWrapper) {
    return wrapper.clone();
  }
  var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
  result.__actions__ = copyArray(wrapper.__actions__);
  result.__index__  = wrapper.__index__;
  result.__values__ = wrapper.__values__;
  return result;
}

module.exports = wrapperClone;

},{"./_LazyWrapper":351,"./_LodashWrapper":353,"./_copyArray":419}],513:[function(require,module,exports){
var assignValue = require('./_assignValue'),
    copyObject = require('./_copyObject'),
    createAssigner = require('./_createAssigner'),
    isArrayLike = require('./isArrayLike'),
    isPrototype = require('./_isPrototype'),
    keys = require('./keys');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Assigns own enumerable string keyed properties of source objects to the
 * destination object. Source objects are applied from left to right.
 * Subsequent sources overwrite property assignments of previous sources.
 *
 * **Note:** This method mutates `object` and is loosely based on
 * [`Object.assign`](https://mdn.io/Object/assign).
 *
 * @static
 * @memberOf _
 * @since 0.10.0
 * @category Object
 * @param {Object} object The destination object.
 * @param {...Object} [sources] The source objects.
 * @returns {Object} Returns `object`.
 * @see _.assignIn
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 * }
 *
 * function Bar() {
 *   this.c = 3;
 * }
 *
 * Foo.prototype.b = 2;
 * Bar.prototype.d = 4;
 *
 * _.assign({ 'a': 0 }, new Foo, new Bar);
 * // => { 'a': 1, 'c': 3 }
 */
var assign = createAssigner(function(object, source) {
  if (isPrototype(source) || isArrayLike(source)) {
    copyObject(source, keys(source), object);
    return;
  }
  for (var key in source) {
    if (hasOwnProperty.call(source, key)) {
      assignValue(object, key, source[key]);
    }
  }
});

module.exports = assign;

},{"./_assignValue":373,"./_copyObject":420,"./_createAssigner":424,"./_isPrototype":468,"./isArrayLike":528,"./keys":539}],514:[function(require,module,exports){
var baseRest = require('./_baseRest'),
    createWrap = require('./_createWrap'),
    getHolder = require('./_getHolder'),
    replaceHolders = require('./_replaceHolders');

/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1,
    WRAP_PARTIAL_FLAG = 32;

/**
 * Creates a function that invokes `func` with the `this` binding of `thisArg`
 * and `partials` prepended to the arguments it receives.
 *
 * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
 * may be used as a placeholder for partially applied arguments.
 *
 * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
 * property of bound functions.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to bind.
 * @param {*} thisArg The `this` binding of `func`.
 * @param {...*} [partials] The arguments to be partially applied.
 * @returns {Function} Returns the new bound function.
 * @example
 *
 * function greet(greeting, punctuation) {
 *   return greeting + ' ' + this.user + punctuation;
 * }
 *
 * var object = { 'user': 'fred' };
 *
 * var bound = _.bind(greet, object, 'hi');
 * bound('!');
 * // => 'hi fred!'
 *
 * // Bound with placeholders.
 * var bound = _.bind(greet, object, _, '!');
 * bound('hi');
 * // => 'hi fred!'
 */
var bind = baseRest(function(func, thisArg, partials) {
  var bitmask = WRAP_BIND_FLAG;
  if (partials.length) {
    var holders = replaceHolders(partials, getHolder(bind));
    bitmask |= WRAP_PARTIAL_FLAG;
  }
  return createWrap(func, bitmask, thisArg, partials, holders);
});

// Assign default placeholders.
bind.placeholder = {};

module.exports = bind;

},{"./_baseRest":405,"./_createWrap":435,"./_getHolder":444,"./_replaceHolders":493}],515:[function(require,module,exports){
/**
 * Creates a function that returns `value`.
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Util
 * @param {*} value The value to return from the new function.
 * @returns {Function} Returns the new constant function.
 * @example
 *
 * var objects = _.times(2, _.constant({ 'a': 1 }));
 *
 * console.log(objects);
 * // => [{ 'a': 1 }, { 'a': 1 }]
 *
 * console.log(objects[0] === objects[1]);
 * // => true
 */
function constant(value) {
  return function() {
    return value;
  };
}

module.exports = constant;

},{}],516:[function(require,module,exports){
var isObject = require('./isObject'),
    now = require('./now'),
    toNumber = require('./toNumber');

/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
    nativeMin = Math.min;

/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked. The debounced function comes with a `cancel` method to cancel
 * delayed `func` invocations and a `flush` method to immediately invoke them.
 * Provide `options` to indicate whether `func` should be invoked on the
 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
 * with the last arguments provided to the debounced function. Subsequent
 * calls to the debounced function return the result of the last `func`
 * invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the debounced function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.debounce` and `_.throttle`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to debounce.
 * @param {number} [wait=0] The number of milliseconds to delay.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=false]
 *  Specify invoking on the leading edge of the timeout.
 * @param {number} [options.maxWait]
 *  The maximum time `func` is allowed to be delayed before it's invoked.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new debounced function.
 * @example
 *
 * // Avoid costly calculations while the window size is in flux.
 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 *
 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 * jQuery(element).on('click', _.debounce(sendMail, 300, {
 *   'leading': true,
 *   'trailing': false
 * }));
 *
 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
 * var source = new EventSource('/stream');
 * jQuery(source).on('message', debounced);
 *
 * // Cancel the trailing debounced invocation.
 * jQuery(window).on('popstate', debounced.cancel);
 */
function debounce(func, wait, options) {
  var lastArgs,
      lastThis,
      maxWait,
      result,
      timerId,
      lastCallTime,
      lastInvokeTime = 0,
      leading = false,
      maxing = false,
      trailing = true;

  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  wait = toNumber(wait) || 0;
  if (isObject(options)) {
    leading = !!options.leading;
    maxing = 'maxWait' in options;
    maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }

  function invokeFunc(time) {
    var args = lastArgs,
        thisArg = lastThis;

    lastArgs = lastThis = undefined;
    lastInvokeTime = time;
    result = func.apply(thisArg, args);
    return result;
  }

  function leadingEdge(time) {
    // Reset any `maxWait` timer.
    lastInvokeTime = time;
    // Start the timer for the trailing edge.
    timerId = setTimeout(timerExpired, wait);
    // Invoke the leading edge.
    return leading ? invokeFunc(time) : result;
  }

  function remainingWait(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime,
        timeWaiting = wait - timeSinceLastCall;

    return maxing
      ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
      : timeWaiting;
  }

  function shouldInvoke(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime;

    // Either this is the first call, activity has stopped and we're at the
    // trailing edge, the system time has gone backwards and we're treating
    // it as the trailing edge, or we've hit the `maxWait` limit.
    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
      (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
  }

  function timerExpired() {
    var time = now();
    if (shouldInvoke(time)) {
      return trailingEdge(time);
    }
    // Restart the timer.
    timerId = setTimeout(timerExpired, remainingWait(time));
  }

  function trailingEdge(time) {
    timerId = undefined;

    // Only invoke if we have `lastArgs` which means `func` has been
    // debounced at least once.
    if (trailing && lastArgs) {
      return invokeFunc(time);
    }
    lastArgs = lastThis = undefined;
    return result;
  }

  function cancel() {
    if (timerId !== undefined) {
      clearTimeout(timerId);
    }
    lastInvokeTime = 0;
    lastArgs = lastCallTime = lastThis = timerId = undefined;
  }

  function flush() {
    return timerId === undefined ? result : trailingEdge(now());
  }

  function debounced() {
    var time = now(),
        isInvoking = shouldInvoke(time);

    lastArgs = arguments;
    lastThis = this;
    lastCallTime = time;

    if (isInvoking) {
      if (timerId === undefined) {
        return leadingEdge(lastCallTime);
      }
      if (maxing) {
        // Handle invocations in a tight loop.
        clearTimeout(timerId);
        timerId = setTimeout(timerExpired, wait);
        return invokeFunc(lastCallTime);
      }
    }
    if (timerId === undefined) {
      timerId = setTimeout(timerExpired, wait);
    }
    return result;
  }
  debounced.cancel = cancel;
  debounced.flush = flush;
  return debounced;
}

module.exports = debounce;

},{"./isObject":534,"./now":543,"./toNumber":549}],517:[function(require,module,exports){
/**
 * Performs a
 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * comparison between two values to determine if they are equivalent.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
 * @example
 *
 * var object = { 'a': 1 };
 * var other = { 'a': 1 };
 *
 * _.eq(object, object);
 * // => true
 *
 * _.eq(object, other);
 * // => false
 *
 * _.eq('a', 'a');
 * // => true
 *
 * _.eq('a', Object('a'));
 * // => false
 *
 * _.eq(NaN, NaN);
 * // => true
 */
function eq(value, other) {
  return value === other || (value !== value && other !== other);
}

module.exports = eq;

},{}],518:[function(require,module,exports){
var arrayFilter = require('./_arrayFilter'),
    baseFilter = require('./_baseFilter'),
    baseIteratee = require('./_baseIteratee'),
    isArray = require('./isArray');

/**
 * Iterates over elements of `collection`, returning an array of all elements
 * `predicate` returns truthy for. The predicate is invoked with three
 * arguments: (value, index|key, collection).
 *
 * **Note:** Unlike `_.remove`, this method returns a new array.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} [predicate=_.identity] The function invoked per iteration.
 * @returns {Array} Returns the new filtered array.
 * @see _.reject
 * @example
 *
 * var users = [
 *   { 'user': 'barney', 'age': 36, 'active': true },
 *   { 'user': 'fred',   'age': 40, 'active': false }
 * ];
 *
 * _.filter(users, function(o) { return !o.active; });
 * // => objects for ['fred']
 *
 * // The `_.matches` iteratee shorthand.
 * _.filter(users, { 'age': 36, 'active': true });
 * // => objects for ['barney']
 *
 * // The `_.matchesProperty` iteratee shorthand.
 * _.filter(users, ['active', false]);
 * // => objects for ['fred']
 *
 * // The `_.property` iteratee shorthand.
 * _.filter(users, 'active');
 * // => objects for ['barney']
 *
 * // Combining several predicates using `_.overEvery` or `_.overSome`.
 * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
 * // => objects for ['fred', 'barney']
 */
function filter(collection, predicate) {
  var func = isArray(collection) ? arrayFilter : baseFilter;
  return func(collection, baseIteratee(predicate, 3));
}

module.exports = filter;

},{"./_arrayFilter":366,"./_baseFilter":380,"./_baseIteratee":397,"./isArray":527}],519:[function(require,module,exports){
var createFind = require('./_createFind'),
    findIndex = require('./findIndex');

/**
 * Iterates over elements of `collection`, returning the first element
 * `predicate` returns truthy for. The predicate is invoked with three
 * arguments: (value, index|key, collection).
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object} collection The collection to inspect.
 * @param {Function} [predicate=_.identity] The function invoked per iteration.
 * @param {number} [fromIndex=0] The index to search from.
 * @returns {*} Returns the matched element, else `undefined`.
 * @example
 *
 * var users = [
 *   { 'user': 'barney',  'age': 36, 'active': true },
 *   { 'user': 'fred',    'age': 40, 'active': false },
 *   { 'user': 'pebbles', 'age': 1,  'active': true }
 * ];
 *
 * _.find(users, function(o) { return o.age < 40; });
 * // => object for 'barney'
 *
 * // The `_.matches` iteratee shorthand.
 * _.find(users, { 'age': 1, 'active': true });
 * // => object for 'pebbles'
 *
 * // The `_.matchesProperty` iteratee shorthand.
 * _.find(users, ['active', false]);
 * // => object for 'fred'
 *
 * // The `_.property` iteratee shorthand.
 * _.find(users, 'active');
 * // => object for 'barney'
 */
var find = createFind(findIndex);

module.exports = find;

},{"./_createFind":430,"./findIndex":520}],520:[function(require,module,exports){
var baseFindIndex = require('./_baseFindIndex'),
    baseIteratee = require('./_baseIteratee'),
    toInteger = require('./toInteger');

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;

/**
 * This method is like `_.find` except that it returns the index of the first
 * element `predicate` returns truthy for instead of the element itself.
 *
 * @static
 * @memberOf _
 * @since 1.1.0
 * @category Array
 * @param {Array} array The array to inspect.
 * @param {Function} [predicate=_.identity] The function invoked per iteration.
 * @param {number} [fromIndex=0] The index to search from.
 * @returns {number} Returns the index of the found element, else `-1`.
 * @example
 *
 * var users = [
 *   { 'user': 'barney',  'active': false },
 *   { 'user': 'fred',    'active': false },
 *   { 'user': 'pebbles', 'active': true }
 * ];
 *
 * _.findIndex(users, function(o) { return o.user == 'barney'; });
 * // => 0
 *
 * // The `_.matches` iteratee shorthand.
 * _.findIndex(users, { 'user': 'fred', 'active': false });
 * // => 1
 *
 * // The `_.matchesProperty` iteratee shorthand.
 * _.findIndex(users, ['active', false]);
 * // => 0
 *
 * // The `_.property` iteratee shorthand.
 * _.findIndex(users, 'active');
 * // => 2
 */
function findIndex(array, predicate, fromIndex) {
  var length = array == null ? 0 : array.length;
  if (!length) {
    return -1;
  }
  var index = fromIndex == null ? 0 : toInteger(fromIndex);
  if (index < 0) {
    index = nativeMax(length + index, 0);
  }
  return baseFindIndex(array, baseIteratee(predicate, 3), index);
}

module.exports = findIndex;

},{"./_baseFindIndex":381,"./_baseIteratee":397,"./toInteger":548}],521:[function(require,module,exports){
var baseFlatten = require('./_baseFlatten');

/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;

/**
 * Recursively flattens `array`.
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Array
 * @param {Array} array The array to flatten.
 * @returns {Array} Returns the new flattened array.
 * @example
 *
 * _.flattenDeep([1, [2, [3, [4]], 5]]);
 * // => [1, 2, 3, 4, 5]
 */
function flattenDeep(array) {
  var length = array == null ? 0 : array.length;
  return length ? baseFlatten(array, INFINITY) : [];
}

module.exports = flattenDeep;

},{"./_baseFlatten":382}],522:[function(require,module,exports){
var arrayEach = require('./_arrayEach'),
    baseEach = require('./_baseEach'),
    castFunction = require('./_castFunction'),
    isArray = require('./isArray');

/**
 * Iterates over elements of `collection` and invokes `iteratee` for each element.
 * The iteratee is invoked with three arguments: (value, index|key, collection).
 * Iteratee functions may exit iteration early by explicitly returning `false`.
 *
 * **Note:** As with other "Collections" methods, objects with a "length"
 * property are iterated like arrays. To avoid this behavior use `_.forIn`
 * or `_.forOwn` for object iteration.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @alias each
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 * @returns {Array|Object} Returns `collection`.
 * @see _.forEachRight
 * @example
 *
 * _.forEach([1, 2], function(value) {
 *   console.log(value);
 * });
 * // => Logs `1` then `2`.
 *
 * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
 *   console.log(key);
 * });
 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
 */
function forEach(collection, iteratee) {
  var func = isArray(collection) ? arrayEach : baseEach;
  return func(collection, castFunction(iteratee));
}

module.exports = forEach;

},{"./_arrayEach":365,"./_baseEach":379,"./_castFunction":415,"./isArray":527}],523:[function(require,module,exports){
var baseGet = require('./_baseGet');

/**
 * Gets the value at `path` of `object`. If the resolved value is
 * `undefined`, the `defaultValue` is returned in its place.
 *
 * @static
 * @memberOf _
 * @since 3.7.0
 * @category Object
 * @param {Object} object The object to query.
 * @param {Array|string} path The path of the property to get.
 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
 * @returns {*} Returns the resolved value.
 * @example
 *
 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
 *
 * _.get(object, 'a[0].b.c');
 * // => 3
 *
 * _.get(object, ['a', '0', 'b', 'c']);
 * // => 3
 *
 * _.get(object, 'a.b.c', 'default');
 * // => 'default'
 */
function get(object, path, defaultValue) {
  var result = object == null ? undefined : baseGet(object, path);
  return result === undefined ? defaultValue : result;
}

module.exports = get;

},{"./_baseGet":385}],524:[function(require,module,exports){
var baseHasIn = require('./_baseHasIn'),
    hasPath = require('./_hasPath');

/**
 * Checks if `path` is a direct or inherited property of `object`.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Object
 * @param {Object} object The object to query.
 * @param {Array|string} path The path to check.
 * @returns {boolean} Returns `true` if `path` exists, else `false`.
 * @example
 *
 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
 *
 * _.hasIn(object, 'a');
 * // => true
 *
 * _.hasIn(object, 'a.b');
 * // => true
 *
 * _.hasIn(object, ['a', 'b']);
 * // => true
 *
 * _.hasIn(object, 'b');
 * // => false
 */
function hasIn(object, path) {
  return object != null && hasPath(object, path, baseHasIn);
}

module.exports = hasIn;

},{"./_baseHasIn":388,"./_hasPath":454}],525:[function(require,module,exports){
/**
 * This method returns the first argument it receives.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Util
 * @param {*} value Any value.
 * @returns {*} Returns `value`.
 * @example
 *
 * var object = { 'a': 1 };
 *
 * console.log(_.identity(object) === object);
 * // => true
 */
function identity(value) {
  return value;
}

module.exports = identity;

},{}],526:[function(require,module,exports){
var baseIsArguments = require('./_baseIsArguments'),
    isObjectLike = require('./isObjectLike');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/** Built-in value references. */
var propertyIsEnumerable = objectProto.propertyIsEnumerable;

/**
 * Checks if `value` is likely an `arguments` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
 *  else `false`.
 * @example
 *
 * _.isArguments(function() { return arguments; }());
 * // => true
 *
 * _.isArguments([1, 2, 3]);
 * // => false
 */
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
    !propertyIsEnumerable.call(value, 'callee');
};

module.exports = isArguments;

},{"./_baseIsArguments":390,"./isObjectLike":535}],527:[function(require,module,exports){
/**
 * Checks if `value` is classified as an `Array` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
 * @example
 *
 * _.isArray([1, 2, 3]);
 * // => true
 *
 * _.isArray(document.body.children);
 * // => false
 *
 * _.isArray('abc');
 * // => false
 *
 * _.isArray(_.noop);
 * // => false
 */
var isArray = Array.isArray;

module.exports = isArray;

},{}],528:[function(require,module,exports){
var isFunction = require('./isFunction'),
    isLength = require('./isLength');

/**
 * Checks if `value` is array-like. A value is considered array-like if it's
 * not a function and has a `value.length` that's an integer greater than or
 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
 * @example
 *
 * _.isArrayLike([1, 2, 3]);
 * // => true
 *
 * _.isArrayLike(document.body.children);
 * // => true
 *
 * _.isArrayLike('abc');
 * // => true
 *
 * _.isArrayLike(_.noop);
 * // => false
 */
function isArrayLike(value) {
  return value != null && isLength(value.length) && !isFunction(value);
}

module.exports = isArrayLike;

},{"./isFunction":532,"./isLength":533}],529:[function(require,module,exports){
var isArrayLike = require('./isArrayLike'),
    isObjectLike = require('./isObjectLike');

/**
 * This method is like `_.isArrayLike` except that it also checks if `value`
 * is an object.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an array-like object,
 *  else `false`.
 * @example
 *
 * _.isArrayLikeObject([1, 2, 3]);
 * // => true
 *
 * _.isArrayLikeObject(document.body.children);
 * // => true
 *
 * _.isArrayLikeObject('abc');
 * // => false
 *
 * _.isArrayLikeObject(_.noop);
 * // => false
 */
function isArrayLikeObject(value) {
  return isObjectLike(value) && isArrayLike(value);
}

module.exports = isArrayLikeObject;

},{"./isArrayLike":528,"./isObjectLike":535}],530:[function(require,module,exports){
var root = require('./_root'),
    stubFalse = require('./stubFalse');

/** Detect free variable `exports`. */
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;

/** Detect free variable `module`. */
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;

/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;

/** Built-in value references. */
var Buffer = moduleExports ? root.Buffer : undefined;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;

/**
 * Checks if `value` is a buffer.
 *
 * @static
 * @memberOf _
 * @since 4.3.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
 * @example
 *
 * _.isBuffer(new Buffer(2));
 * // => true
 *
 * _.isBuffer(new Uint8Array(2));
 * // => false
 */
var isBuffer = nativeIsBuffer || stubFalse;

module.exports = isBuffer;

},{"./_root":494,"./stubFalse":546}],531:[function(require,module,exports){
var baseKeys = require('./_baseKeys'),
    getTag = require('./_getTag'),
    isArguments = require('./isArguments'),
    isArray = require('./isArray'),
    isArrayLike = require('./isArrayLike'),
    isBuffer = require('./isBuffer'),
    isPrototype = require('./_isPrototype'),
    isTypedArray = require('./isTypedArray');

/** `Object#toString` result references. */
var mapTag = '[object Map]',
    setTag = '[object Set]';

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Checks if `value` is an empty object, collection, map, or set.
 *
 * Objects are considered empty if they have no own enumerable string keyed
 * properties.
 *
 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
 * jQuery-like collections are considered empty if they have a `length` of `0`.
 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
 * @example
 *
 * _.isEmpty(null);
 * // => true
 *
 * _.isEmpty(true);
 * // => true
 *
 * _.isEmpty(1);
 * // => true
 *
 * _.isEmpty([1, 2, 3]);
 * // => false
 *
 * _.isEmpty({ 'a': 1 });
 * // => false
 */
function isEmpty(value) {
  if (value == null) {
    return true;
  }
  if (isArrayLike(value) &&
      (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
        isBuffer(value) || isTypedArray(value) || isArguments(value))) {
    return !value.length;
  }
  var tag = getTag(value);
  if (tag == mapTag || tag == setTag) {
    return !value.size;
  }
  if (isPrototype(value)) {
    return !baseKeys(value).length;
  }
  for (var key in value) {
    if (hasOwnProperty.call(value, key)) {
      return false;
    }
  }
  return true;
}

module.exports = isEmpty;

},{"./_baseKeys":398,"./_getTag":451,"./_isPrototype":468,"./isArguments":526,"./isArray":527,"./isArrayLike":528,"./isBuffer":530,"./isTypedArray":537}],532:[function(require,module,exports){
var baseGetTag = require('./_baseGetTag'),
    isObject = require('./isObject');

/** `Object#toString` result references. */
var asyncTag = '[object AsyncFunction]',
    funcTag = '[object Function]',
    genTag = '[object GeneratorFunction]',
    proxyTag = '[object Proxy]';

/**
 * Checks if `value` is classified as a `Function` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
 * @example
 *
 * _.isFunction(_);
 * // => true
 *
 * _.isFunction(/abc/);
 * // => false
 */
function isFunction(value) {
  if (!isObject(value)) {
    return false;
  }
  // The use of `Object#toString` avoids issues with the `typeof` operator
  // in Safari 9 which returns 'object' for typed arrays and other constructors.
  var tag = baseGetTag(value);
  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
}

module.exports = isFunction;

},{"./_baseGetTag":387,"./isObject":534}],533:[function(require,module,exports){
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;

/**
 * Checks if `value` is a valid array-like length.
 *
 * **Note:** This method is loosely based on
 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
 * @example
 *
 * _.isLength(3);
 * // => true
 *
 * _.isLength(Number.MIN_VALUE);
 * // => false
 *
 * _.isLength(Infinity);
 * // => false
 *
 * _.isLength('3');
 * // => false
 */
function isLength(value) {
  return typeof value == 'number' &&
    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}

module.exports = isLength;

},{}],534:[function(require,module,exports){
/**
 * Checks if `value` is the
 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 * @example
 *
 * _.isObject({});
 * // => true
 *
 * _.isObject([1, 2, 3]);
 * // => true
 *
 * _.isObject(_.noop);
 * // => true
 *
 * _.isObject(null);
 * // => false
 */
function isObject(value) {
  var type = typeof value;
  return value != null && (type == 'object' || type == 'function');
}

module.exports = isObject;

},{}],535:[function(require,module,exports){
/**
 * Checks if `value` is object-like. A value is object-like if it's not `null`
 * and has a `typeof` result of "object".
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 * @example
 *
 * _.isObjectLike({});
 * // => true
 *
 * _.isObjectLike([1, 2, 3]);
 * // => true
 *
 * _.isObjectLike(_.noop);
 * // => false
 *
 * _.isObjectLike(null);
 * // => false
 */
function isObjectLike(value) {
  return value != null && typeof value == 'object';
}

module.exports = isObjectLike;

},{}],536:[function(require,module,exports){
var baseGetTag = require('./_baseGetTag'),
    isObjectLike = require('./isObjectLike');

/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';

/**
 * Checks if `value` is classified as a `Symbol` primitive or object.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
 * @example
 *
 * _.isSymbol(Symbol.iterator);
 * // => true
 *
 * _.isSymbol('abc');
 * // => false
 */
function isSymbol(value) {
  return typeof value == 'symbol' ||
    (isObjectLike(value) && baseGetTag(value) == symbolTag);
}

module.exports = isSymbol;

},{"./_baseGetTag":387,"./isObjectLike":535}],537:[function(require,module,exports){
var baseIsTypedArray = require('./_baseIsTypedArray'),
    baseUnary = require('./_baseUnary'),
    nodeUtil = require('./_nodeUtil');

/* Node.js helper references. */
var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;

/**
 * Checks if `value` is classified as a typed array.
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
 * @example
 *
 * _.isTypedArray(new Uint8Array);
 * // => true
 *
 * _.isTypedArray([]);
 * // => false
 */
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;

module.exports = isTypedArray;

},{"./_baseIsTypedArray":396,"./_baseUnary":410,"./_nodeUtil":487}],538:[function(require,module,exports){
var baseAssignValue = require('./_baseAssignValue'),
    createAggregator = require('./_createAggregator');

/**
 * Creates an object composed of keys generated from the results of running
 * each element of `collection` thru `iteratee`. The corresponding value of
 * each key is the last element responsible for generating the key. The
 * iteratee is invoked with one argument: (value).
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
 * @returns {Object} Returns the composed aggregate object.
 * @example
 *
 * var array = [
 *   { 'dir': 'left', 'code': 97 },
 *   { 'dir': 'right', 'code': 100 }
 * ];
 *
 * _.keyBy(array, function(o) {
 *   return String.fromCharCode(o.code);
 * });
 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
 *
 * _.keyBy(array, 'dir');
 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
 */
var keyBy = createAggregator(function(result, value, key) {
  baseAssignValue(result, key, value);
});

module.exports = keyBy;

},{"./_baseAssignValue":376,"./_createAggregator":423}],539:[function(require,module,exports){
var arrayLikeKeys = require('./_arrayLikeKeys'),
    baseKeys = require('./_baseKeys'),
    isArrayLike = require('./isArrayLike');

/**
 * Creates an array of the own enumerable property names of `object`.
 *
 * **Note:** Non-object values are coerced to objects. See the
 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
 * for more details.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.keys(new Foo);
 * // => ['a', 'b'] (iteration order is not guaranteed)
 *
 * _.keys('hi');
 * // => ['0', '1']
 */
function keys(object) {
  return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
}

module.exports = keys;

},{"./_arrayLikeKeys":369,"./_baseKeys":398,"./isArrayLike":528}],540:[function(require,module,exports){
var arrayMap = require('./_arrayMap'),
    baseIteratee = require('./_baseIteratee'),
    baseMap = require('./_baseMap'),
    isArray = require('./isArray');

/**
 * Creates an array of values by running each element in `collection` thru
 * `iteratee`. The iteratee is invoked with three arguments:
 * (value, index|key, collection).
 *
 * Many lodash methods are guarded to work as iteratees for methods like
 * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
 *
 * The guarded methods are:
 * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
 * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
 * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
 * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 * @returns {Array} Returns the new mapped array.
 * @example
 *
 * function square(n) {
 *   return n * n;
 * }
 *
 * _.map([4, 8], square);
 * // => [16, 64]
 *
 * _.map({ 'a': 4, 'b': 8 }, square);
 * // => [16, 64] (iteration order is not guaranteed)
 *
 * var users = [
 *   { 'user': 'barney' },
 *   { 'user': 'fred' }
 * ];
 *
 * // The `_.property` iteratee shorthand.
 * _.map(users, 'user');
 * // => ['barney', 'fred']
 */
function map(collection, iteratee) {
  var func = isArray(collection) ? arrayMap : baseMap;
  return func(collection, baseIteratee(iteratee, 3));
}

module.exports = map;

},{"./_arrayMap":370,"./_baseIteratee":397,"./_baseMap":400,"./isArray":527}],541:[function(require,module,exports){
var MapCache = require('./_MapCache');

/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';

/**
 * Creates a function that memoizes the result of `func`. If `resolver` is
 * provided, it determines the cache key for storing the result based on the
 * arguments provided to the memoized function. By default, the first argument
 * provided to the memoized function is used as the map cache key. The `func`
 * is invoked with the `this` binding of the memoized function.
 *
 * **Note:** The cache is exposed as the `cache` property on the memoized
 * function. Its creation may be customized by replacing the `_.memoize.Cache`
 * constructor with one whose instances implement the
 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to have its output memoized.
 * @param {Function} [resolver] The function to resolve the cache key.
 * @returns {Function} Returns the new memoized function.
 * @example
 *
 * var object = { 'a': 1, 'b': 2 };
 * var other = { 'c': 3, 'd': 4 };
 *
 * var values = _.memoize(_.values);
 * values(object);
 * // => [1, 2]
 *
 * values(other);
 * // => [3, 4]
 *
 * object.a = 2;
 * values(object);
 * // => [1, 2]
 *
 * // Modify the result cache.
 * values.cache.set(object, ['a', 'b']);
 * values(object);
 * // => ['a', 'b']
 *
 * // Replace `_.memoize.Cache`.
 * _.memoize.Cache = WeakMap;
 */
function memoize(func, resolver) {
  if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  var memoized = function() {
    var args = arguments,
        key = resolver ? resolver.apply(this, args) : args[0],
        cache = memoized.cache;

    if (cache.has(key)) {
      return cache.get(key);
    }
    var result = func.apply(this, args);
    memoized.cache = cache.set(key, result) || cache;
    return result;
  };
  memoized.cache = new (memoize.Cache || MapCache);
  return memoized;
}

// Expose `MapCache`.
memoize.Cache = MapCache;

module.exports = memoize;

},{"./_MapCache":355}],542:[function(require,module,exports){
/**
 * This method returns `undefined`.
 *
 * @static
 * @memberOf _
 * @since 2.3.0
 * @category Util
 * @example
 *
 * _.times(2, _.noop);
 * // => [undefined, undefined]
 */
function noop() {
  // No operation performed.
}

module.exports = noop;

},{}],543:[function(require,module,exports){
var root = require('./_root');

/**
 * Gets the timestamp of the number of milliseconds that have elapsed since
 * the Unix epoch (1 January 1970 00:00:00 UTC).
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Date
 * @returns {number} Returns the timestamp.
 * @example
 *
 * _.defer(function(stamp) {
 *   console.log(_.now() - stamp);
 * }, _.now());
 * // => Logs the number of milliseconds it took for the deferred invocation.
 */
var now = function() {
  return root.Date.now();
};

module.exports = now;

},{"./_root":494}],544:[function(require,module,exports){
var baseProperty = require('./_baseProperty'),
    basePropertyDeep = require('./_basePropertyDeep'),
    isKey = require('./_isKey'),
    toKey = require('./_toKey');

/**
 * Creates a function that returns the value at `path` of a given object.
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Util
 * @param {Array|string} path The path of the property to get.
 * @returns {Function} Returns the new accessor function.
 * @example
 *
 * var objects = [
 *   { 'a': { 'b': 2 } },
 *   { 'a': { 'b': 1 } }
 * ];
 *
 * _.map(objects, _.property('a.b'));
 * // => [2, 1]
 *
 * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
 * // => [1, 2]
 */
function property(path) {
  return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
}

module.exports = property;

},{"./_baseProperty":403,"./_basePropertyDeep":404,"./_isKey":464,"./_toKey":509}],545:[function(require,module,exports){
/**
 * This method returns a new empty array.
 *
 * @static
 * @memberOf _
 * @since 4.13.0
 * @category Util
 * @returns {Array} Returns the new empty array.
 * @example
 *
 * var arrays = _.times(2, _.stubArray);
 *
 * console.log(arrays);
 * // => [[], []]
 *
 * console.log(arrays[0] === arrays[1]);
 * // => false
 */
function stubArray() {
  return [];
}

module.exports = stubArray;

},{}],546:[function(require,module,exports){
/**
 * This method returns `false`.
 *
 * @static
 * @memberOf _
 * @since 4.13.0
 * @category Util
 * @returns {boolean} Returns `false`.
 * @example
 *
 * _.times(2, _.stubFalse);
 * // => [false, false]
 */
function stubFalse() {
  return false;
}

module.exports = stubFalse;

},{}],547:[function(require,module,exports){
var toNumber = require('./toNumber');

/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0,
    MAX_INTEGER = 1.7976931348623157e+308;

/**
 * Converts `value` to a finite number.
 *
 * @static
 * @memberOf _
 * @since 4.12.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {number} Returns the converted number.
 * @example
 *
 * _.toFinite(3.2);
 * // => 3.2
 *
 * _.toFinite(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toFinite(Infinity);
 * // => 1.7976931348623157e+308
 *
 * _.toFinite('3.2');
 * // => 3.2
 */
function toFinite(value) {
  if (!value) {
    return value === 0 ? value : 0;
  }
  value = toNumber(value);
  if (value === INFINITY || value === -INFINITY) {
    var sign = (value < 0 ? -1 : 1);
    return sign * MAX_INTEGER;
  }
  return value === value ? value : 0;
}

module.exports = toFinite;

},{"./toNumber":549}],548:[function(require,module,exports){
var toFinite = require('./toFinite');

/**
 * Converts `value` to an integer.
 *
 * **Note:** This method is loosely based on
 * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {number} Returns the converted integer.
 * @example
 *
 * _.toInteger(3.2);
 * // => 3
 *
 * _.toInteger(Number.MIN_VALUE);
 * // => 0
 *
 * _.toInteger(Infinity);
 * // => 1.7976931348623157e+308
 *
 * _.toInteger('3.2');
 * // => 3
 */
function toInteger(value) {
  var result = toFinite(value),
      remainder = result % 1;

  return result === result ? (remainder ? result - remainder : result) : 0;
}

module.exports = toInteger;

},{"./toFinite":547}],549:[function(require,module,exports){
var isObject = require('./isObject'),
    isSymbol = require('./isSymbol');

/** Used as references for various `Number` constants. */
var NAN = 0 / 0;

/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;

/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;

/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;

/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;

/**
 * Converts `value` to a number.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to process.
 * @returns {number} Returns the number.
 * @example
 *
 * _.toNumber(3.2);
 * // => 3.2
 *
 * _.toNumber(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toNumber(Infinity);
 * // => Infinity
 *
 * _.toNumber('3.2');
 * // => 3.2
 */
function toNumber(value) {
  if (typeof value == 'number') {
    return value;
  }
  if (isSymbol(value)) {
    return NAN;
  }
  if (isObject(value)) {
    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
    value = isObject(other) ? (other + '') : other;
  }
  if (typeof value != 'string') {
    return value === 0 ? value : +value;
  }
  value = value.replace(reTrim, '');
  var isBinary = reIsBinary.test(value);
  return (isBinary || reIsOctal.test(value))
    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
    : (reIsBadHex.test(value) ? NAN : +value);
}

module.exports = toNumber;

},{"./isObject":534,"./isSymbol":536}],550:[function(require,module,exports){
var baseToString = require('./_baseToString');

/**
 * Converts `value` to a string. An empty string is returned for `null`
 * and `undefined` values. The sign of `-0` is preserved.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {string} Returns the converted string.
 * @example
 *
 * _.toString(null);
 * // => ''
 *
 * _.toString(-0);
 * // => '-0'
 *
 * _.toString([1, 2, 3]);
 * // => '1,2,3'
 */
function toString(value) {
  return value == null ? '' : baseToString(value);
}

module.exports = toString;

},{"./_baseToString":409}],551:[function(require,module,exports){
var arrayEach = require('./_arrayEach'),
    baseCreate = require('./_baseCreate'),
    baseForOwn = require('./_baseForOwn'),
    baseIteratee = require('./_baseIteratee'),
    getPrototype = require('./_getPrototype'),
    isArray = require('./isArray'),
    isBuffer = require('./isBuffer'),
    isFunction = require('./isFunction'),
    isObject = require('./isObject'),
    isTypedArray = require('./isTypedArray');

/**
 * An alternative to `_.reduce`; this method transforms `object` to a new
 * `accumulator` object which is the result of running each of its own
 * enumerable string keyed properties thru `iteratee`, with each invocation
 * potentially mutating the `accumulator` object. If `accumulator` is not
 * provided, a new object with the same `[[Prototype]]` will be used. The
 * iteratee is invoked with four arguments: (accumulator, value, key, object).
 * Iteratee functions may exit iteration early by explicitly returning `false`.
 *
 * @static
 * @memberOf _
 * @since 1.3.0
 * @category Object
 * @param {Object} object The object to iterate over.
 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 * @param {*} [accumulator] The custom accumulator value.
 * @returns {*} Returns the accumulated value.
 * @example
 *
 * _.transform([2, 3, 4], function(result, n) {
 *   result.push(n *= n);
 *   return n % 2 == 0;
 * }, []);
 * // => [4, 9]
 *
 * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
 *   (result[value] || (result[value] = [])).push(key);
 * }, {});
 * // => { '1': ['a', 'c'], '2': ['b'] }
 */
function transform(object, iteratee, accumulator) {
  var isArr = isArray(object),
      isArrLike = isArr || isBuffer(object) || isTypedArray(object);

  iteratee = baseIteratee(iteratee, 4);
  if (accumulator == null) {
    var Ctor = object && object.constructor;
    if (isArrLike) {
      accumulator = isArr ? new Ctor : [];
    }
    else if (isObject(object)) {
      accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
    }
    else {
      accumulator = {};
    }
  }
  (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
    return iteratee(accumulator, value, index, object);
  });
  return accumulator;
}

module.exports = transform;

},{"./_arrayEach":365,"./_baseCreate":377,"./_baseForOwn":384,"./_baseIteratee":397,"./_getPrototype":448,"./isArray":527,"./isBuffer":530,"./isFunction":532,"./isObject":534,"./isTypedArray":537}],552:[function(require,module,exports){
var baseValues = require('./_baseValues'),
    keys = require('./keys');

/**
 * Creates an array of the own enumerable string keyed property values of `object`.
 *
 * **Note:** Non-object values are coerced to objects.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property values.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.values(new Foo);
 * // => [1, 2] (iteration order is not guaranteed)
 *
 * _.values('hi');
 * // => ['h', 'i']
 */
function values(object) {
  return object == null ? [] : baseValues(object, keys(object));
}

module.exports = values;

},{"./_baseValues":412,"./keys":539}],553:[function(require,module,exports){
var LazyWrapper = require('./_LazyWrapper'),
    LodashWrapper = require('./_LodashWrapper'),
    baseLodash = require('./_baseLodash'),
    isArray = require('./isArray'),
    isObjectLike = require('./isObjectLike'),
    wrapperClone = require('./_wrapperClone');

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Creates a `lodash` object which wraps `value` to enable implicit method
 * chain sequences. Methods that operate on and return arrays, collections,
 * and functions can be chained together. Methods that retrieve a single value
 * or may return a primitive value will automatically end the chain sequence
 * and return the unwrapped value. Otherwise, the value must be unwrapped
 * with `_#value`.
 *
 * Explicit chain sequences, which must be unwrapped with `_#value`, may be
 * enabled using `_.chain`.
 *
 * The execution of chained methods is lazy, that is, it's deferred until
 * `_#value` is implicitly or explicitly called.
 *
 * Lazy evaluation allows several methods to support shortcut fusion.
 * Shortcut fusion is an optimization to merge iteratee calls; this avoids
 * the creation of intermediate arrays and can greatly reduce the number of
 * iteratee executions. Sections of a chain sequence qualify for shortcut
 * fusion if the section is applied to an array and iteratees accept only
 * one argument. The heuristic for whether a section qualifies for shortcut
 * fusion is subject to change.
 *
 * Chaining is supported in custom builds as long as the `_#value` method is
 * directly or indirectly included in the build.
 *
 * In addition to lodash methods, wrappers have `Array` and `String` methods.
 *
 * The wrapper `Array` methods are:
 * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
 *
 * The wrapper `String` methods are:
 * `replace` and `split`
 *
 * The wrapper methods that support shortcut fusion are:
 * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
 * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
 * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
 *
 * The chainable wrapper methods are:
 * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
 * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
 * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
 * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
 * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
 * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
 * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
 * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
 * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
 * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
 * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
 * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
 * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
 * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
 * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
 * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
 * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
 * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
 * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
 * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
 * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
 * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
 * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
 * `zipObject`, `zipObjectDeep`, and `zipWith`
 *
 * The wrapper methods that are **not** chainable by default are:
 * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
 * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
 * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
 * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
 * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
 * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
 * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
 * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
 * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
 * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
 * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
 * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
 * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
 * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
 * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
 * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
 * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
 * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
 * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
 * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
 * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
 * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
 * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
 * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
 * `upperFirst`, `value`, and `words`
 *
 * @name _
 * @constructor
 * @category Seq
 * @param {*} value The value to wrap in a `lodash` instance.
 * @returns {Object} Returns the new `lodash` wrapper instance.
 * @example
 *
 * function square(n) {
 *   return n * n;
 * }
 *
 * var wrapped = _([1, 2, 3]);
 *
 * // Returns an unwrapped value.
 * wrapped.reduce(_.add);
 * // => 6
 *
 * // Returns a wrapped value.
 * var squares = wrapped.map(square);
 *
 * _.isArray(squares);
 * // => false
 *
 * _.isArray(squares.value());
 * // => true
 */
function lodash(value) {
  if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
    if (value instanceof LodashWrapper) {
      return value;
    }
    if (hasOwnProperty.call(value, '__wrapped__')) {
      return wrapperClone(value);
    }
  }
  return new LodashWrapper(value);
}

// Ensure wrappers are instances of `baseLodash`.
lodash.prototype = baseLodash.prototype;
lodash.prototype.constructor = lodash;

module.exports = lodash;

},{"./_LazyWrapper":351,"./_LodashWrapper":353,"./_baseLodash":399,"./_wrapperClone":512,"./isArray":527,"./isObjectLike":535}],554:[function(require,module,exports){
var arrayFilter = require('./_arrayFilter'),
    baseRest = require('./_baseRest'),
    baseXor = require('./_baseXor'),
    isArrayLikeObject = require('./isArrayLikeObject');

/**
 * Creates an array of unique values that is the
 * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
 * of the given arrays. The order of result values is determined by the order
 * they occur in the arrays.
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Array
 * @param {...Array} [arrays] The arrays to inspect.
 * @returns {Array} Returns the new array of filtered values.
 * @see _.difference, _.without
 * @example
 *
 * _.xor([2, 1], [2, 3]);
 * // => [1, 3]
 */
var xor = baseRest(function(arrays) {
  return baseXor(arrayFilter(arrays, isArrayLikeObject));
});

module.exports = xor;

},{"./_arrayFilter":366,"./_baseRest":405,"./_baseXor":413,"./isArrayLikeObject":529}],555:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.flatten = flatten;
exports.find = find;
exports.findIndex = findIndex;
exports.filter = filter;
exports.forEach = forEach;
exports.without = without;
exports.reduce = reduce;
exports.every = every;
exports.some = some;
exports.map = map;
exports.keys = keys;
exports.size = size;
exports.values = values;
exports.groupBy = groupBy;
exports.uniqueBy = uniqueBy;
exports.sortBy = sortBy;
exports.matchPattern = matchPattern;
exports.debounce = debounce;
exports.throttle = throttle;
exports.bind = bind;
exports.isUndefined = isUndefined;
exports.isDefined = isDefined;
exports.isNil = isNil;
exports.isArray = isArray;
exports.isObject = isObject;
exports.isNumber = isNumber;
exports.isFunction = isFunction;
exports.isString = isString;
exports.ensureArray = ensureArray;
exports.has = has;
exports.assign = assign;
exports.pick = pick;
exports.omit = omit;
exports.merge = merge;
exports.unionBy = void 0;

/**
 * Flatten array, one level deep.
 *
 * @param {Array<?>} arr
 *
 * @return {Array<?>}
 */
function flatten(arr) {
  return Array.prototype.concat.apply([], arr);
}

var nativeToString = Object.prototype.toString;
var nativeHasOwnProperty = Object.prototype.hasOwnProperty;

function isUndefined(obj) {
  return obj === undefined;
}

function isDefined(obj) {
  return obj !== undefined;
}

function isNil(obj) {
  return obj == null;
}

function isArray(obj) {
  return nativeToString.call(obj) === '[object Array]';
}

function isObject(obj) {
  return nativeToString.call(obj) === '[object Object]';
}

function isNumber(obj) {
  return nativeToString.call(obj) === '[object Number]';
}

function isFunction(obj) {
  var tag = nativeToString.call(obj);
  return tag === '[object Function]' || tag === '[object AsyncFunction]' || tag === '[object GeneratorFunction]' || tag === '[object AsyncGeneratorFunction]' || tag === '[object Proxy]';
}

function isString(obj) {
  return nativeToString.call(obj) === '[object String]';
}
/**
 * Ensure collection is an array.
 *
 * @param {Object} obj
 */


function ensureArray(obj) {
  if (isArray(obj)) {
    return;
  }

  throw new Error('must supply array');
}
/**
 * Return true, if target owns a property with the given key.
 *
 * @param {Object} target
 * @param {String} key
 *
 * @return {Boolean}
 */


function has(target, key) {
  return nativeHasOwnProperty.call(target, key);
}
/**
 * Find element in collection.
 *
 * @param  {Array|Object} collection
 * @param  {Function|Object} matcher
 *
 * @return {Object}
 */


function find(collection, matcher) {
  matcher = toMatcher(matcher);
  var match;
  forEach(collection, function (val, key) {
    if (matcher(val, key)) {
      match = val;
      return false;
    }
  });
  return match;
}
/**
 * Find element index in collection.
 *
 * @param  {Array|Object} collection
 * @param  {Function} matcher
 *
 * @return {Object}
 */


function findIndex(collection, matcher) {
  matcher = toMatcher(matcher);
  var idx = isArray(collection) ? -1 : undefined;
  forEach(collection, function (val, key) {
    if (matcher(val, key)) {
      idx = key;
      return false;
    }
  });
  return idx;
}
/**
 * Find element in collection.
 *
 * @param  {Array|Object} collection
 * @param  {Function} matcher
 *
 * @return {Array} result
 */


function filter(collection, matcher) {
  var result = [];
  forEach(collection, function (val, key) {
    if (matcher(val, key)) {
      result.push(val);
    }
  });
  return result;
}
/**
 * Iterate over collection; returning something
 * (non-undefined) will stop iteration.
 *
 * @param  {Array|Object} collection
 * @param  {Function} iterator
 *
 * @return {Object} return result that stopped the iteration
 */


function forEach(collection, iterator) {
  var val, result;

  if (isUndefined(collection)) {
    return;
  }

  var convertKey = isArray(collection) ? toNum : identity;

  for (var key in collection) {
    if (has(collection, key)) {
      val = collection[key];
      result = iterator(val, convertKey(key));

      if (result === false) {
        return val;
      }
    }
  }
}
/**
 * Return collection without element.
 *
 * @param  {Array} arr
 * @param  {Function} matcher
 *
 * @return {Array}
 */


function without(arr, matcher) {
  if (isUndefined(arr)) {
    return [];
  }

  ensureArray(arr);
  matcher = toMatcher(matcher);
  return arr.filter(function (el, idx) {
    return !matcher(el, idx);
  });
}
/**
 * Reduce collection, returning a single result.
 *
 * @param  {Object|Array} collection
 * @param  {Function} iterator
 * @param  {Any} result
 *
 * @return {Any} result returned from last iterator
 */


function reduce(collection, iterator, result) {
  forEach(collection, function (value, idx) {
    result = iterator(result, value, idx);
  });
  return result;
}
/**
 * Return true if every element in the collection
 * matches the criteria.
 *
 * @param  {Object|Array} collection
 * @param  {Function} matcher
 *
 * @return {Boolean}
 */


function every(collection, matcher) {
  return !!reduce(collection, function (matches, val, key) {
    return matches && matcher(val, key);
  }, true);
}
/**
 * Return true if some elements in the collection
 * match the criteria.
 *
 * @param  {Object|Array} collection
 * @param  {Function} matcher
 *
 * @return {Boolean}
 */


function some(collection, matcher) {
  return !!find(collection, matcher);
}
/**
 * Transform a collection into another collection
 * by piping each member through the given fn.
 *
 * @param  {Object|Array}   collection
 * @param  {Function} fn
 *
 * @return {Array} transformed collection
 */


function map(collection, fn) {
  var result = [];
  forEach(collection, function (val, key) {
    result.push(fn(val, key));
  });
  return result;
}
/**
 * Get the collections keys.
 *
 * @param  {Object|Array} collection
 *
 * @return {Array}
 */


function keys(collection) {
  return collection && Object.keys(collection) || [];
}
/**
 * Shorthand for `keys(o).length`.
 *
 * @param  {Object|Array} collection
 *
 * @return {Number}
 */


function size(collection) {
  return keys(collection).length;
}
/**
 * Get the values in the collection.
 *
 * @param  {Object|Array} collection
 *
 * @return {Array}
 */


function values(collection) {
  return map(collection, function (val) {
    return val;
  });
}
/**
 * Group collection members by attribute.
 *
 * @param  {Object|Array} collection
 * @param  {Function} extractor
 *
 * @return {Object} map with { attrValue => [ a, b, c ] }
 */


function groupBy(collection, extractor) {
  var grouped = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  extractor = toExtractor(extractor);
  forEach(collection, function (val) {
    var discriminator = extractor(val) || '_';
    var group = grouped[discriminator];

    if (!group) {
      group = grouped[discriminator] = [];
    }

    group.push(val);
  });
  return grouped;
}

function uniqueBy(extractor) {
  extractor = toExtractor(extractor);
  var grouped = {};

  for (var _len = arguments.length, collections = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    collections[_key - 1] = arguments[_key];
  }

  forEach(collections, function (c) {
    return groupBy(c, extractor, grouped);
  });
  var result = map(grouped, function (val, key) {
    return val[0];
  });
  return result;
}

var unionBy = uniqueBy;
/**
 * Sort collection by criteria.
 *
 * @param  {Object|Array} collection
 * @param  {String|Function} extractor
 *
 * @return {Array}
 */

exports.unionBy = unionBy;

function sortBy(collection, extractor) {
  extractor = toExtractor(extractor);
  var sorted = [];
  forEach(collection, function (value, key) {
    var disc = extractor(value, key);
    var entry = {
      d: disc,
      v: value
    };

    for (var idx = 0; idx < sorted.length; idx++) {
      var d = sorted[idx].d;

      if (disc < d) {
        sorted.splice(idx, 0, entry);
        return;
      }
    } // not inserted, append (!)


    sorted.push(entry);
  });
  return map(sorted, function (e) {
    return e.v;
  });
}
/**
 * Create an object pattern matcher.
 *
 * @example
 *
 * const matcher = matchPattern({ id: 1 });
 *
 * var element = find(elements, matcher);
 *
 * @param  {Object} pattern
 *
 * @return {Function} matcherFn
 */


function matchPattern(pattern) {
  return function (el) {
    return every(pattern, function (val, key) {
      return el[key] === val;
    });
  };
}

function toExtractor(extractor) {
  return isFunction(extractor) ? extractor : function (e) {
    return e[extractor];
  };
}

function toMatcher(matcher) {
  return isFunction(matcher) ? matcher : function (e) {
    return e === matcher;
  };
}

function identity(arg) {
  return arg;
}

function toNum(arg) {
  return Number(arg);
}
/**
 * Debounce fn, calling it only once if
 * the given time elapsed between calls.
 *
 * @param  {Function} fn
 * @param  {Number} timeout
 *
 * @return {Function} debounced function
 */


function debounce(fn, timeout) {
  var timer;
  var lastArgs;
  var lastThis;
  var lastNow;

  function fire() {
    var now = Date.now();
    var scheduledDiff = lastNow + timeout - now;

    if (scheduledDiff > 0) {
      return schedule(scheduledDiff);
    }

    fn.apply(lastThis, lastArgs);
    timer = lastNow = lastArgs = lastThis = undefined;
  }

  function schedule(timeout) {
    timer = setTimeout(fire, timeout);
  }

  return function () {
    lastNow = Date.now();

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    lastArgs = args;
    lastThis = this; // ensure an execution is scheduled

    if (!timer) {
      schedule(timeout);
    }
  };
}
/**
 * Throttle fn, calling at most once
 * in the given interval.
 *
 * @param  {Function} fn
 * @param  {Number} interval
 *
 * @return {Function} throttled function
 */


function throttle(fn, interval) {
  var throttling = false;
  return function () {
    if (throttling) {
      return;
    }

    fn.apply(void 0, arguments);
    throttling = true;
    setTimeout(function () {
      throttling = false;
    }, interval);
  };
}
/**
 * Bind function against target <this>.
 *
 * @param  {Function} fn
 * @param  {Object}   target
 *
 * @return {Function} bound function
 */


function bind(fn, target) {
  return fn.bind(target);
}

function _extends() {
  _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;
  };

  return _extends.apply(this, arguments);
}
/**
 * Convenience wrapper for `Object.assign`.
 *
 * @param {Object} target
 * @param {...Object} others
 *
 * @return {Object} the target
 */


function assign(target) {
  for (var _len = arguments.length, others = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    others[_key - 1] = arguments[_key];
  }

  return _extends.apply(void 0, [target].concat(others));
}
/**
 * Pick given properties from the target object.
 *
 * @param {Object} target
 * @param {Array} properties
 *
 * @return {Object} target
 */


function pick(target, properties) {
  var result = {};
  var obj = Object(target);
  forEach(properties, function (prop) {
    if (prop in obj) {
      result[prop] = target[prop];
    }
  });
  return result;
}
/**
 * Pick all target properties, excluding the given ones.
 *
 * @param {Object} target
 * @param {Array} properties
 *
 * @return {Object} target
 */


function omit(target, properties) {
  var result = {};
  var obj = Object(target);
  forEach(obj, function (prop, key) {
    if (properties.indexOf(key) === -1) {
      result[key] = prop;
    }
  });
  return result;
}
/**
 * Recursively merge `...sources` into given target.
 *
 * Does support merging objects; does not support merging arrays.
 *
 * @param {Object} target
 * @param {...Object} sources
 *
 * @return {Object} the target
 */


function merge(target) {
  for (var _len2 = arguments.length, sources = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
    sources[_key2 - 1] = arguments[_key2];
  }

  if (!sources.length) {
    return target;
  }

  forEach(sources, function (source) {
    // skip non-obj sources, i.e. null
    if (!source || !isObject(source)) {
      return;
    }

    forEach(source, function (sourceVal, key) {
      if (key === '__proto__') {
        return;
      }

      var targetVal = target[key];

      if (isObject(sourceVal)) {
        if (!isObject(targetVal)) {
          // override target[key] with object
          targetVal = {};
        }

        target[key] = merge(targetVal, sourceVal);
      } else {
        target[key] = sourceVal;
      }
    });
  });
  return target;
}

},{}],556:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.attr = attr;
exports.classes = classes;
exports.clear = clear;
exports.closest = closest;
exports.query = query;
exports.queryAll = all;
exports.remove = remove;
exports.matches = exports.event = exports.domify = exports.delegate = void 0;

/**
 * Set attribute `name` to `val`, or get attr `name`.
 *
 * @param {Element} el
 * @param {String} name
 * @param {String} [val]
 * @api public
 */
function attr(el, name, val) {
  // get
  if (arguments.length == 2) {
    return el.getAttribute(name);
  } // remove


  if (val === null) {
    return el.removeAttribute(name);
  } // set


  el.setAttribute(name, val);
  return el;
}

var indexOf = [].indexOf;

var indexof = function (arr, obj) {
  if (indexOf) return arr.indexOf(obj);

  for (var i = 0; i < arr.length; ++i) {
    if (arr[i] === obj) return i;
  }

  return -1;
};
/**
 * Taken from https://github.com/component/classes
 *
 * Without the component bits.
 */

/**
 * Whitespace regexp.
 */


var re = /\s+/;
/**
 * toString reference.
 */

var toString = Object.prototype.toString;
/**
 * Wrap `el` in a `ClassList`.
 *
 * @param {Element} el
 * @return {ClassList}
 * @api public
 */

function classes(el) {
  return new ClassList(el);
}
/**
 * Initialize a new ClassList for `el`.
 *
 * @param {Element} el
 * @api private
 */


function ClassList(el) {
  if (!el || !el.nodeType) {
    throw new Error('A DOM element reference is required');
  }

  this.el = el;
  this.list = el.classList;
}
/**
 * Add class `name` if not already present.
 *
 * @param {String} name
 * @return {ClassList}
 * @api public
 */


ClassList.prototype.add = function (name) {
  // classList
  if (this.list) {
    this.list.add(name);
    return this;
  } // fallback


  var arr = this.array();
  var i = indexof(arr, name);
  if (!~i) arr.push(name);
  this.el.className = arr.join(' ');
  return this;
};
/**
 * Remove class `name` when present, or
 * pass a regular expression to remove
 * any which match.
 *
 * @param {String|RegExp} name
 * @return {ClassList}
 * @api public
 */


ClassList.prototype.remove = function (name) {
  if ('[object RegExp]' == toString.call(name)) {
    return this.removeMatching(name);
  } // classList


  if (this.list) {
    this.list.remove(name);
    return this;
  } // fallback


  var arr = this.array();
  var i = indexof(arr, name);
  if (~i) arr.splice(i, 1);
  this.el.className = arr.join(' ');
  return this;
};
/**
 * Remove all classes matching `re`.
 *
 * @param {RegExp} re
 * @return {ClassList}
 * @api private
 */


ClassList.prototype.removeMatching = function (re) {
  var arr = this.array();

  for (var i = 0; i < arr.length; i++) {
    if (re.test(arr[i])) {
      this.remove(arr[i]);
    }
  }

  return this;
};
/**
 * Toggle class `name`, can force state via `force`.
 *
 * For browsers that support classList, but do not support `force` yet,
 * the mistake will be detected and corrected.
 *
 * @param {String} name
 * @param {Boolean} force
 * @return {ClassList}
 * @api public
 */


ClassList.prototype.toggle = function (name, force) {
  // classList
  if (this.list) {
    if ('undefined' !== typeof force) {
      if (force !== this.list.toggle(name, force)) {
        this.list.toggle(name); // toggle again to correct
      }
    } else {
      this.list.toggle(name);
    }

    return this;
  } // fallback


  if ('undefined' !== typeof force) {
    if (!force) {
      this.remove(name);
    } else {
      this.add(name);
    }
  } else {
    if (this.has(name)) {
      this.remove(name);
    } else {
      this.add(name);
    }
  }

  return this;
};
/**
 * Return an array of classes.
 *
 * @return {Array}
 * @api public
 */


ClassList.prototype.array = function () {
  var className = this.el.getAttribute('class') || '';
  var str = className.replace(/^\s+|\s+$/g, '');
  var arr = str.split(re);
  if ('' === arr[0]) arr.shift();
  return arr;
};
/**
 * Check if class `name` is present.
 *
 * @param {String} name
 * @return {ClassList}
 * @api public
 */


ClassList.prototype.has = ClassList.prototype.contains = function (name) {
  return this.list ? this.list.contains(name) : !!~indexof(this.array(), name);
};
/**
 * Remove all children from the given element.
 */


function clear(el) {
  var c;

  while (el.childNodes.length) {
    c = el.childNodes[0];
    el.removeChild(c);
  }

  return el;
}

var proto = typeof Element !== 'undefined' ? Element.prototype : {};
var vendor = proto.matches || proto.matchesSelector || proto.webkitMatchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector;
var matchesSelector = match;
/**
 * Match `el` to `selector`.
 *
 * @param {Element} el
 * @param {String} selector
 * @return {Boolean}
 * @api public
 */

exports.matches = matchesSelector;

function match(el, selector) {
  if (!el || el.nodeType !== 1) return false;
  if (vendor) return vendor.call(el, selector);
  var nodes = el.parentNode.querySelectorAll(selector);

  for (var i = 0; i < nodes.length; i++) {
    if (nodes[i] == el) return true;
  }

  return false;
}
/**
 * Closest
 *
 * @param {Element} el
 * @param {String} selector
 * @param {Boolean} checkYourSelf (optional)
 */


function closest(element, selector, checkYourSelf) {
  var currentElem = checkYourSelf ? element : element.parentNode;

  while (currentElem && currentElem.nodeType !== document.DOCUMENT_NODE && currentElem.nodeType !== document.DOCUMENT_FRAGMENT_NODE) {
    if (matchesSelector(currentElem, selector)) {
      return currentElem;
    }

    currentElem = currentElem.parentNode;
  }

  return matchesSelector(currentElem, selector) ? currentElem : null;
}

var bind = window.addEventListener ? 'addEventListener' : 'attachEvent',
    unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent',
    prefix = bind !== 'addEventListener' ? 'on' : '';
/**
 * Bind `el` event `type` to `fn`.
 *
 * @param {Element} el
 * @param {String} type
 * @param {Function} fn
 * @param {Boolean} capture
 * @return {Function}
 * @api public
 */

var bind_1 = function (el, type, fn, capture) {
  el[bind](prefix + type, fn, capture || false);
  return fn;
};
/**
 * Unbind `el` event `type`'s callback `fn`.
 *
 * @param {Element} el
 * @param {String} type
 * @param {Function} fn
 * @param {Boolean} capture
 * @return {Function}
 * @api public
 */


var unbind_1 = function (el, type, fn, capture) {
  el[unbind](prefix + type, fn, capture || false);
  return fn;
};

var componentEvent = {
  bind: bind_1,
  unbind: unbind_1
};
/**
 * Module dependencies.
 */

/**
 * Delegate event `type` to `selector`
 * and invoke `fn(e)`. A callback function
 * is returned which may be passed to `.unbind()`.
 *
 * @param {Element} el
 * @param {String} selector
 * @param {String} type
 * @param {Function} fn
 * @param {Boolean} capture
 * @return {Function}
 * @api public
 */
// Some events don't bubble, so we want to bind to the capture phase instead
// when delegating.

exports.event = componentEvent;
var forceCaptureEvents = ['focus', 'blur'];

function bind$1(el, selector, type, fn, capture) {
  if (forceCaptureEvents.indexOf(type) !== -1) {
    capture = true;
  }

  return componentEvent.bind(el, type, function (e) {
    var target = e.target || e.srcElement;
    e.delegateTarget = closest(target, selector, true, el);

    if (e.delegateTarget) {
      fn.call(el, e);
    }
  }, capture);
}
/**
 * Unbind event `type`'s callback `fn`.
 *
 * @param {Element} el
 * @param {String} type
 * @param {Function} fn
 * @param {Boolean} capture
 * @api public
 */


function unbind$1(el, type, fn, capture) {
  if (forceCaptureEvents.indexOf(type) !== -1) {
    capture = true;
  }

  return componentEvent.unbind(el, type, fn, capture);
}

var delegate = {
  bind: bind$1,
  unbind: unbind$1
};
/**
 * Expose `parse`.
 */

exports.delegate = delegate;
var domify = parse;
/**
 * Tests for browser support.
 */

exports.domify = domify;
var innerHTMLBug = false;
var bugTestDiv;

if (typeof document !== 'undefined') {
  bugTestDiv = document.createElement('div'); // Setup

  bugTestDiv.innerHTML = '  <link/><table></table><a href="/a">a</a><input type="checkbox"/>'; // Make sure that link elements get serialized correctly by innerHTML
  // This requires a wrapper element in IE

  innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length;
  bugTestDiv = undefined;
}
/**
 * Wrap map from jquery.
 */


var map = {
  legend: [1, '<fieldset>', '</fieldset>'],
  tr: [2, '<table><tbody>', '</tbody></table>'],
  col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
  // for script/link/style tags to work in IE6-8, you have to wrap
  // in a div with a non-whitespace character in front, ha!
  _default: innerHTMLBug ? [1, 'X<div>', '</div>'] : [0, '', '']
};
map.td = map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
map.option = map.optgroup = [1, '<select multiple="multiple">', '</select>'];
map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '<table>', '</table>'];
map.polyline = map.ellipse = map.polygon = map.circle = map.text = map.line = map.path = map.rect = map.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">', '</svg>'];
/**
 * Parse `html` and return a DOM Node instance, which could be a TextNode,
 * HTML DOM Node of some kind (<div> for example), or a DocumentFragment
 * instance, depending on the contents of the `html` string.
 *
 * @param {String} html - HTML string to "domify"
 * @param {Document} doc - The `document` instance to create the Node for
 * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance
 * @api private
 */

function parse(html, doc) {
  if ('string' != typeof html) throw new TypeError('String expected'); // default to the global `document` object

  if (!doc) doc = document; // tag name

  var m = /<([\w:]+)/.exec(html);
  if (!m) return doc.createTextNode(html);
  html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace

  var tag = m[1]; // body support

  if (tag == 'body') {
    var el = doc.createElement('html');
    el.innerHTML = html;
    return el.removeChild(el.lastChild);
  } // wrap map


  var wrap = map[tag] || map._default;
  var depth = wrap[0];
  var prefix = wrap[1];
  var suffix = wrap[2];
  var el = doc.createElement('div');
  el.innerHTML = prefix + html + suffix;

  while (depth--) el = el.lastChild; // one element


  if (el.firstChild == el.lastChild) {
    return el.removeChild(el.firstChild);
  } // several elements


  var fragment = doc.createDocumentFragment();

  while (el.firstChild) {
    fragment.appendChild(el.removeChild(el.firstChild));
  }

  return fragment;
}

function query(selector, el) {
  el = el || document;
  return el.querySelector(selector);
}

function all(selector, el) {
  el = el || document;
  return el.querySelectorAll(selector);
}

function remove(el) {
  el.parentNode && el.parentNode.removeChild(el);
}

},{}],557:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

//
// An event handler can take an optional event argument
// and should not return a value
// An array of all currently registered event handlers for a type
// A map of event types and their corresponding event handlers.

/** Mitt: Tiny (~200b) functional event emitter / pubsub.
 *  @name mitt
 *  @returns {Mitt}
 */
function mitt(all) {
  all = all || Object.create(null);
  return {
    /**
     * Register an event handler for the given type.
     *
     * @param  {String} type	Type of event to listen for, or `"*"` for all events
     * @param  {Function} handler Function to call in response to given event
     * @memberOf mitt
     */
    on: function on(type, handler) {
      (all[type] || (all[type] = [])).push(handler);
    },

    /**
     * Remove an event handler for the given type.
     *
     * @param  {String} type	Type of event to unregister `handler` from, or `"*"`
     * @param  {Function} handler Handler function to remove
     * @memberOf mitt
     */
    off: function off(type, handler) {
      if (all[type]) {
        all[type].splice(all[type].indexOf(handler) >>> 0, 1);
      }
    },

    /**
     * Invoke all handlers for the given type.
     * If present, `"*"` handlers are invoked after type-matched handlers.
     *
     * @param {String} type  The event type to invoke
     * @param {Any} [evt]  Any value (object is recommended and powerful), passed to each handler
     * @memberOf mitt
     */
    emit: function emit(type, evt) {
      (all[type] || []).slice().map(function (handler) {
        handler(evt);
      });
      (all['*'] || []).slice().map(function (handler) {
        handler(type, evt);
      });
    }
  };
}

var _default = mitt;
exports.default = _default;

},{}],558:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Reader = Reader;
exports.Writer = Writer;

var _minDash = require("min-dash");

var _saxen = require("saxen");

var _moddle = require("moddle");

function hasLowerCaseAlias(pkg) {
  return pkg.xml && pkg.xml.tagAlias === 'lowerCase';
}

var DEFAULT_NS_MAP = {
  'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
  'xml': 'http://www.w3.org/XML/1998/namespace'
};
var XSI_TYPE = 'xsi:type';

function serializeFormat(element) {
  return element.xml && element.xml.serialize;
}

function serializeAsType(element) {
  return serializeFormat(element) === XSI_TYPE;
}

function serializeAsProperty(element) {
  return serializeFormat(element) === 'property';
}

function capitalize(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

function aliasToName(aliasNs, pkg) {
  if (!hasLowerCaseAlias(pkg)) {
    return aliasNs.name;
  }

  return aliasNs.prefix + ':' + capitalize(aliasNs.localName);
}

function prefixedToName(nameNs, pkg) {
  var name = nameNs.name,
      localName = nameNs.localName;
  var typePrefix = pkg.xml && pkg.xml.typePrefix;

  if (typePrefix && localName.indexOf(typePrefix) === 0) {
    return nameNs.prefix + ':' + localName.slice(typePrefix.length);
  } else {
    return name;
  }
}

function normalizeXsiTypeName(name, model) {
  var nameNs = (0, _moddle.parseNameNS)(name);
  var pkg = model.getPackage(nameNs.prefix);
  return prefixedToName(nameNs, pkg);
}

function error(message) {
  return new Error(message);
}
/**
 * Get the moddle descriptor for a given instance or type.
 *
 * @param  {ModdleElement|Function} element
 *
 * @return {Object} the moddle descriptor
 */


function getModdleDescriptor(element) {
  return element.$descriptor;
}
/**
 * A parse context.
 *
 * @class
 *
 * @param {Object} options
 * @param {ElementHandler} options.rootHandler the root handler for parsing a document
 * @param {boolean} [options.lax=false] whether or not to ignore invalid elements
 */


function Context(options) {
  /**
   * @property {ElementHandler} rootHandler
   */

  /**
   * @property {Boolean} lax
   */
  (0, _minDash.assign)(this, options);
  this.elementsById = {};
  this.references = [];
  this.warnings = [];
  /**
   * Add an unresolved reference.
   *
   * @param {Object} reference
   */

  this.addReference = function (reference) {
    this.references.push(reference);
  };
  /**
   * Add a processed element.
   *
   * @param {ModdleElement} element
   */


  this.addElement = function (element) {
    if (!element) {
      throw error('expected element');
    }

    var elementsById = this.elementsById;
    var descriptor = getModdleDescriptor(element);
    var idProperty = descriptor.idProperty,
        id;

    if (idProperty) {
      id = element.get(idProperty.name);

      if (id) {
        // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar
        if (!/^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i.test(id)) {
          throw new Error('illegal ID <' + id + '>');
        }

        if (elementsById[id]) {
          throw error('duplicate ID <' + id + '>');
        }

        elementsById[id] = element;
      }
    }
  };
  /**
   * Add an import warning.
   *
   * @param {Object} warning
   * @param {String} warning.message
   * @param {Error} [warning.error]
   */


  this.addWarning = function (warning) {
    this.warnings.push(warning);
  };
}

function BaseHandler() {}

BaseHandler.prototype.handleEnd = function () {};

BaseHandler.prototype.handleText = function () {};

BaseHandler.prototype.handleNode = function () {};
/**
 * A simple pass through handler that does nothing except for
 * ignoring all input it receives.
 *
 * This is used to ignore unknown elements and
 * attributes.
 */


function NoopHandler() {}

NoopHandler.prototype = Object.create(BaseHandler.prototype);

NoopHandler.prototype.handleNode = function () {
  return this;
};

function BodyHandler() {}

BodyHandler.prototype = Object.create(BaseHandler.prototype);

BodyHandler.prototype.handleText = function (text) {
  this.body = (this.body || '') + text;
};

function ReferenceHandler(property, context) {
  this.property = property;
  this.context = context;
}

ReferenceHandler.prototype = Object.create(BodyHandler.prototype);

ReferenceHandler.prototype.handleNode = function (node) {
  if (this.element) {
    throw error('expected no sub nodes');
  } else {
    this.element = this.createReference(node);
  }

  return this;
};

ReferenceHandler.prototype.handleEnd = function () {
  this.element.id = this.body;
};

ReferenceHandler.prototype.createReference = function (node) {
  return {
    property: this.property.ns.name,
    id: ''
  };
};

function ValueHandler(propertyDesc, element) {
  this.element = element;
  this.propertyDesc = propertyDesc;
}

ValueHandler.prototype = Object.create(BodyHandler.prototype);

ValueHandler.prototype.handleEnd = function () {
  var value = this.body || '',
      element = this.element,
      propertyDesc = this.propertyDesc;
  value = (0, _moddle.coerceType)(propertyDesc.type, value);

  if (propertyDesc.isMany) {
    element.get(propertyDesc.name).push(value);
  } else {
    element.set(propertyDesc.name, value);
  }
};

function BaseElementHandler() {}

BaseElementHandler.prototype = Object.create(BodyHandler.prototype);

BaseElementHandler.prototype.handleNode = function (node) {
  var parser = this,
      element = this.element;

  if (!element) {
    element = this.element = this.createElement(node);
    this.context.addElement(element);
  } else {
    parser = this.handleChild(node);
  }

  return parser;
};
/**
 * @class Reader.ElementHandler
 *
 */


function ElementHandler(model, typeName, context) {
  this.model = model;
  this.type = model.getType(typeName);
  this.context = context;
}

ElementHandler.prototype = Object.create(BaseElementHandler.prototype);

ElementHandler.prototype.addReference = function (reference) {
  this.context.addReference(reference);
};

ElementHandler.prototype.handleText = function (text) {
  var element = this.element,
      descriptor = getModdleDescriptor(element),
      bodyProperty = descriptor.bodyProperty;

  if (!bodyProperty) {
    throw error('unexpected body text <' + text + '>');
  }

  BodyHandler.prototype.handleText.call(this, text);
};

ElementHandler.prototype.handleEnd = function () {
  var value = this.body,
      element = this.element,
      descriptor = getModdleDescriptor(element),
      bodyProperty = descriptor.bodyProperty;

  if (bodyProperty && value !== undefined) {
    value = (0, _moddle.coerceType)(bodyProperty.type, value);
    element.set(bodyProperty.name, value);
  }
};
/**
 * Create an instance of the model from the given node.
 *
 * @param  {Element} node the xml node
 */


ElementHandler.prototype.createElement = function (node) {
  var attributes = node.attributes,
      Type = this.type,
      descriptor = getModdleDescriptor(Type),
      context = this.context,
      instance = new Type({}),
      model = this.model,
      propNameNs;
  (0, _minDash.forEach)(attributes, function (value, name) {
    var prop = descriptor.propertiesByName[name],
        values;

    if (prop && prop.isReference) {
      if (!prop.isMany) {
        context.addReference({
          element: instance,
          property: prop.ns.name,
          id: value
        });
      } else {
        // IDREFS: parse references as whitespace-separated list
        values = value.split(' ');
        (0, _minDash.forEach)(values, function (v) {
          context.addReference({
            element: instance,
            property: prop.ns.name,
            id: v
          });
        });
      }
    } else {
      if (prop) {
        value = (0, _moddle.coerceType)(prop.type, value);
      } else if (name !== 'xmlns') {
        propNameNs = (0, _moddle.parseNameNS)(name, descriptor.ns.prefix); // check whether attribute is defined in a well-known namespace
        // if that is the case we emit a warning to indicate potential misuse

        if (model.getPackage(propNameNs.prefix)) {
          context.addWarning({
            message: 'unknown attribute <' + name + '>',
            element: instance,
            property: name,
            value: value
          });
        }
      }

      instance.set(name, value);
    }
  });
  return instance;
};

ElementHandler.prototype.getPropertyForNode = function (node) {
  var name = node.name;
  var nameNs = (0, _moddle.parseNameNS)(name);
  var type = this.type,
      model = this.model,
      descriptor = getModdleDescriptor(type);
  var propertyName = nameNs.name,
      property = descriptor.propertiesByName[propertyName],
      elementTypeName,
      elementType; // search for properties by name first

  if (property && !property.isAttr) {
    if (serializeAsType(property)) {
      elementTypeName = node.attributes[XSI_TYPE]; // xsi type is optional, if it does not exists the
      // default type is assumed

      if (elementTypeName) {
        // take possible type prefixes from XML
        // into account, i.e.: xsi:type="t{ActualType}"
        elementTypeName = normalizeXsiTypeName(elementTypeName, model);
        elementType = model.getType(elementTypeName);
        return (0, _minDash.assign)({}, property, {
          effectiveType: getModdleDescriptor(elementType).name
        });
      }
    } // search for properties by name first


    return property;
  }

  var pkg = model.getPackage(nameNs.prefix);

  if (pkg) {
    elementTypeName = aliasToName(nameNs, pkg);
    elementType = model.getType(elementTypeName); // search for collection members later

    property = (0, _minDash.find)(descriptor.properties, function (p) {
      return !p.isVirtual && !p.isReference && !p.isAttribute && elementType.hasType(p.type);
    });

    if (property) {
      return (0, _minDash.assign)({}, property, {
        effectiveType: getModdleDescriptor(elementType).name
      });
    }
  } else {
    // parse unknown element (maybe extension)
    property = (0, _minDash.find)(descriptor.properties, function (p) {
      return !p.isReference && !p.isAttribute && p.type === 'Element';
    });

    if (property) {
      return property;
    }
  }

  throw error('unrecognized element <' + nameNs.name + '>');
};

ElementHandler.prototype.toString = function () {
  return 'ElementDescriptor[' + getModdleDescriptor(this.type).name + ']';
};

ElementHandler.prototype.valueHandler = function (propertyDesc, element) {
  return new ValueHandler(propertyDesc, element);
};

ElementHandler.prototype.referenceHandler = function (propertyDesc) {
  return new ReferenceHandler(propertyDesc, this.context);
};

ElementHandler.prototype.handler = function (type) {
  if (type === 'Element') {
    return new GenericElementHandler(this.model, type, this.context);
  } else {
    return new ElementHandler(this.model, type, this.context);
  }
};
/**
 * Handle the child element parsing
 *
 * @param  {Element} node the xml node
 */


ElementHandler.prototype.handleChild = function (node) {
  var propertyDesc, type, element, childHandler;
  propertyDesc = this.getPropertyForNode(node);
  element = this.element;
  type = propertyDesc.effectiveType || propertyDesc.type;

  if ((0, _moddle.isSimpleType)(type)) {
    return this.valueHandler(propertyDesc, element);
  }

  if (propertyDesc.isReference) {
    childHandler = this.referenceHandler(propertyDesc).handleNode(node);
  } else {
    childHandler = this.handler(type).handleNode(node);
  }

  var newElement = childHandler.element; // child handles may decide to skip elements
  // by not returning anything

  if (newElement !== undefined) {
    if (propertyDesc.isMany) {
      element.get(propertyDesc.name).push(newElement);
    } else {
      element.set(propertyDesc.name, newElement);
    }

    if (propertyDesc.isReference) {
      (0, _minDash.assign)(newElement, {
        element: element
      });
      this.context.addReference(newElement);
    } else {
      // establish child -> parent relationship
      newElement.$parent = element;
    }
  }

  return childHandler;
};
/**
 * An element handler that performs special validation
 * to ensure the node it gets initialized with matches
 * the handlers type (namespace wise).
 *
 * @param {Moddle} model
 * @param {String} typeName
 * @param {Context} context
 */


function RootElementHandler(model, typeName, context) {
  ElementHandler.call(this, model, typeName, context);
}

RootElementHandler.prototype = Object.create(ElementHandler.prototype);

RootElementHandler.prototype.createElement = function (node) {
  var name = node.name,
      nameNs = (0, _moddle.parseNameNS)(name),
      model = this.model,
      type = this.type,
      pkg = model.getPackage(nameNs.prefix),
      typeName = pkg && aliasToName(nameNs, pkg) || name; // verify the correct namespace if we parse
  // the first element in the handler tree
  //
  // this ensures we don't mistakenly import wrong namespace elements

  if (!type.hasType(typeName)) {
    throw error('unexpected element <' + node.originalName + '>');
  }

  return ElementHandler.prototype.createElement.call(this, node);
};

function GenericElementHandler(model, typeName, context) {
  this.model = model;
  this.context = context;
}

GenericElementHandler.prototype = Object.create(BaseElementHandler.prototype);

GenericElementHandler.prototype.createElement = function (node) {
  var name = node.name,
      ns = (0, _moddle.parseNameNS)(name),
      prefix = ns.prefix,
      uri = node.ns[prefix + '$uri'],
      attributes = node.attributes;
  return this.model.createAny(name, uri, attributes);
};

GenericElementHandler.prototype.handleChild = function (node) {
  var handler = new GenericElementHandler(this.model, 'Element', this.context).handleNode(node),
      element = this.element;
  var newElement = handler.element,
      children;

  if (newElement !== undefined) {
    children = element.$children = element.$children || [];
    children.push(newElement); // establish child -> parent relationship

    newElement.$parent = element;
  }

  return handler;
};

GenericElementHandler.prototype.handleEnd = function () {
  if (this.body) {
    this.element.$body = this.body;
  }
};
/**
 * A reader for a meta-model
 *
 * @param {Object} options
 * @param {Model} options.model used to read xml files
 * @param {Boolean} options.lax whether to make parse errors warnings
 */


function Reader(options) {
  if (options instanceof _moddle.Moddle) {
    options = {
      model: options
    };
  }

  (0, _minDash.assign)(this, {
    lax: false
  }, options);
}
/**
 * The fromXML result.
 *
 * @typedef {Object} ParseResult
 *
 * @property {ModdleElement} rootElement
 * @property {Array<Object>} references
 * @property {Array<Error>} warnings
 * @property {Object} elementsById - a mapping containing each ID -> ModdleElement
 */

/**
 * The fromXML result.
 *
 * @typedef {Error} ParseError
 *
 * @property {Array<Error>} warnings
 */

/**
 * Parse the given XML into a moddle document tree.
 *
 * @param {String} xml
 * @param {ElementHandler|Object} options or rootHandler
 *
 * @returns {Promise<ParseResult, ParseError>}
 */


Reader.prototype.fromXML = function (xml, options, done) {
  var rootHandler = options.rootHandler;

  if (options instanceof ElementHandler) {
    // root handler passed via (xml, { rootHandler: ElementHandler }, ...)
    rootHandler = options;
    options = {};
  } else {
    if (typeof options === 'string') {
      // rootHandler passed via (xml, 'someString', ...)
      rootHandler = this.handler(options);
      options = {};
    } else if (typeof rootHandler === 'string') {
      // rootHandler passed via (xml, { rootHandler: 'someString' }, ...)
      rootHandler = this.handler(rootHandler);
    }
  }

  var model = this.model,
      lax = this.lax;
  var context = new Context((0, _minDash.assign)({}, options, {
    rootHandler: rootHandler
  })),
      parser = new _saxen.Parser({
    proxy: true
  }),
      stack = createStack();
  rootHandler.context = context; // push root handler

  stack.push(rootHandler);
  /**
   * Handle error.
   *
   * @param  {Error} err
   * @param  {Function} getContext
   * @param  {boolean} lax
   *
   * @return {boolean} true if handled
   */

  function handleError(err, getContext, lax) {
    var ctx = getContext();
    var line = ctx.line,
        column = ctx.column,
        data = ctx.data; // we receive the full context data here,
    // for elements trim down the information
    // to the tag name, only

    if (data.charAt(0) === '<' && data.indexOf(' ') !== -1) {
      data = data.slice(0, data.indexOf(' ')) + '>';
    }

    var message = 'unparsable content ' + (data ? data + ' ' : '') + 'detected\n\t' + 'line: ' + line + '\n\t' + 'column: ' + column + '\n\t' + 'nested error: ' + err.message;

    if (lax) {
      context.addWarning({
        message: message,
        error: err
      });
      return true;
    } else {
      throw error(message);
    }
  }

  function handleWarning(err, getContext) {
    // just like handling errors in <lax=true> mode
    return handleError(err, getContext, true);
  }
  /**
   * Resolve collected references on parse end.
   */


  function resolveReferences() {
    var elementsById = context.elementsById;
    var references = context.references;
    var i, r;

    for (i = 0; r = references[i]; i++) {
      var element = r.element;
      var reference = elementsById[r.id];
      var property = getModdleDescriptor(element).propertiesByName[r.property];

      if (!reference) {
        context.addWarning({
          message: 'unresolved reference <' + r.id + '>',
          element: r.element,
          property: r.property,
          value: r.id
        });
      }

      if (property.isMany) {
        var collection = element.get(property.name),
            idx = collection.indexOf(r); // we replace an existing place holder (idx != -1) or
        // append to the collection instead

        if (idx === -1) {
          idx = collection.length;
        }

        if (!reference) {
          // remove unresolvable reference
          collection.splice(idx, 1);
        } else {
          // add or update reference in collection
          collection[idx] = reference;
        }
      } else {
        element.set(property.name, reference);
      }
    }
  }

  function handleClose() {
    stack.pop().handleEnd();
  }

  var PREAMBLE_START_PATTERN = /^<\?xml /i;
  var ENCODING_PATTERN = / encoding="([^"]+)"/i;
  var UTF_8_PATTERN = /^utf-8$/i;

  function handleQuestion(question) {
    if (!PREAMBLE_START_PATTERN.test(question)) {
      return;
    }

    var match = ENCODING_PATTERN.exec(question);
    var encoding = match && match[1];

    if (!encoding || UTF_8_PATTERN.test(encoding)) {
      return;
    }

    context.addWarning({
      message: 'unsupported document encoding <' + encoding + '>, ' + 'falling back to UTF-8'
    });
  }

  function handleOpen(node, getContext) {
    var handler = stack.peek();

    try {
      stack.push(handler.handleNode(node));
    } catch (err) {
      if (handleError(err, getContext, lax)) {
        stack.push(new NoopHandler());
      }
    }
  }

  function handleCData(text, getContext) {
    try {
      stack.peek().handleText(text);
    } catch (err) {
      handleWarning(err, getContext);
    }
  }

  function handleText(text, getContext) {
    // strip whitespace only nodes, i.e. before
    // <!CDATA[ ... ]> sections and in between tags
    text = text.trim();

    if (!text) {
      return;
    }

    handleCData(text, getContext);
  }

  var uriMap = model.getPackages().reduce(function (uriMap, p) {
    uriMap[p.uri] = p.prefix;
    return uriMap;
  }, {
    'http://www.w3.org/XML/1998/namespace': 'xml' // add default xml ns

  });
  parser.ns(uriMap).on('openTag', function (obj, decodeStr, selfClosing, getContext) {
    // gracefully handle unparsable attributes (attrs=false)
    var attrs = obj.attrs || {};
    var decodedAttrs = Object.keys(attrs).reduce(function (d, key) {
      var value = decodeStr(attrs[key]);
      d[key] = value;
      return d;
    }, {});
    var node = {
      name: obj.name,
      originalName: obj.originalName,
      attributes: decodedAttrs,
      ns: obj.ns
    };
    handleOpen(node, getContext);
  }).on('question', handleQuestion).on('closeTag', handleClose).on('cdata', handleCData).on('text', function (text, decodeEntities, getContext) {
    handleText(decodeEntities(text), getContext);
  }).on('error', handleError).on('warn', handleWarning); // async XML parsing to make sure the execution environment
  // (node or brower) is kept responsive and that certain optimization
  // strategies can kick in.

  return new Promise(function (resolve, reject) {
    var err;

    try {
      parser.parse(xml);
      resolveReferences();
    } catch (e) {
      err = e;
    }

    var rootElement = rootHandler.element;

    if (!err && !rootElement) {
      err = error('failed to parse document as <' + rootHandler.type.$descriptor.name + '>');
    }

    var warnings = context.warnings;
    var references = context.references;
    var elementsById = context.elementsById;

    if (err) {
      err.warnings = warnings;
      return reject(err);
    } else {
      return resolve({
        rootElement: rootElement,
        elementsById: elementsById,
        references: references,
        warnings: warnings
      });
    }
  });
};

Reader.prototype.handler = function (name) {
  return new RootElementHandler(this.model, name);
}; // helpers //////////////////////////


function createStack() {
  var stack = [];
  Object.defineProperty(stack, 'peek', {
    value: function () {
      return this[this.length - 1];
    }
  });
  return stack;
}

var XML_PREAMBLE = '<?xml version="1.0" encoding="UTF-8"?>\n';
var ESCAPE_ATTR_CHARS = /<|>|'|"|&|\n\r|\n/g;
var ESCAPE_CHARS = /<|>|&/g;

function Namespaces(parent) {
  var prefixMap = {};
  var uriMap = {};
  var used = {};
  var wellknown = [];
  var custom = []; // API

  this.byUri = function (uri) {
    return uriMap[uri] || parent && parent.byUri(uri);
  };

  this.add = function (ns, isWellknown) {
    uriMap[ns.uri] = ns;

    if (isWellknown) {
      wellknown.push(ns);
    } else {
      custom.push(ns);
    }

    this.mapPrefix(ns.prefix, ns.uri);
  };

  this.uriByPrefix = function (prefix) {
    return prefixMap[prefix || 'xmlns'];
  };

  this.mapPrefix = function (prefix, uri) {
    prefixMap[prefix || 'xmlns'] = uri;
  };

  this.getNSKey = function (ns) {
    return ns.prefix !== undefined ? ns.uri + '|' + ns.prefix : ns.uri;
  };

  this.logUsed = function (ns) {
    var uri = ns.uri;
    var nsKey = this.getNSKey(ns);
    used[nsKey] = this.byUri(uri); // Inform parent recursively about the usage of this NS

    if (parent) {
      parent.logUsed(ns);
    }
  };

  this.getUsed = function (ns) {
    function isUsed(ns) {
      var nsKey = self.getNSKey(ns);
      return used[nsKey];
    }

    var self = this;
    var allNs = [].concat(wellknown, custom);
    return allNs.filter(isUsed);
  };
}

function lower(string) {
  return string.charAt(0).toLowerCase() + string.slice(1);
}

function nameToAlias(name, pkg) {
  if (hasLowerCaseAlias(pkg)) {
    return lower(name);
  } else {
    return name;
  }
}

function inherits(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
}

function nsName(ns) {
  if ((0, _minDash.isString)(ns)) {
    return ns;
  } else {
    return (ns.prefix ? ns.prefix + ':' : '') + ns.localName;
  }
}

function getNsAttrs(namespaces) {
  return (0, _minDash.map)(namespaces.getUsed(), function (ns) {
    var name = 'xmlns' + (ns.prefix ? ':' + ns.prefix : '');
    return {
      name: name,
      value: ns.uri
    };
  });
}

function getElementNs(ns, descriptor) {
  if (descriptor.isGeneric) {
    return (0, _minDash.assign)({
      localName: descriptor.ns.localName
    }, ns);
  } else {
    return (0, _minDash.assign)({
      localName: nameToAlias(descriptor.ns.localName, descriptor.$pkg)
    }, ns);
  }
}

function getPropertyNs(ns, descriptor) {
  return (0, _minDash.assign)({
    localName: descriptor.ns.localName
  }, ns);
}

function getSerializableProperties(element) {
  var descriptor = element.$descriptor;
  return (0, _minDash.filter)(descriptor.properties, function (p) {
    var name = p.name;

    if (p.isVirtual) {
      return false;
    } // do not serialize defaults


    if (!element.hasOwnProperty(name)) {
      return false;
    }

    var value = element[name]; // do not serialize default equals

    if (value === p.default) {
      return false;
    } // do not serialize null properties


    if (value === null) {
      return false;
    }

    return p.isMany ? value.length : true;
  });
}

var ESCAPE_ATTR_MAP = {
  '\n': '#10',
  '\n\r': '#10',
  '"': '#34',
  '\'': '#39',
  '<': '#60',
  '>': '#62',
  '&': '#38'
};
var ESCAPE_MAP = {
  '<': 'lt',
  '>': 'gt',
  '&': 'amp'
};

function escape(str, charPattern, replaceMap) {
  // ensure we are handling strings here
  str = (0, _minDash.isString)(str) ? str : '' + str;
  return str.replace(charPattern, function (s) {
    return '&' + replaceMap[s] + ';';
  });
}
/**
 * Escape a string attribute to not contain any bad values (line breaks, '"', ...)
 *
 * @param {String} str the string to escape
 * @return {String} the escaped string
 */


function escapeAttr(str) {
  return escape(str, ESCAPE_ATTR_CHARS, ESCAPE_ATTR_MAP);
}

function escapeBody(str) {
  return escape(str, ESCAPE_CHARS, ESCAPE_MAP);
}

function filterAttributes(props) {
  return (0, _minDash.filter)(props, function (p) {
    return p.isAttr;
  });
}

function filterContained(props) {
  return (0, _minDash.filter)(props, function (p) {
    return !p.isAttr;
  });
}

function ReferenceSerializer(tagName) {
  this.tagName = tagName;
}

ReferenceSerializer.prototype.build = function (element) {
  this.element = element;
  return this;
};

ReferenceSerializer.prototype.serializeTo = function (writer) {
  writer.appendIndent().append('<' + this.tagName + '>' + this.element.id + '</' + this.tagName + '>').appendNewLine();
};

function BodySerializer() {}

BodySerializer.prototype.serializeValue = BodySerializer.prototype.serializeTo = function (writer) {
  writer.append(this.escape ? escapeBody(this.value) : this.value);
};

BodySerializer.prototype.build = function (prop, value) {
  this.value = value;

  if (prop.type === 'String' && value.search(ESCAPE_CHARS) !== -1) {
    this.escape = true;
  }

  return this;
};

function ValueSerializer(tagName) {
  this.tagName = tagName;
}

inherits(ValueSerializer, BodySerializer);

ValueSerializer.prototype.serializeTo = function (writer) {
  writer.appendIndent().append('<' + this.tagName + '>');
  this.serializeValue(writer);
  writer.append('</' + this.tagName + '>').appendNewLine();
};

function ElementSerializer(parent, propertyDescriptor) {
  this.body = [];
  this.attrs = [];
  this.parent = parent;
  this.propertyDescriptor = propertyDescriptor;
}

ElementSerializer.prototype.build = function (element) {
  this.element = element;
  var elementDescriptor = element.$descriptor,
      propertyDescriptor = this.propertyDescriptor;
  var otherAttrs, properties;
  var isGeneric = elementDescriptor.isGeneric;

  if (isGeneric) {
    otherAttrs = this.parseGeneric(element);
  } else {
    otherAttrs = this.parseNsAttributes(element);
  }

  if (propertyDescriptor) {
    this.ns = this.nsPropertyTagName(propertyDescriptor);
  } else {
    this.ns = this.nsTagName(elementDescriptor);
  } // compute tag name


  this.tagName = this.addTagName(this.ns);

  if (!isGeneric) {
    properties = getSerializableProperties(element);
    this.parseAttributes(filterAttributes(properties));
    this.parseContainments(filterContained(properties));
  }

  this.parseGenericAttributes(element, otherAttrs);
  return this;
};

ElementSerializer.prototype.nsTagName = function (descriptor) {
  var effectiveNs = this.logNamespaceUsed(descriptor.ns);
  return getElementNs(effectiveNs, descriptor);
};

ElementSerializer.prototype.nsPropertyTagName = function (descriptor) {
  var effectiveNs = this.logNamespaceUsed(descriptor.ns);
  return getPropertyNs(effectiveNs, descriptor);
};

ElementSerializer.prototype.isLocalNs = function (ns) {
  return ns.uri === this.ns.uri;
};
/**
 * Get the actual ns attribute name for the given element.
 *
 * @param {Object} element
 * @param {Boolean} [element.inherited=false]
 *
 * @return {Object} nsName
 */


ElementSerializer.prototype.nsAttributeName = function (element) {
  var ns;

  if ((0, _minDash.isString)(element)) {
    ns = (0, _moddle.parseNameNS)(element);
  } else {
    ns = element.ns;
  } // return just local name for inherited attributes


  if (element.inherited) {
    return {
      localName: ns.localName
    };
  } // parse + log effective ns


  var effectiveNs = this.logNamespaceUsed(ns); // LOG ACTUAL namespace use

  this.getNamespaces().logUsed(effectiveNs); // strip prefix if same namespace like parent

  if (this.isLocalNs(effectiveNs)) {
    return {
      localName: ns.localName
    };
  } else {
    return (0, _minDash.assign)({
      localName: ns.localName
    }, effectiveNs);
  }
};

ElementSerializer.prototype.parseGeneric = function (element) {
  var self = this,
      body = this.body;
  var attributes = [];
  (0, _minDash.forEach)(element, function (val, key) {
    var nonNsAttr;

    if (key === '$body') {
      body.push(new BodySerializer().build({
        type: 'String'
      }, val));
    } else if (key === '$children') {
      (0, _minDash.forEach)(val, function (child) {
        body.push(new ElementSerializer(self).build(child));
      });
    } else if (key.indexOf('$') !== 0) {
      nonNsAttr = self.parseNsAttribute(element, key, val);

      if (nonNsAttr) {
        attributes.push({
          name: key,
          value: val
        });
      }
    }
  });
  return attributes;
};

ElementSerializer.prototype.parseNsAttribute = function (element, name, value) {
  var model = element.$model;
  var nameNs = (0, _moddle.parseNameNS)(name);
  var ns; // parse xmlns:foo="http://foo.bar"

  if (nameNs.prefix === 'xmlns') {
    ns = {
      prefix: nameNs.localName,
      uri: value
    };
  } // parse xmlns="http://foo.bar"


  if (!nameNs.prefix && nameNs.localName === 'xmlns') {
    ns = {
      uri: value
    };
  }

  if (!ns) {
    return {
      name: name,
      value: value
    };
  }

  if (model && model.getPackage(value)) {
    // register well known namespace
    this.logNamespace(ns, true, true);
  } else {
    // log custom namespace directly as used
    var actualNs = this.logNamespaceUsed(ns, true);
    this.getNamespaces().logUsed(actualNs);
  }
};
/**
 * Parse namespaces and return a list of left over generic attributes
 *
 * @param  {Object} element
 * @return {Array<Object>}
 */


ElementSerializer.prototype.parseNsAttributes = function (element, attrs) {
  var self = this;
  var genericAttrs = element.$attrs;
  var attributes = []; // parse namespace attributes first
  // and log them. push non namespace attributes to a list
  // and process them later

  (0, _minDash.forEach)(genericAttrs, function (value, name) {
    var nonNsAttr = self.parseNsAttribute(element, name, value);

    if (nonNsAttr) {
      attributes.push(nonNsAttr);
    }
  });
  return attributes;
};

ElementSerializer.prototype.parseGenericAttributes = function (element, attributes) {
  var self = this;
  (0, _minDash.forEach)(attributes, function (attr) {
    // do not serialize xsi:type attribute
    // it is set manually based on the actual implementation type
    if (attr.name === XSI_TYPE) {
      return;
    }

    try {
      self.addAttribute(self.nsAttributeName(attr.name), attr.value);
    } catch (e) {
      console.warn('missing namespace information for ', attr.name, '=', attr.value, 'on', element, e);
    }
  });
};

ElementSerializer.prototype.parseContainments = function (properties) {
  var self = this,
      body = this.body,
      element = this.element;
  (0, _minDash.forEach)(properties, function (p) {
    var value = element.get(p.name),
        isReference = p.isReference,
        isMany = p.isMany;

    if (!isMany) {
      value = [value];
    }

    if (p.isBody) {
      body.push(new BodySerializer().build(p, value[0]));
    } else if ((0, _moddle.isSimpleType)(p.type)) {
      (0, _minDash.forEach)(value, function (v) {
        body.push(new ValueSerializer(self.addTagName(self.nsPropertyTagName(p))).build(p, v));
      });
    } else if (isReference) {
      (0, _minDash.forEach)(value, function (v) {
        body.push(new ReferenceSerializer(self.addTagName(self.nsPropertyTagName(p))).build(v));
      });
    } else {
      // allow serialization via type
      // rather than element name
      var asType = serializeAsType(p),
          asProperty = serializeAsProperty(p);
      (0, _minDash.forEach)(value, function (v) {
        var serializer;

        if (asType) {
          serializer = new TypeSerializer(self, p);
        } else if (asProperty) {
          serializer = new ElementSerializer(self, p);
        } else {
          serializer = new ElementSerializer(self);
        }

        body.push(serializer.build(v));
      });
    }
  });
};

ElementSerializer.prototype.getNamespaces = function (local) {
  var namespaces = this.namespaces,
      parent = this.parent,
      parentNamespaces;

  if (!namespaces) {
    parentNamespaces = parent && parent.getNamespaces();

    if (local || !parentNamespaces) {
      this.namespaces = namespaces = new Namespaces(parentNamespaces);
    } else {
      namespaces = parentNamespaces;
    }
  }

  return namespaces;
};

ElementSerializer.prototype.logNamespace = function (ns, wellknown, local) {
  var namespaces = this.getNamespaces(local);
  var nsUri = ns.uri,
      nsPrefix = ns.prefix;
  var existing = namespaces.byUri(nsUri);

  if (nsPrefix !== 'xml' && (!existing || local)) {
    namespaces.add(ns, wellknown);
  }

  namespaces.mapPrefix(nsPrefix, nsUri);
  return ns;
};

ElementSerializer.prototype.logNamespaceUsed = function (ns, local) {
  var element = this.element,
      model = element.$model,
      namespaces = this.getNamespaces(local); // ns may be
  //
  //   * prefix only
  //   * prefix:uri
  //   * localName only

  var prefix = ns.prefix,
      uri = ns.uri,
      newPrefix,
      idx,
      wellknownUri; // handle anonymous namespaces (elementForm=unqualified), cf. #23

  if (!prefix && !uri) {
    return {
      localName: ns.localName
    };
  }

  wellknownUri = DEFAULT_NS_MAP[prefix] || model && (model.getPackage(prefix) || {}).uri;
  uri = uri || wellknownUri || namespaces.uriByPrefix(prefix);

  if (!uri) {
    throw new Error('no namespace uri given for prefix <' + prefix + '>');
  }

  ns = namespaces.byUri(uri);

  if (!ns) {
    newPrefix = prefix;
    idx = 1; // find a prefix that is not mapped yet

    while (namespaces.uriByPrefix(newPrefix)) {
      newPrefix = prefix + '_' + idx++;
    }

    ns = this.logNamespace({
      prefix: newPrefix,
      uri: uri
    }, wellknownUri === uri);
  }

  if (prefix) {
    namespaces.mapPrefix(prefix, uri);
  }

  return ns;
};

ElementSerializer.prototype.parseAttributes = function (properties) {
  var self = this,
      element = this.element;
  (0, _minDash.forEach)(properties, function (p) {
    var value = element.get(p.name);

    if (p.isReference) {
      if (!p.isMany) {
        value = value.id;
      } else {
        var values = [];
        (0, _minDash.forEach)(value, function (v) {
          values.push(v.id);
        }); // IDREFS is a whitespace-separated list of references.

        value = values.join(' ');
      }
    }

    self.addAttribute(self.nsAttributeName(p), value);
  });
};

ElementSerializer.prototype.addTagName = function (nsTagName) {
  var actualNs = this.logNamespaceUsed(nsTagName);
  this.getNamespaces().logUsed(actualNs);
  return nsName(nsTagName);
};

ElementSerializer.prototype.addAttribute = function (name, value) {
  var attrs = this.attrs;

  if ((0, _minDash.isString)(value)) {
    value = escapeAttr(value);
  }

  attrs.push({
    name: name,
    value: value
  });
};

ElementSerializer.prototype.serializeAttributes = function (writer) {
  var attrs = this.attrs,
      namespaces = this.namespaces;

  if (namespaces) {
    attrs = getNsAttrs(namespaces).concat(attrs);
  }

  (0, _minDash.forEach)(attrs, function (a) {
    writer.append(' ').append(nsName(a.name)).append('="').append(a.value).append('"');
  });
};

ElementSerializer.prototype.serializeTo = function (writer) {
  var firstBody = this.body[0],
      indent = firstBody && firstBody.constructor !== BodySerializer;
  writer.appendIndent().append('<' + this.tagName);
  this.serializeAttributes(writer);
  writer.append(firstBody ? '>' : ' />');

  if (firstBody) {
    if (indent) {
      writer.appendNewLine().indent();
    }

    (0, _minDash.forEach)(this.body, function (b) {
      b.serializeTo(writer);
    });

    if (indent) {
      writer.unindent().appendIndent();
    }

    writer.append('</' + this.tagName + '>');
  }

  writer.appendNewLine();
};
/**
 * A serializer for types that handles serialization of data types
 */


function TypeSerializer(parent, propertyDescriptor) {
  ElementSerializer.call(this, parent, propertyDescriptor);
}

inherits(TypeSerializer, ElementSerializer);

TypeSerializer.prototype.parseNsAttributes = function (element) {
  // extracted attributes
  var attributes = ElementSerializer.prototype.parseNsAttributes.call(this, element);
  var descriptor = element.$descriptor; // only serialize xsi:type if necessary

  if (descriptor.name === this.propertyDescriptor.type) {
    return attributes;
  }

  var typeNs = this.typeNs = this.nsTagName(descriptor);
  this.getNamespaces().logUsed(this.typeNs); // add xsi:type attribute to represent the elements
  // actual type

  var pkg = element.$model.getPackage(typeNs.uri),
      typePrefix = pkg.xml && pkg.xml.typePrefix || '';
  this.addAttribute(this.nsAttributeName(XSI_TYPE), (typeNs.prefix ? typeNs.prefix + ':' : '') + typePrefix + descriptor.ns.localName);
  return attributes;
};

TypeSerializer.prototype.isLocalNs = function (ns) {
  return ns.uri === (this.typeNs || this.ns).uri;
};

function SavingWriter() {
  this.value = '';

  this.write = function (str) {
    this.value += str;
  };
}

function FormatingWriter(out, format) {
  var indent = [''];

  this.append = function (str) {
    out.write(str);
    return this;
  };

  this.appendNewLine = function () {
    if (format) {
      out.write('\n');
    }

    return this;
  };

  this.appendIndent = function () {
    if (format) {
      out.write(indent.join('  '));
    }

    return this;
  };

  this.indent = function () {
    indent.push('');
    return this;
  };

  this.unindent = function () {
    indent.pop();
    return this;
  };
}
/**
 * A writer for meta-model backed document trees
 *
 * @param {Object} options output options to pass into the writer
 */


function Writer(options) {
  options = (0, _minDash.assign)({
    format: false,
    preamble: true
  }, options || {});

  function toXML(tree, writer) {
    var internalWriter = writer || new SavingWriter();
    var formatingWriter = new FormatingWriter(internalWriter, options.format);

    if (options.preamble) {
      formatingWriter.append(XML_PREAMBLE);
    }

    new ElementSerializer().build(tree).serializeTo(formatingWriter);

    if (!writer) {
      return internalWriter.value;
    }
  }

  return {
    toXML: toXML
  };
}

},{"min-dash":555,"moddle":559,"saxen":564}],559:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Moddle = Moddle;
exports.coerceType = coerceType;
exports.isBuiltInType = isBuiltIn;
exports.isSimpleType = isSimple;
exports.parseNameNS = parseName;

var _minDash = require("min-dash");

/**
 * Moddle base element.
 */
function Base() {}

Base.prototype.get = function (name) {
  return this.$model.properties.get(this, name);
};

Base.prototype.set = function (name, value) {
  this.$model.properties.set(this, name, value);
};
/**
 * A model element factory.
 *
 * @param {Moddle} model
 * @param {Properties} properties
 */


function Factory(model, properties) {
  this.model = model;
  this.properties = properties;
}

Factory.prototype.createType = function (descriptor) {
  var model = this.model;
  var props = this.properties,
      prototype = Object.create(Base.prototype); // initialize default values

  (0, _minDash.forEach)(descriptor.properties, function (p) {
    if (!p.isMany && p.default !== undefined) {
      prototype[p.name] = p.default;
    }
  });
  props.defineModel(prototype, model);
  props.defineDescriptor(prototype, descriptor);
  var name = descriptor.ns.name;
  /**
   * The new type constructor
   */

  function ModdleElement(attrs) {
    props.define(this, '$type', {
      value: name,
      enumerable: true
    });
    props.define(this, '$attrs', {
      value: {}
    });
    props.define(this, '$parent', {
      writable: true
    });
    (0, _minDash.forEach)(attrs, (0, _minDash.bind)(function (val, key) {
      this.set(key, val);
    }, this));
  }

  ModdleElement.prototype = prototype;
  ModdleElement.hasType = prototype.$instanceOf = this.model.hasType; // static links

  props.defineModel(ModdleElement, model);
  props.defineDescriptor(ModdleElement, descriptor);
  return ModdleElement;
};
/**
 * Built-in moddle types
 */


var BUILTINS = {
  String: true,
  Boolean: true,
  Integer: true,
  Real: true,
  Element: true
};
/**
 * Converters for built in types from string representations
 */

var TYPE_CONVERTERS = {
  String: function (s) {
    return s;
  },
  Boolean: function (s) {
    return s === 'true';
  },
  Integer: function (s) {
    return parseInt(s, 10);
  },
  Real: function (s) {
    return parseFloat(s, 10);
  }
};
/**
 * Convert a type to its real representation
 */

function coerceType(type, value) {
  var converter = TYPE_CONVERTERS[type];

  if (converter) {
    return converter(value);
  } else {
    return value;
  }
}
/**
 * Return whether the given type is built-in
 */


function isBuiltIn(type) {
  return !!BUILTINS[type];
}
/**
 * Return whether the given type is simple
 */


function isSimple(type) {
  return !!TYPE_CONVERTERS[type];
}
/**
 * Parses a namespaced attribute name of the form (ns:)localName to an object,
 * given a default prefix to assume in case no explicit namespace is given.
 *
 * @param {String} name
 * @param {String} [defaultPrefix] the default prefix to take, if none is present.
 *
 * @return {Object} the parsed name
 */


function parseName(name, defaultPrefix) {
  var parts = name.split(/:/),
      localName,
      prefix; // no prefix (i.e. only local name)

  if (parts.length === 1) {
    localName = name;
    prefix = defaultPrefix;
  } else // prefix + local name
    if (parts.length === 2) {
      localName = parts[1];
      prefix = parts[0];
    } else {
      throw new Error('expected <prefix:localName> or <localName>, got ' + name);
    }

  name = (prefix ? prefix + ':' : '') + localName;
  return {
    name: name,
    prefix: prefix,
    localName: localName
  };
}
/**
 * A utility to build element descriptors.
 */


function DescriptorBuilder(nameNs) {
  this.ns = nameNs;
  this.name = nameNs.name;
  this.allTypes = [];
  this.allTypesByName = {};
  this.properties = [];
  this.propertiesByName = {};
}

DescriptorBuilder.prototype.build = function () {
  return (0, _minDash.pick)(this, ['ns', 'name', 'allTypes', 'allTypesByName', 'properties', 'propertiesByName', 'bodyProperty', 'idProperty']);
};
/**
 * Add property at given index.
 *
 * @param {Object} p
 * @param {Number} [idx]
 * @param {Boolean} [validate=true]
 */


DescriptorBuilder.prototype.addProperty = function (p, idx, validate) {
  if (typeof idx === 'boolean') {
    validate = idx;
    idx = undefined;
  }

  this.addNamedProperty(p, validate !== false);
  var properties = this.properties;

  if (idx !== undefined) {
    properties.splice(idx, 0, p);
  } else {
    properties.push(p);
  }
};

DescriptorBuilder.prototype.replaceProperty = function (oldProperty, newProperty, replace) {
  var oldNameNs = oldProperty.ns;
  var props = this.properties,
      propertiesByName = this.propertiesByName,
      rename = oldProperty.name !== newProperty.name;

  if (oldProperty.isId) {
    if (!newProperty.isId) {
      throw new Error('property <' + newProperty.ns.name + '> must be id property ' + 'to refine <' + oldProperty.ns.name + '>');
    }

    this.setIdProperty(newProperty, false);
  }

  if (oldProperty.isBody) {
    if (!newProperty.isBody) {
      throw new Error('property <' + newProperty.ns.name + '> must be body property ' + 'to refine <' + oldProperty.ns.name + '>');
    } // TODO: Check compatibility


    this.setBodyProperty(newProperty, false);
  } // validate existence and get location of old property


  var idx = props.indexOf(oldProperty);

  if (idx === -1) {
    throw new Error('property <' + oldNameNs.name + '> not found in property list');
  } // remove old property


  props.splice(idx, 1); // replacing the named property is intentional
  //
  //  * validate only if this is a "rename" operation
  //  * add at specific index unless we "replace"
  //

  this.addProperty(newProperty, replace ? undefined : idx, rename); // make new property available under old name

  propertiesByName[oldNameNs.name] = propertiesByName[oldNameNs.localName] = newProperty;
};

DescriptorBuilder.prototype.redefineProperty = function (p, targetPropertyName, replace) {
  var nsPrefix = p.ns.prefix;
  var parts = targetPropertyName.split('#');
  var name = parseName(parts[0], nsPrefix);
  var attrName = parseName(parts[1], name.prefix).name;
  var redefinedProperty = this.propertiesByName[attrName];

  if (!redefinedProperty) {
    throw new Error('refined property <' + attrName + '> not found');
  } else {
    this.replaceProperty(redefinedProperty, p, replace);
  }

  delete p.redefines;
};

DescriptorBuilder.prototype.addNamedProperty = function (p, validate) {
  var ns = p.ns,
      propsByName = this.propertiesByName;

  if (validate) {
    this.assertNotDefined(p, ns.name);
    this.assertNotDefined(p, ns.localName);
  }

  propsByName[ns.name] = propsByName[ns.localName] = p;
};

DescriptorBuilder.prototype.removeNamedProperty = function (p) {
  var ns = p.ns,
      propsByName = this.propertiesByName;
  delete propsByName[ns.name];
  delete propsByName[ns.localName];
};

DescriptorBuilder.prototype.setBodyProperty = function (p, validate) {
  if (validate && this.bodyProperty) {
    throw new Error('body property defined multiple times ' + '(<' + this.bodyProperty.ns.name + '>, <' + p.ns.name + '>)');
  }

  this.bodyProperty = p;
};

DescriptorBuilder.prototype.setIdProperty = function (p, validate) {
  if (validate && this.idProperty) {
    throw new Error('id property defined multiple times ' + '(<' + this.idProperty.ns.name + '>, <' + p.ns.name + '>)');
  }

  this.idProperty = p;
};

DescriptorBuilder.prototype.assertNotDefined = function (p, name) {
  var propertyName = p.name,
      definedProperty = this.propertiesByName[propertyName];

  if (definedProperty) {
    throw new Error('property <' + propertyName + '> already defined; ' + 'override of <' + definedProperty.definedBy.ns.name + '#' + definedProperty.ns.name + '> by ' + '<' + p.definedBy.ns.name + '#' + p.ns.name + '> not allowed without redefines');
  }
};

DescriptorBuilder.prototype.hasProperty = function (name) {
  return this.propertiesByName[name];
};

DescriptorBuilder.prototype.addTrait = function (t, inherited) {
  var typesByName = this.allTypesByName,
      types = this.allTypes;
  var typeName = t.name;

  if (typeName in typesByName) {
    return;
  }

  (0, _minDash.forEach)(t.properties, (0, _minDash.bind)(function (p) {
    // clone property to allow extensions
    p = (0, _minDash.assign)({}, p, {
      name: p.ns.localName,
      inherited: inherited
    });
    Object.defineProperty(p, 'definedBy', {
      value: t
    });
    var replaces = p.replaces,
        redefines = p.redefines; // add replace/redefine support

    if (replaces || redefines) {
      this.redefineProperty(p, replaces || redefines, replaces);
    } else {
      if (p.isBody) {
        this.setBodyProperty(p);
      }

      if (p.isId) {
        this.setIdProperty(p);
      }

      this.addProperty(p);
    }
  }, this));
  types.push(t);
  typesByName[typeName] = t;
};
/**
 * A registry of Moddle packages.
 *
 * @param {Array<Package>} packages
 * @param {Properties} properties
 */


function Registry(packages, properties) {
  this.packageMap = {};
  this.typeMap = {};
  this.packages = [];
  this.properties = properties;
  (0, _minDash.forEach)(packages, (0, _minDash.bind)(this.registerPackage, this));
}

Registry.prototype.getPackage = function (uriOrPrefix) {
  return this.packageMap[uriOrPrefix];
};

Registry.prototype.getPackages = function () {
  return this.packages;
};

Registry.prototype.registerPackage = function (pkg) {
  // copy package
  pkg = (0, _minDash.assign)({}, pkg);
  var pkgMap = this.packageMap;
  ensureAvailable(pkgMap, pkg, 'prefix');
  ensureAvailable(pkgMap, pkg, 'uri'); // register types

  (0, _minDash.forEach)(pkg.types, (0, _minDash.bind)(function (descriptor) {
    this.registerType(descriptor, pkg);
  }, this));
  pkgMap[pkg.uri] = pkgMap[pkg.prefix] = pkg;
  this.packages.push(pkg);
};
/**
 * Register a type from a specific package with us
 */


Registry.prototype.registerType = function (type, pkg) {
  type = (0, _minDash.assign)({}, type, {
    superClass: (type.superClass || []).slice(),
    extends: (type.extends || []).slice(),
    properties: (type.properties || []).slice(),
    meta: (0, _minDash.assign)(type.meta || {})
  });
  var ns = parseName(type.name, pkg.prefix),
      name = ns.name,
      propertiesByName = {}; // parse properties

  (0, _minDash.forEach)(type.properties, (0, _minDash.bind)(function (p) {
    // namespace property names
    var propertyNs = parseName(p.name, ns.prefix),
        propertyName = propertyNs.name; // namespace property types

    if (!isBuiltIn(p.type)) {
      p.type = parseName(p.type, propertyNs.prefix).name;
    }

    (0, _minDash.assign)(p, {
      ns: propertyNs,
      name: propertyName
    });
    propertiesByName[propertyName] = p;
  }, this)); // update ns + name

  (0, _minDash.assign)(type, {
    ns: ns,
    name: name,
    propertiesByName: propertiesByName
  });
  (0, _minDash.forEach)(type.extends, (0, _minDash.bind)(function (extendsName) {
    var extended = this.typeMap[extendsName];
    extended.traits = extended.traits || [];
    extended.traits.push(name);
  }, this)); // link to package

  this.definePackage(type, pkg); // register

  this.typeMap[name] = type;
};
/**
 * Traverse the type hierarchy from bottom to top,
 * calling iterator with (type, inherited) for all elements in
 * the inheritance chain.
 *
 * @param {Object} nsName
 * @param {Function} iterator
 * @param {Boolean} [trait=false]
 */


Registry.prototype.mapTypes = function (nsName, iterator, trait) {
  var type = isBuiltIn(nsName.name) ? {
    name: nsName.name
  } : this.typeMap[nsName.name];
  var self = this;
  /**
   * Traverse the selected trait.
   *
   * @param {String} cls
   */

  function traverseTrait(cls) {
    return traverseSuper(cls, true);
  }
  /**
   * Traverse the selected super type or trait
   *
   * @param {String} cls
   * @param {Boolean} [trait=false]
   */


  function traverseSuper(cls, trait) {
    var parentNs = parseName(cls, isBuiltIn(cls) ? '' : nsName.prefix);
    self.mapTypes(parentNs, iterator, trait);
  }

  if (!type) {
    throw new Error('unknown type <' + nsName.name + '>');
  }

  (0, _minDash.forEach)(type.superClass, trait ? traverseTrait : traverseSuper); // call iterator with (type, inherited=!trait)

  iterator(type, !trait);
  (0, _minDash.forEach)(type.traits, traverseTrait);
};
/**
 * Returns the effective descriptor for a type.
 *
 * @param  {String} type the namespaced name (ns:localName) of the type
 *
 * @return {Descriptor} the resulting effective descriptor
 */


Registry.prototype.getEffectiveDescriptor = function (name) {
  var nsName = parseName(name);
  var builder = new DescriptorBuilder(nsName);
  this.mapTypes(nsName, function (type, inherited) {
    builder.addTrait(type, inherited);
  });
  var descriptor = builder.build(); // define package link

  this.definePackage(descriptor, descriptor.allTypes[descriptor.allTypes.length - 1].$pkg);
  return descriptor;
};

Registry.prototype.definePackage = function (target, pkg) {
  this.properties.define(target, '$pkg', {
    value: pkg
  });
}; ///////// helpers ////////////////////////////


function ensureAvailable(packageMap, pkg, identifierKey) {
  var value = pkg[identifierKey];

  if (value in packageMap) {
    throw new Error('package with ' + identifierKey + ' <' + value + '> already defined');
  }
}
/**
 * A utility that gets and sets properties of model elements.
 *
 * @param {Model} model
 */


function Properties(model) {
  this.model = model;
}
/**
 * Sets a named property on the target element.
 * If the value is undefined, the property gets deleted.
 *
 * @param {Object} target
 * @param {String} name
 * @param {Object} value
 */


Properties.prototype.set = function (target, name, value) {
  var property = this.model.getPropertyDescriptor(target, name);
  var propertyName = property && property.name;

  if (isUndefined(value)) {
    // unset the property, if the specified value is undefined;
    // delete from $attrs (for extensions) or the target itself
    if (property) {
      delete target[propertyName];
    } else {
      delete target.$attrs[name];
    }
  } else {
    // set the property, defining well defined properties on the fly
    // or simply updating them in target.$attrs (for extensions)
    if (property) {
      if (propertyName in target) {
        target[propertyName] = value;
      } else {
        defineProperty(target, property, value);
      }
    } else {
      target.$attrs[name] = value;
    }
  }
};
/**
 * Returns the named property of the given element
 *
 * @param  {Object} target
 * @param  {String} name
 *
 * @return {Object}
 */


Properties.prototype.get = function (target, name) {
  var property = this.model.getPropertyDescriptor(target, name);

  if (!property) {
    return target.$attrs[name];
  }

  var propertyName = property.name; // check if access to collection property and lazily initialize it

  if (!target[propertyName] && property.isMany) {
    defineProperty(target, property, []);
  }

  return target[propertyName];
};
/**
 * Define a property on the target element
 *
 * @param  {Object} target
 * @param  {String} name
 * @param  {Object} options
 */


Properties.prototype.define = function (target, name, options) {
  Object.defineProperty(target, name, options);
};
/**
 * Define the descriptor for an element
 */


Properties.prototype.defineDescriptor = function (target, descriptor) {
  this.define(target, '$descriptor', {
    value: descriptor
  });
};
/**
 * Define the model for an element
 */


Properties.prototype.defineModel = function (target, model) {
  this.define(target, '$model', {
    value: model
  });
};

function isUndefined(val) {
  return typeof val === 'undefined';
}

function defineProperty(target, property, value) {
  Object.defineProperty(target, property.name, {
    enumerable: !property.isReference,
    writable: true,
    value: value,
    configurable: true
  });
} //// Moddle implementation /////////////////////////////////////////////////

/**
 * @class Moddle
 *
 * A model that can be used to create elements of a specific type.
 *
 * @example
 *
 * var Moddle = require('moddle');
 *
 * var pkg = {
 *   name: 'mypackage',
 *   prefix: 'my',
 *   types: [
 *     { name: 'Root' }
 *   ]
 * };
 *
 * var moddle = new Moddle([pkg]);
 *
 * @param {Array<Package>} packages the packages to contain
 */


function Moddle(packages) {
  this.properties = new Properties(this);
  this.factory = new Factory(this, this.properties);
  this.registry = new Registry(packages, this.properties);
  this.typeCache = {};
}
/**
 * Create an instance of the specified type.
 *
 * @method Moddle#create
 *
 * @example
 *
 * var foo = moddle.create('my:Foo');
 * var bar = moddle.create('my:Bar', { id: 'BAR_1' });
 *
 * @param  {String|Object} descriptor the type descriptor or name know to the model
 * @param  {Object} attrs   a number of attributes to initialize the model instance with
 * @return {Object}         model instance
 */


Moddle.prototype.create = function (descriptor, attrs) {
  var Type = this.getType(descriptor);

  if (!Type) {
    throw new Error('unknown type <' + descriptor + '>');
  }

  return new Type(attrs);
};
/**
 * Returns the type representing a given descriptor
 *
 * @method Moddle#getType
 *
 * @example
 *
 * var Foo = moddle.getType('my:Foo');
 * var foo = new Foo({ 'id' : 'FOO_1' });
 *
 * @param  {String|Object} descriptor the type descriptor or name know to the model
 * @return {Object}         the type representing the descriptor
 */


Moddle.prototype.getType = function (descriptor) {
  var cache = this.typeCache;
  var name = (0, _minDash.isString)(descriptor) ? descriptor : descriptor.ns.name;
  var type = cache[name];

  if (!type) {
    descriptor = this.registry.getEffectiveDescriptor(name);
    type = cache[name] = this.factory.createType(descriptor);
  }

  return type;
};
/**
 * Creates an any-element type to be used within model instances.
 *
 * This can be used to create custom elements that lie outside the meta-model.
 * The created element contains all the meta-data required to serialize it
 * as part of meta-model elements.
 *
 * @method Moddle#createAny
 *
 * @example
 *
 * var foo = moddle.createAny('vendor:Foo', 'http://vendor', {
 *   value: 'bar'
 * });
 *
 * var container = moddle.create('my:Container', 'http://my', {
 *   any: [ foo ]
 * });
 *
 * // go ahead and serialize the stuff
 *
 *
 * @param  {String} name  the name of the element
 * @param  {String} nsUri the namespace uri of the element
 * @param  {Object} [properties] a map of properties to initialize the instance with
 * @return {Object} the any type instance
 */


Moddle.prototype.createAny = function (name, nsUri, properties) {
  var nameNs = parseName(name);
  var element = {
    $type: name,
    $instanceOf: function (type) {
      return type === this.$type;
    }
  };
  var descriptor = {
    name: name,
    isGeneric: true,
    ns: {
      prefix: nameNs.prefix,
      localName: nameNs.localName,
      uri: nsUri
    }
  };
  this.properties.defineDescriptor(element, descriptor);
  this.properties.defineModel(element, this);
  this.properties.define(element, '$parent', {
    enumerable: false,
    writable: true
  });
  (0, _minDash.forEach)(properties, function (a, key) {
    if ((0, _minDash.isObject)(a) && a.value !== undefined) {
      element[a.name] = a.value;
    } else {
      element[key] = a;
    }
  });
  return element;
};
/**
 * Returns a registered package by uri or prefix
 *
 * @return {Object} the package
 */


Moddle.prototype.getPackage = function (uriOrPrefix) {
  return this.registry.getPackage(uriOrPrefix);
};
/**
 * Returns a snapshot of all known packages
 *
 * @return {Object} the package
 */


Moddle.prototype.getPackages = function () {
  return this.registry.getPackages();
};
/**
 * Returns the descriptor for an element
 */


Moddle.prototype.getElementDescriptor = function (element) {
  return element.$descriptor;
};
/**
 * Returns true if the given descriptor or instance
 * represents the given type.
 *
 * May be applied to this, if element is omitted.
 */


Moddle.prototype.hasType = function (element, type) {
  if (type === undefined) {
    type = element;
    element = this;
  }

  var descriptor = element.$model.getElementDescriptor(element);
  return type in descriptor.allTypesByName;
};
/**
 * Returns the descriptor of an elements named property
 */


Moddle.prototype.getPropertyDescriptor = function (element, property) {
  return this.getElementDescriptor(element).propertiesByName[property];
};
/**
 * Returns a mapped type's descriptor
 */


Moddle.prototype.getTypeDescriptor = function (type) {
  return this.registry.typeMap[type];
};

},{"min-dash":555}],560:[function(require,module,exports){
module.exports = require('./lib/refs');

module.exports.Collection = require('./lib/collection');
},{"./lib/collection":561,"./lib/refs":562}],561:[function(require,module,exports){
'use strict';

/**
 * An empty collection stub. Use {@link RefsCollection.extend} to extend a
 * collection with ref semantics.
 *
 * @class RefsCollection
 */

/**
 * Extends a collection with {@link Refs} aware methods
 *
 * @memberof RefsCollection
 * @static
 *
 * @param  {Array<Object>} collection
 * @param  {Refs} refs instance
 * @param  {Object} property represented by the collection
 * @param  {Object} target object the collection is attached to
 *
 * @return {RefsCollection<Object>} the extended array
 */
function extend(collection, refs, property, target) {

  var inverseProperty = property.inverse;

  /**
   * Removes the given element from the array and returns it.
   *
   * @method RefsCollection#remove
   *
   * @param {Object} element the element to remove
   */
  Object.defineProperty(collection, 'remove', {
    value: function(element) {
      var idx = this.indexOf(element);
      if (idx !== -1) {
        this.splice(idx, 1);

        // unset inverse
        refs.unset(element, inverseProperty, target);
      }

      return element;
    }
  });

  /**
   * Returns true if the collection contains the given element
   *
   * @method RefsCollection#contains
   *
   * @param {Object} element the element to check for
   */
  Object.defineProperty(collection, 'contains', {
    value: function(element) {
      return this.indexOf(element) !== -1;
    }
  });

  /**
   * Adds an element to the array, unless it exists already (set semantics).
   *
   * @method RefsCollection#add
   *
   * @param {Object} element the element to add
   * @param {Number} optional index to add element to
   *                 (possibly moving other elements around)
   */
  Object.defineProperty(collection, 'add', {
    value: function(element, idx) {

      var currentIdx = this.indexOf(element);

      if (typeof idx === 'undefined') {

        if (currentIdx !== -1) {
          // element already in collection (!)
          return;
        }

        // add to end of array, as no idx is specified
        idx = this.length;
      }

      // handle already in collection
      if (currentIdx !== -1) {

        // remove element from currentIdx
        this.splice(currentIdx, 1);
      }

      // add element at idx
      this.splice(idx, 0, element);

      if (currentIdx === -1) {
        // set inverse, unless element was
        // in collection already
        refs.set(element, inverseProperty, target);
      }
    }
  });

  // a simple marker, identifying this element
  // as being a refs collection
  Object.defineProperty(collection, '__refs_collection', {
    value: true
  });

  return collection;
}


function isExtended(collection) {
  return collection.__refs_collection === true;
}

module.exports.extend = extend;

module.exports.isExtended = isExtended;
},{}],562:[function(require,module,exports){
'use strict';

var Collection = require('./collection');

function hasOwnProperty(e, property) {
  return Object.prototype.hasOwnProperty.call(e, property.name || property);
}

function defineCollectionProperty(ref, property, target) {

  var collection = Collection.extend(target[property.name] || [], ref, property, target);

  Object.defineProperty(target, property.name, {
    enumerable: property.enumerable,
    value: collection
  });

  if (collection.length) {

    collection.forEach(function(o) {
      ref.set(o, property.inverse, target);
    });
  }
}


function defineProperty(ref, property, target) {

  var inverseProperty = property.inverse;

  var _value = target[property.name];

  Object.defineProperty(target, property.name, {
    configurable: property.configurable,
    enumerable: property.enumerable,

    get: function() {
      return _value;
    },

    set: function(value) {

      // return if we already performed all changes
      if (value === _value) {
        return;
      }

      var old = _value;

      // temporary set null
      _value = null;

      if (old) {
        ref.unset(old, inverseProperty, target);
      }

      // set new value
      _value = value;

      // set inverse value
      ref.set(_value, inverseProperty, target);
    }
  });

}

/**
 * Creates a new references object defining two inversly related
 * attribute descriptors a and b.
 *
 * <p>
 *   When bound to an object using {@link Refs#bind} the references
 *   get activated and ensure that add and remove operations are applied
 *   reversely, too.
 * </p>
 *
 * <p>
 *   For attributes represented as collections {@link Refs} provides the
 *   {@link RefsCollection#add}, {@link RefsCollection#remove} and {@link RefsCollection#contains} extensions
 *   that must be used to properly hook into the inverse change mechanism.
 * </p>
 *
 * @class Refs
 *
 * @classdesc A bi-directional reference between two attributes.
 *
 * @param {Refs.AttributeDescriptor} a property descriptor
 * @param {Refs.AttributeDescriptor} b property descriptor
 *
 * @example
 *
 * var refs = Refs({ name: 'wheels', collection: true, enumerable: true }, { name: 'car' });
 *
 * var car = { name: 'toyota' };
 * var wheels = [{ pos: 'front-left' }, { pos: 'front-right' }];
 *
 * refs.bind(car, 'wheels');
 *
 * car.wheels // []
 * car.wheels.add(wheels[0]);
 * car.wheels.add(wheels[1]);
 *
 * car.wheels // [{ pos: 'front-left' }, { pos: 'front-right' }]
 *
 * wheels[0].car // { name: 'toyota' };
 * car.wheels.remove(wheels[0]);
 *
 * wheels[0].car // undefined
 */
function Refs(a, b) {

  if (!(this instanceof Refs)) {
    return new Refs(a, b);
  }

  // link
  a.inverse = b;
  b.inverse = a;

  this.props = {};
  this.props[a.name] = a;
  this.props[b.name] = b;
}

/**
 * Binds one side of a bi-directional reference to a
 * target object.
 *
 * @memberOf Refs
 *
 * @param  {Object} target
 * @param  {String} property
 */
Refs.prototype.bind = function(target, property) {
  if (typeof property === 'string') {
    if (!this.props[property]) {
      throw new Error('no property <' + property + '> in ref');
    }
    property = this.props[property];
  }

  if (property.collection) {
    defineCollectionProperty(this, property, target);
  } else {
    defineProperty(this, property, target);
  }
};

Refs.prototype.ensureRefsCollection = function(target, property) {

  var collection = target[property.name];

  if (!Collection.isExtended(collection)) {
    defineCollectionProperty(this, property, target);
  }

  return collection;
};

Refs.prototype.ensureBound = function(target, property) {
  if (!hasOwnProperty(target, property)) {
    this.bind(target, property);
  }
};

Refs.prototype.unset = function(target, property, value) {

  if (target) {
    this.ensureBound(target, property);

    if (property.collection) {
      this.ensureRefsCollection(target, property).remove(value);
    } else {
      target[property.name] = undefined;
    }
  }
};

Refs.prototype.set = function(target, property, value) {

  if (target) {
    this.ensureBound(target, property);

    if (property.collection) {
      this.ensureRefsCollection(target, property).add(value);
    } else {
      target[property.name] = value;
    }
  }
};

module.exports = Refs;


/**
 * An attribute descriptor to be used specify an attribute in a {@link Refs} instance
 *
 * @typedef {Object} Refs.AttributeDescriptor
 * @property {String} name
 * @property {boolean} [collection=false]
 * @property {boolean} [enumerable=false]
 */
},{"./collection":561}],563:[function(require,module,exports){
'use strict';

/**
 * This file contains source code adapted from Snap.svg (licensed Apache-2.0).
 *
 * @see https://github.com/adobe-webplatform/Snap.svg/blob/master/src/path.js
 */

/* eslint no-fallthrough: "off" */

var p2s = /,?([a-z]),?/gi,
    toFloat = parseFloat,
    math = Math,
    PI = math.PI,
    mmin = math.min,
    mmax = math.max,
    pow = math.pow,
    abs = math.abs,
    pathCommand = /([a-z])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?[\s]*,?[\s]*)+)/ig,
    pathValues = /(-?\d*\.?\d*(?:e[-+]?\\d+)?)[\s]*,?[\s]*/ig;

var isArray = Array.isArray || function(o) { return o instanceof Array; };

function hasProperty(obj, property) {
  return Object.prototype.hasOwnProperty.call(obj, property);
}

function clone(obj) {

  if (typeof obj == 'function' || Object(obj) !== obj) {
    return obj;
  }

  var res = new obj.constructor;

  for (var key in obj) {
    if (hasProperty(obj, key)) {
      res[key] = clone(obj[key]);
    }
  }

  return res;
}

function repush(array, item) {
  for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {
    return array.push(array.splice(i, 1)[0]);
  }
}

function cacher(f) {

  function newf() {

    var arg = Array.prototype.slice.call(arguments, 0),
        args = arg.join('\u2400'),
        cache = newf.cache = newf.cache || {},
        count = newf.count = newf.count || [];

    if (hasProperty(cache, args)) {
      repush(count, args);
      return cache[args];
    }

    count.length >= 1e3 && delete cache[count.shift()];
    count.push(args);
    cache[args] = f.apply(0, arg);

    return cache[args];
  }
  return newf;
}

function parsePathString(pathString) {

  if (!pathString) {
    return null;
  }

  var pth = paths(pathString);

  if (pth.arr) {
    return clone(pth.arr);
  }

  var paramCounts = { a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0 },
      data = [];

  if (isArray(pathString) && isArray(pathString[0])) { // rough assumption
    data = clone(pathString);
  }

  if (!data.length) {

    String(pathString).replace(pathCommand, function(a, b, c) {
      var params = [],
          name = b.toLowerCase();

      c.replace(pathValues, function(a, b) {
        b && params.push(+b);
      });

      if (name == 'm' && params.length > 2) {
        data.push([b].concat(params.splice(0, 2)));
        name = 'l';
        b = b == 'm' ? 'l' : 'L';
      }

      while (params.length >= paramCounts[name]) {
        data.push([b].concat(params.splice(0, paramCounts[name])));
        if (!paramCounts[name]) {
          break;
        }
      }
    });
  }

  data.toString = paths.toString;
  pth.arr = clone(data);

  return data;
}

function paths(ps) {
  var p = paths.ps = paths.ps || {};

  if (p[ps]) {
    p[ps].sleep = 100;
  } else {
    p[ps] = {
      sleep: 100
    };
  }

  setTimeout(function() {
    for (var key in p) {
      if (hasProperty(p, key) && key != ps) {
        p[key].sleep--;
        !p[key].sleep && delete p[key];
      }
    }
  });

  return p[ps];
}

function rectBBox(x, y, width, height) {

  if (arguments.length === 1) {
    y = x.y;
    width = x.width;
    height = x.height;
    x = x.x;
  }

  return {
    x: x,
    y: y,
    width: width,
    height: height,
    x2: x + width,
    y2: y + height
  };
}

function pathToString() {
  return this.join(',').replace(p2s, '$1');
}

function pathClone(pathArray) {
  var res = clone(pathArray);
  res.toString = pathToString;
  return res;
}

function findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
  var t1 = 1 - t,
      t13 = pow(t1, 3),
      t12 = pow(t1, 2),
      t2 = t * t,
      t3 = t2 * t,
      x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x,
      y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y;

  return {
    x: fixError(x),
    y: fixError(y)
  };
}

function bezierBBox(points) {

  var bbox = curveBBox.apply(null, points);

  return rectBBox(
    bbox.x0,
    bbox.y0,
    bbox.x1 - bbox.x0,
    bbox.y1 - bbox.y0
  );
}

function isPointInsideBBox(bbox, x, y) {
  return x >= bbox.x &&
    x <= bbox.x + bbox.width &&
    y >= bbox.y &&
    y <= bbox.y + bbox.height;
}

function isBBoxIntersect(bbox1, bbox2) {
  bbox1 = rectBBox(bbox1);
  bbox2 = rectBBox(bbox2);
  return isPointInsideBBox(bbox2, bbox1.x, bbox1.y)
    || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y)
    || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2)
    || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2)
    || isPointInsideBBox(bbox1, bbox2.x, bbox2.y)
    || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y)
    || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2)
    || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2)
    || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x
        || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x)
    && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y
        || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y);
}

function base3(t, p1, p2, p3, p4) {
  var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4,
      t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;
  return t * t2 - 3 * p1 + 3 * p2;
}

function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) {

  if (z == null) {
    z = 1;
  }

  z = z > 1 ? 1 : z < 0 ? 0 : z;

  var z2 = z / 2,
      n = 12,
      Tvalues = [-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],
      Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472],
      sum = 0;

  for (var i = 0; i < n; i++) {
    var ct = z2 * Tvalues[i] + z2,
        xbase = base3(ct, x1, x2, x3, x4),
        ybase = base3(ct, y1, y2, y3, y4),
        comb = xbase * xbase + ybase * ybase;

    sum += Cvalues[i] * math.sqrt(comb);
  }

  return z2 * sum;
}


function intersectLines(x1, y1, x2, y2, x3, y3, x4, y4) {

  if (
    mmax(x1, x2) < mmin(x3, x4) ||
      mmin(x1, x2) > mmax(x3, x4) ||
      mmax(y1, y2) < mmin(y3, y4) ||
      mmin(y1, y2) > mmax(y3, y4)
  ) {
    return;
  }

  var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4),
      ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4),
      denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);

  if (!denominator) {
    return;
  }

  var px = fixError(nx / denominator),
      py = fixError(ny / denominator),
      px2 = +px.toFixed(2),
      py2 = +py.toFixed(2);

  if (
    px2 < +mmin(x1, x2).toFixed(2) ||
      px2 > +mmax(x1, x2).toFixed(2) ||
      px2 < +mmin(x3, x4).toFixed(2) ||
      px2 > +mmax(x3, x4).toFixed(2) ||
      py2 < +mmin(y1, y2).toFixed(2) ||
      py2 > +mmax(y1, y2).toFixed(2) ||
      py2 < +mmin(y3, y4).toFixed(2) ||
      py2 > +mmax(y3, y4).toFixed(2)
  ) {
    return;
  }

  return { x: px, y: py };
}

function fixError(number) {
  return Math.round(number * 100000000000) / 100000000000;
}

function findBezierIntersections(bez1, bez2, justCount) {
  var bbox1 = bezierBBox(bez1),
      bbox2 = bezierBBox(bez2);

  if (!isBBoxIntersect(bbox1, bbox2)) {
    return justCount ? 0 : [];
  }

  // As an optimization, lines will have only 1 segment

  var l1 = bezlen.apply(0, bez1),
      l2 = bezlen.apply(0, bez2),
      n1 = isLine(bez1) ? 1 : ~~(l1 / 5) || 1,
      n2 = isLine(bez2) ? 1 : ~~(l2 / 5) || 1,
      dots1 = [],
      dots2 = [],
      xy = {},
      res = justCount ? 0 : [];

  for (var i = 0; i < n1 + 1; i++) {
    var p = findDotsAtSegment.apply(0, bez1.concat(i / n1));
    dots1.push({ x: p.x, y: p.y, t: i / n1 });
  }

  for (i = 0; i < n2 + 1; i++) {
    p = findDotsAtSegment.apply(0, bez2.concat(i / n2));
    dots2.push({ x: p.x, y: p.y, t: i / n2 });
  }

  for (i = 0; i < n1; i++) {

    for (var j = 0; j < n2; j++) {
      var di = dots1[i],
          di1 = dots1[i + 1],
          dj = dots2[j],
          dj1 = dots2[j + 1],
          ci = abs(di1.x - di.x) < .01 ? 'y' : 'x',
          cj = abs(dj1.x - dj.x) < .01 ? 'y' : 'x',
          is = intersectLines(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y),
          key;

      if (is) {
        key = is.x.toFixed(9) + '#' + is.y.toFixed(9);

        if (xy[key]) {
          continue;
        }

        xy[key] = true;

        var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t),
            t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t);

        if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {

          if (justCount) {
            res++;
          } else {
            res.push({
              x: is.x,
              y: is.y,
              t1: t1,
              t2: t2
            });
          }
        }
      }
    }
  }

  return res;
}


/**
 * Find or counts the intersections between two SVG paths.
 *
 * Returns a number in counting mode and a list of intersections otherwise.
 *
 * A single intersection entry contains the intersection coordinates (x, y)
 * as well as additional information regarding the intersecting segments
 * on each path (segment1, segment2) and the relative location of the
 * intersection on these segments (t1, t2).
 *
 * The path may be an SVG path string or a list of path components
 * such as `[ [ 'M', 0, 10 ], [ 'L', 20, 0 ] ]`.
 *
 * @example
 *
 * var intersections = findPathIntersections(
 *   'M0,0L100,100',
 *   [ [ 'M', 0, 100 ], [ 'L', 100, 0 ] ]
 * );
 *
 * // intersections = [
 * //   { x: 50, y: 50, segment1: 1, segment2: 1, t1: 0.5, t2: 0.5 }
 * // ]
 *
 * @param {String|Array<PathDef>} path1
 * @param {String|Array<PathDef>} path2
 * @param {Boolean} [justCount=false]
 *
 * @return {Array<Intersection>|Number}
 */
function findPathIntersections(path1, path2, justCount) {
  path1 = pathToCurve(path1);
  path2 = pathToCurve(path2);

  var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2,
      res = justCount ? 0 : [];

  for (var i = 0, ii = path1.length; i < ii; i++) {
    var pi = path1[i];

    if (pi[0] == 'M') {
      x1 = x1m = pi[1];
      y1 = y1m = pi[2];
    } else {

      if (pi[0] == 'C') {
        bez1 = [x1, y1].concat(pi.slice(1));
        x1 = bez1[6];
        y1 = bez1[7];
      } else {
        bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m];
        x1 = x1m;
        y1 = y1m;
      }

      for (var j = 0, jj = path2.length; j < jj; j++) {
        var pj = path2[j];

        if (pj[0] == 'M') {
          x2 = x2m = pj[1];
          y2 = y2m = pj[2];
        } else {

          if (pj[0] == 'C') {
            bez2 = [x2, y2].concat(pj.slice(1));
            x2 = bez2[6];
            y2 = bez2[7];
          } else {
            bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m];
            x2 = x2m;
            y2 = y2m;
          }

          var intr = findBezierIntersections(bez1, bez2, justCount);

          if (justCount) {
            res += intr;
          } else {

            for (var k = 0, kk = intr.length; k < kk; k++) {
              intr[k].segment1 = i;
              intr[k].segment2 = j;
              intr[k].bez1 = bez1;
              intr[k].bez2 = bez2;
            }

            res = res.concat(intr);
          }
        }
      }
    }
  }

  return res;
}


function pathToAbsolute(pathArray) {
  var pth = paths(pathArray);

  if (pth.abs) {
    return pathClone(pth.abs);
  }

  if (!isArray(pathArray) || !isArray(pathArray && pathArray[0])) { // rough assumption
    pathArray = parsePathString(pathArray);
  }

  if (!pathArray || !pathArray.length) {
    return [['M', 0, 0]];
  }

  var res = [],
      x = 0,
      y = 0,
      mx = 0,
      my = 0,
      start = 0,
      pa0;

  if (pathArray[0][0] == 'M') {
    x = +pathArray[0][1];
    y = +pathArray[0][2];
    mx = x;
    my = y;
    start++;
    res[0] = ['M', x, y];
  }

  for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {
    res.push(r = []);
    pa = pathArray[i];
    pa0 = pa[0];

    if (pa0 != pa0.toUpperCase()) {
      r[0] = pa0.toUpperCase();

      switch (r[0]) {
      case 'A':
        r[1] = pa[1];
        r[2] = pa[2];
        r[3] = pa[3];
        r[4] = pa[4];
        r[5] = pa[5];
        r[6] = +pa[6] + x;
        r[7] = +pa[7] + y;
        break;
      case 'V':
        r[1] = +pa[1] + y;
        break;
      case 'H':
        r[1] = +pa[1] + x;
        break;
      case 'M':
        mx = +pa[1] + x;
        my = +pa[2] + y;
      default:
        for (var j = 1, jj = pa.length; j < jj; j++) {
          r[j] = +pa[j] + ((j % 2) ? x : y);
        }
      }
    } else {
      for (var k = 0, kk = pa.length; k < kk; k++) {
        r[k] = pa[k];
      }
    }
    pa0 = pa0.toUpperCase();

    switch (r[0]) {
    case 'Z':
      x = +mx;
      y = +my;
      break;
    case 'H':
      x = r[1];
      break;
    case 'V':
      y = r[1];
      break;
    case 'M':
      mx = r[r.length - 2];
      my = r[r.length - 1];
    default:
      x = r[r.length - 2];
      y = r[r.length - 1];
    }
  }

  res.toString = pathToString;
  pth.abs = pathClone(res);

  return res;
}

function isLine(bez) {
  return (
    bez[0] === bez[2] &&
    bez[1] === bez[3] &&
    bez[4] === bez[6] &&
    bez[5] === bez[7]
  );
}

function lineToCurve(x1, y1, x2, y2) {
  return [
    x1, y1, x2,
    y2, x2, y2
  ];
}

function qubicToCurve(x1, y1, ax, ay, x2, y2) {
  var _13 = 1 / 3,
      _23 = 2 / 3;

  return [
    _13 * x1 + _23 * ax,
    _13 * y1 + _23 * ay,
    _13 * x2 + _23 * ax,
    _13 * y2 + _23 * ay,
    x2,
    y2
  ];
}

function arcToCurve(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {

  // for more information of where this math came from visit:
  // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
  var _120 = PI * 120 / 180,
      rad = PI / 180 * (+angle || 0),
      res = [],
      xy,
      rotate = cacher(function(x, y, rad) {
        var X = x * math.cos(rad) - y * math.sin(rad),
            Y = x * math.sin(rad) + y * math.cos(rad);

        return { x: X, y: Y };
      });

  if (!recursive) {
    xy = rotate(x1, y1, -rad);
    x1 = xy.x;
    y1 = xy.y;
    xy = rotate(x2, y2, -rad);
    x2 = xy.x;
    y2 = xy.y;

    var x = (x1 - x2) / 2,
        y = (y1 - y2) / 2;

    var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);

    if (h > 1) {
      h = math.sqrt(h);
      rx = h * rx;
      ry = h * ry;
    }

    var rx2 = rx * rx,
        ry2 = ry * ry,
        k = (large_arc_flag == sweep_flag ? -1 : 1) *
            math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),
        cx = k * rx * y / ry + (x1 + x2) / 2,
        cy = k * -ry * x / rx + (y1 + y2) / 2,
        f1 = math.asin(((y1 - cy) / ry).toFixed(9)),
        f2 = math.asin(((y2 - cy) / ry).toFixed(9));

    f1 = x1 < cx ? PI - f1 : f1;
    f2 = x2 < cx ? PI - f2 : f2;
    f1 < 0 && (f1 = PI * 2 + f1);
    f2 < 0 && (f2 = PI * 2 + f2);

    if (sweep_flag && f1 > f2) {
      f1 = f1 - PI * 2;
    }
    if (!sweep_flag && f2 > f1) {
      f2 = f2 - PI * 2;
    }
  } else {
    f1 = recursive[0];
    f2 = recursive[1];
    cx = recursive[2];
    cy = recursive[3];
  }

  var df = f2 - f1;

  if (abs(df) > _120) {
    var f2old = f2,
        x2old = x2,
        y2old = y2;

    f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
    x2 = cx + rx * math.cos(f2);
    y2 = cy + ry * math.sin(f2);
    res = arcToCurve(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
  }

  df = f2 - f1;

  var c1 = math.cos(f1),
      s1 = math.sin(f1),
      c2 = math.cos(f2),
      s2 = math.sin(f2),
      t = math.tan(df / 4),
      hx = 4 / 3 * rx * t,
      hy = 4 / 3 * ry * t,
      m1 = [x1, y1],
      m2 = [x1 + hx * s1, y1 - hy * c1],
      m3 = [x2 + hx * s2, y2 - hy * c2],
      m4 = [x2, y2];

  m2[0] = 2 * m1[0] - m2[0];
  m2[1] = 2 * m1[1] - m2[1];

  if (recursive) {
    return [m2, m3, m4].concat(res);
  } else {
    res = [m2, m3, m4].concat(res).join().split(',');
    var newres = [];

    for (var i = 0, ii = res.length; i < ii; i++) {
      newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
    }

    return newres;
  }
}

// Returns bounding box of cubic bezier curve.
// Source: http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
// Original version: NISHIO Hirokazu
// Modifications: https://github.com/timo22345
function curveBBox(x0, y0, x1, y1, x2, y2, x3, y3) {
  var tvalues = [],
      bounds = [[], []],
      a, b, c, t, t1, t2, b2ac, sqrtb2ac;

  for (var i = 0; i < 2; ++i) {

    if (i == 0) {
      b = 6 * x0 - 12 * x1 + 6 * x2;
      a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
      c = 3 * x1 - 3 * x0;
    } else {
      b = 6 * y0 - 12 * y1 + 6 * y2;
      a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
      c = 3 * y1 - 3 * y0;
    }

    if (abs(a) < 1e-12) {

      if (abs(b) < 1e-12) {
        continue;
      }

      t = -c / b;

      if (0 < t && t < 1) {
        tvalues.push(t);
      }

      continue;
    }

    b2ac = b * b - 4 * c * a;
    sqrtb2ac = math.sqrt(b2ac);

    if (b2ac < 0) {
      continue;
    }

    t1 = (-b + sqrtb2ac) / (2 * a);

    if (0 < t1 && t1 < 1) {
      tvalues.push(t1);
    }

    t2 = (-b - sqrtb2ac) / (2 * a);

    if (0 < t2 && t2 < 1) {
      tvalues.push(t2);
    }
  }

  var j = tvalues.length,
      jlen = j,
      mt;

  while (j--) {
    t = tvalues[j];
    mt = 1 - t;
    bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);
    bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);
  }

  bounds[0][jlen] = x0;
  bounds[1][jlen] = y0;
  bounds[0][jlen + 1] = x3;
  bounds[1][jlen + 1] = y3;
  bounds[0].length = bounds[1].length = jlen + 2;

  return {
    x0: mmin.apply(0, bounds[0]),
    y0: mmin.apply(0, bounds[1]),
    x1: mmax.apply(0, bounds[0]),
    y1: mmax.apply(0, bounds[1])
  };
}

function pathToCurve(path) {

  var pth = paths(path);

  // return cached curve, if existing
  if (pth.curve) {
    return pathClone(pth.curve);
  }

  var curvedPath = pathToAbsolute(path),
      attrs = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null },
      processPath = function(path, d, pathCommand) {
        var nx, ny;

        if (!path) {
          return ['C', d.x, d.y, d.x, d.y, d.x, d.y];
        }

        !(path[0] in { T: 1, Q: 1 }) && (d.qx = d.qy = null);

        switch (path[0]) {
        case 'M':
          d.X = path[1];
          d.Y = path[2];
          break;
        case 'A':
          path = ['C'].concat(arcToCurve.apply(0, [d.x, d.y].concat(path.slice(1))));
          break;
        case 'S':
          if (pathCommand == 'C' || pathCommand == 'S') {
            // In 'S' case we have to take into account, if the previous command is C/S.
            nx = d.x * 2 - d.bx;
            // And reflect the previous
            ny = d.y * 2 - d.by;
            // command's control point relative to the current point.
          }
          else {
            // or some else or nothing
            nx = d.x;
            ny = d.y;
          }
          path = ['C', nx, ny].concat(path.slice(1));
          break;
        case 'T':
          if (pathCommand == 'Q' || pathCommand == 'T') {
            // In 'T' case we have to take into account, if the previous command is Q/T.
            d.qx = d.x * 2 - d.qx;
            // And make a reflection similar
            d.qy = d.y * 2 - d.qy;
            // to case 'S'.
          }
          else {
            // or something else or nothing
            d.qx = d.x;
            d.qy = d.y;
          }
          path = ['C'].concat(qubicToCurve(d.x, d.y, d.qx, d.qy, path[1], path[2]));
          break;
        case 'Q':
          d.qx = path[1];
          d.qy = path[2];
          path = ['C'].concat(qubicToCurve(d.x, d.y, path[1], path[2], path[3], path[4]));
          break;
        case 'L':
          path = ['C'].concat(lineToCurve(d.x, d.y, path[1], path[2]));
          break;
        case 'H':
          path = ['C'].concat(lineToCurve(d.x, d.y, path[1], d.y));
          break;
        case 'V':
          path = ['C'].concat(lineToCurve(d.x, d.y, d.x, path[1]));
          break;
        case 'Z':
          path = ['C'].concat(lineToCurve(d.x, d.y, d.X, d.Y));
          break;
        }

        return path;
      },

      fixArc = function(pp, i) {

        if (pp[i].length > 7) {
          pp[i].shift();
          var pi = pp[i];

          while (pi.length) {
            pathCommands[i] = 'A'; // if created multiple C:s, their original seg is saved
            pp.splice(i++, 0, ['C'].concat(pi.splice(0, 6)));
          }

          pp.splice(i, 1);
          ii = curvedPath.length;
        }
      },

      pathCommands = [], // path commands of original path p
      pfirst = '', // temporary holder for original path command
      pathCommand = ''; // holder for previous path command of original path

  for (var i = 0, ii = curvedPath.length; i < ii; i++) {
    curvedPath[i] && (pfirst = curvedPath[i][0]); // save current path command

    if (pfirst != 'C') // C is not saved yet, because it may be result of conversion
    {
      pathCommands[i] = pfirst; // Save current path command
      i && (pathCommand = pathCommands[i - 1]); // Get previous path command pathCommand
    }
    curvedPath[i] = processPath(curvedPath[i], attrs, pathCommand); // Previous path command is inputted to processPath

    if (pathCommands[i] != 'A' && pfirst == 'C') pathCommands[i] = 'C'; // A is the only command
    // which may produce multiple C:s
    // so we have to make sure that C is also C in original path

    fixArc(curvedPath, i); // fixArc adds also the right amount of A:s to pathCommands

    var seg = curvedPath[i],
        seglen = seg.length;

    attrs.x = seg[seglen - 2];
    attrs.y = seg[seglen - 1];
    attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;
    attrs.by = toFloat(seg[seglen - 3]) || attrs.y;
  }

  // cache curve
  pth.curve = pathClone(curvedPath);

  return curvedPath;
}

module.exports = findPathIntersections;

},{}],564:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Parser = Parser;
exports.decode = decodeEntities;
var fromCharCode = String.fromCharCode;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var ENTITY_PATTERN = /&#(\d+);|&#x([0-9a-f]+);|&(\w+);/ig;
var ENTITY_MAPPING = {
  'amp': '&',
  'apos': '\'',
  'gt': '>',
  'lt': '<',
  'quot': '"'
}; // map UPPERCASE variants of supported special chars

Object.keys(ENTITY_MAPPING).forEach(function (k) {
  ENTITY_MAPPING[k.toUpperCase()] = ENTITY_MAPPING[k];
});

function replaceEntities(_, d, x, z) {
  // reserved names, i.e. &nbsp;
  if (z) {
    if (hasOwnProperty.call(ENTITY_MAPPING, z)) {
      return ENTITY_MAPPING[z];
    } else {
      // fall back to original value
      return '&' + z + ';';
    }
  } // decimal encoded char


  if (d) {
    return fromCharCode(d);
  } // hex encoded char


  return fromCharCode(parseInt(x, 16));
}
/**
 * A basic entity decoder that can decode a minimal
 * sub-set of reserved names (&amp;) as well as
 * hex (&#xaaf;) and decimal (&#1231;) encoded characters.
 *
 * @param {string} str
 *
 * @return {string} decoded string
 */


function decodeEntities(s) {
  if (s.length > 3 && s.indexOf('&') !== -1) {
    return s.replace(ENTITY_PATTERN, replaceEntities);
  }

  return s;
}

var XSI_URI = 'http://www.w3.org/2001/XMLSchema-instance';
var XSI_PREFIX = 'xsi';
var XSI_TYPE = 'xsi:type';
var NON_WHITESPACE_OUTSIDE_ROOT_NODE = 'non-whitespace outside of root node';

function error(msg) {
  return new Error(msg);
}

function missingNamespaceForPrefix(prefix) {
  return 'missing namespace for prefix <' + prefix + '>';
}

function getter(getFn) {
  return {
    'get': getFn,
    'enumerable': true
  };
}

function cloneNsMatrix(nsMatrix) {
  var clone = {},
      key;

  for (key in nsMatrix) {
    clone[key] = nsMatrix[key];
  }

  return clone;
}

function uriPrefix(prefix) {
  return prefix + '$uri';
}

function buildNsMatrix(nsUriToPrefix) {
  var nsMatrix = {},
      uri,
      prefix;

  for (uri in nsUriToPrefix) {
    prefix = nsUriToPrefix[uri];
    nsMatrix[prefix] = prefix;
    nsMatrix[uriPrefix(prefix)] = uri;
  }

  return nsMatrix;
}

function noopGetContext() {
  return {
    'line': 0,
    'column': 0
  };
}

function throwFunc(err) {
  throw err;
}
/**
 * Creates a new parser with the given options.
 *
 * @constructor
 *
 * @param  {!Object<string, ?>=} options
 */


function Parser(options) {
  if (!this) {
    return new Parser(options);
  }

  var proxy = options && options['proxy'];
  var onText,
      onOpenTag,
      onCloseTag,
      onCDATA,
      onError = throwFunc,
      onWarning,
      onComment,
      onQuestion,
      onAttention;
  var getContext = noopGetContext;
  /**
   * Do we need to parse the current elements attributes for namespaces?
   *
   * @type {boolean}
   */

  var maybeNS = false;
  /**
   * Do we process namespaces at all?
   *
   * @type {boolean}
   */

  var isNamespace = false;
  /**
   * The caught error returned on parse end
   *
   * @type {Error}
   */

  var returnError = null;
  /**
   * Should we stop parsing?
   *
   * @type {boolean}
   */

  var parseStop = false;
  /**
   * A map of { uri: prefix } used by the parser.
   *
   * This map will ensure we can normalize prefixes during processing;
   * for each uri, only one prefix will be exposed to the handlers.
   *
   * @type {!Object<string, string>}}
   */

  var nsUriToPrefix;
  /**
   * Handle parse error.
   *
   * @param  {string|Error} err
   */

  function handleError(err) {
    if (!(err instanceof Error)) {
      err = error(err);
    }

    returnError = err;
    onError(err, getContext);
  }
  /**
   * Handle parse error.
   *
   * @param  {string|Error} err
   */


  function handleWarning(err) {
    if (!onWarning) {
      return;
    }

    if (!(err instanceof Error)) {
      err = error(err);
    }

    onWarning(err, getContext);
  }
  /**
   * Register parse listener.
   *
   * @param  {string}   name
   * @param  {Function} cb
   *
   * @return {Parser}
   */


  this['on'] = function (name, cb) {
    if (typeof cb !== 'function') {
      throw error('required args <name, cb>');
    }

    switch (name) {
      case 'openTag':
        onOpenTag = cb;
        break;

      case 'text':
        onText = cb;
        break;

      case 'closeTag':
        onCloseTag = cb;
        break;

      case 'error':
        onError = cb;
        break;

      case 'warn':
        onWarning = cb;
        break;

      case 'cdata':
        onCDATA = cb;
        break;

      case 'attention':
        onAttention = cb;
        break;
      // <!XXXXX zzzz="eeee">

      case 'question':
        onQuestion = cb;
        break;
      // <? ....  ?>

      case 'comment':
        onComment = cb;
        break;

      default:
        throw error('unsupported event: ' + name);
    }

    return this;
  };
  /**
   * Set the namespace to prefix mapping.
   *
   * @example
   *
   * parser.ns({
   *   'http://foo': 'foo',
   *   'http://bar': 'bar'
   * });
   *
   * @param  {!Object<string, string>} nsMap
   *
   * @return {Parser}
   */


  this['ns'] = function (nsMap) {
    if (typeof nsMap === 'undefined') {
      nsMap = {};
    }

    if (typeof nsMap !== 'object') {
      throw error('required args <nsMap={}>');
    }

    var _nsUriToPrefix = {},
        k;

    for (k in nsMap) {
      _nsUriToPrefix[k] = nsMap[k];
    } // FORCE default mapping for schema instance


    _nsUriToPrefix[XSI_URI] = XSI_PREFIX;
    isNamespace = true;
    nsUriToPrefix = _nsUriToPrefix;
    return this;
  };
  /**
   * Parse xml string.
   *
   * @param  {string} xml
   *
   * @return {Error} returnError, if not thrown
   */


  this['parse'] = function (xml) {
    if (typeof xml !== 'string') {
      throw error('required args <xml=string>');
    }

    returnError = null;
    parse(xml);
    getContext = noopGetContext;
    parseStop = false;
    return returnError;
  };
  /**
   * Stop parsing.
   */


  this['stop'] = function () {
    parseStop = true;
  };
  /**
   * Parse string, invoking configured listeners on element.
   *
   * @param  {string} xml
   */


  function parse(xml) {
    var nsMatrixStack = isNamespace ? [] : null,
        nsMatrix = isNamespace ? buildNsMatrix(nsUriToPrefix) : null,
        _nsMatrix,
        nodeStack = [],
        anonymousNsCount = 0,
        tagStart = false,
        tagEnd = false,
        i = 0,
        j = 0,
        x,
        y,
        q,
        w,
        v,
        xmlns,
        elementName,
        _elementName,
        elementProxy;

    var attrsString = '',
        attrsStart = 0,
        cachedAttrs // false = parsed with errors, null = needs parsing
    ;
    /**
     * Parse attributes on demand and returns the parsed attributes.
     *
     * Return semantics: (1) `false` on attribute parse error,
     * (2) object hash on extracted attrs.
     *
     * @return {boolean|Object}
     */

    function getAttrs() {
      if (cachedAttrs !== null) {
        return cachedAttrs;
      }

      var nsUri,
          nsUriPrefix,
          nsName,
          defaultAlias = isNamespace && nsMatrix['xmlns'],
          attrList = isNamespace && maybeNS ? [] : null,
          i = attrsStart,
          s = attrsString,
          l = s.length,
          hasNewMatrix,
          newalias,
          value,
          alias,
          name,
          attrs = {},
          seenAttrs = {},
          skipAttr,
          w,
          j;

      parseAttr: for (; i < l; i++) {
        skipAttr = false;
        w = s.charCodeAt(i);

        if (w === 32 || w < 14 && w > 8) {
          // WHITESPACE={ \f\n\r\t\v}
          continue;
        } // wait for non whitespace character


        if (w < 65 || w > 122 || w > 90 && w < 97) {
          if (w !== 95 && w !== 58) {
            // char 95"_" 58":"
            handleWarning('illegal first char attribute name');
            skipAttr = true;
          }
        } // parse attribute name


        for (j = i + 1; j < l; j++) {
          w = s.charCodeAt(j);

          if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 46 || // '.'
          w === 45 || // '-'
          w === 95 // '_'
          ) {
              continue;
            } // unexpected whitespace


          if (w === 32 || w < 14 && w > 8) {
            // WHITESPACE
            handleWarning('missing attribute value');
            i = j;
            continue parseAttr;
          } // expected "="


          if (w === 61) {
            // "=" == 61
            break;
          }

          handleWarning('illegal attribute name char');
          skipAttr = true;
        }

        name = s.substring(i, j);

        if (name === 'xmlns:xmlns') {
          handleWarning('illegal declaration of xmlns');
          skipAttr = true;
        }

        w = s.charCodeAt(j + 1);

        if (w === 34) {
          // '"'
          j = s.indexOf('"', i = j + 2);

          if (j === -1) {
            j = s.indexOf('\'', i);

            if (j !== -1) {
              handleWarning('attribute value quote missmatch');
              skipAttr = true;
            }
          }
        } else if (w === 39) {
          // "'"
          j = s.indexOf('\'', i = j + 2);

          if (j === -1) {
            j = s.indexOf('"', i);

            if (j !== -1) {
              handleWarning('attribute value quote missmatch');
              skipAttr = true;
            }
          }
        } else {
          handleWarning('missing attribute value quotes');
          skipAttr = true; // skip to next space

          for (j = j + 1; j < l; j++) {
            w = s.charCodeAt(j + 1);

            if (w === 32 || w < 14 && w > 8) {
              // WHITESPACE
              break;
            }
          }
        }

        if (j === -1) {
          handleWarning('missing closing quotes');
          j = l;
          skipAttr = true;
        }

        if (!skipAttr) {
          value = s.substring(i, j);
        }

        i = j; // ensure SPACE follows attribute
        // skip illegal content otherwise
        // example a="b"c

        for (; j + 1 < l; j++) {
          w = s.charCodeAt(j + 1);

          if (w === 32 || w < 14 && w > 8) {
            // WHITESPACE
            break;
          } // FIRST ILLEGAL CHAR


          if (i === j) {
            handleWarning('illegal character after attribute end');
            skipAttr = true;
          }
        } // advance cursor to next attribute


        i = j + 1;

        if (skipAttr) {
          continue parseAttr;
        } // check attribute re-declaration


        if (name in seenAttrs) {
          handleWarning('attribute <' + name + '> already defined');
          continue;
        }

        seenAttrs[name] = true;

        if (!isNamespace) {
          attrs[name] = value;
          continue;
        } // try to extract namespace information


        if (maybeNS) {
          newalias = name === 'xmlns' ? 'xmlns' : name.charCodeAt(0) === 120 && name.substr(0, 6) === 'xmlns:' ? name.substr(6) : null; // handle xmlns(:alias) assignment

          if (newalias !== null) {
            nsUri = decodeEntities(value);
            nsUriPrefix = uriPrefix(newalias);
            alias = nsUriToPrefix[nsUri];

            if (!alias) {
              // no prefix defined or prefix collision
              if (newalias === 'xmlns' || nsUriPrefix in nsMatrix && nsMatrix[nsUriPrefix] !== nsUri) {
                // alocate free ns prefix
                do {
                  alias = 'ns' + anonymousNsCount++;
                } while (typeof nsMatrix[alias] !== 'undefined');
              } else {
                alias = newalias;
              }

              nsUriToPrefix[nsUri] = alias;
            }

            if (nsMatrix[newalias] !== alias) {
              if (!hasNewMatrix) {
                nsMatrix = cloneNsMatrix(nsMatrix);
                hasNewMatrix = true;
              }

              nsMatrix[newalias] = alias;

              if (newalias === 'xmlns') {
                nsMatrix[uriPrefix(alias)] = nsUri;
                defaultAlias = alias;
              }

              nsMatrix[nsUriPrefix] = nsUri;
            } // expose xmlns(:asd)="..." in attributes


            attrs[name] = value;
            continue;
          } // collect attributes until all namespace
          // declarations are processed


          attrList.push(name, value);
          continue;
        }
        /** end if (maybeNs) */
        // handle attributes on element without
        // namespace declarations


        w = name.indexOf(':');

        if (w === -1) {
          attrs[name] = value;
          continue;
        } // normalize ns attribute name


        if (!(nsName = nsMatrix[name.substring(0, w)])) {
          handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
          continue;
        }

        name = defaultAlias === nsName ? name.substr(w + 1) : nsName + name.substr(w); // end: normalize ns attribute name
        // normalize xsi:type ns attribute value

        if (name === XSI_TYPE) {
          w = value.indexOf(':');

          if (w !== -1) {
            nsName = value.substring(0, w); // handle default prefixes, i.e. xs:String gracefully

            nsName = nsMatrix[nsName] || nsName;
            value = nsName + value.substring(w);
          } else {
            value = defaultAlias + ':' + value;
          }
        } // end: normalize xsi:type ns attribute value


        attrs[name] = value;
      } // handle deferred, possibly namespaced attributes


      if (maybeNS) {
        // normalize captured attributes
        for (i = 0, l = attrList.length; i < l; i++) {
          name = attrList[i++];
          value = attrList[i];
          w = name.indexOf(':');

          if (w !== -1) {
            // normalize ns attribute name
            if (!(nsName = nsMatrix[name.substring(0, w)])) {
              handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
              continue;
            }

            name = defaultAlias === nsName ? name.substr(w + 1) : nsName + name.substr(w); // end: normalize ns attribute name
            // normalize xsi:type ns attribute value

            if (name === XSI_TYPE) {
              w = value.indexOf(':');

              if (w !== -1) {
                nsName = value.substring(0, w); // handle default prefixes, i.e. xs:String gracefully

                nsName = nsMatrix[nsName] || nsName;
                value = nsName + value.substring(w);
              } else {
                value = defaultAlias + ':' + value;
              }
            } // end: normalize xsi:type ns attribute value

          }

          attrs[name] = value;
        } // end: normalize captured attributes

      }

      return cachedAttrs = attrs;
    }
    /**
     * Extract the parse context { line, column, part }
     * from the current parser position.
     *
     * @return {Object} parse context
     */


    function getParseContext() {
      var splitsRe = /(\r\n|\r|\n)/g;
      var line = 0;
      var column = 0;
      var startOfLine = 0;
      var endOfLine = j;
      var match;
      var data;

      while (i >= startOfLine) {
        match = splitsRe.exec(xml);

        if (!match) {
          break;
        } // end of line = (break idx + break chars)


        endOfLine = match[0].length + match.index;

        if (endOfLine > i) {
          break;
        } // advance to next line


        line += 1;
        startOfLine = endOfLine;
      } // EOF errors


      if (i == -1) {
        column = endOfLine;
        data = xml.substring(j);
      } else // start errors
        if (j === 0) {
          data = xml.substring(j, i);
        } // other errors
        else {
            column = i - startOfLine;
            data = j == -1 ? xml.substring(i) : xml.substring(i, j + 1);
          }

      return {
        'data': data,
        'line': line,
        'column': column
      };
    }

    getContext = getParseContext;

    if (proxy) {
      elementProxy = Object.create({}, {
        'name': getter(function () {
          return elementName;
        }),
        'originalName': getter(function () {
          return _elementName;
        }),
        'attrs': getter(getAttrs),
        'ns': getter(function () {
          return nsMatrix;
        })
      });
    } // actual parse logic


    while (j !== -1) {
      if (xml.charCodeAt(j) === 60) {
        // "<"
        i = j;
      } else {
        i = xml.indexOf('<', j);
      } // parse end


      if (i === -1) {
        if (nodeStack.length) {
          return handleError('unexpected end of file');
        }

        if (j === 0) {
          return handleError('missing start tag');
        }

        if (j < xml.length) {
          if (xml.substring(j).trim()) {
            handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);
          }
        }

        return;
      } // parse text


      if (j !== i) {
        if (nodeStack.length) {
          if (onText) {
            onText(xml.substring(j, i), decodeEntities, getContext);

            if (parseStop) {
              return;
            }
          }
        } else {
          if (xml.substring(j, i).trim()) {
            handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);

            if (parseStop) {
              return;
            }
          }
        }
      }

      w = xml.charCodeAt(i + 1); // parse comments + CDATA

      if (w === 33) {
        // "!"
        q = xml.charCodeAt(i + 2); // CDATA section

        if (q === 91 && xml.substr(i + 3, 6) === 'CDATA[') {
          // 91 == "["
          j = xml.indexOf(']]>', i);

          if (j === -1) {
            return handleError('unclosed cdata');
          }

          if (onCDATA) {
            onCDATA(xml.substring(i + 9, j), getContext);

            if (parseStop) {
              return;
            }
          }

          j += 3;
          continue;
        } // comment


        if (q === 45 && xml.charCodeAt(i + 3) === 45) {
          // 45 == "-"
          j = xml.indexOf('-->', i);

          if (j === -1) {
            return handleError('unclosed comment');
          }

          if (onComment) {
            onComment(xml.substring(i + 4, j), decodeEntities, getContext);

            if (parseStop) {
              return;
            }
          }

          j += 3;
          continue;
        }
      } // parse question <? ... ?>


      if (w === 63) {
        // "?"
        j = xml.indexOf('?>', i);

        if (j === -1) {
          return handleError('unclosed question');
        }

        if (onQuestion) {
          onQuestion(xml.substring(i, j + 2), getContext);

          if (parseStop) {
            return;
          }
        }

        j += 2;
        continue;
      } // find matching closing tag for attention or standard tags
      // for that we must skip through attribute values
      // (enclosed in single or double quotes)


      for (x = i + 1;; x++) {
        v = xml.charCodeAt(x);

        if (isNaN(v)) {
          j = -1;
          return handleError('unclosed tag');
        } // [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
        // skips the quoted string
        // (double quotes) does not appear in a literal enclosed by (double quotes)
        // (single quote) does not appear in a literal enclosed by (single quote)


        if (v === 34) {
          //  '"'
          q = xml.indexOf('"', x + 1);
          x = q !== -1 ? q : x;
        } else if (v === 39) {
          // "'"
          q = xml.indexOf("'", x + 1);
          x = q !== -1 ? q : x;
        } else if (v === 62) {
          // '>'
          j = x;
          break;
        }
      } // parse attention <! ...>
      // previously comment and CDATA have already been parsed


      if (w === 33) {
        // "!"
        if (onAttention) {
          onAttention(xml.substring(i, j + 1), decodeEntities, getContext);

          if (parseStop) {
            return;
          }
        }

        j += 1;
        continue;
      } // don't process attributes;
      // there are none


      cachedAttrs = {}; // if (xml.charCodeAt(i+1) === 47) { // </...

      if (w === 47) {
        // </...
        tagStart = false;
        tagEnd = true;

        if (!nodeStack.length) {
          return handleError('missing open tag');
        } // verify open <-> close tag match


        x = elementName = nodeStack.pop();
        q = i + 2 + x.length;

        if (xml.substring(i + 2, q) !== x) {
          return handleError('closing tag mismatch');
        } // verify chars in close tag


        for (; q < j; q++) {
          w = xml.charCodeAt(q);

          if (w === 32 || w > 8 && w < 14) {
            // \f\n\r\t\v space
            continue;
          }

          return handleError('close tag');
        }
      } else {
        if (xml.charCodeAt(j - 1) === 47) {
          // .../>
          x = elementName = xml.substring(i + 1, j - 1);
          tagStart = true;
          tagEnd = true;
        } else {
          x = elementName = xml.substring(i + 1, j);
          tagStart = true;
          tagEnd = false;
        }

        if (!(w > 96 && w < 123 || w > 64 && w < 91 || w === 95 || w === 58)) {
          // char 95"_" 58":"
          return handleError('illegal first char nodeName');
        }

        for (q = 1, y = x.length; q < y; q++) {
          w = x.charCodeAt(q);

          if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 45 || w === 95 || w == 46) {
            continue;
          }

          if (w === 32 || w < 14 && w > 8) {
            // \f\n\r\t\v space
            elementName = x.substring(0, q); // maybe there are attributes

            cachedAttrs = null;
            break;
          }

          return handleError('invalid nodeName');
        }

        if (!tagEnd) {
          nodeStack.push(elementName);
        }
      }

      if (isNamespace) {
        _nsMatrix = nsMatrix;

        if (tagStart) {
          // remember old namespace
          // unless we're self-closing
          if (!tagEnd) {
            nsMatrixStack.push(_nsMatrix);
          }

          if (cachedAttrs === null) {
            // quick check, whether there may be namespace
            // declarations on the node; if that is the case
            // we need to eagerly parse the node attributes
            if (maybeNS = x.indexOf('xmlns', q) !== -1) {
              attrsStart = q;
              attrsString = x;
              getAttrs();
              maybeNS = false;
            }
          }
        }

        _elementName = elementName;
        w = elementName.indexOf(':');

        if (w !== -1) {
          xmlns = nsMatrix[elementName.substring(0, w)]; // prefix given; namespace must exist

          if (!xmlns) {
            return handleError('missing namespace on <' + _elementName + '>');
          }

          elementName = elementName.substr(w + 1);
        } else {
          xmlns = nsMatrix['xmlns']; // if no default namespace is defined,
          // we'll import the element as anonymous.
          //
          // it is up to users to correct that to the document defined
          // targetNamespace, or whatever their undersanding of the
          // XML spec mandates.
        } // adjust namespace prefixs as configured


        if (xmlns) {
          elementName = xmlns + ':' + elementName;
        }
      }

      if (tagStart) {
        attrsStart = q;
        attrsString = x;

        if (onOpenTag) {
          if (proxy) {
            onOpenTag(elementProxy, decodeEntities, tagEnd, getContext);
          } else {
            onOpenTag(elementName, getAttrs, decodeEntities, tagEnd, getContext);
          }

          if (parseStop) {
            return;
          }
        }
      }

      if (tagEnd) {
        if (onCloseTag) {
          onCloseTag(proxy ? elementProxy : elementName, decodeEntities, tagStart, getContext);

          if (parseStop) {
            return;
          }
        } // restore old namespace


        if (isNamespace) {
          if (!tagStart) {
            nsMatrix = nsMatrixStack.pop();
          } else {
            nsMatrix = _nsMatrix;
          }
        }
      }

      j += 1;
    }
  }
  /** end parse */

}

},{}],565:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = create;

var _minDom = require("min-dom");

var _minDash = require("min-dash");

var _mitt = _interopRequireDefault(require("mitt"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var DEFAULT_OPTIONS = {
  scrollSymbolLeft: '‹',
  scrollSymbolRight: '›'
};
/**
 * This component adds the functionality to scroll over a list of tabs.
 *
 * It adds scroll buttons on the left and right side of the tabs container
 * if not all tabs are visible. It also adds a mouse wheel listener on the
 * container.
 *
 * If either a button is clicked or the mouse wheel is used over the tabs,
 * a 'scroll' event is being fired. This event contains the node elements
 * of the new and old active tab, and the direction in which the tab has
 * changed relative to the old active tab.
 *
 * @example:
 * (1) provide a tabs-container:
 *
 * var $el = (
 *   <div>
 *     <!-- button added by scrollTabs -->
 *     <span class="scroll-tabs-button scroll-tabs-left"></span>
 *     <ul class="my-tabs-container">
 *       <li class="my-tab i-am-active"></li>
 *       <li class="my-tab"></li>
 *       <li class="my-tab ignore-me"></li>
 *     </ul>
 *     <!-- button added by scrollTabs -->
 *     <span class="scroll-tabs-button scroll-tabs-right"></span>
 *   </div>
 * );
 *
 *
 * (2) initialize scrollTabs:
 *
 *  var scroller = scrollTabs(tabBarNode, {
 *    selectors: {
 *      tabsContainer: '.my-tabs-container',
 *      tab: '.my-tab',
 *      ignore: '.ignore-me',
 *      active: '.i-am-active'
 *    }
 *  });
 *
 *
 * (3) listen to the scroll event:
 *
 * scroller.on('scroll', function(newActiveNode, oldActiveNode, direction) {
 *   // direction is any of (-1: left, 1: right)
 *   // activate the new active tab
 * });
 *
 *
 * (4) update the scroller if tabs change and or the tab container resizes:
 *
 * scroller.update();
 *
 *
 * @param  {DOMElement} el
 * @param  {Object} options
 * @param  {Object} options.selectors
 * @param  {String} options.selectors.tabsContainer the container all tabs are contained in
 * @param  {String} options.selectors.tab a single tab inside the tab container
 * @param  {String} options.selectors.ignore tabs that should be ignored during scroll left/right
 * @param  {String} options.selectors.active selector for the current active tab
 * @param  {String} [options.scrollSymbolLeft]
 * @param  {String} [options.scrollSymbolRight]
 */

function ScrollTabs($el, options) {
  // we are an event emitter
  (0, _minDash.assign)(this, (0, _mitt.default)());
  this.options = options = (0, _minDash.assign)({}, DEFAULT_OPTIONS, options);
  this.container = $el;

  this._createScrollButtons($el, options);

  this._bindEvents($el);
}
/**
 * Create a clickable scroll button
 *
 * @param {Object} options
 * @param {String} options.className
 * @param {String} options.label
 * @param {Number} options.direction
 *
 * @return {DOMElement} The created scroll button node
 */


ScrollTabs.prototype._createButton = function (parentNode, options) {
  var className = options.className,
      direction = options.direction;
  var button = (0, _minDom.query)('.' + className, parentNode);

  if (!button) {
    button = (0, _minDom.domify)('<span class="scroll-tabs-button ' + className + '">' + options.label + '</span>');
    parentNode.insertBefore(button, parentNode.childNodes[0]);
  }

  (0, _minDom.attr)(button, 'data-direction', direction);
  return button;
};
/**
 * Create both scroll buttons
 *
 * @param  {DOMElement} parentNode
 * @param  {Object} options
 * @param  {String} options.scrollSymbolLeft
 * @param  {String} options.scrollSymbolRight
 */


ScrollTabs.prototype._createScrollButtons = function (parentNode, options) {
  // Create a button that scrolls to the tab left to the currently active tab
  this._createButton(parentNode, {
    className: 'scroll-tabs-left',
    label: options.scrollSymbolLeft,
    direction: -1
  }); // Create a button that scrolls to the tab right to the currently active tab


  this._createButton(parentNode, {
    className: 'scroll-tabs-right',
    label: options.scrollSymbolRight,
    direction: 1
  });
};
/**
 * Get the current active tab
 *
 * @return {DOMElement}
 */


ScrollTabs.prototype.getActiveTabNode = function () {
  return (0, _minDom.query)(this.options.selectors.active, this.container);
};
/**
 * Get the container all tabs are contained in
 *
 * @return {DOMElement}
 */


ScrollTabs.prototype.getTabsContainerNode = function () {
  return (0, _minDom.query)(this.options.selectors.tabsContainer, this.container);
};
/**
 * Get all tabs (visible and invisible ones)
 *
 * @return {Array<DOMElement>}
 */


ScrollTabs.prototype.getAllTabNodes = function () {
  return (0, _minDom.queryAll)(this.options.selectors.tab, this.container);
};
/**
 * Gets all tabs that don't have the ignore class set
 *
 * @return {Array<DOMElement>}
 */


ScrollTabs.prototype.getVisibleTabs = function () {
  var allTabs = this.getAllTabNodes();
  var ignore = this.options.selectors.ignore;
  return (0, _minDash.filter)(allTabs, function (tabNode) {
    return !(0, _minDom.matches)(tabNode, ignore);
  });
};
/**
 * Get a tab relative to a reference tab.
 *
 * @param  {DOMElement} referenceTabNode
 * @param  {Number} n gets the nth tab next or previous to the reference tab
 *
 * @return {DOMElement}
 *
 * @example:
 * Visible tabs: [ A | B | C | D | E ]
 * Assume tab 'C' is the reference tab:
 * If direction === -1, it returns tab 'B',
 * if direction ===  2, it returns tab 'E'
 */


ScrollTabs.prototype.getAdjacentTab = function (referenceTabNode, n) {
  var visibleTabs = this.getVisibleTabs();
  var index = visibleTabs.indexOf(referenceTabNode);
  return visibleTabs[index + n];
};

ScrollTabs.prototype._bindEvents = function (node) {
  this._bindWheelEvent(node);

  this._bindTabClickEvents(node);

  this._bindScrollButtonEvents(node);
};
/**
 *  Bind a click listener to a DOM node.
 *  Make sure a tab link is entirely visible after onClick.
 *
 * @param {DOMElement} node
 */


ScrollTabs.prototype._bindTabClickEvents = function (node) {
  var selector = this.options.selectors.tab;
  var self = this;

  _minDom.delegate.bind(node, selector, 'click', function onClick(event) {
    self.scrollToTabNode(event.delegateTarget);
  });
};
/**
 * Bind the wheel event listener to a DOM node
 *
 * @param {DOMElement} node
 */


ScrollTabs.prototype._bindWheelEvent = function (node) {
  var self = this;

  _minDom.event.bind(node, 'wheel', function (e) {
    // scroll direction (-1: left, 1: right)
    var direction = Math.sign(e.deltaY);
    var oldActiveTab = self.getActiveTabNode();
    var newActiveTab = self.getAdjacentTab(oldActiveTab, direction);

    if (newActiveTab) {
      self.scrollToTabNode(newActiveTab);
      self.emit('scroll', newActiveTab, oldActiveTab, direction);
    }

    e.preventDefault();
  });
};
/**
 * Bind scroll button events to a DOM node
 *
 * @param  {DOMElement} node
 */


ScrollTabs.prototype._bindScrollButtonEvents = function (node) {
  var self = this;

  _minDom.delegate.bind(node, '.scroll-tabs-button', 'click', function (event) {
    var target = event.delegateTarget; // data-direction is either -1 or 1

    var direction = parseInt((0, _minDom.attr)(target, 'data-direction'), 10);
    var oldActiveTabNode = self.getActiveTabNode();
    var newActiveTabNode = self.getAdjacentTab(oldActiveTabNode, direction);

    if (newActiveTabNode) {
      self.scrollToTabNode(newActiveTabNode);
      self.emit('scroll', newActiveTabNode, oldActiveTabNode, direction);
    }

    event.preventDefault();
  });
};
/**
* Scroll to a tab if it is not entirely visible
*
* @param  {DOMElement} tabNode tab node to scroll to
*/


ScrollTabs.prototype.scrollToTabNode = function (tabNode) {
  if (!tabNode) {
    return;
  }

  var tabsContainerNode = tabNode.parentNode;
  var tabWidth = tabNode.offsetWidth,
      tabOffsetLeft = tabNode.offsetLeft,
      tabOffsetRight = tabOffsetLeft + tabWidth,
      containerWidth = tabsContainerNode.offsetWidth,
      containerScrollLeft = tabsContainerNode.scrollLeft;

  if (containerScrollLeft > tabOffsetLeft) {
    // scroll to the left, if the tab is overflowing on the left side
    tabsContainerNode.scrollLeft = 0;
  } else if (tabOffsetRight > containerWidth) {
    // scroll to the right, if the tab is overflowing on the right side
    tabsContainerNode.scrollLeft = tabOffsetRight - containerWidth;
  }
};
/**
 * React on tab changes from outside (resize/show/hide/add/remove),
 * update scroll button visibility.
 */


ScrollTabs.prototype.update = function () {
  var tabsContainerNode = this.getTabsContainerNode(); // check if tabs fit in container

  var overflow = tabsContainerNode.scrollWidth > tabsContainerNode.offsetWidth; // TODO(nikku): distinguish overflow left / overflow right?

  var overflowClass = 'scroll-tabs-overflow';
  (0, _minDom.classes)(this.container).toggle(overflowClass, overflow);

  if (overflow) {
    // make sure the current active tab is always visible
    this.scrollToTabNode(this.getActiveTabNode());
  }
}; // exports ////////////////

/**
 * Create a scrollTabs instance on the given element.
 *
 * @param {DOMElement} $el
 * @param {Object} options
 *
 * @return {ScrollTabs}
 */


function create($el, options) {
  var scrollTabs = get($el);

  if (!scrollTabs) {
    scrollTabs = new ScrollTabs($el, options);
    $el.__scrollTabs = scrollTabs;
  }

  return scrollTabs;
}
/**
 * Return the scrollTabs instance that has been previously
 * initialized on the element.
 *
 * @param {DOMElement} $el
 * @return {ScrollTabs}
 */


function get($el) {
  return $el.__scrollTabs;
}

create.get = get;

},{"min-dash":555,"min-dom":556,"mitt":557}],566:[function(require,module,exports){
'use strict';

/**
 * Calculate the selection update for the given
 * current and new input values.
 *
 * @param {Object} currentSelection as {start, end}
 * @param {String} currentValue
 * @param {String} newValue
 *
 * @return {Object} newSelection as {start, end}
 */
function calculateUpdate(currentSelection, currentValue, newValue) {

  var currentCursor = currentSelection.start,
      newCursor = currentCursor,
      diff = newValue.length - currentValue.length,
      idx;

  var lengthDelta = newValue.length - currentValue.length;

  var currentTail = currentValue.substring(currentCursor);

  // check if we can remove common ending from the equation
  // to be able to properly detect a selection change for
  // the following scenarios:
  //
  //  * (AAATTT|TF) => (AAAT|TF)
  //  * (AAAT|TF) =>  (AAATTT|TF)
  //
  if (newValue.lastIndexOf(currentTail) === newValue.length - currentTail.length) {
    currentValue = currentValue.substring(0, currentValue.length - currentTail.length);
    newValue = newValue.substring(0, newValue.length - currentTail.length);
  }

  // diff
  var diff = createDiff(currentValue, newValue);

  if (diff) {
    if (diff.type === 'remove') {
      newCursor = diff.newStart;
    } else {
      newCursor = diff.newEnd;
    }
  }

  return range(newCursor);
}

module.exports = calculateUpdate;


function createDiff(currentValue, newValue) {

  var insert;

  var l_str, l_char, l_idx = 0,
      s_str, s_char, s_idx = 0;

  if (newValue.length > currentValue.length) {
    l_str = newValue;
    s_str = currentValue;
  } else {
    l_str = currentValue;
    s_str = newValue;
  }

  // assume there will be only one insert / remove and
  // detect that _first_ edit operation only
  while (l_idx < l_str.length) {

    l_char = l_str.charAt(l_idx);
    s_char = s_str.charAt(s_idx);

    // chars no not equal
    if (l_char !== s_char) {

      if (!insert) {
        insert = {
          l_start: l_idx,
          s_start: s_idx
        };
      }

      l_idx++;
    }

    // chars equal (again?)
    else {

      if (insert && !insert.complete) {
        insert.l_end = l_idx;
        insert.s_end = s_idx;
        insert.complete = true;
      }

      s_idx++;
      l_idx++;
    }
  }

  if (insert && !insert.complete) {
    insert.complete = true;
    insert.s_end = s_str.length;
    insert.l_end = l_str.length;
  }

  // no diff
  if (!insert) {
    return;
  }

  if (newValue.length > currentValue.length) {
    return {
      newStart: insert.l_start,
      newEnd: insert.l_end,
      type: 'add'
    };
  } else {
    return {
      newStart: insert.s_start,
      newEnd: insert.s_end,
      type: newValue.length < currentValue.length ? 'remove' : 'replace'
    };
  }
}

/**
 * Utility method for creating a new selection range {start, end} object.
 *
 * @param {Number} start
 * @param {Number} [end]
 *
 * @return {Object} selection range as {start, end}
 */
function range(start, end) {
  return {
    start: start,
    end: end === undefined ? start : end
  };
}

module.exports.range = range;


function splitStr(str, position) {
  return {
    before: str.substring(0, position),
    after: str.substring(position)
  };
}
},{}],567:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.append = append;
exports.appendTo = appendTo;
exports.attr = attr;
exports.classes = classes;
exports.clear = clear;
exports.clone = clone;
exports.create = create;
exports.innerSVG = innerSVG;
exports.prepend = prepend;
exports.prependTo = prependTo;
exports.remove = remove;
exports.replace = replace;
exports.transform = transform;
exports.on = on;
exports.off = off;
exports.createPoint = createPoint;
exports.createMatrix = createMatrix;
exports.createTransform = createTransform;
exports.select = select;
exports.selectAll = selectAll;

function ensureImported(element, target) {
  if (element.ownerDocument !== target.ownerDocument) {
    try {
      // may fail on webkit
      return target.ownerDocument.importNode(element, true);
    } catch (e) {// ignore
    }
  }

  return element;
}
/**
 * appendTo utility
 */

/**
 * Append a node to a target element and return the appended node.
 *
 * @param  {SVGElement} element
 * @param  {SVGElement} target
 *
 * @return {SVGElement} the appended node
 */


function appendTo(element, target) {
  return target.appendChild(ensureImported(element, target));
}
/**
 * append utility
 */

/**
 * Append a node to an element
 *
 * @param  {SVGElement} element
 * @param  {SVGElement} node
 *
 * @return {SVGElement} the element
 */


function append(target, node) {
  appendTo(node, target);
  return target;
}
/**
 * attribute accessor utility
 */


var LENGTH_ATTR = 2;
var CSS_PROPERTIES = {
  'alignment-baseline': 1,
  'baseline-shift': 1,
  'clip': 1,
  'clip-path': 1,
  'clip-rule': 1,
  'color': 1,
  'color-interpolation': 1,
  'color-interpolation-filters': 1,
  'color-profile': 1,
  'color-rendering': 1,
  'cursor': 1,
  'direction': 1,
  'display': 1,
  'dominant-baseline': 1,
  'enable-background': 1,
  'fill': 1,
  'fill-opacity': 1,
  'fill-rule': 1,
  'filter': 1,
  'flood-color': 1,
  'flood-opacity': 1,
  'font': 1,
  'font-family': 1,
  'font-size': LENGTH_ATTR,
  'font-size-adjust': 1,
  'font-stretch': 1,
  'font-style': 1,
  'font-variant': 1,
  'font-weight': 1,
  'glyph-orientation-horizontal': 1,
  'glyph-orientation-vertical': 1,
  'image-rendering': 1,
  'kerning': 1,
  'letter-spacing': 1,
  'lighting-color': 1,
  'marker': 1,
  'marker-end': 1,
  'marker-mid': 1,
  'marker-start': 1,
  'mask': 1,
  'opacity': 1,
  'overflow': 1,
  'pointer-events': 1,
  'shape-rendering': 1,
  'stop-color': 1,
  'stop-opacity': 1,
  'stroke': 1,
  'stroke-dasharray': 1,
  'stroke-dashoffset': 1,
  'stroke-linecap': 1,
  'stroke-linejoin': 1,
  'stroke-miterlimit': 1,
  'stroke-opacity': 1,
  'stroke-width': LENGTH_ATTR,
  'text-anchor': 1,
  'text-decoration': 1,
  'text-rendering': 1,
  'unicode-bidi': 1,
  'visibility': 1,
  'word-spacing': 1,
  'writing-mode': 1
};

function getAttribute(node, name) {
  if (CSS_PROPERTIES[name]) {
    return node.style[name];
  } else {
    return node.getAttributeNS(null, name);
  }
}

function setAttribute(node, name, value) {
  var hyphenated = name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
  var type = CSS_PROPERTIES[hyphenated];

  if (type) {
    // append pixel unit, unless present
    if (type === LENGTH_ATTR && typeof value === 'number') {
      value = String(value) + 'px';
    }

    node.style[hyphenated] = value;
  } else {
    node.setAttributeNS(null, name, value);
  }
}

function setAttributes(node, attrs) {
  var names = Object.keys(attrs),
      i,
      name;

  for (i = 0, name; name = names[i]; i++) {
    setAttribute(node, name, attrs[name]);
  }
}
/**
 * Gets or sets raw attributes on a node.
 *
 * @param  {SVGElement} node
 * @param  {Object} [attrs]
 * @param  {String} [name]
 * @param  {String} [value]
 *
 * @return {String}
 */


function attr(node, name, value) {
  if (typeof name === 'string') {
    if (value !== undefined) {
      setAttribute(node, name, value);
    } else {
      return getAttribute(node, name);
    }
  } else {
    setAttributes(node, name);
  }

  return node;
}
/**
 * Clear utility
 */


function index(arr, obj) {
  if (arr.indexOf) {
    return arr.indexOf(obj);
  }

  for (var i = 0; i < arr.length; ++i) {
    if (arr[i] === obj) {
      return i;
    }
  }

  return -1;
}

var re = /\s+/;
var toString = Object.prototype.toString;

function defined(o) {
  return typeof o !== 'undefined';
}
/**
 * Wrap `el` in a `ClassList`.
 *
 * @param {Element} el
 * @return {ClassList}
 * @api public
 */


function classes(el) {
  return new ClassList(el);
}

function ClassList(el) {
  if (!el || !el.nodeType) {
    throw new Error('A DOM element reference is required');
  }

  this.el = el;
  this.list = el.classList;
}
/**
 * Add class `name` if not already present.
 *
 * @param {String} name
 * @return {ClassList}
 * @api public
 */


ClassList.prototype.add = function (name) {
  // classList
  if (this.list) {
    this.list.add(name);
    return this;
  } // fallback


  var arr = this.array();
  var i = index(arr, name);

  if (!~i) {
    arr.push(name);
  }

  if (defined(this.el.className.baseVal)) {
    this.el.className.baseVal = arr.join(' ');
  } else {
    this.el.className = arr.join(' ');
  }

  return this;
};
/**
 * Remove class `name` when present, or
 * pass a regular expression to remove
 * any which match.
 *
 * @param {String|RegExp} name
 * @return {ClassList}
 * @api public
 */


ClassList.prototype.remove = function (name) {
  if ('[object RegExp]' === toString.call(name)) {
    return this.removeMatching(name);
  } // classList


  if (this.list) {
    this.list.remove(name);
    return this;
  } // fallback


  var arr = this.array();
  var i = index(arr, name);

  if (~i) {
    arr.splice(i, 1);
  }

  this.el.className.baseVal = arr.join(' ');
  return this;
};
/**
 * Remove all classes matching `re`.
 *
 * @param {RegExp} re
 * @return {ClassList}
 * @api private
 */


ClassList.prototype.removeMatching = function (re) {
  var arr = this.array();

  for (var i = 0; i < arr.length; i++) {
    if (re.test(arr[i])) {
      this.remove(arr[i]);
    }
  }

  return this;
};
/**
 * Toggle class `name`, can force state via `force`.
 *
 * For browsers that support classList, but do not support `force` yet,
 * the mistake will be detected and corrected.
 *
 * @param {String} name
 * @param {Boolean} force
 * @return {ClassList}
 * @api public
 */


ClassList.prototype.toggle = function (name, force) {
  // classList
  if (this.list) {
    if (defined(force)) {
      if (force !== this.list.toggle(name, force)) {
        this.list.toggle(name); // toggle again to correct
      }
    } else {
      this.list.toggle(name);
    }

    return this;
  } // fallback


  if (defined(force)) {
    if (!force) {
      this.remove(name);
    } else {
      this.add(name);
    }
  } else {
    if (this.has(name)) {
      this.remove(name);
    } else {
      this.add(name);
    }
  }

  return this;
};
/**
 * Return an array of classes.
 *
 * @return {Array}
 * @api public
 */


ClassList.prototype.array = function () {
  var className = this.el.getAttribute('class') || '';
  var str = className.replace(/^\s+|\s+$/g, '');
  var arr = str.split(re);

  if ('' === arr[0]) {
    arr.shift();
  }

  return arr;
};
/**
 * Check if class `name` is present.
 *
 * @param {String} name
 * @return {ClassList}
 * @api public
 */


ClassList.prototype.has = ClassList.prototype.contains = function (name) {
  return this.list ? this.list.contains(name) : !!~index(this.array(), name);
};

function remove(element) {
  var parent = element.parentNode;

  if (parent) {
    parent.removeChild(element);
  }

  return element;
}
/**
 * Clear utility
 */

/**
 * Removes all children from the given element
 *
 * @param  {DOMElement} element
 * @return {DOMElement} the element (for chaining)
 */


function clear(element) {
  var child;

  while (child = element.firstChild) {
    remove(child);
  }

  return element;
}

function clone(element) {
  return element.cloneNode(true);
}

var ns = {
  svg: 'http://www.w3.org/2000/svg'
};
/**
 * DOM parsing utility
 */

var SVG_START = '<svg xmlns="' + ns.svg + '"';

function parse(svg) {
  var unwrap = false; // ensure we import a valid svg document

  if (svg.substring(0, 4) === '<svg') {
    if (svg.indexOf(ns.svg) === -1) {
      svg = SVG_START + svg.substring(4);
    }
  } else {
    // namespace svg
    svg = SVG_START + '>' + svg + '</svg>';
    unwrap = true;
  }

  var parsed = parseDocument(svg);

  if (!unwrap) {
    return parsed;
  }

  var fragment = document.createDocumentFragment();
  var parent = parsed.firstChild;

  while (parent.firstChild) {
    fragment.appendChild(parent.firstChild);
  }

  return fragment;
}

function parseDocument(svg) {
  var parser; // parse

  parser = new DOMParser();
  parser.async = false;
  return parser.parseFromString(svg, 'text/xml');
}
/**
 * Create utility for SVG elements
 */

/**
 * Create a specific type from name or SVG markup.
 *
 * @param {String} name the name or markup of the element
 * @param {Object} [attrs] attributes to set on the element
 *
 * @returns {SVGElement}
 */


function create(name, attrs) {
  var element;

  if (name.charAt(0) === '<') {
    element = parse(name).firstChild;
    element = document.importNode(element, true);
  } else {
    element = document.createElementNS(ns.svg, name);
  }

  if (attrs) {
    attr(element, attrs);
  }

  return element;
}
/**
 * Events handling utility
 */


function on(node, event, listener, useCapture) {
  node.addEventListener(event, listener, useCapture);
}

function off(node, event, listener, useCapture) {
  node.removeEventListener(event, listener, useCapture);
}
/**
 * Geometry helpers
 */
// fake node used to instantiate svg geometry elements


var node = create('svg');

function extend(object, props) {
  var i,
      k,
      keys = Object.keys(props);

  for (i = 0; k = keys[i]; i++) {
    object[k] = props[k];
  }

  return object;
}

function createPoint(x, y) {
  var point = node.createSVGPoint();

  switch (arguments.length) {
    case 0:
      return point;

    case 2:
      x = {
        x: x,
        y: y
      };
      break;
  }

  return extend(point, x);
}
/**
 * Create matrix via args.
 *
 * @example
 *
 * createMatrix({ a: 1, b: 1 });
 * createMatrix();
 * createMatrix(1, 2, 0, 0, 30, 20);
 *
 * @return {SVGMatrix}
 */


function createMatrix(a, b, c, d, e, f) {
  var matrix = node.createSVGMatrix();

  switch (arguments.length) {
    case 0:
      return matrix;

    case 1:
      return extend(matrix, a);

    case 6:
      return extend(matrix, {
        a: a,
        b: b,
        c: c,
        d: d,
        e: e,
        f: f
      });
  }
}

function createTransform(matrix) {
  if (matrix) {
    return node.createSVGTransformFromMatrix(matrix);
  } else {
    return node.createSVGTransform();
  }
}
/**
 * Serialization util
 */


var TEXT_ENTITIES = /([&<>]{1})/g;
var ATTR_ENTITIES = /([\n\r"]{1})/g;
var ENTITY_REPLACEMENT = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '\''
};

function escape(str, pattern) {
  function replaceFn(match, entity) {
    return ENTITY_REPLACEMENT[entity] || entity;
  }

  return str.replace(pattern, replaceFn);
}

function serialize(node, output) {
  var i, len, attrMap, attrNode, childNodes;

  switch (node.nodeType) {
    // TEXT
    case 3:
      // replace special XML characters
      output.push(escape(node.textContent, TEXT_ENTITIES));
      break;
    // ELEMENT

    case 1:
      output.push('<', node.tagName);

      if (node.hasAttributes()) {
        attrMap = node.attributes;

        for (i = 0, len = attrMap.length; i < len; ++i) {
          attrNode = attrMap.item(i);
          output.push(' ', attrNode.name, '="', escape(attrNode.value, ATTR_ENTITIES), '"');
        }
      }

      if (node.hasChildNodes()) {
        output.push('>');
        childNodes = node.childNodes;

        for (i = 0, len = childNodes.length; i < len; ++i) {
          serialize(childNodes.item(i), output);
        }

        output.push('</', node.tagName, '>');
      } else {
        output.push('/>');
      }

      break;
    // COMMENT

    case 8:
      output.push('<!--', escape(node.nodeValue, TEXT_ENTITIES), '-->');
      break;
    // CDATA

    case 4:
      output.push('<![CDATA[', node.nodeValue, ']]>');
      break;

    default:
      throw new Error('unable to handle node ' + node.nodeType);
  }

  return output;
}
/**
 * innerHTML like functionality for SVG elements.
 * based on innerSVG (https://code.google.com/p/innersvg)
 */


function set(element, svg) {
  var parsed = parse(svg); // clear element contents

  clear(element);

  if (!svg) {
    return;
  }

  if (!isFragment(parsed)) {
    // extract <svg> from parsed document
    parsed = parsed.documentElement;
  }

  var nodes = slice(parsed.childNodes); // import + append each node

  for (var i = 0; i < nodes.length; i++) {
    appendTo(nodes[i], element);
  }
}

function get(element) {
  var child = element.firstChild,
      output = [];

  while (child) {
    serialize(child, output);
    child = child.nextSibling;
  }

  return output.join('');
}

function isFragment(node) {
  return node.nodeName === '#document-fragment';
}

function innerSVG(element, svg) {
  if (svg !== undefined) {
    try {
      set(element, svg);
    } catch (e) {
      throw new Error('error parsing SVG: ' + e.message);
    }

    return element;
  } else {
    return get(element);
  }
}

function slice(arr) {
  return Array.prototype.slice.call(arr);
}
/**
 * Selection utilities
 */


function select(node, selector) {
  return node.querySelector(selector);
}

function selectAll(node, selector) {
  var nodes = node.querySelectorAll(selector);
  return [].map.call(nodes, function (element) {
    return element;
  });
}
/**
 * prependTo utility
 */

/**
 * Prepend a node to a target element and return the prepended node.
 *
 * @param  {SVGElement} node
 * @param  {SVGElement} target
 *
 * @return {SVGElement} the prepended node
 */


function prependTo(node, target) {
  return target.insertBefore(ensureImported(node, target), target.firstChild || null);
}
/**
 * prepend utility
 */

/**
 * Prepend a node to a target element
 *
 * @param  {SVGElement} target
 * @param  {SVGElement} node
 *
 * @return {SVGElement} the target element
 */


function prepend(target, node) {
  prependTo(node, target);
  return target;
}
/**
 * Replace utility
 */


function replace(element, replacement) {
  element.parentNode.replaceChild(ensureImported(replacement, element), element);
  return replacement;
}
/**
 * transform accessor utility
 */


function wrapMatrix(transformList, transform) {
  if (transform instanceof SVGMatrix) {
    return transformList.createSVGTransformFromMatrix(transform);
  }

  return transform;
}

function setTransforms(transformList, transforms) {
  var i, t;
  transformList.clear();

  for (i = 0; t = transforms[i]; i++) {
    transformList.appendItem(wrapMatrix(transformList, t));
  }
}
/**
 * Get or set the transforms on the given node.
 *
 * @param {SVGElement} node
 * @param  {SVGTransform|SVGMatrix|Array<SVGTransform|SVGMatrix>} [transforms]
 *
 * @return {SVGTransform} the consolidated transform
 */


function transform(node, transforms) {
  var transformList = node.transform.baseVal;

  if (transforms) {
    if (!Array.isArray(transforms)) {
      transforms = [transforms];
    }

    setTransforms(transformList, transforms);
  }

  return transformList.consolidate();
}

},{}],568:[function(require,module,exports){
module.exports={
  "name": "Activiti",
  "uri": "http://activiti.org/bpmn",
  "prefix": "activiti",
  "xml": {
    "tagAlias": "lowerCase"
  },
  "associations": [],
  "types": [
    {
      "name": "Definitions",
      "isAbstract": true,
      "extends": [
        "bpmn:Definitions"
      ],
      "properties": [
        {
          "name": "diagramRelationId",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "InOutBinding",
      "superClass": [
        "Element"
      ],
      "isAbstract": true,
      "properties": [
        {
          "name": "source",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "sourceExpression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "target",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "businessKey",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "local",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        },
        {
          "name": "variables",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "In",
      "superClass": [
        "InOutBinding"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:CallActivity"
        ]
      }
    },
    {
      "name": "Out",
      "superClass": [
        "InOutBinding"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:CallActivity"
        ]
      }
    },
    {
      "name": "AsyncCapable",
      "isAbstract": true,
      "extends": [
        "bpmn:Activity",
        "bpmn:Gateway",
        "bpmn:Event"
      ],
      "properties": [
        {
          "name": "async",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        },
        {
          "name": "asyncBefore",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        },
        {
          "name": "asyncAfter",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        },
        {
          "name": "exclusive",
          "isAttr": true,
          "type": "Boolean",
          "default": true
        }
      ]
    },
    {
      "name": "JobPriorized",
      "isAbstract": true,
      "extends": [
        "bpmn:Process",
        "activiti:AsyncCapable"
      ],
      "properties": [
        {
          "name": "jobPriority",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "SignalEventDefinition",
      "isAbstract": true,
      "extends": [
        "bpmn:SignalEventDefinition"
      ],
      "properties": [
        {
          "name": "async",
          "isAttr": true,
          "type": "Boolean",
          "default": false
        }
      ]
    },
    {
      "name": "ErrorEventDefinition",
      "isAbstract": true,
      "extends": [
        "bpmn:ErrorEventDefinition"
      ],
      "properties": [
        {
          "name": "errorCodeVariable",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "errorMessageVariable",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Error",
      "isAbstract": true,
      "extends": [
        "bpmn:Error"
      ],
      "properties": [
        {
          "name": "activiti:errorMessage",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "PotentialStarter",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "resourceAssignmentExpression",
          "type": "bpmn:ResourceAssignmentExpression"
        }
      ]
    },
    {
      "name": "FormSupported",
      "isAbstract": true,
      "extends": [
        "bpmn:StartEvent",
        "bpmn:UserTask"
      ],
      "properties": [
        {
          "name": "formHandlerClass",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "formKey",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "TemplateSupported",
      "isAbstract": true,
      "extends": [
        "bpmn:Process",
        "bpmn:FlowElement"
      ],
      "properties": [
        {
          "name": "modelerTemplate",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Initiator",
      "isAbstract": true,
      "extends": [ "bpmn:StartEvent" ],
      "properties": [
        {
          "name": "initiator",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "ScriptTask",
      "isAbstract": true,
      "extends": [
        "bpmn:ScriptTask"
      ],
      "properties": [
        {
          "name": "resultVariable",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "resource",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Process",
      "isAbstract": true,
      "extends": [
        "bpmn:Process"
      ],
      "properties": [
        {
          "name": "candidateStarterConfiguration",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "candidateStarterUsers",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "versionTag",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "historyTimeToLive",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "isStartableInTasklist",
          "isAttr": true,
          "type": "Boolean",
          "default": true
        },
        {
          "name": "process-is-executable",
          "isAttr": true,
          "type": "Boolean",
          "default": true
        }
      ]
    },
    {
      "name": "EscalationEventDefinition",
      "isAbstract": true,
      "extends": [
        "bpmn:EscalationEventDefinition"
      ],
      "properties": [
        {
          "name": "escalationCodeVariable",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "FormalExpression",
      "isAbstract": true,
      "extends": [
        "bpmn:FormalExpression"
      ],
      "properties": [
        {
          "name": "resource",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Assignable",
      "extends": [ "bpmn:UserTask" ],
      "properties": [
        {
          "name": "assignee",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "candidateUsers",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "candidateGroups",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "dueDate",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "followUpDate",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "priority",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "CallActivity",
      "extends": [ "bpmn:CallActivity" ],
      "properties": [
        {
          "name": "calledElementBinding",
          "isAttr": true,
          "type": "String",
          "default": "latest"
        },
        {
          "name": "calledElementVersion",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "calledElementVersionTag",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "calledElementTenantId",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "caseRef",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "caseBinding",
          "isAttr": true,
          "type": "String",
          "default": "latest"
        },
        {
          "name": "caseVersion",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "caseTenantId",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "variableMappingClass",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "variableMappingDelegateExpression",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "ServiceTaskLike",
      "extends": [
        "bpmn:ServiceTask",
        "bpmn:BusinessRuleTask",
        "bpmn:SendTask",
        "bpmn:MessageEventDefinition"
      ],
      "properties": [
        {
          "name": "expression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "class",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "delegateExpression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "resultVariable",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "DmnCapable",
      "extends": [
        "bpmn:BusinessRuleTask"
      ],
      "properties": [
        {
          "name": "decisionRef",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "decisionRefBinding",
          "isAttr": true,
          "type": "String",
          "default": "latest"
        },
        {
          "name": "decisionRefVersion",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "mapDecisionResult",
          "isAttr": true,
          "type": "String",
          "default": "resultList"
        },
        {
          "name": "decisionRefTenantId",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "ExternalCapable",
      "extends": [
        "activiti:ServiceTaskLike"
      ],
      "properties": [
        {
          "name": "type",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "topic",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "TaskPriorized",
      "extends": [
        "bpmn:Process",
        "activiti:ExternalCapable"
      ],
      "properties": [
        {
          "name": "taskPriority",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Properties",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [ "*" ]
      },
      "properties": [
        {
          "name": "values",
          "type": "Property",
          "isMany": true
        }
      ]
    },
    {
      "name": "Property",
      "superClass": [
        "Element"
      ],
      "properties": [
        {
          "name": "id",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "name",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "value",
          "type": "String",
          "isAttr": true
        }
      ]
    },
    {
      "name": "Connector",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "activiti:ServiceTaskLike"
        ]
      },
      "properties": [
        {
          "name": "inputOutput",
          "type": "InputOutput"
        },
        {
          "name": "connectorId",
          "type": "String"
        }
      ]
    },
    {
      "name": "InputOutput",
      "superClass": [
        "Element"
      ],
      "meta": {
        "allowedIn": [
          "bpmn:FlowNode",
          "activiti:Connector"
        ]
      },
      "properties": [
        {
          "name": "inputOutput",
          "type": "InputOutput"
        },
        {
          "name": "connectorId",
          "type": "String"
        },
        {
          "name": "inputParameters",
          "isMany": true,
          "type": "InputParameter"
        },
        {
          "name": "outputParameters",
          "isMany": true,
          "type": "OutputParameter"
        }
      ]
    },
    {
      "name": "InputOutputParameter",
      "properties": [
        {
          "name": "name",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "value",
          "isBody": true,
          "type": "String"
        },
        {
          "name": "definition",
          "type": "InputOutputParameterDefinition"
        }
      ]
    },
    {
      "name": "InputOutputParameterDefinition",
      "isAbstract": true
    },
    {
      "name": "List",
      "superClass": [ "InputOutputParameterDefinition" ],
      "properties": [
        {
          "name": "items",
          "isMany": true,
          "type": "InputOutputParameterDefinition"
        }
      ]
    },
    {
      "name": "Map",
      "superClass": [ "InputOutputParameterDefinition" ],
      "properties": [
        {
          "name": "entries",
          "isMany": true,
          "type": "Entry"
        }
      ]
    },
    {
      "name": "Entry",
      "properties": [
        {
          "name": "key",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "value",
          "isBody": true,
          "type": "String"
        },
        {
          "name": "definition",
          "type": "InputOutputParameterDefinition"
        }
      ]
    },
    {
      "name": "Value",
      "superClass": [
        "InputOutputParameterDefinition"
      ],
      "properties": [
        {
          "name": "id",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "name",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "value",
          "isBody": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Script",
      "superClass": [ "InputOutputParameterDefinition" ],
      "properties": [
        {
          "name": "scriptFormat",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "resource",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "value",
          "isBody": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "Field",
      "superClass": [ "Element" ],
      "meta": {
        "allowedIn": [
          "activiti:ServiceTaskLike",
          "activiti:ExecutionListener",
          "activiti:TaskListener"
        ]
      },
      "properties": [
        {
          "name": "name",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "expression",
          "type": "String"
        },
        {
          "name": "stringValue",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "string",
          "type": "String"
        }
      ]
    },
    {
      "name": "InputParameter",
      "superClass": [ "InputOutputParameter" ]
    },
    {
      "name": "OutputParameter",
      "superClass": [ "InputOutputParameter" ]
    },
    {
      "name": "Collectable",
      "isAbstract": true,
      "extends": [ "bpmn:MultiInstanceLoopCharacteristics" ],
      "superClass": [ "activiti:AsyncCapable" ],
      "properties": [
        {
          "name": "collection",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "elementVariable",
          "isAttr": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "FailedJobRetryTimeCycle",
      "superClass": [ "Element" ],
      "meta": {
        "allowedIn": [
          "activiti:AsyncCapable",
          "bpmn:MultiInstanceLoopCharacteristics"
        ]
      },
      "properties": [
        {
          "name": "body",
          "isBody": true,
          "type": "String"
        }
      ]
    },
    {
      "name": "ExecutionListener",
      "superClass": [ "Element" ],
      "meta": {
        "allowedIn": [
          "bpmn:Task",
          "bpmn:ServiceTask",
          "bpmn:UserTask",
          "bpmn:BusinessRuleTask",
          "bpmn:ScriptTask",
          "bpmn:ReceiveTask",
          "bpmn:ManualTask",
          "bpmn:ExclusiveGateway",
          "bpmn:SequenceFlow",
          "bpmn:ParallelGateway",
          "bpmn:InclusiveGateway",
          "bpmn:EventBasedGateway",
          "bpmn:StartEvent",
          "bpmn:IntermediateCatchEvent",
          "bpmn:IntermediateThrowEvent",
          "bpmn:EndEvent",
          "bpmn:BoundaryEvent",
          "bpmn:CallActivity",
          "bpmn:SubProcess",
          "bpmn:Process"
        ]
      },
      "properties": [
        {
          "name": "expression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "class",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "delegateExpression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "event",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "script",
          "type": "Script"
        },
        {
          "name": "fields",
          "type": "Field",
          "isMany": true
        }
      ]
    },
    {
      "name": "TaskListener",
      "superClass": [ "Element" ],
      "meta": {
        "allowedIn": [
          "bpmn:UserTask"
        ]
      },
      "properties": [
        {
          "name": "expression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "class",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "delegateExpression",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "event",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "script",
          "type": "Script"
        },
        {
          "name": "fields",
          "type": "Field",
          "isMany": true
        },
        {
          "name": "id",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "eventDefinitions",
          "type": "bpmn:TimerEventDefinition",
          "isMany": true
        }
      ]
    },
    {
      "name": "FormProperty",
      "superClass": [ "Element" ],
      "meta": {
        "allowedIn": [
          "bpmn:StartEvent",
          "bpmn:UserTask"
        ]
      },
      "properties": [
        {
          "name": "id",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "name",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "type",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "required",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "readable",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "writable",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "variable",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "expression",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "datePattern",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "default",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "values",
          "type": "Value",
          "isMany": true
        }
      ]
    },
    {
      "name": "FormData",
      "superClass": [ "Element" ],
      "meta": {
        "allowedIn": [
          "bpmn:StartEvent",
          "bpmn:UserTask"
        ]
      },
      "properties": [
        {
          "name": "fields",
          "type": "FormField",
          "isMany": true
        },
        {
          "name": "businessKey",
          "type": "String",
          "isAttr": true
        }
      ]
    },
    {
      "name": "FormField",
      "superClass": [ "Element" ],
      "properties": [
        {
          "name": "id",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "label",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "type",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "datePattern",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "defaultValue",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "properties",
          "type": "Properties"
        },
        {
          "name": "validation",
          "type": "Validation"
        },
        {
          "name": "values",
          "type": "Value",
          "isMany": true
        }
      ]
    },
    {
      "name": "Validation",
      "superClass": [ "Element" ],
      "properties": [
        {
          "name": "constraints",
          "type": "Constraint",
          "isMany": true
        }
      ]
    },
    {
      "name": "Constraint",
      "superClass": [ "Element" ],
      "properties": [
        {
          "name": "name",
          "type": "String",
          "isAttr": true
        },
        {
          "name": "config",
          "type": "String",
          "isAttr": true
        }
      ]
    },
    {
      "name": "ConditionalEventDefinition",
      "isAbstract": true,
      "extends": [
        "bpmn:ConditionalEventDefinition"
      ],
      "properties": [
        {
          "name": "variableName",
          "isAttr": true,
          "type": "String"
        },
        {
          "name": "variableEvent",
          "isAttr": true,
          "type": "String"
        }
      ]
    }
  ],
  "emumerations": [ ]
}

},{}],569:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

class CustomContextPad {
  constructor(config, contextPad, create, elementFactory, injector, translate) {
    this.create = create;
    this.elementFactory = elementFactory;
    this.translate = translate; //自动摆放位置

    if (config.autoPlace !== false) {
      this.autoPlace = injector.get('autoPlace', false);
    } //注册工具


    contextPad.registerProvider(this);
  }

  getContextPadEntries(element) {
    const {
      autoPlace,
      create,
      elementFactory,
      translate
    } = this;

    function appendUserTask(event, element) {
      if (autoPlace) {
        const shape = elementFactory.createShape({
          type: 'bpmn:UserTask'
        });
        autoPlace.append(element, shape);
      } else {
        appendUserTaskStart(event, element);
      }
    }

    function appendUserTaskStart(event) {
      const shape = elementFactory.createShape({
        type: 'bpmn:UserTask'
      });
      create.start(event, shape, element);
    }

    function appendCallActivityStart(event) {
      const shape = elementFactory.createShape({
        type: 'bpmn:CallActivity'
      });
      create.start(event, shape, element);
    }

    function appendCallActivity(event, element) {
      if (autoPlace) {
        const shape = elementFactory.createShape({
          type: 'bpmn:CallActivity'
        });
        autoPlace.append(element, shape);
      } else {
        appendCallActivityStart(event, element);
      }
    }

    return {
      'append.user-task': {
        group: 'model',
        className: 'bpmn-icon-user-task',
        title: translate('Append ServiceTask'),
        action: {
          click: appendUserTask,
          dragstart: appendUserTaskStart
        }
      },
      'append.call-activity': {
        group: 'model',
        className: 'bpmn-icon-call-activity',
        title: translate('Append CallActivity'),
        action: {
          click: appendCallActivity,
          dragstart: appendCallActivityStart
        }
      }
    };
  }

}

exports.default = CustomContextPad;
CustomContextPad.$inject = ['config', 'contextPad', 'create', 'elementFactory', 'injector', 'translate'];

},{}],570:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

class CustomPalette {
  constructor(create, elementFactory, palette, translate) {
    this.create = create;
    this.elementFactory = elementFactory;
    this.translate = translate;
    palette.registerProvider(this);
  }

  getPaletteEntries(element) {
    const {
      create,
      elementFactory,
      translate
    } = this;

    function createServiceTask(event) {
      const shape = elementFactory.createShape({
        type: 'bpmn:UserTask'
      });
      create.start(event, shape);
    }

    function createCallActivity(event) {
      const shape = elementFactory.createShape({
        type: 'bpmn:CallActivity'
      });
      create.start(event, shape);
    }

    return {
      'create.user-task': {
        group: 'activity',
        className: 'bpmn-icon-user-task',
        title: translate('Create UserTask'),
        action: {
          dragstart: createServiceTask,
          click: createServiceTask
        }
      },
      'create.call-activity': {
        group: 'activity',
        className: 'bpmn-icon-call-activity',
        title: translate('Create CallActivity'),
        action: {
          dragstart: createCallActivity,
          click: createCallActivity
        }
      }
    };
  }

}

exports.default = CustomPalette;
CustomPalette.$inject = ['create', 'elementFactory', 'palette', 'translate'];

},{}],571:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _CustomContextPad = _interopRequireDefault(require("./CustomContextPad"));

var _CustomPalette = _interopRequireDefault(require("./CustomPalette"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _default = {
  __init__: ['customContextPad', 'customPalette'],
  customContextPad: ['type', _CustomContextPad.default],
  customPalette: ['type', _CustomPalette.default]
};
exports.default = _default;

},{"./CustomContextPad":569,"./CustomPalette":570}],572:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = customTranslate;

var _translationsGerman = _interopRequireDefault(require("./translationsGerman"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function customTranslate(template, replacements) {
  replacements = replacements || {};
  template = _translationsGerman.default[template] || template;
  return template.replace(/{([^}]+)}/g, function (_, key) {
    var str = replacements[key];

    if (_translationsGerman.default[replacements[key]] != null && _translationsGerman.default[replacements[key]] != 'undefined') {
      str = _translationsGerman.default[replacements[key]];
    }

    return str || '{' + key + '}';
  });
}

},{"./translationsGerman":573}],573:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _default = {
  // Labels
  'Activate the global connect tool': '激活全局连接工具',
  'Append {type}': '追加 {type}',
  'Append EndEvent': '追加 结束事件 ',
  'Append Task': '追加 任务',
  'Append Gateway': '追加 网关',
  'Append Intermediate/Boundary Event': '追加 中间/边界 事件',
  'Add Lane above': '在上面添加道',
  'Divide into two Lanes': '分割成两个道',
  'Divide into three Lanes': '分割成三个道',
  'Add Lane below': '在下面添加道',
  'Append compensation activity': '追加补偿活动',
  'Change type': '修改类型',
  'Connect using Association': '使用关联连接',
  'Connect using Sequence/MessageFlow or Association': '使用顺序/消息流或者关联连接',
  'Connect using DataInputAssociation': '使用数据输入关联连接',
  'Remove': '移除',
  'Activate the hand tool': '激活抓手工具',
  'Activate the lasso tool': '激活套索工具',
  'Activate the create/remove space tool': '激活创建/删除空间工具',
  'Create expanded SubProcess': '创建扩展子过程',
  'Create IntermediateThrowEvent/BoundaryEvent': '创建中间抛出事件/边界事件',
  'Create Pool/Participant': '创建池/参与者',
  'Parallel Multi Instance': '并行多重事件',
  'Sequential Multi Instance': '时序多重事件',
  'DataObjectReference': '数据对象参考',
  'DataStoreReference': '数据存储参考',
  'Loop': '循环',
  'Ad-hoc': '即席',
  'Create {type}': '创建 {type}',
  'Create Task': '创建任务',
  'Create StartEvent': '创建开始事件',
  'Create EndEvent': '创建结束事件',
  'Create Group': '创建组',
  'Task': '任务',
  'Send Task': '发送任务',
  'Receive Task': '接收任务',
  'User Task': '用户任务',
  'Manual Task': '手工任务',
  'Business Rule Task': '业务规则任务',
  'Service Task': '服务任务',
  'Script Task': '脚本任务',
  'Call Activity': '调用活动',
  'Sub Process (collapsed)': '子流程(折叠的)',
  'Sub Process (expanded)': '子流程(展开的)',
  'Start Event': '开始事件',
  'StartEvent': '开始事件',
  'Intermediate Throw Event': '中间事件',
  'End Event': '结束事件',
  'EndEvent': '结束事件',
  'Create Gateway': '创建网关',
  'GateWay': '网关',
  'Create Intermediate/Boundary Event': '创建中间/边界事件',
  'Message Start Event': '消息开始事件',
  'Timer Start Event': '定时开始事件',
  'Conditional Start Event': '条件开始事件',
  'Signal Start Event': '信号开始事件',
  'Error Start Event': '错误开始事件',
  'Escalation Start Event': '升级开始事件',
  'Compensation Start Event': '补偿开始事件',
  'Message Start Event (non-interrupting)': '消息开始事件(非中断)',
  'Timer Start Event (non-interrupting)': '定时开始事件(非中断)',
  'Conditional Start Event (non-interrupting)': '条件开始事件(非中断)',
  'Signal Start Event (non-interrupting)': '信号开始事件(非中断)',
  'Escalation Start Event (non-interrupting)': '升级开始事件(非中断)',
  'Message Intermediate Catch Event': '消息中间捕获事件',
  'Message Intermediate Throw Event': '消息中间抛出事件',
  'Timer Intermediate Catch Event': '定时中间捕获事件',
  'Escalation Intermediate Throw Event': '升级中间抛出事件',
  'Conditional Intermediate Catch Event': '条件中间捕获事件',
  'Link Intermediate Catch Event': '链接中间捕获事件',
  'Link Intermediate Throw Event': '链接中间抛出事件',
  'Compensation Intermediate Throw Event': '补偿中间抛出事件',
  'Signal Intermediate Catch Event': '信号中间捕获事件',
  'Signal Intermediate Throw Event': '信号中间抛出事件',
  'Message End Event': '消息结束事件',
  'Escalation End Event': '定时结束事件',
  'Error End Event': '错误结束事件',
  'Cancel End Event': '取消结束事件',
  'Compensation End Event': '补偿结束事件',
  'Signal End Event': '信号结束事件',
  'Terminate End Event': '终止结束事件',
  'Message Boundary Event': '消息边界事件',
  'Message Boundary Event (non-interrupting)': '消息边界事件(非中断)',
  'Timer Boundary Event': '定时边界事件',
  'Timer Boundary Event (non-interrupting)': '定时边界事件(非中断)',
  'Escalation Boundary Event': '升级边界事件',
  'Escalation Boundary Event (non-interrupting)': '升级边界事件(非中断)',
  'Conditional Boundary Event': '条件边界事件',
  'Conditional Boundary Event (non-interrupting)': '条件边界事件(非中断)',
  'Error Boundary Event': '错误边界事件',
  'Cancel Boundary Event': '取消边界事件',
  'Signal Boundary Event': '信号边界事件',
  'Signal Boundary Event (non-interrupting)': '信号边界事件(非中断)',
  'Compensation Boundary Event': '补偿边界事件',
  'Exclusive Gateway': '互斥网关',
  'Parallel Gateway': '并行网关',
  'Inclusive Gateway': '相容网关',
  'Complex Gateway': '复杂网关',
  'Event based Gateway': '事件网关',
  'Transaction': '转运',
  'Sub Process': '子流程',
  'Event Sub Process': '事件子流程',
  'Collapsed Pool': '折叠池',
  'Expanded Pool': '展开池',
  // Errors
  'no parent for {element} in {parent}': '在{parent}里,{element}没有父类',
  'no shape type specified': '没有指定的形状类型',
  'flow elements must be children of pools/participants': '流元素必须是池/参与者的子类',
  'out of bounds release': 'out of bounds release',
  'more than {count} child lanes': '子道大于{count} ',
  'element required': '元素不能为空',
  'diagram not part of bpmn:Definitions': '流程图不符合bpmn规范',
  'no diagram to display': '没有可展示的流程图',
  'no process or collaboration to display': '没有可展示的流程/协作',
  'element {element} referenced by {referenced}#{property} not yet drawn': '由{referenced}#{property}引用的{element}元素仍未绘制',
  'already rendered {element}': '{element} 已被渲染',
  'failed to import {element}': '导入{element}失败',
  //属性面板的参数
  'Id': '编号',
  'Name': '名称',
  'General': '常规',
  'Details': '详情',
  'Message Name': '消息名称',
  'Message': '消息',
  'Initiator': '创建者',
  'Asynchronous Continuations': '持续异步',
  'Asynchronous Before': '异步前',
  'Asynchronous After': '异步后',
  'Job Configuration': '工作配置',
  'Exclusive': '排除',
  'Job Priority': '工作优先级',
  'Retry Time Cycle': '重试时间周期',
  'Documentation': '文档',
  'Element Documentation': '元素文档',
  'History Configuration': '历史配置',
  'History Time To Live': '历史的生存时间',
  'Forms': '表单',
  'Form Key': '表单key',
  'Form Fields': '表单字段',
  'Business Key': '业务key',
  'Form Field': '表单字段',
  'ID': '编号',
  'Type': '类型',
  'Label': '名称',
  'Default Value': '默认值',
  'Validation': '校验',
  'Add Constraint': '添加约束',
  'Config': '配置',
  'Properties': '属性',
  'Add Property': '添加属性',
  'Value': '值',
  'Add': '添加',
  'Values': '值',
  'Add Value': '添加值',
  'Listeners': '监听器',
  'Execution Listener': '执行监听',
  'Event Type': '事件类型',
  'Listener Type': '监听器类型',
  'Java Class': 'Java类',
  'Expression': '表达式',
  'Must provide a value': '必须提供一个值',
  'Delegate Expression': '代理表达式',
  'Script': '脚本',
  'Script Format': '脚本格式',
  'Script Type': '脚本类型',
  'Inline Script': '内联脚本',
  'External Script': '外部脚本',
  'Resource': '资源',
  'Field Injection': '字段注入',
  'Extensions': '扩展',
  'Input/Output': '输入/输出',
  'Input Parameters': '输入参数',
  'Output Parameters': '输出参数',
  'Parameters': '参数',
  'Output Parameter': '输出参数',
  'Timer Definition Type': '定时器定义类型',
  'Timer Definition': '定时器定义',
  'Date': '日期',
  'Duration': '持续',
  'Cycle': '循环',
  'Signal': '信号',
  'Signal Name': '信号名称',
  'Escalation': '升级',
  'Error': '错误',
  'Link Name': '链接名称',
  'Condition': '条件名称',
  'Variable Name': '变量名称',
  'Variable Event': '变量事件',
  'Specify more than one variable change event as a comma separated list.': '多个变量事件以逗号隔开',
  'Wait for Completion': '等待完成',
  'Activity Ref': '活动参考',
  'Version Tag': '版本标签',
  'Executable': '可执行文件',
  'External Task Configuration': '扩展任务配置',
  'Task Priority': '任务优先级',
  'External': '外部',
  'Connector': '连接器',
  'Must configure Connector': '必须配置连接器',
  'Connector Id': '连接器编号',
  'Implementation': '实现方式',
  'Field Injections': '字段注入',
  'Fields': '字段',
  'Result Variable': '结果变量',
  'Topic': '主题',
  'Configure Connector': '配置连接器',
  'Input Parameter': '输入参数',
  'Assignee': '代理人',
  'Candidate Users': '候选用户',
  'Candidate Groups': '候选组',
  'Due Date': '到期时间',
  'Follow Up Date': '跟踪日期',
  'Priority': '优先级',
  'The follow up date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)': '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00',
  'The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)': '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00',
  'Variables': '变量',
  'Candidate Starter Configuration': '候选开始配置',
  'Task Listener': '任务监听器',
  'Candidate Starter Groups': '候选开始组',
  'Candidate Starter Users': '候选开始用户',
  'Tasklist Configuration': '任务列表配置',
  'Startable': '启动',
  'Specify more than one group as a comma separated list.': '指定多个组,用逗号分隔',
  'Specify more than one user as a comma separated list.': '指定多个用户,用逗号分隔',
  'This maps to the process definition key.': '这会映射为流程定义的键',
  'CallActivity Type': '调用活动类型',
  'Condition Type': '条件类型',
  'Create UserTask': '创建用户任务',
  'Create CallActivity': '创建调用活动',
  'Called Element': '调用元素',
  'Create DataObjectReference': '创建数据对象引用',
  'Create DataStoreReference': '创建数据存储引用',
  'Multi Instance': '多实例',
  'Loop Cardinality': '实例数量',
  'Collection': '任务参与人列表',
  'Element Variable': '元素变量',
  'Completion Condition': '完成条件'
};
exports.default = _default;

},{}],574:[function(require,module,exports){
module.exports = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<bpmn2:definitions xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:bpmn2=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\" xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd\" id=\"sample-diagram\" targetNamespace=\"http://activiti.org/bpmn\">\r\n  <bpmn2:process id=\"Process_1\" isExecutable=\"true\">\r\n    <bpmn2:startEvent id=\"StartEvent_1\"/>\r\n  </bpmn2:process>\r\n  <bpmndi:BPMNDiagram id=\"BPMNDiagram_1\">\r\n    <bpmndi:BPMNPlane id=\"BPMNPlane_1\" bpmnElement=\"Process_1\">\r\n      <bpmndi:BPMNShape id=\"_BPMNShape_StartEvent_2\" bpmnElement=\"StartEvent_1\">\r\n        <dc:Bounds height=\"36.0\" width=\"36.0\" x=\"412.0\" y=\"240.0\"/>\r\n      </bpmndi:BPMNShape>\r\n    </bpmndi:BPMNPlane>\r\n  </bpmndi:BPMNDiagram>\r\n</bpmn2:definitions>";

},{}],575:[function(require,module,exports){
'use strict';

var DEFAULT_PRIORITY = 1000;


/**
 * A component that decides upon the visibility / editable
 * state of properties in the properties panel.
 *
 * Implementors must subclass this component and override
 * {@link PropertiesActivator#isEntryVisible} and
 * {@link PropertiesActivator#isPropertyEditable} to provide
 * custom behavior.
 *
 * @class
 * @constructor
 *
 * @param {EventBus} eventBus
 * @param {Number} [priority] at which priority to hook into the activation
 */
function PropertiesActivator(eventBus, priority) {
  var self = this;

  priority = priority || DEFAULT_PRIORITY;

  eventBus.on('propertiesPanel.isEntryVisible', priority, function(e) {
    return self.isEntryVisible(e.entry, e.element);
  });

  eventBus.on('propertiesPanel.isPropertyEditable', priority, function(e) {
    return self.isPropertyEditable(e.entry, e.propertyName, e.element);
  });
}

PropertiesActivator.$inject = [ 'eventBus' ];

module.exports = PropertiesActivator;


/**
 * Should the given entry be visible for the specified element.
 *
 * @method  PropertiesActivator#isEntryVisible
 *
 * @param {EntryDescriptor} entry
 * @param {ModdleElement} element
 *
 * @returns {Boolean}
 */
PropertiesActivator.prototype.isEntryVisible = function(entry, element) {
  return true;
};

/**
 * Should the given property be editable for the specified element
 *
 * @method  PropertiesActivator#isPropertyEditable
 *
 * @param {EntryDescriptor} entry
 * @param {String} propertyName
 * @param {ModdleElement} element
 *
 * @returns {Boolean}
 */
PropertiesActivator.prototype.isPropertyEditable = function(entry, propertyName, element) {
  return true;
};
},{}],576:[function(require,module,exports){
'use strict';

var domQuery = require('min-dom').query,
    domClear = require('min-dom').clear,
    is = require('bpmn-js/lib/util/ModelUtil').is,
    forEach = require('lodash/forEach'),
    domify = require('min-dom').domify,
    Ids = require('ids').default;

var SPACE_REGEX = /\s/;

// for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar
var QNAME_REGEX = /^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i;

// for ID validation as per BPMN Schema (QName - Namespace)
var ID_REGEX = /^[a-z_][\w-.]*$/i;

var PLACEHOLDER_REGEX = /\$\{([^}]*)\}/g;

var HTML_ESCAPE_MAP = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  '\'': '&#39;'
};

function selectedOption(selectBox) {
  if (selectBox.selectedIndex >= 0) {
    return selectBox.options[selectBox.selectedIndex].value;
  }
}

module.exports.selectedOption = selectedOption;


function selectedType(elementSyntax, inputNode) {
  var typeSelect = domQuery(elementSyntax, inputNode);
  return selectedOption(typeSelect);
}

module.exports.selectedType = selectedType;


/**
 * Retrieve the root element the document this
 * business object is contained in.
 *
 * @return {ModdleElement}
 */
function getRoot(businessObject) {
  var parent = businessObject;
  while (parent.$parent) {
    parent = parent.$parent;
  }
  return parent;
}

module.exports.getRoot = getRoot;


/**
 * filters all elements in the list which have a given type.
 * removes a new list
 */
function filterElementsByType(objectList, type) {
  var list = objectList || [];
  var result = [];
  forEach(list, function(obj) {
    if (is(obj, type)) {
      result.push(obj);
    }
  });
  return result;
}

module.exports.filterElementsByType = filterElementsByType;


function findRootElementsByType(businessObject, referencedType) {
  var root = getRoot(businessObject);

  return filterElementsByType(root.rootElements, referencedType);
}

module.exports.findRootElementsByType = findRootElementsByType;


function removeAllChildren(domElement) {
  while (domElement.firstChild) {
    domElement.removeChild(domElement.firstChild);
  }
}

module.exports.removeAllChildren = removeAllChildren;


/**
 * adds an empty option to the list
 */
function addEmptyParameter(list) {
  return list.push({ 'label': '', 'value': '', 'name': '' });
}

module.exports.addEmptyParameter = addEmptyParameter;


/**
 * returns a list with all root elements for the given parameter 'referencedType'
 */
function refreshOptionsModel(businessObject, referencedType) {
  var model = [];
  var referableObjects = findRootElementsByType(businessObject, referencedType);
  forEach(referableObjects, function(obj) {
    model.push({
      label: (obj.name || '') + ' (id='+obj.id+')',
      value: obj.id,
      name: obj.name
    });
  });
  return model;
}

module.exports.refreshOptionsModel = refreshOptionsModel;


/**
 * fills the drop down with options
 */
function updateOptionsDropDown(domSelector, businessObject, referencedType, entryNode) {
  var options = refreshOptionsModel(businessObject, referencedType);
  addEmptyParameter(options);
  var selectBox = domQuery(domSelector, entryNode);
  domClear(selectBox);

  forEach(options, function(option) {
    var optionEntry = domify('<option value="' + escapeHTML(option.value) + '">' + escapeHTML(option.label) + '</option>');
    selectBox.appendChild(optionEntry);
  });
  return options;
}

module.exports.updateOptionsDropDown = updateOptionsDropDown;


/**
 * checks whether the id value is valid
 *
 * @param {ModdleElement} bo
 * @param {String} idValue
 * @param {Function} translate
 *
 * @return {String} error message
 */
function isIdValid(bo, idValue, translate) {
  var assigned = bo.$model.ids.assigned(idValue);

  var idExists = assigned && assigned !== bo;

  if (!idValue || idExists) {
    return translate('Element must have an unique id.');
  }

  return validateId(idValue, translate);
}

module.exports.isIdValid = isIdValid;


function validateId(idValue, translate) {

  idValue = stripPlaceholders(idValue);

  if (containsSpace(idValue)) {
    return translate('Id must not contain spaces.');
  }

  if (!ID_REGEX.test(idValue)) {

    if (QNAME_REGEX.test(idValue)) {
      return translate('Id must not contain prefix.');
    }

    return translate('Id must be a valid QName.');
  }
}

module.exports.validateId = validateId;


function containsSpace(value) {
  return SPACE_REGEX.test(value);
}

module.exports.containsSpace = containsSpace;


function stripPlaceholders(idValue) {

  // replace expression e.g. ${VERSION_TAG}
  // use only the content between ${}
  // for the REGEX check
  return idValue.replace(PLACEHOLDER_REGEX, '$1');
}

/**
 * generate a semantic id with given prefix
 */
function nextId(prefix) {
  var ids = new Ids([32,32,1]);

  return ids.nextPrefixed(prefix);
}

module.exports.nextId = nextId;


function triggerClickEvent(element) {
  var evt;
  var eventType = 'click';

  if (document.createEvent) {
    try {
      // Chrome, Safari, Firefox
      evt = new MouseEvent((eventType), { view: window, bubbles: true, cancelable: true });
    } catch (e) {
      // IE 11, PhantomJS (wat!)
      evt = document.createEvent('MouseEvent');

      evt.initEvent((eventType), true, true);
    }
    return element.dispatchEvent(evt);
  } else {
    // Welcome IE
    evt = document.createEventObject();

    return element.fireEvent('on' + eventType, evt);
  }
}

module.exports.triggerClickEvent = triggerClickEvent;


function escapeHTML(str) {
  str = '' + str;

  return str && str.replace(/[&<>"']/g, function(match) {
    return HTML_ESCAPE_MAP[match];
  });
}

module.exports.escapeHTML = escapeHTML;
},{"bpmn-js/lib/util/ModelUtil":141,"ids":346,"lodash/forEach":522,"min-dom":556}],577:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    cmdHelper = require('../helper/CmdHelper'),
    escapeHTML = require('../Utils').escapeHTML;

var entryFieldDescription = require('./EntryFieldDescription');


var checkbox = function(options, defaultParameters) {
  var resource = defaultParameters,
      id = resource.id,
      label = options.label || id,
      canBeDisabled = !!options.disabled && typeof options.disabled === 'function',
      canBeHidden = !!options.hidden && typeof options.hidden === 'function',
      description = options.description;

  resource.html =
    '<input id="activiti-' + escapeHTML(id) + '" ' +
         'type="checkbox" ' +
         'name="' + escapeHTML(options.modelProperty) + '" ' +
         (canBeDisabled ? 'data-disable="isDisabled"' : '') +
         (canBeHidden ? 'data-show="isHidden"' : '') +
         ' />' +
    '<label for="activiti-' + escapeHTML(id) + '" ' +
         (canBeDisabled ? 'data-disable="isDisabled"' : '') +
         (canBeHidden ? 'data-show="isHidden"' : '') +
         '>' + escapeHTML(label) + '</label>';

  // add description below checkbox entry field
  if (description) {
    resource.html += entryFieldDescription(description);
  }

  resource.get = function(element) {
    var bo = getBusinessObject(element),
        res = {};

    res[options.modelProperty] = bo.get(options.modelProperty);

    return res;
  };

  resource.set = function(element, values) {
    var res = {};

    res[options.modelProperty] = !!values[options.modelProperty];

    return cmdHelper.updateProperties(element, res);
  };

  if (typeof options.set === 'function') {
    resource.set = options.set;
  }

  if (typeof options.get === 'function') {
    resource.get = options.get;
  }

  if (canBeDisabled) {
    resource.isDisabled = function() {
      return options.disabled.apply(resource, arguments);
    };
  }

  if (canBeHidden) {
    resource.isHidden = function() {
      return !options.hidden.apply(resource, arguments);
    };
  }

  resource.cssClasses = ['bpp-checkbox'];

  return resource;
};

module.exports = checkbox;

},{"../Utils":576,"../helper/CmdHelper":590,"./EntryFieldDescription":580,"bpmn-js/lib/util/ModelUtil":141}],578:[function(require,module,exports){
'use strict';

var assign = require('lodash/assign'),
    find = require('lodash/find');

var domQuery = require('min-dom').query;

var escapeHTML = require('../Utils').escapeHTML;

var selectEntryFactory = require('./SelectEntryFactory'),
    entryFieldDescription = require('./EntryFieldDescription');


/**
 * The combo box is a special implementation of the select entry and adds the option 'custom' to the
 * select box. If 'custom' is selected, an additional text input field is shown which allows to define
 * a custom value.
 *
 * @param  {Object} options
 * @param  {string} options.id
 * @param  {string} options.label
 * @param  {Array<Object>} options.selectOptions list of name/value pairs
 * @param  {string} options.modelProperty
 * @param  {function} options.get
 * @param  {function} options.set
 * @param  {string} [options.customValue] custom select option value (default: 'custom')
 * @param  {string} [options.customName] custom select option name visible in the select box (default: 'custom')
 *
 * @return {Object}
 */
var comboBox = function(options) {

  var selectOptions = options.selectOptions,
      modelProperty = options.modelProperty,
      customValue = options.customValue || 'custom',
      customName = options.customName || 'custom ' + modelProperty,
      description = options.description;

  // check if a value is not a built in value
  var isCustomValue = function(value) {
    if (typeof value[modelProperty] === 'undefined') {
      return false;
    }

    var isCustom = !find(selectOptions, function(option) {
      return value[modelProperty] === option.value;
    });

    return isCustom;
  };

  var comboOptions = assign({}, options);

  // true if the selected value in the select box is customValue
  comboOptions.showCustomInput = function(element, node) {
    var selectBox = domQuery('[data-entry="'+ options.id +'"] select', node.parentNode);

    if (selectBox) {
      return selectBox.value === customValue;
    }

    return false;
  };

  comboOptions.get = function(element, node) {
    var value = options.get(element, node);

    var modifiedValues = {};

    if (!isCustomValue(value)) {
      modifiedValues[modelProperty] = value[modelProperty] || '';

      return modifiedValues;
    }

    modifiedValues[modelProperty] = customValue;
    modifiedValues['custom-'+modelProperty] = value[modelProperty];

    return modifiedValues;
  };

  comboOptions.set = function(element, values, node) {
    var modifiedValues = {};

    // if the custom select option has been selected
    // take the value from the text input field
    if (values[modelProperty] === customValue) {
      modifiedValues[modelProperty] = values['custom-' + modelProperty] || '';
    }
    else if (options.emptyParameter && values[modelProperty] === '') {
      modifiedValues[modelProperty] = undefined;
    } else {
      modifiedValues[modelProperty] = values[modelProperty];
    }
    return options.set(element, modifiedValues, node);
  };

  comboOptions.selectOptions.push({ name: customName, value: customValue });

  var comboBoxEntry = assign({}, selectEntryFactory(comboOptions, comboOptions));



  comboBoxEntry.html += '<div class="bpp-field-wrapper bpp-combo-input" ' +
    'data-show="showCustomInput"' +
    '>' +
    '<input id="activiti-' + escapeHTML(options.id) + '-input" type="text" name="custom-' +
      escapeHTML(modelProperty) + '" ' +
    ' />' +
  '</div>';

  // add description below combo box entry field
  if (description) {
    comboBoxEntry.html += entryFieldDescription(description);
  }

  return comboBoxEntry;
};

module.exports = comboBox;

},{"../Utils":576,"./EntryFieldDescription":580,"./SelectEntryFactory":583,"lodash/assign":513,"lodash/find":519,"min-dom":556}],579:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

// input entities
var textInputField = require('./TextInputEntryFactory'),
    checkboxField = require('./CheckboxEntryFactory'),
    selectBoxField = require('./SelectEntryFactory'),
    comboBoxField = require('./ComboEntryFactory'),
    textBoxField = require('./TextBoxEntryFactory'),
    validationAwareTextInputField = require('./ValidationAwareTextInput'),
    tableField = require('./TableEntryFactory'),
    labelEntry = require('./LabelFactory'),
    link = require('./LinkEntryFactory');

var cmdHelper = require('../helper/CmdHelper');

// helpers ////////////////////////////////////////

function ensureNotNull(prop) {
  if (!prop) {
    throw new Error(prop + ' must be set.');
  }

  return prop;
}

/**
 * sets the default parameters which are needed to create an entry
 *
 * @param options
 * @returns {{id: *, description: (*|string), get: (*|Function), set: (*|Function),
 *            validate: (*|Function), html: string}}
 */
var setDefaultParameters = function(options) {

  // default method to fetch the current value of the input field
  var defaultGet = function(element) {
    var bo = getBusinessObject(element),
        res = {},
        prop = ensureNotNull(options.modelProperty);
    res[prop] = bo.get(prop);

    return res;
  };

  // default method to set a new value to the input field
  var defaultSet = function(element, values) {
    var res = {},
        prop = ensureNotNull(options.modelProperty);
    if (values[prop] !== '') {
      res[prop] = values[prop];
    } else {
      res[prop] = undefined;
    }

    return cmdHelper.updateProperties(element, res);
  };

  // default validation method
  var defaultValidate = function() {
    return {};
  };

  return {
    id : options.id,
    description : (options.description || ''),
    get : (options.get || defaultGet),
    set : (options.set || defaultSet),
    validate : (options.validate || defaultValidate),
    html: ''
  };
};

function EntryFactory() {

}

/**
 * Generates an text input entry object for a property panel.
 * options are:
 * - id: id of the entry - String
 *
 * - description: description of the property - String
 *
 * - label: label for the input field - String
 *
 * - set: setter method - Function
 *
 * - get: getter method - Function
 *
 * - validate: validation mehtod - Function
 *
 * - modelProperty: name of the model property - String
 *
 * - buttonAction: Object which contains the following properties: - Object
 * ---- name: name of the [data-action] callback - String
 * ---- method: callback function for [data-action] - Function
 *
 * - buttonShow: Object which contains the following properties: - Object
 * ---- name: name of the [data-show] callback - String
 * ---- method: callback function for [data-show] - Function
 *
 * @param options
 * @returns the propertyPanel entry resource object
 */
EntryFactory.textField = function(options) {
  return textInputField(options, setDefaultParameters(options));
};

EntryFactory.validationAwareTextField = function(options) {
  return validationAwareTextInputField(options, setDefaultParameters(options));
};

/**
 * Generates a checkbox input entry object for a property panel.
 * options are:
 * - id: id of the entry - String
 *
 * - description: description of the property - String
 *
 * - label: label for the input field - String
 *
 * - set: setter method - Function
 *
 * - get: getter method - Function
 *
 * - validate: validation method - Function
 *
 * - modelProperty: name of the model property - String
 *
 * @param options
 * @returns the propertyPanel entry resource object
 */
EntryFactory.checkbox = function(options) {
  return checkboxField(options, setDefaultParameters(options));
};

EntryFactory.textBox = function(options) {
  return textBoxField(options, setDefaultParameters(options));
};

EntryFactory.selectBox = function(options) {
  return selectBoxField(options, setDefaultParameters(options));
};

EntryFactory.comboBox = function(options) {
  return comboBoxField(options);
};

EntryFactory.table = function(options) {
  return tableField(options);
};

EntryFactory.label = function(options) {
  return labelEntry(options);
};

EntryFactory.link = function(options) {
  return link(options);
};

module.exports = EntryFactory;

},{"../helper/CmdHelper":590,"./CheckboxEntryFactory":577,"./ComboEntryFactory":578,"./LabelFactory":581,"./LinkEntryFactory":582,"./SelectEntryFactory":583,"./TableEntryFactory":584,"./TextBoxEntryFactory":585,"./TextInputEntryFactory":586,"./ValidationAwareTextInput":587,"bpmn-js/lib/util/ModelUtil":141}],580:[function(require,module,exports){
'use strict';

var escapeHTML = require('../Utils').escapeHTML;

/**
 * Create a linkified and HTML escaped entry field description.
 *
 * As a special feature, this description may contain both markdown
 * and plain <a href> links.
 *
 * @param {String} description
 */
module.exports = function entryFieldDescription(description) {

  // we tokenize the description to extract text, HTML and markdown links
  // text and links are handled seperately

  var escaped = [];

  // match markdown [{TEXT}]({URL}) and HTML links <a href="{URL}">{TEXT}</a>
  var pattern = /(?:\[([^\]]+)\]\((https?:\/\/[^"<>\]]+)\))|(?:<a href="(https?:\/\/[^"<>]+)">([^<]*)<\/a>)/gi;

  var index = 0;
  var match;
  var link, text;

  while ((match = pattern.exec(description))) {

    // escape + insert text before match
    if (match.index > index) {
      escaped.push(escapeHTML(description.substring(index, match.index)));
    }

    link = match[2] || match[3];
    text = match[1] || match[4];

    // insert safe link
    escaped.push('<a href="' + link + '" target="_blank">' + escapeHTML(text) + '</a>');

    index = match.index + match[0].length;
  }

  // escape and insert text after last match
  if (index < description.length) {
    escaped.push(escapeHTML(description.substring(index)));
  }

  return '<div class="bpp-field-description">' + escaped.join('') + '</div>';
};
},{"../Utils":576}],581:[function(require,module,exports){
'use strict';

/**
 * The label factory provides a label entry. For the label text
 * it expects either a string provided by the options.labelText
 * parameter or it could be generated programmatically using a
 * function passed as the options.get parameter.
 *
 * @param  {Object} options
 * @param  {string} options.id
 * @param  {string} [options.labelText]
 * @param  {Function} [options.get]
 * @param  {Function} [options.showLabel]
 * @param  {Boolean} [options.divider] adds a divider at the top of the label if true; default: false
 */
var label = function(options) {
  return {
    id: options.id,
    html: '<label data-value="label" ' +
            'data-show="showLabel" ' +
            'class="entry-label' + (options.divider ? ' divider' : '') + '">' +
          '</label>',
    get: function(element, node) {
      if (typeof options.get === 'function') {
        return options.get(element, node);
      }
      return { label: options.labelText };
    },
    showLabel: function(element, node) {
      if (typeof options.showLabel === 'function') {
        return options.showLabel(element, node);
      }
      return true;
    }
  };
};

module.exports = label;

},{}],582:[function(require,module,exports){
'use strict';

var escapeHTML = require('../Utils').escapeHTML;

var entryFieldDescription = require('./EntryFieldDescription');

var bind = require('lodash/bind');

/**
 * An entry that renders a clickable link.
 *
 * A passed {@link options#handleClick} handler is responsible
 * to process the click.
 *
 * The link may be conditionally shown or hidden. This can be
 * controlled via the {@link options.showLink}.
 *
 * @param {Object} options
 * @param {String} options.id
 * @param {String} [options.label]
 * @param {Function} options.handleClick
 * @param {Function} [options.showLink] returning false to hide link
 * @param {String} [options.description]
 *
 * @example
 *
 * var linkEntry = link({
 *   id: 'foo',
 *   description: 'Some Description',
 *   handleClick: function(element, node, event) { ... },
 *   showLink: function(element, node) { ... }
 * });
 *
 * @return {Entry} the newly created entry
 */
function link(options) {

  var id = options.id,
      label = options.label || id,
      showLink = options.showLink,
      handleClick = options.handleClick,
      description = options.description;

  if (showLink && typeof showLink !== 'function') {
    throw new Error('options.showLink must be a function');
  }

  if (typeof handleClick !== 'function') {
    throw new Error('options.handleClick must be a function');
  }

  var resource = {
    id: id
  };

  resource.html =
    '<a data-action="handleClick" ' +
    (showLink ? 'data-show="showLink" ' : '') +
    'class="bpp-entry-link' + (options.cssClasses ? ' ' + escapeHTML(options.cssClasses) : '') +
    '">' + escapeHTML(label) + '</a>';

  // add description below link entry field
  if (description) {
    resource.html += entryFieldDescription(description);
  }

  resource.handleClick = bind(handleClick, resource);

  if (typeof showLink === 'function') {
    resource.showLink = function() {
      return showLink.apply(resource, arguments);
    };
  }

  return resource;
}

module.exports = link;

},{"../Utils":576,"./EntryFieldDescription":580,"lodash/bind":514}],583:[function(require,module,exports){
'use strict';

var escapeHTML = require('../Utils').escapeHTML;

var domify = require('min-dom').domify;

var forEach = require('lodash/forEach');

var entryFieldDescription = require('./EntryFieldDescription');


var isList = function(list) {
  return !(!list || Object.prototype.toString.call(list) !== '[object Array]');
};

var addEmptyParameter = function(list) {
  return list.concat([ { name: '', value: '' } ]);
};

var createOption = function(option) {
  return '<option value="' + option.value + '">' + option.name + '</option>';
};

/**
 * @param  {Object} options
 * @param  {string} options.id
 * @param  {string} [options.label]
 * @param  {Array<Object>} options.selectOptions
 * @param  {string} options.modelProperty
 * @param  {boolean} options.emptyParameter
 * @param  {function} options.disabled
 * @param  {function} options.hidden
 * @param  {Object} defaultParameters
 *
 * @return {Object}
 */
var selectbox = function(options, defaultParameters) {
  var resource = defaultParameters,
      label = options.label || resource.id,
      selectOptions = options.selectOptions || [ { name: '', value: '' } ],
      modelProperty = options.modelProperty,
      emptyParameter = options.emptyParameter,
      canBeDisabled = !!options.disabled && typeof options.disabled === 'function',
      canBeHidden = !!options.hidden && typeof options.hidden === 'function',
      description = options.description;


  if (emptyParameter) {
    selectOptions = addEmptyParameter(selectOptions);
  }


  resource.html =
    '<label for="activiti-' + escapeHTML(resource.id) + '"' +
    (canBeDisabled ? 'data-disable="isDisabled" ' : '') +
    (canBeHidden ? 'data-show="isHidden" ' : '') +
    '>' + escapeHTML(label) + '</label>' +
    '<select id="activiti-' + escapeHTML(resource.id) + '-select" name="' +
    escapeHTML(modelProperty) + '"' +
    (canBeDisabled ? 'data-disable="isDisabled" ' : '') +
    (canBeHidden ? 'data-show="isHidden" ' : '') +
    ' data-value>';

  if (isList(selectOptions)) {
    forEach(selectOptions, function(option) {
      resource.html += '<option value="' + escapeHTML(option.value) + '">' +
      (option.name ? escapeHTML(option.name) : '') + '</option>';
    });
  }

  resource.html += '</select>';

  // add description below select box entry field
  if (description && typeof options.showCustomInput !== 'function') {
    resource.html += entryFieldDescription(description);
  }

  /**
   * Fill the select box options dynamically.
   *
   * Calls the defined function #selectOptions in the entry to get the
   * values for the options and set the value to the inputNode.
   *
   * @param {djs.model.Base} element
   * @param {HTMLElement} entryNode
   * @param {EntryDescriptor} inputNode
   * @param {Object} inputName
   * @param {Object} newValue
   */
  resource.setControlValue = function(element, entryNode, inputNode, inputName, newValue) {
    if (typeof selectOptions === 'function') {

      var options = selectOptions(element, inputNode);

      if (options) {

        // remove existing options
        while (inputNode.firstChild) {
          inputNode.removeChild(inputNode.firstChild);
        }

        // add options
        forEach(options, function(option) {
          var template = domify(createOption(option));

          inputNode.appendChild(template);
        });


      }
    }

    // set select value
    if (newValue !== undefined) {
      inputNode.value = newValue;
    }

  };

  if (canBeDisabled) {
    resource.isDisabled = function() {
      return options.disabled.apply(resource, arguments);
    };
  }

  if (canBeHidden) {
    resource.isHidden = function() {
      return !options.hidden.apply(resource, arguments);
    };
  }

  resource.cssClasses = ['bpp-dropdown'];

  return resource;
};

module.exports = selectbox;

},{"../Utils":576,"./EntryFieldDescription":580,"lodash/forEach":522,"min-dom":556}],584:[function(require,module,exports){
'use strict';

var escapeHTML = require('../Utils').escapeHTML;

var cmdHelper = require('../helper/CmdHelper');

var domQuery = require('min-dom').query,
    domAttr = require('min-dom').attr,
    domClosest = require('min-dom').closest;

var filter = require('lodash/filter'),
    forEach = require('lodash/forEach'),
    keys = require('lodash/keys');

var domify = require('min-dom').domify;

var entryFieldDescription = require('./EntryFieldDescription');

var updateSelection = require('selection-update');

var TABLE_ROW_DIV_SNIPPET = '<div class="bpp-field-wrapper bpp-table-row">';
var DELETE_ROW_BUTTON_SNIPPET = '<button class="clear" data-action="deleteElement">' +
                                  '<span>X</span>' +
                                '</button>';

function createInputRowTemplate(properties, canRemove) {
  var template = TABLE_ROW_DIV_SNIPPET;
  template += createInputTemplate(properties, canRemove);
  template += canRemove ? DELETE_ROW_BUTTON_SNIPPET : '';
  template += '</div>';

  return template;
}

function createInputTemplate(properties, canRemove) {
  var columns = properties.length;
  var template = '';
  forEach(properties, function(prop) {
    template += '<input class="bpp-table-row-columns-' + columns + ' ' +
                               (canRemove ? 'bpp-table-row-removable' : '') + '" ' +
                       'id="activiti-table-row-cell-input-value" ' +
                       'type="text" ' +
                       'name="' + escapeHTML(prop) + '" />';
  });
  return template;
}

function createLabelRowTemplate(labels) {
  var template = TABLE_ROW_DIV_SNIPPET;
  template += createLabelTemplate(labels);
  template += '</div>';

  return template;
}

function createLabelTemplate(labels) {
  var columns = labels.length;
  var template = '';
  forEach(labels, function(label) {
    template += '<label class="bpp-table-row-columns-' + columns + '">' + escapeHTML(label) + '</label>';
  });
  return template;
}

function pick(elements, properties) {
  return (elements || []).map(function(elem) {
    var newElement = {};
    forEach(properties, function(prop) {
      newElement[prop] = elem[prop] || '';
    });
    return newElement;
  });
}

function diff(element, node, values, oldValues, editable) {
  return filter(values, function(value, idx) {
    return !valueEqual(element, node, value, oldValues[idx], editable, idx);
  });
}

function valueEqual(element, node, value, oldValue, editable, idx) {
  if (value && !oldValue) {
    return false;
  }
  var allKeys = keys(value).concat(keys(oldValue));

  return allKeys.every(function(key) {
    var n = value[key] || undefined;
    var o = oldValue[key] || undefined;
    return !editable(element, node, key, idx) || n === o;
  });
}

function getEntryNode(node) {
  return domClosest(node, '[data-entry]', true);
}

function getContainer(node) {
  return domQuery('div[data-list-entry-container]', node);
}

function getSelection(node) {
  return {
    start: node.selectionStart,
    end: node.selectionEnd
  };
}

function setSelection(node, selection) {
  node.selectionStart = selection.start;
  node.selectionEnd = selection.end;
}

/**
 * @param  {Object} options
 * @param  {string} options.id
 * @param  {string} options.description
 * @param  {Array<string>} options.modelProperties
 * @param  {Array<string>} options.labels
 * @param  {Function} options.getElements - this callback function must return a list of business object items
 * @param  {Function} options.removeElement
 * @param  {Function} options.addElement
 * @param  {Function} options.updateElement
 * @param  {Function} options.editable
 * @param  {Function} options.setControlValue
 * @param  {Function} options.show
 *
 * @return {Object}
 */
module.exports = function(options) {

  var id = options.id,
      modelProperties = options.modelProperties,
      labels = options.labels,
      description = options.description;

  var labelRow = createLabelRowTemplate(labels);

  var getElements = options.getElements;

  var removeElement = options.removeElement,
      canRemove = typeof removeElement === 'function';

  var addElement = options.addElement,
      canAdd = typeof addElement === 'function',
      addLabel = options.addLabel || 'Add Value';

  var updateElement = options.updateElement,
      canUpdate = typeof updateElement === 'function';

  var editable = options.editable || function() { return true; },
      setControlValue = options.setControlValue;

  var show = options.show,
      canBeShown = typeof show === 'function';

  var elements = function(element, node) {
    return pick(getElements(element, node), modelProperties);
  };

  var factory = {
    id: id,
    html: (canAdd ?
      '<div class="bpp-table-add-row" ' + (canBeShown ? 'data-show="show"' : '') + '>' +
            '<label>' + escapeHTML(addLabel) + '</label>' +
            '<button class="add" data-action="addElement"><span>+</span></button>' +
          '</div>' : '') +
          '<div class="bpp-table" data-show="showTable">' +
            '<div class="bpp-field-wrapper bpp-table-row">' +
               labelRow +
            '</div>' +
            '<div data-list-entry-container>' +
            '</div>' +
          '</div>' +

          // add description below table entry field
          (description ? entryFieldDescription(description) : ''),

    get: function(element, node) {
      var boElements = elements(element, node, this.__invalidValues);

      var invalidValues = this.__invalidValues;

      delete this.__invalidValues;

      forEach(invalidValues, function(value, idx) {
        var element = boElements[idx];

        forEach(modelProperties, function(prop) {
          element[prop] = value[prop];
        });
      });

      return boElements;
    },

    set: function(element, values, node) {
      var action = this.__action || {};
      delete this.__action;

      if (action.id === 'delete-element') {
        return removeElement(element, node, action.idx);
      }
      else if (action.id === 'add-element') {
        return addElement(element, node);
      }
      else if (canUpdate) {
        var commands = [],
            valuesToValidate = values;

        if (typeof options.validate !== 'function') {
          valuesToValidate = diff(element, node, values, elements(element, node), editable);
        }

        var self = this;

        forEach(valuesToValidate, function(value) {
          var validationError,
              idx = values.indexOf(value);

          if (typeof options.validate === 'function') {
            validationError = options.validate(element, value, node, idx);
          }

          if (!validationError) {
            var cmd = updateElement(element, value, node, idx);

            if (cmd) {
              commands.push(cmd);
            }
          } else {
            // cache invalid value in an object by index as key
            self.__invalidValues = self.__invalidValues || {};
            self.__invalidValues[idx] = value;

            // execute a command, which does not do anything
            commands.push(cmdHelper.updateProperties(element, {}));
          }
        });

        return commands;
      }
    },
    createListEntryTemplate: function(value, index, selectBox) {
      return createInputRowTemplate(modelProperties, canRemove);
    },

    addElement: function(element, node, event, scopeNode) {
      var template = domify(createInputRowTemplate(modelProperties, canRemove));

      var container = getContainer(node);
      container.appendChild(template);

      this.__action = {
        id: 'add-element'
      };

      return true;
    },

    deleteElement: function(element, node, event, scopeNode) {
      var container = getContainer(node);
      var rowToDelete = event.delegateTarget.parentNode;
      var idx = parseInt(domAttr(rowToDelete, 'data-index'), 10);

      container.removeChild(rowToDelete);

      this.__action = {
        id: 'delete-element',
        idx: idx
      };

      return true;
    },

    editable: function(element, rowNode, input, prop, value, idx) {
      var entryNode = domClosest(rowNode, '[data-entry]');
      return editable(element, entryNode, prop, idx);
    },

    show: function(element, entryNode, node, scopeNode) {
      entryNode = getEntryNode(entryNode);
      return show(element, entryNode, node, scopeNode);
    },

    showTable: function(element, entryNode, node, scopeNode) {
      entryNode = getEntryNode(entryNode);
      var elems = elements(element, entryNode);
      return elems && elems.length && (!canBeShown || show(element, entryNode, node, scopeNode));
    },

    validateListItem: function(element, value, node, idx) {
      if (typeof options.validate === 'function') {
        return options.validate(element, value, node, idx);
      }
    }

  };

  // Update/set the selection on the correct position.
  // It's the same code like for an input value in the PropertiesPanel.js.
  if (setControlValue) {
    factory.setControlValue = function(element, rowNode, input, prop, value, idx) {
      var entryNode = getEntryNode(rowNode);

      var isReadOnly = domAttr(input, 'readonly');
      var oldValue = input.value;

      var selection;

      // prevents input fields from having the value 'undefined'
      if (value === undefined) {
        value = '';
      }

      // when the attribute 'readonly' exists, ignore the comparison
      // with 'oldValue' and 'value'
      if (!!isReadOnly && oldValue === value) {
        return;
      }

      // update selection on undo/redo
      if (document.activeElement === input) {
        selection = updateSelection(getSelection(input), oldValue, value);
      }

      setControlValue(element, entryNode, input, prop, value, idx);

      if (selection) {
        setSelection(input, selection);
      }

    };
  }

  return factory;

};

},{"../Utils":576,"../helper/CmdHelper":590,"./EntryFieldDescription":580,"lodash/filter":518,"lodash/forEach":522,"lodash/keys":539,"min-dom":556,"selection-update":566}],585:[function(require,module,exports){
'use strict';

var escapeHTML = require('../Utils').escapeHTML;

var entryFieldDescription = require('./EntryFieldDescription');


var textBox = function(options, defaultParameters) {

  var resource = defaultParameters,
      label = options.label || resource.id,
      canBeShown = !!options.show && typeof options.show === 'function',
      description = options.description;


  resource.html =
    '<label for="activiti-' + escapeHTML(resource.id) + '" ' +
    (canBeShown ? 'data-show="isShown"' : '') +
    '>' + label + '</label>' +
    '<div class="bpp-field-wrapper" ' +
    (canBeShown ? 'data-show="isShown"' : '') +
    '>' +
      '<div contenteditable="true" id="activiti-' + escapeHTML(resource.id) + '" ' +
            'name="' + escapeHTML(options.modelProperty) + '" style="height:91px"/>' +
    '</div>';

  // add description below text box entry field
  if (description) {
    resource.html += entryFieldDescription(description);
  }

  if (canBeShown) {
    resource.isShown = function() {
      return options.show.apply(resource, arguments);
    };
  }

  resource.cssClasses = ['bpp-textbox'];

  return resource;
};

module.exports = textBox;

},{"../Utils":576,"./EntryFieldDescription":580}],586:[function(require,module,exports){
'use strict';

var escapeHTML = require('../Utils').escapeHTML;

var domQuery = require('min-dom').query;

var entryFieldDescription = require('./EntryFieldDescription');


var textField = function(options, defaultParameters) {

  // Default action for the button next to the input-field
  var defaultButtonAction = function(element, inputNode) {
    var input = domQuery('input[name="' + options.modelProperty + '"]', inputNode);
    input.value = '';

    return true;
  };

  // default method to determine if the button should be visible
  var defaultButtonShow = function(element, inputNode) {
    var input = domQuery('input[name="' + options.modelProperty + '"]', inputNode);

    return input.value !== '';
  };


  var resource = defaultParameters,
      label = options.label || resource.id,
      dataValueLabel = options.dataValueLabel,
      buttonLabel = (options.buttonLabel || 'X'),
      actionName = (typeof options.buttonAction != 'undefined') ? options.buttonAction.name : 'clear',
      actionMethod = (typeof options.buttonAction != 'undefined') ? options.buttonAction.method : defaultButtonAction,
      showName = (typeof options.buttonShow != 'undefined') ? options.buttonShow.name : 'canClear',
      showMethod = (typeof options.buttonShow != 'undefined') ? options.buttonShow.method : defaultButtonShow,
      canBeDisabled = !!options.disabled && typeof options.disabled === 'function',
      canBeHidden = !!options.hidden && typeof options.hidden === 'function',
      description = options.description;


    resource.html =
      '<label for="activiti-' + escapeHTML(resource.id) + '" ' +
      (canBeDisabled ? 'data-disable="isDisabled" ' : '') +
      (canBeHidden ? 'data-show="isHidden" ' : '') +
      (dataValueLabel ? 'data-value="' + escapeHTML(dataValueLabel) + '"' : '') + '>'+ escapeHTML(label) +'</label>' +
      '<div class="bpp-field-wrapper" ' +
      (canBeDisabled ? 'data-disable="isDisabled"' : '') +
      (canBeHidden ? 'data-show="isHidden"' : '') +
      '>' +
      '<input type="button" name="' + escapeHTML(options.modelProperty) + '" style="width: 100%;text-align: left;"  />' +
      '<input id="activiti-' + escapeHTML(resource.id) + '" type="hidden" name="' + escapeHTML(options.modelProperty) + '" ' +
      (true ? 'data-disable="isDisabled"' : '') +
      (canBeHidden ? 'data-show="isHidden"' : '') +
      ' />' +
      // '<button class="' + escapeHTML(actionName) + '" data-action="' + escapeHTML(actionName) + '" data-show="' + escapeHTML(showName) + '" ' +
      // (canBeDisabled ? 'data-disable="isDisabled"' : '') +
      // (canBeHidden ? ' data-show="isHidden"' : '') + '>' +
      // '<span>' + escapeHTML(buttonLabel) + '</span>' +
      '</button>' +
      '</div>';





  // add description below text input entry field
  if (description) {
    resource.html += entryFieldDescription(description);
  }

  resource[actionName] = actionMethod;
  resource[showName] = showMethod;

  if (canBeDisabled) {
    resource.isDisabled = function() {
      return options.disabled.apply(resource, arguments);
    };
  }

  if (canBeHidden) {
    resource.isHidden = function() {
      return !options.hidden.apply(resource, arguments);
    };
  }

  resource.cssClasses = ['bpp-textfield'];
  return resource;
};

module.exports = textField;

},{"../Utils":576,"./EntryFieldDescription":580,"min-dom":556}],587:[function(require,module,exports){
'use strict';

var textField = require('./TextInputEntryFactory');

/**
 * This function is a wrapper around TextInputEntryFactory.
 * It adds functionality to cache an invalid value entered in the
 * text input, instead of setting it on the business object.
 */
var validationAwareTextField = function(options, defaultParameters) {

  var modelProperty = options.modelProperty;

  defaultParameters.get = function(element, node) {
    var value = this.__lastInvalidValue;

    delete this.__lastInvalidValue;

    var properties = {};

    properties[modelProperty] = value !== undefined ? value : options.getProperty(element, node);

    return properties;
  };

  defaultParameters.set = function(element, values, node) {
    var validationErrors = validate.apply(this, [ element, values, node ]),
        propertyValue = values[modelProperty];

    // make sure we do not update the id
    if (validationErrors && validationErrors[modelProperty]) {
      this.__lastInvalidValue = propertyValue;

      return options.setProperty(element, {}, node);
    } else {
      var properties = {};

      properties[modelProperty] = propertyValue;

      return options.setProperty(element, properties, node);
    }
  };

  var validate = defaultParameters.validate = function(element, values, node) {
    var value = values[modelProperty] || this.__lastInvalidValue;

    var property = {};
    property[modelProperty] = value;

    return options.validate(element, property, node);
  };

  return textField(options, defaultParameters);
};

module.exports = validationAwareTextField;

},{"./TextInputEntryFactory":586}],588:[function(require,module,exports){
'use strict';

var map = require('lodash/map');

var extensionElementsHelper = require('./ExtensionElementsHelper');

/**
 * Returns true if the attribute 'activiti:asyncBefore' is set
 * to true.
 *
 * @param  {ModdleElement} bo
 *
 * @return {boolean} a boolean value
 */
function isAsyncBefore(bo) {
  return !!(bo.get('activiti:asyncBefore') || bo.get('activiti:async'));
}

module.exports.isAsyncBefore = isAsyncBefore;

/**
 * Returns true if the attribute 'activiti:asyncAfter' is set
 * to true.
 *
 * @param  {ModdleElement} bo
 *
 * @return {boolean} a boolean value
 */
function isAsyncAfter(bo) {
  return !!bo.get('activiti:asyncAfter');
}

module.exports.isAsyncAfter = isAsyncAfter;

/**
 * Returns true if the attribute 'activiti:exclusive' is set
 * to true.
 *
 * @param  {ModdleElement} bo
 *
 * @return {boolean} a boolean value
 */
function isExclusive(bo) {
  return !!bo.get('activiti:exclusive');
}

module.exports.isExclusive = isExclusive;

/**
 * Get first 'activiti:FailedJobRetryTimeCycle' from the business object.
 *
 * @param  {ModdleElement} bo
 *
 * @return {Array<ModdleElement>} a list of 'activiti:FailedJobRetryTimeCycle'
 */
function getFailedJobRetryTimeCycle(bo) {
  return (extensionElementsHelper.getExtensionElements(bo, 'activiti:FailedJobRetryTimeCycle') || [])[0];
}

module.exports.getFailedJobRetryTimeCycle = getFailedJobRetryTimeCycle;

/**
 * Removes all existing 'activiti:FailedJobRetryTimeCycle' from the business object
 *
 * @param  {ModdleElement} bo
 *
 * @return {Array<ModdleElement>} a list of 'activiti:FailedJobRetryTimeCycle'
 */
function removeFailedJobRetryTimeCycle(bo, element) {
  var retryTimeCycles = extensionElementsHelper.getExtensionElements(bo, 'activiti:FailedJobRetryTimeCycle');
  return map(retryTimeCycles, function(cycle) {
    return extensionElementsHelper.removeEntry(bo, element, cycle);
  });
}

module.exports.removeFailedJobRetryTimeCycle = removeFailedJobRetryTimeCycle;
},{"./ExtensionElementsHelper":593,"lodash/map":540}],589:[function(require,module,exports){
'use strict';

var collectionAdd = require('diagram-js/lib/util/Collections').add,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var CategoryHelper = {};

module.exports = CategoryHelper;

/**
 * Creates a new bpmn:CategoryValue inside a new bpmn:Category
 *
 * @param {ModdleElement} definitions
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement} categoryValue.
 */
CategoryHelper.createCategoryValue = function(definitions, bpmnFactory) {
  var categoryValue = bpmnFactory.create('bpmn:CategoryValue'),
      category = bpmnFactory.create('bpmn:Category', {
        categoryValue: [ categoryValue ]
      });

  // add to correct place
  collectionAdd(definitions.get('rootElements'), category);
  getBusinessObject(category).$parent = definitions;
  getBusinessObject(categoryValue).$parent = category;

  return categoryValue;

};
},{"bpmn-js/lib/util/ModelUtil":141,"diagram-js/lib/util/Collections":339}],590:[function(require,module,exports){
'use strict';

var CmdHelper = {};
module.exports = CmdHelper;

CmdHelper.updateProperties = function(element, properties) {
  return {
    cmd: 'element.updateProperties',
    context: { element: element, properties: properties }
  };
};

CmdHelper.updateBusinessObject = function(element, businessObject, newProperties) {
  return {
    cmd: 'properties-panel.update-businessobject',
    context: {
      element: element,
      businessObject: businessObject,
      properties: newProperties
    }
  };
};

CmdHelper.addElementsTolist = function(element, businessObject, listPropertyName, objectsToAdd) {
  return {
    cmd: 'properties-panel.update-businessobject-list',
    context: {
      element: element,
      currentObject: businessObject,
      propertyName: listPropertyName,
      objectsToAdd: objectsToAdd
    }
  };
};

CmdHelper.removeElementsFromList = function(element, businessObject, listPropertyName, referencePropertyName, objectsToRemove) {

  return {
    cmd: 'properties-panel.update-businessobject-list',
    context: {
      element: element,
      currentObject: businessObject,
      propertyName: listPropertyName,
      referencePropertyName: referencePropertyName,
      objectsToRemove: objectsToRemove
    }
  };
};


CmdHelper.addAndRemoveElementsFromList = function(element, businessObject, listPropertyName, referencePropertyName, objectsToAdd, objectsToRemove) {

  return {
    cmd: 'properties-panel.update-businessobject-list',
    context: {
      element: element,
      currentObject: businessObject,
      propertyName: listPropertyName,
      referencePropertyName: referencePropertyName,
      objectsToAdd: objectsToAdd,
      objectsToRemove: objectsToRemove
    }
  };
};


CmdHelper.setList = function(element, businessObject, listPropertyName, updatedObjectList) {
  return {
    cmd: 'properties-panel.update-businessobject-list',
    context: {
      element: element,
      currentObject: businessObject,
      propertyName: listPropertyName,
      updatedObjectList: updatedObjectList
    }
  };
};

},{}],591:[function(require,module,exports){
'use strict';

var ElementHelper = {};
module.exports = ElementHelper;

/**
 * Creates a new element and set the parent to it
 *
 * @method ElementHelper#createElement
 *
 * @param {String} elementType of the new element
 * @param {Object} properties of the new element in key-value pairs
 * @param {moddle.object} parent of the new element
 * @param {BpmnFactory} factory which creates the new element
 *
 * @returns {djs.model.Base} element which is created
 */
ElementHelper.createElement = function(elementType, properties, parent, factory) {
  var element = factory.create(elementType, properties);
  element.$parent = parent;

  return element;
};

},{}],592:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    is = require('bpmn-js/lib/util/ModelUtil').is,
    forEach = require('lodash/forEach');

var EventDefinitionHelper = {};

module.exports = EventDefinitionHelper;

EventDefinitionHelper.getEventDefinition = function(element, eventType) {

  var bo = getBusinessObject(element),
      eventDefinition = null;

  if (bo.eventDefinitions) {
    forEach(bo.eventDefinitions, function(event) {
      if (is(event, eventType)) {
        eventDefinition = event;
      }
    });
  }

  return eventDefinition;
};

EventDefinitionHelper.getTimerEventDefinition = function(element) {
  return this.getEventDefinition(element, 'bpmn:TimerEventDefinition');
};

EventDefinitionHelper.getMessageEventDefinition = function(element) {
  return this.getEventDefinition(element, 'bpmn:MessageEventDefinition');
};

EventDefinitionHelper.getSignalEventDefinition = function(element) {
  return this.getEventDefinition(element, 'bpmn:SignalEventDefinition');
};

EventDefinitionHelper.getErrorEventDefinition = function(element) {
  return this.getEventDefinition(element, 'bpmn:ErrorEventDefinition');
};

EventDefinitionHelper.getEscalationEventDefinition = function(element) {
  return this.getEventDefinition(element, 'bpmn:EscalationEventDefinition');
};

EventDefinitionHelper.getCompensateEventDefinition = function(element) {
  return this.getEventDefinition(element, 'bpmn:CompensateEventDefinition');
};

EventDefinitionHelper.getLinkEventDefinition = function(element) {
  return this.getEventDefinition(element, 'bpmn:LinkEventDefinition');
};

EventDefinitionHelper.getConditionalEventDefinition = function(element) {
  return this.getEventDefinition(element, 'bpmn:ConditionalEventDefinition');
};

},{"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],593:[function(require,module,exports){
'use strict';

var cmdHelper = require('./CmdHelper'),
    elementHelper = require('./ElementHelper');

var is = require('bpmn-js/lib/util/ModelUtil').is;

var ExtensionElementsHelper = {};

var getExtensionElements = function(bo) {
  return bo.get('extensionElements');
};

ExtensionElementsHelper.getExtensionElements = function(bo, type) {
  var extensionElements = getExtensionElements(bo);
  if (typeof extensionElements !== 'undefined') {
    var extensionValues = extensionElements.get('values');
    if (typeof extensionValues !== 'undefined') {
      var elements = extensionValues.filter(function(value) {
        return is(value, type);
      });
      if (elements.length) {
        return elements;
      }
    }
  }
};

ExtensionElementsHelper.addEntry = function(bo, element, entry, bpmnFactory) {
  var extensionElements = bo.get('extensionElements');

  // if there is no extensionElements list, create one
  if (!extensionElements) {
    // TODO: Ask Daniel which operation costs more
    extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [entry] }, bo, bpmnFactory);
    return { extensionElements : extensionElements };
  } else {
    // add new failedJobRetryExtensionElement to existing extensionElements list
    return cmdHelper.addElementsTolist(element, extensionElements, 'values', [entry]);
  }
};

ExtensionElementsHelper.removeEntry = function(bo, element, entry) {
  var extensionElements = bo.get('extensionElements');

  if (!extensionElements) {

    // return an empty command when there is no extensionElements list
    return {};
  }

  return cmdHelper.removeElementsFromList(element, extensionElements, 'values', 'extensionElements', [entry]);
};

module.exports = ExtensionElementsHelper;

},{"./CmdHelper":590,"./ElementHelper":591,"bpmn-js/lib/util/ModelUtil":141}],594:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    getExtensionElements = require('./ExtensionElementsHelper').getExtensionElements;

var FormHelper = {};

module.exports = FormHelper;

/**
 * Return form data from business object or undefined if none exist
 *
 * @param  {djs.model.Base} element
 *
 * @return {ModdleElement|undefined} formData
 *
 * 此方法废弃
 *
 */
FormHelper.getFormData = function(element) {
 /* var bo = getBusinessObject(element);

  var formFields = getExtensionElements(bo, 'activiti:FormProperty');

  var formData = {}

  if (typeof formData !== 'undefined') {
    return formData[0];
  }*/
 return {};
};


/**
 * Return all form fields existing in the business object, and
 * an empty array if none exist.
 *
 * @param  {djs.model.Base} element
 *
 * @return {Array} a list of form field objects
 */
FormHelper.getFormFields = function(element) {

  /**直接获取 ExtensionElements的 activiti:FormProperty元素*/
  var bo = getBusinessObject(element);

  var formFields = getExtensionElements(bo, 'activiti:FormProperty');

  return formFields || [];
};


/**
 * Get a form field from the business object at given index
 *
 * @param {djs.model.Base} element
 * @param {number} idx
 *
 * @return {ModdleElement} the form field
 */
FormHelper.getFormField = function(element, idx) {

  var formFields = this.getFormFields(element);

  return formFields[idx];
};


/**
 * Get all constraints for a specific form field from the business object
 *
 * @param  {ModdleElement} formField
 *
 * @return {Array<ModdleElement>} a list of constraint objects
 */
FormHelper.getConstraints = function(formField) {
  if (formField && formField.validation && formField.validation.constraints) {
    return formField.validation.constraints;
  }
  return [];
};


/**
 * Get all activiti:value objects for a specific form field from the business object
 *
 * @param  {ModdleElement} formField
 *
 * @return {Array<ModdleElement>} a list of activiti:value objects
 */
FormHelper.getEnumValues = function(formField) {
  if (formField && formField.values) {
    return formField.values;
  }
  return [];
};


},{"./ExtensionElementsHelper":593,"bpmn-js/lib/util/ModelUtil":141}],595:[function(require,module,exports){
'use strict';

var ModelUtil = require('bpmn-js/lib/util/ModelUtil'),
    is = ModelUtil.is,
    getBusinessObject = ModelUtil.getBusinessObject;

var eventDefinitionHelper = require('./EventDefinitionHelper');
var extensionsElementHelper = require('./ExtensionElementsHelper');

var ImplementationTypeHelper = {};

module.exports = ImplementationTypeHelper;

/**
 * Returns 'true' if the given element is 'activiti:ServiceTaskLike'
 *
 * @param {djs.model.Base} element
 *
 * @return {boolean} a boolean value
 */
ImplementationTypeHelper.isServiceTaskLike = function(element) {
  return is(element, 'activiti:ServiceTaskLike');
};

/**
 * Returns 'true' if the given element is 'activiti:DmnCapable'
 *
 * @param {djs.model.Base} element
 *
 * @return {boolean} a boolean value
 */
ImplementationTypeHelper.isDmnCapable = function(element) {
  return is(element, 'activiti:DmnCapable');
};

/**
 * Returns 'true' if the given element is 'activiti:ExternalCapable'
 *
 * @param {djs.model.Base} element
 *
 * @return {boolean} a boolean value
 */
ImplementationTypeHelper.isExternalCapable = function(element) {
  return is(element, 'activiti:ExternalCapable');
};

/**
 * Returns 'true' if the given element is 'activiti:TaskListener'
 *
 * @param {djs.model.Base} element
 *
 * @return {boolean} a boolean value
 */
ImplementationTypeHelper.isTaskListener = function(element) {
  return is(element, 'activiti:TaskListener');
};

/**
 * Returns 'true' if the given element is 'activiti:ExecutionListener'
 *
 * @param {djs.model.Base} element
 *
 * @return {boolean} a boolean value
 */
ImplementationTypeHelper.isExecutionListener = function(element) {
  return is(element, 'activiti:ExecutionListener');
};

/**
 * Returns 'true' if the given element is 'activiti:ExecutionListener' or
 * 'activiti:TaskListener'
 *
 * @param {djs.model.Base} element
 *
 * @return {boolean} a boolean value
 */
ImplementationTypeHelper.isListener = function(element) {
  return this.isTaskListener(element) || this.isExecutionListener(element);
};

/**
 * Returns 'true' if the given element is 'bpmn:SequenceFlow'
 *
 * @param {djs.model.Base} element
 *
 * @return {boolean} a boolean value
 */
ImplementationTypeHelper.isSequenceFlow = function(element) {
  return is(element, 'bpmn:SequenceFlow');
};

/**
 * Get a 'activiti:ServiceTaskLike' business object.
 *
 * If the given element is not a 'activiti:ServiceTaskLike', then 'false'
 * is returned.
 *
 * @param {djs.model.Base} element
 *
 * @return {ModdleElement} the 'activiti:ServiceTaskLike' business object
 */
ImplementationTypeHelper.getServiceTaskLikeBusinessObject = function(element) {

  if (is(element, 'bpmn:IntermediateThrowEvent') || is(element, 'bpmn:EndEvent')) {

    // change business object to 'messageEventDefinition' when
    // the element is a message intermediate throw event or message end event
    // because the activiti extensions (e.g. activiti:class) are in the message
    // event definition tag and not in the intermediate throw event or end event tag
    var messageEventDefinition = eventDefinitionHelper.getMessageEventDefinition(element);
    if (messageEventDefinition) {
      element = messageEventDefinition;
    }
  }

  return this.isServiceTaskLike(element) && getBusinessObject(element);

};

/**
 * Returns the implementation type of the given element.
 *
 * Possible implementation types are:
 * - dmn
 * - connector
 * - external
 * - class
 * - expression
 * - delegateExpression
 * - script
 * - or undefined, when no matching implementation type is found
 *
 * @param  {djs.model.Base} element
 *
 * @return {String} the implementation type
 */
ImplementationTypeHelper.getImplementationType = function(element) {

  var bo = this.getServiceTaskLikeBusinessObject(element);

  if (!bo) {
    if (this.isListener(element)) {
      bo = element;
    } else {
      return;
    }
  }

  if (this.isDmnCapable(bo)) {
    var decisionRef = bo.get('activiti:decisionRef');
    if (typeof decisionRef !== 'undefined') {
      return 'dmn';
    }
  }

  if (this.isServiceTaskLike(bo)) {
    var connectors = extensionsElementHelper.getExtensionElements(bo, 'activiti:Connector');
    if (typeof connectors !== 'undefined') {
      return 'connector';
    }
  }

  if (this.isExternalCapable(bo)) {
    var type = bo.get('activiti:type');
    if (type === 'external') {
      return 'external';
    }
  }

  var cls = bo.get('activiti:class');
  if (typeof cls !== 'undefined') {
    return 'class';
  }

  var expression = bo.get('activiti:expression');
  if (typeof expression !== 'undefined') {
    return 'expression';
  }

  var delegateExpression = bo.get('activiti:delegateExpression');
  if (typeof delegateExpression !== 'undefined') {
    return 'delegateExpression';
  }

  if (this.isListener(bo)) {
    var script = bo.get('script');
    if (typeof script !== 'undefined') {
      return 'script';
    }
  }

};

},{"./EventDefinitionHelper":592,"./ExtensionElementsHelper":593,"bpmn-js/lib/util/ModelUtil":141}],596:[function(require,module,exports){
'use strict';

var ModelUtil = require('bpmn-js/lib/util/ModelUtil'),
    is = ModelUtil.is,
    getBusinessObject = ModelUtil.getBusinessObject;

var extensionElementsHelper = require('./ExtensionElementsHelper'),
    implementationTypeHelper = require('./ImplementationTypeHelper');

var InputOutputHelper = {};

module.exports = InputOutputHelper;

function getElements(bo, type, prop) {
  var elems = extensionElementsHelper.getExtensionElements(bo, type) || [];
  return !prop ? elems : (elems[0] || {})[prop] || [];
}

function getParameters(element, prop, insideConnector) {
  var inputOutput = InputOutputHelper.getInputOutput(element, insideConnector);
  return (inputOutput && inputOutput.get(prop)) || [];
}

/**
 * Get a inputOutput from the business object
 *
 * @param {djs.model.Base} element
 * @param  {boolean} insideConnector
 *
 * @return {ModdleElement} the inputOutput object
 */
InputOutputHelper.getInputOutput = function(element, insideConnector) {
  if (!insideConnector) {
    var bo = getBusinessObject(element);
    return (getElements(bo, 'activiti:InputOutput') || [])[0];
  }
  var connector = this.getConnector(element);
  return connector && connector.get('inputOutput');
};

/**
 * Get a connector from the business object
 *
 * @param {djs.model.Base} element
 *
 * @return {ModdleElement} the connector object
 */
InputOutputHelper.getConnector = function(element) {
  var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element);
  return bo && (getElements(bo, 'activiti:Connector') || [])[0];
};

/**
 * Return all input parameters existing in the business object, and
 * an empty array if none exist.
 *
 * @param  {djs.model.Base} element
 * @param  {boolean} insideConnector
 *
 * @return {Array} a list of input parameter objects
 */
InputOutputHelper.getInputParameters = function(element, insideConnector) {
  return getParameters.apply(this, [ element, 'inputParameters', insideConnector ]);
};

/**
 * Return all output parameters existing in the business object, and
 * an empty array if none exist.
 *
 * @param  {djs.model.Base} element
 * @param  {boolean} insideConnector
 *
 * @return {Array} a list of output parameter objects
 */
InputOutputHelper.getOutputParameters = function(element, insideConnector) {
  return getParameters.apply(this, [ element, 'outputParameters', insideConnector ]);
};

/**
 * Get a input parameter from the business object at given index
 *
 * @param {djs.model.Base} element
 * @param  {boolean} insideConnector
 * @param {number} idx
 *
 * @return {ModdleElement} input parameter
 */
InputOutputHelper.getInputParameter = function(element, insideConnector, idx) {
  return this.getInputParameters(element, insideConnector)[idx];
};

/**
 * Get a output parameter from the business object at given index
 *
 * @param {djs.model.Base} element
 * @param  {boolean} insideConnector
 * @param {number} idx
 *
 * @return {ModdleElement} output parameter
 */
InputOutputHelper.getOutputParameter = function(element, insideConnector, idx) {
  return this.getOutputParameters(element, insideConnector)[idx];
};

/**
 * Returns 'true' if the given element supports inputOutput
 *
 * @param {djs.model.Base} element
 * @param  {boolean} insideConnector
 *
 * @return {boolean} a boolean value
 */
InputOutputHelper.isInputOutputSupported = function(element, insideConnector) {

  if (insideConnector) {
    return true;
  }

  var bo = getBusinessObject(element);

  return (
    is(bo, 'bpmn:FlowNode') && !(
      is(bo, 'bpmn:StartEvent') ||
      is(bo, 'bpmn:Gateway') ||
      is(bo, 'bpmn:BoundaryEvent') ||
      (
        is(bo, 'bpmn:SubProcess') && bo.get('triggeredByEvent')
      )
    )
  );
};

/**
 * Returns 'true' if the given element supports output parameters
 *
 * @param {djs.model.Base} element
 * @param  {boolean} insideConnector
 *
 * @return {boolean} a boolean value
 */
InputOutputHelper.areOutputParametersSupported = function(element, insideConnector) {
  var bo = getBusinessObject(element);
  return insideConnector || (!is(bo, 'bpmn:EndEvent') && !bo.loopCharacteristics);
};

},{"./ExtensionElementsHelper":593,"./ImplementationTypeHelper":595,"bpmn-js/lib/util/ModelUtil":141}],597:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    cmdHelper = require('./CmdHelper');


var ParticipantHelper = {};

module.exports = ParticipantHelper;

ParticipantHelper.modifyProcessBusinessObject = function(element, property, values) {
  if (!is(element, 'bpmn:Participant')) {
    return {};
  }

  var bo = getBusinessObject(element).get('processRef'),
      properties = {};

  properties[property] = values[property];

  return cmdHelper.updateBusinessObject(element, bo, properties);
};

ParticipantHelper.getProcessBusinessObject = function(element, propertyName) {
  if (!is(element, 'bpmn:Participant')) {
    return {};
  }

  var bo = getBusinessObject(element).get('processRef'),
      properties = {};

  properties[propertyName] = bo.get(propertyName);

  return properties;
};
},{"./CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141}],598:[function(require,module,exports){
'use strict';

var inherits = require('inherits');

var PropertiesActivator = require('../../PropertiesActivator');

var asyncCapableHelper = require('../../helper/AsyncCapableHelper'),
    ImplementationTypeHelper = require('../../helper/ImplementationTypeHelper');

var is = require('bpmn-js/lib/util/ModelUtil').is;

// bpmn properties
var processProps = require('../../provider/bpmn/parts/ProcessProps'),
    eventProps = require('../../provider/bpmn/parts/EventProps'),
    linkProps = require('../../provider/bpmn/parts/LinkProps'),
    documentationProps = require('../../provider/bpmn/parts/DocumentationProps'),
    idProps = require('../../provider/bpmn/parts/IdProps'),
    nameProps = require('../../provider/bpmn/parts/NameProps'),
    executableProps = require('../../provider/bpmn/parts/ExecutableProps');

// activiti properties
var serviceTaskDelegateProps = require('./parts/ServiceTaskDelegateProps'),
    userTaskProps = require('./parts/UserTaskProps'),
    asynchronousContinuationProps = require('./parts/AsynchronousContinuationProps'),
    callActivityProps = require('./parts/CallActivityProps'),
    multiInstanceProps = require('./parts/MultiInstanceLoopProps'),
    conditionalProps = require('./parts/ConditionalProps'),
    scriptProps = require('./parts/ScriptTaskProps'),
    errorProps = require('./parts/ErrorEventProps'),
    formProps = require('./parts/FormProps'),
    startEventInitiator = require('./parts/StartEventInitiator'),
    variableMapping = require('./parts/VariableMappingProps'),
    versionTag = require('./parts/VersionTagProps');

var listenerProps = require('./parts/ListenerProps'),
    listenerDetails = require('./parts/ListenerDetailProps'),
    listenerFields = require('./parts/ListenerFieldInjectionProps');

var elementTemplateChooserProps = require('./element-templates/parts/ChooserProps'),
    elementTemplateCustomProps = require('./element-templates/parts/CustomProps');

// Input/Output
var inputOutput = require('./parts/InputOutputProps'),
    inputOutputParameter = require('./parts/InputOutputParameterProps');

// Connector
var connectorDetails = require('./parts/ConnectorDetailProps'),
    connectorInputOutput = require('./parts/ConnectorInputOutputProps'),
    connectorInputOutputParameter = require('./parts/ConnectorInputOutputParameterProps');

// properties
var properties = require('./parts/PropertiesProps');

// job configuration
var jobConfiguration = require('./parts/JobConfigurationProps');

// history time to live
var historyTimeToLive = require('./parts/HistoryTimeToLiveProps');

// candidate starter groups/users
var candidateStarter = require('./parts/CandidateStarterProps');

// tasklist
var tasklist = require('./parts/TasklistProps');

// external task configuration
var externalTaskConfiguration = require('./parts/ExternalTaskConfigurationProps');

// field injection
var fieldInjections = require('./parts/FieldInjectionProps');

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    eventDefinitionHelper = require('../../helper/EventDefinitionHelper'),
    implementationTypeHelper = require('../../helper/ImplementationTypeHelper');

// helpers ////////////////////////////////////////

var isExternalTaskPriorityEnabled = function(element) {
  var businessObject = getBusinessObject(element);

  // show only if element is a process, a participant ...
  if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
    return true;
  }

  var externalBo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element),
      isExternalTask = ImplementationTypeHelper.getImplementationType(externalBo) === 'external';

  // ... or an external task with selected external implementation type
  return !!ImplementationTypeHelper.isExternalCapable(externalBo) && isExternalTask;
};

var isJobConfigEnabled = function(element) {
  var businessObject = getBusinessObject(element);

  if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) {
    return true;
  }

  // async behavior
  var bo = getBusinessObject(element);
  if (asyncCapableHelper.isAsyncBefore(bo) || asyncCapableHelper.isAsyncAfter(bo)) {
    return true;
  }

  // timer definition
  if (is(element, 'bpmn:Event')) {
    return !!eventDefinitionHelper.getTimerEventDefinition(element);
  }

  return false;
};

var getInputOutputParameterLabel = function(param, translate) {

  if (is(param, 'activiti:InputParameter')) {
    return translate('Input Parameter');
  }

  if (is(param, 'activiti:OutputParameter')) {
    return translate('Output Parameter');
  }

  return '';
};

var getListenerLabel = function(param, translate) {

  if (is(param, 'activiti:ExecutionListener')) {
    return translate('Execution Listener');
  }

  if (is(param, 'activiti:TaskListener')) {
    return translate('Task Listener');
  }

  return '';
};

var PROCESS_KEY_HINT = 'This maps to the process definition key.';
var TASK_KEY_HINT = 'This maps to the task definition key.';

function createGeneralTabGroups(
    element, canvas, bpmnFactory,
    elementRegistry, elementTemplates, translate) {

  // refer to target element for external labels
  element = element.labelTarget || element;

  var generalGroup = {
    id: 'general',
    label: translate('General'),
    entries: []
  };

  var idOptions;
  var processOptions;

  if (is(element, 'bpmn:Process')) {
    idOptions = { description: PROCESS_KEY_HINT };
  }

  if (is(element, 'bpmn:UserTask')) {
    idOptions = { description: TASK_KEY_HINT };
  }

  if (is(element, 'bpmn:Participant')) {
    processOptions = { processIdDescription: PROCESS_KEY_HINT };
  }

  idProps(generalGroup, element, translate, idOptions);
  nameProps(generalGroup, element, bpmnFactory, canvas, translate);
  processProps(generalGroup, element, translate, processOptions);
  versionTag(generalGroup, element, translate);
  executableProps(generalGroup, element, translate);
  elementTemplateChooserProps(generalGroup, element, elementTemplates, translate);

  var customFieldsGroups = elementTemplateCustomProps(element, elementTemplates, bpmnFactory, translate);

  var detailsGroup = {
    id: 'details',
    label: translate('Details'),
    entries: []
  };
  serviceTaskDelegateProps(detailsGroup, element, bpmnFactory, translate);
  userTaskProps(detailsGroup, element, translate);
  scriptProps(detailsGroup, element, bpmnFactory, translate);
  linkProps(detailsGroup, element, translate);
  callActivityProps(detailsGroup, element, bpmnFactory, translate);
  eventProps(detailsGroup, element, bpmnFactory, elementRegistry, translate);
  errorProps(detailsGroup, element, bpmnFactory, translate);
  conditionalProps(detailsGroup, element, bpmnFactory, translate);
  startEventInitiator(detailsGroup, element, translate); // this must be the last element of the details group!

  var multiInstanceGroup = {
    id: 'multiInstance',
    label: translate('Multi Instance'),
    entries: []
  };
  multiInstanceProps(multiInstanceGroup, element, bpmnFactory, translate);

  var asyncGroup = {
    id : 'async',
    label: translate('Asynchronous Continuations'),
    entries : []
  };
  asynchronousContinuationProps(asyncGroup, element, bpmnFactory, translate);

  var jobConfigurationGroup = {
    id : 'jobConfiguration',
    label : translate('Job Configuration'),
    entries : [],
    enabled: isJobConfigEnabled
  };
  jobConfiguration(jobConfigurationGroup, element, bpmnFactory, translate);

  var externalTaskGroup = {
    id : 'externalTaskConfiguration',
    label : translate('External Task Configuration'),
    entries : [],
    enabled: isExternalTaskPriorityEnabled
  };
  externalTaskConfiguration(externalTaskGroup, element, bpmnFactory, translate);


  var candidateStarterGroup = {
    id: 'candidateStarterConfiguration',
    label: translate('Candidate Starter Configuration'),
    entries: []
  };
  candidateStarter(candidateStarterGroup, element, bpmnFactory, translate);

  var historyTimeToLiveGroup = {
    id: 'historyConfiguration',
    label: translate('History Configuration'),
    entries: []
  };
  historyTimeToLive(historyTimeToLiveGroup, element, bpmnFactory, translate);

  var tasklistGroup = {
    id: 'tasklist',
    label: translate('Tasklist Configuration'),
    entries: []
  };
  tasklist(tasklistGroup, element, bpmnFactory, translate);

  var documentationGroup = {
    id: 'documentation',
    label: translate('Documentation'),
    entries: []
  };
  documentationProps(documentationGroup, element, bpmnFactory, translate);

  var groups = [];
  groups.push(generalGroup);
  customFieldsGroups.forEach(function(group) {
    groups.push(group);
  });
  groups.push(detailsGroup);
  groups.push(externalTaskGroup);
  groups.push(multiInstanceGroup);
  groups.push(asyncGroup);
  groups.push(jobConfigurationGroup);
  groups.push(candidateStarterGroup);
  groups.push(historyTimeToLiveGroup);
  groups.push(tasklistGroup);
  groups.push(documentationGroup);

  return groups;
}

function createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate) {
  var variablesGroup = {
    id : 'variables',
    label : translate('Variables'),
    entries: []
  };
  variableMapping(variablesGroup, element, bpmnFactory, translate);

  return [
    variablesGroup
  ];
}

function createFormsTabGroups(element, bpmnFactory, elementRegistry, translate) {
  var formGroup = {
    id : 'forms',
    label : translate('Forms'),
    entries: []
  };
  formProps(formGroup, element, bpmnFactory, translate);

  return [
    formGroup
  ];
}

function createListenersTabGroups(element, bpmnFactory, elementRegistry, translate) {

  var listenersGroup = {
    id : 'listeners',
    label: translate('Listeners'),
    entries: []
  };

  var options = listenerProps(listenersGroup, element, bpmnFactory, translate);

  var listenerDetailsGroup = {
    id: 'listener-details',
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedListener(element, node);
    },
    label: function(element, node) {
      var param = options.getSelectedListener(element, node);
      return getListenerLabel(param, translate);
    }
  };

  listenerDetails(listenerDetailsGroup, element, bpmnFactory, options, translate);

  var listenerFieldsGroup = {
    id: 'listener-fields',
    label: translate('Field Injection'),
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedListener(element, node);
    }
  };

  listenerFields(listenerFieldsGroup, element, bpmnFactory, options, translate);

  return [
    listenersGroup,
    listenerDetailsGroup,
    listenerFieldsGroup
  ];
}

function createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate) {

  var inputOutputGroup = {
    id: 'input-output',
    label: translate('Parameters'),
    entries: []
  };

  var options = inputOutput(inputOutputGroup, element, bpmnFactory, translate);

  var inputOutputParameterGroup = {
    id: 'input-output-parameter',
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedParameter(element, node);
    },
    label: function(element, node) {
      var param = options.getSelectedParameter(element, node);
      return getInputOutputParameterLabel(param, translate);
    }
  };

  inputOutputParameter(inputOutputParameterGroup, element, bpmnFactory, options, translate);

  return [
    inputOutputGroup,
    inputOutputParameterGroup
  ];
}

function createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate) {
  var connectorDetailsGroup = {
    id: 'connector-details',
    label: translate('Details'),
    entries: []
  };

  connectorDetails(connectorDetailsGroup, element, bpmnFactory, translate);

  var connectorInputOutputGroup = {
    id: 'connector-input-output',
    label: translate('Input/Output'),
    entries: []
  };

  var options = connectorInputOutput(connectorInputOutputGroup, element, bpmnFactory, translate);

  var connectorInputOutputParameterGroup = {
    id: 'connector-input-output-parameter',
    entries: [],
    enabled: function(element, node) {
      return options.getSelectedParameter(element, node);
    },
    label: function(element, node) {
      var param = options.getSelectedParameter(element, node);
      return getInputOutputParameterLabel(param, translate);
    }
  };

  connectorInputOutputParameter(connectorInputOutputParameterGroup, element, bpmnFactory, options, translate);

  return [
    connectorDetailsGroup,
    connectorInputOutputGroup,
    connectorInputOutputParameterGroup
  ];
}

function createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate) {

  var fieldGroup = {
    id: 'field-injections-properties',
    label: translate('Field Injections'),
    entries: []
  };

  fieldInjections(fieldGroup, element, bpmnFactory, translate);

  return [
    fieldGroup
  ];
}

function createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate) {

  var propertiesGroup = {
    id : 'extensionElements-properties',
    label: translate('Properties'),
    entries: []
  };
  properties(propertiesGroup, element, bpmnFactory, translate);

  return [
    propertiesGroup
  ];
}

// activiti Properties Provider /////////////////////////////////////


/**
 * A properties provider for activiti related properties.
 *
 * @param {EventBus} eventBus
 * @param {Canvas} canvas
 * @param {BpmnFactory} bpmnFactory
 * @param {ElementRegistry} elementRegistry
 * @param {ElementTemplates} elementTemplates
 * @param {Translate} translate
 */
function ActivitiPropertiesProvider(
    eventBus, canvas, bpmnFactory,
    elementRegistry, elementTemplates, translate) {

  PropertiesActivator.call(this, eventBus);

  this.getTabs = function(element) {

    var generalTab = {
      id: 'general',
      label: translate('General'),
      groups: createGeneralTabGroups(
        element, canvas, bpmnFactory,
        elementRegistry, elementTemplates, translate)
    };

    var variablesTab = {
      id: 'variables',
      label: translate('Variables'),
      groups: createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var formsTab = {
      id: 'forms',
      label: translate('Forms'),
      groups: createFormsTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var listenersTab = {
      id: 'listeners',
      label: translate('Listeners'),
      groups: createListenersTabGroups(element, bpmnFactory, elementRegistry, translate),
      enabled: function(element) {
        return !eventDefinitionHelper.getLinkEventDefinition(element)
          || (!is(element, 'bpmn:IntermediateThrowEvent')
          && eventDefinitionHelper.getLinkEventDefinition(element));
      }
    };

    var inputOutputTab = {
      id: 'input-output',
      label: translate('Input/Output'),
      groups: createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var connectorTab = {
      id: 'connector',
      label: translate('Connector'),
      groups: createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate),
      enabled: function(element) {
        var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element);
        return bo && implementationTypeHelper.getImplementationType(bo) === 'connector';
      }
    };

    var fieldInjectionsTab = {
      id: 'field-injections',
      label: translate('Field Injections'),
      groups: createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate)
    };

    var extensionsTab = {
      id: 'extensionElements',
      label: translate('Extensions'),
      groups: createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate)
    };

    return [
      generalTab,
      variablesTab,
      connectorTab,
      formsTab,
      listenersTab,
      inputOutputTab,
      fieldInjectionsTab,
      extensionsTab
    ];
  };

}

ActivitiPropertiesProvider.$inject = [
  'eventBus',
  'canvas',
  'bpmnFactory',
  'elementRegistry',
  'elementTemplates',
  'translate'
];

inherits(ActivitiPropertiesProvider, PropertiesActivator);

module.exports = ActivitiPropertiesProvider;

},{"../../PropertiesActivator":575,"../../helper/AsyncCapableHelper":588,"../../helper/EventDefinitionHelper":592,"../../helper/ImplementationTypeHelper":595,"../../provider/bpmn/parts/DocumentationProps":659,"../../provider/bpmn/parts/EventProps":660,"../../provider/bpmn/parts/ExecutableProps":661,"../../provider/bpmn/parts/IdProps":662,"../../provider/bpmn/parts/LinkProps":663,"../../provider/bpmn/parts/NameProps":664,"../../provider/bpmn/parts/ProcessProps":665,"./element-templates/parts/ChooserProps":608,"./element-templates/parts/CustomProps":609,"./parts/AsynchronousContinuationProps":611,"./parts/CallActivityProps":612,"./parts/CandidateStarterProps":613,"./parts/ConditionalProps":614,"./parts/ConnectorDetailProps":615,"./parts/ConnectorInputOutputParameterProps":616,"./parts/ConnectorInputOutputProps":617,"./parts/ErrorEventProps":618,"./parts/ExternalTaskConfigurationProps":619,"./parts/FieldInjectionProps":620,"./parts/FormProps":621,"./parts/HistoryTimeToLiveProps":622,"./parts/InputOutputParameterProps":623,"./parts/InputOutputProps":624,"./parts/JobConfigurationProps":625,"./parts/ListenerDetailProps":626,"./parts/ListenerFieldInjectionProps":627,"./parts/ListenerProps":628,"./parts/MultiInstanceLoopProps":629,"./parts/PropertiesProps":630,"./parts/ScriptTaskProps":631,"./parts/ServiceTaskDelegateProps":632,"./parts/StartEventInitiator":633,"./parts/TasklistProps":634,"./parts/UserTaskProps":635,"./parts/VariableMappingProps":636,"./parts/VersionTagProps":637,"bpmn-js/lib/util/ModelUtil":141,"inherits":347}],599:[function(require,module,exports){
'use strict';

var assign = require('lodash/assign');

/**
 * Create an input parameter representing the given
 * binding and value.
 *
 * @param {PropertyBinding} binding
 * @param {String} value
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement}
 */
function createInputParameter(binding, value, bpmnFactory) {
  var scriptFormat = binding.scriptFormat,
      parameterValue,
      parameterDefinition;

  if (scriptFormat) {
    parameterDefinition = bpmnFactory.create('activiti:Script', {
      scriptFormat: scriptFormat,
      value: value
    });
  } else {
    parameterValue = value;
  }

  return bpmnFactory.create('activiti:InputParameter', {
    name: binding.name,
    value: parameterValue,
    definition: parameterDefinition
  });
}

module.exports.createInputParameter = createInputParameter;


/**
 * Create an output parameter representing the given
 * binding and value.
 *
 * @param {PropertyBinding} binding
 * @param {String} value
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement}
 */
function createOutputParameter(binding, value, bpmnFactory) {
  var scriptFormat = binding.scriptFormat,
      parameterValue,
      parameterDefinition;

  if (scriptFormat) {
    parameterDefinition = bpmnFactory.create('activiti:Script', {
      scriptFormat: scriptFormat,
      value: binding.source
    });
  } else {
    parameterValue = binding.source;
  }

  return bpmnFactory.create('activiti:OutputParameter', {
    name: value,
    value: parameterValue,
    definition: parameterDefinition
  });
}

module.exports.createOutputParameter = createOutputParameter;


/**
 * Create activiti property from the given binding.
 *
 * @param {PropertyBinding} binding
 * @param {String} value
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement}
 */
function createActivitiProperty(binding, value, bpmnFactory) {
  return bpmnFactory.create('activiti:Property', {
    name: binding.name,
    value: value || ''
  });
}

module.exports.createActivitiProperty = createActivitiProperty;


/**
 * Create activiti:in element from given binding.
 *
 * @param {PropertyBinding} binding
 * @param {String} value
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement}
 */
function createActivitiIn(binding, value, bpmnFactory) {

  var properties = createActivitiInOutAttrs(binding, value);

  return bpmnFactory.create('activiti:In', properties);
}

module.exports.createActivitiIn = createActivitiIn;


/**
 * Create activiti:in with businessKey element from given binding.
 *
 * @param {PropertyBinding} binding
 * @param {String} value
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement}
 */
function createActivitiInWithBusinessKey(binding, value, bpmnFactory) {
  return bpmnFactory.create('activiti:In', {
    businessKey: value
  });
}

module.exports.createActivitiInWithBusinessKey = createActivitiInWithBusinessKey;


/**
 * Create activiti:out element from given binding.
 *
 * @param {PropertyBinding} binding
 * @param {String} value
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement}
 */
function createActivitiOut(binding, value, bpmnFactory) {
  var properties = createActivitiInOutAttrs(binding, value);

  return bpmnFactory.create('activiti:Out', properties);
}

module.exports.createActivitiOut = createActivitiOut;


/**
 * Create activiti:executionListener element containing an inline script from given binding.
 *
 * @param {PropertyBinding} binding
 * @param {String} value
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement}
 */
function createActivitiExecutionListenerScript(binding, value, bpmnFactory) {
  var scriptFormat = binding.scriptFormat,
      parameterValue,
      parameterDefinition;

  if (scriptFormat) {
    parameterDefinition = bpmnFactory.create('activiti:Script', {
      scriptFormat: scriptFormat,
      value: value
    });
  } else {
    parameterValue = value;
  }

  return bpmnFactory.create('activiti:ExecutionListener', {
    event: binding.event,
    value: parameterValue,
    script: parameterDefinition
  });
}

module.exports.createActivitiExecutionListenerScript = createActivitiExecutionListenerScript;

/**
 * Create activiti:field element containing string or expression from given binding.
 *
 * @param {PropertyBinding} binding
 * @param {String} value
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement}
 */
function createActivitiFieldInjection(binding, value, bpmnFactory) {
  var DEFAULT_PROPS = {
    'string': undefined,
    'expression': undefined,
    'name': undefined
  };

  var props = assign({}, DEFAULT_PROPS);

  if (!binding.expression) {
    props.string = value;
  } else {
    props.expression = value;
  }
  props.name = binding.name;

  return bpmnFactory.create('activiti:Field', props);
}
module.exports.createActivitiFieldInjection = createActivitiFieldInjection;


// helpers ////////////////////////////

/**
 * Create properties for activiti:in and activiti:out types.
 */
function createActivitiInOutAttrs(binding, value) {

  var properties = {};

  // activiti:in source(Expression) target
  if (binding.target) {

    properties.target = binding.target;

    if (binding.expression) {
      properties.sourceExpression = value;
    } else {
      properties.source = value;
    }
  } else

  // activiti:(in|out) variables local
  if (binding.variables) {
    properties.variables = 'all';

    if (binding.variables === 'local') {
      properties.local = true;
    }
  }

  // activiti:out source(Expression) target
  else {
    properties.target = value;

    [ 'source', 'sourceExpression' ].forEach(function(k) {
      if (binding[k]) {
        properties[k] = binding[k];
      }
    });
  }

  return properties;
}

},{"lodash/assign":513}],600:[function(require,module,exports){
'use strict';

var inherits = require('inherits');

var getTemplate = require('./Helper').getTemplate;

var PropertiesActivator = require('../../../PropertiesActivator');

var HIGHER_PRIORITY = 1100;

/**
 * Applies template visibility settings.
 *
 * Controlled using `entriesVisible` on template config object:
 *
 * ```json
 *     "entriesVisible": {
 *       "_all": true|false,
 *       "entryName": true|false,
 *       ...
 *     }
 * ```
 *
 * @param {EventBus} eventBus
 * @param {ElementTemplates} elementTemplates
 */
function CustomElementsPropertiesActivator(eventBus, elementTemplates) {
  PropertiesActivator.call(this, eventBus, HIGHER_PRIORITY);

  this.isEntryVisible = function(entry, element) {

    var template = getTemplate(element, elementTemplates);

    if (template && !isEntryVisible(entry, template)) {
      return false;
    }
  };

  this.isPropertyEditable = function(entry, propertyName, element) {

    var template = getTemplate(element, elementTemplates);

    if (template && !isEntryEditable(entry, template)) {
      return false;
    }
  };
}

CustomElementsPropertiesActivator.$inject = [ 'eventBus', 'elementTemplates' ];

inherits(CustomElementsPropertiesActivator, PropertiesActivator);

module.exports = CustomElementsPropertiesActivator;



// helpers ////////////////////////////////////


var CUSTOM_PROPERTIES_PATTERN = /^custom-/;

var DEFAULT_ENTRIES_VISIBLE = {
  _all: false,
  id: true,
  name: true
};

function isCustomEntry(entry) {
  return CUSTOM_PROPERTIES_PATTERN.test(entry.id);
}

function isEntryVisible(entry, template) {

  var entryId = entry.id;

  if (entryId === 'elementTemplate-chooser' || isCustomEntry(entry)) {
    return true;
  }

  var entriesVisible = template.entriesVisible || DEFAULT_ENTRIES_VISIBLE;

  if (typeof entriesVisible === 'boolean') {
    return entriesVisible;
  }

  var defaultVisible = entriesVisible._all || false,
      entryVisible = entriesVisible[entryId];

  // d = true, e = false => false
  // d = false, e = true => true
  // d = false, e = false
  return (
    (defaultVisible === true && entryVisible !== false) ||
    (defaultVisible === false && entryVisible === true)
  );
}

function isEntryEditable(entry, template) {

  var property;

  if (isCustomEntry(entry)) {
    property = getProperty(template, entry);

    return property && property.editable !== false;
  }

  return true;
}

function getProperty(template, entry) {

  var index;
  var idx = entry.id.replace('custom-' + template.id + '-', '');
  if (idx.indexOf('-') !== -1) {
    var indexes = idx.split('-');
    if (indexes.length == 2) {
      var scopeName = indexes[0].replace(/_/g, ':');
      index = parseInt(indexes[1], 10);
      if (scopeName && !isNaN(index)) {
        return template.scopes[scopeName].properties[index];
      }
    }
  } else {
    index = parseInt(idx, 10);
    if (!isNaN(index)) {
      return template.properties[index];
    }
  }

  throw new Error('cannot extract property index for entry <' + entry.id + '>');
}

},{"../../../PropertiesActivator":575,"./Helper":603,"inherits":347}],601:[function(require,module,exports){
'use strict';

var values = require('lodash/values');

/**
 * The guy knowing all configured element templates.
 *
 * This registry won't validate. Use the {@link Validator}
 * to verify a template is valid prior to adding it to
 * this registry.
 */
function ElementTemplates() {

  this._templates = {};

  /**
   * Sets the known element templates.
   *
   * @param {Array<TemplateDescriptor>} descriptors
   *
   * @return {ElementTemplates}
   */
  this.set = function(descriptors) {

    var templates = this._templates = {};

    descriptors.forEach(function(descriptor) {
      templates[descriptor.id] = descriptor;
    });

    return this;
  };

  /**
   * Get template descriptor with given id.
   *
   * @param {String} id
   *
   * @return {TemplateDescriptor}
   */
  this.get = function(id) {
    return this._templates[id];
  };

  /**
   * Return all known template descriptors.
   *
   * @return {Array<TemplateDescriptor>}
   */
  this.getAll = function() {
    return values(this._templates);
  };

}

module.exports = ElementTemplates;
},{"lodash/values":552}],602:[function(require,module,exports){
'use strict';

var Validator = require('./Validator');

/**
 * The guy responsible for template loading.
 *
 * Provide the actual templates via the `config.elementTemplates`.
 *
 * That configuration can either be an array of template
 * descriptors or a node style callback to retrieve
 * the templates asynchronously.
 *
 * @param {Array<TemplateDescriptor>|Function} loadTemplates
 * @param {EventBus} eventBus
 * @param {ElementTemplates} elementTemplates
 */
function ElementTemplatesLoader(loadTemplates, eventBus, elementTemplates) {
  this._loadTemplates = loadTemplates;
  this._eventBus = eventBus;
  this._elementTemplates = elementTemplates;

  var self = this;

  eventBus.on('diagram.init', function() {
    self.reload();
  });
}

module.exports = ElementTemplatesLoader;

ElementTemplatesLoader.$inject = [
  'config.elementTemplates',
  'eventBus',
  'elementTemplates'
];


ElementTemplatesLoader.prototype.reload = function() {

  var self = this;

  var loadTemplates = this._loadTemplates;

  // no templates specified
  if (typeof loadTemplates === 'undefined') {
    return;
  }

  // template loader function specified
  if (typeof loadTemplates === 'function') {

    return loadTemplates(function(err, templates) {

      if (err) {
        return self.templateErrors([ err ]);
      }

      self.setTemplates(templates);
    });
  }

  // templates array specified
  if (loadTemplates.length) {
    return this.setTemplates(loadTemplates);
  }

};

ElementTemplatesLoader.prototype.setTemplates = function(templates) {

  var elementTemplates = this._elementTemplates;

  var validator = new Validator().addAll(templates);

  var errors = validator.getErrors(),
      validTemplates = validator.getValidTemplates();

  elementTemplates.set(validTemplates);

  if (errors.length) {
    this.templateErrors(errors);
  }

  this.templatesChanged();
};

ElementTemplatesLoader.prototype.templatesChanged = function() {
  this._eventBus.fire('elementTemplates.changed');
};

ElementTemplatesLoader.prototype.templateErrors = function(errors) {
  this._eventBus.fire('elementTemplates.errors', {
    errors: errors
  });
};
},{"./Validator":604}],603:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var is = require('bpmn-js/lib/util/ModelUtil').is,
    isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny;

var find = require('lodash/find');


var TEMPLATE_ATTR = 'activiti:modelerTemplate';

/**
 * The BPMN 2.0 extension attribute name under
 * which the element template is stored.
 *
 * @type {String}
 */
module.exports.TEMPLATE_ATTR = TEMPLATE_ATTR;


/**
 * Get template id for a given diagram element.
 *
 * @param {djs.model.Base} element
 *
 * @return {String}
 */
function getTemplateId(element) {

  var bo = getBusinessObject(element);

  if (bo) {
    return bo.get(TEMPLATE_ATTR);
  }
}

module.exports.getTemplateId = getTemplateId;


/**
 * Get template of a given element.
 *
 * @param {Element} element
 * @param {ElementTemplates} elementTemplates
 *
 * @return {TemplateDefinition}
 */
function getTemplate(element, elementTemplates) {
  var id = getTemplateId(element);

  return id && elementTemplates.get(id);
}

module.exports.getTemplate = getTemplate;

/**
 * Get default template for a given element.
 *
 * @param {Element} element
 * @param {ElementTemplates} elementTemplates
 *
 * @return {TemplateDefinition}
 */
function getDefaultTemplate(element, elementTemplates) {

  // return first default template, if any exists
  return (
    elementTemplates.getAll().filter(function(t) {
      return isAny(element, t.appliesTo) && t.isDefault;
    })
  )[0];
}

module.exports.getDefaultTemplate = getDefaultTemplate;


/**
 * Find extension with given type in
 * BPMN element, diagram element or ExtensionElement.
 *
 * @param {ModdleElement|djs.model.Base} element
 * @param {String} type
 *
 * @return {ModdleElement} the extension
 */
function findExtension(element, type) {
  var bo = getBusinessObject(element);

  var extensionElements;

  if (is(bo, 'bpmn:ExtensionElements')) {
    extensionElements = bo;
  } else {
    extensionElements = bo.extensionElements;
  }

  if (!extensionElements) {
    return null;
  }

  return find(extensionElements.get('values'), function(e) {
    return is(e, type);
  });
}

module.exports.findExtension = findExtension;


function findExtensions(element, types) {
  var extensionElements = getExtensionElements(element);

  if (!extensionElements) {
    return [];
  }

  return extensionElements.get('values').filter(function(e) {
    return isAny(e, types);
  });
}

module.exports.findExtensions = findExtensions;


function findActivitiInOut(element, binding) {

  var extensionElements = getExtensionElements(element);

  if (!extensionElements) {
    return;
  }

  var matcher;

  if (binding.type === 'activiti:in') {
    matcher = function(e) {
      return is(e, 'activiti:In') && isInOut(e, binding);
    };
  } else
  if (binding.type === 'activiti:out') {
    matcher = function(e) {
      return is(e, 'activiti:Out') && isInOut(e, binding);
    };
  } else
  if (binding.type === 'activiti:in:businessKey') {
    matcher = function(e) {
      return is(e, 'activiti:In') && 'businessKey' in e;
    };
  }

  return find(extensionElements.get('values'), matcher);
}

module.exports.findActivitiInOut = findActivitiInOut;

function findActivitiProperty(activitiProperties, binding) {
  return find(activitiProperties.get('values'), function(p) {
    return p.name === binding.name;
  });
}

module.exports.findActivitiProperty = findActivitiProperty;


function findInputParameter(inputOutput, binding) {
  var parameters = inputOutput.get('inputParameters');

  return find(parameters, function(p) {
    return p.name === binding.name;
  });
}

module.exports.findInputParameter = findInputParameter;


function findOutputParameter(inputOutput, binding) {
  var parameters = inputOutput.get('outputParameters');

  return find(parameters, function(p) {
    var value = p.value;

    if (!binding.scriptFormat) {
      return value === binding.source;
    }

    var definition = p.definition;

    if (!definition || binding.scriptFormat !== definition.scriptFormat) {
      return false;
    }

    return definition.value === binding.source;
  });
}

module.exports.findOutputParameter = findOutputParameter;



// helpers /////////////////////////////////

function getExtensionElements(element) {
  var bo = getBusinessObject(element);

  if (is(bo, 'bpmn:ExtensionElements')) {
    return bo;
  } else {
    return bo.extensionElements;
  }
}


function isInOut(element, binding) {

  if (binding.type === 'activiti:in') {
    // find based on target attribute
    if (binding.target) {
      return element.target === binding.target;
    }
  }

  if (binding.type === 'activiti:out') {
    // find based on source / sourceExpression
    if (binding.source) {
      return element.source === binding.source;
    }

    if (binding.sourceExpression) {
      return element.sourceExpression === binding.sourceExpression;
    }
  }

  // find based variables / local combination
  if (binding.variables) {
    return element.variables === 'all' && (
      binding.variables !== 'local' || element.local
    );
  }
}

},{"bpmn-js/lib/features/modeling/util/ModelingUtil":112,"bpmn-js/lib/util/ModelUtil":141,"lodash/find":519}],604:[function(require,module,exports){
'use strict';

var isArray = require('lodash/isArray');
var isObject = require('lodash/isObject');

var DROPDOWN_TYPE = 'Dropdown';

var VALID_TYPES = [ 'String', 'Text', 'Boolean', 'Hidden', DROPDOWN_TYPE ];

var PROPERTY_TYPE = 'property',
    ACTIVITI_PROPERTY_TYPE = 'activiti:property',
    ACTIVITI_INPUT_PARAMETER_TYPE = 'activiti:inputParameter',
    ACTIVITI_OUTPUT_PARAMETER_TYPE = 'activiti:outputParameter',
    ACTIVITI_IN_TYPE = 'activiti:in',
    ACTIVITI_OUT_TYPE = 'activiti:out',
    ACTIVITI_IN_BUSINESS_KEY_TYPE = 'activiti:in:businessKey',
    ACTIVITI_EXECUTION_LISTENER = 'activiti:executionListener',
    ACTIVITI_FIELD = 'activiti:field';

var VALID_BINDING_TYPES = [
  PROPERTY_TYPE,
  ACTIVITI_PROPERTY_TYPE,
  ACTIVITI_INPUT_PARAMETER_TYPE,
  ACTIVITI_OUTPUT_PARAMETER_TYPE,
  ACTIVITI_IN_TYPE,
  ACTIVITI_OUT_TYPE,
  ACTIVITI_IN_BUSINESS_KEY_TYPE,
  ACTIVITI_EXECUTION_LISTENER,
  ACTIVITI_FIELD
];


/**
 * A element template validator.
 */
function Validator() {

  this._templatesById = {};

  this._validTemplates = [];
  this._errors = [];


  /**
   * Adds the templates.
   *
   * @param {Array<TemplateDescriptor>} templates
   *
   * @return {Validator} self
   */
  this.addAll = function(templates) {

    if (!isArray(templates)) {
      this._logError('templates must be []');
    } else {
      templates.forEach(this.add, this);
    }

    return this;
  };

  /**
   * Add the given element template, if it is valid.
   *
   * @param {TemplateDescriptor} template
   *
   * @return {Validator} self
   */
  this.add = function(template) {

    var err = this._validateTemplate(template);

    if (!err) {
      this._templatesById[template.id] = template;

      this._validTemplates.push(template);
    }

    return this;
  };

  /**
   * Validate given template and return error (if any).
   *
   * @param {TemplateDescriptor} template
   *
   * @return {Error} validation error, if any
   */
  this._validateTemplate = function(template) {

    var err,
        id = template.id,
        appliesTo = template.appliesTo,
        properties = template.properties,
        scopes = template.scopes;

    if (!id) {
      return this._logError('missing template id');
    }

    if (id in this._templatesById) {
      return this._logError('template id <' + id + '> already used');
    }

    if (!isArray(appliesTo)) {
      err = this._logError('missing appliesTo=[]', template);
    }

    if (!isArray(properties)) {
      err = this._logError('missing properties=[]', template);
    } else {
      if (!this._validateProperties(properties)) {
        err = new Error('invalid properties');
      }
    }

    if (scopes) {
      err = this._validateScopes(template, scopes);
    }

    return err;
  };

  this._validateScopes = function(template, scopes) {

    var err,
        scope,
        scopeName;

    if (!isObject(scopes) || isArray(scopes)) {
      return this._logError('invalid scopes, should be scopes={}', template);
    }

    for (scopeName in scopes) {
      scope = scopes[scopeName];

      if (!isObject(scope) || isArray(scope)) {
        err = this._logError('invalid scope, should be scope={}', template);
      }

      if (!isArray(scope.properties)) {
        err = this._logError(
          'missing properties=[] in scope <' + scopeName + '>', template
        );
      } else {
        if (!this._validateProperties(scope.properties)) {
          err = new Error('invalid properties in scope <' + scopeName + '>');
        }
      }
    }

    return err;
  };

  /**
   * Validate properties and return false if any is invalid.
   *
   * @param {Array<PropertyDescriptor>} properties
   *
   * @return {Boolean} true if all properties are valid
   */
  this._validateProperties = function(properties) {
    var validProperties = properties.filter(this._validateProperty, this);

    return properties.length === validProperties.length;
  };

  /**
   * Validate property and return false, if there was
   * a validation error.
   *
   * @param {PropertyDescriptor} property
   *
   * @return {Boolean} true if property is valid
   */
  this._validateProperty = function(property) {

    var type = property.type,
        binding = property.binding;

    var err;

    var bindingType = binding.type;

    if (VALID_TYPES.indexOf(type) === -1) {
      err = this._logError(
        'invalid property type <' + type + '>; ' +
        'must be any of { ' + VALID_TYPES.join(', ') + ' }'
      );
    }

    if (type === DROPDOWN_TYPE && bindingType !== ACTIVITI_EXECUTION_LISTENER) {
      if (!isArray(property.choices)) {
        err = this._logError(
          'must provide choices=[] with ' + DROPDOWN_TYPE + ' type'
        );
      } else

      if (!property.choices.every(isDropdownChoiceValid)) {
        err = this._logError(
          '{ name, value } must be specified for ' +
          DROPDOWN_TYPE + ' choices'
        );
      }
    }

    if (!binding) {
      return this._logError('property missing binding');
    }

    if (VALID_BINDING_TYPES.indexOf(bindingType) === -1) {
      err = this._logError(
        'invalid property.binding type <' + bindingType + '>; ' +
        'must be any of { ' + VALID_BINDING_TYPES.join(', ') + ' }'
      );
    }

    if (bindingType === PROPERTY_TYPE ||
        bindingType === ACTIVITI_PROPERTY_TYPE ||
        bindingType === ACTIVITI_INPUT_PARAMETER_TYPE ||
        bindingType === ACTIVITI_FIELD) {

      if (!binding.name) {
        err = this._logError(
          'property.binding <' + bindingType + '> requires name'
        );
      }
    }

    if (bindingType === ACTIVITI_OUTPUT_PARAMETER_TYPE) {
      if (!binding.source) {
        err = this._logError(
          'property.binding <' + bindingType + '> requires source'
        );
      }
    }

    if (bindingType === ACTIVITI_IN_TYPE) {

      if (!binding.variables && !binding.target) {
        err = this._logError(
          'property.binding <' + bindingType + '> requires ' +
          'variables or target'
        );
      }
    }

    if (bindingType === ACTIVITI_OUT_TYPE) {

      if (!binding.variables && !binding.source && !binding.sourceExpression) {
        err = this._logError(
          'property.binding <' + bindingType + '> requires ' +
          'variables, sourceExpression or source'
        );
      }
    }

    if (bindingType === ACTIVITI_EXECUTION_LISTENER) {

      if (type !== 'Hidden') {
        err = this._logError(
          'invalid property type <' + type + '> for ' + ACTIVITI_EXECUTION_LISTENER + '; ' +
          'must be <Hidden>'
        );
      }
    }

    return !err;
  };


  this._logError = function(err, template) {

    if (typeof err === 'string') {
      if (template) {
        err = 'template(id: ' + template.id + ') ' + err;
      }

      err = new Error(err);
    }

    this._errors.push(err);

    return err;
  };

  this.getErrors = function() {
    return this._errors;
  };

  this.getValidTemplates = function() {
    return this._validTemplates;
  };
}

module.exports = Validator;


// helpers ///////////////////////////////////

function isDropdownChoiceValid(c) {
  return 'name' in c && 'value' in c;
}

},{"lodash/isArray":527,"lodash/isObject":534}],605:[function(require,module,exports){
'use strict';

var findExtension = require('../Helper').findExtension,
    findExtensions = require('../Helper').findExtensions;

var createActivitiProperty = require('../CreateHelper').createActivitiProperty,
    createInputParameter = require('../CreateHelper').createInputParameter,
    createOutputParameter = require('../CreateHelper').createOutputParameter,
    createActivitiIn = require('../CreateHelper').createActivitiIn,
    createActivitiOut = require('../CreateHelper').createActivitiOut,
    createActivitiInWithBusinessKey = require('../CreateHelper').createActivitiInWithBusinessKey,
    createActivitiExecutionListenerScript = require('../CreateHelper').createActivitiExecutionListenerScript,
    createActivitiFieldInjection = require('../CreateHelper').createActivitiFieldInjection;

var forEach = require('lodash/forEach');

var ACTIVITI_SERVICE_TASK_LIKE = [
  'activiti:class',
  'activiti:delegateExpression',
  'activiti:expression'
];

/**
 * A handler that changes the modeling template of a BPMN element.
 */
function ChangeElementTemplateHandler(modeling, commandStack, bpmnFactory) {

  function getOrCreateExtensionElements(element) {

    var bo = element.businessObject;

    var extensionElements = bo.extensionElements;

    // add extension elements
    if (!extensionElements) {
      extensionElements = bpmnFactory.create('bpmn:ExtensionElements', {
        values: []
      });

      modeling.updateProperties(element, {
        extensionElements: extensionElements
      });
    }

    return extensionElements;
  }

  function updateModelerTemplate(element, newTemplate) {
    modeling.updateProperties(element, {
      'activiti:modelerTemplate': newTemplate && newTemplate.id
    });
  }

  function updateIoMappings(element, newTemplate, context) {

    var newMappings = createInputOutputMappings(newTemplate, bpmnFactory),
        oldMappings;

    if (!newMappings) {
      return;
    }

    if (context) {
      commandStack.execute('properties-panel.update-businessobject', {
        element: element,
        businessObject: context,
        properties: { inputOutput: newMappings }
      });
    } else {
      context = getOrCreateExtensionElements(element);
      oldMappings = findExtension(element, 'activiti:InputOutput');
      commandStack.execute('properties-panel.update-businessobject-list', {
        element: element,
        currentObject: context,
        propertyName: 'values',
        objectsToAdd: [ newMappings ],
        objectsToRemove: oldMappings ? [ oldMappings ] : []
      });
    }
  }

  function updateActivitiField(element, newTemplate, context) {

    var newMappings = createActivitiFieldInjections(newTemplate, bpmnFactory),
        oldMappings;

    if (!newMappings) {
      return;
    }
    if (context) {
      commandStack.execute('properties-panel.update-businessobject', {
        element: element,
        businessObject: context,
        properties: { field: newMappings }
      });
    } else {
      context = getOrCreateExtensionElements(element);
      oldMappings = findExtensions(element, ['activiti:Field']);

      commandStack.execute('properties-panel.update-businessobject-list', {
        element: element,
        currentObject: context,
        propertyName: 'values',
        objectsToAdd: newMappings,
        objectsToRemove: oldMappings ? oldMappings : []
      });
    }
  }


  function updateActivitiProperties(element, newTemplate, context) {

    var newProperties = createActivitiProperties(newTemplate, bpmnFactory),
        oldProperties;

    if (!newProperties) {
      return;
    }

    if (context) {
      commandStack.execute('properties-panel.update-businessobject', {
        element: element,
        businessObject: context,
        properties: { properties: newProperties }
      });
    } else {
      context = getOrCreateExtensionElements(element);
      oldProperties = findExtension(element, 'activiti:Properties');

      commandStack.execute('properties-panel.update-businessobject-list', {
        element: element,
        currentObject: context,
        propertyName: 'values',
        objectsToAdd: [ newProperties ],
        objectsToRemove: oldProperties ? [ oldProperties ] : []
      });
    }
  }

  function updateProperties(element, newTemplate, context) {

    var newProperties = createBpmnPropertyUpdates(newTemplate, bpmnFactory);

    var newPropertiesCount = Object.keys(newProperties).length;

    if (!newPropertiesCount) {
      return;
    }

    if (context) {
      commandStack.execute('properties-panel.update-businessobject', {
        element: element,
        businessObject: context,
        properties: newProperties
      });
    } else {
      modeling.updateProperties(element, newProperties);
    }
  }

  function updateInOut(element, newTemplate, context) {

    var newInOut = createActivitiInOut(newTemplate, bpmnFactory),
        oldInOut;

    if (!newInOut) {
      return;
    }

    if (context) {
      commandStack.execute('properties-panel.update-businessobject', {
        element: element,
        businessObject: context,
        properties: { inout: newInOut }
      });
    } else {
      context = getOrCreateExtensionElements(element);
      oldInOut = findExtensions(context, [ 'activiti:In', 'activiti:Out' ]);

      commandStack.execute('properties-panel.update-businessobject-list', {
        element: element,
        currentObject: context,
        propertyName: 'values',
        objectsToAdd: newInOut,
        objectsToRemove: oldInOut
      });
    }
  }

  function updateExecutionListener(element, newTemplate, context) {

    var newExecutionListeners = createActivitiExecutionListeners(newTemplate, bpmnFactory),
        oldExecutionsListeners;

    if (!newExecutionListeners.length) {
      return;
    }

    if (context) {
      commandStack.execute('properties-panel.update-businessobject', {
        element: element,
        businessObject: context,
        properties: { executionListener: newExecutionListeners }
      });
    } else {
      context = getOrCreateExtensionElements(element);
      oldExecutionsListeners = findExtensions(context, [ 'activiti:ExecutionListener' ]);

      commandStack.execute('properties-panel.update-businessobject-list', {
        element: element,
        currentObject: context,
        propertyName: 'values',
        objectsToAdd: newExecutionListeners,
        objectsToRemove: oldExecutionsListeners
      });
    }
  }

  /**
   * Update / recreate a scoped element.
   *
   * @param {djs.model.Base} element the diagram parent element
   * @param {String} scopeName name of the scope, i.e. activiti:Connector
   * @param {Object} scopeDefinition
   */
  function updateScopeElements(element, scopeName, scopeDefinition) {

    var scopeElement = bpmnFactory.create(scopeName);

    // update activiti:inputOutput
    updateIoMappings(element, scopeDefinition, scopeElement);

    // update activiti:field
    updateActivitiField(element, scopeDefinition, scopeElement);

    // update activiti:properties
    updateActivitiProperties(element, scopeDefinition, scopeElement);

    // update other properties (bpmn:condition, activiti:async, ...)
    updateProperties(element, scopeDefinition, scopeElement);

    // update activiti:in and activiti:out
    updateInOut(element, scopeDefinition, scopeElement);

    // update activiti:executionListener
    updateExecutionListener(element, scopeDefinition, scopeElement);

    var extensionElements = getOrCreateExtensionElements(element);
    var oldScope = findExtension(extensionElements, scopeName);

    commandStack.execute('properties-panel.update-businessobject-list', {
      element: element,
      currentObject: extensionElements,
      propertyName: 'values',
      objectsToAdd: [ scopeElement ],
      objectsToRemove: oldScope ? [ oldScope ] : []
    });
  }

  /**
   * Compose an element template change action, updating all
   * necessary underlying properties.
   *
   * @param {Object} context
   * @param {Object} context.element
   * @param {Object} context.oldTemplate
   * @param {Object} context.newTemplate
   */
  this.preExecute = function(context) {

    var element = context.element,
        newTemplate = context.newTemplate;

    // update activiti:modelerTemplate attribute
    updateModelerTemplate(element, newTemplate);

    if (newTemplate) {

      // update activiti:inputOutput
      updateIoMappings(element, newTemplate);

      // update activiti:field
      updateActivitiField(element, newTemplate);

      // update activiti:properties
      updateActivitiProperties(element, newTemplate);

      // update other properties (bpmn:condition, activiti:async, ...)
      updateProperties(element, newTemplate);

      // update activiti:in and activiti:out
      updateInOut(element, newTemplate);

      // update activiti:executionListener
      updateExecutionListener(element, newTemplate);

      // loop on scopes properties
      forEach(newTemplate.scopes, function(scopeDefinition, scopeName) {
        updateScopeElements(element, scopeName, scopeDefinition);
      });

    }
  };
}

ChangeElementTemplateHandler.$inject = [ 'modeling', 'commandStack', 'bpmnFactory' ];

module.exports = ChangeElementTemplateHandler;



// helpers /////////////////////////////

function createBpmnPropertyUpdates(template, bpmnFactory) {

  var propertyUpdates = {};

  template.properties.forEach(function(p) {

    var binding = p.binding,
        bindingTarget = binding.name,
        propertyValue;

    if (binding.type === 'property') {

      if (bindingTarget === 'conditionExpression') {
        propertyValue = bpmnFactory.create('bpmn:FormalExpression', {
          body: p.value,
          language: binding.scriptFormat
        });
      } else {
        propertyValue = p.value;
      }

      // assigning activiti:async to true|false
      // assigning bpmn:conditionExpression to { $type: 'bpmn:FormalExpression', ... }
      propertyUpdates[bindingTarget] = propertyValue;

      // make sure we unset other "implementation types"
      // when applying a activiti:class template onto a preconfigured
      // activiti:delegateExpression element
      if (ACTIVITI_SERVICE_TASK_LIKE.indexOf(bindingTarget) !== -1) {
        ACTIVITI_SERVICE_TASK_LIKE.forEach(function(prop) {
          if (prop !== bindingTarget) {
            propertyUpdates[prop] = undefined;
          }
        });
      }
    }
  });

  return propertyUpdates;
}

function createActivitiFieldInjections(template, bpmnFactory) {
  var injections = [];

  template.properties.forEach(function(p) {
    var binding = p.binding,
        bindingType = binding.type;
    if (bindingType === 'activiti:field') {
      injections.push(createActivitiFieldInjection(
        binding, p.value, bpmnFactory
      ));
    }
  });

  if (injections.length) {
    return injections;
  }
}

function createActivitiProperties(template, bpmnFactory) {

  var properties = [];

  template.properties.forEach(function(p) {
    var binding = p.binding,
        bindingType = binding.type;

    if (bindingType === 'activiti:property') {
      properties.push(createActivitiProperty(
        binding, p.value, bpmnFactory
      ));
    }
  });

  if (properties.length) {
    return bpmnFactory.create('activiti:Properties', {
      values: properties
    });
  }
}

function createInputOutputMappings(template, bpmnFactory) {

  var inputParameters = [],
      outputParameters = [];

  template.properties.forEach(function(p) {
    var binding = p.binding,
        bindingType = binding.type;

    if (bindingType === 'activiti:inputParameter') {
      inputParameters.push(createInputParameter(
        binding, p.value, bpmnFactory
      ));
    }

    if (bindingType === 'activiti:outputParameter') {
      outputParameters.push(createOutputParameter(
        binding, p.value, bpmnFactory
      ));
    }
  });

  // do we need to create new ioMappings (?)
  if (outputParameters.length || inputParameters.length) {
    return bpmnFactory.create('activiti:InputOutput', {
      inputParameters: inputParameters,
      outputParameters: outputParameters
    });
  }
}

function createActivitiInOut(template, bpmnFactory) {

  var inOuts = [];

  template.properties.forEach(function(p) {
    var binding = p.binding,
        bindingType = binding.type;

    if (bindingType === 'activiti:in') {
      inOuts.push(createActivitiIn(
        binding, p.value, bpmnFactory
      ));
    } else
    if (bindingType === 'activiti:out') {
      inOuts.push(createActivitiOut(
        binding, p.value, bpmnFactory
      ));
    } else
    if (bindingType === 'activiti:in:businessKey') {
      inOuts.push(createActivitiInWithBusinessKey(
        binding, p.value, bpmnFactory
      ));
    }
  });

  return inOuts;
}


function createActivitiExecutionListeners(template, bpmnFactory) {

  var executionListener = [];

  template.properties.forEach(function(p) {
    var binding = p.binding,
        bindingType = binding.type;

    if (bindingType === 'activiti:executionListener') {
      executionListener.push(createActivitiExecutionListenerScript(
        binding, p.value, bpmnFactory
      ));
    }
  });

  return executionListener;
}

},{"../CreateHelper":599,"../Helper":603,"lodash/forEach":522}],606:[function(require,module,exports){
'use strict';

var ChangeElementTemplateHandler = require('./ChangeElementTemplateHandler');

var getTemplate = require('../Helper').getTemplate,
    getDefaultTemplate = require('../Helper').getDefaultTemplate;

function registerHandlers(commandStack, elementTemplates, eventBus, elementRegistry) {
  commandStack.registerHandler(
    'propertiesPanel.activiti.changeTemplate',
    ChangeElementTemplateHandler
  );

  // apply default element templates on shape creation
  eventBus.on([ 'commandStack.shape.create.postExecuted' ], function(context) {
    applyDefaultTemplate(context.context.shape, elementTemplates, commandStack);
  });

  // apply default element templates on connection creation
  eventBus.on([ 'commandStack.connection.create.postExecuted' ], function(context) {
    applyDefaultTemplate(context.context.connection, elementTemplates, commandStack);
  });
}

registerHandlers.$inject = [ 'commandStack', 'elementTemplates', 'eventBus', 'elementRegistry' ];


module.exports = {
  __init__: [ registerHandlers ]
};


function applyDefaultTemplate(element, elementTemplates, commandStack) {

  if (!getTemplate(element, elementTemplates)
      && getDefaultTemplate(element, elementTemplates)) {

    var command = 'propertiesPanel.activiti.changeTemplate';
    var commandContext = {
      element: element,
      newTemplate: getDefaultTemplate(element, elementTemplates)
    };

    commandStack.execute(command, commandContext);
  }
}

},{"../Helper":603,"./ChangeElementTemplateHandler":605}],607:[function(require,module,exports){
module.exports = {
  __depends__: [
    require('./cmd/index'),
    require('diagram-js/lib/i18n/translate').default
  ],
  __init__: [
    'customElementsPropertiesActivator',
    'elementTemplatesLoader'
  ],
  customElementsPropertiesActivator: [ 'type', require('./CustomElementsPropertiesActivator') ],
  elementTemplates: [ 'type', require('./ElementTemplates') ],
  elementTemplatesLoader: [ 'type', require('./ElementTemplatesLoader') ]
};

},{"./CustomElementsPropertiesActivator":600,"./ElementTemplates":601,"./ElementTemplatesLoader":602,"./cmd/index":606,"diagram-js/lib/i18n/translate":337}],608:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory'),
    is = require('bpmn-js/lib/util/ModelUtil').is,
    getTemplate = require('../Helper').getTemplate,
    getTemplateId = require('../Helper').getTemplateId;

var find = require('lodash/find');

var TEMPLATE_ATTR = require('../Helper').TEMPLATE_ATTR;

function isAny(element, types) {
  return types.reduce(function(result, type) {
    return result || is(element, type);
  }, false);
}


module.exports = function(group, element, elementTemplates, translate) {

  var options = getTemplateOptions(element, elementTemplates, translate);

  if (options.length === 1 && !options[0].isDefault) {
    return;
  }

  // select element template (via dropdown)
  group.entries.push(entryFactory.selectBox({
    id: 'elementTemplate-chooser',
    label: translate('Element Template'),
    modelProperty: 'activiti:modelerTemplate',
    selectOptions: options,
    set: function(element, properties) {
      return applyTemplate(element, properties[TEMPLATE_ATTR], elementTemplates);
    },
    disabled: function() {
      var template = getTemplate(element, elementTemplates);

      return template && isDefaultTemplate(template);
    }
  }));

};


// helpers //////////////////////////////////////

function applyTemplate(element, newTemplateId, elementTemplates) {

  // cleanup
  // clear input output mappings
  // undo changes to properties defined in template

  // re-establish
  // set input output mappings
  // apply changes to properties as defined in new template

  var oldTemplate = getTemplate(element, elementTemplates),
      newTemplate = elementTemplates.get(newTemplateId);

  if (oldTemplate === newTemplate) {
    return;
  }

  return {
    cmd: 'propertiesPanel.activiti.changeTemplate',
    context: {
      element: element,
      oldTemplate: oldTemplate,
      newTemplate: newTemplate
    }
  };
}

function getTemplateOptions(element, elementTemplates, translate) {

  var currentTemplateId = getTemplateId(element);

  var emptyOption = {
    name: '',
    value: ''
  };

  var allOptions = elementTemplates.getAll().reduce(function(templates, t) {
    if (!isAny(element, t.appliesTo)) {
      return templates;
    }

    return templates.concat({
      name: translate(t.name),
      value: t.id,
      isDefault: t.isDefault
    });
  }, [ emptyOption ]);


  var defaultOption = find(allOptions, function(option) {
    return isDefaultTemplate(option);
  });

  var currentOption = find(allOptions, function(option) {
    return option.value === currentTemplateId;
  });

  if (currentTemplateId && !currentOption) {
    currentOption = unknownTemplate(currentTemplateId, translate);

    allOptions.push(currentOption);
  }

  if (!defaultOption) {

    // return all options, including empty
    // and optionally unknownTemplate option
    return allOptions;
  }

  // special limited handling for
  // default options

  var options = [];

  // current template not set
  if (!currentTemplateId) {
    options.push({
      name: '',
      value: ''
    });
  }

  // current template not default
  if (currentOption && currentOption !== defaultOption) {
    options.push(currentOption);
  }

  options.push(defaultOption);

  // [ (empty), (current), defaultOption ]
  return options;
}

function unknownTemplate(templateId, translate) {
  return {
    name: translate('[unknown template: {templateId}]', { templateId: templateId }),
    value: templateId
  };
}

function isDefaultTemplate(elementTemplate) {
  return elementTemplate.isDefault;
}
},{"../../../../factory/EntryFactory":579,"../Helper":603,"bpmn-js/lib/util/ModelUtil":141,"lodash/find":519}],609:[function(require,module,exports){
'use strict';

var assign = require('lodash/assign');

var entryFactory = require('../../../../factory/EntryFactory'),
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    getTemplate = require('../Helper').getTemplate,
    cmdHelper = require('../../../../helper/CmdHelper'),
    elementHelper = require('../../../../helper/ElementHelper');

var findExtension = require('../Helper').findExtension,
    findExtensions = require('../Helper').findExtensions,
    findInputParameter = require('../Helper').findInputParameter,
    findOutputParameter = require('../Helper').findOutputParameter,
    findActivitiProperty = require('../Helper').findActivitiProperty,
    findActivitiInOut = require('../Helper').findActivitiInOut;

var createActivitiProperty = require('../CreateHelper').createActivitiProperty,
    createInputParameter = require('../CreateHelper').createInputParameter,
    createOutputParameter = require('../CreateHelper').createOutputParameter,
    createActivitiIn = require('../CreateHelper').createActivitiIn,
    createActivitiOut = require('../CreateHelper').createActivitiOut,
    createActivitiInWithBusinessKey = require('../CreateHelper').createActivitiInWithBusinessKey,
    createActivitiFieldInjection = require('../CreateHelper').createActivitiFieldInjection;

var ACTIVITI_PROPERTY_TYPE = 'activiti:property',
    ACTIVITI_INPUT_PARAMETER_TYPE = 'activiti:inputParameter',
    ACTIVITI_OUTPUT_PARAMETER_TYPE = 'activiti:outputParameter',
    ACTIVITI_IN_TYPE = 'activiti:in',
    ACTIVITI_OUT_TYPE = 'activiti:out',
    ACTIVITI_IN_BUSINESS_KEY_TYPE = 'activiti:in:businessKey',
    ACTIVITI_EXECUTION_LISTENER_TYPE = 'activiti:executionListener',
    ACTIVITI_FIELD = 'activiti:field';

var BASIC_MODDLE_TYPES = [
  'Boolean',
  'Integer',
  'String'
];

var EXTENSION_BINDING_TYPES = [
  ACTIVITI_PROPERTY_TYPE,
  ACTIVITI_INPUT_PARAMETER_TYPE,
  ACTIVITI_OUTPUT_PARAMETER_TYPE,
  ACTIVITI_IN_TYPE,
  ACTIVITI_OUT_TYPE,
  ACTIVITI_IN_BUSINESS_KEY_TYPE,
  ACTIVITI_FIELD
];

var IO_BINDING_TYPES = [
  ACTIVITI_INPUT_PARAMETER_TYPE,
  ACTIVITI_OUTPUT_PARAMETER_TYPE
];

var IN_OUT_BINDING_TYPES = [
  ACTIVITI_IN_TYPE,
  ACTIVITI_OUT_TYPE,
  ACTIVITI_IN_BUSINESS_KEY_TYPE
];

/**
 * Injects custom properties into the given group.
 *
 * @param {djs.model.Base} element
 * @param {ElementTemplates} elementTemplates
 * @param {BpmnFactory} bpmnFactory
 * @param {Function} translate
 */
module.exports = function(element, elementTemplates, bpmnFactory, translate) {

  var template = getTemplate(element, elementTemplates);

  if (!template) {
    return [];
  }

  var renderCustomField = function(id, p, idx) {
    var propertyType = p.type;

    var entryOptions = {
      id: id,
      description: p.description,
      label: p.label ? translate(p.label) : p.label,
      modelProperty: id,
      get: propertyGetter(id, p),
      set: propertySetter(id, p, bpmnFactory),
      validate: propertyValidator(id, p, translate)
    };

    var entry;

    if (propertyType === 'Boolean') {
      entry = entryFactory.checkbox(entryOptions);
    }

    if (propertyType === 'String') {
      entry = entryFactory.textField(entryOptions);
    }

    if (propertyType === 'Text') {
      entry = entryFactory.textBox(entryOptions);
    }

    if (propertyType === 'Dropdown') {
      entryOptions.selectOptions = p.choices;

      entry = entryFactory.selectBox(entryOptions);
    }

    return entry;
  };

  var groups = [];
  var id, entry;

  var customFieldsGroup = {
    id: 'customField',
    label: translate('Custom Fields'),
    entries: []
  };
  template.properties.forEach(function(p, idx) {

    id = 'custom-' + template.id + '-' + idx;

    entry = renderCustomField(id, p, idx);
    if (entry) {
      customFieldsGroup.entries.push(entry);
    }
  });
  if (customFieldsGroup.entries.length > 0) {
    groups.push(customFieldsGroup);
  }

  if (template.scopes) {
    for (var scopeName in template.scopes) {

      var scope = template.scopes[scopeName];
      var idScopeName = scopeName.replace(/:/g, '_');

      var customScopeFieldsGroup = {
        id: 'customField-' + idScopeName,
        label: translate('Custom Fields for scope: ') + scopeName,
        entries: []
      };

      scope.properties.forEach(function(p, idx) {

        var propertyId = 'custom-' + template.id + '-' + idScopeName + '-' + idx;

        var scopedProperty = propertyWithScope(p, scopeName);

        entry = renderCustomField(propertyId, scopedProperty, idx);
        if (entry) {
          customScopeFieldsGroup.entries.push(entry);
        }
      });

      if (customScopeFieldsGroup.entries.length > 0) {
        groups.push(customScopeFieldsGroup);
      }
    }
  }

  return groups;
};


// getters, setters and validators ///////////////


/**
 * Return a getter that retrieves the given property.
 *
 * @param {String} name
 * @param {PropertyDescriptor} property
 *
 * @return {Function}
 */
function propertyGetter(name, property) {

  /* getter */
  return function get(element) {
    var value = getPropertyValue(element, property);

    return objectWithKey(name, value);
  };
}

/**
 * Return a setter that updates the given property.
 *
 * @param {String} name
 * @param {PropertyDescriptor} property
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {Function}
 */
function propertySetter(name, property, bpmnFactory) {

  /* setter */
  return function set(element, values) {

    var value = values[name];

    return setPropertyValue(element, property, value, bpmnFactory);
  };
}

/**
 * Return a validator that ensures the property is ok.
 *
 * @param {String} name
 * @param {PropertyDescriptor} property
 * @param {Function} translate
 *
 * @return {Function}
 */
function propertyValidator(name, property, translate) {

  /* validator */
  return function validate(element, values) {
    var value = values[name];

    var error = validateValue(value, property, translate);

    if (error) {
      return objectWithKey(name, error);
    }
  };
}


// get, set and validate helpers ///////////////////

/**
 * Return the value of the specified property descriptor,
 * on the passed diagram element.
 *
 * @param {djs.model.Base} element
 * @param {PropertyDescriptor} property
 *
 * @return {Any}
 */
function getPropertyValue(element, property) {

  var bo = getBusinessObject(element);

  var binding = property.binding,
      scope = property.scope;

  var bindingType = binding.type,
      bindingName = binding.name;

  var propertyValue = property.value || '';

  if (scope) {
    bo = findExtension(bo, scope.name);
    if (!bo) {
      return propertyValue;
    }
  }

  // property
  if (bindingType === 'property') {

    var value = bo.get(bindingName);

    if (bindingName === 'conditionExpression') {
      if (value) {
        return value.body;
      } else {
        // return defined default
        return propertyValue;
      }
    } else {
      // return value; default to defined default
      return typeof value !== 'undefined' ? value : propertyValue;
    }
  }

  var activitiProperties,
      activitiProperty;

  if (bindingType === ACTIVITI_PROPERTY_TYPE) {
    if (scope) {
      activitiProperties = bo.get('properties');
    } else {
      activitiProperties = findExtension(bo, 'activiti:Properties');
    }

    if (activitiProperties) {
      activitiProperty = findActivitiProperty(activitiProperties, binding);

      if (activitiProperty) {
        return activitiProperty.value;
      }
    }

    return propertyValue;
  }

  var inputOutput,
      ioParameter;

  if (IO_BINDING_TYPES.indexOf(bindingType) !== -1) {

    if (scope) {
      inputOutput = bo.get('inputOutput');
    } else {
      inputOutput = findExtension(bo, 'activiti:InputOutput');
    }

    if (!inputOutput) {
      // ioParameter cannot exist yet, return property value
      return propertyValue;
    }
  }

  // activiti input parameter
  if (bindingType === ACTIVITI_INPUT_PARAMETER_TYPE) {
    ioParameter = findInputParameter(inputOutput, binding);

    if (ioParameter) {
      if (binding.scriptFormat) {
        if (ioParameter.definition) {
          return ioParameter.definition.value;
        }
      } else {
        return ioParameter.value || '';
      }
    }

    return propertyValue;
  }

  // activiti output parameter
  if (binding.type === ACTIVITI_OUTPUT_PARAMETER_TYPE) {
    ioParameter = findOutputParameter(inputOutput, binding);

    if (ioParameter) {
      return ioParameter.name;
    }

    return propertyValue;
  }


  var ioElement;

  if (IN_OUT_BINDING_TYPES.indexOf(bindingType) != -1) {
    ioElement = findActivitiInOut(bo, binding);

    if (ioElement) {
      if (bindingType === ACTIVITI_IN_BUSINESS_KEY_TYPE) {
        return ioElement.businessKey;
      } else
      if (bindingType === ACTIVITI_OUT_TYPE) {
        return ioElement.target;
      } else
      if (bindingType === ACTIVITI_IN_TYPE) {
        return ioElement[binding.expression ? 'sourceExpression' : 'source'];
      }
    }

    return propertyValue;
  }

  if (bindingType === ACTIVITI_EXECUTION_LISTENER_TYPE) {
    var executionListener;
    if (scope) {
      executionListener = bo.get('executionListener');
    } else {
      executionListener = findExtension(bo, 'activiti:ExecutionListener');
    }

    return executionListener.script.value;
  }

  var fieldInjection;
  if (ACTIVITI_FIELD === bindingType) {
    var fieldInjections = findExtensions(bo, [ 'activiti:Field' ]);
    fieldInjections.forEach(function(item) {
      if (item.name === binding.name) {
        fieldInjection = item;
      }
    });
    if (fieldInjection) {
      return fieldInjection.string || fieldInjection.expression;
    } else {
      return '';
    }
  }

  throw unknownPropertyBinding(property);
}

module.exports.getPropertyValue = getPropertyValue;


/**
 * Return an update operation that changes the diagram
 * element's custom property to the given value.
 *
 * The response of this method will be processed via
 * {@link PropertiesPanel#applyChanges}.
 *
 * @param {djs.model.Base} element
 * @param {PropertyDescriptor} property
 * @param {String} value
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {Object|Array<Object>} results to be processed
 */
function setPropertyValue(element, property, value, bpmnFactory) {
  var bo = getBusinessObject(element);

  var binding = property.binding,
      scope = property.scope;

  var bindingType = binding.type,
      bindingName = binding.name;

  var propertyValue;

  var updates = [];

  var extensionElements;

  if (EXTENSION_BINDING_TYPES.indexOf(bindingType) !== -1) {
    extensionElements = bo.get('extensionElements');

    // create extension elements, if they do not exist (yet)
    if (!extensionElements) {
      extensionElements = elementHelper.createElement('bpmn:ExtensionElements', null, element, bpmnFactory);

      updates.push(cmdHelper.updateBusinessObject(
        element, bo, objectWithKey('extensionElements', extensionElements)
      ));
    }
  }

  if (scope) {
    bo = findExtension(bo, scope.name);
    if (!bo) {
      bo = elementHelper.createElement(scope.name, null, element, bpmnFactory);

      updates.push(cmdHelper.addElementsTolist(
        bo, extensionElements, 'values', [ bo ]
      ));
    }
  }

  // property
  if (bindingType === 'property') {

    if (bindingName === 'conditionExpression') {

      propertyValue = elementHelper.createElement('bpmn:FormalExpression', {
        body: value,
        language: binding.scriptFormat
      }, bo, bpmnFactory);
    } else {

      var moddlePropertyDescriptor = bo.$descriptor.propertiesByName[bindingName];

      var moddleType = moddlePropertyDescriptor.type;

      // make sure we only update String, Integer, Real and
      // Boolean properties (do not accidentally override complex objects...)
      if (BASIC_MODDLE_TYPES.indexOf(moddleType) === -1) {
        throw new Error('cannot set moddle type <' + moddleType + '>');
      }

      if (moddleType === 'Boolean') {
        propertyValue = !!value;
      } else
      if (moddleType === 'Integer') {
        propertyValue = parseInt(value, 10);

        if (isNaN(propertyValue)) {
          // do not write NaN value
          propertyValue = undefined;
        }
      } else {
        propertyValue = value;
      }
    }

    if (propertyValue !== undefined) {
      updates.push(cmdHelper.updateBusinessObject(
        element, bo, objectWithKey(bindingName, propertyValue)
      ));
    }
  }

  // activiti:property
  var activitiProperties,
      existingActivitiProperty,
      newActivitiProperty;

  if (bindingType === ACTIVITI_PROPERTY_TYPE) {

    if (scope) {
      activitiProperties = bo.get('properties');
    } else {
      activitiProperties = findExtension(extensionElements, 'activiti:Properties');
    }

    if (!activitiProperties) {
      activitiProperties = elementHelper.createElement('activiti:Properties', null, bo, bpmnFactory);

      if (scope) {
        updates.push(cmdHelper.updateBusinessObject(
          element, bo, { properties: activitiProperties }
        ));
      }
      else {
        updates.push(cmdHelper.addElementsTolist(
          element, extensionElements, 'values', [ activitiProperties ]
        ));
      }
    }

    existingActivitiProperty = findActivitiProperty(activitiProperties, binding);

    newActivitiProperty = createActivitiProperty(binding, value, bpmnFactory);

    updates.push(cmdHelper.addAndRemoveElementsFromList(
      element,
      activitiProperties,
      'values',
      null,
      [ newActivitiProperty ],
      existingActivitiProperty ? [ existingActivitiProperty ] : []
    ));
  }

  // activiti:inputParameter
  // activiti:outputParameter
  var inputOutput,
      existingIoParameter,
      newIoParameter;

  if (IO_BINDING_TYPES.indexOf(bindingType) !== -1) {

    if (scope) {
      inputOutput = bo.get('inputOutput');
    } else {
      inputOutput = findExtension(extensionElements, 'activiti:InputOutput');
    }

    // create inputOutput element, if it do not exist (yet)
    if (!inputOutput) {
      inputOutput = elementHelper.createElement('activiti:InputOutput', null, bo, bpmnFactory);

      if (scope) {
        updates.push(cmdHelper.updateBusinessObject(
          element, bo, { inputOutput: inputOutput }
        ));
      }
      else {
        updates.push(cmdHelper.addElementsTolist(
          element, extensionElements, 'values', inputOutput
        ));
      }
    }
  }

  if (bindingType === ACTIVITI_INPUT_PARAMETER_TYPE) {

    existingIoParameter = findInputParameter(inputOutput, binding);

    newIoParameter = createInputParameter(binding, value, bpmnFactory);

    updates.push(cmdHelper.addAndRemoveElementsFromList(
      element,
      inputOutput,
      'inputParameters',
      null,
      [ newIoParameter ],
      existingIoParameter ? [ existingIoParameter ] : []
    ));
  }

  if (bindingType === ACTIVITI_OUTPUT_PARAMETER_TYPE) {

    existingIoParameter = findOutputParameter(inputOutput, binding);

    newIoParameter = createOutputParameter(binding, value, bpmnFactory);

    updates.push(cmdHelper.addAndRemoveElementsFromList(
      element,
      inputOutput,
      'outputParameters',
      null,
      [ newIoParameter ],
      existingIoParameter ? [ existingIoParameter ] : []
    ));
  }


  // activiti:in
  // activiti:out
  // activiti:in:businessKey
  var existingInOut,
      newInOut;

  if (IN_OUT_BINDING_TYPES.indexOf(bindingType) !== -1) {

    existingInOut = findActivitiInOut(bo, binding);

    if (bindingType === ACTIVITI_IN_TYPE) {
      newInOut = createActivitiIn(binding, value, bpmnFactory);
    } else
    if (bindingType === ACTIVITI_OUT_TYPE) {
      newInOut = createActivitiOut(binding, value, bpmnFactory);
    } else {
      newInOut = createActivitiInWithBusinessKey(binding, value, bpmnFactory);
    }

    updates.push(cmdHelper.addAndRemoveElementsFromList(
      element,
      extensionElements,
      'values',
      null,
      [ newInOut ],
      existingInOut ? [ existingInOut ] : []
    ));
  }

  if (bindingType === ACTIVITI_FIELD) {
    var existingFieldInjections = findExtensions(bo, [ 'activiti:Field' ]);
    var newFieldInjections = [];

    if (existingFieldInjections.length > 0) {
      existingFieldInjections.forEach(function(item) {
        if (item.name === binding.name) {
          newFieldInjections.push(createActivitiFieldInjection(binding, value, bpmnFactory));
        } else {
          newFieldInjections.push(item);
        }
      });
    } else {
      newFieldInjections.push(createActivitiFieldInjection(binding, value, bpmnFactory));
    }

    updates.push(cmdHelper.addAndRemoveElementsFromList(
      element,
      extensionElements,
      'values',
      null,
      newFieldInjections,
      existingFieldInjections ? existingFieldInjections : []
    ));
  }

  if (updates.length) {
    return updates;
  }

  // quick warning for better debugging
  console.warn('no update', element, property, value);
}

module.exports.setPropertyValue = setPropertyValue;

/**
 * Validate value of a given property.
 *
 * @param {String} value
 * @param {PropertyDescriptor} property
 * @param {Function} translate
 *
 * @return {Object} with validation errors
 */
function validateValue(value, property, translate) {

  var constraints = property.constraints || {};

  if (constraints.notEmpty && isEmpty(value)) {
    return translate('Must not be empty');
  }

  if (constraints.maxLength && value.length > constraints.maxLength) {
    return translate('Must have max length {length}', { length: constraints.maxLength });
  }

  if (constraints.minLength && value.length < constraints.minLength) {
    return translate('Must have min length {length}', { length: constraints.minLength });
  }

  var pattern = constraints.pattern,
      message;

  if (pattern) {

    if (typeof pattern !== 'string') {
      message = pattern.message;
      pattern = pattern.value;
    }

    if (!matchesPattern(value, pattern)) {
      return message || translate('Must match pattern {pattern}', { pattern: pattern });
    }
  }
}


// misc helpers ///////////////////////////////

function propertyWithScope(property, scopeName) {
  if (!scopeName) {
    return property;
  }

  return assign({}, property, {
    scope: {
      name: scopeName
    }
  });
}

/**
 * Return an object with a single key -> value association.
 *
 * @param {String} key
 * @param {Any} value
 *
 * @return {Object}
 */
function objectWithKey(key, value) {
  var obj = {};

  obj[key] = value;

  return obj;
}

/**
 * Does the given string match the specified pattern?
 *
 * @param {String} str
 * @param {String} pattern
 *
 * @return {Boolean}
 */
function matchesPattern(str, pattern) {
  var regexp = new RegExp(pattern);

  return regexp.test(str);
}

function isEmpty(str) {
  return !str || /^\s*$/.test(str);
}

/**
 * Create a new {@link Error} indicating an unknown
 * property binding.
 *
 * @param {PropertyDescriptor} property
 *
 * @return {Error}
 */
function unknownPropertyBinding(property) {
  var binding = property.binding;

  return new Error('unknown binding: <' + binding.type + '>');
}

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../CreateHelper":599,"../Helper":603,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513}],610:[function(require,module,exports){
module.exports = {
  __depends__: [
    require('./element-templates/index'),
    require('diagram-js/lib/i18n/translate').default
  ],
  __init__: [ 'propertiesProvider' ],
  propertiesProvider: [ 'type', require('./ActivitiPropertiesProvider') ]
};


},{"./ActivitiPropertiesProvider":598,"./element-templates/index":607,"diagram-js/lib/i18n/translate":337}],611:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    is = require('bpmn-js/lib/util/ModelUtil').is,
    asyncContinuation = require('./implementation/AsyncContinuation');

module.exports = function(group, element, bpmnFactory, translate) {

  if (is(element, 'activiti:AsyncCapable')) {

    group.entries = group.entries.concat(asyncContinuation(element, bpmnFactory, {
      getBusinessObject: getBusinessObject
    }, translate));

  }
};
},{"./implementation/AsyncContinuation":638,"bpmn-js/lib/util/ModelUtil":141}],612:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    is = require('bpmn-js/lib/util/ModelUtil').is;

var entryFactory = require('../../../factory/EntryFactory');

var callable = require('./implementation/Callable');

var cmdHelper = require('../../../helper/CmdHelper');

var flattenDeep = require('lodash/flattenDeep');
var assign = require('lodash/assign');

function getCallableType(element) {
  var bo = getBusinessObject(element);

  var boCalledElement = bo.get('calledElement'),
      boCaseRef = bo.get('activiti:caseRef');

  var callActivityType = '';
  if (typeof boCalledElement !== 'undefined') {
    callActivityType = 'bpmn';
  } else

  if (typeof boCaseRef !== 'undefined') {
    callActivityType = 'cmmn';
  }

  return callActivityType;
}

var DEFAULT_PROPS = {
  calledElement: undefined,
  'activiti:calledElementBinding': 'latest',
  'activiti:calledElementVersion': undefined,
  'activiti:calledElementTenantId': undefined,
  'activiti:variableMappingClass' : undefined,
  'activiti:variableMappingDelegateExpression' : undefined,
  'activiti:caseRef': undefined,
  'activiti:caseBinding': 'latest',
  'activiti:caseVersion': undefined,
  'activiti:caseTenantId': undefined
};

module.exports = function(group, element, bpmnFactory, translate) {

  if (!is(element, 'activiti:CallActivity')) {
    return;
  }

  group.entries.push(entryFactory.selectBox({
    id : 'callActivity',
    label: translate('CallActivity Type'),
    selectOptions: [
      { name: 'BPMN', value: 'bpmn' },
      { name: 'CMMN', value: 'cmmn' }
    ],
    emptyParameter: true,
    modelProperty: 'callActivityType',

    get: function(element, node) {
      return {
        callActivityType: getCallableType(element)
      };
    },

    set: function(element, values, node) {
      var type = values.callActivityType;

      var props = assign({}, DEFAULT_PROPS);

      if (type === 'bpmn') {
        props.calledElement = '';
      }
      else if (type === 'cmmn') {
        props['activiti:caseRef'] = '';
      }

      return cmdHelper.updateProperties(element, props);
    }

  }));

  group.entries.push(callable(element, bpmnFactory, {
    getCallableType: getCallableType
  }, translate));

  group.entries = flattenDeep(group.entries);
};

},{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"./implementation/Callable":639,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513,"lodash/flattenDeep":521}],613:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var candidateStarter = require('./implementation/CandidateStarter');

module.exports = function(group, element, bpmnFactory, translate) {
  var businessObject = getBusinessObject(element);

  if (is(element, 'activiti:Process') ||
      is(element, 'bpmn:Participant') && businessObject.get('processRef')) {

    group.entries = group.entries.concat(candidateStarter(element, bpmnFactory, {
      getBusinessObject: function(element) {
        var bo = getBusinessObject(element);

        if (!is(bo, 'bpmn:Participant')) {
          return bo;
        }

        return bo.get('processRef');
      }
    }, translate));

  }
};

},{"./implementation/CandidateStarter":640,"bpmn-js/lib/util/ModelUtil":141}],614:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    escapeHTML = require('../../../Utils').escapeHTML,
    domQuery = require('min-dom').query,
    cmdHelper = require('../../../helper/CmdHelper'),
    elementHelper = require('../../../helper/ElementHelper'),
    eventDefinitionHelper = require('../../../helper/EventDefinitionHelper'),
    scriptImplementation = require('./implementation/Script');


module.exports = function(group, element, bpmnFactory, translate) {
  var bo = getBusinessObject(element);

  if (!bo) {
    return;
  }

  var conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(element);

  if (!(is(element, 'bpmn:SequenceFlow') && isConditionalSource(element.source))
    && !conditionalEventDefinition) {
    return;
  }

  var script = scriptImplementation('language', 'body', true, translate);
  group.entries.push({
    id: 'condition',
    label: translate('Condition'),
    html: '<div class="bpp-row">' +
              '<label for="cam-condition-type">'+ escapeHTML(translate('Condition Type')) + '</label>' +
              '<div class="bpp-field-wrapper">' +
                '<select id="cam-condition-type" name="conditionType" data-value>' +
                  '<option value="expression">'+ escapeHTML(translate('Expression')) + '</option>' +
                  '<option value="script">'+ escapeHTML(translate('Script')) + '</option>' +
                  '<option value="" selected></option>' +
                '</select>' +
              '</div>' +
            '</div>' +

            // expression
            '<div class="bpp-row">' +
              '<label for="cam-condition" data-show="isExpression">' + escapeHTML(translate('Expression')) + '</label>' +
              '<div class="bpp-field-wrapper" data-show="isExpression">' +
                '<input id="cam-condition" type="text" name="condition" />' +
                '<button class="clear" data-action="clear" data-show="canClear">' +
                  '<span>X</span>' +
                '</button>' +
              '</div>' +
              '<div data-show="isScript">' +
                script.template +
              '</div>' +
            '</div>',

    get: function(element, propertyName) {
      var conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(element);

      var conditionExpression = conditionalEventDefinition
        ? conditionalEventDefinition.condition
        : bo.conditionExpression;

      var values = {},
          conditionType = '';

      if (conditionExpression) {
        var conditionLanguage = conditionExpression.language;
        if (typeof conditionLanguage !== 'undefined') {
          conditionType = 'script';
          values = script.get(element, conditionExpression);
        } else {
          conditionType = 'expression';
          values.condition = conditionExpression.get('body');
        }
      }

      values.conditionType = conditionType;

      return values;

    },

    set: function(element, values, containerElement) {
      var conditionType = values.conditionType;
      var commands = [];

      var conditionProps = {
        body: undefined
      };

      if (conditionType === 'script') {
        conditionProps = script.set(element, values, containerElement);
      } else {
        var condition = values.condition;

        conditionProps.body = condition;
      }

      var conditionOrConditionExpression;

      if (conditionType) {
        conditionOrConditionExpression = elementHelper.createElement(
          'bpmn:FormalExpression',
          conditionProps,
          conditionalEventDefinition || bo,
          bpmnFactory
        );

        var source = element.source;

        // if default-flow, remove default-property from source
        if (source && source.businessObject.default === bo) {
          commands.push(cmdHelper.updateProperties(source, { 'default': undefined }));
        }
      }

      var update = conditionalEventDefinition
        ? { condition: conditionOrConditionExpression }
        : { conditionExpression: conditionOrConditionExpression };

      commands.push(cmdHelper.updateBusinessObject(element, conditionalEventDefinition || bo, update));

      return commands;
    },

    validate: function(element, values) {
      var validationResult = {};

      if (!values.condition && values.conditionType === 'expression') {
        validationResult.condition = translate('Must provide a value');
      }
      else if (values.conditionType === 'script') {
        validationResult = script.validate(element, values);
      }

      return validationResult;
    },

    isExpression: function(element, inputNode) {
      var conditionType = domQuery('select[name=conditionType]', inputNode);
      if (conditionType.selectedIndex >= 0) {
        return conditionType.options[conditionType.selectedIndex].value === 'expression';
      }
    },

    isScript: function(element, inputNode) {
      var conditionType = domQuery('select[name=conditionType]', inputNode);
      if (conditionType.selectedIndex >= 0) {
        return conditionType.options[conditionType.selectedIndex].value === 'script';
      }
    },

    clear: function(element, inputNode) {
      // clear text input
      domQuery('input[name=condition]', inputNode).value='';

      return true;
    },

    canClear: function(element, inputNode) {
      var input = domQuery('input[name=condition]', inputNode);

      return input.value !== '';
    },

    script : script,

    cssClasses: [ 'bpp-textfield' ]
  });
};


// utilities //////////////////////////

var CONDITIONAL_SOURCES = [
  'bpmn:Activity',
  'bpmn:ExclusiveGateway',
  'bpmn:InclusiveGateway',
  'bpmn:ComplexGateway'
];

function isConditionalSource(element) {
  return isAny(element, CONDITIONAL_SOURCES);
}

},{"../../../Utils":576,"../../../helper/CmdHelper":590,"../../../helper/ElementHelper":591,"../../../helper/EventDefinitionHelper":592,"./implementation/Script":657,"bpmn-js/lib/features/modeling/util/ModelingUtil":112,"bpmn-js/lib/util/ModelUtil":141,"min-dom":556}],615:[function(require,module,exports){
'use strict';

var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'),
    InputOutputHelper = require('../../../helper/InputOutputHelper');

var entryFactory = require('../../../factory/EntryFactory'),
    cmdHelper = require('../../../helper/CmdHelper');

function getImplementationType(element) {
  return ImplementationTypeHelper.getImplementationType(element);
}

function getBusinessObject(element) {
  return ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element);
}

function getConnector(bo) {
  return InputOutputHelper.getConnector(bo);
}

function isConnector(element) {
  return getImplementationType(element) === 'connector';
}

module.exports = function(group, element, bpmnFactory, translate) {

  group.entries.push(entryFactory.textField({
    id: 'connectorId',
    label: translate('Connector Id'),
    modelProperty: 'connectorId',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      var connector = bo && getConnector(bo);
      var value = connector && connector.get('connectorId');
      return { connectorId: value };
    },

    set: function(element, values, node) {
      var bo = getBusinessObject(element);
      var connector = getConnector(bo);
      return cmdHelper.updateBusinessObject(element, connector, {
        connectorId: values.connectorId || undefined
      });
    },

    validate: function(element, values, node) {
      return isConnector(element) && !values.connectorId ? { connectorId: translate('Must provide a value') } : {};
    },

    hidden: function(element, node) {
      return !isConnector(element);
    }

  }));

};

},{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"../../../helper/ImplementationTypeHelper":595,"../../../helper/InputOutputHelper":596}],616:[function(require,module,exports){
'use strict';

var assign = require('lodash/assign');

var inputOutputParameter = require('./implementation/InputOutputParameter');

module.exports = function(group, element, bpmnFactory, options, translate) {

  options = assign({
    idPrefix: 'connector-',
    insideConnector: true
  }, options);

  group.entries = group.entries.concat(inputOutputParameter(element, bpmnFactory, options, translate));

};

},{"./implementation/InputOutputParameter":650,"lodash/assign":513}],617:[function(require,module,exports){
'use strict';

var inputOutput = require('./implementation/InputOutput');

module.exports = function(group, element, bpmnFactory, translate) {

  var inputOutputEntry = inputOutput(element, bpmnFactory, {
    idPrefix: 'connector-',
    insideConnector: true
  }, translate);

  group.entries = group.entries.concat(inputOutputEntry.entries);

  return {
    getSelectedParameter: inputOutputEntry.getSelectedParameter
  };

};

},{"./implementation/InputOutput":649}],618:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    eventDefinitionHelper = require('../../../helper/EventDefinitionHelper'),
    error = require('./implementation/ErrorEventDefinition');

var forEach = require('lodash/forEach');


module.exports = function(group, element, bpmnFactory, translate) {

  var errorEvents = [
    'bpmn:StartEvent',
    'bpmn:BoundaryEvent',
    'bpmn:EndEvent'
  ];

  forEach(errorEvents, function(event) {
    if (is(element, event)) {

      var errorEventDefinition = eventDefinitionHelper.getErrorEventDefinition(element);

      if (errorEventDefinition) {
        var isCatchingErrorEvent = is(element, 'bpmn:StartEvent') || is (element, 'bpmn:BoundaryEvent');

        var showErrorCodeVariable = isCatchingErrorEvent,
            showErrorMessageVariable = isCatchingErrorEvent;

        error(
          group,
          element,
          bpmnFactory,
          errorEventDefinition,
          showErrorCodeVariable,
          showErrorMessageVariable,
          translate);
      }
    }
  });
};

},{"../../../helper/EventDefinitionHelper":592,"./implementation/ErrorEventDefinition":642,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],619:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper');

var externalTaskPriority = require('./implementation/ExternalTaskPriority');

function getServiceTaskLikeBusinessObject(element) {
  var bo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element);

  // if the element is not a serviceTaskLike element, fetch the normal business object
  // This avoids the loss of the process / participant business object
  if (!bo) {
    bo = getBusinessObject(element);
  }

  return bo;
}

module.exports = function(group, element, bpmnFactory, translate) {

  var bo = getServiceTaskLikeBusinessObject(element);

  if (!bo) {
    return;
  }

  if (is(bo, 'activiti:TaskPriorized') || (is(bo, 'bpmn:Participant')) && bo.get('processRef')) {
    group.entries = group.entries.concat(externalTaskPriority(element, bpmnFactory, {
      getBusinessObject: function(element) {
        if (!is(bo, 'bpmn:Participant')) {
          return bo;
        }
        return bo.get('processRef');
      }
    }, translate));
  }
};
},{"../../../helper/ImplementationTypeHelper":595,"./implementation/ExternalTaskPriority":645,"bpmn-js/lib/util/ModelUtil":141}],620:[function(require,module,exports){
'use strict';

var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper');

var fieldInjection = require('./implementation/FieldInjection');

module.exports = function(group, element, bpmnFactory, translate) {

  var bo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element);

  if (!bo) {
    return;
  }

  var fieldInjectionEntry = fieldInjection(element, bpmnFactory, translate, { businessObject: bo });

  if (fieldInjectionEntry && fieldInjectionEntry.length > 0) {
    group.entries = group.entries.concat(fieldInjectionEntry);
  }

};

},{"../../../helper/ImplementationTypeHelper":595,"./implementation/FieldInjection":646}],621:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    getExtensionElements = require('../../../helper/ExtensionElementsHelper').getExtensionElements,
    removeEntry = require('../../../helper/ExtensionElementsHelper').removeEntry,
    extensionElements = require('./implementation/ExtensionElements'),
    properties = require('./implementation/Properties'),
    entryFactory = require('../../../factory/EntryFactory'),
    elementHelper = require('../../../helper/ElementHelper'),
    cmdHelper = require('../../../helper/CmdHelper'),
    formHelper = require('../../../helper/FormHelper'),
    utils = require('../../../Utils'),
    is = require('bpmn-js/lib/util/ModelUtil').is,
    find = require('lodash/find'),
    each = require('lodash/forEach');

function generateValueId() {
  return utils.nextId('Value_');
}

/**
 * Generate a form field specific textField using entryFactory.
 *
 * @param  {string} options.id
 * @param  {string} options.label
 * @param  {string} options.modelProperty
 * @param  {function} options.validate
 *
 * @return {Object} an entryFactory.textField object
 */
function formFieldTextField(options, getSelectedFormField) {

  var id = options.id,
      label = options.label,
      modelProperty = options.modelProperty,
      validate = options.validate;

  return entryFactory.textField({
    id: id,
    label: label,
    modelProperty: modelProperty,
    get: function(element, node) {
      var selectedFormField = getSelectedFormField(element, node) || {},
          values = {};

      values[modelProperty] = selectedFormField[modelProperty];

      return values;
    },

    set: function(element, values, node) {
      var commands = [];

      if (typeof options.set === 'function') {
        var cmd = options.set(element, values, node);

        if (cmd) {
          commands.push(cmd);
        }
      }

      var formField = getSelectedFormField(element, node),
          properties = {};

      properties[modelProperty] = values[modelProperty] || undefined;

      commands.push(cmdHelper.updateBusinessObject(element, formField, properties));

      return commands;
    },
    hidden: function(element, node) {
      return !getSelectedFormField(element, node);
    },
    validate: validate
  });
}

function ensureFormKeyAndDataSupported(element) {
  return (
    is(element, 'bpmn:StartEvent') && !is(element.parent, 'bpmn:SubProcess')
  ) || is(element, 'bpmn:UserTask');
}

module.exports = function(group, element, bpmnFactory, translate) {

  if (!ensureFormKeyAndDataSupported(element)) {
    return;
  }


  /**
   * Return the currently selected form field querying the form field select box
   * from the DOM.
   *
   * @param  {djs.model.Base} element
   * @param  {DOMElement} node - DOM element of any form field text input
   *
   * @return {ModdleElement} the currently selected form field
   */
  function getSelectedFormField(element, node) {
    var selected = formFieldsEntry.getSelected(element, node.parentNode);

    if (selected.idx === -1) {
      return;
    }

    return formHelper.getFormField(element, selected.idx);
  }

  // [FormKey] form key text input field
  group.entries.push(entryFactory.textField({
    id : 'form-key',
    label : translate('Form Key'),
    modelProperty: 'formKey',
    get: function(element, node) {
      var bo = getBusinessObject(element);

      return {
        formKey: bo.get('activiti:formKey')
      };
    },
    set: function(element, values, node) {
      var bo = getBusinessObject(element),
          formKey = values.formKey || undefined;

      return cmdHelper.updateBusinessObject(element, bo, { 'activiti:formKey': formKey });
    }
  }));

  // [FormData] form field select box
  var formFieldsEntry = extensionElements(element, bpmnFactory, {
    id: 'form-fields',
    label: translate('Form Fields'),
    modelProperty: 'id',
    prefix: 'FormProperty',
    createExtensionElement: function(element, extensionElements, value) {
      var bo = getBusinessObject(element), commands = [];

      if (!extensionElements) {
        extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
        commands.push(cmdHelper.updateProperties(element, { extensionElements: extensionElements }));
      }
     /* var formData = formHelper.getFormData(element);

      if (!formData) {
        formData = elementHelper.createElement('activiti:FormData', { fields: [] }, extensionElements, bpmnFactory);
        commands.push(cmdHelper.addAndRemoveElementsFromList(
          element,
          extensionElements,
          'values',
          'extensionElements',
          [formData],
          []
        ));
      }*/
      /**activiti 是向 extensionElements 下追加元素,而不是 formData 下,*/
      var field = elementHelper.createElement('activiti:FormProperty', { id: value }, extensionElements, bpmnFactory);
      if (typeof extensionElements.values !== 'undefined') {
        commands.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', [ field ]));
      } else {
        commands.push(cmdHelper.updateBusinessObject(element, extensionElements, {
            values: [ field ]
        }));
      }
      return commands;
    },
    removeExtensionElement: function(element, extensionElements, value, idx) {
      var fields = formHelper.getFormFields(element);
      var entry = fields[idx],
          commands = [];

      if (fields.length < 2) {
        commands.push(removeEntry(getBusinessObject(element), element, extensionElements));
      } else {
        commands.push(cmdHelper.removeElementsFromList(element, extensionElements, 'values', null, [entry]));
       /* if (entry.id === formData.get('businessKey')) {
          commands.push(cmdHelper.updateBusinessObject(element, extensionElements, { 'businessKey': undefined }));
        }*/
      }

      return commands;
    },
    getExtensionElements: function(element) {
      return formHelper.getFormFields(element);
    },
    hideExtensionElements: function(element, node) {
      return false;
    }
  });
  group.entries.push(formFieldsEntry);


  // [FormData] Form Field label
  group.entries.push(entryFactory.label({
    id: 'form-field-header',
    labelText: translate('Form Field'),
    showLabel: function(element, node) {
      return !!getSelectedFormField(element, node);
    }
  }));

  // [FormData] form field id text input field
  group.entries.push(entryFactory.validationAwareTextField({
    id: 'form-field-id',
    label: translate('ID'),
    modelProperty: 'id',

    getProperty: function(element, node) {
      var selectedFormField = getSelectedFormField(element, node) || {};

      return selectedFormField.id;
    },

    setProperty: function(element, properties, node) {
      var formField = getSelectedFormField(element, node);

      return cmdHelper.updateBusinessObject(element, formField, properties);
    },

    hidden: function(element, node) {
      return !getSelectedFormField(element, node);
    },

    validate: function(element, values, node) {

      var formField = getSelectedFormField(element, node);

      if (formField) {

        var idValue = values.id;

        if (!idValue || idValue.trim() === '') {
          return { id: 'Form field id must not be empty' };
        }

        var formFields = formHelper.getFormFields(element);

        var existingFormField = find(formFields, function(f) {
          return f !== formField && f.id === idValue;
        });

        if (existingFormField) {
          return { id: 'Form field id already used in form data.' };
        }
      }
    }
  }));

  // [FormData] form field type combo box
  group.entries.push(entryFactory.comboBox({
    id: 'form-field-type',
    label: translate('Type'),
    selectOptions: [
      { name: 'string', value: 'string' },
      { name: 'long', value: 'long' },
      { name: 'boolean', value: 'boolean' },
      { name: 'date', value: 'date' },
      { name: 'enum', value: 'enum' }
    ],
    modelProperty: 'type',
    emptyParameter: true,

    get: function(element, node) {
      var selectedFormField = getSelectedFormField(element, node);

      if (selectedFormField) {
        return { type: selectedFormField.type };
      } else {
        return {};
      }
    },
    set: function(element, values, node) {
      var selectedFormField = getSelectedFormField(element, node),
          commands = [];

      if (selectedFormField.type === 'enum' && values.type !== 'enum') {
        // delete activiti:value objects from formField.values when switching from type enum
        commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, { values: undefined }));
      }
      commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, values));

      return commands;
    },
    hidden: function(element, node) {
      return !getSelectedFormField(element, node);
    }
  }));

  // [FormData] form field label text input field
  group.entries.push(formFieldTextField({
    id: 'form-field-label',
    label: translate('Label'),
    modelProperty: 'label'
  }, getSelectedFormField));

  // [FormData] form field defaultValue text input field
  group.entries.push(formFieldTextField({
    id: 'form-field-defaultValue',
    label: translate('Default Value'),
    modelProperty: 'defaultValue'
  }, getSelectedFormField));


  // [FormData] form field enum values label
  group.entries.push(entryFactory.label({
    id: 'form-field-enum-values-header',
    labelText: translate('Values'),
    divider: true,
    showLabel: function(element, node) {
      var selectedFormField = getSelectedFormField(element, node);

      return selectedFormField && selectedFormField.type === 'enum';
    }
  }));

  // [FormData] form field enum values table
  group.entries.push(entryFactory.table({
    id: 'form-field-enum-values',
    labels: [ translate('Id'), translate('Name') ],
    modelProperties: [ 'id', 'name' ],
    addLabel:translate('Add Value'),
    show: function(element, node) {
      var selectedFormField = getSelectedFormField(element, node);

      return selectedFormField && selectedFormField.type === 'enum';
    },
    getElements: function(element, node) {
      var selectedFormField = getSelectedFormField(element, node);

      return formHelper.getEnumValues(selectedFormField);
    },
    addElement: function(element, node) {
      var selectedFormField = getSelectedFormField(element, node),
          id = generateValueId();

      var enumValue = elementHelper.createElement(
        'activiti:Value',
        { id: id, name: undefined },
        getBusinessObject(element),
        bpmnFactory
      );

      return cmdHelper.addElementsTolist(element, selectedFormField, 'values', [enumValue]);
    },
    removeElement: function(element, node, idx) {
      var selectedFormField = getSelectedFormField(element, node),
          enumValue = selectedFormField.values[idx];

      return cmdHelper.removeElementsFromList(element, selectedFormField, 'values', null, [enumValue]);
    },
    updateElement: function(element, value, node, idx) {
      var selectedFormField = getSelectedFormField(element, node),
          enumValue = selectedFormField.values[idx];

      value.name = value.name || undefined;
      return cmdHelper.updateBusinessObject(element, enumValue, value);
    },
    validate: function(element, value, node, idx) {

      var selectedFormField = getSelectedFormField(element, node),
          enumValue = selectedFormField.values[idx];

      if (enumValue) {
        // check if id is valid
        var validationError = utils.isIdValid(enumValue, value.id, translate);

        if (validationError) {
          return { id: validationError };
        }
      }
    }
  }));

  // [FormData] Validation label
  group.entries.push(entryFactory.label({
    id: 'form-field-validation-header',
    labelText: translate('Validation'),
    divider: true,
    showLabel: function(element, node) {
      return !!getSelectedFormField(element, node);
    }
  }));

  // [FormData] form field constraints table
  group.entries.push(entryFactory.table({
    id: 'constraints-list',
    modelProperties: [ 'name', 'config' ],
    labels: [ translate('Name'), translate('Config') ],
    addLabel: translate('Add Constraint'),
    getElements: function(element, node) {
      var formField = getSelectedFormField(element, node);

      return formHelper.getConstraints(formField);
    },
    addElement: function(element, node) {

      var commands = [],
          formField = getSelectedFormField(element, node),
          validation = formField.validation;

      if (!validation) {
        // create validation business object and add it to form data, if it doesn't exist
        validation = elementHelper.createElement('activiti:Validation', {}, getBusinessObject(element), bpmnFactory);

        commands.push(cmdHelper.updateBusinessObject(element, formField, { 'validation': validation }));
      }

      var newConstraint = elementHelper.createElement(
        'activiti:Constraint',
        { name: undefined, config: undefined },
        validation,
        bpmnFactory
      );

      commands.push(cmdHelper.addElementsTolist(element, validation, 'constraints', [ newConstraint ]));

      return commands;
    },
    updateElement: function(element, value, node, idx) {
      var formField = getSelectedFormField(element, node),
          constraint = formHelper.getConstraints(formField)[idx];

      value.name = value.name || undefined;
      value.config = value.config || undefined;

      return cmdHelper.updateBusinessObject(element, constraint, value);
    },
    removeElement: function(element, node, idx) {
      var commands = [],
          formField = getSelectedFormField(element, node),
          constraints = formHelper.getConstraints(formField),
          currentConstraint = constraints[idx];

      commands.push(cmdHelper.removeElementsFromList(
        element,
        formField.validation,
        'constraints',
        null,
        [ currentConstraint ]
      ));

      if (constraints.length === 1) {
        // remove activiti:validation if the last existing constraint has been removed
        commands.push(cmdHelper.updateBusinessObject(element, formField, { validation: undefined }));
      }

      return commands;
    },
    show: function(element, node) {
      return !!getSelectedFormField(element, node);
    }
  }));

  // [FormData] Properties label
  group.entries.push(entryFactory.label({
    id: 'form-field-properties-header',
    labelText: translate('Properties'),
    divider: true,
    showLabel: function(element, node) {
      return !!getSelectedFormField(element, node);
    }
  }));

  // [FormData] activiti:properties table
  group.entries.push(properties(element, bpmnFactory, {
    id: 'form-field-properties',
    modelProperties: [ 'id', 'value' ],
    labels: [ translate('Id'), translate('Value') ],
    getParent: function(element, node) {
      return getSelectedFormField(element, node);
    },
    show: function(element, node) {
      return !!getSelectedFormField(element, node);
    }
  }, translate));
};

},{"../../../Utils":576,"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"../../../helper/ElementHelper":591,"../../../helper/ExtensionElementsHelper":593,"../../../helper/FormHelper":594,"./implementation/ExtensionElements":643,"./implementation/Properties":655,"bpmn-js/lib/util/ModelUtil":141,"lodash/find":519,"lodash/forEach":522}],622:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var historyTimeToLive = require('./implementation/HistoryTimeToLive');

module.exports = function(group, element, bpmnFactory, translate) {
  var businessObject = getBusinessObject(element);

  if (is(element, 'activiti:Process') ||
      is(element, 'bpmn:Participant') && businessObject.get('processRef')) {

    group.entries = group.entries.concat(historyTimeToLive(element, bpmnFactory, {
      getBusinessObject: function(element) {
        var bo = getBusinessObject(element);

        if (!is(bo, 'bpmn:Participant')) {
          return bo;
        }

        return bo.get('processRef');
      }
    }, translate));

  }
};

},{"./implementation/HistoryTimeToLive":647,"bpmn-js/lib/util/ModelUtil":141}],623:[function(require,module,exports){
'use strict';

var inputOutputParameter = require('./implementation/InputOutputParameter');

var assign = require('lodash/assign');

module.exports = function(group, element, bpmnFactory, options, translate) {

  group.entries = group.entries.concat(inputOutputParameter(element, bpmnFactory, assign({}, options), translate));

};

},{"./implementation/InputOutputParameter":650,"lodash/assign":513}],624:[function(require,module,exports){
'use strict';

var inputOutput = require('./implementation/InputOutput');

module.exports = function(group, element, bpmnFactory, translate) {

  var inputOutputEntry = inputOutput(element, bpmnFactory, {}, translate);

  group.entries = group.entries.concat(inputOutputEntry.entries);

  return {
    getSelectedParameter: inputOutputEntry.getSelectedParameter
  };

};

},{"./implementation/InputOutput":649}],625:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var jobPriority = require('./implementation/JobPriority'),
    jobRetryTimeCycle = require('./implementation/JobRetryTimeCycle');

module.exports = function(group, element, bpmnFactory, translate) {
  var businessObject = getBusinessObject(element);

  if (is(element, 'activiti:JobPriorized') ||
      is(element, 'bpmn:Participant') && businessObject.get('processRef')) {

    group.entries = group.entries.concat(jobPriority(element, bpmnFactory, {
      getBusinessObject: function(element) {
        var bo = getBusinessObject(element);

        if (!is(bo, 'bpmn:Participant')) {
          return bo;
        }

        return bo.get('processRef');
      }
    }, translate));
  }

  if (is(element, 'activiti:AsyncCapable')) {
    group.entries = group.entries.concat(jobRetryTimeCycle(element, bpmnFactory, {
      getBusinessObject: getBusinessObject
    }, translate));
  }

};

},{"./implementation/JobPriority":651,"./implementation/JobRetryTimeCycle":652,"bpmn-js/lib/util/ModelUtil":141}],626:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../factory/EntryFactory');

var cmdHelper = require('../../../helper/CmdHelper'),
    ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'),

    scriptImplementation = require('./implementation/Script');


module.exports = function(group, element, bpmnFactory, options, translate) {

  var LISTENER_TYPE_LABEL = {
    class: translate('Java Class'),
    expression: translate('Expression'),
    delegateExpression: translate('Delegate Expression'),
    script: translate('Script')
  };

  options = options || {};

  var getSelectedListener = options.getSelectedListener;

  var classProp = 'class',
      expressionProp = 'expression',
      delegateExpressionProp = 'delegateExpression',
      scriptProp = 'script';

  var executionListenerEventTypeOptions = ImplementationTypeHelper.isSequenceFlow(element) ? [
    { name: translate('take'), value: 'take' }
  ] : [
    { name: translate('start'), value: 'start' },
    { name: translate('end'), value: 'end' }
  ];

  var taskListenerEventTypeOptions = [
    { name: translate('create'), value: 'create' },
    { name: translate('assignment'), value: 'assignment' },
    { name: translate('complete'), value: 'complete' },
    { name: translate('delete'), value: 'delete' }
  ];

  var isSelected = function(element, node) {
    return getSelectedListener(element, node);
  };

  group.entries.push(entryFactory.selectBox({
    id: 'listener-event-type',
    label: translate('Event Type'),
    modelProperty: 'eventType',
    emptyParameter: false,

    get: function(element, node) {


      var listener = getSelectedListener(element, node);

      var eventType = listener && listener.get('event');

      return {
        eventType: eventType
      };
    },

    set: function(element, values, node) {
      var eventType = values.eventType;

      return cmdHelper.updateBusinessObject(element, getSelectedListener(element, node), { event: eventType });
    },

    selectOptions: function(element, node) {
      var eventTypeOptions;

      var selectedListener = getSelectedListener(element, node);
      if (ImplementationTypeHelper.isTaskListener(selectedListener)) {
        eventTypeOptions = taskListenerEventTypeOptions;
      } else if (ImplementationTypeHelper.isExecutionListener(selectedListener)) {
        eventTypeOptions = executionListenerEventTypeOptions;
      }

      return eventTypeOptions;

    },

    hidden: function(element, node) {
      return !isSelected(element, node);
    }

  }));


  group.entries.push(entryFactory.selectBox({
    id: 'listener-type',
    label: translate('Listener Type'),
    selectOptions: [
      { value: classProp, name: translate('Java Class') },
      { value: expressionProp, name: translate('Expression') },
      { value: delegateExpressionProp, name: translate('Delegate Expression') },
      { value: scriptProp, name: translate('Script') }
    ],
    modelProperty: 'listenerType',
    emptyParameter: false,

    get: function(element, node) {
      var listener = getSelectedListener(element, node);
      return {
        listenerType: ImplementationTypeHelper.getImplementationType(listener)
      };
    },

    set: function(element, values, node) {
      var listener = getSelectedListener(element, node),
          listenerType = values.listenerType || undefined,
          update = {};

      update[classProp] = listenerType === classProp ? '' : undefined;
      update[expressionProp] = listenerType === expressionProp ? '' : undefined;
      update[delegateExpressionProp] = listenerType === delegateExpressionProp ? '' : undefined;
      update[scriptProp] = listenerType === scriptProp ? bpmnFactory.create('activiti:Script') : undefined;

      return cmdHelper.updateBusinessObject(element, listener, update);
    },

    hidden: function(element, node) {
      return !isSelected(element, node);
    }

  }));


  group.entries.push(entryFactory.textField({
    id: 'listener-value',
    dataValueLabel: 'listenerValueLabel',
    modelProperty: 'listenerValue',

    get: function(element, node) {
      var value = {},
          listener = getSelectedListener(element, node),
          listenerType = ImplementationTypeHelper.getImplementationType(listener);

      value.listenerValueLabel = LISTENER_TYPE_LABEL[listenerType] || '';
      value.listenerValue = (listener && listener.get(listenerType)) || undefined;

      return value;
    },

    set: function(element, values, node) {
      var update = {},
          listener = getSelectedListener(element, node),
          listenerType = ImplementationTypeHelper.getImplementationType(listener);

      update[listenerType] = values.listenerValue || '';

      return cmdHelper.updateBusinessObject(element, listener, update);
    },

    hidden: function(element, node) {
      var listener = getSelectedListener(element, node);
      return !listener || listener.script;
    },

    validate: function(element, values) {
      var value = values.listenerValue,
          validate = {};

      if (!value) {
        validate.listenerValue = translate('Must provide a value');
      }

      return validate;
    }

  }));

  var script = scriptImplementation('scriptFormat', 'value', true, translate);

  group.entries.push({
    id: 'listener-script-value',
    html: '<div data-show="isScript">' +
            script.template +
          '</div>',

    get: function(element, node) {
      var listener = getSelectedListener(element, node);
      return listener && listener.script ? script.get(element, listener.script) : {};
    },

    set: function(element, values, node) {
      var listener = getSelectedListener(element, node);
      var update = script.set(element, values, listener);
      return cmdHelper.updateBusinessObject(element, listener.script, update);
    },

    validate: function(element, values, node) {
      var listener = getSelectedListener(element, node);
      return listener && listener.script ? script.validate(element, values) : {};
    },

    isScript: function(element, node) {
      var listener = getSelectedListener(element, node);
      return listener && listener.script;
    },

    script: script

  });

};

},{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"../../../helper/ImplementationTypeHelper":595,"./implementation/Script":657}],627:[function(require,module,exports){
'use strict';

var assign = require('lodash/assign');

var fieldInjection = require('./implementation/FieldInjection');

module.exports = function(group, element, bpmnFactory, options, translate) {

  options = assign({
    idPrefix: 'listener-',
    insideListener: true
  }, options);

  var fieldInjectionEntry = fieldInjection(element, bpmnFactory, translate, options);

  if (fieldInjectionEntry && fieldInjectionEntry.length > 0) {
    group.entries = group.entries.concat(fieldInjectionEntry);
  }

};

},{"./implementation/FieldInjection":646,"lodash/assign":513}],628:[function(require,module,exports){
'use strict';

var listener = require('./implementation/Listener');

module.exports = function(group, element, bpmnFactory, translate) {

  var listenerEntry = listener(element, bpmnFactory, {}, translate);

  group.entries = group.entries.concat(listenerEntry.entries);

  return {
    getSelectedListener: listenerEntry.getSelectedListener
  };

};

},{"./implementation/Listener":653}],629:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    is = require('bpmn-js/lib/util/ModelUtil').is;

var multiInstanceLoopCharacteristics = require('./implementation/MultiInstanceLoopCharacteristics');

var jobRetryTimeCycle = require('./implementation/JobRetryTimeCycle'),
    asyncContinuation = require('./implementation/AsyncContinuation');


function getLoopCharacteristics(element) {
  var bo = getBusinessObject(element);
  return bo.loopCharacteristics;
}


function ensureMultiInstanceSupported(element) {
  var loopCharacteristics = getLoopCharacteristics(element);
  return !!loopCharacteristics && is(loopCharacteristics, 'activiti:Collectable');
}

module.exports = function(group, element, bpmnFactory, translate) {

  if (!ensureMultiInstanceSupported(element)) {
    return;
  }

  // multi instance properties
  group.entries = group.entries.concat(multiInstanceLoopCharacteristics(element, bpmnFactory, translate));

  // async continuation ///////////////////////////////////////////////////////
  group.entries = group.entries.concat(asyncContinuation(element, bpmnFactory, {
    getBusinessObject: getLoopCharacteristics,
    idPrefix: 'multiInstance-',
    labelPrefix: translate('Multi Instance ')
  }, translate));


  // retry time cycle //////////////////////////////////////////////////////////
  group.entries = group.entries.concat(jobRetryTimeCycle(element, bpmnFactory, {
    getBusinessObject: getLoopCharacteristics,
    idPrefix: 'multiInstance-',
    labelPrefix: translate('Multi Instance ')
  }, translate));
};

},{"./implementation/AsyncContinuation":638,"./implementation/JobRetryTimeCycle":652,"./implementation/MultiInstanceLoopCharacteristics":654,"bpmn-js/lib/util/ModelUtil":141}],630:[function(require,module,exports){
'use strict';

var properties = require('./implementation/Properties'),
    elementHelper = require('../../../helper/ElementHelper'),
    cmdHelper = require('../../../helper/CmdHelper');


module.exports = function(group, element, bpmnFactory, translate) {

  var propertiesEntry = properties(element, bpmnFactory, {
    id: 'properties',
    modelProperties: [ 'name', 'value' ],
    labels: [ translate('Name'), translate('Value') ],

    getParent: function(element, node, bo) {
      return bo.extensionElements;
    },

    createParent: function(element, bo) {
      var parent = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
      var cmd = cmdHelper.updateBusinessObject(element, bo, { extensionElements: parent });
      return {
        cmd: cmd,
        parent: parent
      };
    }
  }, translate);

  if (propertiesEntry) {
    group.entries.push(propertiesEntry);
  }

};

},{"../../../helper/CmdHelper":590,"../../../helper/ElementHelper":591,"./implementation/Properties":655}],631:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    is = require('bpmn-js/lib/util/ModelUtil').is,
    entryFactory = require('../../../factory/EntryFactory'),
    cmdHelper = require('../../../helper/CmdHelper'),
    scriptImplementation = require('./implementation/Script');


module.exports = function(group, element, bpmnFactory, translate) {
  var bo;

  if (is(element, 'bpmn:ScriptTask')) {
    bo = getBusinessObject(element);
  }

  if (!bo) {
    return;
  }

  var script = scriptImplementation('scriptFormat', 'script', false, translate);
  group.entries.push({
    id: 'script-implementation',
    label: translate('Script'),
    html: script.template,

    get: function(element) {
      return script.get(element, bo);
    },

    set: function(element, values, containerElement) {
      var properties = script.set(element, values, containerElement);

      return cmdHelper.updateProperties(element, properties);
    },

    validate: function(element, values) {
      return script.validate(element, values);
    },

    script : script,

    cssClasses: ['bpp-textfield']

  });

  group.entries.push(entryFactory.textField({
    id : 'scriptResultVariable',
    label : translate('Result Variable'),
    modelProperty : 'scriptResultVariable',

    get: function(element, propertyName) {
      var boResultVariable = bo.get('activiti:resultVariable');

      return { scriptResultVariable : boResultVariable };
    },

    set: function(element, values, containerElement) {
      return cmdHelper.updateProperties(element, {
        'activiti:resultVariable': values.scriptResultVariable.length
          ? values.scriptResultVariable
          : undefined
      });
    }

  }));

};

},{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"./implementation/Script":657,"bpmn-js/lib/util/ModelUtil":141}],632:[function(require,module,exports){
'use strict';

var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'),
    InputOutputHelper = require('../../../helper/InputOutputHelper');

var utils = require('../../../Utils'),
    escapeHTML = utils.escapeHTML,
    triggerClickEvent = utils.triggerClickEvent;

var implementationType = require('./implementation/ImplementationType'),
    delegate = require('./implementation/Delegate'),
    external = require('./implementation/External'),
    callable = require('./implementation/Callable'),
    resultVariable = require('./implementation/ResultVariable');

var entryFactory = require('../../../factory/EntryFactory');

var domQuery = require('min-dom').query,
    domClosest = require('min-dom').closest,
    domClasses = require('min-dom').classes;

function getImplementationType(element) {
  return ImplementationTypeHelper.getImplementationType(element);
}

function getBusinessObject(element) {
  return ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element);
}

function isDmnCapable(element) {
  return ImplementationTypeHelper.isDmnCapable(element);
}

function isExternalCapable(element) {
  return ImplementationTypeHelper.isExternalCapable(element);
}

function isServiceTaskLike(element) {
  return ImplementationTypeHelper.isServiceTaskLike(element);
}

module.exports = function(group, element, bpmnFactory, translate) {

  if (!isServiceTaskLike(getBusinessObject(element))) {
    return;
  }

  var hasDmnSupport = isDmnCapable(element);
  var hasExternalSupport = isExternalCapable(getBusinessObject(element));

  // implementation type ////////////////////////////////////

  group.entries = group.entries.concat(implementationType(element, bpmnFactory, {
    getBusinessObject: getBusinessObject,
    getImplementationType: getImplementationType,
    hasDmnSupport: hasDmnSupport,
    hasExternalSupport: hasExternalSupport,
    hasServiceTaskLikeSupport: true
  }, translate));


  // delegate (class, expression, delegateExpression) //////////

  group.entries = group.entries.concat(delegate(element, bpmnFactory, {
    getBusinessObject: getBusinessObject,
    getImplementationType: getImplementationType
  }, translate));


  // result variable /////////////////////////////////////////

  group.entries = group.entries.concat(resultVariable(element, bpmnFactory, {
    getBusinessObject: getBusinessObject,
    getImplementationType: getImplementationType,
    hideResultVariable: function(element, node) {
      return getImplementationType(element) !== 'expression';
    }
  }, translate));

  // external //////////////////////////////////////////////////

  if (hasExternalSupport) {
    group.entries = group.entries.concat(external(element, bpmnFactory, {
      getBusinessObject: getBusinessObject,
      getImplementationType: getImplementationType
    }, translate));
  }


  // dmn ////////////////////////////////////////////////////////

  if (hasDmnSupport) {
    group.entries = group.entries.concat(callable(element, bpmnFactory, {
      getCallableType: getImplementationType
    }, translate));
  }


  // connector ////////////////////////////////////////////////

  var isConnector = function(element) {
    return getImplementationType(element) === 'connector';
  };

  group.entries.push(entryFactory.link({
    id: 'configureConnectorLink',
    label: translate('Configure Connector'),
    handleClick: function(element, node, event) {

      var connectorTabEl = getTabNode(node, 'connector');

      if (connectorTabEl) {
        triggerClickEvent(connectorTabEl);
      }

      // suppress actual link click
      return false;
    },
    showLink: function(element, node) {
      var link = domQuery('a', node);
      link.textContent = '';

      domClasses(link).remove('bpp-error-message');

      if (isConnector(element)) {
        var connectorId = InputOutputHelper.getConnector(element).get('connectorId');
        if (connectorId) {
          link.textContent = translate('Configure Connector');
        } else {
          link.innerHTML = '<span class="bpp-icon-warning"></span> ' + escapeHTML(translate('Must configure Connector'));
          domClasses(link).add('bpp-error-message');
        }

        return true;
      }

      return false;
    }
  }));

};



// helpers ///////////////////////////

function getTabNode(el, id) {
  var containerEl = domClosest(el, '.bpp-properties-panel');

  return domQuery('a[data-tab-target="' + id + '"]', containerEl);
}
},{"../../../Utils":576,"../../../factory/EntryFactory":579,"../../../helper/ImplementationTypeHelper":595,"../../../helper/InputOutputHelper":596,"./implementation/Callable":639,"./implementation/Delegate":641,"./implementation/External":644,"./implementation/ImplementationType":648,"./implementation/ResultVariable":656,"min-dom":556}],633:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../factory/EntryFactory'),
    is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;


module.exports = function(group, element, translate) {

  var bo = getBusinessObject(element);

  if (!bo) {
    return;
  }

  if (is(element, 'activiti:Initiator') && !is(element.parent, 'bpmn:SubProcess')) {
    group.entries.push(entryFactory.textField({
      id: 'initiator',
      label: translate('Initiator'),
      modelProperty: 'initiator'
    }));
  }
};

},{"../../../factory/EntryFactory":579,"bpmn-js/lib/util/ModelUtil":141}],634:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var tasklist = require('./implementation/Tasklist');

module.exports = function(group, element, bpmnFactory, translate) {
  var businessObject = getBusinessObject(element);

  if (is(element, 'activiti:Process') ||
      is(element, 'bpmn:Participant') && businessObject.get('processRef')) {

    group.entries = group.entries.concat(tasklist(element, bpmnFactory, {
      getBusinessObject: function(element) {
        var bo = getBusinessObject(element);

        if (!is(bo, 'bpmn:Participant')) {
          return bo;
        }

        return bo.get('processRef');
      }
    }, translate));

  }
};

},{"./implementation/Tasklist":658,"bpmn-js/lib/util/ModelUtil":141}],635:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    entryFactory = require('../../../factory/EntryFactory');


module.exports = function(group, element, translate) {
  if (is(element, 'activiti:Assignable')) {

    // Assignee
    group.entries.push(entryFactory.textField({
      id : 'assignee',
      label : translate('Assignee'),
      modelProperty : 'assignee'
    }));

    // Candidate Users
    group.entries.push(entryFactory.textField({
      id : 'candidateUsers',
      label : translate('Candidate Users'),
      modelProperty : 'candidateUsers'
    }));

    // Candidate Groups
    group.entries.push(entryFactory.textField({
      id : 'candidateGroups',
      label : translate('Candidate Groups'),
      modelProperty : 'candidateGroups'
    }));

    // Due Date
    group.entries.push(entryFactory.textField({
      id : 'dueDate',
      description : translate('The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)'),
      label : translate('Due Date'),
      modelProperty : 'dueDate'
    }));

    // FollowUp Date
    group.entries.push(entryFactory.textField({
      id : 'followUpDate',
      description : translate('The follow up date as an EL expression (e.g. ${someDate} or an ' +
                    'ISO date (e.g. 2015-06-26T09:54:00)'),
      label : translate('Follow Up Date'),
      modelProperty : 'followUpDate'
    }));

    // priority
    group.entries.push(entryFactory.textField({
      id : 'priority',
      label : translate('Priority'),
      modelProperty : 'priority'
    }));
  }
};

},{"../../../factory/EntryFactory":579,"bpmn-js/lib/util/ModelUtil":141}],636:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var filter = require('lodash/filter');

var extensionElementsHelper = require('../../../helper/ExtensionElementsHelper'),
    cmdHelper = require('../../../helper/CmdHelper'),
    elementHelper = require('../../../helper/ElementHelper'),
    eventDefinitionHelper = require('../../../helper/EventDefinitionHelper');

var extensionElementsEntry = require('./implementation/ExtensionElements');

var entryFactory = require('../../../factory/EntryFactory');

/**
  * return depend on parameter 'type' activiti:in or activiti:out extension elements
  */
function getActivitiInOutMappings(element, type) {
  var bo = getBusinessObject(element);

  var signalEventDefinition = eventDefinitionHelper.getSignalEventDefinition(bo);

  return extensionElementsHelper.getExtensionElements(signalEventDefinition || bo, type) || [];
}

/**
  * return depend on parameter 'type' activiti:in or activiti:out extension elements
  * with source or sourceExpression attribute
  */
function getVariableMappings(element, type) {
  var activitiMappings = getActivitiInOutMappings(element, type);

  return filter(activitiMappings, function(mapping) {
    return !mapping.businessKey;
  });
}

function getInOutType(mapping) {
  var inOutType = 'source';

  if (mapping.variables === 'all') {
    inOutType = 'variables';
  }
  else if (typeof mapping.source !== 'undefined') {
    inOutType = 'source';
  }
  else if (typeof mapping.sourceExpression !== 'undefined') {
    inOutType = 'sourceExpression';
  }

  return inOutType;
}

var ACTIVITI_IN_EXTENSION_ELEMENT = 'activiti:In',
    ACTIVITI_OUT_EXTENSION_ELEMENT = 'activiti:Out';

var WHITESPACE_REGEX = /\s/;


module.exports = function(group, element, bpmnFactory, translate) {

  var inOutTypeOptions = [
    {
      name: translate('Source'),
      value: 'source'
    },
    {
      name: translate('Source Expression'),
      value: 'sourceExpression'
    },
    {
      name: translate('All'),
      value: 'variables'
    }
  ];

  var signalEventDefinition = eventDefinitionHelper.getSignalEventDefinition(element);

  if (!is(element, 'activiti:CallActivity') && !signalEventDefinition) {
    return;
  }

  if (signalEventDefinition && !(isAny(element, [
    'bpmn:IntermediateThrowEvent',
    'bpmn:EndEvent'
  ]))) {
    return;
  }

  var isSelected = function(element, node) {
    return !!getSelected(element, node);
  };

  var getSelected = function(element, node) {
    var parentNode = node.parentNode;
    var selection = inEntry.getSelected(element, parentNode);

    var parameter = getVariableMappings(element, ACTIVITI_IN_EXTENSION_ELEMENT)[selection.idx];

    if (!parameter && outEntry) {
      selection = outEntry.getSelected(element, parentNode);
      parameter = getVariableMappings(element, ACTIVITI_OUT_EXTENSION_ELEMENT)[selection.idx];
    }

    return parameter;
  };

  var setOptionLabelValue = function(type) {
    return function(element, node, option, property, value, idx) {
      var variableMappings = getVariableMappings(element, type);
      var mappingValue = variableMappings[idx];
      var label = (mappingValue.target || '<undefined>') + ' := ';
      var mappingType = getInOutType(mappingValue);

      if (mappingType === 'variables') {
        label = 'all';
      }
      else if (mappingType === 'source') {
        label = label + (mappingValue.source || '<empty>');
      }
      else if (mappingType === 'sourceExpression') {
        label = label + (mappingValue.sourceExpression || '<empty>');
      } else {
        label = label + '<empty>';
      }

      option.text = label;
    };
  };

  var newElement = function(type) {
    return function(element, extensionElements, value) {
      var newElem = elementHelper.createElement(type, { source: '' }, extensionElements, bpmnFactory);

      return cmdHelper.addElementsTolist(element, extensionElements, 'values', [ newElem ]);
    };
  };

  var removeElement = function(type) {
    return function(element, extensionElements, value, idx) {
      var variablesMappings= getVariableMappings(element, type);
      var mapping = variablesMappings[idx];

      if (mapping) {
        return extensionElementsHelper
          .removeEntry(signalEventDefinition || getBusinessObject(element), element, mapping);
      }
    };
  };

  // in mapping for source and sourceExpression ///////////////////////////////////////////////////////////////

  var inEntry = extensionElementsEntry(element, bpmnFactory, {
    id: 'variableMapping-in',
    label: translate('In Mapping'),
    modelProperty: 'source',
    prefix: 'In',
    idGeneration: false,
    resizable: true,
    businessObject: signalEventDefinition || getBusinessObject(element),

    createExtensionElement: newElement(ACTIVITI_IN_EXTENSION_ELEMENT),
    removeExtensionElement: removeElement(ACTIVITI_IN_EXTENSION_ELEMENT),

    getExtensionElements: function(element) {
      return getVariableMappings(element, ACTIVITI_IN_EXTENSION_ELEMENT);
    },

    onSelectionChange: function(element, node, event, scope) {
      outEntry && outEntry.deselect(element, node.parentNode);
    },

    setOptionLabelValue: setOptionLabelValue(ACTIVITI_IN_EXTENSION_ELEMENT)
  });
  group.entries.push(inEntry);

  // out mapping for source and sourceExpression ///////////////////////////////////////////////////////

  if (!signalEventDefinition) {
    var outEntry = extensionElementsEntry(element, bpmnFactory, {
      id: 'variableMapping-out',
      label: translate('Out Mapping'),
      modelProperty: 'source',
      prefix: 'Out',
      idGeneration: false,
      resizable: true,

      createExtensionElement: newElement(ACTIVITI_OUT_EXTENSION_ELEMENT),
      removeExtensionElement: removeElement(ACTIVITI_OUT_EXTENSION_ELEMENT),

      getExtensionElements: function(element) {
        return getVariableMappings(element, ACTIVITI_OUT_EXTENSION_ELEMENT);
      },

      onSelectionChange: function(element, node, event, scope) {
        inEntry.deselect(element, node.parentNode);
      },

      setOptionLabelValue: setOptionLabelValue(ACTIVITI_OUT_EXTENSION_ELEMENT)
    });
    group.entries.push(outEntry);
  }

  // label for selected mapping ///////////////////////////////////////////////////////

  group.entries.push(entryFactory.label({
    id: 'variableMapping-typeLabel',
    get: function(element, node) {
      var mapping = getSelected(element, node);

      var value = '';
      if (is(mapping, ACTIVITI_IN_EXTENSION_ELEMENT)) {
        value = translate('In Mapping');
      }
      else if (is(mapping, ACTIVITI_OUT_EXTENSION_ELEMENT)) {
        value = translate('Out Mapping');
      }

      return {
        label: value
      };
    },

    showLabel: function(element, node) {
      return isSelected(element, node);
    }
  }));


  group.entries.push(entryFactory.selectBox({
    id: 'variableMapping-inOutType',
    label: translate('Type'),
    selectOptions: inOutTypeOptions,
    modelProperty: 'inOutType',
    get: function(element, node) {
      var mapping = getSelected(element, node) || {};
      return {
        inOutType: getInOutType(mapping)
      };
    },
    set: function(element, values, node) {
      var inOutType = values.inOutType;

      var props = {
        'source' : undefined,
        'sourceExpression' : undefined,
        'variables' : undefined
      };

      if (inOutType === 'source') {
        props.source = '';
      }
      else if (inOutType === 'sourceExpression') {
        props.sourceExpression = '';
      }
      else if (inOutType === 'variables') {
        props.variables = 'all';
        props.target = undefined;
      }

      var mapping = getSelected(element, node);
      return cmdHelper.updateBusinessObject(element, mapping, props);
    },
    hidden: function(element, node) {
      return !isSelected(element, node);
    }

  }));


  group.entries.push(entryFactory.textField({
    id: 'variableMapping-source',
    dataValueLabel: 'sourceLabel',
    modelProperty: 'source',
    get: function(element, node) {
      var mapping = getSelected(element, node) || {};

      var label = '';
      var inOutType = getInOutType(mapping);
      if (inOutType === 'source') {
        label = translate('Source');
      }
      else if (inOutType === 'sourceExpression') {
        label = translate('Source Expression');
      }

      return {
        source: mapping[inOutType],
        sourceLabel: label
      };
    },
    set: function(element, values, node) {
      values.source = values.source || undefined;

      var mapping = getSelected(element, node);
      var inOutType = getInOutType(mapping);

      var props = {};
      props[inOutType] = values.source || '';

      return cmdHelper.updateBusinessObject(element, mapping, props);
    },
    // one of both (source or sourceExpression) must have a value to make
    // the configuration easier and more understandable
    // it is not engine conform
    validate: function(element, values, node) {
      var mapping = getSelected(element, node);

      var validation = {};
      if (mapping) {
        if (!values.source) {
          validation.source =
          validation.source = values.sourceLabel ?
            translate('Mapping must have a {value}', { value: values.sourceLabel.toLowerCase() }) :
            translate('Mapping must have a value');
        }

        var inOutType = getInOutType(mapping);

        if (WHITESPACE_REGEX.test(values.source) && inOutType !== 'sourceExpression') {
          validation.source = translate('{label} must not contain whitespace', { label: values.sourceLabel });
        }
      }

      return validation;
    },
    hidden: function(element, node) {
      var selectedMapping = getSelected(element, node);
      return !selectedMapping || (selectedMapping && selectedMapping.variables);
    }
  }));


  group.entries.push(entryFactory.textField({
    id: 'variableMapping-target',
    label: translate('Target'),
    modelProperty: 'target',
    get: function(element, node) {
      return {
        target: (getSelected(element, node) || {}).target
      };
    },
    set: function(element, values, node) {
      values.target = values.target || undefined;
      var mapping = getSelected(element, node);
      return cmdHelper.updateBusinessObject(element, mapping, values);
    },
    validate: function(element, values, node) {
      var mapping = getSelected(element, node);

      var validation = {};
      if (mapping) {
        var mappingType = getInOutType(mapping);

        if (!values.target && mappingType !== 'variables') {
          validation.target = translate('Mapping must have a target');
        }

        if (values.target
          && WHITESPACE_REGEX.test(values.target)
          && mappingType !== 'variables') {
          validation.target = translate('Target must not contain whitespace');
        }
      }

      return validation;
    },
    hidden: function(element, node) {
      var selectedMapping = getSelected(element, node);
      return !selectedMapping || (selectedMapping && selectedMapping.variables);
    }
  }));


  group.entries.push(entryFactory.checkbox({
    id: 'variableMapping-local',
    label: translate('Local'),
    modelProperty: 'local',
    get: function(element, node) {
      return {
        local: (getSelected(element, node) || {}).local
      };
    },
    set: function(element, values, node) {
      values.local = values.local || false;
      var mapping = getSelected(element, node);
      return cmdHelper.updateBusinessObject(element, mapping, values);
    },
    hidden: function(element, node) {
      return !isSelected(element, node);
    }
  }));

};

},{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"../../../helper/ElementHelper":591,"../../../helper/EventDefinitionHelper":592,"../../../helper/ExtensionElementsHelper":593,"./implementation/ExtensionElements":643,"bpmn-js/lib/features/modeling/util/ModelingUtil":112,"bpmn-js/lib/util/ModelUtil":141,"lodash/filter":518}],637:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../factory/EntryFactory'),
    cmdHelper = require('../../../helper/CmdHelper'),
    is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

module.exports = function(group, element, translate) {

  var bo = getBusinessObject(element);

  if (!bo) {
    return;
  }

  if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && bo.get('processRef')) {
    var versionTagEntry = entryFactory.textField({
      id: 'versionTag',
      label: translate('Version Tag'),
      modelProperty: 'versionTag'
    });

    // in participants we have to change the default behavior of set and get
    if (is(element, 'bpmn:Participant')) {
      versionTagEntry.get = function(element) {
        var processBo = bo.get('processRef');

        return {
          versionTag: processBo.get('activiti:versionTag')
        };
      };

      versionTagEntry.set = function(element, values) {
        var processBo = bo.get('processRef');

        return cmdHelper.updateBusinessObject(element, processBo, {
          'activiti:versionTag': values.versionTag || undefined
        });
      };
    }

    group.entries.push(versionTagEntry);

  }
};

},{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141}],638:[function(require,module,exports){
'use strict';

var assign = require('lodash/assign');

var entryFactory = require('../../../../factory/EntryFactory');

var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper'),
    eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'),
    cmdHelper = require('../../../../helper/CmdHelper');

function isAsyncBefore(bo) {
  return asyncCapableHelper.isAsyncBefore(bo);
}

function isAsyncAfter(bo) {
  return asyncCapableHelper.isAsyncAfter(bo);
}

function isExclusive(bo) {
  return asyncCapableHelper.isExclusive(bo);
}

function removeFailedJobRetryTimeCycle(bo, element) {
  return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element);
}

function canRemoveFailedJobRetryTimeCycle(element) {
  return !eventDefinitionHelper.getTimerEventDefinition(element);
}

module.exports = function(element, bpmnFactory, options, translate) {

  var getBusinessObject = options.getBusinessObject;

  var idPrefix = options.idPrefix || '',
      labelPrefix = options.labelPrefix || '';


  var asyncBeforeEntry = entryFactory.checkbox({
    id: idPrefix + 'asyncBefore',
    label: labelPrefix + translate('Asynchronous Before'),
    modelProperty: 'asyncBefore',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      return {
        asyncBefore: isAsyncBefore(bo)
      };
    },

    set: function(element, values) {
      var bo = getBusinessObject(element);
      var asyncBefore = !!values.asyncBefore;

      var props = {
        'activiti:asyncBefore': asyncBefore,
        'activiti:async': false
      };

      var commands = [];
      if (!isAsyncAfter(bo) && !asyncBefore) {
        props = assign({ 'activiti:exclusive' : true }, props);
        if (canRemoveFailedJobRetryTimeCycle(element)) {
          commands.push(removeFailedJobRetryTimeCycle(bo, element));
        }
      }

      commands.push(cmdHelper.updateBusinessObject(element, bo, props));
      return commands;
    }
  });


  var asyncAfterEntry = entryFactory.checkbox({
    id: idPrefix + 'asyncAfter',
    label: labelPrefix + translate('Asynchronous After'),
    modelProperty: 'asyncAfter',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      return {
        asyncAfter: isAsyncAfter(bo)
      };
    },

    set: function(element, values) {
      var bo = getBusinessObject(element);
      var asyncAfter = !!values.asyncAfter;

      var props = {
        'activiti:asyncAfter': asyncAfter
      };

      var commands = [];
      if (!isAsyncBefore(bo) && !asyncAfter) {
        props = assign({ 'activiti:exclusive' : true }, props);
        if (canRemoveFailedJobRetryTimeCycle(element)) {
          commands.push(removeFailedJobRetryTimeCycle(bo, element));
        }
      }

      commands.push(cmdHelper.updateBusinessObject(element, bo, props));
      return commands;
    }
  });


  var exclusiveEntry = entryFactory.checkbox({
    id: idPrefix + 'exclusive',
    label: labelPrefix + translate('Exclusive'),
    modelProperty: 'exclusive',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      return { exclusive: isExclusive(bo) };
    },

    set: function(element, values) {
      var bo = getBusinessObject(element);
      return cmdHelper.updateBusinessObject(element, bo, { 'activiti:exclusive': !!values.exclusive });
    },

    hidden: function(element) {
      var bo = getBusinessObject(element);
      return bo && !isAsyncAfter(bo) && !isAsyncBefore(bo);
    }
  });

  return [ asyncBeforeEntry, asyncAfterEntry, exclusiveEntry ];
};

},{"../../../../factory/EntryFactory":579,"../../../../helper/AsyncCapableHelper":588,"../../../../helper/CmdHelper":590,"../../../../helper/EventDefinitionHelper":592,"lodash/assign":513}],639:[function(require,module,exports){
'use strict';

var cmdHelper = require('../../../../helper/CmdHelper'),
    entryFactory = require('../../../../factory/EntryFactory'),
    elementHelper = require('../../../../helper/ElementHelper'),
    extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper');


var resultVariable = require('./ResultVariable');

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
var is = require('bpmn-js/lib/util/ModelUtil').is;

var forEach = require('lodash/forEach');

var attributeInfo = {
  bpmn: {
    element: 'calledElement',
    binding: 'activiti:calledElementBinding',
    version: 'activiti:calledElementVersion',
    versionTag: 'activiti:calledElementVersionTag',
    tenantId: 'activiti:calledElementTenantId'
  },

  cmmn: {
    element: 'activiti:caseRef',
    binding: 'activiti:caseBinding',
    version: 'activiti:caseVersion',
    tenantId: 'activiti:caseTenantId'
  },

  dmn: {
    element: 'activiti:decisionRef',
    binding: 'activiti:decisionRefBinding',
    version: 'activiti:decisionRefVersion',
    versionTag: 'activiti:decisionRefVersionTag',
    tenantId: 'activiti:decisionRefTenantId'
  }
};

var mapDecisionResultOptions = [
  {
    name: 'singleEntry (TypedValue)',
    value: 'singleEntry'
  },
  {
    name:'singleResult (Map<String, Object>)',
    value:'singleResult'
  },
  {
    name:'collectEntries (List<Object>)',
    value:'collectEntries'
  },
  {
    name:'resultList (List<Map<String, Object>>)',
    value:'resultList'
  }
];

var delegateVariableMappingOptions = [
  {
    name: 'variableMappingClass',
    value: 'variableMappingClass'
  },
  {
    name: 'variableMappingDelegateExpression',
    value: 'variableMappingDelegateExpression'
  }
];

function getActivitiInWithBusinessKey(element) {
  var activitiIn = [],
      bo = getBusinessObject(element);

  var activitiInParams = extensionElementsHelper.getExtensionElements(bo, 'activiti:In');
  if (activitiInParams) {
    forEach(activitiInParams, function(param) {
      if (param.businessKey !== undefined) {
        activitiIn.push(param);
      }
    });
  }
  return activitiIn;
}

function setBusinessKey(element, text, bpmnFactory) {
  var commands = [];

  var activitiInWithBusinessKey = getActivitiInWithBusinessKey(element);

  if (activitiInWithBusinessKey.length) {
    commands.push(cmdHelper.updateBusinessObject(element, activitiInWithBusinessKey[0], {
      businessKey: text
    }));
  } else {
    var bo = getBusinessObject(element),
        extensionElements = bo.extensionElements;

    if (!extensionElements) {
      extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
      commands.push(cmdHelper.updateProperties(element, { extensionElements: extensionElements }));
    }

    var activitiIn = elementHelper.createElement(
      'activiti:In',
      { 'businessKey': text },
      extensionElements,
      bpmnFactory
    );

    commands.push(cmdHelper.addAndRemoveElementsFromList(
      element,
      extensionElements,
      'values',
      'extensionElements',
      [ activitiIn ],[]
    ));
  }

  return commands;
}

function deleteBusinessKey(element) {
  var activitiInExtensions = getActivitiInWithBusinessKey(element);
  var commands = [];
  forEach(activitiInExtensions, function(elem) {
    commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, elem));
  });
  return commands;
}

function isSupportedCallableType(type) {
  return [ 'bpmn', 'cmmn', 'dmn' ].indexOf(type) !== -1;
}

module.exports = function(element, bpmnFactory, options, translate) {

  var bindingOptions = [
    {
      name: translate('latest'),
      value: 'latest'
    },
    {
      name: translate('deployment'),
      value: 'deployment'
    },
    {
      name: translate('version'),
      value: 'version'
    },
    {
      name: translate('versionTag'),
      value: 'versionTag'
    }
  ];

  var getCallableType = options.getCallableType;

  var entries = [];

  function getAttribute(element, prop) {
    var type = getCallableType(element);
    return (attributeInfo[type] || {})[prop];
  }

  function getCallActivityBindingValue(element) {
    var type = getCallableType(element);
    var bo = getBusinessObject(element);
    var attr = (attributeInfo[type] || {}).binding;
    return bo.get(attr);
  }

  function getDelegateVariableMappingType(element) {
    var bo = getBusinessObject(element);

    var boVariableMappingClass = bo.get('activiti:variableMappingClass'),
        boVariableMappingDelegateExpression = bo.get('activiti:variableMappingDelegateExpression');

    var delegateVariableMappingType = '';
    if (typeof boVariableMappingClass !== 'undefined') {
      delegateVariableMappingType = 'variableMappingClass';
    } else

    if (typeof boVariableMappingDelegateExpression !== 'undefined') {
      delegateVariableMappingType = 'variableMappingDelegateExpression';
    }

    return delegateVariableMappingType;
  }


  entries.push(entryFactory.textField({
    id: 'callable-element-ref',
    dataValueLabel: 'callableElementLabel',
    modelProperty: 'callableElementRef',

    get: function(element, node) {
      var callableElementRef;

      var attr = getAttribute(element, 'element');
      if (attr) {
        var bo = getBusinessObject(element);
        callableElementRef = bo.get(attr);
      }

      var label = '';
      var type = getCallableType(element);
      if (type === 'bpmn') {
        label = translate('Called Element');
      }
      else if (type === 'cmmn') {
        label = translate('Case Ref');
      }
      else if (type === 'dmn') {
        label = translate('Decision Ref');
      }

      return {
        callableElementRef: callableElementRef,
        callableElementLabel: label
      };
    },

    set: function(element, values, node) {
      var newCallableElementRef = values.callableElementRef;
      var attr = getAttribute(element, 'element');

      var props = {};
      props[attr] = newCallableElementRef || '';

      return cmdHelper.updateProperties(element, props);
    },

    validate: function(element, values, node) {
      var elementRef = values.callableElementRef;
      var type = getCallableType(element);
      return isSupportedCallableType(type) && !elementRef ? { callableElementRef: translate('Must provide a value') } : {};
    },

    hidden: function(element, node) {
      return !isSupportedCallableType(getCallableType(element));
    }

  }));

  entries.push(entryFactory.selectBox({
    id: 'callable-binding',
    label: translate('Binding'),
    selectOptions: function(element) {
      var type = getCallableType(element);
      var options;

      if (type === 'cmmn') {
        options = bindingOptions.filter(function(bindingOption) {
          return bindingOption.value !== 'versionTag';
        });
      } else {
        options = bindingOptions;
      }
      return options;
    },
    modelProperty: 'callableBinding',

    get: function(element, node) {
      var callableBinding;

      var attr = getAttribute(element, 'binding');
      if (attr) {
        var bo = getBusinessObject(element);
        callableBinding = bo.get(attr) || 'latest';
      }

      return {
        callableBinding: callableBinding
      };
    },

    set: function(element, values, node) {
      var binding = values.callableBinding;
      var attr = getAttribute(element, 'binding'),
          attrVer = getAttribute(element, 'version'),
          attrVerTag = getAttribute(element, 'versionTag');

      var props = {};
      props[attr] = binding;

      // set version and versionTag values always to undefined to delete the existing value
      props[attrVer] = undefined;
      props[attrVerTag] = undefined;

      return cmdHelper.updateProperties(element, props);
    },

    hidden: function(element, node) {
      return !isSupportedCallableType(getCallableType(element));
    }

  }));

  entries.push(entryFactory.textField({
    id: 'callable-version',
    label: translate('Version'),
    modelProperty: 'callableVersion',

    get: function(element, node) {
      var callableVersion;

      var attr = getAttribute(element, 'version');
      if (attr) {
        var bo = getBusinessObject(element);
        callableVersion = bo.get(attr);
      }

      return {
        callableVersion: callableVersion
      };
    },

    set: function(element, values, node) {
      var version = values.callableVersion;
      var attr = getAttribute(element, 'version');

      var props = {};
      props[attr] = version || undefined;

      return cmdHelper.updateProperties(element, props);
    },

    validate: function(element, values, node) {
      var version = values.callableVersion;

      var type = getCallableType(element);
      return (
        isSupportedCallableType(type) &&
        getCallActivityBindingValue(element) === 'version' && (
          !version ? { callableVersion: translate('Must provide a value') } : {}
        )
      );
    },

    hidden: function(element, node) {
      var type = getCallableType(element);
      return !isSupportedCallableType(type) || getCallActivityBindingValue(element) !== 'version';
    }

  }));

  entries.push(entryFactory.textField({
    id: 'callable-version-tag',
    label: translate('Version Tag'),
    modelProperty: 'versionTag',

    get: function(element, node) {
      var versionTag;

      var attr = getAttribute(element, 'versionTag');

      if (attr) {
        var bo = getBusinessObject(element);

        versionTag = bo.get(attr);
      }

      return {
        versionTag: versionTag
      };
    },

    set: function(element, values, node) {
      var versionTag = values.versionTag;

      var attr = getAttribute(element, 'versionTag');

      var props = {};

      props[attr] = versionTag || undefined;

      return cmdHelper.updateProperties(element, props);
    },

    validate: function(element, values, node) {
      var versionTag = values.versionTag;

      var type = getCallableType(element);

      return (
        isSupportedCallableType(type) &&
        getCallActivityBindingValue(element) === 'versionTag' && (
          !versionTag ? { versionTag: translate('Must provide a value') } : {}
        )
      );
    },

    hidden: function(element, node) {
      var type = getCallableType(element);

      return !isSupportedCallableType(type) || getCallActivityBindingValue(element) !== 'versionTag';
    }

  }));

  entries.push(entryFactory.textField({
    id: 'tenant-id',
    label: translate('Tenant Id'),
    modelProperty: 'tenantId',

    get: function(element, node) {
      var tenantId;

      var attr = getAttribute(element, 'tenantId');
      if (attr) {
        var bo = getBusinessObject(element);
        tenantId = bo.get(attr);
      }

      return {
        tenantId: tenantId
      };
    },

    set: function(element, values, node) {
      var tenantId = values.tenantId;
      var attr = getAttribute(element, 'tenantId');

      var props = {};
      props[attr] = tenantId || undefined;

      return cmdHelper.updateProperties(element, props);
    },

    hidden: function(element, node) {
      var type = getCallableType(element);
      return !isSupportedCallableType(type);
    }

  }));

  if (is(getBusinessObject(element), 'bpmn:CallActivity')) {
    entries.push(entryFactory.checkbox({
      id: 'callable-business-key',
      label: translate('Business Key'),
      modelProperty: 'callableBusinessKey',

      get: function(element, node) {
        var activitiIn = getActivitiInWithBusinessKey(element);

        return {
          callableBusinessKey: !!(activitiIn && activitiIn.length > 0)
        };
      },

      set: function(element, values, node) {
        if (values.callableBusinessKey) {
          return setBusinessKey(element, '#{execution.processBusinessKey}', bpmnFactory);
        } else {
          return deleteBusinessKey(element);
        }
      }
    }));
  }

  entries.push(entryFactory.textField({
    id: 'business-key-expression',
    label: translate('Business Key Expression'),
    modelProperty: 'businessKey',

    get: function(element, node) {
      var activitiInWithBusinessKey = getActivitiInWithBusinessKey(element);

      return {
        businessKey: (
          activitiInWithBusinessKey.length ?
            activitiInWithBusinessKey[0].get('activiti:businessKey') :
            undefined
        )
      };
    },

    set: function(element, values, node) {
      var businessKey = values.businessKey;

      return setBusinessKey(element, businessKey, bpmnFactory);
    },

    validate: function(element, values, node) {
      var businessKey = values.businessKey;

      return businessKey === '' ? { businessKey: translate('Must provide a value') } : {};
    },

    hidden: function(element, node) {
      return !getActivitiInWithBusinessKey(element).length;
    }

  }));

  entries = entries.concat(resultVariable(element, bpmnFactory, {
    id: 'dmn-resultVariable',
    getBusinessObject: getBusinessObject,
    getImplementationType: getCallableType,
    hideResultVariable: function(element, node) {
      return getCallableType(element) !== 'dmn';
    }
  }, translate));

  entries.push(entryFactory.selectBox({
    id: 'dmn-map-decision-result',
    label: translate('Map Decision Result'),
    selectOptions: mapDecisionResultOptions,
    modelProperty: 'mapDecisionResult',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      return {
        mapDecisionResult: bo.get('activiti:mapDecisionResult') || 'resultList'
      };
    },

    set: function(element, values, node) {
      return cmdHelper.updateProperties(element, {
        'activiti:mapDecisionResult': values.mapDecisionResult || 'resultList'
      });
    },

    hidden: function(element, node) {
      var bo = getBusinessObject(element);
      var resultVariable = bo.get('activiti:resultVariable');
      return !(getCallableType(element) === 'dmn' && typeof resultVariable !== 'undefined');
    }

  }));


  entries.push(entryFactory.selectBox({
    id: 'delegateVariableMappingType',
    label: translate('Delegate Variable Mapping'),
    selectOptions: delegateVariableMappingOptions,
    emptyParameter: true,
    modelProperty: 'delegateVariableMappingType',

    get: function(element, node) {
      return {
        delegateVariableMappingType : getDelegateVariableMappingType(element)
      };
    },

    set: function(element, values, node) {
      var delegateVariableMappingType = values.delegateVariableMappingType;

      var props = {
        'activiti:variableMappingClass' : undefined,
        'activiti:variableMappingDelegateExpression' : undefined
      };

      if (delegateVariableMappingType === 'variableMappingClass') {
        props['activiti:variableMappingClass'] = '';
      }
      else if (delegateVariableMappingType === 'variableMappingDelegateExpression') {
        props['activiti:variableMappingDelegateExpression'] = '';
      }

      return cmdHelper.updateProperties(element, props);
    },

    hidden: function(element, node) {
      return (getCallableType(element) !== 'bpmn');
    }

  }));

  entries.push(entryFactory.textField({
    id: 'delegateVariableMapping',
    dataValueLabel: 'delegateVariableMappingLabel',
    modelProperty: 'delegateVariableMapping',

    get: function(element, node) {
      var bo = getBusinessObject(element);

      var label = '';
      var delegateVariableMapping = undefined;
      var type = getDelegateVariableMappingType(element);

      if (type === 'variableMappingClass') {
        label = translate('Class');
        delegateVariableMapping = bo.get('activiti:variableMappingClass');
      }
      else if (type === 'variableMappingDelegateExpression') {
        label = translate('Delegate Expression');
        delegateVariableMapping = bo.get('activiti:variableMappingDelegateExpression');
      }

      return {
        delegateVariableMapping: delegateVariableMapping,
        delegateVariableMappingLabel: label
      };
    },

    set: function(element, values, node) {
      var delegateVariableMapping = values.delegateVariableMapping;

      var attr = 'activiti:' + getDelegateVariableMappingType(element);

      var props = {};
      props[attr] = delegateVariableMapping || undefined;

      return cmdHelper.updateProperties(element, props);
    },

    validate: function(element, values, node) {
      var delegateVariableMapping = values.delegateVariableMapping;
      return (
        getCallableType(element) === 'bpmn' && (
          !delegateVariableMapping ? { delegateVariableMapping: translate('Must provide a value') } : {}
        )
      );
    },

    hidden: function(element, node) {
      return !(getCallableType(element) === 'bpmn' && getDelegateVariableMappingType(element) !== '');
    }

  }));

  return entries;
};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"./ResultVariable":656,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],640:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory');

var cmdHelper = require('../../../../helper/CmdHelper');

module.exports = function(element, bpmnFactory, options, translate) {

  var getBusinessObject = options.getBusinessObject;

  var candidateStarterGroupsEntry = entryFactory.textField({
    id: 'candidateStarterGroups',
    label: translate('Candidate Starter Groups'),
    modelProperty: 'candidateStarterGroups',
    description: translate('Specify more than one group as a comma separated list.'),

    get: function(element, node) {
      var bo = getBusinessObject(element);
      var candidateStarterGroups = bo.get('activiti:candidateStarterGroups');

      return {
        candidateStarterGroups: candidateStarterGroups ? candidateStarterGroups : ''
      };
    },

    set: function(element, values) {
      var bo = getBusinessObject(element);
      return cmdHelper.updateBusinessObject(element, bo, {
        'activiti:candidateStarterGroups': values.candidateStarterGroups || undefined
      });
    }

  });

  var candidateStarterUsersEntry = entryFactory.textField({
    id: 'candidateStarterUsers',
    label: translate('Candidate Starter Users'),
    modelProperty: 'candidateStarterUsers',
    description: translate('Specify more than one user as a comma separated list.'),

    get: function(element, node) {
      var bo = getBusinessObject(element);
      var candidateStarterUsers = bo.get('activiti:candidateStarterUsers');

      return {
        candidateStarterUsers: candidateStarterUsers ? candidateStarterUsers : ''
      };
    },

    set: function(element, values) {
      var bo = getBusinessObject(element);
      return cmdHelper.updateBusinessObject(element, bo, {
        'activiti:candidateStarterUsers': values.candidateStarterUsers || undefined
      });
    }

  });

  return [
    candidateStarterGroupsEntry,
    candidateStarterUsersEntry
  ];
};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],641:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory'),
    cmdHelper = require('../../../../helper/CmdHelper');

var DELEGATE_TYPES = [
  'class',
  'expression',
  'delegateExpression'
];

var PROPERTIES = {
  class: 'activiti:class',
  expression: 'activiti:expression',
  delegateExpression: 'activiti:delegateExpression'
};

function isDelegate(type) {
  return DELEGATE_TYPES.indexOf(type) !== -1;
}

function getAttribute(type) {
  return PROPERTIES[type];
}


module.exports = function(element, bpmnFactory, options, translate) {

  var getImplementationType = options.getImplementationType,
      getBusinessObject = options.getBusinessObject;

  function getDelegationLabel(type) {
    switch (type) {
    case 'class':
      return translate('Java Class');
    case 'expression':
      return translate('Expression');
    case 'delegateExpression':
      return translate('Delegate Expression');
    default:
      return '';
    }
  }

  var delegateEntry = entryFactory.textField({
    id: 'delegate',
    label: translate('Value'),
    dataValueLabel: 'delegationLabel',
    modelProperty: 'delegate',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      var type = getImplementationType(element);
      var attr = getAttribute(type);
      var label = getDelegationLabel(type);
      return {
        delegate: bo.get(attr),
        delegationLabel: label
      };
    },

    set: function(element, values, node) {
      var bo = getBusinessObject(element);
      var type = getImplementationType(element);
      var attr = getAttribute(type);
      var prop = {};
      prop[attr] = values.delegate || '';
      return cmdHelper.updateBusinessObject(element, bo, prop);
    },

    validate: function(element, values, node) {
      return isDelegate(getImplementationType(element)) && !values.delegate ? { delegate: translate('Must provide a value') } : {};
    },

    hidden: function(element, node) {
      return !isDelegate(getImplementationType(element));
    }

  });

  return [ delegateEntry ];

};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],642:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory'),
    cmdHelper = require('../../../../helper/CmdHelper'),
    elementReferenceProperty = require('../../../../provider/bpmn/parts/implementation/ElementReferenceProperty');

module.exports = function(
    group, element, bpmnFactory, errorEventDefinition,
    showErrorCodeVariable, showErrorMessageVariable, translate
) {


  var getValue = function(modelProperty) {
    return function(element) {
      var modelPropertyValue = errorEventDefinition.get('activiti:' + modelProperty);
      var value = {};

      value[modelProperty] = modelPropertyValue;
      return value;
    };
  };

  var setValue = function(modelProperty) {
    return function(element, values) {
      var props = {};

      props['activiti:' + modelProperty] = values[modelProperty] || undefined;

      return cmdHelper.updateBusinessObject(element, errorEventDefinition, props);
    };
  };


  group.entries = group.entries.concat(
    elementReferenceProperty(element, errorEventDefinition, bpmnFactory, {
      id: 'error-element-message',
      label: translate('Error Message'),
      referenceProperty: 'errorRef',
      modelProperty: 'errorMessage'
    })
  );

  if (showErrorCodeVariable) {
    group.entries.push(entryFactory.textField({
      id: 'errorCodeVariable',
      label: translate('Error Code Variable'),
      modelProperty : 'errorCodeVariable',

      get: getValue('errorCodeVariable'),
      set: setValue('errorCodeVariable')
    }));
  }

  if (showErrorMessageVariable) {
    group.entries.push(entryFactory.textField({
      id: 'errorMessageVariable',
      label: translate('Error Message Variable'),
      modelProperty: 'errorMessageVariable',

      get: getValue('errorMessageVariable'),
      set: setValue('errorMessageVariable')
    }));
  }

};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../provider/bpmn/parts/implementation/ElementReferenceProperty":668}],643:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var domQuery = require('min-dom').query,
    domClosest = require('min-dom').closest,
    domify = require('min-dom').domify,
    forEach = require('lodash/forEach');

var elementHelper = require('../../../../helper/ElementHelper'),
    cmdHelper = require('../../../../helper/CmdHelper'),
    utils = require('../../../../Utils'),
    escapeHTML = utils.escapeHTML;

function getSelectBox(node, id) {
  var currentTab = domClosest(node, 'div.bpp-properties-tab');
  var query = 'select[name=selectedExtensionElement]' + (id ? '[id=cam-extensionElements-' + id + ']' : '');
  return domQuery(query, currentTab);
}

function getSelected(node, id) {
  var selectBox = getSelectBox(node, id);
  return {
    value: (selectBox || {}).value,
    idx: (selectBox || {}).selectedIndex
  };
}

function generateElementId(prefix) {
  prefix = prefix + '_';
  return utils.nextId(prefix);
}

var CREATE_EXTENSION_ELEMENT_ACTION = 'create-extension-element',
    REMOVE_EXTENSION_ELEMENT_ACTION = 'remove-extension-element';

module.exports = function(element, bpmnFactory, options, translate) {

  var id = options.id,
      prefix = options.prefix || 'elem',
      label = options.label || id,
      idGeneration = (options.idGeneration === false) ? options.idGeneration : true,
      businessObject = options.businessObject || getBusinessObject(element);

  var modelProperty = options.modelProperty || 'id';

  var getElements = options.getExtensionElements;

  var createElement = options.createExtensionElement,
      canCreate = typeof createElement === 'function';

  var removeElement = options.removeExtensionElement,
      canRemove = typeof removeElement === 'function';

  var onSelectionChange = options.onSelectionChange;

  var hideElements = options.hideExtensionElements,
      canBeHidden = typeof hideElements === 'function';

  var setOptionLabelValue = options.setOptionLabelValue;

  var defaultSize = options.size || 5,
      resizable = options.resizable;

  var reference = options.reference || undefined;

  var selectionChanged = function(element, node, event, scope) {
    if (typeof onSelectionChange === 'function') {
      return onSelectionChange(element, node, event, scope);
    }
  };

  var createOption = function(value) {
    return '<option value="' + escapeHTML(value) + '" data-value data-name="extensionElementValue">' + escapeHTML(value) + '</option>';
  };

  var initSelectionSize = function(selectBox, optionsLength) {
    if (resizable) {
      selectBox.size = optionsLength > defaultSize ? optionsLength : defaultSize;
    }
  };

  return {
    id: id,
    html: '<div class="bpp-row bpp-element-list" ' +
            (canBeHidden ? 'data-show="hideElements"' : '') + '>' +
            '<label for="cam-extensionElements-' + escapeHTML(id) + '">' + escapeHTML(label) + '</label>' +
            '<div class="bpp-field-wrapper">' +
              '<select id="cam-extensionElements-' + escapeHTML(id) + '"' +
                      'name="selectedExtensionElement" ' +
                      'size="' + escapeHTML(defaultSize) + '" ' +
                      'data-list-entry-container ' +
                      'data-on-change="selectElement">' +
              '</select>' +
              (canCreate ? '<button class="add" ' +
                                   'id="cam-extensionElements-create-' + escapeHTML(id) + '" ' +
                                   'data-action="createElement">' +
                             '<span>+</span>' +
                           '</button>' : '') +
              (canRemove ? '<button class="clear" ' +
                                   'id="cam-extensionElements-remove-' + escapeHTML(id) + '" ' +
                                   'data-action="removeElement" ' +
                                   'data-disable="disableRemove">' +
                             '<span>-</span>' +
                           '</button>' : '') +
            '</div>' +
          '</div>',

    get: function(element, node) {
      var elements = getElements(element, node);

      var result = [];
      forEach(elements, function(elem) {
        result.push({
          extensionElementValue: elem.get(modelProperty)
        });
      });

      var selectBox = getSelectBox(node.parentNode, id);
      initSelectionSize(selectBox, result.length);

      return result;
    },

    set: function(element, values, node) {
      var action = this.__action;
      delete this.__action;

      businessObject = businessObject || getBusinessObject(element);

      var bo =
        (reference && businessObject.get(reference))
          ? businessObject.get(reference)
          : businessObject;

      var extensionElements = bo.get('extensionElements');

      if (action.id === CREATE_EXTENSION_ELEMENT_ACTION) {
        var commands = [];
        if (!extensionElements) {
          extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
          commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
        }
        commands.push(createElement(element, extensionElements, action.value, node));
        return commands;

      }
      else if (action.id === REMOVE_EXTENSION_ELEMENT_ACTION) {
        return removeElement(element, extensionElements, action.value, action.idx, node);
      }

    },

    createListEntryTemplate: function(value, index, selectBox) {
      initSelectionSize(selectBox, selectBox.options.length + 1);
      return createOption(value.extensionElementValue);
    },

    deselect: function(element, node) {
      var selectBox = getSelectBox(node, id);
      selectBox.selectedIndex = -1;
    },

    getSelected: function(element, node) {
      return getSelected(node, id);
    },

    setControlValue: function(element, node, option, property, value, idx) {
      node.value = value;

      if (!setOptionLabelValue) {
        node.text = value;
      } else {
        setOptionLabelValue(element, node, option, property, value, idx);
      }
    },

    createElement: function(element, node) {
      // create option template
      var generatedId;
      if (idGeneration) {
        generatedId = generateElementId(prefix);
      }

      var selectBox = getSelectBox(node, id);
      var template = domify(createOption(generatedId));

      // add new empty option as last child element
      selectBox.appendChild(template);

      // select last child element
      selectBox.lastChild.selected = 'selected';
      selectionChanged(element, node);

      // update select box size
      initSelectionSize(selectBox, selectBox.options.length);

      this.__action = {
        id: CREATE_EXTENSION_ELEMENT_ACTION,
        value: generatedId
      };

      return true;
    },

    removeElement: function(element, node) {
      var selection = getSelected(node, id);

      var selectBox = getSelectBox(node, id);
      selectBox.removeChild(selectBox.options[selection.idx]);

      // update select box size
      initSelectionSize(selectBox, selectBox.options.length);

      this.__action = {
        id: REMOVE_EXTENSION_ELEMENT_ACTION,
        value: selection.value,
        idx: selection.idx
      };

      return true;
    },

    hideElements: function(element, entryNode, node, scopeNode) {
      return !hideElements(element, entryNode, node, scopeNode);
    },

    disableRemove: function(element, entryNode, node, scopeNode) {
      return (getSelected(entryNode, id) || {}).idx < 0;
    },

    selectElement: selectionChanged
  };

};

},{"../../../../Utils":576,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522,"min-dom":556}],644:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory'),
    cmdHelper = require('../../../../helper/CmdHelper');

module.exports = function(element, bpmnFactory, options, translate) {

  var getImplementationType = options.getImplementationType,
      getBusinessObject = options.getBusinessObject;

  function isExternal(element) {
    return getImplementationType(element) === 'external';
  }

  var topicEntry = entryFactory.textField({
    id: 'externalTopic',
    label: translate('Topic'),
    modelProperty: 'externalTopic',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      return { externalTopic: bo.get('activiti:topic') };
    },

    set: function(element, values, node) {
      var bo = getBusinessObject(element);
      return cmdHelper.updateBusinessObject(element, bo, {
        'activiti:topic': values.externalTopic
      });
    },

    validate: function(element, values, node) {
      return isExternal(element) && !values.externalTopic ? { externalTopic: translate('Must provide a value') } : {};
    },

    hidden: function(element, node) {
      return !isExternal(element);
    }

  });

  return [ topicEntry ];

};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],645:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory');

var cmdHelper = require('../../../../helper/CmdHelper');

module.exports = function(element, bpmnFactory, options, translate) {

  var getBusinessObject = options.getBusinessObject;

  var externalTaskPriorityEntry = entryFactory.textField({
    id: 'externalTaskPriority',
    label: translate('Task Priority'),
    modelProperty: 'taskPriority',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      return {
        taskPriority: bo.get('activiti:taskPriority')
      };
    },

    set: function(element, values) {
      var bo = getBusinessObject(element);
      return cmdHelper.updateBusinessObject(element, bo, {
        'activiti:taskPriority': values.taskPriority || undefined
      });
    }

  });

  return [ externalTaskPriorityEntry ];

};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],646:[function(require,module,exports){
'use strict';

var extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
    elementHelper = require('../../../../helper/ElementHelper'),
    cmdHelper = require('../../../../helper/CmdHelper');

var utils = require('../../../../Utils');

var entryFactory = require('../../../../factory/EntryFactory');

var extensionElementsEntry = require('./ExtensionElements');

var ModelUtil = require('bpmn-js/lib/util/ModelUtil'),
    getBusinessObject = ModelUtil.getBusinessObject;

var assign = require('lodash/assign');


var DEFAULT_PROPS = {
  'stringValue': undefined,
  'string': undefined,
  'expression': undefined
};

var ACTIVITI_FIELD_EXTENSION_ELEMENT = 'activiti:Field';

module.exports = function(element, bpmnFactory, translate, options) {

  options = options || {};

  var insideListener = !!options.insideListener,
      idPrefix = options.idPrefix || '',
      getSelectedListener = options.getSelectedListener,
      businessObject = options.businessObject || getBusinessObject(element);

  var entries = [];

  var isSelected = function(element, node) {
    return getSelectedField(element, node);
  };

  function getSelectedField(element, node) {
    var selected = fieldEntry.getSelected(element, node.parentNode);

    if (selected.idx === -1) {
      return;
    }

    var fields = getActivitiFields(element, node);

    return fields[selected.idx];
  }

  function getActivitiFields(element, node) {
    if (!insideListener) {
      return (
        businessObject &&
        extensionElementsHelper.getExtensionElements(businessObject, ACTIVITI_FIELD_EXTENSION_ELEMENT)
      ) || [];
    }
    return getActivitiListenerFields(element, node);
  }

  function getActivitiListenerFields(element, node) {
    var selectedListener = getSelectedListener(element, node);
    return selectedListener && selectedListener.fields || [];
  }

  function getFieldType(bo) {
    var fieldType = 'string';

    var expressionValue = bo && bo.expression;
    var stringValue = bo && (bo.string || bo.stringValue);

    if (typeof stringValue !== 'undefined') {
      fieldType = 'string';
    } else if (typeof expressionValue !== 'undefined') {
      fieldType = 'expression';
    }

    return fieldType;
  }

  var setOptionLabelValue = function() {
    return function(element, node, option, property, value, idx) {
      var activitiFields = getActivitiFields(element, node);
      var field = activitiFields[idx];

      value = (field.name) ? field.name : '<empty>';

      var label = idx + ' : ' + value;

      option.text = label;
    };
  };

  var newElement = function() {
    return function(element, extensionElements, value, node) {

      var props = {
        name: '',
        string: ''
      };

      var newFieldElem;

      if (!insideListener) {

        newFieldElem = elementHelper.createElement(ACTIVITI_FIELD_EXTENSION_ELEMENT, props, extensionElements, bpmnFactory);
        return cmdHelper.addElementsTolist(element, extensionElements, 'values', [ newFieldElem ]);

      } else {

        var selectedListener = getSelectedListener(element, node);
        newFieldElem = elementHelper.createElement(ACTIVITI_FIELD_EXTENSION_ELEMENT, props, selectedListener, bpmnFactory);
        return cmdHelper.addElementsTolist(element, selectedListener, 'fields', [ newFieldElem ]);

      }

    };
  };

  var removeElement = function() {
    return function(element, extensionElements, value, idx, node) {
      var activitiFields= getActivitiFields(element, node);
      var field = activitiFields[idx];
      if (field) {
        if (!insideListener) {
          return extensionElementsHelper.removeEntry(businessObject, element, field);
        }
        var selectedListener = getSelectedListener(element, node);
        return cmdHelper.removeElementsFromList(element, selectedListener, 'fields', null, [ field ]);
      }
    };
  };


  var fieldEntry = extensionElementsEntry(element, bpmnFactory, {
    id : idPrefix + 'fields',
    label : translate('Fields'),
    modelProperty: 'fieldName',
    idGeneration: 'false',

    businessObject: businessObject,

    createExtensionElement: newElement(),
    removeExtensionElement: removeElement(),

    getExtensionElements: function(element, node) {
      return getActivitiFields(element, node);
    },

    setOptionLabelValue: setOptionLabelValue()

  });
  entries.push(fieldEntry);


  entries.push(entryFactory.validationAwareTextField({
    id: idPrefix + 'field-name',
    label: translate('Name'),
    modelProperty: 'fieldName',

    getProperty: function(element, node) {
      return (getSelectedField(element, node) || {}).name;
    },

    setProperty: function(element, values, node) {
      var selectedField = getSelectedField(element, node);
      return cmdHelper.updateBusinessObject(element, selectedField, { name : values.fieldName });
    },

    validate: function(element, values, node) {
      var bo = getSelectedField(element, node);

      var validation = {};
      if (bo) {
        var nameValue = values.fieldName;

        if (nameValue) {
          if (utils.containsSpace(nameValue)) {
            validation.fieldName = translate('Name must not contain spaces');
          }
        } else {
          validation.fieldName = translate('Parameter must have a name');
        }
      }

      return validation;
    },

    hidden: function(element, node) {
      return !isSelected(element, node);
    }

  }));

  var fieldTypeOptions = [
    {
      name: translate('String'),
      value: 'string'
    },
    {
      name: translate('Expression'),
      value: 'expression'
    }
  ];

  entries.push(entryFactory.selectBox({
    id: idPrefix + 'field-type',
    label: translate('Type'),
    selectOptions: fieldTypeOptions,
    modelProperty: 'fieldType',

    get: function(element, node) {
      var bo = getSelectedField(element, node);

      var fieldType = getFieldType(bo);

      return {
        fieldType: fieldType
      };
    },

    set: function(element, values, node) {
      var props = assign({}, DEFAULT_PROPS);

      var fieldType = values.fieldType;

      if (fieldType === 'string') {
        props.string = '';
      }
      else if (fieldType === 'expression') {
        props.expression = '';
      }

      return cmdHelper.updateBusinessObject(element, getSelectedField(element, node), props);
    },

    hidden: function(element, node) {
      return !isSelected(element, node);
    }

  }));


  entries.push(entryFactory.textBox({
    id: idPrefix + 'field-value',
    label: translate('Value'),
    modelProperty: 'fieldValue',

    get: function(element, node) {
      var bo = getSelectedField(element, node);
      var fieldType = getFieldType(bo);

      var fieldValue;

      if (fieldType === 'string') {
        fieldValue = bo && (bo.string || bo.stringValue);
      }
      else if (fieldType === 'expression') {
        fieldValue = bo && bo.expression;
      }

      return {
        fieldValue: fieldValue
      };
    },

    set: function(element, values, node) {
      var bo = getSelectedField(element, node);
      var fieldType = getFieldType(bo);

      var props = assign({}, DEFAULT_PROPS);

      var fieldValue = values.fieldValue || undefined;

      if (fieldType === 'string') {
        props.string = fieldValue;
      }
      else if (fieldType === 'expression') {
        props.expression = fieldValue;
      }

      return cmdHelper.updateBusinessObject(element, bo, props);

    },

    validate: function(element, values, node) {
      var bo = getSelectedField(element, node);

      var validation = {};
      if (bo) {
        if (!values.fieldValue) {
          validation.fieldValue = translate('Must provide a value');
        }
      }

      return validation;
    },

    show: function(element, node) {
      return isSelected(element, node);
    }

  }));

  return entries;

};

},{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"./ExtensionElements":643,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513}],647:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory');

var cmdHelper = require('../../../../helper/CmdHelper');

module.exports = function(element, bpmnFactory, options, translate) {

  var getBusinessObject = options.getBusinessObject;

  var historyTimeToLiveEntry = entryFactory.textField({
    id: 'historyTimeToLive',
    label: translate('History Time To Live'),
    modelProperty: 'historyTimeToLive',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      var historyTimeToLive = bo.get('activiti:historyTimeToLive');

      return {
        historyTimeToLive: historyTimeToLive ? historyTimeToLive : ''
      };
    },

    set: function(element, values) {
      var bo = getBusinessObject(element);
      return cmdHelper.updateBusinessObject(element, bo, {
        'activiti:historyTimeToLive': values.historyTimeToLive || undefined
      });
    }

  });

  return [ historyTimeToLiveEntry ];
};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],648:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory'),
    cmdHelper = require('../../../../helper/CmdHelper'),
    extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
    elementHelper = require('../../../../helper/ElementHelper');

var assign = require('lodash/assign');
var map = require('lodash/map');

var DEFAULT_DELEGATE_PROPS = [ 'class', 'expression', 'delegateExpression' ];

var DELEGATE_PROPS = {
  'activiti:class': undefined,
  'activiti:expression': undefined,
  'activiti:delegateExpression': undefined,
  'activiti:resultVariable': undefined
};

var DMN_CAPABLE_PROPS = {
  'activiti:decisionRef': undefined,
  'activiti:decisionRefBinding': 'latest',
  'activiti:decisionRefVersion': undefined,
  'activiti:mapDecisionResult': 'resultList',
  'activiti:decisionRefTenantId': undefined
};


var EXTERNAL_CAPABLE_PROPS = {
  'activiti:type': undefined,
  'activiti:topic': undefined
};

module.exports = function(element, bpmnFactory, options, translate) {

  var DEFAULT_OPTIONS = [
    { value: 'class', name: translate('Java Class') },
    { value: 'expression', name: translate('Expression') },
    { value: 'delegateExpression', name: translate('Delegate Expression') }
  ];

  var DMN_OPTION = [
    { value: 'dmn', name: translate('DMN') }
  ];

  var EXTERNAL_OPTION = [
    { value: 'external', name: translate('External') }
  ];

  var CONNECTOR_OPTION = [
    { value: 'connector', name: translate('Connector') }
  ];

  var SCRIPT_OPTION = [
    { value: 'script', name: translate('Script') }
  ];

  var getType = options.getImplementationType,
      getBusinessObject = options.getBusinessObject;

  var hasDmnSupport = options.hasDmnSupport,
      hasExternalSupport = options.hasExternalSupport,
      hasServiceTaskLikeSupport = options.hasServiceTaskLikeSupport,
      hasScriptSupport = options.hasScriptSupport;

  var entries = [];

  var selectOptions = DEFAULT_OPTIONS.concat([]);

  if (hasDmnSupport) {
    selectOptions = selectOptions.concat(DMN_OPTION);
  }

  if (hasExternalSupport) {
    selectOptions = selectOptions.concat(EXTERNAL_OPTION);
  }

  if (hasServiceTaskLikeSupport) {
    selectOptions = selectOptions.concat(CONNECTOR_OPTION);
  }

  if (hasScriptSupport) {
    selectOptions = selectOptions.concat(SCRIPT_OPTION);
  }

  selectOptions.push({ value: '' });

  entries.push(entryFactory.selectBox({
    id : 'implementation',
    label: translate('Implementation'),
    selectOptions: selectOptions,
    modelProperty: 'implType',

    get: function(element, node) {
      return {
        implType: getType(element) || ''
      };
    },

    set: function(element, values, node) {
      var bo = getBusinessObject(element);
      var oldType = getType(element);
      var newType = values.implType;

      var props = assign({}, DELEGATE_PROPS);

      if (DEFAULT_DELEGATE_PROPS.indexOf(newType) !== -1) {

        var newValue = '';
        if (DEFAULT_DELEGATE_PROPS.indexOf(oldType) !== -1) {
          newValue = bo.get('activiti:' + oldType);
        }
        props['activiti:' + newType] = newValue;
      }

      if (hasDmnSupport) {
        props = assign(props, DMN_CAPABLE_PROPS);
        if (newType === 'dmn') {
          props['activiti:decisionRef'] = '';
        }
      }

      if (hasExternalSupport) {
        props = assign(props, EXTERNAL_CAPABLE_PROPS);
        if (newType === 'external') {
          props['activiti:type'] = 'external';
          props['activiti:topic'] = '';
        }
      }

      if (hasScriptSupport) {
        props['activiti:script'] = undefined;

        if (newType === 'script') {
          props['activiti:script'] = elementHelper.createElement('activiti:Script', {}, bo, bpmnFactory);
        }
      }

      var commands = [];
      commands.push(cmdHelper.updateBusinessObject(element, bo, props));

      if (hasServiceTaskLikeSupport) {
        var connectors = extensionElementsHelper.getExtensionElements(bo, 'activiti:Connector');
        commands.push(map(connectors, function(connector) {
          return extensionElementsHelper.removeEntry(bo, element, connector);
        }));

        if (newType === 'connector') {
          var extensionElements = bo.get('extensionElements');
          if (!extensionElements) {
            extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
            commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
          }
          var connector = elementHelper.createElement('activiti:Connector', {}, extensionElements, bpmnFactory);
          commands.push(cmdHelper.addAndRemoveElementsFromList(
            element,
            extensionElements,
            'values',
            'extensionElements',
            [ connector ],
            []
          ));
        }
      }

      return commands;

    }
  }));

  return entries;

};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"lodash/assign":513,"lodash/map":540}],649:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var elementHelper = require('../../../../helper/ElementHelper'),
    extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
    inputOutputHelper = require('../../../../helper/InputOutputHelper'),
    cmdHelper = require('../../../../helper/CmdHelper');

var extensionElementsEntry = require('./ExtensionElements');


function getInputOutput(element, insideConnector) {
  return inputOutputHelper.getInputOutput(element, insideConnector);
}

function getConnector(element) {
  return inputOutputHelper.getConnector(element);
}

function getInputParameters(element, insideConnector) {
  return inputOutputHelper.getInputParameters(element, insideConnector);
}

function getOutputParameters(element, insideConnector) {
  return inputOutputHelper.getOutputParameters(element, insideConnector);
}

function getInputParameter(element, insideConnector, idx) {
  return inputOutputHelper.getInputParameter(element, insideConnector, idx);
}

function getOutputParameter(element, insideConnector, idx) {
  return inputOutputHelper.getOutputParameter(element, insideConnector, idx);
}


function createElement(type, parent, factory, properties) {
  return elementHelper.createElement(type, properties, parent, factory);
}

function createInputOutput(parent, bpmnFactory, properties) {
  return createElement('activiti:InputOutput', parent, bpmnFactory, properties);
}

function createParameter(type, parent, bpmnFactory, properties) {
  return createElement(type, parent, bpmnFactory, properties);
}


function ensureInputOutputSupported(element, insideConnector) {
  return inputOutputHelper.isInputOutputSupported(element, insideConnector);
}

function ensureOutparameterSupported(element, insideConnector) {
  return inputOutputHelper.areOutputParametersSupported(element, insideConnector);
}

module.exports = function(element, bpmnFactory, options, translate) {

  var TYPE_LABEL = {
    'activiti:Map': translate('Map'),
    'activiti:List': translate('List'),
    'activiti:Script': translate('Script')
  };

  options = options || {};

  var insideConnector = !!options.insideConnector,
      idPrefix = options.idPrefix || '';

  var getSelected = function(element, node) {
    var selection = (inputEntry && inputEntry.getSelected(element, node)) || { idx: -1 };

    var parameter = getInputParameter(element, insideConnector, selection.idx);
    if (!parameter && outputEntry) {
      selection = outputEntry.getSelected(element, node);
      parameter = getOutputParameter(element, insideConnector, selection.idx);
    }
    return parameter;
  };

  var result = {
    getSelectedParameter: getSelected
  };

  var entries = result.entries = [];

  if (!ensureInputOutputSupported(element)) {
    return result;
  }

  var newElement = function(type, prop, factory) {

    return function(element, extensionElements, value) {
      var commands = [];

      var inputOutput = getInputOutput(element, insideConnector);
      if (!inputOutput) {
        var parent = !insideConnector ? extensionElements : getConnector(element);
        inputOutput = createInputOutput(parent, bpmnFactory, {
          inputParameters: [],
          outputParameters: []
        });

        if (!insideConnector) {
          commands.push(cmdHelper.addAndRemoveElementsFromList(
            element,
            extensionElements,
            'values',
            'extensionElements',
            [ inputOutput ],
            []
          ));
        } else {
          commands.push(cmdHelper.updateBusinessObject(element, parent, { inputOutput: inputOutput }));
        }
      }

      var newElem = createParameter(type, inputOutput, bpmnFactory, { name: value });
      commands.push(cmdHelper.addElementsTolist(element, inputOutput, prop, [ newElem ]));

      return commands;
    };
  };

  var removeElement = function(getter, prop, otherProp) {
    return function(element, extensionElements, value, idx) {
      var inputOutput = getInputOutput(element, insideConnector);
      var parameter = getter(element, insideConnector, idx);

      var commands = [];
      commands.push(cmdHelper.removeElementsFromList(element, inputOutput, prop, null, [ parameter ]));

      var firstLength = inputOutput.get(prop).length-1;
      var secondLength = (inputOutput.get(otherProp) || []).length;

      if (!firstLength && !secondLength) {

        if (!insideConnector) {
          commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, inputOutput));
        } else {
          var connector = getConnector(element);
          commands.push(cmdHelper.updateBusinessObject(element, connector, { inputOutput: undefined }));
        }

      }

      return commands;
    };
  };

  var setOptionLabelValue = function(getter) {
    return function(element, node, option, property, value, idx) {
      var parameter = getter(element, insideConnector, idx);

      var suffix = 'Text';

      var definition = parameter.get('definition');
      if (typeof definition !== 'undefined') {
        var type = definition.$type;
        suffix = TYPE_LABEL[type];
      }

      option.text = (value || '') + ' : ' + suffix;
    };
  };


  // input parameters ///////////////////////////////////////////////////////////////

  var inputEntry = extensionElementsEntry(element, bpmnFactory, {
    id: idPrefix + 'inputs',
    label: translate('Input Parameters'),
    modelProperty: 'name',
    prefix: 'Input',
    resizable: true,

    createExtensionElement: newElement('activiti:InputParameter', 'inputParameters'),
    removeExtensionElement: removeElement(getInputParameter, 'inputParameters', 'outputParameters'),

    getExtensionElements: function(element) {
      return getInputParameters(element, insideConnector);
    },

    onSelectionChange: function(element, node, event, scope) {
      outputEntry && outputEntry.deselect(element, node);
    },

    setOptionLabelValue: setOptionLabelValue(getInputParameter)

  });
  entries.push(inputEntry);


  // output parameters ///////////////////////////////////////////////////////

  if (ensureOutparameterSupported(element, insideConnector)) {
    var outputEntry = extensionElementsEntry(element, bpmnFactory, {
      id: idPrefix + 'outputs',
      label: translate('Output Parameters'),
      modelProperty: 'name',
      prefix: 'Output',
      resizable: true,

      createExtensionElement: newElement('activiti:OutputParameter', 'outputParameters'),
      removeExtensionElement: removeElement(getOutputParameter, 'outputParameters', 'inputParameters'),

      getExtensionElements: function(element) {
        return getOutputParameters(element, insideConnector);
      },

      onSelectionChange: function(element, node, event, scope) {
        inputEntry.deselect(element, node);
      },

      setOptionLabelValue: setOptionLabelValue(getOutputParameter)

    });
    entries.push(outputEntry);
  }

  return result;

};

},{"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"../../../../helper/InputOutputHelper":596,"./ExtensionElements":643,"bpmn-js/lib/util/ModelUtil":141}],650:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is;

var elementHelper = require('../../../../helper/ElementHelper'),
    inputOutputHelper = require('../../../../helper/InputOutputHelper'),
    cmdHelper = require('../../../../helper/CmdHelper'),
    utils = require('../../../../Utils');

var entryFactory = require('../../../../factory/EntryFactory'),
    scriptImplementation = require('./Script');


function createElement(type, parent, factory, properties) {
  return elementHelper.createElement(type, properties, parent, factory);
}

function isScript(elem) {
  return is(elem, 'activiti:Script');
}

function isList(elem) {
  return is(elem, 'activiti:List');
}

function isMap(elem) {
  return is(elem, 'activiti:Map');
}

function ensureInputOutputSupported(element, insideConnector) {
  return inputOutputHelper.isInputOutputSupported(element, insideConnector);
}

module.exports = function(element, bpmnFactory, options, translate) {

  var typeInfo = {
    'activiti:Map': {
      value: 'map',
      label: translate('Map')
    },
    'activiti:List': {
      value: 'list',
      label: translate('List')
    },
    'activiti:Script': {
      value: 'script',
      label: translate('Script')
    }
  };

  options = options || {};

  var insideConnector = !!options.insideConnector,
      idPrefix = options.idPrefix || '';

  var getSelected = options.getSelectedParameter;

  if (!ensureInputOutputSupported(element, insideConnector)) {
    return [];
  }

  var entries = [];

  var isSelected = function(element, node) {
    return getSelected(element, node);
  };


  // parameter name ////////////////////////////////////////////////////////

  entries.push(entryFactory.validationAwareTextField({
    id: idPrefix + 'parameterName',
    label: translate('Name'),
    modelProperty: 'name',

    getProperty: function(element, node) {
      return (getSelected(element, node) || {}).name;
    },

    setProperty: function(element, values, node) {
      var param = getSelected(element, node);
      return cmdHelper.updateBusinessObject(element, param, values);
    },

    validate: function(element, values, node) {
      var bo = getSelected(element, node);

      var validation = {};
      if (bo) {
        var nameValue = values.name;

        if (nameValue) {
          if (utils.containsSpace(nameValue)) {
            validation.name = translate('Name must not contain spaces');
          }
        } else {
          validation.name = translate('Parameter must have a name');
        }
      }

      return validation;
    },

    hidden: function(element, node) {
      return !isSelected(element, node);
    }
  }));


  // parameter type //////////////////////////////////////////////////////

  var selectOptions = [
    { value: 'text', name: translate('Text') },
    { value: 'script', name: translate('Script') },
    { value: 'list', name: translate('List') },
    { value: 'map', name: translate('Map') }
  ];

  entries.push(entryFactory.selectBox({
    id : idPrefix + 'parameterType',
    label: translate('Type'),
    selectOptions: selectOptions,
    modelProperty: 'parameterType',

    get: function(element, node) {
      var bo = getSelected(element, node);

      var parameterType = 'text';

      if (typeof bo !== 'undefined') {
        var definition = bo.get('definition');
        if (typeof definition !== 'undefined') {
          var type = definition.$type;
          parameterType = typeInfo[type].value;
        }
      }

      return {
        parameterType: parameterType
      };
    },

    set: function(element, values, node) {
      var bo = getSelected(element, node);

      var properties = {
        value: undefined,
        definition: undefined
      };

      var createParameterTypeElem = function(type) {
        return createElement(type, bo, bpmnFactory);
      };

      var parameterType = values.parameterType;

      if (parameterType === 'script') {
        properties.definition = createParameterTypeElem('activiti:Script');
      }
      else if (parameterType === 'list') {
        properties.definition = createParameterTypeElem('activiti:List');
      }
      else if (parameterType === 'map') {
        properties.definition = createParameterTypeElem('activiti:Map');
      }

      return cmdHelper.updateBusinessObject(element, bo, properties);
    },

    show: function(element, node) {
      return isSelected(element, node);
    }

  }));


  // parameter value (type = text) ///////////////////////////////////////////////////////

  entries.push(entryFactory.textBox({
    id : idPrefix + 'parameterType-text',
    label : translate('Value'),
    modelProperty: 'value',
    get: function(element, node) {
      return {
        value: (getSelected(element, node) || {}).value
      };
    },

    set: function(element, values, node) {
      var param = getSelected(element, node);
      values.value = values.value || undefined;
      return cmdHelper.updateBusinessObject(element, param, values);
    },

    show: function(element, node) {
      var bo = getSelected(element, node);
      return bo && !bo.definition;
    }

  }));


  // parameter value (type = script) ///////////////////////////////////////////////////////
  var script = scriptImplementation('scriptFormat', 'value', true, translate);
  entries.push({
    id: idPrefix + 'parameterType-script',
    html: '<div data-show="isScript">' +
            script.template +
          '</div>',
    get: function(element, node) {
      var bo = getSelected(element, node);
      return bo && isScript(bo.definition) ? script.get(element, bo.definition) : {};
    },

    set: function(element, values, node) {
      var bo = getSelected(element, node);
      var update = script.set(element, values);
      return cmdHelper.updateBusinessObject(element, bo.definition, update);
    },

    validate: function(element, values, node) {
      var bo = getSelected(element, node);
      return bo && isScript(bo.definition) ? script.validate(element, bo.definition) : {};
    },

    isScript: function(element, node) {
      var bo = getSelected(element, node);
      return bo && isScript(bo.definition);
    },

    script: script

  });


  // parameter value (type = list) ///////////////////////////////////////////////////////

  entries.push(entryFactory.table({
    id: idPrefix + 'parameterType-list',
    modelProperties: [ 'value' ],
    labels: [ translate('Value') ],
    addLabel: translate('Add Value'),

    getElements: function(element, node) {
      var bo = getSelected(element, node);

      if (bo && isList(bo.definition)) {
        return bo.definition.items;
      }

      return [];
    },

    updateElement: function(element, values, node, idx) {
      var bo = getSelected(element, node);
      var item = bo.definition.items[idx];
      return cmdHelper.updateBusinessObject(element, item, values);
    },

    addElement: function(element, node) {
      var bo = getSelected(element, node);
      var newValue = createElement('activiti:Value', bo.definition, bpmnFactory, { value: undefined });
      return cmdHelper.addElementsTolist(element, bo.definition, 'items', [ newValue ]);
    },

    removeElement: function(element, node, idx) {
      var bo = getSelected(element, node);
      return cmdHelper.removeElementsFromList(element, bo.definition, 'items', null, [ bo.definition.items[idx] ]);
    },

    editable: function(element, node, prop, idx) {
      var bo = getSelected(element, node);
      var item = bo.definition.items[idx];
      return !isMap(item) && !isList(item) && !isScript(item);
    },

    setControlValue: function(element, node, input, prop, value, idx) {
      var bo = getSelected(element, node);
      var item = bo.definition.items[idx];

      if (!isMap(item) && !isList(item) && !isScript(item)) {
        input.value = value;
      } else {
        input.value = typeInfo[item.$type].label;
      }
    },

    show: function(element, node) {
      var bo = getSelected(element, node);
      return bo && bo.definition && isList(bo.definition);
    }

  }));


  // parameter value (type = map) ///////////////////////////////////////////////////////

  entries.push(entryFactory.table({
    id: idPrefix + 'parameterType-map',
    modelProperties: [ 'key', 'value' ],
    labels: [ translate('Key'), translate('Value') ],
    addLabel: translate('Add Entry'),

    getElements: function(element, node) {
      var bo = getSelected(element, node);

      if (bo && isMap(bo.definition)) {
        return bo.definition.entries;
      }

      return [];
    },

    updateElement: function(element, values, node, idx) {
      var bo = getSelected(element, node);
      var entry = bo.definition.entries[idx];

      if (isMap(entry.definition) || isList(entry.definition) || isScript(entry.definition)) {
        values = {
          key: values.key
        };
      }

      return cmdHelper.updateBusinessObject(element, entry, values);
    },

    addElement: function(element, node) {
      var bo = getSelected(element, node);
      var newEntry = createElement('activiti:Entry', bo.definition, bpmnFactory, { key: undefined, value: undefined });
      return cmdHelper.addElementsTolist(element, bo.definition, 'entries', [ newEntry ]);
    },

    removeElement: function(element, node, idx) {
      var bo = getSelected(element, node);
      return cmdHelper.removeElementsFromList(element, bo.definition, 'entries', null, [ bo.definition.entries[idx] ]);
    },

    editable: function(element, node, prop, idx) {
      var bo = getSelected(element, node);
      var entry = bo.definition.entries[idx];
      return prop === 'key' || (!isMap(entry.definition) && !isList(entry.definition) && !isScript(entry.definition));
    },

    setControlValue: function(element, node, input, prop, value, idx) {
      var bo = getSelected(element, node);
      var entry = bo.definition.entries[idx];

      if (prop === 'key' || (!isMap(entry.definition) && !isList(entry.definition) && !isScript(entry.definition))) {
        input.value = value;
      } else {
        input.value = typeInfo[entry.definition.$type].label;
      }
    },

    show: function(element, node) {
      var bo = getSelected(element, node);
      return bo && bo.definition && isMap(bo.definition);
    }

  }));

  return entries;

};

},{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/InputOutputHelper":596,"./Script":657,"bpmn-js/lib/util/ModelUtil":141}],651:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory');

var cmdHelper = require('../../../../helper/CmdHelper');

module.exports = function(element, bpmnFactory, options, translate) {

  var getBusinessObject = options.getBusinessObject;

  var jobPriorityEntry = entryFactory.textField({
    id: 'jobPriority',
    label: translate('Job Priority'),
    modelProperty: 'jobPriority',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      return {
        jobPriority: bo.get('activiti:jobPriority')
      };
    },

    set: function(element, values) {
      var bo = getBusinessObject(element);
      return cmdHelper.updateBusinessObject(element, bo, {
        'activiti:jobPriority': values.jobPriority || undefined
      });
    }

  });

  return [ jobPriorityEntry ];

};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],652:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is;

var entryFactory = require('../../../../factory/EntryFactory');

var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper');

var elementHelper = require('../../../../helper/ElementHelper'),
    eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'),
    cmdHelper = require('../../../../helper/CmdHelper');

function isAsyncBefore(bo) {
  return asyncCapableHelper.isAsyncBefore(bo);
}

function isAsyncAfter(bo) {
  return asyncCapableHelper.isAsyncAfter(bo);
}

function getFailedJobRetryTimeCycle(bo) {
  return asyncCapableHelper.getFailedJobRetryTimeCycle(bo);
}

function removeFailedJobRetryTimeCycle(bo, element) {
  return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element);
}

function createExtensionElements(parent, bpmnFactory) {
  return elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, parent, bpmnFactory);
}

function createFailedJobRetryTimeCycle(parent, bpmnFactory, cycle) {
  return elementHelper.createElement('activiti:FailedJobRetryTimeCycle', { body: cycle }, parent, bpmnFactory);
}

module.exports = function(element, bpmnFactory, options, translate) {

  var getBusinessObject = options.getBusinessObject;

  var idPrefix = options.idPrefix || '',
      labelPrefix = options.labelPrefix || '';

  var retryTimeCycleEntry = entryFactory.textField({
    id: idPrefix + 'retryTimeCycle',
    label: labelPrefix + translate('Retry Time Cycle'),
    modelProperty: 'cycle',

    get: function(element, node) {
      var retryTimeCycle = getFailedJobRetryTimeCycle(getBusinessObject(element));
      var value = retryTimeCycle && retryTimeCycle.get('body');
      return {
        cycle: value
      };
    },

    set: function(element, values, node) {
      var newCycle = values.cycle;
      var bo = getBusinessObject(element);

      if (newCycle === '' || typeof newCycle === 'undefined') {
        // remove retry time cycle element(s)
        return removeFailedJobRetryTimeCycle(bo, element);
      }

      var retryTimeCycle = getFailedJobRetryTimeCycle(bo);

      if (!retryTimeCycle) {
        // add new retry time cycle element
        var commands = [];

        var extensionElements = bo.get('extensionElements');
        if (!extensionElements) {
          extensionElements = createExtensionElements(bo, bpmnFactory);
          commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
        }

        retryTimeCycle = createFailedJobRetryTimeCycle(extensionElements, bpmnFactory, newCycle);
        commands.push(cmdHelper.addAndRemoveElementsFromList(
          element,
          extensionElements,
          'values',
          'extensionElements',
          [ retryTimeCycle ],
          []
        ));

        return commands;
      }

      // update existing retry time cycle element
      return cmdHelper.updateBusinessObject(element, retryTimeCycle, { body: newCycle });
    },

    hidden: function(element) {
      var bo = getBusinessObject(element);

      if (bo && (isAsyncBefore(bo) || isAsyncAfter(bo))) {
        return false;
      }

      if (is(element, 'bpmn:Event')) {
        return !eventDefinitionHelper.getTimerEventDefinition(element);
      }

      return true;
    }

  });

  return [ retryTimeCycleEntry ];

};

},{"../../../../factory/EntryFactory":579,"../../../../helper/AsyncCapableHelper":588,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/EventDefinitionHelper":592,"bpmn-js/lib/util/ModelUtil":141}],653:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var extensionElementsEntry = require('./ExtensionElements'),
    extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
    cmdHelper = require('../../../../helper/CmdHelper'),
    elementHelper = require('../../../../helper/ElementHelper'),
    ImplementationTypeHelper = require('../../../../helper/ImplementationTypeHelper');


function getListeners(bo, type) {
  return bo && extensionElementsHelper.getExtensionElements(bo, type) || [];
}

var ACTIVITI_EXECUTION_LISTENER_ELEMENT = 'activiti:ExecutionListener';
var ACTIVITI_TASK_LISTENER_ELEMENT = 'activiti:TaskListener';

module.exports = function(element, bpmnFactory, options, translate) {

  var LISTENER_TYPE_LABEL = {
    class: translate('Java Class'),
    expression: translate('Expression'),
    delegateExpression: translate('Delegate Expression'),
    script: translate('Script')
  };

  var bo;

  var result = {
    getSelectedListener: getSelectedListener
  };

  var entries = result.entries = [];

  var isSequenceFlow = ImplementationTypeHelper.isSequenceFlow(element);

  function getSelectedListener(element, node) {
    var selection = (executionListenerEntry && executionListenerEntry.getSelected(element, node)) || { idx: -1 };

    var listener = getListeners(bo, ACTIVITI_EXECUTION_LISTENER_ELEMENT)[selection.idx];
    if (!listener && taskListenerEntry) {
      selection = taskListenerEntry.getSelected(element, node);
      listener = getListeners(bo, ACTIVITI_TASK_LISTENER_ELEMENT)[selection.idx];
    }
    return listener;
  }

  var setOptionLabelValue = function(type) {
    return function(element, node, option, property, value, idx) {
      var listeners = getListeners(bo, type);
      var listener = listeners[idx];
      var listenerType = ImplementationTypeHelper.getImplementationType(listener);

      var event = (listener.get('event')) ? listener.get('event') : '<empty>';

      var label = (event || '*') + ' : ' + (LISTENER_TYPE_LABEL[listenerType] || '');

      option.text = label;
    };
  };

  var newElement = function(element, type, initialEvent) {
    return function(element, extensionElements, value) {
      var props = {
        event: initialEvent,
        class: ''
      };

      var newElem = elementHelper.createElement(type, props, extensionElements, bpmnFactory);

      return cmdHelper.addElementsTolist(element, extensionElements, 'values', [ newElem ]);
    };
  };

  var removeElement = function(element, type) {
    return function(element, extensionElements, value, idx) {
      var listeners = getListeners(bo, type);
      var listener = listeners[idx];
      if (listener) {
        return extensionElementsHelper.removeEntry(bo, element, listener);
      }
    };
  };


  // Execution Listener

  if (is(element, 'bpmn:FlowElement') || is(element, 'bpmn:Process') || is(element, 'bpmn:Participant')) {
    bo = getBusinessObject(element);
    if (is(element, 'bpmn:Participant')) {
      element = element.processRef;
      bo = bo.get('processRef');
    }

    if (bo) {

      var executionListenerEntry = extensionElementsEntry(element, bpmnFactory, {
        id : 'executionListeners',
        label : translate('Execution Listener'),
        modelProperty: 'name',
        idGeneration: 'false',
        reference: 'processRef',

        createExtensionElement: newElement(element, ACTIVITI_EXECUTION_LISTENER_ELEMENT, (isSequenceFlow) ? 'take' : 'start'),
        removeExtensionElement: removeElement(element, ACTIVITI_EXECUTION_LISTENER_ELEMENT),

        getExtensionElements: function(element) {
          return getListeners(bo, ACTIVITI_EXECUTION_LISTENER_ELEMENT);
        },

        onSelectionChange: function(element, node, event, scope) {
          taskListenerEntry && taskListenerEntry.deselect(element, node);
        },

        setOptionLabelValue: setOptionLabelValue(ACTIVITI_EXECUTION_LISTENER_ELEMENT)

      });
      entries.push(executionListenerEntry);

    }
  }


  // Task Listener

  if (is(element, 'bpmn:UserTask')) {
    bo = getBusinessObject(element);

    var taskListenerEntry = extensionElementsEntry(element, bpmnFactory, {
      id : 'taskListeners',
      label : translate('Task Listener'),
      modelProperty: 'name',
      idGeneration: 'false',

      createExtensionElement: newElement(element, ACTIVITI_TASK_LISTENER_ELEMENT, 'create'),
      removeExtensionElement: removeElement(element, ACTIVITI_TASK_LISTENER_ELEMENT),

      getExtensionElements: function(element) {
        return getListeners(bo, ACTIVITI_TASK_LISTENER_ELEMENT);
      },

      onSelectionChange: function(element, node, event, scope) {
        executionListenerEntry.deselect(element, node);
      },

      setOptionLabelValue: setOptionLabelValue(ACTIVITI_TASK_LISTENER_ELEMENT)

    });
    entries.push(taskListenerEntry);
  }

  return result;

};

},{"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"../../../../helper/ImplementationTypeHelper":595,"./ExtensionElements":643,"bpmn-js/lib/util/ModelUtil":141}],654:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    escapeHTML = require('../../../../Utils').escapeHTML;


var entryFactory = require('../../../../factory/EntryFactory');

var elementHelper = require('../../../../helper/ElementHelper'),
    cmdHelper = require('../../../../helper/CmdHelper');

var domClasses = require('min-dom').classes;

/**
 * Get a property value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 * @param {string} propertyName
 *
 * @return {any} the property value
 */
function getProperty(element, propertyName) {
  var loopCharacteristics = getLoopCharacteristics(element);
  return loopCharacteristics && loopCharacteristics.get(propertyName);
}

/**
 * Get the body of a given expression.
 *
 * @param {ModdleElement<bpmn:FormalExpression>} expression
 *
 * @return {string} the body (value) of the expression
 */
function getBody(expression) {
  return expression && expression.get('body');
}


/**
 * Get the loop characteristics of an element.
 *
 * @param {djs.model.Base} element
 *
 * @return {ModdleElement<bpmn:MultiInstanceLoopCharacteristics>} the loop characteristics
 */
function getLoopCharacteristics(element) {
  var bo = getBusinessObject(element);
  return bo.loopCharacteristics;
}

/**
 * Get the loop cardinality of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {ModdleElement<bpmn:FormalExpression>} an expression representing the loop cardinality
 */
function getLoopCardinality(element) {
  return getProperty(element, 'loopCardinality');
}

/**
 * Get the loop cardinality value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {string} the loop cardinality value
 */
function getLoopCardinalityValue(element) {
  var loopCardinality = getLoopCardinality(element);
  return getBody(loopCardinality);
}

/**
 * Get the completion condition of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {ModdleElement<bpmn:FormalExpression>} an expression representing the completion condition
 */
function getCompletionCondition(element) {
  return getProperty(element, 'completionCondition');
}

/**
 * Get the completion condition value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {string} the completion condition value
 */
function getCompletionConditionValue(element) {
  var completionCondition = getCompletionCondition(element);
  return getBody(completionCondition);
}

/**
 * Get the 'activiti:collection' attribute value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {string} the 'activiti:collection' value
 */
function getCollection(element) {
  return getProperty(element, 'activiti:collection');
}

/**
 * Get the 'activiti:elementVariable' attribute value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {string} the 'activiti:elementVariable' value
 */
function getElementVariable(element) {
  return getProperty(element, 'activiti:elementVariable');
}


/**
 * Creates 'bpmn:FormalExpression' element.
 *
 * @param {ModdleElement} parent
 * @param {string} body
 * @param {BpmnFactory} bpmnFactory
 *
 * @result {ModdleElement<bpmn:FormalExpression>} a formal expression
 */
function createFormalExpression(parent, body, bpmnFactory) {
  return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory);
}

/**
 * Updates a specific formal expression of the loop characteristics.
 *
 * @param {djs.model.Base} element
 * @param {string} propertyName
 * @param {string} newValue
 * @param {BpmnFactory} bpmnFactory
 */
function updateFormalExpression(element, propertyName, newValue, bpmnFactory) {
  var loopCharacteristics = getLoopCharacteristics(element);

  var expressionProps = {};

  if (!newValue) {
    // remove formal expression
    expressionProps[propertyName] = undefined;
    return cmdHelper.updateBusinessObject(element, loopCharacteristics, expressionProps);
  }

  var existingExpression = loopCharacteristics.get(propertyName);

  if (!existingExpression) {
    // add formal expression
    expressionProps[propertyName] = createFormalExpression(loopCharacteristics, newValue, bpmnFactory);
    return cmdHelper.updateBusinessObject(element, loopCharacteristics, expressionProps);
  }

  // edit existing formal expression
  return cmdHelper.updateBusinessObject(element, existingExpression, {
    body: newValue
  });
}


module.exports = function(element, bpmnFactory, translate) {

  var entries = [];

  // error message /////////////////////////////////////////////////////////////////

  entries.push({
    id: 'multiInstance-errorMessage',
    html: '<div data-show="isValid">' +
             '<span class="bpp-icon-warning"></span> ' +
             escapeHTML(translate('Must provide either loop cardinality or collection')) +
          '</div>',

    isValid: function(element, node, notification, scope) {
      var loopCharacteristics = getLoopCharacteristics(element);

      var isValid = true;
      if (loopCharacteristics) {
        var loopCardinality = getLoopCardinalityValue(element);
        var collection = getCollection(element);

        isValid = !loopCardinality && !collection;
      }

      domClasses(node).toggle('bpp-hidden', !isValid);
      domClasses(notification).toggle('bpp-error-message', isValid);

      return isValid;
    }
  });

  // loop cardinality //////////////////////////////////////////////////////////////

  entries.push(entryFactory.textField({
    id: 'multiInstance-loopCardinality',
    label: translate('Loop Cardinality'),
    modelProperty: 'loopCardinality',

    get: function(element, node) {
      return {
        loopCardinality: getLoopCardinalityValue(element)
      };
    },

    set: function(element, values) {
      return updateFormalExpression(element, 'loopCardinality', values.loopCardinality, bpmnFactory);
    }
  }));


  // collection //////////////////////////////////////////////////////////////////

  entries.push(entryFactory.textField({
    id: 'multiInstance-collection',
    label: translate('Collection'),
    modelProperty: 'collection',

    get: function(element, node) {
      return {
        collection: getCollection(element)
      };
    },

    set: function(element, values) {
      var loopCharacteristics = getLoopCharacteristics(element);
      return cmdHelper.updateBusinessObject(element, loopCharacteristics, {
        'activiti:collection': values.collection || undefined
      });
    },

    validate: function(element, values, node) {
      var collection = getCollection(element);
      var elementVariable = getElementVariable(element);

      if (!collection && elementVariable) {
        return { collection : 'Must provide a value' };
      }
    }
  }));


  // element variable ////////////////////////////////////////////////////////////

  entries.push(entryFactory.textField({
    id: 'multiInstance-elementVariable',
    label: translate('Element Variable'),
    modelProperty: 'elementVariable',

    get: function(element, node) {
      return {
        elementVariable: getElementVariable(element)
      };
    },

    set: function(element, values) {
      var loopCharacteristics = getLoopCharacteristics(element);
      return cmdHelper.updateBusinessObject(element, loopCharacteristics, {
        'activiti:elementVariable': values.elementVariable || undefined
      });
    }
  }));


  // Completion Condition //////////////////////////////////////////////////////

  entries.push(entryFactory.textField({
    id: 'multiInstance-completionCondition',
    label: translate('Completion Condition'),
    modelProperty: 'completionCondition',

    get: function(element) {
      return {
        completionCondition: getCompletionConditionValue(element)
      };
    },

    set: function(element, values) {
      return updateFormalExpression(element, 'completionCondition', values.completionCondition, bpmnFactory);
    }
  }));

  return entries;

};

},{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"bpmn-js/lib/util/ModelUtil":141,"min-dom":556}],655:[function(require,module,exports){
'use strict';

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    is = require('bpmn-js/lib/util/ModelUtil').is;

var factory = require('../../../../factory/EntryFactory');

var elementHelper = require('../../../../helper/ElementHelper'),
    extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
    cmdHelper = require('../../../../helper/CmdHelper'),
    utils = require('../../../../Utils');

var assign = require('lodash/assign'),
    forEach = require('lodash/forEach'),
    find = require('lodash/find');

function generatePropertyId() {
  return utils.nextId('Property_');
}

/**
 * Get all activiti:property objects for a specific business object
 *
 * @param  {ModdleElement} parent
 *
 * @return {Array<ModdleElement>} a list of activiti:property objects
 */
function getPropertyValues(parent) {
  var properties = parent && getPropertiesElement(parent);
  if (properties && properties.values) {
    return properties.values;
  }
  return [];
}

/**
 * Get all activiti:Properties object for a specific business object
 *
 * @param  {ModdleElement} parent
 *
 * @return {ModdleElement} a activiti:Properties object
 */
function getPropertiesElement(element) {
  if (!isExtensionElements(element)) {
    return element.properties;
  } else {
    return getPropertiesElementInsideExtensionElements(element);
  }
}

/**
 * Get first activiti:Properties object for a specific bpmn:ExtensionElements
 * business object.
 *
 * @param {ModdleElement} extensionElements
 *
 * @return {ModdleElement} a activiti:Properties object
 */
function getPropertiesElementInsideExtensionElements(extensionElements) {
  return find(extensionElements.values, function(elem) {
    return is(elem, 'activiti:Properties');
  });
}

/**
 * Returns true, if the given business object is a bpmn:ExtensionElements.
 *
 * @param {ModdleElement} element
 *
 * @return {boolean} a boolean value
 */
function isExtensionElements(element) {
  return is(element, 'bpmn:ExtensionElements');
}

/**
 * Create a activiti:property entry using tableEntryFactory
 *
 * @param  {djs.model.Base} element
 * @param  {BpmnFactory} bpmnFactory
 * @param  {Object} options
 * @param  {string} options.id
 * @param  {Array<string>} options.modelProperties
 * @param  {Array<string>} options.labels
 * @param  {function} options.getParent Gets the parent business object
 * @param  {function} options.show Indicate when the entry will be shown, should return boolean
 */
module.exports = function(element, bpmnFactory, options, translate) {

  var getParent = options.getParent;

  var modelProperties = options.modelProperties,
      createParent = options.createParent;

  var bo = getBusinessObject(element);
  if (is(element, 'bpmn:Participant')) {
    bo = bo.get('processRef');
  }

  // build properties group only when the participant have a processRef
  if (!bo) {
    return;
  }

  assign(options, {
    addLabel: translate('Add Property'),
    getElements: function(element, node) {
      var parent = getParent(element, node, bo);
      return getPropertyValues(parent);
    },
    addElement: function(element, node) {
      var commands = [],
          parent = getParent(element, node, bo);

      if (!parent && typeof createParent === 'function') {
        var result = createParent(element, bo);
        parent = result.parent;
        commands.push(result.cmd);
      }

      var properties = getPropertiesElement(parent);
      if (!properties) {
        properties = elementHelper.createElement('activiti:Properties', {}, parent, bpmnFactory);

        if (!isExtensionElements(parent)) {
          commands.push(cmdHelper.updateBusinessObject(element, parent, { 'properties': properties }));
        } else {
          commands.push(cmdHelper.addAndRemoveElementsFromList(
            element,
            parent,
            'values',
            'extensionElements',
            [ properties ],
            []
          ));
        }
      }

      var propertyProps = {};
      forEach(modelProperties, function(prop) {
        propertyProps[prop] = undefined;
      });

      // create id if necessary
      if (modelProperties.indexOf('id') >= 0) {
        propertyProps.id = generatePropertyId();
      }

      var property = elementHelper.createElement('activiti:Property', propertyProps, properties, bpmnFactory);
      commands.push(cmdHelper.addElementsTolist(element, properties, 'values', [ property ]));

      return commands;
    },
    updateElement: function(element, value, node, idx) {
      var parent = getParent(element, node, bo),
          property = getPropertyValues(parent)[idx];

      forEach(modelProperties, function(prop) {
        value[prop] = value[prop] || undefined;
      });

      return cmdHelper.updateBusinessObject(element, property, value);
    },
    validate: function(element, value, node, idx) {
      // validate id if necessary
      if (modelProperties.indexOf('id') >= 0) {

        var parent = getParent(element, node, bo),
            properties = getPropertyValues(parent),
            property = properties[idx];

        if (property) {
          // check if id is valid
          var validationError = utils.isIdValid(property, value.id, translate);

          if (validationError) {
            return { id: validationError };
          }
        }
      }
    },
    removeElement: function(element, node, idx) {
      var commands = [],
          parent = getParent(element, node, bo),
          properties = getPropertiesElement(parent),
          propertyValues = getPropertyValues(parent),
          currentProperty = propertyValues[idx];

      commands.push(cmdHelper.removeElementsFromList(element, properties, 'values', null, [ currentProperty ]));

      if (propertyValues.length === 1) {
        // remove activiti:properties if the last existing property has been removed
        if (!isExtensionElements(parent)) {
          commands.push(cmdHelper.updateBusinessObject(element, parent, { properties: undefined }));
        } else {
          forEach(parent.values, function(value) {
            if (is(value, 'activiti:Properties')) {
              commands.push(extensionElementsHelper.removeEntry(bo, element, value));
            }
          });
        }
      }

      return commands;
    }
  });

  return factory.table(options);
};

},{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513,"lodash/find":519,"lodash/forEach":522}],656:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is;

var assign = require('lodash/assign');

var entryFactory = require('../../../../factory/EntryFactory'),
    cmdHelper = require('../../../../helper/CmdHelper');

module.exports = function(element, bpmnFactory, options, translate) {

  var getBusinessObject = options.getBusinessObject,
      hideResultVariable = options.hideResultVariable,
      id = options.id || 'resultVariable';


  var resultVariableEntry = entryFactory.textField({
    id: id,
    label: translate('Result Variable'),
    modelProperty: 'resultVariable',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      return { resultVariable: bo.get('activiti:resultVariable') };
    },

    set: function(element, values, node) {
      var bo = getBusinessObject(element);

      var resultVariable = values.resultVariable || undefined;

      var props = {
        'activiti:resultVariable': resultVariable
      };

      if (is(bo, 'activiti:DmnCapable') && !resultVariable) {
        props = assign({ 'activiti:mapDecisionResult': 'resultList' }, props);
      }

      return cmdHelper.updateBusinessObject(element, bo, props);
    },

    hidden: function(element, node) {
      if (typeof hideResultVariable === 'function') {
        return hideResultVariable.apply(resultVariableEntry, arguments);
      }
    }

  });

  return [ resultVariableEntry ];

};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513}],657:[function(require,module,exports){
'use strict';

var domQuery = require('min-dom').query,
    escapeHTML = require('../../../../Utils').escapeHTML,
    utils = require('../../../../Utils');


function getScriptType(node) {
  return utils.selectedType('select[name=scriptType]', node.parentElement);
}


module.exports = function(scriptLanguagePropName, scriptValuePropName, isFormatRequired, translate) {

  return {
    template:
    '<div class="bpp-row bpp-textfield">' +
      '<label for="cam-script-format">' + escapeHTML(translate('Script Format')) + '</label>' +
      '<div class="bpp-field-wrapper">' +
        '<input id="cam-script-format" type="text" name="scriptFormat" />' +
        '<button class="clear" data-action="script.clearScriptFormat" data-show="script.canClearScriptFormat">' +
          '<span>X</span>' +
        '</button>' +
      '</div>' +
    '</div>' +

    '<div class="bpp-row">' +
      '<label for="cam-script-type">' + escapeHTML(translate('Script Type')) + '</label>' +
      '<div class="bpp-field-wrapper">' +
        '<select id="cam-script-type" name="scriptType" data-value>' +
          '<option value="script" selected>' + escapeHTML(translate('Inline Script')) + '</option>' +
          '<option value="scriptResource">' + escapeHTML(translate('External Resource')) + '</option>' +
        '</select>' +
      '</div>' +
    '</div>' +

    '<div class="bpp-row bpp-textfield">' +
      '<label for="cam-script-resource-val" data-show="script.isScriptResource">' + escapeHTML(translate('Resource')) + '</label>' +
      '<div class="bpp-field-wrapper" data-show="script.isScriptResource">' +
        '<input id="cam-script-resource-val" type="text" name="scriptResourceValue" />' +
        '<button class="clear" data-action="script.clearScriptResource" data-show="script.canClearScriptResource">' +
          '<span>X</span>' +
        '</button>' +
      '</div>' +
    '</div>' +

    '<div class="bpp-row">' +
      '<label for="cam-script-val" data-show="script.isScript">' + escapeHTML(translate('Script')) + '</label>' +
      '<div class="bpp-field-wrapper" data-show="script.isScript">' +
        '<textarea id="cam-script-val" type="text" name="scriptValue"></textarea>' +
      '</div>'+
    '</div>',

    get: function(element, bo) {
      var values = {};

      // read values from xml:
      var boScriptResource = bo.get('activiti:resource'),
          boScript = bo.get(scriptValuePropName),
          boScriptFormat = bo.get(scriptLanguagePropName);

      if (typeof boScriptResource !== 'undefined') {
        values.scriptResourceValue = boScriptResource;
        values.scriptType = 'scriptResource';
      } else {
        values.scriptValue = boScript;
        values.scriptType = 'script';
      }

      values.scriptFormat = boScriptFormat;

      return values;
    },

    set: function(element, values, containerElement) {
      var scriptFormat = values.scriptFormat,
          scriptType = values.scriptType,
          scriptResourceValue = values.scriptResourceValue,
          scriptValue = values.scriptValue;

      // init update
      var update = {
        'activiti:resource': undefined
      };
      update[scriptValuePropName] = undefined;
      update[scriptLanguagePropName] = undefined;

      if (isFormatRequired) {
        // always set language
        update[scriptLanguagePropName] = scriptFormat || '';
      } else
      // set language only when scriptFormat has a value
      if (scriptFormat !== '') {
        update[scriptLanguagePropName] = scriptFormat;
      }

      // set either inline script or resource
      if ('scriptResource' === scriptType) {
        update['activiti:resource'] = scriptResourceValue || '';
      } else {
        update[scriptValuePropName] = scriptValue || '';
      }

      return update;
    },

    validate: function(element, values) {
      var validationResult = {};

      if (values.scriptType === 'script' && !values.scriptValue) {
        validationResult.scriptValue = translate('Must provide a value');
      }

      if (values.scriptType === 'scriptResource' && !values.scriptResourceValue) {
        validationResult.scriptResourceValue = translate('Must provide a value');
      }

      if (isFormatRequired && (!values.scriptFormat || values.scriptFormat.length === 0)) {
        validationResult.scriptFormat = translate('Must provide a value');
      }

      return validationResult;
    },

    clearScriptFormat: function(element, inputNode, btnNode, scopeNode) {
      domQuery('input[name=scriptFormat]', scopeNode).value='';

      return true;
    },

    canClearScriptFormat: function(element, inputNode, btnNode, scopeNode) {
      var input = domQuery('input[name=scriptFormat]', scopeNode);

      return input.value !== '';
    },

    clearScriptResource: function(element, inputNode, btnNode, scopeNode) {
      domQuery('input[name=scriptResourceValue]', scopeNode).value='';

      return true;
    },

    canClearScriptResource: function(element, inputNode, btnNode, scopeNode) {
      var input = domQuery('input[name=scriptResourceValue]', scopeNode);

      return input.value !== '';
    },

    clearScript: function(element, inputNode, btnNode, scopeNode) {
      domQuery('textarea[name=scriptValue]', scopeNode).value='';

      return true;
    },

    canClearScript: function(element, inputNode, btnNode, scopeNode) {
      var input = domQuery('textarea[name=scriptValue]', scopeNode);

      return input.value !== '';
    },

    isScriptResource: function(element, inputNode, btnNode, scopeNode) {
      var scriptType = getScriptType(scopeNode);
      return scriptType === 'scriptResource';
    },

    isScript: function(element, inputNode, btnNode, scopeNode) {
      var scriptType = getScriptType(scopeNode);
      return scriptType === 'script';
    }

  };

};

},{"../../../../Utils":576,"min-dom":556}],658:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory');

var cmdHelper = require('../../../../helper/CmdHelper');

module.exports = function(element, bpmnFactory, options, translate) {

  var getBusinessObject = options.getBusinessObject;

  var isStartableInTasklistEntry = entryFactory.checkbox({
    id: 'isStartableInTasklist',
    label: translate('Startable'),
    modelProperty: 'isStartableInTasklist',

    get: function(element, node) {
      var bo = getBusinessObject(element);
      var isStartableInTasklist = bo.get('activiti:isStartableInTasklist');

      return {
        isStartableInTasklist: isStartableInTasklist ? isStartableInTasklist : ''
      };
    },

    set: function(element, values) {
      var bo = getBusinessObject(element);
      return cmdHelper.updateBusinessObject(element, bo, {
        'activiti:isStartableInTasklist': !!values.isStartableInTasklist
      });
    }

  });

  return [
    isStartableInTasklistEntry
  ];
};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],659:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../factory/EntryFactory'),
    cmdHelper = require('../../../helper/CmdHelper');

var ModelUtil = require('bpmn-js/lib/util/ModelUtil'),
    is = ModelUtil.is,
    getBusinessObject = ModelUtil.getBusinessObject;


module.exports = function(group, element, bpmnFactory, translate) {

  var getValue = function(businessObject) {
    return function(element) {
      var documentations = businessObject && businessObject.get('documentation'),
          text = (documentations && documentations.length > 0) ? documentations[0].text : '';

      return { documentation: text };
    };
  };

  var setValue = function(businessObject) {
    return function(element, values) {
      var newObjectList = [];

      if (typeof values.documentation !== 'undefined' && values.documentation !== '') {
        newObjectList.push(bpmnFactory.create('bpmn:Documentation', {
          text: values.documentation
        }));
      }

      return cmdHelper.setList(element, businessObject, 'documentation', newObjectList);
    };
  };

  // Element Documentation
  var elementDocuEntry = entryFactory.textBox({
    id: 'documentation',
    label: translate('Element Documentation'),
    modelProperty: 'documentation'
  });

  elementDocuEntry.set = setValue(getBusinessObject(element));

  elementDocuEntry.get = getValue(getBusinessObject(element));

  group.entries.push(elementDocuEntry);


  var processRef;

  // Process Documentation when having a Collaboration Diagram
  if (is(element, 'bpmn:Participant')) {

    processRef = getBusinessObject(element).processRef;

    // do not show for collapsed Pools/Participants
    if (processRef) {
      var processDocuEntry = entryFactory.textBox({
        id: 'process-documentation',
        label: translate('Process Documentation'),
        modelProperty: 'documentation'
      });

      processDocuEntry.set = setValue(processRef);

      processDocuEntry.get = getValue(processRef);

      group.entries.push(processDocuEntry);
    }
  }

};

},{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141}],660:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    eventDefinitionHelper = require('../../../helper/EventDefinitionHelper');

var forEach = require('lodash/forEach');

var message = require('./implementation/MessageEventDefinition'),
    signal = require('./implementation/SignalEventDefinition'),
    error = require('./implementation/ErrorEventDefinition'),
    escalation = require('./implementation/EscalationEventDefinition'),
    timer = require('./implementation/TimerEventDefinition'),
    compensation = require('./implementation/CompensateEventDefinition'),
    condition = require('./implementation/ConditionalEventDefinition');


module.exports = function(group, element, bpmnFactory, elementRegistry, translate) {
  var events = [
    'bpmn:StartEvent',
    'bpmn:EndEvent',
    'bpmn:IntermediateThrowEvent',
    'bpmn:BoundaryEvent',
    'bpmn:IntermediateCatchEvent'
  ];

  // Message and Signal Event Definition
  forEach(events, function(event) {
    if (is(element, event)) {

      var messageEventDefinition = eventDefinitionHelper.getMessageEventDefinition(element),
          signalEventDefinition = eventDefinitionHelper.getSignalEventDefinition(element);

      if (messageEventDefinition) {
        message(group, element, bpmnFactory, messageEventDefinition, translate);
      }

      if (signalEventDefinition) {
        signal(group, element, bpmnFactory, signalEventDefinition, translate);
      }

    }
  });

  // Special Case: Receive Task
  if (is(element, 'bpmn:ReceiveTask')) {
    message(group, element, bpmnFactory, getBusinessObject(element), translate);
  }

  // Error Event Definition
  var errorEvents = [
    'bpmn:StartEvent',
    'bpmn:BoundaryEvent',
    'bpmn:EndEvent'
  ];

  forEach(errorEvents, function(event) {
    if (is(element, event)) {

      var errorEventDefinition = eventDefinitionHelper.getErrorEventDefinition(element);

      if (errorEventDefinition) {

        error(group, element, bpmnFactory, errorEventDefinition, translate);
      }
    }
  });

  // Escalation Event Definition
  var escalationEvents = [
    'bpmn:StartEvent',
    'bpmn:BoundaryEvent',
    'bpmn:IntermediateThrowEvent',
    'bpmn:EndEvent'
  ];

  forEach(escalationEvents, function(event) {
    if (is(element, event)) {

      var showEscalationCodeVariable = is(element, 'bpmn:StartEvent') || is(element, 'bpmn:BoundaryEvent');

      // get business object
      var escalationEventDefinition = eventDefinitionHelper.getEscalationEventDefinition(element);

      if (escalationEventDefinition) {
        escalation(group, element, bpmnFactory, escalationEventDefinition, showEscalationCodeVariable,
          translate);
      }
    }

  });

  // Timer Event Definition
  var timerEvents = [
    'bpmn:StartEvent',
    'bpmn:BoundaryEvent',
    'bpmn:IntermediateCatchEvent'
  ];

  forEach(timerEvents, function(event) {
    if (is(element, event)) {

      // get business object
      var timerEventDefinition = eventDefinitionHelper.getTimerEventDefinition(element);

      if (timerEventDefinition) {
        timer(group, element, bpmnFactory, timerEventDefinition, translate);
      }
    }
  });

  // Compensate Event Definition
  var compensationEvents = [
    'bpmn:EndEvent',
    'bpmn:IntermediateThrowEvent'
  ];

  forEach(compensationEvents, function(event) {
    if (is(element, event)) {

      // get business object
      var compensateEventDefinition = eventDefinitionHelper.getCompensateEventDefinition(element);

      if (compensateEventDefinition) {
        compensation(group, element, bpmnFactory, compensateEventDefinition, elementRegistry, translate);
      }
    }
  });


  // Conditional Event Definition
  var conditionalEvents = [
    'bpmn:StartEvent',
    'bpmn:BoundaryEvent',
    'bpmn:IntermediateThrowEvent',
    'bpmn:IntermediateCatchEvent'
  ];

  if (isAny(element, conditionalEvents)) {

    // get business object
    var conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(element);

    if (conditionalEventDefinition) {
      condition(group, element, bpmnFactory, conditionalEventDefinition, elementRegistry, translate);
    }
  }

};

},{"../../../helper/EventDefinitionHelper":592,"./implementation/CompensateEventDefinition":666,"./implementation/ConditionalEventDefinition":667,"./implementation/ErrorEventDefinition":669,"./implementation/EscalationEventDefinition":670,"./implementation/MessageEventDefinition":672,"./implementation/SignalEventDefinition":674,"./implementation/TimerEventDefinition":675,"bpmn-js/lib/features/modeling/util/ModelingUtil":112,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],661:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

var entryFactory = require('../../../factory/EntryFactory');

var participantHelper = require('../../../helper/ParticipantHelper');

module.exports = function(group, element, translate) {

  var bo = getBusinessObject(element);

  if (!bo) {
    return;
  }

  if (is(element, 'bpmn:Process') || (is(element, 'bpmn:Participant') && bo.get('processRef'))) {

    var executableEntry = entryFactory.checkbox({
      id: 'process-is-executable',
      label: translate('Executable'),
      modelProperty: 'isExecutable'
    });

    // in participants we have to change the default behavior of set and get
    if (is(element, 'bpmn:Participant')) {
      executableEntry.get = function(element) {
        return participantHelper.getProcessBusinessObject(element, 'isExecutable');
      };

      executableEntry.set = function(element, values) {
        return participantHelper.modifyProcessBusinessObject(element, 'isExecutable', values);
      };
    }

    group.entries.push(executableEntry);
  }

};

},{"../../../factory/EntryFactory":579,"../../../helper/ParticipantHelper":597,"bpmn-js/lib/util/ModelUtil":141}],662:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../factory/EntryFactory'),
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    utils = require('../../../Utils'),
    cmdHelper = require('../../../helper/CmdHelper');

module.exports = function(group, element, translate, options) {

  var description = options && options.description;

  // Id
  group.entries.push(entryFactory.validationAwareTextField({
    id: 'id',
    label: translate('Id'),
    description: description && translate(description),
    modelProperty: 'id',
    getProperty: function(element) {
      return getBusinessObject(element).id;
    },
    setProperty: function(element, properties) {

      element = element.labelTarget || element;

      return cmdHelper.updateProperties(element, properties);
    },
    validate: function(element, values) {
      var idValue = values.id;

      var bo = getBusinessObject(element);

      var idError = utils.isIdValid(bo, idValue, translate);

      return idError ? { id: idError } : {};
    }
  }));

};

},{"../../../Utils":576,"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141}],663:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    entryFactory = require('../../../factory/EntryFactory'),
    cmdHelper = require('../../../helper/CmdHelper');

var forEach = require('lodash/forEach');

function getLinkEventDefinition(element) {

  var bo = getBusinessObject(element);

  var linkEventDefinition = null;
  if (bo.eventDefinitions) {
    forEach(bo.eventDefinitions, function(eventDefinition) {
      if (is(eventDefinition, 'bpmn:LinkEventDefinition')) {
        linkEventDefinition = eventDefinition;
      }
    });
  }

  return linkEventDefinition;
}

module.exports = function(group, element, translate) {
  var linkEvents = [ 'bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent' ];

  forEach(linkEvents, function(event) {
    if (is(element, event)) {

      var linkEventDefinition = getLinkEventDefinition(element);

      if (linkEventDefinition) {
        var entry = entryFactory.textField({
          id: 'link-event',
          label: translate('Link Name'),
          modelProperty: 'link-name'
        });

        entry.get = function() {
          return { 'link-name': linkEventDefinition.get('name') };
        };

        entry.set = function(element, values) {
          var newProperties = {
            name: values['link-name']
          };
          return cmdHelper.updateBusinessObject(element, linkEventDefinition, newProperties);
        };

        group.entries.push(entry);
      }
    }
  });
};


},{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],664:[function(require,module,exports){
'use strict';

var nameEntryFactory = require('./implementation/Name'),
    createCategoryValue = require('../../../helper/CategoryHelper').createCategoryValue,
    is = require('bpmn-js/lib/util/ModelUtil').is,
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;

module.exports = function(group, element, bpmnFactory, canvas, translate) {

  function initializeCategory(semantic) {
    var rootElement = canvas.getRootElement(),
        definitions = getBusinessObject(rootElement).$parent,
        categoryValue = createCategoryValue(definitions, bpmnFactory);

    semantic.categoryValueRef = categoryValue;

  }

  function setGroupName(element, values) {
    var bo = getBusinessObject(element),
        categoryValueRef = bo.categoryValueRef;

    if (!categoryValueRef) {
      initializeCategory(bo);
    }

    // needs direct call to update categoryValue properly
    return {
      cmd: 'element.updateLabel',
      context: {
        element: element,
        newLabel: values.categoryValue
      }
    };
  }

  function getGroupName(element) {
    var bo = getBusinessObject(element),
        value = (bo.categoryValueRef || {}).value;

    return { categoryValue: value };
  }

  if (!is(element, 'bpmn:Collaboration')) {

    var options;
    if (is(element, 'bpmn:TextAnnotation')) {
      options = { modelProperty: 'text', label: translate('Text') };
    } else if (is(element, 'bpmn:Group')) {
      options = {
        modelProperty: 'categoryValue',
        label: translate('Category Value'),
        get: getGroupName,
        set: setGroupName
      };
    }

    // name
    group.entries = group.entries.concat(nameEntryFactory(element, options, translate));

  }

};

},{"../../../helper/CategoryHelper":589,"./implementation/Name":673,"bpmn-js/lib/util/ModelUtil":141}],665:[function(require,module,exports){
'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is,
    entryFactory = require('../../../factory/EntryFactory'),
    participantHelper = require('../../../helper/ParticipantHelper'),
    getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    nameEntryFactory = require('./implementation/Name'),
    utils = require('../../../Utils');

module.exports = function(group, element, translate, options) {
  var businessObject = getBusinessObject(element);

  var processIdDescription = options && options.processIdDescription;

  if (is(element, 'bpmn:Process') || (is(element, 'bpmn:Participant') && businessObject.get('processRef'))) {

    /**
     * processId
     */
    if (is(element, 'bpmn:Participant')) {
      var idEntry = entryFactory.validationAwareTextField({
        id: 'process-id',
        label: translate('Process Id'),
        description: processIdDescription && translate(processIdDescription),
        modelProperty: 'processId'
      });

      // in participants we have to change the default behavior of set and get
      idEntry.get = function(element) {
        var properties = participantHelper.getProcessBusinessObject(element, 'id');
        return { processId: properties.id };
      };

      idEntry.set = function(element, values) {
        return participantHelper.modifyProcessBusinessObject(element, 'id', { id: values.processId });
      };

      idEntry.validate = function(element, values) {
        var idValue = values.processId;

        var bo = getBusinessObject(element);

        var processIdError = utils.isIdValid(bo.processRef, idValue, translate);

        return processIdError ? { processId: processIdError } : {};
      };

      group.entries.push(idEntry);


      /**
       * process name
       */
      var processNameEntry = nameEntryFactory(element, {
        id: 'process-name',
        label: translate('Process Name')
      })[0];

      // in participants we have to change the default behavior of set and get
      processNameEntry.get = function(element) {
        return participantHelper.getProcessBusinessObject(element, 'name');
      };

      processNameEntry.set = function(element, values) {
        return participantHelper.modifyProcessBusinessObject(element, 'name', values);
      };

      group.entries.push(processNameEntry);
    }
  }
};

},{"../../../Utils":576,"../../../factory/EntryFactory":579,"../../../helper/ParticipantHelper":597,"./implementation/Name":673,"bpmn-js/lib/util/ModelUtil":141}],666:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory');

var cmdHelper = require('../../../../helper/CmdHelper'),
    eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'),
    utils = require('../../../../Utils');

var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject,
    is = require('bpmn-js/lib/util/ModelUtil').is;

var forEach = require('lodash/forEach'),
    find = require('lodash/find'),
    filter = require('lodash/filter');


function getContainedActivities(element) {
  return getFlowElements(element, 'bpmn:Activity');
}

function getContainedBoundaryEvents(element) {
  return getFlowElements(element, 'bpmn:BoundaryEvent');
}

function getFlowElements(element, type) {
  return utils.filterElementsByType(element.flowElements, type);
}

function isCompensationEventAttachedToActivity(activity, boundaryEvents) {
  var activityId = activity.id;
  var boundaryEvent = find(boundaryEvents, function(boundaryEvent) {
    var compensateEventDefinition = eventDefinitionHelper.getCompensateEventDefinition(boundaryEvent);
    var attachedToRef = boundaryEvent.attachedToRef;
    return compensateEventDefinition && attachedToRef && attachedToRef.id === activityId;
  });
  return !!boundaryEvent;
}

// subprocess: only when it is not triggeredByEvent
// activity: only when it attach a compensation boundary event
// callActivity: no limitation
function canActivityBeCompensated(activity, boundaryEvents) {
  return (is(activity, 'bpmn:SubProcess') && !activity.triggeredByEvent) ||
          is(activity, 'bpmn:CallActivity') ||
          isCompensationEventAttachedToActivity(activity, boundaryEvents);
}

function getActivitiesForCompensation(element) {
  var boundaryEvents = getContainedBoundaryEvents(element);
  return filter(getContainedActivities(element), function(activity) {
    return canActivityBeCompensated(activity, boundaryEvents);
  });
}

function getActivitiesForActivityRef(element) {
  var bo = getBusinessObject(element);
  var parent = bo.$parent;

  var activitiesForActivityRef = getActivitiesForCompensation(parent);

  // if throwing compensation event is in an event sub process:
  // get also all activities outside of the event sub process
  if (is(parent, 'bpmn:SubProcess') && parent.triggeredByEvent) {
    parent = parent.$parent;
    if (parent) {
      activitiesForActivityRef = activitiesForActivityRef.concat(getActivitiesForCompensation(parent));
    }

  }

  return activitiesForActivityRef;
}

function createActivityRefOptions(element) {
  var options = [ { value: '' } ];

  var activities = getActivitiesForActivityRef(element);
  forEach(activities, function(activity) {
    var activityId = activity.id;
    var name = (activity.name ? (activity.name + ' ') : '') + '(id=' + activityId + ')';
    options.push({ value: activityId, name: name });
  });

  return options;
}


module.exports = function(group, element, bpmnFactory, compensateEventDefinition, elementRegistry, translate) {

  group.entries.push(entryFactory.checkbox({
    id: 'wait-for-completion',
    label: translate('Wait for Completion'),
    modelProperty: 'waitForCompletion',

    get: function(element, node) {
      return {
        waitForCompletion: compensateEventDefinition.waitForCompletion
      };
    },

    set: function(element, values) {
      values.waitForCompletion = values.waitForCompletion || false;
      return cmdHelper.updateBusinessObject(element, compensateEventDefinition, values);
    }
  }));

  group.entries.push(entryFactory.selectBox({
    id: 'activity-ref',
    label: translate('Activity Ref'),
    selectOptions: createActivityRefOptions(element),
    modelProperty: 'activityRef',

    get: function(element, node) {
      var activityRef = compensateEventDefinition.activityRef;
      activityRef = activityRef && activityRef.id;
      return {
        activityRef: activityRef || ''
      };
    },

    set: function(element, values) {
      var activityRef = values.activityRef || undefined;
      activityRef = activityRef && getBusinessObject(elementRegistry.get(activityRef));
      return cmdHelper.updateBusinessObject(element, compensateEventDefinition, {
        activityRef: activityRef
      });
    }
  }));

};

},{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/EventDefinitionHelper":592,"bpmn-js/lib/util/ModelUtil":141,"lodash/filter":518,"lodash/find":519,"lodash/forEach":522}],667:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory'),
    cmdHelper = require('../../../../helper/CmdHelper');

var is = require('bpmn-js/lib/util/ModelUtil').is,
    isEventSubProcess = require('bpmn-js/lib/util/DiUtil').isEventSubProcess;

module.exports = function(group, element, bpmnFactory, conditionalEventDefinition, elementRegistry, translate) {

  var getValue = function(modelProperty) {
    return function(element) {
      var modelPropertyValue = conditionalEventDefinition.get('camunda:' + modelProperty);
      var value = {};

      value[modelProperty] = modelPropertyValue;
      return value;
    };
  };

  var setValue = function(modelProperty) {
    return function(element, values) {
      var props = {};

      props['camunda:' + modelProperty] = values[modelProperty] || undefined;

      return cmdHelper.updateBusinessObject(element, conditionalEventDefinition, props);
    };
  };

  group.entries.push(entryFactory.textField({
    id: 'variableName',
    label: translate('Variable Name'),
    modelProperty : 'variableName',

    get: getValue('variableName'),
    set: setValue('variableName')
  }));

  var isConditionalStartEvent =
    is(element, 'bpmn:StartEvent') && !isEventSubProcess(element.parent);

  if (!isConditionalStartEvent) {
    group.entries.push(entryFactory.textField({
      id: 'variableEvent',
      label: translate('Variable Event'),
      description: translate('Specify more than one variable change event as a comma separated list.'),
      modelProperty : 'variableEvent',

      get: getValue('variableEvent'),
      set: setValue('variableEvent')
    }));
  }
};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"bpmn-js/lib/util/DiUtil":139,"bpmn-js/lib/util/ModelUtil":141}],668:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory');

var cmdHelper = require('../../../../helper/CmdHelper');

/**
 * Create an entry to modify a property of an element which
 * is referenced by a event definition.
 *
 * @param  {djs.model.Base} element
 * @param  {ModdleElement} definition
 * @param  {BpmnFactory} bpmnFactory
 * @param  {Object} options
 * @param  {string} options.id the id of the entry
 * @param  {string} options.label the label of the entry
 * @param  {string} options.referenceProperty the name of referencing property
 * @param  {string} options.modelProperty the name of property to modify
 * @param  {string} options.shouldValidate a flag indicate whether to validate or not
 *
 * @return {Array<Object>} return an array containing the entries
 */
module.exports = function(element, definition, bpmnFactory, options) {

  var id = options.id || 'element-property';
  var label = options.label;
  var referenceProperty = options.referenceProperty;
  var modelProperty = options.modelProperty || 'name';
  var shouldValidate = options.shouldValidate || false;

  var entry = entryFactory.textField({
    id: id,
    label: label,
    modelProperty: modelProperty,

    get: function(element, node) {
      var reference = definition.get(referenceProperty);
      var props = {};
      props[modelProperty] = reference && reference.get(modelProperty);
      return props;
    },

    set: function(element, values, node) {
      var reference = definition.get(referenceProperty);
      var props = {};
      props[modelProperty] = values[modelProperty] || undefined;
      return cmdHelper.updateBusinessObject(element, reference, props);
    },

    hidden: function(element, node) {
      return !definition.get(referenceProperty);
    }
  });

  if (shouldValidate) {
    entry.validate = function(element, values, node) {
      var reference = definition.get(referenceProperty);
      if (reference && !values[modelProperty]) {
        var validationErrors = {};
        validationErrors[modelProperty] = 'Must provide a value';
        return validationErrors;
      }
    };
  }

  return [ entry ];
};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],669:[function(require,module,exports){
'use strict';

var eventDefinitionReference = require('./EventDefinitionReference'),
    elementReferenceProperty = require('./ElementReferenceProperty');


module.exports = function(group, element, bpmnFactory, errorEventDefinition, translate) {


  group.entries = group.entries.concat(eventDefinitionReference(element, errorEventDefinition, bpmnFactory, {
    label: translate('Error'),
    elementName: 'error',
    elementType: 'bpmn:Error',
    referenceProperty: 'errorRef',
    newElementIdPrefix: 'Error_'
  }));


  group.entries = group.entries.concat(elementReferenceProperty(element, errorEventDefinition, bpmnFactory, {
    id: 'error-element-name',
    label: translate('Error Name'),
    referenceProperty: 'errorRef',
    modelProperty: 'name',
    shouldValidate: true
  }));


  group.entries = group.entries.concat(elementReferenceProperty(element, errorEventDefinition, bpmnFactory, {
    id: 'error-element-code',
    label: translate('Error Code'),
    referenceProperty: 'errorRef',
    modelProperty: 'errorCode'
  }));

};

},{"./ElementReferenceProperty":668,"./EventDefinitionReference":671}],670:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory'),
    cmdHelper = require('../../../../helper/CmdHelper');

var eventDefinitionReference = require('./EventDefinitionReference'),
    elementReferenceProperty = require('./ElementReferenceProperty');


module.exports = function(group, element, bpmnFactory, escalationEventDefinition, showEscalationCodeVariable, translate) {

  group.entries = group.entries.concat(eventDefinitionReference(element, escalationEventDefinition, bpmnFactory, {
    label: translate('Escalation'),
    elementName: 'escalation',
    elementType: 'bpmn:Escalation',
    referenceProperty: 'escalationRef',
    newElementIdPrefix: 'Escalation_'
  }));


  group.entries = group.entries.concat(elementReferenceProperty(element, escalationEventDefinition, bpmnFactory, {
    id: 'escalation-element-name',
    label: translate('Escalation Name'),
    referenceProperty: 'escalationRef',
    modelProperty: 'name',
    shouldValidate: true
  }));


  group.entries = group.entries.concat(elementReferenceProperty(element, escalationEventDefinition, bpmnFactory, {
    id: 'escalation-element-code',
    label: translate('Escalation Code'),
    referenceProperty: 'escalationRef',
    modelProperty: 'escalationCode'
  }));


  if (showEscalationCodeVariable) {
    group.entries.push(entryFactory.textField({
      id : 'escalationCodeVariable',
      label : translate('Escalation Code Variable'),
      modelProperty : 'escalationCodeVariable',

      get: function(element) {
        var codeVariable = escalationEventDefinition.get('camunda:escalationCodeVariable');
        return {
          escalationCodeVariable: codeVariable
        };
      },

      set: function(element, values) {
        return cmdHelper.updateBusinessObject(element, escalationEventDefinition, {
          'camunda:escalationCodeVariable': values.escalationCodeVariable || undefined
        });
      }
    }));
  }
};

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"./ElementReferenceProperty":668,"./EventDefinitionReference":671}],671:[function(require,module,exports){
'use strict';

var cmdHelper = require('../../../../helper/CmdHelper');

var domQuery = require('min-dom').query,
    domify = require('min-dom').domify,
    domAttr = require('min-dom').attr;

var forEach = require('lodash/forEach'),
    find = require('lodash/find');

var elementHelper = require('../../../../helper/ElementHelper');
var utils = require('../../../../Utils'),
    escapeHTML = utils.escapeHTML;

var selector = 'select[name=selectedElement]';

/**
 * Get select box containing all elements.
 *
 * @param {DOMElement} node
 *
 * @return {DOMElement} the select box
 */
function getSelectBox(node) {
  return domQuery(selector, node.parentElement);
}

/**
 * Find element by given id.
 *
 * @param {ModdleElement} eventDefinition
 *
 * @return {ModdleElement} an element
 */
function findElementById(eventDefinition, type, id) {
  var elements = utils.findRootElementsByType(eventDefinition, type);
  return find(elements, function(element) {
    return element.id === id;
  });
}

/**
 * Create an entry to modify the reference to an element from an
 * event definition.
 *
 * @param  {djs.model.Base} element
 * @param  {ModdleElement} definition
 * @param  {BpmnFactory} bpmnFactory
 * @param  {Object} options
 * @param  {string} options.label the label of the entry
 * @param  {string} options.description the description of the entry
 * @param  {string} options.elementName the name of the element
 * @param  {string} options.elementType the type of the element
 * @param  {string} options.referenceProperty the name of referencing property
 * @param  {string} options.newElementIdPrefix the prefix of a new created element
 *
 * @return {Array<Object>} return an array containing the entries
 */
module.exports = function(element, definition, bpmnFactory, options) {

  var elementName = options.elementName || '',
      elementType = options.elementType,
      referenceProperty = options.referenceProperty;

  var newElementIdPrefix = options.newElementIdPrefix || 'elem_';

  var label = options.label || '',
      description = options.description || '';

  var entries = [];

  entries.push({

    id: 'event-definitions-' + elementName,
    description: description,
    html: '<div class="bpp-row bpp-select">' +
             '<label for="camunda-' + escapeHTML(elementName) + '">' + escapeHTML(label) + '</label>' +
             '<div class="bpp-field-wrapper">' +
               '<select id="camunda-' + escapeHTML(elementName) + '" name="selectedElement" data-value>' +
               '</select>' +
               '<button class="add" id="addElement" data-action="addElement"><span>+</span></button>' +
             '</div>' +
          '</div>',

    get: function(element, entryNode) {
      utils.updateOptionsDropDown(selector, definition, elementType, entryNode);
      var reference = definition.get(referenceProperty);
      return {
        selectedElement: (reference && reference.id) || ''
      };
    },

    set: function(element, values) {
      var selection = values.selectedElement;

      var props = {};

      if (!selection || typeof selection === 'undefined') {
        // remove reference to element
        props[referenceProperty] = undefined;
        return cmdHelper.updateBusinessObject(element, definition, props);
      }

      var commands = [];

      var selectedElement = findElementById(definition, elementType, selection);
      if (!selectedElement) {
        var root = utils.getRoot(definition);

        // create a new element
        selectedElement = elementHelper.createElement(elementType, { name: selection }, root, bpmnFactory);
        commands.push(cmdHelper.addAndRemoveElementsFromList(element, root, 'rootElements', null, [ selectedElement ]));
      }

      // update reference to element
      props[referenceProperty] = selectedElement;
      commands.push(cmdHelper.updateBusinessObject(element, definition, props));

      return commands;
    },

    addElement: function(element, inputNode) {
      // note: this generated id will be used as name
      // of the element and not as id
      var id = utils.nextId(newElementIdPrefix);

      var optionTemplate = domify('<option value="' + escapeHTML(id) + '"> (id='+escapeHTML(id)+')' + '</option>');

      // add new option
      var selectBox = getSelectBox(inputNode);
      selectBox.insertBefore(optionTemplate, selectBox.firstChild);

      // select new element in the select box
      forEach(selectBox, function(option) {
        if (option.value === id) {
          domAttr(option, 'selected', 'selected');
        } else {
          domAttr(option, 'selected', null);
        }
      });

      return true;
    }

  });

  return entries;

};

},{"../../../../Utils":576,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"lodash/find":519,"lodash/forEach":522,"min-dom":556}],672:[function(require,module,exports){
'use strict';

var eventDefinitionReference = require('./EventDefinitionReference'),
    elementReferenceProperty = require('./ElementReferenceProperty');


module.exports = function(group, element, bpmnFactory, messageEventDefinition, translate) {

  group.entries = group.entries.concat(eventDefinitionReference(element, messageEventDefinition, bpmnFactory, {
    label: translate('Message'),
    elementName: 'message',
    elementType: 'bpmn:Message',
    referenceProperty: 'messageRef',
    newElementIdPrefix: 'Message_'
  }));


  group.entries = group.entries.concat(elementReferenceProperty(element, messageEventDefinition, bpmnFactory, {
    id: 'message-element-name',
    label: translate('Message Name'),
    referenceProperty: 'messageRef',
    modelProperty: 'name',
    shouldValidate: true
  }));

};

},{"./ElementReferenceProperty":668,"./EventDefinitionReference":671}],673:[function(require,module,exports){
'use strict';

var entryFactory = require('../../../../factory/EntryFactory');

/**
 * Create an entry to modify the name of an an element.
 *
 * @param  {djs.model.Base} element
 * @param  {Object} options
 * @param  {string} options.id the id of the entry
 * @param  {string} options.label the label of the entry
 *
 * @return {Array<Object>} return an array containing
 *                         the entry to modify the name
 */
module.exports = function(element, options, translate) {

  options = options || {};
  var id = options.id || 'name',
      label = options.label || translate('Name'),
      modelProperty = options.modelProperty || 'name';

  var nameEntry = entryFactory.textBox({
    id: id,
    label: label,
    modelProperty: modelProperty,
    get: options.get,
    set: options.set
  });

  return [ nameEntry ];

};

},{"../../../../factory/EntryFactory":579}],674:[function(require,module,exports){
'use strict';

var eventDefinitionReference = require('./EventDefinitionReference'),
    elementReferenceProperty = require('./ElementReferenceProperty');


module.exports = function(group, element, bpmnFactory, signalEventDefinition, translate) {

  group.entries = group.entries.concat(eventDefinitionReference(element, signalEventDefinition, bpmnFactory, {
    label: translate('Signal'),
    elementName: 'signal',
    elementType: 'bpmn:Signal',
    referenceProperty: 'signalRef',
    newElementIdPrefix: 'Signal_'
  }));


  group.entries = group.entries.concat(elementReferenceProperty(element, signalEventDefinition, bpmnFactory, {
    id: 'signal-element-name',
    label: translate('Signal Name'),
    referenceProperty: 'signalRef',
    modelProperty: 'name',
    shouldValidate: true
  }));

};

},{"./ElementReferenceProperty":668,"./EventDefinitionReference":671}],675:[function(require,module,exports){
'use strict';

var elementHelper = require('../../../../helper/ElementHelper'),
    cmdHelper = require('../../../../helper/CmdHelper');

var entryFactory = require('../../../../factory/EntryFactory');

/**
 * Get the timer definition type for a given timer event definition.
 *
 * @param {ModdleElement<bpmn:TimerEventDefinition>} timer
 *
 * @return {string|undefined} the timer definition type
 */
function getTimerDefinitionType(timer) {
  var timeDate = timer.get('timeDate');
  if (typeof timeDate !== 'undefined') {
    return 'timeDate';
  }

  var timeCycle = timer.get('timeCycle');
  if (typeof timeCycle !== 'undefined') {
    return 'timeCycle';
  }

  var timeDuration = timer.get('timeDuration');
  if (typeof timeDuration !== 'undefined') {
    return 'timeDuration';
  }
}

/**
 * Creates 'bpmn:FormalExpression' element.
 *
 * @param {ModdleElement} parent
 * @param {string} body
 * @param {BpmnFactory} bpmnFactory
 *
 * @return {ModdleElement<bpmn:FormalExpression>} a formal expression
 */
function createFormalExpression(parent, body, bpmnFactory) {
  body = body || undefined;
  return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory);
}

function TimerEventDefinition(group, element, bpmnFactory, timerEventDefinition, translate) {

  var selectOptions = [
    { value: 'timeDate', name: translate('Date') },
    { value: 'timeDuration', name: translate('Duration') },
    { value: 'timeCycle', name: translate('Cycle') }
  ];

  group.entries.push(entryFactory.selectBox({
    id: 'timer-event-definition-type',
    label: translate('Timer Definition Type'),
    selectOptions: selectOptions,
    emptyParameter: true,
    modelProperty: 'timerDefinitionType',

    get: function(element, node) {
      return {
        timerDefinitionType: getTimerDefinitionType(timerEventDefinition) || ''
      };
    },

    set: function(element, values) {
      var props = {
        timeDuration: undefined,
        timeDate: undefined,
        timeCycle: undefined
      };

      var newType = values.timerDefinitionType;
      if (values.timerDefinitionType) {
        var oldType = getTimerDefinitionType(timerEventDefinition);

        var value;
        if (oldType) {
          var definition = timerEventDefinition.get(oldType);
          value = definition.get('body');
        }

        props[newType] = createFormalExpression(timerEventDefinition, value, bpmnFactory);
      }

      return cmdHelper.updateBusinessObject(element, timerEventDefinition, props);
    }

  }));


  group.entries.push(entryFactory.textField({
    id: 'timer-event-definition',
    label: translate('Timer Definition'),
    modelProperty: 'timerDefinition',

    get: function(element, node) {
      var type = getTimerDefinitionType(timerEventDefinition);
      var definition = type && timerEventDefinition.get(type);
      var value = definition && definition.get('body');
      return {
        timerDefinition: value
      };
    },

    set: function(element, values) {
      var type = getTimerDefinitionType(timerEventDefinition);
      var definition = type && timerEventDefinition.get(type);

      if (definition) {
        return cmdHelper.updateBusinessObject(element, definition, {
          body: values.timerDefinition || undefined
        });
      }
    },

    validate: function(element) {
      var type = getTimerDefinitionType(timerEventDefinition);
      var definition = type && timerEventDefinition.get(type);
      if (definition) {
        var value = definition.get('body');
        if (!value) {
          return {
            timerDefinition: translate('Must provide a value')
          };
        }
      }
    },

    hidden: function(element) {
      return !getTimerDefinitionType(timerEventDefinition);
    }

  }));

}

module.exports = TimerEventDefinition;

},{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591}],676:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _jquery = _interopRequireDefault(require("jquery"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * @description 全局功能封装
 * @author zr
 * @type {{registerFileDrop(*, *): void, saveBpmn(Object): void, handleDragOver(*): void, setColor(Object): void, downLoad(Object): void, upload(Object, Object, Object): void, handleFileSelect(*): void, setEncoded(Object, string, string): void, openFromUrl(Object, Object, Object, string): void, createDiagram(string, Object, Object): Promise<void>, getUrlParam: tools.getUrlParam}}
 */
const proHost = window.location.protocol + "//" + window.location.host;
const href = window.location.href.split("bpmnjs")[0];
const key = href.split(window.location.host)[1];
const publicurl = proHost + key;
const tools = {
  registerFileDrop(container, callback) {
    container.get(0).addEventListener('dragover', tools.handleDragOver, false);
    container.get(0).addEventListener('drop', tools.handleFileSelect, false);
  },

  /**
   * 获取地址栏参数
   * @param {string} value
   */
  getUrlParam: function (url) {
    var object = {};

    if (url.indexOf("?") != -1) {
      var str = url.split("?")[1];
      var strs = str.split("&");

      for (var i = 0; i < strs.length; i++) {
        object[strs[i].split("=")[0]] = strs[i].split("=")[1];
      }

      return object;
    }

    return object[url];
  },

  /**
   * 通过xml创建bpmn
   * @param {string} xml 创建bpms xml
   * @param {object} bpmnModeler bpmn对象
   * @param {object} container 容器对象
   */
  async createDiagram(xml, bpmnModeler, container) {
    try {
      await bpmnModeler.importXML(xml);
      container.removeClass('with-error').addClass('with-diagram');
    } catch (err) {
      container.removeClass('with-diagram').addClass('with-error');
      container.find('.error pre').text(err.message);
      console.error(err);
    }
  },

  /**
   * 通过Json设置颜色
   * @param {object} json json 字符串
   */
  setColor(json, bpmnModeler) {
    var modeling = bpmnModeler.get('modeling');
    var elementRegistry = bpmnModeler.get('elementRegistry');
    var elementToColor = elementRegistry.get(json.name);

    if (elementToColor) {
      modeling.setColor([elementToColor], {
        stroke: json.stroke,
        fill: json.fill
      });
    }
  },

  /**
   * 保存bpmn对象
   * @param {object} bpmnModeler bpmn对象
   */
  saveBpmn(bpmnModeler,modelId) {
    bpmnModeler.saveXML({
      format: true
    }, function (err, xml) {
      if (err) {
        return console.error('保存失败,请重试', err);
      }

      var param = {
        "stringBPMN": xml,
        "modelId":modelId
      };
      _jquery.default.ajax({
        url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/actModel/update',
        type: 'POST',
        dataType: "json",
headers: {
                    'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'),
                  },
        data: param,
        //headers:{'Content-Type':'application/json;charset=utf8'},
        success: function (result) {
          if (result.code === 200) {
            tools.syhide('alert');
            alert(result.msg);
          } else {
            tools.syhide('alert');
            alert(result.msg);
          }
        },
        error: function (err) {
          console.log(err);
        }
      });
    });
  },

  /**
   * 下载bpmn
   * @param {object} bpmnModeler bpmn对象
   */
  downLoad(bpmnModeler) {
    var downloadLink = (0, _jquery.default)("#downloadBpmn");
    bpmnModeler.saveXML({
      format: true
    }, function (err, xml) {
      if (err) {
        return console.error('could not save BPMN 2.0 diagram', err);
      }

      tools.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml);
    });
  },

  /**
   * 转码xml并下载
   * @param {object} link 按钮
   * @param {string} name 下载名称
   * @param {string} data base64XML
   */
  setEncoded(link, name, data) {
    var encodedData = encodeURIComponent(data);

    if (data) {
      link.addClass('active').attr({
        'href': 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData,
        'download': name
      });
    } else {
      link.removeClass('active');
    }
  },

  /**
   * 上传bpmn
   * @param {object} bpmnModeler bpmn对象
   * @param {object} container 容器对象
   */
  upload(bpmnModeler, container) {
    var FileUpload = document.myForm.uploadFile.files[0];
    var fm = new FormData();
    fm.append('processFile', FileUpload);

    _jquery.default.ajax({
      url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/processDefinition/upload',
      // url: 'http://localhost:8080/processDefinition/upload',
      type: 'POST',
headers: {
                    'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'),
                  },
      data: fm,
      async: false,
      contentType: false,
      //禁止设置请求类型
      processData: false,
      //禁止jquery对DAta数据的处理,默认会处理
      success: function (result) {
        var url = result.data.substr(0, 4) == "http" ? result.data : localStorage.getItem("VUE_APP_BASE_API") + result.data;
        tools.openFromUrl(bpmnModeler, container, url);
      },
      error: function (err) {
        console.log(err);
      }
    });
  },

  /**
   * 打开xml  Url 地址
   * @param {object} bpmnModeler bpmn对象
   * @param {object} container 容器对象
   * @param {string} url url地址
   */
  openFromUrl(bpmnModeler, container, url) {
    _jquery.default.ajax(url, {
      dataType: 'text'
    }).done(async function (xml) {
      try {
        await bpmnModeler.importXML(xml);
        container.removeClass('with-error').addClass('with-diagram');
      } catch (err) {
        console.error(err);
      }
    });
  },

  /**
   * 打开弹出框
   * @param id
   */
  syopen(id) {
    var dom = (0, _jquery.default)("#" + id);
    this.sycenter(dom);
    dom.addClass(name);
    dom.show();
    var that = this;
    (0, _jquery.default)(".sy-mask").fadeIn(300);
    setTimeout(function () {
      dom.removeClass(name);
    }, 300);
  },

  /**
   * 隐藏弹出框
   * @param id
   */
  syhide(id) {
    if (typeof id == "undefined") {
      var dom = (0, _jquery.default)(".sy-alert");
    } else {
      var dom = (0, _jquery.default)("#" + id);
    }

    var name = dom.attr("sy-leave");
    dom.addClass(name);
    (0, _jquery.default)(".sy-mask").fadeOut(300);
    setTimeout(function () {
      dom.hide();
      dom.removeClass(name);
    }, 300);
  },

  /**
   * 弹出框居中
   * @param dom
   */
  sycenter(dom) {
    var mgtop = parseFloat(dom.height() / 2);
    dom.css({
      "top": "50%",
      "margin-top": "-" + mgtop + "px"
    });
  },

  /**
   * 判断是否是数组
   * @param value
   * @returns {arg is Array<any>|boolean}
   */
  isArrayFn(value) {
    if (typeof Array.isArray === "function") {
      return Array.isArray(value);
    } else {
      return Object.prototype.toString.call(value) === "[object Array]";
    }
  },

  /**
   * 根据数据设置颜色
   * @param data
   * @returns {Array}
   */
  getByColor(data) {
    var ColorJson = [];

    for (var k in data['highLine']) {
      var par = {
        "name": data['highLine'][k],
        "stroke": "green",
        "fill": "green"
      };
      ColorJson.push(par);
    }

    for (var k in data['highPoint']) {
      var par = {
        "name": data['highPoint'][k],
        "stroke": "gray",
        "fill": "#eae9e9"
      };
      ColorJson.push(par);
    }

    for (var k in data['iDo']) {
      var par = {
        "name": data['iDo'][k],
        "stroke": "green",
        "fill": "#a3d68e"
      };
      ColorJson.push(par);
    }

    for (var k in data['waitingToDo']) {
      var par = {
        "name": data['waitingToDo'][k],
        "stroke": "green",
        "fill": "yellow"
      };
      ColorJson.push(par);
    }

    return ColorJson;
  }

};
var _default = tools;
exports.default = _default;

},{"jquery":348}]},{},[1])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJhcHAvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMtcHJvcGVydGllcy1wYW5lbC9saWIvUHJvcGVydGllc1BhbmVsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMtcHJvcGVydGllcy1wYW5lbC9saWIvVXRpbHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2xpYi9jbWQvQ3JlYXRlQW5kUmVmZXJlbmNlSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzLXByb3BlcnRpZXMtcGFuZWwvbGliL2NtZC9DcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMtcHJvcGVydGllcy1wYW5lbC9saWIvY21kL011bHRpQ29tbWFuZEhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2xpYi9jbWQvVXBkYXRlQnVzaW5lc3NPYmplY3RIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMtcHJvcGVydGllcy1wYW5lbC9saWIvY21kL1VwZGF0ZUJ1c2luZXNzT2JqZWN0TGlzdEhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2xpYi9jbWQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2xpYi9oZWxwZXIvRWxlbWVudEhlbHBlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzLXByb3BlcnRpZXMtcGFuZWwvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL0Jhc2VNb2RlbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL0Jhc2VWaWV3ZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvTW9kZWxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9OYXZpZ2F0ZWRWaWV3ZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvVmlld2VyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2NvcmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZHJhdy9CcG1uUmVuZGVyVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9kcmF3L0JwbW5SZW5kZXJlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9kcmF3L1BhdGhNYXAuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZHJhdy9UZXh0UmVuZGVyZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZHJhdy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXBsYWNlL0JwbW5BdXRvUGxhY2UuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvYXV0by1wbGFjZS9CcG1uQXV0b1BsYWNlVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXBsYWNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2F1dG8tcmVzaXplL0JwbW5BdXRvUmVzaXplLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2F1dG8tcmVzaXplL0JwbW5BdXRvUmVzaXplUHJvdmlkZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvYXV0by1yZXNpemUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvY29udGV4dC1wYWQvQ29udGV4dFBhZFByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2NvbnRleHQtcGFkL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2NvcHktcGFzdGUvQnBtbkNvcHlQYXN0ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9jb3B5LXBhc3RlL01vZGRsZUNvcHkuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvY29weS1wYXN0ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9kaS1vcmRlcmluZy9CcG1uRGlPcmRlcmluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9kaS1vcmRlcmluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9kaXN0cmlidXRlLWVsZW1lbnRzL0JwbW5EaXN0cmlidXRlRWxlbWVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9lZGl0b3ItYWN0aW9ucy9CcG1uRWRpdG9yQWN0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9lZGl0b3ItYWN0aW9ucy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL0JwbW5HcmlkU25hcHBpbmcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9iZWhhdmlvci9BdXRvUGxhY2VCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL2JlaGF2aW9yL0NyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9iZWhhdmlvci9MYXlvdXRDb25uZWN0aW9uQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9iZWhhdmlvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2ludGVyYWN0aW9uLWV2ZW50cy9CcG1uSW50ZXJhY3Rpb25FdmVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvaW50ZXJhY3Rpb24tZXZlbnRzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2tleWJvYXJkL0JwbW5LZXlib2FyZEJpbmRpbmdzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2tleWJvYXJkL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2xhYmVsLWVkaXRpbmcvTGFiZWxFZGl0aW5nUHJldmlldy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9sYWJlbC1lZGl0aW5nL0xhYmVsRWRpdGluZ1Byb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2xhYmVsLWVkaXRpbmcvTGFiZWxVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2xhYmVsLWVkaXRpbmcvY21kL1VwZGF0ZUxhYmVsSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9sYWJlbC1lZGl0aW5nL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL0JwbW5GYWN0b3J5LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL0JwbW5MYXlvdXRlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9CcG1uVXBkYXRlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9FbGVtZW50RmFjdG9yeS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9Nb2RlbGluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9BZGFwdGl2ZUxhYmVsUG9zaXRpb25pbmdCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9BcHBlbmRCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9Bc3NvY2lhdGlvbkJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0F0dGFjaEV2ZW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvQm91bmRhcnlFdmVudEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0NyZWF0ZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0NyZWF0ZURhdGFPYmplY3RCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9DcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0RhdGFJbnB1dEFzc29jaWF0aW9uQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvRGF0YVN0b3JlQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvRGVsZXRlTGFuZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0RldGFjaEV2ZW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvRHJvcE9uRmxvd0JlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0V2ZW50QmFzZWRHYXRld2F5QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvRml4SG92ZXJCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9Hcm91cEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0ltcG9ydERvY2tpbmdGaXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvSXNIb3Jpem9udGFsRml4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0xhYmVsQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvTW9kZWxpbmdGZWVkYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9SZW1vdmVFbGVtZW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvUmVtb3ZlUGFydGljaXBhbnRCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9SZXBsYWNlQ29ubmVjdGlvbkJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1JlcGxhY2VFbGVtZW50QmVoYXZpb3VyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1Jlc2l6ZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1Jlc2l6ZUxhbmVCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9Sb290RWxlbWVudFJlZmVyZW5jZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1NwYWNlVG9vbEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1N1YlByb2Nlc3NTdGFydEV2ZW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvVG9nZ2xlRWxlbWVudENvbGxhcHNlQmVoYXZpb3VyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1VuY2xhaW1JZEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1Vuc2V0RGVmYXVsdEZsb3dCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9VcGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci91dGlsL0NhdGVnb3J5VXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci91dGlsL0dlb21ldHJpY1V0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvdXRpbC9MYWJlbExheW91dFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvdXRpbC9MaW5lQXR0YWNobWVudFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvdXRpbC9MaW5lSW50ZXJzZWN0LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL3V0aWwvUmVzaXplVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvQWRkTGFuZUhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL0lkQ2xhaW1IYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9SZXNpemVMYW5lSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvU2V0Q29sb3JIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9TcGxpdExhbmVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9VcGRhdGVDYW52YXNSb290SGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvVXBkYXRlRmxvd05vZGVSZWZzSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvVXBkYXRlUHJvcGVydGllc0hhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL1VwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy91dGlsL0xhbmVVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL29yZGVyaW5nL0JwbW5PcmRlcmluZ1Byb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL29yZGVyaW5nL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3BhbGV0dGUvUGFsZXR0ZVByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3BhbGV0dGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvcG9wdXAtbWVudS9SZXBsYWNlTWVudVByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3BvcHVwLW1lbnUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvcG9wdXAtbWVudS91dGlsL1R5cGVVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3JlcGxhY2UtcHJldmlldy9CcG1uUmVwbGFjZVByZXZpZXcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvcmVwbGFjZS1wcmV2aWV3L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3JlcGxhY2UvQnBtblJlcGxhY2UuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvcmVwbGFjZS9SZXBsYWNlT3B0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9yZXBsYWNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3J1bGVzL0JwbW5SdWxlcy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9ydWxlcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9zZWFyY2gvQnBtblNlYXJjaFByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3NlYXJjaC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9CcG1uQ29ubmVjdFNuYXBwaW5nLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3NuYXBwaW5nL0JwbW5DcmVhdGVNb3ZlU25hcHBpbmcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvc25hcHBpbmcvQnBtblNuYXBwaW5nVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9pbXBvcnQvQnBtbkltcG9ydGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ltcG9ydC9CcG1uVHJlZVdhbGtlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9pbXBvcnQvSW1wb3J0ZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvaW1wb3J0L1V0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvaW1wb3J0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL3V0aWwvQ29tcGF0aWJpbGl0eVV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvdXRpbC9EaVV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvdXRpbC9MYWJlbFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvdXRpbC9Qb3dlcmVkQnlVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvRGlhZ3JhbS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRTdGFjay5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb21tYW5kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2NvcmUvQ2FudmFzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2NvcmUvRWxlbWVudEZhY3RvcnkuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvY29yZS9FbGVtZW50UmVnaXN0cnkuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvY29yZS9FdmVudEJ1cy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb3JlL0dyYXBoaWNzRmFjdG9yeS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb3JlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2RyYXcvQmFzZVJlbmRlcmVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2RyYXcvRGVmYXVsdFJlbmRlcmVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2RyYXcvU3R5bGVzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2RyYXcvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYWxpZ24tZWxlbWVudHMvQWxpZ25FbGVtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hbGlnbi1lbGVtZW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hdHRhY2gtc3VwcG9ydC9BdHRhY2hTdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F0dGFjaC1zdXBwb3J0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F1dG8tcGxhY2UvQXV0b1BsYWNlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F1dG8tcGxhY2UvQXV0b1BsYWNlU2VsZWN0aW9uQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1wbGFjZS9BdXRvUGxhY2VVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F1dG8tcGxhY2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1yZXNpemUvQXV0b1Jlc2l6ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXJlc2l6ZS9BdXRvUmVzaXplUHJvdmlkZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1zY3JvbGwvQXV0b1Njcm9sbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXNjcm9sbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9iZW5kcG9pbnRzL0JlbmRwb2ludE1vdmUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYmVuZHBvaW50cy9CZW5kcG9pbnRNb3ZlUHJldmlldy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9iZW5kcG9pbnRzL0JlbmRwb2ludFNuYXBwaW5nLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2JlbmRwb2ludHMvQmVuZHBvaW50VXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9iZW5kcG9pbnRzL0JlbmRwb2ludHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYmVuZHBvaW50cy9Db25uZWN0aW9uU2VnbWVudE1vdmUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYmVuZHBvaW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jaGFuZ2Utc3VwcG9ydC9DaGFuZ2VTdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NoYW5nZS1zdXBwb3J0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NsaXBib2FyZC9DbGlwYm9hcmQuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY2xpcGJvYXJkL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2Nvbm5lY3QvQ29ubmVjdC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jb25uZWN0L0Nvbm5lY3RQcmV2aWV3LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2Nvbm5lY3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY29ubmVjdGlvbi1wcmV2aWV3L0Nvbm5lY3Rpb25QcmV2aWV3LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2Nvbm5lY3Rpb24tcHJldmlldy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jb250ZXh0LXBhZC9Db250ZXh0UGFkLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvbnRleHQtcGFkL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvcHktcGFzdGUvQ29weVBhc3RlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvcHktcGFzdGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY3JlYXRlL0NyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jcmVhdGUvQ3JlYXRlUHJldmlldy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jcmVhdGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cy9EaXN0cmlidXRlRWxlbWVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9kcmFnZ2luZy9EcmFnZ2luZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9kcmFnZ2luZy9Ib3ZlckZpeC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9kcmFnZ2luZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9lZGl0b3ItYWN0aW9ucy9FZGl0b3JBY3Rpb25zLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2VkaXRvci1hY3Rpb25zL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2dsb2JhbC1jb25uZWN0L0dsb2JhbENvbm5lY3QuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZ2xvYmFsLWNvbm5lY3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9HcmlkU25hcHBpbmcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9HcmlkVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL2JlaGF2aW9yL1Jlc2l6ZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2dyaWQtc25hcHBpbmcvYmVoYXZpb3IvU3BhY2VUb29sQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9iZWhhdmlvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2hhbmQtdG9vbC9IYW5kVG9vbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9oYW5kLXRvb2wvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvaW50ZXJhY3Rpb24tZXZlbnRzL0ludGVyYWN0aW9uRXZlbnRzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2ludGVyYWN0aW9uLWV2ZW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9rZXlib2FyZC1tb3ZlLXNlbGVjdGlvbi9LZXlib2FyZE1vdmVTZWxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQtbW92ZS1zZWxlY3Rpb24vaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQvS2V5Ym9hcmQuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQvS2V5Ym9hcmRCaW5kaW5ncy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9rZXlib2FyZC9LZXlib2FyZFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbGFiZWwtc3VwcG9ydC9MYWJlbFN1cHBvcnQuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbGFiZWwtc3VwcG9ydC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9sYXNzby10b29sL0xhc3NvVG9vbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9sYXNzby10b29sL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL01vZGVsaW5nLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9BbGlnbkVsZW1lbnRzSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvQXBwZW5kU2hhcGVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9DcmVhdGVDb25uZWN0aW9uSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvQ3JlYXRlRWxlbWVudHNIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9DcmVhdGVMYWJlbEhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL0NyZWF0ZVNoYXBlSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL0RlbGV0ZUVsZW1lbnRzSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvRGVsZXRlU2hhcGVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9EaXN0cmlidXRlRWxlbWVudHNIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9MYXlvdXRDb25uZWN0aW9uSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvTW92ZUNvbm5lY3Rpb25IYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9Nb3ZlRWxlbWVudHNIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9Nb3ZlU2hhcGVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9SZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvUmVwbGFjZVNoYXBlSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvUmVzaXplU2hhcGVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9TcGFjZVRvb2xIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9Ub2dnbGVTaGFwZUNvbGxhcHNlSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvVXBkYXRlQXR0YWNobWVudEhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL1VwZGF0ZVdheXBvaW50c0hhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL2hlbHBlci9BbmNob3JzSGVscGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9oZWxwZXIvTW92ZUNsb3N1cmUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL2hlbHBlci9Nb3ZlSGVscGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdXNlL01vdXNlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdmUvTW92ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb3ZlL01vdmVQcmV2aWV3LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvb3JkZXJpbmcvT3JkZXJpbmdQcm92aWRlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9vdXRsaW5lL091dGxpbmUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvb3V0bGluZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9vdmVybGF5cy9PdmVybGF5cy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9vdmVybGF5cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wYWxldHRlL1BhbGV0dGUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcGFsZXR0ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wb3B1cC1tZW51L1BvcHVwTWVudS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wb3B1cC1tZW51L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3ByZXZpZXctc3VwcG9ydC9QcmV2aWV3U3VwcG9ydC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wcmV2aWV3LXN1cHBvcnQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcmVwbGFjZS9SZXBsYWNlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3JlcGxhY2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcmVzaXplL1Jlc2l6ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvUmVzaXplSGFuZGxlcy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvUmVzaXplUHJldmlldy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvUmVzaXplVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcnVsZXMvUnVsZVByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3J1bGVzL1J1bGVzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3J1bGVzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NlYXJjaC1wYWQvU2VhcmNoUGFkLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NlYXJjaC1wYWQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc2VsZWN0aW9uL1NlbGVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zZWxlY3Rpb24vU2VsZWN0aW9uQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc2VsZWN0aW9uL1NlbGVjdGlvblZpc3VhbHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc2VsZWN0aW9uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NuYXBwaW5nL0NyZWF0ZU1vdmVTbmFwcGluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9SZXNpemVTbmFwcGluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwQ29udGV4dC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwcGluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zcGFjZS10b29sL1NwYWNlVG9vbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zcGFjZS10b29sL1NwYWNlVG9vbFByZXZpZXcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc3BhY2UtdG9vbC9TcGFjZVV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc3BhY2UtdG9vbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy90b29sLW1hbmFnZXIvVG9vbE1hbmFnZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvdG9vbC1tYW5hZ2VyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Rvb2x0aXBzL1Rvb2x0aXBzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Rvb2x0aXBzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3RvdWNoL1RvdWNoRml4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3RvdWNoL1RvdWNoSW50ZXJhY3Rpb25FdmVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvdG91Y2gvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUvdHJhbnNsYXRlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2xheW91dC9CYXNlTGF5b3V0ZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0Nyb3BwaW5nQ29ubmVjdGlvbkRvY2tpbmcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbGF5b3V0L01hbmhhdHRhbkxheW91dC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9tb2RlbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL2tleWJvYXJkLW1vdmUvS2V5Ym9hcmRNb3ZlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL25hdmlnYXRpb24va2V5Ym9hcmQtbW92ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL21vdmVjYW52YXMvTW92ZUNhbnZhcy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL21vdmVjYW52YXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbmF2aWdhdGlvbi90b3VjaC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL3pvb21zY3JvbGwvWm9vbVNjcm9sbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL3pvb21zY3JvbGwvWm9vbVV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbmF2aWdhdGlvbi96b29tc2Nyb2xsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvQXR0YWNoVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0NsaWNrVHJhcC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvQ3Vyc29yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvRWxlbWVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvdXRpbC9Fc2NhcGVVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvRXZlbnQuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvdXRpbC9HZW9tZXRyeS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0dyYXBoaWNzVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0lkR2VuZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvTGluZUludGVyc2VjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL01hdGguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvdXRpbC9Nb3VzZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL1BsYXRmb3JtLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvUG9zaXRpb25VdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvUmVtb3ZhbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL1JlbmRlclV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvdXRpbC9TdmdUcmFuc2Zvcm1VdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvVGV4dC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLW1vZGRsZS9kaXN0L2luZGV4LmVzbS5qcyIsIm5vZGVfbW9kdWxlcy9jc3MuZXNjYXBlL2Nzcy5lc2NhcGUuanMiLCJub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy1kaXJlY3QtZWRpdGluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9kaWFncmFtLWpzLWRpcmVjdC1lZGl0aW5nL2xpYi9EaXJlY3RFZGl0aW5nLmpzIiwibm9kZV9tb2R1bGVzL2RpYWdyYW0tanMtZGlyZWN0LWVkaXRpbmcvbGliL1RleHRCb3guanMiLCJub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvaW50ZXJhY3Rpb24tZXZlbnRzL0ludGVyYWN0aW9uRXZlbnRzLmpzIiwibm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2kxOG4vdHJhbnNsYXRlL3RyYW5zbGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zLmpzIiwibm9kZV9tb2R1bGVzL2RpZGkvZGlzdC9pbmRleC5lc20uanMiLCJub2RlX21vZHVsZXMvaGFtbWVyanMvaGFtbWVyLmpzIiwibm9kZV9tb2R1bGVzL2lkcy9ub2RlX21vZHVsZXMvaGF0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2lkcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2pxdWVyeS9kaXN0L2pxdWVyeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX0RhdGFWaWV3LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fSGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX0xhenlXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fTGlzdENhY2hlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fTG9kYXNoV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX01hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX01hcENhY2hlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fUHJvbWlzZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX1NldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX1NldENhY2hlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fU3RhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19TeW1ib2wuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19VaW50OEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fV2Vha01hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2FwcGx5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlBZ2dyZWdhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlGaWx0ZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheUluY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlJbmNsdWRlc1dpdGguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheUxpa2VLZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheVB1c2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheVNvbWUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hc3NpZ25WYWx1ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Fzc29jSW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VBZ2dyZWdhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUFzc2lnblZhbHVlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUNyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VEaWZmZXJlbmNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlRmlsdGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VGbGF0dGVuLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUZvci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VGb3JPd24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlR2V0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUdldEFsbEtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlR2V0VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUhhc0luLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUluZGV4T2YuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlSXNBcmd1bWVudHMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlSXNFcXVhbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc0VxdWFsRGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc01hdGNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzTmFOLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzTmF0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzVHlwZWRBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJdGVyYXRlZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VLZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUxvZGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlTWF0Y2hlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VNYXRjaGVzUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlUHJvcGVydHlEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZVJlc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlU2V0RGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VTZXRUb1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VUaW1lcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VUb1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VVbmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VVbmlxLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZVZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VYb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jYWNoZUhhcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nhc3RGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nhc3RQYXRoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY29tcG9zZUFyZ3MuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jb21wb3NlQXJnc1JpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY29weUFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY29weU9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NvcmVKc0RhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jb3VudEhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jcmVhdGVBZ2dyZWdhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlQXNzaWduZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jcmVhdGVCYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NyZWF0ZUJhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jcmVhdGVCaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlQ3Rvci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NyZWF0ZUN1cnJ5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlRmluZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NyZWF0ZUh5YnJpZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NyZWF0ZVBhcnRpYWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jcmVhdGVSZWN1cnJ5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlU2V0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlV3JhcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2RlZmluZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZXF1YWxBcnJheXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19lcXVhbEJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZXF1YWxPYmplY3RzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZnJlZUdsb2JhbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldEFsbEtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19nZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0RnVuY05hbWUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19nZXRIb2xkZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19nZXRNYXBEYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0TWF0Y2hEYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0TmF0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0UHJvdG90eXBlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0UmF3VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0U3ltYm9scy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFRhZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFZhbHVlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0V3JhcERldGFpbHMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19oYXNQYXRoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaENsZWFyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaERlbGV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2hhc2hHZXQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19oYXNoSGFzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaFNldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2luc2VydFdyYXBEZXRhaWxzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faXNGbGF0dGVuYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2lzSW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19pc0l0ZXJhdGVlQ2FsbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2lzS2V5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faXNLZXlhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faXNMYXppYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2lzTWFza2VkLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faXNQcm90b3R5cGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19pc1N0cmljdENvbXBhcmFibGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19saXN0Q2FjaGVDbGVhci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZURlbGV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZUhhcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZVNldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlQ2xlYXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tYXBDYWNoZURlbGV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlR2V0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fbWFwQ2FjaGVIYXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tYXBDYWNoZVNldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcFRvQXJyYXkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tYXRjaGVzU3RyaWN0Q29tcGFyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX21lbW9pemVDYXBwZWQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tZXJnZURhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tZXRhTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fbmF0aXZlQ3JlYXRlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fbmF0aXZlS2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX25vZGVVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fb2JqZWN0VG9TdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19vdmVyQXJnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fb3ZlclJlc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19yZWFsTmFtZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19yZW9yZGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fcmVwbGFjZUhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19yb290LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fc2V0Q2FjaGVBZGQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zZXRDYWNoZUhhcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3NldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zZXRUb0FycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fc2V0VG9TdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zZXRXcmFwVG9TdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zaG9ydE91dC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0YWNrQ2xlYXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja0RlbGV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0YWNrR2V0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fc3RhY2tIYXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja1NldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0cmljdEluZGV4T2YuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zdHJpbmdUb1BhdGguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL190b0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3RvU291cmNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fdXBkYXRlV3JhcERldGFpbHMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL193cmFwcGVyQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2Fzc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvYmluZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvY29uc3RhbnQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2RlYm91bmNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9lcS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvZmlsdGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9maW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9maW5kSW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ZsYXR0ZW5EZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9mb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9nZXQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2hhc0luLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNBcmd1bWVudHMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzQXJyYXkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzQXJyYXlMaWtlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pc0FycmF5TGlrZU9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNCdWZmZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzRW1wdHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzRnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzTGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pc09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNPYmplY3RMaWtlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pc1N5bWJvbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9rZXlCeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gva2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9tZW1vaXplLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9ub29wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9ub3cuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9zdHViQXJyYXkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3N0dWJGYWxzZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvdG9GaW5pdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3RvSW50ZWdlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvdG9OdW1iZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3RvU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3ZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvd3JhcHBlckxvZGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gveG9yLmpzIiwibm9kZV9tb2R1bGVzL21pbi1kYXNoL2Rpc3QvaW5kZXguZXNtLmpzIiwibm9kZV9tb2R1bGVzL21pbi1kb20vZGlzdC9pbmRleC5lc20uanMiLCJub2RlX21vZHVsZXMvbWl0dC9kaXN0L21pdHQuZXMuanMiLCJub2RlX21vZHVsZXMvbW9kZGxlLXhtbC9kaXN0L2luZGV4LmVzbS5qcyIsIm5vZGVfbW9kdWxlcy9tb2RkbGUvZGlzdC9pbmRleC5lc20uanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LXJlZnMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LXJlZnMvbGliL2NvbGxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LXJlZnMvbGliL3JlZnMuanMiLCJub2RlX21vZHVsZXMvcGF0aC1pbnRlcnNlY3Rpb24vaW50ZXJzZWN0LmpzIiwibm9kZV9tb2R1bGVzL3NheGVuL2Rpc3QvaW5kZXguZXNtLmpzIiwibm9kZV9tb2R1bGVzL3Njcm9sbC10YWJzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3NlbGVjdGlvbi11cGRhdGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvdGlueS1zdmcvZGlzdC9pbmRleC5lc20uanMiLCJyZXNvdXJjZXMvYWN0aXZpdGkuanNvbiIsInJlc291cmNlcy9jdXN0b21Db250cm9scy9DdXN0b21Db250ZXh0UGFkLmpzIiwicmVzb3VyY2VzL2N1c3RvbUNvbnRyb2xzL0N1c3RvbVBhbGV0dGUuanMiLCJyZXNvdXJjZXMvY3VzdG9tQ29udHJvbHMvaW5kZXguanMiLCJyZXNvdXJjZXMvY3VzdG9tVHJhbnNsYXRlL2N1c3RvbVRyYW5zbGF0ZS5qcyIsInJlc291cmNlcy9jdXN0b21UcmFuc2xhdGUvdHJhbnNsYXRpb25zR2VybWFuLmpzIiwicmVzb3VyY2VzL25ld0RpYWdyYW0uYnBtbiIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL1Byb3BlcnRpZXNBY3RpdmF0b3IuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9VdGlscy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL2ZhY3RvcnkvQ2hlY2tib3hFbnRyeUZhY3RvcnkuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9mYWN0b3J5L0NvbWJvRW50cnlGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9FbnRyeUZhY3RvcnkuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9mYWN0b3J5L0VudHJ5RmllbGREZXNjcmlwdGlvbi5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL2ZhY3RvcnkvTGFiZWxGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9MaW5rRW50cnlGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9TZWxlY3RFbnRyeUZhY3RvcnkuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9mYWN0b3J5L1RhYmxlRW50cnlGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9UZXh0Qm94RW50cnlGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9UZXh0SW5wdXRFbnRyeUZhY3RvcnkuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9mYWN0b3J5L1ZhbGlkYXRpb25Bd2FyZVRleHRJbnB1dC5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL2hlbHBlci9Bc3luY0NhcGFibGVIZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9oZWxwZXIvQ2F0ZWdvcnlIZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9oZWxwZXIvQ21kSGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL0VsZW1lbnRIZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL0Zvcm1IZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9oZWxwZXIvSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL0lucHV0T3V0cHV0SGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL1BhcnRpY2lwYW50SGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvQWN0aXZpdGlQcm9wZXJ0aWVzUHJvdmlkZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9DcmVhdGVIZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9DdXN0b21FbGVtZW50c1Byb3BlcnRpZXNBY3RpdmF0b3IuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9FbGVtZW50VGVtcGxhdGVzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvZWxlbWVudC10ZW1wbGF0ZXMvRWxlbWVudFRlbXBsYXRlc0xvYWRlci5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL2VsZW1lbnQtdGVtcGxhdGVzL0hlbHBlci5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL2VsZW1lbnQtdGVtcGxhdGVzL1ZhbGlkYXRvci5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL2VsZW1lbnQtdGVtcGxhdGVzL2NtZC9DaGFuZ2VFbGVtZW50VGVtcGxhdGVIYW5kbGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvZWxlbWVudC10ZW1wbGF0ZXMvY21kL2luZGV4LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvZWxlbWVudC10ZW1wbGF0ZXMvaW5kZXguanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9wYXJ0cy9DaG9vc2VyUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9wYXJ0cy9DdXN0b21Qcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL2luZGV4LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvQXN5bmNocm9ub3VzQ29udGludWF0aW9uUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9DYWxsQWN0aXZpdHlQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0NhbmRpZGF0ZVN0YXJ0ZXJQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0NvbmRpdGlvbmFsUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9Db25uZWN0b3JEZXRhaWxQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0Nvbm5lY3RvcklucHV0T3V0cHV0UGFyYW1ldGVyUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9Db25uZWN0b3JJbnB1dE91dHB1dFByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvRXJyb3JFdmVudFByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvRXh0ZXJuYWxUYXNrQ29uZmlndXJhdGlvblByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvRmllbGRJbmplY3Rpb25Qcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0Zvcm1Qcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0hpc3RvcnlUaW1lVG9MaXZlUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9JbnB1dE91dHB1dFBhcmFtZXRlclByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvSW5wdXRPdXRwdXRQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0pvYkNvbmZpZ3VyYXRpb25Qcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0xpc3RlbmVyRGV0YWlsUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9MaXN0ZW5lckZpZWxkSW5qZWN0aW9uUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9MaXN0ZW5lclByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvTXVsdGlJbnN0YW5jZUxvb3BQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1Byb3BlcnRpZXNQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1NjcmlwdFRhc2tQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1NlcnZpY2VUYXNrRGVsZWdhdGVQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1N0YXJ0RXZlbnRJbml0aWF0b3IuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9UYXNrbGlzdFByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvVXNlclRhc2tQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1ZhcmlhYmxlTWFwcGluZ1Byb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvVmVyc2lvblRhZ1Byb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vQXN5bmNDb250aW51YXRpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9DYWxsYWJsZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0NhbmRpZGF0ZVN0YXJ0ZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9EZWxlZ2F0ZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0Vycm9yRXZlbnREZWZpbml0aW9uLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vRXh0ZW5zaW9uRWxlbWVudHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9FeHRlcm5hbC5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0V4dGVybmFsVGFza1ByaW9yaXR5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vRmllbGRJbmplY3Rpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9IaXN0b3J5VGltZVRvTGl2ZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0ltcGxlbWVudGF0aW9uVHlwZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0lucHV0T3V0cHV0LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vSW5wdXRPdXRwdXRQYXJhbWV0ZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9Kb2JQcmlvcml0eS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0pvYlJldHJ5VGltZUN5Y2xlLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vTGlzdGVuZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9NdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL1Byb3BlcnRpZXMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9SZXN1bHRWYXJpYWJsZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL1NjcmlwdC5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL1Rhc2tsaXN0LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYnBtbi9wYXJ0cy9Eb2N1bWVudGF0aW9uUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL0V2ZW50UHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL0V4ZWN1dGFibGVQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvSWRQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvTGlua1Byb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYnBtbi9wYXJ0cy9OYW1lUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL1Byb2Nlc3NQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vQ29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbi5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vQ29uZGl0aW9uYWxFdmVudERlZmluaXRpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL2ltcGxlbWVudGF0aW9uL0VsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vRXJyb3JFdmVudERlZmluaXRpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL2ltcGxlbWVudGF0aW9uL0VzY2FsYXRpb25FdmVudERlZmluaXRpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL2ltcGxlbWVudGF0aW9uL0V2ZW50RGVmaW5pdGlvblJlZmVyZW5jZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vTWVzc2FnZUV2ZW50RGVmaW5pdGlvbi5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vTmFtZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vU2lnbmFsRXZlbnREZWZpbml0aW9uLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYnBtbi9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9UaW1lckV2ZW50RGVmaW5pdGlvbi5qcyIsInJlc291cmNlcy90b29scy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0FDQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFQQTtBQVFBLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxRQUFQLENBQWdCLFFBQWhCLEdBQTJCLElBQTNCLEdBQWtDLE1BQU0sQ0FBQyxRQUFQLENBQWdCLElBQWxFO0FBQ0EsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLFFBQVAsQ0FBZ0IsSUFBaEIsQ0FBcUIsS0FBckIsQ0FBMkIsUUFBM0IsRUFBcUMsQ0FBckMsQ0FBYjtBQUNBLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFMLENBQVcsTUFBTSxDQUFDLFFBQVAsQ0FBZ0IsSUFBM0IsRUFBaUMsQ0FBakMsQ0FBWjtBQUNBLE1BQU0sU0FBUyxHQUFHLE9BQU8sR0FBRyxHQUE1QixDLENBRUE7O0FBQ0EsSUFBSSxxQkFBcUIsR0FBRztBQUN4QixFQUFBLFNBQVMsRUFBRSxDQUFDLE9BQUQsRUFBVSx3QkFBVjtBQURhLENBQTVCO0FBR0EsSUFBSSxTQUFTLEdBQUcscUJBQUUsZUFBRixDQUFoQjtBQUNBLElBQUksTUFBTSxHQUFHLHFCQUFFLFlBQUYsQ0FBYjtBQUNBLElBQUksV0FBVyxHQUFHLElBQUksZ0JBQUosQ0FBZ0I7QUFDOUIsRUFBQSxTQUFTLEVBQUUsTUFEbUI7QUFFOUIsRUFBQSxlQUFlLEVBQUU7QUFDYixJQUFBLE1BQU0sRUFBRTtBQURLLEdBRmE7QUFLOUIsRUFBQSxpQkFBaUIsRUFBRSxDQUNmLDhCQURlLEVBRWYsaUJBRmUsRUFHZix1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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcnZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7OztBQ1JBOztBQUVBOztBQUVBOzs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSxTQUFTLFdBQVQsQ0FBcUIsT0FBckIsRUFBOEI7QUFDM0Msc0JBQVcsSUFBWCxDQUFnQixJQUFoQixFQUFzQixPQUF0QixFQUQyQyxDQUczQzs7O0FBQ0EsT0FBSyxFQUFMLENBQVEs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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3huVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDek1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBUyxHQUFULENBQWEsR0FBYixFQUFrQjtBQUNoQixTQUFPLEdBQUcsQ0FBQyxZQUFYO0FBQ0Q7O0FBRUQsTUFBTSxDQUFDLEdBQVAsR0FBYSxHQUFiOzs7QUN4WUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN0SkEsU0FBUyxjQUFULENBQXdCLE9BQXhCLEVBQWlDLE1BQWpDLEVBQXlDO0FBRXZDLE1BQUksT0FBTyxDQUFDLGFBQVIsS0FBMEIsTUFBTSxDQUFDLGFBQXJDLEVBQW9EO0FBQ2xELFFBQUk7QUFDRjtBQUNBLGFBQU8sTUFBTSxDQUFDLGFBQVAsQ0FBcUIsVUFBckIsQ0FBZ0MsT0FBaEMsRUFBeUMsSUFBekMsQ0FBUDtBQUNELEtBSEQsQ0FHRSxPQUFPLENBQVAsRUFBVSxDQUNWO0FBQ0Q7QUFDRjs7QUFFRCxTQUFPLE9BQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQSxTQUFTLFFBQVQsQ0FBa0IsT0FBbEIsRUFBMkIsTUFBM0IsRUFBbUM7QUFDakMsU0FBTyxNQUFNLENBQUMsV0FBUCxDQUFtQixjQUFjLENBQUMsT0FBRCxFQUFVLE1BQVYsQ0FBakMsQ0FBUDtBQUNEO0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBLFNBQVMsTUFBVCxDQUFnQixNQUFoQixFQUF3QixJQUF4QixFQUE4QjtBQUM1QixFQUFBLFFBQVEsQ0FBQyxJQUFELEVBQU8sTUFBUCxDQUFSO0FBQ0EsU0FBTyxNQUFQO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7OztBQUVBLElBQUksV0FBVyxHQUFHLENBQWxCO0FBRUEsSUFBSSxjQUFjLEdBQUc7QUFDbkIsd0JBQXNCLENBREg7QUFFbkIsb0JBQWtCLENBRkM7QUFHbkIsVUFBUSxDQUhXO0FBSW5CLGVBQWEsQ0FKTTtBQUtuQixlQUFhLENBTE07QUFNbkIsV0FBUyxDQU5VO0FBT25CLHlCQUF1QixDQVBKO0FBUW5CLGlDQUErQixDQVJaO0FBU25CLG1CQUFpQixDQVRFO0FBVW5CLHFCQUFtQixDQVZBO0FBV25CLFlBQVUsQ0FYUztBQVluQixlQUFhLENBWk07QUFhbkIsYUFBVyxDQWJRO0FBY25CLHVCQUFxQixDQWRGO0FBZW5CLHVCQUFxQixDQWZGO0FBZ0JuQixVQUFRLENBaEJXO0FBaUJuQixrQkFBZ0IsQ0FqQkc7QUFrQm5CLGVBQWEsQ0FsQk07QUFtQm5CLFlBQVUsQ0FuQlM7QUFvQm5CLGlCQUFlLENBcEJJO0FBcUJuQixtQkFBaUIsQ0FyQkU7QUFzQm5CLFVBQVEsQ0F0Qlc7QUF1Qm5CLGlCQUFlLENBdkJJO0FBd0JuQixlQUFhLFdBeEJNO0FBeUJuQixzQkFBb0IsQ0F6QkQ7QUEwQm5CLGtCQUFnQixDQTFCRztBQTJCbkIsZ0JBQWMsQ0EzQks7QUE0Qm5CLGtCQUFnQixDQTVCRztBQTZCbkIsaUJBQWUsQ0E3Qkk7QUE4Qm5CLGtDQUFnQyxDQTlCYjtBQStCbkIsZ0NBQThCLENBL0JYO0FBZ0NuQixxQkFBbUIsQ0FoQ0E7QUFpQ25CLGFBQVcsQ0FqQ1E7QUFrQ25CLG9CQUFrQixDQWxDQztBQW1DbkIsb0JBQWtCLENBbkNDO0FBb0NuQixZQUFVLENBcENTO0FBcUNuQixnQkFBYyxDQXJDSztBQXNDbkIsZ0JBQWMsQ0F0Q0s7QUF1Q25CLGtCQUFnQixDQXZDRztBQXdDbkIsVUFBUSxDQXhDVztBQXlDbkIsYUFBVyxDQXpDUTtBQTBDbkIsY0FBWSxDQTFDTztBQTJDbkIsb0JBQWtCLENBM0NDO0FBNENuQixxQkFBbUIsQ0E1Q0E7QUE2Q25CLGdCQUFjLENBN0NLO0FBOENuQixrQkFBZ0IsQ0E5Q0c7QUErQ25CLFlBQVUsQ0EvQ1M7QUFnRG5CLHNCQUFvQixDQWhERDtBQWlEbkIsdUJBQXFCLENBakRGO0FBa0RuQixvQkFBa0IsQ0FsREM7QUFtRG5CLHFCQUFtQixDQW5EQTtBQW9EbkIsdUJBQXFCLENBcERGO0FBcURuQixvQkFBa0IsQ0FyREM7QUFzRG5CLGtCQUFnQixXQXRERztBQXVEbkIsaUJBQWUsQ0F2REk7QUF3RG5CLHFCQUFtQixDQXhEQTtBQXlEbkIsb0JBQWtCLENBekRDO0FBMERuQixrQkFBZ0IsQ0ExREc7QUEyRG5CLGdCQUFjLENBM0RLO0FBNERuQixrQkFBZ0IsQ0E1REc7QUE2RG5CLGtCQUFnQjtBQTdERyxDQUFyQjs7QUFpRUEsU0FBUyxZQUFULENBQXNCLElBQXRCLEVBQTRCLElBQTVCLEVBQWtDO0FBQ2hDLE1BQUksY0FBYyxDQUFDLElBQUQsQ0FBbEIsRUFBMEI7QUFDeEIsV0FBTyxJQUFJLENBQUMsS0FBTCxDQUFXLElBQVgsQ0FBUDtBQUNELEdBRkQsTUFFTztBQUNMLFdBQU8sSUFBSSxDQUFDLGNBQUwsQ0FBb0IsSUFBcEIsRUFBMEIsSUFBMUIsQ0FBUDtBQUNEO0FBQ0Y7O0FBRUQsU0FBUyxZQUFULENBQXNCLElBQXRCLEVBQTRCLElBQTVCLEVBQWtDLEtBQWxDLEVBQXlDO0FBQ3ZDLE1BQUksVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFMLENBQWEsaUJBQWIsRUFBZ0MsT0FBaEMsRUFBeUMsV0FBekMsRUFBakI7QUFFQSxNQUFJLElBQUksR0FBRyxjQUFjLENBQUMsVUFBRCxDQUF6Qjs7QUFFQSxNQUFJLElBQUosRUFBVTtBQUNSO0FBQ0EsUUFBSSxJQUFJLEtBQUssV0FBVCxJQUF3QixPQUFPLEtBQVAsS0FBaUIsUUFBN0MsRUFBdUQ7QUFDckQsTUFBQSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUQsQ0FBTixHQUFnQixJQUF4QjtBQUNEOztBQUVELElBQUEsSUFBSSxDQUFDLEtBQUwsQ0FBVyxVQUFYLElBQXlCLEtBQXpCO0FBQ0QsR0FQRCxNQU9PO0FBQ0wsSUFBQSxJQUFJLENBQUMsY0FBTCxDQUFvQixJQUFwQixFQUEwQixJQUExQixFQUFnQyxLQUFoQztBQUNEO0FBQ0Y7O0FBRUQsU0FBUyxhQUFULENBQXVCLElBQXZCLEVBQTZCLEtBQTdCLEVBQW9DO0FBRWxDLE1BQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFQLENBQVksS0FBWixDQUFaO0FBQUEsTUFBZ0MsQ0FBaEM7QUFBQSxNQUFtQyxJQUFuQzs7QUFFQSxPQUFLLENBQUMsR0FBRyxDQUFKLEVBQU8sSUFBWixFQUFtQixJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUQsQ0FBL0IsRUFBcUMsQ0FBQyxFQUF0QyxFQUEwQztBQUN4QyxJQUFBLFlBQVksQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFhLEtBQUssQ0FBQyxJQUFELENBQWxCLENBQVo7QUFDRDtBQUNGO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBLFNBQVMsSUFBVCxDQUFjLElBQWQsRUFBb0IsSUFBcEIsRUFBMEIsS0FBMUIsRUFBaUM7QUFDL0IsTUFBSSxPQUFPLElBQVAsS0FBZ0IsUUFBcEIsRUFBOEI7QUFDNUIsUUFBSSxLQUFLLEtBQUssU0FBZCxFQUF5QjtBQUN2QixNQUFBLFlBQVksQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFhLEtBQWIsQ0FBWjtBQUNELEtBRkQsTUFFTztBQUNMLGFBQU8sWUFBWSxDQUFDLElBQUQsRUFBTyxJQUFQLENBQW5CO0FBQ0Q7QUFDRixHQU5ELE1BTU87QUFDTCxJQUFBLGFBQWEsQ0FBQyxJQUFELEVBQU8sSUFBUCxDQUFiO0FBQ0Q7O0FBRUQsU0FBTyxJQUFQO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7OztBQUNBLFNBQVMsS0FBVCxDQUFlLEdBQWYsRUFBb0IsR0FBcEIsRUFBeUI7QUFDdkIsTUFBSSxHQUFHLENBQUMsT0FBUixFQUFpQjtBQUNmLFdBQU8sR0FBRyxDQUFDLE9BQUosQ0FBWSxHQUFaLENBQVA7QUFDRDs7QUFHRCxPQUFLLElBQUksQ0FBQyxHQUFHLENBQWIsRUFBZ0IsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUF4QixFQUFnQyxFQUFFLENBQWxDLEVBQXFDO0FBQ25DLFFBQUksR0FBRyxDQUFDLENBQUQsQ0FBSCxLQUFXLEdBQWYsRUFBb0I7QUFDbEIsYUFBTyxDQUFQO0FBQ0Q7QUFDRjs7QUFFRCxTQUFPLENBQUMsQ0FBUjtBQUNEOztBQUVELElBQUksRUFBRSxHQUFHLEtBQVQ7QUFFQSxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUCxDQUFpQixRQUFoQzs7QUFFQSxTQUFTLE9BQVQsQ0FBaUIsQ0FBakIsRUFBb0I7QUFDbEIsU0FBTyxPQUFPLENBQVAsS0FBYSxXQUFwQjtBQUNEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUVBLFNBQVMsT0FBVCxDQUFpQixFQUFqQixFQUFxQjtBQUNuQixTQUFPLElBQUksU0FBSixDQUFjLEVBQWQsQ0FBUDtBQUNEOztBQUVELFNBQVMsU0FBVCxDQUFtQixFQUFuQixFQUF1QjtBQUNyQixNQUFJLENBQUMsRUFBRCxJQUFPLENBQUMsRUFBRSxDQUFDLFFBQWYsRUFBeUI7QUFDdkIsVUFBTSxJQUFJLEtBQUosQ0FBVSxxQ0FBVixDQUFOO0FBQ0Q7O0FBQ0QsT0FBSyxFQUFMLEdBQVUsRUFBVjtBQUNBLE9BQUssSUFBTCxHQUFZLEVBQUUsQ0FBQyxTQUFmO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBRUEsU0FBUyxDQUFDLFNBQVYsQ0FBb0IsR0FBcEIsR0FBMEIsVUFBUyxJQUFULEVBQWU7QUFFdkM7QUFDQSxNQUFJLEtBQUssSUFBVCxFQUFlO0FBQ2IsU0FBSyxJQUFMLENBQVUsR0FBVixDQUFjLElBQWQ7QUFDQSxXQUFPLElBQVA7QUFDRCxHQU5zQyxDQVF2Qzs7O0FBQ0EsTUFBSSxHQUFHLEdBQUcsS0FBSyxLQUFMLEVBQVY7QUFDQSxNQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsR0FBRCxFQUFNLElBQU4sQ0FBYjs7QUFDQSxNQUFJLENBQUMsQ0FBQyxDQUFOLEVBQVM7QUFDUCxJQUFBLEdBQUcsQ0FBQyxJQUFKLENBQVMsSUFBVDtBQUNEOztBQUVELE1BQUksT0FBTyxDQUFDLEtBQUssRUFBTCxDQUFRLFNBQVIsQ0FBa0IsT0FBbkIsQ0FBWCxFQUF3QztBQUN0QyxTQUFLLEVBQUwsQ0FBUSxTQUFSLENBQWtCLE9BQWxCLEdBQTRCLEdBQUcsQ0FBQyxJQUFKLENBQVMsR0FBVCxDQUE1QjtBQUNELEdBRkQsTUFFTztBQUNMLFNBQUssRUFBTCxDQUFRLFNBQVIsR0FBb0IsR0FBRyxDQUFDLElBQUosQ0FBUyxHQUFULENBQXBCO0FBQ0Q7O0FBRUQsU0FBTyxJQUFQO0FBQ0QsQ0F0QkQ7QUF3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFFQSxTQUFTLENBQUMsU0FBVixDQUFvQixNQUFwQixHQUE2QixVQUFTLElBQVQsRUFBZTtBQUMxQyxNQUFJLHNCQUFzQixRQUFRLENBQUMsSUFBVCxDQUFjLElBQWQsQ0FBMUIsRUFBK0M7QUFDN0MsV0FBTyxLQUFLLGNBQUwsQ0FBb0IsSUFBcEIsQ0FBUDtBQUNELEdBSHlDLENBSzFDOzs7QUFDQSxNQUFJLEtBQUssSUFBVCxFQUFlO0FBQ2IsU0FBSyxJQUFMLENBQVUsTUFBVixDQUFpQixJQUFqQjtBQUNBLFdBQU8sSUFBUDtBQUNELEdBVHlDLENBVzFDOzs7QUFDQSxNQUFJLEdBQUcsR0FBRyxLQUFLLEtBQUwsRUFBVjtBQUNBLE1BQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxHQUFELEVBQU0sSUFBTixDQUFiOztBQUNBLE1BQUksQ0FBQyxDQUFMLEVBQVE7QUFDTixJQUFBLEdBQUcsQ0FBQyxNQUFKLENBQVcsQ0FBWCxFQUFjLENBQWQ7QUFDRDs7QUFDRCxPQUFLLEVBQUwsQ0FBUSxTQUFSLENBQWtCLE9BQWxCLEdBQTRCLEdBQUcsQ0FBQyxJQUFKLENBQVMsR0FBVCxDQUE1QjtBQUNBLFNBQU8sSUFBUDtBQUNELENBbkJEO0FBcUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFFQSxTQUFTLENBQUMsU0FBVixDQUFvQixjQUFwQixHQUFxQyxVQUFTLEVBQVQsRUFBYTtBQUNoRCxNQUFJLEdBQUcsR0FBRyxLQUFLLEtBQUwsRUFBVjs7QUFDQSxPQUFLLElBQUksQ0FBQyxHQUFHLENBQWIsRUFBZ0IsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUF4QixFQUFnQyxDQUFDLEVBQWpDLEVBQXFDO0FBQ25DLFFBQUksRUFBRSxDQUFDLElBQUgsQ0FBUSxHQUFHLENBQUMsQ0FBRCxDQUFYLENBQUosRUFBcUI7QUFDbkIsV0FBSyxNQUFMLENBQVksR0FBRyxDQUFDLENBQUQsQ0FBZjtBQUNEO0FBQ0Y7O0FBQ0QsU0FBTyxJQUFQO0FBQ0QsQ0FSRDtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUVBLFNBQVMsQ0FBQyxTQUFWLENBQW9CLE1BQXBCLEdBQTZCLFVBQVMsSUFBVCxFQUFlLEtBQWYsRUFBc0I7QUFDakQ7QUFDQSxNQUFJLEtBQUssSUFBVCxFQUFlO0FBQ2IsUUFBSSxPQUFPLENBQUMsS0FBRCxDQUFYLEVBQW9CO0FBQ2xCLFVBQUksS0FBSyxLQUFLLEtBQUssSUFBTCxDQUFVLE1BQVYsQ0FBaUIsSUFBakIsRUFBdUIsS0FBdkIsQ0FBZCxFQUE2QztBQUMzQyxhQUFLLElBQUwsQ0FBVSxNQUFWLENBQWlCLElBQWpCLEVBRDJDLENBQ25CO0FBQ3pCO0FBQ0YsS0FKRCxNQUlPO0FBQ0wsV0FBSyxJQUFMLENBQVUsTUFBVixDQUFpQixJQUFqQjtBQUNEOztBQUNELFdBQU8sSUFBUDtBQUNELEdBWGdELENBYWpEOzs7QUFDQSxNQUFJLE9BQU8sQ0FBQyxLQUFELENBQVgsRUFBb0I7QUFDbEIsUUFBSSxDQUFDLEtBQUwsRUFBWTtBQUNWLFdBQUssTUFBTCxDQUFZLElBQVo7QUFDRCxLQUZELE1BRU87QUFDTCxXQUFLLEdBQUwsQ0FBUyxJQUFUO0FBQ0Q7QUFDRixHQU5ELE1BTU87QUFDTCxRQUFJLEtBQUssR0FBTCxDQUFTLElBQVQsQ0FBSixFQUFvQjtBQUNsQixXQUFLLE1BQUwsQ0FBWSxJQUFaO0FBQ0QsS0FGRCxNQUVPO0FBQ0wsV0FBSyxHQUFMLENBQVMsSUFBVDtBQUNEO0FBQ0Y7O0FBRUQsU0FBTyxJQUFQO0FBQ0QsQ0E3QkQ7QUErQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFFQSxTQUFTLENBQUMsU0FBVixDQUFvQixLQUFwQixHQUE0QixZQUFXO0FBQ3JDLE1BQUksU0FBUyxHQUFHLEtBQUssRUFBTCxDQUFRLFlBQVIsQ0FBcUIsT0FBckIsS0FBaUMsRUFBakQ7QUFDQSxNQUFJLEdBQUcsR0FBRyxTQUFTLENBQUMsT0FBVixDQUFrQixZQUFsQixFQUFnQyxFQUFoQyxDQUFWO0FBQ0EsTUFBSSxHQUFHLEdBQUcsR0FBRyxDQUFDLEtBQUosQ0FBVSxFQUFWLENBQVY7O0FBQ0EsTUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFELENBQWQsRUFBbUI7QUFDakIsSUFBQSxHQUFHLENBQUMsS0FBSjtBQUNEOztBQUNELFNBQU8sR0FBUDtBQUNELENBUkQ7QUFVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBRUEsU0FBUyxDQUFDLFNBQVYsQ0FBb0IsR0FBcEIsR0FDQSxTQUFTLENBQUMsU0FBVixDQUFvQixRQUFwQixHQUErQixVQUFTLElBQVQsRUFBZTtBQUM1QyxTQUNFLEtBQUssSUFBTCxHQUNFLEtBQUssSUFBTCxDQUFVLFFBQVYsQ0FBbUIsSUFBbkIsQ0FERixHQUVFLENBQUMsQ0FBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLEtBQUwsRUFBRCxFQUFlLElBQWYsQ0FIYjtBQUtELENBUEQ7O0FBU0EsU0FBUyxNQUFULENBQWdCLE9BQWhCLEVBQXlCO0FBQ3ZCLE1BQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxVQUFyQjs7QUFFQSxNQUFJLE1BQUosRUFBWTtBQUNWLElBQUEsTUFBTSxDQUFDLFdBQVAsQ0FBbUIsT0FBbkI7QUFDRDs7QUFFRCxTQUFPLE9BQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBLFNBQVMsS0FBVCxDQUFlLE9BQWYsRUFBd0I7QUFDdEIsTUFBSSxLQUFKOztBQUVBLFNBQVEsS0FBSyxHQUFHLE9BQU8sQ0FBQyxVQUF4QixFQUFxQztBQUNuQyxJQUFBLE1BQU0sQ0FBQyxLQUFELENBQU47QUFDRDs7QUFFRCxTQUFPLE9BQVA7QUFDRDs7QUFFRCxTQUFTLEtBQVQsQ0FBZSxPQUFmLEVBQXdCO0FBQ3RCLFNBQU8sT0FBTyxDQUFDLFNBQVIsQ0FBa0IsSUFBbEIsQ0FBUDtBQUNEOztBQUVELElBQUksRUFBRSxHQUFHO0FBQ1AsRUFBQSxHQUFHLEVBQUU7QUFERSxDQUFUO0FBSUE7QUFDQTtBQUNBOztBQUVBLElBQUksU0FBUyxHQUFHLGlCQUFpQixFQUFFLENBQUMsR0FBcEIsR0FBMEIsR0FBMUM7O0FBRUEsU0FBUyxLQUFULENBQWUsR0FBZixFQUFvQjtBQUVsQixNQUFJLE1BQU0sR0FBRyxLQUFiLENBRmtCLENBSWxCOztBQUNBLE1BQUksR0FBRyxDQUFDLFNBQUosQ0FBYyxDQUFkLEVBQWlCLENBQWpCLE1BQXdCLE1BQTVCLEVBQW9DO0FBQ2xDLFFBQUksR0FBRyxDQUFDLE9BQUosQ0FBWSxFQUFFLENBQUMsR0FBZixNQUF3QixDQUFDLENBQTdCLEVBQWdDO0FBQzlCLE1BQUEsR0FBRyxHQUFHLFNBQVMsR0FBRyxHQUFHLENBQUMsU0FBSixDQUFjLENBQWQsQ0FBbEI7QUFDRDtBQUNGLEdBSkQsTUFJTztBQUNMO0FBQ0EsSUFBQSxHQUFHLEdBQUcsU0FBUyxHQUFHLEdBQVosR0FBa0IsR0FBbEIsR0FBd0IsUUFBOUI7QUFDQSxJQUFBLE1BQU0sR0FBRyxJQUFUO0FBQ0Q7O0FBRUQsTUFBSSxNQUFNLEdBQUcsYUFBYSxDQUFDLEdBQUQsQ0FBMUI7O0FBRUEsTUFBSSxDQUFDLE1BQUwsRUFBYTtBQUNYLFdBQU8sTUFBUDtBQUNEOztBQUVELE1BQUksUUFBUSxHQUFHLFFBQVEsQ0FBQyxzQkFBVCxFQUFmO0FBRUEsTUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLFVBQXBCOztBQUVBLFNBQU8sTUFBTSxDQUFDLFVBQWQsRUFBMEI7QUFDeEIsSUFBQSxRQUFRLENBQUMsV0FBVCxDQUFxQixNQUFNLENBQUMsVUFBNUI7QUFDRDs7QUFFRCxTQUFPLFFBQVA7QUFDRDs7QUFFRCxTQUFTLGFBQVQsQ0FBdUIsR0FBdkIsRUFBNEI7QUFFMUIsTUFBSSxNQUFKLENBRjBCLENBSTFCOztBQUNBLEVBQUEsTUFBTSxHQUFHLElBQUksU0FBSixFQUFUO0FBQ0EsRUFBQSxNQUFNLENBQUMsS0FBUCxHQUFlLEtBQWY7QUFFQSxTQUFPLE1BQU0sQ0FBQyxlQUFQLENBQXVCLEdBQXZCLEVBQTRCLFVBQTVCLENBQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQSxTQUFTLE1BQVQsQ0FBZ0IsSUFBaEIsRUFBc0IsS0FBdEIsRUFBNkI7QUFDM0IsTUFBSSxPQUFKOztBQUVBLE1BQUksSUFBSSxDQUFDLE1BQUwsQ0FBWSxDQUFaLE1BQW1CLEdBQXZCLEVBQTRCO0FBQzFCLElBQUEsT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFELENBQUwsQ0FBWSxVQUF0QjtBQUNBLElBQUEsT0FBTyxHQUFHLFFBQVEsQ0FBQyxVQUFULENBQW9CLE9BQXBCLEVBQTZCLElBQTdCLENBQVY7QUFDRCxHQUhELE1BR087QUFDTCxJQUFBLE9BQU8sR0FBRyxRQUFRLENBQUMsZUFBVCxDQUF5QixFQUFFLENBQUMsR0FBNUIsRUFBaUMsSUFBakMsQ0FBVjtBQUNEOztBQUVELE1BQUksS0FBSixFQUFXO0FBQ1QsSUFBQSxJQUFJLENBQUMsT0FBRCxFQUFVLEtBQVYsQ0FBSjtBQUNEOztBQUVELFNBQU8sT0FBUDtBQUNEO0FBRUQ7QUFDQTtBQUNBOzs7QUFFQSxTQUFTLEVBQVQsQ0FBWSxJQUFaLEVBQWtCLEtBQWxCLEVBQXlCLFFBQXpCLEVBQW1DLFVBQW5DLEVBQStDO0FBQzdDLEVBQUEsSUFBSSxDQUFDLGdCQUFMLENBQXNCLEtBQXRCLEVBQTZCLFFBQTdCLEVBQXVDLFVBQXZDO0FBQ0Q7O0FBRUQsU0FBUyxHQUFULENBQWEsSUFBYixFQUFtQixLQUFuQixFQUEwQixRQUExQixFQUFvQyxVQUFwQyxFQUFnRDtBQUM5QyxFQUFBLElBQUksQ0FBQyxtQkFBTCxDQUF5QixLQUF6QixFQUFnQyxRQUFoQyxFQUEwQyxVQUExQztBQUNEO0FBRUQ7QUFDQTtBQUNBO0FBRUE7OztBQUNBLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxLQUFELENBQWpCOztBQUVBLFNBQVMsTUFBVCxDQUFnQixNQUFoQixFQUF3QixLQUF4QixFQUErQjtBQUM3QixNQUFJLENBQUo7QUFBQSxNQUFPLENBQVA7QUFBQSxNQUFVLElBQUksR0FBRyxNQUFNLENBQUMsSUFBUCxDQUFZLEtBQVosQ0FBakI7O0FBRUEsT0FBSyxDQUFDLEdBQUcsQ0FBVCxFQUFhLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBRCxDQUFyQixFQUEyQixDQUFDLEVBQTVCLEVBQWdDO0FBQzlCLElBQUEsTUFBTSxDQUFDLENBQUQsQ0FBTixHQUFZLEtBQUssQ0FBQyxDQUFELENBQWpCO0FBQ0Q7O0FBRUQsU0FBTyxNQUFQO0FBQ0Q7O0FBR0QsU0FBUyxXQUFULENBQXFCLENBQXJCLEVBQXdCLENBQXhCLEVBQTJCO0FBQ3pCLE1BQUksS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFMLEVBQVo7O0FBRUEsVUFBUSxTQUFTLENBQUMsTUFBbEI7QUFDQSxTQUFLLENBQUw7QUFDRSxhQUFPLEtBQVA7O0FBQ0YsU0FBSyxDQUFMO0FBQ0UsTUFBQSxDQUFDLEdBQUc7QUFDRixRQUFBLENBQUMsRUFBRSxDQUREO0FBRUYsUUFBQSxDQUFDLEVBQUU7QUFGRCxPQUFKO0FBSUE7QUFSRjs7QUFXQSxTQUFPLE1BQU0sQ0FBQyxLQUFELEVBQVEsQ0FBUixDQUFiO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQSxTQUFTLFlBQVQsQ0FBc0IsQ0FBdEIsRUFBeUIsQ0FBekIsRUFBNEIsQ0FBNUIsRUFBK0IsQ0FBL0IsRUFBa0MsQ0FBbEMsRUFBcUMsQ0FBckMsRUFBd0M7QUFDdEMsTUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQUwsRUFBYjs7QUFFQSxVQUFRLFNBQVMsQ0FBQyxNQUFsQjtBQUNBLFNBQUssQ0FBTDtBQUNFLGFBQU8sTUFBUDs7QUFDRixTQUFLLENBQUw7QUFDRSxhQUFPLE1BQU0sQ0FBQyxNQUFELEVBQVMsQ0FBVCxDQUFiOztBQUNGLFNBQUssQ0FBTDtBQUNFLGFBQU8sTUFBTSxDQUFDLE1BQUQsRUFBUztBQUNwQixRQUFBLENBQUMsRUFBRSxDQURpQjtBQUVwQixRQUFBLENBQUMsRUFBRSxDQUZpQjtBQUdwQixRQUFBLENBQUMsRUFBRSxDQUhpQjtBQUlwQixRQUFBLENBQUMsRUFBRSxDQUppQjtBQUtwQixRQUFBLENBQUMsRUFBRSxDQUxpQjtBQU1wQixRQUFBLENBQUMsRUFBRTtBQU5pQixPQUFULENBQWI7QUFORjtBQWVEOztBQUVELFNBQVMsZUFBVCxDQUF5QixNQUF6QixFQUFpQztBQUMvQixNQUFJLE1BQUosRUFBWTtBQUNWLFdBQU8sSUFBSSxDQUFDLDRCQUFMLENBQWtDLE1BQWxDLENBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxXQUFPLElBQUksQ0FBQyxrQkFBTCxFQUFQO0FBQ0Q7QUFDRjtBQUVEO0FBQ0E7QUFDQTs7O0FBRUEsSUFBSSxhQUFhLEdBQUcsYUFBcEI7QUFDQSxJQUFJLGFBQWEsR0FBRyxlQUFwQjtBQUVBLElBQUksa0JBQWtCLEdBQUc7QUFDdkIsT0FBSyxPQURrQjtBQUV2QixPQUFLLE1BRmtCO0FBR3ZCLE9BQUssTUFIa0I7QUFJdkIsT0FBSztBQUprQixDQUF6Qjs7QUFPQSxTQUFTLE1BQVQsQ0FBZ0IsR0FBaEIsRUFBcUIsT0FBckIsRUFBOEI7QUFFNUIsV0FBUyxTQUFULENBQW1CLEtBQW5CLEVBQTBCLE1BQTFCLEVBQWtDO0FBQ2hDLFdBQU8sa0JBQWtCLENBQUMsTUFBRCxDQUFsQixJQUE4QixNQUFyQztBQUNEOztBQUVELFNBQU8sR0FBRyxDQUFDLE9BQUosQ0FBWSxPQUFaLEVBQXFCLFNBQXJCLENBQVA7QUFDRDs7QUFFRCxTQUFTLFNBQVQsQ0FBbUIsSUFBbkIsRUFBeUIsTUFBekIsRUFBaUM7QUFFL0IsTUFBSSxDQUFKLEVBQU8sR0FBUCxFQUFZLE9BQVosRUFBcUIsUUFBckIsRUFBK0IsVUFBL0I7O0FBRUEsVUFBUSxJQUFJLENBQUMsUUFBYjtBQUNBO0FBQ0EsU0FBSyxDQUFMO0FBQ0U7QUFDQSxNQUFBLE1BQU0sQ0FBQyxJQUFQLENBQVksTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFOLEVBQW1CLGFBQW5CLENBQWxCO0FBQ0E7QUFFRjs7QUFDQSxTQUFLLENBQUw7QUFDRSxNQUFBLE1BQU0sQ0FBQyxJQUFQLENBQVksR0FBWixFQUFpQixJQUFJLENBQUMsT0FBdEI7O0FBRUEsVUFBSSxJQUFJLENBQUMsYUFBTCxFQUFKLEVBQTBCO0FBQ3hCLFFBQUEsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFmOztBQUNBLGFBQUssQ0FBQyxHQUFHLENBQUosRUFBTyxHQUFHLEdBQUcsT0FBTyxDQUFDLE1BQTFCLEVBQWtDLENBQUMsR0FBRyxHQUF0QyxFQUEyQyxFQUFFLENBQTdDLEVBQWdEO0FBQzlDLFVBQUEsUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFSLENBQWEsQ0FBYixDQUFYO0FBQ0EsVUFBQSxNQUFNLENBQUMsSUFBUCxDQUFZLEdBQVosRUFBaUIsUUFBUSxDQUFDLElBQTFCLEVBQWdDLElBQWhDLEVBQXNDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBVixFQUFpQixhQUFqQixDQUE1QyxFQUE2RSxHQUE3RTtBQUNEO0FBQ0Y7O0FBRUQsVUFBSSxJQUFJLENBQUMsYUFBTCxFQUFKLEVBQTBCO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLElBQVAsQ0FBWSxHQUFaO0FBQ0EsUUFBQSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQWxCOztBQUNBLGFBQUssQ0FBQyxHQUFHLENBQUosRUFBTyxHQUFHLEdBQUcsVUFBVSxDQUFDLE1BQTdCLEVBQXFDLENBQUMsR0FBRyxHQUF6QyxFQUE4QyxFQUFFLENBQWhELEVBQW1EO0FBQ2pELFVBQUEsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFYLENBQWdCLENBQWhCLENBQUQsRUFBcUIsTUFBckIsQ0FBVDtBQUNEOztBQUNELFFBQUEsTUFBTSxDQUFDLElBQVAsQ0FBWSxJQUFaLEVBQWtCLElBQUksQ0FBQyxPQUF2QixFQUFnQyxHQUFoQztBQUNELE9BUEQsTUFPTztBQUNMLFFBQUEsTUFBTSxDQUFDLElBQVAsQ0FBWSxJQUFaO0FBQ0Q7O0FBQ0Q7QUFFRjs7QUFDQSxTQUFLLENBQUw7QUFDRSxNQUFBLE1BQU0sQ0FBQyxJQUFQLENBQVksTUFBWixFQUFvQixNQUFNLENBQUMsSUFBSSxDQUFDLFNBQU4sRUFBaUIsYUFBakIsQ0FBMUIsRUFBMkQsS0FBM0Q7QUFDQTtBQUVGOztBQUNBLFNBQUssQ0FBTDtBQUNFLE1BQUEsTUFBTSxDQUFDLElBQVAsQ0FBWSxXQUFaLEVBQXlCLElBQUksQ0FBQyxTQUE5QixFQUF5QyxLQUF6QztBQUNBOztBQUVGO0FBQ0UsWUFBTSxJQUFJLEtBQUosQ0FBVSwyQkFBMkIsSUFBSSxDQUFDLFFBQTFDLENBQU47QUExQ0Y7O0FBNkNBLFNBQU8sTUFBUDtBQUNEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7OztBQUdBLFNBQVMsR0FBVCxDQUFhLE9BQWIsRUFBc0IsR0FBdEIsRUFBMkI7QUFFekIsTUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDLEdBQUQsQ0FBbEIsQ0FGeUIsQ0FJekI7O0FBQ0EsRUFBQSxLQUFLLENBQUMsT0FBRCxDQUFMOztBQUVBLE1BQUksQ0FBQyxHQUFMLEVBQVU7QUFDUjtBQUNEOztBQUVELE1BQUksQ0FBQyxVQUFVLENBQUMsTUFBRCxDQUFmLEVBQXlCO0FBQ3ZCO0FBQ0EsSUFBQSxNQUFNLEdBQUcsTUFBTSxDQUFDLGVBQWhCO0FBQ0Q7O0FBRUQsTUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFSLENBQWpCLENBaEJ5QixDQWtCekI7O0FBQ0EsT0FBSyxJQUFJLENBQUMsR0FBRyxDQUFiLEVBQWdCLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBMUIsRUFBa0MsQ0FBQyxFQUFuQyxFQUF1QztBQUNyQyxJQUFBLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBRCxDQUFOLEVBQVcsT0FBWCxDQUFSO0FBQ0Q7QUFFRjs7QUFFRCxTQUFTLEdBQVQsQ0FBYSxPQUFiLEVBQXNCO0FBQ3BCLE1BQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxVQUFwQjtBQUFBLE1BQ0ksTUFBTSxHQUFHLEVBRGI7O0FBR0EsU0FBTyxLQUFQLEVBQWM7QUFDWixJQUFBLFNBQVMsQ0FBQyxLQUFELEVBQVEsTUFBUixDQUFUO0FBQ0EsSUFBQSxLQUFLLEdBQUcsS0FBSyxDQUFDLFdBQWQ7QUFDRDs7QUFFRCxTQUFPLE1BQU0sQ0FBQyxJQUFQLENBQVksRUFBWixDQUFQO0FBQ0Q7O0FBRUQsU0FBUyxVQUFULENBQW9CLElBQXBCLEVBQTBCO0FBQ3hCLFNBQU8sSUFBSSxDQUFDLFFBQUwsS0FBa0Isb0JBQXpCO0FBQ0Q7O0FBRUQsU0FBUyxRQUFULENBQWtCLE9BQWxCLEVBQTJCLEdBQTNCLEVBQWdDO0FBRTlCLE1BQUksR0FBRyxLQUFLLFNBQVosRUFBdUI7QUFFckIsUUFBSTtBQUNGLE1BQUEsR0FBRyxDQUFDLE9BQUQsRUFBVSxHQUFWLENBQUg7QUFDRCxLQUZELENBRUUsT0FBTyxDQUFQLEVBQVU7QUFDVixZQUFNLElBQUksS0FBSixDQUFVLHdCQUF3QixDQUFDLENBQUMsT0FBcEMsQ0FBTjtBQUNEOztBQUVELFdBQU8sT0FBUDtBQUNELEdBVEQsTUFTTztBQUNMLFdBQU8sR0FBRyxDQUFDLE9BQUQsQ0FBVjtBQUNEO0FBQ0Y7O0FBR0QsU0FBUyxLQUFULENBQWUsR0FBZixFQUFvQjtBQUNsQixTQUFPLEtBQUssQ0FBQyxTQUFOLENBQWdCLEtBQWhCLENBQXNCLElBQXRCLENBQTJCLEdBQTNCLENBQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTs7O0FBRUEsU0FBUyxNQUFULENBQWdCLElBQWhCLEVBQXNCLFFBQXRCLEVBQWdDO0FBQzlCLFNBQU8sSUFBSSxDQUFDLGFBQUwsQ0FBbUIsUUFBbkIsQ0FBUDtBQUNEOztBQUVELFNBQVMsU0FBVCxDQUFtQixJQUFuQixFQUF5QixRQUF6QixFQUFtQztBQUNqQyxNQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQUwsQ0FBc0IsUUFBdEIsQ0FBWjtBQUVBLFNBQU8sR0FBRyxHQUFILENBQU8sSUFBUCxDQUFZLEtBQVosRUFBbUIsVUFBUyxPQUFULEVBQWtCO0FBQzFDLFdBQU8sT0FBUDtBQUNELEdBRk0sQ0FBUDtBQUdEO0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBLFNBQVMsU0FBVCxDQUFtQixJQUFuQixFQUF5QixNQUF6QixFQUFpQztBQUMvQixTQUFPLE1BQU0sQ0FBQyxZQUFQLENBQW9CLGNBQWMsQ0FBQyxJQUFELEVBQU8sTUFBUCxDQUFsQyxFQUFrRCxNQUFNLENBQUMsVUFBUCxJQUFxQixJQUF2RSxDQUFQO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBUyxPQUFULENBQWlCLE1BQWpCLEVBQXlCLElBQXpCLEVBQStCO0FBQzdCLEVBQUEsU0FBUyxDQUFDLElBQUQsRUFBTyxNQUFQLENBQVQ7QUFDQSxTQUFPLE1BQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTs7O0FBRUEsU0FBUyxPQUFULENBQWlCLE9BQWpCLEVBQTBCLFdBQTFCLEVBQXVDO0FBQ3JDLEVBQUEsT0FBTyxDQUFDLFVBQVIsQ0FBbUIsWUFBbkIsQ0FBZ0MsY0FBYyxDQUFDLFdBQUQsRUFBYyxPQUFkLENBQTlDLEVBQXNFLE9BQXRFO0FBQ0EsU0FBTyxXQUFQO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7OztBQUVBLFNBQVMsVUFBVCxDQUFvQixhQUFwQixFQUFtQyxTQUFuQyxFQUE4QztBQUM1QyxNQUFJLFNBQVMsWUFBWSxTQUF6QixFQUFvQztBQUNsQyxXQUFPLGFBQWEsQ0FBQyw0QkFBZCxDQUEyQyxTQUEzQyxDQUFQO0FBQ0Q7O0FBRUQsU0FBTyxTQUFQO0FBQ0Q7O0FBR0QsU0FBUyxhQUFULENBQXVCLGFBQXZCLEVBQXNDLFVBQXRDLEVBQWtEO0FBQ2hELE1BQUksQ0FBSixFQUFPLENBQVA7QUFFQSxFQUFBLGFBQWEsQ0FBQyxLQUFkOztBQUVBLE9BQUssQ0FBQyxHQUFHLENBQVQsRUFBYSxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUQsQ0FBM0IsRUFBaUMsQ0FBQyxFQUFsQyxFQUFzQztBQUNwQyxJQUFBLGFBQWEsQ0FBQyxVQUFkLENBQXlCLFVBQVUsQ0FBQyxhQUFELEVBQWdCLENBQWhCLENBQW5DO0FBQ0Q7QUFDRjtBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBLFNBQVMsU0FBVCxDQUFtQixJQUFuQixFQUF5QixVQUF6QixFQUFxQztBQUNuQyxNQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMsU0FBTCxDQUFlLE9BQW5DOztBQUVBLE1BQUksVUFBSixFQUFnQjtBQUVkLFFBQUksQ0FBQyxLQUFLLENBQUMsT0FBTixDQUFjLFVBQWQsQ0FBTCxFQUFnQztBQUM5QixNQUFBLFVBQVUsR0FBRyxDQUFFLFVBQUYsQ0FBYjtBQUNEOztBQUVELElBQUEsYUFBYSxDQUFDLGFBQUQsRUFBZ0IsVUFBaEIsQ0FBYjtBQUNEOztBQUVELFNBQU8sYUFBYSxDQUFDLFdBQWQsRUFBUDtBQUNEOzs7QUM1ekJEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaE1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5aEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9PQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdmRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsd0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN1lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2puQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1V0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDak5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7O0FDcklBOzs7O0FBTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxR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Q0FBQyxLQUFELENBQWpCLEVBQXlCO0FBQ3JCLFVBQUksR0FBRyxHQUFDO0FBQ0osZ0JBQVEsSUFBSSxDQUFDLEtBQUQsQ0FBSixDQUFZLENBQVosQ0FESjtBQUVKLGtCQUFTLE9BRkw7QUFHSixnQkFBTztBQUhILE9BQVI7QUFLQSxNQUFBLFNBQVMsQ0FBQyxJQUFWLENBQWUsR0FBZjtBQUNIOztBQUNELFNBQUksSUFBSSxDQUFSLElBQWEsSUFBSSxDQUFDLGFBQUQsQ0FBakIsRUFBaUM7QUFDN0IsVUFBSSxHQUFHLEdBQUM7QUFDSixnQkFBUSxJQUFJLENBQUMsYUFBRCxDQUFKLENBQW9CLENBQXBCLENBREo7QUFFSixrQkFBUyxPQUZMO0FBR0osZ0JBQU87QUFISCxPQUFSO0FBS0EsTUFBQSxTQUFTLENBQUMsSUFBVixDQUFlLEdBQWY7QUFDSDs7QUFDRCxXQUFPLFNBQVA7QUFDSDs7QUEvUFMsQ0FBZDtlQXFRZSxLIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiXG5pbXBvcnQgJCBmcm9tICdqcXVlcnknO1xuaW1wb3J0IEJwbW5Nb2RlbGVyIGZyb20gJ2JwbW4tanMvbGliL01vZGVsZXInO1xuLy9pbXBvcnQgcHJvcGVydGllc1BhbmVsTW9kdWxlIGZyb20gJy4uL3Jlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsJztcbmltcG9ydCBwcm9wZXJ0aWVzUGFuZWxNb2R1bGUgZnJvbSAnYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsJztcbmltcG9ydCBwcm9wZXJ0aWVzUHJvdmlkZXJNb2R1bGUgZnJvbSAnLi4vcmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGknO1xuaW1wb3J0IGFjdGl2aXRpTW9kZGxlRGVzY3JpcHRvciBmcm9tICcuLi9yZXNvdXJjZXMvYWN0aXZpdGkuanNvbic7XG5pbXBvcnQgY3VzdG9tVHJhbnNsYXRlIGZyb20gJy4uL3Jlc291cmNlcy9jdXN0b21UcmFuc2xhdGUvY3VzdG9tVHJhbnNsYXRlJztcbmltcG9ydCBjdXN0b21Db250cm9sc01vZHVsZSBmcm9tICcuLi9yZXNvdXJjZXMvY3VzdG9tQ29udHJvbHMnO1xuaW1wb3J0IHRvb2xzIGZyb20gJy4uL3Jlc291cmNlcy90b29scydcbmltcG9ydCBkaWFncmFtWE1MIGZyb20gJy4uL3Jlc291cmNlcy9uZXdEaWFncmFtLmJwbW4nO1xuY29uc3QgcHJvSG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0O1xuY29uc3QgaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KFwiYnBtbmpzXCIpWzBdO1xuY29uc3Qga2V5ID0gaHJlZi5zcGxpdCh3aW5kb3cubG9jYXRpb24uaG9zdClbMV07XG5jb25zdCBwdWJsaWN1cmwgPSBwcm9Ib3N0ICsga2V5O1xuXG4vLyDmt7vliqDnv7vor5Hnu4Tku7ZcbnZhciBjdXN0b21UcmFuc2xhdGVNb2R1bGUgPSB7XG4gICAgdHJhbnNsYXRlOiBbJ3ZhbHVlJywgY3VzdG9tVHJhbnNsYXRlXVxufTtcbnZhciBjb250YWluZXIgPSAkKCcjanMtZHJvcC16b25lJyk7XG52YXIgY2FudmFzID0gJCgnI2pzLWNhbnZhcycpO1xudmFyIGJwbW5Nb2RlbGVyID0gbmV3IEJwbW5Nb2RlbGVyKHtcbiAgICBjb250YWluZXI6IGNhbnZhcyxcbiAgICBwcm9wZXJ0aWVzUGFuZWw6IHtcbiAgICAgICAgcGFyZW50OiAnI2pzLXByb3BlcnRpZXMtcGFuZWwnXG4gICAgfSxcbiAgICBhZGRpdGlvbmFsTW9kdWxlczogW1xuICAgICAgICBwcm9wZXJ0aWVzUGFuZWxNb2R1bGUsXG4gICAgICAgIHByb3BlcnRpZXNQcm92aWRlck1vZHVsZSxcbiAgICAgICAgY3VzdG9tQ29udHJvbHNNb2R1bGUsXG4gICAgICAgIGN1c3RvbVRyYW5zbGF0ZU1vZHVsZVxuICAgIF0sXG4gICAgbW9kZGxlRXh0ZW5zaW9uczoge1xuICAgICAgICBhY3Rpdml0aTphY3Rpdml0aU1vZGRsZURlc2NyaXB0b3JcbiAgICB9XG59KTtcbmNvbnRhaW5lci5yZW1vdmVDbGFzcygnd2l0aC1kaWFncmFtJyk7XG4vLyDliKTmlq3mtY/op4jlmajmlK/mjIHnqIvluqZcbmlmICghd2luZG93LkZpbGVMaXN0IHx8ICF3aW5kb3cuRmlsZVJlYWRlcikge1xuICAgIHdpbmRvdy5hbGVydCgn6K+35L2/55So6LC35q2M44CB54Gr54uQ44CBSUUxMCvmtY/op4jlmagnKTtcbn0gZWxzZSB7XG4gICAgdG9vbHMucmVnaXN0ZXJGaWxlRHJvcChjb250YWluZXIsIHRvb2xzLmNyZWF0ZURpYWdyYW0oZGlhZ3JhbVhNTCwgYnBtbk1vZGVsZXIsIGNvbnRhaW5lcikpO1xufVxuXG5cbiQoZnVuY3Rpb24gKCkge1xuICAgIC8vIOWIm+W7umJwbW5cbiAgICB2YXIgcGFyYW0gPSB0b29scy5nZXRVcmxQYXJhbSh3aW5kb3cubG9jYXRpb24uaHJlZilcbiAgICAgICAgJCgnLml0ZW0nKS5zaG93KClcbiAgICBpZiAocGFyYW0udHlwZSA9PT0gJ2FkZEJwbW4nKSB7XG4gICAgICAgIHRvb2xzLmNyZWF0ZURpYWdyYW0oZGlhZ3JhbVhNTCwgYnBtbk1vZGVsZXIsIGNvbnRhaW5lcik7XG4gICAgfSBlbHNlIGlmIChwYXJhbS50eXBlID09PSAnbG9va0JwbW4nKSB7IC8v57yW6L6RYnBtblxuICAgICAgICAkKCcuaXRlbScpLmhpZGUoKVxuICAgICAgICAkKCcuZG93bmxvYWQnKS5zaG93KClcbiAgICAgICAgY29uc3QgSWQgPSBwYXJhbS5kZXBsb3ltZW50RmlsZVVVSUQgfHwgJzZkNGFmMmRjLWJhYjAtMTFlYS1iNTg0LTNjZjAxMWVhYWZjYSdcbiAgICAgICAgY29uc3QgTmFtZT1wYXJhbS5kZXBsb3ltZW50TmFtZSB8fCAnU3RyaW5nLmJwbW4nXG4gICAgICAgIGNvbnN0IGluc3RhbmNlSWQ9cGFyYW0uaW5zdGFuY2VJZFxuICAgICAgICB2YXIgcGFyYW09e1xuICAgICAgICAgICAgXCJkZXBsb3ltZW50SWRcIjpJZCxcbiAgICAgICAgICAgIFwicmVzb3VyY2VOYW1lXCI6ZGVjb2RlVVJJKE5hbWUpXG4gICAgICAgIH1cbiAgICAgICAgaWYoaW5zdGFuY2VJZCl7XG4gICAgICAgICAgICB2YXIgcGFyYW0xPXtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJWVUVfQVBQX0JBU0VfQVBJXCIpKycvYWN0aXZpdGlIaXN0b3J5L2dldGhpZ2hMaW5lJyxcbiAgICAgICAgICAgICAgICAvLyB1cmw6ICdodHRwOi8vbG9jYWxob3N0OjgwODAvYWN0aXZpdGlIaXN0b3J5L2dldGhpZ2hMaW5lJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnR0VUJyxcbiAgICAgICAgICAgICAgICBkYXRhOiBwYXJhbTEsXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6J2pzb24nLFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdClcbiAgICAgICAgICAgICAgICAgIHZhciBDb2xvckpzb249dG9vbHMuZ2V0QnlDb2xvcihyZXN1bHQuZGF0YSlcbiAgICAgICAgICAgICAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVybDogbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJWVUVfQVBQX0JBU0VfQVBJXCIpKycvcHJvY2Vzc0RlZmluaXRpb24vZ2V0RGVmaW5pdGlvblhNTCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB1cmw6ICdodHRwOi8vbG9jYWxob3N0OjgwODAvcHJvY2Vzc0RlZmluaXRpb24vZ2V0RGVmaW5pdGlvblhNTCcsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnR0VUJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHBhcmFtLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6J3RleHQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdYbWxEYXRhID0gcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHMuY3JlYXRlRGlhZ3JhbShuZXdYbWxEYXRhLCBicG1uTW9kZWxlciwgY29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBDb2xvckpzb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xzLnNldENvbG9yKENvbG9ySnNvbltpXSxicG1uTW9kZWxlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDIwMClcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycilcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1lbHNle1xuICAgICAgICAgICAgLy/liqDovb3lkI7lj7Dmlrnms5Xojrflj5Z4bWxcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcIlZVRV9BUFBfQkFTRV9BUElcIikrJy9wcm9jZXNzRGVmaW5pdGlvbi9nZXREZWZpbml0aW9uWE1MJyxcbiAgICAgICAgICAgICAgLy8gdXJsOiAnaHR0cDovL2xvY2FsaG9zdDo4MDgwL3Byb2Nlc3NEZWZpbml0aW9uL2dldERlZmluaXRpb25YTUwnLFxuICAgICAgICAgICAgICAgIHR5cGU6ICdHRVQnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHBhcmFtLFxuICAgICAgICAgICAgICAgIGRhdGFUeXBlOid0ZXh0JyxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXdYbWxEYXRhID0gcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgIHRvb2xzLmNyZWF0ZURpYWdyYW0obmV3WG1sRGF0YSwgYnBtbk1vZGVsZXIsIGNvbnRhaW5lcik7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYocGFyYW0udHlwZSA9PT0gXCJoaXN0b3J5QnBtblwiKSB7IC8vIGJwbW7ljoblj7JcbiAgICAgICAgJCgnLml0ZW0nKS5oaWRlKClcbiAgICAgICAgJCgnLmRvd25sb2FkJykuc2hvdygpXG4gICAgfVxuICAgIC8vIOeCueWHu+aWsOWinlxuICAgICQoJyNqcy1kb3dubG9hZC1kaWFncmFtJykub24oXCJjbGlja1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgdG9vbHMuc3lvcGVuKCdhbGVydCcpXG4gICAgfSlcblxuICAgIC8vIOeCueWHu+WPlua2iFxuICAgICQoJy5jYW5jZWwnKS5vbihcImNsaWNrXCIsZnVuY3Rpb24gKCkge1xuICAgICAgICB0b29scy5zeWhpZGUoJ2FsZXJ0JylcbiAgICB9KVxuICAgIC8vIOeCueWHu+ehruWumlxuICAgICQoJyNzdXJlJykub24oJ2NsaWNrJyxmdW5jdGlvbigpe1xuICAgICAgIC8vIGNvbnN0IHRleHQ9JChcIiNkZXBsb3ltZW50TmFtZVwiKS52YWwoKVxuICAgICAgICB0b29scy5zYXZlQnBtbihicG1uTW9kZWxlcilcbiAgICB9KVxuXG5cblxuICAgIC8vIOeCueWHu+S4i+i9vVxuICAgICQoXCIjZG93bmxvYWRCcG1uXCIpLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICB0b29scy5kb3duTG9hZChicG1uTW9kZWxlcilcbiAgICB9KVxuICAgIC8vIOeCueWHu+S4iuS8oFxuICAgICQoXCIjdXBsb2FkRmlsZVwiKS5vbihcImNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRvb2xzLnVwbG9hZChicG1uTW9kZWxlcixjb250YWluZXIpXG4gICAgfSlcbn0pO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYicpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4vVXRpbHMnKS5lc2NhcGVIVE1MO1xuXG52YXIgZG9taWZ5ID0gcmVxdWlyZSgnbWluLWRvbScpLmRvbWlmeSxcbiAgICBkb21RdWVyeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeSxcbiAgICBkb21RdWVyeUFsbCA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeUFsbCxcbiAgICBkb21SZW1vdmUgPSByZXF1aXJlKCdtaW4tZG9tJykucmVtb3ZlLFxuICAgIGRvbUNsYXNzZXMgPSByZXF1aXJlKCdtaW4tZG9tJykuY2xhc3NlcyxcbiAgICBkb21DbG9zZXN0ID0gcmVxdWlyZSgnbWluLWRvbScpLmNsb3Nlc3QsXG4gICAgZG9tQXR0ciA9IHJlcXVpcmUoJ21pbi1kb20nKS5hdHRyLFxuICAgIGRvbURlbGVnYXRlID0gcmVxdWlyZSgnbWluLWRvbScpLmRlbGVnYXRlLFxuICAgIGRvbU1hdGNoZXMgPSByZXF1aXJlKCdtaW4tZG9tJykubWF0Y2hlcztcblxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpLFxuICAgIGZpbHRlciA9IHJlcXVpcmUoJ2xvZGFzaC9maWx0ZXInKSxcbiAgICBnZXQgPSByZXF1aXJlKCdsb2Rhc2gvZ2V0JyksXG4gICAga2V5cyA9IHJlcXVpcmUoJ2xvZGFzaC9rZXlzJyksXG4gICAgaXNFbXB0eSA9IHJlcXVpcmUoJ2xvZGFzaC9pc0VtcHR5JyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJ2xvZGFzaC9pc0FycmF5JyksXG4gICAgeG9yID0gcmVxdWlyZSgnbG9kYXNoL3hvcicpLFxuICAgIGRlYm91bmNlID0gcmVxdWlyZSgnbG9kYXNoL2RlYm91bmNlJyk7XG5cbnZhciB1cGRhdGVTZWxlY3Rpb24gPSByZXF1aXJlKCdzZWxlY3Rpb24tdXBkYXRlJyk7XG5cbnZhciBzY3JvbGxUYWJzID0gcmVxdWlyZSgnc2Nyb2xsLXRhYnMnKS5kZWZhdWx0O1xuXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xuXG52YXIgSElERV9DTEFTUyA9ICdicHAtaGlkZGVuJztcbnZhciBERUJPVU5DRV9ERUxBWSA9IDMwMDtcblxuXG5mdW5jdGlvbiBpc1RvZ2dsZShub2RlKSB7XG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdjaGVja2JveCcgfHwgbm9kZS50eXBlID09PSAncmFkaW8nO1xufVxuXG5mdW5jdGlvbiBpc1NlbGVjdChub2RlKSB7XG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdzZWxlY3Qtb25lJztcbn1cblxuZnVuY3Rpb24gaXNDb250ZW50RWRpdGFibGUobm9kZSkge1xuICByZXR1cm4gZG9tQXR0cihub2RlLCAnY29udGVudGVkaXRhYmxlJyk7XG59XG5cbmZ1bmN0aW9uIGdldFByb3BlcnR5UGxhY2Vob2xkZXJzKG5vZGUpIHtcbiAgdmFyIHNlbGVjdG9yID0gJ2lucHV0W25hbWVdLCB0ZXh0YXJlYVtuYW1lXSwgW2RhdGEtdmFsdWVdLCBbY29udGVudGVkaXRhYmxlXSc7XG4gIHZhciBwbGFjZWhvbGRlcnMgPSBkb21RdWVyeUFsbChzZWxlY3Rvciwgbm9kZSk7XG4gIGlmICgoIXBsYWNlaG9sZGVycyB8fCAhcGxhY2Vob2xkZXJzLmxlbmd0aCkgJiYgZG9tTWF0Y2hlcyhub2RlLCBzZWxlY3RvcikpIHtcbiAgICBwbGFjZWhvbGRlcnMgPSBbIG5vZGUgXTtcbiAgfVxuICByZXR1cm4gcGxhY2Vob2xkZXJzO1xufVxuXG4vKipcbiAqIFJldHVybiBhbGwgYWN0aXZlIGZvcm0gY29udHJvbHMuXG4gKiBUaGlzIGV4Y2x1ZGVzIHRoZSBpbnZpc2libGUgY29udHJvbHMgdW5sZXNzIGFsbCBpcyB0cnVlXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFthbGw9ZmFsc2VdXG4gKi9cbmZ1bmN0aW9uIGdldEZvcm1Db250cm9scyhub2RlLCBhbGwpIHtcbiAgdmFyIGNvbnRyb2xzID0gZG9tUXVlcnlBbGwoJ2lucHV0W25hbWVdLCB0ZXh0YXJlYVtuYW1lXSwgc2VsZWN0W25hbWVdLCBbY29udGVudGVkaXRhYmxlXScsIG5vZGUpO1xuXG4gIGlmICghY29udHJvbHMgfHwgIWNvbnRyb2xzLmxlbmd0aCkge1xuICAgIGNvbnRyb2xzID0gZG9tTWF0Y2hlcyhub2RlLCAnb3B0aW9uJykgPyBbIG5vZGUgXSA6IGNvbnRyb2xzO1xuICB9XG5cbiAgaWYgKCFhbGwpIHtcbiAgICBjb250cm9scyA9IGZpbHRlcihjb250cm9scywgZnVuY3Rpb24obm9kZSkge1xuICAgICAgcmV0dXJuICFkb21DbG9zZXN0KG5vZGUsICcuJyArIEhJREVfQ0xBU1MpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRyb2xzO1xufVxuXG5mdW5jdGlvbiBnZXRGb3JtQ29udHJvbFZhbHVlc0luU2NvcGUoZW50cnlOb2RlKSB7XG4gIHZhciB2YWx1ZXMgPSB7fTtcblxuICB2YXIgY29udHJvbE5vZGVzID0gZ2V0Rm9ybUNvbnRyb2xzKGVudHJ5Tm9kZSk7XG5cbiAgZm9yRWFjaChjb250cm9sTm9kZXMsIGZ1bmN0aW9uKGNvbnRyb2xOb2RlKSB7XG4gICAgdmFyIHZhbHVlID0gY29udHJvbE5vZGUudmFsdWU7XG5cbiAgICB2YXIgbmFtZSA9IGRvbUF0dHIoY29udHJvbE5vZGUsICduYW1lJykgfHwgZG9tQXR0cihjb250cm9sTm9kZSwgJ2RhdGEtbmFtZScpO1xuXG4gICAgLy8gdGFrZSB0b2dnbGUgc3RhdGUgaW50byBhY2NvdW50IGZvciByYWRpbyAvIGNoZWNrYm94ZXNcbiAgICBpZiAoaXNUb2dnbGUoY29udHJvbE5vZGUpKSB7XG4gICAgICBpZiAoY29udHJvbE5vZGUuY2hlY2tlZCkge1xuICAgICAgICBpZiAoIWRvbUF0dHIoY29udHJvbE5vZGUsICd2YWx1ZScpKSB7XG4gICAgICAgICAgdmFsdWUgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlID0gY29udHJvbE5vZGUudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2VcbiAgICBpZiAoaXNDb250ZW50RWRpdGFibGUoY29udHJvbE5vZGUpKSB7XG4gICAgICB2YWx1ZSA9IGNvbnRyb2xOb2RlLmlubmVyVGV4dDtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgIC8vIHJldHVybiB0aGUgYWN0dWFsIHZhbHVlXG4gICAgICAvLyBoYW5kbGUgc2VyaWFsaXphdGlvbiBpbiBlbnRyeSBwcm92aWRlclxuICAgICAgLy8gKGllLiBpZiBlbXB0eSBzdHJpbmcgc2hvdWxkIGJlIHNlcmlhbGl6ZWQgb3Igbm90KVxuICAgICAgdmFsdWVzW25hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gdmFsdWVzO1xuXG59XG5cbi8qKlxuICogRXh0cmFjdCBpbnB1dCB2YWx1ZXMgZnJvbSBlbnRyeSBub2RlXG4gKlxuICogQHBhcmFtICB7RE9NRWxlbWVudH0gZW50cnlOb2RlXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBnZXRGb3JtQ29udHJvbFZhbHVlcyhlbnRyeU5vZGUpIHtcblxuICB2YXIgdmFsdWVzO1xuXG4gIHZhciBsaXN0Q29udGFpbmVyID0gZG9tUXVlcnkoJ1tkYXRhLWxpc3QtZW50cnktY29udGFpbmVyXScsIGVudHJ5Tm9kZSk7XG4gIGlmIChsaXN0Q29udGFpbmVyKSB7XG4gICAgdmFsdWVzID0gW107XG4gICAgdmFyIGxpc3ROb2RlcyA9IGxpc3RDb250YWluZXIuY2hpbGRyZW4gfHwgW107XG4gICAgZm9yRWFjaChsaXN0Tm9kZXMsIGZ1bmN0aW9uKGxpc3ROb2RlKSB7XG4gICAgICB2YWx1ZXMucHVzaChnZXRGb3JtQ29udHJvbFZhbHVlc0luU2NvcGUobGlzdE5vZGUpKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB2YWx1ZXMgPSBnZXRGb3JtQ29udHJvbFZhbHVlc0luU2NvcGUoZW50cnlOb2RlKTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZXM7XG59XG5cbi8qKlxuICogUmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIGZvcm0gZXh0cmFjdGVkIHZhbHVlIGVxdWFsc1xuICogdG8gYW4gb2xkIGNhY2hlZCB2ZXJzaW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZVxuICogQHBhcmFtIHtPYmplY3R9IG9sZFZhbHVlXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiB2YWx1ZUVxdWFsKHZhbHVlLCBvbGRWYWx1ZSkge1xuXG4gIGlmICh2YWx1ZSAmJiAhb2xkVmFsdWUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgYWxsS2V5cyA9IGtleXModmFsdWUpLmNvbmNhdChrZXlzKG9sZFZhbHVlKSk7XG5cbiAgcmV0dXJuIGFsbEtleXMuZXZlcnkoZnVuY3Rpb24oa2V5KSB7XG4gICAgcmV0dXJuIHZhbHVlW2tleV0gPT09IG9sZFZhbHVlW2tleV07XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBmb3JtIGV4dHJhY3RlZCB2YWx1ZShzKVxuICogZXF1YWwgYW4gb2xkIGNhY2hlZCB2ZXJzaW9uLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0PnxPYmplY3R9IHZhbHVlc1xuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fE9iamVjdH0gb2xkVmFsdWVzXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiB2YWx1ZXNFcXVhbCh2YWx1ZXMsIG9sZFZhbHVlcykge1xuXG4gIGlmIChpc0FycmF5KHZhbHVlcykpIHtcblxuICAgIGlmICh2YWx1ZXMubGVuZ3RoICE9PSBvbGRWYWx1ZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcy5ldmVyeShmdW5jdGlvbih2LCBpZHgpIHtcbiAgICAgIHJldHVybiB2YWx1ZUVxdWFsKHYsIG9sZFZhbHVlc1tpZHhdKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZUVxdWFsKHZhbHVlcywgb2xkVmFsdWVzKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBtYXBwaW5nIG9mIHsgaWQ6IGVudHJ5IH0gZm9yIGFsbCBlbnRyaWVzIGluIHRoZSBnaXZlbiBncm91cHMgaW4gdGhlIGdpdmVuIHRhYnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRhYnNcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZXh0cmFjdEVudHJpZXModGFicykge1xuICByZXR1cm4ga2V5QnkoZmxhdHRlbkRlZXAobWFwKGZsYXR0ZW5EZWVwKG1hcCh0YWJzLCAnZ3JvdXBzJykpLCAnZW50cmllcycpKSwgJ2lkJyk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgbWFwcGluZyBvZiB7IGlkOiBncm91cCB9IGZvciBhbGwgZ3JvdXBzIGluIHRoZSBnaXZlbiB0YWJzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YWJzXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RHcm91cHModGFicykge1xuICByZXR1cm4ga2V5QnkoZmxhdHRlbkRlZXAobWFwKHRhYnMsICdncm91cHMnKSksICdpZCcpO1xufVxuXG4vKipcbiAqIEEgcHJvcGVydGllcyBwYW5lbCBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKiBUbyB1c2UgaXQgcHJvdmlkZSBhIGBwcm9wZXJ0aWVzUHJvdmlkZXJgIGNvbXBvbmVudCB0aGF0IGtub3dzXG4gKiBhYm91dCB3aGljaCBwcm9wZXJ0aWVzIHRvIGRpc3BsYXkuXG4gKlxuICogUHJvcGVydGllcyBlZGl0IHN0YXRlIC8gdmlzaWJpbGl0eSBjYW4gYmUgaW50ZXJjZXB0ZWRcbiAqIHZpYSBhIGN1c3RvbSB7QGxpbmsgUHJvcGVydGllc0FjdGl2YXRvcn0uXG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqIEBwYXJhbSB7UHJvcGVydGllc1Byb3ZpZGVyfSBwcm9wZXJ0aWVzUHJvdmlkZXJcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7Q29tbWFuZFN0YWNrfSBjb21tYW5kU3RhY2tcbiAqL1xuZnVuY3Rpb24gUHJvcGVydGllc1BhbmVsKGNvbmZpZywgZXZlbnRCdXMsIG1vZGVsaW5nLCBwcm9wZXJ0aWVzUHJvdmlkZXIsIGNvbW1hbmRTdGFjaywgY2FudmFzKSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fY29tbWFuZFN0YWNrID0gY29tbWFuZFN0YWNrO1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX3Byb3BlcnRpZXNQcm92aWRlciA9IHByb3BlcnRpZXNQcm92aWRlcjtcblxuICB0aGlzLl9pbml0KGNvbmZpZyk7XG59XG5cblByb3BlcnRpZXNQYW5lbC4kaW5qZWN0ID0gW1xuICAnY29uZmlnLnByb3BlcnRpZXNQYW5lbCcsXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZycsXG4gICdwcm9wZXJ0aWVzUHJvdmlkZXInLFxuICAnY29tbWFuZFN0YWNrJyxcbiAgJ2NhbnZhcydcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvcGVydGllc1BhbmVsO1xuXG5cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbihjb25maWcpIHtcblxuICB2YXIgY2FudmFzID0gdGhpcy5fY2FudmFzLFxuICAgICAgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgLyoqXG4gICAqIFNlbGVjdCB0aGUgcm9vdCBlbGVtZW50IG9uY2UgaXQgaXMgYWRkZWQgdG8gdGhlIGNhbnZhc1xuICAgKi9cbiAgZXZlbnRCdXMub24oJ3Jvb3QuYWRkZWQnLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBlLmVsZW1lbnQ7XG5cbiAgICBpZiAoaXNJbXBsaWNpdFJvb3QoZWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmLnVwZGF0ZShlbGVtZW50KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ3NlbGVjdGlvbi5jaGFuZ2VkJywgZnVuY3Rpb24oZSkge1xuICAgIHZhciBuZXdFbGVtZW50ID0gZS5uZXdTZWxlY3Rpb25bMF07XG5cbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKTtcblxuICAgIGlmIChpc0ltcGxpY2l0Um9vdChyb290RWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmLnVwZGF0ZShuZXdFbGVtZW50KTtcbiAgfSk7XG5cbiAgLy8gYWRkIC8gdXBkYXRlIHRhYi1iYXIgc2Nyb2xsaW5nXG4gIGV2ZW50QnVzLm9uKFtcbiAgICAncHJvcGVydGllc1BhbmVsLmNoYW5nZWQnLFxuICAgICdwcm9wZXJ0aWVzUGFuZWwucmVzaXplZCdcbiAgXSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciB0YWJCYXJOb2RlID0gZG9tUXVlcnkoJy5icHAtcHJvcGVydGllcy10YWItYmFyJywgc2VsZi5fY29udGFpbmVyKTtcblxuICAgIGlmICghdGFiQmFyTm9kZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBzY3JvbGxlciA9IHNjcm9sbFRhYnMuZ2V0KHRhYkJhck5vZGUpO1xuXG4gICAgaWYgKCFzY3JvbGxlcikge1xuXG4gICAgICAvLyB3ZSBkaWQgbm90IGluaXRpYWxpemUgeWV0LCBkbyB0aGF0XG4gICAgICAvLyBub3cgYW5kIG1ha2Ugc3VyZSB3ZSBzZWxlY3QgdGhlIGFjdGl2ZVxuICAgICAgLy8gdGFiIG9uIHNjcm9sbCB1cGRhdGVcbiAgICAgIHNjcm9sbGVyID0gc2Nyb2xsVGFicyh0YWJCYXJOb2RlLCB7XG4gICAgICAgIHNlbGVjdG9yczoge1xuICAgICAgICAgIHRhYnNDb250YWluZXI6ICcuYnBwLXByb3BlcnRpZXMtdGFicy1saW5rcycsXG4gICAgICAgICAgdGFiOiAnLmJwcC1wcm9wZXJ0aWVzLXRhYnMtbGlua3MgbGknLFxuICAgICAgICAgIGlnbm9yZTogJy5icHAtaGlkZGVuJyxcbiAgICAgICAgICBhY3RpdmU6ICcuYnBwLWFjdGl2ZSdcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgc2Nyb2xsZXIub24oJ3Njcm9sbCcsIGZ1bmN0aW9uKG5ld0FjdGl2ZU5vZGUsIG9sZEFjdGl2ZU5vZGUsIGRpcmVjdGlvbikge1xuXG4gICAgICAgIHZhciBsaW5rTm9kZSA9IGRvbVF1ZXJ5KCdbZGF0YS10YWItdGFyZ2V0XScsIG5ld0FjdGl2ZU5vZGUpO1xuXG4gICAgICAgIHZhciB0YWJJZCA9IGRvbUF0dHIobGlua05vZGUsICdkYXRhLXRhYi10YXJnZXQnKTtcblxuICAgICAgICBzZWxmLmFjdGl2YXRlVGFiKHRhYklkKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIHJlYWN0IG9uIHRhYiBjaGFuZ2VzIGFuZCBvciB0YWJDb250YWluZXIgcmVzaXplXG4gICAgLy8gYW5kIG1ha2Ugc3VyZSB0aGUgYWN0aXZlIHRhYiBpcyBzaG93biBjb21wbGV0ZWx5XG4gICAgc2Nyb2xsZXIudXBkYXRlKCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50cy5jaGFuZ2VkJywgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGN1cnJlbnQgPSBzZWxmLl9jdXJyZW50O1xuICAgIHZhciBlbGVtZW50ID0gY3VycmVudCAmJiBjdXJyZW50LmVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgaWYgKGUuZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTEpIHtcbiAgICAgICAgc2VsZi51cGRhdGUoZWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudFRlbXBsYXRlcy5jaGFuZ2VkJywgZnVuY3Rpb24oKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBzZWxmLl9jdXJyZW50O1xuICAgIHZhciBlbGVtZW50ID0gY3VycmVudCAmJiBjdXJyZW50LmVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgc2VsZi51cGRhdGUoZWxlbWVudCk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5kZXN0cm95JywgZnVuY3Rpb24oKSB7XG4gICAgc2VsZi5kZXRhY2goKTtcbiAgfSk7XG5cbiAgdGhpcy5fY29udGFpbmVyID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiYnBwLXByb3BlcnRpZXMtcGFuZWxcIj48L2Rpdj4nKTtcblxuICB0aGlzLl9iaW5kTGlzdGVuZXJzKHRoaXMuX2NvbnRhaW5lcik7XG5cbiAgaWYgKGNvbmZpZyAmJiBjb25maWcucGFyZW50KSB7XG4gICAgdGhpcy5hdHRhY2hUbyhjb25maWcucGFyZW50KTtcbiAgfVxufTtcblxuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLmF0dGFjaFRvID0gZnVuY3Rpb24ocGFyZW50Tm9kZSkge1xuXG4gIGlmICghcGFyZW50Tm9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncGFyZW50Tm9kZSByZXF1aXJlZCcpO1xuICB9XG5cbiAgLy8gZW5zdXJlIHdlIGRldGFjaCBmcm9tIHRoZVxuICAvLyBwcmV2aW91cywgb2xkIHBhcmVudFxuICB0aGlzLmRldGFjaCgpO1xuXG4gIC8vIHVud3JhcCBqUXVlcnkgaWYgcHJvdmlkZWRcbiAgaWYgKHBhcmVudE5vZGUuZ2V0ICYmIHBhcmVudE5vZGUuY29uc3RydWN0b3IucHJvdG90eXBlLmpxdWVyeSkge1xuICAgIHBhcmVudE5vZGUgPSBwYXJlbnROb2RlLmdldCgwKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcGFyZW50Tm9kZSA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXJlbnROb2RlID0gZG9tUXVlcnkocGFyZW50Tm9kZSk7XG4gIH1cblxuICB2YXIgY29udGFpbmVyID0gdGhpcy5fY29udGFpbmVyO1xuXG4gIHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICB0aGlzLl9lbWl0KCdhdHRhY2gnKTtcbn07XG5cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuZGV0YWNoID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lcixcbiAgICAgIHBhcmVudE5vZGUgPSBjb250YWluZXIucGFyZW50Tm9kZTtcblxuICBpZiAoIXBhcmVudE5vZGUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9lbWl0KCdkZXRhY2gnKTtcblxuICBwYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNvbnRhaW5lcik7XG59O1xuXG5cbi8qKlxuICogU2VsZWN0IHRoZSBnaXZlbiB0YWIgd2l0aGluIHRoZSBwcm9wZXJ0aWVzIHBhbmVsLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fFN0cmluZ30gdGFiXG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuYWN0aXZhdGVUYWIgPSBmdW5jdGlvbih0YWIpIHtcblxuICB2YXIgdGFiSWQgPSB0eXBlb2YgdGFiID09PSAnc3RyaW5nJyA/IHRhYiA6IHRhYi5pZDtcblxuICB2YXIgY3VycmVudCA9IHRoaXMuX2N1cnJlbnQ7XG5cbiAgdmFyIHBhbmVsTm9kZSA9IGN1cnJlbnQucGFuZWw7XG5cbiAgdmFyIGFsbFRhYk5vZGVzID0gZG9tUXVlcnlBbGwoJy5icHAtcHJvcGVydGllcy10YWInLCBwYW5lbE5vZGUpLFxuICAgICAgYWxsVGFiTGlua05vZGVzID0gZG9tUXVlcnlBbGwoJy5icHAtcHJvcGVydGllcy10YWItbGluaycsIHBhbmVsTm9kZSk7XG5cbiAgZm9yRWFjaChhbGxUYWJOb2RlcywgZnVuY3Rpb24odGFiTm9kZSkge1xuXG4gICAgdmFyIGN1cnJlbnRUYWJJZCA9IGRvbUF0dHIodGFiTm9kZSwgJ2RhdGEtdGFiJyk7XG5cbiAgICBkb21DbGFzc2VzKHRhYk5vZGUpLnRvZ2dsZSgnYnBwLWFjdGl2ZScsIHRhYklkID09PSBjdXJyZW50VGFiSWQpO1xuICB9KTtcblxuICBmb3JFYWNoKGFsbFRhYkxpbmtOb2RlcywgZnVuY3Rpb24odGFiTGlua05vZGUpIHtcblxuICAgIHZhciB0YWJMaW5rID0gZG9tUXVlcnkoJ1tkYXRhLXRhYi10YXJnZXRdJywgdGFiTGlua05vZGUpLFxuICAgICAgICBjdXJyZW50VGFiSWQgPSBkb21BdHRyKHRhYkxpbmssICdkYXRhLXRhYi10YXJnZXQnKTtcblxuICAgIGRvbUNsYXNzZXModGFiTGlua05vZGUpLnRvZ2dsZSgnYnBwLWFjdGl2ZScsIHRhYklkID09PSBjdXJyZW50VGFiSWQpO1xuICB9KTtcbn07XG5cbi8qKlxuICogVXBkYXRlIHRoZSBET00gcmVwcmVzZW50YXRpb24gb2YgdGhlIHByb3BlcnRpZXMgcGFuZWxcbiAqL1xuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5fY3VycmVudDtcblxuICAvLyBubyBhY3R1YWwgc2VsZWN0aW9uIGNoYW5nZVxuICB2YXIgbmVlZHNDcmVhdGUgPSB0cnVlO1xuXG4gIGlmICh0eXBlb2YgZWxlbWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcblxuICAgIC8vIHVzZSBSb290RWxlbWVudCBvZiBCUE1OIGRpYWdyYW0gdG8gZ2VuZXJhdGUgcHJvcGVydGllcyBwYW5lbCBpZiBubyBlbGVtZW50IGlzIHNlbGVjdGVkXG4gICAgZWxlbWVudCA9IHRoaXMuX2NhbnZhcy5nZXRSb290RWxlbWVudCgpO1xuICB9XG5cbiAgdmFyIG5ld1RhYnMgPSB0aGlzLl9wcm9wZXJ0aWVzUHJvdmlkZXIuZ2V0VGFicyhlbGVtZW50KTtcblxuICBpZiAoY3VycmVudCAmJiBjdXJyZW50LmVsZW1lbnQgPT09IGVsZW1lbnQpIHtcbiAgICAvLyBzZWUgaWYgd2UgY2FuIHJldXNlIHRoZSBleGlzdGluZyBwYW5lbFxuXG4gICAgbmVlZHNDcmVhdGUgPSB0aGlzLl9lbnRyaWVzQ2hhbmdlZChjdXJyZW50LCBuZXdUYWJzKTtcbiAgfVxuXG4gIGlmIChuZWVkc0NyZWF0ZSkge1xuXG4gICAgaWYgKGN1cnJlbnQpIHtcblxuICAgICAgLy8gZ2V0IGFjdGl2ZSB0YWIgZnJvbSB0aGUgZXhpc3RpbmcgcGFuZWwgYmVmb3JlIHJlbW92ZSBpdFxuICAgICAgdmFyIGFjdGl2ZVRhYk5vZGUgPSBkb21RdWVyeSgnLmJwcC1wcm9wZXJ0aWVzLXRhYi5icHAtYWN0aXZlJywgY3VycmVudC5wYW5lbCk7XG5cbiAgICAgIHZhciBhY3RpdmVUYWJJZDtcbiAgICAgIGlmIChhY3RpdmVUYWJOb2RlKSB7XG4gICAgICAgIGFjdGl2ZVRhYklkID0gZG9tQXR0cihhY3RpdmVUYWJOb2RlLCAnZGF0YS10YWInKTtcbiAgICAgIH1cblxuICAgICAgLy8gcmVtb3ZlIG9sZCBwYW5lbFxuICAgICAgZG9tUmVtb3ZlKGN1cnJlbnQucGFuZWwpO1xuICAgIH1cblxuICAgIHRoaXMuX2N1cnJlbnQgPSB0aGlzLl9jcmVhdGUoZWxlbWVudCwgbmV3VGFicyk7XG5cbiAgICAvLyBhY3RpdmF0ZSB0aGUgc2F2ZWQgYWN0aXZlIHRhYiBmcm9tIHRoZSByZW1vdmUgcGFuZWwgb3IgdGhlIGZpcnN0IHRhYlxuICAgIChhY3RpdmVUYWJJZCkgPyB0aGlzLmFjdGl2YXRlVGFiKGFjdGl2ZVRhYklkKSA6IHRoaXMuYWN0aXZhdGVUYWIodGhpcy5fY3VycmVudC50YWJzWzBdKTtcblxuICB9XG5cbiAgaWYgKHRoaXMuX2N1cnJlbnQpIHtcbiAgICAvLyBtYWtlIHN1cmUgY29ycmVjdCB0YWIgY29udGVudHMgYXJlIHZpc2libGVcbiAgICB0aGlzLl91cGRhdGVBY3RpdmF0aW9uKHRoaXMuX2N1cnJlbnQpO1xuXG4gIH1cblxuICB0aGlzLl9lbWl0KCdjaGFuZ2VkJyk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIG9uZSBvZiB0d28gZ3JvdXBzIGhhcyBkaWZmZXJlbnQgZW50cmllcyB0aGFuIHRoZSBvdGhlci5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGN1cnJlbnRcbiAqIEBwYXJhbSAge09iamVjdH0gbmV3VGFic1xuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS5fZW50cmllc0NoYW5nZWQgPSBmdW5jdGlvbihjdXJyZW50LCBuZXdUYWJzKSB7XG5cbiAgdmFyIG9sZEVudHJ5SWRzID0ga2V5cyhjdXJyZW50LmVudHJpZXMpLFxuICAgICAgbmV3RW50cnlJZHMgPSBrZXlzKGV4dHJhY3RFbnRyaWVzKG5ld1RhYnMpKTtcblxuICByZXR1cm4gIWlzRW1wdHkoeG9yKG9sZEVudHJ5SWRzLCBuZXdFbnRyeUlkcykpO1xufTtcblxuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS5fZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3Byb3BlcnRpZXNQYW5lbC4nICsgZXZlbnQsIHsgcGFuZWw6IHRoaXMsIGN1cnJlbnQ6IHRoaXMuX2N1cnJlbnQgfSk7XG59O1xuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLl9iaW5kTGlzdGVuZXJzID0gZnVuY3Rpb24oY29udGFpbmVyKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vIGhhbmRsZXMgYSBjaGFuZ2UgZm9yIGEgZ2l2ZW4gZXZlbnRcbiAgdmFyIGhhbmRsZUNoYW5nZSA9IGZ1bmN0aW9uIGhhbmRsZUNoYW5nZShldmVudCkge1xuXG4gICAgLy8gc2VlIGlmIHdlIGhhbmRsZSBhIGNoYW5nZSBpbnNpZGUgYSBbZGF0YS1lbnRyeV0gZWxlbWVudC5cbiAgICAvLyBpZiBub3QsIGRyb3Agb3V0XG4gICAgdmFyIGlucHV0Tm9kZSA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0LFxuICAgICAgICBlbnRyeU5vZGUgPSBkb21DbG9zZXN0KGlucHV0Tm9kZSwgJ1tkYXRhLWVudHJ5XScpLFxuICAgICAgICBlbnRyeUlkLCBlbnRyeTtcblxuICAgIC8vIGNoYW5nZSBmcm9tIG91dHNpZGUgYSBbZGF0YS1lbnRyeV0gZWxlbWVudCwgc2ltcGx5IGlnbm9yZVxuICAgIGlmICghZW50cnlOb2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZW50cnlJZCA9IGRvbUF0dHIoZW50cnlOb2RlLCAnZGF0YS1lbnRyeScpO1xuICAgIGVudHJ5ID0gc2VsZi5nZXRFbnRyeShlbnRyeUlkKTtcblxuICAgIHZhciB2YWx1ZXMgPSBnZXRGb3JtQ29udHJvbFZhbHVlcyhlbnRyeU5vZGUpO1xuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09ICdjaGFuZ2UnKSB7XG5cbiAgICAgIC8vIC0gaWYgdGhlIFwiZGF0YS1vbi1jaGFuZ2VcIiBhdHRyaWJ1dGUgaXMgcHJlc2VudCBhbmQgYSB2YWx1ZSBpcyBjaGFuZ2VkLFxuICAgICAgLy8gICB0aGVuIHRoZSBhc3NvY2lhdGVkIGFjdGlvbiBpcyBwZXJmb3JtZWQuXG4gICAgICAvLyAtIGlmIHRoZSBhc3NvY2lhdGVkIGFjdGlvbiByZXR1cm5zIFwidHJ1ZVwiIHRoZW4gYW4gdXBkYXRlIHRvIHRoZSBidXNpbmVzc1xuICAgICAgLy8gICBvYmplY3QgaXMgZG9uZVxuICAgICAgLy8gLSBpZiBpdCBkb2VzIG5vdCByZXR1cm4gXCJ0cnVlXCIsIHRoZW4gb25seSB0aGUgRE9NIGNvbnRlbnQgaXMgdXBkYXRlZFxuICAgICAgdmFyIG9uQ2hhbmdlQWN0aW9uID0gZG9tQXR0cihpbnB1dE5vZGUsICdkYXRhLW9uLWNoYW5nZScpO1xuXG4gICAgICBpZiAob25DaGFuZ2VBY3Rpb24pIHtcbiAgICAgICAgdmFyIGlzRW50cnlEaXJ0eSA9IHNlbGYuZXhlY3V0ZUFjdGlvbihlbnRyeSwgZW50cnlOb2RlLCBvbkNoYW5nZUFjdGlvbiwgZXZlbnQpO1xuXG4gICAgICAgIGlmICghaXNFbnRyeURpcnR5KSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYudXBkYXRlKHNlbGYuX2N1cnJlbnQuZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgc2VsZi5hcHBseUNoYW5nZXMoZW50cnksIHZhbHVlcywgZW50cnlOb2RlKTtcbiAgICBzZWxmLnVwZGF0ZVN0YXRlKGVudHJ5LCBlbnRyeU5vZGUpO1xuICB9O1xuXG4gIC8vIGRlYm91bmNlIHVwZGF0ZSBvbmx5IGVsZW1lbnRzIHRoYXQgYXJlIHRhcmdldCBvZiBrZXkgZXZlbnRzLFxuICAvLyBpLmUuIElOUFVUIGFuZCBURVhUQVJFQS4gU0VMRUNUcyB3aWxsIHRyaWdnZXIgYW4gaW1tZWRpYXRlIHVwZGF0ZSBhbnl3YXkuXG4gIGRvbURlbGVnYXRlLmJpbmQoY29udGFpbmVyLCAnaW5wdXQsIHRleHRhcmVhLCBbY29udGVudGVkaXRhYmxlXScsICdpbnB1dCcsIGRlYm91bmNlKGhhbmRsZUNoYW5nZSwgREVCT1VOQ0VfREVMQVkpKTtcbiAgZG9tRGVsZWdhdGUuYmluZChjb250YWluZXIsICdpbnB1dCwgdGV4dGFyZWEsIHNlbGVjdCwgW2NvbnRlbnRlZGl0YWJsZV0nLCAnY2hhbmdlJywgaGFuZGxlQ2hhbmdlKTtcblxuICAvLyBoYW5kbGUga2V5IGV2ZW50c1xuICBkb21EZWxlZ2F0ZS5iaW5kKGNvbnRhaW5lciwgJ3NlbGVjdCcsICdrZXlkb3duJywgZnVuY3Rpb24oZSkge1xuXG4gICAgLy8gREVMXG4gICAgaWYgKGUua2V5Q29kZSA9PT0gNDYpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9KTtcblxuICBkb21EZWxlZ2F0ZS5iaW5kKGNvbnRhaW5lciwgJ1tkYXRhLWFjdGlvbl0nLCAnY2xpY2snLCBmdW5jdGlvbiBvbkNsaWNrKGV2ZW50KSB7XG5cbiAgICAvLyB0cmlnZ2VycyBvbiBhbGwgaW5wdXRzXG4gICAgdmFyIGlucHV0Tm9kZSA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0LFxuICAgICAgICBlbnRyeU5vZGUgPSBkb21DbG9zZXN0KGlucHV0Tm9kZSwgJ1tkYXRhLWVudHJ5XScpO1xuXG4gICAgdmFyIGFjdGlvbklkID0gZG9tQXR0cihpbnB1dE5vZGUsICdkYXRhLWFjdGlvbicpLFxuICAgICAgICBlbnRyeUlkID0gZG9tQXR0cihlbnRyeU5vZGUsICdkYXRhLWVudHJ5Jyk7XG5cbiAgICB2YXIgZW50cnkgPSBzZWxmLmdldEVudHJ5KGVudHJ5SWQpO1xuXG4gICAgdmFyIGlzRW50cnlEaXJ0eSA9IHNlbGYuZXhlY3V0ZUFjdGlvbihlbnRyeSwgZW50cnlOb2RlLCBhY3Rpb25JZCwgZXZlbnQpO1xuXG4gICAgaWYgKGlzRW50cnlEaXJ0eSkge1xuICAgICAgdmFyIHZhbHVlcyA9IGdldEZvcm1Db250cm9sVmFsdWVzKGVudHJ5Tm9kZSk7XG5cbiAgICAgIHNlbGYuYXBwbHlDaGFuZ2VzKGVudHJ5LCB2YWx1ZXMsIGVudHJ5Tm9kZSk7XG4gICAgfVxuXG4gICAgc2VsZi51cGRhdGVTdGF0ZShlbnRyeSwgZW50cnlOb2RlKTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gaGFuZGxlSW5wdXQoZXZlbnQsIGVsZW1lbnQpIHtcbiAgICAvLyB0cmlnZ2VycyBvbiBhbGwgaW5wdXRzXG4gICAgdmFyIGlucHV0Tm9kZSA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0O1xuXG4gICAgdmFyIGVudHJ5Tm9kZSA9IGRvbUNsb3Nlc3QoaW5wdXROb2RlLCAnW2RhdGEtZW50cnldJyk7XG5cbiAgICAvLyBvbmx5IHdvcmsgb24gZGF0YSBlbnRyaWVzXG4gICAgaWYgKCFlbnRyeU5vZGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZXZlbnRIYW5kbGVySWQgPSBkb21BdHRyKGlucHV0Tm9kZSwgJ2RhdGEtYmx1cicpLFxuICAgICAgICBlbnRyeUlkID0gZG9tQXR0cihlbnRyeU5vZGUsICdkYXRhLWVudHJ5Jyk7XG5cbiAgICB2YXIgZW50cnkgPSBzZWxmLmdldEVudHJ5KGVudHJ5SWQpO1xuXG4gICAgdmFyIGlzRW50cnlEaXJ0eSA9IHNlbGYuZXhlY3V0ZUFjdGlvbihlbnRyeSwgZW50cnlOb2RlLCBldmVudEhhbmRsZXJJZCwgZXZlbnQpO1xuXG4gICAgaWYgKGlzRW50cnlEaXJ0eSkge1xuICAgICAgdmFyIHZhbHVlcyA9IGdldEZvcm1Db250cm9sVmFsdWVzKGVudHJ5Tm9kZSk7XG5cbiAgICAgIHNlbGYuYXBwbHlDaGFuZ2VzKGVudHJ5LCB2YWx1ZXMsIGVudHJ5Tm9kZSk7XG4gICAgfVxuXG4gICAgc2VsZi51cGRhdGVTdGF0ZShlbnRyeSwgZW50cnlOb2RlKTtcbiAgfVxuXG4gIGRvbURlbGVnYXRlLmJpbmQoY29udGFpbmVyLCAnW2RhdGEtYmx1cl0nLCAnYmx1cicsIGhhbmRsZUlucHV0LCB0cnVlKTtcblxuICAvLyBtYWtlIHRhYiBsaW5rcyBpbnRlcmFjdGl2ZVxuICBkb21EZWxlZ2F0ZS5iaW5kKGNvbnRhaW5lciwgJy5icHAtcHJvcGVydGllcy10YWJzLWxpbmtzIFtkYXRhLXRhYi10YXJnZXRdJywgJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgdmFyIGRlbGVnYXRlVGFyZ2V0ID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQ7XG5cbiAgICB2YXIgdGFiSWQgPSBkb21BdHRyKGRlbGVnYXRlVGFyZ2V0LCAnZGF0YS10YWItdGFyZ2V0Jyk7XG5cbiAgICAvLyBhY3RpdmF0ZSB0YWIgb24gbGluayBjbGlja1xuICAgIHNlbGYuYWN0aXZhdGVUYWIodGFiSWQpO1xuICB9KTtcblxufTtcblxuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS51cGRhdGVTdGF0ZSA9IGZ1bmN0aW9uKGVudHJ5LCBlbnRyeU5vZGUpIHtcbiAgdGhpcy51cGRhdGVTaG93KGVudHJ5LCBlbnRyeU5vZGUpO1xuICB0aGlzLnVwZGF0ZURpc2FibGUoZW50cnksIGVudHJ5Tm9kZSk7XG59O1xuXG4vKipcbiAqIFVwZGF0ZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgZW50cnkgbm9kZSBpbiB0aGUgRE9NXG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUudXBkYXRlU2hvdyA9IGZ1bmN0aW9uKGVudHJ5LCBub2RlKSB7XG5cbiAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50O1xuXG4gIGlmICghY3VycmVudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzaG93Tm9kZXMgPSBkb21RdWVyeUFsbCgnW2RhdGEtc2hvd10nLCBub2RlKSB8fCBbXTtcblxuICBmb3JFYWNoKHNob3dOb2RlcywgZnVuY3Rpb24oc2hvd05vZGUpIHtcblxuICAgIHZhciBleHByID0gZG9tQXR0cihzaG93Tm9kZSwgJ2RhdGEtc2hvdycpO1xuICAgIHZhciBmbiA9IGdldChlbnRyeSwgZXhwcik7XG4gICAgaWYgKGZuKSB7XG4gICAgICB2YXIgc2NvcGUgPSBkb21DbG9zZXN0KHNob3dOb2RlLCAnW2RhdGEtc2NvcGVdJykgfHwgbm9kZTtcbiAgICAgIHZhciBzaG91bGRTaG93ID0gZm4oY3VycmVudC5lbGVtZW50LCBub2RlLCBzaG93Tm9kZSwgc2NvcGUpIHx8IGZhbHNlO1xuICAgICAgaWYgKHNob3VsZFNob3cpIHtcbiAgICAgICAgZG9tQ2xhc3NlcyhzaG93Tm9kZSkucmVtb3ZlKEhJREVfQ0xBU1MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG9tQ2xhc3NlcyhzaG93Tm9kZSkuYWRkKEhJREVfQ0xBU1MpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59O1xuXG4vKipcbiAqIEV2YWx1YXRlcyBhIGdpdmVuIGZ1bmN0aW9uLiBJZiBpdCByZXR1cm5zIHRydWUsIHRoZW4gdGhlXG4gKiBub2RlIGlzIG1hcmtlZCBhcyBcImRpc2FibGVkXCIuXG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUudXBkYXRlRGlzYWJsZSA9IGZ1bmN0aW9uKGVudHJ5LCBub2RlKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5fY3VycmVudDtcblxuICBpZiAoIWN1cnJlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbm9kZXMgPSBkb21RdWVyeUFsbCgnW2RhdGEtZGlzYWJsZV0nLCBub2RlKSB8fCBbXTtcblxuICBmb3JFYWNoKG5vZGVzLCBmdW5jdGlvbihjdXJyZW50Tm9kZSkge1xuICAgIHZhciBleHByID0gZG9tQXR0cihjdXJyZW50Tm9kZSwgJ2RhdGEtZGlzYWJsZScpO1xuICAgIHZhciBmbiA9IGdldChlbnRyeSwgZXhwcik7XG4gICAgaWYgKGZuKSB7XG4gICAgICB2YXIgc2NvcGUgPSBkb21DbG9zZXN0KGN1cnJlbnROb2RlLCAnW2RhdGEtc2NvcGVdJykgfHwgbm9kZTtcbiAgICAgIHZhciBzaG91bGREaXNhYmxlID0gZm4oY3VycmVudC5lbGVtZW50LCBub2RlLCBjdXJyZW50Tm9kZSwgc2NvcGUpIHx8IGZhbHNlO1xuICAgICAgZG9tQXR0cihjdXJyZW50Tm9kZSwgJ2Rpc2FibGVkJywgc2hvdWxkRGlzYWJsZSA/ICcnIDogbnVsbCk7XG4gICAgfVxuICB9KTtcbn07XG5cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuZXhlY3V0ZUFjdGlvbiA9IGZ1bmN0aW9uKGVudHJ5LCBlbnRyeU5vZGUsIGFjdGlvbklkLCBldmVudCkge1xuICB2YXIgY3VycmVudCA9IHRoaXMuX2N1cnJlbnQ7XG5cbiAgaWYgKCFjdXJyZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGZuID0gZ2V0KGVudHJ5LCBhY3Rpb25JZCk7XG4gIGlmIChmbikge1xuICAgIHZhciBzY29wZU5vZGUgPSBkb21DbG9zZXN0KGV2ZW50LnRhcmdldCwgJ1tkYXRhLXNjb3BlXScpIHx8IGVudHJ5Tm9kZTtcbiAgICByZXR1cm4gZm4uYXBwbHkoZW50cnksIFsgY3VycmVudC5lbGVtZW50LCBlbnRyeU5vZGUsIGV2ZW50LCBzY29wZU5vZGUgXSk7XG4gIH1cbn07XG5cbi8qKlxuICogQXBwbHkgY2hhbmdlcyB0byB0aGUgYnVzaW5lc3Mgb2JqZWN0IGJ5IGV4ZWN1dGluZyBhIGNvbW1hbmRcbiAqL1xuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS5hcHBseUNoYW5nZXMgPSBmdW5jdGlvbihlbnRyeSwgdmFsdWVzLCBjb250YWluZXJFbGVtZW50KSB7XG5cbiAgdmFyIGVsZW1lbnQgPSB0aGlzLl9jdXJyZW50LmVsZW1lbnQ7XG5cbiAgLy8gZW5zdXJlIHdlIG9ubHkgdXBkYXRlIHRoZSBtb2RlbCBpZiB3ZSBnb3QgZGlydHkgY2hhbmdlc1xuICBpZiAodmFsdWVzRXF1YWwodmFsdWVzLCBlbnRyeS5vbGRWYWx1ZXMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGNvbW1hbmQgPSBlbnRyeS5zZXQoZWxlbWVudCwgdmFsdWVzLCBjb250YWluZXJFbGVtZW50KTtcblxuICB2YXIgY29tbWFuZFRvRXhlY3V0ZTtcblxuICBpZiAoaXNBcnJheShjb21tYW5kKSkge1xuICAgIGlmIChjb21tYW5kLmxlbmd0aCkge1xuICAgICAgY29tbWFuZFRvRXhlY3V0ZSA9IHtcbiAgICAgICAgY21kOiAncHJvcGVydGllcy1wYW5lbC5tdWx0aS1jb21tYW5kLWV4ZWN1dG9yJyxcbiAgICAgICAgY29udGV4dDogZmxhdHRlbkRlZXAoY29tbWFuZClcbiAgICAgIH07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNvbW1hbmRUb0V4ZWN1dGUgPSBjb21tYW5kO1xuICB9XG5cbiAgaWYgKGNvbW1hbmRUb0V4ZWN1dGUpIHtcbiAgICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZShjb21tYW5kVG9FeGVjdXRlLmNtZCwgY29tbWFuZFRvRXhlY3V0ZS5jb250ZXh0IHx8IHsgZWxlbWVudCA6IGVsZW1lbnQgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy51cGRhdGUoZWxlbWVudCk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBhcHBseSB2YWxpZGF0aW9uIGVycm9ycyBpbiB0aGUgRE9NIGFuZCBzaG93IG9yIHJlbW92ZSBhbiBlcnJvciBtZXNzYWdlIG5lYXIgdGhlIGVudHJ5IG5vZGUuXG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuYXBwbHlWYWxpZGF0aW9uRXJyb3JzID0gZnVuY3Rpb24odmFsaWRhdGlvbkVycm9ycywgZW50cnlOb2RlKSB7XG5cbiAgdmFyIHZhbGlkID0gdHJ1ZTtcblxuICB2YXIgY29udHJvbE5vZGVzID0gZ2V0Rm9ybUNvbnRyb2xzKGVudHJ5Tm9kZSwgdHJ1ZSk7XG5cbiAgZm9yRWFjaChjb250cm9sTm9kZXMsIGZ1bmN0aW9uKGNvbnRyb2xOb2RlKSB7XG5cbiAgICB2YXIgbmFtZSA9IGRvbUF0dHIoY29udHJvbE5vZGUsICduYW1lJykgfHwgZG9tQXR0cihjb250cm9sTm9kZSwgJ2RhdGEtbmFtZScpO1xuXG4gICAgdmFyIGVycm9yID0gdmFsaWRhdGlvbkVycm9ycyAmJiB2YWxpZGF0aW9uRXJyb3JzW25hbWVdO1xuXG4gICAgdmFyIGVycm9yTWVzc2FnZU5vZGUgPSBkb21RdWVyeSgnLmJwcC1lcnJvci1tZXNzYWdlJywgY29udHJvbE5vZGUucGFyZW50Tm9kZSk7XG5cbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHZhbGlkID0gZmFsc2U7XG5cbiAgICAgIGlmICghZXJyb3JNZXNzYWdlTm9kZSkge1xuICAgICAgICBlcnJvck1lc3NhZ2VOb2RlID0gZG9taWZ5KCc8ZGl2PjwvZGl2PicpO1xuXG4gICAgICAgIGRvbUNsYXNzZXMoZXJyb3JNZXNzYWdlTm9kZSkuYWRkKCdicHAtZXJyb3ItbWVzc2FnZScpO1xuXG4gICAgICAgIC8vIGluc2VydCBlcnJvck1lc3NhZ2VOb2RlIGFmdGVyIGNvbnRyb2xOb2RlXG4gICAgICAgIGNvbnRyb2xOb2RlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVycm9yTWVzc2FnZU5vZGUsIGNvbnRyb2xOb2RlLm5leHRTaWJsaW5nKTtcbiAgICAgIH1cblxuICAgICAgZXJyb3JNZXNzYWdlTm9kZS50ZXh0Q29udGVudCA9IGVycm9yO1xuXG4gICAgICBkb21DbGFzc2VzKGNvbnRyb2xOb2RlKS5hZGQoJ2ludmFsaWQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZG9tQ2xhc3Nlcyhjb250cm9sTm9kZSkucmVtb3ZlKCdpbnZhbGlkJyk7XG5cbiAgICAgIGlmIChlcnJvck1lc3NhZ2VOb2RlKSB7XG4gICAgICAgIGNvbnRyb2xOb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZXJyb3JNZXNzYWdlTm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gdmFsaWQ7XG59O1xuXG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIGVudHJ5IGNvbnRhaW5zIHZhbGlkIGlucHV0XG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbihlbnRyeSwgdmFsdWVzLCBlbnRyeU5vZGUpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBjdXJyZW50ID0gdGhpcy5fY3VycmVudDtcblxuICB2YXIgdmFsaWQgPSB0cnVlO1xuXG4gIGVudHJ5Tm9kZSA9IGVudHJ5Tm9kZSB8fCBkb21RdWVyeSgnW2RhdGEtZW50cnk9XCInICsgZW50cnkuaWQgKyAnXCJdJywgY3VycmVudC5wYW5lbCk7XG5cbiAgaWYgKHZhbHVlcyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgdmFyIGxpc3RDb250YWluZXIgPSBkb21RdWVyeSgnW2RhdGEtbGlzdC1lbnRyeS1jb250YWluZXJdJywgZW50cnlOb2RlKSxcbiAgICAgICAgbGlzdEVudHJ5Tm9kZXMgPSBsaXN0Q29udGFpbmVyLmNoaWxkcmVuIHx8IFtdO1xuXG4gICAgLy8gY3JlYXRlIG5ldyBlbGVtZW50c1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbGlzdFZhbHVlID0gdmFsdWVzW2ldO1xuXG4gICAgICBpZiAoZW50cnkudmFsaWRhdGVMaXN0SXRlbSkge1xuXG4gICAgICAgIHZhciB2YWxpZGF0aW9uRXJyb3JzID0gZW50cnkudmFsaWRhdGVMaXN0SXRlbShjdXJyZW50LmVsZW1lbnQsIGxpc3RWYWx1ZSwgZW50cnlOb2RlLCBpKSxcbiAgICAgICAgICAgIGxpc3RFbnRyeU5vZGUgPSBsaXN0RW50cnlOb2Rlc1tpXTtcblxuICAgICAgICB2YWxpZCA9IHNlbGYuYXBwbHlWYWxpZGF0aW9uRXJyb3JzKHZhbGlkYXRpb25FcnJvcnMsIGxpc3RFbnRyeU5vZGUpICYmIHZhbGlkO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZW50cnkudmFsaWRhdGUpIHtcbiAgICAgIHRoaXMudmFsaWRhdGlvbkVycm9ycyA9IGVudHJ5LnZhbGlkYXRlKGN1cnJlbnQuZWxlbWVudCwgdmFsdWVzLCBlbnRyeU5vZGUpO1xuXG4gICAgICB2YWxpZCA9IHNlbGYuYXBwbHlWYWxpZGF0aW9uRXJyb3JzKHRoaXMudmFsaWRhdGlvbkVycm9ycywgZW50cnlOb2RlKSAmJiB2YWxpZDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdmFsaWQ7XG59O1xuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLmdldEVudHJ5ID0gZnVuY3Rpb24oaWQpIHtcbiAgcmV0dXJuIHRoaXMuX2N1cnJlbnQgJiYgdGhpcy5fY3VycmVudC5lbnRyaWVzW2lkXTtcbn07XG5cbnZhciBmbGF0dGVuRGVlcCA9IHJlcXVpcmUoJ2xvZGFzaC9mbGF0dGVuRGVlcCcpLFxuICAgIGtleUJ5ID0gcmVxdWlyZSgnbG9kYXNoL2tleUJ5JyksXG4gICAgbWFwID0gcmVxdWlyZSgnbG9kYXNoL21hcCcpO1xuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLl9jcmVhdGUgPSBmdW5jdGlvbihlbGVtZW50LCB0YWJzKSB7XG5cbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgY29udGFpbmVyTm9kZSA9IHRoaXMuX2NvbnRhaW5lcjtcblxuICB2YXIgcGFuZWxOb2RlID0gdGhpcy5fY3JlYXRlUGFuZWwoZWxlbWVudCwgdGFicyk7XG5cbiAgY29udGFpbmVyTm9kZS5hcHBlbmRDaGlsZChwYW5lbE5vZGUpO1xuXG4gIHZhciBlbnRyaWVzID0gZXh0cmFjdEVudHJpZXModGFicyk7XG4gIHZhciBncm91cHMgPSBleHRyYWN0R3JvdXBzKHRhYnMpO1xuXG4gIHJldHVybiB7XG4gICAgdGFiczogdGFicyxcbiAgICBncm91cHM6IGdyb3VwcyxcbiAgICBlbnRyaWVzOiBlbnRyaWVzLFxuICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgcGFuZWw6IHBhbmVsTm9kZVxuICB9O1xufTtcblxuLyoqXG4gKiBVcGRhdGUgdmFyaWFibGUgcGFydHMgb2YgdGhlIGVudHJ5IG5vZGUgb24gZWxlbWVudCBjaGFuZ2VzLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSB7RW50cnlEZXNjcmlwdG9yfSBlbnRyeVxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlc1xuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZW50cnlOb2RlXG4gKiBAcGFyYW0ge051bWJlcn0gaWR4XG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuX2JpbmRUZW1wbGF0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIGVudHJ5LCB2YWx1ZXMsIGVudHJ5Tm9kZSwgaWR4KSB7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgZnVuY3Rpb24gaXNQcm9wZXJ0eUVkaXRhYmxlKGVudHJ5LCBwcm9wZXJ0eU5hbWUpIHtcbiAgICByZXR1cm4gZXZlbnRCdXMuZmlyZSgncHJvcGVydGllc1BhbmVsLmlzUHJvcGVydHlFZGl0YWJsZScsIHtcbiAgICAgIGVudHJ5OiBlbnRyeSxcbiAgICAgIHByb3BlcnR5TmFtZTogcHJvcGVydHlOYW1lLFxuICAgICAgZWxlbWVudDogZWxlbWVudFxuICAgIH0pO1xuICB9XG5cbiAgdmFyIGlucHV0Tm9kZXMgPSBnZXRQcm9wZXJ0eVBsYWNlaG9sZGVycyhlbnRyeU5vZGUpO1xuXG4gIGZvckVhY2goaW5wdXROb2RlcywgZnVuY3Rpb24obm9kZSkge1xuXG4gICAgdmFyIG5hbWUsXG4gICAgICAgIG5ld1ZhbHVlLFxuICAgICAgICBlZGl0YWJsZTtcblxuICAgIC8vIHdlIGRlYWwgd2l0aCBhbiBpbnB1dCBlbGVtZW50XG4gICAgaWYgKCd2YWx1ZScgaW4gbm9kZSB8fCBpc0NvbnRlbnRFZGl0YWJsZShub2RlKSA9PT0gJ3RydWUnKSB7XG4gICAgICBuYW1lID0gZG9tQXR0cihub2RlLCAnbmFtZScpIHx8IGRvbUF0dHIobm9kZSwgJ2RhdGEtbmFtZScpO1xuICAgICAgbmV3VmFsdWUgPSB2YWx1ZXNbbmFtZV07XG5cbiAgICAgIGVkaXRhYmxlID0gaXNQcm9wZXJ0eUVkaXRhYmxlKGVudHJ5LCBuYW1lKTtcbiAgICAgIGlmIChlZGl0YWJsZSAmJiBlbnRyeS5lZGl0YWJsZSkge1xuICAgICAgICBlZGl0YWJsZSA9IGVudHJ5LmVkaXRhYmxlKGVsZW1lbnQsIGVudHJ5Tm9kZSwgbm9kZSwgbmFtZSwgbmV3VmFsdWUsIGlkeCk7XG4gICAgICB9XG5cbiAgICAgIGRvbUF0dHIobm9kZSwgJ3JlYWRvbmx5JywgZWRpdGFibGUgPyBudWxsIDogJycpO1xuICAgICAgZG9tQXR0cihub2RlLCAnZGlzYWJsZWQnLCBlZGl0YWJsZSA/IG51bGwgOiAnJyk7XG5cbiAgICAgIC8vIHRha2UgZnVsbCBjb250cm9sIG92ZXIgc2V0dGluZyB0aGUgdmFsdWVcbiAgICAgIC8vIGFuZCBwb3NzaWJseSB1cGRhdGluZyB0aGUgaW5wdXQgaW4gZW50cnkjc2V0Q29udHJvbFZhbHVlXG4gICAgICBpZiAoZW50cnkuc2V0Q29udHJvbFZhbHVlKSB7XG4gICAgICAgIGVudHJ5LnNldENvbnRyb2xWYWx1ZShlbGVtZW50LCBlbnRyeU5vZGUsIG5vZGUsIG5hbWUsIG5ld1ZhbHVlLCBpZHgpO1xuICAgICAgfSBlbHNlIGlmIChpc1RvZ2dsZShub2RlKSkge1xuICAgICAgICBzZXRUb2dnbGVWYWx1ZShub2RlLCBuZXdWYWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGlzU2VsZWN0KG5vZGUpKSB7XG4gICAgICAgIHNldFNlbGVjdFZhbHVlKG5vZGUsIG5ld1ZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldElucHV0VmFsdWUobm9kZSwgbmV3VmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHdlIGRlYWwgd2l0aCBzb21lIG5vbi1lZGl0YWJsZSBodG1sIGVsZW1lbnRcbiAgICBlbHNlIHtcbiAgICAgIG5hbWUgPSBkb21BdHRyKG5vZGUsICdkYXRhLXZhbHVlJyk7XG4gICAgICBuZXdWYWx1ZSA9IHZhbHVlc1tuYW1lXTtcbiAgICAgIGlmIChlbnRyeS5zZXRDb250cm9sVmFsdWUpIHtcbiAgICAgICAgZW50cnkuc2V0Q29udHJvbFZhbHVlKGVsZW1lbnQsIGVudHJ5Tm9kZSwgbm9kZSwgbmFtZSwgbmV3VmFsdWUsIGlkeCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRUZXh0VmFsdWUobm9kZSwgbmV3VmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59O1xuXG4vLyBUT0RPKG5pa2t1KTogV1RGIGZyZWFraW5nIG5hbWU/IENoYW5nZSAvIGNsYXJpZnkuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLl91cGRhdGVBY3RpdmF0aW9uID0gZnVuY3Rpb24oY3VycmVudCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgdmFyIGVsZW1lbnQgPSBjdXJyZW50LmVsZW1lbnQ7XG5cbiAgZnVuY3Rpb24gaXNFbnRyeVZpc2libGUoZW50cnkpIHtcbiAgICByZXR1cm4gZXZlbnRCdXMuZmlyZSgncHJvcGVydGllc1BhbmVsLmlzRW50cnlWaXNpYmxlJywge1xuICAgICAgZW50cnk6IGVudHJ5LFxuICAgICAgZWxlbWVudDogZWxlbWVudFxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNHcm91cFZpc2libGUoZ3JvdXAsIGVsZW1lbnQsIGdyb3VwTm9kZSkge1xuICAgIGlmICh0eXBlb2YgZ3JvdXAuZW5hYmxlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIGdyb3VwLmVuYWJsZWQoZWxlbWVudCwgZ3JvdXBOb2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaXNUYWJWaXNpYmxlKHRhYiwgZWxlbWVudCkge1xuICAgIGlmICh0eXBlb2YgdGFiLmVuYWJsZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB0YWIuZW5hYmxlZChlbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdG9nZ2xlVmlzaWJsZShub2RlLCB2aXNpYmxlKSB7XG4gICAgZG9tQ2xhc3Nlcyhub2RlKS50b2dnbGUoSElERV9DTEFTUywgIXZpc2libGUpO1xuICB9XG5cbiAgLy8gY2hlY2sgd2hldGhlciB0aGUgYWN0aXZlIHRhYiBpcyB2aXNpYmxlXG4gIC8vIGlmIG5vdDogc2V0IHRoZSBmaXJzdCB0YWIgYXMgYWN0aXZlIHRhYlxuICBmdW5jdGlvbiBjaGVja0FjdGl2ZVRhYlZpc2liaWxpdHkobm9kZSwgdmlzaWJsZSkge1xuICAgIHZhciBpc0FjdGl2ZSA9IGRvbUNsYXNzZXMobm9kZSkuaGFzKCdicHAtYWN0aXZlJyk7XG4gICAgaWYgKCF2aXNpYmxlICYmIGlzQWN0aXZlKSB7XG4gICAgICBzZWxmLmFjdGl2YXRlVGFiKGN1cnJlbnQudGFic1swXSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTGFiZWwoZWxlbWVudCwgc2VsZWN0b3IsIHRleHQpIHtcbiAgICB2YXIgbGFiZWxOb2RlID0gZG9tUXVlcnkoc2VsZWN0b3IsIGVsZW1lbnQpO1xuXG4gICAgaWYgKCFsYWJlbE5vZGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsYWJlbE5vZGUudGV4dENvbnRlbnQgPSB0ZXh0O1xuICB9XG5cbiAgdmFyIHBhbmVsTm9kZSA9IGN1cnJlbnQucGFuZWw7XG5cbiAgZm9yRWFjaChjdXJyZW50LnRhYnMsIGZ1bmN0aW9uKHRhYikge1xuXG4gICAgdmFyIHRhYk5vZGUgPSBkb21RdWVyeSgnW2RhdGEtdGFiPScgKyB0YWIuaWQgKyAnXScsIHBhbmVsTm9kZSk7XG4gICAgdmFyIHRhYkxpbmtOb2RlID0gZG9tUXVlcnkoJ1tkYXRhLXRhYi10YXJnZXQ9JyArIHRhYi5pZCArICddJywgcGFuZWxOb2RlKS5wYXJlbnROb2RlO1xuXG4gICAgdmFyIHRhYlZpc2libGUgPSBmYWxzZTtcblxuICAgIGZvckVhY2godGFiLmdyb3VwcywgZnVuY3Rpb24oZ3JvdXApIHtcblxuICAgICAgdmFyIGdyb3VwVmlzaWJsZSA9IGZhbHNlO1xuXG4gICAgICB2YXIgZ3JvdXBOb2RlID0gZG9tUXVlcnkoJ1tkYXRhLWdyb3VwPScgKyBncm91cC5pZCArICddJywgdGFiTm9kZSk7XG5cbiAgICAgIGZvckVhY2goZ3JvdXAuZW50cmllcywgZnVuY3Rpb24oZW50cnkpIHtcblxuICAgICAgICB2YXIgZW50cnlOb2RlID0gZG9tUXVlcnkoJ1tkYXRhLWVudHJ5PVwiJyArIGVudHJ5LmlkICsgJ1wiXScsIGdyb3VwTm9kZSk7XG5cbiAgICAgICAgdmFyIGVudHJ5VmlzaWJsZSA9IGlzRW50cnlWaXNpYmxlKGVudHJ5KTtcblxuICAgICAgICBncm91cFZpc2libGUgPSBncm91cFZpc2libGUgfHwgZW50cnlWaXNpYmxlO1xuXG4gICAgICAgIHRvZ2dsZVZpc2libGUoZW50cnlOb2RlLCBlbnRyeVZpc2libGUpO1xuXG4gICAgICAgIHZhciB2YWx1ZXMgPSAnZ2V0JyBpbiBlbnRyeSA/IGVudHJ5LmdldChlbGVtZW50LCBlbnRyeU5vZGUpIDoge307XG5cbiAgICAgICAgaWYgKHZhbHVlcyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgdmFyIGxpc3RFbnRyeUNvbnRhaW5lciA9IGRvbVF1ZXJ5KCdbZGF0YS1saXN0LWVudHJ5LWNvbnRhaW5lcl0nLCBlbnRyeU5vZGUpO1xuICAgICAgICAgIHZhciBleGlzdGluZ0VsZW1lbnRzID0gbGlzdEVudHJ5Q29udGFpbmVyLmNoaWxkcmVuIHx8IFtdO1xuXG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBsaXN0VmFsdWUgPSB2YWx1ZXNbaV07XG4gICAgICAgICAgICB2YXIgbGlzdEl0ZW1Ob2RlID0gZXhpc3RpbmdFbGVtZW50c1tpXTtcbiAgICAgICAgICAgIGlmICghbGlzdEl0ZW1Ob2RlKSB7XG4gICAgICAgICAgICAgIGxpc3RJdGVtTm9kZSA9IGRvbWlmeShlbnRyeS5jcmVhdGVMaXN0RW50cnlUZW1wbGF0ZShsaXN0VmFsdWUsIGksIGxpc3RFbnRyeUNvbnRhaW5lcikpO1xuICAgICAgICAgICAgICBsaXN0RW50cnlDb250YWluZXIuYXBwZW5kQ2hpbGQobGlzdEl0ZW1Ob2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbUF0dHIobGlzdEl0ZW1Ob2RlLCAnZGF0YS1pbmRleCcsIGkpO1xuXG4gICAgICAgICAgICBzZWxmLl9iaW5kVGVtcGxhdGUoZWxlbWVudCwgZW50cnksIGxpc3RWYWx1ZSwgbGlzdEl0ZW1Ob2RlLCBpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgZW50cmllc1RvUmVtb3ZlID0gZXhpc3RpbmdFbGVtZW50cy5sZW5ndGggLSB2YWx1ZXMubGVuZ3RoO1xuXG4gICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBlbnRyaWVzVG9SZW1vdmU7IGorKykge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIG9ycGhhbmVkIGVsZW1lbnRcbiAgICAgICAgICAgIGxpc3RFbnRyeUNvbnRhaW5lci5yZW1vdmVDaGlsZChsaXN0RW50cnlDb250YWluZXIubGFzdENoaWxkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZWxmLl9iaW5kVGVtcGxhdGUoZWxlbWVudCwgZW50cnksIHZhbHVlcywgZW50cnlOb2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHVwZGF0ZSBjb25kaXRpb25hbGx5IHZpc2libGUgZWxlbWVudHNcbiAgICAgICAgc2VsZi51cGRhdGVTdGF0ZShlbnRyeSwgZW50cnlOb2RlKTtcbiAgICAgICAgc2VsZi52YWxpZGF0ZShlbnRyeSwgdmFsdWVzLCBlbnRyeU5vZGUpO1xuXG4gICAgICAgIC8vIHJlbWVtYmVyIGluaXRpYWwgc3RhdGUgZm9yIGxhdGVyIGRpcnR5IGNoZWNraW5nXG4gICAgICAgIGVudHJ5Lm9sZFZhbHVlcyA9IGdldEZvcm1Db250cm9sVmFsdWVzKGVudHJ5Tm9kZSk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKHR5cGVvZiBncm91cC5sYWJlbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB1cGRhdGVMYWJlbChncm91cE5vZGUsICcuZ3JvdXAtbGFiZWwnLCBncm91cC5sYWJlbChlbGVtZW50LCBncm91cE5vZGUpKTtcbiAgICAgIH1cblxuICAgICAgZ3JvdXBWaXNpYmxlID0gZ3JvdXBWaXNpYmxlICYmIGlzR3JvdXBWaXNpYmxlKGdyb3VwLCBlbGVtZW50LCBncm91cE5vZGUpO1xuXG4gICAgICB0YWJWaXNpYmxlID0gdGFiVmlzaWJsZSB8fCBncm91cFZpc2libGU7XG5cbiAgICAgIHRvZ2dsZVZpc2libGUoZ3JvdXBOb2RlLCBncm91cFZpc2libGUpO1xuICAgIH0pO1xuXG4gICAgdGFiVmlzaWJsZSA9IHRhYlZpc2libGUgJiYgaXNUYWJWaXNpYmxlKHRhYiwgZWxlbWVudCk7XG5cbiAgICB0b2dnbGVWaXNpYmxlKHRhYk5vZGUsIHRhYlZpc2libGUpO1xuICAgIHRvZ2dsZVZpc2libGUodGFiTGlua05vZGUsIHRhYlZpc2libGUpO1xuXG4gICAgY2hlY2tBY3RpdmVUYWJWaXNpYmlsaXR5KHRhYk5vZGUsIHRhYlZpc2libGUpO1xuICB9KTtcblxuICAvLyBpbmplY3QgZWxlbWVudHMgaWQgaW50byBoZWFkZXJcbiAgdXBkYXRlTGFiZWwocGFuZWxOb2RlLCAnW2RhdGEtbGFiZWwtaWRdJywgZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkuaWQgfHwgJycpO1xufTtcblxuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS5fY3JlYXRlUGFuZWwgPSBmdW5jdGlvbihlbGVtZW50LCB0YWJzKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgcGFuZWxOb2RlID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiYnBwLXByb3BlcnRpZXNcIj48L2Rpdj4nKSxcbiAgICAgIGhlYWRlck5vZGUgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJicHAtcHJvcGVydGllcy1oZWFkZXJcIj4nICtcbiAgICAgICAgJzxkaXYgY2xhc3M9XCJsYWJlbFwiIGRhdGEtbGFiZWwtaWQ+PC9kaXY+JyArXG4gICAgICAgICc8ZGl2IGNsYXNzPVwic2VhcmNoXCI+JyArXG4gICAgICAgICAgJzxpbnB1dCB0eXBlPVwic2VhcmNoXCIgcGxhY2Vob2xkZXI9XCJTZWFyY2ggZm9yIHByb3BlcnR5XCIgLz4nICtcbiAgICAgICAgICAnPGJ1dHRvbj48c3Bhbj5TZWFyY2g8L3NwYW4+PC9idXR0b24+JyArXG4gICAgICAgICc8L2Rpdj4nICtcbiAgICAgICc8L2Rpdj4nKSxcbiAgICAgIHRhYkJhck5vZGUgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJicHAtcHJvcGVydGllcy10YWItYmFyXCI+PC9kaXY+JyksXG4gICAgICB0YWJMaW5rc05vZGUgPSBkb21pZnkoJzx1bCBjbGFzcz1cImJwcC1wcm9wZXJ0aWVzLXRhYnMtbGlua3NcIj48L3VsPicpLFxuICAgICAgdGFiQ29udGFpbmVyTm9kZSA9IGRvbWlmeSgnPGRpdiBjbGFzcz1cImJwcC1wcm9wZXJ0aWVzLXRhYnMtY29udGFpbmVyXCI+PC9kaXY+Jyk7XG5cbiAgcGFuZWxOb2RlLmFwcGVuZENoaWxkKGhlYWRlck5vZGUpO1xuXG4gIGZvckVhY2godGFicywgZnVuY3Rpb24odGFiLCB0YWJJbmRleCkge1xuXG4gICAgaWYgKCF0YWIuaWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFiIG11c3QgaGF2ZSBhbiBpZCcpO1xuICAgIH1cblxuICAgIHZhciB0YWJOb2RlID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiYnBwLXByb3BlcnRpZXMtdGFiXCIgZGF0YS10YWI9XCInICsgZXNjYXBlSFRNTCh0YWIuaWQpICsgJ1wiPjwvZGl2PicpLFxuICAgICAgICB0YWJMaW5rTm9kZSA9IGRvbWlmeSgnPGxpIGNsYXNzPVwiYnBwLXByb3BlcnRpZXMtdGFiLWxpbmtcIj4nICtcbiAgICAgICAgICAnPGEgaHJlZiBkYXRhLXRhYi10YXJnZXQ9XCInICsgZXNjYXBlSFRNTCh0YWIuaWQpICsgJ1wiPicgKyBlc2NhcGVIVE1MKHRhYi5sYWJlbCkgKyAnPC9hPicgK1xuICAgICAgICAnPC9saT4nKTtcblxuICAgIHZhciBncm91cHMgPSB0YWIuZ3JvdXBzO1xuXG4gICAgZm9yRWFjaChncm91cHMsIGZ1bmN0aW9uKGdyb3VwKSB7XG5cbiAgICAgIGlmICghZ3JvdXAuaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdncm91cCBtdXN0IGhhdmUgYW4gaWQnKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGdyb3VwTm9kZSA9IGRvbWlmeSgnPGRpdiBjbGFzcz1cImJwcC1wcm9wZXJ0aWVzLWdyb3VwXCIgZGF0YS1ncm91cD1cIicgKyBlc2NhcGVIVE1MKGdyb3VwLmlkKSArICdcIj4nICtcbiAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJncm91cC10b2dnbGVcIj48L3NwYW4+JyArXG4gICAgICAgICAgJzxzcGFuIGNsYXNzPVwiZ3JvdXAtbGFiZWxcIj4nICsgZXNjYXBlSFRNTChncm91cC5sYWJlbCkgKyAnPC9zcGFuPicgK1xuICAgICAgICAnPC9kaXY+Jyk7XG5cbiAgICAgIC8vIFRPRE8obnJlKTogdXNlIGV2ZW50IGRlbGVnYXRpb24gdG8gaGFuZGxlIHRoYXQuLi5cbiAgICAgIGdyb3VwTm9kZS5xdWVyeVNlbGVjdG9yKCcuZ3JvdXAtdG9nZ2xlJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldnQpIHtcbiAgICAgICAgZG9tQ2xhc3Nlcyhncm91cE5vZGUpLnRvZ2dsZSgnZ3JvdXAtY2xvc2VkJyk7XG4gICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9KTtcbiAgICAgIGdyb3VwTm9kZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGV2dCkge1xuICAgICAgICBpZiAoIWV2dC5kZWZhdWx0UHJldmVudGVkICYmIGRvbUNsYXNzZXMoZ3JvdXBOb2RlKS5oYXMoJ2dyb3VwLWNsb3NlZCcpKSB7XG4gICAgICAgICAgZG9tQ2xhc3Nlcyhncm91cE5vZGUpLnJlbW92ZSgnZ3JvdXAtY2xvc2VkJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBmb3JFYWNoKGdyb3VwLmVudHJpZXMsIGZ1bmN0aW9uKGVudHJ5KSB7XG5cbiAgICAgICAgaWYgKCFlbnRyeS5pZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZW50cnkgbXVzdCBoYXZlIGFuIGlkJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaHRtbCA9IGVudHJ5Lmh0bWw7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBodG1sID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGh0bWwgPSBkb21pZnkoaHRtbCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB1bndyYXAganF1ZXJ5XG4gICAgICAgIGlmIChodG1sLmdldCAmJiBodG1sLmNvbnN0cnVjdG9yLnByb3RvdHlwZS5qcXVlcnkpIHtcbiAgICAgICAgICBodG1sID0gaHRtbC5nZXQoMCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZW50cnlOb2RlID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiYnBwLXByb3BlcnRpZXMtZW50cnlcIiBkYXRhLWVudHJ5PVwiJyArIGVzY2FwZUhUTUwoZW50cnkuaWQpICsgJ1wiPjwvZGl2PicpO1xuXG4gICAgICAgIGZvckVhY2goZW50cnkuY3NzQ2xhc3NlcyB8fCBbXSwgZnVuY3Rpb24oY3NzQ2xhc3MpIHtcbiAgICAgICAgICBkb21DbGFzc2VzKGVudHJ5Tm9kZSkuYWRkKGNzc0NsYXNzKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZW50cnlOb2RlLmFwcGVuZENoaWxkKGh0bWwpO1xuXG4gICAgICAgIGdyb3VwTm9kZS5hcHBlbmRDaGlsZChlbnRyeU5vZGUpO1xuXG4gICAgICAgIC8vIHVwZGF0ZSBjb25kaXRpb25hbGx5IHZpc2libGUgZWxlbWVudHNcbiAgICAgICAgc2VsZi51cGRhdGVTdGF0ZShlbnRyeSwgZW50cnlOb2RlKTtcbiAgICAgIH0pO1xuXG4gICAgICB0YWJOb2RlLmFwcGVuZENoaWxkKGdyb3VwTm9kZSk7XG4gICAgfSk7XG5cbiAgICB0YWJMaW5rc05vZGUuYXBwZW5kQ2hpbGQodGFiTGlua05vZGUpO1xuICAgIHRhYkNvbnRhaW5lck5vZGUuYXBwZW5kQ2hpbGQodGFiTm9kZSk7XG4gIH0pO1xuXG4gIHRhYkJhck5vZGUuYXBwZW5kQ2hpbGQodGFiTGlua3NOb2RlKTtcblxuICBwYW5lbE5vZGUuYXBwZW5kQ2hpbGQodGFiQmFyTm9kZSk7XG4gIHBhbmVsTm9kZS5hcHBlbmRDaGlsZCh0YWJDb250YWluZXJOb2RlKTtcblxuICByZXR1cm4gcGFuZWxOb2RlO1xufTtcblxuXG5cbmZ1bmN0aW9uIHNldElucHV0VmFsdWUobm9kZSwgdmFsdWUpIHtcblxuICB2YXIgY29udGVudEVkaXRhYmxlID0gaXNDb250ZW50RWRpdGFibGUobm9kZSk7XG5cbiAgdmFyIG9sZFZhbHVlID0gY29udGVudEVkaXRhYmxlID8gbm9kZS5pbm5lclRleHQgOiBub2RlLnZhbHVlO1xuXG4gIHZhciBzZWxlY3Rpb247XG5cbiAgLy8gcHJldmVudHMgaW5wdXQgZmllbGRzIGZyb20gaGF2aW5nIHRoZSB2YWx1ZSAndW5kZWZpbmVkJ1xuICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgIHZhbHVlID0gJyc7XG4gIH1cblxuICBpZiAob2xkVmFsdWUgPT09IHZhbHVlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gdXBkYXRlIHNlbGVjdGlvbiBvbiB1bmRvL3JlZG9cbiAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT09IG5vZGUpIHtcbiAgICBzZWxlY3Rpb24gPSB1cGRhdGVTZWxlY3Rpb24oZ2V0U2VsZWN0aW9uKG5vZGUpLCBvbGRWYWx1ZSwgdmFsdWUpO1xuICB9XG5cbiAgaWYgKGNvbnRlbnRFZGl0YWJsZSkge1xuICAgIG5vZGUuaW5uZXJUZXh0ID0gdmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgbm9kZS52YWx1ZSA9IHZhbHVlO1xuICB9XG5cbiAgaWYgKHNlbGVjdGlvbikge1xuICAgIHNldFNlbGVjdGlvbihub2RlLCBzZWxlY3Rpb24pO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNldFNlbGVjdFZhbHVlKG5vZGUsIHZhbHVlKSB7XG4gIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgbm9kZS52YWx1ZSA9IHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNldFRvZ2dsZVZhbHVlKG5vZGUsIHZhbHVlKSB7XG4gIHZhciBub2RlVmFsdWUgPSBub2RlLnZhbHVlO1xuXG4gIG5vZGUuY2hlY2tlZCA9ICh2YWx1ZSA9PT0gbm9kZVZhbHVlKSB8fCAoIWRvbUF0dHIobm9kZSwgJ3ZhbHVlJykgJiYgdmFsdWUpO1xufVxuXG5mdW5jdGlvbiBzZXRUZXh0VmFsdWUobm9kZSwgdmFsdWUpIHtcbiAgbm9kZS50ZXh0Q29udGVudCA9IHZhbHVlO1xufVxuXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb24obm9kZSkge1xuXG4gIHJldHVybiBpc0NvbnRlbnRFZGl0YWJsZShub2RlKSA/IGdldENvbnRlbnRFZGl0YWJsZVNlbGVjdGlvbihub2RlKSA6IHtcbiAgICBzdGFydDogbm9kZS5zZWxlY3Rpb25TdGFydCxcbiAgICBlbmQ6IG5vZGUuc2VsZWN0aW9uRW5kXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldENvbnRlbnRFZGl0YWJsZVNlbGVjdGlvbihub2RlKSB7XG5cbiAgdmFyIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcblxuICB2YXIgZm9jdXNOb2RlID0gc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgIGZvY3VzT2Zmc2V0ID0gc2VsZWN0aW9uLmZvY3VzT2Zmc2V0LFxuICAgICAgYW5jaG9yT2Zmc2V0ID0gc2VsZWN0aW9uLmFuY2hvck9mZnNldDtcblxuICBpZiAoIWZvY3VzTm9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbm90IHNlbGVjdGVkJyk7XG4gIH1cblxuICAvLyB2ZXJpZnkgd2UgaGF2ZSBzZWxlY3Rpb24gb24gdGhlIGN1cnJlbnQgZWxlbWVudFxuICBpZiAoIW5vZGUuY29udGFpbnMoZm9jdXNOb2RlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbm90IHNlbGVjdGVkJyk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHN0YXJ0OiBNYXRoLm1pbihmb2N1c09mZnNldCwgYW5jaG9yT2Zmc2V0KSxcbiAgICBlbmQ6IE1hdGgubWF4KGZvY3VzT2Zmc2V0LCBhbmNob3JPZmZzZXQpXG4gIH07XG59XG5cbmZ1bmN0aW9uIHNldFNlbGVjdGlvbihub2RlLCBzZWxlY3Rpb24pIHtcblxuICBpZiAoaXNDb250ZW50RWRpdGFibGUobm9kZSkpIHtcbiAgICBzZXRDb250ZW50RWRpdGFibGVTZWxlY3Rpb24obm9kZSwgc2VsZWN0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICBub2RlLnNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uLnN0YXJ0O1xuICAgIG5vZGUuc2VsZWN0aW9uRW5kID0gc2VsZWN0aW9uLmVuZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBzZXRDb250ZW50RWRpdGFibGVTZWxlY3Rpb24obm9kZSwgc2VsZWN0aW9uKSB7XG5cbiAgdmFyIGZvY3VzTm9kZSxcbiAgICAgIGRvbVJhbmdlLFxuICAgICAgZG9tU2VsZWN0aW9uO1xuXG4gIGZvY3VzTm9kZSA9IG5vZGUuZmlyc3RDaGlsZCB8fCBub2RlLFxuICBkb21SYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gIGRvbVJhbmdlLnNldFN0YXJ0KGZvY3VzTm9kZSwgc2VsZWN0aW9uLnN0YXJ0KTtcbiAgZG9tUmFuZ2Uuc2V0RW5kKGZvY3VzTm9kZSwgc2VsZWN0aW9uLmVuZCk7XG5cbiAgZG9tU2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICBkb21TZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gIGRvbVNlbGVjdGlvbi5hZGRSYW5nZShkb21SYW5nZSk7XG59XG5cbmZ1bmN0aW9uIGlzSW1wbGljaXRSb290KGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQuaWQgPT09ICdfX2ltcGxpY2l0cm9vdCc7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBkb21RdWVyeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeSxcbiAgICBkb21DbGVhciA9IHJlcXVpcmUoJ21pbi1kb20nKS5jbGVhcixcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXG4gICAgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyksXG4gICAgZG9taWZ5ID0gcmVxdWlyZSgnbWluLWRvbScpLmRvbWlmeSxcbiAgICBJZHMgPSByZXF1aXJlKCdpZHMnKS5kZWZhdWx0O1xuXG52YXIgU1BBQ0VfUkVHRVggPSAvXFxzLztcblxuLy8gZm9yIFFOYW1lIHZhbGlkYXRpb24gYXMgcGVyIGh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwvI05ULU5hbWVDaGFyXG52YXIgUU5BTUVfUkVHRVggPSAvXihbYS16XVtcXHctLl0qOik/W2Etel9dW1xcdy0uXSokL2k7XG5cbi8vIGZvciBJRCB2YWxpZGF0aW9uIGFzIHBlciBCUE1OIFNjaGVtYSAoUU5hbWUgLSBOYW1lc3BhY2UpXG52YXIgSURfUkVHRVggPSAvXlthLXpfXVtcXHctLl0qJC9pO1xuXG52YXIgUExBQ0VIT0xERVJfUkVHRVggPSAvXFwkXFx7KFtefV0qKVxcfS9nO1xuXG52YXIgSFRNTF9FU0NBUEVfTUFQID0ge1xuICAnJic6ICcmYW1wOycsXG4gICc8JzogJyZsdDsnLFxuICAnPic6ICcmZ3Q7JyxcbiAgJ1wiJzogJyZxdW90OycsXG4gICdcXCcnOiAnJiMzOTsnXG59O1xuXG5mdW5jdGlvbiBzZWxlY3RlZE9wdGlvbihzZWxlY3RCb3gpIHtcbiAgaWYgKHNlbGVjdEJveC5zZWxlY3RlZEluZGV4ID49IDApIHtcbiAgICByZXR1cm4gc2VsZWN0Qm94Lm9wdGlvbnNbc2VsZWN0Qm94LnNlbGVjdGVkSW5kZXhdLnZhbHVlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzLnNlbGVjdGVkT3B0aW9uID0gc2VsZWN0ZWRPcHRpb247XG5cblxuZnVuY3Rpb24gc2VsZWN0ZWRUeXBlKGVsZW1lbnRTeW50YXgsIGlucHV0Tm9kZSkge1xuICB2YXIgdHlwZVNlbGVjdCA9IGRvbVF1ZXJ5KGVsZW1lbnRTeW50YXgsIGlucHV0Tm9kZSk7XG4gIHJldHVybiBzZWxlY3RlZE9wdGlvbih0eXBlU2VsZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMuc2VsZWN0ZWRUeXBlID0gc2VsZWN0ZWRUeXBlO1xuXG5cbi8qKlxuICogUmV0cmlldmUgdGhlIHJvb3QgZWxlbWVudCB0aGUgZG9jdW1lbnQgdGhpc1xuICogYnVzaW5lc3Mgb2JqZWN0IGlzIGNvbnRhaW5lZCBpbi5cbiAqXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxuICovXG5mdW5jdGlvbiBnZXRSb290KGJ1c2luZXNzT2JqZWN0KSB7XG4gIHZhciBwYXJlbnQgPSBidXNpbmVzc09iamVjdDtcbiAgd2hpbGUgKHBhcmVudC4kcGFyZW50KSB7XG4gICAgcGFyZW50ID0gcGFyZW50LiRwYXJlbnQ7XG4gIH1cbiAgcmV0dXJuIHBhcmVudDtcbn1cblxubW9kdWxlLmV4cG9ydHMuZ2V0Um9vdCA9IGdldFJvb3Q7XG5cblxuLyoqXG4gKiBmaWx0ZXJzIGFsbCBlbGVtZW50cyBpbiB0aGUgbGlzdCB3aGljaCBoYXZlIGEgZ2l2ZW4gdHlwZS5cbiAqIHJlbW92ZXMgYSBuZXcgbGlzdFxuICovXG5mdW5jdGlvbiBmaWx0ZXJFbGVtZW50c0J5VHlwZShvYmplY3RMaXN0LCB0eXBlKSB7XG4gIHZhciBsaXN0ID0gb2JqZWN0TGlzdCB8fCBbXTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3JFYWNoKGxpc3QsIGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChpcyhvYmosIHR5cGUpKSB7XG4gICAgICByZXN1bHQucHVzaChvYmopO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzLmZpbHRlckVsZW1lbnRzQnlUeXBlID0gZmlsdGVyRWxlbWVudHNCeVR5cGU7XG5cblxuZnVuY3Rpb24gZmluZFJvb3RFbGVtZW50c0J5VHlwZShidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpIHtcbiAgdmFyIHJvb3QgPSBnZXRSb290KGJ1c2luZXNzT2JqZWN0KTtcblxuICByZXR1cm4gZmlsdGVyRWxlbWVudHNCeVR5cGUocm9vdC5yb290RWxlbWVudHMsIHJlZmVyZW5jZWRUeXBlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuZmluZFJvb3RFbGVtZW50c0J5VHlwZSA9IGZpbmRSb290RWxlbWVudHNCeVR5cGU7XG5cblxuZnVuY3Rpb24gcmVtb3ZlQWxsQ2hpbGRyZW4oZG9tRWxlbWVudCkge1xuICB3aGlsZSAoZG9tRWxlbWVudC5maXJzdENoaWxkKSB7XG4gICAgZG9tRWxlbWVudC5yZW1vdmVDaGlsZChkb21FbGVtZW50LmZpcnN0Q2hpbGQpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzLnJlbW92ZUFsbENoaWxkcmVuID0gcmVtb3ZlQWxsQ2hpbGRyZW47XG5cblxuLyoqXG4gKiBhZGRzIGFuIGVtcHR5IG9wdGlvbiB0byB0aGUgbGlzdFxuICovXG5mdW5jdGlvbiBhZGRFbXB0eVBhcmFtZXRlcihsaXN0KSB7XG4gIHJldHVybiBsaXN0LnB1c2goeyAnbGFiZWwnOiAnJywgJ3ZhbHVlJzogJycsICduYW1lJzogJycgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzLmFkZEVtcHR5UGFyYW1ldGVyID0gYWRkRW1wdHlQYXJhbWV0ZXI7XG5cblxuLyoqXG4gKiByZXR1cm5zIGEgbGlzdCB3aXRoIGFsbCByb290IGVsZW1lbnRzIGZvciB0aGUgZ2l2ZW4gcGFyYW1ldGVyICdyZWZlcmVuY2VkVHlwZSdcbiAqL1xuZnVuY3Rpb24gcmVmcmVzaE9wdGlvbnNNb2RlbChidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpIHtcbiAgdmFyIG1vZGVsID0gW107XG4gIHZhciByZWZlcmFibGVPYmplY3RzID0gZmluZFJvb3RFbGVtZW50c0J5VHlwZShidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpO1xuICBmb3JFYWNoKHJlZmVyYWJsZU9iamVjdHMsIGZ1bmN0aW9uKG9iaikge1xuICAgIG1vZGVsLnB1c2goe1xuICAgICAgbGFiZWw6IChvYmoubmFtZSB8fCAnJykgKyAnIChpZD0nK29iai5pZCsnKScsXG4gICAgICB2YWx1ZTogb2JqLmlkLFxuICAgICAgbmFtZTogb2JqLm5hbWVcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBtb2RlbDtcbn1cblxubW9kdWxlLmV4cG9ydHMucmVmcmVzaE9wdGlvbnNNb2RlbCA9IHJlZnJlc2hPcHRpb25zTW9kZWw7XG5cblxuLyoqXG4gKiBmaWxscyB0aGUgZHJvcCBkb3duIHdpdGggb3B0aW9uc1xuICovXG5mdW5jdGlvbiB1cGRhdGVPcHRpb25zRHJvcERvd24oZG9tU2VsZWN0b3IsIGJ1c2luZXNzT2JqZWN0LCByZWZlcmVuY2VkVHlwZSwgZW50cnlOb2RlKSB7XG4gIHZhciBvcHRpb25zID0gcmVmcmVzaE9wdGlvbnNNb2RlbChidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpO1xuICBhZGRFbXB0eVBhcmFtZXRlcihvcHRpb25zKTtcbiAgdmFyIHNlbGVjdEJveCA9IGRvbVF1ZXJ5KGRvbVNlbGVjdG9yLCBlbnRyeU5vZGUpO1xuICBkb21DbGVhcihzZWxlY3RCb3gpO1xuXG4gIGZvckVhY2gob3B0aW9ucywgZnVuY3Rpb24ob3B0aW9uKSB7XG4gICAgdmFyIG9wdGlvbkVudHJ5ID0gZG9taWZ5KCc8b3B0aW9uIHZhbHVlPVwiJyArIGVzY2FwZUhUTUwob3B0aW9uLnZhbHVlKSArICdcIj4nICsgZXNjYXBlSFRNTChvcHRpb24ubGFiZWwpICsgJzwvb3B0aW9uPicpO1xuICAgIHNlbGVjdEJveC5hcHBlbmRDaGlsZChvcHRpb25FbnRyeSk7XG4gIH0pO1xuICByZXR1cm4gb3B0aW9ucztcbn1cblxubW9kdWxlLmV4cG9ydHMudXBkYXRlT3B0aW9uc0Ryb3BEb3duID0gdXBkYXRlT3B0aW9uc0Ryb3BEb3duO1xuXG5cbi8qKlxuICogY2hlY2tzIHdoZXRoZXIgdGhlIGlkIHZhbHVlIGlzIHZhbGlkXG4gKlxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBib1xuICogQHBhcmFtIHtTdHJpbmd9IGlkVmFsdWVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zbGF0ZVxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gZXJyb3IgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBpc0lkVmFsaWQoYm8sIGlkVmFsdWUsIHRyYW5zbGF0ZSkge1xuICB2YXIgYXNzaWduZWQgPSBiby4kbW9kZWwuaWRzLmFzc2lnbmVkKGlkVmFsdWUpO1xuXG4gIHZhciBpZEV4aXN0cyA9IGFzc2lnbmVkICYmIGFzc2lnbmVkICE9PSBibztcblxuICBpZiAoIWlkVmFsdWUgfHwgaWRFeGlzdHMpIHtcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdFbGVtZW50IG11c3QgaGF2ZSBhbiB1bmlxdWUgaWQuJyk7XG4gIH1cblxuICByZXR1cm4gdmFsaWRhdGVJZChpZFZhbHVlLCB0cmFuc2xhdGUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cy5pc0lkVmFsaWQgPSBpc0lkVmFsaWQ7XG5cblxuZnVuY3Rpb24gdmFsaWRhdGVJZChpZFZhbHVlLCB0cmFuc2xhdGUpIHtcblxuICBpZFZhbHVlID0gc3RyaXBQbGFjZWhvbGRlcnMoaWRWYWx1ZSk7XG5cbiAgaWYgKGNvbnRhaW5zU3BhY2UoaWRWYWx1ZSkpIHtcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdJZCBtdXN0IG5vdCBjb250YWluIHNwYWNlcy4nKTtcbiAgfVxuXG4gIGlmICghSURfUkVHRVgudGVzdChpZFZhbHVlKSkge1xuXG4gICAgaWYgKFFOQU1FX1JFR0VYLnRlc3QoaWRWYWx1ZSkpIHtcbiAgICAgIHJldHVybiB0cmFuc2xhdGUoJ0lkIG11c3Qgbm90IGNvbnRhaW4gcHJlZml4LicpO1xuICAgIH1cblxuICAgIHJldHVybiB0cmFuc2xhdGUoJ0lkIG11c3QgYmUgYSB2YWxpZCBRTmFtZS4nKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cy52YWxpZGF0ZUlkID0gdmFsaWRhdGVJZDtcblxuXG5mdW5jdGlvbiBjb250YWluc1NwYWNlKHZhbHVlKSB7XG4gIHJldHVybiBTUEFDRV9SRUdFWC50ZXN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuY29udGFpbnNTcGFjZSA9IGNvbnRhaW5zU3BhY2U7XG5cblxuZnVuY3Rpb24gc3RyaXBQbGFjZWhvbGRlcnMoaWRWYWx1ZSkge1xuXG4gIC8vIHJlcGxhY2UgZXhwcmVzc2lvbiBlLmcuICR7VkVSU0lPTl9UQUd9XG4gIC8vIHVzZSBvbmx5IHRoZSBjb250ZW50IGJldHdlZW4gJHt9XG4gIC8vIGZvciB0aGUgUkVHRVggY2hlY2tcbiAgcmV0dXJuIGlkVmFsdWUucmVwbGFjZShQTEFDRUhPTERFUl9SRUdFWCwgJyQxJyk7XG59XG5cbi8qKlxuICogZ2VuZXJhdGUgYSBzZW1hbnRpYyBpZCB3aXRoIGdpdmVuIHByZWZpeFxuICovXG5mdW5jdGlvbiBuZXh0SWQocHJlZml4KSB7XG4gIHZhciBpZHMgPSBuZXcgSWRzKFszMiwzMiwxXSk7XG5cbiAgcmV0dXJuIGlkcy5uZXh0UHJlZml4ZWQocHJlZml4KTtcbn1cblxubW9kdWxlLmV4cG9ydHMubmV4dElkID0gbmV4dElkO1xuXG5cbmZ1bmN0aW9uIHRyaWdnZXJDbGlja0V2ZW50KGVsZW1lbnQpIHtcbiAgdmFyIGV2dDtcbiAgdmFyIGV2ZW50VHlwZSA9ICdjbGljayc7XG5cbiAgaWYgKGRvY3VtZW50LmNyZWF0ZUV2ZW50KSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENocm9tZSwgU2FmYXJpLCBGaXJlZm94XG4gICAgICBldnQgPSBuZXcgTW91c2VFdmVudCgoZXZlbnRUeXBlKSwgeyB2aWV3OiB3aW5kb3csIGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibGU6IHRydWUgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gSUUgMTEsIFBoYW50b21KUyAod2F0ISlcbiAgICAgIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50Jyk7XG5cbiAgICAgIGV2dC5pbml0RXZlbnQoKGV2ZW50VHlwZSksIHRydWUsIHRydWUpO1xuICAgIH1cbiAgICByZXR1cm4gZWxlbWVudC5kaXNwYXRjaEV2ZW50KGV2dCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gV2VsY29tZSBJRVxuICAgIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50T2JqZWN0KCk7XG5cbiAgICByZXR1cm4gZWxlbWVudC5maXJlRXZlbnQoJ29uJyArIGV2ZW50VHlwZSwgZXZ0KTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cy50cmlnZ2VyQ2xpY2tFdmVudCA9IHRyaWdnZXJDbGlja0V2ZW50O1xuXG5cbmZ1bmN0aW9uIGVzY2FwZUhUTUwoc3RyKSB7XG4gIHN0ciA9ICcnICsgc3RyO1xuXG4gIHJldHVybiBzdHIgJiYgc3RyLnJlcGxhY2UoL1smPD5cIiddL2csIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgcmV0dXJuIEhUTUxfRVNDQVBFX01BUFttYXRjaF07XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cy5lc2NhcGVIVE1MID0gZXNjYXBlSFRNTDsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKTtcblxuLyoqXG4gKiBBIGhhbmRsZXIgY2FwYWJsZSBvZiBjcmVhdGluZyBhIG5ldyBlbGVtZW50IHVuZGVyIGEgcHJvdmlkZWQgcGFyZW50XG4gKiBhbmQgdXBkYXRpbmcgLyBjcmVhdGluZyBhIHJlZmVyZW5jZSB0byBpdCBpbiBvbmUgYXRvbWljIGFjdGlvbi5cbiAqXG4gKiBAY2xhc3NcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBDcmVhdGVBbmRSZWZlcmVuY2VFbGVtZW50SGFuZGxlcihlbGVtZW50UmVnaXN0cnksIGJwbW5GYWN0b3J5KSB7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbiAgdGhpcy5fYnBtbkZhY3RvcnkgPSBicG1uRmFjdG9yeTtcbn1cblxuQ3JlYXRlQW5kUmVmZXJlbmNlRWxlbWVudEhhbmRsZXIuJGluamVjdCA9IFsgJ2VsZW1lbnRSZWdpc3RyeScsICdicG1uRmFjdG9yeScgXTtcblxubW9kdWxlLmV4cG9ydHMgPSBDcmVhdGVBbmRSZWZlcmVuY2VFbGVtZW50SGFuZGxlcjtcblxuXG4vLyBhcGkgLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGVsZW1lbnQgdW5kZXIgYSBwcm92aWRlZCBwYXJlbnQgYW5kIHVwZGF0ZXMgLyBjcmVhdGVzIGEgcmVmZXJlbmNlIHRvIGl0IGluXG4gKiBvbmUgYXRvbWljIGFjdGlvbi5cbiAqXG4gKiBAbWV0aG9kICBDcmVhdGVBbmRSZWZlcmVuY2VFbGVtZW50SGFuZGxlciNleGVjdXRlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGNvbnRleHQuZWxlbWVudCB3aGljaCBpcyB0aGUgY29udGV4dCBmb3IgdGhlIHJlZmVyZW5jZVxuICogQHBhcmFtIHttb2RkbGUucmVmZXJlbmNpbmdPYmplY3R9IGNvbnRleHQucmVmZXJlbmNpbmdPYmplY3QgdGhlIG9iamVjdCB3aGljaCBjcmVhdGVzIHRoZSByZWZlcmVuY2VcbiAqIEBwYXJhbSB7U3RyaW5nfSBjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5IHRoZSBwcm9wZXJ0eSBvZiB0aGUgcmVmZXJlbmNpbmdPYmplY3Qgd2hpY2ggbWFrZXMgdGhlIHJlZmVyZW5jZVxuICogQHBhcmFtIHttb2RkbGUubmV3T2JqZWN0fSBjb250ZXh0Lm5ld09iamVjdCB0aGUgbmV3IG9iamVjdCB0byBhZGRcbiAqIEBwYXJhbSB7bW9kZGxlLm5ld09iamVjdENvbnRhaW5lcn0gY29udGV4dC5uZXdPYmplY3RDb250YWluZXIgdGhlIGNvbnRhaW5lciBmb3IgdGhlIG5ldyBvYmplY3RcbiAqXG4gKiBAcmV0dXJucyB7QXJyYXk8ZGpzLm1vZGUuQmFzZT59IHRoZSB1cGRhdGVkIGVsZW1lbnRcbiAqL1xuQ3JlYXRlQW5kUmVmZXJlbmNlRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHJlZmVyZW5jaW5nT2JqZWN0ID0gZW5zdXJlTm90TnVsbChjb250ZXh0LnJlZmVyZW5jaW5nT2JqZWN0LCAncmVmZXJlbmNpbmdPYmplY3QnKSxcbiAgICAgIHJlZmVyZW5jZVByb3BlcnR5ID0gZW5zdXJlTm90TnVsbChjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5LCAncmVmZXJlbmNlUHJvcGVydHknKSxcbiAgICAgIG5ld09iamVjdCA9IGVuc3VyZU5vdE51bGwoY29udGV4dC5uZXdPYmplY3QsICduZXdPYmplY3QnKSxcbiAgICAgIG5ld09iamVjdENvbnRhaW5lciA9IGVuc3VyZU5vdE51bGwoY29udGV4dC5uZXdPYmplY3RDb250YWluZXIsICduZXdPYmplY3RDb250YWluZXInKSxcbiAgICAgIG5ld09iamVjdFBhcmVudCA9IGVuc3VyZU5vdE51bGwoY29udGV4dC5uZXdPYmplY3RQYXJlbnQsICduZXdPYmplY3RQYXJlbnQnKSxcbiAgICAgIGNoYW5nZWQgPSBbIGNvbnRleHQuZWxlbWVudCBdOyAvLyB0aGlzIHdpbGwgbm90IGNoYW5nZSBhbnkgZGlhZ3JhbS1qcyBlbGVtZW50c1xuXG4gIC8vIGNyZWF0ZSBuZXcgb2JqZWN0XG4gIHZhciByZWZlcmVuY2VkT2JqZWN0ID0gZWxlbWVudEhlbHBlclxuICAgIC5jcmVhdGVFbGVtZW50KG5ld09iamVjdC50eXBlLCBuZXdPYmplY3QucHJvcGVydGllcywgbmV3T2JqZWN0UGFyZW50LCB0aGlzLl9icG1uRmFjdG9yeSk7XG4gIGNvbnRleHQucmVmZXJlbmNlZE9iamVjdCA9IHJlZmVyZW5jZWRPYmplY3Q7XG5cbiAgLy8gYWRkIHRvIGNvbnRhaW5pbmcgbGlzdFxuICBuZXdPYmplY3RDb250YWluZXIucHVzaChyZWZlcmVuY2VkT2JqZWN0KTtcblxuICAvLyBhZGp1c3QgcmVmZXJlbmNlIGF0dHJpYnV0ZVxuICBjb250ZXh0LnByZXZpb3VzUmVmZXJlbmNlID0gcmVmZXJlbmNpbmdPYmplY3RbcmVmZXJlbmNlUHJvcGVydHldO1xuICByZWZlcmVuY2luZ09iamVjdFtyZWZlcmVuY2VQcm9wZXJ0eV0gPSByZWZlcmVuY2VkT2JqZWN0O1xuXG4gIGNvbnRleHQuY2hhbmdlZCA9IGNoYW5nZWQ7XG5cbiAgLy8gaW5kaWNhdGUgY2hhbmdlZCBvbiBvYmplY3RzIGFmZmVjdGVkIGJ5IHRoZSB1cGRhdGVcbiAgcmV0dXJuIGNoYW5nZWQ7XG59O1xuXG4vKipcbiAqIFJldmVydHMgdGhlIHVwZGF0ZVxuICpcbiAqIEBtZXRob2QgIENyZWF0ZUFuZFJlZmVyZW5jZUVsZW1lbnRIYW5kbGVyI3JldmVydFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKlxuICogQHJldHVybnMge2Rqcy5tb2RlLkJhc2V9IHRoZSB1cGRhdGVkIGVsZW1lbnRcbiAqL1xuQ3JlYXRlQW5kUmVmZXJlbmNlRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgcmVmZXJlbmNpbmdPYmplY3QgPSBjb250ZXh0LnJlZmVyZW5jaW5nT2JqZWN0LFxuICAgICAgcmVmZXJlbmNlUHJvcGVydHkgPSBjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5LFxuICAgICAgcHJldmlvdXNSZWZlcmVuY2UgPSBjb250ZXh0LnByZXZpb3VzUmVmZXJlbmNlLFxuICAgICAgcmVmZXJlbmNlZE9iamVjdCA9IGNvbnRleHQucmVmZXJlbmNlZE9iamVjdCxcbiAgICAgIG5ld09iamVjdENvbnRhaW5lciA9IGNvbnRleHQubmV3T2JqZWN0Q29udGFpbmVyO1xuXG4gIC8vIHJlc2V0IHJlZmVyZW5jZVxuICByZWZlcmVuY2luZ09iamVjdC5zZXQocmVmZXJlbmNlUHJvcGVydHksIHByZXZpb3VzUmVmZXJlbmNlKTtcblxuICAvLyByZW1vdmUgbmV3IGVsZW1lbnRcbiAgbmV3T2JqZWN0Q29udGFpbmVyLnNwbGljZShuZXdPYmplY3RDb250YWluZXIuaW5kZXhPZihyZWZlcmVuY2VkT2JqZWN0KSwgMSk7XG5cbiAgcmV0dXJuIGNvbnRleHQuY2hhbmdlZDtcbn07XG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGVuc3VyZU5vdE51bGwocHJvcCwgbmFtZSkge1xuICBpZiAoIXByb3ApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IobmFtZSArICcgcmVxdWlyZWQnKTtcbiAgfVxuICByZXR1cm4gcHJvcDtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xuXG52YXIgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyk7XG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyBhIEJQTU4gMi4wIHByb3BlcnR5IHVwZGF0ZVxuICogZm9yIGJ1c2luZXNzIG9iamVjdHMgd2hpY2ggYXJlIG5vdCByZXByZXNlbnRlZCBpbiB0aGVcbiAqIGRpYWdyYW0uXG4gKlxuICogVGhpcyBpcyB1c2VmdWwgaW4gdGhlIGNvbnRleHQgb2YgdGhlIHByb3BlcnRpZXMgcGFuZWwgaW5cbiAqIG9yZGVyIHRvIHVwZGF0ZSBjaGlsZCBlbGVtZW50cyBvZiBlbGVtZW50cyB2aXNpYmxlIGluXG4gKiB0aGUgZGlhZ3JhbS5cbiAqXG4gKiBFeGFtcGxlOiBwZXJmb3JtIGFuIHVwZGF0ZSBvZiBhIHNwZWNpZmljIGV2ZW50IGRlZmluaXRpb25cbiAqIG9mIGFuIGludGVybWVkaWF0ZSBldmVudC5cbiAqXG4gKiBAY2xhc3NcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBDcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyKGVsZW1lbnRSZWdpc3RyeSwgYnBtbkZhY3RvcnkpIHtcbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9icG1uRmFjdG9yeSA9IGJwbW5GYWN0b3J5O1xufVxuXG5DcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLiRpbmplY3QgPSBbICdlbGVtZW50UmVnaXN0cnknLCAnYnBtbkZhY3RvcnknIF07XG5cbm1vZHVsZS5leHBvcnRzID0gQ3JlYXRlQnVzaW5lc3NPYmplY3RMaXN0SGFuZGxlcjtcblxuZnVuY3Rpb24gZW5zdXJlTm90TnVsbChwcm9wLCBuYW1lKSB7XG4gIGlmICghcHJvcCkge1xuICAgIHRocm93IG5ldyBFcnJvcihuYW1lICsgJyByZXF1aXJlZCcpO1xuICB9XG4gIHJldHVybiBwcm9wO1xuXG59XG5mdW5jdGlvbiBlbnN1cmVMaXN0KHByb3AsIG5hbWUpIHtcbiAgaWYgKCFwcm9wIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChwcm9wKSAhPT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgIHRocm93IG5ldyBFcnJvcihuYW1lICsgJyBuZWVkcyB0byBiZSBhIGxpc3QnKTtcbiAgfVxuICByZXR1cm4gcHJvcDtcbn1cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZWxlbWVudCB1bmRlciBhIHByb3ZpZGVkIHBhcmVudCBhbmQgdXBkYXRlcyAvIGNyZWF0ZXMgYSByZWZlcmVuY2UgdG8gaXQgaW5cbiAqIG9uZSBhdG9taWMgYWN0aW9uLlxuICpcbiAqIEBtZXRob2QgIENyZWF0ZUJ1c2luZXNzT2JqZWN0TGlzdEhhbmRsZXIjZXhlY3V0ZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBjb250ZXh0LmVsZW1lbnQgd2hpY2ggaXMgdGhlIGNvbnRleHQgZm9yIHRoZSByZWZlcmVuY2VcbiAqIEBwYXJhbSB7bW9kZGxlLnJlZmVyZW5jaW5nT2JqZWN0fSBjb250ZXh0LnJlZmVyZW5jaW5nT2JqZWN0IHRoZSBvYmplY3Qgd2hpY2ggY3JlYXRlcyB0aGUgcmVmZXJlbmNlXG4gKiBAcGFyYW0ge1N0cmluZ30gY29udGV4dC5yZWZlcmVuY2VQcm9wZXJ0eSB0aGUgcHJvcGVydHkgb2YgdGhlIHJlZmVyZW5jaW5nT2JqZWN0IHdoaWNoIG1ha2VzIHRoZSByZWZlcmVuY2VcbiAqIEBwYXJhbSB7bW9kZGxlLm5ld09iamVjdH0gY29udGV4dC5uZXdPYmplY3QgdGhlIG5ldyBvYmplY3QgdG8gYWRkXG4gKiBAcGFyYW0ge21vZGRsZS5uZXdPYmplY3RDb250YWluZXJ9IGNvbnRleHQubmV3T2JqZWN0Q29udGFpbmVyIHRoZSBjb250YWluZXIgZm9yIHRoZSBuZXcgb2JqZWN0XG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGUuQmFzZT59IHRoZSB1cGRhdGVkIGVsZW1lbnRcbiAqL1xuQ3JlYXRlQnVzaW5lc3NPYmplY3RMaXN0SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY3VycmVudE9iamVjdCA9IGVuc3VyZU5vdE51bGwoY29udGV4dC5jdXJyZW50T2JqZWN0LCAnY3VycmVudE9iamVjdCcpLFxuICAgICAgcHJvcGVydHlOYW1lID0gZW5zdXJlTm90TnVsbChjb250ZXh0LnByb3BlcnR5TmFtZSwgJ3Byb3BlcnR5TmFtZScpLFxuICAgICAgbmV3T2JqZWN0cyA9IGVuc3VyZUxpc3QoY29udGV4dC5uZXdPYmplY3RzLCAnbmV3T2JqZWN0cycpLFxuICAgICAgY2hhbmdlZCA9IFsgY29udGV4dC5lbGVtZW50IF07IC8vIHRoaXMgd2lsbCBub3QgY2hhbmdlIGFueSBkaWFncmFtLWpzIGVsZW1lbnRzXG5cblxuICB2YXIgY2hpbGRPYmplY3RzID0gW107XG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvLyBjcmVhdGUgbmV3IGFycmF5IG9mIGJ1c2luZXNzIG9iamVjdHNcbiAgZm9yRWFjaChuZXdPYmplY3RzLCBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgZWxlbWVudCA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudChvYmoudHlwZSwgb2JqLnByb3BlcnRpZXMsIGN1cnJlbnRPYmplY3QsIHNlbGYuX2JwbW5GYWN0b3J5KTtcblxuICAgIGNoaWxkT2JqZWN0cy5wdXNoKGVsZW1lbnQpO1xuICB9KTtcbiAgY29udGV4dC5jaGlsZE9iamVjdCA9IGNoaWxkT2JqZWN0cztcblxuICAvLyBhZGp1c3QgYXJyYXkgcmVmZXJlbmNlIGluIHRoZSBwYXJlbnQgYnVzaW5lc3Mgb2JqZWN0XG4gIGNvbnRleHQucHJldmlvdXNDaGlsZHMgPSBjdXJyZW50T2JqZWN0W3Byb3BlcnR5TmFtZV07XG4gIGN1cnJlbnRPYmplY3RbcHJvcGVydHlOYW1lXSA9IGNoaWxkT2JqZWN0cztcblxuICBjb250ZXh0LmNoYW5nZWQgPSBjaGFuZ2VkO1xuXG4gIC8vIGluZGljYXRlIGNoYW5nZWQgb24gb2JqZWN0cyBhZmZlY3RlZCBieSB0aGUgdXBkYXRlXG4gIHJldHVybiBjaGFuZ2VkO1xufTtcblxuLyoqXG4gKiBSZXZlcnRzIHRoZSB1cGRhdGVcbiAqXG4gKiBAbWV0aG9kICBDcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyI3JldmVydFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGUuQmFzZX0gdGhlIHVwZGF0ZWQgZWxlbWVudFxuICovXG5DcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGN1cnJlbnRPYmplY3QgPSBjb250ZXh0LmN1cnJlbnRPYmplY3QsXG4gICAgICBwcm9wZXJ0eU5hbWUgPSBjb250ZXh0LnByb3BlcnR5TmFtZSxcbiAgICAgIHByZXZpb3VzQ2hpbGRzID0gY29udGV4dC5wcmV2aW91c0NoaWxkcztcblxuICAvLyByZW1vdmUgbmV3IGVsZW1lbnRcbiAgY3VycmVudE9iamVjdC5zZXQocHJvcGVydHlOYW1lLCBwcmV2aW91c0NoaWxkcyk7XG5cbiAgcmV0dXJuIGNvbnRleHQuY2hhbmdlZDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKTtcblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBjb21iaW5lcyBhbmQgZXhlY3V0ZXMgbXVsdGlwbGUgY29tbWFuZHMuXG4gKlxuICogQWxsIHVwZGF0ZXMgYXJlIGJ1bmRsZWQgb24gdGhlIGNvbW1hbmQgc3RhY2sgYW5kIGV4ZWN1dGVkIGluIG9uZSBzdGVwLlxuICogVGhpcyBhbHNvIG1ha2VzIGl0IHBvc3NpYmxlIHRvIHJldmVydCB0aGUgY2hhbmdlcyBpbiBvbmUgc3RlcC5cbiAqXG4gKiBFeGFtcGxlIHVzZSBjYXNlOiByZW1vdmUgdGhlIGNhbXVuZGE6Zm9ybUtleSBhdHRyaWJ1dGUgYW5kIGluIGFkZGl0aW9uXG4gKiBhZGQgYWxsIGZvcm0gZmllbGRzIG5lZWRlZCBmb3IgdGhlIGNhbXVuZGE6Zm9ybURhdGEgcHJvcGVydHkuXG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gTXVsdGlDb21tYW5kSGFuZGxlcihjb21tYW5kU3RhY2spIHtcbiAgdGhpcy5fY29tbWFuZFN0YWNrID0gY29tbWFuZFN0YWNrO1xufVxuXG5NdWx0aUNvbW1hbmRIYW5kbGVyLiRpbmplY3QgPSBbICdjb21tYW5kU3RhY2snIF07XG5cbm1vZHVsZS5leHBvcnRzID0gTXVsdGlDb21tYW5kSGFuZGxlcjtcblxuTXVsdGlDb21tYW5kSGFuZGxlci5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY29tbWFuZFN0YWNrID0gdGhpcy5fY29tbWFuZFN0YWNrO1xuXG4gIGZvckVhY2goY29udGV4dCwgZnVuY3Rpb24oY29tbWFuZCkge1xuICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKGNvbW1hbmQuY21kLCBjb21tYW5kLmNvbnRleHQpO1xuICB9KTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgcmVkdWNlID0gcmVxdWlyZSgnbG9kYXNoL3RyYW5zZm9ybScpLFxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcbiAgICBrZXlzID0gcmVxdWlyZSgnbG9kYXNoL2tleXMnKSxcbiAgICBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKTtcblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBpbXBsZW1lbnRzIGEgQlBNTiAyLjAgcHJvcGVydHkgdXBkYXRlXG4gKiBmb3IgYnVzaW5lc3Mgb2JqZWN0cyB3aGljaCBhcmUgbm90IHJlcHJlc2VudGVkIGluIHRoZVxuICogZGlhZ3JhbS5cbiAqXG4gKiBUaGlzIGlzIHVzZWZ1bCBpbiB0aGUgY29udGV4dCBvZiB0aGUgcHJvcGVydGllcyBwYW5lbCBpblxuICogb3JkZXIgdG8gdXBkYXRlIGNoaWxkIGVsZW1lbnRzIG9mIGVsZW1lbnRzIHZpc2libGUgaW5cbiAqIHRoZSBkaWFncmFtLlxuICpcbiAqIEV4YW1wbGU6IHBlcmZvcm0gYW4gdXBkYXRlIG9mIGEgc3BlY2lmaWMgZXZlbnQgZGVmaW5pdGlvblxuICogb2YgYW4gaW50ZXJtZWRpYXRlIGV2ZW50LlxuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIFVwZGF0ZUJ1c2luZXNzT2JqZWN0SGFuZGxlcihlbGVtZW50UmVnaXN0cnkpIHtcbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xufVxuXG5VcGRhdGVCdXNpbmVzc09iamVjdEhhbmRsZXIuJGluamVjdCA9IFsgJ2VsZW1lbnRSZWdpc3RyeScgXTtcblxubW9kdWxlLmV4cG9ydHMgPSBVcGRhdGVCdXNpbmVzc09iamVjdEhhbmRsZXI7XG5cbi8qKlxuICogcmV0dXJucyB0aGUgcm9vdCBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGdldFJvb3QoYnVzaW5lc3NPYmplY3QpIHtcbiAgdmFyIHBhcmVudCA9IGJ1c2luZXNzT2JqZWN0O1xuICB3aGlsZSAocGFyZW50LiRwYXJlbnQpIHtcbiAgICBwYXJlbnQgPSBwYXJlbnQuJHBhcmVudDtcbiAgfVxuICByZXR1cm4gcGFyZW50O1xufVxuXG5mdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBwcm9wZXJ0eU5hbWVzKSB7XG4gIHJldHVybiByZWR1Y2UocHJvcGVydHlOYW1lcywgZnVuY3Rpb24ocmVzdWx0LCBrZXkpIHtcbiAgICByZXN1bHRba2V5XSA9IGJ1c2luZXNzT2JqZWN0LmdldChrZXkpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sIHt9KTtcbn1cblxuXG5mdW5jdGlvbiBzZXRQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBwcm9wZXJ0aWVzKSB7XG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgIGJ1c2luZXNzT2JqZWN0LnNldChrZXksIHZhbHVlKTtcbiAgfSk7XG59XG5cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIFVwZGF0ZXMgYSBidXNpbmVzcyBvYmplY3Qgd2l0aCBhIGxpc3Qgb2YgbmV3IHByb3BlcnRpZXNcbiAqXG4gKiBAbWV0aG9kICBVcGRhdGVCdXNpbmVzc09iamVjdEhhbmRsZXIjZXhlY3V0ZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBjb250ZXh0LmVsZW1lbnQgdGhlIGVsZW1lbnQgd2hpY2ggaGFzIGEgY2hpbGQgYnVzaW5lc3Mgb2JqZWN0IHVwZGF0ZWRcbiAqIEBwYXJhbSB7bW9kZGxlLmJ1c2luZXNzT2JqZWN0fSBjb250ZXh0LmJ1c2luZXNzT2JqZWN0IHRoZSBidXNpbmVzc09iamVjdCB0byB1cGRhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LnByb3BlcnRpZXMgYSBsaXN0IG9mIHByb3BlcnRpZXMgdG8gc2V0IG9uIHRoZSBidXNpbmVzc09iamVjdFxuICpcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlLkJhc2U+fSB0aGUgdXBkYXRlZCBlbGVtZW50XG4gKi9cblVwZGF0ZUJ1c2luZXNzT2JqZWN0SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcbiAgICAgIGJ1c2luZXNzT2JqZWN0ID0gY29udGV4dC5idXNpbmVzc09iamVjdCxcbiAgICAgIHJvb3RFbGVtZW50cyA9IGdldFJvb3QoYnVzaW5lc3NPYmplY3QpLnJvb3RFbGVtZW50cyxcbiAgICAgIHJlZmVyZW5jZVR5cGUgPSBjb250ZXh0LnJlZmVyZW5jZVR5cGUsXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eSA9IGNvbnRleHQucmVmZXJlbmNlUHJvcGVydHksXG4gICAgICBjaGFuZ2VkID0gWyBlbGVtZW50IF07IC8vIHRoaXMgd2lsbCBub3QgY2hhbmdlIGFueSBkaWFncmFtLWpzIGVsZW1lbnRzXG5cbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbGVtZW50IHJlcXVpcmVkJyk7XG4gIH1cblxuICBpZiAoIWJ1c2luZXNzT2JqZWN0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdidXNpbmVzc09iamVjdCByZXF1aXJlZCcpO1xuICB9XG5cbiAgdmFyIHByb3BlcnRpZXMgPSBjb250ZXh0LnByb3BlcnRpZXMsXG4gICAgICBvbGRQcm9wZXJ0aWVzID0gY29udGV4dC5vbGRQcm9wZXJ0aWVzIHx8IGdldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIGtleXMocHJvcGVydGllcykpO1xuXG4gIC8vIGNoZWNrIGlmIHRoZXJlIHRoZSB1cGRhdGUgbmVlZHMgYW4gZXh0ZXJuYWwgZWxlbWVudCBmb3IgcmVmZXJlbmNlXG4gIGlmICh0eXBlb2YgcmVmZXJlbmNlVHlwZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHJlZmVyZW5jZVByb3BlcnR5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGZvckVhY2gocm9vdEVsZW1lbnRzLCBmdW5jdGlvbihyb290RWxlbWVudCkge1xuICAgICAgaWYgKGlzKHJvb3RFbGVtZW50LCByZWZlcmVuY2VUeXBlKSkge1xuICAgICAgICBpZiAocm9vdEVsZW1lbnQuaWQgPT09IHByb3BlcnRpZXNbcmVmZXJlbmNlUHJvcGVydHldKSB7XG4gICAgICAgICAgcHJvcGVydGllc1tyZWZlcmVuY2VQcm9wZXJ0eV0gPSByb290RWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gdXBkYXRlIHByb3BlcnRpZXNcbiAgc2V0UHJvcGVydGllcyhidXNpbmVzc09iamVjdCwgcHJvcGVydGllcyk7XG5cbiAgLy8gc3RvcmUgb2xkIHZhbHVlc1xuICBjb250ZXh0Lm9sZFByb3BlcnRpZXMgPSBvbGRQcm9wZXJ0aWVzO1xuICBjb250ZXh0LmNoYW5nZWQgPSBjaGFuZ2VkO1xuXG4gIC8vIGluZGljYXRlIGNoYW5nZWQgb24gb2JqZWN0cyBhZmZlY3RlZCBieSB0aGUgdXBkYXRlXG4gIHJldHVybiBjaGFuZ2VkO1xufTtcblxuLyoqXG4gKiBSZXZlcnRzIHRoZSB1cGRhdGVcbiAqXG4gKiBAbWV0aG9kICBVcGRhdGVCdXNpbmVzc09iamVjdEhhbmRsZXIjcmV2ZXJ0XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqXG4gKiBAcmV0dXJuIHtkanMubW9kZS5CYXNlfSB0aGUgdXBkYXRlZCBlbGVtZW50XG4gKi9cblVwZGF0ZUJ1c2luZXNzT2JqZWN0SGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBvbGRQcm9wZXJ0aWVzID0gY29udGV4dC5vbGRQcm9wZXJ0aWVzLFxuICAgICAgYnVzaW5lc3NPYmplY3QgPSBjb250ZXh0LmJ1c2luZXNzT2JqZWN0O1xuXG4gIC8vIHVwZGF0ZSBwcm9wZXJ0aWVzXG4gIHNldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIG9sZFByb3BlcnRpZXMpO1xuXG4gIHJldHVybiBjb250ZXh0LmNoYW5nZWQ7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyBhIEJQTU4gMi4wIHByb3BlcnR5IHVwZGF0ZVxuICogZm9yIGJ1c2luZXNzIG9iamVjdCBsaXN0cyB3aGljaCBhcmUgbm90IHJlcHJlc2VudGVkIGluIHRoZVxuICogZGlhZ3JhbS5cbiAqXG4gKiBUaGlzIGlzIHVzZWZ1bCBpbiB0aGUgY29udGV4dCBvZiB0aGUgcHJvcGVydGllcyBwYW5lbCBpblxuICogb3JkZXIgdG8gdXBkYXRlIGNoaWxkIGVsZW1lbnRzIG9mIGVsZW1lbnRzIHZpc2libGUgaW5cbiAqIHRoZSBkaWFncmFtLlxuICpcbiAqIEV4YW1wbGU6IHBlcmZvcm0gYW4gdXBkYXRlIG9mIGEgc3BlY2lmaWMgZXZlbnQgZGVmaW5pdGlvblxuICogb2YgYW4gaW50ZXJtZWRpYXRlIGV2ZW50LlxuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIFVwZGF0ZUJ1c2luZXNzT2JqZWN0TGlzdEhhbmRsZXIoZWxlbWVudFJlZ2lzdHJ5LCBicG1uRmFjdG9yeSkge1xuICB0aGlzLl9lbGVtZW50UmVnaXN0cnkgPSBlbGVtZW50UmVnaXN0cnk7XG4gIHRoaXMuX2JwbW5GYWN0b3J5ID0gYnBtbkZhY3Rvcnk7XG59XG5cblVwZGF0ZUJ1c2luZXNzT2JqZWN0TGlzdEhhbmRsZXIuJGluamVjdCA9IFsgJ2VsZW1lbnRSZWdpc3RyeScsICdicG1uRmFjdG9yeScgXTtcblxubW9kdWxlLmV4cG9ydHMgPSBVcGRhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyO1xuXG5mdW5jdGlvbiBlbnN1cmVOb3ROdWxsKHByb3AsIG5hbWUpIHtcbiAgaWYgKCFwcm9wKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKG5hbWUgKyAncmVxdWlyZWQnKTtcbiAgfVxuICByZXR1cm4gcHJvcDtcbn1cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIFVwZGF0ZXMgYSBlbGVtZW50IHVuZGVyIGEgcHJvdmlkZWQgcGFyZW50LlxuICovXG5VcGRhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjdXJyZW50T2JqZWN0ID0gZW5zdXJlTm90TnVsbChjb250ZXh0LmN1cnJlbnRPYmplY3QsICdjdXJyZW50T2JqZWN0JyksXG4gICAgICBwcm9wZXJ0eU5hbWUgPSBlbnN1cmVOb3ROdWxsKGNvbnRleHQucHJvcGVydHlOYW1lLCAncHJvcGVydHlOYW1lJyksXG4gICAgICB1cGRhdGVkT2JqZWN0TGlzdCA9IGNvbnRleHQudXBkYXRlZE9iamVjdExpc3QsXG4gICAgICBvYmplY3RzVG9SZW1vdmUgPSBjb250ZXh0Lm9iamVjdHNUb1JlbW92ZSB8fCBbXSxcbiAgICAgIG9iamVjdHNUb0FkZCA9IGNvbnRleHQub2JqZWN0c1RvQWRkIHx8IFtdLFxuICAgICAgY2hhbmdlZCA9IFsgY29udGV4dC5lbGVtZW50XSwgLy8gdGhpcyB3aWxsIG5vdCBjaGFuZ2UgYW55IGRpYWdyYW0tanMgZWxlbWVudHNcbiAgICAgIHJlZmVyZW5jZVByb3BlcnR5TmFtZTtcblxuICBpZiAoY29udGV4dC5yZWZlcmVuY2VQcm9wZXJ0eU5hbWUpIHtcbiAgICByZWZlcmVuY2VQcm9wZXJ0eU5hbWUgPSBjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5TmFtZTtcbiAgfVxuXG4gIHZhciBvYmplY3RMaXN0ID0gY3VycmVudE9iamVjdFtwcm9wZXJ0eU5hbWVdO1xuICAvLyBhZGp1c3QgYXJyYXkgcmVmZXJlbmNlIGluIHRoZSBwYXJlbnQgYnVzaW5lc3Mgb2JqZWN0XG4gIGNvbnRleHQucHJldmlvdXNMaXN0ID0gY3VycmVudE9iamVjdFtwcm9wZXJ0eU5hbWVdO1xuXG4gIGlmICh1cGRhdGVkT2JqZWN0TGlzdCkge1xuICAgIGN1cnJlbnRPYmplY3RbcHJvcGVydHlOYW1lXSA9IHVwZGF0ZWRPYmplY3RMaXN0O1xuICB9IGVsc2Uge1xuICAgIHZhciBsaXN0Q29weSA9IFtdO1xuICAgIC8vIHJlbW92ZSBhbGwgb2JqZWN0cyB3aGljaCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgIGZvckVhY2gob2JqZWN0TGlzdCwgZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0c1RvUmVtb3ZlLmluZGV4T2Yob2JqZWN0KSA9PSAtMSkge1xuICAgICAgICBsaXN0Q29weS5wdXNoKG9iamVjdCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gYWRkIGFsbCBvYmplY3RzIHdoaWNoIHNob3VsZCBiZSBhZGRlZFxuICAgIGxpc3RDb3B5ID0gbGlzdENvcHkuY29uY2F0KG9iamVjdHNUb0FkZCk7XG5cbiAgICAvLyBzZXQgcHJvcGVydHkgdG8gbmV3IGxpc3RcbiAgICBpZiAobGlzdENvcHkubGVuZ3RoID4gMCB8fCAhcmVmZXJlbmNlUHJvcGVydHlOYW1lKSB7XG5cbiAgICAgIC8vIGFzIGxvbmcgYXMgdGhlcmUgYXJlIGVsZW1lbnRzIGluIHRoZSBsaXN0IHVwZGF0ZSB0aGUgbGlzdFxuICAgICAgY3VycmVudE9iamVjdFtwcm9wZXJ0eU5hbWVdID0gbGlzdENvcHk7XG4gICAgfSBlbHNlIGlmIChyZWZlcmVuY2VQcm9wZXJ0eU5hbWUpIHtcblxuICAgICAgLy8gcmVtb3ZlIHRoZSBsaXN0IHdoZW4gaXQgaXMgZW1wdHlcbiAgICAgIHZhciBwYXJlbnRPYmplY3QgPSBjdXJyZW50T2JqZWN0LiRwYXJlbnQ7XG4gICAgICBwYXJlbnRPYmplY3Quc2V0KHJlZmVyZW5jZVByb3BlcnR5TmFtZSwgdW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cblxuICBjb250ZXh0LmNoYW5nZWQgPSBjaGFuZ2VkO1xuXG4gIC8vIGluZGljYXRlIGNoYW5nZWQgb24gb2JqZWN0cyBhZmZlY3RlZCBieSB0aGUgdXBkYXRlXG4gIHJldHVybiBjaGFuZ2VkO1xufTtcblxuLyoqXG4gKiBSZXZlcnRzIHRoZSB1cGRhdGVcbiAqXG4gKiBAbWV0aG9kICBDcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyI3JldmVydFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGUuQmFzZX0gdGhlIHVwZGF0ZWQgZWxlbWVudFxuICovXG5VcGRhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGN1cnJlbnRPYmplY3QgPSBjb250ZXh0LmN1cnJlbnRPYmplY3QsXG4gICAgICBwcm9wZXJ0eU5hbWUgPSBjb250ZXh0LnByb3BlcnR5TmFtZSxcbiAgICAgIHByZXZpb3VzTGlzdCA9IGNvbnRleHQucHJldmlvdXNMaXN0LFxuICAgICAgcGFyZW50T2JqZWN0ID0gY3VycmVudE9iamVjdC4kcGFyZW50O1xuXG4gIGlmIChjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5TmFtZSkge1xuICAgIHBhcmVudE9iamVjdC5zZXQoY29udGV4dC5yZWZlcmVuY2VQcm9wZXJ0eU5hbWUsIGN1cnJlbnRPYmplY3QpO1xuICB9XG5cbiAgLy8gcmVtb3ZlIG5ldyBlbGVtZW50XG4gIGN1cnJlbnRPYmplY3Quc2V0KHByb3BlcnR5TmFtZSwgcHJldmlvdXNMaXN0KTtcblxuICByZXR1cm4gY29udGV4dC5jaGFuZ2VkO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xuXG52YXIgSEFORExFUlMgPSB7XG4gICdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdCc6IHJlcXVpcmUoJy4vVXBkYXRlQnVzaW5lc3NPYmplY3RIYW5kbGVyJyksXG4gICdwcm9wZXJ0aWVzLXBhbmVsLmNyZWF0ZS1hbmQtcmVmZXJlbmNlJzogcmVxdWlyZSgnLi9DcmVhdGVBbmRSZWZlcmVuY2VIYW5kbGVyJyksXG4gICdwcm9wZXJ0aWVzLXBhbmVsLmNyZWF0ZS1idXNpbmVzc29iamVjdC1saXN0JzogcmVxdWlyZSgnLi9DcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyJyksXG4gICdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0JzogcmVxdWlyZSgnLi9VcGRhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyJyksXG4gICdwcm9wZXJ0aWVzLXBhbmVsLm11bHRpLWNvbW1hbmQtZXhlY3V0b3InOiByZXF1aXJlKCcuL011bHRpQ29tbWFuZEhhbmRsZXInKVxufTtcblxuXG5mdW5jdGlvbiBDb21tYW5kSW5pdGlhbGl6ZXIoZXZlbnRCdXMsIGNvbW1hbmRTdGFjaykge1xuXG4gIGV2ZW50QnVzLm9uKCdkaWFncmFtLmluaXQnLCBmdW5jdGlvbigpIHtcbiAgICBmb3JFYWNoKEhBTkRMRVJTLCBmdW5jdGlvbihoYW5kbGVyLCBpZCkge1xuICAgICAgY29tbWFuZFN0YWNrLnJlZ2lzdGVySGFuZGxlcihpZCwgaGFuZGxlcik7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5Db21tYW5kSW5pdGlhbGl6ZXIuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2NvbW1hbmRTdGFjaycgXTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIF9faW5pdF9fOiBbIENvbW1hbmRJbml0aWFsaXplciBdXG59OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIEVsZW1lbnRIZWxwZXIgPSB7fTtcbm1vZHVsZS5leHBvcnRzID0gRWxlbWVudEhlbHBlcjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGVsZW1lbnQgYW5kIHNldCB0aGUgcGFyZW50IHRvIGl0XG4gKlxuICogQG1ldGhvZCBFbGVtZW50SGVscGVyI2NyZWF0ZUVsZW1lbnRcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZWxlbWVudFR5cGUgb2YgdGhlIG5ldyBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBvZiB0aGUgbmV3IGVsZW1lbnQgaW4ga2V5LXZhbHVlIHBhaXJzXG4gKiBAcGFyYW0ge21vZGRsZS5vYmplY3R9IHBhcmVudCBvZiB0aGUgbmV3IGVsZW1lbnRcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGZhY3Rvcnkgd2hpY2ggY3JlYXRlcyB0aGUgbmV3IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJucyB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnQgd2hpY2ggaXMgY3JlYXRlZFxuICovXG5FbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50VHlwZSwgcHJvcGVydGllcywgcGFyZW50LCBmYWN0b3J5KSB7XG4gIHZhciBlbGVtZW50ID0gZmFjdG9yeS5jcmVhdGUoZWxlbWVudFR5cGUsIHByb3BlcnRpZXMpO1xuICBlbGVtZW50LiRwYXJlbnQgPSBwYXJlbnQ7XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgcmVxdWlyZSgnLi9jbWQnKSxcbiAgICByZXF1aXJlKCdkaWFncmFtLWpzL2xpYi9pMThuL3RyYW5zbGF0ZScpLmRlZmF1bHRcbiAgXSxcbiAgX19pbml0X186IFsgJ3Byb3BlcnRpZXNQYW5lbCcgXSxcbiAgcHJvcGVydGllc1BhbmVsOiBbICd0eXBlJywgcmVxdWlyZSgnLi9Qcm9wZXJ0aWVzUGFuZWwnKSBdXG59O1xuIiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IElkcyBmcm9tICdpZHMnO1xuXG5pbXBvcnQgQmFzZVZpZXdlciBmcm9tICcuL0Jhc2VWaWV3ZXInO1xuXG5cbi8qKlxuICogQSBiYXNlIG1vZGVsZXIgZm9yIEJQTU4gMi4wIGRpYWdyYW1zLlxuICpcbiAqIEhhdmUgYSBsb29rIGF0IHtAbGluayBNb2RlbGVyfSBmb3IgYSBidW5kbGUgdGhhdCBpbmNsdWRlcyBhY3R1YWwgZmVhdHVyZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gcGFzcyB0byB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IFtvcHRpb25zLmNvbnRhaW5lcl0gdGhlIGNvbnRhaW5lciB0byByZW5kZXIgdGhlIHZpZXdlciBpbiwgZGVmYXVsdHMgdG8gYm9keS5cbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gW29wdGlvbnMud2lkdGhdIHRoZSB3aWR0aCBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IFtvcHRpb25zLmhlaWdodF0gdGhlIGhlaWdodCBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMubW9kZGxlRXh0ZW5zaW9uc10gZXh0ZW5zaW9uIHBhY2thZ2VzIHRvIHByb3ZpZGVcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5tb2R1bGVzXSBhIGxpc3Qgb2YgbW9kdWxlcyB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCBtb2R1bGVzXG4gKiBAcGFyYW0ge0FycmF5PGRpZGkuTW9kdWxlPn0gW29wdGlvbnMuYWRkaXRpb25hbE1vZHVsZXNdIGEgbGlzdCBvZiBtb2R1bGVzIHRvIHVzZSB3aXRoIHRoZSBkZWZhdWx0IG1vZHVsZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmFzZU1vZGVsZXIob3B0aW9ucykge1xuICBCYXNlVmlld2VyLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgLy8gaG9vayBJRCBjb2xsZWN0aW9uIGludG8gdGhlIG1vZGVsZXJcbiAgdGhpcy5vbignaW1wb3J0LnBhcnNlLmNvbXBsZXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBpZiAoIWV2ZW50LmVycm9yKSB7XG4gICAgICB0aGlzLl9jb2xsZWN0SWRzKGV2ZW50LmRlZmluaXRpb25zLCBldmVudC5lbGVtZW50c0J5SWQpO1xuICAgIH1cbiAgfSwgdGhpcyk7XG5cbiAgdGhpcy5vbignZGlhZ3JhbS5kZXN0cm95JywgZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5nZXQoJ21vZGRsZScpLmlkcy5jbGVhcigpO1xuICB9LCB0aGlzKTtcbn1cblxuaW5oZXJpdHMoQmFzZU1vZGVsZXIsIEJhc2VWaWV3ZXIpO1xuXG5cbi8qKlxuICogQ3JlYXRlIGEgbW9kZGxlIGluc3RhbmNlLCBhdHRhY2hpbmcgaWRzIHRvIGl0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKi9cbkJhc2VNb2RlbGVyLnByb3RvdHlwZS5fY3JlYXRlTW9kZGxlID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICB2YXIgbW9kZGxlID0gQmFzZVZpZXdlci5wcm90b3R5cGUuX2NyZWF0ZU1vZGRsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIC8vIGF0dGFjaCBpZHMgdG8gbW9kZGxlIHRvIGJlIGFibGUgdG8gdHJhY2tcbiAgLy8gYW5kIHZhbGlkYXRlZCBpZHMgaW4gdGhlIEJQTU4gMi4wIFhNTCBkb2N1bWVudFxuICAvLyB0cmVlXG4gIG1vZGRsZS5pZHMgPSBuZXcgSWRzKFsgMzIsIDM2LCAxIF0pO1xuXG4gIHJldHVybiBtb2RkbGU7XG59O1xuXG4vKipcbiAqIENvbGxlY3QgaWRzIHByb2Nlc3NlZCBkdXJpbmcgcGFyc2luZyBvZiB0aGVcbiAqIGRlZmluaXRpb25zIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGRlZmluaXRpb25zXG4gKiBAcGFyYW0ge0NvbnRleHR9IGNvbnRleHRcbiAqL1xuQmFzZU1vZGVsZXIucHJvdG90eXBlLl9jb2xsZWN0SWRzID0gZnVuY3Rpb24oZGVmaW5pdGlvbnMsIGVsZW1lbnRzQnlJZCkge1xuXG4gIHZhciBtb2RkbGUgPSBkZWZpbml0aW9ucy4kbW9kZWwsXG4gICAgICBpZHMgPSBtb2RkbGUuaWRzLFxuICAgICAgaWQ7XG5cbiAgLy8gcmVtb3ZlIHJlZmVyZW5jZXMgZnJvbSBwcmV2aW91cyBpbXBvcnRcbiAgaWRzLmNsZWFyKCk7XG5cbiAgZm9yIChpZCBpbiBlbGVtZW50c0J5SWQpIHtcbiAgICBpZHMuY2xhaW0oaWQsIGVsZW1lbnRzQnlJZFtpZF0pO1xuICB9XG59O1xuIiwiLyoqXG4gKiBUaGUgY29kZSBpbiB0aGUgPHByb2plY3QtbG9nbz48L3Byb2plY3QtbG9nbz4gYXJlYVxuICogbXVzdCBub3QgYmUgY2hhbmdlZC5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9icG1uLmlvL2xpY2Vuc2UgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKi9cbmltcG9ydCB7XG4gIGFzc2lnbixcbiAgZmluZCxcbiAgaXNOdW1iZXIsXG4gIG9taXRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBkb21pZnksXG4gIHF1ZXJ5IGFzIGRvbVF1ZXJ5LFxuICByZW1vdmUgYXMgZG9tUmVtb3ZlXG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICBpbm5lclNWR1xufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCBEaWFncmFtIGZyb20gJ2RpYWdyYW0tanMnO1xuaW1wb3J0IEJwbW5Nb2RkbGUgZnJvbSAnYnBtbi1tb2RkbGUnO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQge1xuICBpbXBvcnRCcG1uRGlhZ3JhbVxufSBmcm9tICcuL2ltcG9ydC9JbXBvcnRlcic7XG5cbmltcG9ydCB7XG4gIHdyYXBGb3JDb21wYXRpYmlsaXR5XG59IGZyb20gJy4vdXRpbC9Db21wYXRpYmlsaXR5VXRpbCc7XG5cbi8qKlxuICogQSBiYXNlIHZpZXdlciBmb3IgQlBNTiAyLjAgZGlhZ3JhbXMuXG4gKlxuICogSGF2ZSBhIGxvb2sgYXQge0BsaW5rIFZpZXdlcn0sIHtAbGluayBOYXZpZ2F0ZWRWaWV3ZXJ9IG9yIHtAbGluayBNb2RlbGVyfSBmb3JcbiAqIGJ1bmRsZXMgdGhhdCBpbmNsdWRlIGFjdHVhbCBmZWF0dXJlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBwYXNzIHRvIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gW29wdGlvbnMuY29udGFpbmVyXSB0aGUgY29udGFpbmVyIHRvIHJlbmRlciB0aGUgdmlld2VyIGluLCBkZWZhdWx0cyB0byBib2R5LlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBbb3B0aW9ucy53aWR0aF0gdGhlIHdpZHRoIG9mIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gW29wdGlvbnMuaGVpZ2h0XSB0aGUgaGVpZ2h0IG9mIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5tb2RkbGVFeHRlbnNpb25zXSBleHRlbnNpb24gcGFja2FnZXMgdG8gcHJvdmlkZVxuICogQHBhcmFtIHtBcnJheTxkaWRpLk1vZHVsZT59IFtvcHRpb25zLm1vZHVsZXNdIGEgbGlzdCBvZiBtb2R1bGVzIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IG1vZHVsZXNcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5hZGRpdGlvbmFsTW9kdWxlc10gYSBsaXN0IG9mIG1vZHVsZXMgdG8gdXNlIHdpdGggdGhlIGRlZmF1bHQgbW9kdWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCYXNlVmlld2VyKG9wdGlvbnMpIHtcblxuICBvcHRpb25zID0gYXNzaWduKHt9LCBERUZBVUxUX09QVElPTlMsIG9wdGlvbnMpO1xuXG4gIHRoaXMuX21vZGRsZSA9IHRoaXMuX2NyZWF0ZU1vZGRsZShvcHRpb25zKTtcblxuICB0aGlzLl9jb250YWluZXIgPSB0aGlzLl9jcmVhdGVDb250YWluZXIob3B0aW9ucyk7XG5cbiAgLyogPHByb2plY3QtbG9nbz4gKi9cblxuICBhZGRQcm9qZWN0TG9nbyh0aGlzLl9jb250YWluZXIpO1xuXG4gIC8qIDwvcHJvamVjdC1sb2dvPiAqL1xuXG4gIHRoaXMuX2luaXQodGhpcy5fY29udGFpbmVyLCB0aGlzLl9tb2RkbGUsIG9wdGlvbnMpO1xufVxuXG5pbmhlcml0cyhCYXNlVmlld2VyLCBEaWFncmFtKTtcblxuLyoqXG4qIFRoZSBpbXBvcnRYTUwgcmVzdWx0LlxuKlxuKiBAdHlwZWRlZiB7T2JqZWN0fSBJbXBvcnRYTUxSZXN1bHRcbipcbiogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuKi9cblxuLyoqXG4qIFRoZSBpbXBvcnRYTUwgZXJyb3IuXG4qXG4qIEB0eXBlZGVmIHtFcnJvcn0gSW1wb3J0WE1MRXJyb3JcbipcbiogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuKi9cblxuLyoqXG4gKiBQYXJzZSBhbmQgcmVuZGVyIGEgQlBNTiAyLjAgZGlhZ3JhbS5cbiAqXG4gKiBPbmNlIGZpbmlzaGVkIHRoZSB2aWV3ZXIgcmVwb3J0cyBiYWNrIHRoZSByZXN1bHQgdG8gdGhlXG4gKiBwcm92aWRlZCBjYWxsYmFjayBmdW5jdGlvbiB3aXRoIChlcnIsIHdhcm5pbmdzKS5cbiAqXG4gKiAjIyBMaWZlLUN5Y2xlIEV2ZW50c1xuICpcbiAqIER1cmluZyBpbXBvcnQgdGhlIHZpZXdlciB3aWxsIGZpcmUgbGlmZS1jeWNsZSBldmVudHM6XG4gKlxuICogICAqIGltcG9ydC5wYXJzZS5zdGFydCAoYWJvdXQgdG8gcmVhZCBtb2RlbCBmcm9tIHhtbClcbiAqICAgKiBpbXBvcnQucGFyc2UuY29tcGxldGUgKG1vZGVsIHJlYWQ7IG1heSBoYXZlIHdvcmtlZCBvciBub3QpXG4gKiAgICogaW1wb3J0LnJlbmRlci5zdGFydCAoZ3JhcGhpY2FsIGltcG9ydCBzdGFydClcbiAqICAgKiBpbXBvcnQucmVuZGVyLmNvbXBsZXRlIChncmFwaGljYWwgaW1wb3J0IGZpbmlzaGVkKVxuICogICAqIGltcG9ydC5kb25lIChldmVyeXRoaW5nIGRvbmUpXG4gKlxuICogWW91IGNhbiB1c2UgdGhlc2UgZXZlbnRzIHRvIGhvb2sgaW50byB0aGUgbGlmZS1jeWNsZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30geG1sIHRoZSBCUE1OIDIuMCB4bWxcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxCUE1ORGlhZ3JhbT58c3RyaW5nfSBbYnBtbkRpYWdyYW1dIEJQTU4gZGlhZ3JhbSBvciBpZCBvZiBkaWFncmFtIHRvIHJlbmRlciAoaWYgbm90IHByb3ZpZGVkLCB0aGUgZmlyc3Qgb25lIHdpbGwgYmUgcmVuZGVyZWQpXG4gKlxuICogUmV0dXJucyB7UHJvbWlzZTxJbXBvcnRYTUxSZXN1bHQsIEltcG9ydFhNTEVycm9yPn1cbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUuaW1wb3J0WE1MID0gd3JhcEZvckNvbXBhdGliaWxpdHkoZnVuY3Rpb24gaW1wb3J0WE1MKHhtbCwgYnBtbkRpYWdyYW0pIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gUGFyc2VDb21wbGV0ZUV2ZW50KGRhdGEpIHtcblxuICAgIHZhciBldmVudCA9IHNlbGYuZ2V0KCdldmVudEJ1cycpLmNyZWF0ZUV2ZW50KGRhdGEpO1xuXG4gICAgLy8gVE9ETyhuaWtrdSk6IHJlbW92ZSB3aXRoIGZ1dHVyZSBicG1uLWpzIHZlcnNpb25cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZXZlbnQsICdjb250ZXh0Jywge1xuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgY29uc29sZS53YXJuKG5ldyBFcnJvcihcbiAgICAgICAgICAnaW1wb3J0LnBhcnNlLmNvbXBsZXRlIDxjb250ZXh0PiBpcyBkZXByZWNhdGVkICcgK1xuICAgICAgICAgICdhbmQgd2lsbCBiZSByZW1vdmVkIGluIGZ1dHVyZSBsaWJyYXJ5IHZlcnNpb25zJ1xuICAgICAgICApKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHdhcm5pbmdzOiBkYXRhLndhcm5pbmdzLFxuICAgICAgICAgIHJlZmVyZW5jZXM6IGRhdGEucmVmZXJlbmNlcyxcbiAgICAgICAgICBlbGVtZW50c0J5SWQ6IGRhdGEuZWxlbWVudHNCeUlkXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZXZlbnQ7XG4gIH1cblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG5cbiAgICAvLyBob29rIGluIHByZS1wYXJzZSBsaXN0ZW5lcnMgK1xuICAgIC8vIGFsbG93IHhtbCBtYW5pcHVsYXRpb25cbiAgICB4bWwgPSBzZWxmLl9lbWl0KCdpbXBvcnQucGFyc2Uuc3RhcnQnLCB7IHhtbDogeG1sIH0pIHx8IHhtbDtcblxuICAgIHNlbGYuX21vZGRsZS5mcm9tWE1MKHhtbCwgJ2JwbW46RGVmaW5pdGlvbnMnKS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgICAgdmFyIGRlZmluaXRpb25zID0gcmVzdWx0LnJvb3RFbGVtZW50O1xuICAgICAgdmFyIHJlZmVyZW5jZXMgPSByZXN1bHQucmVmZXJlbmNlcztcbiAgICAgIHZhciBwYXJzZVdhcm5pbmdzID0gcmVzdWx0Lndhcm5pbmdzO1xuICAgICAgdmFyIGVsZW1lbnRzQnlJZCA9IHJlc3VsdC5lbGVtZW50c0J5SWQ7XG5cbiAgICAgIC8vIGhvb2sgaW4gcG9zdCBwYXJzZSBsaXN0ZW5lcnMgK1xuICAgICAgLy8gYWxsb3cgZGVmaW5pdGlvbnMgbWFuaXB1bGF0aW9uXG4gICAgICBkZWZpbml0aW9ucyA9IHNlbGYuX2VtaXQoJ2ltcG9ydC5wYXJzZS5jb21wbGV0ZScsIFBhcnNlQ29tcGxldGVFdmVudCh7XG4gICAgICAgIGVycm9yOiBudWxsLFxuICAgICAgICBkZWZpbml0aW9uczogZGVmaW5pdGlvbnMsXG4gICAgICAgIGVsZW1lbnRzQnlJZDogZWxlbWVudHNCeUlkLFxuICAgICAgICByZWZlcmVuY2VzOiByZWZlcmVuY2VzLFxuICAgICAgICB3YXJuaW5nczogcGFyc2VXYXJuaW5nc1xuICAgICAgfSkpIHx8IGRlZmluaXRpb25zO1xuXG4gICAgICBzZWxmLmltcG9ydERlZmluaXRpb25zKGRlZmluaXRpb25zLCBicG1uRGlhZ3JhbSkudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgdmFyIGFsbFdhcm5pbmdzID0gW10uY29uY2F0KHBhcnNlV2FybmluZ3MsIHJlc3VsdC53YXJuaW5ncyB8fCBbXSk7XG5cbiAgICAgICAgc2VsZi5fZW1pdCgnaW1wb3J0LmRvbmUnLCB7IGVycm9yOiBudWxsLCB3YXJuaW5nczogYWxsV2FybmluZ3MgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc29sdmUoeyB3YXJuaW5nczogYWxsV2FybmluZ3MgfSk7XG4gICAgICB9KS5jYXRjaChmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgdmFyIGFsbFdhcm5pbmdzID0gW10uY29uY2F0KHBhcnNlV2FybmluZ3MsIGVyci53YXJuaW5ncyB8fCBbXSk7XG5cbiAgICAgICAgc2VsZi5fZW1pdCgnaW1wb3J0LmRvbmUnLCB7IGVycm9yOiBlcnIsIHdhcm5pbmdzOiBhbGxXYXJuaW5ncyB9KTtcblxuICAgICAgICByZXR1cm4gcmVqZWN0KGFkZFdhcm5pbmdzVG9FcnJvcihlcnIsIGFsbFdhcm5pbmdzKSk7XG4gICAgICB9KTtcbiAgICB9KS5jYXRjaChmdW5jdGlvbihlcnIpIHtcblxuICAgICAgc2VsZi5fZW1pdCgnaW1wb3J0LnBhcnNlLmNvbXBsZXRlJywge1xuICAgICAgICBlcnJvcjogZXJyXG4gICAgICB9KTtcblxuICAgICAgZXJyID0gY2hlY2tWYWxpZGF0aW9uRXJyb3IoZXJyKTtcblxuICAgICAgc2VsZi5fZW1pdCgnaW1wb3J0LmRvbmUnLCB7IGVycm9yOiBlcnIsIHdhcm5pbmdzOiBlcnIud2FybmluZ3MgfSk7XG5cbiAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLyoqXG4qIFRoZSBpbXBvcnREZWZpbml0aW9ucyByZXN1bHQuXG4qXG4qIEB0eXBlZGVmIHtPYmplY3R9IEltcG9ydERlZmluaXRpb25zUmVzdWx0XG4qXG4qIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gd2FybmluZ3NcbiovXG5cbi8qKlxuKiBUaGUgaW1wb3J0RGVmaW5pdGlvbnMgZXJyb3IuXG4qXG4qIEB0eXBlZGVmIHtFcnJvcn0gSW1wb3J0RGVmaW5pdGlvbnNFcnJvclxuKlxuKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IHdhcm5pbmdzXG4qL1xuXG4vKipcbiAqIEltcG9ydCBwYXJzZWQgZGVmaW5pdGlvbnMgYW5kIHJlbmRlciBhIEJQTU4gMi4wIGRpYWdyYW0uXG4gKlxuICogT25jZSBmaW5pc2hlZCB0aGUgdmlld2VyIHJlcG9ydHMgYmFjayB0aGUgcmVzdWx0IHRvIHRoZVxuICogcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCAoZXJyLCB3YXJuaW5ncykuXG4gKlxuICogIyMgTGlmZS1DeWNsZSBFdmVudHNcbiAqXG4gKiBEdXJpbmcgaW1wb3J0IHRoZSB2aWV3ZXIgd2lsbCBmaXJlIGxpZmUtY3ljbGUgZXZlbnRzOlxuICpcbiAqICAgKiBpbXBvcnQucmVuZGVyLnN0YXJ0IChncmFwaGljYWwgaW1wb3J0IHN0YXJ0KVxuICogICAqIGltcG9ydC5yZW5kZXIuY29tcGxldGUgKGdyYXBoaWNhbCBpbXBvcnQgZmluaXNoZWQpXG4gKlxuICogWW91IGNhbiB1c2UgdGhlc2UgZXZlbnRzIHRvIGhvb2sgaW50byB0aGUgbGlmZS1jeWNsZS5cbiAqXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnQ8RGVmaW5pdGlvbnM+fSBkZWZpbml0aW9ucyBwYXJzZWQgQlBNTiAyLjAgZGVmaW5pdGlvbnNcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxCUE1ORGlhZ3JhbT58c3RyaW5nfSBbYnBtbkRpYWdyYW1dIEJQTU4gZGlhZ3JhbSBvciBpZCBvZiBkaWFncmFtIHRvIHJlbmRlciAoaWYgbm90IHByb3ZpZGVkLCB0aGUgZmlyc3Qgb25lIHdpbGwgYmUgcmVuZGVyZWQpXG4gKlxuICogUmV0dXJucyB7UHJvbWlzZTxJbXBvcnREZWZpbml0aW9uc1Jlc3VsdCwgSW1wb3J0RGVmaW5pdGlvbnNFcnJvcj59XG4gKi9cbkJhc2VWaWV3ZXIucHJvdG90eXBlLmltcG9ydERlZmluaXRpb25zID0gd3JhcEZvckNvbXBhdGliaWxpdHkoZnVuY3Rpb24gaW1wb3J0RGVmaW5pdGlvbnMoZGVmaW5pdGlvbnMsIGJwbW5EaWFncmFtKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcblxuICAgIHNlbGYuX3NldERlZmluaXRpb25zKGRlZmluaXRpb25zKTtcblxuICAgIHNlbGYub3BlbihicG1uRGlhZ3JhbSkudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcblxuICAgICAgdmFyIHdhcm5pbmdzID0gcmVzdWx0Lndhcm5pbmdzO1xuXG4gICAgICByZXR1cm4gcmVzb2x2ZSh7IHdhcm5pbmdzOiB3YXJuaW5ncyB9KTtcbiAgICB9KS5jYXRjaChmdW5jdGlvbihlcnIpIHtcblxuICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG4vKipcbiAqIFRoZSBvcGVuIHJlc3VsdC5cbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcGVuUmVzdWx0XG4gKlxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuICovXG5cbi8qKlxuKiBUaGUgb3BlbiBlcnJvci5cbipcbiogQHR5cGVkZWYge0Vycm9yfSBPcGVuRXJyb3JcbipcbiogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuKi9cblxuLyoqXG4gKiBPcGVuIGRpYWdyYW0gb2YgcHJldmlvdXNseSBpbXBvcnRlZCBYTUwuXG4gKlxuICogT25jZSBmaW5pc2hlZCB0aGUgdmlld2VyIHJlcG9ydHMgYmFjayB0aGUgcmVzdWx0IHRvIHRoZVxuICogcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCAoZXJyLCB3YXJuaW5ncykuXG4gKlxuICogIyMgTGlmZS1DeWNsZSBFdmVudHNcbiAqXG4gKiBEdXJpbmcgc3dpdGNoIHRoZSB2aWV3ZXIgd2lsbCBmaXJlIGxpZmUtY3ljbGUgZXZlbnRzOlxuICpcbiAqICAgKiBpbXBvcnQucmVuZGVyLnN0YXJ0IChncmFwaGljYWwgaW1wb3J0IHN0YXJ0KVxuICogICAqIGltcG9ydC5yZW5kZXIuY29tcGxldGUgKGdyYXBoaWNhbCBpbXBvcnQgZmluaXNoZWQpXG4gKlxuICogWW91IGNhbiB1c2UgdGhlc2UgZXZlbnRzIHRvIGhvb2sgaW50byB0aGUgbGlmZS1jeWNsZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xNb2RkbGVFbGVtZW50PEJQTU5EaWFncmFtPn0gW2JwbW5EaWFncmFtT3JJZF0gaWQgb3IgdGhlIGRpYWdyYW0gdG8gb3BlblxuICpcbiAqIFJldHVybnMge1Byb21pc2U8T3BlblJlc3VsdCwgT3BlbkVycm9yPn1cbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUub3BlbiA9IHdyYXBGb3JDb21wYXRpYmlsaXR5KGZ1bmN0aW9uIG9wZW4oYnBtbkRpYWdyYW1PcklkKSB7XG5cbiAgdmFyIGRlZmluaXRpb25zID0gdGhpcy5fZGVmaW5pdGlvbnM7XG4gIHZhciBicG1uRGlhZ3JhbSA9IGJwbW5EaWFncmFtT3JJZDtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGlmICghZGVmaW5pdGlvbnMpIHtcbiAgICAgIHZhciBlcnIxID0gbmV3IEVycm9yKCdubyBYTUwgaW1wb3J0ZWQnKTtcblxuICAgICAgcmV0dXJuIHJlamVjdChhZGRXYXJuaW5nc1RvRXJyb3IoZXJyMSwgW10pKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGJwbW5EaWFncmFtT3JJZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGJwbW5EaWFncmFtID0gZmluZEJQTU5EaWFncmFtKGRlZmluaXRpb25zLCBicG1uRGlhZ3JhbU9ySWQpO1xuXG4gICAgICBpZiAoIWJwbW5EaWFncmFtKSB7XG4gICAgICAgIHZhciBlcnIyID0gbmV3IEVycm9yKCdCUE1ORGlhZ3JhbSA8JyArIGJwbW5EaWFncmFtT3JJZCArICc+IG5vdCBmb3VuZCcpO1xuXG4gICAgICAgIHJldHVybiByZWplY3QoYWRkV2FybmluZ3NUb0Vycm9yKGVycjIsIFtdKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2xlYXIgZXhpc3RpbmcgcmVuZGVyZWQgZGlhZ3JhbVxuICAgIC8vIGNhdGNoIHN5bmNocm9ub3VzIGV4Y2VwdGlvbnMgZHVyaW5nICNjbGVhcigpXG4gICAgdHJ5IHtcbiAgICAgIHNlbGYuY2xlYXIoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuXG4gICAgICByZXR1cm4gcmVqZWN0KGFkZFdhcm5pbmdzVG9FcnJvcihlcnJvciwgW10pKTtcbiAgICB9XG5cbiAgICAvLyBwZXJmb3JtIGdyYXBoaWNhbCBpbXBvcnRcbiAgICBpbXBvcnRCcG1uRGlhZ3JhbShzZWxmLCBkZWZpbml0aW9ucywgYnBtbkRpYWdyYW0pLnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XG5cbiAgICAgIHZhciB3YXJuaW5ncyA9IHJlc3VsdC53YXJuaW5ncztcblxuICAgICAgcmV0dXJuIHJlc29sdmUoeyB3YXJuaW5nczogd2FybmluZ3MgfSk7XG4gICAgfSkuY2F0Y2goZnVuY3Rpb24oZXJyKSB7XG5cbiAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLyoqXG4gKiBUaGUgc2F2ZVhNTCByZXN1bHQuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gU2F2ZVhNTFJlc3VsdFxuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB4bWxcbiAqL1xuXG4vKipcbiAqIEV4cG9ydCB0aGUgY3VycmVudGx5IGRpc3BsYXllZCBCUE1OIDIuMCBkaWFncmFtIGFzXG4gKiBhIEJQTU4gMi4wIFhNTCBkb2N1bWVudC5cbiAqXG4gKiAjIyBMaWZlLUN5Y2xlIEV2ZW50c1xuICpcbiAqIER1cmluZyBYTUwgc2F2aW5nIHRoZSB2aWV3ZXIgd2lsbCBmaXJlIGxpZmUtY3ljbGUgZXZlbnRzOlxuICpcbiAqICAgKiBzYXZlWE1MLnN0YXJ0IChiZWZvcmUgc2VyaWFsaXphdGlvbilcbiAqICAgKiBzYXZlWE1MLnNlcmlhbGl6ZWQgKGFmdGVyIHhtbCBnZW5lcmF0aW9uKVxuICogICAqIHNhdmVYTUwuZG9uZSAoZXZlcnl0aGluZyBkb25lKVxuICpcbiAqIFlvdSBjYW4gdXNlIHRoZXNlIGV2ZW50cyB0byBob29rIGludG8gdGhlIGxpZmUtY3ljbGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBleHBvcnQgb3B0aW9uc1xuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5mb3JtYXQ9ZmFsc2VdIG91dHB1dCBmb3JtYXR0ZWQgWE1MXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnByZWFtYmxlPXRydWVdIG91dHB1dCBwcmVhbWJsZVxuICpcbiAqIFJldHVybnMge1Byb21pc2U8U2F2ZVhNTFJlc3VsdCwgRXJyb3I+fVxuICovXG5CYXNlVmlld2VyLnByb3RvdHlwZS5zYXZlWE1MID0gd3JhcEZvckNvbXBhdGliaWxpdHkoZnVuY3Rpb24gc2F2ZVhNTChvcHRpb25zKSB7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBkZWZpbml0aW9ucyA9IHRoaXMuX2RlZmluaXRpb25zO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcblxuICAgIGlmICghZGVmaW5pdGlvbnMpIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ25vIGRlZmluaXRpb25zIGxvYWRlZCcpO1xuXG4gICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgfVxuXG4gICAgLy8gYWxsb3cgdG8gZmlkZGxlIGFyb3VuZCB3aXRoIGRlZmluaXRpb25zXG4gICAgZGVmaW5pdGlvbnMgPSBzZWxmLl9lbWl0KCdzYXZlWE1MLnN0YXJ0Jywge1xuICAgICAgZGVmaW5pdGlvbnM6IGRlZmluaXRpb25zXG4gICAgfSkgfHwgZGVmaW5pdGlvbnM7XG5cbiAgICBzZWxmLl9tb2RkbGUudG9YTUwoZGVmaW5pdGlvbnMsIG9wdGlvbnMpLnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XG5cbiAgICAgIHZhciB4bWwgPSByZXN1bHQueG1sO1xuXG4gICAgICB0cnkge1xuICAgICAgICB4bWwgPSBzZWxmLl9lbWl0KCdzYXZlWE1MLnNlcmlhbGl6ZWQnLCB7XG4gICAgICAgICAgZXJyb3I6IG51bGwsXG4gICAgICAgICAgeG1sOiB4bWxcbiAgICAgICAgfSkgfHwgeG1sO1xuXG4gICAgICAgIHNlbGYuX2VtaXQoJ3NhdmVYTUwuZG9uZScsIHtcbiAgICAgICAgICBlcnJvcjogbnVsbCxcbiAgICAgICAgICB4bWw6IHhtbFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignZXJyb3IgaW4gc2F2ZVhNTCBsaWZlLWN5Y2xlIGxpc3RlbmVyJywgZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXNvbHZlKHsgeG1sOiB4bWwgfSk7XG4gICAgfSkuY2F0Y2goZnVuY3Rpb24oZXJyKSB7XG5cbiAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLyoqXG4gKiBUaGUgc2F2ZVNWRyByZXN1bHQuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gU2F2ZVNWR1Jlc3VsdFxuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdmdcbiAqL1xuXG4vKipcbiAqIEV4cG9ydCB0aGUgY3VycmVudGx5IGRpc3BsYXllZCBCUE1OIDIuMCBkaWFncmFtIGFzXG4gKiBhbiBTVkcgaW1hZ2UuXG4gKlxuICogIyMgTGlmZS1DeWNsZSBFdmVudHNcbiAqXG4gKiBEdXJpbmcgU1ZHIHNhdmluZyB0aGUgdmlld2VyIHdpbGwgZmlyZSBsaWZlLWN5Y2xlIGV2ZW50czpcbiAqXG4gKiAgICogc2F2ZVNWRy5zdGFydCAoYmVmb3JlIHNlcmlhbGl6YXRpb24pXG4gKiAgICogc2F2ZVNWRy5kb25lIChldmVyeXRoaW5nIGRvbmUpXG4gKlxuICogWW91IGNhbiB1c2UgdGhlc2UgZXZlbnRzIHRvIGhvb2sgaW50byB0aGUgbGlmZS1jeWNsZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gKlxuICogUmV0dXJucyB7UHJvbWlzZTxTYXZlU1ZHUmVzdWx0LCBFcnJvcj59XG4gKi9cbkJhc2VWaWV3ZXIucHJvdG90eXBlLnNhdmVTVkcgPSB3cmFwRm9yQ29tcGF0aWJpbGl0eShmdW5jdGlvbiBzYXZlU1ZHKG9wdGlvbnMpIHtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuXG4gICAgc2VsZi5fZW1pdCgnc2F2ZVNWRy5zdGFydCcpO1xuXG4gICAgdmFyIHN2ZywgZXJyO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBjYW52YXMgPSBzZWxmLmdldCgnY2FudmFzJyk7XG5cbiAgICAgIHZhciBjb250ZW50Tm9kZSA9IGNhbnZhcy5nZXREZWZhdWx0TGF5ZXIoKSxcbiAgICAgICAgICBkZWZzTm9kZSA9IGRvbVF1ZXJ5KCdkZWZzJywgY2FudmFzLl9zdmcpO1xuXG4gICAgICB2YXIgY29udGVudHMgPSBpbm5lclNWRyhjb250ZW50Tm9kZSksXG4gICAgICAgICAgZGVmcyA9IGRlZnNOb2RlID8gJzxkZWZzPicgKyBpbm5lclNWRyhkZWZzTm9kZSkgKyAnPC9kZWZzPicgOiAnJztcblxuICAgICAgdmFyIGJib3ggPSBjb250ZW50Tm9kZS5nZXRCQm94KCk7XG5cbiAgICAgIHN2ZyA9XG4gICAgICAgICc8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJ1dGYtOFwiPz5cXG4nICtcbiAgICAgICAgJzwhLS0gY3JlYXRlZCB3aXRoIGJwbW4tanMgLyBodHRwOi8vYnBtbi5pbyAtLT5cXG4nICtcbiAgICAgICAgJzwhRE9DVFlQRSBzdmcgUFVCTElDIFwiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU5cIiBcImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZFwiPlxcbicgK1xuICAgICAgICAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgJyArXG4gICAgICAgICAgICAgJ3dpZHRoPVwiJyArIGJib3gud2lkdGggKyAnXCIgaGVpZ2h0PVwiJyArIGJib3guaGVpZ2h0ICsgJ1wiICcgK1xuICAgICAgICAgICAgICd2aWV3Qm94PVwiJyArIGJib3gueCArICcgJyArIGJib3gueSArICcgJyArIGJib3gud2lkdGggKyAnICcgKyBiYm94LmhlaWdodCArICdcIiB2ZXJzaW9uPVwiMS4xXCI+JyArXG4gICAgICAgICAgZGVmcyArIGNvbnRlbnRzICtcbiAgICAgICAgJzwvc3ZnPic7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZXJyID0gZTtcbiAgICB9XG5cbiAgICBzZWxmLl9lbWl0KCdzYXZlU1ZHLmRvbmUnLCB7XG4gICAgICBlcnJvcjogZXJyLFxuICAgICAgc3ZnOiBzdmdcbiAgICB9KTtcblxuICAgIGlmICghZXJyKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZSh7IHN2Zzogc3ZnIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgfSk7XG59KTtcblxuLyoqXG4gKiBHZXQgYSBuYW1lZCBkaWFncmFtIHNlcnZpY2UuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgZWxlbWVudFJlZ2lzdHJ5ID0gdmlld2VyLmdldCgnZWxlbWVudFJlZ2lzdHJ5Jyk7XG4gKiB2YXIgc3RhcnRFdmVudFNoYXBlID0gZWxlbWVudFJlZ2lzdHJ5LmdldCgnU3RhcnRFdmVudF8xJyk7XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGRpYWdyYW0gc2VydmljZSBpbnN0YW5jZVxuICpcbiAqIEBtZXRob2QgQmFzZVZpZXdlciNnZXRcbiAqL1xuXG4vKipcbiAqIEludm9rZSBhIGZ1bmN0aW9uIGluIHRoZSBjb250ZXh0IG9mIHRoaXMgdmlld2VyLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogdmlld2VyLmludm9rZShmdW5jdGlvbihlbGVtZW50UmVnaXN0cnkpIHtcbiAqICAgdmFyIHN0YXJ0RXZlbnRTaGFwZSA9IGVsZW1lbnRSZWdpc3RyeS5nZXQoJ1N0YXJ0RXZlbnRfMScpO1xuICogfSk7XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gdG8gYmUgaW52b2tlZFxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIGZ1bmN0aW9ucyByZXR1cm4gdmFsdWVcbiAqXG4gKiBAbWV0aG9kIEJhc2VWaWV3ZXIjaW52b2tlXG4gKi9cblxuXG5CYXNlVmlld2VyLnByb3RvdHlwZS5fc2V0RGVmaW5pdGlvbnMgPSBmdW5jdGlvbihkZWZpbml0aW9ucykge1xuICB0aGlzLl9kZWZpbml0aW9ucyA9IGRlZmluaXRpb25zO1xufTtcblxuQmFzZVZpZXdlci5wcm90b3R5cGUuZ2V0TW9kdWxlcyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fbW9kdWxlcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFsbCBkcmF3biBlbGVtZW50cyBmcm9tIHRoZSB2aWV3ZXIuXG4gKlxuICogQWZ0ZXIgY2FsbGluZyB0aGlzIG1ldGhvZCB0aGUgdmlld2VyIGNhbiBzdGlsbFxuICogYmUgcmV1c2VkIGZvciBvcGVuaW5nIGFub3RoZXIgZGlhZ3JhbS5cbiAqXG4gKiBAbWV0aG9kIEJhc2VWaWV3ZXIjY2xlYXJcbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLmdldERlZmluaXRpb25zKCkpIHtcblxuICAgIC8vIG5vIGRpYWdyYW0gdG8gY2xlYXJcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyByZW1vdmUgYnVzaW5lc3NPYmplY3QjZGkgYmluZGluZ1xuICAvL1xuICAvLyB0aGlzIGlzIG5lY2Vzc2FyeSwgYXMgd2UgZXN0YWJsaXNoIHRoZSBiaW5kaW5nc1xuICAvLyBpbiB0aGUgQnBtblRyZWVXYWxrZXIgKGFuZCBhc3N1bWUgbm9uZSBhcmUgZ2l2ZW5cbiAgLy8gb24gcmVpbXBvcnQpXG4gIHRoaXMuZ2V0KCdlbGVtZW50UmVnaXN0cnknKS5mb3JFYWNoKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICB2YXIgYm8gPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgaWYgKGJvICYmIGJvLmRpKSB7XG4gICAgICBkZWxldGUgYm8uZGk7XG4gICAgfVxuICB9KTtcblxuICAvLyByZW1vdmUgZHJhd24gZWxlbWVudHNcbiAgRGlhZ3JhbS5wcm90b3R5cGUuY2xlYXIuY2FsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogRGVzdHJveSB0aGUgdmlld2VyIGluc3RhbmNlIGFuZCByZW1vdmUgYWxsIGl0c1xuICogcmVtYWluZGVycyBmcm9tIHRoZSBkb2N1bWVudCB0cmVlLlxuICovXG5CYXNlVmlld2VyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG5cbiAgLy8gZGlhZ3JhbSBkZXN0cm95XG4gIERpYWdyYW0ucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcblxuICAvLyBkb20gZGV0YWNoXG4gIGRvbVJlbW92ZSh0aGlzLl9jb250YWluZXIpO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlciBhbiBldmVudCBsaXN0ZW5lclxuICpcbiAqIFJlbW92ZSBhIHByZXZpb3VzbHkgYWRkZWQgbGlzdGVuZXIgdmlhIHtAbGluayAjb2ZmKGV2ZW50LCBjYWxsYmFjayl9LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtudW1iZXJ9IFtwcmlvcml0eV1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcGFyYW0ge09iamVjdH0gW3RoYXRdXG4gKi9cbkJhc2VWaWV3ZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24oZXZlbnQsIHByaW9yaXR5LCBjYWxsYmFjaywgdGFyZ2V0KSB7XG4gIHJldHVybiB0aGlzLmdldCgnZXZlbnRCdXMnKS5vbihldmVudCwgcHJpb3JpdHksIGNhbGxiYWNrLCB0YXJnZXQpO1xufTtcblxuLyoqXG4gKiBEZS1yZWdpc3RlciBhbiBldmVudCBsaXN0ZW5lclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gIHRoaXMuZ2V0KCdldmVudEJ1cycpLm9mZihldmVudCwgY2FsbGJhY2spO1xufTtcblxuQmFzZVZpZXdlci5wcm90b3R5cGUuYXR0YWNoVG8gPSBmdW5jdGlvbihwYXJlbnROb2RlKSB7XG5cbiAgaWYgKCFwYXJlbnROb2RlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwYXJlbnROb2RlIHJlcXVpcmVkJyk7XG4gIH1cblxuICAvLyBlbnN1cmUgd2UgZGV0YWNoIGZyb20gdGhlXG4gIC8vIHByZXZpb3VzLCBvbGQgcGFyZW50XG4gIHRoaXMuZGV0YWNoKCk7XG5cbiAgLy8gdW53cmFwIGpRdWVyeSBpZiBwcm92aWRlZFxuICBpZiAocGFyZW50Tm9kZS5nZXQgJiYgcGFyZW50Tm9kZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUuanF1ZXJ5KSB7XG4gICAgcGFyZW50Tm9kZSA9IHBhcmVudE5vZGUuZ2V0KDApO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJlbnROb2RlID09PSAnc3RyaW5nJykge1xuICAgIHBhcmVudE5vZGUgPSBkb21RdWVyeShwYXJlbnROb2RlKTtcbiAgfVxuXG4gIHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcy5fY29udGFpbmVyKTtcblxuICB0aGlzLl9lbWl0KCdhdHRhY2gnLCB7fSk7XG5cbiAgdGhpcy5nZXQoJ2NhbnZhcycpLnJlc2l6ZWQoKTtcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLmdldERlZmluaXRpb25zID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9kZWZpbml0aW9ucztcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLmRldGFjaCA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBjb250YWluZXIgPSB0aGlzLl9jb250YWluZXIsXG4gICAgICBwYXJlbnROb2RlID0gY29udGFpbmVyLnBhcmVudE5vZGU7XG5cbiAgaWYgKCFwYXJlbnROb2RlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fZW1pdCgnZGV0YWNoJywge30pO1xuXG4gIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY29udGFpbmVyKTtcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24oY29udGFpbmVyLCBtb2RkbGUsIG9wdGlvbnMpIHtcblxuICB2YXIgYmFzZU1vZHVsZXMgPSBvcHRpb25zLm1vZHVsZXMgfHwgdGhpcy5nZXRNb2R1bGVzKCksXG4gICAgICBhZGRpdGlvbmFsTW9kdWxlcyA9IG9wdGlvbnMuYWRkaXRpb25hbE1vZHVsZXMgfHwgW10sXG4gICAgICBzdGF0aWNNb2R1bGVzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYnBtbmpzOiBbICd2YWx1ZScsIHRoaXMgXSxcbiAgICAgICAgICBtb2RkbGU6IFsgJ3ZhbHVlJywgbW9kZGxlIF1cbiAgICAgICAgfVxuICAgICAgXTtcblxuICB2YXIgZGlhZ3JhbU1vZHVsZXMgPSBbXS5jb25jYXQoc3RhdGljTW9kdWxlcywgYmFzZU1vZHVsZXMsIGFkZGl0aW9uYWxNb2R1bGVzKTtcblxuICB2YXIgZGlhZ3JhbU9wdGlvbnMgPSBhc3NpZ24ob21pdChvcHRpb25zLCBbICdhZGRpdGlvbmFsTW9kdWxlcycgXSksIHtcbiAgICBjYW52YXM6IGFzc2lnbih7fSwgb3B0aW9ucy5jYW52YXMsIHsgY29udGFpbmVyOiBjb250YWluZXIgfSksXG4gICAgbW9kdWxlczogZGlhZ3JhbU1vZHVsZXNcbiAgfSk7XG5cbiAgLy8gaW52b2tlIGRpYWdyYW0gY29uc3RydWN0b3JcbiAgRGlhZ3JhbS5jYWxsKHRoaXMsIGRpYWdyYW1PcHRpb25zKTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmNvbnRhaW5lcikge1xuICAgIHRoaXMuYXR0YWNoVG8ob3B0aW9ucy5jb250YWluZXIpO1xuICB9XG59O1xuXG4vKipcbiAqIEVtaXQgYW4gZXZlbnQgb24gdGhlIHVuZGVybHlpbmcge0BsaW5rIEV2ZW50QnVzfVxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gdHlwZVxuICogQHBhcmFtICB7T2JqZWN0fSBldmVudFxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gZXZlbnQgcHJvY2Vzc2luZyByZXN1bHQgKGlmIGFueSlcbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUuX2VtaXQgPSBmdW5jdGlvbih0eXBlLCBldmVudCkge1xuICByZXR1cm4gdGhpcy5nZXQoJ2V2ZW50QnVzJykuZmlyZSh0eXBlLCBldmVudCk7XG59O1xuXG5CYXNlVmlld2VyLnByb3RvdHlwZS5fY3JlYXRlQ29udGFpbmVyID0gZnVuY3Rpb24ob3B0aW9ucykge1xuXG4gIHZhciBjb250YWluZXIgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJianMtY29udGFpbmVyXCI+PC9kaXY+Jyk7XG5cbiAgYXNzaWduKGNvbnRhaW5lci5zdHlsZSwge1xuICAgIHdpZHRoOiBlbnN1cmVVbml0KG9wdGlvbnMud2lkdGgpLFxuICAgIGhlaWdodDogZW5zdXJlVW5pdChvcHRpb25zLmhlaWdodCksXG4gICAgcG9zaXRpb246IG9wdGlvbnMucG9zaXRpb25cbiAgfSk7XG5cbiAgcmV0dXJuIGNvbnRhaW5lcjtcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLl9jcmVhdGVNb2RkbGUgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gIHZhciBtb2RkbGVPcHRpb25zID0gYXNzaWduKHt9LCB0aGlzLl9tb2RkbGVFeHRlbnNpb25zLCBvcHRpb25zLm1vZGRsZUV4dGVuc2lvbnMpO1xuXG4gIHJldHVybiBuZXcgQnBtbk1vZGRsZShtb2RkbGVPcHRpb25zKTtcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLl9tb2R1bGVzID0gW107XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGFkZFdhcm5pbmdzVG9FcnJvcihlcnIsIHdhcm5pbmdzQXJ5KSB7XG4gIGVyci53YXJuaW5ncyA9IHdhcm5pbmdzQXJ5O1xuICByZXR1cm4gZXJyO1xufVxuXG5mdW5jdGlvbiBjaGVja1ZhbGlkYXRpb25FcnJvcihlcnIpIHtcblxuICAvLyBjaGVjayBpZiB3ZSBjYW4gaGVscCB0aGUgdXNlciBieSBpbmRpY2F0aW5nIHdyb25nIEJQTU4gMi4wIHhtbFxuICAvLyAoaW4gY2FzZSBoZSBvciB0aGUgZXhwb3J0aW5nIHRvb2wgZGlkIG5vdCBnZXQgdGhhdCByaWdodClcblxuICB2YXIgcGF0dGVybiA9IC91bnBhcnNhYmxlIGNvbnRlbnQgPChbXj5dKyk+IGRldGVjdGVkKFtcXHNcXFNdKikkLztcbiAgdmFyIG1hdGNoID0gcGF0dGVybi5leGVjKGVyci5tZXNzYWdlKTtcblxuICBpZiAobWF0Y2gpIHtcbiAgICBlcnIubWVzc2FnZSA9XG4gICAgICAndW5wYXJzYWJsZSBjb250ZW50IDwnICsgbWF0Y2hbMV0gKyAnPiBkZXRlY3RlZDsgJyArXG4gICAgICAndGhpcyBtYXkgaW5kaWNhdGUgYW4gaW52YWxpZCBCUE1OIDIuMCBkaWFncmFtIGZpbGUnICsgbWF0Y2hbMl07XG4gIH1cblxuICByZXR1cm4gZXJyO1xufVxuXG52YXIgREVGQVVMVF9PUFRJT05TID0ge1xuICB3aWR0aDogJzEwMCUnLFxuICBoZWlnaHQ6ICcxMDAlJyxcbiAgcG9zaXRpb246ICdyZWxhdGl2ZSdcbn07XG5cblxuLyoqXG4gKiBFbnN1cmUgdGhlIHBhc3NlZCBhcmd1bWVudCBpcyBhIHByb3BlciB1bml0IChkZWZhdWx0aW5nIHRvIHB4KVxuICovXG5mdW5jdGlvbiBlbnN1cmVVbml0KHZhbCkge1xuICByZXR1cm4gdmFsICsgKGlzTnVtYmVyKHZhbCkgPyAncHgnIDogJycpO1xufVxuXG5cbi8qKlxuICogRmluZCBCUE1ORGlhZ3JhbSBpbiBkZWZpbml0aW9ucyBieSBJRFxuICpcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxEZWZpbml0aW9ucz59IGRlZmluaXRpb25zXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlhZ3JhbUlkXG4gKlxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudDxCUE1ORGlhZ3JhbT58bnVsbH1cbiAqL1xuZnVuY3Rpb24gZmluZEJQTU5EaWFncmFtKGRlZmluaXRpb25zLCBkaWFncmFtSWQpIHtcbiAgaWYgKCFkaWFncmFtSWQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBmaW5kKGRlZmluaXRpb25zLmRpYWdyYW1zLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQuaWQgPT09IGRpYWdyYW1JZDtcbiAgfSkgfHwgbnVsbDtcbn1cblxuXG4vKiA8cHJvamVjdC1sb2dvPiAqL1xuXG5pbXBvcnQge1xuICBvcGVuIGFzIG9wZW5Qb3dlcmVkQnksXG4gIEJQTU5JT19JTUcsXG4gIExJTktfU1RZTEVTIGFzIEJQTU5JT19MSU5LX1NUWUxFU1xufSBmcm9tICcuL3V0aWwvUG93ZXJlZEJ5VXRpbCc7XG5cbmltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50XG59IGZyb20gJ21pbi1kb20nO1xuXG4vKipcbiAqIEFkZHMgdGhlIHByb2plY3QgbG9nbyB0byB0aGUgZGlhZ3JhbSBjb250YWluZXIgYXNcbiAqIHJlcXVpcmVkIGJ5IHRoZSBicG1uLmlvIGxpY2Vuc2UuXG4gKlxuICogQHNlZSBodHRwOi8vYnBtbi5pby9saWNlbnNlXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBjb250YWluZXJcbiAqL1xuZnVuY3Rpb24gYWRkUHJvamVjdExvZ28oY29udGFpbmVyKSB7XG4gIHZhciBpbWcgPSBCUE1OSU9fSU1HO1xuXG4gIHZhciBsaW5rTWFya3VwID1cbiAgICAnPGEgaHJlZj1cImh0dHA6Ly9icG1uLmlvXCIgJyArXG4gICAgICAgJ3RhcmdldD1cIl9ibGFua1wiICcgK1xuICAgICAgICdjbGFzcz1cImJqcy1wb3dlcmVkLWJ5XCIgJyArXG4gICAgICAgJ3RpdGxlPVwiUG93ZXJlZCBieSBicG1uLmlvXCIgJyArXG4gICAgICAgJ3N0eWxlPVwicG9zaXRpb246IGFic29sdXRlOyBib3R0b206IDE1cHg7IHJpZ2h0OiAxNXB4OyB6LWluZGV4OiAxMDA7ICcgKyBCUE1OSU9fTElOS19TVFlMRVMgKyAnXCI+JyArXG4gICAgICBpbWcgK1xuICAgICc8L2E+JztcblxuICB2YXIgbGlua0VsZW1lbnQgPSBkb21pZnkobGlua01hcmt1cCk7XG5cbiAgY29udGFpbmVyLmFwcGVuZENoaWxkKGxpbmtFbGVtZW50KTtcblxuICBkb21FdmVudC5iaW5kKGxpbmtFbGVtZW50LCAnY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgIG9wZW5Qb3dlcmVkQnkoKTtcblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH0pO1xufVxuXG4vKiA8L3Byb2plY3QtbG9nbz4gKi9cbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBCYXNlTW9kZWxlciBmcm9tICcuL0Jhc2VNb2RlbGVyJztcblxuaW1wb3J0IFZpZXdlciBmcm9tICcuL1ZpZXdlcic7XG5pbXBvcnQgTmF2aWdhdGVkVmlld2VyIGZyb20gJy4vTmF2aWdhdGVkVmlld2VyJztcblxuaW1wb3J0IEtleWJvYXJkTW92ZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL2tleWJvYXJkLW1vdmUnO1xuaW1wb3J0IE1vdmVDYW52YXNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvbmF2aWdhdGlvbi9tb3ZlY2FudmFzJztcbmltcG9ydCBUb3VjaE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL3RvdWNoJztcbmltcG9ydCBab29tU2Nyb2xsTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL25hdmlnYXRpb24vem9vbXNjcm9sbCc7XG5cbmltcG9ydCBBbGlnbkVsZW1lbnRzTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2FsaWduLWVsZW1lbnRzJztcbmltcG9ydCBBdXRvUGxhY2VNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9hdXRvLXBsYWNlJztcbmltcG9ydCBBdXRvUmVzaXplTW9kdWxlIGZyb20gJy4vZmVhdHVyZXMvYXV0by1yZXNpemUnO1xuaW1wb3J0IEF1dG9TY3JvbGxNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1zY3JvbGwnO1xuaW1wb3J0IEJlbmRwb2ludHNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYmVuZHBvaW50cyc7XG5pbXBvcnQgQ29ubmVjdE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jb25uZWN0JztcbmltcG9ydCBDb25uZWN0aW9uUHJldmlld01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jb25uZWN0aW9uLXByZXZpZXcnO1xuaW1wb3J0IENvbnRleHRQYWRNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9jb250ZXh0LXBhZCc7XG5pbXBvcnQgQ29weVBhc3RlTW9kdWxlIGZyb20gJy4vZmVhdHVyZXMvY29weS1wYXN0ZSc7XG5pbXBvcnQgQ3JlYXRlTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NyZWF0ZSc7XG5pbXBvcnQgRGlzdHJpYnV0ZUVsZW1lbnRzTW9kdWxlIGZyb20gJy4vZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cyc7XG5pbXBvcnQgRWRpdG9yQWN0aW9uc01vZHVsZSBmcm9tICcuL2ZlYXR1cmVzL2VkaXRvci1hY3Rpb25zJztcbmltcG9ydCBHcmlkU25hcHBpbmdNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nJztcbmltcG9ydCBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSBmcm9tICcuL2ZlYXR1cmVzL2ludGVyYWN0aW9uLWV2ZW50cyc7XG5pbXBvcnQgS2V5Ym9hcmRNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9rZXlib2FyZCc7XG5pbXBvcnQgS2V5Ym9hcmRNb3ZlU2VsZWN0aW9uTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2tleWJvYXJkLW1vdmUtc2VsZWN0aW9uJztcbmltcG9ydCBMYWJlbEVkaXRpbmdNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9sYWJlbC1lZGl0aW5nJztcbmltcG9ydCBNb2RlbGluZ01vZHVsZSBmcm9tICcuL2ZlYXR1cmVzL21vZGVsaW5nJztcbmltcG9ydCBNb3ZlTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdmUnO1xuaW1wb3J0IFBhbGV0dGVNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9wYWxldHRlJztcbmltcG9ydCBSZXBsYWNlUHJldmlld01vZHVsZSBmcm9tICcuL2ZlYXR1cmVzL3JlcGxhY2UtcHJldmlldyc7XG5pbXBvcnQgUmVzaXplTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Jlc2l6ZSc7XG5pbXBvcnQgU25hcHBpbmdNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9zbmFwcGluZyc7XG5pbXBvcnQgU2VhcmNoTW9kdWxlIGZyb20gJy4vZmVhdHVyZXMvc2VhcmNoJztcblxuaW1wb3J0IHtcbiAgd3JhcEZvckNvbXBhdGliaWxpdHlcbn0gZnJvbSAnLi91dGlsL0NvbXBhdGliaWxpdHlVdGlsJztcblxudmFyIGluaXRpYWxEaWFncmFtID1cbiAgJzw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCI/PicgK1xuICAnPGJwbW46ZGVmaW5pdGlvbnMgeG1sbnM6eHNpPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2VcIiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ3htbG5zOmJwbW49XCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9CUE1OLzIwMTAwNTI0L01PREVMXCIgJyArXG4gICAgICAgICAgICAgICAgICAgICd4bWxuczpicG1uZGk9XCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9CUE1OLzIwMTAwNTI0L0RJXCIgJyArXG4gICAgICAgICAgICAgICAgICAgICd4bWxuczpkYz1cImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0RELzIwMTAwNTI0L0RDXCIgJyArXG4gICAgICAgICAgICAgICAgICAgICd0YXJnZXROYW1lc3BhY2U9XCJodHRwOi8vYnBtbi5pby9zY2hlbWEvYnBtblwiICcgK1xuICAgICAgICAgICAgICAgICAgICAnaWQ9XCJEZWZpbml0aW9uc18xXCI+JyArXG4gICAgJzxicG1uOnByb2Nlc3MgaWQ9XCJQcm9jZXNzXzFcIiBpc0V4ZWN1dGFibGU9XCJmYWxzZVwiPicgK1xuICAgICAgJzxicG1uOnN0YXJ0RXZlbnQgaWQ9XCJTdGFydEV2ZW50XzFcIi8+JyArXG4gICAgJzwvYnBtbjpwcm9jZXNzPicgK1xuICAgICc8YnBtbmRpOkJQTU5EaWFncmFtIGlkPVwiQlBNTkRpYWdyYW1fMVwiPicgK1xuICAgICAgJzxicG1uZGk6QlBNTlBsYW5lIGlkPVwiQlBNTlBsYW5lXzFcIiBicG1uRWxlbWVudD1cIlByb2Nlc3NfMVwiPicgK1xuICAgICAgICAnPGJwbW5kaTpCUE1OU2hhcGUgaWQ9XCJfQlBNTlNoYXBlX1N0YXJ0RXZlbnRfMlwiIGJwbW5FbGVtZW50PVwiU3RhcnRFdmVudF8xXCI+JyArXG4gICAgICAgICAgJzxkYzpCb3VuZHMgaGVpZ2h0PVwiMzYuMFwiIHdpZHRoPVwiMzYuMFwiIHg9XCIxNzMuMFwiIHk9XCIxMDIuMFwiLz4nICtcbiAgICAgICAgJzwvYnBtbmRpOkJQTU5TaGFwZT4nICtcbiAgICAgICc8L2JwbW5kaTpCUE1OUGxhbmU+JyArXG4gICAgJzwvYnBtbmRpOkJQTU5EaWFncmFtPicgK1xuICAnPC9icG1uOmRlZmluaXRpb25zPic7XG5cblxuLyoqXG4gKiBBIG1vZGVsZXIgZm9yIEJQTU4gMi4wIGRpYWdyYW1zLlxuICpcbiAqXG4gKiAjIyBFeHRlbmRpbmcgdGhlIE1vZGVsZXJcbiAqXG4gKiBJbiBvcmRlciB0byBleHRlbmQgdGhlIHZpZXdlciBwYXNzIGV4dGVuc2lvbiBtb2R1bGVzIHRvIGJvb3RzdHJhcCB2aWEgdGhlXG4gKiBgYWRkaXRpb25hbE1vZHVsZXNgIG9wdGlvbi4gQW4gZXh0ZW5zaW9uIG1vZHVsZSBpcyBhbiBvYmplY3QgdGhhdCBleHBvc2VzXG4gKiBuYW1lZCBzZXJ2aWNlcy5cbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgZGVwaWN0cyB0aGUgaW50ZWdyYXRpb24gb2YgYSBzaW1wbGVcbiAqIGxvZ2dpbmcgY29tcG9uZW50IHRoYXQgaW50ZWdyYXRlcyB3aXRoIGludGVyYWN0aW9uIGV2ZW50czpcbiAqXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICpcbiAqIC8vIGxvZ2dpbmcgY29tcG9uZW50XG4gKiBmdW5jdGlvbiBJbnRlcmFjdGlvbkxvZ2dlcihldmVudEJ1cykge1xuICogICBldmVudEJ1cy5vbignZWxlbWVudC5ob3ZlcicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gKiAgICAgY29uc29sZS5sb2coKVxuICogICB9KVxuICogfVxuICpcbiAqIEludGVyYWN0aW9uTG9nZ2VyLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTsgLy8gbWluaWZpY2F0aW9uIHNhdmVcbiAqXG4gKiAvLyBleHRlbnNpb24gbW9kdWxlXG4gKiB2YXIgZXh0ZW5zaW9uTW9kdWxlID0ge1xuICogICBfX2luaXRfXzogWyAnaW50ZXJhY3Rpb25Mb2dnZXInIF0sXG4gKiAgIGludGVyYWN0aW9uTG9nZ2VyOiBbICd0eXBlJywgSW50ZXJhY3Rpb25Mb2dnZXIgXVxuICogfTtcbiAqXG4gKiAvLyBleHRlbmQgdGhlIHZpZXdlclxuICogdmFyIGJwbW5Nb2RlbGVyID0gbmV3IE1vZGVsZXIoeyBhZGRpdGlvbmFsTW9kdWxlczogWyBleHRlbnNpb25Nb2R1bGUgXSB9KTtcbiAqIGJwbW5Nb2RlbGVyLmltcG9ydFhNTCguLi4pO1xuICogYGBgXG4gKlxuICpcbiAqICMjIEN1c3RvbWl6aW5nIC8gUmVwbGFjaW5nIENvbXBvbmVudHNcbiAqXG4gKiBZb3UgY2FuIHJlcGxhY2UgaW5kaXZpZHVhbCBkaWFncmFtIGNvbXBvbmVudHMgYnkgcmVkZWZpbmluZyB0aGVtIGluIG92ZXJyaWRlIG1vZHVsZXMuXG4gKiBUaGlzIHdvcmtzIGZvciBhbGwgY29tcG9uZW50cywgaW5jbHVkaW5nIHRob3NlIGRlZmluZWQgaW4gdGhlIGNvcmUuXG4gKlxuICogUGFzcyBpbiBvdmVycmlkZSBtb2R1bGVzIHZpYSB0aGUgYG9wdGlvbnMuYWRkaXRpb25hbE1vZHVsZXNgIGZsYWcgbGlrZSB0aGlzOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGZ1bmN0aW9uIEN1c3RvbUNvbnRleHRQYWRQcm92aWRlcihjb250ZXh0UGFkKSB7XG4gKlxuICogICBjb250ZXh0UGFkLnJlZ2lzdGVyUHJvdmlkZXIodGhpcyk7XG4gKlxuICogICB0aGlzLmdldENvbnRleHRQYWRFbnRyaWVzID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICogICAgIC8vIG5vIGVudHJpZXMsIGVmZmVjdGl2ZWx5IGRpc2FibGUgdGhlIGNvbnRleHQgcGFkXG4gKiAgICAgcmV0dXJuIHt9O1xuICogICB9O1xuICogfVxuICpcbiAqIEN1c3RvbUNvbnRleHRQYWRQcm92aWRlci4kaW5qZWN0ID0gWyAnY29udGV4dFBhZCcgXTtcbiAqXG4gKiB2YXIgb3ZlcnJpZGVNb2R1bGUgPSB7XG4gKiAgIGNvbnRleHRQYWRQcm92aWRlcjogWyAndHlwZScsIEN1c3RvbUNvbnRleHRQYWRQcm92aWRlciBdXG4gKiB9O1xuICpcbiAqIHZhciBicG1uTW9kZWxlciA9IG5ldyBNb2RlbGVyKHsgYWRkaXRpb25hbE1vZHVsZXM6IFsgb3ZlcnJpZGVNb2R1bGUgXX0pO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gcGFzcyB0byB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IFtvcHRpb25zLmNvbnRhaW5lcl0gdGhlIGNvbnRhaW5lciB0byByZW5kZXIgdGhlIHZpZXdlciBpbiwgZGVmYXVsdHMgdG8gYm9keS5cbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gW29wdGlvbnMud2lkdGhdIHRoZSB3aWR0aCBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IFtvcHRpb25zLmhlaWdodF0gdGhlIGhlaWdodCBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMubW9kZGxlRXh0ZW5zaW9uc10gZXh0ZW5zaW9uIHBhY2thZ2VzIHRvIHByb3ZpZGVcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5tb2R1bGVzXSBhIGxpc3Qgb2YgbW9kdWxlcyB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCBtb2R1bGVzXG4gKiBAcGFyYW0ge0FycmF5PGRpZGkuTW9kdWxlPn0gW29wdGlvbnMuYWRkaXRpb25hbE1vZHVsZXNdIGEgbGlzdCBvZiBtb2R1bGVzIHRvIHVzZSB3aXRoIHRoZSBkZWZhdWx0IG1vZHVsZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW9kZWxlcihvcHRpb25zKSB7XG4gIEJhc2VNb2RlbGVyLmNhbGwodGhpcywgb3B0aW9ucyk7XG59XG5cbmluaGVyaXRzKE1vZGVsZXIsIEJhc2VNb2RlbGVyKTtcblxuXG5Nb2RlbGVyLlZpZXdlciA9IFZpZXdlcjtcbk1vZGVsZXIuTmF2aWdhdGVkVmlld2VyID0gTmF2aWdhdGVkVmlld2VyO1xuXG4vKipcbiogVGhlIGNyZWF0ZURpYWdyYW0gcmVzdWx0LlxuKlxuKiBAdHlwZWRlZiB7T2JqZWN0fSBDcmVhdGVEaWFncmFtUmVzdWx0XG4qXG4qIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gd2FybmluZ3NcbiovXG5cbi8qKlxuKiBUaGUgY3JlYXRlRGlhZ3JhbSBlcnJvci5cbipcbiogQHR5cGVkZWYge0Vycm9yfSBDcmVhdGVEaWFncmFtRXJyb3JcbipcbiogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuKi9cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgZGlhZ3JhbSB0byBzdGFydCBtb2RlbGluZy5cbiAqXG4gKiBSZXR1cm5zIHtQcm9taXNlPENyZWF0ZURpYWdyYW1SZXN1bHQsIENyZWF0ZURpYWdyYW1FcnJvcj59XG4gKi9cbk1vZGVsZXIucHJvdG90eXBlLmNyZWF0ZURpYWdyYW0gPSB3cmFwRm9yQ29tcGF0aWJpbGl0eShmdW5jdGlvbiBjcmVhdGVEaWFncmFtKCkge1xuICByZXR1cm4gdGhpcy5pbXBvcnRYTUwoaW5pdGlhbERpYWdyYW0pO1xufSk7XG5cblxuTW9kZWxlci5wcm90b3R5cGUuX2ludGVyYWN0aW9uTW9kdWxlcyA9IFtcblxuICAvLyBub24tbW9kZWxpbmcgY29tcG9uZW50c1xuICBLZXlib2FyZE1vdmVNb2R1bGUsXG4gIE1vdmVDYW52YXNNb2R1bGUsXG4gIFRvdWNoTW9kdWxlLFxuICBab29tU2Nyb2xsTW9kdWxlXG5dO1xuXG5Nb2RlbGVyLnByb3RvdHlwZS5fbW9kZWxpbmdNb2R1bGVzID0gW1xuXG4gIC8vIG1vZGVsaW5nIGNvbXBvbmVudHNcbiAgQWxpZ25FbGVtZW50c01vZHVsZSxcbiAgQXV0b1BsYWNlTW9kdWxlLFxuICBBdXRvU2Nyb2xsTW9kdWxlLFxuICBBdXRvUmVzaXplTW9kdWxlLFxuICBCZW5kcG9pbnRzTW9kdWxlLFxuICBDb25uZWN0TW9kdWxlLFxuICBDb25uZWN0aW9uUHJldmlld01vZHVsZSxcbiAgQ29udGV4dFBhZE1vZHVsZSxcbiAgQ29weVBhc3RlTW9kdWxlLFxuICBDcmVhdGVNb2R1bGUsXG4gIERpc3RyaWJ1dGVFbGVtZW50c01vZHVsZSxcbiAgRWRpdG9yQWN0aW9uc01vZHVsZSxcbiAgR3JpZFNuYXBwaW5nTW9kdWxlLFxuICBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSxcbiAgS2V5Ym9hcmRNb2R1bGUsXG4gIEtleWJvYXJkTW92ZVNlbGVjdGlvbk1vZHVsZSxcbiAgTGFiZWxFZGl0aW5nTW9kdWxlLFxuICBNb2RlbGluZ01vZHVsZSxcbiAgTW92ZU1vZHVsZSxcbiAgUGFsZXR0ZU1vZHVsZSxcbiAgUmVwbGFjZVByZXZpZXdNb2R1bGUsXG4gIFJlc2l6ZU1vZHVsZSxcbiAgU25hcHBpbmdNb2R1bGUsXG4gIFNlYXJjaE1vZHVsZVxuXTtcblxuXG4vLyBtb2R1bGVzIHRoZSBtb2RlbGVyIGlzIGNvbXBvc2VkIG9mXG4vL1xuLy8gLSB2aWV3ZXIgbW9kdWxlc1xuLy8gLSBpbnRlcmFjdGlvbiBtb2R1bGVzXG4vLyAtIG1vZGVsaW5nIG1vZHVsZXNcblxuTW9kZWxlci5wcm90b3R5cGUuX21vZHVsZXMgPSBbXS5jb25jYXQoXG4gIFZpZXdlci5wcm90b3R5cGUuX21vZHVsZXMsXG4gIE1vZGVsZXIucHJvdG90eXBlLl9pbnRlcmFjdGlvbk1vZHVsZXMsXG4gIE1vZGVsZXIucHJvdG90eXBlLl9tb2RlbGluZ01vZHVsZXNcbik7XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgVmlld2VyIGZyb20gJy4vVmlld2VyJztcblxuaW1wb3J0IEtleWJvYXJkTW92ZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL2tleWJvYXJkLW1vdmUnO1xuaW1wb3J0IE1vdmVDYW52YXNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvbmF2aWdhdGlvbi9tb3ZlY2FudmFzJztcbmltcG9ydCBab29tU2Nyb2xsTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL25hdmlnYXRpb24vem9vbXNjcm9sbCc7XG5cblxuLyoqXG4gKiBBIHZpZXdlciB0aGF0IGluY2x1ZGVzIG1vdXNlIG5hdmlnYXRpb24gZmFjaWxpdGllc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE5hdmlnYXRlZFZpZXdlcihvcHRpb25zKSB7XG4gIFZpZXdlci5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5pbmhlcml0cyhOYXZpZ2F0ZWRWaWV3ZXIsIFZpZXdlcik7XG5cblxuTmF2aWdhdGVkVmlld2VyLnByb3RvdHlwZS5fbmF2aWdhdGlvbk1vZHVsZXMgPSBbXG4gIEtleWJvYXJkTW92ZU1vZHVsZSxcbiAgTW92ZUNhbnZhc01vZHVsZSxcbiAgWm9vbVNjcm9sbE1vZHVsZVxuXTtcblxuTmF2aWdhdGVkVmlld2VyLnByb3RvdHlwZS5fbW9kdWxlcyA9IFtdLmNvbmNhdChcbiAgVmlld2VyLnByb3RvdHlwZS5fbW9kdWxlcyxcbiAgTmF2aWdhdGVkVmlld2VyLnByb3RvdHlwZS5fbmF2aWdhdGlvbk1vZHVsZXNcbik7IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvcmVNb2R1bGUgZnJvbSAnLi9jb3JlJztcbmltcG9ydCBUcmFuc2xhdGVNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zZWxlY3Rpb24nO1xuaW1wb3J0IE92ZXJsYXlzTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL292ZXJsYXlzJztcblxuaW1wb3J0IEJhc2VWaWV3ZXIgZnJvbSAnLi9CYXNlVmlld2VyJztcblxuXG4vKipcbiAqIEEgdmlld2VyIGZvciBCUE1OIDIuMCBkaWFncmFtcy5cbiAqXG4gKiBIYXZlIGEgbG9vayBhdCB7QGxpbmsgTmF2aWdhdGVkVmlld2VyfSBvciB7QGxpbmsgTW9kZWxlcn0gZm9yIGJ1bmRsZXMgdGhhdCBpbmNsdWRlXG4gKiBhZGRpdGlvbmFsIGZlYXR1cmVzLlxuICpcbiAqXG4gKiAjIyBFeHRlbmRpbmcgdGhlIFZpZXdlclxuICpcbiAqIEluIG9yZGVyIHRvIGV4dGVuZCB0aGUgdmlld2VyIHBhc3MgZXh0ZW5zaW9uIG1vZHVsZXMgdG8gYm9vdHN0cmFwIHZpYSB0aGVcbiAqIGBhZGRpdGlvbmFsTW9kdWxlc2Agb3B0aW9uLiBBbiBleHRlbnNpb24gbW9kdWxlIGlzIGFuIG9iamVjdCB0aGF0IGV4cG9zZXNcbiAqIG5hbWVkIHNlcnZpY2VzLlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBkZXBpY3RzIHRoZSBpbnRlZ3JhdGlvbiBvZiBhIHNpbXBsZVxuICogbG9nZ2luZyBjb21wb25lbnQgdGhhdCBpbnRlZ3JhdGVzIHdpdGggaW50ZXJhY3Rpb24gZXZlbnRzOlxuICpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKlxuICogLy8gbG9nZ2luZyBjb21wb25lbnRcbiAqIGZ1bmN0aW9uIEludGVyYWN0aW9uTG9nZ2VyKGV2ZW50QnVzKSB7XG4gKiAgIGV2ZW50QnVzLm9uKCdlbGVtZW50LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgICBjb25zb2xlLmxvZygpXG4gKiAgIH0pXG4gKiB9XG4gKlxuICogSW50ZXJhY3Rpb25Mb2dnZXIuJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdOyAvLyBtaW5pZmljYXRpb24gc2F2ZVxuICpcbiAqIC8vIGV4dGVuc2lvbiBtb2R1bGVcbiAqIHZhciBleHRlbnNpb25Nb2R1bGUgPSB7XG4gKiAgIF9faW5pdF9fOiBbICdpbnRlcmFjdGlvbkxvZ2dlcicgXSxcbiAqICAgaW50ZXJhY3Rpb25Mb2dnZXI6IFsgJ3R5cGUnLCBJbnRlcmFjdGlvbkxvZ2dlciBdXG4gKiB9O1xuICpcbiAqIC8vIGV4dGVuZCB0aGUgdmlld2VyXG4gKiB2YXIgYnBtblZpZXdlciA9IG5ldyBWaWV3ZXIoeyBhZGRpdGlvbmFsTW9kdWxlczogWyBleHRlbnNpb25Nb2R1bGUgXSB9KTtcbiAqIGJwbW5WaWV3ZXIuaW1wb3J0WE1MKC4uLik7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBwYXNzIHRvIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gW29wdGlvbnMuY29udGFpbmVyXSB0aGUgY29udGFpbmVyIHRvIHJlbmRlciB0aGUgdmlld2VyIGluLCBkZWZhdWx0cyB0byBib2R5LlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBbb3B0aW9ucy53aWR0aF0gdGhlIHdpZHRoIG9mIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gW29wdGlvbnMuaGVpZ2h0XSB0aGUgaGVpZ2h0IG9mIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5tb2RkbGVFeHRlbnNpb25zXSBleHRlbnNpb24gcGFja2FnZXMgdG8gcHJvdmlkZVxuICogQHBhcmFtIHtBcnJheTxkaWRpLk1vZHVsZT59IFtvcHRpb25zLm1vZHVsZXNdIGEgbGlzdCBvZiBtb2R1bGVzIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IG1vZHVsZXNcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5hZGRpdGlvbmFsTW9kdWxlc10gYSBsaXN0IG9mIG1vZHVsZXMgdG8gdXNlIHdpdGggdGhlIGRlZmF1bHQgbW9kdWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBWaWV3ZXIob3B0aW9ucykge1xuICBCYXNlVmlld2VyLmNhbGwodGhpcywgb3B0aW9ucyk7XG59XG5cbmluaGVyaXRzKFZpZXdlciwgQmFzZVZpZXdlcik7XG5cbi8vIG1vZHVsZXMgdGhlIHZpZXdlciBpcyBjb21wb3NlZCBvZlxuVmlld2VyLnByb3RvdHlwZS5fbW9kdWxlcyA9IFtcbiAgQ29yZU1vZHVsZSxcbiAgVHJhbnNsYXRlTW9kdWxlLFxuICBTZWxlY3Rpb25Nb2R1bGUsXG4gIE92ZXJsYXlzTW9kdWxlXG5dO1xuXG4vLyBkZWZhdWx0IG1vZGRsZSBleHRlbnNpb25zIHRoZSB2aWV3ZXIgaXMgY29tcG9zZWQgb2ZcblZpZXdlci5wcm90b3R5cGUuX21vZGRsZUV4dGVuc2lvbnMgPSB7fTsiLCJpbXBvcnQgRHJhd01vZHVsZSBmcm9tICcuLi9kcmF3JztcbmltcG9ydCBJbXBvcnRNb2R1bGUgZnJvbSAnLi4vaW1wb3J0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIERyYXdNb2R1bGUsXG4gICAgSW1wb3J0TW9kdWxlXG4gIF1cbn07IiwiaW1wb3J0IHtcbiAgZXZlcnksXG4gIHNvbWVcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBjb21wb25lbnRzVG9QYXRoXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvUmVuZGVyVXRpbCc7XG5cblxuLy8gZWxlbWVudCB1dGlscyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQ2hlY2tzIGlmIGV2ZW50RGVmaW5pdGlvbiBvZiB0aGUgZ2l2ZW4gZWxlbWVudCBtYXRjaGVzIHdpdGggc2VtYW50aWMgdHlwZS5cbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIGVsZW1lbnQgaXMgb2YgdGhlIGdpdmVuIHNlbWFudGljIHR5cGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVHlwZWRFdmVudChldmVudCwgZXZlbnREZWZpbml0aW9uVHlwZSwgZmlsdGVyKSB7XG5cbiAgZnVuY3Rpb24gbWF0Y2hlcyhkZWZpbml0aW9uLCBmaWx0ZXIpIHtcbiAgICByZXR1cm4gZXZlcnkoZmlsdGVyLCBmdW5jdGlvbih2YWwsIGtleSkge1xuXG4gICAgICAvLyB3ZSB3YW50IGEgPT0gY29udmVyc2lvbiBoZXJlLCB0byBiZSBhYmxlIHRvIGNhdGNoXG4gICAgICAvLyB1bmRlZmluZWQgPT0gZmFsc2UgYW5kIGZyaWVuZHNcbiAgICAgIC8qIGpzaGludCAtVzExNiAqL1xuICAgICAgcmV0dXJuIGRlZmluaXRpb25ba2V5XSA9PSB2YWw7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gc29tZShldmVudC5ldmVudERlZmluaXRpb25zLCBmdW5jdGlvbihkZWZpbml0aW9uKSB7XG4gICAgcmV0dXJuIGRlZmluaXRpb24uJHR5cGUgPT09IGV2ZW50RGVmaW5pdGlvblR5cGUgJiYgbWF0Y2hlcyhldmVudCwgZmlsdGVyKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1Rocm93RXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIChldmVudC4kdHlwZSA9PT0gJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcpIHx8IChldmVudC4kdHlwZSA9PT0gJ2JwbW46RW5kRXZlbnQnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ29sbGVjdGlvbihlbGVtZW50KSB7XG4gIHZhciBkYXRhT2JqZWN0ID0gZWxlbWVudC5kYXRhT2JqZWN0UmVmO1xuXG4gIHJldHVybiBlbGVtZW50LmlzQ29sbGVjdGlvbiB8fCAoZGF0YU9iamVjdCAmJiBkYXRhT2JqZWN0LmlzQ29sbGVjdGlvbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREaShlbGVtZW50KSB7XG4gIHJldHVybiBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LmRpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VtYW50aWMoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudC5idXNpbmVzc09iamVjdDtcbn1cblxuXG4vLyBjb2xvciBhY2Nlc3MgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRDb2xvcikge1xuICByZXR1cm4gZ2V0RGkoZWxlbWVudCkuZ2V0KCdiaW9jOmZpbGwnKSB8fCBkZWZhdWx0Q29sb3IgfHwgJ3doaXRlJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRDb2xvcikge1xuICByZXR1cm4gZ2V0RGkoZWxlbWVudCkuZ2V0KCdiaW9jOnN0cm9rZScpIHx8IGRlZmF1bHRDb2xvciB8fCAnYmxhY2snO1xufVxuXG5cbi8vIGNyb3BwaW5nIHBhdGggY3VzdG9taXphdGlvbnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2lyY2xlUGF0aChzaGFwZSkge1xuXG4gIHZhciBjeCA9IHNoYXBlLnggKyBzaGFwZS53aWR0aCAvIDIsXG4gICAgICBjeSA9IHNoYXBlLnkgKyBzaGFwZS5oZWlnaHQgLyAyLFxuICAgICAgcmFkaXVzID0gc2hhcGUud2lkdGggLyAyO1xuXG4gIHZhciBjaXJjbGVQYXRoID0gW1xuICAgIFsnTScsIGN4LCBjeV0sXG4gICAgWydtJywgMCwgLXJhZGl1c10sXG4gICAgWydhJywgcmFkaXVzLCByYWRpdXMsIDAsIDEsIDEsIDAsIDIgKiByYWRpdXNdLFxuICAgIFsnYScsIHJhZGl1cywgcmFkaXVzLCAwLCAxLCAxLCAwLCAtMiAqIHJhZGl1c10sXG4gICAgWyd6J11cbiAgXTtcblxuICByZXR1cm4gY29tcG9uZW50c1RvUGF0aChjaXJjbGVQYXRoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvdW5kUmVjdFBhdGgoc2hhcGUsIGJvcmRlclJhZGl1cykge1xuXG4gIHZhciB4ID0gc2hhcGUueCxcbiAgICAgIHkgPSBzaGFwZS55LFxuICAgICAgd2lkdGggPSBzaGFwZS53aWR0aCxcbiAgICAgIGhlaWdodCA9IHNoYXBlLmhlaWdodDtcblxuICB2YXIgcm91bmRSZWN0UGF0aCA9IFtcbiAgICBbJ00nLCB4ICsgYm9yZGVyUmFkaXVzLCB5XSxcbiAgICBbJ2wnLCB3aWR0aCAtIGJvcmRlclJhZGl1cyAqIDIsIDBdLFxuICAgIFsnYScsIGJvcmRlclJhZGl1cywgYm9yZGVyUmFkaXVzLCAwLCAwLCAxLCBib3JkZXJSYWRpdXMsIGJvcmRlclJhZGl1c10sXG4gICAgWydsJywgMCwgaGVpZ2h0IC0gYm9yZGVyUmFkaXVzICogMl0sXG4gICAgWydhJywgYm9yZGVyUmFkaXVzLCBib3JkZXJSYWRpdXMsIDAsIDAsIDEsIC1ib3JkZXJSYWRpdXMsIGJvcmRlclJhZGl1c10sXG4gICAgWydsJywgYm9yZGVyUmFkaXVzICogMiAtIHdpZHRoLCAwXSxcbiAgICBbJ2EnLCBib3JkZXJSYWRpdXMsIGJvcmRlclJhZGl1cywgMCwgMCwgMSwgLWJvcmRlclJhZGl1cywgLWJvcmRlclJhZGl1c10sXG4gICAgWydsJywgMCwgYm9yZGVyUmFkaXVzICogMiAtIGhlaWdodF0sXG4gICAgWydhJywgYm9yZGVyUmFkaXVzLCBib3JkZXJSYWRpdXMsIDAsIDAsIDEsIGJvcmRlclJhZGl1cywgLWJvcmRlclJhZGl1c10sXG4gICAgWyd6J11cbiAgXTtcblxuICByZXR1cm4gY29tcG9uZW50c1RvUGF0aChyb3VuZFJlY3RQYXRoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERpYW1vbmRQYXRoKHNoYXBlKSB7XG5cbiAgdmFyIHdpZHRoID0gc2hhcGUud2lkdGgsXG4gICAgICBoZWlnaHQgPSBzaGFwZS5oZWlnaHQsXG4gICAgICB4ID0gc2hhcGUueCxcbiAgICAgIHkgPSBzaGFwZS55LFxuICAgICAgaGFsZldpZHRoID0gd2lkdGggLyAyLFxuICAgICAgaGFsZkhlaWdodCA9IGhlaWdodCAvIDI7XG5cbiAgdmFyIGRpYW1vbmRQYXRoID0gW1xuICAgIFsnTScsIHggKyBoYWxmV2lkdGgsIHldLFxuICAgIFsnbCcsIGhhbGZXaWR0aCwgaGFsZkhlaWdodF0sXG4gICAgWydsJywgLWhhbGZXaWR0aCwgaGFsZkhlaWdodF0sXG4gICAgWydsJywgLWhhbGZXaWR0aCwgLWhhbGZIZWlnaHRdLFxuICAgIFsneiddXG4gIF07XG5cbiAgcmV0dXJuIGNvbXBvbmVudHNUb1BhdGgoZGlhbW9uZFBhdGgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVjdFBhdGgoc2hhcGUpIHtcbiAgdmFyIHggPSBzaGFwZS54LFxuICAgICAgeSA9IHNoYXBlLnksXG4gICAgICB3aWR0aCA9IHNoYXBlLndpZHRoLFxuICAgICAgaGVpZ2h0ID0gc2hhcGUuaGVpZ2h0O1xuXG4gIHZhciByZWN0UGF0aCA9IFtcbiAgICBbJ00nLCB4LCB5XSxcbiAgICBbJ2wnLCB3aWR0aCwgMF0sXG4gICAgWydsJywgMCwgaGVpZ2h0XSxcbiAgICBbJ2wnLCAtd2lkdGgsIDBdLFxuICAgIFsneiddXG4gIF07XG5cbiAgcmV0dXJuIGNvbXBvbmVudHNUb1BhdGgocmVjdFBhdGgpO1xufSIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCB7XG4gIGlzT2JqZWN0LFxuICBhc3NpZ24sXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgQmFzZVJlbmRlcmVyIGZyb20gJ2RpYWdyYW0tanMvbGliL2RyYXcvQmFzZVJlbmRlcmVyJztcblxuaW1wb3J0IHtcbiAgaXNFeHBhbmRlZCxcbiAgaXNFdmVudFN1YlByb2Nlc3Ncbn0gZnJvbSAnLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRMYWJlbFxufSBmcm9tICcuLi9mZWF0dXJlcy9sYWJlbC1lZGl0aW5nL0xhYmVsVXRpbCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVMaW5lXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvUmVuZGVyVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzVHlwZWRFdmVudCxcbiAgaXNUaHJvd0V2ZW50LFxuICBpc0NvbGxlY3Rpb24sXG4gIGdldERpLFxuICBnZXRTZW1hbnRpYyxcbiAgZ2V0Q2lyY2xlUGF0aCxcbiAgZ2V0Um91bmRSZWN0UGF0aCxcbiAgZ2V0RGlhbW9uZFBhdGgsXG4gIGdldFJlY3RQYXRoLFxuICBnZXRGaWxsQ29sb3IsXG4gIGdldFN0cm9rZUNvbG9yXG59IGZyb20gJy4vQnBtblJlbmRlclV0aWwnO1xuXG5pbXBvcnQge1xuICBxdWVyeSBhcyBkb21RdWVyeVxufSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICBjbGFzc2VzIGFzIHN2Z0NsYXNzZXNcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICByb3RhdGUsXG4gIHRyYW5zZm9ybSxcbiAgdHJhbnNsYXRlXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvU3ZnVHJhbnNmb3JtVXRpbCc7XG5cbmltcG9ydCBJZHMgZnJvbSAnaWRzJztcblxudmFyIFJFTkRFUkVSX0lEUyA9IG5ldyBJZHMoKTtcblxudmFyIFRBU0tfQk9SREVSX1JBRElVUyA9IDEwO1xudmFyIElOTkVSX09VVEVSX0RJU1QgPSAzO1xuXG52YXIgREVGQVVMVF9GSUxMX09QQUNJVFkgPSAuOTUsXG4gICAgSElHSF9GSUxMX09QQUNJVFkgPSAuMzU7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtblJlbmRlcmVyKFxuICAgIGNvbmZpZywgZXZlbnRCdXMsIHN0eWxlcywgcGF0aE1hcCxcbiAgICBjYW52YXMsIHRleHRSZW5kZXJlciwgcHJpb3JpdHkpIHtcblxuICBCYXNlUmVuZGVyZXIuY2FsbCh0aGlzLCBldmVudEJ1cywgcHJpb3JpdHkpO1xuXG4gIHZhciBkZWZhdWx0RmlsbENvbG9yID0gY29uZmlnICYmIGNvbmZpZy5kZWZhdWx0RmlsbENvbG9yLFxuICAgICAgZGVmYXVsdFN0cm9rZUNvbG9yID0gY29uZmlnICYmIGNvbmZpZy5kZWZhdWx0U3Ryb2tlQ29sb3I7XG5cbiAgdmFyIHJlbmRlcmVySWQgPSBSRU5ERVJFUl9JRFMubmV4dCgpO1xuXG4gIHZhciBtYXJrZXJzID0ge307XG5cbiAgdmFyIGNvbXB1dGVTdHlsZSA9IHN0eWxlcy5jb21wdXRlU3R5bGU7XG5cbiAgZnVuY3Rpb24gYWRkTWFya2VyKGlkLCBvcHRpb25zKSB7XG4gICAgdmFyIGF0dHJzID0gYXNzaWduKHtcbiAgICAgIGZpbGw6ICdibGFjaycsXG4gICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgIHN0cm9rZUxpbmVjYXA6ICdyb3VuZCcsXG4gICAgICBzdHJva2VEYXNoYXJyYXk6ICdub25lJ1xuICAgIH0sIG9wdGlvbnMuYXR0cnMpO1xuXG4gICAgdmFyIHJlZiA9IG9wdGlvbnMucmVmIHx8IHsgeDogMCwgeTogMCB9O1xuXG4gICAgdmFyIHNjYWxlID0gb3B0aW9ucy5zY2FsZSB8fCAxO1xuXG4gICAgLy8gZml4IGZvciBzYWZhcmkgLyBjaHJvbWUgLyBmaXJlZm94IGJ1ZyBub3QgY29ycmVjdGx5XG4gICAgLy8gcmVzZXR0aW5nIHN0cm9rZSBkYXNoIGFycmF5XG4gICAgaWYgKGF0dHJzLnN0cm9rZURhc2hhcnJheSA9PT0gJ25vbmUnKSB7XG4gICAgICBhdHRycy5zdHJva2VEYXNoYXJyYXkgPSBbMTAwMDAsIDFdO1xuICAgIH1cblxuICAgIHZhciBtYXJrZXIgPSBzdmdDcmVhdGUoJ21hcmtlcicpO1xuXG4gICAgc3ZnQXR0cihvcHRpb25zLmVsZW1lbnQsIGF0dHJzKTtcblxuICAgIHN2Z0FwcGVuZChtYXJrZXIsIG9wdGlvbnMuZWxlbWVudCk7XG5cbiAgICBzdmdBdHRyKG1hcmtlciwge1xuICAgICAgaWQ6IGlkLFxuICAgICAgdmlld0JveDogJzAgMCAyMCAyMCcsXG4gICAgICByZWZYOiByZWYueCxcbiAgICAgIHJlZlk6IHJlZi55LFxuICAgICAgbWFya2VyV2lkdGg6IDIwICogc2NhbGUsXG4gICAgICBtYXJrZXJIZWlnaHQ6IDIwICogc2NhbGUsXG4gICAgICBvcmllbnQ6ICdhdXRvJ1xuICAgIH0pO1xuXG4gICAgdmFyIGRlZnMgPSBkb21RdWVyeSgnZGVmcycsIGNhbnZhcy5fc3ZnKTtcblxuICAgIGlmICghZGVmcykge1xuICAgICAgZGVmcyA9IHN2Z0NyZWF0ZSgnZGVmcycpO1xuXG4gICAgICBzdmdBcHBlbmQoY2FudmFzLl9zdmcsIGRlZnMpO1xuICAgIH1cblxuICAgIHN2Z0FwcGVuZChkZWZzLCBtYXJrZXIpO1xuXG4gICAgbWFya2Vyc1tpZF0gPSBtYXJrZXI7XG4gIH1cblxuICBmdW5jdGlvbiBjb2xvckVzY2FwZShzdHIpIHtcblxuICAgIC8vIG9ubHkgYWxsb3cgY2hhcmFjdGVycyBhbmQgbnVtYmVyc1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvW14wLTlhLXpBLXpdKy9nLCAnXycpO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFya2VyKHR5cGUsIGZpbGwsIHN0cm9rZSkge1xuICAgIHZhciBpZCA9IHR5cGUgKyAnLScgKyBjb2xvckVzY2FwZShmaWxsKSArICctJyArIGNvbG9yRXNjYXBlKHN0cm9rZSkgKyAnLScgKyByZW5kZXJlcklkO1xuXG4gICAgaWYgKCFtYXJrZXJzW2lkXSkge1xuICAgICAgY3JlYXRlTWFya2VyKGlkLCB0eXBlLCBmaWxsLCBzdHJva2UpO1xuICAgIH1cblxuICAgIHJldHVybiAndXJsKCMnICsgaWQgKyAnKSc7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVNYXJrZXIoaWQsIHR5cGUsIGZpbGwsIHN0cm9rZSkge1xuXG4gICAgaWYgKHR5cGUgPT09ICdzZXF1ZW5jZWZsb3ctZW5kJykge1xuICAgICAgdmFyIHNlcXVlbmNlZmxvd0VuZCA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuICAgICAgc3ZnQXR0cihzZXF1ZW5jZWZsb3dFbmQsIHsgZDogJ00gMSA1IEwgMTEgMTAgTCAxIDE1IFonIH0pO1xuXG4gICAgICBhZGRNYXJrZXIoaWQsIHtcbiAgICAgICAgZWxlbWVudDogc2VxdWVuY2VmbG93RW5kLFxuICAgICAgICByZWY6IHsgeDogMTEsIHk6IDEwIH0sXG4gICAgICAgIHNjYWxlOiAwLjUsXG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgZmlsbDogc3Ryb2tlLFxuICAgICAgICAgIHN0cm9rZTogc3Ryb2tlXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnbWVzc2FnZWZsb3ctc3RhcnQnKSB7XG4gICAgICB2YXIgbWVzc2FnZWZsb3dTdGFydCA9IHN2Z0NyZWF0ZSgnY2lyY2xlJyk7XG4gICAgICBzdmdBdHRyKG1lc3NhZ2VmbG93U3RhcnQsIHsgY3g6IDYsIGN5OiA2LCByOiAzLjUgfSk7XG5cbiAgICAgIGFkZE1hcmtlcihpZCwge1xuICAgICAgICBlbGVtZW50OiBtZXNzYWdlZmxvd1N0YXJ0LFxuICAgICAgICBhdHRyczoge1xuICAgICAgICAgIGZpbGw6IGZpbGwsXG4gICAgICAgICAgc3Ryb2tlOiBzdHJva2VcbiAgICAgICAgfSxcbiAgICAgICAgcmVmOiB7IHg6IDYsIHk6IDYgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdtZXNzYWdlZmxvdy1lbmQnKSB7XG4gICAgICB2YXIgbWVzc2FnZWZsb3dFbmQgPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICAgIHN2Z0F0dHIobWVzc2FnZWZsb3dFbmQsIHsgZDogJ20gMSA1IGwgMCAtMyBsIDcgMyBsIC03IDMgeicgfSk7XG5cbiAgICAgIGFkZE1hcmtlcihpZCwge1xuICAgICAgICBlbGVtZW50OiBtZXNzYWdlZmxvd0VuZCxcbiAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICBmaWxsOiBmaWxsLFxuICAgICAgICAgIHN0cm9rZTogc3Ryb2tlLFxuICAgICAgICAgIHN0cm9rZUxpbmVjYXA6ICdidXR0J1xuICAgICAgICB9LFxuICAgICAgICByZWY6IHsgeDogOC41LCB5OiA1IH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnYXNzb2NpYXRpb24tc3RhcnQnKSB7XG4gICAgICB2YXIgYXNzb2NpYXRpb25TdGFydCA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuICAgICAgc3ZnQXR0cihhc3NvY2lhdGlvblN0YXJ0LCB7IGQ6ICdNIDExIDUgTCAxIDEwIEwgMTEgMTUnIH0pO1xuXG4gICAgICBhZGRNYXJrZXIoaWQsIHtcbiAgICAgICAgZWxlbWVudDogYXNzb2NpYXRpb25TdGFydCxcbiAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICBmaWxsOiAnbm9uZScsXG4gICAgICAgICAgc3Ryb2tlOiBzdHJva2UsXG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IDEuNVxuICAgICAgICB9LFxuICAgICAgICByZWY6IHsgeDogMSwgeTogMTAgfSxcbiAgICAgICAgc2NhbGU6IDAuNVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdhc3NvY2lhdGlvbi1lbmQnKSB7XG4gICAgICB2YXIgYXNzb2NpYXRpb25FbmQgPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICAgIHN2Z0F0dHIoYXNzb2NpYXRpb25FbmQsIHsgZDogJ00gMSA1IEwgMTEgMTAgTCAxIDE1JyB9KTtcblxuICAgICAgYWRkTWFya2VyKGlkLCB7XG4gICAgICAgIGVsZW1lbnQ6IGFzc29jaWF0aW9uRW5kLFxuICAgICAgICBhdHRyczoge1xuICAgICAgICAgIGZpbGw6ICdub25lJyxcbiAgICAgICAgICBzdHJva2U6IHN0cm9rZSxcbiAgICAgICAgICBzdHJva2VXaWR0aDogMS41XG4gICAgICAgIH0sXG4gICAgICAgIHJlZjogeyB4OiAxMiwgeTogMTAgfSxcbiAgICAgICAgc2NhbGU6IDAuNVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdjb25kaXRpb25hbC1mbG93LW1hcmtlcicpIHtcbiAgICAgIHZhciBjb25kaXRpb25hbGZsb3dNYXJrZXIgPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICAgIHN2Z0F0dHIoY29uZGl0aW9uYWxmbG93TWFya2VyLCB7IGQ6ICdNIDAgMTAgTCA4IDYgTCAxNiAxMCBMIDggMTQgWicgfSk7XG5cbiAgICAgIGFkZE1hcmtlcihpZCwge1xuICAgICAgICBlbGVtZW50OiBjb25kaXRpb25hbGZsb3dNYXJrZXIsXG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgZmlsbDogZmlsbCxcbiAgICAgICAgICBzdHJva2U6IHN0cm9rZVxuICAgICAgICB9LFxuICAgICAgICByZWY6IHsgeDogLTEsIHk6IDEwIH0sXG4gICAgICAgIHNjYWxlOiAwLjVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnY29uZGl0aW9uYWwtZGVmYXVsdC1mbG93LW1hcmtlcicpIHtcbiAgICAgIHZhciBjb25kaXRpb25hbGRlZmF1bHRmbG93TWFya2VyID0gc3ZnQ3JlYXRlKCdwYXRoJyk7XG4gICAgICBzdmdBdHRyKGNvbmRpdGlvbmFsZGVmYXVsdGZsb3dNYXJrZXIsIHsgZDogJ00gNiA0IEwgMTAgMTYnIH0pO1xuXG4gICAgICBhZGRNYXJrZXIoaWQsIHtcbiAgICAgICAgZWxlbWVudDogY29uZGl0aW9uYWxkZWZhdWx0Zmxvd01hcmtlcixcbiAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICBzdHJva2U6IHN0cm9rZVxuICAgICAgICB9LFxuICAgICAgICByZWY6IHsgeDogMCwgeTogMTAgfSxcbiAgICAgICAgc2NhbGU6IDAuNVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZHJhd0NpcmNsZShwYXJlbnRHZngsIHdpZHRoLCBoZWlnaHQsIG9mZnNldCwgYXR0cnMpIHtcblxuICAgIGlmIChpc09iamVjdChvZmZzZXQpKSB7XG4gICAgICBhdHRycyA9IG9mZnNldDtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgfVxuXG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG5cbiAgICBhdHRycyA9IGNvbXB1dGVTdHlsZShhdHRycywge1xuICAgICAgc3Ryb2tlOiAnYmxhY2snLFxuICAgICAgc3Ryb2tlV2lkdGg6IDIsXG4gICAgICBmaWxsOiAnd2hpdGUnXG4gICAgfSk7XG5cbiAgICBpZiAoYXR0cnMuZmlsbCA9PT0gJ25vbmUnKSB7XG4gICAgICBkZWxldGUgYXR0cnMuZmlsbE9wYWNpdHk7XG4gICAgfVxuXG4gICAgdmFyIGN4ID0gd2lkdGggLyAyLFxuICAgICAgICBjeSA9IGhlaWdodCAvIDI7XG5cbiAgICB2YXIgY2lyY2xlID0gc3ZnQ3JlYXRlKCdjaXJjbGUnKTtcbiAgICBzdmdBdHRyKGNpcmNsZSwge1xuICAgICAgY3g6IGN4LFxuICAgICAgY3k6IGN5LFxuICAgICAgcjogTWF0aC5yb3VuZCgod2lkdGggKyBoZWlnaHQpIC8gNCAtIG9mZnNldClcbiAgICB9KTtcbiAgICBzdmdBdHRyKGNpcmNsZSwgYXR0cnMpO1xuXG4gICAgc3ZnQXBwZW5kKHBhcmVudEdmeCwgY2lyY2xlKTtcblxuICAgIHJldHVybiBjaXJjbGU7XG4gIH1cblxuICBmdW5jdGlvbiBkcmF3UmVjdChwYXJlbnRHZngsIHdpZHRoLCBoZWlnaHQsIHIsIG9mZnNldCwgYXR0cnMpIHtcblxuICAgIGlmIChpc09iamVjdChvZmZzZXQpKSB7XG4gICAgICBhdHRycyA9IG9mZnNldDtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgfVxuXG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG5cbiAgICBhdHRycyA9IGNvbXB1dGVTdHlsZShhdHRycywge1xuICAgICAgc3Ryb2tlOiAnYmxhY2snLFxuICAgICAgc3Ryb2tlV2lkdGg6IDIsXG4gICAgICBmaWxsOiAnd2hpdGUnXG4gICAgfSk7XG5cbiAgICB2YXIgcmVjdCA9IHN2Z0NyZWF0ZSgncmVjdCcpO1xuICAgIHN2Z0F0dHIocmVjdCwge1xuICAgICAgeDogb2Zmc2V0LFxuICAgICAgeTogb2Zmc2V0LFxuICAgICAgd2lkdGg6IHdpZHRoIC0gb2Zmc2V0ICogMixcbiAgICAgIGhlaWdodDogaGVpZ2h0IC0gb2Zmc2V0ICogMixcbiAgICAgIHJ4OiByLFxuICAgICAgcnk6IHJcbiAgICB9KTtcbiAgICBzdmdBdHRyKHJlY3QsIGF0dHJzKTtcblxuICAgIHN2Z0FwcGVuZChwYXJlbnRHZngsIHJlY3QpO1xuXG4gICAgcmV0dXJuIHJlY3Q7XG4gIH1cblxuICBmdW5jdGlvbiBkcmF3RGlhbW9uZChwYXJlbnRHZngsIHdpZHRoLCBoZWlnaHQsIGF0dHJzKSB7XG5cbiAgICB2YXIgeF8yID0gd2lkdGggLyAyO1xuICAgIHZhciB5XzIgPSBoZWlnaHQgLyAyO1xuXG4gICAgdmFyIHBvaW50cyA9IFt7IHg6IHhfMiwgeTogMCB9LCB7IHg6IHdpZHRoLCB5OiB5XzIgfSwgeyB4OiB4XzIsIHk6IGhlaWdodCB9LCB7IHg6IDAsIHk6IHlfMiB9XTtcblxuICAgIHZhciBwb2ludHNTdHJpbmcgPSBwb2ludHMubWFwKGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgICByZXR1cm4gcG9pbnQueCArICcsJyArIHBvaW50Lnk7XG4gICAgfSkuam9pbignICcpO1xuXG4gICAgYXR0cnMgPSBjb21wdXRlU3R5bGUoYXR0cnMsIHtcbiAgICAgIHN0cm9rZTogJ2JsYWNrJyxcbiAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgZmlsbDogJ3doaXRlJ1xuICAgIH0pO1xuXG4gICAgdmFyIHBvbHlnb24gPSBzdmdDcmVhdGUoJ3BvbHlnb24nKTtcbiAgICBzdmdBdHRyKHBvbHlnb24sIHtcbiAgICAgIHBvaW50czogcG9pbnRzU3RyaW5nXG4gICAgfSk7XG4gICAgc3ZnQXR0cihwb2x5Z29uLCBhdHRycyk7XG5cbiAgICBzdmdBcHBlbmQocGFyZW50R2Z4LCBwb2x5Z29uKTtcblxuICAgIHJldHVybiBwb2x5Z29uO1xuICB9XG5cbiAgZnVuY3Rpb24gZHJhd0xpbmUocGFyZW50R2Z4LCB3YXlwb2ludHMsIGF0dHJzKSB7XG4gICAgYXR0cnMgPSBjb21wdXRlU3R5bGUoYXR0cnMsIFsgJ25vLWZpbGwnIF0sIHtcbiAgICAgIHN0cm9rZTogJ2JsYWNrJyxcbiAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgZmlsbDogJ25vbmUnXG4gICAgfSk7XG5cbiAgICB2YXIgbGluZSA9IGNyZWF0ZUxpbmUod2F5cG9pbnRzLCBhdHRycyk7XG5cbiAgICBzdmdBcHBlbmQocGFyZW50R2Z4LCBsaW5lKTtcblxuICAgIHJldHVybiBsaW5lO1xuICB9XG5cbiAgZnVuY3Rpb24gZHJhd1BhdGgocGFyZW50R2Z4LCBkLCBhdHRycykge1xuXG4gICAgYXR0cnMgPSBjb21wdXRlU3R5bGUoYXR0cnMsIFsgJ25vLWZpbGwnIF0sIHtcbiAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgc3Ryb2tlOiAnYmxhY2snXG4gICAgfSk7XG5cbiAgICB2YXIgcGF0aCA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuICAgIHN2Z0F0dHIocGF0aCwgeyBkOiBkIH0pO1xuICAgIHN2Z0F0dHIocGF0aCwgYXR0cnMpO1xuXG4gICAgc3ZnQXBwZW5kKHBhcmVudEdmeCwgcGF0aCk7XG5cbiAgICByZXR1cm4gcGF0aDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRyYXdNYXJrZXIodHlwZSwgcGFyZW50R2Z4LCBwYXRoLCBhdHRycykge1xuICAgIHJldHVybiBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGgsIGFzc2lnbih7ICdkYXRhLW1hcmtlcic6IHR5cGUgfSwgYXR0cnMpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFzKHR5cGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICByZXR1cm4gaGFuZGxlcnNbdHlwZV0ocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyZXIodHlwZSkge1xuICAgIHJldHVybiBoYW5kbGVyc1t0eXBlXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlckV2ZW50Q29udGVudChlbGVtZW50LCBwYXJlbnRHZngpIHtcblxuICAgIHZhciBldmVudCA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuICAgIHZhciBpc1Rocm93aW5nID0gaXNUaHJvd0V2ZW50KGV2ZW50KTtcblxuICAgIGlmIChldmVudC5ldmVudERlZmluaXRpb25zICYmIGV2ZW50LmV2ZW50RGVmaW5pdGlvbnMubGVuZ3RoPjEpIHtcbiAgICAgIGlmIChldmVudC5wYXJhbGxlbE11bHRpcGxlKSB7XG4gICAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpQYXJhbGxlbE11bHRpcGxlRXZlbnREZWZpbml0aW9uJykocGFyZW50R2Z4LCBlbGVtZW50LCBpc1Rocm93aW5nKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46TXVsdGlwbGVFdmVudERlZmluaXRpb24nKShwYXJlbnRHZngsIGVsZW1lbnQsIGlzVGhyb3dpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc1R5cGVkRXZlbnQoZXZlbnQsICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKShwYXJlbnRHZngsIGVsZW1lbnQsIGlzVGhyb3dpbmcpO1xuICAgIH1cblxuICAgIGlmIChpc1R5cGVkRXZlbnQoZXZlbnQsICdicG1uOlRpbWVyRXZlbnREZWZpbml0aW9uJykpIHtcbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpUaW1lckV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJykocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICB9XG5cbiAgICBpZiAoaXNUeXBlZEV2ZW50KGV2ZW50LCAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicpKSB7XG4gICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpKSB7XG4gICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46RXJyb3JFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOkVycm9yRXZlbnREZWZpbml0aW9uJykocGFyZW50R2Z4LCBlbGVtZW50LCBpc1Rocm93aW5nKTtcbiAgICB9XG5cbiAgICBpZiAoaXNUeXBlZEV2ZW50KGV2ZW50LCAnYnBtbjpDYW5jZWxFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOkNhbmNlbEV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46Q29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbicpKSB7XG4gICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46Q29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46VGVybWluYXRlRXZlbnREZWZpbml0aW9uJykpIHtcbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpUZXJtaW5hdGVFdmVudERlZmluaXRpb24nKShwYXJlbnRHZngsIGVsZW1lbnQsIGlzVGhyb3dpbmcpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyTGFiZWwocGFyZW50R2Z4LCBsYWJlbCwgb3B0aW9ucykge1xuXG4gICAgb3B0aW9ucyA9IGFzc2lnbih7XG4gICAgICBzaXplOiB7XG4gICAgICAgIHdpZHRoOiAxMDBcbiAgICAgIH1cbiAgICB9LCBvcHRpb25zKTtcblxuICAgIHZhciB0ZXh0ID0gdGV4dFJlbmRlcmVyLmNyZWF0ZVRleHQobGFiZWwgfHwgJycsIG9wdGlvbnMpO1xuXG4gICAgc3ZnQ2xhc3Nlcyh0ZXh0KS5hZGQoJ2Rqcy1sYWJlbCcpO1xuXG4gICAgc3ZnQXBwZW5kKHBhcmVudEdmeCwgdGV4dCk7XG5cbiAgICByZXR1cm4gdGV4dDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlckVtYmVkZGVkTGFiZWwocGFyZW50R2Z4LCBlbGVtZW50LCBhbGlnbikge1xuICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgcmV0dXJuIHJlbmRlckxhYmVsKHBhcmVudEdmeCwgc2VtYW50aWMubmFtZSwge1xuICAgICAgYm94OiBlbGVtZW50LFxuICAgICAgYWxpZ246IGFsaWduLFxuICAgICAgcGFkZGluZzogNSxcbiAgICAgIHN0eWxlOiB7XG4gICAgICAgIGZpbGw6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlckV4dGVybmFsTGFiZWwocGFyZW50R2Z4LCBlbGVtZW50KSB7XG5cbiAgICB2YXIgYm94ID0ge1xuICAgICAgd2lkdGg6IDkwLFxuICAgICAgaGVpZ2h0OiAzMCxcbiAgICAgIHg6IGVsZW1lbnQud2lkdGggLyAyICsgZWxlbWVudC54LFxuICAgICAgeTogZWxlbWVudC5oZWlnaHQgLyAyICsgZWxlbWVudC55XG4gICAgfTtcblxuICAgIHJldHVybiByZW5kZXJMYWJlbChwYXJlbnRHZngsIGdldExhYmVsKGVsZW1lbnQpLCB7XG4gICAgICBib3g6IGJveCxcbiAgICAgIGZpdEJveDogdHJ1ZSxcbiAgICAgIHN0eWxlOiBhc3NpZ24oXG4gICAgICAgIHt9LFxuICAgICAgICB0ZXh0UmVuZGVyZXIuZ2V0RXh0ZXJuYWxTdHlsZSgpLFxuICAgICAgICB7XG4gICAgICAgICAgZmlsbDogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgICB9XG4gICAgICApXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZW5kZXJMYW5lTGFiZWwocGFyZW50R2Z4LCB0ZXh0LCBlbGVtZW50KSB7XG4gICAgdmFyIHRleHRCb3ggPSByZW5kZXJMYWJlbChwYXJlbnRHZngsIHRleHQsIHtcbiAgICAgIGJveDoge1xuICAgICAgICBoZWlnaHQ6IDMwLFxuICAgICAgICB3aWR0aDogZWxlbWVudC5oZWlnaHRcbiAgICAgIH0sXG4gICAgICBhbGlnbjogJ2NlbnRlci1taWRkbGUnLFxuICAgICAgc3R5bGU6IHtcbiAgICAgICAgZmlsbDogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdmFyIHRvcCA9IC0xICogZWxlbWVudC5oZWlnaHQ7XG5cbiAgICB0cmFuc2Zvcm0odGV4dEJveCwgMCwgLXRvcCwgMjcwKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVBhdGhGcm9tQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgdmFyIHdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzO1xuXG4gICAgdmFyIHBhdGhEYXRhID0gJ20gICcgKyB3YXlwb2ludHNbMF0ueCArICcsJyArIHdheXBvaW50c1swXS55O1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgd2F5cG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBwYXRoRGF0YSArPSAnTCcgKyB3YXlwb2ludHNbaV0ueCArICcsJyArIHdheXBvaW50c1tpXS55ICsgJyAnO1xuICAgIH1cbiAgICByZXR1cm4gcGF0aERhdGE7XG4gIH1cblxuICB2YXIgaGFuZGxlcnMgPSB0aGlzLmhhbmRsZXJzID0ge1xuICAgICdicG1uOkV2ZW50JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50LCBhdHRycykge1xuXG4gICAgICBpZiAoISgnZmlsbE9wYWNpdHknIGluIGF0dHJzKSkge1xuICAgICAgICBhdHRycy5maWxsT3BhY2l0eSA9IERFRkFVTFRfRklMTF9PUEFDSVRZO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZHJhd0NpcmNsZShwYXJlbnRHZngsIGVsZW1lbnQud2lkdGgsIGVsZW1lbnQuaGVpZ2h0LCBhdHRycyk7XG4gICAgfSxcbiAgICAnYnBtbjpTdGFydEV2ZW50JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgYXR0cnMgPSB7XG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9O1xuXG4gICAgICB2YXIgc2VtYW50aWMgPSBnZXRTZW1hbnRpYyhlbGVtZW50KTtcblxuICAgICAgaWYgKCFzZW1hbnRpYy5pc0ludGVycnVwdGluZykge1xuICAgICAgICBhdHRycyA9IHtcbiAgICAgICAgICBzdHJva2VEYXNoYXJyYXk6ICc2JyxcbiAgICAgICAgICBzdHJva2VMaW5lY2FwOiAncm91bmQnLFxuICAgICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgdmFyIGNpcmNsZSA9IHJlbmRlcmVyKCdicG1uOkV2ZW50JykocGFyZW50R2Z4LCBlbGVtZW50LCBhdHRycyk7XG5cbiAgICAgIHJlbmRlckV2ZW50Q29udGVudChlbGVtZW50LCBwYXJlbnRHZngpO1xuXG4gICAgICByZXR1cm4gY2lyY2xlO1xuICAgIH0sXG4gICAgJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbic6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZykge1xuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdFVkVOVF9NRVNTQUdFJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDAuOSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAwLjksXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjIzNSxcbiAgICAgICAgICBteTogMC4zMTVcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBmaWxsID0gaXNUaHJvd2luZyA/IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcikgOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvcik7XG4gICAgICB2YXIgc3Ryb2tlID0gaXNUaHJvd2luZyA/IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSA6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcik7XG5cbiAgICAgIHZhciBtZXNzYWdlUGF0aCA9IGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGZpbGwsXG4gICAgICAgIHN0cm9rZTogc3Ryb2tlXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIG1lc3NhZ2VQYXRoO1xuICAgIH0sXG4gICAgJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBjaXJjbGUgPSBkcmF3Q2lyY2xlKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIDAuMiAqIGVsZW1lbnQuaGVpZ2h0LCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnRVZFTlRfVElNRVJfV0gnLCB7XG4gICAgICAgIHhTY2FsZUZhY3RvcjogMC43NSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAwLjc1LFxuICAgICAgICBjb250YWluZXJXaWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBlbGVtZW50LmhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogMC41LFxuICAgICAgICAgIG15OiAwLjVcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDIsXG4gICAgICAgIHN0cm9rZUxpbmVjYXA6ICdzcXVhcmUnLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDtpIDwgMTI7IGkrKykge1xuXG4gICAgICAgIHZhciBsaW5lUGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX1RJTUVSX0xJTkUnLCB7XG4gICAgICAgICAgeFNjYWxlRmFjdG9yOiAwLjc1LFxuICAgICAgICAgIHlTY2FsZUZhY3RvcjogMC43NSxcbiAgICAgICAgICBjb250YWluZXJXaWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgICBteDogMC41LFxuICAgICAgICAgICAgbXk6IDAuNVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHdpZHRoID0gZWxlbWVudC53aWR0aCAvIDI7XG4gICAgICAgIHZhciBoZWlnaHQgPSBlbGVtZW50LmhlaWdodCAvIDI7XG5cbiAgICAgICAgZHJhd1BhdGgocGFyZW50R2Z4LCBsaW5lUGF0aERhdGEsIHtcbiAgICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgICBzdHJva2VMaW5lY2FwOiAnc3F1YXJlJyxcbiAgICAgICAgICB0cmFuc2Zvcm06ICdyb3RhdGUoJyArIChpICogMzApICsgJywnICsgaGVpZ2h0ICsgJywnICsgd2lkdGggKyAnKScsXG4gICAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2lyY2xlO1xuICAgIH0sXG4gICAgJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbic6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZXZlbnQsIGlzVGhyb3dpbmcpIHtcbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnRVZFTlRfRVNDQUxBVElPTicsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBldmVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBldmVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNSxcbiAgICAgICAgICBteTogMC4yXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZmlsbCA9IGlzVGhyb3dpbmcgPyBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSA6ICdub25lJztcblxuICAgICAgcmV0dXJuIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGZpbGwsXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50KSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX0NPTkRJVElPTkFMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGV2ZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGV2ZW50LmhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogMC41LFxuICAgICAgICAgIG15OiAwLjIyMlxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbic6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZXZlbnQsIGlzVGhyb3dpbmcpIHtcbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnRVZFTlRfTElOSycsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBldmVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBldmVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNTcsXG4gICAgICAgICAgbXk6IDAuMjYzXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZmlsbCA9IGlzVGhyb3dpbmcgPyBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSA6ICdub25lJztcblxuICAgICAgcmV0dXJuIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGZpbGwsXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgJ2JwbW46RXJyb3JFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50LCBpc1Rocm93aW5nKSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX0VSUk9SJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEuMSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAxLjEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBldmVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBldmVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuMixcbiAgICAgICAgICBteTogMC43MjJcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBmaWxsID0gaXNUaHJvd2luZyA/IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpIDogJ25vbmUnO1xuXG4gICAgICByZXR1cm4gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZmlsbCxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpDYW5jZWxFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50LCBpc1Rocm93aW5nKSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX0NBTkNFTF80NScsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLjAsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMS4wLFxuICAgICAgICBjb250YWluZXJXaWR0aDogZXZlbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZXZlbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjYzOCxcbiAgICAgICAgICBteTogLTAuMDU1XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZmlsbCA9IGlzVGhyb3dpbmcgPyBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSA6ICdub25lJztcblxuICAgICAgdmFyIHBhdGggPSBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBmaWxsLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcm90YXRlKHBhdGgsIDQ1KTtcblxuICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfSxcbiAgICAnYnBtbjpDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBldmVudCwgaXNUaHJvd2luZykge1xuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdFVkVOVF9DT01QRU5TQVRJT04nLCB7XG4gICAgICAgIHhTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAxLFxuICAgICAgICBjb250YWluZXJXaWR0aDogZXZlbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZXZlbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjIyLFxuICAgICAgICAgIG15OiAwLjVcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBmaWxsID0gaXNUaHJvd2luZyA/IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpIDogJ25vbmUnO1xuXG4gICAgICByZXR1cm4gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZmlsbCxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50LCBpc1Rocm93aW5nKSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX1NJR05BTCcsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAwLjksXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMC45LFxuICAgICAgICBjb250YWluZXJXaWR0aDogZXZlbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZXZlbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjUsXG4gICAgICAgICAgbXk6IDAuMlxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdmFyIGZpbGwgPSBpc1Rocm93aW5nID8gZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcikgOiAnbm9uZSc7XG5cbiAgICAgIHJldHVybiBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBmaWxsLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdicG1uOk11bHRpcGxlRXZlbnREZWZpbml0aW9uJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBldmVudCwgaXNUaHJvd2luZykge1xuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdFVkVOVF9NVUxUSVBMRScsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLjEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMS4xLFxuICAgICAgICBjb250YWluZXJXaWR0aDogZXZlbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZXZlbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjIyMixcbiAgICAgICAgICBteTogMC4zNlxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdmFyIGZpbGwgPSBpc1Rocm93aW5nID8gZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcikgOiAnbm9uZSc7XG5cbiAgICAgIHJldHVybiBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBmaWxsXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdicG1uOlBhcmFsbGVsTXVsdGlwbGVFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50KSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX1BBUkFMTEVMX01VTFRJUExFJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEuMixcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAxLjIsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBldmVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBldmVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNDU4LFxuICAgICAgICAgIG15OiAwLjE5NFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdicG1uOkVuZEV2ZW50JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgY2lyY2xlID0gcmVuZGVyZXIoJ2JwbW46RXZlbnQnKShwYXJlbnRHZngsIGVsZW1lbnQsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDQsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmVuZGVyRXZlbnRDb250ZW50KGVsZW1lbnQsIHBhcmVudEdmeCwgdHJ1ZSk7XG5cbiAgICAgIHJldHVybiBjaXJjbGU7XG4gICAgfSxcbiAgICAnYnBtbjpUZXJtaW5hdGVFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBjaXJjbGUgPSBkcmF3Q2lyY2xlKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIDgsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDQsXG4gICAgICAgIGZpbGw6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBjaXJjbGU7XG4gICAgfSxcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVFdmVudCc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIG91dGVyID0gcmVuZGVyZXIoJ2JwbW46RXZlbnQnKShwYXJlbnRHZngsIGVsZW1lbnQsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgLyogaW5uZXIgKi9cbiAgICAgIGRyYXdDaXJjbGUocGFyZW50R2Z4LCBlbGVtZW50LndpZHRoLCBlbGVtZW50LmhlaWdodCwgSU5ORVJfT1VURVJfRElTVCwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsICdub25lJyksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJlbmRlckV2ZW50Q29udGVudChlbGVtZW50LCBwYXJlbnRHZngpO1xuXG4gICAgICByZXR1cm4gb3V0ZXI7XG4gICAgfSxcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JzogYXMoJ2JwbW46SW50ZXJtZWRpYXRlRXZlbnQnKSxcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JzogYXMoJ2JwbW46SW50ZXJtZWRpYXRlRXZlbnQnKSxcblxuICAgICdicG1uOkFjdGl2aXR5JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50LCBhdHRycykge1xuXG4gICAgICBhdHRycyA9IGF0dHJzIHx8IHt9O1xuXG4gICAgICBpZiAoISgnZmlsbE9wYWNpdHknIGluIGF0dHJzKSkge1xuICAgICAgICBhdHRycy5maWxsT3BhY2l0eSA9IERFRkFVTFRfRklMTF9PUEFDSVRZO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZHJhd1JlY3QocGFyZW50R2Z4LCBlbGVtZW50LndpZHRoLCBlbGVtZW50LmhlaWdodCwgVEFTS19CT1JERVJfUkFESVVTLCBhdHRycyk7XG4gICAgfSxcblxuICAgICdicG1uOlRhc2snOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH07XG5cbiAgICAgIHZhciByZWN0ID0gcmVuZGVyZXIoJ2JwbW46QWN0aXZpdHknKShwYXJlbnRHZngsIGVsZW1lbnQsIGF0dHJzKTtcblxuICAgICAgcmVuZGVyRW1iZWRkZWRMYWJlbChwYXJlbnRHZngsIGVsZW1lbnQsICdjZW50ZXItbWlkZGxlJyk7XG4gICAgICBhdHRhY2hUYXNrTWFya2VycyhwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICByZXR1cm4gcmVjdDtcbiAgICB9LFxuICAgICdicG1uOlNlcnZpY2VUYXNrJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgdGFzayA9IHJlbmRlcmVyKCdicG1uOlRhc2snKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICB2YXIgcGF0aERhdGFCRyA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX1NFUlZJQ0UnLCB7XG4gICAgICAgIGFic3Bvczoge1xuICAgICAgICAgIHg6IDEyLFxuICAgICAgICAgIHk6IDE4XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKiBzZXJ2aWNlIGJnICovIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGFCRywge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZmlsbFBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdUQVNLX1RZUEVfU0VSVklDRV9GSUxMJywge1xuICAgICAgICBhYnNwb3M6IHtcbiAgICAgICAgICB4OiAxNy4yLFxuICAgICAgICAgIHk6IDE4XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKiBzZXJ2aWNlIGZpbGwgKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBmaWxsUGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDAsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX1NFUlZJQ0UnLCB7XG4gICAgICAgIGFic3Bvczoge1xuICAgICAgICAgIHg6IDE3LFxuICAgICAgICAgIHk6IDIyXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKiBzZXJ2aWNlICovIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRhc2s7XG4gICAgfSxcbiAgICAnYnBtbjpVc2VyVGFzayc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIHRhc2sgPSByZW5kZXJlcignYnBtbjpUYXNrJykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgdmFyIHggPSAxNTtcbiAgICAgIHZhciB5ID0gMTI7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX1VTRVJfMScsIHtcbiAgICAgICAgYWJzcG9zOiB7XG4gICAgICAgICAgeDogeCxcbiAgICAgICAgICB5OiB5XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKiB1c2VyIHBhdGggKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgICBzdHJva2VXaWR0aDogMC41LFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBwYXRoRGF0YTIgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9VU0VSXzInLCB7XG4gICAgICAgIGFic3Bvczoge1xuICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgeTogeVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyogdXNlcjIgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhMiwge1xuICAgICAgICBzdHJva2VXaWR0aDogMC41LFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBwYXRoRGF0YTMgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9VU0VSXzMnLCB7XG4gICAgICAgIGFic3Bvczoge1xuICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgeTogeVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyogdXNlcjMgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhMywge1xuICAgICAgICBzdHJva2VXaWR0aDogMC41LFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdGFzaztcbiAgICB9LFxuICAgICdicG1uOk1hbnVhbFRhc2snOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciB0YXNrID0gcmVuZGVyZXIoJ2JwbW46VGFzaycpKHBhcmVudEdmeCwgZWxlbWVudCk7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX01BTlVBTCcsIHtcbiAgICAgICAgYWJzcG9zOiB7XG4gICAgICAgICAgeDogMTcsXG4gICAgICAgICAgeTogMTVcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qIG1hbnVhbCBwYXRoICovIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDAuNSwgLy8gMC4yNSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdGFzaztcbiAgICB9LFxuICAgICdicG1uOlNlbmRUYXNrJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgdGFzayA9IHJlbmRlcmVyKCdicG1uOlRhc2snKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9TRU5EJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IDIxLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IDE0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjI4NSxcbiAgICAgICAgICBteTogMC4zNTdcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qIHNlbmQgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0YXNrO1xuICAgIH0sXG4gICAgJ2JwbW46UmVjZWl2ZVRhc2snIDogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgc2VtYW50aWMgPSBnZXRTZW1hbnRpYyhlbGVtZW50KTtcblxuICAgICAgdmFyIHRhc2sgPSByZW5kZXJlcignYnBtbjpUYXNrJykocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICAgIHZhciBwYXRoRGF0YTtcblxuICAgICAgaWYgKHNlbWFudGljLmluc3RhbnRpYXRlKSB7XG4gICAgICAgIGRyYXdDaXJjbGUocGFyZW50R2Z4LCAyOCwgMjgsIDIwICogMC4yMiwgeyBzdHJva2VXaWR0aDogMSB9KTtcblxuICAgICAgICBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX0lOU1RBTlRJQVRJTkdfU0VORCcsIHtcbiAgICAgICAgICBhYnNwb3M6IHtcbiAgICAgICAgICAgIHg6IDcuNzcsXG4gICAgICAgICAgICB5OiA5LjUyXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9TRU5EJywge1xuICAgICAgICAgIHhTY2FsZUZhY3RvcjogMC45LFxuICAgICAgICAgIHlTY2FsZUZhY3RvcjogMC45LFxuICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiAyMSxcbiAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IDE0LFxuICAgICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgICBteDogMC4zLFxuICAgICAgICAgICAgbXk6IDAuNFxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8qIHJlY2VpdmUgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0YXNrO1xuICAgIH0sXG4gICAgJ2JwbW46U2NyaXB0VGFzayc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIHRhc2sgPSByZW5kZXJlcignYnBtbjpUYXNrJykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdUQVNLX1RZUEVfU0NSSVBUJywge1xuICAgICAgICBhYnNwb3M6IHtcbiAgICAgICAgICB4OiAxNSxcbiAgICAgICAgICB5OiAyMFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyogc2NyaXB0IHBhdGggKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRhc2s7XG4gICAgfSxcbiAgICAnYnBtbjpCdXNpbmVzc1J1bGVUYXNrJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgdGFzayA9IHJlbmRlcmVyKCdicG1uOlRhc2snKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICB2YXIgaGVhZGVyUGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9CVVNJTkVTU19SVUxFX0hFQURFUicsIHtcbiAgICAgICAgYWJzcG9zOiB7XG4gICAgICAgICAgeDogOCxcbiAgICAgICAgICB5OiA4XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgYnVzaW5lc3NIZWFkZXJQYXRoID0gZHJhd1BhdGgocGFyZW50R2Z4LCBoZWFkZXJQYXRoRGF0YSk7XG4gICAgICBzdmdBdHRyKGJ1c2luZXNzSGVhZGVyUGF0aCwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsICcjYWFhYWFhJyksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBoZWFkZXJEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdUQVNLX1RZUEVfQlVTSU5FU1NfUlVMRV9NQUlOJywge1xuICAgICAgICBhYnNwb3M6IHtcbiAgICAgICAgICB4OiA4LFxuICAgICAgICAgIHk6IDhcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBidXNpbmVzc1BhdGggPSBkcmF3UGF0aChwYXJlbnRHZngsIGhlYWRlckRhdGEpO1xuICAgICAgc3ZnQXR0cihidXNpbmVzc1BhdGgsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0YXNrO1xuICAgIH0sXG4gICAgJ2JwbW46U3ViUHJvY2Vzcyc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCwgYXR0cnMpIHtcbiAgICAgIGF0dHJzID0gYXNzaWduKHtcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0sIGF0dHJzKTtcblxuICAgICAgdmFyIHJlY3QgPSByZW5kZXJlcignYnBtbjpBY3Rpdml0eScpKHBhcmVudEdmeCwgZWxlbWVudCwgYXR0cnMpO1xuXG4gICAgICB2YXIgZXhwYW5kZWQgPSBpc0V4cGFuZGVkKGVsZW1lbnQpO1xuXG4gICAgICBpZiAoaXNFdmVudFN1YlByb2Nlc3MoZWxlbWVudCkpIHtcbiAgICAgICAgc3ZnQXR0cihyZWN0LCB7XG4gICAgICAgICAgc3Ryb2tlRGFzaGFycmF5OiAnMSwyJ1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmVuZGVyRW1iZWRkZWRMYWJlbChwYXJlbnRHZngsIGVsZW1lbnQsIGV4cGFuZGVkID8gJ2NlbnRlci10b3AnIDogJ2NlbnRlci1taWRkbGUnKTtcblxuICAgICAgaWYgKGV4cGFuZGVkKSB7XG4gICAgICAgIGF0dGFjaFRhc2tNYXJrZXJzKHBhcmVudEdmeCwgZWxlbWVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdHRhY2hUYXNrTWFya2VycyhwYXJlbnRHZngsIGVsZW1lbnQsIFsnU3ViUHJvY2Vzc01hcmtlciddKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlY3Q7XG4gICAgfSxcbiAgICAnYnBtbjpBZEhvY1N1YlByb2Nlc3MnOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpTdWJQcm9jZXNzJykocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICB9LFxuICAgICdicG1uOlRyYW5zYWN0aW9uJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgb3V0ZXIgPSByZW5kZXJlcignYnBtbjpTdWJQcm9jZXNzJykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgdmFyIGlubmVyQXR0cnMgPSBzdHlsZXMuc3R5bGUoWyAnbm8tZmlsbCcsICduby1ldmVudHMnIF0sIHtcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgLyogaW5uZXIgcGF0aCAqLyBkcmF3UmVjdChwYXJlbnRHZngsIGVsZW1lbnQud2lkdGgsIGVsZW1lbnQuaGVpZ2h0LCBUQVNLX0JPUkRFUl9SQURJVVMgLSAyLCBJTk5FUl9PVVRFUl9ESVNULCBpbm5lckF0dHJzKTtcblxuICAgICAgcmV0dXJuIG91dGVyO1xuICAgIH0sXG4gICAgJ2JwbW46Q2FsbEFjdGl2aXR5JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46U3ViUHJvY2VzcycpKHBhcmVudEdmeCwgZWxlbWVudCwge1xuICAgICAgICBzdHJva2VXaWR0aDogNVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpQYXJ0aWNpcGFudCc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuXG4gICAgICB2YXIgYXR0cnMgPSB7XG4gICAgICAgIGZpbGxPcGFjaXR5OiBERUZBVUxUX0ZJTExfT1BBQ0lUWSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH07XG5cbiAgICAgIHZhciBsYW5lID0gcmVuZGVyZXIoJ2JwbW46TGFuZScpKHBhcmVudEdmeCwgZWxlbWVudCwgYXR0cnMpO1xuXG4gICAgICB2YXIgZXhwYW5kZWRQb29sID0gaXNFeHBhbmRlZChlbGVtZW50KTtcblxuICAgICAgaWYgKGV4cGFuZGVkUG9vbCkge1xuICAgICAgICBkcmF3TGluZShwYXJlbnRHZngsIFtcbiAgICAgICAgICB7IHg6IDMwLCB5OiAwIH0sXG4gICAgICAgICAgeyB4OiAzMCwgeTogZWxlbWVudC5oZWlnaHQgfVxuICAgICAgICBdLCB7XG4gICAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgdGV4dCA9IGdldFNlbWFudGljKGVsZW1lbnQpLm5hbWU7XG4gICAgICAgIHJlbmRlckxhbmVMYWJlbChwYXJlbnRHZngsIHRleHQsIGVsZW1lbnQpO1xuICAgICAgfSBlbHNlIHtcblxuICAgICAgICAvLyBDb2xsYXBzZWQgcG9vbCBkcmF3IHRleHQgaW5saW5lXG4gICAgICAgIHZhciB0ZXh0MiA9IGdldFNlbWFudGljKGVsZW1lbnQpLm5hbWU7XG4gICAgICAgIHJlbmRlckxhYmVsKHBhcmVudEdmeCwgdGV4dDIsIHtcbiAgICAgICAgICBib3g6IGVsZW1lbnQsIGFsaWduOiAnY2VudGVyLW1pZGRsZScsXG4gICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgIGZpbGw6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB2YXIgcGFydGljaXBhbnRNdWx0aXBsaWNpdHkgPSAhIShnZXRTZW1hbnRpYyhlbGVtZW50KS5wYXJ0aWNpcGFudE11bHRpcGxpY2l0eSk7XG5cbiAgICAgIGlmIChwYXJ0aWNpcGFudE11bHRpcGxpY2l0eSkge1xuICAgICAgICByZW5kZXJlcignUGFydGljaXBhbnRNdWx0aXBsaWNpdHlNYXJrZXInKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbGFuZTtcbiAgICB9LFxuICAgICdicG1uOkxhbmUnOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIGF0dHJzKSB7XG4gICAgICB2YXIgcmVjdCA9IGRyYXdSZWN0KHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIDAsIGFzc2lnbih7XG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgZmlsbE9wYWNpdHk6IEhJR0hfRklMTF9PUEFDSVRZLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0sIGF0dHJzKSk7XG5cbiAgICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgICBpZiAoc2VtYW50aWMuJHR5cGUgPT09ICdicG1uOkxhbmUnKSB7XG4gICAgICAgIHZhciB0ZXh0ID0gc2VtYW50aWMubmFtZTtcbiAgICAgICAgcmVuZGVyTGFuZUxhYmVsKHBhcmVudEdmeCwgdGV4dCwgZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZWN0O1xuICAgIH0sXG4gICAgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheSc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIGRpYW1vbmQgPSByZW5kZXJlcignYnBtbjpHYXRld2F5JykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgLyogY2lyY2xlIHBhdGggKi9cbiAgICAgIGRyYXdDaXJjbGUocGFyZW50R2Z4LCBlbGVtZW50LndpZHRoLCBlbGVtZW50LmhlaWdodCwgZWxlbWVudC5oZWlnaHQgKiAwLjI0LCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAyLjUsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGRpYW1vbmQ7XG4gICAgfSxcbiAgICAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgZGlhbW9uZCA9IHJlbmRlcmVyKCdicG1uOkdhdGV3YXknKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0dBVEVXQVlfRVhDTFVTSVZFJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDAuNCxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAwLjQsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjMyLFxuICAgICAgICAgIG15OiAwLjNcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmICgoZ2V0RGkoZWxlbWVudCkuaXNNYXJrZXJWaXNpYmxlKSkge1xuICAgICAgICBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgICAgZmlsbDogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSxcbiAgICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBkaWFtb25kO1xuICAgIH0sXG4gICAgJ2JwbW46Q29tcGxleEdhdGV3YXknOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBkaWFtb25kID0gcmVuZGVyZXIoJ2JwbW46R2F0ZXdheScpKHBhcmVudEdmeCwgZWxlbWVudCk7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnR0FURVdBWV9DT01QTEVYJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDAuNSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOjAuNSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNDYsXG4gICAgICAgICAgbXk6IDAuMjZcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qIGNvbXBsZXggcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gZGlhbW9uZDtcbiAgICB9LFxuICAgICdicG1uOlBhcmFsbGVsR2F0ZXdheSc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIGRpYW1vbmQgPSByZW5kZXJlcignYnBtbjpHYXRld2F5JykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdHQVRFV0FZX1BBUkFMTEVMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDAuNixcbiAgICAgICAgeVNjYWxlRmFjdG9yOjAuNixcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNDYsXG4gICAgICAgICAgbXk6IDAuMlxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyogcGFyYWxsZWwgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gZGlhbW9uZDtcbiAgICB9LFxuICAgICdicG1uOkV2ZW50QmFzZWRHYXRld2F5JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG5cbiAgICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgICB2YXIgZGlhbW9uZCA9IHJlbmRlcmVyKCdicG1uOkdhdGV3YXknKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICAvKiBvdXRlciBjaXJjbGUgcGF0aCAqLyBkcmF3Q2lyY2xlKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIGVsZW1lbnQuaGVpZ2h0ICogMC4yMCwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogJ25vbmUnLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgdHlwZSA9IHNlbWFudGljLmV2ZW50R2F0ZXdheVR5cGU7XG4gICAgICB2YXIgaW5zdGFudGlhdGUgPSAhIXNlbWFudGljLmluc3RhbnRpYXRlO1xuXG4gICAgICBmdW5jdGlvbiBkcmF3RXZlbnQoKSB7XG5cbiAgICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdHQVRFV0FZX0VWRU5UX0JBU0VEJywge1xuICAgICAgICAgIHhTY2FsZUZhY3RvcjogMC4xOCxcbiAgICAgICAgICB5U2NhbGVGYWN0b3I6IDAuMTgsXG4gICAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgICAgY29udGFpbmVySGVpZ2h0OiBlbGVtZW50LmhlaWdodCxcbiAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgbXg6IDAuMzYsXG4gICAgICAgICAgICBteTogMC40NFxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIGF0dHJzID0ge1xuICAgICAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCAnbm9uZScpLFxuICAgICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qIGV2ZW50IHBhdGggKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwgYXR0cnMpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZSA9PT0gJ1BhcmFsbGVsJykge1xuXG4gICAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnR0FURVdBWV9QQVJBTExFTCcsIHtcbiAgICAgICAgICB4U2NhbGVGYWN0b3I6IDAuNCxcbiAgICAgICAgICB5U2NhbGVGYWN0b3I6MC40LFxuICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICAgIG14OiAwLjQ3NCxcbiAgICAgICAgICAgIG15OiAwLjI5NlxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHBhcmFsbGVsUGF0aCA9IGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEpO1xuICAgICAgICBzdmdBdHRyKHBhcmFsbGVsUGF0aCwge1xuICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICAgIGZpbGw6ICdub25lJ1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ0V4Y2x1c2l2ZScpIHtcblxuICAgICAgICBpZiAoIWluc3RhbnRpYXRlKSB7XG4gICAgICAgICAgdmFyIGlubmVyQ2lyY2xlID0gZHJhd0NpcmNsZShwYXJlbnRHZngsIGVsZW1lbnQud2lkdGgsIGVsZW1lbnQuaGVpZ2h0LCBlbGVtZW50LmhlaWdodCAqIDAuMjYpO1xuICAgICAgICAgIHN2Z0F0dHIoaW5uZXJDaXJjbGUsIHtcbiAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICAgICAgZmlsbDogJ25vbmUnLFxuICAgICAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBkcmF3RXZlbnQoKTtcbiAgICAgIH1cblxuXG4gICAgICByZXR1cm4gZGlhbW9uZDtcbiAgICB9LFxuICAgICdicG1uOkdhdGV3YXknOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBmaWxsT3BhY2l0eTogREVGQVVMVF9GSUxMX09QQUNJVFksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIGRyYXdEaWFtb25kKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIGF0dHJzKTtcbiAgICB9LFxuICAgICdicG1uOlNlcXVlbmNlRmxvdyc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIHBhdGhEYXRhID0gY3JlYXRlUGF0aEZyb21Db25uZWN0aW9uKGVsZW1lbnQpO1xuXG4gICAgICB2YXIgZmlsbCA9IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgICBzdHJva2UgPSBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpO1xuXG4gICAgICB2YXIgYXR0cnMgPSB7XG4gICAgICAgIHN0cm9rZUxpbmVqb2luOiAncm91bmQnLFxuICAgICAgICBtYXJrZXJFbmQ6IG1hcmtlcignc2VxdWVuY2VmbG93LWVuZCcsIGZpbGwsIHN0cm9rZSksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfTtcblxuICAgICAgdmFyIHBhdGggPSBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCBhdHRycyk7XG5cbiAgICAgIHZhciBzZXF1ZW5jZUZsb3cgPSBnZXRTZW1hbnRpYyhlbGVtZW50KTtcblxuICAgICAgdmFyIHNvdXJjZTtcblxuICAgICAgaWYgKGVsZW1lbnQuc291cmNlKSB7XG4gICAgICAgIHNvdXJjZSA9IGVsZW1lbnQuc291cmNlLmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgICAgIC8vIGNvbmRpdGlvbmFsIGZsb3cgbWFya2VyXG4gICAgICAgIGlmIChzZXF1ZW5jZUZsb3cuY29uZGl0aW9uRXhwcmVzc2lvbiAmJiBzb3VyY2UuJGluc3RhbmNlT2YoJ2JwbW46QWN0aXZpdHknKSkge1xuICAgICAgICAgIHN2Z0F0dHIocGF0aCwge1xuICAgICAgICAgICAgbWFya2VyU3RhcnQ6IG1hcmtlcignY29uZGl0aW9uYWwtZmxvdy1tYXJrZXInLCBmaWxsLCBzdHJva2UpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkZWZhdWx0IG1hcmtlclxuICAgICAgICBpZiAoc291cmNlLmRlZmF1bHQgJiYgKHNvdXJjZS4kaW5zdGFuY2VPZignYnBtbjpHYXRld2F5JykgfHwgc291cmNlLiRpbnN0YW5jZU9mKCdicG1uOkFjdGl2aXR5JykpICYmXG4gICAgICAgICAgICBzb3VyY2UuZGVmYXVsdCA9PT0gc2VxdWVuY2VGbG93KSB7XG4gICAgICAgICAgc3ZnQXR0cihwYXRoLCB7XG4gICAgICAgICAgICBtYXJrZXJTdGFydDogbWFya2VyKCdjb25kaXRpb25hbC1kZWZhdWx0LWZsb3ctbWFya2VyJywgZmlsbCwgc3Ryb2tlKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXRoO1xuICAgIH0sXG4gICAgJ2JwbW46QXNzb2NpYXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIGF0dHJzKSB7XG5cbiAgICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgICB2YXIgZmlsbCA9IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgICBzdHJva2UgPSBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpO1xuXG4gICAgICBhdHRycyA9IGFzc2lnbih7XG4gICAgICAgIHN0cm9rZURhc2hhcnJheTogJzAuNSwgNScsXG4gICAgICAgIHN0cm9rZUxpbmVjYXA6ICdyb3VuZCcsXG4gICAgICAgIHN0cm9rZUxpbmVqb2luOiAncm91bmQnLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0sIGF0dHJzIHx8IHt9KTtcblxuICAgICAgaWYgKHNlbWFudGljLmFzc29jaWF0aW9uRGlyZWN0aW9uID09PSAnT25lJyB8fFxuICAgICAgICAgIHNlbWFudGljLmFzc29jaWF0aW9uRGlyZWN0aW9uID09PSAnQm90aCcpIHtcbiAgICAgICAgYXR0cnMubWFya2VyRW5kID0gbWFya2VyKCdhc3NvY2lhdGlvbi1lbmQnLCBmaWxsLCBzdHJva2UpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2VtYW50aWMuYXNzb2NpYXRpb25EaXJlY3Rpb24gPT09ICdCb3RoJykge1xuICAgICAgICBhdHRycy5tYXJrZXJTdGFydCA9IG1hcmtlcignYXNzb2NpYXRpb24tc3RhcnQnLCBmaWxsLCBzdHJva2UpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZHJhd0xpbmUocGFyZW50R2Z4LCBlbGVtZW50LndheXBvaW50cywgYXR0cnMpO1xuICAgIH0sXG4gICAgJ2JwbW46RGF0YUlucHV0QXNzb2NpYXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBmaWxsID0gZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICAgIHN0cm9rZSA9IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcik7XG5cbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpBc3NvY2lhdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwge1xuICAgICAgICBtYXJrZXJFbmQ6IG1hcmtlcignYXNzb2NpYXRpb24tZW5kJywgZmlsbCwgc3Ryb2tlKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpEYXRhT3V0cHV0QXNzb2NpYXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBmaWxsID0gZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICAgIHN0cm9rZSA9IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcik7XG5cbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpBc3NvY2lhdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwge1xuICAgICAgICBtYXJrZXJFbmQ6IG1hcmtlcignYXNzb2NpYXRpb24tZW5kJywgZmlsbCwgc3Ryb2tlKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpNZXNzYWdlRmxvdyc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuXG4gICAgICB2YXIgc2VtYW50aWMgPSBnZXRTZW1hbnRpYyhlbGVtZW50KSxcbiAgICAgICAgICBkaSA9IGdldERpKGVsZW1lbnQpO1xuXG4gICAgICB2YXIgZmlsbCA9IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgICBzdHJva2UgPSBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpO1xuXG4gICAgICB2YXIgcGF0aERhdGEgPSBjcmVhdGVQYXRoRnJvbUNvbm5lY3Rpb24oZWxlbWVudCk7XG5cbiAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgbWFya2VyRW5kOiBtYXJrZXIoJ21lc3NhZ2VmbG93LWVuZCcsIGZpbGwsIHN0cm9rZSksXG4gICAgICAgIG1hcmtlclN0YXJ0OiBtYXJrZXIoJ21lc3NhZ2VmbG93LXN0YXJ0JywgZmlsbCwgc3Ryb2tlKSxcbiAgICAgICAgc3Ryb2tlRGFzaGFycmF5OiAnMTAsIDEyJyxcbiAgICAgICAgc3Ryb2tlTGluZWNhcDogJ3JvdW5kJyxcbiAgICAgICAgc3Ryb2tlTGluZWpvaW46ICdyb3VuZCcsXG4gICAgICAgIHN0cm9rZVdpZHRoOiAnMS41cHgnLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH07XG5cbiAgICAgIHZhciBwYXRoID0gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwgYXR0cnMpO1xuXG4gICAgICBpZiAoc2VtYW50aWMubWVzc2FnZVJlZikge1xuICAgICAgICB2YXIgbWlkUG9pbnQgPSBwYXRoLmdldFBvaW50QXRMZW5ndGgocGF0aC5nZXRUb3RhbExlbmd0aCgpIC8gMik7XG5cbiAgICAgICAgdmFyIG1hcmtlclBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdNRVNTQUdFX0ZMT1dfTUFSS0VSJywge1xuICAgICAgICAgIGFic3Bvczoge1xuICAgICAgICAgICAgeDogbWlkUG9pbnQueCxcbiAgICAgICAgICAgIHk6IG1pZFBvaW50LnlcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHZhciBtZXNzYWdlQXR0cnMgPSB7IHN0cm9rZVdpZHRoOiAxIH07XG5cbiAgICAgICAgaWYgKGRpLm1lc3NhZ2VWaXNpYmxlS2luZCA9PT0gJ2luaXRpYXRpbmcnKSB7XG4gICAgICAgICAgbWVzc2FnZUF0dHJzLmZpbGwgPSAnd2hpdGUnO1xuICAgICAgICAgIG1lc3NhZ2VBdHRycy5zdHJva2UgPSAnYmxhY2snO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1lc3NhZ2VBdHRycy5maWxsID0gJyM4ODgnO1xuICAgICAgICAgIG1lc3NhZ2VBdHRycy5zdHJva2UgPSAnd2hpdGUnO1xuICAgICAgICB9XG5cbiAgICAgICAgZHJhd1BhdGgocGFyZW50R2Z4LCBtYXJrZXJQYXRoRGF0YSwgbWVzc2FnZUF0dHJzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfSxcbiAgICAnYnBtbjpEYXRhT2JqZWN0JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0RBVEFfT0JKRUNUX1BBVEgnLCB7XG4gICAgICAgIHhTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAxLFxuICAgICAgICBjb250YWluZXJXaWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBlbGVtZW50LmhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogMC40NzQsXG4gICAgICAgICAgbXk6IDAuMjk2XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZWxlbWVudE9iamVjdCA9IGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBmaWxsT3BhY2l0eTogREVGQVVMVF9GSUxMX09QQUNJVFksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgICBpZiAoaXNDb2xsZWN0aW9uKHNlbWFudGljKSkge1xuICAgICAgICByZW5kZXJEYXRhSXRlbUNvbGxlY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGVsZW1lbnRPYmplY3Q7XG4gICAgfSxcbiAgICAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJzogYXMoJ2JwbW46RGF0YU9iamVjdCcpLFxuICAgICdicG1uOkRhdGFJbnB1dCc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuXG4gICAgICB2YXIgYXJyb3dQYXRoRGF0YSA9IHBhdGhNYXAuZ2V0UmF3UGF0aCgnREFUQV9BUlJPVycpO1xuXG4gICAgICAvLyBwYWdlXG4gICAgICB2YXIgZWxlbWVudE9iamVjdCA9IHJlbmRlcmVyKCdicG1uOkRhdGFPYmplY3QnKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICAvKiBpbnB1dCBhcnJvdyBwYXRoICovIGRyYXdQYXRoKHBhcmVudEdmeCwgYXJyb3dQYXRoRGF0YSwgeyBzdHJva2VXaWR0aDogMSB9KTtcblxuICAgICAgcmV0dXJuIGVsZW1lbnRPYmplY3Q7XG4gICAgfSxcbiAgICAnYnBtbjpEYXRhT3V0cHV0JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgYXJyb3dQYXRoRGF0YSA9IHBhdGhNYXAuZ2V0UmF3UGF0aCgnREFUQV9BUlJPVycpO1xuXG4gICAgICAvLyBwYWdlXG4gICAgICB2YXIgZWxlbWVudE9iamVjdCA9IHJlbmRlcmVyKCdicG1uOkRhdGFPYmplY3QnKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICAvKiBvdXRwdXQgYXJyb3cgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIGFycm93UGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6ICdibGFjaydcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gZWxlbWVudE9iamVjdDtcbiAgICB9LFxuICAgICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZSc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIERBVEFfU1RPUkVfUEFUSCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnREFUQV9TVE9SRScsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLFxuICAgICAgICAgIG15OiAwLjEzM1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdmFyIGVsZW1lbnRTdG9yZSA9IGRyYXdQYXRoKHBhcmVudEdmeCwgREFUQV9TVE9SRV9QQVRILCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIGZpbGxPcGFjaXR5OiBERUZBVUxUX0ZJTExfT1BBQ0lUWSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGVsZW1lbnRTdG9yZTtcbiAgICB9LFxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcblxuICAgICAgdmFyIHNlbWFudGljID0gZ2V0U2VtYW50aWMoZWxlbWVudCksXG4gICAgICAgICAgY2FuY2VsID0gc2VtYW50aWMuY2FuY2VsQWN0aXZpdHk7XG5cbiAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9O1xuXG4gICAgICBpZiAoIWNhbmNlbCkge1xuICAgICAgICBhdHRycy5zdHJva2VEYXNoYXJyYXkgPSAnNic7XG4gICAgICAgIGF0dHJzLnN0cm9rZUxpbmVjYXAgPSAncm91bmQnO1xuICAgICAgfVxuXG4gICAgICAvLyBhcHBseSBmaWxsT3BhY2l0eVxuICAgICAgdmFyIG91dGVyQXR0cnMgPSBhc3NpZ24oe30sIGF0dHJzLCB7XG4gICAgICAgIGZpbGxPcGFjaXR5OiAxXG4gICAgICB9KTtcblxuICAgICAgLy8gYXBwbHkgbm8tZmlsbFxuICAgICAgdmFyIGlubmVyQXR0cnMgPSBhc3NpZ24oe30sIGF0dHJzLCB7XG4gICAgICAgIGZpbGw6ICdub25lJ1xuICAgICAgfSk7XG5cbiAgICAgIHZhciBvdXRlciA9IHJlbmRlcmVyKCdicG1uOkV2ZW50JykocGFyZW50R2Z4LCBlbGVtZW50LCBvdXRlckF0dHJzKTtcblxuICAgICAgLyogaW5uZXIgcGF0aCAqLyBkcmF3Q2lyY2xlKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIElOTkVSX09VVEVSX0RJU1QsIGlubmVyQXR0cnMpO1xuXG4gICAgICByZW5kZXJFdmVudENvbnRlbnQoZWxlbWVudCwgcGFyZW50R2Z4KTtcblxuICAgICAgcmV0dXJuIG91dGVyO1xuICAgIH0sXG4gICAgJ2JwbW46R3JvdXAnOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcblxuICAgICAgdmFyIGdyb3VwID0gZHJhd1JlY3QocGFyZW50R2Z4LCBlbGVtZW50LndpZHRoLCBlbGVtZW50LmhlaWdodCwgVEFTS19CT1JERVJfUkFESVVTLCB7XG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSxcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIHN0cm9rZURhc2hhcnJheTogJzgsMywxLDMnLFxuICAgICAgICBmaWxsOiAnbm9uZScsXG4gICAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJ1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBncm91cDtcbiAgICB9LFxuICAgICdsYWJlbCc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgcmV0dXJuIHJlbmRlckV4dGVybmFsTGFiZWwocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICB9LFxuICAgICdicG1uOlRleHRBbm5vdGF0aW9uJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgc3R5bGUgPSB7XG4gICAgICAgICdmaWxsJzogJ25vbmUnLFxuICAgICAgICAnc3Ryb2tlJzogJ25vbmUnXG4gICAgICB9O1xuXG4gICAgICB2YXIgdGV4dEVsZW1lbnQgPSBkcmF3UmVjdChwYXJlbnRHZngsIGVsZW1lbnQud2lkdGgsIGVsZW1lbnQuaGVpZ2h0LCAwLCAwLCBzdHlsZSk7XG5cbiAgICAgIHZhciB0ZXh0UGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RFWFRfQU5OT1RBVElPTicsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjAsXG4gICAgICAgICAgbXk6IDAuMFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZHJhd1BhdGgocGFyZW50R2Z4LCB0ZXh0UGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgdmFyIHRleHQgPSBnZXRTZW1hbnRpYyhlbGVtZW50KS50ZXh0IHx8ICcnO1xuICAgICAgcmVuZGVyTGFiZWwocGFyZW50R2Z4LCB0ZXh0LCB7XG4gICAgICAgIGJveDogZWxlbWVudCxcbiAgICAgICAgYWxpZ246ICdsZWZ0LXRvcCcsXG4gICAgICAgIHBhZGRpbmc6IDUsXG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgZmlsbDogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRleHRFbGVtZW50O1xuICAgIH0sXG4gICAgJ1BhcnRpY2lwYW50TXVsdGlwbGljaXR5TWFya2VyJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgbWFya2VyUGF0aCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnTUFSS0VSX1BBUkFMTEVMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6ICgoZWxlbWVudC53aWR0aCAvIDIpIC8gZWxlbWVudC53aWR0aCksXG4gICAgICAgICAgbXk6IChlbGVtZW50LmhlaWdodCAtIDE1KSAvIGVsZW1lbnQuaGVpZ2h0XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBkcmF3TWFya2VyKCdwYXJ0aWNpcGFudC1tdWx0aXBsaWNpdHknLCBwYXJlbnRHZngsIG1hcmtlclBhdGgsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdTdWJQcm9jZXNzTWFya2VyJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgbWFya2VyUmVjdCA9IGRyYXdSZWN0KHBhcmVudEdmeCwgMTQsIDE0LCAwLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIC8vIFByb2Nlc3MgbWFya2VyIGlzIHBsYWNlZCBpbiB0aGUgbWlkZGxlIG9mIHRoZSBib3hcbiAgICAgIC8vIHRoZXJlZm9yZSBmaXhlZCB2YWx1ZXMgY2FuIGJlIHVzZWQgaGVyZVxuICAgICAgdHJhbnNsYXRlKG1hcmtlclJlY3QsIGVsZW1lbnQud2lkdGggLyAyIC0gNy41LCBlbGVtZW50LmhlaWdodCAtIDIwKTtcblxuICAgICAgdmFyIG1hcmtlclBhdGggPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ01BUktFUl9TVUJfUFJPQ0VTUycsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLjUsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMS41LFxuICAgICAgICBjb250YWluZXJXaWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBlbGVtZW50LmhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogKGVsZW1lbnQud2lkdGggLyAyIC0gNy41KSAvIGVsZW1lbnQud2lkdGgsXG4gICAgICAgICAgbXk6IChlbGVtZW50LmhlaWdodCAtIDIwKSAvIGVsZW1lbnQuaGVpZ2h0XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBkcmF3TWFya2VyKCdzdWItcHJvY2VzcycsIHBhcmVudEdmeCwgbWFya2VyUGF0aCwge1xuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnUGFyYWxsZWxNYXJrZXInOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIHBvc2l0aW9uKSB7XG4gICAgICB2YXIgbWFya2VyUGF0aCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnTUFSS0VSX1BBUkFMTEVMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6ICgoZWxlbWVudC53aWR0aCAvIDIgKyBwb3NpdGlvbi5wYXJhbGxlbCkgLyBlbGVtZW50LndpZHRoKSxcbiAgICAgICAgICBteTogKGVsZW1lbnQuaGVpZ2h0IC0gMjApIC8gZWxlbWVudC5oZWlnaHRcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGRyYXdNYXJrZXIoJ3BhcmFsbGVsJywgcGFyZW50R2Z4LCBtYXJrZXJQYXRoLCB7XG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdTZXF1ZW50aWFsTWFya2VyJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50LCBwb3NpdGlvbikge1xuICAgICAgdmFyIG1hcmtlclBhdGggPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ01BUktFUl9TRVFVRU5USUFMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6ICgoZWxlbWVudC53aWR0aCAvIDIgKyBwb3NpdGlvbi5zZXEpIC8gZWxlbWVudC53aWR0aCksXG4gICAgICAgICAgbXk6IChlbGVtZW50LmhlaWdodCAtIDE5KSAvIGVsZW1lbnQuaGVpZ2h0XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBkcmF3TWFya2VyKCdzZXF1ZW50aWFsJywgcGFyZW50R2Z4LCBtYXJrZXJQYXRoLCB7XG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdDb21wZW5zYXRpb25NYXJrZXInOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIHBvc2l0aW9uKSB7XG4gICAgICB2YXIgbWFya2VyTWF0aCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnTUFSS0VSX0NPTVBFTlNBVElPTicsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAoKGVsZW1lbnQud2lkdGggLyAyICsgcG9zaXRpb24uY29tcGVuc2F0aW9uKSAvIGVsZW1lbnQud2lkdGgpLFxuICAgICAgICAgIG15OiAoZWxlbWVudC5oZWlnaHQgLSAxMykgLyBlbGVtZW50LmhlaWdodFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZHJhd01hcmtlcignY29tcGVuc2F0aW9uJywgcGFyZW50R2Z4LCBtYXJrZXJNYXRoLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnTG9vcE1hcmtlcic6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCwgcG9zaXRpb24pIHtcbiAgICAgIHZhciBtYXJrZXJQYXRoID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdNQVJLRVJfTE9PUCcsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAoKGVsZW1lbnQud2lkdGggLyAyICsgcG9zaXRpb24ubG9vcCkgLyBlbGVtZW50LndpZHRoKSxcbiAgICAgICAgICBteTogKGVsZW1lbnQuaGVpZ2h0IC0gNykgLyBlbGVtZW50LmhlaWdodFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZHJhd01hcmtlcignbG9vcCcsIHBhcmVudEdmeCwgbWFya2VyUGF0aCwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvciksXG4gICAgICAgIHN0cm9rZUxpbmVjYXA6ICdyb3VuZCcsXG4gICAgICAgIHN0cm9rZU1pdGVybGltaXQ6IDAuNVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnQWRob2NNYXJrZXInOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIHBvc2l0aW9uKSB7XG4gICAgICB2YXIgbWFya2VyUGF0aCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnTUFSS0VSX0FESE9DJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6ICgoZWxlbWVudC53aWR0aCAvIDIgKyBwb3NpdGlvbi5hZGhvYykgLyBlbGVtZW50LndpZHRoKSxcbiAgICAgICAgICBteTogKGVsZW1lbnQuaGVpZ2h0IC0gMTUpIC8gZWxlbWVudC5oZWlnaHRcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGRyYXdNYXJrZXIoJ2FkaG9jJywgcGFyZW50R2Z4LCBtYXJrZXJQYXRoLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBhdHRhY2hUYXNrTWFya2VycyhwYXJlbnRHZngsIGVsZW1lbnQsIHRhc2tNYXJrZXJzKSB7XG4gICAgdmFyIG9iaiA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgdmFyIHN1YnByb2Nlc3MgPSB0YXNrTWFya2VycyAmJiB0YXNrTWFya2Vycy5pbmRleE9mKCdTdWJQcm9jZXNzTWFya2VyJykgIT09IC0xO1xuICAgIHZhciBwb3NpdGlvbjtcblxuICAgIGlmIChzdWJwcm9jZXNzKSB7XG4gICAgICBwb3NpdGlvbiA9IHtcbiAgICAgICAgc2VxOiAtMjEsXG4gICAgICAgIHBhcmFsbGVsOiAtMjIsXG4gICAgICAgIGNvbXBlbnNhdGlvbjogLTQyLFxuICAgICAgICBsb29wOiAtMTgsXG4gICAgICAgIGFkaG9jOiAxMFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcG9zaXRpb24gPSB7XG4gICAgICAgIHNlcTogLTMsXG4gICAgICAgIHBhcmFsbGVsOiAtNixcbiAgICAgICAgY29tcGVuc2F0aW9uOiAtMjcsXG4gICAgICAgIGxvb3A6IDAsXG4gICAgICAgIGFkaG9jOiAxMFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3JFYWNoKHRhc2tNYXJrZXJzLCBmdW5jdGlvbihtYXJrZXIpIHtcbiAgICAgIHJlbmRlcmVyKG1hcmtlcikocGFyZW50R2Z4LCBlbGVtZW50LCBwb3NpdGlvbik7XG4gICAgfSk7XG5cbiAgICBpZiAob2JqLmlzRm9yQ29tcGVuc2F0aW9uKSB7XG4gICAgICByZW5kZXJlcignQ29tcGVuc2F0aW9uTWFya2VyJykocGFyZW50R2Z4LCBlbGVtZW50LCBwb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKG9iai4kdHlwZSA9PT0gJ2JwbW46QWRIb2NTdWJQcm9jZXNzJykge1xuICAgICAgcmVuZGVyZXIoJ0FkaG9jTWFya2VyJykocGFyZW50R2Z4LCBlbGVtZW50LCBwb3NpdGlvbik7XG4gICAgfVxuXG4gICAgdmFyIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSBvYmoubG9vcENoYXJhY3RlcmlzdGljcyxcbiAgICAgICAgaXNTZXF1ZW50aWFsID0gbG9vcENoYXJhY3RlcmlzdGljcyAmJiBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbDtcblxuICAgIGlmIChsb29wQ2hhcmFjdGVyaXN0aWNzKSB7XG5cbiAgICAgIGlmIChpc1NlcXVlbnRpYWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZW5kZXJlcignTG9vcE1hcmtlcicpKHBhcmVudEdmeCwgZWxlbWVudCwgcG9zaXRpb24pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNTZXF1ZW50aWFsID09PSBmYWxzZSkge1xuICAgICAgICByZW5kZXJlcignUGFyYWxsZWxNYXJrZXInKShwYXJlbnRHZngsIGVsZW1lbnQsIHBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzU2VxdWVudGlhbCA9PT0gdHJ1ZSkge1xuICAgICAgICByZW5kZXJlcignU2VxdWVudGlhbE1hcmtlcicpKHBhcmVudEdmeCwgZWxlbWVudCwgcG9zaXRpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlckRhdGFJdGVtQ29sbGVjdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcblxuICAgIHZhciB5UG9zaXRpb24gPSAoZWxlbWVudC5oZWlnaHQgLSAxNikgLyBlbGVtZW50LmhlaWdodDtcblxuICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnREFUQV9PQkpFQ1RfQ09MTEVDVElPTl9QQVRIJywge1xuICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgeVNjYWxlRmFjdG9yOiAxLFxuICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgbXg6IDAuNDUxLFxuICAgICAgICBteTogeVBvc2l0aW9uXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKiBjb2xsZWN0aW9uIHBhdGggKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgc3Ryb2tlV2lkdGg6IDJcbiAgICB9KTtcbiAgfVxuXG5cbiAgLy8gZXh0ZW5zaW9uIEFQSSwgdXNlIGF0IHlvdXIgb3duIHJpc2tcbiAgdGhpcy5fZHJhd1BhdGggPSBkcmF3UGF0aDtcblxufVxuXG5cbmluaGVyaXRzKEJwbW5SZW5kZXJlciwgQmFzZVJlbmRlcmVyKTtcblxuQnBtblJlbmRlcmVyLiRpbmplY3QgPSBbXG4gICdjb25maWcuYnBtblJlbmRlcmVyJyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ3N0eWxlcycsXG4gICdwYXRoTWFwJyxcbiAgJ2NhbnZhcycsXG4gICd0ZXh0UmVuZGVyZXInXG5dO1xuXG5cbkJwbW5SZW5kZXJlci5wcm90b3R5cGUuY2FuUmVuZGVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46QmFzZUVsZW1lbnQnKTtcbn07XG5cbkJwbW5SZW5kZXJlci5wcm90b3R5cGUuZHJhd1NoYXBlID0gZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gIHZhciB0eXBlID0gZWxlbWVudC50eXBlO1xuICB2YXIgaCA9IHRoaXMuaGFuZGxlcnNbdHlwZV07XG5cbiAgLyoganNoaW50IC1XMDQwICovXG4gIHJldHVybiBoKHBhcmVudEdmeCwgZWxlbWVudCk7XG59O1xuXG5CcG1uUmVuZGVyZXIucHJvdG90eXBlLmRyYXdDb25uZWN0aW9uID0gZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gIHZhciB0eXBlID0gZWxlbWVudC50eXBlO1xuICB2YXIgaCA9IHRoaXMuaGFuZGxlcnNbdHlwZV07XG5cbiAgLyoganNoaW50IC1XMDQwICovXG4gIHJldHVybiBoKHBhcmVudEdmeCwgZWxlbWVudCk7XG59O1xuXG5CcG1uUmVuZGVyZXIucHJvdG90eXBlLmdldFNoYXBlUGF0aCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSkge1xuICAgIHJldHVybiBnZXRDaXJjbGVQYXRoKGVsZW1lbnQpO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkFjdGl2aXR5JykpIHtcbiAgICByZXR1cm4gZ2V0Um91bmRSZWN0UGF0aChlbGVtZW50LCBUQVNLX0JPUkRFUl9SQURJVVMpO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkdhdGV3YXknKSkge1xuICAgIHJldHVybiBnZXREaWFtb25kUGF0aChlbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiBnZXRSZWN0UGF0aChlbGVtZW50KTtcbn07XG4iLCIvKipcbiAqIE1hcCBjb250YWluaW5nIFNWRyBwYXRocyBuZWVkZWQgYnkgQnBtblJlbmRlcmVyLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFBhdGhNYXAoKSB7XG5cbiAgLyoqXG4gICAqIENvbnRhaW5zIGEgbWFwIG9mIHBhdGggZWxlbWVudHNcbiAgICpcbiAgICogPGgxPlBhdGggZGVmaW5pdGlvbjwvaDE+XG4gICAqIEEgcGFyYW1ldGVyaXplZCBwYXRoIGlzIGRlZmluZWQgbGlrZSB0aGlzOlxuICAgKiA8cHJlPlxuICAgKiAnR0FURVdBWV9QQVJBTExFTCc6IHtcbiAgICogICBkOiAnbSB7bXh9LHtteX0ge2UueDB9LDAgMCx7ZS54MX0ge2UueDF9LDAgMCx7ZS55MH0gLXtlLngxfSwwIDAse2UueTF9ICcgK1xuICAgICAgICAgICcte2UueDB9LDAgMCwte2UueTF9IC17ZS54MX0sMCAwLC17ZS55MH0ge2UueDF9LDAgeicsXG4gICAqICAgaGVpZ2h0OiAxNy41LFxuICAgKiAgIHdpZHRoOiAgMTcuNSxcbiAgICogICBoZWlnaHRFbGVtZW50czogWzIuNSwgNy41XSxcbiAgICogICB3aWR0aEVsZW1lbnRzOiBbMi41LCA3LjVdXG4gICAqIH1cbiAgICogPC9wcmU+XG4gICAqIDxwPkl0J3MgaW1wb3J0YW50IHRvIHNwZWNpZnkgYSBjb3JyZWN0IDxiPmhlaWdodCBhbmQgd2lkdGg8L2I+IGZvciB0aGUgcGF0aCBhcyB0aGUgc2NhbGluZ1xuICAgKiBpcyBiYXNlZCBvbiB0aGUgcmF0aW8gYmV0d2VlbiB0aGUgc3BlY2lmaWVkIGhlaWdodCBhbmQgd2lkdGggaW4gdGhpcyBvYmplY3QgYW5kIHRoZVxuICAgKiBoZWlnaHQgYW5kIHdpZHRoIHRoYXQgaXMgc2V0IGFzIHNjYWxlIHRhcmdldCAoTm90ZSB4LHkgY29vcmRpbmF0ZXMgd2lsbCBiZSBzY2FsZWQgd2l0aFxuICAgKiBpbmRpdmlkdWFsIHJhdGlvcykuPC9wPlxuICAgKiA8cD5UaGUgJzxiPmhlaWdodEVsZW1lbnRzPC9iPicgYW5kICc8Yj53aWR0aEVsZW1lbnRzPC9iPicgYXJyYXkgbXVzdCBjb250YWluIHRoZSB2YWx1ZXMgdGhhdCB3aWxsIGJlIHNjYWxlZC5cbiAgICogVGhlIHNjYWxpbmcgaXMgYmFzZWQgb24gdGhlIGNvbXB1dGVkIHJhdGlvcy5cbiAgICogQ29vcmRpbmF0ZXMgb24gdGhlIHkgYXhpcyBzaG91bGQgYmUgaW4gdGhlIDxiPmhlaWdodEVsZW1lbnQ8L2I+J3MgYXJyYXksIHRoZXkgd2lsbCBiZSBzY2FsZWQgdXNpbmdcbiAgICogdGhlIGNvbXB1dGVkIHJhdGlvIGNvZWZmaWNpZW50LlxuICAgKiBJbiB0aGUgcGFyYW1ldGVyaXplZCBwYXRoIHRoZSBzY2FsZWQgdmFsdWVzIGNhbiBiZSBhY2Nlc3NlZCB0aHJvdWdoIHRoZSAnZScgb2JqZWN0IGluIHt9IGJyYWNrZXRzLlxuICAgKiAgIDx1bD5cbiAgICogICAgPGxpPlRoZSB2YWx1ZXMgZm9yIHRoZSB5IGF4aXMgY2FuIGJlIGFjY2Vzc2VkIGluIHRoZSBwYXRoIHN0cmluZyB1c2luZyB7ZS55MH0sIHtlLnkxfSwgLi4uLjwvbGk+XG4gICAqICAgIDxsaT5UaGUgdmFsdWVzIGZvciB0aGUgeCBheGlzIGNhbiBiZSBhY2Nlc3NlZCBpbiB0aGUgcGF0aCBzdHJpbmcgdXNpbmcge2UueDB9LCB7ZS54MX0sIC4uLi48L2xpPlxuICAgKiAgIDwvdWw+XG4gICAqICAgVGhlIG51bWJlcnMgeDAsIHgxIHJlc3BlY3RpdmVseSB5MCwgeTEsIC4uLiBtYXAgdG8gdGhlIGNvcnJlc3BvbmRpbmcgYXJyYXkgaW5kZXguXG4gICAqIDwvcD5cbiAgICovXG4gIHRoaXMucGF0aE1hcCA9IHtcbiAgICAnRVZFTlRfTUVTU0FHRSc6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSBsIDAse2UueTF9IGwge2UueDF9LDAgbCAwLC17ZS55MX0geiBsIHtlLngwfSx7ZS55MH0gbCB7ZS54MH0sLXtlLnkwfScsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6ICAzNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNiwgMTRdLFxuICAgICAgd2lkdGhFbGVtZW50czogWzEwLjUsIDIxXVxuICAgIH0sXG4gICAgJ0VWRU5UX1NJR05BTCc6IHtcbiAgICAgIGQ6ICdNIHtteH0se215fSBsIHtlLngwfSx7ZS55MH0gbCAte2UueDF9LDAgWicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6IDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFsxOF0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMTAsIDIwXVxuICAgIH0sXG4gICAgJ0VWRU5UX0VTQ0FMQVRJT04nOiB7XG4gICAgICBkOiAnTSB7bXh9LHtteX0gbCB7ZS54MH0se2UueTB9IGwgLXtlLngwfSwte2UueTF9IGwgLXtlLngwfSx7ZS55MX0gWicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6IDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFsyMCwgN10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbOF1cbiAgICB9LFxuICAgICdFVkVOVF9DT05ESVRJT05BTCc6IHtcbiAgICAgIGQ6ICdNIHtlLngwfSx7ZS55MH0gbCB7ZS54MX0sMCBsIDAse2UueTJ9IGwgLXtlLngxfSwwIFogJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTN9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTR9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTV9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTZ9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTd9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTh9IGwge2UueDB9LDAgJyxcbiAgICAgIGhlaWdodDogMzYsXG4gICAgICB3aWR0aDogIDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFs4LjUsIDE0LjUsIDE4LCAxMS41LCAxNC41LCAxNy41LCAyMC41LCAyMy41LCAyNi41XSxcbiAgICAgIHdpZHRoRWxlbWVudHM6ICBbMTAuNSwgMTQuNSwgMTIuNV1cbiAgICB9LFxuICAgICdFVkVOVF9MSU5LJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IDAse2UueTB9IC17ZS54MX0sMCAwLHtlLnkxfSB7ZS54MX0sMCAwLHtlLnkwfSB7ZS54MH0sLXtlLnkyfSAte2UueDB9LC17ZS55Mn0geicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6IDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFs0LjQzNzUsIDYuNzUsIDcuODEyNV0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbOS44NDM3NSwgMTMuNV1cbiAgICB9LFxuICAgICdFVkVOVF9FUlJPUic6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSB7ZS54MH0sLXtlLnkwfSB7ZS54MX0sLXtlLnkxfSB7ZS54Mn0se2UueTJ9IHtlLngzfSwte2UueTN9IC17ZS54NH0se2UueTR9IC17ZS54NX0sLXtlLnk1fSB6JyxcbiAgICAgIGhlaWdodDogMzYsXG4gICAgICB3aWR0aDogMzYsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzAuMDIzLCA4LjczNywgOC4xNTEsIDE2LjU2NCwgMTAuNTkxLCA4LjcxNF0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMC4wODUsIDYuNjcyLCA2Ljk3LCA0LjI3MywgNS4zMzcsIDYuNjM2XVxuICAgIH0sXG4gICAgJ0VWRU5UX0NBTkNFTF80NSc6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSAte2UueDF9LDAgMCx7ZS54MH0ge2UueDF9LDAgMCx7ZS55MX0ge2UueDB9LDAgJyArXG4gICAgICAgICcwLC17ZS55MX0ge2UueDF9LDAgMCwte2UueTB9IC17ZS54MX0sMCAwLC17ZS55MX0gLXtlLngwfSwwIHonLFxuICAgICAgaGVpZ2h0OiAzNixcbiAgICAgIHdpZHRoOiAzNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNC43NSwgOC41XSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFs0Ljc1LCA4LjVdXG4gICAgfSxcbiAgICAnRVZFTlRfQ09NUEVOU0FUSU9OJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IHtlLngwfSwte2UueTB9IDAse2UueTF9IHogbSB7ZS54MX0sLXtlLnkyfSB7ZS54Mn0sLXtlLnkzfSAwLHtlLnkxfSAte2UueDJ9LC17ZS55M30geicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6IDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFs2LjUsIDEzLCAwLjQsIDYuMV0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbOSwgOS4zLCA4LjddXG4gICAgfSxcbiAgICAnRVZFTlRfVElNRVJfV0gnOiB7XG4gICAgICBkOiAnTSB7bXh9LHtteX0gbCB7ZS54MH0sLXtlLnkwfSBtIC17ZS54MH0se2UueTB9IGwge2UueDF9LHtlLnkxfSAnLFxuICAgICAgaGVpZ2h0OiAzNixcbiAgICAgIHdpZHRoOiAgMzYsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzEwLCAyXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFszLCA3XVxuICAgIH0sXG4gICAgJ0VWRU5UX1RJTUVSX0xJTkUnOiB7XG4gICAgICBkOiAgJ00ge214fSx7bXl9ICcgK1xuICAgICAgICAgICdtIHtlLngwfSx7ZS55MH0gbCAte2UueDF9LHtlLnkxfSAnLFxuICAgICAgaGVpZ2h0OiAzNixcbiAgICAgIHdpZHRoOiAgMzYsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzEwLCAzXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFswLCAwXVxuICAgIH0sXG4gICAgJ0VWRU5UX01VTFRJUExFJzoge1xuICAgICAgZDonbSB7bXh9LHtteX0ge2UueDF9LC17ZS55MH0ge2UueDF9LHtlLnkwfSAte2UueDB9LHtlLnkxfSAte2UueDJ9LDAgeicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6ICAzNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNi4yODA5OSwgMTIuNTYxOTldLFxuICAgICAgd2lkdGhFbGVtZW50czogWzMuMTQwNSwgOS40MjE0OSwgMTIuNTYxOThdXG4gICAgfSxcbiAgICAnRVZFTlRfUEFSQUxMRUxfTVVMVElQTEUnOiB7XG4gICAgICBkOidtIHtteH0se215fSB7ZS54MH0sMCAwLHtlLnkxfSB7ZS54MX0sMCAwLHtlLnkwfSAte2UueDF9LDAgMCx7ZS55MX0gJyArXG4gICAgICAgICcte2UueDB9LDAgMCwte2UueTF9IC17ZS54MX0sMCAwLC17ZS55MH0ge2UueDF9LDAgeicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6ICAzNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbMi41NjIyOCwgNy42ODY4M10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMi41NjIyOCwgNy42ODY4M11cbiAgICB9LFxuICAgICdHQVRFV0FZX0VYQ0xVU0lWRSc6IHtcbiAgICAgIGQ6J20ge214fSx7bXl9IHtlLngwfSx7ZS55MH0ge2UueDF9LHtlLnkwfSB7ZS54Mn0sMCB7ZS54NH0se2UueTJ9ICcgK1xuICAgICAgICAgICAgICAgICAgICAne2UueDR9LHtlLnkxfSB7ZS54Mn0sMCB7ZS54MX0se2UueTN9IHtlLngwfSx7ZS55M30gJyArXG4gICAgICAgICAgICAgICAgICAgICd7ZS54M30sMCB7ZS54NX0se2UueTF9IHtlLng1fSx7ZS55Mn0ge2UueDN9LDAgeicsXG4gICAgICBoZWlnaHQ6IDE3LjUsXG4gICAgICB3aWR0aDogIDE3LjUsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzguNSwgNi41MzEyLCAtNi41MzEyLCAtOC41XSxcbiAgICAgIHdpZHRoRWxlbWVudHM6ICBbNi41LCAtNi41LCAzLCAtMywgNSwgLTVdXG4gICAgfSxcbiAgICAnR0FURVdBWV9QQVJBTExFTCc6IHtcbiAgICAgIGQ6J20ge214fSx7bXl9IDAse2UueTF9IC17ZS54MX0sMCAwLHtlLnkwfSB7ZS54MX0sMCAwLHtlLnkxfSB7ZS54MH0sMCAnICtcbiAgICAgICAgJzAsLXtlLnkxfSB7ZS54MX0sMCAwLC17ZS55MH0gLXtlLngxfSwwIDAsLXtlLnkxfSAte2UueDB9LDAgeicsXG4gICAgICBoZWlnaHQ6IDMwLFxuICAgICAgd2lkdGg6ICAzMCxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNSwgMTIuNV0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbNSwgMTIuNV1cbiAgICB9LFxuICAgICdHQVRFV0FZX0VWRU5UX0JBU0VEJzoge1xuICAgICAgZDonbSB7bXh9LHtteX0ge2UueDB9LHtlLnkwfSB7ZS54MH0se2UueTF9IHtlLngxfSx7ZS55Mn0ge2UueDJ9LDAgeicsXG4gICAgICBoZWlnaHQ6IDExLFxuICAgICAgd2lkdGg6ICAxMSxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbLTYsIDYsIDEyLCAtMTJdLFxuICAgICAgd2lkdGhFbGVtZW50czogWzksIC0zLCAtMTJdXG4gICAgfSxcbiAgICAnR0FURVdBWV9DT01QTEVYJzoge1xuICAgICAgZDonbSB7bXh9LHtteX0gMCx7ZS55MH0gLXtlLngwfSwte2UueTF9IC17ZS54MX0se2UueTJ9IHtlLngwfSx7ZS55MX0gLXtlLngyfSwwIDAse2UueTN9ICcgK1xuICAgICAgICAne2UueDJ9LDAgIC17ZS54MH0se2UueTF9IGwge2UueDF9LHtlLnkyfSB7ZS54MH0sLXtlLnkxfSAwLHtlLnkwfSB7ZS54M30sMCAwLC17ZS55MH0ge2UueDB9LHtlLnkxfSAnICtcbiAgICAgICAgJ3tlLngxfSwte2UueTJ9IC17ZS54MH0sLXtlLnkxfSB7ZS54Mn0sMCAwLC17ZS55M30gLXtlLngyfSwwIHtlLngwfSwte2UueTF9IC17ZS54MX0sLXtlLnkyfSAnICtcbiAgICAgICAgJy17ZS54MH0se2UueTF9IDAsLXtlLnkwfSAte2UueDN9LDAgeicsXG4gICAgICBoZWlnaHQ6IDE3LjEyNSxcbiAgICAgIHdpZHRoOiAgMTcuMTI1LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFs0Ljg3NSwgMy40Mzc1LCAyLjEyNSwgM10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMy40Mzc1LCAyLjEyNSwgNC44NzUsIDNdXG4gICAgfSxcbiAgICAnREFUQV9PQkpFQ1RfUEFUSCc6IHtcbiAgICAgIGQ6J20gMCwwIHtlLngxfSwwIHtlLngwfSx7ZS55MH0gMCx7ZS55MX0gLXtlLngyfSwwIDAsLXtlLnkyfSB7ZS54MX0sMCAwLHtlLnkwfSB7ZS54MH0sMCcsXG4gICAgICBoZWlnaHQ6IDYxLFxuICAgICAgd2lkdGg6ICA1MSxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbMTAsIDUwLCA2MF0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMTAsIDQwLCA1MCwgNjBdXG4gICAgfSxcbiAgICAnREFUQV9PQkpFQ1RfQ09MTEVDVElPTl9QQVRIJzoge1xuICAgICAgZDonbSB7bXh9LCB7bXl9ICcgK1xuICAgICAgICAnbSAgMCAxNSAgbCAwIC0xNSAnICtcbiAgICAgICAgJ20gIDQgMTUgIGwgMCAtMTUgJyArXG4gICAgICAgICdtICA0IDE1ICBsIDAgLTE1ICcsXG4gICAgICBoZWlnaHQ6IDYxLFxuICAgICAgd2lkdGg6ICA1MSxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbMTJdLFxuICAgICAgd2lkdGhFbGVtZW50czogWzEsIDYsIDEyLCAxNV1cbiAgICB9LFxuICAgICdEQVRBX0FSUk9XJzoge1xuICAgICAgZDonbSA1LDkgOSwwIDAsLTMgNSw1IC01LDUgMCwtMyAtOSwwIHonLFxuICAgICAgaGVpZ2h0OiA2MSxcbiAgICAgIHdpZHRoOiAgNTEsXG4gICAgICBoZWlnaHRFbGVtZW50czogW10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbXVxuICAgIH0sXG4gICAgJ0RBVEFfU1RPUkUnOiB7XG4gICAgICBkOidtICB7bXh9LHtteX0gJyArXG4gICAgICAgICdsICAwLHtlLnkyfSAnICtcbiAgICAgICAgJ2MgIHtlLngwfSx7ZS55MX0ge2UueDF9LHtlLnkxfSAge2UueDJ9LDAgJyArXG4gICAgICAgICdsICAwLC17ZS55Mn0gJyArXG4gICAgICAgICdjIC17ZS54MH0sLXtlLnkxfSAte2UueDF9LC17ZS55MX0gLXtlLngyfSwwJyArXG4gICAgICAgICdjICB7ZS54MH0se2UueTF9IHtlLngxfSx7ZS55MX0gIHtlLngyfSwwICcgK1xuICAgICAgICAnbSAgLXtlLngyfSx7ZS55MH0nICtcbiAgICAgICAgJ2MgIHtlLngwfSx7ZS55MX0ge2UueDF9LHtlLnkxfSB7ZS54Mn0sMCcgK1xuICAgICAgICAnbSAgLXtlLngyfSx7ZS55MH0nICtcbiAgICAgICAgJ2MgIHtlLngwfSx7ZS55MX0ge2UueDF9LHtlLnkxfSAge2UueDJ9LDAnLFxuICAgICAgaGVpZ2h0OiA2MSxcbiAgICAgIHdpZHRoOiAgNjEsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzcsIDEwLCA0NV0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiAgWzIsIDU4LCA2MF1cbiAgICB9LFxuICAgICdURVhUX0FOTk9UQVRJT04nOiB7XG4gICAgICBkOiAnbSB7bXh9LCB7bXl9IG0gMTAsMCBsIC0xMCwwIGwgMCx7ZS55MH0gbCAxMCwwJyxcbiAgICAgIGhlaWdodDogMzAsXG4gICAgICB3aWR0aDogMTAsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzMwXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFsxMF1cbiAgICB9LFxuICAgICdNQVJLRVJfU1VCX1BST0NFU1MnOiB7XG4gICAgICBkOiAnbXtteH0se215fSBtIDcsMiBsIDAsMTAgbSAtNSwtNSBsIDEwLDAnLFxuICAgICAgaGVpZ2h0OiAxMCxcbiAgICAgIHdpZHRoOiAxMCxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFtdXG4gICAgfSxcbiAgICAnTUFSS0VSX1BBUkFMTEVMJzoge1xuICAgICAgZDogJ217bXh9LHtteX0gbSAzLDIgbCAwLDEwIG0gMywtMTAgbCAwLDEwIG0gMywtMTAgbCAwLDEwJyxcbiAgICAgIGhlaWdodDogMTAsXG4gICAgICB3aWR0aDogMTAsXG4gICAgICBoZWlnaHRFbGVtZW50czogW10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbXVxuICAgIH0sXG4gICAgJ01BUktFUl9TRVFVRU5USUFMJzoge1xuICAgICAgZDogJ217bXh9LHtteX0gbSAwLDMgbCAxMCwwIG0gLTEwLDMgbCAxMCwwIG0gLTEwLDMgbCAxMCwwJyxcbiAgICAgIGhlaWdodDogMTAsXG4gICAgICB3aWR0aDogMTAsXG4gICAgICBoZWlnaHRFbGVtZW50czogW10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbXVxuICAgIH0sXG4gICAgJ01BUktFUl9DT01QRU5TQVRJT04nOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gNywtNSAwLDEwIHogbSA3LjEsLTAuMyA2LjksLTQuNyAwLDEwIC02LjksLTQuNyB6JyxcbiAgICAgIGhlaWdodDogMTAsXG4gICAgICB3aWR0aDogMjEsXG4gICAgICBoZWlnaHRFbGVtZW50czogW10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbXVxuICAgIH0sXG4gICAgJ01BUktFUl9MT09QJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IGMgMy41MjY5NzksMCA2LjM4NjE2MSwtMi44Mjk4NTggNi4zODYxNjEsLTYuMzIwNjYxIDAsLTMuNDkwODA2IC0yLjg1OTE4MiwtNi4zMjA2NjEgJyArXG4gICAgICAgICctNi4zODYxNjEsLTYuMzIwNjYxIC0zLjUyNjk3OCwwIC02LjM4NjE2LDIuODI5ODU1IC02LjM4NjE2LDYuMzIwNjYxIDAsMS43NDU0MDIgJyArXG4gICAgICAgICcwLjcxNDc5NywzLjMyNTU2NyAxLjg3MDQ2Myw0LjQ2OTM4MSAwLjU3NzgzNCwwLjU3MTkwOCAxLjI2NTg4NSwxLjAzNDcyOCAyLjAyOTkxNiwxLjM1NDU3ICcgK1xuICAgICAgICAnbCAtMC43MTgxNjMsLTMuOTA5NzkzIG0gMC43MTgxNjMsMy45MDk3OTMgLTMuODg1MjExLDAuODAyOTAyJyxcbiAgICAgIGhlaWdodDogMTMuOSxcbiAgICAgIHdpZHRoOiAxMy43LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFtdLFxuICAgICAgd2lkdGhFbGVtZW50czogW11cbiAgICB9LFxuICAgICdNQVJLRVJfQURIT0MnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gbSAwLjg0NDYxLDIuNjQ0MTEgYyAxLjA1NTMzLC0xLjIzNzgwOTk2IDIuNjQzMzcsLTIuMDc4ODIgNC4yOTY1MywtMS45Nzk5Nzk5NiAyLjA1MTYzLDAuMDgwNSAnICtcbiAgICAgICAgJzMuODU1NzksMS4xNTgwMyA1Ljc2MDgyLDEuNzkxMDcgMS4wNjM4NSwwLjM0MTM5OTk2IDIuMjQ0NTQsMC4xNDM4IDMuMTg3NTksLTAuNDM3NjcgMC42MTc0MywtMC4zMzY0MiAnICtcbiAgICAgICAgJzEuMjc3NSwtMC42NDA3OCAxLjc1NDIsLTEuMTc1MTEgMCwwLjU2MDIzIDAsMS4xMjA0NiAwLDEuNjgwNyAtMC45ODcwNiwwLjk2MjM3OTk2IC0yLjI5NzkyLDEuNjIzOTM5OTYgJyArXG4gICAgICAgICctMy42OTE4LDEuNjYxODE5OTYgLTEuMjQ0NTksMC4wOTI3IC0yLjQ2NjcxLC0wLjI0OTEgLTMuNTk1MDUsLTAuNzQ4MTIgLTEuMzU3ODksLTAuNTU5NjUgJyArXG4gICAgICAgICctMi43NTEzMywtMS4zMzQzNjk5NiAtNC4yNzAyNywtMS4xODEyMTk5NiAtMS4zNzc0MSwwLjE0NjAxIC0yLjQxODQyLDEuMTM2ODU5OTYgLTMuNDQyODgsMS45Njc4Mjk5NiB6JyxcbiAgICAgIGhlaWdodDogNCxcbiAgICAgIHdpZHRoOiAxNSxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFtdXG4gICAgfSxcbiAgICAnVEFTS19UWVBFX1NFTkQnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gbCAwLHtlLnkxfSBsIHtlLngxfSwwIGwgMCwte2UueTF9IHogbCB7ZS54MH0se2UueTB9IGwge2UueDB9LC17ZS55MH0nLFxuICAgICAgaGVpZ2h0OiAxNCxcbiAgICAgIHdpZHRoOiAgMjEsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzYsIDE0XSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFsxMC41LCAyMV1cbiAgICB9LFxuICAgICdUQVNLX1RZUEVfU0NSSVBUJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IGMgOS45NjY1NTMsLTYuMjcyNzYgLTguMDAwOTI2LC03LjkxOTMyIDIuOTY4OTY4LC0xNC45MzggbCAtOC44MDI3MjgsMCAnICtcbiAgICAgICAgJ2MgLTEwLjk2OTg5NCw3LjAxODY4IDYuOTk3NTg1LDguNjY1MjQgLTIuOTY4OTY3LDE0LjkzOCB6ICcgK1xuICAgICAgICAnbSAtNywtMTIgbCA1LDAgJyArXG4gICAgICAgICdtIC00LjUsMyBsIDQuNSwwICcgK1xuICAgICAgICAnbSAtMywzIGwgNSwwJyArXG4gICAgICAgICdtIC00LDMgbCA1LDAnLFxuICAgICAgaGVpZ2h0OiAxNSxcbiAgICAgIHdpZHRoOiAgMTIuNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNiwgMTRdLFxuICAgICAgd2lkdGhFbGVtZW50czogWzEwLjUsIDIxXVxuICAgIH0sXG4gICAgJ1RBU0tfVFlQRV9VU0VSXzEnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gYyAwLjkwOSwtMC44NDUgMS41OTQsLTIuMDQ5IDEuNTk0LC0zLjM4NSAwLC0yLjU1NCAtMS44MDUsLTQuNjIxOTk5OTkgJyArXG4gICAgICAgICctNC4zNTcsLTQuNjIxOTk5OTkgLTIuNTUxOTk5OTgsMCAtNC4yODc5OTk5OCwyLjA2Nzk5OTk5IC00LjI4Nzk5OTk4LDQuNjIxOTk5OTkgMCwxLjM0OCAnICtcbiAgICAgICAgJzAuOTc0LDIuNTYyIDEuODk1OTk5OTgsMy40MDUgLTAuNTI4OTk5OTgsMC4xODcgLTUuNjY5LDIuMDk3IC01Ljc5NCw0Ljc1NjAwMDUgdiA2LjcxOCAnICtcbiAgICAgICAgJ2ggMTcgdiAtNi43MTggYyAwLC0yLjI5ODAwMDUgLTUuNTI3OTk5NiwtNC41OTUwMDA1IC02LjA1MDk5OTYsLTQuNzc2MDAwNSB6JyArXG4gICAgICAgICdtIC04LDYgbCAwLDUuNSBtIDExLDAgbCAwLC01J1xuICAgIH0sXG4gICAgJ1RBU0tfVFlQRV9VU0VSXzInOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gbSAyLjE2MiwxLjAwOSBjIDAsMi40NDcwMDA1IC0yLjE1OCw0LjQzMTAwMDUgLTQuODIxLDQuNDMxMDAwNSAnICtcbiAgICAgICAgJy0yLjY2NDk5OTk4LDAgLTQuODIyLC0xLjk4MSAtNC44MjIsLTQuNDMxMDAwNSAnXG4gICAgfSxcbiAgICAnVEFTS19UWVBFX1VTRVJfMyc6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSBtIC02LjksLTMuODAgYyAwLDAgMi4yNTA5OTk5OCwtMi4zNTggNC4yNzM5OTk5OCwtMS4xNzcgMi4wMjQsMS4xODEgNC4yMjEsMS41MzcgJyArXG4gICAgICAgICc0LjEyNCwwLjk2NSAtMC4wOTgsLTAuNTcgLTAuMTE3LC0zLjc5MDk5OTk5IC00LjE5MSwtNC4xMzU5OTk5OSAtMy41NzQ5OTk5OCwwLjAwMSAnICtcbiAgICAgICAgJy00LjIwNzk5OTk4LDMuMzY2OTk5OTkgLTQuMjA2OTk5OTgsNC4zNDc5OTk5OSB6J1xuICAgIH0sXG4gICAgJ1RBU0tfVFlQRV9NQU5VQUwnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gYyAwLjIzNCwtMC4wMSA1LjYwNCwwLjAwOCA4LjAyOSwwLjAwNCAwLjgwOCwwIDEuMjcxLC0wLjE3MiAxLjQxNywtMC43NTIgMC4yMjcsLTAuODk4ICcgK1xuICAgICAgICAnLTAuMzM0LC0xLjMxNCAtMS4zMzgsLTEuMzE2IC0yLjQ2NywtMC4wMSAtNy44ODYsLTAuMDA0IC04LjEwOCwtMC4wMDQgLTAuMDE0LC0wLjA3OSAwLjAxNiwtMC41MzMgMCwtMC42MSAnICtcbiAgICAgICAgJzAuMTk1LC0wLjA0MiA4LjUwNywwLjAwNiA5LjYxNiwwLjAwMiAwLjg3NywtMC4wMDcgMS4zNSwtMC40MzggMS4zNTMsLTEuMjA4IDAuMDAzLC0wLjc2OCAtMC40NzksLTEuMDkgJyArXG4gICAgICAgICctMS4zNSwtMS4wOTEgLTIuOTY4LC0wLjAwMiAtOS42MTksLTAuMDEzIC05LjYxOSwtMC4wMTMgdiAtMC41OTEgYyAwLDAgNS4wNTIsLTAuMDE2IDcuMjI1LC0wLjAxNiAnICtcbiAgICAgICAgJzAuODg4LC0wLjAwMiAxLjM1NCwtMC40MTYgMS4zNTEsLTEuMTkzIC0wLjAwNiwtMC43NjEgLTAuNDkyLC0xLjE5NiAtMS4zNjEsLTEuMTk2IC0zLjQ3MywtMC4wMDUgJyArXG4gICAgICAgICctMTAuODYsLTAuMDAzIC0xMS4wODI5OTk1LC0wLjAwMyAtMC4wMjIsLTAuMDQ3IC0wLjA0NSwtMC4wOTQgLTAuMDY5LC0wLjEzOSAwLjM5Mzk5OTUsLTAuMzE5ICcgK1xuICAgICAgICAnMi4wNDA5OTk1LC0xLjYyNiAyLjQxNDk5OTUsLTIuMDE3IDAuNDY5LC0wLjQ4NzAwMDUgMC41MTksLTEuMTY1MDAwNSAwLjE2MiwtMS42MDQwMDA1IC0wLjQxNCwtMC41MTEgJyArXG4gICAgICAgICctMC45NzMsLTAuNSAtMS40OCwtMC4yMzYgLTEuNDYwOTk5NSwwLjc2NCAtNi41OTk5OTk1LDMuNjQzMDAwNSAtNy43MzI5OTk1LDQuMjcxMDAwNSAtMC45LDAuNDk5ICcgK1xuICAgICAgICAnLTEuNTE2LDEuMjUzIC0xLjg4MiwyLjE5IC0wLjM3MDAwMDAyLDAuOTUgLTAuMTcsMi4wMSAtMC4xNjYsMi45NzkgMC4wMDQsMC43MTggLTAuMjczMDAwMDIsMS4zNDUgJyArXG4gICAgICAgICctMC4wNTUsMi4wNjMgMC42MjksMi4wODcgMi40MjUsMy4zMTIgNC44NTksMy4zMTggNC42MTc5OTk1LDAuMDE0IDkuMjM3OTk5NSwtMC4xMzkgMTMuODU2OTk5NSwtMC4xNTggJyArXG4gICAgICAgICcwLjc1NSwtMC4wMDQgMS4xNzEsLTAuMzAxIDEuMTgyLC0xLjAzMyAwLjAxMiwtMC43NTQgLTAuNDIzLC0wLjk2OSAtMS4xODMsLTAuOTczIC0xLjc3OCwtMC4wMSAnICtcbiAgICAgICAgJy01LjgyNCwtMC4wMDQgLTYuMDQsLTAuMDA0IDEwZS00LC0wLjA4NCAwLjAwMywtMC41ODYgMTBlLTQsLTAuNjcgeidcbiAgICB9LFxuICAgICdUQVNLX1RZUEVfSU5TVEFOVElBVElOR19TRU5EJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IGwgMCw4LjQgbCAxMi42LDAgbCAwLC04LjQgeiBsIDYuMywzLjYgbCA2LjMsLTMuNidcbiAgICB9LFxuICAgICdUQVNLX1RZUEVfU0VSVklDRSc6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSB2IC0xLjcxMzM1IGMgMC4zNTIzMjYsLTAuMDcwNSAwLjcwMzkzMiwtMC4xNzgzOCAxLjA0NzYyOCwtMC4zMjEzMyAnICtcbiAgICAgICAgJzAuMzQ0NDE2LC0wLjE0NDY1IDAuNjY1ODIyLC0wLjMyMTMzIDAuOTY2Mzc3LC0wLjUyMTQ1IGwgMS4xOTQzMSwxLjE4MDA1IDEuNTY3NDg3LC0xLjU3Njg4ICcgK1xuICAgICAgICAnLTEuMTk1MDI4LC0xLjE4MDE0IGMgMC40MDMzNzYsLTAuNjEzOTQgMC42ODMwNzksLTEuMjk5MDggMC44MjU0NDcsLTIuMDE4MjQgbCAxLjYyMjEzMywtMC4wMSAnICtcbiAgICAgICAgJ3YgLTIuMjE5NiBsIC0xLjYzNjUxNCwwLjAxIGMgLTAuMDczMzMsLTAuMzUxNTMgLTAuMTc4MzE5LC0wLjcwMDI0IC0wLjMyMzU2NCwtMS4wNDM3MiAnICtcbiAgICAgICAgJy0wLjE0NTI0NCwtMC4zNDQwNiAtMC4zMjE0MDcsLTAuNjY0NCAtMC41MjI3MzUsLTAuOTYyMTcgbCAxLjEzMTAzNSwtMS4xMzYzMSAtMS41ODMzMDUsLTEuNTYyOTMgJyArXG4gICAgICAgICctMS4xMjk1OTgsMS4xMzU4OSBjIC0wLjYxNDA1MiwtMC40MDEwOCAtMS4zMDI4ODMsLTAuNjgwOTMgLTIuMDIyNjMzLC0wLjgyMjQ3IGwgMC4wMDkzLC0xLjYxODUyICcgK1xuICAgICAgICAnaCAtMi4yNDExNzMgbCAwLjAwNDIsMS42MzEyNCBjIC0wLjM1Mzc2MywwLjA3MzYgLTAuNzA1MzY5LDAuMTc5NzcgLTEuMDQ5Nzg1LDAuMzIzNzEgLTAuMzQ0NDE1LDAuMTQ0MzcgJyArXG4gICAgICAgICctMC42NjUxMDIsMC4zMjA5MiAtMC45NjM1MDA2LDAuNTIwNDYgbCAtMS4xNjk4NjI4LC0xLjE1ODIzIC0xLjU2Njc2OTEsMS41NzkyIDEuMTY4NDI2NSwxLjE1NjY5ICcgK1xuICAgICAgICAnYyAtMC40MDI2NTczLDAuNjEyODMgLTAuNjgzMDgsMS4yOTc5NyAtMC44MjQ3Mjg3LDIuMDE3MTMgbCAtMS42NTg4MDQxLDAuMDAzIHYgMi4yMjE3NCAnICtcbiAgICAgICAgJ2wgMS42NzI0NjQ4LC0wLjAwNiBjIDAuMDczMzI3LDAuMzUwNzcgMC4xNzk3NTk4LDAuNzAyNDMgMC4zMjQyODUxLDEuMDQ0NzIgMC4xNDUyNDI4LDAuMzQ0NDggJyArXG4gICAgICAgICcwLjMyMTQwNjQsMC42NjQ0IDAuNTIyNzMzOSwwLjk2MDY2IGwgLTEuMTk5MzQzMSwxLjE5NzIzIDEuNTg0MDI1NiwxLjU2MDExIDEuMTk2NDY2OCwtMS4xOTM0OCAnICtcbiAgICAgICAgJ2MgMC42MTQwNTE3LDAuNDAzNDYgMS4zMDI4ODI3LDAuNjgyMzIgMi4wMjMzNTE3LDAuODIzMzEgbCA3LjE5ZS00LDEuNjk4OTIgaCAyLjIyNjg0OCB6ICcgK1xuICAgICAgICAnbSAwLjIyMTQ2MiwtMy45OTU3IGMgLTEuNzg4OTQ4LDAuNzUwMiAtMy44NTc2LC0wLjA5MjggLTQuNjA5NzA1NSwtMS44NzQzOCAtMC43NTIxMDY1LC0xLjc4MzIxICcgK1xuICAgICAgICAnMC4wOTA1OTgsLTMuODQ2MjcgMS44ODAyNjQ1LC00LjU5NjA0IDEuNzg4MjMsLTAuNzQ5MzYgMy44NTY4ODEsMC4wOTI5IDQuNjA4OTg3LDEuODc0MzcgJyArXG4gICAgICAgICcwLjc1MjEwNiwxLjc4MTY1IC0wLjA5MDYsMy44NDYxMiAtMS44Nzk1NDYsNC41OTYwNSB6J1xuICAgIH0sXG4gICAgJ1RBU0tfVFlQRV9TRVJWSUNFX0ZJTEwnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gYyAtMS43ODg5NDgsMC43NTAyIC0zLjg1NzYsLTAuMDkyOCAtNC42MDk3MDU1LC0xLjg3NDM4IC0wLjc1MjEwNjUsLTEuNzgzMjEgJyArXG4gICAgICAgICcwLjA5MDU5OCwtMy44NDYyNyAxLjg4MDI2NDUsLTQuNTk2MDQgMS43ODgyMywtMC43NDkzNiAzLjg1Njg4MSwwLjA5MjkgNC42MDg5ODcsMS44NzQzNyAnICtcbiAgICAgICAgJzAuNzUyMTA2LDEuNzgxNjUgLTAuMDkwNiwzLjg0NjEyIC0xLjg3OTU0Niw0LjU5NjA1IHonXG4gICAgfSxcbiAgICAnVEFTS19UWVBFX0JVU0lORVNTX1JVTEVfSEVBREVSJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IDAsNCAyMCwwIDAsLTQgeidcbiAgICB9LFxuICAgICdUQVNLX1RZUEVfQlVTSU5FU1NfUlVMRV9NQUlOJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IDAsMTIgMjAsMCAwLC0xMiB6JyArXG4gICAgICAgICdtIDAsOCBsIDIwLDAgJyArXG4gICAgICAgICdtIC0xMywtNCBsIDAsOCdcbiAgICB9LFxuICAgICdNRVNTQUdFX0ZMT1dfTUFSS0VSJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IG0gLTEwLjUgLC03IGwgMCwxNCBsIDIxLDAgbCAwLC0xNCB6IGwgMTAuNSw2IGwgMTAuNSwtNidcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5nZXRSYXdQYXRoID0gZnVuY3Rpb24gZ2V0UmF3UGF0aChwYXRoSWQpIHtcbiAgICByZXR1cm4gdGhpcy5wYXRoTWFwW3BhdGhJZF0uZDtcbiAgfTtcblxuICAvKipcbiAgICogU2NhbGVzIHRoZSBwYXRoIHRvIHRoZSBnaXZlbiBoZWlnaHQgYW5kIHdpZHRoLlxuICAgKiA8aDE+VXNlIGNhc2U8L2gxPlxuICAgKiA8cD5Vc2UgY2FzZSBpcyB0byBzY2FsZSB0aGUgY29udGVudCBvZiBlbGVtZW50cyAoZXZlbnQsIGdhdGV3YXlzKSBiYXNlZFxuICAgKiBvbiB0aGUgZWxlbWVudCBib3VuZGluZyBib3gncyBzaXplLlxuICAgKiA8L3A+XG4gICAqIDxoMT5XaHkgbm90IHRyYW5zZm9ybTwvaDE+XG4gICAqIDxwPlNjYWxpbmcgYSBwYXRoIHdpdGggdHJhbnNmb3JtKCkgd2lsbCBhbHNvIHNjYWxlIHRoZSBzdHJva2UgYW5kIElFIGRvZXMgbm90IHN1cHBvcnRcbiAgICogdGhlIG9wdGlvbiAnbm9uLXNjYWxpbmctc3Ryb2tlJyB0byBwcmV2ZW50IHRoaXMuXG4gICAqIEFsc28gdGhlcmUgYXJlIHVzZSBjYXNlcyB3aGVyZSBvbmx5IHNvbWUgcGFydHMgb2YgYSBwYXRoIHNob3VsZCBiZVxuICAgKiBzY2FsZWQuPC9wPlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aElkIFRoZSBJRCBvZiB0aGUgcGF0aC5cbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtIDxwPlxuICAgKiAgIEV4YW1wbGUgcGFyYW0gb2JqZWN0IHNjYWxlcyB0aGUgcGF0aCB0byA2MCUgc2l6ZSBvZiB0aGUgY29udGFpbmVyIChkYXRhLndpZHRoLCBkYXRhLmhlaWdodCkuXG4gICAqICAgPHByZT5cbiAgICogICB7XG4gICAqICAgICB4U2NhbGVGYWN0b3I6IDAuNixcbiAgICogICAgIHlTY2FsZUZhY3RvcjowLjYsXG4gICAqICAgICBjb250YWluZXJXaWR0aDogZGF0YS53aWR0aCxcbiAgICogICAgIGNvbnRhaW5lckhlaWdodDogZGF0YS5oZWlnaHQsXG4gICAqICAgICBwb3NpdGlvbjoge1xuICAgKiAgICAgICBteDogMC40NixcbiAgICogICAgICAgbXk6IDAuMixcbiAgICogICAgIH1cbiAgICogICB9XG4gICAqICAgPC9wcmU+XG4gICAqICAgPHVsPlxuICAgKiAgICA8bGk+dGFyZ2V0cGF0aHdpZHRoID0geFNjYWxlRmFjdG9yICogY29udGFpbmVyV2lkdGg8L2xpPlxuICAgKiAgICA8bGk+dGFyZ2V0cGF0aGhlaWdodCA9IHlTY2FsZUZhY3RvciAqIGNvbnRhaW5lckhlaWdodDwvbGk+XG4gICAqICAgIDxsaT5Qb3NpdGlvbiBpcyB1c2VkIHRvIHNldCB0aGUgc3RhcnRpbmcgY29vcmRpbmF0ZSBvZiB0aGUgcGF0aC4gTSBpcyBjb21wdXRlZDpcbiAgICAqICAgIDx1bD5cbiAgICAqICAgICAgPGxpPnBvc2l0aW9uLnggKiBjb250YWluZXJXaWR0aDwvbGk+XG4gICAgKiAgICAgIDxsaT5wb3NpdGlvbi55ICogY29udGFpbmVySGVpZ2h0PC9saT5cbiAgICAqICAgIDwvdWw+XG4gICAgKiAgICBDZW50ZXIgb2YgdGhlIGNvbnRhaW5lciA8cHJlPiBwb3NpdGlvbjoge1xuICAgKiAgICAgICBteDogMC41LFxuICAgKiAgICAgICBteTogMC41LFxuICAgKiAgICAgfTwvcHJlPlxuICAgKiAgICAgVXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIGNvbnRhaW5lclxuICAgKiAgICAgPHByZT4gcG9zaXRpb246IHtcbiAgICogICAgICAgbXg6IDAuMCxcbiAgICogICAgICAgbXk6IDAuMCxcbiAgICogICAgIH08L3ByZT5cbiAgICogICAgPC9saT5cbiAgICogICA8L3VsPlxuICAgKiA8L3A+XG4gICAqXG4gICAqL1xuICB0aGlzLmdldFNjYWxlZFBhdGggPSBmdW5jdGlvbiBnZXRTY2FsZWRQYXRoKHBhdGhJZCwgcGFyYW0pIHtcbiAgICB2YXIgcmF3UGF0aCA9IHRoaXMucGF0aE1hcFtwYXRoSWRdO1xuXG4gICAgLy8gcG9zaXRpb25pbmdcbiAgICAvLyBjb21wdXRlIHRoZSBzdGFydCBwb2ludCBvZiB0aGUgcGF0aFxuICAgIHZhciBteCwgbXk7XG5cbiAgICBpZiAocGFyYW0uYWJzcG9zKSB7XG4gICAgICBteCA9IHBhcmFtLmFic3Bvcy54O1xuICAgICAgbXkgPSBwYXJhbS5hYnNwb3MueTtcbiAgICB9IGVsc2Uge1xuICAgICAgbXggPSBwYXJhbS5jb250YWluZXJXaWR0aCAqIHBhcmFtLnBvc2l0aW9uLm14O1xuICAgICAgbXkgPSBwYXJhbS5jb250YWluZXJIZWlnaHQgKiBwYXJhbS5wb3NpdGlvbi5teTtcbiAgICB9XG5cbiAgICB2YXIgY29vcmRpbmF0ZXMgPSB7fTsgLy8gbWFwIGZvciB0aGUgc2NhbGVkIGNvb3JkaW5hdGVzXG4gICAgaWYgKHBhcmFtLnBvc2l0aW9uKSB7XG5cbiAgICAgIC8vIHBhdGhcbiAgICAgIHZhciBoZWlnaHRSYXRpbyA9IChwYXJhbS5jb250YWluZXJIZWlnaHQgLyByYXdQYXRoLmhlaWdodCkgKiBwYXJhbS55U2NhbGVGYWN0b3I7XG4gICAgICB2YXIgd2lkdGhSYXRpbyA9IChwYXJhbS5jb250YWluZXJXaWR0aCAvIHJhd1BhdGgud2lkdGgpICogcGFyYW0ueFNjYWxlRmFjdG9yO1xuXG5cbiAgICAgIC8vIEFwcGx5IGhlaWdodCByYXRpb1xuICAgICAgZm9yICh2YXIgaGVpZ2h0SW5kZXggPSAwOyBoZWlnaHRJbmRleCA8IHJhd1BhdGguaGVpZ2h0RWxlbWVudHMubGVuZ3RoOyBoZWlnaHRJbmRleCsrKSB7XG4gICAgICAgIGNvb3JkaW5hdGVzWyd5JyArIGhlaWdodEluZGV4XSA9IHJhd1BhdGguaGVpZ2h0RWxlbWVudHNbaGVpZ2h0SW5kZXhdICogaGVpZ2h0UmF0aW87XG4gICAgICB9XG5cbiAgICAgIC8vIEFwcGx5IHdpZHRoIHJhdGlvXG4gICAgICBmb3IgKHZhciB3aWR0aEluZGV4ID0gMDsgd2lkdGhJbmRleCA8IHJhd1BhdGgud2lkdGhFbGVtZW50cy5sZW5ndGg7IHdpZHRoSW5kZXgrKykge1xuICAgICAgICBjb29yZGluYXRlc1sneCcgKyB3aWR0aEluZGV4XSA9IHJhd1BhdGgud2lkdGhFbGVtZW50c1t3aWR0aEluZGV4XSAqIHdpZHRoUmF0aW87XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQXBwbHkgdmFsdWUgdG8gcmF3IHBhdGhcbiAgICB2YXIgcGF0aCA9IGZvcm1hdChcbiAgICAgIHJhd1BhdGguZCwge1xuICAgICAgICBteDogbXgsXG4gICAgICAgIG15OiBteSxcbiAgICAgICAgZTogY29vcmRpbmF0ZXNcbiAgICAgIH1cbiAgICApO1xuICAgIHJldHVybiBwYXRoO1xuICB9O1xufVxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLy8gY29waWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2Fkb2JlLXdlYnBsYXRmb3JtL1NuYXAuc3ZnL2Jsb2IvbWFzdGVyL3NyYy9zdmcuanNcbnZhciB0b2tlblJlZ2V4ID0gL1xceyhbXn1dKylcXH0vZyxcbiAgICBvYmpOb3RhdGlvblJlZ2V4ID0gLyg/Oig/Ol58XFwuKSguKz8pKD89XFxbfFxcLnwkfFxcKCl8XFxbKCd8XCIpKC4rPylcXDJcXF0pKFxcKFxcKSk/L2c7IC8vIG1hdGNoZXMgLnh4eHh4IG9yIFtcInh4eHh4XCJdIHRvIHJ1biBvdmVyIG9iamVjdCBwcm9wZXJ0aWVzXG5cbmZ1bmN0aW9uIHJlcGxhY2VyKGFsbCwga2V5LCBvYmopIHtcbiAgdmFyIHJlcyA9IG9iajtcbiAga2V5LnJlcGxhY2Uob2JqTm90YXRpb25SZWdleCwgZnVuY3Rpb24oYWxsLCBuYW1lLCBxdW90ZSwgcXVvdGVkTmFtZSwgaXNGdW5jKSB7XG4gICAgbmFtZSA9IG5hbWUgfHwgcXVvdGVkTmFtZTtcbiAgICBpZiAocmVzKSB7XG4gICAgICBpZiAobmFtZSBpbiByZXMpIHtcbiAgICAgICAgcmVzID0gcmVzW25hbWVdO1xuICAgICAgfVxuICAgICAgdHlwZW9mIHJlcyA9PSAnZnVuY3Rpb24nICYmIGlzRnVuYyAmJiAocmVzID0gcmVzKCkpO1xuICAgIH1cbiAgfSk7XG4gIHJlcyA9IChyZXMgPT0gbnVsbCB8fCByZXMgPT0gb2JqID8gYWxsIDogcmVzKSArICcnO1xuXG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdChzdHIsIG9iaikge1xuICByZXR1cm4gU3RyaW5nKHN0cikucmVwbGFjZSh0b2tlblJlZ2V4LCBmdW5jdGlvbihhbGwsIGtleSkge1xuICAgIHJldHVybiByZXBsYWNlcihhbGwsIGtleSwgb2JqKTtcbiAgfSk7XG59XG4iLCJpbXBvcnQgeyBhc3NpZ24gfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCBUZXh0VXRpbCBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL1RleHQnO1xuXG52YXIgREVGQVVMVF9GT05UX1NJWkUgPSAxMjtcbnZhciBMSU5FX0hFSUdIVF9SQVRJTyA9IDEuMjtcblxudmFyIE1JTl9URVhUX0FOTk9UQVRJT05fSEVJR0hUID0gMzA7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVGV4dFJlbmRlcmVyKGNvbmZpZykge1xuXG4gIHZhciBkZWZhdWx0U3R5bGUgPSBhc3NpZ24oe1xuICAgIGZvbnRGYW1pbHk6ICdBcmlhbCwgc2Fucy1zZXJpZicsXG4gICAgZm9udFNpemU6IERFRkFVTFRfRk9OVF9TSVpFLFxuICAgIGZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgIGxpbmVIZWlnaHQ6IExJTkVfSEVJR0hUX1JBVElPXG4gIH0sIGNvbmZpZyAmJiBjb25maWcuZGVmYXVsdFN0eWxlIHx8IHt9KTtcblxuICB2YXIgZm9udFNpemUgPSBwYXJzZUludChkZWZhdWx0U3R5bGUuZm9udFNpemUsIDEwKSAtIDE7XG5cbiAgdmFyIGV4dGVybmFsU3R5bGUgPSBhc3NpZ24oe30sIGRlZmF1bHRTdHlsZSwge1xuICAgIGZvbnRTaXplOiBmb250U2l6ZVxuICB9LCBjb25maWcgJiYgY29uZmlnLmV4dGVybmFsU3R5bGUgfHwge30pO1xuXG4gIHZhciB0ZXh0VXRpbCA9IG5ldyBUZXh0VXRpbCh7XG4gICAgc3R5bGU6IGRlZmF1bHRTdHlsZVxuICB9KTtcblxuICAvKipcbiAgICogR2V0IHRoZSBuZXcgYm91bmRzIG9mIGFuIGV4dGVybmFsbHkgcmVuZGVyZWQsXG4gICAqIGxheW91dGVkIGxhYmVsLlxuICAgKlxuICAgKiBAcGFyYW0gIHtCb3VuZHN9IGJvdW5kc1xuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHRleHRcbiAgICpcbiAgICogQHJldHVybiB7Qm91bmRzfVxuICAgKi9cbiAgdGhpcy5nZXRFeHRlcm5hbExhYmVsQm91bmRzID0gZnVuY3Rpb24oYm91bmRzLCB0ZXh0KSB7XG5cbiAgICB2YXIgbGF5b3V0ZWREaW1lbnNpb25zID0gdGV4dFV0aWwuZ2V0RGltZW5zaW9ucyh0ZXh0LCB7XG4gICAgICBib3g6IHtcbiAgICAgICAgd2lkdGg6IDkwLFxuICAgICAgICBoZWlnaHQ6IDMwLFxuICAgICAgICB4OiBib3VuZHMud2lkdGggLyAyICsgYm91bmRzLngsXG4gICAgICAgIHk6IGJvdW5kcy5oZWlnaHQgLyAyICsgYm91bmRzLnlcbiAgICAgIH0sXG4gICAgICBzdHlsZTogZXh0ZXJuYWxTdHlsZVxuICAgIH0pO1xuXG4gICAgLy8gcmVzaXplIGxhYmVsIHNoYXBlIHRvIGZpdCBsYWJlbCB0ZXh0XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IE1hdGgucm91bmQoYm91bmRzLnggKyBib3VuZHMud2lkdGggLyAyIC0gbGF5b3V0ZWREaW1lbnNpb25zLndpZHRoIC8gMiksXG4gICAgICB5OiBNYXRoLnJvdW5kKGJvdW5kcy55KSxcbiAgICAgIHdpZHRoOiBNYXRoLmNlaWwobGF5b3V0ZWREaW1lbnNpb25zLndpZHRoKSxcbiAgICAgIGhlaWdodDogTWF0aC5jZWlsKGxheW91dGVkRGltZW5zaW9ucy5oZWlnaHQpXG4gICAgfTtcblxuICB9O1xuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG5ldyBib3VuZHMgb2YgdGV4dCBhbm5vdGF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gIHtCb3VuZHN9IGJvdW5kc1xuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHRleHRcbiAgICpcbiAgICogQHJldHVybiB7Qm91bmRzfVxuICAgKi9cbiAgdGhpcy5nZXRUZXh0QW5ub3RhdGlvbkJvdW5kcyA9IGZ1bmN0aW9uKGJvdW5kcywgdGV4dCkge1xuXG4gICAgdmFyIGxheW91dGVkRGltZW5zaW9ucyA9IHRleHRVdGlsLmdldERpbWVuc2lvbnModGV4dCwge1xuICAgICAgYm94OiBib3VuZHMsXG4gICAgICBzdHlsZTogZGVmYXVsdFN0eWxlLFxuICAgICAgYWxpZ246ICdsZWZ0LXRvcCcsXG4gICAgICBwYWRkaW5nOiA1XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgeDogYm91bmRzLngsXG4gICAgICB5OiBib3VuZHMueSxcbiAgICAgIHdpZHRoOiBib3VuZHMud2lkdGgsXG4gICAgICBoZWlnaHQ6IE1hdGgubWF4KE1JTl9URVhUX0FOTk9UQVRJT05fSEVJR0hULCBNYXRoLnJvdW5kKGxheW91dGVkRGltZW5zaW9ucy5oZWlnaHQpKVxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGxheW91dGVkIHRleHQgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSByZW5kZXJlZCB0ZXh0XG4gICAqL1xuICB0aGlzLmNyZWF0ZVRleHQgPSBmdW5jdGlvbih0ZXh0LCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRleHRVdGlsLmNyZWF0ZVRleHQodGV4dCwgb3B0aW9ucyB8fCB7fSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEdldCBkZWZhdWx0IHRleHQgc3R5bGUuXG4gICAqL1xuICB0aGlzLmdldERlZmF1bHRTdHlsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkZWZhdWx0U3R5bGU7XG4gIH07XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZXh0ZXJuYWwgdGV4dCBzdHlsZS5cbiAgICovXG4gIHRoaXMuZ2V0RXh0ZXJuYWxTdHlsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBleHRlcm5hbFN0eWxlO1xuICB9O1xuXG59XG5cblRleHRSZW5kZXJlci4kaW5qZWN0ID0gW1xuICAnY29uZmlnLnRleHRSZW5kZXJlcidcbl07IiwiaW1wb3J0IEJwbW5SZW5kZXJlciBmcm9tICcuL0JwbW5SZW5kZXJlcic7XG5pbXBvcnQgVGV4dFJlbmRlcmVyIGZyb20gJy4vVGV4dFJlbmRlcmVyJztcblxuaW1wb3J0IFBhdGhNYXAgZnJvbSAnLi9QYXRoTWFwJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnYnBtblJlbmRlcmVyJyBdLFxuICBicG1uUmVuZGVyZXI6IFsgJ3R5cGUnLCBCcG1uUmVuZGVyZXIgXSxcbiAgdGV4dFJlbmRlcmVyOiBbICd0eXBlJywgVGV4dFJlbmRlcmVyIF0sXG4gIHBhdGhNYXA6IFsgJ3R5cGUnLCBQYXRoTWFwIF1cbn07XG4iLCJpbXBvcnQgeyBnZXROZXdTaGFwZVBvc2l0aW9uIH0gZnJvbSAnLi9CcG1uQXV0b1BsYWNlVXRpbCc7XG5cblxuLyoqXG4gKiBCUE1OIGF1dG8tcGxhY2UgYmVoYXZpb3IuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1BsYWNlKGV2ZW50QnVzKSB7XG4gIGV2ZW50QnVzLm9uKCdhdXRvUGxhY2UnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2U7XG5cbiAgICByZXR1cm4gZ2V0TmV3U2hhcGVQb3NpdGlvbihzb3VyY2UsIHNoYXBlKTtcbiAgfSk7XG59XG5cbkF1dG9QbGFjZS4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07IiwiaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5pbXBvcnQgeyBpc0FueSB9IGZyb20gJy4uL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0TWlkLFxuICBhc1RSQkwsXG4gIGdldE9yaWVudGF0aW9uXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgZmluZEZyZWVQb3NpdGlvbixcbiAgZ2VuZXJhdGVHZXROZXh0UG9zaXRpb24sXG4gIGdldENvbm5lY3RlZERpc3RhbmNlXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F1dG8tcGxhY2UvQXV0b1BsYWNlVXRpbCc7XG5cblxuLyoqXG4gKiBGaW5kIHRoZSBuZXcgcG9zaXRpb24gZm9yIHRoZSB0YXJnZXQgZWxlbWVudCB0b1xuICogY29ubmVjdCB0byBzb3VyY2UuXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLlNoYXBlfSBzb3VyY2VcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5TaGFwZX0gZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmV3U2hhcGVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQpIHtcblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46VGV4dEFubm90YXRpb24nKSkge1xuICAgIHJldHVybiBnZXRUZXh0QW5ub3RhdGlvblBvc2l0aW9uKHNvdXJjZSwgZWxlbWVudCk7XG4gIH1cblxuICBpZiAoaXNBbnkoZWxlbWVudCwgWyAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJywgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJyBdKSkge1xuICAgIHJldHVybiBnZXREYXRhRWxlbWVudFBvc2l0aW9uKHNvdXJjZSwgZWxlbWVudCk7XG4gIH1cblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46Rmxvd05vZGUnKSkge1xuICAgIHJldHVybiBnZXRGbG93Tm9kZVBvc2l0aW9uKHNvdXJjZSwgZWxlbWVudCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBbHdheXMgdHJ5IHRvIHBsYWNlIGVsZW1lbnQgcmlnaHQgb2Ygc291cmNlO1xuICogY29tcHV0ZSBhY3R1YWwgZGlzdGFuY2UgZnJvbSBwcmV2aW91cyBub2RlcyBpbiBmbG93LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rmxvd05vZGVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQpIHtcblxuICB2YXIgc291cmNlVHJibCA9IGFzVFJCTChzb3VyY2UpO1xuICB2YXIgc291cmNlTWlkID0gZ2V0TWlkKHNvdXJjZSk7XG5cbiAgdmFyIGhvcml6b250YWxEaXN0YW5jZSA9IGdldENvbm5lY3RlZERpc3RhbmNlKHNvdXJjZSwge1xuICAgIGZpbHRlcjogZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgcmV0dXJuIGlzKGNvbm5lY3Rpb24sICdicG1uOlNlcXVlbmNlRmxvdycpO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIG1hcmdpbiA9IDMwLFxuICAgICAgbWluRGlzdGFuY2UgPSA4MCxcbiAgICAgIG9yaWVudGF0aW9uID0gJ2xlZnQnO1xuXG4gIGlmIChpcyhzb3VyY2UsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSkge1xuICAgIG9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24oc291cmNlLCBzb3VyY2UuaG9zdCwgLTI1KTtcblxuICAgIGlmIChvcmllbnRhdGlvbi5pbmRleE9mKCd0b3AnKSAhPT0gLTEpIHtcbiAgICAgIG1hcmdpbiAqPSAtMTtcbiAgICB9XG4gIH1cblxuICB2YXIgcG9zaXRpb24gPSB7XG4gICAgeDogc291cmNlVHJibC5yaWdodCArIGhvcml6b250YWxEaXN0YW5jZSArIGVsZW1lbnQud2lkdGggLyAyLFxuICAgIHk6IHNvdXJjZU1pZC55ICsgZ2V0VmVydGljYWxEaXN0YW5jZShvcmllbnRhdGlvbiwgbWluRGlzdGFuY2UpXG4gIH07XG5cbiAgdmFyIG5leHRQb3NpdGlvbkRpcmVjdGlvbiA9IHtcbiAgICB5OiB7XG4gICAgICBtYXJnaW46IG1hcmdpbixcbiAgICAgIG1pbkRpc3RhbmNlOiBtaW5EaXN0YW5jZVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gZmluZEZyZWVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQsIHBvc2l0aW9uLCBnZW5lcmF0ZUdldE5leHRQb3NpdGlvbihuZXh0UG9zaXRpb25EaXJlY3Rpb24pKTtcbn1cblxuXG5mdW5jdGlvbiBnZXRWZXJ0aWNhbERpc3RhbmNlKG9yaWVudGF0aW9uLCBtaW5EaXN0YW5jZSkge1xuICBpZiAob3JpZW50YXRpb24uaW5kZXhPZigndG9wJykgIT0gLTEpIHtcbiAgICByZXR1cm4gLTEgKiBtaW5EaXN0YW5jZTtcbiAgfSBlbHNlIGlmIChvcmllbnRhdGlvbi5pbmRleE9mKCdib3R0b20nKSAhPSAtMSkge1xuICAgIHJldHVybiBtaW5EaXN0YW5jZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMDtcbiAgfVxufVxuXG5cbi8qKlxuICogQWx3YXlzIHRyeSB0byBwbGFjZSB0ZXh0IGFubm90YXRpb25zIHRvcCByaWdodCBvZiBzb3VyY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUZXh0QW5ub3RhdGlvblBvc2l0aW9uKHNvdXJjZSwgZWxlbWVudCkge1xuXG4gIHZhciBzb3VyY2VUcmJsID0gYXNUUkJMKHNvdXJjZSk7XG5cbiAgdmFyIHBvc2l0aW9uID0ge1xuICAgIHg6IHNvdXJjZVRyYmwucmlnaHQgKyBlbGVtZW50LndpZHRoIC8gMixcbiAgICB5OiBzb3VyY2VUcmJsLnRvcCAtIDUwIC0gZWxlbWVudC5oZWlnaHQgLyAyXG4gIH07XG5cbiAgdmFyIG5leHRQb3NpdGlvbkRpcmVjdGlvbiA9IHtcbiAgICB5OiB7XG4gICAgICBtYXJnaW46IC0zMCxcbiAgICAgIG1pbkRpc3RhbmNlOiAyMFxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gZmluZEZyZWVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQsIHBvc2l0aW9uLCBnZW5lcmF0ZUdldE5leHRQb3NpdGlvbihuZXh0UG9zaXRpb25EaXJlY3Rpb24pKTtcbn1cblxuXG4vKipcbiAqIEFsd2F5cyBwdXQgZWxlbWVudCBib3R0b20gcmlnaHQgb2Ygc291cmNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGF0YUVsZW1lbnRQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQpIHtcblxuICB2YXIgc291cmNlVHJibCA9IGFzVFJCTChzb3VyY2UpO1xuXG4gIHZhciBwb3NpdGlvbiA9IHtcbiAgICB4OiBzb3VyY2VUcmJsLnJpZ2h0IC0gMTAgKyBlbGVtZW50LndpZHRoIC8gMixcbiAgICB5OiBzb3VyY2VUcmJsLmJvdHRvbSArIDQwICsgZWxlbWVudC53aWR0aCAvIDJcbiAgfTtcblxuICB2YXIgbmV4dFBvc2l0aW9uRGlyZWN0aW9uID0ge1xuICAgIHg6IHtcbiAgICAgIG1hcmdpbjogMzAsXG4gICAgICBtaW5EaXN0YW5jZTogMzBcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGZpbmRGcmVlUG9zaXRpb24oc291cmNlLCBlbGVtZW50LCBwb3NpdGlvbiwgZ2VuZXJhdGVHZXROZXh0UG9zaXRpb24obmV4dFBvc2l0aW9uRGlyZWN0aW9uKSk7XG59IiwiaW1wb3J0IEF1dG9QbGFjZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXBsYWNlJztcblxuaW1wb3J0IEJwbW5BdXRvUGxhY2UgZnJvbSAnLi9CcG1uQXV0b1BsYWNlJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogWyBBdXRvUGxhY2VNb2R1bGUgXSxcbiAgX19pbml0X186IFsgJ2JwbW5BdXRvUGxhY2UnIF0sXG4gIGJwbW5BdXRvUGxhY2U6IFsgJ3R5cGUnLCBCcG1uQXV0b1BsYWNlIF1cbn07IiwiaW1wb3J0IEF1dG9SZXNpemUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1yZXNpemUvQXV0b1Jlc2l6ZSc7XG5cbmltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5cbi8qKlxuICogU3ViIGNsYXNzIG9mIHRoZSBBdXRvUmVzaXplIG1vZHVsZSB3aGljaCBpbXBsZW1lbnRzIGEgQlBNTlxuICogc3BlY2lmaWMgcmVzaXplIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uQXV0b1Jlc2l6ZShpbmplY3Rvcikge1xuXG4gIGluamVjdG9yLmludm9rZShBdXRvUmVzaXplLCB0aGlzKTtcbn1cblxuQnBtbkF1dG9SZXNpemUuJGluamVjdCA9IFtcbiAgJ2luamVjdG9yJ1xuXTtcblxuaW5oZXJpdHMoQnBtbkF1dG9SZXNpemUsIEF1dG9SZXNpemUpO1xuXG5cbi8qKlxuICogUmVzaXplIHNoYXBlcyBhbmQgbGFuZXMuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHRhcmdldFxuICogQHBhcmFtIHtCb3VuZHN9IG5ld0JvdW5kc1xuICogQHBhcmFtIHtPYmplY3R9IGhpbnRzXG4gKi9cbkJwbW5BdXRvUmVzaXplLnByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbih0YXJnZXQsIG5ld0JvdW5kcywgaGludHMpIHtcblxuICBpZiAoaXModGFyZ2V0LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgdGhpcy5fbW9kZWxpbmcucmVzaXplTGFuZSh0YXJnZXQsIG5ld0JvdW5kcywgbnVsbCwgaGludHMpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuX21vZGVsaW5nLnJlc2l6ZVNoYXBlKHRhcmdldCwgbmV3Qm91bmRzLCBudWxsLCBoaW50cyk7XG4gIH1cbn07IiwiaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCBBdXRvUmVzaXplUHJvdmlkZXIgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1yZXNpemUvQXV0b1Jlc2l6ZVByb3ZpZGVyJztcblxuXG4vKipcbiAqIFRoaXMgbW9kdWxlIGlzIGEgcHJvdmlkZXIgZm9yIGF1dG9tYXRpY2FsbHkgcmVzaXppbmcgcGFyZW50IEJQTU4gZWxlbWVudHNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkF1dG9SZXNpemVQcm92aWRlcihldmVudEJ1cywgbW9kZWxpbmcpIHtcbiAgQXV0b1Jlc2l6ZVByb3ZpZGVyLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cbmluaGVyaXRzKEJwbW5BdXRvUmVzaXplUHJvdmlkZXIsIEF1dG9SZXNpemVQcm92aWRlcik7XG5cbkJwbW5BdXRvUmVzaXplUHJvdmlkZXIuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSBnaXZlbiB0YXJnZXQgY2FuIGJlIGV4cGFuZGVkXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLlNoYXBlfSB0YXJnZXRcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5CcG1uQXV0b1Jlc2l6ZVByb3ZpZGVyLnByb3RvdHlwZS5jYW5SZXNpemUgPSBmdW5jdGlvbihlbGVtZW50cywgdGFyZ2V0KSB7XG5cbiAgaWYgKCFpcyh0YXJnZXQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgIWlzKHRhcmdldCwgJ2JwbW46TGFuZScpICYmICEoaXModGFyZ2V0LCAnYnBtbjpTdWJQcm9jZXNzJykpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIGNhblJlc2l6ZSA9IHRydWU7XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkxhbmUnKSB8fCBlbGVtZW50LmxhYmVsVGFyZ2V0KSB7XG4gICAgICBjYW5SZXNpemUgPSBmYWxzZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBjYW5SZXNpemU7XG59O1xuIiwiaW1wb3J0IEJwbW5BdXRvUmVzaXplIGZyb20gJy4vQnBtbkF1dG9SZXNpemUnO1xuaW1wb3J0IEJwbW5BdXRvUmVzaXplUHJvdmlkZXIgZnJvbSAnLi9CcG1uQXV0b1Jlc2l6ZVByb3ZpZGVyJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbXG4gICAgJ2JwbW5BdXRvUmVzaXplJyxcbiAgICAnYnBtbkF1dG9SZXNpemVQcm92aWRlcidcbiAgXSxcbiAgYnBtbkF1dG9SZXNpemU6IFsgJ3R5cGUnLCBCcG1uQXV0b1Jlc2l6ZSBdLFxuICBicG1uQXV0b1Jlc2l6ZVByb3ZpZGVyOiBbICd0eXBlJywgQnBtbkF1dG9SZXNpemVQcm92aWRlciBdXG59O1xuIiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmb3JFYWNoLFxuICBpc0FycmF5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgaXNcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0V4cGFuZGVkLFxuICBpc0V2ZW50U3ViUHJvY2Vzc1xufSBmcm9tICcuLi8uLi91dGlsL0RpVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzQW55XG59IGZyb20gJy4uL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0Q2hpbGRMYW5lc1xufSBmcm9tICcuLi9tb2RlbGluZy91dGlsL0xhbmVVdGlsJztcblxuaW1wb3J0IHtcbiAgaGFzUHJpbWFyeU1vZGlmaWVyXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvTW91c2UnO1xuXG5cbi8qKlxuICogQSBwcm92aWRlciBmb3IgQlBNTiAyLjAgZWxlbWVudHMgY29udGV4dCBwYWRcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ29udGV4dFBhZFByb3ZpZGVyKFxuICAgIGNvbmZpZywgaW5qZWN0b3IsIGV2ZW50QnVzLFxuICAgIGNvbnRleHRQYWQsIG1vZGVsaW5nLCBlbGVtZW50RmFjdG9yeSxcbiAgICBjb25uZWN0LCBjcmVhdGUsIHBvcHVwTWVudSxcbiAgICBjYW52YXMsIHJ1bGVzLCB0cmFuc2xhdGUpIHtcblxuICBjb25maWcgPSBjb25maWcgfHwge307XG5cbiAgY29udGV4dFBhZC5yZWdpc3RlclByb3ZpZGVyKHRoaXMpO1xuXG4gIHRoaXMuX2NvbnRleHRQYWQgPSBjb250ZXh0UGFkO1xuXG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG5cbiAgdGhpcy5fZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcbiAgdGhpcy5fY29ubmVjdCA9IGNvbm5lY3Q7XG4gIHRoaXMuX2NyZWF0ZSA9IGNyZWF0ZTtcbiAgdGhpcy5fcG9wdXBNZW51ID0gcG9wdXBNZW51O1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX3J1bGVzID0gcnVsZXM7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcblxuICBpZiAoY29uZmlnLmF1dG9QbGFjZSAhPT0gZmFsc2UpIHtcbiAgICB0aGlzLl9hdXRvUGxhY2UgPSBpbmplY3Rvci5nZXQoJ2F1dG9QbGFjZScsIGZhbHNlKTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjcmVhdGUuZW5kJywgMjUwLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKCFoYXNQcmltYXJ5TW9kaWZpZXIoZXZlbnQpIHx8ICFjb250ZXh0UGFkLmlzT3BlbihzaGFwZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZW50cmllcyA9IGNvbnRleHRQYWQuZ2V0RW50cmllcyhzaGFwZSk7XG5cbiAgICBpZiAoZW50cmllcy5yZXBsYWNlKSB7XG4gICAgICBlbnRyaWVzLnJlcGxhY2UuYWN0aW9uLmNsaWNrKGV2ZW50LCBzaGFwZSk7XG4gICAgfVxuICB9KTtcbn1cblxuQ29udGV4dFBhZFByb3ZpZGVyLiRpbmplY3QgPSBbXG4gICdjb25maWcuY29udGV4dFBhZCcsXG4gICdpbmplY3RvcicsXG4gICdldmVudEJ1cycsXG4gICdjb250ZXh0UGFkJyxcbiAgJ21vZGVsaW5nJyxcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcbiAgJ2Nvbm5lY3QnLFxuICAnY3JlYXRlJyxcbiAgJ3BvcHVwTWVudScsXG4gICdjYW52YXMnLFxuICAncnVsZXMnLFxuICAndHJhbnNsYXRlJ1xuXTtcblxuXG5Db250ZXh0UGFkUHJvdmlkZXIucHJvdG90eXBlLmdldENvbnRleHRQYWRFbnRyaWVzID0gZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gIHZhciBjb250ZXh0UGFkID0gdGhpcy5fY29udGV4dFBhZCxcbiAgICAgIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmcsXG5cbiAgICAgIGVsZW1lbnRGYWN0b3J5ID0gdGhpcy5fZWxlbWVudEZhY3RvcnksXG4gICAgICBjb25uZWN0ID0gdGhpcy5fY29ubmVjdCxcbiAgICAgIGNyZWF0ZSA9IHRoaXMuX2NyZWF0ZSxcbiAgICAgIHBvcHVwTWVudSA9IHRoaXMuX3BvcHVwTWVudSxcbiAgICAgIGNhbnZhcyA9IHRoaXMuX2NhbnZhcyxcbiAgICAgIHJ1bGVzID0gdGhpcy5fcnVsZXMsXG4gICAgICBhdXRvUGxhY2UgPSB0aGlzLl9hdXRvUGxhY2UsXG4gICAgICB0cmFuc2xhdGUgPSB0aGlzLl90cmFuc2xhdGU7XG5cbiAgdmFyIGFjdGlvbnMgPSB7fTtcblxuICBpZiAoZWxlbWVudC50eXBlID09PSAnbGFiZWwnKSB7XG4gICAgcmV0dXJuIGFjdGlvbnM7XG4gIH1cblxuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0O1xuXG4gIGZ1bmN0aW9uIHN0YXJ0Q29ubmVjdChldmVudCwgZWxlbWVudCkge1xuICAgIGNvbm5lY3Quc3RhcnQoZXZlbnQsIGVsZW1lbnQpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlRWxlbWVudChlKSB7XG4gICAgbW9kZWxpbmcucmVtb3ZlRWxlbWVudHMoWyBlbGVtZW50IF0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0UmVwbGFjZU1lbnVQb3NpdGlvbihlbGVtZW50KSB7XG5cbiAgICB2YXIgWV9PRkZTRVQgPSA1O1xuXG4gICAgdmFyIGRpYWdyYW1Db250YWluZXIgPSBjYW52YXMuZ2V0Q29udGFpbmVyKCksXG4gICAgICAgIHBhZCA9IGNvbnRleHRQYWQuZ2V0UGFkKGVsZW1lbnQpLmh0bWw7XG5cbiAgICB2YXIgZGlhZ3JhbVJlY3QgPSBkaWFncmFtQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgICBwYWRSZWN0ID0gcGFkLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgdmFyIHRvcCA9IHBhZFJlY3QudG9wIC0gZGlhZ3JhbVJlY3QudG9wO1xuICAgIHZhciBsZWZ0ID0gcGFkUmVjdC5sZWZ0IC0gZGlhZ3JhbVJlY3QubGVmdDtcblxuICAgIHZhciBwb3MgPSB7XG4gICAgICB4OiBsZWZ0LFxuICAgICAgeTogdG9wICsgcGFkUmVjdC5oZWlnaHQgKyBZX09GRlNFVFxuICAgIH07XG5cbiAgICByZXR1cm4gcG9zO1xuICB9XG5cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIGFwcGVuZCBhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzTmFtZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3RpdGxlXVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqXG4gICAqIEByZXR1cm4ge09iamVjdH0gZGVzY3JpcHRvclxuICAgKi9cbiAgZnVuY3Rpb24gYXBwZW5kQWN0aW9uKHR5cGUsIGNsYXNzTmFtZSwgdGl0bGUsIG9wdGlvbnMpIHtcblxuICAgIGlmICh0eXBlb2YgdGl0bGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zID0gdGl0bGU7XG4gICAgICB0aXRsZSA9IHRyYW5zbGF0ZSgnQXBwZW5kIHt0eXBlfScsIHsgdHlwZTogdHlwZS5yZXBsYWNlKC9eYnBtbjovLCAnJykgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYXBwZW5kU3RhcnQoZXZlbnQsIGVsZW1lbnQpIHtcblxuICAgICAgdmFyIHNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoYXNzaWduKHsgdHlwZTogdHlwZSB9LCBvcHRpb25zKSk7XG4gICAgICBjcmVhdGUuc3RhcnQoZXZlbnQsIHNoYXBlLCB7XG4gICAgICAgIHNvdXJjZTogZWxlbWVudFxuICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICB2YXIgYXBwZW5kID0gYXV0b1BsYWNlID8gZnVuY3Rpb24oZXZlbnQsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBzaGFwZSA9IGVsZW1lbnRGYWN0b3J5LmNyZWF0ZVNoYXBlKGFzc2lnbih7IHR5cGU6IHR5cGUgfSwgb3B0aW9ucykpO1xuXG4gICAgICBhdXRvUGxhY2UuYXBwZW5kKGVsZW1lbnQsIHNoYXBlKTtcbiAgICB9IDogYXBwZW5kU3RhcnQ7XG5cblxuICAgIHJldHVybiB7XG4gICAgICBncm91cDogJ21vZGVsJyxcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgYWN0aW9uOiB7XG4gICAgICAgIGRyYWdzdGFydDogYXBwZW5kU3RhcnQsXG4gICAgICAgIGNsaWNrOiBhcHBlbmRcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gc3BsaXRMYW5lSGFuZGxlcihjb3VudCkge1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50LCBlbGVtZW50KSB7XG5cbiAgICAgIC8vIGFjdHVhbCBzcGxpdFxuICAgICAgbW9kZWxpbmcuc3BsaXRMYW5lKGVsZW1lbnQsIGNvdW50KTtcblxuICAgICAgLy8gcmVmcmVzaCBjb250ZXh0IHBhZCBhZnRlciBzcGxpdCB0b1xuICAgICAgLy8gZ2V0IHJpZCBvZiBzcGxpdCBpY29uc1xuICAgICAgY29udGV4dFBhZC5vcGVuKGVsZW1lbnQsIHRydWUpO1xuICAgIH07XG4gIH1cblxuXG4gIGlmIChpc0FueShidXNpbmVzc09iamVjdCwgWyAnYnBtbjpMYW5lJywgJ2JwbW46UGFydGljaXBhbnQnIF0pICYmIGlzRXhwYW5kZWQoYnVzaW5lc3NPYmplY3QpKSB7XG5cbiAgICB2YXIgY2hpbGRMYW5lcyA9IGdldENoaWxkTGFuZXMoZWxlbWVudCk7XG5cbiAgICBhc3NpZ24oYWN0aW9ucywge1xuICAgICAgJ2xhbmUtaW5zZXJ0LWFib3ZlJzoge1xuICAgICAgICBncm91cDogJ2xhbmUtaW5zZXJ0LWFib3ZlJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWxhbmUtaW5zZXJ0LWFib3ZlJyxcbiAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQWRkIExhbmUgYWJvdmUnKSxcbiAgICAgICAgYWN0aW9uOiB7XG4gICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uKGV2ZW50LCBlbGVtZW50KSB7XG4gICAgICAgICAgICBtb2RlbGluZy5hZGRMYW5lKGVsZW1lbnQsICd0b3AnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChjaGlsZExhbmVzLmxlbmd0aCA8IDIpIHtcblxuICAgICAgaWYgKGVsZW1lbnQuaGVpZ2h0ID49IDEyMCkge1xuICAgICAgICBhc3NpZ24oYWN0aW9ucywge1xuICAgICAgICAgICdsYW5lLWRpdmlkZS10d28nOiB7XG4gICAgICAgICAgICBncm91cDogJ2xhbmUtZGl2aWRlJyxcbiAgICAgICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sYW5lLWRpdmlkZS10d28nLFxuICAgICAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnRGl2aWRlIGludG8gdHdvIExhbmVzJyksXG4gICAgICAgICAgICBhY3Rpb246IHtcbiAgICAgICAgICAgICAgY2xpY2s6IHNwbGl0TGFuZUhhbmRsZXIoMilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZWxlbWVudC5oZWlnaHQgPj0gMTgwKSB7XG4gICAgICAgIGFzc2lnbihhY3Rpb25zLCB7XG4gICAgICAgICAgJ2xhbmUtZGl2aWRlLXRocmVlJzoge1xuICAgICAgICAgICAgZ3JvdXA6ICdsYW5lLWRpdmlkZScsXG4gICAgICAgICAgICBjbGFzc05hbWU6ICdicG1uLWljb24tbGFuZS1kaXZpZGUtdGhyZWUnLFxuICAgICAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnRGl2aWRlIGludG8gdGhyZWUgTGFuZXMnKSxcbiAgICAgICAgICAgIGFjdGlvbjoge1xuICAgICAgICAgICAgICBjbGljazogc3BsaXRMYW5lSGFuZGxlcigzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdsYW5lLWluc2VydC1iZWxvdyc6IHtcbiAgICAgICAgZ3JvdXA6ICdsYW5lLWluc2VydC1iZWxvdycsXG4gICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sYW5lLWluc2VydC1iZWxvdycsXG4gICAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FkZCBMYW5lIGJlbG93JyksXG4gICAgICAgIGFjdGlvbjoge1xuICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbihldmVudCwgZWxlbWVudCkge1xuICAgICAgICAgICAgbW9kZWxpbmcuYWRkTGFuZShlbGVtZW50LCAnYm90dG9tJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgfVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46Rmxvd05vZGUnKSkge1xuXG4gICAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpFdmVudEJhc2VkR2F0ZXdheScpKSB7XG5cbiAgICAgIGFzc2lnbihhY3Rpb25zLCB7XG4gICAgICAgICdhcHBlbmQucmVjZWl2ZS10YXNrJzogYXBwZW5kQWN0aW9uKFxuICAgICAgICAgICdicG1uOlJlY2VpdmVUYXNrJyxcbiAgICAgICAgICAnYnBtbi1pY29uLXJlY2VpdmUtdGFzaycsXG4gICAgICAgICAgdHJhbnNsYXRlKCdBcHBlbmQgUmVjZWl2ZVRhc2snKVxuICAgICAgICApLFxuICAgICAgICAnYXBwZW5kLm1lc3NhZ2UtaW50ZXJtZWRpYXRlLWV2ZW50JzogYXBwZW5kQWN0aW9uKFxuICAgICAgICAgICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnLFxuICAgICAgICAgICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW1lc3NhZ2UnLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIE1lc3NhZ2VJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyksXG4gICAgICAgICAgeyBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpNZXNzYWdlRXZlbnREZWZpbml0aW9uJyB9XG4gICAgICAgICksXG4gICAgICAgICdhcHBlbmQudGltZXItaW50ZXJtZWRpYXRlLWV2ZW50JzogYXBwZW5kQWN0aW9uKFxuICAgICAgICAgICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnLFxuICAgICAgICAgICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLXRpbWVyJyxcbiAgICAgICAgICB0cmFuc2xhdGUoJ0FwcGVuZCBUaW1lckludGVybWVkaWF0ZUNhdGNoRXZlbnQnKSxcbiAgICAgICAgICB7IGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlRpbWVyRXZlbnREZWZpbml0aW9uJyB9XG4gICAgICAgICksXG4gICAgICAgICdhcHBlbmQuY29uZGl0aW9uLWludGVybWVkaWF0ZS1ldmVudCc6IGFwcGVuZEFjdGlvbihcbiAgICAgICAgICAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyxcbiAgICAgICAgICAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb25kaXRpb24nLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIENvbmRpdGlvbkludGVybWVkaWF0ZUNhdGNoRXZlbnQnKSxcbiAgICAgICAgICB7IGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJyB9XG4gICAgICAgICksXG4gICAgICAgICdhcHBlbmQuc2lnbmFsLWludGVybWVkaWF0ZS1ldmVudCc6IGFwcGVuZEFjdGlvbihcbiAgICAgICAgICAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyxcbiAgICAgICAgICAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1zaWduYWwnLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIFNpZ25hbEludGVybWVkaWF0ZUNhdGNoRXZlbnQnKSxcbiAgICAgICAgICB7IGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbicgfVxuICAgICAgICApXG4gICAgICB9KTtcbiAgICB9IGVsc2VcblxuICAgIGlmIChpc0V2ZW50VHlwZShidXNpbmVzc09iamVjdCwgJ2JwbW46Qm91bmRhcnlFdmVudCcsICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nKSkge1xuXG4gICAgICBhc3NpZ24oYWN0aW9ucywge1xuICAgICAgICAnYXBwZW5kLmNvbXBlbnNhdGlvbi1hY3Rpdml0eSc6XG4gICAgICAgICAgICBhcHBlbmRBY3Rpb24oXG4gICAgICAgICAgICAgICdicG1uOlRhc2snLFxuICAgICAgICAgICAgICAnYnBtbi1pY29uLXRhc2snLFxuICAgICAgICAgICAgICB0cmFuc2xhdGUoJ0FwcGVuZCBjb21wZW5zYXRpb24gYWN0aXZpdHknKSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlzRm9yQ29tcGVuc2F0aW9uOiB0cnVlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIClcbiAgICAgIH0pO1xuICAgIH0gZWxzZVxuXG4gICAgaWYgKCFpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46RW5kRXZlbnQnKSAmJlxuICAgICAgICAhYnVzaW5lc3NPYmplY3QuaXNGb3JDb21wZW5zYXRpb24gJiZcbiAgICAgICAgIWlzRXZlbnRUeXBlKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JywgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpICYmXG4gICAgICAgICFpc0V2ZW50U3ViUHJvY2VzcyhidXNpbmVzc09iamVjdCkpIHtcblxuICAgICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICAgJ2FwcGVuZC5lbmQtZXZlbnQnOiBhcHBlbmRBY3Rpb24oXG4gICAgICAgICAgJ2JwbW46RW5kRXZlbnQnLFxuICAgICAgICAgICdicG1uLWljb24tZW5kLWV2ZW50LW5vbmUnLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIEVuZEV2ZW50JylcbiAgICAgICAgKSxcbiAgICAgICAgJ2FwcGVuZC5nYXRld2F5JzogYXBwZW5kQWN0aW9uKFxuICAgICAgICAgICdicG1uOkV4Y2x1c2l2ZUdhdGV3YXknLFxuICAgICAgICAgICdicG1uLWljb24tZ2F0ZXdheS1ub25lJyxcbiAgICAgICAgICB0cmFuc2xhdGUoJ0FwcGVuZCBHYXRld2F5JylcbiAgICAgICAgKSxcbiAgICAgICAgJ2FwcGVuZC5hcHBlbmQtdGFzayc6IGFwcGVuZEFjdGlvbihcbiAgICAgICAgICAnYnBtbjpUYXNrJyxcbiAgICAgICAgICAnYnBtbi1pY29uLXRhc2snLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIFRhc2snKVxuICAgICAgICApLFxuICAgICAgICAnYXBwZW5kLmludGVybWVkaWF0ZS1ldmVudCc6IGFwcGVuZEFjdGlvbihcbiAgICAgICAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcbiAgICAgICAgICAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1ub25lJyxcbiAgICAgICAgICB0cmFuc2xhdGUoJ0FwcGVuZCBJbnRlcm1lZGlhdGUvQm91bmRhcnkgRXZlbnQnKVxuICAgICAgICApXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXBvcHVwTWVudS5pc0VtcHR5KGVsZW1lbnQsICdicG1uLXJlcGxhY2UnKSkge1xuXG4gICAgLy8gUmVwbGFjZSBtZW51IGVudHJ5XG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdyZXBsYWNlJzoge1xuICAgICAgICBncm91cDogJ2VkaXQnLFxuICAgICAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc2NyZXctd3JlbmNoJyxcbiAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQ2hhbmdlIHR5cGUnKSxcbiAgICAgICAgYWN0aW9uOiB7XG4gICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uKGV2ZW50LCBlbGVtZW50KSB7XG5cbiAgICAgICAgICAgIHZhciBwb3NpdGlvbiA9IGFzc2lnbihnZXRSZXBsYWNlTWVudVBvc2l0aW9uKGVsZW1lbnQpLCB7XG4gICAgICAgICAgICAgIGN1cnNvcjogeyB4OiBldmVudC54LCB5OiBldmVudC55IH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBwb3B1cE1lbnUub3BlbihlbGVtZW50LCAnYnBtbi1yZXBsYWNlJywgcG9zaXRpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGlzQW55KGJ1c2luZXNzT2JqZWN0LCBbXG4gICAgJ2JwbW46Rmxvd05vZGUnLFxuICAgICdicG1uOkludGVyYWN0aW9uTm9kZScsXG4gICAgJ2JwbW46RGF0YU9iamVjdFJlZmVyZW5jZScsXG4gICAgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJ1xuICBdKSkge1xuXG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdhcHBlbmQudGV4dC1hbm5vdGF0aW9uJzogYXBwZW5kQWN0aW9uKCdicG1uOlRleHRBbm5vdGF0aW9uJywgJ2JwbW4taWNvbi10ZXh0LWFubm90YXRpb24nKSxcblxuICAgICAgJ2Nvbm5lY3QnOiB7XG4gICAgICAgIGdyb3VwOiAnY29ubmVjdCcsXG4gICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jb25uZWN0aW9uLW11bHRpJyxcbiAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQ29ubmVjdCB1c2luZyAnICtcbiAgICAgICAgICAgICAgICAgIChidXNpbmVzc09iamVjdC5pc0ZvckNvbXBlbnNhdGlvbiA/ICcnIDogJ1NlcXVlbmNlL01lc3NhZ2VGbG93IG9yICcpICtcbiAgICAgICAgICAgICAgICAgICdBc3NvY2lhdGlvbicpLFxuICAgICAgICBhY3Rpb246IHtcbiAgICAgICAgICBjbGljazogc3RhcnRDb25uZWN0LFxuICAgICAgICAgIGRyYWdzdGFydDogc3RhcnRDb25uZWN0XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChpc0FueShidXNpbmVzc09iamVjdCwgWyAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJywgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJyBdKSkge1xuICAgIGFzc2lnbihhY3Rpb25zLCB7XG4gICAgICAnY29ubmVjdCc6IHtcbiAgICAgICAgZ3JvdXA6ICdjb25uZWN0JyxcbiAgICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWNvbm5lY3Rpb24tbXVsdGknLFxuICAgICAgICB0aXRsZTogdHJhbnNsYXRlKCdDb25uZWN0IHVzaW5nIERhdGFJbnB1dEFzc29jaWF0aW9uJyksXG4gICAgICAgIGFjdGlvbjoge1xuICAgICAgICAgIGNsaWNrOiBzdGFydENvbm5lY3QsXG4gICAgICAgICAgZHJhZ3N0YXJ0OiBzdGFydENvbm5lY3RcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpHcm91cCcpKSB7XG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdhcHBlbmQudGV4dC1hbm5vdGF0aW9uJzogYXBwZW5kQWN0aW9uKCdicG1uOlRleHRBbm5vdGF0aW9uJywgJ2JwbW4taWNvbi10ZXh0LWFubm90YXRpb24nKVxuICAgIH0pO1xuICB9XG5cbiAgLy8gZGVsZXRlIGVsZW1lbnQgZW50cnksIG9ubHkgc2hvdyBpZiBhbGxvd2VkIGJ5IHJ1bGVzXG4gIHZhciBkZWxldGVBbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMuZGVsZXRlJywgeyBlbGVtZW50czogWyBlbGVtZW50IF0gfSk7XG5cbiAgaWYgKGlzQXJyYXkoZGVsZXRlQWxsb3dlZCkpIHtcblxuICAgIC8vIHdhcyB0aGUgZWxlbWVudCByZXR1cm5lZCBhcyBhIGRlbGV0aW9uIGNhbmRpZGF0ZT9cbiAgICBkZWxldGVBbGxvd2VkID0gZGVsZXRlQWxsb3dlZFswXSA9PT0gZWxlbWVudDtcbiAgfVxuXG4gIGlmIChkZWxldGVBbGxvd2VkKSB7XG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdkZWxldGUnOiB7XG4gICAgICAgIGdyb3VwOiAnZWRpdCcsXG4gICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi10cmFzaCcsXG4gICAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ1JlbW92ZScpLFxuICAgICAgICBhY3Rpb246IHtcbiAgICAgICAgICBjbGljazogcmVtb3ZlRWxlbWVudFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gYWN0aW9ucztcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNFdmVudFR5cGUoZXZlbnRCbywgdHlwZSwgZGVmaW5pdGlvbikge1xuXG4gIHZhciBpc1R5cGUgPSBldmVudEJvLiRpbnN0YW5jZU9mKHR5cGUpO1xuICB2YXIgaXNEZWZpbml0aW9uID0gZmFsc2U7XG5cbiAgdmFyIGRlZmluaXRpb25zID0gZXZlbnRCby5ldmVudERlZmluaXRpb25zIHx8IFtdO1xuICBmb3JFYWNoKGRlZmluaXRpb25zLCBmdW5jdGlvbihkZWYpIHtcbiAgICBpZiAoZGVmLiR0eXBlID09PSBkZWZpbml0aW9uKSB7XG4gICAgICBpc0RlZmluaXRpb24gPSB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGlzVHlwZSAmJiBpc0RlZmluaXRpb247XG59XG4iLCJpbXBvcnQgRGlyZWN0RWRpdGluZ01vZHVsZSBmcm9tICdkaWFncmFtLWpzLWRpcmVjdC1lZGl0aW5nJztcbmltcG9ydCBDb250ZXh0UGFkTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvbnRleHQtcGFkJztcbmltcG9ydCBTZWxlY3Rpb25Nb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc2VsZWN0aW9uJztcbmltcG9ydCBDb25uZWN0TW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2Nvbm5lY3QnO1xuaW1wb3J0IENyZWF0ZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jcmVhdGUnO1xuaW1wb3J0IFBvcHVwTWVudU1vZHVsZSBmcm9tICcuLi9wb3B1cC1tZW51JztcblxuaW1wb3J0IENvbnRleHRQYWRQcm92aWRlciBmcm9tICcuL0NvbnRleHRQYWRQcm92aWRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBEaXJlY3RFZGl0aW5nTW9kdWxlLFxuICAgIENvbnRleHRQYWRNb2R1bGUsXG4gICAgU2VsZWN0aW9uTW9kdWxlLFxuICAgIENvbm5lY3RNb2R1bGUsXG4gICAgQ3JlYXRlTW9kdWxlLFxuICAgIFBvcHVwTWVudU1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogWyAnY29udGV4dFBhZFByb3ZpZGVyJyBdLFxuICBjb250ZXh0UGFkUHJvdmlkZXI6IFsgJ3R5cGUnLCBDb250ZXh0UGFkUHJvdmlkZXIgXVxufTsiLCJpbXBvcnQge1xuICBnZXRCdXNpbmVzc09iamVjdCxcbiAgaXNcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBmb3JFYWNoLFxuICBpc0FycmF5LFxuICBpc1VuZGVmaW5lZCxcbiAgb21pdCxcbiAgcmVkdWNlXG59IGZyb20gJ21pbi1kYXNoJztcblxuZnVuY3Rpb24gY29weVByb3BlcnRpZXMoc291cmNlLCB0YXJnZXQsIHByb3BlcnRpZXMpIHtcbiAgaWYgKCFpc0FycmF5KHByb3BlcnRpZXMpKSB7XG4gICAgcHJvcGVydGllcyA9IFsgcHJvcGVydGllcyBdO1xuICB9XG5cbiAgZm9yRWFjaChwcm9wZXJ0aWVzLCBmdW5jdGlvbihwcm9wZXJ0eSkge1xuICAgIGlmICghaXNVbmRlZmluZWQoc291cmNlW3Byb3BlcnR5XSkpIHtcbiAgICAgIHRhcmdldFtwcm9wZXJ0eV0gPSBzb3VyY2VbcHJvcGVydHldO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVByb3BlcnRpZXMoZWxlbWVudCwgcHJvcGVydGllcykge1xuICBpZiAoIWlzQXJyYXkocHJvcGVydGllcykpIHtcbiAgICBwcm9wZXJ0aWVzID0gWyBwcm9wZXJ0aWVzIF07XG4gIH1cblxuICBmb3JFYWNoKHByb3BlcnRpZXMsIGZ1bmN0aW9uKHByb3BlcnR5KSB7XG4gICAgaWYgKGVsZW1lbnRbcHJvcGVydHldKSB7XG4gICAgICBkZWxldGUgZWxlbWVudFtwcm9wZXJ0eV07XG4gICAgfVxuICB9KTtcbn1cblxudmFyIExPV19QUklPUklUWSA9IDc1MDtcblxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uQ29weVBhc3RlKGJwbW5GYWN0b3J5LCBldmVudEJ1cywgbW9kZGxlQ29weSkge1xuXG4gIGV2ZW50QnVzLm9uKCdjb3B5UGFzdGUuY29weUVsZW1lbnQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZGVzY3JpcHRvciA9IGNvbnRleHQuZGVzY3JpcHRvcixcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudDtcblxuICAgIHZhciBidXNpbmVzc09iamVjdCA9IGRlc2NyaXB0b3Iub2xkQnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcblxuICAgIGRlc2NyaXB0b3IudHlwZSA9IGVsZW1lbnQudHlwZTtcblxuICAgIGNvcHlQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBkZXNjcmlwdG9yLCAnbmFtZScpO1xuXG4gICAgZGVzY3JpcHRvci5kaSA9IHt9O1xuXG4gICAgLy8gZmlsbCBhbmQgc3Ryb2tlIHdpbGwgYmUgc2V0IHRvIERJXG4gICAgY29weVByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QuZGksIGRlc2NyaXB0b3IuZGksIFtcbiAgICAgICdmaWxsJyxcbiAgICAgICdzdHJva2UnXG4gICAgXSk7XG5cbiAgICBjb3B5UHJvcGVydGllcyhidXNpbmVzc09iamVjdC5kaSwgZGVzY3JpcHRvciwgJ2lzRXhwYW5kZWQnKTtcblxuICAgIGlmIChpc0xhYmVsKGRlc2NyaXB0b3IpKSB7XG4gICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICB9XG5cbiAgICAvLyBkZWZhdWx0IHNlcXVlbmNlIGZsb3dcbiAgICBpZiAoYnVzaW5lc3NPYmplY3QuZGVmYXVsdCkge1xuICAgICAgZGVzY3JpcHRvci5kZWZhdWx0ID0gYnVzaW5lc3NPYmplY3QuZGVmYXVsdC5pZDtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0eScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICAgIHByb3BlcnR5ID0gY29udGV4dC5wcm9wZXJ0eSxcbiAgICAgICAgcHJvcGVydHlOYW1lID0gY29udGV4dC5wcm9wZXJ0eU5hbWUsXG4gICAgICAgIGJwbW5Qcm9jZXNzO1xuXG4gICAgaWYgKFxuICAgICAgcHJvcGVydHlOYW1lID09PSAncHJvY2Vzc1JlZicgJiZcbiAgICAgIGlzKHBhcmVudCwgJ2JwbW46UGFydGljaXBhbnQnKSAmJlxuICAgICAgaXMocHJvcGVydHksICdicG1uOlByb2Nlc3MnKVxuICAgICkge1xuICAgICAgYnBtblByb2Nlc3MgPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46UHJvY2VzcycpO1xuXG4gICAgICAvLyByZXR1cm4gY29weSBvZiBwcm9jZXNzXG4gICAgICByZXR1cm4gbW9kZGxlQ29weS5jb3B5RWxlbWVudChwcm9wZXJ0eSwgYnBtblByb2Nlc3MpO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIHJlZmVyZW5jZXM7XG5cbiAgZnVuY3Rpb24gcmVzb2x2ZVJlZmVyZW5jZXMoZGVzY3JpcHRvciwgY2FjaGUpIHtcbiAgICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChkZXNjcmlwdG9yKTtcblxuICAgIC8vIGRlZmF1bHQgc2VxdWVuY2UgZmxvd3NcbiAgICBpZiAoZGVzY3JpcHRvci5kZWZhdWx0KSB7XG5cbiAgICAgIC8vIHJlbGF0aW9uc2hpcCBjYW5ub3QgYmUgcmVzb2x2ZWQgaW1tZWRpYXRlbHlcbiAgICAgIHJlZmVyZW5jZXNbIGRlc2NyaXB0b3IuZGVmYXVsdCBdID0ge1xuICAgICAgICBlbGVtZW50OiBidXNpbmVzc09iamVjdCxcbiAgICAgICAgcHJvcGVydHk6ICdkZWZhdWx0J1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBib3VuZGFyeSBldmVudHNcbiAgICBpZiAoZGVzY3JpcHRvci5ob3N0KSB7XG5cbiAgICAgIC8vIHJlbGF0aW9uc2hpcCBjYW4gYmUgcmVzb2x2ZWQgaW1tZWRpYXRlbHlcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0KGRlc2NyaXB0b3IpLmF0dGFjaGVkVG9SZWYgPSBnZXRCdXNpbmVzc09iamVjdChjYWNoZVsgZGVzY3JpcHRvci5ob3N0IF0pO1xuICAgIH1cblxuICAgIHJlZmVyZW5jZXMgPSBvbWl0KHJlZmVyZW5jZXMsIHJlZHVjZShyZWZlcmVuY2VzLCBmdW5jdGlvbihhcnJheSwgcmVmZXJlbmNlLCBrZXkpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gcmVmZXJlbmNlLmVsZW1lbnQsXG4gICAgICAgICAgcHJvcGVydHkgPSByZWZlcmVuY2UucHJvcGVydHk7XG5cbiAgICAgIGlmIChrZXkgPT09IGRlc2NyaXB0b3IuaWQpIHtcbiAgICAgICAgZWxlbWVudFsgcHJvcGVydHkgXSA9IGJ1c2luZXNzT2JqZWN0O1xuXG4gICAgICAgIGFycmF5LnB1c2goZGVzY3JpcHRvci5pZCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9LCBbXSkpO1xuICB9XG5cbiAgZXZlbnRCdXMub24oJ2NvcHlQYXN0ZS5wYXN0ZUVsZW1lbnRzJywgZnVuY3Rpb24oKSB7XG4gICAgcmVmZXJlbmNlcyA9IHt9O1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29weVBhc3RlLnBhc3RlRWxlbWVudCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgY2FjaGUgPSBjb250ZXh0LmNhY2hlLFxuICAgICAgICBkZXNjcmlwdG9yID0gY29udGV4dC5kZXNjcmlwdG9yLFxuICAgICAgICBvbGRCdXNpbmVzc09iamVjdCA9IGRlc2NyaXB0b3Iub2xkQnVzaW5lc3NPYmplY3QsXG4gICAgICAgIG5ld0J1c2luZXNzT2JqZWN0O1xuXG4gICAgLy8gZG8gTk9UIGNvcHkgYnVzaW5lc3Mgb2JqZWN0IGlmIGV4dGVybmFsIGxhYmVsXG4gICAgaWYgKGlzTGFiZWwoZGVzY3JpcHRvcikpIHtcbiAgICAgIGRlc2NyaXB0b3IuYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChjYWNoZVsgZGVzY3JpcHRvci5sYWJlbFRhcmdldCBdKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG5ld0J1c2luZXNzT2JqZWN0ID0gYnBtbkZhY3RvcnkuY3JlYXRlKG9sZEJ1c2luZXNzT2JqZWN0LiR0eXBlKTtcblxuICAgIGRlc2NyaXB0b3IuYnVzaW5lc3NPYmplY3QgPSBtb2RkbGVDb3B5LmNvcHlFbGVtZW50KFxuICAgICAgb2xkQnVzaW5lc3NPYmplY3QsXG4gICAgICBuZXdCdXNpbmVzc09iamVjdFxuICAgICk7XG5cbiAgICAvLyByZXNvbHZlIHJlZmVyZW5jZXMgZS5nLiBkZWZhdWx0IHNlcXVlbmNlIGZsb3dcbiAgICByZXNvbHZlUmVmZXJlbmNlcyhkZXNjcmlwdG9yLCBjYWNoZSk7XG5cbiAgICBjb3B5UHJvcGVydGllcyhkZXNjcmlwdG9yLCBuZXdCdXNpbmVzc09iamVjdCwgW1xuICAgICAgJ2lzRXhwYW5kZWQnLFxuICAgICAgJ25hbWUnXG4gICAgXSk7XG5cbiAgICByZW1vdmVQcm9wZXJ0aWVzKGRlc2NyaXB0b3IsICdvbGRCdXNpbmVzc09iamVjdCcpO1xuICB9KTtcblxufVxuXG5cbkJwbW5Db3B5UGFzdGUuJGluamVjdCA9IFtcbiAgJ2JwbW5GYWN0b3J5JyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGRsZUNvcHknXG5dO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNMYWJlbChlbGVtZW50KSB7XG4gIHJldHVybiAhIWVsZW1lbnQubGFiZWxUYXJnZXQ7XG59XG4iLCJpbXBvcnQge1xuICBmaW5kLFxuICBmb3JFYWNoLFxuICBpc0FycmF5LFxuICBpc0RlZmluZWQsXG4gIGlzT2JqZWN0LFxuICBtYXRjaFBhdHRlcm4sXG4gIHJlZHVjZSxcbiAgaGFzLFxuICBzb3J0Qnlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgRElTQUxMT1dFRF9QUk9QRVJUSUVTID0gW1xuICAnYXJ0aWZhY3RzJyxcbiAgJ2RhdGFJbnB1dEFzc29jaWF0aW9ucycsXG4gICdkYXRhT3V0cHV0QXNzb2NpYXRpb25zJyxcbiAgJ2RlZmF1bHQnLFxuICAnZmxvd0VsZW1lbnRzJyxcbiAgJ2xhbmVzJyxcbiAgJ2luY29taW5nJyxcbiAgJ291dGdvaW5nJ1xuXTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7RnVuY3Rpb259IDxtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0aWVzPiBsaXN0ZW5lclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IGNvbnRleHQucHJvcGVydHlOYW1lc1xuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBjb250ZXh0LnNvdXJjZUVsZW1lbnRcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gY29udGV4dC50YXJnZXRFbGVtZW50XG4gKlxuICogQHJldHVybnMge0FycmF5PHN0cmluZz58Ym9vbGVhbn0gLSBSZXR1cm4gcHJvcGVydGllcyB0byBiZSBjb3BpZWQgb3IgZmFsc2UgdG8gZGlzYWxsb3dcbiAqIGNvcHlpbmcuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7RnVuY3Rpb259IDxtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0eT4gbGlzdGVuZXJcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBjb250ZXh0LnBhcmVudFxuICogQHBhcmFtIHsqfSBjb250ZXh0LnByb3BlcnR5XG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGV4dC5wcm9wZXJ0eU5hbWVcbiAqXG4gKiBAcmV0dXJucyB7Knxib29sZWFufSAtIFJldHVybiBjb3BpZWQgcHJvcGVydHkgb3IgZmFsc2UgdG8gZGlzYWxsb3dcbiAqIGNvcHlpbmcuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7RnVuY3Rpb259IDxtb2RkbGVDb3B5LmNhblNldENvcGllZFByb3BlcnR5PiBsaXN0ZW5lclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGNvbnRleHQucGFyZW50XG4gKiBAcGFyYW0geyp9IGNvbnRleHQucHJvcGVydHlcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZXh0LnByb3BlcnR5TmFtZVxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSAtIFJldHVybiBmYWxzZSB0byBkaXNhbGxvd1xuICogc2V0dGluZyBjb3BpZWQgcHJvcGVydHkuXG4gKi9cblxuLyoqXG4gKiBVdGlsaXR5IGZvciBjb3B5aW5nIG1vZGVsIHByb3BlcnRpZXMgZnJvbSBzb3VyY2UgZWxlbWVudCB0byB0YXJnZXQgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcbiAqIEBwYXJhbSB7QnBtbk1vZGRsZX0gbW9kZGxlXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1vZGRsZUNvcHkoZXZlbnRCdXMsIGJwbW5GYWN0b3J5LCBtb2RkbGUpIHtcbiAgdGhpcy5fYnBtbkZhY3RvcnkgPSBicG1uRmFjdG9yeTtcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fbW9kZGxlID0gbW9kZGxlO1xuXG4gIC8vIGNvcHkgZXh0ZW5zaW9uIGVsZW1lbnRzIGxhc3RcbiAgZXZlbnRCdXMub24oJ21vZGRsZUNvcHkuY2FuQ29weVByb3BlcnRpZXMnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHByb3BlcnR5TmFtZXMgPSBjb250ZXh0LnByb3BlcnR5TmFtZXM7XG5cbiAgICBpZiAoIXByb3BlcnR5TmFtZXMgfHwgIXByb3BlcnR5TmFtZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIHNvcnRCeShwcm9wZXJ0eU5hbWVzLCBmdW5jdGlvbihwcm9wZXJ0eU5hbWUpIHtcbiAgICAgIHJldHVybiBwcm9wZXJ0eU5hbWUgPT09ICdleHRlbnNpb25FbGVtZW50cyc7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIGRlZmF1bHQgY2hlY2sgd2hldGhlciBwcm9wZXJ0eSBjYW4gYmUgY29waWVkXG4gIGV2ZW50QnVzLm9uKCdtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0eScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICAgIHBhcmVudERlc2NyaXB0b3IgPSBpc09iamVjdChwYXJlbnQpICYmIHBhcmVudC4kZGVzY3JpcHRvcixcbiAgICAgICAgcHJvcGVydHlOYW1lID0gY29udGV4dC5wcm9wZXJ0eU5hbWU7XG5cbiAgICBpZiAocHJvcGVydHlOYW1lICYmIERJU0FMTE9XRURfUFJPUEVSVElFUy5pbmRleE9mKHByb3BlcnR5TmFtZSkgIT09IC0xKSB7XG5cbiAgICAgIC8vIGRpc2FsbG93IGNvcHlpbmcgcHJvcGVydHlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAocHJvcGVydHlOYW1lICYmXG4gICAgICBwYXJlbnREZXNjcmlwdG9yICYmXG4gICAgICAhZmluZChwYXJlbnREZXNjcmlwdG9yLnByb3BlcnRpZXMsIG1hdGNoUGF0dGVybih7IG5hbWU6IHByb3BlcnR5TmFtZSB9KSkpIHtcblxuICAgICAgLy8gZGlzYWxsb3cgY29weWluZyBwcm9wZXJ0eVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gZG8gTk9UIGFsbG93IHRvIGNvcHkgZW1wdHkgZXh0ZW5zaW9uIGVsZW1lbnRzXG4gIGV2ZW50QnVzLm9uKCdtb2RkbGVDb3B5LmNhblNldENvcGllZFByb3BlcnR5JywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBwcm9wZXJ0eSA9IGNvbnRleHQucHJvcGVydHk7XG5cbiAgICBpZiAoaXMocHJvcGVydHksICdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJykgJiYgKCFwcm9wZXJ0eS52YWx1ZXMgfHwgIXByb3BlcnR5LnZhbHVlcy5sZW5ndGgpKSB7XG5cbiAgICAgIC8vIGRpc2FsbG93IHNldHRpbmcgY29waWVkIHByb3BlcnR5XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbn1cblxuTW9kZGxlQ29weS4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnYnBtbkZhY3RvcnknLFxuICAnbW9kZGxlJ1xuXTtcblxuLyoqXG4gKiBDb3B5IG1vZGVsIHByb3BlcnRpZXMgb2Ygc291cmNlIGVsZW1lbnQgdG8gdGFyZ2V0IGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBzb3VyY2VFbGVtZW50XG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IHRhcmdldEVsZW1lbnRcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gW3Byb3BlcnR5TmFtZXNdXG4gKlxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fVxuICovXG5Nb2RkbGVDb3B5LnByb3RvdHlwZS5jb3B5RWxlbWVudCA9IGZ1bmN0aW9uKHNvdXJjZUVsZW1lbnQsIHRhcmdldEVsZW1lbnQsIHByb3BlcnR5TmFtZXMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmIChwcm9wZXJ0eU5hbWVzICYmICFpc0FycmF5KHByb3BlcnR5TmFtZXMpKSB7XG4gICAgcHJvcGVydHlOYW1lcyA9IFsgcHJvcGVydHlOYW1lcyBdO1xuICB9XG5cbiAgcHJvcGVydHlOYW1lcyA9IHByb3BlcnR5TmFtZXMgfHwgZ2V0UHJvcGVydHlOYW1lcyhzb3VyY2VFbGVtZW50LiRkZXNjcmlwdG9yKTtcblxuICB2YXIgY2FuQ29weVByb3BlcnRpZXMgPSB0aGlzLl9ldmVudEJ1cy5maXJlKCdtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0aWVzJywge1xuICAgIHByb3BlcnR5TmFtZXM6IHByb3BlcnR5TmFtZXMsXG4gICAgc291cmNlRWxlbWVudDogc291cmNlRWxlbWVudCxcbiAgICB0YXJnZXRFbGVtZW50OiB0YXJnZXRFbGVtZW50XG4gIH0pO1xuXG4gIGlmIChjYW5Db3B5UHJvcGVydGllcyA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gdGFyZ2V0RWxlbWVudDtcbiAgfVxuXG4gIGlmIChpc0FycmF5KGNhbkNvcHlQcm9wZXJ0aWVzKSkge1xuICAgIHByb3BlcnR5TmFtZXMgPSBjYW5Db3B5UHJvcGVydGllcztcbiAgfVxuXG4gIC8vIGNvcHkgcHJvcGVydGllc1xuICBmb3JFYWNoKHByb3BlcnR5TmFtZXMsIGZ1bmN0aW9uKHByb3BlcnR5TmFtZSkge1xuICAgIHZhciBzb3VyY2VQcm9wZXJ0eTtcblxuICAgIGlmIChoYXMoc291cmNlRWxlbWVudCwgcHJvcGVydHlOYW1lKSkge1xuICAgICAgc291cmNlUHJvcGVydHkgPSBzb3VyY2VFbGVtZW50LmdldChwcm9wZXJ0eU5hbWUpO1xuICAgIH1cblxuICAgIHZhciBjb3BpZWRQcm9wZXJ0eSA9IHNlbGYuY29weVByb3BlcnR5KHNvdXJjZVByb3BlcnR5LCB0YXJnZXRFbGVtZW50LCBwcm9wZXJ0eU5hbWUpO1xuXG4gICAgdmFyIGNhblNldFByb3BlcnR5ID0gc2VsZi5fZXZlbnRCdXMuZmlyZSgnbW9kZGxlQ29weS5jYW5TZXRDb3BpZWRQcm9wZXJ0eScsIHtcbiAgICAgIHBhcmVudDogdGFyZ2V0RWxlbWVudCxcbiAgICAgIHByb3BlcnR5OiBjb3BpZWRQcm9wZXJ0eSxcbiAgICAgIHByb3BlcnR5TmFtZTogcHJvcGVydHlOYW1lXG4gICAgfSk7XG5cbiAgICBpZiAoY2FuU2V0UHJvcGVydHkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGlzRGVmaW5lZChjb3BpZWRQcm9wZXJ0eSkpIHtcbiAgICAgIHRhcmdldEVsZW1lbnQuc2V0KHByb3BlcnR5TmFtZSwgY29waWVkUHJvcGVydHkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHRhcmdldEVsZW1lbnQ7XG59O1xuXG4vKipcbiAqIENvcHkgbW9kZWwgcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHsqfSBwcm9wZXJ0eVxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBwYXJlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eU5hbWVcbiAqXG4gKiBAcmV0dXJucyB7Kn1cbiAqL1xuTW9kZGxlQ29weS5wcm90b3R5cGUuY29weVByb3BlcnR5ID0gZnVuY3Rpb24ocHJvcGVydHksIHBhcmVudCwgcHJvcGVydHlOYW1lKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvLyBhbGxvdyBvdGhlcnMgdG8gY29weSBwcm9wZXJ0eVxuICB2YXIgY29waWVkUHJvcGVydHkgPSB0aGlzLl9ldmVudEJ1cy5maXJlKCdtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0eScsIHtcbiAgICBwYXJlbnQ6IHBhcmVudCxcbiAgICBwcm9wZXJ0eTogcHJvcGVydHksXG4gICAgcHJvcGVydHlOYW1lOiBwcm9wZXJ0eU5hbWVcbiAgfSk7XG5cbiAgLy8gcmV0dXJuIGlmIGNvcHlpbmcgaXMgTk9UIGFsbG93ZWRcbiAgaWYgKGNvcGllZFByb3BlcnR5ID09PSBmYWxzZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChjb3BpZWRQcm9wZXJ0eSkge1xuICAgIGlmIChpc09iamVjdChjb3BpZWRQcm9wZXJ0eSkgJiYgY29waWVkUHJvcGVydHkuJHR5cGUgJiYgIWNvcGllZFByb3BlcnR5LiRwYXJlbnQpIHtcbiAgICAgIGNvcGllZFByb3BlcnR5LiRwYXJlbnQgPSBwYXJlbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvcGllZFByb3BlcnR5O1xuICB9XG5cbiAgdmFyIHByb3BlcnR5RGVzY3JpcHRvciA9IHRoaXMuX21vZGRsZS5nZXRQcm9wZXJ0eURlc2NyaXB0b3IocGFyZW50LCBwcm9wZXJ0eU5hbWUpO1xuXG4gIC8vIGRvIE5PVCBjb3B5IElkcyBhbmQgcmVmZXJlbmNlc1xuICBpZiAocHJvcGVydHlEZXNjcmlwdG9yLmlzSWQgfHwgcHJvcGVydHlEZXNjcmlwdG9yLmlzUmVmZXJlbmNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gY29weSBhcnJheXNcbiAgaWYgKGlzQXJyYXkocHJvcGVydHkpKSB7XG4gICAgcmV0dXJuIHJlZHVjZShwcm9wZXJ0eSwgZnVuY3Rpb24oY2hpbGRQcm9wZXJ0aWVzLCBjaGlsZFByb3BlcnR5KSB7XG5cbiAgICAgIC8vIHJlY3Vyc2lvblxuICAgICAgY29waWVkUHJvcGVydHkgPSBzZWxmLmNvcHlQcm9wZXJ0eShjaGlsZFByb3BlcnR5LCBwYXJlbnQsIHByb3BlcnR5TmFtZSk7XG5cbiAgICAgIC8vIGNvcHlpbmcgbWlnaHQgTk9UIGJlIGFsbG93ZWRcbiAgICAgIGlmIChjb3BpZWRQcm9wZXJ0eSkge1xuICAgICAgICBjb3BpZWRQcm9wZXJ0eS4kcGFyZW50ID0gcGFyZW50O1xuXG4gICAgICAgIHJldHVybiBjaGlsZFByb3BlcnRpZXMuY29uY2F0KGNvcGllZFByb3BlcnR5KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNoaWxkUHJvcGVydGllcztcbiAgICB9LCBbXSk7XG4gIH1cblxuICAvLyBjb3B5IG1vZGVsIGVsZW1lbnRzXG4gIGlmIChpc09iamVjdChwcm9wZXJ0eSkgJiYgcHJvcGVydHkuJHR5cGUpIHtcbiAgICBpZiAodGhpcy5fbW9kZGxlLmdldEVsZW1lbnREZXNjcmlwdG9yKHByb3BlcnR5KS5pc0dlbmVyaWMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb3BpZWRQcm9wZXJ0eSA9IHNlbGYuX2JwbW5GYWN0b3J5LmNyZWF0ZShwcm9wZXJ0eS4kdHlwZSk7XG5cbiAgICBjb3BpZWRQcm9wZXJ0eS4kcGFyZW50ID0gcGFyZW50O1xuXG4gICAgLy8gcmVjdXJzaW9uXG4gICAgY29waWVkUHJvcGVydHkgPSBzZWxmLmNvcHlFbGVtZW50KHByb3BlcnR5LCBjb3BpZWRQcm9wZXJ0eSk7XG5cbiAgICByZXR1cm4gY29waWVkUHJvcGVydHk7XG4gIH1cblxuICAvLyBjb3B5IHByaW1pdGl2ZSBwcm9wZXJ0aWVzXG4gIHJldHVybiBwcm9wZXJ0eTtcbn07XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJvcGVydHlOYW1lcyhkZXNjcmlwdG9yLCBrZWVwRGVmYXVsdFByb3BlcnRpZXMpIHtcbiAgcmV0dXJuIHJlZHVjZShkZXNjcmlwdG9yLnByb3BlcnRpZXMsIGZ1bmN0aW9uKHByb3BlcnRpZXMsIHByb3BlcnR5KSB7XG5cbiAgICBpZiAoa2VlcERlZmF1bHRQcm9wZXJ0aWVzICYmIHByb3BlcnR5LmRlZmF1bHQpIHtcbiAgICAgIHJldHVybiBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9wZXJ0aWVzLmNvbmNhdChwcm9wZXJ0eS5uYW1lKTtcbiAgfSwgW10pO1xufVxuXG5mdW5jdGlvbiBpcyhlbGVtZW50LCB0eXBlKSB7XG4gIHJldHVybiBlbGVtZW50ICYmICh0eXBlb2YgZWxlbWVudC4kaW5zdGFuY2VPZiA9PT0gJ2Z1bmN0aW9uJykgJiYgZWxlbWVudC4kaW5zdGFuY2VPZih0eXBlKTtcbn0iLCJpbXBvcnQgQ29weVBhc3RlTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvcHktcGFzdGUnO1xuXG5pbXBvcnQgQnBtbkNvcHlQYXN0ZSBmcm9tICcuL0JwbW5Db3B5UGFzdGUnO1xuaW1wb3J0IE1vZGRsZUNvcHkgZnJvbSAnLi9Nb2RkbGVDb3B5JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIENvcHlQYXN0ZU1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogWyAnYnBtbkNvcHlQYXN0ZScsICdtb2RkbGVDb3B5JyBdLFxuICBicG1uQ29weVBhc3RlOiBbICd0eXBlJywgQnBtbkNvcHlQYXN0ZSBdLFxuICBtb2RkbGVDb3B5OiBbICd0eXBlJywgTW9kZGxlQ29weSBdXG59O1xuIiwiaW1wb3J0IHsgZ2V0RGkgfSBmcm9tICcuLi8uLi9kcmF3L0JwbW5SZW5kZXJVdGlsJztcbmltcG9ydCB7IGdldEJ1c2luZXNzT2JqZWN0IH0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBmaWx0ZXIsXG4gIG1hcFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IHNlbGZBbmRBbGxDaGlsZHJlbiB9IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvRWxlbWVudHMnO1xuXG5cbnZhciBISUdIX1BSSU9SSVRZID0gMjAwMDtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkRpT3JkZXJpbmcoZXZlbnRCdXMsIGNhbnZhcykge1xuXG4gIGV2ZW50QnVzLm9uKCdzYXZlWE1MLnN0YXJ0JywgSElHSF9QUklPUklUWSwgb3JkZXJEaSk7XG5cbiAgZnVuY3Rpb24gb3JkZXJEaSgpIHtcbiAgICB2YXIgcm9vdCA9IGNhbnZhcy5nZXRSb290RWxlbWVudCgpLFxuICAgICAgICByb290RGkgPSBnZXRCdXNpbmVzc09iamVjdChyb290KS5kaSxcbiAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIGRpRWxlbWVudHM7XG5cbiAgICBlbGVtZW50cyA9IHNlbGZBbmRBbGxDaGlsZHJlbihbIHJvb3QgXSwgZmFsc2UpO1xuXG4gICAgLy8gb25seSBicG1uZGk6U2hhcGUgYW5kIGJwbW5kaTpFZGdlIGNhbiBiZSBkaXJlY3QgY2hpbGRyZW4gb2YgYnBtbmRpOlBsYW5lXG4gICAgZWxlbWVudHMgPSBmaWx0ZXIoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBlbGVtZW50ICE9PSByb290ICYmICFlbGVtZW50LmxhYmVsVGFyZ2V0O1xuICAgIH0pO1xuXG4gICAgZGlFbGVtZW50cyA9IG1hcChlbGVtZW50cywgZ2V0RGkpO1xuXG4gICAgcm9vdERpLnNldCgncGxhbmVFbGVtZW50JywgZGlFbGVtZW50cyk7XG4gIH1cbn1cblxuQnBtbkRpT3JkZXJpbmcuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2NhbnZhcycgXTtcbiIsImltcG9ydCBCcG1uRGlPcmRlcmluZyBmcm9tICcuLi9kaS1vcmRlcmluZy9CcG1uRGlPcmRlcmluZyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFtcbiAgICAnYnBtbkRpT3JkZXJpbmcnXG4gIF0sXG4gIGJwbW5EaU9yZGVyaW5nOiBbICd0eXBlJywgQnBtbkRpT3JkZXJpbmcgXVxufTsiLCJpbXBvcnQge1xuICBmaWx0ZXJcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBpc0FueVxufSBmcm9tICcuLi9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCc7XG5cblxuLyoqXG4gKiBSZWdpc3RlcnMgZWxlbWVudCBleGNsdWRlIGZpbHRlcnMgZm9yIGVsZW1lbnRzIHRoYXRcbiAqIGN1cnJlbnRseSBkbyBub3Qgc3VwcG9ydCBkaXN0cmlidXRpb24uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5EaXN0cmlidXRlRWxlbWVudHMoZGlzdHJpYnV0ZUVsZW1lbnRzKSB7XG5cbiAgZGlzdHJpYnV0ZUVsZW1lbnRzLnJlZ2lzdGVyRmlsdGVyKGZ1bmN0aW9uKGVsZW1lbnRzKSB7XG4gICAgcmV0dXJuIGZpbHRlcihlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgdmFyIGNhbm5vdERpc3RyaWJ1dGUgPSBpc0FueShlbGVtZW50LCBbXG4gICAgICAgICdicG1uOkFzc29jaWF0aW9uJyxcbiAgICAgICAgJ2JwbW46Qm91bmRhcnlFdmVudCcsXG4gICAgICAgICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJyxcbiAgICAgICAgJ2JwbW46RGF0YU91dHB1dEFzc29jaWF0aW9uJyxcbiAgICAgICAgJ2JwbW46TGFuZScsXG4gICAgICAgICdicG1uOk1lc3NhZ2VGbG93JyxcbiAgICAgICAgJ2JwbW46UGFydGljaXBhbnQnLFxuICAgICAgICAnYnBtbjpTZXF1ZW5jZUZsb3cnLFxuICAgICAgICAnYnBtbjpUZXh0QW5ub3RhdGlvbidcbiAgICAgIF0pO1xuXG4gICAgICByZXR1cm4gIShlbGVtZW50LmxhYmVsVGFyZ2V0IHx8IGNhbm5vdERpc3RyaWJ1dGUpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuQnBtbkRpc3RyaWJ1dGVFbGVtZW50cy4kaW5qZWN0ID0gWyAnZGlzdHJpYnV0ZUVsZW1lbnRzJyBdOyIsImltcG9ydCBEaXN0cmlidXRlRWxlbWVudHNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cyc7XG5cbmltcG9ydCBCcG1uRGlzdHJpYnV0ZUVsZW1lbnRzIGZyb20gJy4vQnBtbkRpc3RyaWJ1dGVFbGVtZW50cyc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIERpc3RyaWJ1dGVFbGVtZW50c01vZHVsZVxuICBdLFxuICBfX2luaXRfXzogWyAnYnBtbkRpc3RyaWJ1dGVFbGVtZW50cycgXSxcbiAgYnBtbkRpc3RyaWJ1dGVFbGVtZW50czogWyAndHlwZScsIEJwbW5EaXN0cmlidXRlRWxlbWVudHMgXVxufTtcbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBFZGl0b3JBY3Rpb25zIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2VkaXRvci1hY3Rpb25zL0VkaXRvckFjdGlvbnMnO1xuXG5pbXBvcnQgeyBmaWx0ZXIgfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRCQm94XG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvRWxlbWVudHMnO1xuXG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuZCBleGVjdXRlcyBCUE1OIHNwZWNpZmljIGVkaXRvciBhY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5FZGl0b3JBY3Rpb25zKGluamVjdG9yKSB7XG4gIGluamVjdG9yLmludm9rZShFZGl0b3JBY3Rpb25zLCB0aGlzKTtcbn1cblxuaW5oZXJpdHMoQnBtbkVkaXRvckFjdGlvbnMsIEVkaXRvckFjdGlvbnMpO1xuXG5CcG1uRWRpdG9yQWN0aW9ucy4kaW5qZWN0ID0gW1xuICAnaW5qZWN0b3InXG5dO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGRlZmF1bHQgYWN0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge0luamVjdG9yfSBpbmplY3RvclxuICovXG5CcG1uRWRpdG9yQWN0aW9ucy5wcm90b3R5cGUuX3JlZ2lzdGVyRGVmYXVsdEFjdGlvbnMgPSBmdW5jdGlvbihpbmplY3Rvcikge1xuXG4gIC8vICgwKSBpbnZva2Ugc3VwZXIgbWV0aG9kXG5cbiAgRWRpdG9yQWN0aW9ucy5wcm90b3R5cGUuX3JlZ2lzdGVyRGVmYXVsdEFjdGlvbnMuY2FsbCh0aGlzLCBpbmplY3Rvcik7XG5cbiAgLy8gKDEpIHJldHJpZXZlIG9wdGlvbmFsIGNvbXBvbmVudHMgdG8gaW50ZWdyYXRlIHdpdGhcblxuICB2YXIgY2FudmFzID0gaW5qZWN0b3IuZ2V0KCdjYW52YXMnLCBmYWxzZSk7XG4gIHZhciBlbGVtZW50UmVnaXN0cnkgPSBpbmplY3Rvci5nZXQoJ2VsZW1lbnRSZWdpc3RyeScsIGZhbHNlKTtcbiAgdmFyIHNlbGVjdGlvbiA9IGluamVjdG9yLmdldCgnc2VsZWN0aW9uJywgZmFsc2UpO1xuICB2YXIgc3BhY2VUb29sID0gaW5qZWN0b3IuZ2V0KCdzcGFjZVRvb2wnLCBmYWxzZSk7XG4gIHZhciBsYXNzb1Rvb2wgPSBpbmplY3Rvci5nZXQoJ2xhc3NvVG9vbCcsIGZhbHNlKTtcbiAgdmFyIGhhbmRUb29sID0gaW5qZWN0b3IuZ2V0KCdoYW5kVG9vbCcsIGZhbHNlKTtcbiAgdmFyIGdsb2JhbENvbm5lY3QgPSBpbmplY3Rvci5nZXQoJ2dsb2JhbENvbm5lY3QnLCBmYWxzZSk7XG4gIHZhciBkaXN0cmlidXRlRWxlbWVudHMgPSBpbmplY3Rvci5nZXQoJ2Rpc3RyaWJ1dGVFbGVtZW50cycsIGZhbHNlKTtcbiAgdmFyIGFsaWduRWxlbWVudHMgPSBpbmplY3Rvci5nZXQoJ2FsaWduRWxlbWVudHMnLCBmYWxzZSk7XG4gIHZhciBkaXJlY3RFZGl0aW5nID0gaW5qZWN0b3IuZ2V0KCdkaXJlY3RFZGl0aW5nJywgZmFsc2UpO1xuICB2YXIgc2VhcmNoUGFkID0gaW5qZWN0b3IuZ2V0KCdzZWFyY2hQYWQnLCBmYWxzZSk7XG4gIHZhciBtb2RlbGluZyA9IGluamVjdG9yLmdldCgnbW9kZWxpbmcnLCBmYWxzZSk7XG5cbiAgLy8gKDIpIGNoZWNrIGNvbXBvbmVudHMgYW5kIHJlZ2lzdGVyIGFjdGlvbnNcblxuICBpZiAoY2FudmFzICYmIGVsZW1lbnRSZWdpc3RyeSAmJiBzZWxlY3Rpb24pIHtcbiAgICB0aGlzLl9yZWdpc3RlckFjdGlvbignc2VsZWN0RWxlbWVudHMnLCBmdW5jdGlvbigpIHtcblxuICAgICAgLy8gc2VsZWN0IGFsbCBlbGVtZW50cyBleGNlcHQgZm9yIHRoZSBpbnZpc2libGVcbiAgICAgIC8vIHJvb3QgZWxlbWVudFxuICAgICAgdmFyIHJvb3RFbGVtZW50ID0gY2FudmFzLmdldFJvb3RFbGVtZW50KCk7XG5cbiAgICAgIHZhciBlbGVtZW50cyA9IGVsZW1lbnRSZWdpc3RyeS5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZWxlbWVudCAhPT0gcm9vdEVsZW1lbnQ7XG4gICAgICB9KTtcblxuICAgICAgc2VsZWN0aW9uLnNlbGVjdChlbGVtZW50cyk7XG5cbiAgICAgIHJldHVybiBlbGVtZW50cztcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChzcGFjZVRvb2wpIHtcbiAgICB0aGlzLl9yZWdpc3RlckFjdGlvbignc3BhY2VUb29sJywgZnVuY3Rpb24oKSB7XG4gICAgICBzcGFjZVRvb2wudG9nZ2xlKCk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAobGFzc29Ub29sKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2xhc3NvVG9vbCcsIGZ1bmN0aW9uKCkge1xuICAgICAgbGFzc29Ub29sLnRvZ2dsZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGhhbmRUb29sKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2hhbmRUb29sJywgZnVuY3Rpb24oKSB7XG4gICAgICBoYW5kVG9vbC50b2dnbGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChnbG9iYWxDb25uZWN0KSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2dsb2JhbENvbm5lY3RUb29sJywgZnVuY3Rpb24oKSB7XG4gICAgICBnbG9iYWxDb25uZWN0LnRvZ2dsZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHNlbGVjdGlvbiAmJiBkaXN0cmlidXRlRWxlbWVudHMpIHtcbiAgICB0aGlzLl9yZWdpc3RlckFjdGlvbignZGlzdHJpYnV0ZUVsZW1lbnRzJywgZnVuY3Rpb24ob3B0cykge1xuICAgICAgdmFyIGN1cnJlbnRTZWxlY3Rpb24gPSBzZWxlY3Rpb24uZ2V0KCksXG4gICAgICAgICAgdHlwZSA9IG9wdHMudHlwZTtcblxuICAgICAgaWYgKGN1cnJlbnRTZWxlY3Rpb24ubGVuZ3RoKSB7XG4gICAgICAgIGRpc3RyaWJ1dGVFbGVtZW50cy50cmlnZ2VyKGN1cnJlbnRTZWxlY3Rpb24sIHR5cGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKHNlbGVjdGlvbiAmJiBhbGlnbkVsZW1lbnRzKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2FsaWduRWxlbWVudHMnLCBmdW5jdGlvbihvcHRzKSB7XG4gICAgICB2YXIgY3VycmVudFNlbGVjdGlvbiA9IHNlbGVjdGlvbi5nZXQoKSxcbiAgICAgICAgICBhbGlnbmVhYmxlRWxlbWVudHMgPSBbXSxcbiAgICAgICAgICB0eXBlID0gb3B0cy50eXBlO1xuXG4gICAgICBpZiAoY3VycmVudFNlbGVjdGlvbi5sZW5ndGgpIHtcbiAgICAgICAgYWxpZ25lYWJsZUVsZW1lbnRzID0gZmlsdGVyKGN1cnJlbnRTZWxlY3Rpb24sIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgICByZXR1cm4gIWlzKGVsZW1lbnQsICdicG1uOkxhbmUnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYWxpZ25FbGVtZW50cy50cmlnZ2VyKGFsaWduZWFibGVFbGVtZW50cywgdHlwZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBpZiAoc2VsZWN0aW9uICYmIG1vZGVsaW5nKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ3NldENvbG9yJywgZnVuY3Rpb24ob3B0cykge1xuICAgICAgdmFyIGN1cnJlbnRTZWxlY3Rpb24gPSBzZWxlY3Rpb24uZ2V0KCk7XG5cbiAgICAgIGlmIChjdXJyZW50U2VsZWN0aW9uLmxlbmd0aCkge1xuICAgICAgICBtb2RlbGluZy5zZXRDb2xvcihjdXJyZW50U2VsZWN0aW9uLCBvcHRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChzZWxlY3Rpb24gJiYgZGlyZWN0RWRpdGluZykge1xuICAgIHRoaXMuX3JlZ2lzdGVyQWN0aW9uKCdkaXJlY3RFZGl0aW5nJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgY3VycmVudFNlbGVjdGlvbiA9IHNlbGVjdGlvbi5nZXQoKTtcblxuICAgICAgaWYgKGN1cnJlbnRTZWxlY3Rpb24ubGVuZ3RoKSB7XG4gICAgICAgIGRpcmVjdEVkaXRpbmcuYWN0aXZhdGUoY3VycmVudFNlbGVjdGlvblswXSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBpZiAoc2VhcmNoUGFkKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2ZpbmQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHNlYXJjaFBhZC50b2dnbGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChjYW52YXMgJiYgbW9kZWxpbmcpIHtcbiAgICB0aGlzLl9yZWdpc3RlckFjdGlvbignbW92ZVRvT3JpZ2luJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgICAgICBib3VuZGluZ0JveCxcbiAgICAgICAgICBlbGVtZW50cztcblxuICAgICAgaWYgKGlzKHJvb3RFbGVtZW50LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykpIHtcbiAgICAgICAgZWxlbWVudHMgPSBlbGVtZW50UmVnaXN0cnkuZmlsdGVyKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgICByZXR1cm4gaXMoZWxlbWVudC5wYXJlbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbGVtZW50cyA9IGVsZW1lbnRSZWdpc3RyeS5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgIHJldHVybiBlbGVtZW50ICE9PSByb290RWxlbWVudCAmJiAhaXMoZWxlbWVudC5wYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGJvdW5kaW5nQm94ID0gZ2V0QkJveChlbGVtZW50cyk7XG5cbiAgICAgIG1vZGVsaW5nLm1vdmVFbGVtZW50cyhcbiAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIHsgeDogLWJvdW5kaW5nQm94LngsIHk6IC1ib3VuZGluZ0JveC55IH0sXG4gICAgICAgIHJvb3RFbGVtZW50XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbn07IiwiaW1wb3J0IEVkaXRvckFjdGlvbnNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZWRpdG9yLWFjdGlvbnMnO1xuXG5pbXBvcnQgQnBtbkVkaXRvckFjdGlvbnMgZnJvbSAnLi9CcG1uRWRpdG9yQWN0aW9ucyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBFZGl0b3JBY3Rpb25zTW9kdWxlXG4gIF0sXG4gIGVkaXRvckFjdGlvbnM6IFsgJ3R5cGUnLCBCcG1uRWRpdG9yQWN0aW9ucyBdXG59O1xuIiwiaW1wb3J0IHsgaXNBbnkgfSBmcm9tICcuLi9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uR3JpZFNuYXBwaW5nKGV2ZW50QnVzKSB7XHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2NyZWF0ZS5pbml0JyxcclxuICAgICdzaGFwZS5tb3ZlLmluaXQnXHJcbiAgXSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBzaGFwZSA9IGV2ZW50LnNoYXBlO1xyXG5cclxuICAgIGlmIChpc0FueShzaGFwZSwgW1xyXG4gICAgICAnYnBtbjpQYXJ0aWNpcGFudCcsXHJcbiAgICAgICdicG1uOlN1YlByb2Nlc3MnLFxyXG4gICAgICAnYnBtbjpUZXh0QW5ub3RhdGlvbidcclxuICAgIF0pKSB7XHJcbiAgICAgIGlmICghY29udGV4dC5ncmlkU25hcHBpbmdDb250ZXh0KSB7XHJcbiAgICAgICAgY29udGV4dC5ncmlkU25hcHBpbmdDb250ZXh0ID0ge307XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnRleHQuZ3JpZFNuYXBwaW5nQ29udGV4dC5zbmFwTG9jYXRpb24gPSAndG9wLWxlZnQnO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5CcG1uR3JpZFNuYXBwaW5nLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTsiLCJpbXBvcnQgeyBnZXROZXdTaGFwZVBvc2l0aW9uIH0gZnJvbSAnLi4vLi4vYXV0by1wbGFjZS9CcG1uQXV0b1BsYWNlVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBnZXRNaWQgfSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XHJcbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xyXG5cclxudmFyIEhJR0hfUFJJT1JJVFkgPSAyMDAwO1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEF1dG9QbGFjZUJlaGF2aW9yKGV2ZW50QnVzLCBncmlkU25hcHBpbmcpIHtcclxuICBldmVudEJ1cy5vbignYXV0b1BsYWNlJywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oY29udGV4dCkge1xyXG4gICAgdmFyIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxyXG4gICAgICAgIHNvdXJjZU1pZCA9IGdldE1pZChzb3VyY2UpLFxyXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZTtcclxuXHJcbiAgICB2YXIgcG9zaXRpb24gPSBnZXROZXdTaGFwZVBvc2l0aW9uKHNvdXJjZSwgc2hhcGUpO1xyXG5cclxuICAgIFsgJ3gnLCAneScgXS5mb3JFYWNoKGZ1bmN0aW9uKGF4aXMpIHtcclxuICAgICAgdmFyIG9wdGlvbnMgPSB7fTtcclxuXHJcbiAgICAgIC8vIGRvIG5vdCBzbmFwIGlmIHgveSBlcXVhbFxyXG4gICAgICBpZiAocG9zaXRpb25bIGF4aXMgXSA9PT0gc291cmNlTWlkWyBheGlzIF0pIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChwb3NpdGlvblsgYXhpcyBdID4gc291cmNlTWlkWyBheGlzIF0pIHtcclxuICAgICAgICBvcHRpb25zLm1pbiA9IHBvc2l0aW9uWyBheGlzIF07XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgb3B0aW9ucy5tYXggPSBwb3NpdGlvblsgYXhpcyBdO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXMoc2hhcGUsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcclxuXHJcbiAgICAgICAgaWYgKGlzSG9yaXpvbnRhbChheGlzKSkge1xyXG4gICAgICAgICAgb3B0aW9ucy5vZmZzZXQgPSAtc2hhcGUud2lkdGggLyAyO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBvcHRpb25zLm9mZnNldCA9IC1zaGFwZS5oZWlnaHQgLyAyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHBvc2l0aW9uWyBheGlzIF0gPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKHBvc2l0aW9uWyBheGlzIF0sIG9wdGlvbnMpO1xyXG5cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIG11c3QgYmUgcmV0dXJuZWQgdG8gYmUgY29uc2lkZXJlZCBieSBhdXRvIHBsYWNlXHJcbiAgICByZXR1cm4gcG9zaXRpb247XHJcbiAgfSk7XHJcbn1cclxuXHJcbkF1dG9QbGFjZUJlaGF2aW9yLiRpbmplY3QgPSBbXHJcbiAgJ2V2ZW50QnVzJyxcclxuICAnZ3JpZFNuYXBwaW5nJ1xyXG5dO1xyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBpc0hvcml6b250YWwoYXhpcykge1xyXG4gIHJldHVybiBheGlzID09PSAneCc7XHJcbn0iLCJpbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcclxuXHJcbnZhciBISUdIRVJfUFJJT1JJVFkgPSAxNzUwO1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IoY2FudmFzLCBldmVudEJ1cywgZ3JpZFNuYXBwaW5nKSB7XHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2NyZWF0ZS5zdGFydCcsXHJcbiAgICAnc2hhcGUubW92ZS5zdGFydCdcclxuICBdLCBISUdIRVJfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxyXG4gICAgICAgIHJvb3RFbGVtZW50ID0gY2FudmFzLmdldFJvb3RFbGVtZW50KCk7XHJcblxyXG4gICAgaWYgKCFpcyhzaGFwZSwgJ2JwbW46UGFydGljaXBhbnQnKSB8fFxyXG4gICAgICAhaXMocm9vdEVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSB8fFxyXG4gICAgICAhcm9vdEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgY3JlYXRlQ29uc3RyYWludHMgPSBjb250ZXh0LmNyZWF0ZUNvbnN0cmFpbnRzO1xyXG5cclxuICAgIGlmICghY3JlYXRlQ29uc3RyYWludHMpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHNoYXBlLndpZHRoID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShzaGFwZS53aWR0aCwgeyBtaW46IHNoYXBlLndpZHRoIH0pO1xyXG4gICAgc2hhcGUuaGVpZ2h0ID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShzaGFwZS5oZWlnaHQsIHsgbWluOiBzaGFwZS5oZWlnaHQgfSk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbkNyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IuJGluamVjdCA9IFtcclxuICAnY2FudmFzJyxcclxuICAnZXZlbnRCdXMnLFxyXG4gICdncmlkU25hcHBpbmcnXHJcbl07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7IHBvaW50c0FsaWduZWQgfSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0dlb21ldHJ5JztcblxuaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIEhJR0hfUFJJT1JJVFkgPSAzMDAwO1xuXG5cbi8qKlxuICogU25hcHMgY29ubmVjdGlvbnMgd2l0aCBNYW5oYXR0YW4gbGF5b3V0LlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBMYXlvdXRDb25uZWN0aW9uQmVoYXZpb3IoZXZlbnRCdXMsIGdyaWRTbmFwcGluZywgbW9kZWxpbmcpIHtcbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuX2dyaWRTbmFwcGluZyA9IGdyaWRTbmFwcGluZztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoW1xuICAgICdjb25uZWN0aW9uLmNyZWF0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubGF5b3V0J1xuICBdLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cztcblxuICAgIGlmIChoaW50cy5jb25uZWN0aW9uU3RhcnQgfHwgaGludHMuY29ubmVjdGlvbkVuZCB8fCBoaW50cy5jcmVhdGVFbGVtZW50c0JlaGF2aW9yID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaGFzTWlkZGxlU2VnbWVudHMod2F5cG9pbnRzKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG1vZGVsaW5nLnVwZGF0ZVdheXBvaW50cyhjb25uZWN0aW9uLCBzZWxmLnNuYXBNaWRkbGVTZWdtZW50cyh3YXlwb2ludHMpKTtcbiAgfSk7XG59XG5cbkxheW91dENvbm5lY3Rpb25CZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZ3JpZFNuYXBwaW5nJyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuaW5oZXJpdHMoTGF5b3V0Q29ubmVjdGlvbkJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG4vKipcbiAqIFNuYXAgbWlkZGxlIHNlZ21lbnRzIG9mIGEgZ2l2ZW4gY29ubmVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PFBvaW50Pn0gd2F5cG9pbnRzXG4gKlxuICogQHJldHVybnMge0FycmF5PFBvaW50Pn1cbiAqL1xuTGF5b3V0Q29ubmVjdGlvbkJlaGF2aW9yLnByb3RvdHlwZS5zbmFwTWlkZGxlU2VnbWVudHMgPSBmdW5jdGlvbih3YXlwb2ludHMpIHtcbiAgdmFyIGdyaWRTbmFwcGluZyA9IHRoaXMuX2dyaWRTbmFwcGluZyxcbiAgICAgIHNuYXBwZWQ7XG5cbiAgd2F5cG9pbnRzID0gd2F5cG9pbnRzLnNsaWNlKCk7XG5cbiAgZm9yICh2YXIgaSA9IDE7IGkgPCB3YXlwb2ludHMubGVuZ3RoIC0gMjsgaSsrKSB7XG5cbiAgICBzbmFwcGVkID0gc25hcFNlZ21lbnQoZ3JpZFNuYXBwaW5nLCB3YXlwb2ludHNbaV0sIHdheXBvaW50c1tpICsgMV0pO1xuXG4gICAgd2F5cG9pbnRzW2ldID0gc25hcHBlZFswXTtcbiAgICB3YXlwb2ludHNbaSArIDFdID0gc25hcHBlZFsxXTtcbiAgfVxuXG4gIHJldHVybiB3YXlwb2ludHM7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgYSBjb25uZWN0aW9uIGhhcyBhIG1pZGRsZSBzZWdtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSB3YXlwb2ludHNcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaGFzTWlkZGxlU2VnbWVudHMod2F5cG9pbnRzKSB7XG4gIHJldHVybiB3YXlwb2ludHMubGVuZ3RoID4gMztcbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGFuIGFsaWdubWVudCBpcyBob3Jpem9udGFsLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhbGlnbmVkXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGhvcml6b250YWxseUFsaWduZWQoYWxpZ25lZCkge1xuICByZXR1cm4gYWxpZ25lZCA9PT0gJ2gnO1xufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgYW4gYWxpZ25tZW50IGlzIHZlcnRpY2FsLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhbGlnbmVkXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIHZlcnRpY2FsbHlBbGlnbmVkKGFsaWduZWQpIHtcbiAgcmV0dXJuIGFsaWduZWQgPT09ICd2Jztcbn1cblxuLyoqXG4gKiBHZXQgbWlkZGxlIHNlZ21lbnRzIGZyb20gYSBnaXZlbiBjb25uZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHdheXBvaW50c1xuICpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gc25hcFNlZ21lbnQoZ3JpZFNuYXBwaW5nLCBzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQpIHtcblxuICB2YXIgYWxpZ25lZCA9IHBvaW50c0FsaWduZWQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKTtcblxuICB2YXIgc25hcHBlZCA9IHt9O1xuXG4gIGlmIChob3Jpem9udGFsbHlBbGlnbmVkKGFsaWduZWQpKSB7XG5cbiAgICAvLyBzbmFwIGhvcml6b250YWxseVxuICAgIHNuYXBwZWQueSA9IGdyaWRTbmFwcGluZy5zbmFwVmFsdWUoc2VnbWVudFN0YXJ0LnkpO1xuICB9XG5cbiAgaWYgKHZlcnRpY2FsbHlBbGlnbmVkKGFsaWduZWQpKSB7XG5cbiAgICAvLyBzbmFwIHZlcnRpY2FsbHlcbiAgICBzbmFwcGVkLnggPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKHNlZ21lbnRTdGFydC54KTtcbiAgfVxuXG4gIGlmICgneCcgaW4gc25hcHBlZCB8fCAneScgaW4gc25hcHBlZCkge1xuICAgIHNlZ21lbnRTdGFydCA9IGFzc2lnbih7fSwgc2VnbWVudFN0YXJ0LCBzbmFwcGVkKTtcbiAgICBzZWdtZW50RW5kID0gYXNzaWduKHt9LCBzZWdtZW50RW5kLCBzbmFwcGVkKTtcbiAgfVxuXG4gIHJldHVybiBbIHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCBdO1xufSIsImltcG9ydCBBdXRvUGxhY2VCZWhhdmlvciBmcm9tICcuL0F1dG9QbGFjZUJlaGF2aW9yJztcclxuaW1wb3J0IENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IgZnJvbSAnLi9DcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yJztcclxuaW1wb3J0IExheW91dENvbm5lY3Rpb25CZWhhdmlvciBmcm9tICcuL0xheW91dENvbm5lY3Rpb25CZWhhdmlvcic7XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgX19pbml0X186IFtcclxuICAgICdncmlkU25hcHBpbmdBdXRvUGxhY2VCZWhhdmlvcicsXHJcbiAgICAnZ3JpZFNuYXBwaW5nQ3JlYXRlUGFydGljaXBhbnRCZWhhdmlvcicsXHJcbiAgICAnZ3JpZFNuYXBwaW5nTGF5b3V0Q29ubmVjdGlvbkJlaGF2aW9yJyxcclxuICBdLFxyXG4gIGdyaWRTbmFwcGluZ0F1dG9QbGFjZUJlaGF2aW9yOiBbICd0eXBlJywgQXV0b1BsYWNlQmVoYXZpb3IgXSxcclxuICBncmlkU25hcHBpbmdDcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yOiBbICd0eXBlJywgQ3JlYXRlUGFydGljaXBhbnRCZWhhdmlvciBdLFxyXG4gIGdyaWRTbmFwcGluZ0xheW91dENvbm5lY3Rpb25CZWhhdmlvcjogWyAndHlwZScsIExheW91dENvbm5lY3Rpb25CZWhhdmlvciBdXHJcbn07IiwiaW1wb3J0IEJwbW5HcmlkU25hcHBpbmcgZnJvbSAnLi9CcG1uR3JpZFNuYXBwaW5nJztcclxuaW1wb3J0IEdyaWRTbmFwcGluZ01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nJztcclxuXHJcbmltcG9ydCBHcmlkU25hcHBpbmdCZWhhdmlvck1vZHVsZSBmcm9tICcuL2JlaGF2aW9yJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBfX2RlcGVuZHNfXzogW1xyXG4gICAgR3JpZFNuYXBwaW5nTW9kdWxlLFxyXG4gICAgR3JpZFNuYXBwaW5nQmVoYXZpb3JNb2R1bGVcclxuICBdLFxyXG4gIF9faW5pdF9fOiBbICdicG1uR3JpZFNuYXBwaW5nJyBdLFxyXG4gIGJwbW5HcmlkU25hcHBpbmc6IFsgJ3R5cGUnLCBCcG1uR3JpZFNuYXBwaW5nIF1cclxufTsiLCJpbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHsgaXNFeHBhbmRlZCB9IGZyb20gJy4uLy4uL3V0aWwvRGlVdGlsJztcblxudmFyIExBQkVMX1dJRFRIID0gMzAsXG4gICAgTEFCRUxfSEVJR0hUID0gMzA7XG5cblxuLyoqXG4gKiBCUE1OLXNwZWNpZmljIGhpdCB6b25lcyBhbmQgaW50ZXJhY3Rpb24gZml4ZXMuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7SW50ZXJhY3Rpb25FdmVudHN9IGludGVyYWN0aW9uRXZlbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5JbnRlcmFjdGlvbkV2ZW50cyhldmVudEJ1cywgaW50ZXJhY3Rpb25FdmVudHMpIHtcblxuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cyA9IGludGVyYWN0aW9uRXZlbnRzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbihbXG4gICAgJ2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUhpdCcsXG4gICAgJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCdcbiAgXSwgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBnZnggPSBjb250ZXh0LmdmeDtcblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpMYW5lJykpIHtcbiAgICAgIHJldHVybiBzZWxmLmNyZWF0ZVBhcnRpY2lwYW50SGl0KGVsZW1lbnQsIGdmeCk7XG4gICAgfSBlbHNlXG5cbiAgICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuICAgICAgaWYgKGlzRXhwYW5kZWQoZWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuY3JlYXRlUGFydGljaXBhbnRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgICAgIH1cbiAgICB9IGVsc2VcblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpTdWJQcm9jZXNzJykpIHtcbiAgICAgIGlmIChpc0V4cGFuZGVkKGVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZVN1YlByb2Nlc3NIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG59XG5cbkJwbW5JbnRlcmFjdGlvbkV2ZW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnaW50ZXJhY3Rpb25FdmVudHMnXG5dO1xuXG5cbkJwbW5JbnRlcmFjdGlvbkV2ZW50cy5wcm90b3R5cGUuY3JlYXRlRGVmYXVsdEhpdCA9IGZ1bmN0aW9uKGVsZW1lbnQsIGdmeCkge1xuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cy5yZW1vdmVIaXRzKGdmeCk7XG5cbiAgdGhpcy5faW50ZXJhY3Rpb25FdmVudHMuY3JlYXRlRGVmYXVsdEhpdChlbGVtZW50LCBnZngpO1xuXG4gIC8vIGluZGljYXRlIHRoYXQgd2UgY3JlYXRlZCBhIGhpdFxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkJwbW5JbnRlcmFjdGlvbkV2ZW50cy5wcm90b3R5cGUuY3JlYXRlUGFydGljaXBhbnRIaXQgPSBmdW5jdGlvbihlbGVtZW50LCBnZngpIHtcblxuICAvLyByZW1vdmUgZXhpc3RpbmcgaGl0c1xuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cy5yZW1vdmVIaXRzKGdmeCk7XG5cbiAgLy8gYWRkIG91dGxpbmUgaGl0XG4gIHRoaXMuX2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUJveEhpdChnZngsICdjbGljay1zdHJva2UnLCB7XG4gICAgd2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICB9KTtcblxuICAvLyBhZGQgbGFiZWwgaGl0XG4gIHRoaXMuX2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUJveEhpdChnZngsICdhbGwnLCB7XG4gICAgd2lkdGg6IExBQkVMX1dJRFRILFxuICAgIGhlaWdodDogZWxlbWVudC5oZWlnaHRcbiAgfSk7XG5cbiAgLy8gaW5kaWNhdGUgdGhhdCB3ZSBjcmVhdGVkIGEgaGl0XG4gIHJldHVybiB0cnVlO1xufTtcblxuQnBtbkludGVyYWN0aW9uRXZlbnRzLnByb3RvdHlwZS5jcmVhdGVTdWJQcm9jZXNzSGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG5cbiAgLy8gcmVtb3ZlIGV4aXN0aW5nIGhpdHNcbiAgdGhpcy5faW50ZXJhY3Rpb25FdmVudHMucmVtb3ZlSGl0cyhnZngpO1xuXG4gIC8vIGFkZCBvdXRsaW5lIGhpdFxuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cy5jcmVhdGVCb3hIaXQoZ2Z4LCAnY2xpY2stc3Ryb2tlJywge1xuICAgIHdpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgIGhlaWdodDogZWxlbWVudC5oZWlnaHRcbiAgfSk7XG5cbiAgLy8gYWRkIGxhYmVsIGhpdFxuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cy5jcmVhdGVCb3hIaXQoZ2Z4LCAnYWxsJywge1xuICAgIHdpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgIGhlaWdodDogTEFCRUxfSEVJR0hUXG4gIH0pO1xuXG4gIC8vIGluZGljYXRlIHRoYXQgd2UgY3JlYXRlZCBhIGhpdFxuICByZXR1cm4gdHJ1ZTtcbn07IiwiaW1wb3J0IEJwbW5JbnRlcmFjdGlvbkV2ZW50cyBmcm9tICcuL0JwbW5JbnRlcmFjdGlvbkV2ZW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2JwbW5JbnRlcmFjdGlvbkV2ZW50cycgXSxcbiAgYnBtbkludGVyYWN0aW9uRXZlbnRzOiBbICd0eXBlJywgQnBtbkludGVyYWN0aW9uRXZlbnRzIF1cbn07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IEtleWJvYXJkQmluZGluZ3MgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQvS2V5Ym9hcmRCaW5kaW5ncyc7XG5cblxuLyoqXG4gKiBCUE1OIDIuMCBzcGVjaWZpYyBrZXlib2FyZCBiaW5kaW5ncy5cbiAqXG4gKiBAcGFyYW0ge0luamVjdG9yfSBpbmplY3RvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uS2V5Ym9hcmRCaW5kaW5ncyhpbmplY3Rvcikge1xuICBpbmplY3Rvci5pbnZva2UoS2V5Ym9hcmRCaW5kaW5ncywgdGhpcyk7XG59XG5cbmluaGVyaXRzKEJwbW5LZXlib2FyZEJpbmRpbmdzLCBLZXlib2FyZEJpbmRpbmdzKTtcblxuQnBtbktleWJvYXJkQmluZGluZ3MuJGluamVjdCA9IFtcbiAgJ2luamVjdG9yJ1xuXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVyIGF2YWlsYWJsZSBrZXlib2FyZCBiaW5kaW5ncy5cbiAqXG4gKiBAcGFyYW0ge0tleWJvYXJkfSBrZXlib2FyZFxuICogQHBhcmFtIHtFZGl0b3JBY3Rpb25zfSBlZGl0b3JBY3Rpb25zXG4gKi9cbkJwbW5LZXlib2FyZEJpbmRpbmdzLnByb3RvdHlwZS5yZWdpc3RlckJpbmRpbmdzID0gZnVuY3Rpb24oa2V5Ym9hcmQsIGVkaXRvckFjdGlvbnMpIHtcblxuICAvLyBpbmhlcml0IGRlZmF1bHQgYmluZGluZ3NcbiAgS2V5Ym9hcmRCaW5kaW5ncy5wcm90b3R5cGUucmVnaXN0ZXJCaW5kaW5ncy5jYWxsKHRoaXMsIGtleWJvYXJkLCBlZGl0b3JBY3Rpb25zKTtcblxuICAvKipcbiAgICogQWRkIGtleWJvYXJkIGJpbmRpbmcgaWYgcmVzcGVjdGl2ZSBlZGl0b3IgYWN0aW9uXG4gICAqIGlzIHJlZ2lzdGVyZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24gbmFtZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiB0aGF0IGltcGxlbWVudHMgdGhlIGtleSBiaW5kaW5nXG4gICAqL1xuICBmdW5jdGlvbiBhZGRMaXN0ZW5lcihhY3Rpb24sIGZuKSB7XG5cbiAgICBpZiAoZWRpdG9yQWN0aW9ucy5pc1JlZ2lzdGVyZWQoYWN0aW9uKSkge1xuICAgICAga2V5Ym9hcmQuYWRkTGlzdGVuZXIoZm4pO1xuICAgIH1cbiAgfVxuXG4gIC8vIHNlbGVjdCBhbGwgZWxlbWVudHNcbiAgLy8gQ1RSTCArIEFcbiAgYWRkTGlzdGVuZXIoJ3NlbGVjdEVsZW1lbnRzJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGV2ZW50ID0gY29udGV4dC5rZXlFdmVudDtcblxuICAgIGlmIChrZXlib2FyZC5pc0tleShbJ2EnLCAnQSddLCBldmVudCkgJiYga2V5Ym9hcmQuaXNDbWQoZXZlbnQpKSB7XG4gICAgICBlZGl0b3JBY3Rpb25zLnRyaWdnZXIoJ3NlbGVjdEVsZW1lbnRzJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gc2VhcmNoIGxhYmVsc1xuICAvLyBDVFJMICsgRlxuICBhZGRMaXN0ZW5lcignZmluZCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoa2V5Ym9hcmQuaXNLZXkoWydmJywgJ0YnXSwgZXZlbnQpICYmIGtleWJvYXJkLmlzQ21kKGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdmaW5kJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWN0aXZhdGUgc3BhY2UgdG9vbFxuICAvLyBTXG4gIGFkZExpc3RlbmVyKCdzcGFjZVRvb2wnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGtleWJvYXJkLmhhc01vZGlmaWVyKGV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChrZXlib2FyZC5pc0tleShbJ3MnLCAnUyddLCBldmVudCkpIHtcbiAgICAgIGVkaXRvckFjdGlvbnMudHJpZ2dlcignc3BhY2VUb29sJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWN0aXZhdGUgbGFzc28gdG9vbFxuICAvLyBMXG4gIGFkZExpc3RlbmVyKCdsYXNzb1Rvb2wnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGtleWJvYXJkLmhhc01vZGlmaWVyKGV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChrZXlib2FyZC5pc0tleShbJ2wnLCAnTCddLCBldmVudCkpIHtcbiAgICAgIGVkaXRvckFjdGlvbnMudHJpZ2dlcignbGFzc29Ub29sJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWN0aXZhdGUgaGFuZCB0b29sXG4gIC8vIEhcbiAgYWRkTGlzdGVuZXIoJ2hhbmRUb29sJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGV2ZW50ID0gY29udGV4dC5rZXlFdmVudDtcblxuICAgIGlmIChrZXlib2FyZC5oYXNNb2RpZmllcihldmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoa2V5Ym9hcmQuaXNLZXkoWydoJywgJ0gnXSwgZXZlbnQpKSB7XG4gICAgICBlZGl0b3JBY3Rpb25zLnRyaWdnZXIoJ2hhbmRUb29sJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWN0aXZhdGUgZ2xvYmFsIGNvbm5lY3QgdG9vbFxuICAvLyBDXG4gIGFkZExpc3RlbmVyKCdnbG9iYWxDb25uZWN0VG9vbCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoa2V5Ym9hcmQuaGFzTW9kaWZpZXIoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGtleWJvYXJkLmlzS2V5KFsnYycsICdDJ10sIGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdnbG9iYWxDb25uZWN0VG9vbCcpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIGFjdGl2YXRlIGRpcmVjdCBlZGl0aW5nXG4gIC8vIEVcbiAgYWRkTGlzdGVuZXIoJ2RpcmVjdEVkaXRpbmcnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGtleWJvYXJkLmhhc01vZGlmaWVyKGV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChrZXlib2FyZC5pc0tleShbJ2UnLCAnRSddLCBldmVudCkpIHtcbiAgICAgIGVkaXRvckFjdGlvbnMudHJpZ2dlcignZGlyZWN0RWRpdGluZycpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG59OyIsImltcG9ydCBLZXlib2FyZE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9rZXlib2FyZCc7XG5cbmltcG9ydCBCcG1uS2V5Ym9hcmRCaW5kaW5ncyBmcm9tICcuL0JwbW5LZXlib2FyZEJpbmRpbmdzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIEtleWJvYXJkTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdrZXlib2FyZEJpbmRpbmdzJyBdLFxuICBrZXlib2FyZEJpbmRpbmdzOiBbICd0eXBlJywgQnBtbktleWJvYXJkQmluZGluZ3MgXVxufTtcbiIsImltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY3JlYXRlIGFzIHN2Z0NyZWF0ZSxcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIHRyYW5zbGF0ZVxufSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL1N2Z1RyYW5zZm9ybVV0aWwnO1xuXG52YXIgTUFSS0VSX0hJRERFTiA9ICdkanMtZWxlbWVudC1oaWRkZW4nLFxuICAgIE1BUktFUl9MQUJFTF9ISURERU4gPSAnZGpzLWxhYmVsLWhpZGRlbic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGFiZWxFZGl0aW5nUHJldmlldyhcbiAgICBldmVudEJ1cywgY2FudmFzLCBlbGVtZW50UmVnaXN0cnksXG4gICAgcGF0aE1hcCkge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgZGVmYXVsdExheWVyID0gY2FudmFzLmdldERlZmF1bHRMYXllcigpO1xuXG4gIHZhciBlbGVtZW50LCBhYnNvbHV0ZUVsZW1lbnRCQm94LCBnZng7XG5cbiAgZXZlbnRCdXMub24oJ2RpcmVjdEVkaXRpbmcuYWN0aXZhdGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIGFjdGl2ZVByb3ZpZGVyID0gY29udGV4dC5hY3RpdmU7XG5cbiAgICBlbGVtZW50ID0gYWN0aXZlUHJvdmlkZXIuZWxlbWVudC5sYWJlbCB8fCBhY3RpdmVQcm92aWRlci5lbGVtZW50O1xuXG4gICAgLy8gdGV4dCBhbm5vdGF0aW9uXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcbiAgICAgIGFic29sdXRlRWxlbWVudEJCb3ggPSBjYW52YXMuZ2V0QWJzb2x1dGVCQm94KGVsZW1lbnQpO1xuXG4gICAgICBnZnggPSBzdmdDcmVhdGUoJ2cnKTtcblxuICAgICAgdmFyIHRleHRQYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEVYVF9BTk5PVEFUSU9OJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuMCxcbiAgICAgICAgICBteTogMC4wXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgcGF0aCA9IHNlbGYucGF0aCA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuXG4gICAgICBzdmdBdHRyKHBhdGgsIHtcbiAgICAgICAgZDogdGV4dFBhdGhEYXRhLFxuICAgICAgICBzdHJva2VXaWR0aDogMixcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50KVxuICAgICAgfSk7XG5cbiAgICAgIHN2Z0FwcGVuZChnZngsIHBhdGgpO1xuXG4gICAgICBzdmdBcHBlbmQoZGVmYXVsdExheWVyLCBnZngpO1xuXG4gICAgICB0cmFuc2xhdGUoZ2Z4LCBlbGVtZW50LngsIGVsZW1lbnQueSk7XG4gICAgfVxuXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykgfHxcbiAgICAgICAgZWxlbWVudC5sYWJlbFRhcmdldCkge1xuICAgICAgY2FudmFzLmFkZE1hcmtlcihlbGVtZW50LCBNQVJLRVJfSElEREVOKTtcbiAgICB9IGVsc2UgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRhc2snKSB8fFxuICAgICAgICAgICAgICAgaXMoZWxlbWVudCwgJ2JwbW46Q2FsbEFjdGl2aXR5JykgfHxcbiAgICAgICAgICAgICAgIGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSB8fFxuICAgICAgICAgICAgICAgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuICAgICAgY2FudmFzLmFkZE1hcmtlcihlbGVtZW50LCBNQVJLRVJfTEFCRUxfSElEREVOKTtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdkaXJlY3RFZGl0aW5nLnJlc2l6ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIC8vIHRleHQgYW5ub3RhdGlvblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgICB2YXIgaGVpZ2h0ID0gY29udGV4dC5oZWlnaHQsXG4gICAgICAgICAgZHkgPSBjb250ZXh0LmR5O1xuXG4gICAgICB2YXIgbmV3RWxlbWVudEhlaWdodCA9IE1hdGgubWF4KGVsZW1lbnQuaGVpZ2h0IC8gYWJzb2x1dGVFbGVtZW50QkJveC5oZWlnaHQgKiAoaGVpZ2h0ICsgZHkpLCAwKTtcblxuICAgICAgdmFyIHRleHRQYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEVYVF9BTk5PVEFUSU9OJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogbmV3RWxlbWVudEhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogMC4wLFxuICAgICAgICAgIG15OiAwLjBcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHN2Z0F0dHIoc2VsZi5wYXRoLCB7XG4gICAgICAgIGQ6IHRleHRQYXRoRGF0YVxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdkaXJlY3RFZGl0aW5nLmNvbXBsZXRlJywgJ2RpcmVjdEVkaXRpbmcuY2FuY2VsJyBdLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIGFjdGl2ZVByb3ZpZGVyID0gY29udGV4dC5hY3RpdmU7XG5cbiAgICBpZiAoYWN0aXZlUHJvdmlkZXIpIHtcbiAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoYWN0aXZlUHJvdmlkZXIuZWxlbWVudC5sYWJlbCB8fCBhY3RpdmVQcm92aWRlci5lbGVtZW50LCBNQVJLRVJfSElEREVOKTtcbiAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoZWxlbWVudCwgTUFSS0VSX0xBQkVMX0hJRERFTik7XG4gICAgfVxuXG4gICAgZWxlbWVudCA9IHVuZGVmaW5lZDtcbiAgICBhYnNvbHV0ZUVsZW1lbnRCQm94ID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGdmeCkge1xuICAgICAgc3ZnUmVtb3ZlKGdmeCk7XG5cbiAgICAgIGdmeCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0pO1xufVxuXG5MYWJlbEVkaXRpbmdQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ3BhdGhNYXAnXG5dO1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0Q29sb3IpIHtcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XG5cbiAgcmV0dXJuIGJvLmRpLmdldCgnc3Ryb2tlJykgfHwgZGVmYXVsdENvbG9yIHx8ICdibGFjayc7XG59IiwiaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0TGFiZWxcbn0gZnJvbSAnLi9MYWJlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRCdXNpbmVzc09iamVjdCxcbiAgaXNcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVDYXRlZ29yeVZhbHVlXG59IGZyb20gJy4uL21vZGVsaW5nL2JlaGF2aW9yL3V0aWwvQ2F0ZWdvcnlVdGlsJztcblxuaW1wb3J0IHsgaXNBbnkgfSBmcm9tICcuLi9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCc7XG5pbXBvcnQgeyBpc0V4cGFuZGVkIH0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRFeHRlcm5hbExhYmVsTWlkLFxuICBpc0xhYmVsRXh0ZXJuYWwsXG4gIGhhc0V4dGVybmFsTGFiZWwsXG4gIGlzTGFiZWxcbn0gZnJvbSAnLi4vLi4vdXRpbC9MYWJlbFV0aWwnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIExhYmVsRWRpdGluZ1Byb3ZpZGVyKFxuICAgIGV2ZW50QnVzLCBicG1uRmFjdG9yeSwgY2FudmFzLCBkaXJlY3RFZGl0aW5nLFxuICAgIG1vZGVsaW5nLCByZXNpemVIYW5kbGVzLCB0ZXh0UmVuZGVyZXIpIHtcblxuICB0aGlzLl9icG1uRmFjdG9yeSA9IGJwbW5GYWN0b3J5O1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX3RleHRSZW5kZXJlciA9IHRleHRSZW5kZXJlcjtcblxuICBkaXJlY3RFZGl0aW5nLnJlZ2lzdGVyUHJvdmlkZXIodGhpcyk7XG5cbiAgLy8gbGlzdGVuIHRvIGRibGNsaWNrIG9uIG5vbi1yb290IGVsZW1lbnRzXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LmRibGNsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBhY3RpdmF0ZURpcmVjdEVkaXQoZXZlbnQuZWxlbWVudCwgdHJ1ZSk7XG4gIH0pO1xuXG4gIC8vIGNvbXBsZXRlIG9uIGZvbGxvd3VwIGNhbnZhcyBvcGVyYXRpb25cbiAgZXZlbnRCdXMub24oW1xuICAgICdhdXRvUGxhY2Uuc3RhcnQnLFxuICAgICdjYW52YXMudmlld2JveC5jaGFuZ2luZycsXG4gICAgJ2RyYWcuaW5pdCcsXG4gICAgJ2VsZW1lbnQubW91c2Vkb3duJyxcbiAgICAncG9wdXBNZW51Lm9wZW4nXG4gIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICBpZiAoZGlyZWN0RWRpdGluZy5pc0FjdGl2ZSgpKSB7XG4gICAgICBkaXJlY3RFZGl0aW5nLmNvbXBsZXRlKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBjYW5jZWwgb24gY29tbWFuZCBzdGFjayBjaGFuZ2VzXG4gIGV2ZW50QnVzLm9uKFsgJ2NvbW1hbmRTdGFjay5jaGFuZ2VkJyBdLCBmdW5jdGlvbihlKSB7XG4gICAgaWYgKGRpcmVjdEVkaXRpbmcuaXNBY3RpdmUoKSkge1xuICAgICAgZGlyZWN0RWRpdGluZy5jYW5jZWwoKTtcbiAgICB9XG4gIH0pO1xuXG5cbiAgZXZlbnRCdXMub24oJ2RpcmVjdEVkaXRpbmcuYWN0aXZhdGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHJlc2l6ZUhhbmRsZXMucmVtb3ZlUmVzaXplcnMoKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2NyZWF0ZS5lbmQnLCA1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnQgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBjYW5FeGVjdXRlID0gZXZlbnQuY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBpc1RvdWNoID0gZXZlbnQuaXNUb3VjaDtcblxuICAgIC8vIFRPRE8obmlra3UpOiB3ZSBuZWVkIHRvIGZpbmQgYSB3YXkgdG8gc3VwcG9ydCB0aGVcbiAgICAvLyBkaXJlY3QgZWRpdGluZyBvbiBtb2JpbGUgZGV2aWNlczsgcmlnaHQgbm93IHRoaXMgd2lsbFxuICAgIC8vIGJyZWFrIGZvciBkZXN3b3JrZmxvd2VkaXRpbmcgb24gbW9iaWxlIGRldmljZXNcbiAgICAvLyBhcyBpdCBicmVha3MgdGhlIHVzZXIgaW50ZXJhY3Rpb24gd29ya2Zsb3dcblxuICAgIC8vIFRPRE8obnJlKTogd2Ugc2hvdWxkIHRlbXBvcmFyaWx5IGZvY3VzIHRoZSBlZGl0ZWQgZWxlbWVudFxuICAgIC8vIGhlcmUgYW5kIHJlbGVhc2UgdGhlIGZvY3VzZWQgdmlld3BvcnQgYWZ0ZXIgdGhlIGRpcmVjdCBlZGl0XG4gICAgLy8gb3BlcmF0aW9uIGlzIGZpbmlzaGVkXG4gICAgaWYgKGlzVG91Y2gpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWNhbkV4ZWN1dGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dC5oaW50cyAmJiBjb250ZXh0LmhpbnRzLmNyZWF0ZUVsZW1lbnRzQmVoYXZpb3IgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYWN0aXZhdGVEaXJlY3RFZGl0KGVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignYXV0b1BsYWNlLmVuZCcsIDUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBhY3RpdmF0ZURpcmVjdEVkaXQoZXZlbnQuc2hhcGUpO1xuICB9KTtcblxuXG4gIGZ1bmN0aW9uIGFjdGl2YXRlRGlyZWN0RWRpdChlbGVtZW50LCBmb3JjZSkge1xuICAgIGlmIChmb3JjZSB8fFxuICAgICAgICBpc0FueShlbGVtZW50LCBbICdicG1uOlRhc2snLCAnYnBtbjpUZXh0QW5ub3RhdGlvbicsICdicG1uOkdyb3VwJyBdKSB8fFxuICAgICAgICBpc0NvbGxhcHNlZFN1YlByb2Nlc3MoZWxlbWVudCkpIHtcblxuICAgICAgZGlyZWN0RWRpdGluZy5hY3RpdmF0ZShlbGVtZW50KTtcbiAgICB9XG4gIH1cblxufVxuXG5MYWJlbEVkaXRpbmdQcm92aWRlci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnYnBtbkZhY3RvcnknLFxuICAnY2FudmFzJyxcbiAgJ2RpcmVjdEVkaXRpbmcnLFxuICAnbW9kZWxpbmcnLFxuICAncmVzaXplSGFuZGxlcycsXG4gICd0ZXh0UmVuZGVyZXInXG5dO1xuXG5cbi8qKlxuICogQWN0aXZhdGUgZGlyZWN0IGVkaXRpbmcgZm9yIGFjdGl2aXRpZXMgYW5kIHRleHQgYW5ub3RhdGlvbnMuXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGFuIG9iamVjdCB3aXRoIHByb3BlcnRpZXMgYm91bmRzIChwb3NpdGlvbiBhbmQgc2l6ZSksIHRleHQgYW5kIG9wdGlvbnNcbiAqL1xuTGFiZWxFZGl0aW5nUHJvdmlkZXIucHJvdG90eXBlLmFjdGl2YXRlID0gZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gIC8vIHRleHRcbiAgdmFyIHRleHQgPSBnZXRMYWJlbChlbGVtZW50KTtcblxuICBpZiAodGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgdGV4dDogdGV4dFxuICB9O1xuXG4gIC8vIGJvdW5kc1xuICB2YXIgYm91bmRzID0gdGhpcy5nZXRFZGl0aW5nQkJveChlbGVtZW50KTtcblxuICBhc3NpZ24oY29udGV4dCwgYm91bmRzKTtcblxuICB2YXIgb3B0aW9ucyA9IHt9O1xuXG4gIC8vIHRhc2tzXG4gIGlmIChcbiAgICBpc0FueShlbGVtZW50LCBbXG4gICAgICAnYnBtbjpUYXNrJyxcbiAgICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAgICdicG1uOkxhbmUnLFxuICAgICAgJ2JwbW46Q2FsbEFjdGl2aXR5J1xuICAgIF0pIHx8XG4gICAgaXNDb2xsYXBzZWRTdWJQcm9jZXNzKGVsZW1lbnQpXG4gICkge1xuICAgIGFzc2lnbihvcHRpb25zLCB7XG4gICAgICBjZW50ZXJWZXJ0aWNhbGx5OiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICAvLyBleHRlcm5hbCBsYWJlbHNcbiAgaWYgKGlzTGFiZWxFeHRlcm5hbChlbGVtZW50KSkge1xuICAgIGFzc2lnbihvcHRpb25zLCB7XG4gICAgICBhdXRvUmVzaXplOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICAvLyB0ZXh0IGFubm90YXRpb25zXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgYXNzaWduKG9wdGlvbnMsIHtcbiAgICAgIHJlc2l6YWJsZTogdHJ1ZSxcbiAgICAgIGF1dG9SZXNpemU6IHRydWVcbiAgICB9KTtcbiAgfVxuXG4gIGFzc2lnbihjb250ZXh0LCB7XG4gICAgb3B0aW9uczogb3B0aW9uc1xuICB9KTtcblxuICByZXR1cm4gY29udGV4dDtcbn07XG5cblxuLyoqXG4gKiBHZXQgdGhlIGVkaXRpbmcgYm91bmRpbmcgYm94IGJhc2VkIG9uIHRoZSBlbGVtZW50J3Mgc2l6ZSBhbmQgcG9zaXRpb25cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gYW4gb2JqZWN0IGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gYWJvdXQgcG9zaXRpb25cbiAqICAgICAgICAgICAgICAgICAgYW5kIHNpemUgKGZpeGVkIG9yIG1pbmltdW0gYW5kL29yIG1heGltdW0pXG4gKi9cbkxhYmVsRWRpdGluZ1Byb3ZpZGVyLnByb3RvdHlwZS5nZXRFZGl0aW5nQkJveCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgdmFyIGNhbnZhcyA9IHRoaXMuX2NhbnZhcztcblxuICB2YXIgdGFyZ2V0ID0gZWxlbWVudC5sYWJlbCB8fCBlbGVtZW50O1xuXG4gIHZhciBiYm94ID0gY2FudmFzLmdldEFic29sdXRlQkJveCh0YXJnZXQpO1xuXG4gIHZhciBtaWQgPSB7XG4gICAgeDogYmJveC54ICsgYmJveC53aWR0aCAvIDIsXG4gICAgeTogYmJveC55ICsgYmJveC5oZWlnaHQgLyAyXG4gIH07XG5cbiAgLy8gZGVmYXVsdCBwb3NpdGlvblxuICB2YXIgYm91bmRzID0geyB4OiBiYm94LngsIHk6IGJib3gueSB9O1xuXG4gIHZhciB6b29tID0gY2FudmFzLnpvb20oKTtcblxuICB2YXIgZGVmYXVsdFN0eWxlID0gdGhpcy5fdGV4dFJlbmRlcmVyLmdldERlZmF1bHRTdHlsZSgpLFxuICAgICAgZXh0ZXJuYWxTdHlsZSA9IHRoaXMuX3RleHRSZW5kZXJlci5nZXRFeHRlcm5hbFN0eWxlKCk7XG5cbiAgLy8gdGFrZSB6b29tIGludG8gYWNjb3VudFxuICB2YXIgZXh0ZXJuYWxGb250U2l6ZSA9IGV4dGVybmFsU3R5bGUuZm9udFNpemUgKiB6b29tLFxuICAgICAgZXh0ZXJuYWxMaW5lSGVpZ2h0ID0gZXh0ZXJuYWxTdHlsZS5saW5lSGVpZ2h0LFxuICAgICAgZGVmYXVsdEZvbnRTaXplID0gZGVmYXVsdFN0eWxlLmZvbnRTaXplICogem9vbSxcbiAgICAgIGRlZmF1bHRMaW5lSGVpZ2h0ID0gZGVmYXVsdFN0eWxlLmxpbmVIZWlnaHQ7XG5cbiAgdmFyIHN0eWxlID0ge1xuICAgIGZvbnRGYW1pbHk6IHRoaXMuX3RleHRSZW5kZXJlci5nZXREZWZhdWx0U3R5bGUoKS5mb250RmFtaWx5LFxuICAgIGZvbnRXZWlnaHQ6IHRoaXMuX3RleHRSZW5kZXJlci5nZXREZWZhdWx0U3R5bGUoKS5mb250V2VpZ2h0XG4gIH07XG5cbiAgLy8gYWRqdXN0IGZvciBleHBhbmRlZCBwb29scyBBTkQgbGFuZXNcbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkxhbmUnKSB8fCBpc0V4cGFuZGVkUG9vbChlbGVtZW50KSkge1xuXG4gICAgYXNzaWduKGJvdW5kcywge1xuICAgICAgd2lkdGg6IGJib3guaGVpZ2h0LFxuICAgICAgaGVpZ2h0OiAzMCAqIHpvb20sXG4gICAgICB4OiBiYm94LnggLSBiYm94LmhlaWdodCAvIDIgKyAoMTUgKiB6b29tKSxcbiAgICAgIHk6IG1pZC55IC0gKDMwICogem9vbSkgLyAyXG4gICAgfSk7XG5cbiAgICBhc3NpZ24oc3R5bGUsIHtcbiAgICAgIGZvbnRTaXplOiBkZWZhdWx0Rm9udFNpemUgKyAncHgnLFxuICAgICAgbGluZUhlaWdodDogZGVmYXVsdExpbmVIZWlnaHQsXG4gICAgICBwYWRkaW5nVG9wOiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdCb3R0b206ICg3ICogem9vbSkgKyAncHgnLFxuICAgICAgcGFkZGluZ0xlZnQ6ICg1ICogem9vbSkgKyAncHgnLFxuICAgICAgcGFkZGluZ1JpZ2h0OiAoNSAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHRyYW5zZm9ybTogJ3JvdGF0ZSgtOTBkZWcpJ1xuICAgIH0pO1xuICB9XG5cblxuICAvLyBpbnRlcm5hbCBsYWJlbHMgZm9yIHRhc2tzIGFuZCBjb2xsYXBzZWQgY2FsbCBhY3Rpdml0aWVzLFxuICAvLyBzdWIgcHJvY2Vzc2VzIGFuZCBwYXJ0aWNpcGFudHNcbiAgaWYgKGlzQW55KGVsZW1lbnQsIFsgJ2JwbW46VGFzaycsICdicG1uOkNhbGxBY3Rpdml0eSddKSB8fFxuICAgICAgaXNDb2xsYXBzZWRQb29sKGVsZW1lbnQpIHx8XG4gICAgICBpc0NvbGxhcHNlZFN1YlByb2Nlc3MoZWxlbWVudCkpIHtcblxuICAgIGFzc2lnbihib3VuZHMsIHtcbiAgICAgIHdpZHRoOiBiYm94LndpZHRoLFxuICAgICAgaGVpZ2h0OiBiYm94LmhlaWdodFxuICAgIH0pO1xuXG4gICAgYXNzaWduKHN0eWxlLCB7XG4gICAgICBmb250U2l6ZTogZGVmYXVsdEZvbnRTaXplICsgJ3B4JyxcbiAgICAgIGxpbmVIZWlnaHQ6IGRlZmF1bHRMaW5lSGVpZ2h0LFxuICAgICAgcGFkZGluZ1RvcDogKDcgKiB6b29tKSArICdweCcsXG4gICAgICBwYWRkaW5nQm90dG9tOiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdMZWZ0OiAoNSAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdSaWdodDogKDUgKiB6b29tKSArICdweCdcbiAgICB9KTtcbiAgfVxuXG5cbiAgLy8gaW50ZXJuYWwgbGFiZWxzIGZvciBleHBhbmRlZCBzdWIgcHJvY2Vzc2VzXG4gIGlmIChpc0V4cGFuZGVkU3ViUHJvY2VzcyhlbGVtZW50KSkge1xuICAgIGFzc2lnbihib3VuZHMsIHtcbiAgICAgIHdpZHRoOiBiYm94LndpZHRoLFxuICAgICAgeDogYmJveC54XG4gICAgfSk7XG5cbiAgICBhc3NpZ24oc3R5bGUsIHtcbiAgICAgIGZvbnRTaXplOiBkZWZhdWx0Rm9udFNpemUgKyAncHgnLFxuICAgICAgbGluZUhlaWdodDogZGVmYXVsdExpbmVIZWlnaHQsXG4gICAgICBwYWRkaW5nVG9wOiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdCb3R0b206ICg3ICogem9vbSkgKyAncHgnLFxuICAgICAgcGFkZGluZ0xlZnQ6ICg1ICogem9vbSkgKyAncHgnLFxuICAgICAgcGFkZGluZ1JpZ2h0OiAoNSAqIHpvb20pICsgJ3B4J1xuICAgIH0pO1xuICB9XG5cbiAgdmFyIHdpZHRoID0gOTAgKiB6b29tLFxuICAgICAgcGFkZGluZ1RvcCA9IDcgKiB6b29tLFxuICAgICAgcGFkZGluZ0JvdHRvbSA9IDQgKiB6b29tO1xuXG4gIC8vIGV4dGVybmFsIGxhYmVscyBmb3IgZXZlbnRzLCBkYXRhIGVsZW1lbnRzLCBnYXRld2F5cywgZ3JvdXBzIGFuZCBjb25uZWN0aW9uc1xuICBpZiAodGFyZ2V0LmxhYmVsVGFyZ2V0KSB7XG4gICAgYXNzaWduKGJvdW5kcywge1xuICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgaGVpZ2h0OiBiYm94LmhlaWdodCArIHBhZGRpbmdUb3AgKyBwYWRkaW5nQm90dG9tLFxuICAgICAgeDogbWlkLnggLSB3aWR0aCAvIDIsXG4gICAgICB5OiBiYm94LnkgLSBwYWRkaW5nVG9wXG4gICAgfSk7XG5cbiAgICBhc3NpZ24oc3R5bGUsIHtcbiAgICAgIGZvbnRTaXplOiBleHRlcm5hbEZvbnRTaXplICsgJ3B4JyxcbiAgICAgIGxpbmVIZWlnaHQ6IGV4dGVybmFsTGluZUhlaWdodCxcbiAgICAgIHBhZGRpbmdUb3A6IHBhZGRpbmdUb3AgKyAncHgnLFxuICAgICAgcGFkZGluZ0JvdHRvbTogcGFkZGluZ0JvdHRvbSArICdweCdcbiAgICB9KTtcbiAgfVxuXG4gIC8vIGV4dGVybmFsIGxhYmVsIG5vdCB5ZXQgY3JlYXRlZFxuICBpZiAoaXNMYWJlbEV4dGVybmFsKHRhcmdldClcbiAgICAgICYmICFoYXNFeHRlcm5hbExhYmVsKHRhcmdldClcbiAgICAgICYmICFpc0xhYmVsKHRhcmdldCkpIHtcblxuICAgIHZhciBleHRlcm5hbExhYmVsTWlkID0gZ2V0RXh0ZXJuYWxMYWJlbE1pZChlbGVtZW50KTtcblxuICAgIHZhciBhYnNvbHV0ZUJCb3ggPSBjYW52YXMuZ2V0QWJzb2x1dGVCQm94KHtcbiAgICAgIHg6IGV4dGVybmFsTGFiZWxNaWQueCxcbiAgICAgIHk6IGV4dGVybmFsTGFiZWxNaWQueSxcbiAgICAgIHdpZHRoOiAwLFxuICAgICAgaGVpZ2h0OiAwXG4gICAgfSk7XG5cbiAgICB2YXIgaGVpZ2h0ID0gZXh0ZXJuYWxGb250U2l6ZSArIHBhZGRpbmdUb3AgKyBwYWRkaW5nQm90dG9tO1xuXG4gICAgYXNzaWduKGJvdW5kcywge1xuICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICB4OiBhYnNvbHV0ZUJCb3gueCAtIHdpZHRoIC8gMixcbiAgICAgIHk6IGFic29sdXRlQkJveC55IC0gaGVpZ2h0IC8gMlxuICAgIH0pO1xuXG4gICAgYXNzaWduKHN0eWxlLCB7XG4gICAgICBmb250U2l6ZTogZXh0ZXJuYWxGb250U2l6ZSArICdweCcsXG4gICAgICBsaW5lSGVpZ2h0OiBleHRlcm5hbExpbmVIZWlnaHQsXG4gICAgICBwYWRkaW5nVG9wOiBwYWRkaW5nVG9wICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdCb3R0b206IHBhZGRpbmdCb3R0b20gKyAncHgnXG4gICAgfSk7XG4gIH1cblxuICAvLyB0ZXh0IGFubm90YXRpb25zXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgYXNzaWduKGJvdW5kcywge1xuICAgICAgd2lkdGg6IGJib3gud2lkdGgsXG4gICAgICBoZWlnaHQ6IGJib3guaGVpZ2h0LFxuICAgICAgbWluV2lkdGg6IDMwICogem9vbSxcbiAgICAgIG1pbkhlaWdodDogMTAgKiB6b29tXG4gICAgfSk7XG5cbiAgICBhc3NpZ24oc3R5bGUsIHtcbiAgICAgIHRleHRBbGlnbjogJ2xlZnQnLFxuICAgICAgcGFkZGluZ1RvcDogKDUgKiB6b29tKSArICdweCcsXG4gICAgICBwYWRkaW5nQm90dG9tOiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdMZWZ0OiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdSaWdodDogKDUgKiB6b29tKSArICdweCcsXG4gICAgICBmb250U2l6ZTogZGVmYXVsdEZvbnRTaXplICsgJ3B4JyxcbiAgICAgIGxpbmVIZWlnaHQ6IGRlZmF1bHRMaW5lSGVpZ2h0XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4geyBib3VuZHM6IGJvdW5kcywgc3R5bGU6IHN0eWxlIH07XG59O1xuXG5cbkxhYmVsRWRpdGluZ1Byb3ZpZGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihcbiAgICBlbGVtZW50LCBuZXdMYWJlbCxcbiAgICBhY3RpdmVDb250ZXh0VGV4dCwgYm91bmRzKSB7XG5cbiAgdmFyIG5ld0JvdW5kcyxcbiAgICAgIGJib3g7XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcblxuICAgIGJib3ggPSB0aGlzLl9jYW52YXMuZ2V0QWJzb2x1dGVCQm94KGVsZW1lbnQpO1xuXG4gICAgbmV3Qm91bmRzID0ge1xuICAgICAgeDogZWxlbWVudC54LFxuICAgICAgeTogZWxlbWVudC55LFxuICAgICAgd2lkdGg6IGVsZW1lbnQud2lkdGggLyBiYm94LndpZHRoICogYm91bmRzLndpZHRoLFxuICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodCAvIGJib3guaGVpZ2h0ICogYm91bmRzLmhlaWdodFxuICAgIH07XG4gIH1cblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46R3JvdXAnKSkge1xuXG4gICAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XG5cbiAgICAvLyBpbml0aWFsaXplIGNhdGVnb3J5VmFsdWUgaWYgbm90IGV4aXN0aW5nXG4gICAgaWYgKCFidXNpbmVzc09iamVjdC5jYXRlZ29yeVZhbHVlUmVmKSB7XG5cbiAgICAgIHZhciByb290RWxlbWVudCA9IHRoaXMuX2NhbnZhcy5nZXRSb290RWxlbWVudCgpLFxuICAgICAgICAgIGRlZmluaXRpb25zID0gZ2V0QnVzaW5lc3NPYmplY3Qocm9vdEVsZW1lbnQpLiRwYXJlbnQ7XG5cbiAgICAgIHZhciBjYXRlZ29yeVZhbHVlID0gY3JlYXRlQ2F0ZWdvcnlWYWx1ZShkZWZpbml0aW9ucywgdGhpcy5fYnBtbkZhY3RvcnkpO1xuXG4gICAgICBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5jYXRlZ29yeVZhbHVlUmVmID0gY2F0ZWdvcnlWYWx1ZTtcbiAgICB9XG5cbiAgfVxuXG4gIGlmIChpc0VtcHR5VGV4dChuZXdMYWJlbCkpIHtcbiAgICBuZXdMYWJlbCA9IG51bGw7XG4gIH1cblxuICB0aGlzLl9tb2RlbGluZy51cGRhdGVMYWJlbChlbGVtZW50LCBuZXdMYWJlbCwgbmV3Qm91bmRzKTtcbn07XG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNDb2xsYXBzZWRTdWJQcm9jZXNzKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJiAhaXNFeHBhbmRlZChlbGVtZW50KTtcbn1cblxuZnVuY3Rpb24gaXNFeHBhbmRlZFN1YlByb2Nlc3MoZWxlbWVudCkge1xuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46U3ViUHJvY2VzcycpICYmIGlzRXhwYW5kZWQoZWxlbWVudCk7XG59XG5cbmZ1bmN0aW9uIGlzQ29sbGFwc2VkUG9vbChlbGVtZW50KSB7XG4gIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpICYmICFpc0V4cGFuZGVkKGVsZW1lbnQpO1xufVxuXG5mdW5jdGlvbiBpc0V4cGFuZGVkUG9vbChlbGVtZW50KSB7XG4gIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpICYmIGlzRXhwYW5kZWQoZWxlbWVudCk7XG59XG5cbmZ1bmN0aW9uIGlzRW1wdHlUZXh0KGxhYmVsKSB7XG4gIHJldHVybiAhbGFiZWwgfHwgIWxhYmVsLnRyaW0oKTtcbn0iLCJpbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuZnVuY3Rpb24gZ2V0TGFiZWxBdHRyKHNlbWFudGljKSB7XG4gIGlmIChcbiAgICBpcyhzZW1hbnRpYywgJ2JwbW46Rmxvd0VsZW1lbnQnKSB8fFxuICAgIGlzKHNlbWFudGljLCAnYnBtbjpQYXJ0aWNpcGFudCcpIHx8XG4gICAgaXMoc2VtYW50aWMsICdicG1uOkxhbmUnKSB8fFxuICAgIGlzKHNlbWFudGljLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSB8fFxuICAgIGlzKHNlbWFudGljLCAnYnBtbjpNZXNzYWdlRmxvdycpIHx8XG4gICAgaXMoc2VtYW50aWMsICdicG1uOkRhdGFJbnB1dCcpIHx8XG4gICAgaXMoc2VtYW50aWMsICdicG1uOkRhdGFPdXRwdXQnKVxuICApIHtcbiAgICByZXR1cm4gJ25hbWUnO1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgcmV0dXJuICd0ZXh0JztcbiAgfVxuXG4gIGlmIChpcyhzZW1hbnRpYywgJ2JwbW46R3JvdXAnKSkge1xuICAgIHJldHVybiAnY2F0ZWdvcnlWYWx1ZVJlZic7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0Q2F0ZWdvcnlWYWx1ZShzZW1hbnRpYykge1xuICB2YXIgY2F0ZWdvcnlWYWx1ZVJlZiA9IHNlbWFudGljWydjYXRlZ29yeVZhbHVlUmVmJ107XG5cbiAgaWYgKCFjYXRlZ29yeVZhbHVlUmVmKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cblxuICByZXR1cm4gY2F0ZWdvcnlWYWx1ZVJlZi52YWx1ZSB8fCAnJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExhYmVsKGVsZW1lbnQpIHtcbiAgdmFyIHNlbWFudGljID0gZWxlbWVudC5idXNpbmVzc09iamVjdCxcbiAgICAgIGF0dHIgPSBnZXRMYWJlbEF0dHIoc2VtYW50aWMpO1xuXG4gIGlmIChhdHRyKSB7XG5cbiAgICBpZiAoYXR0ciA9PT0gJ2NhdGVnb3J5VmFsdWVSZWYnKSB7XG5cbiAgICAgIHJldHVybiBnZXRDYXRlZ29yeVZhbHVlKHNlbWFudGljKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VtYW50aWNbYXR0cl0gfHwgJyc7XG4gIH1cbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gc2V0TGFiZWwoZWxlbWVudCwgdGV4dCwgaXNFeHRlcm5hbCkge1xuICB2YXIgc2VtYW50aWMgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LFxuICAgICAgYXR0ciA9IGdldExhYmVsQXR0cihzZW1hbnRpYyk7XG5cbiAgaWYgKGF0dHIpIHtcblxuICAgIGlmIChhdHRyID09PSAnY2F0ZWdvcnlWYWx1ZVJlZicpIHtcbiAgICAgIHNlbWFudGljWydjYXRlZ29yeVZhbHVlUmVmJ10udmFsdWUgPSB0ZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICBzZW1hbnRpY1thdHRyXSA9IHRleHQ7XG4gICAgfVxuXG4gIH1cblxuICByZXR1cm4gZWxlbWVudDtcbn0iLCJpbXBvcnQge1xuICBzZXRMYWJlbCxcbiAgZ2V0TGFiZWxcbn0gZnJvbSAnLi4vTGFiZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0RXh0ZXJuYWxMYWJlbE1pZCxcbiAgaXNMYWJlbEV4dGVybmFsLFxuICBoYXNFeHRlcm5hbExhYmVsLFxuICBpc0xhYmVsXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTGFiZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgaXNcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG52YXIgTlVMTF9ESU1FTlNJT05TID0ge1xuICB3aWR0aDogMCxcbiAgaGVpZ2h0OiAwXG59O1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgdXBkYXRlcyB0aGUgdGV4dCBvZiBhIEJQTU4gZWxlbWVudC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVXBkYXRlTGFiZWxIYW5kbGVyKG1vZGVsaW5nLCB0ZXh0UmVuZGVyZXIpIHtcblxuICAvKipcbiAgICogU2V0IHRoZSBsYWJlbCBhbmQgcmV0dXJuIHRoZSBjaGFuZ2VkIGVsZW1lbnRzLlxuICAgKlxuICAgKiBFbGVtZW50IHBhcmFtZXRlciBjYW4gYmUgbGFiZWwgaXRzZWxmIG9yIGNvbm5lY3Rpb24gKGkuZS4gc2VxdWVuY2UgZmxvdykuXG4gICAqXG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICovXG4gIGZ1bmN0aW9uIHNldFRleHQoZWxlbWVudCwgdGV4dCkge1xuXG4gICAgLy8gZXh0ZXJuYWwgbGFiZWwgaWYgcHJlc2VudFxuICAgIHZhciBsYWJlbCA9IGVsZW1lbnQubGFiZWwgfHwgZWxlbWVudDtcblxuICAgIHZhciBsYWJlbFRhcmdldCA9IGVsZW1lbnQubGFiZWxUYXJnZXQgfHwgZWxlbWVudDtcblxuICAgIHNldExhYmVsKGxhYmVsLCB0ZXh0LCBsYWJlbFRhcmdldCAhPT0gbGFiZWwpO1xuXG4gICAgcmV0dXJuIFsgbGFiZWwsIGxhYmVsVGFyZ2V0IF07XG4gIH1cblxuICBmdW5jdGlvbiBwcmVFeGVjdXRlKGN0eCkge1xuICAgIHZhciBlbGVtZW50ID0gY3R4LmVsZW1lbnQsXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0ID0gZWxlbWVudC5idXNpbmVzc09iamVjdCxcbiAgICAgICAgbmV3TGFiZWwgPSBjdHgubmV3TGFiZWw7XG5cbiAgICBpZiAoIWlzTGFiZWwoZWxlbWVudClcbiAgICAgICAgJiYgaXNMYWJlbEV4dGVybmFsKGVsZW1lbnQpXG4gICAgICAgICYmICFoYXNFeHRlcm5hbExhYmVsKGVsZW1lbnQpXG4gICAgICAgICYmICFpc0VtcHR5VGV4dChuZXdMYWJlbCkpIHtcblxuICAgICAgLy8gY3JlYXRlIGxhYmVsXG4gICAgICB2YXIgcGFkZGluZ1RvcCA9IDc7XG5cbiAgICAgIHZhciBsYWJlbENlbnRlciA9IGdldEV4dGVybmFsTGFiZWxNaWQoZWxlbWVudCk7XG5cbiAgICAgIGxhYmVsQ2VudGVyID0ge1xuICAgICAgICB4OiBsYWJlbENlbnRlci54LFxuICAgICAgICB5OiBsYWJlbENlbnRlci55ICsgcGFkZGluZ1RvcFxuICAgICAgfTtcblxuICAgICAgbW9kZWxpbmcuY3JlYXRlTGFiZWwoZWxlbWVudCwgbGFiZWxDZW50ZXIsIHtcbiAgICAgICAgaWQ6IGJ1c2luZXNzT2JqZWN0LmlkICsgJ19sYWJlbCcsXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0OiBidXNpbmVzc09iamVjdFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZXhlY3V0ZShjdHgpIHtcbiAgICBjdHgub2xkTGFiZWwgPSBnZXRMYWJlbChjdHguZWxlbWVudCk7XG4gICAgcmV0dXJuIHNldFRleHQoY3R4LmVsZW1lbnQsIGN0eC5uZXdMYWJlbCk7XG4gIH1cblxuICBmdW5jdGlvbiByZXZlcnQoY3R4KSB7XG4gICAgcmV0dXJuIHNldFRleHQoY3R4LmVsZW1lbnQsIGN0eC5vbGRMYWJlbCk7XG4gIH1cblxuICBmdW5jdGlvbiBwb3N0RXhlY3V0ZShjdHgpIHtcbiAgICB2YXIgZWxlbWVudCA9IGN0eC5lbGVtZW50LFxuICAgICAgICBsYWJlbCA9IGVsZW1lbnQubGFiZWwgfHwgZWxlbWVudCxcbiAgICAgICAgbmV3TGFiZWwgPSBjdHgubmV3TGFiZWwsXG4gICAgICAgIG5ld0JvdW5kcyA9IGN0eC5uZXdCb3VuZHMsXG4gICAgICAgIGhpbnRzID0gY3R4LmhpbnRzIHx8IHt9O1xuXG4gICAgLy8gaWdub3JlIGludGVybmFsIGxhYmVscyBmb3IgZWxlbWVudHMgZXhjZXB0IHRleHQgYW5ub3RhdGlvbnNcbiAgICBpZiAoIWlzTGFiZWwobGFiZWwpICYmICFpcyhsYWJlbCwgJ2JwbW46VGV4dEFubm90YXRpb24nKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpc0xhYmVsKGxhYmVsKSAmJiBpc0VtcHR5VGV4dChuZXdMYWJlbCkpIHtcblxuICAgICAgaWYgKGhpbnRzLnJlbW92ZVNoYXBlICE9PSBmYWxzZSkge1xuICAgICAgICBtb2RlbGluZy5yZW1vdmVTaGFwZShsYWJlbCwgeyB1bnNldExhYmVsOiBmYWxzZSB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciB0ZXh0ID0gZ2V0TGFiZWwobGFiZWwpO1xuXG4gICAgLy8gcmVzaXplIGVsZW1lbnQgYmFzZWQgb24gbGFiZWwgX29yXyBwcmUtZGVmaW5lZCBib3VuZHNcbiAgICBpZiAodHlwZW9mIG5ld0JvdW5kcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG5ld0JvdW5kcyA9IHRleHRSZW5kZXJlci5nZXRFeHRlcm5hbExhYmVsQm91bmRzKGxhYmVsLCB0ZXh0KTtcbiAgICB9XG5cbiAgICAvLyBzZXR0aW5nIG5ld0JvdW5kcyB0byBmYWxzZSBvciBfbnVsbF8gd2lsbFxuICAgIC8vIGRpc2FibGUgdGhlIHBvc3RFeGVjdXRlIHJlc2l6ZSBvcGVyYXRpb25cbiAgICBpZiAobmV3Qm91bmRzKSB7XG4gICAgICBtb2RlbGluZy5yZXNpemVTaGFwZShsYWJlbCwgbmV3Qm91bmRzLCBOVUxMX0RJTUVOU0lPTlMpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFQSVxuXG4gIHRoaXMucHJlRXhlY3V0ZSA9IHByZUV4ZWN1dGU7XG4gIHRoaXMuZXhlY3V0ZSA9IGV4ZWN1dGU7XG4gIHRoaXMucmV2ZXJ0ID0gcmV2ZXJ0O1xuICB0aGlzLnBvc3RFeGVjdXRlID0gcG9zdEV4ZWN1dGU7XG59XG5cblVwZGF0ZUxhYmVsSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnbW9kZWxpbmcnLFxuICAndGV4dFJlbmRlcmVyJ1xuXTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGlzRW1wdHlUZXh0KGxhYmVsKSB7XG4gIHJldHVybiAhbGFiZWwgfHwgIWxhYmVsLnRyaW0oKTtcbn0iLCJpbXBvcnQgQ2hhbmdlU3VwcG9ydE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jaGFuZ2Utc3VwcG9ydCc7XG5pbXBvcnQgUmVzaXplTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Jlc2l6ZSc7XG5pbXBvcnQgRGlyZWN0RWRpdGluZ01vZHVsZSBmcm9tICdkaWFncmFtLWpzLWRpcmVjdC1lZGl0aW5nJztcblxuaW1wb3J0IExhYmVsRWRpdGluZ1Byb3ZpZGVyIGZyb20gJy4vTGFiZWxFZGl0aW5nUHJvdmlkZXInO1xuaW1wb3J0IExhYmVsRWRpdGluZ1ByZXZpZXcgZnJvbSAnLi9MYWJlbEVkaXRpbmdQcmV2aWV3JztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgQ2hhbmdlU3VwcG9ydE1vZHVsZSxcbiAgICBSZXNpemVNb2R1bGUsXG4gICAgRGlyZWN0RWRpdGluZ01vZHVsZVxuICBdLFxuICBfX2luaXRfXzogW1xuICAgICdsYWJlbEVkaXRpbmdQcm92aWRlcicsXG4gICAgJ2xhYmVsRWRpdGluZ1ByZXZpZXcnXG4gIF0sXG4gIGxhYmVsRWRpdGluZ1Byb3ZpZGVyOiBbICd0eXBlJywgTGFiZWxFZGl0aW5nUHJvdmlkZXIgXSxcbiAgbGFiZWxFZGl0aW5nUHJldmlldzogWyAndHlwZScsIExhYmVsRWRpdGluZ1ByZXZpZXcgXVxufTtcbiIsImltcG9ydCB7XG4gIG1hcCxcbiAgYXNzaWduLFxuICBwaWNrXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgaXNBbnlcbn0gZnJvbSAnLi91dGlsL01vZGVsaW5nVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzXG59IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uRmFjdG9yeShtb2RkbGUpIHtcbiAgdGhpcy5fbW9kZWwgPSBtb2RkbGU7XG59XG5cbkJwbW5GYWN0b3J5LiRpbmplY3QgPSBbICdtb2RkbGUnIF07XG5cblxuQnBtbkZhY3RvcnkucHJvdG90eXBlLl9uZWVkc0lkID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICByZXR1cm4gaXNBbnkoZWxlbWVudCwgW1xuICAgICdicG1uOlJvb3RFbGVtZW50JyxcbiAgICAnYnBtbjpGbG93RWxlbWVudCcsXG4gICAgJ2JwbW46TWVzc2FnZUZsb3cnLFxuICAgICdicG1uOkRhdGFBc3NvY2lhdGlvbicsXG4gICAgJ2JwbW46QXJ0aWZhY3QnLFxuICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAnYnBtbjpMYW5lJyxcbiAgICAnYnBtbjpMYW5lU2V0JyxcbiAgICAnYnBtbjpQcm9jZXNzJyxcbiAgICAnYnBtbjpDb2xsYWJvcmF0aW9uJyxcbiAgICAnYnBtbmRpOkJQTU5TaGFwZScsXG4gICAgJ2JwbW5kaTpCUE1ORWRnZScsXG4gICAgJ2JwbW5kaTpCUE1ORGlhZ3JhbScsXG4gICAgJ2JwbW5kaTpCUE1OUGxhbmUnLFxuICAgICdicG1uOlByb3BlcnR5JyxcbiAgICAnYnBtbjpDYXRlZ29yeVZhbHVlJ1xuICBdKTtcbn07XG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5fZW5zdXJlSWQgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgLy8gZ2VuZXJhdGUgc2VtYW50aWMgaWRzIGZvciBlbGVtZW50c1xuICAvLyBicG1uOlNlcXVlbmNlRmxvdyAtPiBTZXF1ZW5jZUZsb3dfSURcbiAgdmFyIHByZWZpeDtcblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46QWN0aXZpdHknKSkge1xuICAgIHByZWZpeCA9ICdBY3Rpdml0eSc7XG4gIH0gZWxzZSBpZiAoaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSkge1xuICAgIHByZWZpeCA9ICdFdmVudCc7XG4gIH0gZWxzZSBpZiAoaXMoZWxlbWVudCwgJ2JwbW46R2F0ZXdheScpKSB7XG4gICAgcHJlZml4ID0gJ0dhdGV3YXknO1xuICB9IGVsc2UgaWYgKGlzQW55KGVsZW1lbnQsIFsgJ2JwbW46U2VxdWVuY2VGbG93JywgJ2JwbW46TWVzc2FnZUZsb3cnIF0pKSB7XG4gICAgcHJlZml4ID0gJ0Zsb3cnO1xuICB9IGVsc2Uge1xuICAgIHByZWZpeCA9IChlbGVtZW50LiR0eXBlIHx8ICcnKS5yZXBsYWNlKC9eW146XSo6L2csICcnKTtcbiAgfVxuXG4gIHByZWZpeCArPSAnXyc7XG5cbiAgaWYgKCFlbGVtZW50LmlkICYmIHRoaXMuX25lZWRzSWQoZWxlbWVudCkpIHtcbiAgICBlbGVtZW50LmlkID0gdGhpcy5fbW9kZWwuaWRzLm5leHRQcmVmaXhlZChwcmVmaXgsIGVsZW1lbnQpO1xuICB9XG59O1xuXG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbih0eXBlLCBhdHRycykge1xuICB2YXIgZWxlbWVudCA9IHRoaXMuX21vZGVsLmNyZWF0ZSh0eXBlLCBhdHRycyB8fCB7fSk7XG5cbiAgdGhpcy5fZW5zdXJlSWQoZWxlbWVudCk7XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuXG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVEaUxhYmVsID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnYnBtbmRpOkJQTU5MYWJlbCcsIHtcbiAgICBib3VuZHM6IHRoaXMuY3JlYXRlRGlCb3VuZHMoKVxuICB9KTtcbn07XG5cblxuQnBtbkZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZURpU2hhcGUgPSBmdW5jdGlvbihzZW1hbnRpYywgYm91bmRzLCBhdHRycykge1xuXG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnYnBtbmRpOkJQTU5TaGFwZScsIGFzc2lnbih7XG4gICAgYnBtbkVsZW1lbnQ6IHNlbWFudGljLFxuICAgIGJvdW5kczogdGhpcy5jcmVhdGVEaUJvdW5kcyhib3VuZHMpXG4gIH0sIGF0dHJzKSk7XG59O1xuXG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVEaUJvdW5kcyA9IGZ1bmN0aW9uKGJvdW5kcykge1xuICByZXR1cm4gdGhpcy5jcmVhdGUoJ2RjOkJvdW5kcycsIGJvdW5kcyk7XG59O1xuXG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVEaVdheXBvaW50cyA9IGZ1bmN0aW9uKHdheXBvaW50cykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgcmV0dXJuIG1hcCh3YXlwb2ludHMsIGZ1bmN0aW9uKHBvcykge1xuICAgIHJldHVybiBzZWxmLmNyZWF0ZURpV2F5cG9pbnQocG9zKTtcbiAgfSk7XG59O1xuXG5CcG1uRmFjdG9yeS5wcm90b3R5cGUuY3JlYXRlRGlXYXlwb2ludCA9IGZ1bmN0aW9uKHBvaW50KSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnZGM6UG9pbnQnLCBwaWNrKHBvaW50LCBbICd4JywgJ3knIF0pKTtcbn07XG5cblxuQnBtbkZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZURpRWRnZSA9IGZ1bmN0aW9uKHNlbWFudGljLCB3YXlwb2ludHMsIGF0dHJzKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnYnBtbmRpOkJQTU5FZGdlJywgYXNzaWduKHtcbiAgICBicG1uRWxlbWVudDogc2VtYW50aWNcbiAgfSwgYXR0cnMpKTtcbn07XG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVEaVBsYW5lID0gZnVuY3Rpb24oc2VtYW50aWMpIHtcbiAgcmV0dXJuIHRoaXMuY3JlYXRlKCdicG1uZGk6QlBNTlBsYW5lJywge1xuICAgIGJwbW5FbGVtZW50OiBzZW1hbnRpY1xuICB9KTtcbn07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IEJhc2VMYXlvdXRlciBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvQmFzZUxheW91dGVyJztcblxuaW1wb3J0IHtcbiAgcmVwYWlyQ29ubmVjdGlvbixcbiAgd2l0aG91dFJlZHVuZGFudFBvaW50c1xufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTWFuaGF0dGFuTGF5b3V0JztcblxuaW1wb3J0IHtcbiAgZ2V0TWlkLFxuICBnZXRPcmllbnRhdGlvblxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzRXhwYW5kZWRcbn0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxudmFyIEFUVEFDSF9PUklFTlRBVElPTl9QQURESU5HID0gLTEwLFxuICAgIEJPVU5EQVJZX1RPX0hPU1RfVEhSRVNIT0xEID0gNDA7XG5cbnZhciBvcHBvc2l0ZU9yaWVudGF0aW9uTWFwcGluZyA9IHtcbiAgJ3RvcCc6ICdib3R0b20nLFxuICAndG9wLXJpZ2h0JzogJ2JvdHRvbS1sZWZ0JyxcbiAgJ3RvcC1sZWZ0JzogJ2JvdHRvbS1yaWdodCcsXG4gICdyaWdodCc6ICdsZWZ0JyxcbiAgJ2JvdHRvbSc6ICd0b3AnLFxuICAnYm90dG9tLXJpZ2h0JzogJ3RvcC1sZWZ0JyxcbiAgJ2JvdHRvbS1sZWZ0JzogJ3RvcC1yaWdodCcsXG4gICdsZWZ0JzogJ3JpZ2h0J1xufTtcblxudmFyIG9yaWVudGF0aW9uRGlyZWN0aW9uTWFwcGluZyA9IHtcbiAgdG9wOiAndCcsXG4gIHJpZ2h0OiAncicsXG4gIGJvdHRvbTogJ2InLFxuICBsZWZ0OiAnbCdcbn07XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkxheW91dGVyKCkge31cblxuaW5oZXJpdHMoQnBtbkxheW91dGVyLCBCYXNlTGF5b3V0ZXIpO1xuXG5cbkJwbW5MYXlvdXRlci5wcm90b3R5cGUubGF5b3V0Q29ubmVjdGlvbiA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIGhpbnRzKSB7XG4gIGlmICghaGludHMpIHtcbiAgICBoaW50cyA9IHt9O1xuICB9XG5cbiAgdmFyIHNvdXJjZSA9IGhpbnRzLnNvdXJjZSB8fCBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgIHRhcmdldCA9IGhpbnRzLnRhcmdldCB8fCBjb25uZWN0aW9uLnRhcmdldCxcbiAgICAgIHdheXBvaW50cyA9IGhpbnRzLndheXBvaW50cyB8fCBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgIGNvbm5lY3Rpb25TdGFydCA9IGhpbnRzLmNvbm5lY3Rpb25TdGFydCxcbiAgICAgIGNvbm5lY3Rpb25FbmQgPSBoaW50cy5jb25uZWN0aW9uRW5kO1xuXG4gIHZhciBtYW5oYXR0YW5PcHRpb25zLFxuICAgICAgdXBkYXRlZFdheXBvaW50cztcblxuICBpZiAoIWNvbm5lY3Rpb25TdGFydCkge1xuICAgIGNvbm5lY3Rpb25TdGFydCA9IGdldENvbm5lY3Rpb25Eb2NraW5nKHdheXBvaW50cyAmJiB3YXlwb2ludHNbIDAgXSwgc291cmNlKTtcbiAgfVxuXG4gIGlmICghY29ubmVjdGlvbkVuZCkge1xuICAgIGNvbm5lY3Rpb25FbmQgPSBnZXRDb25uZWN0aW9uRG9ja2luZyh3YXlwb2ludHMgJiYgd2F5cG9pbnRzWyB3YXlwb2ludHMubGVuZ3RoIC0gMSBdLCB0YXJnZXQpO1xuICB9XG5cbiAgLy8gVE9ETyhuaWtrdSk6IHN1cHBvcnQgdmVydGljYWwgbW9kZWxpbmdcbiAgLy8gYW5kIGludmVydCBwcmVmZXJyZWRMYXlvdXRzIGFjY29yZGluZ2x5XG5cbiAgaWYgKGlzKGNvbm5lY3Rpb24sICdicG1uOkFzc29jaWF0aW9uJykgfHxcbiAgICAgIGlzKGNvbm5lY3Rpb24sICdicG1uOkRhdGFBc3NvY2lhdGlvbicpKSB7XG5cbiAgICBpZiAod2F5cG9pbnRzICYmICFpc0NvbXBlbnNhdGlvbkFzc29jaWF0aW9uKHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgICAgcmV0dXJuIFtdLmNvbmNhdChbIGNvbm5lY3Rpb25TdGFydCBdLCB3YXlwb2ludHMuc2xpY2UoMSwgLTEpLCBbIGNvbm5lY3Rpb25FbmQgXSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzKGNvbm5lY3Rpb24sICdicG1uOk1lc3NhZ2VGbG93JykpIHtcbiAgICBtYW5oYXR0YW5PcHRpb25zID0gZ2V0TWVzc2FnZUZsb3dNYW5oYXR0YW5PcHRpb25zKHNvdXJjZSwgdGFyZ2V0KTtcbiAgfSBlbHNlIGlmIChpcyhjb25uZWN0aW9uLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSB8fCBpc0NvbXBlbnNhdGlvbkFzc29jaWF0aW9uKHNvdXJjZSwgdGFyZ2V0KSkge1xuXG4gICAgLy8gbGF5b3V0IGFsbCBjb25uZWN0aW9uIGJldHdlZW4gZmxvdyBlbGVtZW50cyBoOmgsIGV4Y2VwdCBmb3JcbiAgICAvLyAoMSkgb3V0Z29pbmcgb2YgYm91bmRhcnkgZXZlbnRzIC0+IGxheW91dCBiYXNlZCBvbiBhdHRhY2ggb3JpZW50YXRpb24gYW5kIHRhcmdldCBvcmllbnRhdGlvblxuICAgIC8vICgyKSBpbmNvbWluZy9vdXRnb2luZyBvZiBnYXRld2F5cyAtPiB2OmggZm9yIG91dGdvaW5nLCBoOnYgZm9yIGluY29taW5nXG4gICAgLy8gKDMpIGxvb3BzXG4gICAgaWYgKHNvdXJjZSA9PT0gdGFyZ2V0KSB7XG4gICAgICBtYW5oYXR0YW5PcHRpb25zID0ge1xuICAgICAgICBwcmVmZXJyZWRMYXlvdXRzOiBnZXRMb29wUHJlZmVycmVkTGF5b3V0KHNvdXJjZSwgY29ubmVjdGlvbilcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChpcyhzb3VyY2UsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSkge1xuICAgICAgbWFuaGF0dGFuT3B0aW9ucyA9IHtcbiAgICAgICAgcHJlZmVycmVkTGF5b3V0czogZ2V0Qm91bmRhcnlFdmVudFByZWZlcnJlZExheW91dHMoc291cmNlLCB0YXJnZXQsIGNvbm5lY3Rpb25FbmQpXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoaXNFeHBhbmRlZFN1YlByb2Nlc3Moc291cmNlKSB8fCBpc0V4cGFuZGVkU3ViUHJvY2Vzcyh0YXJnZXQpKSB7XG4gICAgICBtYW5oYXR0YW5PcHRpb25zID0gZ2V0U3ViUHJvY2Vzc01hbmhhdHRhbk9wdGlvbnMoc291cmNlKTtcbiAgICB9IGVsc2UgaWYgKGlzKHNvdXJjZSwgJ2JwbW46R2F0ZXdheScpKSB7XG4gICAgICBtYW5oYXR0YW5PcHRpb25zID0ge1xuICAgICAgICBwcmVmZXJyZWRMYXlvdXRzOiBbICd2OmgnIF1cbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChpcyh0YXJnZXQsICdicG1uOkdhdGV3YXknKSkge1xuICAgICAgbWFuaGF0dGFuT3B0aW9ucyA9IHtcbiAgICAgICAgcHJlZmVycmVkTGF5b3V0czogWyAnaDp2JyBdXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBtYW5oYXR0YW5PcHRpb25zID0ge1xuICAgICAgICBwcmVmZXJyZWRMYXlvdXRzOiBbICdoOmgnIF1cbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgaWYgKG1hbmhhdHRhbk9wdGlvbnMpIHtcbiAgICBtYW5oYXR0YW5PcHRpb25zID0gYXNzaWduKG1hbmhhdHRhbk9wdGlvbnMsIGhpbnRzKTtcblxuICAgIHVwZGF0ZWRXYXlwb2ludHMgPSB3aXRob3V0UmVkdW5kYW50UG9pbnRzKHJlcGFpckNvbm5lY3Rpb24oXG4gICAgICBzb3VyY2UsXG4gICAgICB0YXJnZXQsXG4gICAgICBjb25uZWN0aW9uU3RhcnQsXG4gICAgICBjb25uZWN0aW9uRW5kLFxuICAgICAgd2F5cG9pbnRzLFxuICAgICAgbWFuaGF0dGFuT3B0aW9uc1xuICAgICkpO1xuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZWRXYXlwb2ludHMgfHwgWyBjb25uZWN0aW9uU3RhcnQsIGNvbm5lY3Rpb25FbmQgXTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldEF0dGFjaE9yaWVudGF0aW9uKGF0dGFjaGVkRWxlbWVudCkge1xuICB2YXIgaG9zdEVsZW1lbnQgPSBhdHRhY2hlZEVsZW1lbnQuaG9zdDtcblxuICByZXR1cm4gZ2V0T3JpZW50YXRpb24oZ2V0TWlkKGF0dGFjaGVkRWxlbWVudCksIGhvc3RFbGVtZW50LCBBVFRBQ0hfT1JJRU5UQVRJT05fUEFERElORyk7XG59XG5cbmZ1bmN0aW9uIGdldE1lc3NhZ2VGbG93TWFuaGF0dGFuT3B0aW9ucyhzb3VyY2UsIHRhcmdldCkge1xuICByZXR1cm4ge1xuICAgIHByZWZlcnJlZExheW91dHM6IFsgJ3N0cmFpZ2h0JywgJ3Y6dicgXSxcbiAgICBwcmVzZXJ2ZURvY2tpbmc6IGdldE1lc3NhZ2VGbG93UHJlc2VydmVEb2NraW5nKHNvdXJjZSwgdGFyZ2V0KVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRNZXNzYWdlRmxvd1ByZXNlcnZlRG9ja2luZyhzb3VyY2UsIHRhcmdldCkge1xuXG4gIC8vICgxKSBkb2NraW5nIGVsZW1lbnQgY29ubmVjdGVkIHRvIHBhcnRpY2lwYW50IGhhcyBwcmVjZWRlbmNlXG4gIGlmIChpcyh0YXJnZXQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICByZXR1cm4gJ3NvdXJjZSc7XG4gIH1cblxuICBpZiAoaXMoc291cmNlLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgcmV0dXJuICd0YXJnZXQnO1xuICB9XG5cbiAgLy8gKDIpIGRvY2tpbmcgZWxlbWVudCBjb25uZWN0ZWQgdG8gZXhwYW5kZWQgc3ViLXByb2Nlc3MgaGFzIHByZWNlZGVuY2VcbiAgaWYgKGlzRXhwYW5kZWRTdWJQcm9jZXNzKHRhcmdldCkpIHtcbiAgICByZXR1cm4gJ3NvdXJjZSc7XG4gIH1cblxuICBpZiAoaXNFeHBhbmRlZFN1YlByb2Nlc3Moc291cmNlKSkge1xuICAgIHJldHVybiAndGFyZ2V0JztcbiAgfVxuXG4gIC8vICgzKSBkb2NraW5nIGV2ZW50IGhhcyBwcmVjZWRlbmNlXG4gIGlmIChpcyh0YXJnZXQsICdicG1uOkV2ZW50JykpIHtcbiAgICByZXR1cm4gJ3RhcmdldCc7XG4gIH1cblxuICBpZiAoaXMoc291cmNlLCAnYnBtbjpFdmVudCcpKSB7XG4gICAgcmV0dXJuICdzb3VyY2UnO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldFN1YlByb2Nlc3NNYW5oYXR0YW5PcHRpb25zKHNvdXJjZSkge1xuICByZXR1cm4ge1xuICAgIHByZWZlcnJlZExheW91dHM6IFsgJ3N0cmFpZ2h0JywgJ2g6aCcgXSxcbiAgICBwcmVzZXJ2ZURvY2tpbmc6IGdldFN1YlByb2Nlc3NQcmVzZXJ2ZURvY2tpbmcoc291cmNlKVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRTdWJQcm9jZXNzUHJlc2VydmVEb2NraW5nKHNvdXJjZSkge1xuICByZXR1cm4gaXNFeHBhbmRlZFN1YlByb2Nlc3Moc291cmNlKSA/ICd0YXJnZXQnIDogJ3NvdXJjZSc7XG59XG5cbmZ1bmN0aW9uIGdldENvbm5lY3Rpb25Eb2NraW5nKHBvaW50LCBzaGFwZSkge1xuICByZXR1cm4gcG9pbnQgPyAocG9pbnQub3JpZ2luYWwgfHwgcG9pbnQpIDogZ2V0TWlkKHNoYXBlKTtcbn1cblxuZnVuY3Rpb24gaXNDb21wZW5zYXRpb25Bc3NvY2lhdGlvbihzb3VyY2UsIHRhcmdldCkge1xuICByZXR1cm4gaXModGFyZ2V0LCAnYnBtbjpBY3Rpdml0eScpICYmXG4gICAgaXMoc291cmNlLCAnYnBtbjpCb3VuZGFyeUV2ZW50JykgJiZcbiAgICB0YXJnZXQuYnVzaW5lc3NPYmplY3QuaXNGb3JDb21wZW5zYXRpb247XG59XG5cbmZ1bmN0aW9uIGlzRXhwYW5kZWRTdWJQcm9jZXNzKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJiBpc0V4cGFuZGVkKGVsZW1lbnQpO1xufVxuXG5mdW5jdGlvbiBpc1NhbWUoYSwgYikge1xuICByZXR1cm4gYSA9PT0gYjtcbn1cblxuZnVuY3Rpb24gaXNBbnlPcmllbnRhdGlvbihvcmllbnRhdGlvbiwgb3JpZW50YXRpb25zKSB7XG4gIHJldHVybiBvcmllbnRhdGlvbnMuaW5kZXhPZihvcmllbnRhdGlvbikgIT09IC0xO1xufVxuXG5mdW5jdGlvbiBnZXRIb3Jpem9udGFsT3JpZW50YXRpb24ob3JpZW50YXRpb24pIHtcbiAgdmFyIG1hdGNoZXMgPSAvcmlnaHR8bGVmdC8uZXhlYyhvcmllbnRhdGlvbik7XG5cbiAgcmV0dXJuIG1hdGNoZXMgJiYgbWF0Y2hlc1swXTtcbn1cblxuZnVuY3Rpb24gZ2V0VmVydGljYWxPcmllbnRhdGlvbihvcmllbnRhdGlvbikge1xuICB2YXIgbWF0Y2hlcyA9IC90b3B8Ym90dG9tLy5leGVjKG9yaWVudGF0aW9uKTtcblxuICByZXR1cm4gbWF0Y2hlcyAmJiBtYXRjaGVzWzBdO1xufVxuXG5mdW5jdGlvbiBpc09wcG9zaXRlT3JpZW50YXRpb24oYSwgYikge1xuICByZXR1cm4gb3Bwb3NpdGVPcmllbnRhdGlvbk1hcHBpbmdbYV0gPT09IGI7XG59XG5cbmZ1bmN0aW9uIGlzT3Bwb3NpdGVIb3Jpem9udGFsT3JpZW50YXRpb24oYSwgYikge1xuICB2YXIgaG9yaXpvbnRhbE9yaWVudGF0aW9uID0gZ2V0SG9yaXpvbnRhbE9yaWVudGF0aW9uKGEpO1xuXG4gIHZhciBvcHBvc2l0ZUhvcml6b250YWxPcmllbnRhdGlvbiA9IG9wcG9zaXRlT3JpZW50YXRpb25NYXBwaW5nW2hvcml6b250YWxPcmllbnRhdGlvbl07XG5cbiAgcmV0dXJuIGIuaW5kZXhPZihvcHBvc2l0ZUhvcml6b250YWxPcmllbnRhdGlvbikgIT09IC0xO1xufVxuXG5mdW5jdGlvbiBpc09wcG9zaXRlVmVydGljYWxPcmllbnRhdGlvbihhLCBiKSB7XG4gIHZhciB2ZXJ0aWNhbE9yaWVudGF0aW9uID0gZ2V0VmVydGljYWxPcmllbnRhdGlvbihhKTtcblxuICB2YXIgb3Bwb3NpdGVWZXJ0aWNhbE9yaWVudGF0aW9uID0gb3Bwb3NpdGVPcmllbnRhdGlvbk1hcHBpbmdbdmVydGljYWxPcmllbnRhdGlvbl07XG5cbiAgcmV0dXJuIGIuaW5kZXhPZihvcHBvc2l0ZVZlcnRpY2FsT3JpZW50YXRpb24pICE9PSAtMTtcbn1cblxuZnVuY3Rpb24gaXNIb3Jpem9udGFsT3JpZW50YXRpb24ob3JpZW50YXRpb24pIHtcbiAgcmV0dXJuIG9yaWVudGF0aW9uID09PSAncmlnaHQnIHx8IG9yaWVudGF0aW9uID09PSAnbGVmdCc7XG59XG5cbmZ1bmN0aW9uIGdldExvb3BQcmVmZXJyZWRMYXlvdXQoc291cmNlLCBjb25uZWN0aW9uKSB7XG4gIHZhciB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cztcblxuICB2YXIgb3JpZW50YXRpb24gPSB3YXlwb2ludHMgJiYgd2F5cG9pbnRzLmxlbmd0aCAmJiBnZXRPcmllbnRhdGlvbih3YXlwb2ludHNbMF0sIHNvdXJjZSk7XG5cbiAgaWYgKG9yaWVudGF0aW9uID09PSAndG9wJykge1xuICAgIHJldHVybiBbICd0OnInIF07XG4gIH0gZWxzZSBpZiAob3JpZW50YXRpb24gPT09ICdyaWdodCcpIHtcbiAgICByZXR1cm4gWyAncjpiJyBdO1xuICB9IGVsc2UgaWYgKG9yaWVudGF0aW9uID09PSAnbGVmdCcpIHtcbiAgICByZXR1cm4gWyAnbDp0JyBdO1xuICB9XG5cbiAgcmV0dXJuIFsgJ2I6bCcgXTtcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRhcnlFdmVudFByZWZlcnJlZExheW91dHMoc291cmNlLCB0YXJnZXQsIGVuZCkge1xuICB2YXIgc291cmNlTWlkID0gZ2V0TWlkKHNvdXJjZSksXG4gICAgICB0YXJnZXRNaWQgPSBnZXRNaWQodGFyZ2V0KSxcbiAgICAgIGF0dGFjaE9yaWVudGF0aW9uID0gZ2V0QXR0YWNoT3JpZW50YXRpb24oc291cmNlKSxcbiAgICAgIHNvdXJjZUxheW91dCxcbiAgICAgIHRhcmdldExheW91dDtcblxuICB2YXIgaXNMb29wID0gaXNTYW1lKHNvdXJjZS5ob3N0LCB0YXJnZXQpO1xuXG4gIHZhciBhdHRhY2hlZFRvU2lkZSA9IGlzQW55T3JpZW50YXRpb24oYXR0YWNoT3JpZW50YXRpb24sIFsgJ3RvcCcsICdyaWdodCcsICdib3R0b20nLCAnbGVmdCcgXSk7XG5cbiAgdmFyIHRhcmdldE9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24odGFyZ2V0TWlkLCBzb3VyY2VNaWQsIHtcbiAgICB4OiBzb3VyY2Uud2lkdGggLyAyICsgdGFyZ2V0LndpZHRoIC8gMixcbiAgICB5OiBzb3VyY2UuaGVpZ2h0IC8gMiArIHRhcmdldC5oZWlnaHQgLyAyXG4gIH0pO1xuXG4gIGlmIChpc0xvb3ApIHtcbiAgICByZXR1cm4gZ2V0Qm91bmRhcnlFdmVudExvb3BMYXlvdXQoYXR0YWNoT3JpZW50YXRpb24sIGF0dGFjaGVkVG9TaWRlLCBzb3VyY2UsIHRhcmdldCwgZW5kKTtcbiAgfVxuXG4gIC8vIHNvdXJjZSBsYXlvdXRcbiAgc291cmNlTGF5b3V0ID0gZ2V0Qm91bmRhcnlFdmVudFNvdXJjZUxheW91dChhdHRhY2hPcmllbnRhdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24sIGF0dGFjaGVkVG9TaWRlKTtcblxuICAvLyB0YXJnZXQgbGF5b3V0XG4gIHRhcmdldExheW91dCA9IGdldEJvdW5kYXJ5RXZlbnRUYXJnZXRMYXlvdXQoYXR0YWNoT3JpZW50YXRpb24sIHRhcmdldE9yaWVudGF0aW9uLCBhdHRhY2hlZFRvU2lkZSk7XG5cbiAgcmV0dXJuIFsgc291cmNlTGF5b3V0ICsgJzonICsgdGFyZ2V0TGF5b3V0IF07XG59XG5cbmZ1bmN0aW9uIGdldEJvdW5kYXJ5RXZlbnRMb29wTGF5b3V0KGF0dGFjaE9yaWVudGF0aW9uLCBhdHRhY2hlZFRvU2lkZSwgc291cmNlLCB0YXJnZXQsIGVuZCkge1xuICB2YXIgb3JpZW50YXRpb24gPSBhdHRhY2hlZFRvU2lkZSA/IGF0dGFjaE9yaWVudGF0aW9uIDogZ2V0VmVydGljYWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbiksXG4gICAgICBzb3VyY2VMYXlvdXQgPSBvcmllbnRhdGlvbkRpcmVjdGlvbk1hcHBpbmdbIG9yaWVudGF0aW9uIF0sXG4gICAgICB0YXJnZXRMYXlvdXQ7XG5cbiAgaWYgKGF0dGFjaGVkVG9TaWRlKSB7XG4gICAgaWYgKGlzSG9yaXpvbnRhbE9yaWVudGF0aW9uKGF0dGFjaE9yaWVudGF0aW9uKSkge1xuICAgICAgdGFyZ2V0TGF5b3V0ID0gc2hvdWxkQ29ubmVjdFRvU2FtZVNpZGUoJ3knLCBzb3VyY2UsIHRhcmdldCwgZW5kKSA/ICdoJyA6ICdiJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGFyZ2V0TGF5b3V0ID0gc2hvdWxkQ29ubmVjdFRvU2FtZVNpZGUoJ3gnLCBzb3VyY2UsIHRhcmdldCwgZW5kKSA/ICd2JyA6ICdsJztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0TGF5b3V0ID0gJ3YnO1xuICB9XG5cbiAgcmV0dXJuIFsgc291cmNlTGF5b3V0ICsgJzonICsgdGFyZ2V0TGF5b3V0IF07XG59XG5cbmZ1bmN0aW9uIHNob3VsZENvbm5lY3RUb1NhbWVTaWRlKGF4aXMsIHNvdXJjZSwgdGFyZ2V0LCBlbmQpIHtcbiAgdmFyIHRocmVzaG9sZCA9IEJPVU5EQVJZX1RPX0hPU1RfVEhSRVNIT0xEO1xuXG4gIHJldHVybiAhKFxuICAgIGFyZUNsb3NlT25BeGlzKGF4aXMsIGVuZCwgdGFyZ2V0LCB0aHJlc2hvbGQpIHx8XG4gICAgYXJlQ2xvc2VPbkF4aXMoYXhpcywgZW5kLCB7XG4gICAgICB4OiB0YXJnZXQueCArIHRhcmdldC53aWR0aCxcbiAgICAgIHk6IHRhcmdldC55ICsgdGFyZ2V0LmhlaWdodFxuICAgIH0sIHRocmVzaG9sZCkgfHxcbiAgICBhcmVDbG9zZU9uQXhpcyhheGlzLCBlbmQsIGdldE1pZChzb3VyY2UpLCB0aHJlc2hvbGQpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGFyZUNsb3NlT25BeGlzKGF4aXMsIGEsIGIsIHRocmVzaG9sZCkge1xuICByZXR1cm4gTWF0aC5hYnMoYVsgYXhpcyBdIC0gYlsgYXhpcyBdKSA8IHRocmVzaG9sZDtcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRhcnlFdmVudFNvdXJjZUxheW91dChhdHRhY2hPcmllbnRhdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24sIGF0dGFjaGVkVG9TaWRlKSB7XG5cbiAgLy8gYXR0YWNoZWQgdG8gZWl0aGVyIHRvcCwgcmlnaHQsIGJvdHRvbSBvciBsZWZ0IHNpZGVcbiAgaWYgKGF0dGFjaGVkVG9TaWRlKSB7XG4gICAgcmV0dXJuIG9yaWVudGF0aW9uRGlyZWN0aW9uTWFwcGluZ1sgYXR0YWNoT3JpZW50YXRpb24gXTtcbiAgfVxuXG4gIC8vIGF0dGFjaGVkIHRvIGVpdGhlciB0b3AtcmlnaHQsIHRvcC1sZWZ0LCBib3R0b20tcmlnaHQgb3IgYm90dG9tLWxlZnQgY29ybmVyXG5cbiAgLy8gc2FtZSB2ZXJ0aWNhbCBvciBvcHBvc2l0ZSBob3Jpem9udGFsIG9yaWVudGF0aW9uXG4gIGlmIChpc1NhbWUoXG4gICAgZ2V0VmVydGljYWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbiksIGdldFZlcnRpY2FsT3JpZW50YXRpb24odGFyZ2V0T3JpZW50YXRpb24pXG4gICkgfHwgaXNPcHBvc2l0ZU9yaWVudGF0aW9uKFxuICAgIGdldEhvcml6b250YWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbiksIGdldEhvcml6b250YWxPcmllbnRhdGlvbih0YXJnZXRPcmllbnRhdGlvbilcbiAgKSkge1xuICAgIHJldHVybiBvcmllbnRhdGlvbkRpcmVjdGlvbk1hcHBpbmdbIGdldFZlcnRpY2FsT3JpZW50YXRpb24oYXR0YWNoT3JpZW50YXRpb24pIF07XG4gIH1cblxuICAvLyBmYWxsYmFja1xuICByZXR1cm4gb3JpZW50YXRpb25EaXJlY3Rpb25NYXBwaW5nWyBnZXRIb3Jpem9udGFsT3JpZW50YXRpb24oYXR0YWNoT3JpZW50YXRpb24pIF07XG59XG5cbmZ1bmN0aW9uIGdldEJvdW5kYXJ5RXZlbnRUYXJnZXRMYXlvdXQoYXR0YWNoT3JpZW50YXRpb24sIHRhcmdldE9yaWVudGF0aW9uLCBhdHRhY2hlZFRvU2lkZSkge1xuXG4gIC8vIGF0dGFjaGVkIHRvIGVpdGhlciB0b3AsIHJpZ2h0LCBib3R0b20gb3IgbGVmdCBzaWRlXG4gIGlmIChhdHRhY2hlZFRvU2lkZSkge1xuICAgIGlmIChpc0hvcml6b250YWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbikpIHtcblxuICAgICAgLy8gb3JpZW50YXRpb24gaXMgcmlnaHQgb3IgbGVmdFxuXG4gICAgICAvLyBvcHBvc2l0ZSBob3Jpem9udGFsIG9yaWVudGF0aW9uIG9yIHNhbWUgb3JpZW50YXRpb25cbiAgICAgIGlmIChcbiAgICAgICAgaXNPcHBvc2l0ZUhvcml6b250YWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24pIHx8XG4gICAgICAgIGlzU2FtZShhdHRhY2hPcmllbnRhdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24pXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuICdoJztcbiAgICAgIH1cblxuICAgICAgLy8gZmFsbGJhY2tcbiAgICAgIHJldHVybiAndic7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gb3JpZW50YXRpb24gaXMgdG9wIG9yIGJvdHRvbVxuXG4gICAgICAvLyBvcHBvc2l0ZSB2ZXJ0aWNhbCBvcmllbnRhdGlvbiBvciBzYW1lIG9yaWVudGF0aW9uXG4gICAgICBpZiAoXG4gICAgICAgIGlzT3Bwb3NpdGVWZXJ0aWNhbE9yaWVudGF0aW9uKGF0dGFjaE9yaWVudGF0aW9uLCB0YXJnZXRPcmllbnRhdGlvbikgfHxcbiAgICAgICAgaXNTYW1lKGF0dGFjaE9yaWVudGF0aW9uLCB0YXJnZXRPcmllbnRhdGlvbilcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gJ3YnO1xuICAgICAgfVxuXG4gICAgICAvLyBmYWxsYmFja1xuICAgICAgcmV0dXJuICdoJztcbiAgICB9XG4gIH1cblxuICAvLyBhdHRhY2hlZCB0byBlaXRoZXIgdG9wLXJpZ2h0LCB0b3AtbGVmdCwgYm90dG9tLXJpZ2h0IG9yIGJvdHRvbS1sZWZ0IGNvcm5lclxuXG4gIC8vIG9yaWVudGF0aW9uIGlzIHJpZ2h0LCBsZWZ0XG4gIC8vIG9yIHNhbWUgdmVydGljYWwgb3JpZW50YXRpb24gYnV0IGFsc28gcmlnaHQgb3IgbGVmdFxuICBpZiAoaXNIb3Jpem9udGFsT3JpZW50YXRpb24odGFyZ2V0T3JpZW50YXRpb24pIHx8XG4gICAgKGlzU2FtZShnZXRWZXJ0aWNhbE9yaWVudGF0aW9uKGF0dGFjaE9yaWVudGF0aW9uKSwgZ2V0VmVydGljYWxPcmllbnRhdGlvbih0YXJnZXRPcmllbnRhdGlvbikpICYmXG4gICAgICBnZXRIb3Jpem9udGFsT3JpZW50YXRpb24odGFyZ2V0T3JpZW50YXRpb24pKSkge1xuICAgIHJldHVybiAnaCc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuICd2JztcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHtcbiAgcmVtb3ZlIGFzIGNvbGxlY3Rpb25SZW1vdmUsXG4gIGFkZCBhcyBjb2xsZWN0aW9uQWRkXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5pbXBvcnQge1xuICBMYWJlbFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9tb2RlbCc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzQW55XG59IGZyb20gJy4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuLyoqXG4gKiBBIGhhbmRsZXIgcmVzcG9uc2libGUgZm9yIHVwZGF0aW5nIHRoZSB1bmRlcmx5aW5nIEJQTU4gMi4wIFhNTCArIERJXG4gKiBvbmNlIGNoYW5nZXMgb24gdGhlIGRpYWdyYW0gaGFwcGVuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5VcGRhdGVyKFxuICAgIGV2ZW50QnVzLCBicG1uRmFjdG9yeSwgY29ubmVjdGlvbkRvY2tpbmcsXG4gICAgdHJhbnNsYXRlKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuX2JwbW5GYWN0b3J5ID0gYnBtbkZhY3Rvcnk7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cblxuXG4gIC8vIGNvbm5lY3Rpb24gY3JvcHBpbmcgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIC8vIGNyb3AgY29ubmVjdGlvbiBlbmRzIGR1cmluZyBjcmVhdGUvdXBkYXRlXG4gIGZ1bmN0aW9uIGNyb3BDb25uZWN0aW9uKGUpIHtcbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICBjb25uZWN0aW9uO1xuXG4gICAgaWYgKCFjb250ZXh0LmNyb3BwZWQgJiYgaGludHMuY3JlYXRlRWxlbWVudHNCZWhhdmlvciAhPT0gZmFsc2UpIHtcbiAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb247XG4gICAgICBjb25uZWN0aW9uLndheXBvaW50cyA9IGNvbm5lY3Rpb25Eb2NraW5nLmdldENyb3BwZWRXYXlwb2ludHMoY29ubmVjdGlvbik7XG4gICAgICBjb250ZXh0LmNyb3BwZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuZXhlY3V0ZWQoW1xuICAgICdjb25uZWN0aW9uLmxheW91dCcsXG4gICAgJ2Nvbm5lY3Rpb24uY3JlYXRlJ1xuICBdLCBjcm9wQ29ubmVjdGlvbik7XG5cbiAgdGhpcy5yZXZlcnRlZChbICdjb25uZWN0aW9uLmxheW91dCcgXSwgZnVuY3Rpb24oZSkge1xuICAgIGRlbGV0ZSBlLmNvbnRleHQuY3JvcHBlZDtcbiAgfSk7XG5cblxuXG4gIC8vIEJQTU4gKyBESSB1cGRhdGUgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5cbiAgLy8gdXBkYXRlIHBhcmVudFxuICBmdW5jdGlvbiB1cGRhdGVQYXJlbnQoZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0O1xuXG4gICAgc2VsZi51cGRhdGVQYXJlbnQoY29udGV4dC5zaGFwZSB8fCBjb250ZXh0LmNvbm5lY3Rpb24sIGNvbnRleHQub2xkUGFyZW50KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJldmVyc2VVcGRhdGVQYXJlbnQoZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0O1xuXG4gICAgdmFyIGVsZW1lbnQgPSBjb250ZXh0LnNoYXBlIHx8IGNvbnRleHQuY29ubmVjdGlvbixcblxuICAgICAgICAvLyBvbGRQYXJlbnQgaXMgdGhlIChvbGQpIG5ldyBwYXJlbnQsIGJlY2F1c2Ugd2UgYXJlIHVuZG9pbmdcbiAgICAgICAgb2xkUGFyZW50ID0gY29udGV4dC5wYXJlbnQgfHwgY29udGV4dC5uZXdQYXJlbnQ7XG5cbiAgICBzZWxmLnVwZGF0ZVBhcmVudChlbGVtZW50LCBvbGRQYXJlbnQpO1xuICB9XG5cbiAgdGhpcy5leGVjdXRlZChbXG4gICAgJ3NoYXBlLm1vdmUnLFxuICAgICdzaGFwZS5jcmVhdGUnLFxuICAgICdzaGFwZS5kZWxldGUnLFxuICAgICdjb25uZWN0aW9uLmNyZWF0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubW92ZScsXG4gICAgJ2Nvbm5lY3Rpb24uZGVsZXRlJ1xuICBdLCBpZkJwbW4odXBkYXRlUGFyZW50KSk7XG5cbiAgdGhpcy5yZXZlcnRlZChbXG4gICAgJ3NoYXBlLm1vdmUnLFxuICAgICdzaGFwZS5jcmVhdGUnLFxuICAgICdzaGFwZS5kZWxldGUnLFxuICAgICdjb25uZWN0aW9uLmNyZWF0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubW92ZScsXG4gICAgJ2Nvbm5lY3Rpb24uZGVsZXRlJ1xuICBdLCBpZkJwbW4ocmV2ZXJzZVVwZGF0ZVBhcmVudCkpO1xuXG4gIC8qXG4gICAqICMjIFVwZGF0aW5nIFBhcmVudFxuICAgKlxuICAgKiBXaGVuIG1vcnBoaW5nIGEgUHJvY2VzcyBpbnRvIGEgQ29sbGFib3JhdGlvbiBvciB2aWNlLXZlcnNhLFxuICAgKiBtYWtlIHN1cmUgdGhhdCBib3RoIHRoZSAqc2VtYW50aWMqIGFuZCAqZGkqIHBhcmVudCBvZiBlYWNoIGVsZW1lbnRcbiAgICogaXMgdXBkYXRlZC5cbiAgICpcbiAgICovXG4gIGZ1bmN0aW9uIHVwZGF0ZVJvb3QoZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIG9sZFJvb3QgPSBjb250ZXh0Lm9sZFJvb3QsXG4gICAgICAgIGNoaWxkcmVuID0gb2xkUm9vdC5jaGlsZHJlbjtcblxuICAgIGZvckVhY2goY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICBpZiAoaXMoY2hpbGQsICdicG1uOkJhc2VFbGVtZW50JykpIHtcbiAgICAgICAgc2VsZi51cGRhdGVQYXJlbnQoY2hpbGQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdGhpcy5leGVjdXRlZChbICdjYW52YXMudXBkYXRlUm9vdCcgXSwgdXBkYXRlUm9vdCk7XG4gIHRoaXMucmV2ZXJ0ZWQoWyAnY2FudmFzLnVwZGF0ZVJvb3QnIF0sIHVwZGF0ZVJvb3QpO1xuXG5cbiAgLy8gdXBkYXRlIGJvdW5kc1xuICBmdW5jdGlvbiB1cGRhdGVCb3VuZHMoZSkge1xuICAgIHZhciBzaGFwZSA9IGUuY29udGV4dC5zaGFwZTtcblxuICAgIGlmICghaXMoc2hhcGUsICdicG1uOkJhc2VFbGVtZW50JykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmLnVwZGF0ZUJvdW5kcyhzaGFwZSk7XG4gIH1cblxuICB0aGlzLmV4ZWN1dGVkKFsgJ3NoYXBlLm1vdmUnLCAnc2hhcGUuY3JlYXRlJywgJ3NoYXBlLnJlc2l6ZScgXSwgaWZCcG1uKGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICAvLyBleGNsdWRlIGxhYmVscyBiZWNhdXNlIHRoZXkncmUgaGFuZGxlZCBzZXBhcmF0ZWx5IGR1cmluZyBzaGFwZS5jaGFuZ2VkXG4gICAgaWYgKGV2ZW50LmNvbnRleHQuc2hhcGUudHlwZSA9PT0gJ2xhYmVsJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHVwZGF0ZUJvdW5kcyhldmVudCk7XG4gIH0pKTtcblxuICB0aGlzLnJldmVydGVkKFsgJ3NoYXBlLm1vdmUnLCAnc2hhcGUuY3JlYXRlJywgJ3NoYXBlLnJlc2l6ZScgXSwgaWZCcG1uKGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICAvLyBleGNsdWRlIGxhYmVscyBiZWNhdXNlIHRoZXkncmUgaGFuZGxlZCBzZXBhcmF0ZWx5IGR1cmluZyBzaGFwZS5jaGFuZ2VkXG4gICAgaWYgKGV2ZW50LmNvbnRleHQuc2hhcGUudHlwZSA9PT0gJ2xhYmVsJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHVwZGF0ZUJvdW5kcyhldmVudCk7XG4gIH0pKTtcblxuICAvLyBIYW5kbGUgbGFiZWxzIHNlcGFyYXRlbHkuIFRoaXMgaXMgbmVjZXNzYXJ5LCBiZWNhdXNlIHRoZSBsYWJlbCBib3VuZHMgaGF2ZSB0byBiZSB1cGRhdGVkXG4gIC8vIGV2ZXJ5IHRpbWUgaXRzIHNoYXBlIGNoYW5nZXMsIG5vdCBvbmx5IG9uIG1vdmUsIGNyZWF0ZSBhbmQgcmVzaXplLlxuICBldmVudEJ1cy5vbignc2hhcGUuY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LmVsZW1lbnQudHlwZSA9PT0gJ2xhYmVsJykge1xuICAgICAgdXBkYXRlQm91bmRzKHsgY29udGV4dDogeyBzaGFwZTogZXZlbnQuZWxlbWVudCB9IH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYXR0YWNoIC8gZGV0YWNoIGNvbm5lY3Rpb25cbiAgZnVuY3Rpb24gdXBkYXRlQ29ubmVjdGlvbihlKSB7XG4gICAgc2VsZi51cGRhdGVDb25uZWN0aW9uKGUuY29udGV4dCk7XG4gIH1cblxuICB0aGlzLmV4ZWN1dGVkKFtcbiAgICAnY29ubmVjdGlvbi5jcmVhdGUnLFxuICAgICdjb25uZWN0aW9uLm1vdmUnLFxuICAgICdjb25uZWN0aW9uLmRlbGV0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ucmVjb25uZWN0J1xuICBdLCBpZkJwbW4odXBkYXRlQ29ubmVjdGlvbikpO1xuXG4gIHRoaXMucmV2ZXJ0ZWQoW1xuICAgICdjb25uZWN0aW9uLmNyZWF0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubW92ZScsXG4gICAgJ2Nvbm5lY3Rpb24uZGVsZXRlJyxcbiAgICAnY29ubmVjdGlvbi5yZWNvbm5lY3QnXG4gIF0sIGlmQnBtbih1cGRhdGVDb25uZWN0aW9uKSk7XG5cblxuICAvLyB1cGRhdGUgd2F5cG9pbnRzXG4gIGZ1bmN0aW9uIHVwZGF0ZUNvbm5lY3Rpb25XYXlwb2ludHMoZSkge1xuICAgIHNlbGYudXBkYXRlQ29ubmVjdGlvbldheXBvaW50cyhlLmNvbnRleHQuY29ubmVjdGlvbik7XG4gIH1cblxuICB0aGlzLmV4ZWN1dGVkKFtcbiAgICAnY29ubmVjdGlvbi5sYXlvdXQnLFxuICAgICdjb25uZWN0aW9uLm1vdmUnLFxuICAgICdjb25uZWN0aW9uLnVwZGF0ZVdheXBvaW50cycsXG4gIF0sIGlmQnBtbih1cGRhdGVDb25uZWN0aW9uV2F5cG9pbnRzKSk7XG5cbiAgdGhpcy5yZXZlcnRlZChbXG4gICAgJ2Nvbm5lY3Rpb24ubGF5b3V0JyxcbiAgICAnY29ubmVjdGlvbi5tb3ZlJyxcbiAgICAnY29ubmVjdGlvbi51cGRhdGVXYXlwb2ludHMnLFxuICBdLCBpZkJwbW4odXBkYXRlQ29ubmVjdGlvbldheXBvaW50cykpO1xuXG4gIC8vIHVwZGF0ZSBjb25kaXRpb25hbC9kZWZhdWx0IGZsb3dzXG4gIHRoaXMuZXhlY3V0ZWQoJ2Nvbm5lY3Rpb24ucmVjb25uZWN0JywgaWZCcG1uKGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBvbGRTb3VyY2UgPSBjb250ZXh0Lm9sZFNvdXJjZSxcbiAgICAgICAgbmV3U291cmNlID0gY29udGV4dC5uZXdTb3VyY2UsXG4gICAgICAgIGNvbm5lY3Rpb25CbyA9IGdldEJ1c2luZXNzT2JqZWN0KGNvbm5lY3Rpb24pLFxuICAgICAgICBvbGRTb3VyY2VCbyA9IGdldEJ1c2luZXNzT2JqZWN0KG9sZFNvdXJjZSksXG4gICAgICAgIG5ld1NvdXJjZUJvID0gZ2V0QnVzaW5lc3NPYmplY3QobmV3U291cmNlKTtcblxuICAgIC8vIHJlbW92ZSBjb25kaXRpb24gZnJvbSBjb25uZWN0aW9uIG9uIHJlY29ubmVjdCB0byBuZXcgc291cmNlXG4gICAgLy8gaWYgbmV3IHNvdXJjZSBjYW4gTk9UIGhhdmUgY29uZGlvbmFsIHNlcXVlbmNlIGZsb3dcbiAgICBpZiAoY29ubmVjdGlvbkJvLmNvbmRpdGlvbkV4cHJlc3Npb24gJiYgIWlzQW55KG5ld1NvdXJjZUJvLCBbXG4gICAgICAnYnBtbjpBY3Rpdml0eScsXG4gICAgICAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JyxcbiAgICAgICdicG1uOkluY2x1c2l2ZUdhdGV3YXknXG4gICAgXSkpIHtcbiAgICAgIGNvbnRleHQub2xkQ29uZGl0aW9uRXhwcmVzc2lvbiA9IGNvbm5lY3Rpb25Cby5jb25kaXRpb25FeHByZXNzaW9uO1xuXG4gICAgICBkZWxldGUgY29ubmVjdGlvbkJvLmNvbmRpdGlvbkV4cHJlc3Npb247XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGRlZmF1bHQgZnJvbSBvbGQgc291cmNlIGZsb3cgb24gcmVjb25uZWN0IHRvIG5ldyBzb3VyY2VcbiAgICAvLyBpZiBzb3VyY2UgY2hhbmdlZFxuICAgIGlmIChvbGRTb3VyY2UgIT09IG5ld1NvdXJjZSAmJiBvbGRTb3VyY2VCby5kZWZhdWx0ID09PSBjb25uZWN0aW9uQm8pIHtcbiAgICAgIGNvbnRleHQub2xkRGVmYXVsdCA9IG9sZFNvdXJjZUJvLmRlZmF1bHQ7XG5cbiAgICAgIGRlbGV0ZSBvbGRTb3VyY2VCby5kZWZhdWx0O1xuICAgIH1cbiAgfSkpO1xuXG4gIHRoaXMucmV2ZXJ0ZWQoJ2Nvbm5lY3Rpb24ucmVjb25uZWN0JywgaWZCcG1uKGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBvbGRTb3VyY2UgPSBjb250ZXh0Lm9sZFNvdXJjZSxcbiAgICAgICAgbmV3U291cmNlID0gY29udGV4dC5uZXdTb3VyY2UsXG4gICAgICAgIGNvbm5lY3Rpb25CbyA9IGdldEJ1c2luZXNzT2JqZWN0KGNvbm5lY3Rpb24pLFxuICAgICAgICBvbGRTb3VyY2VCbyA9IGdldEJ1c2luZXNzT2JqZWN0KG9sZFNvdXJjZSksXG4gICAgICAgIG5ld1NvdXJjZUJvID0gZ2V0QnVzaW5lc3NPYmplY3QobmV3U291cmNlKTtcblxuICAgIC8vIGFkZCBjb25kaXRpb24gdG8gY29ubmVjdGlvbiBvbiByZXZlcnQgcmVjb25uZWN0IHRvIG5ldyBzb3VyY2VcbiAgICBpZiAoY29udGV4dC5vbGRDb25kaXRpb25FeHByZXNzaW9uKSB7XG4gICAgICBjb25uZWN0aW9uQm8uY29uZGl0aW9uRXhwcmVzc2lvbiA9IGNvbnRleHQub2xkQ29uZGl0aW9uRXhwcmVzc2lvbjtcbiAgICB9XG5cbiAgICAvLyBhZGQgZGVmYXVsdCB0byBvbGQgc291cmNlIG9uIHJldmVydCByZWNvbm5lY3QgdG8gbmV3IHNvdXJjZVxuICAgIGlmIChjb250ZXh0Lm9sZERlZmF1bHQpIHtcbiAgICAgIG9sZFNvdXJjZUJvLmRlZmF1bHQgPSBjb250ZXh0Lm9sZERlZmF1bHQ7XG5cbiAgICAgIGRlbGV0ZSBuZXdTb3VyY2VCby5kZWZhdWx0O1xuICAgIH1cbiAgfSkpO1xuXG4gIC8vIHVwZGF0ZSBhdHRhY2htZW50c1xuICBmdW5jdGlvbiB1cGRhdGVBdHRhY2htZW50KGUpIHtcbiAgICBzZWxmLnVwZGF0ZUF0dGFjaG1lbnQoZS5jb250ZXh0KTtcbiAgfVxuXG4gIHRoaXMuZXhlY3V0ZWQoWyAnZWxlbWVudC51cGRhdGVBdHRhY2htZW50JyBdLCBpZkJwbW4odXBkYXRlQXR0YWNobWVudCkpO1xuICB0aGlzLnJldmVydGVkKFsgJ2VsZW1lbnQudXBkYXRlQXR0YWNobWVudCcgXSwgaWZCcG1uKHVwZGF0ZUF0dGFjaG1lbnQpKTtcbn1cblxuaW5oZXJpdHMoQnBtblVwZGF0ZXIsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cbkJwbW5VcGRhdGVyLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdicG1uRmFjdG9yeScsXG4gICdjb25uZWN0aW9uRG9ja2luZycsXG4gICd0cmFuc2xhdGUnXG5dO1xuXG5cbi8vIGltcGxlbWVudGF0aW9uIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZUF0dGFjaG1lbnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIGJ1c2luZXNzT2JqZWN0ID0gc2hhcGUuYnVzaW5lc3NPYmplY3QsXG4gICAgICBob3N0ID0gc2hhcGUuaG9zdDtcblxuICBidXNpbmVzc09iamVjdC5hdHRhY2hlZFRvUmVmID0gaG9zdCAmJiBob3N0LmJ1c2luZXNzT2JqZWN0O1xufTtcblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZVBhcmVudCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG9sZFBhcmVudCkge1xuXG4gIC8vIGRvIG5vdCB1cGRhdGUgQlBNTiAyLjAgbGFiZWwgcGFyZW50XG4gIGlmIChlbGVtZW50IGluc3RhbmNlb2YgTGFiZWwpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBkYXRhIHN0b3JlcyBpbiBjb2xsYWJvcmF0aW9ucyBhcmUgaGFuZGxlZCBzZXBhcmF0ZWx5IGJ5IERhdGFTdG9yZUJlaGF2aW9yXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSAmJlxuICAgICAgZWxlbWVudC5wYXJlbnQgJiZcbiAgICAgIGlzKGVsZW1lbnQucGFyZW50LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGFyZW50U2hhcGUgPSBlbGVtZW50LnBhcmVudDtcblxuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LFxuICAgICAgcGFyZW50QnVzaW5lc3NPYmplY3QgPSBwYXJlbnRTaGFwZSAmJiBwYXJlbnRTaGFwZS5idXNpbmVzc09iamVjdCxcbiAgICAgIHBhcmVudERpID0gcGFyZW50QnVzaW5lc3NPYmplY3QgJiYgcGFyZW50QnVzaW5lc3NPYmplY3QuZGk7XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkZsb3dOb2RlJykpIHtcbiAgICB0aGlzLnVwZGF0ZUZsb3dOb2RlUmVmcyhidXNpbmVzc09iamVjdCwgcGFyZW50QnVzaW5lc3NPYmplY3QsIG9sZFBhcmVudCAmJiBvbGRQYXJlbnQuYnVzaW5lc3NPYmplY3QpO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkRhdGFPdXRwdXRBc3NvY2lhdGlvbicpKSB7XG4gICAgaWYgKGVsZW1lbnQuc291cmNlKSB7XG4gICAgICBwYXJlbnRCdXNpbmVzc09iamVjdCA9IGVsZW1lbnQuc291cmNlLmJ1c2luZXNzT2JqZWN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJlbnRCdXNpbmVzc09iamVjdCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJykpIHtcbiAgICBpZiAoZWxlbWVudC50YXJnZXQpIHtcbiAgICAgIHBhcmVudEJ1c2luZXNzT2JqZWN0ID0gZWxlbWVudC50YXJnZXQuYnVzaW5lc3NPYmplY3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcmVudEJ1c2luZXNzT2JqZWN0ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICB0aGlzLnVwZGF0ZVNlbWFudGljUGFyZW50KGJ1c2luZXNzT2JqZWN0LCBwYXJlbnRCdXNpbmVzc09iamVjdCk7XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnKSAmJiBidXNpbmVzc09iamVjdC5kYXRhT2JqZWN0UmVmKSB7XG4gICAgdGhpcy51cGRhdGVTZW1hbnRpY1BhcmVudChidXNpbmVzc09iamVjdC5kYXRhT2JqZWN0UmVmLCBwYXJlbnRCdXNpbmVzc09iamVjdCk7XG4gIH1cblxuICB0aGlzLnVwZGF0ZURpUGFyZW50KGJ1c2luZXNzT2JqZWN0LmRpLCBwYXJlbnREaSk7XG59O1xuXG5cbkJwbW5VcGRhdGVyLnByb3RvdHlwZS51cGRhdGVCb3VuZHMgPSBmdW5jdGlvbihzaGFwZSkge1xuXG4gIHZhciBkaSA9IHNoYXBlLmJ1c2luZXNzT2JqZWN0LmRpO1xuXG4gIHZhciB0YXJnZXQgPSAoc2hhcGUgaW5zdGFuY2VvZiBMYWJlbCkgPyB0aGlzLl9nZXRMYWJlbChkaSkgOiBkaTtcblxuICB2YXIgYm91bmRzID0gdGFyZ2V0LmJvdW5kcztcblxuICBpZiAoIWJvdW5kcykge1xuICAgIGJvdW5kcyA9IHRoaXMuX2JwbW5GYWN0b3J5LmNyZWF0ZURpQm91bmRzKCk7XG4gICAgdGFyZ2V0LnNldCgnYm91bmRzJywgYm91bmRzKTtcbiAgfVxuXG4gIGFzc2lnbihib3VuZHMsIHtcbiAgICB4OiBzaGFwZS54LFxuICAgIHk6IHNoYXBlLnksXG4gICAgd2lkdGg6IHNoYXBlLndpZHRoLFxuICAgIGhlaWdodDogc2hhcGUuaGVpZ2h0XG4gIH0pO1xufTtcblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZUZsb3dOb2RlUmVmcyA9IGZ1bmN0aW9uKGJ1c2luZXNzT2JqZWN0LCBuZXdDb250YWlubWVudCwgb2xkQ29udGFpbm1lbnQpIHtcblxuICBpZiAob2xkQ29udGFpbm1lbnQgPT09IG5ld0NvbnRhaW5tZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG9sZFJlZnMsIG5ld1JlZnM7XG5cbiAgaWYgKGlzIChvbGRDb250YWlubWVudCwgJ2JwbW46TGFuZScpKSB7XG4gICAgb2xkUmVmcyA9IG9sZENvbnRhaW5tZW50LmdldCgnZmxvd05vZGVSZWYnKTtcbiAgICBjb2xsZWN0aW9uUmVtb3ZlKG9sZFJlZnMsIGJ1c2luZXNzT2JqZWN0KTtcbiAgfVxuXG4gIGlmIChpcyhuZXdDb250YWlubWVudCwgJ2JwbW46TGFuZScpKSB7XG4gICAgbmV3UmVmcyA9IG5ld0NvbnRhaW5tZW50LmdldCgnZmxvd05vZGVSZWYnKTtcbiAgICBjb2xsZWN0aW9uQWRkKG5ld1JlZnMsIGJ1c2luZXNzT2JqZWN0KTtcbiAgfVxufTtcblxuXG4vLyB1cGRhdGUgZXhpc3Rpbmcgc291cmNlRWxlbWVudCBhbmQgdGFyZ2V0RWxlbWVudCBkaSBpbmZvcm1hdGlvblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZURpQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKGRpLCBuZXdTb3VyY2UsIG5ld1RhcmdldCkge1xuXG4gIGlmIChkaS5zb3VyY2VFbGVtZW50ICYmIGRpLnNvdXJjZUVsZW1lbnQuYnBtbkVsZW1lbnQgIT09IG5ld1NvdXJjZSkge1xuICAgIGRpLnNvdXJjZUVsZW1lbnQgPSBuZXdTb3VyY2UgJiYgbmV3U291cmNlLmRpO1xuICB9XG5cbiAgaWYgKGRpLnRhcmdldEVsZW1lbnQgJiYgZGkudGFyZ2V0RWxlbWVudC5icG1uRWxlbWVudCAhPT0gbmV3VGFyZ2V0KSB7XG4gICAgZGkudGFyZ2V0RWxlbWVudCA9IG5ld1RhcmdldCAmJiBuZXdUYXJnZXQuZGk7XG4gIH1cblxufTtcblxuXG5CcG1uVXBkYXRlci5wcm90b3R5cGUudXBkYXRlRGlQYXJlbnQgPSBmdW5jdGlvbihkaSwgcGFyZW50RGkpIHtcblxuICBpZiAocGFyZW50RGkgJiYgIWlzKHBhcmVudERpLCAnYnBtbmRpOkJQTU5QbGFuZScpKSB7XG4gICAgcGFyZW50RGkgPSBwYXJlbnREaS4kcGFyZW50O1xuICB9XG5cbiAgaWYgKGRpLiRwYXJlbnQgPT09IHBhcmVudERpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBsYW5lRWxlbWVudHMgPSAocGFyZW50RGkgfHwgZGkuJHBhcmVudCkuZ2V0KCdwbGFuZUVsZW1lbnQnKTtcblxuICBpZiAocGFyZW50RGkpIHtcbiAgICBwbGFuZUVsZW1lbnRzLnB1c2goZGkpO1xuICAgIGRpLiRwYXJlbnQgPSBwYXJlbnREaTtcbiAgfSBlbHNlIHtcbiAgICBjb2xsZWN0aW9uUmVtb3ZlKHBsYW5lRWxlbWVudHMsIGRpKTtcbiAgICBkaS4kcGFyZW50ID0gbnVsbDtcbiAgfVxufTtcblxuZnVuY3Rpb24gZ2V0RGVmaW5pdGlvbnMoZWxlbWVudCkge1xuICB3aGlsZSAoZWxlbWVudCAmJiAhaXMoZWxlbWVudCwgJ2JwbW46RGVmaW5pdGlvbnMnKSkge1xuICAgIGVsZW1lbnQgPSBlbGVtZW50LiRwYXJlbnQ7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudDtcbn1cblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLmdldExhbmVTZXQgPSBmdW5jdGlvbihjb250YWluZXIpIHtcblxuICB2YXIgbGFuZVNldCwgbGFuZVNldHM7XG5cbiAgLy8gYnBtbjpMYW5lXG4gIGlmIChpcyhjb250YWluZXIsICdicG1uOkxhbmUnKSkge1xuICAgIGxhbmVTZXQgPSBjb250YWluZXIuY2hpbGRMYW5lU2V0O1xuXG4gICAgaWYgKCFsYW5lU2V0KSB7XG4gICAgICBsYW5lU2V0ID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkxhbmVTZXQnKTtcbiAgICAgIGNvbnRhaW5lci5jaGlsZExhbmVTZXQgPSBsYW5lU2V0O1xuICAgICAgbGFuZVNldC4kcGFyZW50ID0gY29udGFpbmVyO1xuICAgIH1cblxuICAgIHJldHVybiBsYW5lU2V0O1xuICB9XG5cbiAgLy8gYnBtbjpQYXJ0aWNpcGFudFxuICBpZiAoaXMoY29udGFpbmVyLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgY29udGFpbmVyID0gY29udGFpbmVyLnByb2Nlc3NSZWY7XG4gIH1cblxuICAvLyBicG1uOkZsb3dFbGVtZW50c0NvbnRhaW5lclxuICBsYW5lU2V0cyA9IGNvbnRhaW5lci5nZXQoJ2xhbmVTZXRzJyk7XG4gIGxhbmVTZXQgPSBsYW5lU2V0c1swXTtcblxuICBpZiAoIWxhbmVTZXQpIHtcbiAgICBsYW5lU2V0ID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkxhbmVTZXQnKTtcbiAgICBsYW5lU2V0LiRwYXJlbnQgPSBjb250YWluZXI7XG4gICAgbGFuZVNldHMucHVzaChsYW5lU2V0KTtcbiAgfVxuXG4gIHJldHVybiBsYW5lU2V0O1xufTtcblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZVNlbWFudGljUGFyZW50ID0gZnVuY3Rpb24oYnVzaW5lc3NPYmplY3QsIG5ld1BhcmVudCwgdmlzdWFsUGFyZW50KSB7XG5cbiAgdmFyIGNvbnRhaW5tZW50LFxuICAgICAgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuXG4gIGlmIChidXNpbmVzc09iamVjdC4kcGFyZW50ID09PSBuZXdQYXJlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkRhdGFJbnB1dCcpIHx8IGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpEYXRhT3V0cHV0JykpIHtcblxuICAgIGlmIChpcyhuZXdQYXJlbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgJ3Byb2Nlc3NSZWYnIGluIG5ld1BhcmVudCkge1xuICAgICAgbmV3UGFyZW50ID0gbmV3UGFyZW50LnByb2Nlc3NSZWY7XG4gICAgfVxuXG4gICAgLy8gYWxyZWFkeSBpbiBjb3JyZWN0IGlvU3BlY2lmaWNhdGlvblxuICAgIGlmICgnaW9TcGVjaWZpY2F0aW9uJyBpbiBuZXdQYXJlbnQgJiYgbmV3UGFyZW50LmlvU3BlY2lmaWNhdGlvbiA9PT0gYnVzaW5lc3NPYmplY3QuJHBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46TGFuZScpKSB7XG5cbiAgICBpZiAobmV3UGFyZW50KSB7XG4gICAgICBuZXdQYXJlbnQgPSB0aGlzLmdldExhbmVTZXQobmV3UGFyZW50KTtcbiAgICB9XG5cbiAgICBjb250YWlubWVudCA9ICdsYW5lcyc7XG4gIH0gZWxzZVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46Rmxvd0VsZW1lbnQnKSkge1xuXG4gICAgaWYgKG5ld1BhcmVudCkge1xuXG4gICAgICBpZiAoaXMobmV3UGFyZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgICAgIG5ld1BhcmVudCA9IG5ld1BhcmVudC5wcm9jZXNzUmVmO1xuICAgICAgfSBlbHNlXG5cbiAgICAgIGlmIChpcyhuZXdQYXJlbnQsICdicG1uOkxhbmUnKSkge1xuICAgICAgICBkbyB7XG5cbiAgICAgICAgICAvLyB1bndyYXAgTGFuZSAtPiBMYW5lU2V0IC0+IChMYW5lIHwgRmxvd0VsZW1lbnRzQ29udGFpbmVyKVxuICAgICAgICAgIG5ld1BhcmVudCA9IG5ld1BhcmVudC4kcGFyZW50LiRwYXJlbnQ7XG4gICAgICAgIH0gd2hpbGUgKGlzKG5ld1BhcmVudCwgJ2JwbW46TGFuZScpKTtcblxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnRhaW5tZW50ID0gJ2Zsb3dFbGVtZW50cyc7XG5cbiAgfSBlbHNlXG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpBcnRpZmFjdCcpKSB7XG5cbiAgICB3aGlsZSAobmV3UGFyZW50ICYmXG4gICAgICAgICAgICFpcyhuZXdQYXJlbnQsICdicG1uOlByb2Nlc3MnKSAmJlxuICAgICAgICAgICAhaXMobmV3UGFyZW50LCAnYnBtbjpTdWJQcm9jZXNzJykgJiZcbiAgICAgICAgICAgIWlzKG5ld1BhcmVudCwgJ2JwbW46Q29sbGFib3JhdGlvbicpKSB7XG5cbiAgICAgIGlmIChpcyhuZXdQYXJlbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICAgICAgbmV3UGFyZW50ID0gbmV3UGFyZW50LnByb2Nlc3NSZWY7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3UGFyZW50ID0gbmV3UGFyZW50LiRwYXJlbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29udGFpbm1lbnQgPSAnYXJ0aWZhY3RzJztcbiAgfSBlbHNlXG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpNZXNzYWdlRmxvdycpKSB7XG4gICAgY29udGFpbm1lbnQgPSAnbWVzc2FnZUZsb3dzJztcblxuICB9IGVsc2VcblxuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICBjb250YWlubWVudCA9ICdwYXJ0aWNpcGFudHMnO1xuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBwYXJ0aWNpcGFudHMgcHJvY2VzcyBpcyBwcm9wZXJseSBhdHRhY2hlZCAvIGRldGFjaGVkXG4gICAgLy8gZnJvbSB0aGUgWE1MIGRvY3VtZW50XG5cbiAgICB2YXIgcHJvY2VzcyA9IGJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWYsXG4gICAgICAgIGRlZmluaXRpb25zO1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcbiAgICAgIGRlZmluaXRpb25zID0gZ2V0RGVmaW5pdGlvbnMoYnVzaW5lc3NPYmplY3QuJHBhcmVudCB8fCBuZXdQYXJlbnQpO1xuXG4gICAgICBpZiAoYnVzaW5lc3NPYmplY3QuJHBhcmVudCkge1xuICAgICAgICBjb2xsZWN0aW9uUmVtb3ZlKGRlZmluaXRpb25zLmdldCgncm9vdEVsZW1lbnRzJyksIHByb2Nlc3MpO1xuICAgICAgICBwcm9jZXNzLiRwYXJlbnQgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAobmV3UGFyZW50KSB7XG4gICAgICAgIGNvbGxlY3Rpb25BZGQoZGVmaW5pdGlvbnMuZ2V0KCdyb290RWxlbWVudHMnKSwgcHJvY2Vzcyk7XG4gICAgICAgIHByb2Nlc3MuJHBhcmVudCA9IGRlZmluaXRpb25zO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlXG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpEYXRhT3V0cHV0QXNzb2NpYXRpb24nKSkge1xuICAgIGNvbnRhaW5tZW50ID0gJ2RhdGFPdXRwdXRBc3NvY2lhdGlvbnMnO1xuICB9IGVsc2VcblxuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJykpIHtcbiAgICBjb250YWlubWVudCA9ICdkYXRhSW5wdXRBc3NvY2lhdGlvbnMnO1xuICB9XG5cbiAgaWYgKCFjb250YWlubWVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcih0cmFuc2xhdGUoXG4gICAgICAnbm8gcGFyZW50IGZvciB7ZWxlbWVudH0gaW4ge3BhcmVudH0nLFxuICAgICAge1xuICAgICAgICBlbGVtZW50OiBidXNpbmVzc09iamVjdC5pZCxcbiAgICAgICAgcGFyZW50OiBuZXdQYXJlbnQuaWRcbiAgICAgIH1cbiAgICApKTtcbiAgfVxuXG4gIHZhciBjaGlsZHJlbjtcblxuICBpZiAoYnVzaW5lc3NPYmplY3QuJHBhcmVudCkge1xuXG4gICAgLy8gcmVtb3ZlIGZyb20gb2xkIHBhcmVudFxuICAgIGNoaWxkcmVuID0gYnVzaW5lc3NPYmplY3QuJHBhcmVudC5nZXQoY29udGFpbm1lbnQpO1xuICAgIGNvbGxlY3Rpb25SZW1vdmUoY2hpbGRyZW4sIGJ1c2luZXNzT2JqZWN0KTtcbiAgfVxuXG4gIGlmICghbmV3UGFyZW50KSB7XG4gICAgYnVzaW5lc3NPYmplY3QuJHBhcmVudCA9IG51bGw7XG4gIH0gZWxzZSB7XG5cbiAgICAvLyBhZGQgdG8gbmV3IHBhcmVudFxuICAgIGNoaWxkcmVuID0gbmV3UGFyZW50LmdldChjb250YWlubWVudCk7XG4gICAgY2hpbGRyZW4ucHVzaChidXNpbmVzc09iamVjdCk7XG4gICAgYnVzaW5lc3NPYmplY3QuJHBhcmVudCA9IG5ld1BhcmVudDtcbiAgfVxuXG4gIGlmICh2aXN1YWxQYXJlbnQpIHtcbiAgICB2YXIgZGlDaGlsZHJlbiA9IHZpc3VhbFBhcmVudC5nZXQoY29udGFpbm1lbnQpO1xuXG4gICAgY29sbGVjdGlvblJlbW92ZShjaGlsZHJlbiwgYnVzaW5lc3NPYmplY3QpO1xuXG4gICAgaWYgKG5ld1BhcmVudCkge1xuXG4gICAgICBpZiAoIWRpQ2hpbGRyZW4pIHtcbiAgICAgICAgZGlDaGlsZHJlbiA9IFtdO1xuICAgICAgICBuZXdQYXJlbnQuc2V0KGNvbnRhaW5tZW50LCBkaUNoaWxkcmVuKTtcbiAgICAgIH1cblxuICAgICAgZGlDaGlsZHJlbi5wdXNoKGJ1c2luZXNzT2JqZWN0KTtcbiAgICB9XG4gIH1cbn07XG5cblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZUNvbm5lY3Rpb25XYXlwb2ludHMgPSBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gIGNvbm5lY3Rpb24uYnVzaW5lc3NPYmplY3QuZGkuc2V0KCd3YXlwb2ludCcsIHRoaXMuX2JwbW5GYWN0b3J5LmNyZWF0ZURpV2F5cG9pbnRzKGNvbm5lY3Rpb24ud2F5cG9pbnRzKSk7XG59O1xuXG5cbkJwbW5VcGRhdGVyLnByb3RvdHlwZS51cGRhdGVDb25uZWN0aW9uID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChjb25uZWN0aW9uKSxcbiAgICAgIG5ld1NvdXJjZSA9IGdldEJ1c2luZXNzT2JqZWN0KGNvbm5lY3Rpb24uc291cmNlKSxcbiAgICAgIG5ld1RhcmdldCA9IGdldEJ1c2luZXNzT2JqZWN0KGNvbm5lY3Rpb24udGFyZ2V0KSxcbiAgICAgIHZpc3VhbFBhcmVudDtcblxuICBpZiAoIWlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpEYXRhQXNzb2NpYXRpb24nKSkge1xuXG4gICAgdmFyIGludmVyc2VTZXQgPSBpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46U2VxdWVuY2VGbG93Jyk7XG5cbiAgICBpZiAoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmICE9PSBuZXdTb3VyY2UpIHtcbiAgICAgIGlmIChpbnZlcnNlU2V0KSB7XG4gICAgICAgIGNvbGxlY3Rpb25SZW1vdmUoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmICYmIGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZi5nZXQoJ291dGdvaW5nJyksIGJ1c2luZXNzT2JqZWN0KTtcblxuICAgICAgICBpZiAobmV3U291cmNlICYmIG5ld1NvdXJjZS5nZXQoJ291dGdvaW5nJykpIHtcbiAgICAgICAgICBuZXdTb3VyY2UuZ2V0KCdvdXRnb2luZycpLnB1c2goYnVzaW5lc3NPYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiA9IG5ld1NvdXJjZTtcbiAgICB9XG5cbiAgICBpZiAoYnVzaW5lc3NPYmplY3QudGFyZ2V0UmVmICE9PSBuZXdUYXJnZXQpIHtcbiAgICAgIGlmIChpbnZlcnNlU2V0KSB7XG4gICAgICAgIGNvbGxlY3Rpb25SZW1vdmUoYnVzaW5lc3NPYmplY3QudGFyZ2V0UmVmICYmIGJ1c2luZXNzT2JqZWN0LnRhcmdldFJlZi5nZXQoJ2luY29taW5nJyksIGJ1c2luZXNzT2JqZWN0KTtcblxuICAgICAgICBpZiAobmV3VGFyZ2V0ICYmIG5ld1RhcmdldC5nZXQoJ2luY29taW5nJykpIHtcbiAgICAgICAgICBuZXdUYXJnZXQuZ2V0KCdpbmNvbWluZycpLnB1c2goYnVzaW5lc3NPYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGJ1c2luZXNzT2JqZWN0LnRhcmdldFJlZiA9IG5ld1RhcmdldDtcbiAgICB9XG4gIH0gZWxzZVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46RGF0YUlucHV0QXNzb2NpYXRpb24nKSkge1xuXG4gICAgLy8gaGFuZGxlIG9ibm94aW91cyBpc01zb21lIHNvdXJjZVJlZlxuICAgIGJ1c2luZXNzT2JqZWN0LmdldCgnc291cmNlUmVmJylbMF0gPSBuZXdTb3VyY2U7XG5cbiAgICB2aXN1YWxQYXJlbnQgPSBjb250ZXh0LnBhcmVudCB8fCBjb250ZXh0Lm5ld1BhcmVudCB8fCBuZXdUYXJnZXQ7XG5cbiAgICB0aGlzLnVwZGF0ZVNlbWFudGljUGFyZW50KGJ1c2luZXNzT2JqZWN0LCBuZXdUYXJnZXQsIHZpc3VhbFBhcmVudCk7XG4gIH0gZWxzZVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46RGF0YU91dHB1dEFzc29jaWF0aW9uJykpIHtcbiAgICB2aXN1YWxQYXJlbnQgPSBjb250ZXh0LnBhcmVudCB8fCBjb250ZXh0Lm5ld1BhcmVudCB8fCBuZXdTb3VyY2U7XG5cbiAgICB0aGlzLnVwZGF0ZVNlbWFudGljUGFyZW50KGJ1c2luZXNzT2JqZWN0LCBuZXdTb3VyY2UsIHZpc3VhbFBhcmVudCk7XG5cbiAgICAvLyB0YXJnZXRSZWYgPSBuZXcgdGFyZ2V0XG4gICAgYnVzaW5lc3NPYmplY3QudGFyZ2V0UmVmID0gbmV3VGFyZ2V0O1xuICB9XG5cbiAgdGhpcy51cGRhdGVDb25uZWN0aW9uV2F5cG9pbnRzKGNvbm5lY3Rpb24pO1xuXG4gIHRoaXMudXBkYXRlRGlDb25uZWN0aW9uKGJ1c2luZXNzT2JqZWN0LmRpLCBuZXdTb3VyY2UsIG5ld1RhcmdldCk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5CcG1uVXBkYXRlci5wcm90b3R5cGUuX2dldExhYmVsID0gZnVuY3Rpb24oZGkpIHtcbiAgaWYgKCFkaS5sYWJlbCkge1xuICAgIGRpLmxhYmVsID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlRGlMYWJlbCgpO1xuICB9XG5cbiAgcmV0dXJuIGRpLmxhYmVsO1xufTtcblxuXG4vKipcbiAqIE1ha2Ugc3VyZSB0aGUgZXZlbnQgbGlzdGVuZXIgaXMgb25seSBjYWxsZWRcbiAqIGlmIHRoZSB0b3VjaGVkIGVsZW1lbnQgaXMgYSBCUE1OIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gZ3VhcmRlZCBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBpZkJwbW4oZm4pIHtcblxuICByZXR1cm4gZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuc2hhcGUgfHwgY29udGV4dC5jb25uZWN0aW9uO1xuXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkJhc2VFbGVtZW50JykpIHtcbiAgICAgIGZuKGV2ZW50KTtcbiAgICB9XG4gIH07XG59XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIGlzT2JqZWN0XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzRXhwYW5kZWRcbn0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQgQmFzZUVsZW1lbnRGYWN0b3J5IGZyb20gJ2RpYWdyYW0tanMvbGliL2NvcmUvRWxlbWVudEZhY3RvcnknO1xuXG5pbXBvcnQge1xuICBERUZBVUxUX0xBQkVMX1NJWkVcbn0gZnJvbSAnLi4vLi4vdXRpbC9MYWJlbFV0aWwnO1xuXG5cbi8qKlxuICogQSBicG1uLWF3YXJlIGZhY3RvcnkgZm9yIGRpYWdyYW0tanMgc2hhcGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEVsZW1lbnRGYWN0b3J5KGJwbW5GYWN0b3J5LCBtb2RkbGUsIHRyYW5zbGF0ZSkge1xuICBCYXNlRWxlbWVudEZhY3RvcnkuY2FsbCh0aGlzKTtcblxuICB0aGlzLl9icG1uRmFjdG9yeSA9IGJwbW5GYWN0b3J5O1xuICB0aGlzLl9tb2RkbGUgPSBtb2RkbGU7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcbn1cblxuaW5oZXJpdHMoRWxlbWVudEZhY3RvcnksIEJhc2VFbGVtZW50RmFjdG9yeSk7XG5cbkVsZW1lbnRGYWN0b3J5LiRpbmplY3QgPSBbXG4gICdicG1uRmFjdG9yeScsXG4gICdtb2RkbGUnLFxuICAndHJhbnNsYXRlJ1xuXTtcblxuRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmJhc2VDcmVhdGUgPSBCYXNlRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZTtcblxuRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uKGVsZW1lbnRUeXBlLCBhdHRycykge1xuXG4gIC8vIG5vIHNwZWNpYWwgbWFnaWMgZm9yIGxhYmVscyxcbiAgLy8gd2UgYXNzdW1lIHRoZWlyIGJ1c2luZXNzT2JqZWN0cyBoYXZlIGFscmVhZHkgYmVlbiBjcmVhdGVkXG4gIC8vIGFuZCB3aXJlZCB2aWEgYXR0cnNcbiAgaWYgKGVsZW1lbnRUeXBlID09PSAnbGFiZWwnKSB7XG4gICAgcmV0dXJuIHRoaXMuYmFzZUNyZWF0ZShlbGVtZW50VHlwZSwgYXNzaWduKHsgdHlwZTogJ2xhYmVsJyB9LCBERUZBVUxUX0xBQkVMX1NJWkUsIGF0dHJzKSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jcmVhdGVCcG1uRWxlbWVudChlbGVtZW50VHlwZSwgYXR0cnMpO1xufTtcblxuRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZUJwbW5FbGVtZW50ID0gZnVuY3Rpb24oZWxlbWVudFR5cGUsIGF0dHJzKSB7XG4gIHZhciBzaXplLFxuICAgICAgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuXG4gIGF0dHJzID0gYXR0cnMgfHwge307XG5cbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gYXR0cnMuYnVzaW5lc3NPYmplY3Q7XG5cbiAgaWYgKCFidXNpbmVzc09iamVjdCkge1xuICAgIGlmICghYXR0cnMudHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnbm8gc2hhcGUgdHlwZSBzcGVjaWZpZWQnKSk7XG4gICAgfVxuXG4gICAgYnVzaW5lc3NPYmplY3QgPSB0aGlzLl9icG1uRmFjdG9yeS5jcmVhdGUoYXR0cnMudHlwZSk7XG4gIH1cblxuICBpZiAoIWJ1c2luZXNzT2JqZWN0LmRpKSB7XG4gICAgaWYgKGVsZW1lbnRUeXBlID09PSAncm9vdCcpIHtcbiAgICAgIGJ1c2luZXNzT2JqZWN0LmRpID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlRGlQbGFuZShidXNpbmVzc09iamVjdCwgW10sIHtcbiAgICAgICAgaWQ6IGJ1c2luZXNzT2JqZWN0LmlkICsgJ19kaSdcbiAgICAgIH0pO1xuICAgIH0gZWxzZVxuICAgIGlmIChlbGVtZW50VHlwZSA9PT0gJ2Nvbm5lY3Rpb24nKSB7XG4gICAgICBidXNpbmVzc09iamVjdC5kaSA9IHRoaXMuX2JwbW5GYWN0b3J5LmNyZWF0ZURpRWRnZShidXNpbmVzc09iamVjdCwgW10sIHtcbiAgICAgICAgaWQ6IGJ1c2luZXNzT2JqZWN0LmlkICsgJ19kaSdcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBidXNpbmVzc09iamVjdC5kaSA9IHRoaXMuX2JwbW5GYWN0b3J5LmNyZWF0ZURpU2hhcGUoYnVzaW5lc3NPYmplY3QsIHt9LCB7XG4gICAgICAgIGlkOiBidXNpbmVzc09iamVjdC5pZCArICdfZGknXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkdyb3VwJykpIHtcbiAgICBhdHRycyA9IGFzc2lnbih7XG4gICAgICBpc0ZyYW1lOiB0cnVlXG4gICAgfSwgYXR0cnMpO1xuICB9XG5cbiAgaWYgKGF0dHJzLmRpKSB7XG4gICAgYXNzaWduKGJ1c2luZXNzT2JqZWN0LmRpLCBhdHRycy5kaSk7XG5cbiAgICBkZWxldGUgYXR0cnMuZGk7XG4gIH1cblxuICBhcHBseUF0dHJpYnV0ZXMoYnVzaW5lc3NPYmplY3QsIGF0dHJzLCBbXG4gICAgJ3Byb2Nlc3NSZWYnLFxuICAgICdpc0ludGVycnVwdGluZycsXG4gICAgJ2Fzc29jaWF0aW9uRGlyZWN0aW9uJyxcbiAgICAnaXNGb3JDb21wZW5zYXRpb24nXG4gIF0pO1xuXG4gIGlmIChhdHRycy5pc0V4cGFuZGVkKSB7XG4gICAgYXBwbHlBdHRyaWJ1dGUoYnVzaW5lc3NPYmplY3QuZGksIGF0dHJzLCAnaXNFeHBhbmRlZCcpO1xuICB9XG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JykpIHtcbiAgICBidXNpbmVzc09iamVjdC5kaS5pc01hcmtlclZpc2libGUgPSB0cnVlO1xuICB9XG5cbiAgdmFyIGV2ZW50RGVmaW5pdGlvbnMsXG4gICAgICBuZXdFdmVudERlZmluaXRpb247XG5cbiAgaWYgKGF0dHJzLmV2ZW50RGVmaW5pdGlvblR5cGUpIHtcbiAgICBldmVudERlZmluaXRpb25zID0gYnVzaW5lc3NPYmplY3QuZ2V0KCdldmVudERlZmluaXRpb25zJykgfHwgW107XG4gICAgbmV3RXZlbnREZWZpbml0aW9uID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlKGF0dHJzLmV2ZW50RGVmaW5pdGlvblR5cGUsIGF0dHJzLmV2ZW50RGVmaW5pdGlvbkF0dHJzKTtcblxuICAgIGlmIChhdHRycy5ldmVudERlZmluaXRpb25UeXBlID09PSAnYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbicpIHtcbiAgICAgIG5ld0V2ZW50RGVmaW5pdGlvbi5jb25kaXRpb24gPSB0aGlzLl9icG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46Rm9ybWFsRXhwcmVzc2lvbicpO1xuICAgIH1cblxuICAgIGV2ZW50RGVmaW5pdGlvbnMucHVzaChuZXdFdmVudERlZmluaXRpb24pO1xuXG4gICAgbmV3RXZlbnREZWZpbml0aW9uLiRwYXJlbnQgPSBidXNpbmVzc09iamVjdDtcbiAgICBidXNpbmVzc09iamVjdC5ldmVudERlZmluaXRpb25zID0gZXZlbnREZWZpbml0aW9ucztcblxuICAgIGRlbGV0ZSBhdHRycy5ldmVudERlZmluaXRpb25UeXBlO1xuICB9XG5cbiAgc2l6ZSA9IHRoaXMuX2dldERlZmF1bHRTaXplKGJ1c2luZXNzT2JqZWN0KTtcblxuICBhdHRycyA9IGFzc2lnbih7XG4gICAgYnVzaW5lc3NPYmplY3Q6IGJ1c2luZXNzT2JqZWN0LFxuICAgIGlkOiBidXNpbmVzc09iamVjdC5pZFxuICB9LCBzaXplLCBhdHRycyk7XG5cbiAgcmV0dXJuIHRoaXMuYmFzZUNyZWF0ZShlbGVtZW50VHlwZSwgYXR0cnMpO1xufTtcblxuXG5FbGVtZW50RmFjdG9yeS5wcm90b3R5cGUuX2dldERlZmF1bHRTaXplID0gZnVuY3Rpb24oc2VtYW50aWMpIHtcblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuXG4gICAgaWYgKGlzRXhwYW5kZWQoc2VtYW50aWMpKSB7XG4gICAgICByZXR1cm4geyB3aWR0aDogMzUwLCBoZWlnaHQ6IDIwMCB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4geyB3aWR0aDogMTAwLCBoZWlnaHQ6IDgwIH07XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpUYXNrJykpIHtcbiAgICByZXR1cm4geyB3aWR0aDogMTAwLCBoZWlnaHQ6IDgwIH07XG4gIH1cblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkdhdGV3YXknKSkge1xuICAgIHJldHVybiB7IHdpZHRoOiA1MCwgaGVpZ2h0OiA1MCB9O1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpFdmVudCcpKSB7XG4gICAgcmV0dXJuIHsgd2lkdGg6IDM2LCBoZWlnaHQ6IDM2IH07XG4gIH1cblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICBpZiAoaXNFeHBhbmRlZChzZW1hbnRpYykpIHtcbiAgICAgIHJldHVybiB7IHdpZHRoOiA2MDAsIGhlaWdodDogMjUwIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IHdpZHRoOiA0MDAsIGhlaWdodDogNjAgfTtcbiAgICB9XG4gIH1cblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkxhbmUnKSkge1xuICAgIHJldHVybiB7IHdpZHRoOiA0MDAsIGhlaWdodDogMTAwIH07XG4gIH1cblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnKSkge1xuICAgIHJldHVybiB7IHdpZHRoOiAzNiwgaGVpZ2h0OiA1MCB9O1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSkge1xuICAgIHJldHVybiB7IHdpZHRoOiA1MCwgaGVpZ2h0OiA1MCB9O1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgcmV0dXJuIHsgd2lkdGg6IDEwMCwgaGVpZ2h0OiAzMCB9O1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpHcm91cCcpKSB7XG4gICAgcmV0dXJuIHsgd2lkdGg6IDMwMCwgaGVpZ2h0OiAzMDAgfTtcbiAgfVxuXG4gIHJldHVybiB7IHdpZHRoOiAxMDAsIGhlaWdodDogODAgfTtcbn07XG5cblxuLyoqXG4gKiBDcmVhdGUgcGFydGljaXBhbnQuXG4gKlxuICogQHBhcmFtIHtib29sZWFufE9iamVjdH0gW2F0dHJzXSBhdHRyc1xuICpcbiAqIEByZXR1cm5zIHtkanMubW9kZWwuU2hhcGV9XG4gKi9cbkVsZW1lbnRGYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVQYXJ0aWNpcGFudFNoYXBlID0gZnVuY3Rpb24oYXR0cnMpIHtcblxuICBpZiAoIWlzT2JqZWN0KGF0dHJzKSkge1xuICAgIGF0dHJzID0geyBpc0V4cGFuZGVkOiBhdHRycyB9O1xuICB9XG5cbiAgYXR0cnMgPSBhc3NpZ24oeyB0eXBlOiAnYnBtbjpQYXJ0aWNpcGFudCcgfSwgYXR0cnMgfHwge30pO1xuXG4gIC8vIHBhcnRpY2lwYW50cyBhcmUgZXhwYW5kZWQgYnkgZGVmYXVsdFxuICBpZiAoYXR0cnMuaXNFeHBhbmRlZCAhPT0gZmFsc2UpIHtcbiAgICBhdHRycy5wcm9jZXNzUmVmID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOlByb2Nlc3MnKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmNyZWF0ZVNoYXBlKGF0dHJzKTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQXBwbHkgYXR0cmlidXRlcyBmcm9tIGEgbWFwIHRvIHRoZSBnaXZlbiBlbGVtZW50LFxuICogcmVtb3ZlIGF0dHJpYnV0ZSBmcm9tIHRoZSBtYXAgb24gYXBwbGljYXRpb24uXG4gKlxuICogQHBhcmFtIHtCYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gYXR0cnMgKGluL291dCBtYXAgb2YgYXR0cmlidXRlcylcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gYXR0cmlidXRlTmFtZXMgbmFtZSBvZiBhdHRyaWJ1dGVzIHRvIGFwcGx5XG4gKi9cbmZ1bmN0aW9uIGFwcGx5QXR0cmlidXRlcyhlbGVtZW50LCBhdHRycywgYXR0cmlidXRlTmFtZXMpIHtcblxuICBmb3JFYWNoKGF0dHJpYnV0ZU5hbWVzLCBmdW5jdGlvbihwcm9wZXJ0eSkge1xuICAgIGlmIChhdHRyc1twcm9wZXJ0eV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXBwbHlBdHRyaWJ1dGUoZWxlbWVudCwgYXR0cnMsIHByb3BlcnR5KTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIEFwcGx5IG5hbWVkIHByb3BlcnR5IHRvIGVsZW1lbnQgYW5kIGRyYWluIGl0IGZyb20gdGhlIGF0dHJzXG4gKiBjb2xsZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7QmFzZX0gZWxlbWVudFxuICogQHBhcmFtIHtPYmplY3R9IGF0dHJzIChpbi9vdXQgbWFwIG9mIGF0dHJpYnV0ZXMpXG4gKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlTmFtZSB0byBhcHBseVxuICovXG5mdW5jdGlvbiBhcHBseUF0dHJpYnV0ZShlbGVtZW50LCBhdHRycywgYXR0cmlidXRlTmFtZSkge1xuICBlbGVtZW50W2F0dHJpYnV0ZU5hbWVdID0gYXR0cnNbYXR0cmlidXRlTmFtZV07XG5cbiAgZGVsZXRlIGF0dHJzW2F0dHJpYnV0ZU5hbWVdO1xufSIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBCYXNlTW9kZWxpbmcgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvTW9kZWxpbmcnO1xuXG5pbXBvcnQgVXBkYXRlUHJvcGVydGllc0hhbmRsZXIgZnJvbSAnLi9jbWQvVXBkYXRlUHJvcGVydGllc0hhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhbnZhc1Jvb3RIYW5kbGVyIGZyb20gJy4vY21kL1VwZGF0ZUNhbnZhc1Jvb3RIYW5kbGVyJztcbmltcG9ydCBBZGRMYW5lSGFuZGxlciBmcm9tICcuL2NtZC9BZGRMYW5lSGFuZGxlcic7XG5pbXBvcnQgU3BsaXRMYW5lSGFuZGxlciBmcm9tICcuL2NtZC9TcGxpdExhbmVIYW5kbGVyJztcbmltcG9ydCBSZXNpemVMYW5lSGFuZGxlciBmcm9tICcuL2NtZC9SZXNpemVMYW5lSGFuZGxlcic7XG5pbXBvcnQgVXBkYXRlRmxvd05vZGVSZWZzSGFuZGxlciBmcm9tICcuL2NtZC9VcGRhdGVGbG93Tm9kZVJlZnNIYW5kbGVyJztcbmltcG9ydCBJZENsYWltSGFuZGxlciBmcm9tICcuL2NtZC9JZENsYWltSGFuZGxlcic7XG5pbXBvcnQgU2V0Q29sb3JIYW5kbGVyIGZyb20gJy4vY21kL1NldENvbG9ySGFuZGxlcic7XG5cbmltcG9ydCBVcGRhdGVMYWJlbEhhbmRsZXIgZnJvbSAnLi4vbGFiZWwtZWRpdGluZy9jbWQvVXBkYXRlTGFiZWxIYW5kbGVyJztcblxuXG4vKipcbiAqIEJQTU4gMi4wIG1vZGVsaW5nIGZlYXR1cmVzIGFjdGl2YXRvclxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0VsZW1lbnRGYWN0b3J5fSBlbGVtZW50RmFjdG9yeVxuICogQHBhcmFtIHtDb21tYW5kU3RhY2t9IGNvbW1hbmRTdGFja1xuICogQHBhcmFtIHtCcG1uUnVsZXN9IGJwbW5SdWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb2RlbGluZyhcbiAgICBldmVudEJ1cywgZWxlbWVudEZhY3RvcnksIGNvbW1hbmRTdGFjayxcbiAgICBicG1uUnVsZXMpIHtcblxuICBCYXNlTW9kZWxpbmcuY2FsbCh0aGlzLCBldmVudEJ1cywgZWxlbWVudEZhY3RvcnksIGNvbW1hbmRTdGFjayk7XG5cbiAgdGhpcy5fYnBtblJ1bGVzID0gYnBtblJ1bGVzO1xufVxuXG5pbmhlcml0cyhNb2RlbGluZywgQmFzZU1vZGVsaW5nKTtcblxuTW9kZWxpbmcuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcbiAgJ2NvbW1hbmRTdGFjaycsXG4gICdicG1uUnVsZXMnXG5dO1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5nZXRIYW5kbGVycyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgaGFuZGxlcnMgPSBCYXNlTW9kZWxpbmcucHJvdG90eXBlLmdldEhhbmRsZXJzLmNhbGwodGhpcyk7XG5cbiAgaGFuZGxlcnNbJ2VsZW1lbnQudXBkYXRlUHJvcGVydGllcyddID0gVXBkYXRlUHJvcGVydGllc0hhbmRsZXI7XG4gIGhhbmRsZXJzWydjYW52YXMudXBkYXRlUm9vdCddID0gVXBkYXRlQ2FudmFzUm9vdEhhbmRsZXI7XG4gIGhhbmRsZXJzWydsYW5lLmFkZCddID0gQWRkTGFuZUhhbmRsZXI7XG4gIGhhbmRsZXJzWydsYW5lLnJlc2l6ZSddID0gUmVzaXplTGFuZUhhbmRsZXI7XG4gIGhhbmRsZXJzWydsYW5lLnNwbGl0J10gPSBTcGxpdExhbmVIYW5kbGVyO1xuICBoYW5kbGVyc1snbGFuZS51cGRhdGVSZWZzJ10gPSBVcGRhdGVGbG93Tm9kZVJlZnNIYW5kbGVyO1xuICBoYW5kbGVyc1snaWQudXBkYXRlQ2xhaW0nXSA9IElkQ2xhaW1IYW5kbGVyO1xuICBoYW5kbGVyc1snZWxlbWVudC5zZXRDb2xvciddID0gU2V0Q29sb3JIYW5kbGVyO1xuICBoYW5kbGVyc1snZWxlbWVudC51cGRhdGVMYWJlbCddID0gVXBkYXRlTGFiZWxIYW5kbGVyO1xuXG4gIHJldHVybiBoYW5kbGVycztcbn07XG5cblxuTW9kZWxpbmcucHJvdG90eXBlLnVwZGF0ZUxhYmVsID0gZnVuY3Rpb24oZWxlbWVudCwgbmV3TGFiZWwsIG5ld0JvdW5kcywgaGludHMpIHtcbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnQudXBkYXRlTGFiZWwnLCB7XG4gICAgZWxlbWVudDogZWxlbWVudCxcbiAgICBuZXdMYWJlbDogbmV3TGFiZWwsXG4gICAgbmV3Qm91bmRzOiBuZXdCb3VuZHMsXG4gICAgaGludHM6IGhpbnRzIHx8IHt9XG4gIH0pO1xufTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBhdHRycywgaGludHMpIHtcblxuICB2YXIgYnBtblJ1bGVzID0gdGhpcy5fYnBtblJ1bGVzO1xuXG4gIGlmICghYXR0cnMpIHtcbiAgICBhdHRycyA9IGJwbW5SdWxlcy5jYW5Db25uZWN0KHNvdXJjZSwgdGFyZ2V0KTtcbiAgfVxuXG4gIGlmICghYXR0cnMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICByZXR1cm4gdGhpcy5jcmVhdGVDb25uZWN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBhdHRycywgc291cmNlLnBhcmVudCwgaGludHMpO1xufTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUudXBkYXRlUHJvcGVydGllcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHByb3BlcnRpZXMpIHtcbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnQudXBkYXRlUHJvcGVydGllcycsIHtcbiAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgIHByb3BlcnRpZXM6IHByb3BlcnRpZXNcbiAgfSk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUucmVzaXplTGFuZSA9IGZ1bmN0aW9uKGxhbmVTaGFwZSwgbmV3Qm91bmRzLCBiYWxhbmNlZCkge1xuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnbGFuZS5yZXNpemUnLCB7XG4gICAgc2hhcGU6IGxhbmVTaGFwZSxcbiAgICBuZXdCb3VuZHM6IG5ld0JvdW5kcyxcbiAgICBiYWxhbmNlZDogYmFsYW5jZWRcbiAgfSk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUuYWRkTGFuZSA9IGZ1bmN0aW9uKHRhcmdldExhbmVTaGFwZSwgbG9jYXRpb24pIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgc2hhcGU6IHRhcmdldExhbmVTaGFwZSxcbiAgICBsb2NhdGlvbjogbG9jYXRpb25cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnbGFuZS5hZGQnLCBjb250ZXh0KTtcblxuICByZXR1cm4gY29udGV4dC5uZXdMYW5lO1xufTtcblxuTW9kZWxpbmcucHJvdG90eXBlLnNwbGl0TGFuZSA9IGZ1bmN0aW9uKHRhcmdldExhbmUsIGNvdW50KSB7XG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdsYW5lLnNwbGl0Jywge1xuICAgIHNoYXBlOiB0YXJnZXRMYW5lLFxuICAgIGNvdW50OiBjb3VudFxuICB9KTtcbn07XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBjdXJyZW50IGRpYWdyYW0gaW50byBhIGNvbGxhYm9yYXRpb24uXG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGVsLlJvb3R9IHRoZSBuZXcgcm9vdCBlbGVtZW50XG4gKi9cbk1vZGVsaW5nLnByb3RvdHlwZS5tYWtlQ29sbGFib3JhdGlvbiA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBjb2xsYWJvcmF0aW9uRWxlbWVudCA9IHRoaXMuX2NyZWF0ZSgncm9vdCcsIHtcbiAgICB0eXBlOiAnYnBtbjpDb2xsYWJvcmF0aW9uJ1xuICB9KTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBuZXdSb290OiBjb2xsYWJvcmF0aW9uRWxlbWVudFxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdjYW52YXMudXBkYXRlUm9vdCcsIGNvbnRleHQpO1xuXG4gIHJldHVybiBjb2xsYWJvcmF0aW9uRWxlbWVudDtcbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS51cGRhdGVMYW5lUmVmcyA9IGZ1bmN0aW9uKGZsb3dOb2RlU2hhcGVzLCBsYW5lU2hhcGVzKSB7XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2xhbmUudXBkYXRlUmVmcycsIHtcbiAgICBmbG93Tm9kZVNoYXBlczogZmxvd05vZGVTaGFwZXMsXG4gICAgbGFuZVNoYXBlczogbGFuZVNoYXBlc1xuICB9KTtcbn07XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBjdXJyZW50IGRpYWdyYW0gaW50byBhIHByb2Nlc3MuXG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGVsLlJvb3R9IHRoZSBuZXcgcm9vdCBlbGVtZW50XG4gKi9cbk1vZGVsaW5nLnByb3RvdHlwZS5tYWtlUHJvY2VzcyA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBwcm9jZXNzRWxlbWVudCA9IHRoaXMuX2NyZWF0ZSgncm9vdCcsIHtcbiAgICB0eXBlOiAnYnBtbjpQcm9jZXNzJ1xuICB9KTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBuZXdSb290OiBwcm9jZXNzRWxlbWVudFxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdjYW52YXMudXBkYXRlUm9vdCcsIGNvbnRleHQpO1xufTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUuY2xhaW1JZCA9IGZ1bmN0aW9uKGlkLCBtb2RkbGVFbGVtZW50KSB7XG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdpZC51cGRhdGVDbGFpbScsIHtcbiAgICBpZDogaWQsXG4gICAgZWxlbWVudDogbW9kZGxlRWxlbWVudCxcbiAgICBjbGFpbWluZzogdHJ1ZVxuICB9KTtcbn07XG5cblxuTW9kZWxpbmcucHJvdG90eXBlLnVuY2xhaW1JZCA9IGZ1bmN0aW9uKGlkLCBtb2RkbGVFbGVtZW50KSB7XG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdpZC51cGRhdGVDbGFpbScsIHtcbiAgICBpZDogaWQsXG4gICAgZWxlbWVudDogbW9kZGxlRWxlbWVudFxuICB9KTtcbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS5zZXRDb2xvciA9IGZ1bmN0aW9uKGVsZW1lbnRzLCBjb2xvcnMpIHtcbiAgaWYgKCFlbGVtZW50cy5sZW5ndGgpIHtcbiAgICBlbGVtZW50cyA9IFsgZWxlbWVudHMgXTtcbiAgfVxuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdlbGVtZW50LnNldENvbG9yJywge1xuICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICBjb2xvcnM6IGNvbG9yc1xuICB9KTtcbn07XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQge1xuICBnZXRPcmllbnRhdGlvbixcbiAgZ2V0TWlkLFxuICBhc1RSQkxcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBzdWJzdHJhY3Rcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9NYXRoJztcblxuaW1wb3J0IHtcbiAgaGFzRXh0ZXJuYWxMYWJlbFxufSBmcm9tICcuLi8uLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG52YXIgQUxJR05NRU5UUyA9IFtcbiAgJ3RvcCcsXG4gICdib3R0b20nLFxuICAnbGVmdCcsXG4gICdyaWdodCdcbl07XG5cbnZhciBFTEVNRU5UX0xBQkVMX0RJU1RBTkNFID0gMTA7XG5cbi8qKlxuICogQSBjb21wb25lbnQgdGhhdCBtYWtlcyBzdXJlIHRoYXQgZXh0ZXJuYWwgbGFiZWxzIGFyZSBhZGRlZFxuICogdG9nZXRoZXIgd2l0aCByZXNwZWN0aXZlIGVsZW1lbnRzIGFuZCBwcm9wZXJseSB1cGRhdGVkIChESSB3aXNlKVxuICogZHVyaW5nIG1vdmUuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFkYXB0aXZlTGFiZWxQb3NpdGlvbmluZ0JlaGF2aW9yKGV2ZW50QnVzLCBtb2RlbGluZykge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuICB0aGlzLnBvc3RFeGVjdXRlZChbXG4gICAgJ2Nvbm5lY3Rpb24uY3JlYXRlJyxcbiAgICAnY29ubmVjdGlvbi5sYXlvdXQnLFxuICAgICdjb25uZWN0aW9uLnVwZGF0ZVdheXBvaW50cydcbiAgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHNvdXJjZSA9IGNvbm5lY3Rpb24uc291cmNlLFxuICAgICAgICB0YXJnZXQgPSBjb25uZWN0aW9uLnRhcmdldCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gICAgaWYgKGhpbnRzLmNyZWF0ZUVsZW1lbnRzQmVoYXZpb3IgIT09IGZhbHNlKSB7XG4gICAgICBjaGVja0xhYmVsQWRqdXN0bWVudChzb3VyY2UpO1xuICAgICAgY2hlY2tMYWJlbEFkanVzdG1lbnQodGFyZ2V0KTtcbiAgICB9XG4gIH0pO1xuXG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoW1xuICAgICdsYWJlbC5jcmVhdGUnXG4gIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fTtcblxuICAgIGlmIChoaW50cy5jcmVhdGVFbGVtZW50c0JlaGF2aW9yICE9PSBmYWxzZSkge1xuICAgICAgY2hlY2tMYWJlbEFkanVzdG1lbnQoc2hhcGUubGFiZWxUYXJnZXQpO1xuICAgIH1cbiAgfSk7XG5cblxuICB0aGlzLnBvc3RFeGVjdXRlZChbXG4gICAgJ2VsZW1lbnRzLmNyZWF0ZSdcbiAgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnRzID0gY29udGV4dC5lbGVtZW50cyxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gICAgaWYgKGhpbnRzLmNyZWF0ZUVsZW1lbnRzQmVoYXZpb3IgIT09IGZhbHNlKSB7XG4gICAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgY2hlY2tMYWJlbEFkanVzdG1lbnQoZWxlbWVudCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIGNoZWNrTGFiZWxBZGp1c3RtZW50KGVsZW1lbnQpIHtcblxuICAgIC8vIHNraXAgbm9uLWV4aXN0aW5nIGxhYmVsc1xuICAgIGlmICghaGFzRXh0ZXJuYWxMYWJlbChlbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBvcHRpbWFsUG9zaXRpb24gPSBnZXRPcHRpbWFsUG9zaXRpb24oZWxlbWVudCk7XG5cbiAgICAvLyBubyBvcHRpbWFsIHBvc2l0aW9uIGZvdW5kXG4gICAgaWYgKCFvcHRpbWFsUG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhZGp1c3RMYWJlbFBvc2l0aW9uKGVsZW1lbnQsIG9wdGltYWxQb3NpdGlvbik7XG4gIH1cblxuICBmdW5jdGlvbiBhZGp1c3RMYWJlbFBvc2l0aW9uKGVsZW1lbnQsIG9yaWVudGF0aW9uKSB7XG5cbiAgICB2YXIgZWxlbWVudE1pZCA9IGdldE1pZChlbGVtZW50KSxcbiAgICAgICAgbGFiZWwgPSBlbGVtZW50LmxhYmVsLFxuICAgICAgICBsYWJlbE1pZCA9IGdldE1pZChsYWJlbCk7XG5cbiAgICAvLyBpZ25vcmUgbGFiZWxzIHRoYXQgYXJlIGJlaW5nIGNyZWF0ZWRcbiAgICBpZiAoIWxhYmVsLnBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBlbGVtZW50VHJibCA9IGFzVFJCTChlbGVtZW50KTtcblxuICAgIHZhciBuZXdMYWJlbE1pZDtcblxuICAgIHN3aXRjaCAob3JpZW50YXRpb24pIHtcbiAgICBjYXNlICd0b3AnOlxuICAgICAgbmV3TGFiZWxNaWQgPSB7XG4gICAgICAgIHg6IGVsZW1lbnRNaWQueCxcbiAgICAgICAgeTogZWxlbWVudFRyYmwudG9wIC0gRUxFTUVOVF9MQUJFTF9ESVNUQU5DRSAtIGxhYmVsLmhlaWdodCAvIDJcbiAgICAgIH07XG5cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnbGVmdCc6XG5cbiAgICAgIG5ld0xhYmVsTWlkID0ge1xuICAgICAgICB4OiBlbGVtZW50VHJibC5sZWZ0IC0gRUxFTUVOVF9MQUJFTF9ESVNUQU5DRSAtIGxhYmVsLndpZHRoIC8gMixcbiAgICAgICAgeTogZWxlbWVudE1pZC55XG4gICAgICB9O1xuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2JvdHRvbSc6XG5cbiAgICAgIG5ld0xhYmVsTWlkID0ge1xuICAgICAgICB4OiBlbGVtZW50TWlkLngsXG4gICAgICAgIHk6IGVsZW1lbnRUcmJsLmJvdHRvbSArIEVMRU1FTlRfTEFCRUxfRElTVEFOQ0UgKyBsYWJlbC5oZWlnaHQgLyAyXG4gICAgICB9O1xuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3JpZ2h0JzpcblxuICAgICAgbmV3TGFiZWxNaWQgPSB7XG4gICAgICAgIHg6IGVsZW1lbnRUcmJsLnJpZ2h0ICsgRUxFTUVOVF9MQUJFTF9ESVNUQU5DRSArIGxhYmVsLndpZHRoIC8gMixcbiAgICAgICAgeTogZWxlbWVudE1pZC55XG4gICAgICB9O1xuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICB2YXIgZGVsdGEgPSBzdWJzdHJhY3QobmV3TGFiZWxNaWQsIGxhYmVsTWlkKTtcblxuICAgIG1vZGVsaW5nLm1vdmVTaGFwZShsYWJlbCwgZGVsdGEpO1xuICB9XG5cbn1cblxuaW5oZXJpdHMoQWRhcHRpdmVMYWJlbFBvc2l0aW9uaW5nQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cbkFkYXB0aXZlTGFiZWxQb3NpdGlvbmluZ0JlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogUmV0dXJuIGFsaWdubWVudHMgd2hpY2ggYXJlIHRha2VuIGJ5IGEgYm91bmRhcnkncyBob3N0IGVsZW1lbnRcbiAqXG4gKiBAcGFyYW0ge1NoYXBlfSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn1cbiAqL1xuZnVuY3Rpb24gZ2V0VGFrZW5Ib3N0QWxpZ25tZW50cyhlbGVtZW50KSB7XG5cbiAgdmFyIGhvc3RFbGVtZW50ID0gZWxlbWVudC5ob3N0LFxuICAgICAgZWxlbWVudE1pZCA9IGdldE1pZChlbGVtZW50KSxcbiAgICAgIGhvc3RPcmllbnRhdGlvbiA9IGdldE9yaWVudGF0aW9uKGVsZW1lbnRNaWQsIGhvc3RFbGVtZW50KTtcblxuICB2YXIgZnJlZUFsaWdubWVudHM7XG5cbiAgLy8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBhIG11bHRpLW9yaWVudGF0aW9uLCBlLmcuICd0b3AtbGVmdCdcbiAgaWYgKGhvc3RPcmllbnRhdGlvbi5pbmRleE9mKCctJykgPj0gMCkge1xuICAgIGZyZWVBbGlnbm1lbnRzID0gaG9zdE9yaWVudGF0aW9uLnNwbGl0KCctJyk7XG4gIH0gZWxzZSB7XG4gICAgZnJlZUFsaWdubWVudHMgPSBbIGhvc3RPcmllbnRhdGlvbiBdO1xuICB9XG5cbiAgdmFyIHRha2VuQWxpZ25tZW50cyA9IEFMSUdOTUVOVFMuZmlsdGVyKGZ1bmN0aW9uKGFsaWdubWVudCkge1xuXG4gICAgcmV0dXJuIGZyZWVBbGlnbm1lbnRzLmluZGV4T2YoYWxpZ25tZW50KSA9PT0gLTE7XG4gIH0pO1xuXG4gIHJldHVybiB0YWtlbkFsaWdubWVudHM7XG5cbn1cblxuLyoqXG4gKiBSZXR1cm4gYWxpZ25tZW50cyB3aGljaCBhcmUgdGFrZW4gYnkgcmVsYXRlZCBjb25uZWN0aW9uc1xuICpcbiAqIEBwYXJhbSB7U2hhcGV9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxzdHJpbmc+fVxuICovXG5mdW5jdGlvbiBnZXRUYWtlbkNvbm5lY3Rpb25BbGlnbm1lbnRzKGVsZW1lbnQpIHtcblxuICB2YXIgZWxlbWVudE1pZCA9IGdldE1pZChlbGVtZW50KTtcblxuICB2YXIgdGFrZW5BbGlnbm1lbnRzID0gW10uY29uY2F0KFxuICAgIGVsZW1lbnQuaW5jb21pbmcubWFwKGZ1bmN0aW9uKGMpIHtcbiAgICAgIHJldHVybiBjLndheXBvaW50c1tjLndheXBvaW50cy5sZW5ndGggLSAyIF07XG4gICAgfSksXG4gICAgZWxlbWVudC5vdXRnb2luZy5tYXAoZnVuY3Rpb24oYykge1xuICAgICAgcmV0dXJuIGMud2F5cG9pbnRzWzFdO1xuICAgIH0pXG4gICkubWFwKGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgcmV0dXJuIGdldEFwcHJveGltYXRlT3JpZW50YXRpb24oZWxlbWVudE1pZCwgcG9pbnQpO1xuICB9KTtcblxuICByZXR1cm4gdGFrZW5BbGlnbm1lbnRzO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgb3B0aW1hbCBsYWJlbCBwb3NpdGlvbiBhcm91bmQgYW4gZWxlbWVudFxuICogb3IgX3VuZGVmaW5lZF8sIGlmIG5vbmUgd2FzIGZvdW5kLlxuICpcbiAqIEBwYXJhbSAge1NoYXBlfSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7c3RyaW5nfSBwb3NpdGlvbmluZyBpZGVudGlmaWVyXG4gKi9cbmZ1bmN0aW9uIGdldE9wdGltYWxQb3NpdGlvbihlbGVtZW50KSB7XG5cbiAgdmFyIGxhYmVsTWlkID0gZ2V0TWlkKGVsZW1lbnQubGFiZWwpO1xuXG4gIHZhciBlbGVtZW50TWlkID0gZ2V0TWlkKGVsZW1lbnQpO1xuXG4gIHZhciBsYWJlbE9yaWVudGF0aW9uID0gZ2V0QXBwcm94aW1hdGVPcmllbnRhdGlvbihlbGVtZW50TWlkLCBsYWJlbE1pZCk7XG5cbiAgaWYgKCFpc0FsaWduZWQobGFiZWxPcmllbnRhdGlvbikpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgdGFrZW5BbGlnbm1lbnRzID0gZ2V0VGFrZW5Db25uZWN0aW9uQWxpZ25tZW50cyhlbGVtZW50KTtcblxuICBpZiAoZWxlbWVudC5ob3N0KSB7XG4gICAgdmFyIHRha2VuSG9zdEFsaWdubWVudHMgPSBnZXRUYWtlbkhvc3RBbGlnbm1lbnRzKGVsZW1lbnQpO1xuXG4gICAgdGFrZW5BbGlnbm1lbnRzID0gdGFrZW5BbGlnbm1lbnRzLmNvbmNhdCh0YWtlbkhvc3RBbGlnbm1lbnRzKTtcbiAgfVxuXG4gIHZhciBmcmVlQWxpZ25tZW50cyA9IEFMSUdOTUVOVFMuZmlsdGVyKGZ1bmN0aW9uKGFsaWdubWVudCkge1xuXG4gICAgcmV0dXJuIHRha2VuQWxpZ25tZW50cy5pbmRleE9mKGFsaWdubWVudCkgPT09IC0xO1xuICB9KTtcblxuICAvLyBOT1RISU5HIFRPIERPOyBsYWJlbCBhbHJlYWR5IGFsaWduZWQgYS5PLksuXG4gIGlmIChmcmVlQWxpZ25tZW50cy5pbmRleE9mKGxhYmVsT3JpZW50YXRpb24pICE9PSAtMSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiBmcmVlQWxpZ25tZW50c1swXTtcbn1cblxuZnVuY3Rpb24gZ2V0QXBwcm94aW1hdGVPcmllbnRhdGlvbihwMCwgcDEpIHtcbiAgcmV0dXJuIGdldE9yaWVudGF0aW9uKHAxLCBwMCwgNSk7XG59XG5cbmZ1bmN0aW9uIGlzQWxpZ25lZChvcmllbnRhdGlvbikge1xuICByZXR1cm4gQUxJR05NRU5UUy5pbmRleE9mKG9yaWVudGF0aW9uKSAhPT0gLTE7XG59XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwZW5kQmVoYXZpb3IoZXZlbnRCdXMsIGVsZW1lbnRGYWN0b3J5LCBicG1uUnVsZXMpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgLy8gYXNzaWduIGNvcnJlY3Qgc2hhcGUgcG9zaXRpb24gdW5sZXNzIGFscmVhZHkgc2V0XG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5hcHBlbmQnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZTtcblxuICAgIGlmICghY29udGV4dC5wb3NpdGlvbikge1xuXG4gICAgICBpZiAoaXMoc2hhcGUsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcbiAgICAgICAgY29udGV4dC5wb3NpdGlvbiA9IHtcbiAgICAgICAgICB4OiBzb3VyY2UueCArIHNvdXJjZS53aWR0aCAvIDIgKyA3NSxcbiAgICAgICAgICB5OiBzb3VyY2UueSAtICg1MCkgLSBzaGFwZS5oZWlnaHQgLyAyXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZXh0LnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IHNvdXJjZS54ICsgc291cmNlLndpZHRoICsgODAgKyBzaGFwZS53aWR0aCAvIDIsXG4gICAgICAgICAgeTogc291cmNlLnkgKyBzb3VyY2UuaGVpZ2h0IC8gMlxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfSwgdHJ1ZSk7XG59XG5cbmluaGVyaXRzKEFwcGVuZEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5BcHBlbmRCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnYnBtblJ1bGVzJ1xuXTsiLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xyXG5cclxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XHJcblxyXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcclxuXHJcbmltcG9ydCB7XHJcbiAgZmlsdGVyLFxyXG4gIGZvckVhY2hcclxufSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXNzb2NpYXRpb25CZWhhdmlvcihpbmplY3RvciwgbW9kZWxpbmcpIHtcclxuICBpbmplY3Rvci5pbnZva2UoQ29tbWFuZEludGVyY2VwdG9yLCB0aGlzKTtcclxuXHJcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUubW92ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIHZhciBuZXdQYXJlbnQgPSBjb250ZXh0Lm5ld1BhcmVudCxcclxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XHJcblxyXG4gICAgdmFyIGFzc29jaWF0aW9ucyA9IGZpbHRlcihzaGFwZS5pbmNvbWluZy5jb25jYXQoc2hhcGUub3V0Z29pbmcpLCBmdW5jdGlvbihjb25uZWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiBpcyhjb25uZWN0aW9uLCAnYnBtbjpBc3NvY2lhdGlvbicpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgZm9yRWFjaChhc3NvY2lhdGlvbnMsIGZ1bmN0aW9uKGFzc29jaWF0aW9uKSB7XHJcbiAgICAgIG1vZGVsaW5nLm1vdmVDb25uZWN0aW9uKGFzc29jaWF0aW9uLCB7IHg6IDAsIHk6IDAgfSwgbmV3UGFyZW50KTtcclxuICAgIH0pO1xyXG4gIH0sIHRydWUpO1xyXG59XHJcblxyXG5pbmhlcml0cyhBc3NvY2lhdGlvbkJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xyXG5cclxuQXNzb2NpYXRpb25CZWhhdmlvci4kaW5qZWN0ID0gW1xyXG4gICdpbmplY3RvcicsXHJcbiAgJ21vZGVsaW5nJ1xyXG5dOyIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5pbXBvcnQgeyBnZXRCdXNpbmVzc09iamVjdCB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHsgaXNBbnkgfSBmcm9tICcuLi91dGlsL01vZGVsaW5nVXRpbCc7XG5cbmltcG9ydCB7IGlzTGFiZWwgfSBmcm9tICcuLi8uLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cblxuLyoqXG4gKiBSZXBsYWNlIGludGVybWVkaWF0ZSBldmVudCB3aXRoIGJvdW5kYXJ5IGV2ZW50IHdoZW4gY3JlYXRpbmcgb3IgbW92aW5nIHJlc3VsdHMgaW4gYXR0YWNoZWQgZXZlbnQuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEF0dGFjaEV2ZW50QmVoYXZpb3IoYnBtblJlcGxhY2UsIGluamVjdG9yKSB7XG4gIGluamVjdG9yLmludm9rZShDb21tYW5kSW50ZXJjZXB0b3IsIHRoaXMpO1xuXG4gIHRoaXMuX2JwbW5SZXBsYWNlID0gYnBtblJlcGxhY2U7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdlbGVtZW50cy5jcmVhdGUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzO1xuXG4gICAgZWxlbWVudHMgPSBlbGVtZW50cy5maWx0ZXIoZnVuY3Rpb24oc2hhcGUpIHtcbiAgICAgIHZhciBob3N0ID0gc2hhcGUuaG9zdDtcblxuICAgICAgcmV0dXJuIHNob3VsZFJlcGxhY2Uoc2hhcGUsIGhvc3QpO1xuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGVsZW1lbnRzLm1hcChmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KTtcbiAgICB9KS5mb3JFYWNoKGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICB2YXIgaG9zdCA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXG4gICAgICBjb250ZXh0LmVsZW1lbnRzWyBpbmRleCBdID0gc2VsZi5yZXBsYWNlU2hhcGUoZWxlbWVudHNbIGluZGV4IF0sIGhvc3QpO1xuICAgIH0pO1xuICB9LCB0cnVlKTtcblxuXG4gIHRoaXMucHJlRXhlY3V0ZSgnZWxlbWVudHMubW92ZScsIExPV19QUklPUklUWSwgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgaG9zdCA9IGNvbnRleHQubmV3SG9zdDtcblxuICAgIGlmIChzaGFwZXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNoYXBlID0gc2hhcGVzWzBdO1xuXG4gICAgaWYgKHNob3VsZFJlcGxhY2Uoc2hhcGUsIGhvc3QpKSB7XG4gICAgICBjb250ZXh0LnNoYXBlcyA9IFsgc2VsZi5yZXBsYWNlU2hhcGUoc2hhcGUsIGhvc3QpIF07XG4gICAgfVxuICB9LCB0cnVlKTtcbn1cblxuQXR0YWNoRXZlbnRCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnYnBtblJlcGxhY2UnLFxuICAnaW5qZWN0b3InXG5dO1xuXG5pbmhlcml0cyhBdHRhY2hFdmVudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5BdHRhY2hFdmVudEJlaGF2aW9yLnByb3RvdHlwZS5yZXBsYWNlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgaG9zdCkge1xuICB2YXIgZXZlbnREZWZpbml0aW9uID0gZ2V0RXZlbnREZWZpbml0aW9uKHNoYXBlKTtcblxuICB2YXIgYm91bmRhcnlFdmVudCA9IHtcbiAgICB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcbiAgICBob3N0OiBob3N0XG4gIH07XG5cbiAgaWYgKGV2ZW50RGVmaW5pdGlvbikge1xuICAgIGJvdW5kYXJ5RXZlbnQuZXZlbnREZWZpbml0aW9uVHlwZSA9IGV2ZW50RGVmaW5pdGlvbi4kdHlwZTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9icG1uUmVwbGFjZS5yZXBsYWNlRWxlbWVudChzaGFwZSwgYm91bmRhcnlFdmVudCwgeyBsYXlvdXRDb25uZWN0aW9uOiBmYWxzZSB9KTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50KSB7XG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxuICAgICAgZXZlbnREZWZpbml0aW9ucyA9IGJ1c2luZXNzT2JqZWN0LmV2ZW50RGVmaW5pdGlvbnM7XG5cbiAgcmV0dXJuIGV2ZW50RGVmaW5pdGlvbnMgJiYgZXZlbnREZWZpbml0aW9uc1swXTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkUmVwbGFjZShzaGFwZSwgaG9zdCkge1xuICByZXR1cm4gIWlzTGFiZWwoc2hhcGUpICYmXG4gICAgaXNBbnkoc2hhcGUsIFsgJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcsICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnIF0pICYmICEhaG9zdDtcbn1cbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgZmlsdGVyLFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEJQTU4gc3BlY2lmaWMgYm91bmRhcnkgZXZlbnQgYmVoYXZpb3JcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQm91bmRhcnlFdmVudEJlaGF2aW9yKGV2ZW50QnVzLCBtb2RlbGluZykge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuICBmdW5jdGlvbiBnZXRCb3VuZGFyeUV2ZW50cyhlbGVtZW50KSB7XG4gICAgcmV0dXJuIGZpbHRlcihlbGVtZW50LmF0dGFjaGVycywgZnVuY3Rpb24oYXR0YWNoZXIpIHtcbiAgICAgIHJldHVybiBpcyhhdHRhY2hlciwgJ2JwbW46Qm91bmRhcnlFdmVudCcpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gcmVtb3ZlIGFmdGVyIGNvbm5lY3RpbmcgdG8gZXZlbnQtYmFzZWQgZ2F0ZXdheVxuICB0aGlzLnBvc3RFeGVjdXRlKCdjb25uZWN0aW9uLmNyZWF0ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIHNvdXJjZSA9IGV2ZW50LmNvbnRleHQuc291cmNlLFxuICAgICAgICB0YXJnZXQgPSBldmVudC5jb250ZXh0LnRhcmdldCxcbiAgICAgICAgYm91bmRhcnlFdmVudHMgPSBnZXRCb3VuZGFyeUV2ZW50cyh0YXJnZXQpO1xuXG4gICAgaWYgKFxuICAgICAgaXMoc291cmNlLCAnYnBtbjpFdmVudEJhc2VkR2F0ZXdheScpICYmXG4gICAgICBpcyh0YXJnZXQsICdicG1uOlJlY2VpdmVUYXNrJykgJiZcbiAgICAgIGJvdW5kYXJ5RXZlbnRzLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIG1vZGVsaW5nLnJlbW92ZUVsZW1lbnRzKGJvdW5kYXJ5RXZlbnRzKTtcbiAgICB9XG5cbiAgfSk7XG5cbiAgLy8gcmVtb3ZlIGFmdGVyIHJlcGxhY2luZyBjb25uZWN0ZWQgZ2F0ZXdheSB3aXRoIGV2ZW50LWJhc2VkIGdhdGV3YXlcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBvbGRTb3VyY2UgPSBldmVudC5jb250ZXh0Lm9sZFNvdXJjZSxcbiAgICAgICAgbmV3U291cmNlID0gZXZlbnQuY29udGV4dC5uZXdTb3VyY2U7XG5cbiAgICBpZiAoaXMob2xkU291cmNlLCAnYnBtbjpHYXRld2F5JykgJiZcbiAgICAgICAgaXMobmV3U291cmNlLCAnYnBtbjpFdmVudEJhc2VkR2F0ZXdheScpKSB7XG4gICAgICBmb3JFYWNoKG5ld1NvdXJjZS5vdXRnb2luZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgICB2YXIgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgICAgICBhdHRhY2hlZGJvdW5kYXJ5RXZlbnRzID0gZ2V0Qm91bmRhcnlFdmVudHModGFyZ2V0KTtcblxuICAgICAgICBpZiAoaXModGFyZ2V0LCAnYnBtbjpSZWNlaXZlVGFzaycpICYmXG4gICAgICAgICAgICBhdHRhY2hlZGJvdW5kYXJ5RXZlbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBtb2RlbGluZy5yZW1vdmVFbGVtZW50cyhhdHRhY2hlZGJvdW5kYXJ5RXZlbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbn1cblxuQm91bmRhcnlFdmVudEJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cbmluaGVyaXRzKEJvdW5kYXJ5RXZlbnRCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTtcbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgZ2V0UGFyZW50IH0gZnJvbSAnLi4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENyZWF0ZUJlaGF2aW9yKGluamVjdG9yKSB7XG4gIGluamVjdG9yLmludm9rZShDb21tYW5kSW50ZXJjZXB0b3IsIHRoaXMpO1xuXG4gIHRoaXMucHJlRXhlY3V0ZSgnc2hhcGUuY3JlYXRlJywgMTUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMocGFyZW50LCAnYnBtbjpMYW5lJykgJiYgIWlzKHNoYXBlLCAnYnBtbjpMYW5lJykpIHtcbiAgICAgIGNvbnRleHQucGFyZW50ID0gZ2V0UGFyZW50KHBhcmVudCwgJ2JwbW46UGFydGljaXBhbnQnKTtcbiAgICB9XG4gIH0pO1xuXG59XG5cblxuQ3JlYXRlQmVoYXZpb3IuJGluamVjdCA9IFsgJ2luamVjdG9yJyBdO1xuXG5pbmhlcml0cyhDcmVhdGVCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTsiLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cblxuLyoqXG4gKiBCUE1OIHNwZWNpZmljIGNyZWF0ZSBkYXRhIG9iamVjdCBiZWhhdmlvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3IoZXZlbnRCdXMsIGJwbW5GYWN0b3J5LCBtb2RkbGUpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnKSAmJiBzaGFwZS50eXBlICE9PSAnbGFiZWwnKSB7XG5cbiAgICAgIC8vIGNyZWF0ZSBhIERhdGFPYmplY3QgZXZlcnkgdGltZSBhIERhdGFPYmplY3RSZWZlcmVuY2UgaXMgY3JlYXRlZFxuICAgICAgdmFyIGRhdGFPYmplY3QgPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46RGF0YU9iamVjdCcpO1xuXG4gICAgICAvLyBzZXQgdGhlIHJlZmVyZW5jZSB0byB0aGUgRGF0YU9iamVjdFxuICAgICAgc2hhcGUuYnVzaW5lc3NPYmplY3QuZGF0YU9iamVjdFJlZiA9IGRhdGFPYmplY3Q7XG4gICAgfVxuICB9KTtcblxufVxuXG5DcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2JwbW5GYWN0b3J5JyxcbiAgJ21vZGRsZSdcbl07XG5cbmluaGVyaXRzKENyZWF0ZURhdGFPYmplY3RCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTsiLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7IGlzTGFiZWwgfSBmcm9tICcuLi8uLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbmltcG9ydCB7IGdldEJCb3ggfSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaW5kXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgYXNUUkJMIH0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG52YXIgSE9SSVpPTlRBTF9QQVJUSUNJUEFOVF9QQURESU5HID0gMjAsXG4gICAgVkVSVElDQUxfUEFSVElDSVBBTlRfUEFERElORyA9IDIwO1xuXG5leHBvcnQgdmFyIFBBUlRJQ0lQQU5UX0JPUkRFUl9XSURUSCA9IDMwO1xuXG52YXIgSElHSF9QUklPUklUWSA9IDIwMDA7XG5cblxuLyoqXG4gKiBCUE1OLXNwZWNpZmljIGJlaGF2aW9yIGZvciBjcmVhdGluZyBwYXJ0aWNpcGFudHMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IoY2FudmFzLCBldmVudEJ1cywgbW9kZWxpbmcpIHtcbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8vIGZpdCBwYXJ0aWNpcGFudFxuICBldmVudEJ1cy5vbihbXG4gICAgJ2NyZWF0ZS5zdGFydCcsXG4gICAgJ3NoYXBlLm1vdmUuc3RhcnQnXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIHJvb3RFbGVtZW50ID0gY2FudmFzLmdldFJvb3RFbGVtZW50KCk7XG5cbiAgICBpZiAoIWlzKHNoYXBlLCAnYnBtbjpQYXJ0aWNpcGFudCcpIHx8XG4gICAgICAhaXMocm9vdEVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSB8fFxuICAgICAgIXJvb3RFbGVtZW50LmNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGlnbm9yZSBjb25uZWN0aW9ucywgZ3JvdXBzIGFuZCBsYWJlbHNcbiAgICB2YXIgY2hpbGRyZW4gPSByb290RWxlbWVudC5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuICFpcyhlbGVtZW50LCAnYnBtbjpHcm91cCcpICYmXG4gICAgICAgICFpc0xhYmVsKGVsZW1lbnQpICYmXG4gICAgICAgICFpc0Nvbm5lY3Rpb24oZWxlbWVudCk7XG4gICAgfSk7XG5cbiAgICAvLyBlbnN1cmUgZm9yIGF2YWlsYWJsZSBjaGlsZHJlbiB0byBjYWxjdWxhdGUgYm91bmRzXG4gICAgaWYgKCFjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY2hpbGRyZW5CQm94ID0gZ2V0QkJveChjaGlsZHJlbik7XG5cbiAgICB2YXIgcGFydGljaXBhbnRCb3VuZHMgPSBnZXRQYXJ0aWNpcGFudEJvdW5kcyhzaGFwZSwgY2hpbGRyZW5CQm94KTtcblxuICAgIC8vIGFzc2lnbiB3aWR0aCBhbmQgaGVpZ2h0XG4gICAgYXNzaWduKHNoYXBlLCBwYXJ0aWNpcGFudEJvdW5kcyk7XG5cbiAgICAvLyBhc3NpZ24gY3JlYXRlIGNvbnN0cmFpbnRzXG4gICAgY29udGV4dC5jcmVhdGVDb25zdHJhaW50cyA9IGdldFBhcnRpY2lwYW50Q3JlYXRlQ29uc3RyYWludHMoc2hhcGUsIGNoaWxkcmVuQkJveCk7XG4gIH0pO1xuXG4gIC8vIGZvcmNlIGhvdmVyaW5nIHByb2Nlc3Mgd2hlbiBjcmVhdGluZyBmaXJzdCBwYXJ0aWNpcGFudFxuICBldmVudEJ1cy5vbignY3JlYXRlLnN0YXJ0JywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgICAgcm9vdEVsZW1lbnRHZnggPSBjYW52YXMuZ2V0R3JhcGhpY3Mocm9vdEVsZW1lbnQpO1xuXG4gICAgZnVuY3Rpb24gZW5zdXJlSG92ZXJpbmdQcm9jZXNzKGV2ZW50KSB7XG4gICAgICBldmVudC5lbGVtZW50ID0gcm9vdEVsZW1lbnQ7XG4gICAgICBldmVudC5nZnggPSByb290RWxlbWVudEdmeDtcbiAgICB9XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykgJiYgaXMocm9vdEVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSkge1xuICAgICAgZXZlbnRCdXMub24oJ2VsZW1lbnQuaG92ZXInLCBISUdIX1BSSU9SSVRZLCBlbnN1cmVIb3ZlcmluZ1Byb2Nlc3MpO1xuXG4gICAgICBldmVudEJ1cy5vbmNlKCdjcmVhdGUuY2xlYW51cCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICBldmVudEJ1cy5vZmYoJ2VsZW1lbnQuaG92ZXInLCBlbnN1cmVIb3ZlcmluZ1Byb2Nlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICBmdW5jdGlvbiBlbnN1cmVDb2xsYWJvcmF0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICAgIGNvbGxhYm9yYXRpb247XG5cbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKTtcblxuICAgIGlmIChpcyhyb290RWxlbWVudCwgJ2JwbW46Q29sbGFib3JhdGlvbicpKSB7XG4gICAgICBjb2xsYWJvcmF0aW9uID0gcm9vdEVsZW1lbnQ7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gdXBkYXRlIHJvb3QgZWxlbWVudCBieSBtYWtpbmcgY29sbGFib3JhdGlvblxuICAgICAgY29sbGFib3JhdGlvbiA9IG1vZGVsaW5nLm1ha2VDb2xsYWJvcmF0aW9uKCk7XG5cbiAgICAgIC8vIHJlLXVzZSBwcm9jZXNzIHdoZW4gY3JlYXRpbmcgZmlyc3QgcGFydGljaXBhbnRcbiAgICAgIGNvbnRleHQucHJvY2VzcyA9IHBhcmVudDtcbiAgICB9XG5cbiAgICBjb250ZXh0LnBhcmVudCA9IGNvbGxhYm9yYXRpb247XG4gIH1cblxuICAvLyB0dXJuIHByb2Nlc3MgaW50byBjb2xsYWJvcmF0aW9uIGJlZm9yZSBhZGRpbmcgcGFydGljaXBhbnRcbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykgJiYgaXMocGFyZW50LCAnYnBtbjpQcm9jZXNzJykpIHtcbiAgICAgIGVuc3VyZUNvbGxhYm9yYXRpb24oY29udGV4dCk7XG4gICAgfVxuICB9LCB0cnVlKTtcblxuICB0aGlzLmV4ZWN1dGUoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcHJvY2VzcyA9IGNvbnRleHQucHJvY2VzcyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcbiAgICAgIGNvbnRleHQub2xkUHJvY2Vzc1JlZiA9IHNoYXBlLmJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWY7XG5cbiAgICAgIC8vIHJlLXVzZSBwcm9jZXNzIHdoZW4gY3JlYXRpbmcgZmlyc3QgcGFydGljaXBhbnRcbiAgICAgIHNoYXBlLmJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWYgPSBwcm9jZXNzLmJ1c2luZXNzT2JqZWN0O1xuICAgIH1cbiAgfSwgdHJ1ZSk7XG5cbiAgdGhpcy5yZXZlcnQoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcHJvY2VzcyA9IGNvbnRleHQucHJvY2VzcyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcblxuICAgICAgLy8gcmUtdXNlIHByb2Nlc3Mgd2hlbiBjcmVhdGluZyBmaXJzdCBwYXJ0aWNpcGFudFxuICAgICAgc2hhcGUuYnVzaW5lc3NPYmplY3QucHJvY2Vzc1JlZiA9IGNvbnRleHQub2xkUHJvY2Vzc1JlZjtcbiAgICB9XG4gIH0sIHRydWUpO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcHJvY2VzcyA9IGNvbnRleHQucHJvY2VzcyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcblxuICAgICAgLy8gbW92ZSBjaGlsZHJlbiBmcm9tIHByb2Nlc3MgdG8gcGFydGljaXBhbnRcbiAgICAgIHZhciBwcm9jZXNzQ2hpbGRyZW4gPSBwcm9jZXNzLmNoaWxkcmVuLnNsaWNlKCk7XG5cbiAgICAgIG1vZGVsaW5nLm1vdmVFbGVtZW50cyhwcm9jZXNzQ2hpbGRyZW4sIHsgeDogMCwgeTogMCB9LCBzaGFwZSk7XG4gICAgfVxuXG4gIH0sIHRydWUpO1xuXG4gIC8vIHR1cm4gcHJvY2VzcyBpbnRvIGNvbGxhYm9yYXRpb24gd2hlbiBjcmVhdGluZyBwYXJ0aWNpcGFudHNcbiAgdGhpcy5wcmVFeGVjdXRlKCdlbGVtZW50cy5jcmVhdGUnLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIGVsZW1lbnRzID0gY29udGV4dC5lbGVtZW50cyxcbiAgICAgICAgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICAgIHBhcnRpY2lwYW50O1xuXG4gICAgdmFyIGhhc1BhcnRpY2lwYW50cyA9IGZpbmRQYXJ0aWNpcGFudChlbGVtZW50cyk7XG5cbiAgICBpZiAoaGFzUGFydGljaXBhbnRzICYmIGlzKHBhcmVudCwgJ2JwbW46UHJvY2VzcycpKSB7XG4gICAgICBlbnN1cmVDb2xsYWJvcmF0aW9uKGNvbnRleHQpO1xuXG4gICAgICBwYXJ0aWNpcGFudCA9IGZpbmRQYXJ0aWNpcGFudChlbGVtZW50cyk7XG5cbiAgICAgIGNvbnRleHQub2xkUHJvY2Vzc1JlZiA9IHBhcnRpY2lwYW50LmJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWY7XG5cbiAgICAgIC8vIHJlLXVzZSBwcm9jZXNzIHdoZW4gY3JlYXRpbmcgZmlyc3QgcGFydGljaXBhbnRcbiAgICAgIHBhcnRpY2lwYW50LmJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWYgPSBwYXJlbnQuYnVzaW5lc3NPYmplY3Q7XG4gICAgfVxuICB9LCB0cnVlKTtcblxuICB0aGlzLnJldmVydCgnZWxlbWVudHMuY3JlYXRlJywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXG4gICAgICAgIHByb2Nlc3MgPSBjb250ZXh0LnByb2Nlc3MsXG4gICAgICAgIHBhcnRpY2lwYW50O1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcbiAgICAgIHBhcnRpY2lwYW50ID0gZmluZFBhcnRpY2lwYW50KGVsZW1lbnRzKTtcblxuICAgICAgLy8gcmUtdXNlIHByb2Nlc3Mgd2hlbiBjcmVhdGluZyBmaXJzdCBwYXJ0aWNpcGFudFxuICAgICAgcGFydGljaXBhbnQuYnVzaW5lc3NPYmplY3QucHJvY2Vzc1JlZiA9IGNvbnRleHQub2xkUHJvY2Vzc1JlZjtcbiAgICB9XG4gIH0sIHRydWUpO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ2VsZW1lbnRzLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzLFxuICAgICAgICBwcm9jZXNzID0gY29udGV4dC5wcm9jZXNzLFxuICAgICAgICBwYXJ0aWNpcGFudDtcblxuICAgIGlmIChwcm9jZXNzKSB7XG4gICAgICBwYXJ0aWNpcGFudCA9IGZpbmRQYXJ0aWNpcGFudChlbGVtZW50cyk7XG5cbiAgICAgIC8vIG1vdmUgY2hpbGRyZW4gZnJvbSBwcm9jZXNzIHRvIGZpcnN0IHBhcnRpY2lwYW50XG4gICAgICB2YXIgcHJvY2Vzc0NoaWxkcmVuID0gcHJvY2Vzcy5jaGlsZHJlbi5zbGljZSgpO1xuXG4gICAgICBtb2RlbGluZy5tb3ZlRWxlbWVudHMocHJvY2Vzc0NoaWxkcmVuLCB7IHg6IDAsIHk6IDAgfSwgcGFydGljaXBhbnQpO1xuICAgIH1cblxuICB9LCB0cnVlKTtcblxufVxuXG5DcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdjYW52YXMnLFxuICAnZXZlbnRCdXMnLFxuICAnbW9kZWxpbmcnXG5dO1xuXG5pbmhlcml0cyhDcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZ2V0UGFydGljaXBhbnRCb3VuZHMoc2hhcGUsIGNoaWxkcmVuQkJveCkge1xuICBjaGlsZHJlbkJCb3ggPSB7XG4gICAgd2lkdGg6IGNoaWxkcmVuQkJveC53aWR0aCArIEhPUklaT05UQUxfUEFSVElDSVBBTlRfUEFERElORyAqIDIgKyBQQVJUSUNJUEFOVF9CT1JERVJfV0lEVEgsXG4gICAgaGVpZ2h0OiBjaGlsZHJlbkJCb3guaGVpZ2h0ICsgVkVSVElDQUxfUEFSVElDSVBBTlRfUEFERElORyAqIDJcbiAgfTtcblxuICB2YXIgd2lkdGggPSBNYXRoLm1heChzaGFwZS53aWR0aCwgY2hpbGRyZW5CQm94LndpZHRoKSxcbiAgICAgIGhlaWdodCA9IE1hdGgubWF4KHNoYXBlLmhlaWdodCwgY2hpbGRyZW5CQm94LmhlaWdodCk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiAtd2lkdGggLyAyLFxuICAgIHk6IC1oZWlnaHQgLyAyLFxuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRQYXJ0aWNpcGFudENyZWF0ZUNvbnN0cmFpbnRzKHNoYXBlLCBjaGlsZHJlbkJCb3gpIHtcbiAgY2hpbGRyZW5CQm94ID0gYXNUUkJMKGNoaWxkcmVuQkJveCk7XG5cbiAgcmV0dXJuIHtcbiAgICBib3R0b206IGNoaWxkcmVuQkJveC50b3AgKyBzaGFwZS5oZWlnaHQgLyAyIC0gVkVSVElDQUxfUEFSVElDSVBBTlRfUEFERElORyxcbiAgICBsZWZ0OiBjaGlsZHJlbkJCb3gucmlnaHQgLSBzaGFwZS53aWR0aCAvIDIgKyBIT1JJWk9OVEFMX1BBUlRJQ0lQQU5UX1BBRERJTkcsXG4gICAgdG9wOiBjaGlsZHJlbkJCb3guYm90dG9tIC0gc2hhcGUuaGVpZ2h0IC8gMiArIFZFUlRJQ0FMX1BBUlRJQ0lQQU5UX1BBRERJTkcsXG4gICAgcmlnaHQ6IGNoaWxkcmVuQkJveC5sZWZ0ICsgc2hhcGUud2lkdGggLyAyIC0gSE9SSVpPTlRBTF9QQVJUSUNJUEFOVF9QQURESU5HIC0gUEFSVElDSVBBTlRfQk9SREVSX1dJRFRIXG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzQ29ubmVjdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiAhIWVsZW1lbnQud2F5cG9pbnRzO1xufVxuXG5mdW5jdGlvbiBmaW5kUGFydGljaXBhbnQoZWxlbWVudHMpIHtcbiAgcmV0dXJuIGZpbmQoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKTtcbiAgfSk7XG59IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGFkZCBhcyBjb2xsZWN0aW9uQWRkLFxuICByZW1vdmUgYXMgY29sbGVjdGlvblJlbW92ZVxufSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zJztcblxuaW1wb3J0IHtcbiAgZmluZFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGlzXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxudmFyIFRBUkdFVF9SRUZfUExBQ0VIT0xERVJfTkFNRSA9ICdfX3RhcmdldFJlZl9wbGFjZWhvbGRlcic7XG5cblxuLyoqXG4gKiBUaGlzIGJlaGF2aW9yIG1ha2VzIHN1cmUgd2UgYWx3YXlzIHNldCBhIGZha2VcbiAqIERhdGFJbnB1dEFzc29jaWF0aW9uI3RhcmdldFJlZiBhcyBkZW1hbmRlZCBieSB0aGUgQlBNTiAyLjBcbiAqIFhTRCBzY2hlbWEuXG4gKlxuICogVGhlIHJlZmVyZW5jZSBpcyBzZXQgdG8gYSBicG1uOlByb3BlcnR5eyBuYW1lOiAnX190YXJnZXRSZWZfcGxhY2Vob2xkZXInIH1cbiAqIHdoaWNoIGlzIGNyZWF0ZWQgb24gdGhlIGZseSBhbmQgY2xlYW5lZCB1cCBhZnRlcndhcmRzIGlmIG5vdCBuZWVkZWRcbiAqIGFueW1vcmUuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERhdGFJbnB1dEFzc29jaWF0aW9uQmVoYXZpb3IoZXZlbnRCdXMsIGJwbW5GYWN0b3J5KSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG5cbiAgdGhpcy5leGVjdXRlZChbXG4gICAgJ2Nvbm5lY3Rpb24uY3JlYXRlJyxcbiAgICAnY29ubmVjdGlvbi5kZWxldGUnLFxuICAgICdjb25uZWN0aW9uLm1vdmUnLFxuICAgICdjb25uZWN0aW9uLnJlY29ubmVjdCdcbiAgXSwgaWZEYXRhSW5wdXRBc3NvY2lhdGlvbihmaXhUYXJnZXRSZWYpKTtcblxuICB0aGlzLnJldmVydGVkKFtcbiAgICAnY29ubmVjdGlvbi5jcmVhdGUnLFxuICAgICdjb25uZWN0aW9uLmRlbGV0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubW92ZScsXG4gICAgJ2Nvbm5lY3Rpb24ucmVjb25uZWN0J1xuICBdLCBpZkRhdGFJbnB1dEFzc29jaWF0aW9uKGZpeFRhcmdldFJlZikpO1xuXG5cbiAgZnVuY3Rpb24gdXNlc1RhcmdldFJlZihlbGVtZW50LCB0YXJnZXRSZWYsIHJlbW92ZWRDb25uZWN0aW9uKSB7XG5cbiAgICB2YXIgaW5wdXRBc3NvY2lhdGlvbnMgPSBlbGVtZW50LmdldCgnZGF0YUlucHV0QXNzb2NpYXRpb25zJyk7XG5cbiAgICByZXR1cm4gZmluZChpbnB1dEFzc29jaWF0aW9ucywgZnVuY3Rpb24oYXNzb2NpYXRpb24pIHtcbiAgICAgIHJldHVybiBhc3NvY2lhdGlvbiAhPT0gcmVtb3ZlZENvbm5lY3Rpb24gJiZcbiAgICAgICAgICAgICBhc3NvY2lhdGlvbi50YXJnZXRSZWYgPT09IHRhcmdldFJlZjtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFRhcmdldFJlZihlbGVtZW50LCBjcmVhdGUpIHtcblxuICAgIHZhciBwcm9wZXJ0aWVzID0gZWxlbWVudC5nZXQoJ3Byb3BlcnRpZXMnKTtcblxuICAgIHZhciB0YXJnZXRSZWZQcm9wID0gZmluZChwcm9wZXJ0aWVzLCBmdW5jdGlvbihwKSB7XG4gICAgICByZXR1cm4gcC5uYW1lID09PSBUQVJHRVRfUkVGX1BMQUNFSE9MREVSX05BTUU7XG4gICAgfSk7XG5cbiAgICBpZiAoIXRhcmdldFJlZlByb3AgJiYgY3JlYXRlKSB7XG4gICAgICB0YXJnZXRSZWZQcm9wID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOlByb3BlcnR5Jywge1xuICAgICAgICBuYW1lOiBUQVJHRVRfUkVGX1BMQUNFSE9MREVSX05BTUVcbiAgICAgIH0pO1xuXG4gICAgICBjb2xsZWN0aW9uQWRkKHByb3BlcnRpZXMsIHRhcmdldFJlZlByb3ApO1xuICAgIH1cblxuICAgIHJldHVybiB0YXJnZXRSZWZQcm9wO1xuICB9XG5cbiAgZnVuY3Rpb24gY2xlYW51cFRhcmdldFJlZihlbGVtZW50LCBjb25uZWN0aW9uKSB7XG5cbiAgICB2YXIgdGFyZ2V0UmVmUHJvcCA9IGdldFRhcmdldFJlZihlbGVtZW50KTtcblxuICAgIGlmICghdGFyZ2V0UmVmUHJvcCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdXNlc1RhcmdldFJlZihlbGVtZW50LCB0YXJnZXRSZWZQcm9wLCBjb25uZWN0aW9uKSkge1xuICAgICAgY29sbGVjdGlvblJlbW92ZShlbGVtZW50LmdldCgncHJvcGVydGllcycpLCB0YXJnZXRSZWZQcm9wKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBzdXJlIHRhcmdldFJlZiBpcyBzZXQgdG8gYSB2YWxpZCBwcm9wZXJ0eSBvclxuICAgKiBgbnVsbGAgaWYgdGhlIGNvbm5lY3Rpb24gaXMgZGV0YWNoZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50XG4gICAqL1xuICBmdW5jdGlvbiBmaXhUYXJnZXRSZWYoZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgY29ubmVjdGlvbkJvID0gY29ubmVjdGlvbi5idXNpbmVzc09iamVjdCxcbiAgICAgICAgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIHRhcmdldEJvID0gdGFyZ2V0ICYmIHRhcmdldC5idXNpbmVzc09iamVjdCxcbiAgICAgICAgbmV3VGFyZ2V0ID0gY29udGV4dC5uZXdUYXJnZXQsXG4gICAgICAgIG5ld1RhcmdldEJvID0gbmV3VGFyZ2V0ICYmIG5ld1RhcmdldC5idXNpbmVzc09iamVjdCxcbiAgICAgICAgb2xkVGFyZ2V0ID0gY29udGV4dC5vbGRUYXJnZXQgfHwgY29udGV4dC50YXJnZXQsXG4gICAgICAgIG9sZFRhcmdldEJvID0gb2xkVGFyZ2V0ICYmIG9sZFRhcmdldC5idXNpbmVzc09iamVjdDtcblxuICAgIHZhciBkYXRhQXNzb2NpYXRpb24gPSBjb25uZWN0aW9uLmJ1c2luZXNzT2JqZWN0LFxuICAgICAgICB0YXJnZXRSZWZQcm9wO1xuXG4gICAgaWYgKG9sZFRhcmdldEJvICYmIG9sZFRhcmdldEJvICE9PSB0YXJnZXRCbykge1xuICAgICAgY2xlYW51cFRhcmdldFJlZihvbGRUYXJnZXRCbywgY29ubmVjdGlvbkJvKTtcbiAgICB9XG5cbiAgICBpZiAobmV3VGFyZ2V0Qm8gJiYgbmV3VGFyZ2V0Qm8gIT09IHRhcmdldEJvKSB7XG4gICAgICBjbGVhbnVwVGFyZ2V0UmVmKG5ld1RhcmdldEJvLCBjb25uZWN0aW9uQm8pO1xuICAgIH1cblxuICAgIGlmICh0YXJnZXRCbykge1xuICAgICAgdGFyZ2V0UmVmUHJvcCA9IGdldFRhcmdldFJlZih0YXJnZXRCbywgdHJ1ZSk7XG4gICAgICBkYXRhQXNzb2NpYXRpb24udGFyZ2V0UmVmID0gdGFyZ2V0UmVmUHJvcDtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YUFzc29jaWF0aW9uLnRhcmdldFJlZiA9IG51bGw7XG4gICAgfVxuICB9XG59XG5cbkRhdGFJbnB1dEFzc29jaWF0aW9uQmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2JwbW5GYWN0b3J5J1xuXTtcblxuaW5oZXJpdHMoRGF0YUlucHV0QXNzb2NpYXRpb25CZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuXG4vKipcbiAqIE9ubHkgY2FsbCB0aGUgZ2l2ZW4gZnVuY3Rpb24gd2hlbiB0aGUgZXZlbnRcbiAqIHRvdWNoZXMgYSBicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gaWZEYXRhSW5wdXRBc3NvY2lhdGlvbihmbikge1xuXG4gIHJldHVybiBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbjtcblxuICAgIGlmIChpcyhjb25uZWN0aW9uLCAnYnBtbjpEYXRhSW5wdXRBc3NvY2lhdGlvbicpKSB7XG4gICAgICByZXR1cm4gZm4oZXZlbnQpO1xuICAgIH1cbiAgfTtcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xyXG5cclxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XHJcblxyXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcclxuXHJcbmltcG9ydCB7IGlzQW55IH0gZnJvbSAnLi4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xyXG5cclxuaW1wb3J0IFVwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlciBmcm9tICcuLi9jbWQvVXBkYXRlU2VtYW50aWNQYXJlbnRIYW5kbGVyJztcclxuXHJcblxyXG4vKipcclxuICogQlBNTiBzcGVjaWZpYyBkYXRhIHN0b3JlIGJlaGF2aW9yXHJcbiAqL1xyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEYXRhU3RvcmVCZWhhdmlvcihcclxuICAgIGNhbnZhcywgY29tbWFuZFN0YWNrLCBlbGVtZW50UmVnaXN0cnksXHJcbiAgICBldmVudEJ1cykge1xyXG5cclxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XHJcblxyXG4gIGNvbW1hbmRTdGFjay5yZWdpc3RlckhhbmRsZXIoJ2RhdGFTdG9yZS51cGRhdGVDb250YWlubWVudCcsIFVwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlcik7XHJcblxyXG4gIGZ1bmN0aW9uIGdldEZpcnN0UGFydGljaXBhbnQoKSB7XHJcbiAgICByZXR1cm4gZWxlbWVudFJlZ2lzdHJ5LmZpbHRlcihmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpO1xyXG4gICAgfSlbMF07XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBnZXREYXRhU3RvcmVzKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBlbGVtZW50LmNoaWxkcmVuLmZpbHRlcihmdW5jdGlvbihjaGlsZCkge1xyXG4gICAgICByZXR1cm4gaXMoY2hpbGQsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpICYmICFjaGlsZC5sYWJlbFRhcmdldDtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlRGF0YVN0b3JlUGFyZW50KGRhdGFTdG9yZSwgbmV3RGF0YVN0b3JlUGFyZW50KSB7XHJcbiAgICB2YXIgZGF0YVN0b3JlQm8gPSBkYXRhU3RvcmUuYnVzaW5lc3NPYmplY3QgfHwgZGF0YVN0b3JlO1xyXG5cclxuICAgIG5ld0RhdGFTdG9yZVBhcmVudCA9IG5ld0RhdGFTdG9yZVBhcmVudCB8fCBnZXRGaXJzdFBhcnRpY2lwYW50KCk7XHJcblxyXG4gICAgaWYgKG5ld0RhdGFTdG9yZVBhcmVudCkge1xyXG4gICAgICB2YXIgbmV3RGF0YVN0b3JlUGFyZW50Qm8gPSBuZXdEYXRhU3RvcmVQYXJlbnQuYnVzaW5lc3NPYmplY3QgfHwgbmV3RGF0YVN0b3JlUGFyZW50O1xyXG5cclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2RhdGFTdG9yZS51cGRhdGVDb250YWlubWVudCcsIHtcclxuICAgICAgICBkYXRhU3RvcmVCbzogZGF0YVN0b3JlQm8sXHJcbiAgICAgICAgbmV3U2VtYW50aWNQYXJlbnQ6IG5ld0RhdGFTdG9yZVBhcmVudEJvLnByb2Nlc3NSZWYgfHwgbmV3RGF0YVN0b3JlUGFyZW50Qm8sXHJcbiAgICAgICAgbmV3RGlQYXJlbnQ6IG5ld0RhdGFTdG9yZVBhcmVudEJvLmRpXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIC8vIGRpc2FibGUgYXV0by1yZXNpemUgZm9yIGRhdGEgc3RvcmVzXHJcbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xyXG5cclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XHJcblxyXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSAmJlxyXG4gICAgICAgIHNoYXBlLnR5cGUgIT09ICdsYWJlbCcpIHtcclxuXHJcbiAgICAgIGlmICghY29udGV4dC5oaW50cykge1xyXG4gICAgICAgIGNvbnRleHQuaGludHMgPSB7fTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gcHJldmVudCBhdXRvIHJlc2l6aW5nXHJcbiAgICAgIGNvbnRleHQuaGludHMuYXV0b1Jlc2l6ZSA9IGZhbHNlO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgLy8gZGlzYWJsZSBhdXRvLXJlc2l6ZSBmb3IgZGF0YSBzdG9yZXNcclxuICB0aGlzLnByZUV4ZWN1dGUoJ2VsZW1lbnRzLm1vdmUnLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzO1xyXG5cclxuICAgIHZhciBkYXRhU3RvcmVSZWZlcmVuY2VzID0gc2hhcGVzLmZpbHRlcihmdW5jdGlvbihzaGFwZSkge1xyXG4gICAgICByZXR1cm4gaXMoc2hhcGUsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKGRhdGFTdG9yZVJlZmVyZW5jZXMubGVuZ3RoKSB7XHJcbiAgICAgIGlmICghY29udGV4dC5oaW50cykge1xyXG4gICAgICAgIGNvbnRleHQuaGludHMgPSB7fTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gcHJldmVudCBhdXRvIHJlc2l6aW5nIGZvciBkYXRhIHN0b3JlIHJlZmVyZW5jZXNcclxuICAgICAgY29udGV4dC5oaW50cy5hdXRvUmVzaXplID0gc2hhcGVzLmZpbHRlcihmdW5jdGlvbihzaGFwZSkge1xyXG4gICAgICAgIHJldHVybiAhaXMoc2hhcGUsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9KTtcclxuXHJcblxyXG4gIC8vIHVwZGF0ZSBwYXJlbnQgb24gZGF0YSBzdG9yZSBjcmVhdGVkXHJcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUuY3JlYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXHJcbiAgICAgICAgcGFyZW50ID0gc2hhcGUucGFyZW50O1xyXG5cclxuXHJcbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpICYmXHJcbiAgICAgICAgc2hhcGUudHlwZSAhPT0gJ2xhYmVsJyAmJlxyXG4gICAgICAgIGlzKHBhcmVudCwgJ2JwbW46Q29sbGFib3JhdGlvbicpKSB7XHJcblxyXG4gICAgICB1cGRhdGVEYXRhU3RvcmVQYXJlbnQoc2hhcGUpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgLy8gdXBkYXRlIHBhcmVudCBvbiBkYXRhIHN0b3JlIG1vdmVkXHJcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxyXG4gICAgICAgIG9sZFBhcmVudCA9IGNvbnRleHQub2xkUGFyZW50LFxyXG4gICAgICAgIHBhcmVudCA9IHNoYXBlLnBhcmVudDtcclxuXHJcbiAgICBpZiAoaXMob2xkUGFyZW50LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykpIHtcclxuXHJcbiAgICAgIC8vIGRvIG5vdGhpbmcgaWYgbm90IG5lY2Vzc2FyeVxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSAmJlxyXG4gICAgICAgIHNoYXBlLnR5cGUgIT09ICdsYWJlbCcgJiZcclxuICAgICAgICBpcyhwYXJlbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKSkge1xyXG5cclxuICAgICAgdmFyIHBhcnRpY2lwYW50ID0gaXMob2xkUGFyZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpID9cclxuICAgICAgICBvbGRQYXJlbnQgOlxyXG4gICAgICAgIGdldEFuY2VzdG9yKG9sZFBhcmVudCwgJ2JwbW46UGFydGljaXBhbnQnKTtcclxuXHJcbiAgICAgIHVwZGF0ZURhdGFTdG9yZVBhcmVudChzaGFwZSwgcGFydGljaXBhbnQpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgLy8gdXBkYXRlIGRhdGEgc3RvcmUgcGFyZW50cyBvbiBwYXJ0aWNpcGFudCBvciBzdWJwcm9jZXNzIGRlbGV0ZWRcclxuICB0aGlzLnBvc3RFeGVjdXRlKCdzaGFwZS5kZWxldGUnLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcclxuICAgICAgICByb290RWxlbWVudCA9IGNhbnZhcy5nZXRSb290RWxlbWVudCgpO1xyXG5cclxuICAgIGlmIChpc0FueShzaGFwZSwgWyAnYnBtbjpQYXJ0aWNpcGFudCcsICdicG1uOlN1YlByb2Nlc3MnIF0pXHJcbiAgICAgICAgJiYgaXMocm9vdEVsZW1lbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKSkge1xyXG4gICAgICBnZXREYXRhU3RvcmVzKHJvb3RFbGVtZW50KVxyXG4gICAgICAgIC5maWx0ZXIoZnVuY3Rpb24oZGF0YVN0b3JlKSB7XHJcbiAgICAgICAgICByZXR1cm4gaXNEZXNjZW5kYW50KGRhdGFTdG9yZSwgc2hhcGUpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmZvckVhY2goZnVuY3Rpb24oZGF0YVN0b3JlKSB7XHJcbiAgICAgICAgICB1cGRhdGVEYXRhU3RvcmVQYXJlbnQoZGF0YVN0b3JlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gdXBkYXRlIGRhdGEgc3RvcmUgcGFyZW50cyBvbiBjb2xsYWJvcmF0aW9uIC0+IHByb2Nlc3NcclxuICB0aGlzLnBvc3RFeGVjdXRlKCdjYW52YXMudXBkYXRlUm9vdCcsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgb2xkUm9vdCA9IGNvbnRleHQub2xkUm9vdCxcclxuICAgICAgICBuZXdSb290ID0gY29udGV4dC5uZXdSb290O1xyXG5cclxuICAgIHZhciBkYXRhU3RvcmVzID0gZ2V0RGF0YVN0b3JlcyhvbGRSb290KTtcclxuXHJcbiAgICBkYXRhU3RvcmVzLmZvckVhY2goZnVuY3Rpb24oZGF0YVN0b3JlKSB7XHJcblxyXG4gICAgICBpZiAoaXMobmV3Um9vdCwgJ2JwbW46UHJvY2VzcycpKSB7XHJcbiAgICAgICAgdXBkYXRlRGF0YVN0b3JlUGFyZW50KGRhdGFTdG9yZSwgbmV3Um9vdCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICB9KTtcclxuICB9KTtcclxufVxyXG5cclxuRGF0YVN0b3JlQmVoYXZpb3IuJGluamVjdCA9IFtcclxuICAnY2FudmFzJyxcclxuICAnY29tbWFuZFN0YWNrJyxcclxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcclxuICAnZXZlbnRCdXMnLFxyXG5dO1xyXG5cclxuaW5oZXJpdHMoRGF0YVN0b3JlQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XHJcblxyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBpc0Rlc2NlbmRhbnQoZGVzY2VuZGFudCwgYW5jZXN0b3IpIHtcclxuICB2YXIgZGVzY2VuZGFudEJvID0gZGVzY2VuZGFudC5idXNpbmVzc09iamVjdCB8fCBkZXNjZW5kYW50LFxyXG4gICAgICBhbmNlc3RvckJvID0gYW5jZXN0b3IuYnVzaW5lc3NPYmplY3QgfHwgYW5jZXN0b3I7XHJcblxyXG4gIHdoaWxlIChkZXNjZW5kYW50Qm8uJHBhcmVudCkge1xyXG4gICAgaWYgKGRlc2NlbmRhbnRCby4kcGFyZW50ID09PSBhbmNlc3RvckJvLnByb2Nlc3NSZWYgfHwgYW5jZXN0b3JCbykge1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBkZXNjZW5kYW50Qm8gPSBkZXNjZW5kYW50Qm8uJHBhcmVudDtcclxuICB9XHJcblxyXG4gIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0QW5jZXN0b3IoZWxlbWVudCwgdHlwZSkge1xyXG5cclxuICB3aGlsZSAoZWxlbWVudC5wYXJlbnQpIHtcclxuICAgIGlmIChpcyhlbGVtZW50LnBhcmVudCwgdHlwZSkpIHtcclxuICAgICAgcmV0dXJuIGVsZW1lbnQucGFyZW50O1xyXG4gICAgfVxyXG5cclxuICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudDtcclxuICB9XHJcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldENoaWxkTGFuZXNcbn0gZnJvbSAnLi4vdXRpbC9MYW5lVXRpbCc7XG5cbmltcG9ydCB7XG4gIGVhY2hFbGVtZW50XG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvRWxlbWVudHMnO1xuXG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cblxuLyoqXG4gKiBCUE1OIHNwZWNpZmljIGRlbGV0ZSBsYW5lIGJlaGF2aW9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERlbGV0ZUxhbmVCZWhhdmlvcihldmVudEJ1cywgbW9kZWxpbmcsIHNwYWNlVG9vbCkge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuXG4gIGZ1bmN0aW9uIGNvbXBlbnNhdGVMYW5lRGVsZXRlKHNoYXBlLCBvbGRQYXJlbnQpIHtcblxuICAgIHZhciBzaWJsaW5ncyA9IGdldENoaWxkTGFuZXMob2xkUGFyZW50KTtcblxuICAgIHZhciB0b3BBZmZlY3RlZCA9IFtdO1xuICAgIHZhciBib3R0b21BZmZlY3RlZCA9IFtdO1xuXG4gICAgZWFjaEVsZW1lbnQoc2libGluZ3MsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICAgICAgaWYgKGVsZW1lbnQueSA+IHNoYXBlLnkpIHtcbiAgICAgICAgYm90dG9tQWZmZWN0ZWQucHVzaChlbGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRvcEFmZmVjdGVkLnB1c2goZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlbGVtZW50LmNoaWxkcmVuO1xuICAgIH0pO1xuXG4gICAgaWYgKCFzaWJsaW5ncy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgb2Zmc2V0O1xuXG4gICAgaWYgKGJvdHRvbUFmZmVjdGVkLmxlbmd0aCAmJiB0b3BBZmZlY3RlZC5sZW5ndGgpIHtcbiAgICAgIG9mZnNldCA9IHNoYXBlLmhlaWdodCAvIDI7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9mZnNldCA9IHNoYXBlLmhlaWdodDtcbiAgICB9XG5cbiAgICB2YXIgdG9wQWRqdXN0bWVudHMsXG4gICAgICAgIGJvdHRvbUFkanVzdG1lbnRzO1xuXG4gICAgaWYgKHRvcEFmZmVjdGVkLmxlbmd0aCkge1xuICAgICAgdG9wQWRqdXN0bWVudHMgPSBzcGFjZVRvb2wuY2FsY3VsYXRlQWRqdXN0bWVudHMoXG4gICAgICAgIHRvcEFmZmVjdGVkLCAneScsIG9mZnNldCwgc2hhcGUueSAtIDEwKTtcblxuICAgICAgc3BhY2VUb29sLm1ha2VTcGFjZShcbiAgICAgICAgdG9wQWRqdXN0bWVudHMubW92aW5nU2hhcGVzLFxuICAgICAgICB0b3BBZGp1c3RtZW50cy5yZXNpemluZ1NoYXBlcyxcbiAgICAgICAgeyB4OiAwLCB5OiBvZmZzZXQgfSwgJ3MnKTtcbiAgICB9XG5cbiAgICBpZiAoYm90dG9tQWZmZWN0ZWQubGVuZ3RoKSB7XG4gICAgICBib3R0b21BZGp1c3RtZW50cyA9IHNwYWNlVG9vbC5jYWxjdWxhdGVBZGp1c3RtZW50cyhcbiAgICAgICAgYm90dG9tQWZmZWN0ZWQsICd5JywgLW9mZnNldCwgc2hhcGUueSArIHNoYXBlLmhlaWdodCArIDEwKTtcblxuICAgICAgc3BhY2VUb29sLm1ha2VTcGFjZShcbiAgICAgICAgYm90dG9tQWRqdXN0bWVudHMubW92aW5nU2hhcGVzLFxuICAgICAgICBib3R0b21BZGp1c3RtZW50cy5yZXNpemluZ1NoYXBlcyxcbiAgICAgICAgeyB4OiAwLCB5OiAtb2Zmc2V0IH0sICduJyk7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQWRqdXN0IHNpemVzIG9mIG90aGVyIGxhbmVzIGFmdGVyIGxhbmUgZGVsZXRpb25cbiAgICovXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdzaGFwZS5kZWxldGUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBvbGRQYXJlbnQgPSBjb250ZXh0Lm9sZFBhcmVudDtcblxuICAgIC8vIG9ubHkgY29tcGVuc2F0ZSBsYW5lIGRlbGV0ZXNcbiAgICBpZiAoIWlzKHNoYXBlLCAnYnBtbjpMYW5lJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBjb21wZW5zYXRlIHJvb3QgZGVsZXRlcyBvbmx5XG4gICAgaWYgKGhpbnRzICYmIGhpbnRzLm5lc3RlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbXBlbnNhdGVMYW5lRGVsZXRlKHNoYXBlLCBvbGRQYXJlbnQpO1xuICB9KTtcbn1cblxuRGVsZXRlTGFuZUJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZycsXG4gICdzcGFjZVRvb2wnXG5dO1xuXG5pbmhlcml0cyhEZWxldGVMYW5lQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7IGlzTGFiZWwgfSBmcm9tICcuLi8uLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cblxuLyoqXG4gKiBSZXBsYWNlIGJvdW5kYXJ5IGV2ZW50IHdpdGggaW50ZXJtZWRpYXRlIGV2ZW50IHdoZW4gY3JlYXRpbmcgb3IgbW92aW5nIHJlc3VsdHMgaW4gZGV0YWNoZWQgZXZlbnQuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERldGFjaEV2ZW50QmVoYXZpb3IoYnBtblJlcGxhY2UsIGluamVjdG9yKSB7XG4gIGluamVjdG9yLmludm9rZShDb21tYW5kSW50ZXJjZXB0b3IsIHRoaXMpO1xuXG4gIHRoaXMuX2JwbW5SZXBsYWNlID0gYnBtblJlcGxhY2U7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdlbGVtZW50cy5jcmVhdGUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzO1xuXG4gICAgZWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICB2YXIgaG9zdCA9IHNoYXBlLmhvc3Q7XG5cbiAgICAgIHJldHVybiBzaG91bGRSZXBsYWNlKHNoYXBlLCBob3N0KTtcbiAgICB9KS5tYXAoZnVuY3Rpb24oc2hhcGUpIHtcbiAgICAgIHJldHVybiBlbGVtZW50cy5pbmRleE9mKHNoYXBlKTtcbiAgICB9KS5mb3JFYWNoKGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICBjb250ZXh0LmVsZW1lbnRzWyBpbmRleCBdID0gc2VsZi5yZXBsYWNlU2hhcGUoZWxlbWVudHNbIGluZGV4IF0pO1xuICAgIH0pO1xuICB9LCB0cnVlKTtcblxuICB0aGlzLnByZUV4ZWN1dGUoJ2VsZW1lbnRzLm1vdmUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgc2hhcGVzID0gY29udGV4dC5zaGFwZXMsXG4gICAgICAgIG5ld0hvc3QgPSBjb250ZXh0Lm5ld0hvc3Q7XG5cbiAgICBzaGFwZXMuZm9yRWFjaChmdW5jdGlvbihzaGFwZSwgaW5kZXgpIHtcbiAgICAgIHZhciBob3N0ID0gc2hhcGUuaG9zdDtcblxuICAgICAgaWYgKHNob3VsZFJlcGxhY2Uoc2hhcGUsIGluY2x1ZGVzKHNoYXBlcywgaG9zdCkgPyBob3N0IDogbmV3SG9zdCkpIHtcbiAgICAgICAgc2hhcGVzWyBpbmRleCBdID0gc2VsZi5yZXBsYWNlU2hhcGUoc2hhcGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9LCB0cnVlKTtcbn1cblxuRGV0YWNoRXZlbnRCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnYnBtblJlcGxhY2UnLFxuICAnaW5qZWN0b3InXG5dO1xuXG5pbmhlcml0cyhEZXRhY2hFdmVudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5EZXRhY2hFdmVudEJlaGF2aW9yLnByb3RvdHlwZS5yZXBsYWNlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSkge1xuICB2YXIgZXZlbnREZWZpbml0aW9uID0gZ2V0RXZlbnREZWZpbml0aW9uKHNoYXBlKSxcbiAgICAgIGludGVybWVkaWF0ZUV2ZW50O1xuXG4gIGlmIChldmVudERlZmluaXRpb24pIHtcbiAgICBpbnRlcm1lZGlhdGVFdmVudCA9IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogZXZlbnREZWZpbml0aW9uLiR0eXBlXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBpbnRlcm1lZGlhdGVFdmVudCA9IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9icG1uUmVwbGFjZS5yZXBsYWNlRWxlbWVudChzaGFwZSwgaW50ZXJtZWRpYXRlRXZlbnQsIHsgbGF5b3V0Q29ubmVjdGlvbjogZmFsc2UgfSk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBnZXRFdmVudERlZmluaXRpb24oZWxlbWVudCkge1xuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcbiAgICAgIGV2ZW50RGVmaW5pdGlvbnMgPSBidXNpbmVzc09iamVjdC5ldmVudERlZmluaXRpb25zO1xuXG4gIHJldHVybiBldmVudERlZmluaXRpb25zICYmIGV2ZW50RGVmaW5pdGlvbnNbMF07XG59XG5cbmZ1bmN0aW9uIHNob3VsZFJlcGxhY2Uoc2hhcGUsIGhvc3QpIHtcbiAgcmV0dXJuICFpc0xhYmVsKHNoYXBlKSAmJiBpcyhzaGFwZSwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmICFob3N0O1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlcyhhcnJheSwgaXRlbSkge1xuICByZXR1cm4gYXJyYXkuaW5kZXhPZihpdGVtKSAhPT0gLTE7XG59IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaWx0ZXIsXG4gIGZpbmQsXG4gIGlzTnVtYmVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgZ2V0TWlkIH0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHtcbiAgZ2V0QXBwcm94SW50ZXJzZWN0aW9uXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvTGluZUludGVyc2VjdGlvbic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRHJvcE9uRmxvd0JlaGF2aW9yKGV2ZW50QnVzLCBicG1uUnVsZXMsIG1vZGVsaW5nKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8qKlxuICAgKiBSZWNvbm5lY3Qgc3RhcnQgLyBlbmQgb2YgYSBjb25uZWN0aW9uIGFmdGVyXG4gICAqIGRyb3BwaW5nIGFuIGVsZW1lbnQgb24gYSBmbG93LlxuICAgKi9cblxuICBmdW5jdGlvbiBpbnNlcnRTaGFwZShzaGFwZSwgdGFyZ2V0RmxvdywgcG9zaXRpb25PckJvdW5kcykge1xuICAgIHZhciB3YXlwb2ludHMgPSB0YXJnZXRGbG93LndheXBvaW50cyxcbiAgICAgICAgd2F5cG9pbnRzQmVmb3JlLFxuICAgICAgICB3YXlwb2ludHNBZnRlcixcbiAgICAgICAgZG9ja2luZ1BvaW50LFxuICAgICAgICBzb3VyY2UsXG4gICAgICAgIHRhcmdldCxcbiAgICAgICAgaW5jb21pbmdDb25uZWN0aW9uLFxuICAgICAgICBvdXRnb2luZ0Nvbm5lY3Rpb24sXG4gICAgICAgIG9sZE91dGdvaW5nID0gc2hhcGUub3V0Z29pbmcuc2xpY2UoKSxcbiAgICAgICAgb2xkSW5jb21pbmcgPSBzaGFwZS5pbmNvbWluZy5zbGljZSgpO1xuXG4gICAgdmFyIG1pZDtcblxuICAgIGlmIChpc051bWJlcihwb3NpdGlvbk9yQm91bmRzLndpZHRoKSkge1xuICAgICAgbWlkID0gZ2V0TWlkKHBvc2l0aW9uT3JCb3VuZHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtaWQgPSBwb3NpdGlvbk9yQm91bmRzO1xuICAgIH1cblxuICAgIHZhciBpbnRlcnNlY3Rpb24gPSBnZXRBcHByb3hJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCBtaWQpO1xuXG4gICAgaWYgKGludGVyc2VjdGlvbikge1xuICAgICAgd2F5cG9pbnRzQmVmb3JlID0gd2F5cG9pbnRzLnNsaWNlKDAsIGludGVyc2VjdGlvbi5pbmRleCk7XG4gICAgICB3YXlwb2ludHNBZnRlciA9IHdheXBvaW50cy5zbGljZShpbnRlcnNlY3Rpb24uaW5kZXggKyAoaW50ZXJzZWN0aW9uLmJlbmRwb2ludCA/IDEgOiAwKSk7XG5cbiAgICAgIC8vIGR1ZSB0byBpbmFjY3VyYWN5IGludGVyc2VjdGlvbiBtaWdodCBoYXZlIGJlZW4gZm91bmRcbiAgICAgIGlmICghd2F5cG9pbnRzQmVmb3JlLmxlbmd0aCB8fCAhd2F5cG9pbnRzQWZ0ZXIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZG9ja2luZ1BvaW50ID0gaW50ZXJzZWN0aW9uLmJlbmRwb2ludCA/IHdheXBvaW50c1tpbnRlcnNlY3Rpb24uaW5kZXhdIDogbWlkO1xuXG4gICAgICAvLyBpZiBsYXN0IHdheXBvaW50QmVmb3JlIGlzIGluc2lkZSBzaGFwZSdzIGJvdW5kcywgaWdub3JlIGRvY2tpbmcgcG9pbnRcbiAgICAgIGlmICghaXNQb2ludEluc2lkZUJCb3goc2hhcGUsIHdheXBvaW50c0JlZm9yZVt3YXlwb2ludHNCZWZvcmUubGVuZ3RoLTFdKSkge1xuICAgICAgICB3YXlwb2ludHNCZWZvcmUucHVzaChjb3B5KGRvY2tpbmdQb2ludCkpO1xuICAgICAgfVxuXG4gICAgICAvLyBpZiBmaXJzdCB3YXlwb2ludEFmdGVyIGlzIGluc2lkZSBzaGFwZSdzIGJvdW5kcywgaWdub3JlIGRvY2tpbmcgcG9pbnRcbiAgICAgIGlmICghaXNQb2ludEluc2lkZUJCb3goc2hhcGUsIHdheXBvaW50c0FmdGVyWzBdKSkge1xuICAgICAgICB3YXlwb2ludHNBZnRlci51bnNoaWZ0KGNvcHkoZG9ja2luZ1BvaW50KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc291cmNlID0gdGFyZ2V0Rmxvdy5zb3VyY2U7XG4gICAgdGFyZ2V0ID0gdGFyZ2V0Rmxvdy50YXJnZXQ7XG5cbiAgICBpZiAoYnBtblJ1bGVzLmNhbkNvbm5lY3Qoc291cmNlLCBzaGFwZSwgdGFyZ2V0RmxvdykpIHtcblxuICAgICAgLy8gcmVjb25uZWN0IHNvdXJjZSAtPiBpbnNlcnRlZCBzaGFwZVxuICAgICAgbW9kZWxpbmcucmVjb25uZWN0RW5kKHRhcmdldEZsb3csIHNoYXBlLCB3YXlwb2ludHNCZWZvcmUgfHwgbWlkKTtcblxuICAgICAgaW5jb21pbmdDb25uZWN0aW9uID0gdGFyZ2V0RmxvdztcbiAgICB9XG5cbiAgICBpZiAoYnBtblJ1bGVzLmNhbkNvbm5lY3Qoc2hhcGUsIHRhcmdldCwgdGFyZ2V0RmxvdykpIHtcblxuICAgICAgaWYgKCFpbmNvbWluZ0Nvbm5lY3Rpb24pIHtcblxuICAgICAgICAvLyByZWNvbm5lY3QgaW5zZXJ0ZWQgc2hhcGUgLT4gZW5kXG4gICAgICAgIG1vZGVsaW5nLnJlY29ubmVjdFN0YXJ0KHRhcmdldEZsb3csIHNoYXBlLCB3YXlwb2ludHNBZnRlciB8fCBtaWQpO1xuXG4gICAgICAgIG91dGdvaW5nQ29ubmVjdGlvbiA9IHRhcmdldEZsb3c7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRnb2luZ0Nvbm5lY3Rpb24gPSBtb2RlbGluZy5jb25uZWN0KFxuICAgICAgICAgIHNoYXBlLCB0YXJnZXQsIHsgdHlwZTogdGFyZ2V0Rmxvdy50eXBlLCB3YXlwb2ludHM6IHdheXBvaW50c0FmdGVyIH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZHVwbGljYXRlQ29ubmVjdGlvbnMgPSBbXS5jb25jYXQoXG5cbiAgICAgIGluY29taW5nQ29ubmVjdGlvbiAmJiBmaWx0ZXIob2xkSW5jb21pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb24uc291cmNlID09PSBpbmNvbWluZ0Nvbm5lY3Rpb24uc291cmNlO1xuICAgICAgfSkgfHwgW10sXG5cbiAgICAgIG91dGdvaW5nQ29ubmVjdGlvbiAmJiBmaWx0ZXIob2xkT3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb24udGFyZ2V0ID09PSBvdXRnb2luZ0Nvbm5lY3Rpb24udGFyZ2V0O1xuICAgICAgfSkgfHwgW11cbiAgICApO1xuXG4gICAgaWYgKGR1cGxpY2F0ZUNvbm5lY3Rpb25zLmxlbmd0aCkge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlRWxlbWVudHMoZHVwbGljYXRlQ29ubmVjdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMucHJlRXhlY3V0ZSgnZWxlbWVudHMubW92ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBuZXdQYXJlbnQgPSBjb250ZXh0Lm5ld1BhcmVudCxcbiAgICAgICAgc2hhcGVzID0gY29udGV4dC5zaGFwZXMsXG4gICAgICAgIGRlbHRhID0gY29udGV4dC5kZWx0YSxcbiAgICAgICAgc2hhcGUgPSBzaGFwZXNbMF07XG5cbiAgICBpZiAoIXNoYXBlIHx8ICFuZXdQYXJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBpZiB0aGUgbmV3IHBhcmVudCBpcyBhIGNvbm5lY3Rpb24sXG4gICAgLy8gY2hhbmdlIGl0IHRvIHRoZSBuZXcgcGFyZW50J3MgcGFyZW50XG4gICAgaWYgKG5ld1BhcmVudCAmJiBuZXdQYXJlbnQud2F5cG9pbnRzKSB7XG4gICAgICBjb250ZXh0Lm5ld1BhcmVudCA9IG5ld1BhcmVudCA9IG5ld1BhcmVudC5wYXJlbnQ7XG4gICAgfVxuXG4gICAgdmFyIHNoYXBlTWlkID0gZ2V0TWlkKHNoYXBlKTtcbiAgICB2YXIgbmV3U2hhcGVNaWQgPSB7XG4gICAgICB4OiBzaGFwZU1pZC54ICsgZGVsdGEueCxcbiAgICAgIHk6IHNoYXBlTWlkLnkgKyBkZWx0YS55XG4gICAgfTtcblxuICAgIC8vIGZpbmQgYSBjb25uZWN0aW9uIHdoaWNoIGludGVyc2VjdHMgd2l0aCB0aGVcbiAgICAvLyBlbGVtZW50J3MgbWlkIHBvaW50XG4gICAgdmFyIGNvbm5lY3Rpb24gPSBmaW5kKG5ld1BhcmVudC5jaGlsZHJlbiwgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgdmFyIGNhbkluc2VydCA9IGJwbW5SdWxlcy5jYW5JbnNlcnQoc2hhcGVzLCBlbGVtZW50KTtcblxuICAgICAgcmV0dXJuIGNhbkluc2VydCAmJiBnZXRBcHByb3hJbnRlcnNlY3Rpb24oZWxlbWVudC53YXlwb2ludHMsIG5ld1NoYXBlTWlkKTtcbiAgICB9KTtcblxuICAgIGlmIChjb25uZWN0aW9uKSB7XG4gICAgICBjb250ZXh0LnRhcmdldEZsb3cgPSBjb25uZWN0aW9uO1xuICAgICAgY29udGV4dC5wb3NpdGlvbiA9IG5ld1NoYXBlTWlkO1xuICAgIH1cblxuICB9LCB0cnVlKTtcblxuICB0aGlzLnBvc3RFeGVjdXRlZCgnZWxlbWVudHMubW92ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgdGFyZ2V0RmxvdyA9IGNvbnRleHQudGFyZ2V0RmxvdyxcbiAgICAgICAgcG9zaXRpb24gPSBjb250ZXh0LnBvc2l0aW9uO1xuXG4gICAgaWYgKHRhcmdldEZsb3cpIHtcbiAgICAgIGluc2VydFNoYXBlKHNoYXBlc1swXSwgdGFyZ2V0RmxvdywgcG9zaXRpb24pO1xuICAgIH1cblxuICB9LCB0cnVlKTtcblxuICB0aGlzLnByZUV4ZWN1dGUoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBwYXJlbnQgPSBjb250ZXh0LnBhcmVudCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKGJwbW5SdWxlcy5jYW5JbnNlcnQoc2hhcGUsIHBhcmVudCkpIHtcbiAgICAgIGNvbnRleHQudGFyZ2V0RmxvdyA9IHBhcmVudDtcbiAgICAgIGNvbnRleHQucGFyZW50ID0gcGFyZW50LnBhcmVudDtcbiAgICB9XG4gIH0sIHRydWUpO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICB0YXJnZXRGbG93ID0gY29udGV4dC50YXJnZXRGbG93LFxuICAgICAgICBwb3NpdGlvbk9yQm91bmRzID0gY29udGV4dC5wb3NpdGlvbjtcblxuICAgIGlmICh0YXJnZXRGbG93KSB7XG4gICAgICBpbnNlcnRTaGFwZShzaGFwZSwgdGFyZ2V0RmxvdywgcG9zaXRpb25PckJvdW5kcyk7XG4gICAgfVxuICB9LCB0cnVlKTtcbn1cblxuaW5oZXJpdHMoRHJvcE9uRmxvd0JlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5Ecm9wT25GbG93QmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2JwbW5SdWxlcycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNQb2ludEluc2lkZUJCb3goYmJveCwgcG9pbnQpIHtcbiAgdmFyIHggPSBwb2ludC54LFxuICAgICAgeSA9IHBvaW50Lnk7XG5cbiAgcmV0dXJuIHggPj0gYmJveC54ICYmXG4gICAgeCA8PSBiYm94LnggKyBiYm94LndpZHRoICYmXG4gICAgeSA+PSBiYm94LnkgJiZcbiAgICB5IDw9IGJib3gueSArIGJib3guaGVpZ2h0O1xufVxuXG5mdW5jdGlvbiBjb3B5KG9iaikge1xuICByZXR1cm4gYXNzaWduKHt9LCBvYmopO1xufVxuXG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEV2ZW50QmFzZWRHYXRld2F5QmVoYXZpb3IoZXZlbnRCdXMsIG1vZGVsaW5nKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8qKlxuICAgKiBSZW1vdmUgZXhpc3Rpbmcgc2VxdWVuY2UgZmxvd3Mgb2YgZXZlbnQtYmFzZWQgdGFyZ2V0IGJlZm9yZSBjb25uZWN0aW5nXG4gICAqIGZyb20gZXZlbnQtYmFzZWQgZ2F0ZXdheS5cbiAgICovXG4gIHRoaXMucHJlRXhlY3V0ZWQoJ2Nvbm5lY3Rpb24uY3JlYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICBleGlzdGluZ0luY29taW5nQ29ubmVjdGlvbnMgPSB0YXJnZXQuaW5jb21pbmcuc2xpY2UoKTtcblxuICAgIGlmIChjb250ZXh0LmhpbnRzICYmIGNvbnRleHQuaGludHMuY3JlYXRlRWxlbWVudHNCZWhhdmlvciA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBpcyhzb3VyY2UsICdicG1uOkV2ZW50QmFzZWRHYXRld2F5JykgJiZcbiAgICAgIHRhcmdldC5pbmNvbWluZy5sZW5ndGhcbiAgICApIHtcblxuICAgICAgZXhpc3RpbmdJbmNvbWluZ0Nvbm5lY3Rpb25zLmZpbHRlcihpc1NlcXVlbmNlRmxvdylcbiAgICAgICAgLmZvckVhY2goZnVuY3Rpb24oc2VxdWVuY2VGbG93KSB7XG4gICAgICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihzZXF1ZW5jZUZsb3cpO1xuICAgICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAgQWZ0ZXIgcmVwbGFjaW5nIHNoYXBlIHdpdGggZXZlbnQtYmFzZWQgZ2F0ZXdheSwgcmVtb3ZlIGluY29taW5nIHNlcXVlbmNlXG4gICAqICBmbG93cyBvZiBldmVudC1iYXNlZCB0YXJnZXRzIHdoaWNoIGRvIG5vdCBiZWxvbmcgdG8gZXZlbnQtYmFzZWQgZ2F0ZXdheVxuICAgKiAgc291cmNlLlxuICAgKi9cbiAgdGhpcy5wcmVFeGVjdXRlZCgnc2hhcGUucmVwbGFjZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgbmV3U2hhcGUgPSBldmVudC5jb250ZXh0Lm5ld1NoYXBlLFxuICAgICAgICBuZXdTaGFwZVRhcmdldHMsXG4gICAgICAgIG5ld1NoYXBlVGFyZ2V0c0luY29taW5nU2VxdWVuY2VGbG93cztcblxuICAgIGlmICghaXMobmV3U2hhcGUsICdicG1uOkV2ZW50QmFzZWRHYXRld2F5JykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXdTaGFwZVRhcmdldHMgPSBuZXdTaGFwZS5vdXRnb2luZy5maWx0ZXIoaXNTZXF1ZW5jZUZsb3cpXG4gICAgICAubWFwKGZ1bmN0aW9uKHNlcXVlbmNlRmxvdykge1xuICAgICAgICByZXR1cm4gc2VxdWVuY2VGbG93LnRhcmdldDtcbiAgICAgIH0pO1xuXG4gICAgbmV3U2hhcGVUYXJnZXRzSW5jb21pbmdTZXF1ZW5jZUZsb3dzID0gbmV3U2hhcGVUYXJnZXRzLnJlZHVjZShmdW5jdGlvbihzZXF1ZW5jZUZsb3dzLCB0YXJnZXQpIHtcbiAgICAgIHZhciBpbmNvbWluZ1NlcXVlbmNlRmxvd3MgPSB0YXJnZXQuaW5jb21pbmcuZmlsdGVyKGlzU2VxdWVuY2VGbG93KTtcblxuICAgICAgcmV0dXJuIHNlcXVlbmNlRmxvd3MuY29uY2F0KGluY29taW5nU2VxdWVuY2VGbG93cyk7XG4gICAgfSwgW10pO1xuXG4gICAgbmV3U2hhcGVUYXJnZXRzSW5jb21pbmdTZXF1ZW5jZUZsb3dzLmZvckVhY2goZnVuY3Rpb24oc2VxdWVuY2VGbG93KSB7XG4gICAgICBpZiAoc2VxdWVuY2VGbG93LnNvdXJjZSAhPT0gbmV3U2hhcGUpIHtcbiAgICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihzZXF1ZW5jZUZsb3cpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuRXZlbnRCYXNlZEdhdGV3YXlCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnbW9kZWxpbmcnXG5dO1xuXG5pbmhlcml0cyhFdmVudEJhc2VkR2F0ZXdheUJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGlzU2VxdWVuY2VGbG93KGNvbm5lY3Rpb24pIHtcbiAgcmV0dXJuIGlzKGNvbm5lY3Rpb24sICdicG1uOlNlcXVlbmNlRmxvdycpO1xufVxuIiwiaW1wb3J0IHsgZ2V0TGFuZXNSb290IH0gZnJvbSAnLi4vdXRpbC9MYW5lVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcclxuXHJcbmltcG9ydCB7IGlzQW55IH0gZnJvbSAnLi4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xyXG5cclxudmFyIEhJR0hfUFJJT1JJVFkgPSAxNTAwO1xyXG52YXIgSElHSEVTVF9QUklPUklUWSA9IDIwMDA7XHJcblxyXG5cclxuLyoqXHJcbiAqIENvcnJlY3QgaG92ZXIgdGFyZ2V0cyBpbiBjZXJ0YWluIHNpdHVhdGlvbnMgdG8gaW1wcm92ZSBkaWFncmFtIGludGVyYWN0aW9uLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XHJcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXHJcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEZpeEhvdmVyQmVoYXZpb3IoZWxlbWVudFJlZ2lzdHJ5LCBldmVudEJ1cywgY2FudmFzKSB7XHJcblxyXG4gIGV2ZW50QnVzLm9uKFtcclxuICAgICdjcmVhdGUuaG92ZXInLFxyXG4gICAgJ2NyZWF0ZS5tb3ZlJyxcclxuICAgICdjcmVhdGUuZW5kJyxcclxuICAgICdzaGFwZS5tb3ZlLmhvdmVyJyxcclxuICAgICdzaGFwZS5tb3ZlLm1vdmUnLFxyXG4gICAgJ3NoYXBlLm1vdmUuZW5kJ1xyXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlIHx8IGV2ZW50LnNoYXBlLFxyXG4gICAgICAgIGhvdmVyID0gZXZlbnQuaG92ZXI7XHJcblxyXG4gICAgLy8gZW5zdXJlIGVsZW1lbnRzIGFyZSBub3QgZHJvcHBlZCBvbnRvIGEgYnBtbjpMYW5lIGJ1dCBvbnRvXHJcbiAgICAvLyB0aGUgdW5kZXJseWluZyBicG1uOlBhcnRpY2lwYW50XHJcbiAgICBpZiAoaXMoaG92ZXIsICdicG1uOkxhbmUnKSAmJiAhaXNBbnkoc2hhcGUsIFsgJ2JwbW46TGFuZScsICdicG1uOlBhcnRpY2lwYW50JyBdKSkge1xyXG4gICAgICBldmVudC5ob3ZlciA9IGdldExhbmVzUm9vdChob3Zlcik7XHJcbiAgICAgIGV2ZW50LmhvdmVyR2Z4ID0gZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGV2ZW50LmhvdmVyKTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKTtcclxuXHJcbiAgICAvLyBlbnN1cmUgYnBtbjpHcm91cCBhbmQgbGFiZWwgZWxlbWVudHMgYXJlIGRyb3BwZWRcclxuICAgIC8vIGFsd2F5cyBvbnRvIHRoZSByb290XHJcbiAgICBpZiAoaG92ZXIgIT09IHJvb3RFbGVtZW50ICYmIChzaGFwZS5sYWJlbFRhcmdldCB8fCBpcyhzaGFwZSwgJ2JwbW46R3JvdXAnKSkpIHtcclxuICAgICAgZXZlbnQuaG92ZXIgPSByb290RWxlbWVudDtcclxuICAgICAgZXZlbnQuaG92ZXJHZnggPSBlbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZXZlbnQuaG92ZXIpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2Nvbm5lY3QuaG92ZXInLFxyXG4gICAgJ2Nvbm5lY3Qub3V0JyxcclxuICAgICdjb25uZWN0LmVuZCcsXHJcbiAgICAnY29ubmVjdC5jbGVhbnVwJyxcclxuICAgICdnbG9iYWwtY29ubmVjdC5ob3ZlcicsXHJcbiAgICAnZ2xvYmFsLWNvbm5lY3Qub3V0JyxcclxuICAgICdnbG9iYWwtY29ubmVjdC5lbmQnLFxyXG4gICAgJ2dsb2JhbC1jb25uZWN0LmNsZWFudXAnXHJcbiAgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBob3ZlciA9IGV2ZW50LmhvdmVyO1xyXG5cclxuICAgIC8vIGVuc3VyZSBjb25uZWN0aW9ucyBzdGFydC9lbmQgb24gYnBtbjpQYXJ0aWNpcGFudCxcclxuICAgIC8vIG5vdCB0aGUgdW5kZXJseWluZyBicG1uOkxhbmVcclxuICAgIGlmIChpcyhob3ZlciwgJ2JwbW46TGFuZScpKSB7XHJcbiAgICAgIGV2ZW50LmhvdmVyID0gZ2V0TGFuZXNSb290KGhvdmVyKSB8fCBob3ZlcjtcclxuICAgICAgZXZlbnQuaG92ZXJHZnggPSBlbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZXZlbnQuaG92ZXIpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2JlbmRwb2ludC5tb3ZlLmhvdmVyJ1xyXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgaG92ZXIgPSBldmVudC5ob3ZlcixcclxuICAgICAgICB0eXBlID0gY29udGV4dC50eXBlO1xyXG5cclxuICAgIC8vIGVuc3VyZSByZWNvbm5lY3Qgc3RhcnQvZW5kIG9uIGJwbW46UGFydGljaXBhbnQsXHJcbiAgICAvLyBub3QgdGhlIHVuZGVybHlpbmcgYnBtbjpMYW5lXHJcbiAgICBpZiAoaXMoaG92ZXIsICdicG1uOkxhbmUnKSAmJiAvcmVjb25uZWN0Ly50ZXN0KHR5cGUpKSB7XHJcbiAgICAgIGV2ZW50LmhvdmVyID0gZ2V0TGFuZXNSb290KGhvdmVyKSB8fCBob3ZlcjtcclxuICAgICAgZXZlbnQuaG92ZXJHZnggPSBlbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZXZlbnQuaG92ZXIpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2Nvbm5lY3Quc3RhcnQnXHJcbiAgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBzdGFydCA9IGNvbnRleHQuc3RhcnQ7XHJcblxyXG4gICAgLy8gZW5zdXJlIGNvbm5lY3Qgc3RhcnQgb24gYnBtbjpQYXJ0aWNpcGFudCxcclxuICAgIC8vIG5vdCB0aGUgdW5kZXJseWluZyBicG1uOkxhbmVcclxuICAgIGlmIChpcyhzdGFydCwgJ2JwbW46TGFuZScpKSB7XHJcbiAgICAgIGNvbnRleHQuc3RhcnQgPSBnZXRMYW5lc1Jvb3Qoc3RhcnQpIHx8IHN0YXJ0O1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgLy8gYWxsb3cgbW92ZW1lbnQgb2YgcGFydGljaXBhbnRzIGZyb20gbGFuZXNcclxuICBldmVudEJ1cy5vbignc2hhcGUubW92ZS5zdGFydCcsIEhJR0hFU1RfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgc2hhcGUgPSBldmVudC5zaGFwZTtcclxuXHJcbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkxhbmUnKSkge1xyXG4gICAgICBldmVudC5zaGFwZSA9IGdldExhbmVzUm9vdChzaGFwZSkgfHwgc2hhcGU7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG59XHJcblxyXG5GaXhIb3ZlckJlaGF2aW9yLiRpbmplY3QgPSBbXHJcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXHJcbiAgJ2V2ZW50QnVzJyxcclxuICAnY2FudmFzJ1xyXG5dOyIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5pbXBvcnQge1xuICBhZGQgYXMgY29sbGVjdGlvbkFkZCxcbiAgcmVtb3ZlIGFzIGNvbGxlY3Rpb25SZW1vdmVcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9Db2xsZWN0aW9ucyc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZUNhdGVnb3J5VmFsdWVcbn0gZnJvbSAnLi91dGlsL0NhdGVnb3J5VXRpbCc7XG5cbnZhciBISUdIX1BSSU9SSVRZID0gMjAwMDtcblxuXG4vKipcbiAqIEJQTU4gc3BlY2lmaWMgR3JvdXAgYmVoYXZpb3JcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gR3JvdXBCZWhhdmlvcihcbiAgICBicG1uRmFjdG9yeSxcbiAgICBjYW52YXMsXG4gICAgZWxlbWVudFJlZ2lzdHJ5LFxuICAgIGV2ZW50QnVzLFxuICAgIGluamVjdG9yLFxuICAgIG1vZGRsZUNvcHlcbikge1xuICBpbmplY3Rvci5pbnZva2UoQ29tbWFuZEludGVyY2VwdG9yLCB0aGlzKTtcblxuICAvKipcbiAgICogR2V0cyBwcm9jZXNzIGRlZmluaXRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9IGRlZmluaXRpb25zXG4gICAqL1xuICBmdW5jdGlvbiBnZXREZWZpbml0aW9ucygpIHtcbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgICAgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChyb290RWxlbWVudCk7XG5cbiAgICByZXR1cm4gYnVzaW5lc3NPYmplY3QuJHBhcmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgcmVmZXJlbmNlZCBjYXRlZ29yeSB2YWx1ZSBmb3IgYSBnaXZlbiBncm91cCBzaGFwZVxuICAgKlxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAgICovXG4gIGZ1bmN0aW9uIHJlbW92ZVJlZmVyZW5jZWRDYXRlZ29yeVZhbHVlKHNoYXBlKSB7XG5cbiAgICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChzaGFwZSksXG4gICAgICAgIGNhdGVnb3J5VmFsdWUgPSBidXNpbmVzc09iamVjdC5jYXRlZ29yeVZhbHVlUmVmO1xuXG4gICAgaWYgKCFjYXRlZ29yeVZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGNhdGVnb3J5ID0gY2F0ZWdvcnlWYWx1ZS4kcGFyZW50O1xuXG4gICAgaWYgKCFjYXRlZ29yeVZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29sbGVjdGlvblJlbW92ZShjYXRlZ29yeS5jYXRlZ29yeVZhbHVlLCBjYXRlZ29yeVZhbHVlKTtcblxuICAgIC8vIGNsZWFudXAgY2F0ZWdvcnkgaWYgaXQgaXMgZW1wdHlcbiAgICBpZiAoY2F0ZWdvcnkgJiYgIWNhdGVnb3J5LmNhdGVnb3J5VmFsdWUubGVuZ3RoKSB7XG4gICAgICByZW1vdmVDYXRlZ29yeShjYXRlZ29yeSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSBnaXZlbiBjYXRlZ29yeSBmcm9tIHRoZSBkZWZpbml0aW9uc1xuICAgKlxuICAgKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGNhdGVnb3J5XG4gICAqL1xuICBmdW5jdGlvbiByZW1vdmVDYXRlZ29yeShjYXRlZ29yeSkge1xuXG4gICAgdmFyIGRlZmluaXRpb25zID0gZ2V0RGVmaW5pdGlvbnMoKTtcblxuICAgIGNvbGxlY3Rpb25SZW1vdmUoZGVmaW5pdGlvbnMuZ2V0KCdyb290RWxlbWVudHMnKSwgY2F0ZWdvcnkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYWxsIGdyb3VwIGVsZW1lbnQgaW4gdGhlIGN1cnJlbnQgcmVnaXN0cnlcbiAgICpcbiAgICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLnNoYXBlPn0gYSBsaXN0IG9mIGdyb3VwIHNoYXBlc1xuICAgKi9cbiAgZnVuY3Rpb24gZ2V0R3JvdXBFbGVtZW50cygpIHtcbiAgICByZXR1cm4gZWxlbWVudFJlZ2lzdHJ5LmZpbHRlcihmdW5jdGlvbihlKSB7XG4gICAgICByZXR1cm4gaXMoZSwgJ2JwbW46R3JvdXAnKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgZ2l2ZW4gY2F0ZWdvcnlWYWx1ZSBpcyByZWZlcmVuY2VkIGluIG9uZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudHNcbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuc2hhcGU+fSBlbGVtZW50c1xuICAgKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGNhdGVnb3J5VmFsdWVcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGZ1bmN0aW9uIGlzUmVmZXJlbmNlZChlbGVtZW50cywgY2F0ZWdvcnlWYWx1ZSkge1xuICAgIHJldHVybiBlbGVtZW50cy5zb21lKGZ1bmN0aW9uKGUpIHtcblxuICAgICAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZSk7XG5cbiAgICAgIHJldHVybiBidXNpbmVzc09iamVjdC5jYXRlZ29yeVZhbHVlUmVmXG4gICAgICAgICYmIGJ1c2luZXNzT2JqZWN0LmNhdGVnb3J5VmFsdWVSZWYgPT09IGNhdGVnb3J5VmFsdWU7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogcmVtb3ZlIHJlZmVyZW5jZWQgY2F0ZWdvcnkgKyB2YWx1ZSB3aGVuIGdyb3VwIHdhcyBkZWxldGVkXG4gICAqL1xuICB0aGlzLmV4ZWN1dGVkKCdzaGFwZS5kZWxldGUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkdyb3VwJykpIHtcblxuICAgICAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3Qoc2hhcGUpLFxuICAgICAgICAgIGNhdGVnb3J5VmFsdWVSZWYgPSBidXNpbmVzc09iamVjdC5jYXRlZ29yeVZhbHVlUmVmLFxuICAgICAgICAgIGdyb3VwRWxlbWVudHMgPSBnZXRHcm91cEVsZW1lbnRzKCk7XG5cbiAgICAgIGlmICghaXNSZWZlcmVuY2VkKGdyb3VwRWxlbWVudHMsIGNhdGVnb3J5VmFsdWVSZWYpKSB7XG4gICAgICAgIHJlbW92ZVJlZmVyZW5jZWRDYXRlZ29yeVZhbHVlKHNoYXBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiByZS1hdHRhY2ggcmVtb3ZlZCBjYXRlZ29yeVxuICAgKi9cbiAgdGhpcy5yZXZlcnRlZCgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpHcm91cCcpKSB7XG5cbiAgICAgIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KHNoYXBlKSxcbiAgICAgICAgICBjYXRlZ29yeVZhbHVlUmVmID0gYnVzaW5lc3NPYmplY3QuY2F0ZWdvcnlWYWx1ZVJlZixcbiAgICAgICAgICBkZWZpbml0aW9ucyA9IGdldERlZmluaXRpb25zKCksXG4gICAgICAgICAgY2F0ZWdvcnkgPSBjYXRlZ29yeVZhbHVlUmVmID8gY2F0ZWdvcnlWYWx1ZVJlZi4kcGFyZW50IDogbnVsbDtcblxuICAgICAgY29sbGVjdGlvbkFkZChjYXRlZ29yeS5nZXQoJ2NhdGVnb3J5VmFsdWUnKSwgY2F0ZWdvcnlWYWx1ZVJlZik7XG4gICAgICBjb2xsZWN0aW9uQWRkKGRlZmluaXRpb25zLmdldCgncm9vdEVsZW1lbnRzJyksIGNhdGVnb3J5KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgbmV3IGNhdGVnb3J5ICsgdmFsdWUgd2hlbiBncm91cCB3YXMgY3JlYXRlZFxuICAgKi9cbiAgdGhpcy5leGVjdXRlKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KHNoYXBlKTtcblxuICAgIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46R3JvdXAnKSAmJiAhYnVzaW5lc3NPYmplY3QuY2F0ZWdvcnlWYWx1ZVJlZikge1xuXG4gICAgICB2YXIgZGVmaW5pdGlvbnMgPSBnZXREZWZpbml0aW9ucygpLFxuICAgICAgICAgIGNhdGVnb3J5VmFsdWUgPSBjcmVhdGVDYXRlZ29yeVZhbHVlKGRlZmluaXRpb25zLCBicG1uRmFjdG9yeSk7XG5cbiAgICAgIC8vIGxpbmsgdGhlIHJlZmVyZW5jZSB0byB0aGUgR3JvdXBcbiAgICAgIGJ1c2luZXNzT2JqZWN0LmNhdGVnb3J5VmFsdWVSZWYgPSBjYXRlZ29yeVZhbHVlO1xuICAgIH1cbiAgfSk7XG5cblxuICB0aGlzLnJldmVydCgnc2hhcGUuY3JlYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpHcm91cCcpKSB7XG4gICAgICByZW1vdmVSZWZlcmVuY2VkQ2F0ZWdvcnlWYWx1ZShzaGFwZSk7XG5cbiAgICAgIGRlbGV0ZSBnZXRCdXNpbmVzc09iamVjdChzaGFwZSkuY2F0ZWdvcnlWYWx1ZVJlZjtcblxuICAgIH1cbiAgfSk7XG5cbiAgLy8gY29weSBicG1uOkNhdGVnb3J5VmFsdWUgd2hlbiBjb3B5aW5nIGVsZW1lbnRcbiAgZXZlbnRCdXMub24oJ21vZGRsZUNvcHkuY2FuQ29weVByb3BlcnR5JywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBwcm9wZXJ0eSA9IGNvbnRleHQucHJvcGVydHksXG4gICAgICAgIGNhdGVnb3J5VmFsdWU7XG5cbiAgICBpZiAoaXMocHJvcGVydHksICdicG1uOkNhdGVnb3J5VmFsdWUnKSkge1xuICAgICAgY2F0ZWdvcnlWYWx1ZSA9IGNyZWF0ZUNhdGVnb3J5VmFsdWUoZ2V0RGVmaW5pdGlvbnMoKSwgYnBtbkZhY3RvcnkpO1xuXG4gICAgICAvLyByZXR1cm4gY29weSBvZiBjYXRlZ29yeVxuICAgICAgcmV0dXJuIG1vZGRsZUNvcHkuY29weUVsZW1lbnQocHJvcGVydHksIGNhdGVnb3J5VmFsdWUpO1xuICAgIH1cbiAgfSk7XG5cbn1cblxuR3JvdXBCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnYnBtbkZhY3RvcnknLFxuICAnY2FudmFzJyxcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXG4gICdldmVudEJ1cycsXG4gICdpbmplY3RvcicsXG4gICdtb2RkbGVDb3B5J1xuXTtcblxuaW5oZXJpdHMoR3JvdXBCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTsiLCJpbXBvcnQge1xuICBnZXRNaWRcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQgbGluZUludGVyc2VjdCBmcm9tICcuL3V0aWwvTGluZUludGVyc2VjdCc7XG5cblxuLyoqXG4gKiBGaXggYnJva2VuIGRvY2tpbmdzIGFmdGVyIERJIGltcG9ydHMuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gSW1wb3J0RG9ja2luZ0ZpeChldmVudEJ1cykge1xuXG4gIGZ1bmN0aW9uIGFkanVzdERvY2tpbmcoc3RhcnRQb2ludCwgbmV4dFBvaW50LCBlbGVtZW50TWlkKSB7XG5cbiAgICB2YXIgZWxlbWVudFRvcCA9IHtcbiAgICAgIHg6IGVsZW1lbnRNaWQueCxcbiAgICAgIHk6IGVsZW1lbnRNaWQueSAtIDUwXG4gICAgfTtcblxuICAgIHZhciBlbGVtZW50TGVmdCA9IHtcbiAgICAgIHg6IGVsZW1lbnRNaWQueCAtIDUwLFxuICAgICAgeTogZWxlbWVudE1pZC55XG4gICAgfTtcblxuICAgIHZhciB2ZXJ0aWNhbEludGVyc2VjdCA9IGxpbmVJbnRlcnNlY3Qoc3RhcnRQb2ludCwgbmV4dFBvaW50LCBlbGVtZW50TWlkLCBlbGVtZW50VG9wKSxcbiAgICAgICAgaG9yaXpvbnRhbEludGVyc2VjdCA9IGxpbmVJbnRlcnNlY3Qoc3RhcnRQb2ludCwgbmV4dFBvaW50LCBlbGVtZW50TWlkLCBlbGVtZW50TGVmdCk7XG5cbiAgICAvLyBvcmlnaW5hbCBpcyBob3Jpem9udGFsIG9yIHZlcnRpY2FsIGNlbnRlciBjcm9zcyBpbnRlcnNlY3Rpb25cbiAgICB2YXIgY2VudGVySW50ZXJzZWN0O1xuXG4gICAgaWYgKHZlcnRpY2FsSW50ZXJzZWN0ICYmIGhvcml6b250YWxJbnRlcnNlY3QpIHtcbiAgICAgIGlmIChnZXREaXN0YW5jZSh2ZXJ0aWNhbEludGVyc2VjdCwgZWxlbWVudE1pZCkgPiBnZXREaXN0YW5jZShob3Jpem9udGFsSW50ZXJzZWN0LCBlbGVtZW50TWlkKSkge1xuICAgICAgICBjZW50ZXJJbnRlcnNlY3QgPSBob3Jpem9udGFsSW50ZXJzZWN0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2VudGVySW50ZXJzZWN0ID0gdmVydGljYWxJbnRlcnNlY3Q7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNlbnRlckludGVyc2VjdCA9IHZlcnRpY2FsSW50ZXJzZWN0IHx8IGhvcml6b250YWxJbnRlcnNlY3Q7XG4gICAgfVxuXG4gICAgc3RhcnRQb2ludC5vcmlnaW5hbCA9IGNlbnRlckludGVyc2VjdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpeERvY2tpbmdzKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG5cbiAgICBhZGp1c3REb2NraW5nKFxuICAgICAgd2F5cG9pbnRzWzBdLFxuICAgICAgd2F5cG9pbnRzWzFdLFxuICAgICAgZ2V0TWlkKGNvbm5lY3Rpb24uc291cmNlKVxuICAgICk7XG5cbiAgICBhZGp1c3REb2NraW5nKFxuICAgICAgd2F5cG9pbnRzW3dheXBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgIHdheXBvaW50c1t3YXlwb2ludHMubGVuZ3RoIC0gMl0sXG4gICAgICBnZXRNaWQoY29ubmVjdGlvbi50YXJnZXQpXG4gICAgKTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdicG1uRWxlbWVudC5hZGRlZCcsIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBlbGVtZW50ID0gZS5lbGVtZW50O1xuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICBmaXhEb2NraW5ncyhlbGVtZW50KTtcbiAgICB9XG4gIH0pO1xufVxuXG5JbXBvcnREb2NraW5nRml4LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldERpc3RhbmNlKHAxLCBwMikge1xuICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHAxLnggLSBwMi54LCAyKSArIE1hdGgucG93KHAxLnkgLSBwMi55LCAyKSk7XG59IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0XG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgaXNBbnlcbn0gZnJvbSAnLi4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgbWFrZXMgc3VyZSB0aGF0IGVhY2ggY3JlYXRlZCBvciB1cGRhdGVkXG4gKiBQb29sIGFuZCBMYW5lIGlzIGFzc2lnbmVkIGFuIGlzSG9yaXpvbnRhbCBwcm9wZXJ0eSBzZXQgdG8gdHJ1ZS5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBJc0hvcml6b250YWxGaXgoZXZlbnRCdXMpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdmFyIGVsZW1lbnRUeXBlc1RvVXBkYXRlID0gW1xuICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAnYnBtbjpMYW5lJ1xuICBdO1xuXG4gIHRoaXMuZXhlY3V0ZWQoWyAnc2hhcGUubW92ZScsICdzaGFwZS5jcmVhdGUnLCAnc2hhcGUucmVzaXplJyBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGV2ZW50LmNvbnRleHQuc2hhcGUpO1xuXG4gICAgaWYgKGlzQW55KGJvLCBlbGVtZW50VHlwZXNUb1VwZGF0ZSkgJiYgIWJvLmRpLmdldCgnaXNIb3Jpem9udGFsJykpIHtcblxuICAgICAgLy8gc2V0IGF0dHJpYnV0ZSBkaXJlY3RseSB0byBhdm9pZCBtb2RlbGluZyN1cGRhdGVQcm9wZXJ0eSBzaWRlIGVmZmVjdHNcbiAgICAgIGJvLmRpLnNldCgnaXNIb3Jpem9udGFsJywgdHJ1ZSk7XG4gICAgfVxuICB9KTtcblxufVxuXG5Jc0hvcml6b250YWxGaXguJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdO1xuXG5pbmhlcml0cyhJc0hvcml6b250YWxGaXgsIENvbW1hbmRJbnRlcmNlcHRvcik7XG4iLCJpbXBvcnQge1xuICBhc3NpZ25cbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQge1xuICBpcyxcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0xhYmVsRXh0ZXJuYWwsXG4gIGdldEV4dGVybmFsTGFiZWxNaWQsXG4gIGhhc0V4dGVybmFsTGFiZWwsXG4gIGlzTGFiZWxcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9MYWJlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRMYWJlbFxufSBmcm9tICcuLi8uLi9sYWJlbC1lZGl0aW5nL0xhYmVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldExhYmVsQWRqdXN0bWVudFxufSBmcm9tICcuL3V0aWwvTGFiZWxMYXlvdXRVdGlsJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldE5ld0F0dGFjaFBvaW50XG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvQXR0YWNoVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldE1pZCxcbiAgcm91bmRQb2ludFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7XG4gIGRlbHRhXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvUG9zaXRpb25VdGlsJztcblxuaW1wb3J0IHtcbiAgc29ydEJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0RGlzdGFuY2VQb2ludExpbmUsXG4gIHBlcnBlbmRpY3VsYXJGb290XG59IGZyb20gJy4vdXRpbC9HZW9tZXRyaWNVdGlsJztcblxudmFyIERFRkFVTFRfTEFCRUxfRElNRU5TSU9OUyA9IHtcbiAgd2lkdGg6IDkwLFxuICBoZWlnaHQ6IDIwXG59O1xuXG52YXIgTkFNRV9QUk9QRVJUWSA9ICduYW1lJztcbnZhciBURVhUX1BST1BFUlRZID0gJ3RleHQnO1xuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgbWFrZXMgc3VyZSB0aGF0IGV4dGVybmFsIGxhYmVscyBhcmUgYWRkZWRcbiAqIHRvZ2V0aGVyIHdpdGggcmVzcGVjdGl2ZSBlbGVtZW50cyBhbmQgcHJvcGVybHkgdXBkYXRlZCAoREkgd2lzZSlcbiAqIGR1cmluZyBtb3ZlLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcbiAqIEBwYXJhbSB7VGV4dFJlbmRlcmVyfSB0ZXh0UmVuZGVyZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGFiZWxCZWhhdmlvcihcbiAgICBldmVudEJ1cywgbW9kZWxpbmcsIGJwbW5GYWN0b3J5LFxuICAgIHRleHRSZW5kZXJlcikge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuICAvLyB1cGRhdGUgbGFiZWwgaWYgbmFtZSBwcm9wZXJ0eSB3YXMgdXBkYXRlZFxuICB0aGlzLnBvc3RFeGVjdXRlKCdlbGVtZW50LnVwZGF0ZVByb3BlcnRpZXMnLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnQgPSBjb250ZXh0LmVsZW1lbnQsXG4gICAgICAgIHByb3BlcnRpZXMgPSBjb250ZXh0LnByb3BlcnRpZXM7XG5cbiAgICBpZiAoTkFNRV9QUk9QRVJUWSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICBtb2RlbGluZy51cGRhdGVMYWJlbChlbGVtZW50LCBwcm9wZXJ0aWVzW05BTUVfUFJPUEVSVFldKTtcbiAgICB9XG5cbiAgICBpZiAoVEVYVF9QUk9QRVJUWSBpbiBwcm9wZXJ0aWVzXG4gICAgICAgICYmIGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcblxuICAgICAgdmFyIG5ld0JvdW5kcyA9IHRleHRSZW5kZXJlci5nZXRUZXh0QW5ub3RhdGlvbkJvdW5kcyhcbiAgICAgICAge1xuICAgICAgICAgIHg6IGVsZW1lbnQueCxcbiAgICAgICAgICB5OiBlbGVtZW50LnksXG4gICAgICAgICAgd2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICAgICAgICB9LFxuICAgICAgICBwcm9wZXJ0aWVzW1RFWFRfUFJPUEVSVFldIHx8ICcnXG4gICAgICApO1xuXG4gICAgICBtb2RlbGluZy51cGRhdGVMYWJlbChlbGVtZW50LCBwcm9wZXJ0aWVzLnRleHQsIG5ld0JvdW5kcyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBjcmVhdGUgbGFiZWwgc2hhcGUgYWZ0ZXIgc2hhcGUvY29ubmVjdGlvbiB3YXMgY3JlYXRlZFxuICB0aGlzLnBvc3RFeGVjdXRlKFsgJ3NoYXBlLmNyZWF0ZScsICdjb25uZWN0aW9uLmNyZWF0ZScgXSwgZnVuY3Rpb24oZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgICBpZiAoaGludHMuY3JlYXRlRWxlbWVudHNCZWhhdmlvciA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZWxlbWVudCA9IGNvbnRleHQuc2hhcGUgfHwgY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBidXNpbmVzc09iamVjdCA9IGVsZW1lbnQuYnVzaW5lc3NPYmplY3Q7XG5cbiAgICBpZiAoaXNMYWJlbChlbGVtZW50KSB8fCAhaXNMYWJlbEV4dGVybmFsKGVsZW1lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gb25seSBjcmVhdGUgbGFiZWwgaWYgYXR0cmlidXRlIGF2YWlsYWJsZVxuICAgIGlmICghZ2V0TGFiZWwoZWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbGFiZWxDZW50ZXIgPSBnZXRFeHRlcm5hbExhYmVsTWlkKGVsZW1lbnQpO1xuXG4gICAgLy8gd2UgZG9uJ3QgY2FyZSBhYm91dCB4IGFuZCB5XG4gICAgdmFyIGxhYmVsRGltZW5zaW9ucyA9IHRleHRSZW5kZXJlci5nZXRFeHRlcm5hbExhYmVsQm91bmRzKFxuICAgICAgREVGQVVMVF9MQUJFTF9ESU1FTlNJT05TLFxuICAgICAgZ2V0TGFiZWwoZWxlbWVudClcbiAgICApO1xuXG4gICAgbW9kZWxpbmcuY3JlYXRlTGFiZWwoZWxlbWVudCwgbGFiZWxDZW50ZXIsIHtcbiAgICAgIGlkOiBidXNpbmVzc09iamVjdC5pZCArICdfbGFiZWwnLFxuICAgICAgYnVzaW5lc3NPYmplY3Q6IGJ1c2luZXNzT2JqZWN0LFxuICAgICAgd2lkdGg6IGxhYmVsRGltZW5zaW9ucy53aWR0aCxcbiAgICAgIGhlaWdodDogbGFiZWxEaW1lbnNpb25zLmhlaWdodFxuICAgIH0pO1xuICB9KTtcblxuICAvLyB1cGRhdGUgbGFiZWwgYWZ0ZXIgbGFiZWwgc2hhcGUgd2FzIGRlbGV0ZWRcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGxhYmVsVGFyZ2V0ID0gY29udGV4dC5sYWJlbFRhcmdldCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gICAgLy8gY2hlY2sgaWYgbGFiZWxcbiAgICBpZiAobGFiZWxUYXJnZXQgJiYgaGludHMudW5zZXRMYWJlbCAhPT0gZmFsc2UpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZUxhYmVsKGxhYmVsVGFyZ2V0LCBudWxsLCBudWxsLCB7IHJlbW92ZVNoYXBlOiBmYWxzZSB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHVwZGF0ZSBkaSBpbmZvcm1hdGlvbiBvbiBsYWJlbCBjcmVhdGlvblxuICB0aGlzLnBvc3RFeGVjdXRlKFsgJ2xhYmVsLmNyZWF0ZScgXSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0LFxuICAgICAgICBkaTtcblxuICAgIC8vIHdlIHdhbnQgdG8gdHJpZ2dlciBvbiByZWFsIGxhYmVscyBvbmx5XG4gICAgaWYgKCFlbGVtZW50LmxhYmVsVGFyZ2V0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gd2Ugd2FudCB0byB0cmlnZ2VyIG9uIEJQTU4gZWxlbWVudHMgb25seVxuICAgIGlmICghaXMoZWxlbWVudC5sYWJlbFRhcmdldCB8fCBlbGVtZW50LCAnYnBtbjpCYXNlRWxlbWVudCcpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYnVzaW5lc3NPYmplY3QgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LFxuICAgIGRpID0gYnVzaW5lc3NPYmplY3QuZGk7XG5cblxuICAgIGlmICghZGkubGFiZWwpIHtcbiAgICAgIGRpLmxhYmVsID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uZGk6QlBNTkxhYmVsJywge1xuICAgICAgICBib3VuZHM6IGJwbW5GYWN0b3J5LmNyZWF0ZSgnZGM6Qm91bmRzJylcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzc2lnbihkaS5sYWJlbC5ib3VuZHMsIHtcbiAgICAgIHg6IGVsZW1lbnQueCxcbiAgICAgIHk6IGVsZW1lbnQueSxcbiAgICAgIHdpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICAgIH0pO1xuICB9KTtcblxuICBmdW5jdGlvbiBnZXRWaXNpYmxlTGFiZWxBZGp1c3RtZW50KGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIGxhYmVsID0gY29ubmVjdGlvbi5sYWJlbCxcbiAgICAgICAgaGludHMgPSBhc3NpZ24oe30sIGNvbnRleHQuaGludHMpLFxuICAgICAgICBuZXdXYXlwb2ludHMgPSBjb250ZXh0Lm5ld1dheXBvaW50cyB8fCBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgICAgb2xkV2F5cG9pbnRzID0gY29udGV4dC5vbGRXYXlwb2ludHM7XG5cblxuICAgIGlmICh0eXBlb2YgaGludHMuc3RhcnRDaGFuZ2VkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgaGludHMuc3RhcnRDaGFuZ2VkID0gISFoaW50cy5jb25uZWN0aW9uU3RhcnQ7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBoaW50cy5lbmRDaGFuZ2VkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgaGludHMuZW5kQ2hhbmdlZCA9ICEhaGludHMuY29ubmVjdGlvbkVuZDtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0TGFiZWxBZGp1c3RtZW50KGxhYmVsLCBuZXdXYXlwb2ludHMsIG9sZFdheXBvaW50cywgaGludHMpO1xuICB9XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZShbXG4gICAgJ2Nvbm5lY3Rpb24ubGF5b3V0JyxcbiAgICAnY29ubmVjdGlvbi51cGRhdGVXYXlwb2ludHMnXG4gIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgICBpZiAoaGludHMubGFiZWxCZWhhdmlvciA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgbGFiZWwgPSBjb25uZWN0aW9uLmxhYmVsLFxuICAgICAgICBsYWJlbEFkanVzdG1lbnQ7XG5cbiAgICAvLyBoYW5kbGUgbWlzc2luZyBsYWJlbCBhcyB3ZWxsIGFzIHRoZSBjYXNlXG4gICAgLy8gdGhhdCB0aGUgbGFiZWwgcGFyZW50IGRvZXMgbm90IGV4aXN0ICh5ZXQpLFxuICAgIC8vIGJlY2F1c2UgaXQgaXMgYmVpbmcgcGFzdGVkIC8gY3JlYXRlZCB2aWEgbXVsdGkgZWxlbWVudCBjcmVhdGVcbiAgICAvL1xuICAgIC8vIENmLiBodHRwczovL2dpdGh1Yi5jb20vYnBtbi1pby9icG1uLWpzL3B1bGwvMTIyN1xuICAgIGlmICghbGFiZWwgfHwgIWxhYmVsLnBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxhYmVsQWRqdXN0bWVudCA9IGdldFZpc2libGVMYWJlbEFkanVzdG1lbnQoZXZlbnQpO1xuXG4gICAgbW9kZWxpbmcubW92ZVNoYXBlKGxhYmVsLCBsYWJlbEFkanVzdG1lbnQpO1xuICB9KTtcblxuXG4gIC8vIGtlZXAgbGFiZWwgcG9zaXRpb24gb24gc2hhcGUgcmVwbGFjZVxuICB0aGlzLnBvc3RFeGVjdXRlKFsgJ3NoYXBlLnJlcGxhY2UnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBuZXdTaGFwZSA9IGNvbnRleHQubmV3U2hhcGUsXG4gICAgICAgIG9sZFNoYXBlID0gY29udGV4dC5vbGRTaGFwZTtcblxuICAgIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KG5ld1NoYXBlKTtcblxuICAgIGlmIChidXNpbmVzc09iamVjdFxuICAgICAgJiYgaXNMYWJlbEV4dGVybmFsKGJ1c2luZXNzT2JqZWN0KVxuICAgICAgJiYgb2xkU2hhcGUubGFiZWxcbiAgICAgICYmIG5ld1NoYXBlLmxhYmVsKSB7XG4gICAgICBuZXdTaGFwZS5sYWJlbC54ID0gb2xkU2hhcGUubGFiZWwueDtcbiAgICAgIG5ld1NoYXBlLmxhYmVsLnkgPSBvbGRTaGFwZS5sYWJlbC55O1xuICAgIH1cbiAgfSk7XG5cblxuICAvLyBtb3ZlIGV4dGVybmFsIGxhYmVsIGFmdGVyIHJlc2l6aW5nXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ3NoYXBlLnJlc2l6ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgbmV3Qm91bmRzID0gY29udGV4dC5uZXdCb3VuZHMsXG4gICAgICAgIG9sZEJvdW5kcyA9IGNvbnRleHQub2xkQm91bmRzO1xuXG4gICAgaWYgKGhhc0V4dGVybmFsTGFiZWwoc2hhcGUpKSB7XG5cbiAgICAgIHZhciBsYWJlbCA9IHNoYXBlLmxhYmVsLFxuICAgICAgICAgIGxhYmVsTWlkID0gZ2V0TWlkKGxhYmVsKSxcbiAgICAgICAgICBlZGdlcyA9IGFzRWRnZXMob2xkQm91bmRzKTtcblxuICAgICAgLy8gZ2V0IG5lYXJlc3QgYm9yZGVyIHBvaW50IHRvIGxhYmVsIGFzIHJlZmVyZW5jZSBwb2ludFxuICAgICAgdmFyIHJlZmVyZW5jZVBvaW50ID0gZ2V0UmVmZXJlbmNlUG9pbnQobGFiZWxNaWQsIGVkZ2VzKTtcblxuICAgICAgdmFyIGRlbHRhID0gZ2V0UmVmZXJlbmNlUG9pbnREZWx0YShyZWZlcmVuY2VQb2ludCwgb2xkQm91bmRzLCBuZXdCb3VuZHMpO1xuXG4gICAgICBtb2RlbGluZy5tb3ZlU2hhcGUobGFiZWwsIGRlbHRhKTtcblxuICAgIH1cblxuICB9KTtcblxufVxuXG5pbmhlcml0cyhMYWJlbEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5MYWJlbEJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZycsXG4gICdicG1uRmFjdG9yeScsXG4gICd0ZXh0UmVuZGVyZXInXG5dO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBDYWxjdWxhdGVzIGEgcmVmZXJlbmNlIHBvaW50IGRlbHRhIHJlbGF0aXZlIHRvIGEgbmV3IHBvc2l0aW9uXG4gKiBvZiBhIGNlcnRhaW4gZWxlbWVudCdzIGJvdW5kc1xuICpcbiAqIEBwYXJhbSB7UG9pbnR9IHBvaW50XG4gKiBAcGFyYW0ge0JvdW5kc30gb2xkQm91bmRzXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXG4gKlxuICogQHJldHVybiB7RGVsdGF9IGRlbHRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZWZlcmVuY2VQb2ludERlbHRhKHJlZmVyZW5jZVBvaW50LCBvbGRCb3VuZHMsIG5ld0JvdW5kcykge1xuXG4gIHZhciBuZXdSZWZlcmVuY2VQb2ludCA9IGdldE5ld0F0dGFjaFBvaW50KHJlZmVyZW5jZVBvaW50LCBvbGRCb3VuZHMsIG5ld0JvdW5kcyk7XG5cbiAgcmV0dXJuIHJvdW5kUG9pbnQoZGVsdGEobmV3UmVmZXJlbmNlUG9pbnQsIHJlZmVyZW5jZVBvaW50KSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBuZWFyZXN0IHBvaW50IChyZWZlcmVuY2UgcG9pbnQpIGZvciBhIGdpdmVuIHBvaW50XG4gKiBvbnRvIGdpdmVuIHNldCBvZiBsaW5lc1xuICpcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQsIFBvaW50Pn0gbGluZXNcbiAqIEBwYXJhbSB7UG9pbnR9IHBvaW50XG4gKlxuICogQHBhcmFtIHtQb2ludH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlZmVyZW5jZVBvaW50KHBvaW50LCBsaW5lcykge1xuXG4gIGlmICghbGluZXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG5lYXJlc3RMaW5lID0gZ2V0TmVhcmVzdExpbmUocG9pbnQsIGxpbmVzKTtcblxuICByZXR1cm4gcGVycGVuZGljdWxhckZvb3QocG9pbnQsIG5lYXJlc3RMaW5lKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IHRoZSBnaXZlbiBib3VuZHMgdG8gYSBsaW5lcyBhcnJheSBjb250YWluaW5nIGFsbCBlZGdlc1xuICpcbiAqIEBwYXJhbSB7Qm91bmRzfFBvaW50fSBib3VuZHNcbiAqXG4gKiBAcmV0dXJuIEFycmF5PFBvaW50PlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNFZGdlcyhib3VuZHMpIHtcbiAgcmV0dXJuIFtcbiAgICBbIC8vIHRvcFxuICAgICAge1xuICAgICAgICB4OiBib3VuZHMueCxcbiAgICAgICAgeTogYm91bmRzLnlcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHg6IGJvdW5kcy54ICsgKGJvdW5kcy53aWR0aCB8fCAwKSxcbiAgICAgICAgeTogYm91bmRzLnlcbiAgICAgIH1cbiAgICBdLFxuICAgIFsgLy8gcmlnaHRcbiAgICAgIHtcbiAgICAgICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIHx8IDApLFxuICAgICAgICB5OiBib3VuZHMueVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIHx8IDApLFxuICAgICAgICB5OiBib3VuZHMueSArIChib3VuZHMuaGVpZ2h0IHx8IDApXG4gICAgICB9XG4gICAgXSxcbiAgICBbIC8vIGJvdHRvbVxuICAgICAge1xuICAgICAgICB4OiBib3VuZHMueCxcbiAgICAgICAgeTogYm91bmRzLnkgKyAoYm91bmRzLmhlaWdodCB8fCAwKVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIHx8IDApLFxuICAgICAgICB5OiBib3VuZHMueSArIChib3VuZHMuaGVpZ2h0IHx8IDApXG4gICAgICB9XG4gICAgXSxcbiAgICBbIC8vIGxlZnRcbiAgICAgIHtcbiAgICAgICAgeDogYm91bmRzLngsXG4gICAgICAgIHk6IGJvdW5kcy55XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB4OiBib3VuZHMueCxcbiAgICAgICAgeTogYm91bmRzLnkgKyAoYm91bmRzLmhlaWdodCB8fCAwKVxuICAgICAgfVxuICAgIF1cbiAgXTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBuZWFyZXN0IGxpbmUgZm9yIGEgZ2l2ZW4gcG9pbnQgYnkgZGlzdGFuY2VcbiAqIEBwYXJhbSB7UG9pbnR9IHBvaW50XG4gKiBAcGFyYW0gQXJyYXk8UG9pbnQ+IGxpbmVzXG4gKlxuICogQHJldHVybiBBcnJheTxQb2ludD5cbiAqL1xuZnVuY3Rpb24gZ2V0TmVhcmVzdExpbmUocG9pbnQsIGxpbmVzKSB7XG5cbiAgdmFyIGRpc3RhbmNlcyA9IGxpbmVzLm1hcChmdW5jdGlvbihsKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxpbmU6IGwsXG4gICAgICBkaXN0YW5jZTogZ2V0RGlzdGFuY2VQb2ludExpbmUocG9pbnQsIGwpXG4gICAgfTtcbiAgfSk7XG5cbiAgdmFyIHNvcnRlZCA9IHNvcnRCeShkaXN0YW5jZXMsICdkaXN0YW5jZScpO1xuXG4gIHJldHVybiBzb3J0ZWRbMF0ubGluZTtcbn1cbiIsImltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG52YXIgQ09MTEFCX0VSUl9NU0cgPSAnZmxvdyBlbGVtZW50cyBtdXN0IGJlIGNoaWxkcmVuIG9mIHBvb2xzL3BhcnRpY2lwYW50cycsXG4gICAgUFJPQ0VTU19FUlJfTVNHID0gJ3BhcnRpY2lwYW50cyBjYW5ub3QgYmUgcGFzdGVkIG9udG8gYSBub24tZW1wdHkgcHJvY2VzcyBkaWFncmFtJztcblxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb2RlbGluZ0ZlZWRiYWNrKGV2ZW50QnVzLCB0b29sdGlwcywgdHJhbnNsYXRlKSB7XG5cbiAgZnVuY3Rpb24gc2hvd0Vycm9yKHBvc2l0aW9uLCBtZXNzYWdlLCB0aW1lb3V0KSB7XG4gICAgdG9vbHRpcHMuYWRkKHtcbiAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgIHg6IHBvc2l0aW9uLnggKyA1LFxuICAgICAgICB5OiBwb3NpdGlvbi55ICsgNVxuICAgICAgfSxcbiAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICB0aW1lb3V0OiB0aW1lb3V0IHx8IDIwMDAsXG4gICAgICBodG1sOiAnPGRpdj4nICsgbWVzc2FnZSArICc8L2Rpdj4nXG4gICAgfSk7XG4gIH1cblxuICBldmVudEJ1cy5vbihbICdzaGFwZS5tb3ZlLnJlamVjdGVkJywgJ2NyZWF0ZS5yZWplY3RlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgdGFyZ2V0ID0gY29udGV4dC50YXJnZXQ7XG5cbiAgICBpZiAoaXModGFyZ2V0LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykgJiYgaXMoc2hhcGUsICdicG1uOkZsb3dOb2RlJykpIHtcbiAgICAgIHNob3dFcnJvcihldmVudCwgdHJhbnNsYXRlKENPTExBQl9FUlJfTVNHKSk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdlbGVtZW50cy5wYXN0ZS5yZWplY3RlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHBvc2l0aW9uID0gY29udGV4dC5wb3NpdGlvbixcbiAgICAgICAgdGFyZ2V0ID0gY29udGV4dC50YXJnZXQ7XG5cbiAgICBpZiAoaXModGFyZ2V0LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykpIHtcbiAgICAgIHNob3dFcnJvcihwb3NpdGlvbiwgdHJhbnNsYXRlKENPTExBQl9FUlJfTVNHKSk7XG4gICAgfVxuXG4gICAgaWYgKGlzKHRhcmdldCwgJ2JwbW46UHJvY2VzcycpKSB7XG4gICAgICBzaG93RXJyb3IocG9zaXRpb24sIHRyYW5zbGF0ZShQUk9DRVNTX0VSUl9NU0cpLCAzMDAwKTtcbiAgICB9XG4gIH0pO1xufVxuXG5Nb2RlbGluZ0ZlZWRiYWNrLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICd0b29sdGlwcycsXG4gICd0cmFuc2xhdGUnXG5dO1xuIiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5pbXBvcnQgbGluZUludGVyc2VjdCBmcm9tICcuL3V0aWwvTGluZUludGVyc2VjdCc7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVtb3ZlRWxlbWVudEJlaGF2aW9yKGV2ZW50QnVzLCBicG1uUnVsZXMsIG1vZGVsaW5nKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8qKlxuICAgKiBDb21iaW5lIHNlcXVlbmNlIGZsb3dzIHdoZW4gZGVsZXRpbmcgYW4gZWxlbWVudFxuICAgKiBpZiB0aGVyZSBpcyBvbmUgaW5jb21pbmcgYW5kIG9uZSBvdXRnb2luZ1xuICAgKiBzZXF1ZW5jZSBmbG93XG4gICAqL1xuICB0aGlzLnByZUV4ZWN1dGUoJ3NoYXBlLmRlbGV0ZScsIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBzaGFwZSA9IGUuY29udGV4dC5zaGFwZTtcblxuICAgIC8vIG9ubHkgaGFuZGxlIFthXSAtPiBbc2hhcGVdIC0+IFtiXSBwYXR0ZXJuc1xuICAgIGlmIChzaGFwZS5pbmNvbWluZy5sZW5ndGggIT09IDEgfHwgc2hhcGUub3V0Z29pbmcubGVuZ3RoICE9PSAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGluQ29ubmVjdGlvbiA9IHNoYXBlLmluY29taW5nWzBdLFxuICAgICAgICBvdXRDb25uZWN0aW9uID0gc2hhcGUub3V0Z29pbmdbMF07XG5cbiAgICAvLyBvbmx5IGhhbmRsZSBzZXF1ZW5jZSBmbG93c1xuICAgIGlmICghaXMoaW5Db25uZWN0aW9uLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSB8fCAhaXMob3V0Q29ubmVjdGlvbiwgJ2JwbW46U2VxdWVuY2VGbG93JykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoYnBtblJ1bGVzLmNhbkNvbm5lY3QoaW5Db25uZWN0aW9uLnNvdXJjZSwgb3V0Q29ubmVjdGlvbi50YXJnZXQsIGluQ29ubmVjdGlvbikpIHtcblxuICAgICAgLy8gY29tcHV0ZSBuZXcsIGNvbWJpbmVkIHdheXBvaW50c1xuICAgICAgdmFyIG5ld1dheXBvaW50cyA9IGdldE5ld1dheXBvaW50cyhpbkNvbm5lY3Rpb24ud2F5cG9pbnRzLCBvdXRDb25uZWN0aW9uLndheXBvaW50cyk7XG5cbiAgICAgIG1vZGVsaW5nLnJlY29ubmVjdEVuZChpbkNvbm5lY3Rpb24sIG91dENvbm5lY3Rpb24udGFyZ2V0LCBuZXdXYXlwb2ludHMpO1xuICAgIH1cbiAgfSk7XG5cbn1cblxuaW5oZXJpdHMoUmVtb3ZlRWxlbWVudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5SZW1vdmVFbGVtZW50QmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2JwbW5SdWxlcycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldERvY2tpbmcocG9pbnQpIHtcbiAgcmV0dXJuIHBvaW50Lm9yaWdpbmFsIHx8IHBvaW50O1xufVxuXG5cbmZ1bmN0aW9uIGdldE5ld1dheXBvaW50cyhpbldheXBvaW50cywgb3V0V2F5cG9pbnRzKSB7XG5cbiAgdmFyIGludGVyc2VjdGlvbiA9IGxpbmVJbnRlcnNlY3QoXG4gICAgZ2V0RG9ja2luZyhpbldheXBvaW50c1tpbldheXBvaW50cy5sZW5ndGggLSAyXSksXG4gICAgZ2V0RG9ja2luZyhpbldheXBvaW50c1tpbldheXBvaW50cy5sZW5ndGggLSAxXSksXG4gICAgZ2V0RG9ja2luZyhvdXRXYXlwb2ludHNbMV0pLFxuICAgIGdldERvY2tpbmcob3V0V2F5cG9pbnRzWzBdKSk7XG5cbiAgaWYgKGludGVyc2VjdGlvbikge1xuICAgIHJldHVybiBbXS5jb25jYXQoXG4gICAgICBpbldheXBvaW50cy5zbGljZSgwLCBpbldheXBvaW50cy5sZW5ndGggLSAxKSxcbiAgICAgIFsgaW50ZXJzZWN0aW9uIF0sXG4gICAgICBvdXRXYXlwb2ludHMuc2xpY2UoMSkpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbXG4gICAgICBnZXREb2NraW5nKGluV2F5cG9pbnRzWzBdKSxcbiAgICAgIGdldERvY2tpbmcob3V0V2F5cG9pbnRzW291dFdheXBvaW50cy5sZW5ndGggLSAxXSlcbiAgICBdO1xuICB9XG59IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5cbi8qKlxuICogQlBNTiBzcGVjaWZpYyByZW1vdmUgYmVoYXZpb3JcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVtb3ZlUGFydGljaXBhbnRCZWhhdmlvcihldmVudEJ1cywgbW9kZWxpbmcpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cblxuICAvKipcbiAgICogbW9ycGggY29sbGFib3JhdGlvbiBkaWFncmFtIGludG8gcHJvY2VzcyBkaWFncmFtXG4gICAqIGFmdGVyIHRoZSBsYXN0IHBhcnRpY2lwYW50IGhhcyBiZWVuIHJlbW92ZWRcbiAgICovXG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5kZWxldGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBwYXJlbnQgPSBzaGFwZS5wYXJlbnQ7XG5cbiAgICAvLyBhY3RpdmF0ZSB0aGUgYmVoYXZpb3IgaWYgdGhlIHNoYXBlIHRvIGJlIHJlbW92ZWRcbiAgICAvLyBpcyBhIHBhcnRpY2lwYW50XG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgICBjb250ZXh0LmNvbGxhYm9yYXRpb25Sb290ID0gcGFyZW50O1xuICAgIH1cbiAgfSwgdHJ1ZSk7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGNvbGxhYm9yYXRpb25Sb290ID0gY29udGV4dC5jb2xsYWJvcmF0aW9uUm9vdDtcblxuICAgIGlmIChjb2xsYWJvcmF0aW9uUm9vdCAmJiAhY29sbGFib3JhdGlvblJvb3QuYnVzaW5lc3NPYmplY3QucGFydGljaXBhbnRzLmxlbmd0aCkge1xuXG4gICAgICAvLyByZXBsYWNlIGVtcHR5IGNvbGxhYm9yYXRpb24gd2l0aCBwcm9jZXNzIGRpYWdyYW1cbiAgICAgIG1vZGVsaW5nLm1ha2VQcm9jZXNzKCk7XG4gICAgfVxuICB9LCB0cnVlKTtcblxufVxuXG5SZW1vdmVQYXJ0aWNpcGFudEJlaGF2aW9yLiRpbmplY3QgPSBbICdldmVudEJ1cycsICdtb2RlbGluZycgXTtcblxuaW5oZXJpdHMoUmVtb3ZlUGFydGljaXBhbnRCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTsiLCJpbXBvcnQge1xuICBmb3JFYWNoLFxuICBmaW5kLFxuICBtYXRjaFBhdHRlcm5cbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVwbGFjZUNvbm5lY3Rpb25CZWhhdmlvcihldmVudEJ1cywgbW9kZWxpbmcsIGJwbW5SdWxlcywgaW5qZWN0b3IpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdmFyIGRyYWdnaW5nID0gaW5qZWN0b3IuZ2V0KCdkcmFnZ2luZycsIGZhbHNlKTtcblxuICBmdW5jdGlvbiBmaXhDb25uZWN0aW9uKGNvbm5lY3Rpb24pIHtcblxuICAgIHZhciBzb3VyY2UgPSBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIHBhcmVudCA9IGNvbm5lY3Rpb24ucGFyZW50O1xuXG4gICAgLy8gZG8gbm90IGRvIGFueXRoaW5nIGlmIGNvbm5lY3Rpb25cbiAgICAvLyBpcyBhbHJlYWR5IGRlbGV0ZWQgKG1heSBoYXBwZW4gZHVlIHRvIG90aGVyXG4gICAgLy8gYmVoYXZpb3JzIHBsdWdnZWQtaW4gYmVmb3JlKVxuICAgIGlmICghcGFyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHJlcGxhY2VtZW50VHlwZSxcbiAgICAgICAgcmVtb3ZlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgaW5jb21pbmcgb3Igb3V0Z29pbmcgY29ubmVjdGlvbnNcbiAgICAgKiBjYW4gc3RheSBvciBjb3VsZCBiZSBzdWJzdGl0dXRlZCB3aXRoIGFuXG4gICAgICogYXBwcm9wcmlhdGUgcmVwbGFjZW1lbnQuXG4gICAgICpcbiAgICAgKiBUaGlzIGhvbGRzIHRydWUgZm9yIFNlcXVlbmNlRmxvdyA8PiBNZXNzYWdlRmxvdy5cbiAgICAgKi9cblxuICAgIGlmIChpcyhjb25uZWN0aW9uLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgICAgaWYgKCFicG1uUnVsZXMuY2FuQ29ubmVjdFNlcXVlbmNlRmxvdyhzb3VyY2UsIHRhcmdldCkpIHtcbiAgICAgICAgcmVtb3ZlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGJwbW5SdWxlcy5jYW5Db25uZWN0TWVzc2FnZUZsb3coc291cmNlLCB0YXJnZXQpKSB7XG4gICAgICAgIHJlcGxhY2VtZW50VHlwZSA9ICdicG1uOk1lc3NhZ2VGbG93JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB0cmFuc2Zvcm0gbWVzc2FnZSBmbG93cyBpbnRvIHNlcXVlbmNlIGZsb3dzLCBpZiBwb3NzaWJsZVxuXG4gICAgaWYgKGlzKGNvbm5lY3Rpb24sICdicG1uOk1lc3NhZ2VGbG93JykpIHtcblxuICAgICAgaWYgKCFicG1uUnVsZXMuY2FuQ29ubmVjdE1lc3NhZ2VGbG93KHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgICAgICByZW1vdmUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoYnBtblJ1bGVzLmNhbkNvbm5lY3RTZXF1ZW5jZUZsb3coc291cmNlLCB0YXJnZXQpKSB7XG4gICAgICAgIHJlcGxhY2VtZW50VHlwZSA9ICdicG1uOlNlcXVlbmNlRmxvdyc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzKGNvbm5lY3Rpb24sICdicG1uOkFzc29jaWF0aW9uJykgJiYgIWJwbW5SdWxlcy5jYW5Db25uZWN0QXNzb2NpYXRpb24oc291cmNlLCB0YXJnZXQpKSB7XG4gICAgICByZW1vdmUgPSB0cnVlO1xuICAgIH1cblxuXG4gICAgLy8gcmVtb3ZlIGludmFsaWQgY29ubmVjdGlvbixcbiAgICAvLyB1bmxlc3MgaXQgaGFzIGJlZW4gcmVtb3ZlZCBhbHJlYWR5XG4gICAgaWYgKHJlbW92ZSkge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihjb25uZWN0aW9uKTtcbiAgICB9XG5cbiAgICAvLyByZXBsYWNlIFNlcXVlbmNlRmxvdyA8PiBNZXNzYWdlRmxvd1xuXG4gICAgaWYgKHJlcGxhY2VtZW50VHlwZSkge1xuICAgICAgbW9kZWxpbmcuY29ubmVjdChzb3VyY2UsIHRhcmdldCwge1xuICAgICAgICB0eXBlOiByZXBsYWNlbWVudFR5cGUsXG4gICAgICAgIHdheXBvaW50czogY29ubmVjdGlvbi53YXlwb2ludHMuc2xpY2UoKVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVwbGFjZVJlY29ubmVjdGVkQ29ubmVjdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBzb3VyY2UgPSBjb250ZXh0Lm5ld1NvdXJjZSB8fCBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgdGFyZ2V0ID0gY29udGV4dC5uZXdUYXJnZXQgfHwgY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIGFsbG93ZWQsXG4gICAgICAgIHJlcGxhY2VtZW50O1xuXG4gICAgYWxsb3dlZCA9IGJwbW5SdWxlcy5jYW5Db25uZWN0KHNvdXJjZSwgdGFyZ2V0KTtcblxuICAgIGlmICghYWxsb3dlZCB8fCBhbGxvd2VkLnR5cGUgPT09IGNvbm5lY3Rpb24udHlwZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHJlcGxhY2VtZW50ID0gbW9kZWxpbmcuY29ubmVjdChzb3VyY2UsIHRhcmdldCwge1xuICAgICAgdHlwZTogYWxsb3dlZC50eXBlLFxuICAgICAgd2F5cG9pbnRzOiBjb25uZWN0aW9uLndheXBvaW50cy5zbGljZSgpXG4gICAgfSk7XG5cbiAgICAvLyByZW1vdmUgb2xkIGNvbm5lY3Rpb25cbiAgICBtb2RlbGluZy5yZW1vdmVDb25uZWN0aW9uKGNvbm5lY3Rpb24pO1xuXG4gICAgLy8gcmVwbGFjZSBjb25uZWN0aW9uIGluIGNvbnRleHQgdG8gcmVjb25uZWN0IGVuZC9zdGFydFxuICAgIGNvbnRleHQuY29ubmVjdGlvbiA9IHJlcGxhY2VtZW50O1xuXG4gICAgaWYgKGRyYWdnaW5nKSB7XG4gICAgICBjbGVhbkRyYWdnaW5nU2VsZWN0aW9uKGNvbm5lY3Rpb24sIHJlcGxhY2VtZW50KTtcbiAgICB9XG4gIH1cblxuICAvLyBtb25rZXktcGF0Y2ggc2VsZWN0aW9uIHNhdmVkIGluIGRyYWdnaW5nIGluIG9yZGVyIHRvIHJlLXNlbGVjdCBpdCB3aGVuIG9wZXJhdGlvbiBpcyBmaW5pc2hlZFxuICBmdW5jdGlvbiBjbGVhbkRyYWdnaW5nU2VsZWN0aW9uKG9sZENvbm5lY3Rpb24sIG5ld0Nvbm5lY3Rpb24pIHtcbiAgICB2YXIgY29udGV4dCA9IGRyYWdnaW5nLmNvbnRleHQoKSxcbiAgICAgICAgcHJldmlvdXNTZWxlY3Rpb24gPSBjb250ZXh0ICYmIGNvbnRleHQucGF5bG9hZC5wcmV2aW91c1NlbGVjdGlvbixcbiAgICAgICAgaW5kZXg7XG5cbiAgICAvLyBkbyBub3RoaW5nIGlmIG5vdCBkcmFnZ2luZyBvciBubyBzZWxlY3Rpb24gd2FzIHByZXNlbnRcbiAgICBpZiAoIXByZXZpb3VzU2VsZWN0aW9uIHx8ICFwcmV2aW91c1NlbGVjdGlvbi5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpbmRleCA9IHByZXZpb3VzU2VsZWN0aW9uLmluZGV4T2Yob2xkQ29ubmVjdGlvbik7XG5cbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcHJldmlvdXNTZWxlY3Rpb24uc3BsaWNlKGluZGV4LCAxLCBuZXdDb25uZWN0aW9uKTtcbiAgfVxuXG4gIC8vIGxpZmVjeWNsZSBob29rc1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdlbGVtZW50cy5tb3ZlJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGNsb3N1cmUgPSBjb250ZXh0LmNsb3N1cmUsXG4gICAgICAgIGFsbENvbm5lY3Rpb25zID0gY2xvc3VyZS5hbGxDb25uZWN0aW9ucztcblxuICAgIGZvckVhY2goYWxsQ29ubmVjdGlvbnMsIGZpeENvbm5lY3Rpb24pO1xuICB9LCB0cnVlKTtcblxuICB0aGlzLnByZUV4ZWN1dGUoJ2Nvbm5lY3Rpb24ucmVjb25uZWN0JywgcmVwbGFjZVJlY29ubmVjdGVkQ29ubmVjdGlvbik7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoJ2VsZW1lbnQudXBkYXRlUHJvcGVydGllcycsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBwcm9wZXJ0aWVzID0gY29udGV4dC5wcm9wZXJ0aWVzLFxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBidXNpbmVzc09iamVjdCA9IGVsZW1lbnQuYnVzaW5lc3NPYmplY3QsXG4gICAgICAgIGNvbm5lY3Rpb247XG5cbiAgICAvLyByZW1vdmUgY29uZGl0aW9uIG9uIGNoYW5nZSB0byBkZWZhdWx0XG4gICAgaWYgKHByb3BlcnRpZXMuZGVmYXVsdCkge1xuICAgICAgY29ubmVjdGlvbiA9IGZpbmQoXG4gICAgICAgIGVsZW1lbnQub3V0Z29pbmcsXG4gICAgICAgIG1hdGNoUGF0dGVybih7IGlkOiBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LmRlZmF1bHQuaWQgfSlcbiAgICAgICk7XG5cbiAgICAgIGlmIChjb25uZWN0aW9uKSB7XG4gICAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoY29ubmVjdGlvbiwgeyBjb25kaXRpb25FeHByZXNzaW9uOiB1bmRlZmluZWQgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGRlZmF1bHQgZnJvbSBzb3VyY2Ugb24gY2hhbmdlIHRvIGNvbmRpdGlvbmFsXG4gICAgaWYgKHByb3BlcnRpZXMuY29uZGl0aW9uRXhwcmVzc2lvbiAmJiBidXNpbmVzc09iamVjdC5zb3VyY2VSZWYuZGVmYXVsdCA9PT0gYnVzaW5lc3NPYmplY3QpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudC5zb3VyY2UsIHsgZGVmYXVsdDogdW5kZWZpbmVkIH0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmluaGVyaXRzKFJlcGxhY2VDb25uZWN0aW9uQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cblJlcGxhY2VDb25uZWN0aW9uQmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGVsaW5nJyxcbiAgJ2JwbW5SdWxlcycsXG4gICdpbmplY3Rvcidcbl07XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXNFdmVudFN1YlByb2Nlc3MgfSBmcm9tICcuLi8uLi8uLi91dGlsL0RpVXRpbCc7XG5cblxuLyoqXG4gKiBCUE1OLXNwZWNpZmljIHJlcGxhY2UgYmVoYXZpb3IuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlcGxhY2VFbGVtZW50QmVoYXZpb3VyKFxuICAgIGJwbW5SZXBsYWNlLFxuICAgIGJwbW5SdWxlcyxcbiAgICBlbGVtZW50UmVnaXN0cnksXG4gICAgaW5qZWN0b3IsXG4gICAgbW9kZWxpbmcsXG4gICAgc2VsZWN0aW9uXG4pIHtcbiAgaW5qZWN0b3IuaW52b2tlKENvbW1hbmRJbnRlcmNlcHRvciwgdGhpcyk7XG5cbiAgdGhpcy5fYnBtblJlcGxhY2UgPSBicG1uUmVwbGFjZTtcbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9zZWxlY3Rpb24gPSBzZWxlY3Rpb247XG5cbiAgLy8gcmVwbGFjZSBlbGVtZW50cyBvbiBtb3ZlXG4gIHRoaXMucG9zdEV4ZWN1dGVkKFsgJ2VsZW1lbnRzLm1vdmUnIF0sIDUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQubmV3UGFyZW50LFxuICAgICAgICBuZXdIb3N0ID0gY29udGV4dC5uZXdIb3N0LFxuICAgICAgICBlbGVtZW50cyA9IFtdO1xuXG4gICAgZm9yRWFjaChjb250ZXh0LmNsb3N1cmUudG9wTGV2ZWwsIGZ1bmN0aW9uKHRvcExldmVsRWxlbWVudHMpIHtcbiAgICAgIGlmIChpc0V2ZW50U3ViUHJvY2Vzcyh0b3BMZXZlbEVsZW1lbnRzKSkge1xuICAgICAgICBlbGVtZW50cyA9IGVsZW1lbnRzLmNvbmNhdCh0b3BMZXZlbEVsZW1lbnRzLmNoaWxkcmVuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnRzID0gZWxlbWVudHMuY29uY2F0KHRvcExldmVsRWxlbWVudHMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gc2V0IHRhcmdldCB0byBob3N0IGlmIGF0dGFjaGluZ1xuICAgIGlmIChlbGVtZW50cy5sZW5ndGggPT09IDEgJiYgbmV3SG9zdCkge1xuICAgICAgdGFyZ2V0ID0gbmV3SG9zdDtcbiAgICB9XG5cbiAgICB2YXIgY2FuUmVwbGFjZSA9IGJwbW5SdWxlcy5jYW5SZXBsYWNlKGVsZW1lbnRzLCB0YXJnZXQpO1xuXG4gICAgaWYgKGNhblJlcGxhY2UpIHtcbiAgICAgIHRoaXMucmVwbGFjZUVsZW1lbnRzKGVsZW1lbnRzLCBjYW5SZXBsYWNlLnJlcGxhY2VtZW50cywgbmV3SG9zdCk7XG4gICAgfVxuICB9LCB0aGlzKTtcblxuICAvLyB1cGRhdGUgYXR0YWNobWVudHMgb24gaG9zdCByZXBsYWNlXG4gIHRoaXMucG9zdEV4ZWN1dGUoWyAnc2hhcGUucmVwbGFjZScgXSwgMTUwMCwgZnVuY3Rpb24oZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBvbGRTaGFwZSA9IGNvbnRleHQub2xkU2hhcGUsXG4gICAgICAgIG5ld1NoYXBlID0gY29udGV4dC5uZXdTaGFwZSxcbiAgICAgICAgYXR0YWNoZXJzID0gb2xkU2hhcGUuYXR0YWNoZXJzLFxuICAgICAgICBjYW5SZXBsYWNlO1xuXG4gICAgaWYgKGF0dGFjaGVycyAmJiBhdHRhY2hlcnMubGVuZ3RoKSB7XG4gICAgICBjYW5SZXBsYWNlID0gYnBtblJ1bGVzLmNhblJlcGxhY2UoYXR0YWNoZXJzLCBuZXdTaGFwZSk7XG5cbiAgICAgIHRoaXMucmVwbGFjZUVsZW1lbnRzKGF0dGFjaGVycywgY2FuUmVwbGFjZS5yZXBsYWNlbWVudHMpO1xuICAgIH1cblxuICB9LCB0aGlzKTtcblxuICAvLyBrZWVwIElEIG9uIHNoYXBlIHJlcGxhY2VcbiAgdGhpcy5wb3N0RXhlY3V0ZWQoWyAnc2hhcGUucmVwbGFjZScgXSwgMTUwMCwgZnVuY3Rpb24oZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBvbGRTaGFwZSA9IGNvbnRleHQub2xkU2hhcGUsXG4gICAgICAgIG5ld1NoYXBlID0gY29udGV4dC5uZXdTaGFwZTtcblxuICAgIG1vZGVsaW5nLnVuY2xhaW1JZChvbGRTaGFwZS5idXNpbmVzc09iamVjdC5pZCwgb2xkU2hhcGUuYnVzaW5lc3NPYmplY3QpO1xuICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMobmV3U2hhcGUsIHsgaWQ6IG9sZFNoYXBlLmlkIH0pO1xuICB9KTtcbn1cblxuaW5oZXJpdHMoUmVwbGFjZUVsZW1lbnRCZWhhdmlvdXIsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cblJlcGxhY2VFbGVtZW50QmVoYXZpb3VyLnByb3RvdHlwZS5yZXBsYWNlRWxlbWVudHMgPSBmdW5jdGlvbihlbGVtZW50cywgbmV3RWxlbWVudHMpIHtcbiAgdmFyIGVsZW1lbnRSZWdpc3RyeSA9IHRoaXMuX2VsZW1lbnRSZWdpc3RyeSxcbiAgICAgIGJwbW5SZXBsYWNlID0gdGhpcy5fYnBtblJlcGxhY2UsXG4gICAgICBzZWxlY3Rpb24gPSB0aGlzLl9zZWxlY3Rpb247XG5cbiAgZm9yRWFjaChuZXdFbGVtZW50cywgZnVuY3Rpb24ocmVwbGFjZW1lbnQpIHtcbiAgICB2YXIgbmV3RWxlbWVudCA9IHtcbiAgICAgIHR5cGU6IHJlcGxhY2VtZW50Lm5ld0VsZW1lbnRUeXBlXG4gICAgfTtcblxuICAgIHZhciBvbGRFbGVtZW50ID0gZWxlbWVudFJlZ2lzdHJ5LmdldChyZXBsYWNlbWVudC5vbGRFbGVtZW50SWQpO1xuXG4gICAgdmFyIGlkeCA9IGVsZW1lbnRzLmluZGV4T2Yob2xkRWxlbWVudCk7XG5cbiAgICBlbGVtZW50c1tpZHhdID0gYnBtblJlcGxhY2UucmVwbGFjZUVsZW1lbnQob2xkRWxlbWVudCwgbmV3RWxlbWVudCwgeyBzZWxlY3Q6IGZhbHNlIH0pO1xuICB9KTtcblxuICBpZiAobmV3RWxlbWVudHMpIHtcbiAgICBzZWxlY3Rpb24uc2VsZWN0KGVsZW1lbnRzKTtcbiAgfVxufTtcblxuUmVwbGFjZUVsZW1lbnRCZWhhdmlvdXIuJGluamVjdCA9IFtcbiAgJ2JwbW5SZXBsYWNlJyxcbiAgJ2JwbW5SdWxlcycsXG4gICdlbGVtZW50UmVnaXN0cnknLFxuICAnaW5qZWN0b3InLFxuICAnbW9kZWxpbmcnLFxuICAnc2VsZWN0aW9uJ1xuXTtcbiIsImltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xyXG5cclxuaW1wb3J0IHsgaXNFeHBhbmRlZCB9IGZyb20gJy4uLy4uLy4uL3V0aWwvRGlVdGlsJztcclxuXHJcbmltcG9ydCB7IGdldFBhcnRpY2lwYW50UmVzaXplQ29uc3RyYWludHMgfSBmcm9tICcuL3V0aWwvUmVzaXplVXRpbCc7XHJcblxyXG52YXIgSElHSF9QUklPUklUWSA9IDE1MDA7XHJcblxyXG5leHBvcnQgdmFyIExBTkVfTUlOX0RJTUVOU0lPTlMgPSB7IHdpZHRoOiAzMDAsIGhlaWdodDogNjAgfTtcclxuXHJcbmV4cG9ydCB2YXIgUEFSVElDSVBBTlRfTUlOX0RJTUVOU0lPTlMgPSB7IHdpZHRoOiAzMDAsIGhlaWdodDogMTUwIH07XHJcblxyXG5leHBvcnQgdmFyIFNVQl9QUk9DRVNTX01JTl9ESU1FTlNJT05TID0geyB3aWR0aDogMTQwLCBoZWlnaHQ6IDEyMCB9O1xyXG5cclxuZXhwb3J0IHZhciBURVhUX0FOTk9UQVRJT05fTUlOX0RJTUVOU0lPTlMgPSB7IHdpZHRoOiA1MCwgaGVpZ2h0OiAzMCB9O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBTZXQgbWluaW11bSBib3VuZHMvcmVzaXplIGNvbnN0cmFpbnRzIG9uIHJlc2l6ZS5cclxuICpcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlc2l6ZUJlaGF2aW9yKGV2ZW50QnVzKSB7XHJcbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5zdGFydCcsIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxyXG4gICAgICAgIGRpcmVjdGlvbiA9IGNvbnRleHQuZGlyZWN0aW9uLFxyXG4gICAgICAgIGJhbGFuY2VkID0gY29udGV4dC5iYWxhbmNlZDtcclxuXHJcbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkxhbmUnKSB8fCBpcyhzaGFwZSwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICBjb250ZXh0LnJlc2l6ZUNvbnN0cmFpbnRzID0gZ2V0UGFydGljaXBhbnRSZXNpemVDb25zdHJhaW50cyhzaGFwZSwgZGlyZWN0aW9uLCBiYWxhbmNlZCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICAgIGNvbnRleHQubWluRGltZW5zaW9ucyA9IFBBUlRJQ0lQQU5UX01JTl9ESU1FTlNJT05TO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpcyhzaGFwZSwgJ2JwbW46U3ViUHJvY2VzcycpICYmIGlzRXhwYW5kZWQoc2hhcGUpKSB7XHJcbiAgICAgIGNvbnRleHQubWluRGltZW5zaW9ucyA9IFNVQl9QUk9DRVNTX01JTl9ESU1FTlNJT05TO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpcyhzaGFwZSwgJ2JwbW46VGV4dEFubm90YXRpb24nKSkge1xyXG4gICAgICBjb250ZXh0Lm1pbkRpbWVuc2lvbnMgPSBURVhUX0FOTk9UQVRJT05fTUlOX0RJTUVOU0lPTlM7XHJcbiAgICB9XHJcbiAgfSk7XHJcbn1cclxuXHJcblJlc2l6ZUJlaGF2aW9yLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTsiLCJpbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgcm91bmRCb3VuZHNcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBoYXNQcmltYXJ5TW9kaWZpZXJcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9Nb3VzZSc7XG5cbnZhciBTTElHSFRMWV9ISUdIRVJfUFJJT1JJVFkgPSAxMDAxO1xuXG5cbi8qKlxuICogSW52b2tlIHtAbGluayBNb2RlbGluZyNyZXNpemVMYW5lfSBpbnN0ZWFkIG9mXG4gKiB7QGxpbmsgTW9kZWxpbmcjcmVzaXplU2hhcGV9IHdoZW4gcmVzaXppbmcgYSBMYW5lXG4gKiBvciBQYXJ0aWNpcGFudCBzaGFwZS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVzaXplTGFuZUJlaGF2aW9yKGV2ZW50QnVzLCBtb2RlbGluZykge1xuXG4gIGV2ZW50QnVzLm9uKCdyZXNpemUuc3RhcnQnLCBTTElHSFRMWV9ISUdIRVJfUFJJT1JJVFkgKyA1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkxhbmUnKSB8fCBpcyhzaGFwZSwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuXG4gICAgICAvLyBzaG91bGQgd2UgcmVzaXplIHRoZSBvcHBvc2l0ZSBsYW5lKHMpIGluXG4gICAgICAvLyBvcmRlciB0byBjb21wZW5zYXRlIGZvciB0aGUgcmVzaXplIG9wZXJhdGlvbj9cbiAgICAgIGNvbnRleHQuYmFsYW5jZWQgPSAhaGFzUHJpbWFyeU1vZGlmaWVyKGV2ZW50KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBJbnRlcmNlcHQgcmVzaXplIGVuZCBhbmQgY2FsbCByZXNpemUgbGFuZSBmdW5jdGlvbiBpbnN0ZWFkLlxuICAgKi9cbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5lbmQnLCBTTElHSFRMWV9ISUdIRVJfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIGNhbkV4ZWN1dGUgPSBjb250ZXh0LmNhbkV4ZWN1dGUsXG4gICAgICAgIG5ld0JvdW5kcyA9IGNvbnRleHQubmV3Qm91bmRzO1xuXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpMYW5lJykgfHwgaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykpIHtcblxuICAgICAgaWYgKGNhbkV4ZWN1dGUpIHtcblxuICAgICAgICAvLyBlbnN1cmUgd2UgaGF2ZSBhY3R1YWwgcGl4ZWwgdmFsdWVzIGZvciBuZXcgYm91bmRzXG4gICAgICAgIC8vIChpbXBvcnRhbnQgd2hlbiB6b29tIGxldmVsIHdhcyA+IDEgZHVyaW5nIG1vdmUpXG4gICAgICAgIG5ld0JvdW5kcyA9IHJvdW5kQm91bmRzKG5ld0JvdW5kcyk7XG5cbiAgICAgICAgLy8gcGVyZm9ybSB0aGUgYWN0dWFsIHJlc2l6ZVxuICAgICAgICBtb2RlbGluZy5yZXNpemVMYW5lKHNoYXBlLCBuZXdCb3VuZHMsIGNvbnRleHQuYmFsYW5jZWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBzdG9wIHByb3BhZ2F0aW9uXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbn1cblxuUmVzaXplTGFuZUJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xyXG5cclxuaW1wb3J0IHtcclxuICBmaW5kLFxyXG4gIGlzQXJyYXksXHJcbiAgbWF0Y2hQYXR0ZXJuLFxyXG4gIHNvbWVcclxufSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcclxuXHJcbmltcG9ydCB7XHJcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXHJcbiAgcmVtb3ZlIGFzIGNvbGxlY3Rpb25SZW1vdmVcclxufSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zJztcclxuXHJcbmltcG9ydCB7XHJcbiAgZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgaXNcclxufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0FueSB9IGZyb20gJy4uL3V0aWwvTW9kZWxpbmdVdGlsJztcclxuXHJcbmltcG9ydCB7IGhhc0V2ZW50RGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uL3V0aWwvRGlVdGlsJztcclxuXHJcbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XHJcblxyXG5cclxuLyoqXHJcbiAqIEFkZCByZWZlcmVuY2VkIHJvb3QgZWxlbWVudHMgKGVycm9yLCBlc2NhbGF0aW9uLCBtZXNzYWdlLCBzaWduYWwpIGlmIHRoZXkgZG9uJ3QgZXhpc3QuXHJcbiAqIENvcHkgcmVmZXJlbmNlZCByb290IGVsZW1lbnRzIG9uIGNvcHkgJiBwYXN0ZS5cclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3IoXHJcbiAgICBicG1uanMsIGV2ZW50QnVzLCBpbmplY3RvciwgbW9kZGxlQ29weSwgYnBtbkZhY3RvcnlcclxuKSB7XHJcbiAgaW5qZWN0b3IuaW52b2tlKENvbW1hbmRJbnRlcmNlcHRvciwgdGhpcyk7XHJcblxyXG4gIGZ1bmN0aW9uIGNhbkhhdmVSb290RWxlbWVudFJlZmVyZW5jZShlbGVtZW50KSB7XHJcbiAgICByZXR1cm4gaXNBbnkoZWxlbWVudCwgWyAnYnBtbjpSZWNlaXZlVGFzaycsICdicG1uOlNlbmRUYXNrJyBdKSB8fFxyXG4gICAgICBoYXNBbnlFdmVudERlZmluaXRpb24oZWxlbWVudCwgW1xyXG4gICAgICAgICdicG1uOkVycm9yRXZlbnREZWZpbml0aW9uJyxcclxuICAgICAgICAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJyxcclxuICAgICAgICAnYnBtbjpNZXNzYWdlRXZlbnREZWZpbml0aW9uJyxcclxuICAgICAgICAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nXHJcbiAgICAgIF0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gaGFzUm9vdEVsZW1lbnQocm9vdEVsZW1lbnQpIHtcclxuICAgIHZhciBkZWZpbml0aW9ucyA9IGJwbW5qcy5nZXREZWZpbml0aW9ucygpLFxyXG4gICAgICAgIHJvb3RFbGVtZW50cyA9IGRlZmluaXRpb25zLmdldCgncm9vdEVsZW1lbnRzJyk7XHJcblxyXG4gICAgcmV0dXJuICEhZmluZChyb290RWxlbWVudHMsIG1hdGNoUGF0dGVybih7IGlkOiByb290RWxlbWVudC5pZCB9KSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBnZXRSb290RWxlbWVudFJlZmVyZW5jZVByb3BlcnR5TmFtZShldmVudERlZmluaXRpb24pIHtcclxuICAgIGlmIChpcyhldmVudERlZmluaXRpb24sICdicG1uOkVycm9yRXZlbnREZWZpbml0aW9uJykpIHtcclxuICAgICAgcmV0dXJuICdlcnJvclJlZic7XHJcbiAgICB9IGVsc2UgaWYgKGlzKGV2ZW50RGVmaW5pdGlvbiwgJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicpKSB7XHJcbiAgICAgIHJldHVybiAnZXNjYWxhdGlvblJlZic7XHJcbiAgICB9IGVsc2UgaWYgKGlzKGV2ZW50RGVmaW5pdGlvbiwgJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbicpKSB7XHJcbiAgICAgIHJldHVybiAnbWVzc2FnZVJlZic7XHJcbiAgICB9IGVsc2UgaWYgKGlzKGV2ZW50RGVmaW5pdGlvbiwgJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJykpIHtcclxuICAgICAgcmV0dXJuICdzaWduYWxSZWYnO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0Um9vdEVsZW1lbnQoYnVzaW5lc3NPYmplY3QpIHtcclxuICAgIGlmIChpc0FueShidXNpbmVzc09iamVjdCwgWyAnYnBtbjpSZWNlaXZlVGFzaycsICdicG1uOlNlbmRUYXNrJyBdKSkge1xyXG4gICAgICByZXR1cm4gYnVzaW5lc3NPYmplY3QuZ2V0KCdtZXNzYWdlUmVmJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGV2ZW50RGVmaW5pdGlvbnMgPSBidXNpbmVzc09iamVjdC5nZXQoJ2V2ZW50RGVmaW5pdGlvbnMnKSxcclxuICAgICAgICBldmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25zWyAwIF07XHJcblxyXG4gICAgcmV0dXJuIGV2ZW50RGVmaW5pdGlvbi5nZXQoZ2V0Um9vdEVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eU5hbWUoZXZlbnREZWZpbml0aW9uKSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBzZXRSb290RWxlbWVudChidXNpbmVzc09iamVjdCwgcm9vdEVsZW1lbnQpIHtcclxuICAgIGlmIChpc0FueShidXNpbmVzc09iamVjdCwgWyAnYnBtbjpSZWNlaXZlVGFzaycsICdicG1uOlNlbmRUYXNrJyBdKSkge1xyXG4gICAgICByZXR1cm4gYnVzaW5lc3NPYmplY3Quc2V0KCdtZXNzYWdlUmVmJywgcm9vdEVsZW1lbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBldmVudERlZmluaXRpb25zID0gYnVzaW5lc3NPYmplY3QuZ2V0KCdldmVudERlZmluaXRpb25zJyksXHJcbiAgICAgICAgZXZlbnREZWZpbml0aW9uID0gZXZlbnREZWZpbml0aW9uc1sgMCBdO1xyXG5cclxuICAgIHJldHVybiBldmVudERlZmluaXRpb24uc2V0KGdldFJvb3RFbGVtZW50UmVmZXJlbmNlUHJvcGVydHlOYW1lKGV2ZW50RGVmaW5pdGlvbiksIHJvb3RFbGVtZW50KTtcclxuICB9XHJcblxyXG4gIC8vIGNyZWF0ZSBzaGFwZVxyXG4gIHRoaXMuZXhlY3V0ZWQoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XHJcblxyXG4gICAgaWYgKCFjYW5IYXZlUm9vdEVsZW1lbnRSZWZlcmVuY2Uoc2hhcGUpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChzaGFwZSksXHJcbiAgICAgICAgcm9vdEVsZW1lbnQgPSBnZXRSb290RWxlbWVudChidXNpbmVzc09iamVjdCksXHJcbiAgICAgICAgcm9vdEVsZW1lbnRzO1xyXG5cclxuICAgIGlmIChyb290RWxlbWVudCAmJiAhaGFzUm9vdEVsZW1lbnQocm9vdEVsZW1lbnQpKSB7XHJcbiAgICAgIHJvb3RFbGVtZW50cyA9IGJwbW5qcy5nZXREZWZpbml0aW9ucygpLmdldCgncm9vdEVsZW1lbnRzJyk7XHJcblxyXG4gICAgICAvLyBhZGQgcm9vdCBlbGVtZW50XHJcbiAgICAgIGNvbGxlY3Rpb25BZGQocm9vdEVsZW1lbnRzLCByb290RWxlbWVudCk7XHJcblxyXG4gICAgICBjb250ZXh0LmFkZGVkUm9vdEVsZW1lbnQgPSByb290RWxlbWVudDtcclxuICAgIH1cclxuICB9LCB0cnVlKTtcclxuXHJcbiAgdGhpcy5yZXZlcnRlZCgnc2hhcGUuY3JlYXRlJywgZnVuY3Rpb24oY29udGV4dCkge1xyXG4gICAgdmFyIGFkZGVkUm9vdEVsZW1lbnQgPSBjb250ZXh0LmFkZGVkUm9vdEVsZW1lbnQ7XHJcblxyXG4gICAgaWYgKCFhZGRlZFJvb3RFbGVtZW50KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcm9vdEVsZW1lbnRzID0gYnBtbmpzLmdldERlZmluaXRpb25zKCkuZ2V0KCdyb290RWxlbWVudHMnKTtcclxuXHJcbiAgICAvLyByZW1vdmUgcm9vdCBlbGVtZW50XHJcbiAgICBjb2xsZWN0aW9uUmVtb3ZlKHJvb3RFbGVtZW50cywgYWRkZWRSb290RWxlbWVudCk7XHJcbiAgfSwgdHJ1ZSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdjb3B5UGFzdGUuY29weUVsZW1lbnQnLCBmdW5jdGlvbihjb250ZXh0KSB7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGNvbnRleHQuZGVzY3JpcHRvcixcclxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50O1xyXG5cclxuICAgIGlmICghY2FuSGF2ZVJvb3RFbGVtZW50UmVmZXJlbmNlKGVsZW1lbnQpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICByb290RWxlbWVudCA9IGdldFJvb3RFbGVtZW50KGJ1c2luZXNzT2JqZWN0KTtcclxuXHJcbiAgICBpZiAocm9vdEVsZW1lbnQpIHtcclxuICAgICAgZGVzY3JpcHRvci5yZWZlcmVuY2VkUm9vdEVsZW1lbnQgPSByb290RWxlbWVudDtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgZXZlbnRCdXMub24oJ2NvcHlQYXN0ZS5wYXN0ZUVsZW1lbnQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIHZhciBkZXNjcmlwdG9yID0gY29udGV4dC5kZXNjcmlwdG9yLFxyXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0ID0gZGVzY3JpcHRvci5idXNpbmVzc09iamVjdDtcclxuXHJcbiAgICBpZiAoIWNhbkhhdmVSb290RWxlbWVudFJlZmVyZW5jZShidXNpbmVzc09iamVjdCkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciByZWZlcmVuY2VkUm9vdEVsZW1lbnQgPSBkZXNjcmlwdG9yLnJlZmVyZW5jZWRSb290RWxlbWVudDtcclxuXHJcbiAgICBpZiAoIXJlZmVyZW5jZWRSb290RWxlbWVudCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFoYXNSb290RWxlbWVudChyZWZlcmVuY2VkUm9vdEVsZW1lbnQpKSB7XHJcbiAgICAgIHJlZmVyZW5jZWRSb290RWxlbWVudCA9IG1vZGRsZUNvcHkuY29weUVsZW1lbnQoXHJcbiAgICAgICAgcmVmZXJlbmNlZFJvb3RFbGVtZW50LFxyXG4gICAgICAgIGJwbW5GYWN0b3J5LmNyZWF0ZShyZWZlcmVuY2VkUm9vdEVsZW1lbnQuJHR5cGUpXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0Um9vdEVsZW1lbnQoYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRSb290RWxlbWVudCk7XHJcbiAgfSk7XHJcbn1cclxuXHJcblJvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3IuJGluamVjdCA9IFtcclxuICAnYnBtbmpzJyxcclxuICAnZXZlbnRCdXMnLFxyXG4gICdpbmplY3RvcicsXHJcbiAgJ21vZGRsZUNvcHknLFxyXG4gICdicG1uRmFjdG9yeSdcclxuXTtcclxuXHJcbmluaGVyaXRzKFJvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIGhhc0FueUV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCB0eXBlcykge1xyXG4gIGlmICghaXNBcnJheSh0eXBlcykpIHtcclxuICAgIHR5cGVzID0gWyB0eXBlcyBdO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHNvbWUodHlwZXMsIGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgdHlwZSk7XHJcbiAgfSk7XHJcbn0iLCJpbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0V4cGFuZGVkIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9EaVV0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBMQU5FX01JTl9ESU1FTlNJT05TLFxyXG4gIFBBUlRJQ0lQQU5UX01JTl9ESU1FTlNJT05TLFxyXG4gIFNVQl9QUk9DRVNTX01JTl9ESU1FTlNJT05TLFxyXG4gIFRFWFRfQU5OT1RBVElPTl9NSU5fRElNRU5TSU9OU1xyXG59IGZyb20gJy4vUmVzaXplQmVoYXZpb3InO1xyXG5cclxuaW1wb3J0IHsgZ2V0Q2hpbGRMYW5lcyB9IGZyb20gJy4uL3V0aWwvTGFuZVV0aWwnO1xyXG5cclxudmFyIG1heCA9IE1hdGgubWF4O1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNwYWNlVG9vbEJlaGF2aW9yKGV2ZW50QnVzKSB7XHJcbiAgZXZlbnRCdXMub24oJ3NwYWNlVG9vbC5nZXRNaW5EaW1lbnNpb25zJywgZnVuY3Rpb24oY29udGV4dCkge1xyXG4gICAgdmFyIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzLFxyXG4gICAgICAgIGF4aXMgPSBjb250ZXh0LmF4aXMsXHJcbiAgICAgICAgc3RhcnQgPSBjb250ZXh0LnN0YXJ0LFxyXG4gICAgICAgIG1pbkRpbWVuc2lvbnMgPSB7fTtcclxuXHJcbiAgICBmb3JFYWNoKHNoYXBlcywgZnVuY3Rpb24oc2hhcGUpIHtcclxuICAgICAgdmFyIGlkID0gc2hhcGUuaWQ7XHJcblxyXG4gICAgICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuXHJcbiAgICAgICAgaWYgKGlzSG9yaXpvbnRhbChheGlzKSkge1xyXG4gICAgICAgICAgbWluRGltZW5zaW9uc1sgaWQgXSA9IFBBUlRJQ0lQQU5UX01JTl9ESU1FTlNJT05TO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBtaW5EaW1lbnNpb25zWyBpZCBdID0ge1xyXG4gICAgICAgICAgICB3aWR0aDogUEFSVElDSVBBTlRfTUlOX0RJTUVOU0lPTlMud2lkdGgsXHJcbiAgICAgICAgICAgIGhlaWdodDogZ2V0UGFydGljaXBhbnRNaW5IZWlnaHQoc2hhcGUsIHN0YXJ0KVxyXG4gICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXMoc2hhcGUsICdicG1uOlN1YlByb2Nlc3MnKSAmJiBpc0V4cGFuZGVkKHNoYXBlKSkge1xyXG4gICAgICAgIG1pbkRpbWVuc2lvbnNbIGlkIF0gPSBTVUJfUFJPQ0VTU19NSU5fRElNRU5TSU9OUztcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XHJcbiAgICAgICAgbWluRGltZW5zaW9uc1sgaWQgXSA9IFRFWFRfQU5OT1RBVElPTl9NSU5fRElNRU5TSU9OUztcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIG1pbkRpbWVuc2lvbnM7XHJcbiAgfSk7XHJcbn1cclxuXHJcblNwYWNlVG9vbEJlaGF2aW9yLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTtcclxuXHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuZnVuY3Rpb24gaXNIb3Jpem9udGFsKGF4aXMpIHtcclxuICByZXR1cm4gYXhpcyA9PT0gJ3gnO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IG1pbmltdW0gaGVpZ2h0IGZvciBwYXJ0aWNpcGFudCB0YWtpbmcgbGFuZXMgaW50byBhY2NvdW50LlxyXG4gKlxyXG4gKiBAcGFyYW0gezxkanMubW9kZWwuU2hhcGU+fSBwYXJ0aWNpcGFudFxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcclxuICpcclxuICogQHJldHVybnMge09iamVjdH1cclxuICovXHJcbmZ1bmN0aW9uIGdldFBhcnRpY2lwYW50TWluSGVpZ2h0KHBhcnRpY2lwYW50LCBzdGFydCkge1xyXG4gIHZhciBsYW5lc01pbkhlaWdodDtcclxuXHJcbiAgaWYgKCFoYXNDaGlsZExhbmVzKHBhcnRpY2lwYW50KSkge1xyXG4gICAgcmV0dXJuIFBBUlRJQ0lQQU5UX01JTl9ESU1FTlNJT05TLmhlaWdodDtcclxuICB9XHJcblxyXG4gIGxhbmVzTWluSGVpZ2h0ID0gZ2V0TGFuZXNNaW5IZWlnaHQocGFydGljaXBhbnQsIHN0YXJ0KTtcclxuXHJcbiAgcmV0dXJuIG1heChQQVJUSUNJUEFOVF9NSU5fRElNRU5TSU9OUy5oZWlnaHQsIGxhbmVzTWluSGVpZ2h0KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaGFzQ2hpbGRMYW5lcyhlbGVtZW50KSB7XHJcbiAgcmV0dXJuICEhZ2V0Q2hpbGRMYW5lcyhlbGVtZW50KS5sZW5ndGg7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldExhbmVzTWluSGVpZ2h0KHBhcnRpY2lwYW50LCByZXNpemVTdGFydCkge1xyXG4gIHZhciBsYW5lcyA9IGdldENoaWxkTGFuZXMocGFydGljaXBhbnQpLFxyXG4gICAgICByZXNpemVkTGFuZTtcclxuXHJcbiAgLy8gZmluZCB0aGUgbmVzdGVkIGxhbmUgd2hpY2ggaXMgY3VycmVudGx5IHJlc2l6ZWRcclxuICByZXNpemVkTGFuZSA9IGZpbmRSZXNpemVkTGFuZShsYW5lcywgcmVzaXplU3RhcnQpO1xyXG5cclxuICAvLyByZXNpemVkIGxhbmUgY2Fubm90IHNocmluayBiZWxvdyB0aGUgbWluaW11bSBoZWlnaHRcclxuICAvLyBidXQgcmVtYWluaW5nIGxhbmVzJyBkaW1lbnNpb25zIGFyZSBrZXB0IGludGFjdFxyXG4gIHJldHVybiBwYXJ0aWNpcGFudC5oZWlnaHQgLSByZXNpemVkTGFuZS5oZWlnaHQgKyBMQU5FX01JTl9ESU1FTlNJT05TLmhlaWdodDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbmQgbmVzdGVkIGxhbmUgd2hpY2ggaXMgY3VycmVudGx5IHJlc2l6ZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLlNoYXBlPn0gbGFuZXNcclxuICogQHBhcmFtIHtudW1iZXJ9IHJlc2l6ZVN0YXJ0XHJcbiAqL1xyXG5mdW5jdGlvbiBmaW5kUmVzaXplZExhbmUobGFuZXMsIHJlc2l6ZVN0YXJ0KSB7XHJcbiAgdmFyIGksIGxhbmUsIGNoaWxkTGFuZXM7XHJcblxyXG4gIGZvciAoaSA9IDA7IGkgPCBsYW5lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgbGFuZSA9IGxhbmVzW2ldO1xyXG5cclxuICAgIC8vIHJlc2l6aW5nIGN1cnJlbnQgbGFuZSBvciBhIGxhbmUgbmVzdGVkXHJcbiAgICBpZiAocmVzaXplU3RhcnQgPj0gbGFuZS55ICYmIHJlc2l6ZVN0YXJ0IDw9IGxhbmUueSArIGxhbmUuaGVpZ2h0KSB7XHJcbiAgICAgIGNoaWxkTGFuZXMgPSBnZXRDaGlsZExhbmVzKGxhbmUpO1xyXG5cclxuICAgICAgLy8gYSBuZXN0ZWQgbGFuZSBpcyByZXNpemVkXHJcbiAgICAgIGlmIChjaGlsZExhbmVzLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBmaW5kUmVzaXplZExhbmUoY2hpbGRMYW5lcywgcmVzaXplU3RhcnQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBjdXJyZW50IGxhbmUgaXMgdGhlIHJlc2l6ZWQgb25lXHJcbiAgICAgIHJldHVybiBsYW5lO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5pbXBvcnQgeyBpc0V4cGFuZGVkIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9EaVV0aWwuanMnO1xuXG4vKipcbiAqIEFkZCBzdGFydCBldmVudCByZXBsYWNpbmcgZWxlbWVudCB3aXRoIGV4cGFuZGVkIHN1YiBwcm9jZXNzLlxuICpcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBTdWJQcm9jZXNzU3RhcnRFdmVudEJlaGF2aW9yKGluamVjdG9yLCBtb2RlbGluZykge1xuICBpbmplY3Rvci5pbnZva2UoQ29tbWFuZEludGVyY2VwdG9yLCB0aGlzKTtcblxuICB0aGlzLnBvc3RFeGVjdXRlZCgnc2hhcGUucmVwbGFjZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIG9sZFNoYXBlID0gZXZlbnQuY29udGV4dC5vbGRTaGFwZSxcbiAgICAgICAgbmV3U2hhcGUgPSBldmVudC5jb250ZXh0Lm5ld1NoYXBlO1xuXG4gICAgaWYgKFxuICAgICAgIWlzKG5ld1NoYXBlLCAnYnBtbjpTdWJQcm9jZXNzJykgfHxcbiAgICAgICFpcyhvbGRTaGFwZSwgJ2JwbW46VGFzaycpIHx8XG4gICAgICAhaXNFeHBhbmRlZChuZXdTaGFwZSlcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcG9zaXRpb24gPSBnZXRTdGFydEV2ZW50UG9zaXRpb24obmV3U2hhcGUpO1xuXG4gICAgbW9kZWxpbmcuY3JlYXRlU2hhcGUoeyB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyB9LCBwb3NpdGlvbiwgbmV3U2hhcGUpO1xuICB9KTtcbn1cblxuU3ViUHJvY2Vzc1N0YXJ0RXZlbnRCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnaW5qZWN0b3InLFxuICAnbW9kZWxpbmcnXG5dO1xuXG5pbmhlcml0cyhTdWJQcm9jZXNzU3RhcnRFdmVudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZ2V0U3RhcnRFdmVudFBvc2l0aW9uKHNoYXBlKSB7XG4gIHJldHVybiB7XG4gICAgeDogc2hhcGUueCArIHNoYXBlLndpZHRoIC8gNixcbiAgICB5OiBzaGFwZS55ICsgc2hhcGUuaGVpZ2h0IC8gMlxuICB9O1xufVxuIiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGNvbXB1dGVDaGlsZHJlbkJCb3hcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcmVzaXplL1Jlc2l6ZVV0aWwnO1xuXG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVG9nZ2xlRWxlbWVudENvbGxhcHNlQmVoYXZpb3VyKFxuICAgIGV2ZW50QnVzLCBlbGVtZW50RmFjdG9yeSwgbW9kZWxpbmcsXG4gICAgcmVzaXplKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG5cbiAgZnVuY3Rpb24gaGlkZUVtcHR5TGFiZWxzKGNoaWxkcmVuKSB7XG4gICAgaWYgKGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbihjaGlsZCkge1xuICAgICAgICBpZiAoY2hpbGQudHlwZSA9PT0gJ2xhYmVsJyAmJiAhY2hpbGQuYnVzaW5lc3NPYmplY3QubmFtZSkge1xuICAgICAgICAgIGNoaWxkLmhpZGRlbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGV4cGFuZGVkQm91bmRzKHNoYXBlLCBkZWZhdWx0U2l6ZSkge1xuICAgIHZhciBjaGlsZHJlbiA9IHNoYXBlLmNoaWxkcmVuLFxuICAgICAgICBuZXdCb3VuZHMgPSBkZWZhdWx0U2l6ZSxcbiAgICAgICAgdmlzaWJsZUVsZW1lbnRzLFxuICAgICAgICB2aXNpYmxlQkJveDtcblxuICAgIHZpc2libGVFbGVtZW50cyA9IGZpbHRlclZpc2libGUoY2hpbGRyZW4pLmNvbmNhdChbIHNoYXBlIF0pO1xuXG4gICAgdmlzaWJsZUJCb3ggPSBjb21wdXRlQ2hpbGRyZW5CQm94KHZpc2libGVFbGVtZW50cyk7XG5cbiAgICBpZiAodmlzaWJsZUJCb3gpIHtcblxuICAgICAgLy8gY2VudGVyIHRvIHZpc2libGVCQm94IHdpdGggbWF4KGRlZmF1bHRTaXplLCBjaGlsZHJlbkJvdW5kcylcbiAgICAgIG5ld0JvdW5kcy53aWR0aCA9IE1hdGgubWF4KHZpc2libGVCQm94LndpZHRoLCBuZXdCb3VuZHMud2lkdGgpO1xuICAgICAgbmV3Qm91bmRzLmhlaWdodCA9IE1hdGgubWF4KHZpc2libGVCQm94LmhlaWdodCwgbmV3Qm91bmRzLmhlaWdodCk7XG5cbiAgICAgIG5ld0JvdW5kcy54ID0gdmlzaWJsZUJCb3gueCArICh2aXNpYmxlQkJveC53aWR0aCAtIG5ld0JvdW5kcy53aWR0aCkgLyAyO1xuICAgICAgbmV3Qm91bmRzLnkgPSB2aXNpYmxlQkJveC55ICsgKHZpc2libGVCQm94LmhlaWdodCAtIG5ld0JvdW5kcy5oZWlnaHQpIC8gMjtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBjZW50ZXIgdG8gY29sbGFwc2VkIHNoYXBlIHdpdGggZGVmYXVsdFNpemVcbiAgICAgIG5ld0JvdW5kcy54ID0gc2hhcGUueCArIChzaGFwZS53aWR0aCAtIG5ld0JvdW5kcy53aWR0aCkgLyAyO1xuICAgICAgbmV3Qm91bmRzLnkgPSBzaGFwZS55ICsgKHNoYXBlLmhlaWdodCAtIG5ld0JvdW5kcy5oZWlnaHQpIC8gMjtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3Qm91bmRzO1xuICB9XG5cbiAgZnVuY3Rpb24gY29sbGFwc2VkQm91bmRzKHNoYXBlLCBkZWZhdWx0U2l6ZSkge1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHNoYXBlLnggKyAoc2hhcGUud2lkdGggLSBkZWZhdWx0U2l6ZS53aWR0aCkgLyAyLFxuICAgICAgeTogc2hhcGUueSArIChzaGFwZS5oZWlnaHQgLSBkZWZhdWx0U2l6ZS5oZWlnaHQpIC8gMixcbiAgICAgIHdpZHRoOiBkZWZhdWx0U2l6ZS53aWR0aCxcbiAgICAgIGhlaWdodDogZGVmYXVsdFNpemUuaGVpZ2h0XG4gICAgfTtcbiAgfVxuXG4gIHRoaXMuZXhlY3V0ZWQoWyAnc2hhcGUudG9nZ2xlQ29sbGFwc2UnIF0sIExPV19QUklPUklUWSwgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZTtcblxuICAgIGlmICghaXMoc2hhcGUsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghc2hhcGUuY29sbGFwc2VkKSB7XG5cbiAgICAgIC8vIGFsbCBjaGlsZHJlbiBnb3QgbWFkZSB2aXNpYmxlIHRocm91Z2ggZGpzLCBoaWRlIGVtcHR5IGxhYmVsc1xuICAgICAgaGlkZUVtcHR5TGFiZWxzKHNoYXBlLmNoaWxkcmVuKTtcblxuICAgICAgLy8gcmVtb3ZlIGNvbGxhcHNlZCBtYXJrZXJcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0KHNoYXBlKS5kaS5pc0V4cGFuZGVkID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBwbGFjZSBjb2xsYXBzZWQgbWFya2VyXG4gICAgICBnZXRCdXNpbmVzc09iamVjdChzaGFwZSkuZGkuaXNFeHBhbmRlZCA9IGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5yZXZlcnRlZChbICdzaGFwZS50b2dnbGVDb2xsYXBzZScgXSwgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dDtcbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG5cbiAgICAvLyByZXZlcnQgcmVtb3ZpbmcvcGxhY2luZyBjb2xsYXBzZWQgbWFya2VyXG4gICAgaWYgKCFzaGFwZS5jb2xsYXBzZWQpIHtcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0KHNoYXBlKS5kaS5pc0V4cGFuZGVkID0gdHJ1ZTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBnZXRCdXNpbmVzc09iamVjdChzaGFwZSkuZGkuaXNFeHBhbmRlZCA9IGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoWyAnc2hhcGUudG9nZ2xlQ29sbGFwc2UnIF0sIExPV19QUklPUklUWSwgZnVuY3Rpb24oZSkge1xuICAgIHZhciBzaGFwZSA9IGUuY29udGV4dC5zaGFwZSxcbiAgICAgICAgZGVmYXVsdFNpemUgPSBlbGVtZW50RmFjdG9yeS5fZ2V0RGVmYXVsdFNpemUoc2hhcGUpLFxuICAgICAgICBuZXdCb3VuZHM7XG5cbiAgICBpZiAoc2hhcGUuY29sbGFwc2VkKSB7XG5cbiAgICAgIC8vIHJlc2l6ZSB0byBkZWZhdWx0IHNpemUgb2YgY29sbGFwc2VkIHNoYXBlc1xuICAgICAgbmV3Qm91bmRzID0gY29sbGFwc2VkQm91bmRzKHNoYXBlLCBkZWZhdWx0U2l6ZSk7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gcmVzaXplIHRvIGJvdW5kcyBvZiBtYXgodmlzaWJsZSBjaGlsZHJlbiwgZGVmYXVsdFNpemUpXG4gICAgICBuZXdCb3VuZHMgPSBleHBhbmRlZEJvdW5kcyhzaGFwZSwgZGVmYXVsdFNpemUpO1xuICAgIH1cblxuICAgIG1vZGVsaW5nLnJlc2l6ZVNoYXBlKHNoYXBlLCBuZXdCb3VuZHMsIG51bGwsIHtcbiAgICAgIGF1dG9SZXNpemU6IHNoYXBlLmNvbGxhcHNlZCA/IGZhbHNlIDogJ253c2UnXG4gICAgfSk7XG4gIH0pO1xuXG59XG5cblxuaW5oZXJpdHMoVG9nZ2xlRWxlbWVudENvbGxhcHNlQmVoYXZpb3VyLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5Ub2dnbGVFbGVtZW50Q29sbGFwc2VCZWhhdmlvdXIuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZmlsdGVyVmlzaWJsZShlbGVtZW50cykge1xuICByZXR1cm4gZWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uKGUpIHtcbiAgICByZXR1cm4gIWUuaGlkZGVuO1xuICB9KTtcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5pbXBvcnQgeyBpc0V4cGFuZGVkIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9EaVV0aWwnO1xuaW1wb3J0IHsgaXNMYWJlbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTGFiZWxVdGlsJztcblxuXG4vKipcbiAqIFVuY2xhaW1zIG1vZGVsIElEcyBvbiBlbGVtZW50IGRlbGV0aW9uLlxuICpcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKiBAcGFyYW0ge01vZGRsZX0gbW9kZGxlXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBVbmNsYWltSWRCZWhhdmlvcihjYW52YXMsIGluamVjdG9yLCBtb2RkbGUsIG1vZGVsaW5nKSB7XG4gIGluamVjdG9yLmludm9rZShDb21tYW5kSW50ZXJjZXB0b3IsIHRoaXMpO1xuXG4gIHRoaXMucHJlRXhlY3V0ZSgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgc2hhcGVCbyA9IHNoYXBlLmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgaWYgKGlzTGFiZWwoc2hhcGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpQYXJ0aWNpcGFudCcpICYmIGlzRXhwYW5kZWQoc2hhcGUpKSB7XG4gICAgICBtb2RkbGUuaWRzLnVuY2xhaW0oc2hhcGVCby5wcm9jZXNzUmVmLmlkKTtcbiAgICB9XG5cbiAgICBtb2RlbGluZy51bmNsYWltSWQoc2hhcGVCby5pZCwgc2hhcGVCbyk7XG4gIH0pO1xuXG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdjb25uZWN0aW9uLmRlbGV0ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBjb25uZWN0aW9uQm8gPSBjb25uZWN0aW9uLmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgbW9kZWxpbmcudW5jbGFpbUlkKGNvbm5lY3Rpb25Cby5pZCwgY29ubmVjdGlvbkJvKTtcbiAgfSk7XG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdjYW52YXMudXBkYXRlUm9vdCcsIGZ1bmN0aW9uKCkge1xuICAgIHZhciByb290RWxlbWVudCA9IGNhbnZhcy5nZXRSb290RWxlbWVudCgpLFxuICAgICAgICByb290RWxlbWVudEJvID0gcm9vdEVsZW1lbnQuYnVzaW5lc3NPYmplY3Q7XG5cbiAgICBtb2RkbGUuaWRzLnVuY2xhaW0ocm9vdEVsZW1lbnRCby5pZCk7XG4gIH0pO1xufVxuXG5pbmhlcml0cyhVbmNsYWltSWRCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuVW5jbGFpbUlkQmVoYXZpb3IuJGluamVjdCA9IFsgJ2NhbnZhcycsICdpbmplY3RvcicsICdtb2RkbGUnLCAnbW9kZWxpbmcnIF07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cblxuLyoqXG4gKiBBIGJlaGF2aW9yIHRoYXQgdW5zZXRzIHRoZSBEZWZhdWx0IHByb3BlcnR5IG9mXG4gKiBzZXF1ZW5jZSBmbG93IHNvdXJjZSBvbiBlbGVtZW50IGRlbGV0ZSwgaWYgdGhlXG4gKiByZW1vdmVkIGVsZW1lbnQgaXMgdGhlIEdhdGV3YXkgb3IgVGFzaydzIGRlZmF1bHQgZmxvdy5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRGVsZXRlU2VxdWVuY2VGbG93QmVoYXZpb3IoZXZlbnRCdXMsIG1vZGVsaW5nKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdjb25uZWN0aW9uLmRlbGV0ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBzb3VyY2UgPSBjb25uZWN0aW9uLnNvdXJjZTtcblxuICAgIGlmIChpc0RlZmF1bHRGbG93KGNvbm5lY3Rpb24sIHNvdXJjZSkpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoc291cmNlLCB7XG4gICAgICAgICdkZWZhdWx0JzogbnVsbFxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbn1cblxuaW5oZXJpdHMoRGVsZXRlU2VxdWVuY2VGbG93QmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cbkRlbGV0ZVNlcXVlbmNlRmxvd0JlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGlzRGVmYXVsdEZsb3coY29ubmVjdGlvbiwgc291cmNlKSB7XG5cbiAgaWYgKCFpcyhjb25uZWN0aW9uLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBzb3VyY2VCbyA9IGdldEJ1c2luZXNzT2JqZWN0KHNvdXJjZSksXG4gICAgICBzZXF1ZW5jZUZsb3cgPSBnZXRCdXNpbmVzc09iamVjdChjb25uZWN0aW9uKTtcblxuICByZXR1cm4gc291cmNlQm8uZ2V0KCdkZWZhdWx0JykgPT09IHNlcXVlbmNlRmxvdztcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHtcbiAgaXNcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gNTAwLFxuICAgIEhJR0hfUFJJT1JJVFkgPSA1MDAwO1xuXG5cbi8qKlxuICogQlBNTiBzcGVjaWZpYyBkZWxldGUgbGFuZSBiZWhhdmlvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBVcGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvcihldmVudEJ1cywgbW9kZWxpbmcsIHRyYW5zbGF0ZSkge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuICAvKipcbiAgICogT2ssIHRoaXMgaXMgaXQ6XG4gICAqXG4gICAqIFdlIGhhdmUgdG8gdXBkYXRlIHRoZSBMYW5lI2Zsb3dOb2RlUmVmcyBfYW5kX1xuICAgKiBGbG93Tm9kZSNsYW5lcyB3aXRoIGV2ZXJ5IEZsb3dOb2RlIG1vdmUvcmVzaXplIGFuZFxuICAgKiBMYW5lIG1vdmUvcmVzaXplLlxuICAgKlxuICAgKiBXZSB3YW50IHRvIGdyb3VwIHRoYXQgc3R1ZmYgdG8gcmVjb21wdXRlIGNvbnRhaW5tZW50c1xuICAgKiBhcyBlZmZpY2llbnQgYXMgcG9zc2libGUuXG4gICAqXG4gICAqIFllYSFcbiAgICovXG5cbiAgLy8gdGhlIHVwZGF0ZSBjb250ZXh0XG4gIHZhciBjb250ZXh0O1xuXG5cbiAgZnVuY3Rpb24gaW5pdENvbnRleHQoKSB7XG4gICAgY29udGV4dCA9IGNvbnRleHQgfHwgbmV3IFVwZGF0ZUNvbnRleHQoKTtcbiAgICBjb250ZXh0LmVudGVyKCk7XG5cbiAgICByZXR1cm4gY29udGV4dDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldENvbnRleHQoKSB7XG4gICAgaWYgKCFjb250ZXh0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodHJhbnNsYXRlKCdvdXQgb2YgYm91bmRzIHJlbGVhc2UnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRleHQ7XG4gIH1cblxuICBmdW5jdGlvbiByZWxlYXNlQ29udGV4dCgpIHtcblxuICAgIGlmICghY29udGV4dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnb3V0IG9mIGJvdW5kcyByZWxlYXNlJykpO1xuICAgIH1cblxuICAgIHZhciB0cmlnZ2VyVXBkYXRlID0gY29udGV4dC5sZWF2ZSgpO1xuXG4gICAgaWYgKHRyaWdnZXJVcGRhdGUpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZUxhbmVSZWZzKGNvbnRleHQuZmxvd05vZGVzLCBjb250ZXh0LmxhbmVzKTtcblxuICAgICAgY29udGV4dCA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyaWdnZXJVcGRhdGU7XG4gIH1cblxuXG4gIHZhciBsYW5lUmVmVXBkYXRlRXZlbnRzID0gW1xuICAgICdzcGFjZVRvb2wnLFxuICAgICdsYW5lLmFkZCcsXG4gICAgJ2xhbmUucmVzaXplJyxcbiAgICAnbGFuZS5zcGxpdCcsXG4gICAgJ2VsZW1lbnRzLmNyZWF0ZScsXG4gICAgJ2VsZW1lbnRzLmRlbGV0ZScsXG4gICAgJ2VsZW1lbnRzLm1vdmUnLFxuICAgICdzaGFwZS5jcmVhdGUnLFxuICAgICdzaGFwZS5kZWxldGUnLFxuICAgICdzaGFwZS5tb3ZlJyxcbiAgICAnc2hhcGUucmVzaXplJ1xuICBdO1xuXG5cbiAgLy8gbGlzdGVuIHRvIGEgbG90IG9mIHN0dWZmIHRvIGdyb3VwIGxhbmUgdXBkYXRlc1xuXG4gIHRoaXMucHJlRXhlY3V0ZShsYW5lUmVmVXBkYXRlRXZlbnRzLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIGluaXRDb250ZXh0KCk7XG4gIH0pO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKGxhbmVSZWZVcGRhdGVFdmVudHMsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICByZWxlYXNlQ29udGV4dCgpO1xuICB9KTtcblxuXG4gIC8vIE1hcmsgZmxvdyBub2RlcyArIGxhbmVzIHRoYXQgbmVlZCBhbiB1cGRhdGVcblxuICB0aGlzLnByZUV4ZWN1dGUoW1xuICAgICdzaGFwZS5jcmVhdGUnLFxuICAgICdzaGFwZS5tb3ZlJyxcbiAgICAnc2hhcGUuZGVsZXRlJyxcbiAgICAnc2hhcGUucmVzaXplJ1xuICBdLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICB2YXIgdXBkYXRlQ29udGV4dCA9IGdldENvbnRleHQoKTtcblxuICAgIC8vIG5vIG5lZWQgdG8gdXBkYXRlIGxhYmVsc1xuICAgIGlmIChzaGFwZS5sYWJlbFRhcmdldCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpcyhzaGFwZSwgJ2JwbW46TGFuZScpKSB7XG4gICAgICB1cGRhdGVDb250ZXh0LmFkZExhbmUoc2hhcGUpO1xuICAgIH1cblxuICAgIGlmIChpcyhzaGFwZSwgJ2JwbW46Rmxvd05vZGUnKSkge1xuICAgICAgdXBkYXRlQ29udGV4dC5hZGRGbG93Tm9kZShzaGFwZSk7XG4gICAgfVxuICB9KTtcbn1cblxuVXBkYXRlRmxvd05vZGVSZWZzQmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGVsaW5nJyAsXG4gICd0cmFuc2xhdGUnXG5dO1xuXG5pbmhlcml0cyhVcGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuXG5mdW5jdGlvbiBVcGRhdGVDb250ZXh0KCkge1xuXG4gIHRoaXMuZmxvd05vZGVzID0gW107XG4gIHRoaXMubGFuZXMgPSBbXTtcblxuICB0aGlzLmNvdW50ZXIgPSAwO1xuXG4gIHRoaXMuYWRkTGFuZSA9IGZ1bmN0aW9uKGxhbmUpIHtcbiAgICB0aGlzLmxhbmVzLnB1c2gobGFuZSk7XG4gIH07XG5cbiAgdGhpcy5hZGRGbG93Tm9kZSA9IGZ1bmN0aW9uKGZsb3dOb2RlKSB7XG4gICAgdGhpcy5mbG93Tm9kZXMucHVzaChmbG93Tm9kZSk7XG4gIH07XG5cbiAgdGhpcy5lbnRlciA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuY291bnRlcisrO1xuICB9O1xuXG4gIHRoaXMubGVhdmUgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLmNvdW50ZXItLTtcblxuICAgIHJldHVybiAhdGhpcy5jb3VudGVyO1xuICB9O1xufSIsImltcG9ydCBBZGFwdGl2ZUxhYmVsUG9zaXRpb25pbmdCZWhhdmlvciBmcm9tICcuL0FkYXB0aXZlTGFiZWxQb3NpdGlvbmluZ0JlaGF2aW9yJztcbmltcG9ydCBBcHBlbmRCZWhhdmlvciBmcm9tICcuL0FwcGVuZEJlaGF2aW9yJztcbmltcG9ydCBBc3NvY2lhdGlvbkJlaGF2aW9yIGZyb20gJy4vQXNzb2NpYXRpb25CZWhhdmlvcic7XG5pbXBvcnQgQXR0YWNoRXZlbnRCZWhhdmlvciBmcm9tICcuL0F0dGFjaEV2ZW50QmVoYXZpb3InO1xuaW1wb3J0IEJvdW5kYXJ5RXZlbnRCZWhhdmlvciBmcm9tICcuL0JvdW5kYXJ5RXZlbnRCZWhhdmlvcic7XG5pbXBvcnQgUm9vdEVsZW1lbnRSZWZlcmVuY2VCZWhhdmlvciBmcm9tICcuL1Jvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3InO1xuaW1wb3J0IENyZWF0ZUJlaGF2aW9yIGZyb20gJy4vQ3JlYXRlQmVoYXZpb3InO1xuaW1wb3J0IEZpeEhvdmVyQmVoYXZpb3IgZnJvbSAnLi9GaXhIb3ZlckJlaGF2aW9yJztcbmltcG9ydCBDcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3IgZnJvbSAnLi9DcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3InO1xuaW1wb3J0IENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IgZnJvbSAnLi9DcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yJztcbmltcG9ydCBEYXRhSW5wdXRBc3NvY2lhdGlvbkJlaGF2aW9yIGZyb20gJy4vRGF0YUlucHV0QXNzb2NpYXRpb25CZWhhdmlvcic7XG5pbXBvcnQgRGF0YVN0b3JlQmVoYXZpb3IgZnJvbSAnLi9EYXRhU3RvcmVCZWhhdmlvcic7XG5pbXBvcnQgRGVsZXRlTGFuZUJlaGF2aW9yIGZyb20gJy4vRGVsZXRlTGFuZUJlaGF2aW9yJztcbmltcG9ydCBEZXRhY2hFdmVudEJlaGF2aW9yIGZyb20gJy4vRGV0YWNoRXZlbnRCZWhhdmlvcic7XG5pbXBvcnQgRHJvcE9uRmxvd0JlaGF2aW9yIGZyb20gJy4vRHJvcE9uRmxvd0JlaGF2aW9yJztcbmltcG9ydCBFdmVudEJhc2VkR2F0ZXdheUJlaGF2aW9yIGZyb20gJy4vRXZlbnRCYXNlZEdhdGV3YXlCZWhhdmlvcic7XG5pbXBvcnQgR3JvdXBCZWhhdmlvciBmcm9tICcuL0dyb3VwQmVoYXZpb3InO1xuaW1wb3J0IEltcG9ydERvY2tpbmdGaXggZnJvbSAnLi9JbXBvcnREb2NraW5nRml4JztcbmltcG9ydCBJc0hvcml6b250YWxGaXggZnJvbSAnLi9Jc0hvcml6b250YWxGaXgnO1xuaW1wb3J0IExhYmVsQmVoYXZpb3IgZnJvbSAnLi9MYWJlbEJlaGF2aW9yJztcbmltcG9ydCBNb2RlbGluZ0ZlZWRiYWNrIGZyb20gJy4vTW9kZWxpbmdGZWVkYmFjayc7XG5pbXBvcnQgUmVwbGFjZUNvbm5lY3Rpb25CZWhhdmlvciBmcm9tICcuL1JlcGxhY2VDb25uZWN0aW9uQmVoYXZpb3InO1xuaW1wb3J0IFJlbW92ZVBhcnRpY2lwYW50QmVoYXZpb3IgZnJvbSAnLi9SZW1vdmVQYXJ0aWNpcGFudEJlaGF2aW9yJztcbmltcG9ydCBSZXBsYWNlRWxlbWVudEJlaGF2aW91ciBmcm9tICcuL1JlcGxhY2VFbGVtZW50QmVoYXZpb3VyJztcbmltcG9ydCBSZXNpemVCZWhhdmlvciBmcm9tICcuL1Jlc2l6ZUJlaGF2aW9yJztcbmltcG9ydCBSZXNpemVMYW5lQmVoYXZpb3IgZnJvbSAnLi9SZXNpemVMYW5lQmVoYXZpb3InO1xuaW1wb3J0IFJlbW92ZUVsZW1lbnRCZWhhdmlvciBmcm9tICcuL1JlbW92ZUVsZW1lbnRCZWhhdmlvcic7XG5pbXBvcnQgU3BhY2VUb29sQmVoYXZpb3IgZnJvbSAnLi9TcGFjZVRvb2xCZWhhdmlvcic7XG5pbXBvcnQgU3ViUHJvY2Vzc1N0YXJ0RXZlbnRCZWhhdmlvciBmcm9tICcuL1N1YlByb2Nlc3NTdGFydEV2ZW50QmVoYXZpb3InO1xuaW1wb3J0IFRvZ2dsZUVsZW1lbnRDb2xsYXBzZUJlaGF2aW91ciBmcm9tICcuL1RvZ2dsZUVsZW1lbnRDb2xsYXBzZUJlaGF2aW91cic7XG5pbXBvcnQgVW5jbGFpbUlkQmVoYXZpb3IgZnJvbSAnLi9VbmNsYWltSWRCZWhhdmlvcic7XG5pbXBvcnQgVXBkYXRlRmxvd05vZGVSZWZzQmVoYXZpb3IgZnJvbSAnLi9VcGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvcic7XG5pbXBvcnQgVW5zZXREZWZhdWx0Rmxvd0JlaGF2aW9yIGZyb20gJy4vVW5zZXREZWZhdWx0Rmxvd0JlaGF2aW9yJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogW1xuICAgICdhZGFwdGl2ZUxhYmVsUG9zaXRpb25pbmdCZWhhdmlvcicsXG4gICAgJ2FwcGVuZEJlaGF2aW9yJyxcbiAgICAnYXNzb2NpYXRpb25CZWhhdmlvcicsXG4gICAgJ2F0dGFjaEV2ZW50QmVoYXZpb3InLFxuICAgICdib3VuZGFyeUV2ZW50QmVoYXZpb3InLFxuICAgICdyb290RWxlbWVudFJlZmVyZW5jZUJlaGF2aW9yJyxcbiAgICAnY3JlYXRlQmVoYXZpb3InLFxuICAgICdmaXhIb3ZlckJlaGF2aW9yJyxcbiAgICAnY3JlYXRlRGF0YU9iamVjdEJlaGF2aW9yJyxcbiAgICAnY3JlYXRlUGFydGljaXBhbnRCZWhhdmlvcicsXG4gICAgJ2RhdGFTdG9yZUJlaGF2aW9yJyxcbiAgICAnZGF0YUlucHV0QXNzb2NpYXRpb25CZWhhdmlvcicsXG4gICAgJ2RlbGV0ZUxhbmVCZWhhdmlvcicsXG4gICAgJ2RldGFjaEV2ZW50QmVoYXZpb3InLFxuICAgICdkcm9wT25GbG93QmVoYXZpb3InLFxuICAgICdldmVudEJhc2VkR2F0ZXdheUJlaGF2aW9yJyxcbiAgICAnZ3JvdXBCZWhhdmlvcicsXG4gICAgJ2ltcG9ydERvY2tpbmdGaXgnLFxuICAgICdpc0hvcml6b250YWxGaXgnLFxuICAgICdsYWJlbEJlaGF2aW9yJyxcbiAgICAnbW9kZWxpbmdGZWVkYmFjaycsXG4gICAgJ3JlbW92ZUVsZW1lbnRCZWhhdmlvcicsXG4gICAgJ3JlbW92ZVBhcnRpY2lwYW50QmVoYXZpb3InLFxuICAgICdyZXBsYWNlQ29ubmVjdGlvbkJlaGF2aW9yJyxcbiAgICAncmVwbGFjZUVsZW1lbnRCZWhhdmlvdXInLFxuICAgICdyZXNpemVCZWhhdmlvcicsXG4gICAgJ3Jlc2l6ZUxhbmVCZWhhdmlvcicsXG4gICAgJ3RvZ2dsZUVsZW1lbnRDb2xsYXBzZUJlaGF2aW91cicsXG4gICAgJ3NwYWNlVG9vbEJlaGF2aW9yJyxcbiAgICAnc3ViUHJvY2Vzc1N0YXJ0RXZlbnRCZWhhdmlvcicsXG4gICAgJ3VuY2xhaW1JZEJlaGF2aW9yJyxcbiAgICAndW5zZXREZWZhdWx0Rmxvd0JlaGF2aW9yJyxcbiAgICAndXBkYXRlRmxvd05vZGVSZWZzQmVoYXZpb3InXG4gIF0sXG4gIGFkYXB0aXZlTGFiZWxQb3NpdGlvbmluZ0JlaGF2aW9yOiBbICd0eXBlJywgQWRhcHRpdmVMYWJlbFBvc2l0aW9uaW5nQmVoYXZpb3IgXSxcbiAgYXBwZW5kQmVoYXZpb3I6IFsgJ3R5cGUnLCBBcHBlbmRCZWhhdmlvciBdLFxuICBhc3NvY2lhdGlvbkJlaGF2aW9yOiBbICd0eXBlJywgQXNzb2NpYXRpb25CZWhhdmlvciBdLFxuICBhdHRhY2hFdmVudEJlaGF2aW9yOiBbICd0eXBlJywgQXR0YWNoRXZlbnRCZWhhdmlvciBdLFxuICBib3VuZGFyeUV2ZW50QmVoYXZpb3I6IFsgJ3R5cGUnLCBCb3VuZGFyeUV2ZW50QmVoYXZpb3IgXSxcbiAgcm9vdEVsZW1lbnRSZWZlcmVuY2VCZWhhdmlvcjogWyAndHlwZScsIFJvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3IgXSxcbiAgY3JlYXRlQmVoYXZpb3I6IFsgJ3R5cGUnLCBDcmVhdGVCZWhhdmlvciBdLFxuICBmaXhIb3ZlckJlaGF2aW9yOiBbICd0eXBlJywgRml4SG92ZXJCZWhhdmlvciBdLFxuICBjcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3I6IFsgJ3R5cGUnLCBDcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3IgXSxcbiAgY3JlYXRlUGFydGljaXBhbnRCZWhhdmlvcjogWyAndHlwZScsIENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IgXSxcbiAgZGF0YUlucHV0QXNzb2NpYXRpb25CZWhhdmlvcjogWyAndHlwZScsIERhdGFJbnB1dEFzc29jaWF0aW9uQmVoYXZpb3IgXSxcbiAgZGF0YVN0b3JlQmVoYXZpb3I6IFsgJ3R5cGUnLCBEYXRhU3RvcmVCZWhhdmlvciBdLFxuICBkZWxldGVMYW5lQmVoYXZpb3I6IFsgJ3R5cGUnLCBEZWxldGVMYW5lQmVoYXZpb3IgXSxcbiAgZGV0YWNoRXZlbnRCZWhhdmlvcjogWyAndHlwZScsIERldGFjaEV2ZW50QmVoYXZpb3IgXSxcbiAgZHJvcE9uRmxvd0JlaGF2aW9yOiBbICd0eXBlJywgRHJvcE9uRmxvd0JlaGF2aW9yIF0sXG4gIGV2ZW50QmFzZWRHYXRld2F5QmVoYXZpb3I6IFsgJ3R5cGUnLCBFdmVudEJhc2VkR2F0ZXdheUJlaGF2aW9yIF0sXG4gIGdyb3VwQmVoYXZpb3I6IFsgJ3R5cGUnLCBHcm91cEJlaGF2aW9yIF0sXG4gIGltcG9ydERvY2tpbmdGaXg6IFsgJ3R5cGUnLCBJbXBvcnREb2NraW5nRml4IF0sXG4gIGlzSG9yaXpvbnRhbEZpeDogWyAndHlwZScsIElzSG9yaXpvbnRhbEZpeCBdLFxuICBsYWJlbEJlaGF2aW9yOiBbICd0eXBlJywgTGFiZWxCZWhhdmlvciBdLFxuICBtb2RlbGluZ0ZlZWRiYWNrOiBbICd0eXBlJywgTW9kZWxpbmdGZWVkYmFjayBdLFxuICByZXBsYWNlQ29ubmVjdGlvbkJlaGF2aW9yOiBbICd0eXBlJywgUmVwbGFjZUNvbm5lY3Rpb25CZWhhdmlvciBdLFxuICByZW1vdmVQYXJ0aWNpcGFudEJlaGF2aW9yOiBbICd0eXBlJywgUmVtb3ZlUGFydGljaXBhbnRCZWhhdmlvciBdLFxuICByZXBsYWNlRWxlbWVudEJlaGF2aW91cjogWyAndHlwZScsIFJlcGxhY2VFbGVtZW50QmVoYXZpb3VyIF0sXG4gIHJlc2l6ZUJlaGF2aW9yOiBbICd0eXBlJywgUmVzaXplQmVoYXZpb3IgXSxcbiAgcmVzaXplTGFuZUJlaGF2aW9yOiBbICd0eXBlJywgUmVzaXplTGFuZUJlaGF2aW9yIF0sXG4gIHJlbW92ZUVsZW1lbnRCZWhhdmlvcjogWyAndHlwZScsIFJlbW92ZUVsZW1lbnRCZWhhdmlvciBdLFxuICB0b2dnbGVFbGVtZW50Q29sbGFwc2VCZWhhdmlvdXIgOiBbICd0eXBlJywgVG9nZ2xlRWxlbWVudENvbGxhcHNlQmVoYXZpb3VyIF0sXG4gIHNwYWNlVG9vbEJlaGF2aW9yOiBbICd0eXBlJywgU3BhY2VUb29sQmVoYXZpb3IgXSxcbiAgc3ViUHJvY2Vzc1N0YXJ0RXZlbnRCZWhhdmlvcjogWyAndHlwZScsIFN1YlByb2Nlc3NTdGFydEV2ZW50QmVoYXZpb3IgXSxcbiAgdW5jbGFpbUlkQmVoYXZpb3I6IFsgJ3R5cGUnLCBVbmNsYWltSWRCZWhhdmlvciBdLFxuICB1cGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvcjogWyAndHlwZScsIFVwZGF0ZUZsb3dOb2RlUmVmc0JlaGF2aW9yIF0sXG4gIHVuc2V0RGVmYXVsdEZsb3dCZWhhdmlvcjogWyAndHlwZScsIFVuc2V0RGVmYXVsdEZsb3dCZWhhdmlvciBdXG59O1xuIiwiaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGRcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9Db2xsZWN0aW9ucyc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0XG59IGZyb20gJy4uLy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGJwbW46Q2F0ZWdvcnlWYWx1ZSBpbnNpZGUgYSBuZXcgYnBtbjpDYXRlZ29yeVxuICpcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gZGVmaW5pdGlvbnNcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XG4gKlxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gY2F0ZWdvcnlWYWx1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNhdGVnb3J5VmFsdWUoZGVmaW5pdGlvbnMsIGJwbW5GYWN0b3J5KSB7XG4gIHZhciBjYXRlZ29yeVZhbHVlID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkNhdGVnb3J5VmFsdWUnKSxcbiAgICAgIGNhdGVnb3J5ID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkNhdGVnb3J5Jywge1xuICAgICAgICBjYXRlZ29yeVZhbHVlOiBbIGNhdGVnb3J5VmFsdWUgXVxuICAgICAgfSk7XG5cbiAgLy8gYWRkIHRvIGNvcnJlY3QgcGxhY2VcbiAgY29sbGVjdGlvbkFkZChkZWZpbml0aW9ucy5nZXQoJ3Jvb3RFbGVtZW50cycpLCBjYXRlZ29yeSk7XG4gIGdldEJ1c2luZXNzT2JqZWN0KGNhdGVnb3J5KS4kcGFyZW50ID0gZGVmaW5pdGlvbnM7XG4gIGdldEJ1c2luZXNzT2JqZWN0KGNhdGVnb3J5VmFsdWUpLiRwYXJlbnQgPSBjYXRlZ29yeTtcblxuICByZXR1cm4gY2F0ZWdvcnlWYWx1ZTtcblxufSIsIi8qKlxuICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIGEgdmVjdG9yXG4gKlxuICogQHBhcmFtIHtWZWN0b3J9XG4gKiBAcmV0dXJuIHtGbG9hdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlY3Rvckxlbmd0aCh2KSB7XG4gIHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3codi54LCAyKSArIE1hdGgucG93KHYueSwgMikpO1xufVxuXG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgYW5nbGUgYmV0d2VlbiBhIGxpbmUgYSB0aGUgeUF4aXNcbiAqXG4gKiBAcGFyYW0ge0FycmF5fVxuICogQHJldHVybiB7RmxvYXR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBbmdsZShsaW5lKSB7XG5cbiAgLy8gcmV0dXJuIHZhbHVlIGlzIGJldHdlZW4gMCwgMTgwIGFuZCAtMTgwLCAtMFxuICAvLyBAamFuc3R1ZW1tZWw6IG1heWJlIHJlcGxhY2UgcmV0dXJuIGEvYiB3aXRoIGIvYVxuICByZXR1cm4gTWF0aC5hdGFuKChsaW5lWzFdLnkgLSBsaW5lWzBdLnkpIC8gKGxpbmVbMV0ueCAtIGxpbmVbMF0ueCkpO1xufVxuXG5cbi8qKlxuICogUm90YXRlcyBhIHZlY3RvciBieSBhIGdpdmVuIGFuZ2xlXG4gKlxuICogQHBhcmFtIHtWZWN0b3J9XG4gKiBAcGFyYW0ge0Zsb2F0fSBBbmdsZSBpbiByYWRpYW5zXG4gKiBAcmV0dXJuIHtWZWN0b3J9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVWZWN0b3IodmVjdG9yLCBhbmdsZSkge1xuICByZXR1cm4gKCFhbmdsZSkgPyB2ZWN0b3IgOiB7XG4gICAgeDogTWF0aC5jb3MoYW5nbGUpICogdmVjdG9yLnggLSBNYXRoLnNpbihhbmdsZSkgKiB2ZWN0b3IueSxcbiAgICB5OiBNYXRoLnNpbihhbmdsZSkgKiB2ZWN0b3IueCArIE1hdGguY29zKGFuZ2xlKSAqIHZlY3Rvci55XG4gIH07XG59XG5cblxuLyoqXG4gKiBTb2x2ZXMgYSAyRCBlcXVhdGlvbiBzeXN0ZW1cbiAqIGEgKyByKmIgPSBjLCB3aGVyZSBhLGIsYyBhcmUgMkQgdmVjdG9yc1xuICpcbiAqIEBwYXJhbSB7VmVjdG9yfVxuICogQHBhcmFtIHtWZWN0b3J9XG4gKiBAcGFyYW0ge1ZlY3Rvcn1cbiAqIEByZXR1cm4ge0Zsb2F0fVxuICovXG5mdW5jdGlvbiBzb2x2ZUxhbWJhU3lzdGVtKGEsIGIsIGMpIHtcblxuICAvLyB0aGUgMmQgc3lzdGVtXG4gIHZhciBzeXN0ZW0gPSBbXG4gICAgeyBuOiBhWzBdIC0gY1swXSwgbGFtYmRhOiBiWzBdIH0sXG4gICAgeyBuOiBhWzFdIC0gY1sxXSwgbGFtYmRhOiBiWzFdIH1cbiAgXTtcblxuICAvLyBzb2x2ZVxuICB2YXIgbiA9IHN5c3RlbVswXS5uICogYlswXSArIHN5c3RlbVsxXS5uICogYlsxXSxcbiAgICAgIGwgPSBzeXN0ZW1bMF0ubGFtYmRhICogYlswXSArIHN5c3RlbVsxXS5sYW1iZGEgKiBiWzFdO1xuXG4gIHJldHVybiAtbi9sO1xufVxuXG5cbi8qKlxuICogUG9zaXRpb24gb2YgcGVycGVuZGljdWxhciBmb290XG4gKlxuICogQHBhcmFtIHtQb2ludH1cbiAqIEBwYXJhbSBbIHtQb2ludH0sIHtQb2ludH0gXSBsaW5lIGRlZmluZWQgdGhyb3VnaCB0d28gcG9pbnRzXG4gKiBAcmV0dXJuIHtQb2ludH0gdGhlIHBlcnBlbmRpY3VsYXIgZm9vdCBwb3NpdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gcGVycGVuZGljdWxhckZvb3QocG9pbnQsIGxpbmUpIHtcblxuICB2YXIgYSA9IGxpbmVbMF0sIGIgPSBsaW5lWzFdO1xuXG4gIC8vIHJlbGF0aXZlIHBvc2l0aW9uIG9mIGIgZnJvbSBhXG4gIHZhciBiZCA9IHsgeDogYi54IC0gYS54LCB5OiBiLnkgLSBhLnkgfTtcblxuICAvLyBzb2x2ZSBlcXVhdGlvbiBzeXN0ZW0gdG8gdGhlIHBhcmFtZXRyaXplZCB2ZWN0b3JzIHBhcmFtIHJlYWwgdmFsdWVcbiAgdmFyIHIgPSBzb2x2ZUxhbWJhU3lzdGVtKFsgYS54LCBhLnkgXSwgWyBiZC54LCBiZC55IF0sIFsgcG9pbnQueCwgcG9pbnQueSBdKTtcblxuICByZXR1cm4geyB4OiBhLnggKyByKmJkLngsIHk6IGEueSArIHIqYmQueSB9O1xufVxuXG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiBhIHBvaW50IGFuZCBhIGxpbmVcbiAqXG4gKiBAcGFyYW0ge1BvaW50fVxuICogQHBhcmFtIFsge1BvaW50fSwge1BvaW50fSBdIGxpbmUgZGVmaW5lZCB0aHJvdWdoIHR3byBwb2ludHNcbiAqIEByZXR1cm4ge0Zsb2F0fSBkaXN0YW5jZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGlzdGFuY2VQb2ludExpbmUocG9pbnQsIGxpbmUpIHtcblxuICB2YXIgcGZQb2ludCA9IHBlcnBlbmRpY3VsYXJGb290KHBvaW50LCBsaW5lKTtcblxuICAvLyBkaXN0YW5jZSB2ZWN0b3JcbiAgdmFyIGNvbm5lY3Rpb25WZWN0b3IgPSB7XG4gICAgeDogcGZQb2ludC54IC0gcG9pbnQueCxcbiAgICB5OiBwZlBvaW50LnkgLSBwb2ludC55XG4gIH07XG5cbiAgcmV0dXJuIHZlY3Rvckxlbmd0aChjb25uZWN0aW9uVmVjdG9yKTtcbn1cblxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGRpc3RhbmNlIGJldHdlZW4gdHdvIHBvaW50c1xuICpcbiAqIEBwYXJhbSB7UG9pbnR9XG4gKiBAcGFyYW0ge1BvaW50fVxuICogQHJldHVybiB7RmxvYXR9IGRpc3RhbmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREaXN0YW5jZVBvaW50UG9pbnQocG9pbnQxLCBwb2ludDIpIHtcblxuICByZXR1cm4gdmVjdG9yTGVuZ3RoKHtcbiAgICB4OiBwb2ludDEueCAtIHBvaW50Mi54LFxuICAgIHk6IHBvaW50MS55IC0gcG9pbnQyLnlcbiAgfSk7XG59IiwiaW1wb3J0IHtcbiAgZ2V0RGlzdGFuY2VQb2ludFBvaW50LFxuICByb3RhdGVWZWN0b3IsXG4gIGdldEFuZ2xlXG59IGZyb20gJy4vR2VvbWV0cmljVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldEF0dGFjaG1lbnRcbn0gZnJvbSAnLi9MaW5lQXR0YWNobWVudFV0aWwnO1xuXG5pbXBvcnQge1xuICByb3VuZFBvaW50XG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2xheW91dC9MYXlvdXRVdGlsJztcblxuXG5leHBvcnQgZnVuY3Rpb24gZmluZE5ld0xhYmVsTGluZVN0YXJ0SW5kZXgob2xkV2F5cG9pbnRzLCBuZXdXYXlwb2ludHMsIGF0dGFjaG1lbnQsIGhpbnRzKSB7XG5cbiAgdmFyIGluZGV4ID0gYXR0YWNobWVudC5zZWdtZW50SW5kZXg7XG5cbiAgdmFyIG9mZnNldCA9IG5ld1dheXBvaW50cy5sZW5ndGggLSBvbGRXYXlwb2ludHMubGVuZ3RoO1xuXG4gIC8vIHNlZ21lbnRNb3ZlIGhhcHBlbmVkXG4gIGlmIChoaW50cy5zZWdtZW50TW92ZSkge1xuXG4gICAgdmFyIG9sZFNlZ21lbnRTdGFydEluZGV4ID0gaGludHMuc2VnbWVudE1vdmUuc2VnbWVudFN0YXJ0SW5kZXgsXG4gICAgICAgIG5ld1NlZ21lbnRTdGFydEluZGV4ID0gaGludHMuc2VnbWVudE1vdmUubmV3U2VnbWVudFN0YXJ0SW5kZXg7XG5cbiAgICAvLyBpZiBsYWJlbCB3YXMgb24gbW92ZWQgc2VnbWVudCByZXR1cm4gbmV3IHNlZ21lbnQgaW5kZXhcbiAgICBpZiAoaW5kZXggPT09IG9sZFNlZ21lbnRTdGFydEluZGV4KSB7XG4gICAgICByZXR1cm4gbmV3U2VnbWVudFN0YXJ0SW5kZXg7XG4gICAgfVxuXG4gICAgLy8gbGFiZWwgaXMgYWZ0ZXIgbmV3IHNlZ21lbnQgaW5kZXhcbiAgICBpZiAoaW5kZXggPj0gbmV3U2VnbWVudFN0YXJ0SW5kZXgpIHtcbiAgICAgIHJldHVybiAoaW5kZXgrb2Zmc2V0IDwgbmV3U2VnbWVudFN0YXJ0SW5kZXgpID8gbmV3U2VnbWVudFN0YXJ0SW5kZXggOiBpbmRleCtvZmZzZXQ7XG4gICAgfVxuXG4gICAgLy8gaWYgbGFiZWwgaXMgYmVmb3JlIG5ldyBzZWdtZW50IGluZGV4XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLy8gYmVuZHBvaW50TW92ZSBoYXBwZW5lZFxuICBpZiAoaGludHMuYmVuZHBvaW50TW92ZSkge1xuXG4gICAgdmFyIGluc2VydCA9IGhpbnRzLmJlbmRwb2ludE1vdmUuaW5zZXJ0LFxuICAgICAgICBiZW5kcG9pbnRJbmRleCA9IGhpbnRzLmJlbmRwb2ludE1vdmUuYmVuZHBvaW50SW5kZXgsXG4gICAgICAgIG5ld0luZGV4O1xuXG4gICAgLy8gd2F5cG9pbnRzIGxlbmd0aCBkaWRudCBjaGFuZ2VcbiAgICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuXG4gICAgLy8gbGFiZWwgYmVoaW5kIG5ldy9yZW1vdmVkIGJlbmRwb2ludFxuICAgIGlmIChpbmRleCA+PSBiZW5kcG9pbnRJbmRleCkge1xuICAgICAgbmV3SW5kZXggPSBpbnNlcnQgPyBpbmRleCArIDEgOiBpbmRleCAtIDE7XG4gICAgfVxuXG4gICAgLy8gbGFiZWwgYmVmb3JlIG5ldy9yZW1vdmVkIGJlbmRwb2ludFxuICAgIGlmIChpbmRleCA8IGJlbmRwb2ludEluZGV4KSB7XG5cbiAgICAgIG5ld0luZGV4ID0gaW5kZXg7XG5cbiAgICAgIC8vIGRlY2lkZSBsYWJlbCBzaG91bGQgdGFrZSByaWdodCBvciBsZWZ0IHNlZ21lbnRcbiAgICAgIGlmIChpbnNlcnQgJiYgYXR0YWNobWVudC50eXBlICE9PSAnYmVuZHBvaW50JyAmJiBiZW5kcG9pbnRJbmRleC0xID09PSBpbmRleCkge1xuXG4gICAgICAgIHZhciByZWwgPSByZWxhdGl2ZVBvc2l0aW9uTWlkV2F5cG9pbnQobmV3V2F5cG9pbnRzLCBiZW5kcG9pbnRJbmRleCk7XG5cbiAgICAgICAgaWYgKHJlbCA8IGF0dGFjaG1lbnQucmVsYXRpdmVMb2NhdGlvbikge1xuICAgICAgICAgIG5ld0luZGV4Kys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3SW5kZXg7XG4gIH1cblxuICAvLyBzdGFydC9lbmQgY2hhbmdlZFxuICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgaWYgKGhpbnRzLmNvbm5lY3Rpb25TdGFydCkge1xuICAgIHJldHVybiAoaW5kZXggPT09IDApID8gMCA6IG51bGw7XG4gIH1cblxuICBpZiAoaGludHMuY29ubmVjdGlvbkVuZCkge1xuICAgIHJldHVybiAoaW5kZXggPT09IG9sZFdheXBvaW50cy5sZW5ndGggLSAyKSA/IG5ld1dheXBvaW50cy5sZW5ndGggLSAyIDogbnVsbDtcbiAgfVxuXG4gIC8vIGlmIG5vdGhpbmcgZml0cywgcmV0dXJuIG51bGxcbiAgcmV0dXJuIG51bGw7XG59XG5cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHJlcXVpcmVkIGFkanVzdG1lbnQgKG1vdmUgZGVsdGEpIGZvciB0aGUgZ2l2ZW4gbGFiZWxcbiAqIGFmdGVyIHRoZSBjb25uZWN0aW9uIHdheXBvaW50cyBnb3QgdXBkYXRlZC5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5MYWJlbH0gbGFiZWxcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSBuZXdXYXlwb2ludHNcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSBvbGRXYXlwb2ludHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBoaW50c1xuICpcbiAqIEByZXR1cm4ge1BvaW50fSBkZWx0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGFiZWxBZGp1c3RtZW50KGxhYmVsLCBuZXdXYXlwb2ludHMsIG9sZFdheXBvaW50cywgaGludHMpIHtcblxuICB2YXIgeCA9IDAsXG4gICAgICB5ID0gMDtcblxuICB2YXIgbGFiZWxQb3NpdGlvbiA9IGdldExhYmVsTWlkKGxhYmVsKTtcblxuICAvLyBnZXQgY2xvc2VzdCBhdHRhY2htZW50XG4gIHZhciBhdHRhY2htZW50ID0gZ2V0QXR0YWNobWVudChsYWJlbFBvc2l0aW9uLCBvbGRXYXlwb2ludHMpLFxuICAgICAgb2xkTGFiZWxMaW5lSW5kZXggPSBhdHRhY2htZW50LnNlZ21lbnRJbmRleCxcbiAgICAgIG5ld0xhYmVsTGluZUluZGV4ID0gZmluZE5ld0xhYmVsTGluZVN0YXJ0SW5kZXgob2xkV2F5cG9pbnRzLCBuZXdXYXlwb2ludHMsIGF0dGFjaG1lbnQsIGhpbnRzKTtcblxuICBpZiAobmV3TGFiZWxMaW5lSW5kZXggPT09IG51bGwpIHtcbiAgICByZXR1cm4geyB4OiB4LCB5OiB5IH07XG4gIH1cblxuICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuXG4gIC8vIFRPRE8oQGphbnN0dWVtbWVsKTogdGhyb3cgYW4gZXJyb3IgaGVyZSB3aGVuIGNvbm5lY3Rpb25TZWdtZW50TW92ZSBpcyByZWZhY3RvcmVkXG4gIGlmIChuZXdMYWJlbExpbmVJbmRleCA8IDAgfHxcbiAgICAgIG5ld0xhYmVsTGluZUluZGV4ID4gbmV3V2F5cG9pbnRzLmxlbmd0aCAtIDIpIHtcbiAgICByZXR1cm4geyB4OiB4LCB5OiB5IH07XG4gIH1cblxuICB2YXIgb2xkTGFiZWxMaW5lID0gZ2V0TGluZShvbGRXYXlwb2ludHMsIG9sZExhYmVsTGluZUluZGV4KSxcbiAgICAgIG5ld0xhYmVsTGluZSA9IGdldExpbmUobmV3V2F5cG9pbnRzLCBuZXdMYWJlbExpbmVJbmRleCksXG4gICAgICBvbGRGb290ID0gYXR0YWNobWVudC5wb3NpdGlvbjtcblxuICB2YXIgcmVsYXRpdmVGb290UG9zaXRpb24gPSBnZXRSZWxhdGl2ZUZvb3RQb3NpdGlvbihvbGRMYWJlbExpbmUsIG9sZEZvb3QpLFxuICAgICAgYW5nbGVEZWx0YSA9IGdldEFuZ2xlRGVsdGEob2xkTGFiZWxMaW5lLCBuZXdMYWJlbExpbmUpO1xuXG4gIC8vIHNwZWNpYWwgcnVsZSBpZiBsYWJlbCBvbiBiZW5kcG9pbnRcbiAgaWYgKGF0dGFjaG1lbnQudHlwZSA9PT0gJ2JlbmRwb2ludCcpIHtcblxuICAgIHZhciBvZmZzZXQgPSBuZXdXYXlwb2ludHMubGVuZ3RoIC0gb2xkV2F5cG9pbnRzLmxlbmd0aCxcbiAgICAgICAgb2xkQmVuZHBvaW50SW5kZXggPSBhdHRhY2htZW50LmJlbmRwb2ludEluZGV4LFxuICAgICAgICBvbGRCZW5kcG9pbnQgPSBvbGRXYXlwb2ludHNbb2xkQmVuZHBvaW50SW5kZXhdO1xuXG4gICAgLy8gYmVuZHBvaW50IHBvc2l0aW9uIGhhc24ndCBjaGFuZ2VkLCByZXR1cm4gc2FtZSBwb3NpdGlvblxuICAgIGlmIChuZXdXYXlwb2ludHMuaW5kZXhPZihvbGRCZW5kcG9pbnQpICE9PSAtMSkge1xuICAgICAgcmV0dXJuIHsgeDogeCwgeTogeSB9O1xuICAgIH1cblxuICAgIC8vIG5ldyBiZW5kcG9pbnQgYW5kIG9sZCBiZW5kcG9pbnQgaGF2ZSBzYW1lIGluZGV4LCB0aGVuIGp1c3QgcmV0dXJuIHRoZSBvZmZzZXRcbiAgICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgICB2YXIgbmV3QmVuZHBvaW50ID0gbmV3V2F5cG9pbnRzW29sZEJlbmRwb2ludEluZGV4XTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgeDogbmV3QmVuZHBvaW50LnggLSBhdHRhY2htZW50LnBvc2l0aW9uLngsXG4gICAgICAgIHk6IG5ld0JlbmRwb2ludC55IC0gYXR0YWNobWVudC5wb3NpdGlvbi55XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIGlmIGJlbmRwb2ludHMgZ2V0IHJlbW92ZWRcbiAgICBpZiAob2Zmc2V0IDwgMCAmJiBvbGRCZW5kcG9pbnRJbmRleCAhPT0gMCAmJiBvbGRCZW5kcG9pbnRJbmRleCA8IG9sZFdheXBvaW50cy5sZW5ndGggLSAxKSB7XG4gICAgICByZWxhdGl2ZUZvb3RQb3NpdGlvbiA9IHJlbGF0aXZlUG9zaXRpb25NaWRXYXlwb2ludChvbGRXYXlwb2ludHMsIG9sZEJlbmRwb2ludEluZGV4KTtcbiAgICB9XG4gIH1cblxuICB2YXIgbmV3Rm9vdCA9IHtcbiAgICB4OiAobmV3TGFiZWxMaW5lWzFdLnggLSBuZXdMYWJlbExpbmVbMF0ueCkgKiByZWxhdGl2ZUZvb3RQb3NpdGlvbiArIG5ld0xhYmVsTGluZVswXS54LFxuICAgIHk6IChuZXdMYWJlbExpbmVbMV0ueSAtIG5ld0xhYmVsTGluZVswXS55KSAqIHJlbGF0aXZlRm9vdFBvc2l0aW9uICsgbmV3TGFiZWxMaW5lWzBdLnlcbiAgfTtcblxuICAvLyB0aGUgcm90YXRlZCB2ZWN0b3IgdG8gbGFiZWxcbiAgdmFyIG5ld0xhYmVsVmVjdG9yID0gcm90YXRlVmVjdG9yKHtcbiAgICB4OiBsYWJlbFBvc2l0aW9uLnggLSBvbGRGb290LngsXG4gICAgeTogbGFiZWxQb3NpdGlvbi55IC0gb2xkRm9vdC55XG4gIH0sIGFuZ2xlRGVsdGEpO1xuXG4gIC8vIHRoZSBuZXcgcmVsYXRpdmUgcG9zaXRpb25cbiAgeCA9IG5ld0Zvb3QueCArIG5ld0xhYmVsVmVjdG9yLnggLSBsYWJlbFBvc2l0aW9uLng7XG4gIHkgPSBuZXdGb290LnkgKyBuZXdMYWJlbFZlY3Rvci55IC0gbGFiZWxQb3NpdGlvbi55O1xuXG4gIHJldHVybiByb3VuZFBvaW50KHtcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfSk7XG59XG5cblxuLy8gSEVMUEVSUyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIHJlbGF0aXZlUG9zaXRpb25NaWRXYXlwb2ludCh3YXlwb2ludHMsIGlkeCkge1xuXG4gIHZhciBkaXN0YW5jZVNlZ21lbnQxID0gZ2V0RGlzdGFuY2VQb2ludFBvaW50KHdheXBvaW50c1tpZHgtMV0sIHdheXBvaW50c1tpZHhdKSxcbiAgICAgIGRpc3RhbmNlU2VnbWVudDIgPSBnZXREaXN0YW5jZVBvaW50UG9pbnQod2F5cG9pbnRzW2lkeF0sIHdheXBvaW50c1tpZHgrMV0pO1xuXG4gIHZhciByZWxhdGl2ZVBvc2l0aW9uID0gZGlzdGFuY2VTZWdtZW50MSAvIChkaXN0YW5jZVNlZ21lbnQxICsgZGlzdGFuY2VTZWdtZW50Mik7XG5cbiAgcmV0dXJuIHJlbGF0aXZlUG9zaXRpb247XG59XG5cbmZ1bmN0aW9uIGdldExhYmVsTWlkKGxhYmVsKSB7XG4gIHJldHVybiB7XG4gICAgeDogbGFiZWwueCArIGxhYmVsLndpZHRoIC8gMixcbiAgICB5OiBsYWJlbC55ICsgbGFiZWwuaGVpZ2h0IC8gMlxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRBbmdsZURlbHRhKGwxLCBsMikge1xuICB2YXIgYTEgPSBnZXRBbmdsZShsMSksXG4gICAgICBhMiA9IGdldEFuZ2xlKGwyKTtcbiAgcmV0dXJuIGEyIC0gYTE7XG59XG5cbmZ1bmN0aW9uIGdldExpbmUod2F5cG9pbnRzLCBpZHgpIHtcbiAgcmV0dXJuIFsgd2F5cG9pbnRzW2lkeF0sIHdheXBvaW50c1tpZHgrMV0gXTtcbn1cblxuZnVuY3Rpb24gZ2V0UmVsYXRpdmVGb290UG9zaXRpb24obGluZSwgZm9vdCkge1xuXG4gIHZhciBsZW5ndGggPSBnZXREaXN0YW5jZVBvaW50UG9pbnQobGluZVswXSwgbGluZVsxXSksXG4gICAgICBsZW5ndGhUb0Zvb3QgPSBnZXREaXN0YW5jZVBvaW50UG9pbnQobGluZVswXSwgZm9vdCk7XG5cbiAgcmV0dXJuIGxlbmd0aCA9PT0gMCA/IDAgOiBsZW5ndGhUb0Zvb3QgLyBsZW5ndGg7XG59XG4iLCJ2YXIgc3FydCA9IE1hdGguc3FydCxcbiAgICBtaW4gPSBNYXRoLm1pbixcbiAgICBtYXggPSBNYXRoLm1heCxcbiAgICBhYnMgPSBNYXRoLmFicztcblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHNxdWFyZSAocG93ZXIgdG8gdHdvKSBvZiBhIG51bWJlci5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gblxuICpcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZnVuY3Rpb24gc3Eobikge1xuICByZXR1cm4gTWF0aC5wb3cobiwgMik7XG59XG5cbi8qKlxuICogR2V0IGRpc3RhbmNlIGJldHdlZW4gdHdvIHBvaW50cy5cbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBwMVxuICogQHBhcmFtIHtQb2ludH0gcDJcbiAqXG4gKiBAcmV0dXJuIHtudW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIGdldERpc3RhbmNlKHAxLCBwMikge1xuICByZXR1cm4gc3FydChzcShwMS54IC0gcDIueCkgKyBzcShwMS55IC0gcDIueSkpO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgYXR0YWNobWVudCBvZiB0aGUgZ2l2ZW4gcG9pbnQgb24gdGhlIHNwZWNpZmllZCBsaW5lLlxuICpcbiAqIFRoZSBhdHRhY2htZW50IGlzIGVpdGhlciBhIGJlbmRwb2ludCAoYXR0YWNoZWQgdG8gdGhlIGdpdmVuIHBvaW50KVxuICogb3Igc2VnbWVudCAoYXR0YWNoZWQgdG8gYSBsb2NhdGlvbiBvbiBhIGxpbmUgc2VnbWVudCkgYXR0YWNobWVudDpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiB2YXIgcG9pbnRBdHRhY2htZW50ID0ge1xuICogICB0eXBlOiAnYmVuZHBvaW50JyxcbiAqICAgYmVuZHBvaW50SW5kZXg6IDMsXG4gKiAgIHBvc2l0aW9uOiB7IHg6IDEwLCB5OiAxMCB9IC8vIHRoZSBhdHRhY2ggcG9pbnQgb24gdGhlIGxpbmVcbiAqIH07XG4gKlxuICogdmFyIHNlZ21lbnRBdHRhY2htZW50ID0ge1xuICogICB0eXBlOiAnc2VnbWVudCcsXG4gKiAgIHNlZ21lbnRJbmRleDogMixcbiAqICAgcmVsYXRpdmVMb2NhdGlvbjogMC4zMSwgLy8gYXR0YWNoIHBvaW50IGxvY2F0aW9uIGJldHdlZW4gMCAoYXQgc3RhcnQpIGFuZCAxIChhdCBlbmQpXG4gKiAgIHBvc2l0aW9uOiB7IHg6IDEwLCB5OiAxMCB9IC8vIHRoZSBhdHRhY2ggcG9pbnQgb24gdGhlIGxpbmVcbiAqIH07XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBwb2ludFxuICogQHBhcmFtIHtBcnJheTxQb2ludD59IGxpbmVcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGF0dGFjaG1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF0dGFjaG1lbnQocG9pbnQsIGxpbmUpIHtcblxuICB2YXIgaWR4ID0gMCxcbiAgICAgIHNlZ21lbnRTdGFydCxcbiAgICAgIHNlZ21lbnRFbmQsXG4gICAgICBzZWdtZW50U3RhcnREaXN0YW5jZSxcbiAgICAgIHNlZ21lbnRFbmREaXN0YW5jZSxcbiAgICAgIGF0dGFjaG1lbnRQb3NpdGlvbixcbiAgICAgIG1pbkRpc3RhbmNlLFxuICAgICAgaW50ZXJzZWN0aW9ucyxcbiAgICAgIGF0dGFjaG1lbnQsXG4gICAgICBhdHRhY2htZW50RGlzdGFuY2UsXG4gICAgICBjbG9zZXN0QXR0YWNobWVudERpc3RhbmNlLFxuICAgICAgY2xvc2VzdEF0dGFjaG1lbnQ7XG5cbiAgZm9yIChpZHggPSAwOyBpZHggPCBsaW5lLmxlbmd0aCAtIDE7IGlkeCsrKSB7XG5cbiAgICBzZWdtZW50U3RhcnQgPSBsaW5lW2lkeF07XG4gICAgc2VnbWVudEVuZCA9IGxpbmVbaWR4ICsgMV07XG5cbiAgICBpZiAocG9pbnRzRXF1YWwoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKSkge1xuICAgICAgaW50ZXJzZWN0aW9ucyA9IFsgc2VnbWVudFN0YXJ0IF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlZ21lbnRTdGFydERpc3RhbmNlID0gZ2V0RGlzdGFuY2UocG9pbnQsIHNlZ21lbnRTdGFydCk7XG4gICAgICBzZWdtZW50RW5kRGlzdGFuY2UgPSBnZXREaXN0YW5jZShwb2ludCwgc2VnbWVudEVuZCk7XG5cbiAgICAgIG1pbkRpc3RhbmNlID0gbWluKHNlZ21lbnRTdGFydERpc3RhbmNlLCBzZWdtZW50RW5kRGlzdGFuY2UpO1xuXG4gICAgICBpbnRlcnNlY3Rpb25zID0gZ2V0Q2lyY2xlU2VnbWVudEludGVyc2VjdGlvbnMoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kLCBwb2ludCwgbWluRGlzdGFuY2UpO1xuICAgIH1cblxuICAgIGlmIChpbnRlcnNlY3Rpb25zLmxlbmd0aCA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0ZWQgYmV0d2VlbiBbMSwgMl0gY2lyY2xlIC0+IGxpbmUgaW50ZXJzZWN0aW9ucycpO1xuICAgIH1cblxuICAgIC8vIG9uZSBpbnRlcnNlY3Rpb24gLT4gYmVuZHBvaW50IGF0dGFjaG1lbnRcbiAgICBpZiAoaW50ZXJzZWN0aW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGF0dGFjaG1lbnQgPSB7XG4gICAgICAgIHR5cGU6ICdiZW5kcG9pbnQnLFxuICAgICAgICBwb3NpdGlvbjogaW50ZXJzZWN0aW9uc1swXSxcbiAgICAgICAgc2VnbWVudEluZGV4OiBpZHgsXG4gICAgICAgIGJlbmRwb2ludEluZGV4OiBwb2ludHNFcXVhbChzZWdtZW50U3RhcnQsIGludGVyc2VjdGlvbnNbMF0pID8gaWR4IDogaWR4ICsgMVxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyB0d28gaW50ZXJzZWN0aW9ucyAtPiBzZWdtZW50IGF0dGFjaG1lbnRcbiAgICBpZiAoaW50ZXJzZWN0aW9ucy5sZW5ndGggPT09IDIpIHtcblxuICAgICAgYXR0YWNobWVudFBvc2l0aW9uID0gbWlkKGludGVyc2VjdGlvbnNbMF0sIGludGVyc2VjdGlvbnNbMV0pO1xuXG4gICAgICBhdHRhY2htZW50ID0ge1xuICAgICAgICB0eXBlOiAnc2VnbWVudCcsXG4gICAgICAgIHBvc2l0aW9uOiBhdHRhY2htZW50UG9zaXRpb24sXG4gICAgICAgIHNlZ21lbnRJbmRleDogaWR4LFxuICAgICAgICByZWxhdGl2ZUxvY2F0aW9uOiBnZXREaXN0YW5jZShzZWdtZW50U3RhcnQsIGF0dGFjaG1lbnRQb3NpdGlvbikgLyBnZXREaXN0YW5jZShzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQpXG4gICAgICB9O1xuICAgIH1cblxuICAgIGF0dGFjaG1lbnREaXN0YW5jZSA9IGdldERpc3RhbmNlKGF0dGFjaG1lbnQucG9zaXRpb24sIHBvaW50KTtcblxuICAgIGlmICghY2xvc2VzdEF0dGFjaG1lbnQgfHwgY2xvc2VzdEF0dGFjaG1lbnREaXN0YW5jZSA+IGF0dGFjaG1lbnREaXN0YW5jZSkge1xuICAgICAgY2xvc2VzdEF0dGFjaG1lbnQgPSBhdHRhY2htZW50O1xuICAgICAgY2xvc2VzdEF0dGFjaG1lbnREaXN0YW5jZSA9IGF0dGFjaG1lbnREaXN0YW5jZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY2xvc2VzdEF0dGFjaG1lbnQ7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgaW50ZXJzZWN0aW9uIGJldHdlZW4gYSBjaXJjbGUgYW5kIGEgbGluZSBzZWdtZW50LlxuICpcbiAqIEBwYXJhbSB7UG9pbnR9IHMxIHNlZ21lbnQgc3RhcnRcbiAqIEBwYXJhbSB7UG9pbnR9IHMyIHNlZ21lbnQgZW5kXG4gKiBAcGFyYW0ge1BvaW50fSBjYyBjaXJjbGUgY2VudGVyXG4gKiBAcGFyYW0ge251bWJlcn0gY3IgY2lyY2xlIHJhZGl1c1xuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gaW50ZXJzZWN0aW9uc1xuICovXG5mdW5jdGlvbiBnZXRDaXJjbGVTZWdtZW50SW50ZXJzZWN0aW9ucyhzMSwgczIsIGNjLCBjcikge1xuXG4gIHZhciBiYVggPSBzMi54IC0gczEueDtcbiAgdmFyIGJhWSA9IHMyLnkgLSBzMS55O1xuICB2YXIgY2FYID0gY2MueCAtIHMxLng7XG4gIHZhciBjYVkgPSBjYy55IC0gczEueTtcblxuICB2YXIgYSA9IGJhWCAqIGJhWCArIGJhWSAqIGJhWTtcbiAgdmFyIGJCeTIgPSBiYVggKiBjYVggKyBiYVkgKiBjYVk7XG4gIHZhciBjID0gY2FYICogY2FYICsgY2FZICogY2FZIC0gY3IgKiBjcjtcblxuICB2YXIgcEJ5MiA9IGJCeTIgLyBhO1xuICB2YXIgcSA9IGMgLyBhO1xuXG4gIHZhciBkaXNjID0gcEJ5MiAqIHBCeTIgLSBxO1xuXG4gIC8vIGNoZWNrIGFnYWluc3QgbmVnYXRpdmUgdmFsdWUgdG8gd29yayBhcm91bmRcbiAgLy8gbmVnYXRpdmUsIHZlcnkgY2xvc2UgdG8gemVybyByZXN1bHRzICgtNGUtMTUpXG4gIC8vIGJlaW5nIHByb2R1Y2VkIGluIHNvbWUgZW52aXJvbm1lbnRzXG4gIGlmIChkaXNjIDwgMCAmJiBkaXNjID4gLTAuMDAwMDAxKSB7XG4gICAgZGlzYyA9IDA7XG4gIH1cblxuICBpZiAoZGlzYyA8IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvLyBpZiBkaXNjID09IDAgLi4uIGRlYWx0IHdpdGggbGF0ZXJcbiAgdmFyIHRtcFNxcnQgPSBzcXJ0KGRpc2MpO1xuICB2YXIgYWJTY2FsaW5nRmFjdG9yMSA9IC1wQnkyICsgdG1wU3FydDtcbiAgdmFyIGFiU2NhbGluZ0ZhY3RvcjIgPSAtcEJ5MiAtIHRtcFNxcnQ7XG5cbiAgdmFyIGkxID0ge1xuICAgIHg6IHMxLnggLSBiYVggKiBhYlNjYWxpbmdGYWN0b3IxLFxuICAgIHk6IHMxLnkgLSBiYVkgKiBhYlNjYWxpbmdGYWN0b3IxXG4gIH07XG5cbiAgaWYgKGRpc2MgPT09IDApIHsgLy8gYWJTY2FsaW5nRmFjdG9yMSA9PSBhYlNjYWxpbmdGYWN0b3IyXG4gICAgcmV0dXJuIFsgaTEgXTtcbiAgfVxuXG4gIHZhciBpMiA9IHtcbiAgICB4OiBzMS54IC0gYmFYICogYWJTY2FsaW5nRmFjdG9yMixcbiAgICB5OiBzMS55IC0gYmFZICogYWJTY2FsaW5nRmFjdG9yMlxuICB9O1xuXG4gIC8vIHJldHVybiBvbmx5IHBvaW50cyBvbiBsaW5lIHNlZ21lbnRcbiAgcmV0dXJuIFsgaTEsIGkyIF0uZmlsdGVyKGZ1bmN0aW9uKHApIHtcbiAgICByZXR1cm4gaXNQb2ludEluU2VnbWVudChwLCBzMSwgczIpO1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBpc1BvaW50SW5TZWdtZW50KHAsIHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCkge1xuICByZXR1cm4gKFxuICAgIGZlbmNlZChwLngsIHNlZ21lbnRTdGFydC54LCBzZWdtZW50RW5kLngpICYmXG4gICAgZmVuY2VkKHAueSwgc2VnbWVudFN0YXJ0LnksIHNlZ21lbnRFbmQueSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gZmVuY2VkKG4sIHJhbmdlU3RhcnQsIHJhbmdlRW5kKSB7XG5cbiAgLy8gdXNlIG1hdGNoaW5nIHRocmVzaG9sZCB0byB3b3JrIGFyb3VuZFxuICAvLyBwcmVjaXNpb24gZXJyb3JzIGluIGludGVyc2VjdGlvbiBjb21wdXRhdGlvblxuXG4gIHJldHVybiAoXG4gICAgbiA+PSBtaW4ocmFuZ2VTdGFydCwgcmFuZ2VFbmQpIC0gRVFVQUxfVEhSRVNIT0xEICYmXG4gICAgbiA8PSBtYXgocmFuZ2VTdGFydCwgcmFuZ2VFbmQpICsgRVFVQUxfVEhSRVNIT0xEXG4gICk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIG1pZCBvZiB0d28gcG9pbnRzLlxuICpcbiAqIEBwYXJhbSB7UG9pbnR9IHAxXG4gKiBAcGFyYW0ge1BvaW50fSBwMlxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5mdW5jdGlvbiBtaWQocDEsIHAyKSB7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiAocDEueCArIHAyLngpIC8gMixcbiAgICB5OiAocDEueSArIHAyLnkpIC8gMlxuICB9O1xufVxuXG52YXIgRVFVQUxfVEhSRVNIT0xEID0gMC4xO1xuXG5mdW5jdGlvbiBwb2ludHNFcXVhbChwMSwgcDIpIHtcblxuICByZXR1cm4gKFxuICAgIGFicyhwMS54IC0gcDIueCkgPD0gRVFVQUxfVEhSRVNIT0xEICYmXG4gICAgYWJzKHAxLnkgLSBwMi55KSA8PSBFUVVBTF9USFJFU0hPTERcbiAgKTtcbn1cbiIsIi8qKlxuICogUmV0dXJucyB0aGUgaW50ZXJzZWN0aW9uIGJldHdlZW4gdHdvIGxpbmUgc2VnbWVudHMgYSBhbmQgYi5cbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBsMXNcbiAqIEBwYXJhbSB7UG9pbnR9IGwxZVxuICogQHBhcmFtIHtQb2ludH0gbDJzXG4gKiBAcGFyYW0ge1BvaW50fSBsMmVcbiAqXG4gKiBAcmV0dXJuIHtQb2ludH1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGluZUludGVyc2VjdChsMXMsIGwxZSwgbDJzLCBsMmUpIHtcblxuICAvLyBpZiB0aGUgbGluZXMgaW50ZXJzZWN0LCB0aGUgcmVzdWx0IGNvbnRhaW5zIHRoZSB4IGFuZCB5IG9mIHRoZVxuICAvLyBpbnRlcnNlY3Rpb24gKHRyZWF0aW5nIHRoZSBsaW5lcyBhcyBpbmZpbml0ZSkgYW5kIGJvb2xlYW5zIGZvclxuICAvLyB3aGV0aGVyIGxpbmUgc2VnbWVudCAxIG9yIGxpbmUgc2VnbWVudCAyIGNvbnRhaW4gdGhlIHBvaW50XG4gIHZhciBkZW5vbWluYXRvciwgYSwgYiwgYywgbnVtZXJhdG9yO1xuXG4gIGRlbm9taW5hdG9yID0gKChsMmUueSAtIGwycy55KSAqIChsMWUueCAtIGwxcy54KSkgLSAoKGwyZS54IC0gbDJzLngpICogKGwxZS55IC0gbDFzLnkpKTtcblxuICBpZiAoZGVub21pbmF0b3IgPT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgYSA9IGwxcy55IC0gbDJzLnk7XG4gIGIgPSBsMXMueCAtIGwycy54O1xuICBudW1lcmF0b3IgPSAoKGwyZS54IC0gbDJzLngpICogYSkgLSAoKGwyZS55IC0gbDJzLnkpICogYik7XG5cbiAgYyA9IG51bWVyYXRvciAvIGRlbm9taW5hdG9yO1xuXG4gIC8vIGlmIHdlIGNhc3QgdGhlc2UgbGluZXMgaW5maW5pdGVseSBpblxuICAvLyBib3RoIGRpcmVjdGlvbnMsIHRoZXkgaW50ZXJzZWN0IGhlcmVcbiAgcmV0dXJuIHtcbiAgICB4OiBNYXRoLnJvdW5kKGwxcy54ICsgKGMgKiAobDFlLnggLSBsMXMueCkpKSxcbiAgICB5OiBNYXRoLnJvdW5kKGwxcy55ICsgKGMgKiAobDFlLnkgLSBsMXMueSkpKVxuICB9O1xufSIsImltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBhc1RSQkxcclxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIGNvbGxlY3RMYW5lcyxcclxuICBnZXRMYW5lc1Jvb3RcclxufSBmcm9tICcuLi8uLi8uLi9tb2RlbGluZy91dGlsL0xhbmVVdGlsJztcclxuXHJcbmltcG9ydCB7IExBTkVfTUlOX0RJTUVOU0lPTlMgfSBmcm9tICcuLi9SZXNpemVCZWhhdmlvcic7XHJcblxyXG52YXIgYWJzID0gTWF0aC5hYnMsXHJcbiAgICBtaW4gPSBNYXRoLm1pbixcclxuICAgIG1heCA9IE1hdGgubWF4O1xyXG5cclxuXHJcbmZ1bmN0aW9uIGFkZFRvVHJibCh0cmJsLCBhdHRyLCB2YWx1ZSwgY2hvaWNlKSB7XHJcbiAgdmFyIGN1cnJlbnQgPSB0cmJsW2F0dHJdO1xyXG5cclxuICAvLyBtYWtlIHN1cmUgdG8gc2V0IHRoZSB2YWx1ZSBpZiBpdCBkb2VzIG5vdCBleGlzdFxyXG4gIC8vIG9yIGFwcGx5IHRoZSBjb3JyZWN0IHZhbHVlIGJ5IGNvbXBhcmluZyBhZ2FpbnN0XHJcbiAgLy8gY2hvaWNlKHZhbHVlLCBjdXJyZW50VmFsdWUpXHJcbiAgdHJibFthdHRyXSA9IGN1cnJlbnQgPT09IHVuZGVmaW5lZCA/IHZhbHVlIDogY2hvaWNlKHZhbHVlLCBjdXJyZW50KTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkTWluKHRyYmwsIGF0dHIsIHZhbHVlKSB7XHJcbiAgcmV0dXJuIGFkZFRvVHJibCh0cmJsLCBhdHRyLCB2YWx1ZSwgbWluKTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkTWF4KHRyYmwsIGF0dHIsIHZhbHVlKSB7XHJcbiAgcmV0dXJuIGFkZFRvVHJibCh0cmJsLCBhdHRyLCB2YWx1ZSwgbWF4KTtcclxufVxyXG5cclxudmFyIExBTkVfUklHSFRfUEFERElORyA9IDIwLFxyXG4gICAgTEFORV9MRUZUX1BBRERJTkcgPSA1MCxcclxuICAgIExBTkVfVE9QX1BBRERJTkcgPSAyMCxcclxuICAgIExBTkVfQk9UVE9NX1BBRERJTkcgPSAyMDtcclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFydGljaXBhbnRSZXNpemVDb25zdHJhaW50cyhsYW5lU2hhcGUsIHJlc2l6ZURpcmVjdGlvbiwgYmFsYW5jZWQpIHtcclxuICB2YXIgbGFuZXNSb290ID0gZ2V0TGFuZXNSb290KGxhbmVTaGFwZSk7XHJcblxyXG4gIHZhciBpc0ZpcnN0ID0gdHJ1ZSxcclxuICAgICAgaXNMYXN0ID0gdHJ1ZTtcclxuXHJcbiAgLy8gbWF4IHRvcC9ib3R0b20gc2l6ZSBmb3IgbGFuZXNcclxuICB2YXIgYWxsTGFuZXMgPSBjb2xsZWN0TGFuZXMobGFuZXNSb290LCBbIGxhbmVzUm9vdCBdKTtcclxuXHJcbiAgdmFyIGxhbmVUcmJsID0gYXNUUkJMKGxhbmVTaGFwZSk7XHJcblxyXG4gIHZhciBtYXhUcmJsID0ge30sXHJcbiAgICAgIG1pblRyYmwgPSB7fTtcclxuXHJcbiAgaWYgKC9lLy50ZXN0KHJlc2l6ZURpcmVjdGlvbikpIHtcclxuICAgIG1pblRyYmwucmlnaHQgPSBsYW5lVHJibC5sZWZ0ICsgTEFORV9NSU5fRElNRU5TSU9OUy53aWR0aDtcclxuICB9IGVsc2VcclxuICBpZiAoL3cvLnRlc3QocmVzaXplRGlyZWN0aW9uKSkge1xyXG4gICAgbWluVHJibC5sZWZ0ID0gbGFuZVRyYmwucmlnaHQgLSBMQU5FX01JTl9ESU1FTlNJT05TLndpZHRoO1xyXG4gIH1cclxuXHJcbiAgYWxsTGFuZXMuZm9yRWFjaChmdW5jdGlvbihvdGhlcikge1xyXG5cclxuICAgIHZhciBvdGhlclRyYmwgPSBhc1RSQkwob3RoZXIpO1xyXG5cclxuICAgIGlmICgvbi8udGVzdChyZXNpemVEaXJlY3Rpb24pKSB7XHJcblxyXG4gICAgICBpZiAob3RoZXJUcmJsLnRvcCA8IChsYW5lVHJibC50b3AgLSAxMCkpIHtcclxuICAgICAgICBpc0ZpcnN0ID0gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIG1heCB0b3Agc2l6ZSAoYmFzZWQgb24gbmV4dCBlbGVtZW50KVxyXG4gICAgICBpZiAoYmFsYW5jZWQgJiYgYWJzKGxhbmVUcmJsLnRvcCAtIG90aGVyVHJibC5ib3R0b20pIDwgMTApIHtcclxuICAgICAgICBhZGRNYXgobWF4VHJibCwgJ3RvcCcsIG90aGVyVHJibC50b3AgKyBMQU5FX01JTl9ESU1FTlNJT05TLmhlaWdodCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIG1pbiB0b3Agc2l6ZSAoYmFzZWQgb24gc2VsZiBvciBuZXN0ZWQgZWxlbWVudClcclxuICAgICAgaWYgKGFicyhsYW5lVHJibC50b3AgLSBvdGhlclRyYmwudG9wKSA8IDUpIHtcclxuICAgICAgICBhZGRNaW4obWluVHJibCwgJ3RvcCcsIG90aGVyVHJibC5ib3R0b20gLSBMQU5FX01JTl9ESU1FTlNJT05TLmhlaWdodCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoL3MvLnRlc3QocmVzaXplRGlyZWN0aW9uKSkge1xyXG5cclxuICAgICAgaWYgKG90aGVyVHJibC5ib3R0b20gPiAobGFuZVRyYmwuYm90dG9tICsgMTApKSB7XHJcbiAgICAgICAgaXNMYXN0ID0gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIG1heCBib3R0b20gc2l6ZSAoYmFzZWQgb24gcHJldmlvdXMgZWxlbWVudClcclxuICAgICAgaWYgKGJhbGFuY2VkICYmIGFicyhsYW5lVHJibC5ib3R0b20gLSBvdGhlclRyYmwudG9wKSA8IDEwKSB7XHJcbiAgICAgICAgYWRkTWluKG1heFRyYmwsICdib3R0b20nLCBvdGhlclRyYmwuYm90dG9tIC0gTEFORV9NSU5fRElNRU5TSU9OUy5oZWlnaHQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBtaW4gYm90dG9tIHNpemUgKGJhc2VkIG9uIHNlbGYgb3IgbmVzdGVkIGVsZW1lbnQpXHJcbiAgICAgIGlmIChhYnMobGFuZVRyYmwuYm90dG9tIC0gb3RoZXJUcmJsLmJvdHRvbSkgPCA1KSB7XHJcbiAgICAgICAgYWRkTWF4KG1pblRyYmwsICdib3R0b20nLCBvdGhlclRyYmwudG9wICsgTEFORV9NSU5fRElNRU5TSU9OUy5oZWlnaHQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIC8vIG1heCB0b3AvYm90dG9tL2xlZnQvcmlnaHQgc2l6ZSBiYXNlZCBvbiBmbG93IG5vZGVzXHJcbiAgdmFyIGZsb3dFbGVtZW50cyA9IGxhbmVzUm9vdC5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24ocykge1xyXG4gICAgcmV0dXJuICFzLmhpZGRlbiAmJiAhcy53YXlwb2ludHMgJiYgKGlzKHMsICdicG1uOkZsb3dFbGVtZW50JykgfHwgaXMocywgJ2JwbW46QXJ0aWZhY3QnKSk7XHJcbiAgfSk7XHJcblxyXG4gIGZsb3dFbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dFbGVtZW50KSB7XHJcblxyXG4gICAgdmFyIGZsb3dFbGVtZW50VHJibCA9IGFzVFJCTChmbG93RWxlbWVudCk7XHJcblxyXG4gICAgaWYgKGlzRmlyc3QgJiYgL24vLnRlc3QocmVzaXplRGlyZWN0aW9uKSkge1xyXG4gICAgICBhZGRNaW4obWluVHJibCwgJ3RvcCcsIGZsb3dFbGVtZW50VHJibC50b3AgLSBMQU5FX1RPUF9QQURESU5HKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoL2UvLnRlc3QocmVzaXplRGlyZWN0aW9uKSkge1xyXG4gICAgICBhZGRNYXgobWluVHJibCwgJ3JpZ2h0JywgZmxvd0VsZW1lbnRUcmJsLnJpZ2h0ICsgTEFORV9SSUdIVF9QQURESU5HKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaXNMYXN0ICYmIC9zLy50ZXN0KHJlc2l6ZURpcmVjdGlvbikpIHtcclxuICAgICAgYWRkTWF4KG1pblRyYmwsICdib3R0b20nLCBmbG93RWxlbWVudFRyYmwuYm90dG9tICsgTEFORV9CT1RUT01fUEFERElORyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKC93Ly50ZXN0KHJlc2l6ZURpcmVjdGlvbikpIHtcclxuICAgICAgYWRkTWluKG1pblRyYmwsICdsZWZ0JywgZmxvd0VsZW1lbnRUcmJsLmxlZnQgLSBMQU5FX0xFRlRfUEFERElORyk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBtaW46IG1pblRyYmwsXHJcbiAgICBtYXg6IG1heFRyYmxcclxuICB9O1xyXG59IiwiaW1wb3J0IHtcbiAgZmlsdGVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZWFjaEVsZW1lbnRcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9FbGVtZW50cyc7XG5cbmltcG9ydCB7XG4gIGdldExhbmVzUm9vdCxcbiAgZ2V0Q2hpbGRMYW5lcyxcbiAgTEFORV9JTkRFTlRBVElPTlxufSBmcm9tICcuLi91dGlsL0xhbmVVdGlsJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGFsbG93cyB1cyB0byBhZGQgYSBuZXcgbGFuZVxuICogYWJvdmUgb3IgYmVsb3cgYW4gZXhpc3Rpbmcgb25lLlxuICpcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKiBAcGFyYW0ge1NwYWNlVG9vbH0gc3BhY2VUb29sXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFkZExhbmVIYW5kbGVyKG1vZGVsaW5nLCBzcGFjZVRvb2wpIHtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fc3BhY2VUb29sID0gc3BhY2VUb29sO1xufVxuXG5BZGRMYW5lSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnbW9kZWxpbmcnLFxuICAnc3BhY2VUb29sJ1xuXTtcblxuXG5BZGRMYW5lSGFuZGxlci5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgc3BhY2VUb29sID0gdGhpcy5fc3BhY2VUb29sLFxuICAgICAgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgbG9jYXRpb24gPSBjb250ZXh0LmxvY2F0aW9uO1xuXG4gIHZhciBsYW5lc1Jvb3QgPSBnZXRMYW5lc1Jvb3Qoc2hhcGUpO1xuXG4gIHZhciBpc1Jvb3QgPSBsYW5lc1Jvb3QgPT09IHNoYXBlLFxuICAgICAgbGFuZVBhcmVudCA9IGlzUm9vdCA/IHNoYXBlIDogc2hhcGUucGFyZW50O1xuXG4gIHZhciBleGlzdGluZ0NoaWxkTGFuZXMgPSBnZXRDaGlsZExhbmVzKGxhbmVQYXJlbnQpO1xuXG4gIC8vICgwKSBhZGQgYSBsYW5lIGlmIHdlIGN1cnJlbnRseSBnb3Qgbm9uZSBhbmQgYXJlIGFkZGluZyB0byByb290XG4gIGlmICghZXhpc3RpbmdDaGlsZExhbmVzLmxlbmd0aCkge1xuICAgIG1vZGVsaW5nLmNyZWF0ZVNoYXBlKHsgdHlwZTogJ2JwbW46TGFuZScgfSwge1xuICAgICAgeDogc2hhcGUueCArIExBTkVfSU5ERU5UQVRJT04sXG4gICAgICB5OiBzaGFwZS55LFxuICAgICAgd2lkdGg6IHNoYXBlLndpZHRoIC0gTEFORV9JTkRFTlRBVElPTixcbiAgICAgIGhlaWdodDogc2hhcGUuaGVpZ2h0XG4gICAgfSwgbGFuZVBhcmVudCk7XG4gIH1cblxuICAvLyAoMSkgY29sbGVjdCBhZmZlY3RlZCBlbGVtZW50cyB0byBjcmVhdGUgbmVjZXNzYXJ5IHNwYWNlXG4gIHZhciBhbGxBZmZlY3RlZCA9IFtdO1xuXG4gIGVhY2hFbGVtZW50KGxhbmVzUm9vdCwgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGFsbEFmZmVjdGVkLnB1c2goZWxlbWVudCk7XG5cbiAgICAvLyBoYW5kbGUgZWxlbWVudCBsYWJlbHMgaW4gdGhlIGRpYWdyYW0gcm9vdFxuICAgIGlmIChlbGVtZW50LmxhYmVsKSB7XG4gICAgICBhbGxBZmZlY3RlZC5wdXNoKGVsZW1lbnQubGFiZWwpO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50ID09PSBzaGFwZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXIoZWxlbWVudC5jaGlsZHJlbiwgZnVuY3Rpb24oYykge1xuICAgICAgcmV0dXJuIGMgIT09IHNoYXBlO1xuICAgIH0pO1xuICB9KTtcblxuICB2YXIgb2Zmc2V0ID0gbG9jYXRpb24gPT09ICd0b3AnID8gLTEyMCA6IDEyMCxcbiAgICAgIGxhbmVQb3NpdGlvbiA9IGxvY2F0aW9uID09PSAndG9wJyA/IHNoYXBlLnkgOiBzaGFwZS55ICsgc2hhcGUuaGVpZ2h0LFxuICAgICAgc3BhY2VQb3MgPSBsYW5lUG9zaXRpb24gKyAobG9jYXRpb24gPT09ICd0b3AnID8gMTAgOiAtMTApLFxuICAgICAgZGlyZWN0aW9uID0gbG9jYXRpb24gPT09ICd0b3AnID8gJ24nIDogJ3MnO1xuXG4gIHZhciBhZGp1c3RtZW50cyA9IHNwYWNlVG9vbC5jYWxjdWxhdGVBZGp1c3RtZW50cyhhbGxBZmZlY3RlZCwgJ3knLCBvZmZzZXQsIHNwYWNlUG9zKTtcblxuICBzcGFjZVRvb2wubWFrZVNwYWNlKFxuICAgIGFkanVzdG1lbnRzLm1vdmluZ1NoYXBlcyxcbiAgICBhZGp1c3RtZW50cy5yZXNpemluZ1NoYXBlcyxcbiAgICB7IHg6IDAsIHk6IG9mZnNldCB9LFxuICAgIGRpcmVjdGlvbixcbiAgICBzcGFjZVBvc1xuICApO1xuXG4gIC8vICgyKSBjcmVhdGUgbmV3IGxhbmUgYXQgb3BlbiBzcGFjZVxuICBjb250ZXh0Lm5ld0xhbmUgPSBtb2RlbGluZy5jcmVhdGVTaGFwZSh7IHR5cGU6ICdicG1uOkxhbmUnIH0sIHtcbiAgICB4OiBzaGFwZS54ICsgKGlzUm9vdCA/IExBTkVfSU5ERU5UQVRJT04gOiAwKSxcbiAgICB5OiBsYW5lUG9zaXRpb24gLSAobG9jYXRpb24gPT09ICd0b3AnID8gMTIwIDogMCksXG4gICAgd2lkdGg6IHNoYXBlLndpZHRoIC0gKGlzUm9vdCA/IExBTkVfSU5ERU5UQVRJT04gOiAwKSxcbiAgICBoZWlnaHQ6IDEyMFxuICB9LCBsYW5lUGFyZW50KTtcbn07XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBJZENsYWltSGFuZGxlcihtb2RkbGUpIHtcbiAgdGhpcy5fbW9kZGxlID0gbW9kZGxlO1xufVxuXG5JZENsYWltSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZGxlJyBdO1xuXG5cbklkQ2xhaW1IYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgaWRzID0gdGhpcy5fbW9kZGxlLmlkcyxcbiAgICAgIGlkID0gY29udGV4dC5pZCxcbiAgICAgIGVsZW1lbnQgPSBjb250ZXh0LmVsZW1lbnQsXG4gICAgICBjbGFpbWluZyA9IGNvbnRleHQuY2xhaW1pbmc7XG5cbiAgaWYgKGNsYWltaW5nKSB7XG4gICAgaWRzLmNsYWltKGlkLCBlbGVtZW50KTtcbiAgfSBlbHNlIHtcbiAgICBpZHMudW5jbGFpbShpZCk7XG4gIH1cbn07XG5cbi8qKlxuICogQ29tbWFuZCByZXZlcnQgaW1wbGVtZW50YXRpb24uXG4gKi9cbklkQ2xhaW1IYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBpZHMgPSB0aGlzLl9tb2RkbGUuaWRzLFxuICAgICAgaWQgPSBjb250ZXh0LmlkLFxuICAgICAgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcbiAgICAgIGNsYWltaW5nID0gY29udGV4dC5jbGFpbWluZztcblxuICBpZiAoY2xhaW1pbmcpIHtcbiAgICBpZHMudW5jbGFpbShpZCk7XG4gIH0gZWxzZSB7XG4gICAgaWRzLmNsYWltKGlkLCBlbGVtZW50KTtcbiAgfVxufTtcblxuIiwiaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldExhbmVzUm9vdCxcbiAgY29tcHV0ZUxhbmVzUmVzaXplXG59IGZyb20gJy4uL3V0aWwvTGFuZVV0aWwnO1xuXG5pbXBvcnQge1xuICBlYWNoRWxlbWVudFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IHtcbiAgYXNUUkJMXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgc3Vic3RyYWN0VFJCTFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvUmVzaXplVXRpbCc7XG5cblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCByZXNpemVzIGEgbGFuZS5cbiAqXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSZXNpemVMYW5lSGFuZGxlcihtb2RlbGluZywgc3BhY2VUb29sKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX3NwYWNlVG9vbCA9IHNwYWNlVG9vbDtcbn1cblxuUmVzaXplTGFuZUhhbmRsZXIuJGluamVjdCA9IFtcbiAgJ21vZGVsaW5nJyxcbiAgJ3NwYWNlVG9vbCdcbl07XG5cblxuUmVzaXplTGFuZUhhbmRsZXIucHJvdG90eXBlLnByZUV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG5ld0JvdW5kcyA9IGNvbnRleHQubmV3Qm91bmRzLFxuICAgICAgYmFsYW5jZWQgPSBjb250ZXh0LmJhbGFuY2VkO1xuXG4gIGlmIChiYWxhbmNlZCAhPT0gZmFsc2UpIHtcbiAgICB0aGlzLnJlc2l6ZUJhbGFuY2VkKHNoYXBlLCBuZXdCb3VuZHMpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucmVzaXplU3BhY2Uoc2hhcGUsIG5ld0JvdW5kcyk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBSZXNpemUgYmFsYW5jZWQsIGFkanVzdGluZyBuZXh0IC8gcHJldmlvdXMgbGFuZSBzaXplcy5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAqIEBwYXJhbSB7Qm91bmRzfSBuZXdCb3VuZHNcbiAqL1xuUmVzaXplTGFuZUhhbmRsZXIucHJvdG90eXBlLnJlc2l6ZUJhbGFuY2VkID0gZnVuY3Rpb24oc2hhcGUsIG5ld0JvdW5kcykge1xuXG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nO1xuXG4gIHZhciByZXNpemVOZWVkZWQgPSBjb21wdXRlTGFuZXNSZXNpemUoc2hhcGUsIG5ld0JvdW5kcyk7XG5cbiAgLy8gcmVzaXplIHRoZSBsYW5lXG4gIG1vZGVsaW5nLnJlc2l6ZVNoYXBlKHNoYXBlLCBuZXdCb3VuZHMpO1xuXG4gIC8vIHJlc2l6ZSBvdGhlciBsYW5lcyBhcyBuZWVkZWRcbiAgcmVzaXplTmVlZGVkLmZvckVhY2goZnVuY3Rpb24ocikge1xuICAgIG1vZGVsaW5nLnJlc2l6ZVNoYXBlKHIuc2hhcGUsIHIubmV3Qm91bmRzKTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmVzaXplLCBtYWtpbmcgYWN0dWFsIHNwYWNlIGFuZCBtb3ZpbmcgYmVsb3cgLyBhYm92ZSBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAqIEBwYXJhbSB7Qm91bmRzfSBuZXdCb3VuZHNcbiAqL1xuUmVzaXplTGFuZUhhbmRsZXIucHJvdG90eXBlLnJlc2l6ZVNwYWNlID0gZnVuY3Rpb24oc2hhcGUsIG5ld0JvdW5kcykge1xuICB2YXIgc3BhY2VUb29sID0gdGhpcy5fc3BhY2VUb29sO1xuXG4gIHZhciBzaGFwZVRyYmwgPSBhc1RSQkwoc2hhcGUpLFxuICAgICAgbmV3VHJibCA9IGFzVFJCTChuZXdCb3VuZHMpO1xuXG4gIHZhciB0cmJsRGlmZiA9IHN1YnN0cmFjdFRSQkwobmV3VHJibCwgc2hhcGVUcmJsKTtcblxuICB2YXIgbGFuZXNSb290ID0gZ2V0TGFuZXNSb290KHNoYXBlKTtcblxuICB2YXIgYWxsQWZmZWN0ZWQgPSBbXSxcbiAgICAgIGFsbExhbmVzID0gW107XG5cbiAgZWFjaEVsZW1lbnQobGFuZXNSb290LCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgYWxsQWZmZWN0ZWQucHVzaChlbGVtZW50KTtcblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpMYW5lJykgfHwgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuICAgICAgYWxsTGFuZXMucHVzaChlbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudC5jaGlsZHJlbjtcbiAgfSk7XG5cbiAgdmFyIGNoYW5nZSxcbiAgICAgIHNwYWNlUG9zLFxuICAgICAgZGlyZWN0aW9uLFxuICAgICAgb2Zmc2V0LFxuICAgICAgYWRqdXN0bWVudHM7XG5cbiAgaWYgKHRyYmxEaWZmLmJvdHRvbSB8fCB0cmJsRGlmZi50b3ApIHtcblxuICAgIGNoYW5nZSA9IHRyYmxEaWZmLmJvdHRvbSB8fCB0cmJsRGlmZi50b3A7XG4gICAgc3BhY2VQb3MgPSBzaGFwZS55ICsgKHRyYmxEaWZmLmJvdHRvbSA/IHNoYXBlLmhlaWdodCA6IDApICsgKHRyYmxEaWZmLmJvdHRvbSA/IC0xMCA6IDEwKTtcbiAgICBkaXJlY3Rpb24gPSB0cmJsRGlmZi5ib3R0b20gPyAncycgOiAnbic7XG5cbiAgICBvZmZzZXQgPSB0cmJsRGlmZi50b3AgPiAwIHx8IHRyYmxEaWZmLmJvdHRvbSA8IDAgPyAtY2hhbmdlIDogY2hhbmdlO1xuXG4gICAgYWRqdXN0bWVudHMgPSBzcGFjZVRvb2wuY2FsY3VsYXRlQWRqdXN0bWVudHMoYWxsQWZmZWN0ZWQsICd5Jywgb2Zmc2V0LCBzcGFjZVBvcyk7XG5cbiAgICBzcGFjZVRvb2wubWFrZVNwYWNlKGFkanVzdG1lbnRzLm1vdmluZ1NoYXBlcywgYWRqdXN0bWVudHMucmVzaXppbmdTaGFwZXMsIHsgeDogMCwgeTogY2hhbmdlIH0sIGRpcmVjdGlvbik7XG4gIH1cblxuXG4gIGlmICh0cmJsRGlmZi5sZWZ0IHx8IHRyYmxEaWZmLnJpZ2h0KSB7XG5cbiAgICBjaGFuZ2UgPSB0cmJsRGlmZi5yaWdodCB8fCB0cmJsRGlmZi5sZWZ0O1xuICAgIHNwYWNlUG9zID0gc2hhcGUueCArICh0cmJsRGlmZi5yaWdodCA/IHNoYXBlLndpZHRoIDogMCkgKyAodHJibERpZmYucmlnaHQgPyAtMTAgOiAxMDApO1xuICAgIGRpcmVjdGlvbiA9IHRyYmxEaWZmLnJpZ2h0ID8gJ2UnIDogJ3cnO1xuXG4gICAgb2Zmc2V0ID0gdHJibERpZmYubGVmdCA+IDAgfHwgdHJibERpZmYucmlnaHQgPCAwID8gLWNoYW5nZSA6IGNoYW5nZTtcblxuICAgIGFkanVzdG1lbnRzID0gc3BhY2VUb29sLmNhbGN1bGF0ZUFkanVzdG1lbnRzKGFsbExhbmVzLCAneCcsIG9mZnNldCwgc3BhY2VQb3MpO1xuXG4gICAgc3BhY2VUb29sLm1ha2VTcGFjZShhZGp1c3RtZW50cy5tb3ZpbmdTaGFwZXMsIGFkanVzdG1lbnRzLnJlc2l6aW5nU2hhcGVzLCB7IHg6IGNoYW5nZSwgeTogMCB9LCBkaXJlY3Rpb24pO1xuICB9XG59OyIsImltcG9ydCB7XHJcbiAgYXNzaWduLFxyXG4gIGZvckVhY2hcclxufSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG5cclxudmFyIERFRkFVTFRfQ09MT1JTID0ge1xyXG4gIGZpbGw6IHVuZGVmaW5lZCxcclxuICBzdHJva2U6IHVuZGVmaW5lZFxyXG59O1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNldENvbG9ySGFuZGxlcihjb21tYW5kU3RhY2spIHtcclxuICB0aGlzLl9jb21tYW5kU3RhY2sgPSBjb21tYW5kU3RhY2s7XHJcbn1cclxuXHJcblNldENvbG9ySGFuZGxlci4kaW5qZWN0ID0gW1xyXG4gICdjb21tYW5kU3RhY2snXHJcbl07XHJcblxyXG5cclxuU2V0Q29sb3JIYW5kbGVyLnByb3RvdHlwZS5wb3N0RXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzLFxyXG4gICAgICBjb2xvcnMgPSBjb250ZXh0LmNvbG9ycyB8fCBERUZBVUxUX0NPTE9SUztcclxuXHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICB2YXIgZGkgPSB7fTtcclxuXHJcbiAgaWYgKCdmaWxsJyBpbiBjb2xvcnMpIHtcclxuICAgIGFzc2lnbihkaSwgeyBmaWxsOiBjb2xvcnMuZmlsbCB9KTtcclxuICB9XHJcblxyXG4gIGlmICgnc3Ryb2tlJyBpbiBjb2xvcnMpIHtcclxuICAgIGFzc2lnbihkaSwgeyBzdHJva2U6IGNvbG9ycy5zdHJva2UgfSk7XHJcbiAgfVxyXG5cclxuICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XHJcblxyXG4gICAgc2VsZi5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnQudXBkYXRlUHJvcGVydGllcycsIHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgcHJvcGVydGllczoge1xyXG4gICAgICAgIGRpOiBkaVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9KTtcclxuXHJcbn07IiwiaW1wb3J0IHtcbiAgZ2V0Q2hpbGRMYW5lcyxcbiAgTEFORV9JTkRFTlRBVElPTlxufSBmcm9tICcuLi91dGlsL0xhbmVVdGlsJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IHNwbGl0cyBhIGxhbmUgaW50byBhIG51bWJlciBvZiBzdWItbGFuZXMsXG4gKiBjcmVhdGluZyBuZXcgc3ViIGxhbmVzLCBpZiBuZWNlc3NhcnkuXG4gKlxuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gU3BsaXRMYW5lSGFuZGxlcihtb2RlbGluZywgdHJhbnNsYXRlKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcbn1cblxuU3BsaXRMYW5lSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnbW9kZWxpbmcnLFxuICAndHJhbnNsYXRlJ1xuXTtcblxuXG5TcGxpdExhbmVIYW5kbGVyLnByb3RvdHlwZS5wcmVFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nLFxuICAgICAgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuXG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBuZXdMYW5lc0NvdW50ID0gY29udGV4dC5jb3VudDtcblxuICB2YXIgY2hpbGRMYW5lcyA9IGdldENoaWxkTGFuZXMoc2hhcGUpLFxuICAgICAgZXhpc3RpbmdMYW5lc0NvdW50ID0gY2hpbGRMYW5lcy5sZW5ndGg7XG5cbiAgaWYgKGV4aXN0aW5nTGFuZXNDb3VudCA+IG5ld0xhbmVzQ291bnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodHJhbnNsYXRlKCdtb3JlIHRoYW4ge2NvdW50fSBjaGlsZCBsYW5lcycsIHsgY291bnQ6IG5ld0xhbmVzQ291bnQgfSkpO1xuICB9XG5cbiAgdmFyIG5ld0xhbmVzSGVpZ2h0ID0gTWF0aC5yb3VuZChzaGFwZS5oZWlnaHQgLyBuZXdMYW5lc0NvdW50KTtcblxuICAvLyBJdGVyYXRlIGZyb20gdG9wIHRvIGJvdHRvbSBpbiBjaGlsZCBsYW5lIG9yZGVyLFxuICAvLyByZXNpemluZyBleGlzdGluZyBsYW5lcyBhbmQgY3JlYXRpbmcgbmV3IG9uZXNcbiAgLy8gc28gdGhhdCB0aGV5IHNwbGl0IHRoZSBwYXJlbnQgcHJvcG9ydGlvbmFsbHkuXG4gIC8vXG4gIC8vIER1ZSB0byByb3VuZGluZyByZWxhdGVkIGVycm9ycywgdGhlIGJvdHRvbSBsYW5lXG4gIC8vIG5lZWRzIHRvIHRha2UgdXAgYWxsIHRoZSByZW1haW5pbmcgc3BhY2UuXG4gIHZhciBsYW5lWSxcbiAgICAgIGxhbmVIZWlnaHQsXG4gICAgICBsYW5lQm91bmRzLFxuICAgICAgbmV3TGFuZUF0dHJzLFxuICAgICAgaWR4O1xuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbmV3TGFuZXNDb3VudDsgaWR4KyspIHtcblxuICAgIGxhbmVZID0gc2hhcGUueSArIGlkeCAqIG5ld0xhbmVzSGVpZ2h0O1xuXG4gICAgLy8gaWYgYm90dG9tIGxhbmVcbiAgICBpZiAoaWR4ID09PSBuZXdMYW5lc0NvdW50IC0gMSkge1xuICAgICAgbGFuZUhlaWdodCA9IHNoYXBlLmhlaWdodCAtIChuZXdMYW5lc0hlaWdodCAqIGlkeCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxhbmVIZWlnaHQgPSBuZXdMYW5lc0hlaWdodDtcbiAgICB9XG5cbiAgICBsYW5lQm91bmRzID0ge1xuICAgICAgeDogc2hhcGUueCArIExBTkVfSU5ERU5UQVRJT04sXG4gICAgICB5OiBsYW5lWSxcbiAgICAgIHdpZHRoOiBzaGFwZS53aWR0aCAtIExBTkVfSU5ERU5UQVRJT04sXG4gICAgICBoZWlnaHQ6IGxhbmVIZWlnaHRcbiAgICB9O1xuXG4gICAgaWYgKGlkeCA8IGV4aXN0aW5nTGFuZXNDb3VudCkge1xuXG4gICAgICAvLyByZXNpemUgZXhpc3RpbmcgbGFuZVxuICAgICAgbW9kZWxpbmcucmVzaXplU2hhcGUoY2hpbGRMYW5lc1tpZHhdLCBsYW5lQm91bmRzKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBjcmVhdGUgYSBuZXcgbGFuZSBhdCBwb3NpdGlvblxuICAgICAgbmV3TGFuZUF0dHJzID0ge1xuICAgICAgICB0eXBlOiAnYnBtbjpMYW5lJ1xuICAgICAgfTtcblxuICAgICAgbW9kZWxpbmcuY3JlYXRlU2hhcGUobmV3TGFuZUF0dHJzLCBsYW5lQm91bmRzLCBzaGFwZSk7XG4gICAgfVxuICB9XG59O1xuIiwiaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIHJlbW92ZSBhcyBjb2xsZWN0aW9uUmVtb3ZlXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFVwZGF0ZUNhbnZhc1Jvb3RIYW5kbGVyKGNhbnZhcywgbW9kZWxpbmcpIHtcbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xufVxuXG5VcGRhdGVDYW52YXNSb290SGFuZGxlci4kaW5qZWN0ID0gW1xuICAnY2FudmFzJyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuXG5VcGRhdGVDYW52YXNSb290SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY2FudmFzID0gdGhpcy5fY2FudmFzO1xuXG4gIHZhciBuZXdSb290ID0gY29udGV4dC5uZXdSb290LFxuICAgICAgbmV3Um9vdEJ1c2luZXNzT2JqZWN0ID0gbmV3Um9vdC5idXNpbmVzc09iamVjdCxcbiAgICAgIG9sZFJvb3QgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgIG9sZFJvb3RCdXNpbmVzc09iamVjdCA9IG9sZFJvb3QuYnVzaW5lc3NPYmplY3QsXG4gICAgICBicG1uRGVmaW5pdGlvbnMgPSBvbGRSb290QnVzaW5lc3NPYmplY3QuJHBhcmVudCxcbiAgICAgIGRpUGxhbmUgPSBvbGRSb290QnVzaW5lc3NPYmplY3QuZGk7XG5cbiAgLy8gKDEpIHJlcGxhY2UgcHJvY2VzcyBvbGQgPD4gbmV3IHJvb3RcbiAgY2FudmFzLnNldFJvb3RFbGVtZW50KG5ld1Jvb3QsIHRydWUpO1xuXG4gIC8vICgyKSB1cGRhdGUgcm9vdCBlbGVtZW50c1xuICBjb2xsZWN0aW9uQWRkKGJwbW5EZWZpbml0aW9ucy5yb290RWxlbWVudHMsIG5ld1Jvb3RCdXNpbmVzc09iamVjdCk7XG4gIG5ld1Jvb3RCdXNpbmVzc09iamVjdC4kcGFyZW50ID0gYnBtbkRlZmluaXRpb25zO1xuXG4gIGNvbGxlY3Rpb25SZW1vdmUoYnBtbkRlZmluaXRpb25zLnJvb3RFbGVtZW50cywgb2xkUm9vdEJ1c2luZXNzT2JqZWN0KTtcbiAgb2xkUm9vdEJ1c2luZXNzT2JqZWN0LiRwYXJlbnQgPSBudWxsO1xuXG4gIC8vICgzKSB3aXJlIGRpXG4gIG9sZFJvb3RCdXNpbmVzc09iamVjdC5kaSA9IG51bGw7XG5cbiAgZGlQbGFuZS5icG1uRWxlbWVudCA9IG5ld1Jvb3RCdXNpbmVzc09iamVjdDtcbiAgbmV3Um9vdEJ1c2luZXNzT2JqZWN0LmRpID0gZGlQbGFuZTtcblxuICBjb250ZXh0Lm9sZFJvb3QgPSBvbGRSb290O1xuXG4gIC8vIFRPRE8obmlra3UpOiByZXR1cm4gY2hhbmdlZCBlbGVtZW50cz9cbiAgLy8gcmV0dXJuIFsgbmV3Um9vdCwgb2xkUm9vdCBdO1xufTtcblxuXG5VcGRhdGVDYW52YXNSb290SGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjYW52YXMgPSB0aGlzLl9jYW52YXM7XG5cbiAgdmFyIG5ld1Jvb3QgPSBjb250ZXh0Lm5ld1Jvb3QsXG4gICAgICBuZXdSb290QnVzaW5lc3NPYmplY3QgPSBuZXdSb290LmJ1c2luZXNzT2JqZWN0LFxuICAgICAgb2xkUm9vdCA9IGNvbnRleHQub2xkUm9vdCxcbiAgICAgIG9sZFJvb3RCdXNpbmVzc09iamVjdCA9IG9sZFJvb3QuYnVzaW5lc3NPYmplY3QsXG4gICAgICBicG1uRGVmaW5pdGlvbnMgPSBuZXdSb290QnVzaW5lc3NPYmplY3QuJHBhcmVudCxcbiAgICAgIGRpUGxhbmUgPSBuZXdSb290QnVzaW5lc3NPYmplY3QuZGk7XG5cbiAgLy8gKDEpIHJlcGxhY2UgcHJvY2VzcyBvbGQgPD4gbmV3IHJvb3RcbiAgY2FudmFzLnNldFJvb3RFbGVtZW50KG9sZFJvb3QsIHRydWUpO1xuXG4gIC8vICgyKSB1cGRhdGUgcm9vdCBlbGVtZW50c1xuICBjb2xsZWN0aW9uUmVtb3ZlKGJwbW5EZWZpbml0aW9ucy5yb290RWxlbWVudHMsIG5ld1Jvb3RCdXNpbmVzc09iamVjdCk7XG4gIG5ld1Jvb3RCdXNpbmVzc09iamVjdC4kcGFyZW50ID0gbnVsbDtcblxuICBjb2xsZWN0aW9uQWRkKGJwbW5EZWZpbml0aW9ucy5yb290RWxlbWVudHMsIG9sZFJvb3RCdXNpbmVzc09iamVjdCk7XG4gIG9sZFJvb3RCdXNpbmVzc09iamVjdC4kcGFyZW50ID0gYnBtbkRlZmluaXRpb25zO1xuXG4gIC8vICgzKSB3aXJlIGRpXG4gIG5ld1Jvb3RCdXNpbmVzc09iamVjdC5kaSA9IG51bGw7XG5cbiAgZGlQbGFuZS5icG1uRWxlbWVudCA9IG9sZFJvb3RCdXNpbmVzc09iamVjdDtcbiAgb2xkUm9vdEJ1c2luZXNzT2JqZWN0LmRpID0gZGlQbGFuZTtcblxuICAvLyBUT0RPKG5pa2t1KTogcmV0dXJuIGNoYW5nZWQgZWxlbWVudHM/XG4gIC8vIHJldHVybiBbIG5ld1Jvb3QsIG9sZFJvb3QgXTtcbn07IiwiaW1wb3J0IHtcbiAgY29sbGVjdExhbmVzLFxuICBnZXRMYW5lc1Jvb3Rcbn0gZnJvbSAnLi4vdXRpbC9MYW5lVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIHJlbW92ZSBhcyBjb2xsZWN0aW9uUmVtb3ZlXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5pbXBvcnQge1xuICBhc1RSQkxcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG52YXIgRkxPV19OT0RFX1JFRlNfQVRUUiA9ICdmbG93Tm9kZVJlZicsXG4gICAgTEFORVNfQVRUUiA9ICdsYW5lcyc7XG5cblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCB1cGRhdGVzIGxhbmUgcmVmcyBvbiBjaGFuZ2VkIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFVwZGF0ZUZsb3dOb2RlUmVmc0hhbmRsZXIoZWxlbWVudFJlZ2lzdHJ5KSB7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbn1cblxuVXBkYXRlRmxvd05vZGVSZWZzSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnZWxlbWVudFJlZ2lzdHJ5J1xuXTtcblxuXG5VcGRhdGVGbG93Tm9kZVJlZnNIYW5kbGVyLnByb3RvdHlwZS5jb21wdXRlVXBkYXRlcyA9IGZ1bmN0aW9uKGZsb3dOb2RlU2hhcGVzLCBsYW5lU2hhcGVzKSB7XG5cbiAgdmFyIGhhbmRsZWROb2RlcyA9IFtdO1xuXG4gIHZhciB1cGRhdGVzID0gW107XG5cbiAgdmFyIHBhcnRpY2lwYW50Q2FjaGUgPSB7fTtcblxuICB2YXIgYWxsRmxvd05vZGVTaGFwZXMgPSBbXTtcblxuICBmdW5jdGlvbiBpc0luTGFuZVNoYXBlKGVsZW1lbnQsIGxhbmVTaGFwZSkge1xuXG4gICAgdmFyIGxhbmVUcmJsID0gYXNUUkJMKGxhbmVTaGFwZSk7XG5cbiAgICB2YXIgZWxlbWVudE1pZCA9IHtcbiAgICAgIHg6IGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGggLyAyLFxuICAgICAgeTogZWxlbWVudC55ICsgZWxlbWVudC5oZWlnaHQgLyAyXG4gICAgfTtcblxuICAgIHJldHVybiBlbGVtZW50TWlkLnggPiBsYW5lVHJibC5sZWZ0ICYmXG4gICAgICAgICAgIGVsZW1lbnRNaWQueCA8IGxhbmVUcmJsLnJpZ2h0ICYmXG4gICAgICAgICAgIGVsZW1lbnRNaWQueSA+IGxhbmVUcmJsLnRvcCAmJlxuICAgICAgICAgICBlbGVtZW50TWlkLnkgPCBsYW5lVHJibC5ib3R0b207XG4gIH1cblxuICBmdW5jdGlvbiBhZGRGbG93Tm9kZVNoYXBlKGZsb3dOb2RlU2hhcGUpIHtcbiAgICBpZiAoaGFuZGxlZE5vZGVzLmluZGV4T2YoZmxvd05vZGVTaGFwZSkgPT09IC0xKSB7XG4gICAgICBhbGxGbG93Tm9kZVNoYXBlcy5wdXNoKGZsb3dOb2RlU2hhcGUpO1xuICAgICAgaGFuZGxlZE5vZGVzLnB1c2goZmxvd05vZGVTaGFwZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ2V0QWxsTGFuZVNoYXBlcyhmbG93Tm9kZVNoYXBlKSB7XG5cbiAgICB2YXIgcm9vdCA9IGdldExhbmVzUm9vdChmbG93Tm9kZVNoYXBlKTtcblxuICAgIGlmICghcGFydGljaXBhbnRDYWNoZVtyb290LmlkXSkge1xuICAgICAgcGFydGljaXBhbnRDYWNoZVtyb290LmlkXSA9IGNvbGxlY3RMYW5lcyhyb290KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFydGljaXBhbnRDYWNoZVtyb290LmlkXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE5ld0xhbmVzKGZsb3dOb2RlU2hhcGUpIHtcbiAgICBpZiAoIWZsb3dOb2RlU2hhcGUucGFyZW50KSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgdmFyIGFsbExhbmVTaGFwZXMgPSBnZXRBbGxMYW5lU2hhcGVzKGZsb3dOb2RlU2hhcGUpO1xuXG4gICAgcmV0dXJuIGFsbExhbmVTaGFwZXMuZmlsdGVyKGZ1bmN0aW9uKGwpIHtcbiAgICAgIHJldHVybiBpc0luTGFuZVNoYXBlKGZsb3dOb2RlU2hhcGUsIGwpO1xuICAgIH0pLm1hcChmdW5jdGlvbihzaGFwZSkge1xuICAgICAgcmV0dXJuIHNoYXBlLmJ1c2luZXNzT2JqZWN0O1xuICAgIH0pO1xuICB9XG5cbiAgbGFuZVNoYXBlcy5mb3JFYWNoKGZ1bmN0aW9uKGxhbmVTaGFwZSkge1xuICAgIHZhciByb290ID0gZ2V0TGFuZXNSb290KGxhbmVTaGFwZSk7XG5cbiAgICBpZiAoIXJvb3QgfHwgaGFuZGxlZE5vZGVzLmluZGV4T2Yocm9vdCkgIT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGNoaWxkcmVuID0gcm9vdC5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24oYykge1xuICAgICAgcmV0dXJuIGlzKGMsICdicG1uOkZsb3dOb2RlJyk7XG4gICAgfSk7XG5cbiAgICBjaGlsZHJlbi5mb3JFYWNoKGFkZEZsb3dOb2RlU2hhcGUpO1xuXG4gICAgaGFuZGxlZE5vZGVzLnB1c2gocm9vdCk7XG4gIH0pO1xuXG4gIGZsb3dOb2RlU2hhcGVzLmZvckVhY2goYWRkRmxvd05vZGVTaGFwZSk7XG5cblxuICBhbGxGbG93Tm9kZVNoYXBlcy5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dOb2RlU2hhcGUpIHtcblxuICAgIHZhciBmbG93Tm9kZSA9IGZsb3dOb2RlU2hhcGUuYnVzaW5lc3NPYmplY3Q7XG5cbiAgICB2YXIgbGFuZXMgPSBmbG93Tm9kZS5nZXQoTEFORVNfQVRUUiksXG4gICAgICAgIHJlbW92ZSA9IGxhbmVzLnNsaWNlKCksXG4gICAgICAgIGFkZCA9IGdldE5ld0xhbmVzKGZsb3dOb2RlU2hhcGUpO1xuXG4gICAgdXBkYXRlcy5wdXNoKHsgZmxvd05vZGU6IGZsb3dOb2RlLCByZW1vdmU6IHJlbW92ZSwgYWRkOiBhZGQgfSk7XG4gIH0pO1xuXG4gIGxhbmVTaGFwZXMuZm9yRWFjaChmdW5jdGlvbihsYW5lU2hhcGUpIHtcblxuICAgIHZhciBsYW5lID0gbGFuZVNoYXBlLmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgLy8gbGFuZSBnb3QgcmVtb3ZlZCBYWC0pXG4gICAgaWYgKCFsYW5lU2hhcGUucGFyZW50KSB7XG4gICAgICBsYW5lLmdldChGTE9XX05PREVfUkVGU19BVFRSKS5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dOb2RlKSB7XG4gICAgICAgIHVwZGF0ZXMucHVzaCh7IGZsb3dOb2RlOiBmbG93Tm9kZSwgcmVtb3ZlOiBbIGxhbmUgXSwgYWRkOiBbXSB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHVwZGF0ZXM7XG59O1xuXG5VcGRhdGVGbG93Tm9kZVJlZnNIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciB1cGRhdGVzID0gY29udGV4dC51cGRhdGVzO1xuXG4gIGlmICghdXBkYXRlcykge1xuICAgIHVwZGF0ZXMgPSBjb250ZXh0LnVwZGF0ZXMgPSB0aGlzLmNvbXB1dGVVcGRhdGVzKGNvbnRleHQuZmxvd05vZGVTaGFwZXMsIGNvbnRleHQubGFuZVNoYXBlcyk7XG4gIH1cblxuXG4gIHVwZGF0ZXMuZm9yRWFjaChmdW5jdGlvbih1cGRhdGUpIHtcblxuICAgIHZhciBmbG93Tm9kZSA9IHVwZGF0ZS5mbG93Tm9kZSxcbiAgICAgICAgbGFuZXMgPSBmbG93Tm9kZS5nZXQoTEFORVNfQVRUUik7XG5cbiAgICAvLyB1bndpcmUgb2xkXG4gICAgdXBkYXRlLnJlbW92ZS5mb3JFYWNoKGZ1bmN0aW9uKG9sZExhbmUpIHtcbiAgICAgIGNvbGxlY3Rpb25SZW1vdmUobGFuZXMsIG9sZExhbmUpO1xuICAgICAgY29sbGVjdGlvblJlbW92ZShvbGRMYW5lLmdldChGTE9XX05PREVfUkVGU19BVFRSKSwgZmxvd05vZGUpO1xuICAgIH0pO1xuXG4gICAgLy8gd2lyZSBuZXdcbiAgICB1cGRhdGUuYWRkLmZvckVhY2goZnVuY3Rpb24obmV3TGFuZSkge1xuICAgICAgY29sbGVjdGlvbkFkZChsYW5lcywgbmV3TGFuZSk7XG4gICAgICBjb2xsZWN0aW9uQWRkKG5ld0xhbmUuZ2V0KEZMT1dfTk9ERV9SRUZTX0FUVFIpLCBmbG93Tm9kZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIFRPRE8obmlra3UpOiByZXR1cm4gY2hhbmdlZCBlbGVtZW50c1xuICAvLyByZXR1cm4gWyAuLi4gXTtcbn07XG5cblxuVXBkYXRlRmxvd05vZGVSZWZzSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciB1cGRhdGVzID0gY29udGV4dC51cGRhdGVzO1xuXG4gIHVwZGF0ZXMuZm9yRWFjaChmdW5jdGlvbih1cGRhdGUpIHtcblxuICAgIHZhciBmbG93Tm9kZSA9IHVwZGF0ZS5mbG93Tm9kZSxcbiAgICAgICAgbGFuZXMgPSBmbG93Tm9kZS5nZXQoTEFORVNfQVRUUik7XG5cbiAgICAvLyB1bndpcmUgbmV3XG4gICAgdXBkYXRlLmFkZC5mb3JFYWNoKGZ1bmN0aW9uKG5ld0xhbmUpIHtcbiAgICAgIGNvbGxlY3Rpb25SZW1vdmUobGFuZXMsIG5ld0xhbmUpO1xuICAgICAgY29sbGVjdGlvblJlbW92ZShuZXdMYW5lLmdldChGTE9XX05PREVfUkVGU19BVFRSKSwgZmxvd05vZGUpO1xuICAgIH0pO1xuXG4gICAgLy8gd2lyZSBvbGRcbiAgICB1cGRhdGUucmVtb3ZlLmZvckVhY2goZnVuY3Rpb24ob2xkTGFuZSkge1xuICAgICAgY29sbGVjdGlvbkFkZChsYW5lcywgb2xkTGFuZSk7XG4gICAgICBjb2xsZWN0aW9uQWRkKG9sZExhbmUuZ2V0KEZMT1dfTk9ERV9SRUZTX0FUVFIpLCBmbG93Tm9kZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIFRPRE8obmlra3UpOiByZXR1cm4gY2hhbmdlZCBlbGVtZW50c1xuICAvLyByZXR1cm4gWyAuLi4gXTtcbn07XG4iLCJpbXBvcnQge1xuICByZWR1Y2UsXG4gIGtleXMsXG4gIGZvckVhY2gsXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0XG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxudmFyIERFRkFVTFRfRkxPVyA9ICdkZWZhdWx0JyxcbiAgICBJRCA9ICdpZCcsXG4gICAgREkgPSAnZGknO1xuXG52YXIgTlVMTF9ESU1FTlNJT05TID0ge1xuICB3aWR0aDogMCxcbiAgaGVpZ2h0OiAwXG59O1xuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgYSBCUE1OIDIuMCBwcm9wZXJ0eSB1cGRhdGUuXG4gKlxuICogVGhpcyBzaG91bGQgYmUgdXNlZCB0byBzZXQgc2ltcGxlIHByb3BlcnRpZXMgb24gZWxlbWVudHMgd2l0aFxuICogYW4gdW5kZXJseWluZyBCUE1OIGJ1c2luZXNzIG9iamVjdC5cbiAqXG4gKiBVc2UgcmVzcGVjdGl2ZSBkaWFncmFtLWpzIHByb3ZpZGVkIGhhbmRsZXJzIGlmIHlvdSB3b3VsZFxuICogbGlrZSB0byBwZXJmb3JtIGF1dG9tYXRlZCBtb2RlbGluZy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVXBkYXRlUHJvcGVydGllc0hhbmRsZXIoXG4gICAgZWxlbWVudFJlZ2lzdHJ5LCBtb2RkbGUsIHRyYW5zbGF0ZSxcbiAgICBtb2RlbGluZywgdGV4dFJlbmRlcmVyKSB7XG5cbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9tb2RkbGUgPSBtb2RkbGU7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fdGV4dFJlbmRlcmVyID0gdGV4dFJlbmRlcmVyO1xufVxuXG5VcGRhdGVQcm9wZXJ0aWVzSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ21vZGRsZScsXG4gICd0cmFuc2xhdGUnLFxuICAnbW9kZWxpbmcnLFxuICAndGV4dFJlbmRlcmVyJ1xuXTtcblxuXG4vLyBhcGkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIFVwZGF0ZXMgYSBCUE1OIGVsZW1lbnQgd2l0aCBhIGxpc3Qgb2YgbmV3IHByb3BlcnRpZXNcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gY29udGV4dC5lbGVtZW50IHRoZSBlbGVtZW50IHRvIHVwZGF0ZVxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQucHJvcGVydGllcyBhIGxpc3Qgb2YgcHJvcGVydGllcyB0byBzZXQgb24gdGhlIGVsZW1lbnQnc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXNpbmVzc09iamVjdCAodGhlIEJQTU4gbW9kZWwgZWxlbWVudClcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuQmFzZT59IHRoZSB1cGRhdGVkIGVsZW1lbnRcbiAqL1xuVXBkYXRlUHJvcGVydGllc0hhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGVsZW1lbnQgPSBjb250ZXh0LmVsZW1lbnQsXG4gICAgICBjaGFuZ2VkID0gWyBlbGVtZW50IF0sXG4gICAgICB0cmFuc2xhdGUgPSB0aGlzLl90cmFuc2xhdGU7XG5cbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnZWxlbWVudCByZXF1aXJlZCcpKTtcbiAgfVxuXG4gIHZhciBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnksXG4gICAgICBpZHMgPSB0aGlzLl9tb2RkbGUuaWRzO1xuXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGVsZW1lbnQuYnVzaW5lc3NPYmplY3QsXG4gICAgICBwcm9wZXJ0aWVzID0gdW53cmFwQnVzaW5lc3NPYmplY3RzKGNvbnRleHQucHJvcGVydGllcyksXG4gICAgICBvbGRQcm9wZXJ0aWVzID0gY29udGV4dC5vbGRQcm9wZXJ0aWVzIHx8IGdldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIHByb3BlcnRpZXMpO1xuXG4gIGlmIChpc0lkQ2hhbmdlKHByb3BlcnRpZXMsIGJ1c2luZXNzT2JqZWN0KSkge1xuICAgIGlkcy51bmNsYWltKGJ1c2luZXNzT2JqZWN0W0lEXSk7XG5cbiAgICBlbGVtZW50UmVnaXN0cnkudXBkYXRlSWQoZWxlbWVudCwgcHJvcGVydGllc1tJRF0pO1xuXG4gICAgaWRzLmNsYWltKHByb3BlcnRpZXNbSURdLCBidXNpbmVzc09iamVjdCk7XG4gIH1cblxuICAvLyBjb3JyZWN0bHkgaW5kaWNhdGUgdmlzdWFsIGNoYW5nZXMgb24gZGVmYXVsdCBmbG93IHVwZGF0ZXNcbiAgaWYgKERFRkFVTFRfRkxPVyBpbiBwcm9wZXJ0aWVzKSB7XG5cbiAgICBpZiAocHJvcGVydGllc1tERUZBVUxUX0ZMT1ddKSB7XG4gICAgICBjaGFuZ2VkLnB1c2goZWxlbWVudFJlZ2lzdHJ5LmdldChwcm9wZXJ0aWVzW0RFRkFVTFRfRkxPV10uaWQpKTtcbiAgICB9XG5cbiAgICBpZiAoYnVzaW5lc3NPYmplY3RbREVGQVVMVF9GTE9XXSkge1xuICAgICAgY2hhbmdlZC5wdXNoKGVsZW1lbnRSZWdpc3RyeS5nZXQoYnVzaW5lc3NPYmplY3RbREVGQVVMVF9GTE9XXS5pZCkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHVwZGF0ZSBwcm9wZXJ0aWVzXG4gIHNldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIHByb3BlcnRpZXMpO1xuXG4gIC8vIHN0b3JlIG9sZCB2YWx1ZXNcbiAgY29udGV4dC5vbGRQcm9wZXJ0aWVzID0gb2xkUHJvcGVydGllcztcbiAgY29udGV4dC5jaGFuZ2VkID0gY2hhbmdlZDtcblxuICAvLyBpbmRpY2F0ZSBjaGFuZ2VkIG9uIG9iamVjdHMgYWZmZWN0ZWQgYnkgdGhlIHVwZGF0ZVxuICByZXR1cm4gY2hhbmdlZDtcbn07XG5cblxuVXBkYXRlUHJvcGVydGllc0hhbmRsZXIucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcbiAgICAgIGxhYmVsID0gZWxlbWVudC5sYWJlbDtcblxuICB2YXIgdGV4dCA9IGxhYmVsICYmIGdldEJ1c2luZXNzT2JqZWN0KGxhYmVsKS5uYW1lO1xuXG4gIGlmICghdGV4dCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGdldCBsYXlvdXRlZCB0ZXh0IGJvdW5kcyBhbmQgcmVzaXplIGV4dGVybmFsXG4gIC8vIGV4dGVybmFsIGxhYmVsIGFjY29yZGluZ2x5XG4gIHZhciBuZXdMYWJlbEJvdW5kcyA9IHRoaXMuX3RleHRSZW5kZXJlci5nZXRFeHRlcm5hbExhYmVsQm91bmRzKGxhYmVsLCB0ZXh0KTtcblxuICB0aGlzLl9tb2RlbGluZy5yZXNpemVTaGFwZShsYWJlbCwgbmV3TGFiZWxCb3VuZHMsIE5VTExfRElNRU5TSU9OUyk7XG59O1xuXG4vKipcbiAqIFJldmVydHMgdGhlIHVwZGF0ZSBvbiBhIEJQTU4gZWxlbWVudHMgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGNvbnRleHRcbiAqXG4gKiBAcmV0dXJuIHtkanMubW9kZWwuQmFzZX0gdGhlIHVwZGF0ZWQgZWxlbWVudFxuICovXG5VcGRhdGVQcm9wZXJ0aWVzSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgcHJvcGVydGllcyA9IGNvbnRleHQucHJvcGVydGllcyxcbiAgICAgIG9sZFByb3BlcnRpZXMgPSBjb250ZXh0Lm9sZFByb3BlcnRpZXMsXG4gICAgICBidXNpbmVzc09iamVjdCA9IGVsZW1lbnQuYnVzaW5lc3NPYmplY3QsXG4gICAgICBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnksXG4gICAgICBpZHMgPSB0aGlzLl9tb2RkbGUuaWRzO1xuXG4gIC8vIHVwZGF0ZSBwcm9wZXJ0aWVzXG4gIHNldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIG9sZFByb3BlcnRpZXMpO1xuXG4gIGlmIChpc0lkQ2hhbmdlKHByb3BlcnRpZXMsIGJ1c2luZXNzT2JqZWN0KSkge1xuICAgIGlkcy51bmNsYWltKHByb3BlcnRpZXNbSURdKTtcblxuICAgIGVsZW1lbnRSZWdpc3RyeS51cGRhdGVJZChlbGVtZW50LCBvbGRQcm9wZXJ0aWVzW0lEXSk7XG5cbiAgICBpZHMuY2xhaW0ob2xkUHJvcGVydGllc1tJRF0sIGJ1c2luZXNzT2JqZWN0KTtcbiAgfVxuXG4gIHJldHVybiBjb250ZXh0LmNoYW5nZWQ7XG59O1xuXG5cbmZ1bmN0aW9uIGlzSWRDaGFuZ2UocHJvcGVydGllcywgYnVzaW5lc3NPYmplY3QpIHtcbiAgcmV0dXJuIElEIGluIHByb3BlcnRpZXMgJiYgcHJvcGVydGllc1tJRF0gIT09IGJ1c2luZXNzT2JqZWN0W0lEXTtcbn1cblxuXG5mdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBwcm9wZXJ0aWVzKSB7XG4gIHZhciBwcm9wZXJ0eU5hbWVzID0ga2V5cyhwcm9wZXJ0aWVzKTtcblxuICByZXR1cm4gcmVkdWNlKHByb3BlcnR5TmFtZXMsIGZ1bmN0aW9uKHJlc3VsdCwga2V5KSB7XG5cbiAgICAvLyBoYW5kbGUgREkgc2VwYXJhdGVseVxuICAgIGlmIChrZXkgIT09IERJKSB7XG4gICAgICByZXN1bHRba2V5XSA9IGJ1c2luZXNzT2JqZWN0LmdldChrZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHRba2V5XSA9IGdldERpUHJvcGVydGllcyhidXNpbmVzc09iamVjdC5kaSwga2V5cyhwcm9wZXJ0aWVzLmRpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSwge30pO1xufVxuXG5cbmZ1bmN0aW9uIGdldERpUHJvcGVydGllcyhkaSwgcHJvcGVydHlOYW1lcykge1xuICByZXR1cm4gcmVkdWNlKHByb3BlcnR5TmFtZXMsIGZ1bmN0aW9uKHJlc3VsdCwga2V5KSB7XG4gICAgcmVzdWx0W2tleV0gPSBkaS5nZXQoa2V5KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sIHt9KTtcbn1cblxuXG5mdW5jdGlvbiBzZXRQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBwcm9wZXJ0aWVzKSB7XG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuXG4gICAgaWYgKGtleSAhPT0gREkpIHtcbiAgICAgIGJ1c2luZXNzT2JqZWN0LnNldChrZXksIHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBvbmx5IHVwZGF0ZSwgaWYgYnVzaW5lc3NPYmplY3QuZGkgZXhpc3RzXG4gICAgICBpZiAoYnVzaW5lc3NPYmplY3QuZGkpIHtcbiAgICAgICAgc2V0RGlQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LmRpLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBzZXREaVByb3BlcnRpZXMoZGksIHByb3BlcnRpZXMpIHtcbiAgZm9yRWFjaChwcm9wZXJ0aWVzLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgZGkuc2V0KGtleSwgdmFsdWUpO1xuICB9KTtcbn1cblxuXG52YXIgcmVmZXJlbmNlUHJvcGVydHlOYW1lcyA9IFsgJ2RlZmF1bHQnIF07XG5cbi8qKlxuICogTWFrZSBzdXJlIHdlIHVud3JhcCB0aGUgYWN0dWFsIGJ1c2luZXNzIG9iamVjdFxuICogYmVoaW5kIGRpYWdyYW0gZWxlbWVudCB0aGF0IG1heSBoYXZlIGJlZW5cbiAqIHBhc3NlZCBhcyBhcmd1bWVudHMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBwcm9wZXJ0aWVzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB1bndyYXBwZWRQcm9wc1xuICovXG5mdW5jdGlvbiB1bndyYXBCdXNpbmVzc09iamVjdHMocHJvcGVydGllcykge1xuXG4gIHZhciB1bndyYXBwZWRQcm9wcyA9IGFzc2lnbih7fSwgcHJvcGVydGllcyk7XG5cbiAgcmVmZXJlbmNlUHJvcGVydHlOYW1lcy5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBpZiAobmFtZSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICB1bndyYXBwZWRQcm9wc1tuYW1lXSA9IGdldEJ1c2luZXNzT2JqZWN0KHVud3JhcHBlZFByb3BzW25hbWVdKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB1bndyYXBwZWRQcm9wcztcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBVcGRhdGVTZW1hbnRpY1BhcmVudEhhbmRsZXIoYnBtblVwZGF0ZXIpIHtcclxuICB0aGlzLl9icG1uVXBkYXRlciA9IGJwbW5VcGRhdGVyO1xyXG59XHJcblxyXG5VcGRhdGVTZW1hbnRpY1BhcmVudEhhbmRsZXIuJGluamVjdCA9IFsgJ2JwbW5VcGRhdGVyJyBdO1xyXG5cclxuXHJcblVwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICB2YXIgZGF0YVN0b3JlQm8gPSBjb250ZXh0LmRhdGFTdG9yZUJvLFxyXG4gICAgICBuZXdTZW1hbnRpY1BhcmVudCA9IGNvbnRleHQubmV3U2VtYW50aWNQYXJlbnQsXHJcbiAgICAgIG5ld0RpUGFyZW50ID0gY29udGV4dC5uZXdEaVBhcmVudDtcclxuXHJcbiAgY29udGV4dC5vbGRTZW1hbnRpY1BhcmVudCA9IGRhdGFTdG9yZUJvLiRwYXJlbnQ7XHJcbiAgY29udGV4dC5vbGREaVBhcmVudCA9IGRhdGFTdG9yZUJvLmRpLiRwYXJlbnQ7XHJcblxyXG4gIC8vIHVwZGF0ZSBzZW1hbnRpYyBwYXJlbnRcclxuICB0aGlzLl9icG1uVXBkYXRlci51cGRhdGVTZW1hbnRpY1BhcmVudChkYXRhU3RvcmVCbywgbmV3U2VtYW50aWNQYXJlbnQpO1xyXG5cclxuICAvLyB1cGRhdGUgREkgcGFyZW50XHJcbiAgdGhpcy5fYnBtblVwZGF0ZXIudXBkYXRlRGlQYXJlbnQoZGF0YVN0b3JlQm8uZGksIG5ld0RpUGFyZW50KTtcclxufTtcclxuXHJcblVwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xyXG4gIHZhciBkYXRhU3RvcmVCbyA9IGNvbnRleHQuZGF0YVN0b3JlQm8sXHJcbiAgICAgIG9sZFNlbWFudGljUGFyZW50ID0gY29udGV4dC5vbGRTZW1hbnRpY1BhcmVudCxcclxuICAgICAgb2xkRGlQYXJlbnQgPSBjb250ZXh0Lm9sZERpUGFyZW50O1xyXG5cclxuICAvLyB1cGRhdGUgc2VtYW50aWMgcGFyZW50XHJcbiAgdGhpcy5fYnBtblVwZGF0ZXIudXBkYXRlU2VtYW50aWNQYXJlbnQoZGF0YVN0b3JlQm8sIG9sZFNlbWFudGljUGFyZW50KTtcclxuXHJcbiAgLy8gdXBkYXRlIERJIHBhcmVudFxyXG4gIHRoaXMuX2JwbW5VcGRhdGVyLnVwZGF0ZURpUGFyZW50KGRhdGFTdG9yZUJvLmRpLCBvbGREaVBhcmVudCk7XHJcbn07XHJcblxyXG4iLCJpbXBvcnQgQmVoYXZpb3JNb2R1bGUgZnJvbSAnLi9iZWhhdmlvcic7XG5pbXBvcnQgUnVsZXNNb2R1bGUgZnJvbSAnLi4vcnVsZXMnO1xuaW1wb3J0IERpT3JkZXJpbmdNb2R1bGUgZnJvbSAnLi4vZGktb3JkZXJpbmcnO1xuaW1wb3J0IE9yZGVyaW5nTW9kdWxlIGZyb20gJy4uL29yZGVyaW5nJztcbmltcG9ydCBSZXBsYWNlTW9kdWxlIGZyb20gJy4uL3JlcGxhY2UnO1xuXG5pbXBvcnQgQ29tbWFuZE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kJztcbmltcG9ydCBUb29sdGlwc01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy90b29sdGlwcyc7XG5pbXBvcnQgTGFiZWxTdXBwb3J0TW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2xhYmVsLXN1cHBvcnQnO1xuaW1wb3J0IEF0dGFjaFN1cHBvcnRNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXR0YWNoLXN1cHBvcnQnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zZWxlY3Rpb24nO1xuaW1wb3J0IENoYW5nZVN1cHBvcnRNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY2hhbmdlLXN1cHBvcnQnO1xuaW1wb3J0IFNwYWNlVG9vbE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zcGFjZS10b29sJztcblxuaW1wb3J0IEJwbW5GYWN0b3J5IGZyb20gJy4vQnBtbkZhY3RvcnknO1xuaW1wb3J0IEJwbW5VcGRhdGVyIGZyb20gJy4vQnBtblVwZGF0ZXInO1xuaW1wb3J0IEVsZW1lbnRGYWN0b3J5IGZyb20gJy4vRWxlbWVudEZhY3RvcnknO1xuaW1wb3J0IE1vZGVsaW5nIGZyb20gJy4vTW9kZWxpbmcnO1xuaW1wb3J0IEJwbW5MYXlvdXRlciBmcm9tICcuL0JwbW5MYXlvdXRlcic7XG5pbXBvcnQgQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZyBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZyc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogW1xuICAgICdtb2RlbGluZycsXG4gICAgJ2JwbW5VcGRhdGVyJ1xuICBdLFxuICBfX2RlcGVuZHNfXzogW1xuICAgIEJlaGF2aW9yTW9kdWxlLFxuICAgIFJ1bGVzTW9kdWxlLFxuICAgIERpT3JkZXJpbmdNb2R1bGUsXG4gICAgT3JkZXJpbmdNb2R1bGUsXG4gICAgUmVwbGFjZU1vZHVsZSxcbiAgICBDb21tYW5kTW9kdWxlLFxuICAgIFRvb2x0aXBzTW9kdWxlLFxuICAgIExhYmVsU3VwcG9ydE1vZHVsZSxcbiAgICBBdHRhY2hTdXBwb3J0TW9kdWxlLFxuICAgIFNlbGVjdGlvbk1vZHVsZSxcbiAgICBDaGFuZ2VTdXBwb3J0TW9kdWxlLFxuICAgIFNwYWNlVG9vbE1vZHVsZVxuICBdLFxuICBicG1uRmFjdG9yeTogWyAndHlwZScsIEJwbW5GYWN0b3J5IF0sXG4gIGJwbW5VcGRhdGVyOiBbICd0eXBlJywgQnBtblVwZGF0ZXIgXSxcbiAgZWxlbWVudEZhY3Rvcnk6IFsgJ3R5cGUnLCBFbGVtZW50RmFjdG9yeSBdLFxuICBtb2RlbGluZzogWyAndHlwZScsIE1vZGVsaW5nIF0sXG4gIGxheW91dGVyOiBbICd0eXBlJywgQnBtbkxheW91dGVyIF0sXG4gIGNvbm5lY3Rpb25Eb2NraW5nOiBbICd0eXBlJywgQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZyBdXG59OyIsImltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRQYXJlbnRcbn0gZnJvbSAnLi9Nb2RlbGluZ1V0aWwnO1xuXG5pbXBvcnQge1xuICBhc1RSQkxcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBzdWJzdHJhY3RUUkJMLFxuICByZXNpemVUUkJMXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Jlc2l6ZS9SZXNpemVVdGlsJztcblxudmFyIGFicyA9IE1hdGguYWJzO1xuXG5cbmZ1bmN0aW9uIGdldFRSQkxSZXNpemUob2xkQm91bmRzLCBuZXdCb3VuZHMpIHtcbiAgcmV0dXJuIHN1YnN0cmFjdFRSQkwoYXNUUkJMKG5ld0JvdW5kcyksIGFzVFJCTChvbGRCb3VuZHMpKTtcbn1cblxuXG52YXIgTEFORV9QQVJFTlRTID0gW1xuICAnYnBtbjpQYXJ0aWNpcGFudCcsXG4gICdicG1uOlByb2Nlc3MnLFxuICAnYnBtbjpTdWJQcm9jZXNzJ1xuXTtcblxuZXhwb3J0IHZhciBMQU5FX0lOREVOVEFUSU9OID0gMzA7XG5cblxuLyoqXG4gKiBDb2xsZWN0IGFsbCBsYW5lIHNoYXBlcyBpbiB0aGUgZ2l2ZW4gcGFyZW5cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuU2hhcGV9IHNoYXBlXG4gKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuQmFzZT59IFtjb2xsZWN0ZWRTaGFwZXNdXG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29sbGVjdExhbmVzKHNoYXBlLCBjb2xsZWN0ZWRTaGFwZXMpIHtcblxuICBjb2xsZWN0ZWRTaGFwZXMgPSBjb2xsZWN0ZWRTaGFwZXMgfHwgW107XG5cbiAgc2hhcGUuY2hpbGRyZW4uZmlsdGVyKGZ1bmN0aW9uKHMpIHtcbiAgICBpZiAoaXMocywgJ2JwbW46TGFuZScpKSB7XG4gICAgICBjb2xsZWN0TGFuZXMocywgY29sbGVjdGVkU2hhcGVzKTtcblxuICAgICAgY29sbGVjdGVkU2hhcGVzLnB1c2gocyk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gY29sbGVjdGVkU2hhcGVzO1xufVxuXG5cbi8qKlxuICogUmV0dXJuIHRoZSBsYW5lIGNoaWxkcmVuIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICpcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGlsZExhbmVzKHNoYXBlKSB7XG4gIHJldHVybiBzaGFwZS5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24oYykge1xuICAgIHJldHVybiBpcyhjLCAnYnBtbjpMYW5lJyk7XG4gIH0pO1xufVxuXG5cbi8qKlxuICogUmV0dXJuIHRoZSByb290IGVsZW1lbnQgY29udGFpbmluZyB0aGUgZ2l2ZW4gbGFuZSBzaGFwZVxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5TaGFwZX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExhbmVzUm9vdChzaGFwZSkge1xuICByZXR1cm4gZ2V0UGFyZW50KHNoYXBlLCBMQU5FX1BBUkVOVFMpIHx8IHNoYXBlO1xufVxuXG5cbi8qKlxuICogQ29tcHV0ZSB0aGUgcmVxdWlyZWQgcmVzaXplIG9wZXJhdGlvbnMgZm9yIGxhbmVzXG4gKiBhZGphY2VudCB0byB0aGUgZ2l2ZW4gc2hhcGUsIGFzc3VtaW5nIGl0IHdpbGwgYmVcbiAqIHJlc2l6ZWQgdG8gdGhlIGdpdmVuIG5ldyBib3VuZHMuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHNoYXBlXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXG4gKlxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVMYW5lc1Jlc2l6ZShzaGFwZSwgbmV3Qm91bmRzKSB7XG5cbiAgdmFyIHJvb3RFbGVtZW50ID0gZ2V0TGFuZXNSb290KHNoYXBlKTtcblxuICB2YXIgaW5pdGlhbFNoYXBlcyA9IGlzKHJvb3RFbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgPyBbXSA6IFsgcm9vdEVsZW1lbnQgXTtcblxuICB2YXIgYWxsTGFuZXMgPSBjb2xsZWN0TGFuZXMocm9vdEVsZW1lbnQsIGluaXRpYWxTaGFwZXMpLFxuICAgICAgc2hhcGVUcmJsID0gYXNUUkJMKHNoYXBlKSxcbiAgICAgIHNoYXBlTmV3VHJibCA9IGFzVFJCTChuZXdCb3VuZHMpLFxuICAgICAgdHJibFJlc2l6ZSA9IGdldFRSQkxSZXNpemUoc2hhcGUsIG5ld0JvdW5kcyksXG4gICAgICByZXNpemVOZWVkZWQgPSBbXTtcblxuICBhbGxMYW5lcy5mb3JFYWNoKGZ1bmN0aW9uKG90aGVyKSB7XG5cbiAgICBpZiAob3RoZXIgPT09IHNoYXBlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRvcFJlc2l6ZSA9IDAsXG4gICAgICAgIHJpZ2h0UmVzaXplID0gdHJibFJlc2l6ZS5yaWdodCxcbiAgICAgICAgYm90dG9tUmVzaXplID0gMCxcbiAgICAgICAgbGVmdFJlc2l6ZSA9IHRyYmxSZXNpemUubGVmdDtcblxuICAgIHZhciBvdGhlclRyYmwgPSBhc1RSQkwob3RoZXIpO1xuXG4gICAgaWYgKHRyYmxSZXNpemUudG9wKSB7XG4gICAgICBpZiAoYWJzKG90aGVyVHJibC5ib3R0b20gLSBzaGFwZVRyYmwudG9wKSA8IDEwKSB7XG4gICAgICAgIGJvdHRvbVJlc2l6ZSA9IHNoYXBlTmV3VHJibC50b3AgLSBvdGhlclRyYmwuYm90dG9tO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWJzKG90aGVyVHJibC50b3AgLSBzaGFwZVRyYmwudG9wKSA8IDUpIHtcbiAgICAgICAgdG9wUmVzaXplID0gc2hhcGVOZXdUcmJsLnRvcCAtIG90aGVyVHJibC50b3A7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRyYmxSZXNpemUuYm90dG9tKSB7XG4gICAgICBpZiAoYWJzKG90aGVyVHJibC50b3AgLSBzaGFwZVRyYmwuYm90dG9tKSA8IDEwKSB7XG4gICAgICAgIHRvcFJlc2l6ZSA9IHNoYXBlTmV3VHJibC5ib3R0b20gLSBvdGhlclRyYmwudG9wO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWJzKG90aGVyVHJibC5ib3R0b20gLSBzaGFwZVRyYmwuYm90dG9tKSA8IDUpIHtcbiAgICAgICAgYm90dG9tUmVzaXplID0gc2hhcGVOZXdUcmJsLmJvdHRvbSAtIG90aGVyVHJibC5ib3R0b207XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRvcFJlc2l6ZSB8fCByaWdodFJlc2l6ZSB8fCBib3R0b21SZXNpemUgfHwgbGVmdFJlc2l6ZSkge1xuXG4gICAgICByZXNpemVOZWVkZWQucHVzaCh7XG4gICAgICAgIHNoYXBlOiBvdGhlcixcbiAgICAgICAgbmV3Qm91bmRzOiByZXNpemVUUkJMKG90aGVyLCB7XG4gICAgICAgICAgdG9wOiB0b3BSZXNpemUsXG4gICAgICAgICAgcmlnaHQ6IHJpZ2h0UmVzaXplLFxuICAgICAgICAgIGJvdHRvbTogYm90dG9tUmVzaXplLFxuICAgICAgICAgIGxlZnQ6IGxlZnRSZXNpemVcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgIH1cblxuICB9KTtcblxuICByZXR1cm4gcmVzaXplTmVlZGVkO1xufSIsImltcG9ydCB7XG4gIHNvbWVcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuXG4vKipcbiAqIFJldHVybiB0cnVlIGlmIGVsZW1lbnQgaGFzIGFueSBvZiB0aGUgZ2l2ZW4gdHlwZXMuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSB0eXBlc1xuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0FueShlbGVtZW50LCB0eXBlcykge1xuICByZXR1cm4gc29tZSh0eXBlcywgZnVuY3Rpb24odCkge1xuICAgIHJldHVybiBpcyhlbGVtZW50LCB0KTtcbiAgfSk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm4gdGhlIHBhcmVudCBvZiB0aGUgZWxlbWVudCB3aXRoIGFueSBvZiB0aGUgZ2l2ZW4gdHlwZXMuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gYW55VHlwZVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5CYXNlfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFyZW50KGVsZW1lbnQsIGFueVR5cGUpIHtcblxuICBpZiAodHlwZW9mIGFueVR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgYW55VHlwZSA9IFsgYW55VHlwZSBdO1xuICB9XG5cbiAgd2hpbGUgKChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnQpKSB7XG4gICAgaWYgKGlzQW55KGVsZW1lbnQsIGFueVR5cGUpKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgT3JkZXJpbmdQcm92aWRlciBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9vcmRlcmluZy9PcmRlcmluZ1Byb3ZpZGVyJztcblxuaW1wb3J0IHtcbiAgaXNBbnlcbn0gZnJvbSAnLi4vbW9kZWxpbmcvdXRpbC9Nb2RlbGluZ1V0aWwnO1xuXG5pbXBvcnQge1xuICBmaW5kSW5kZXgsXG4gIGZpbmRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5cbi8qKlxuICogYSBzaW1wbGUgb3JkZXJpbmcgcHJvdmlkZXIgdGhhdCBtYWtlcyBzdXJlOlxuICpcbiAqICgwKSBsYWJlbHMgYW5kIGdyb3VwcyBhcmUgcmVuZGVyZWQgYWx3YXlzIG9uIHRvcFxuICogKDEpIGVsZW1lbnRzIGFyZSBvcmRlcmVkIGJ5IGEge2xldmVsfSBwcm9wZXJ0eVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uT3JkZXJpbmdQcm92aWRlcihldmVudEJ1cywgY2FudmFzLCB0cmFuc2xhdGUpIHtcblxuICBPcmRlcmluZ1Byb3ZpZGVyLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHZhciBvcmRlcnMgPSBbXG4gICAgeyB0eXBlOiAnYnBtbjpTdWJQcm9jZXNzJywgb3JkZXI6IHsgbGV2ZWw6IDYgfSB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdicG1uOlNlcXVlbmNlRmxvdycsXG4gICAgICBvcmRlcjoge1xuICAgICAgICBsZXZlbDogMyxcbiAgICAgICAgY29udGFpbmVyczogW1xuICAgICAgICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAgICAgICAnYnBtbjpGbG93RWxlbWVudHNDb250YWluZXInXG4gICAgICAgIF1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLy8gaGFuZGxlIERhdGFBc3NvY2lhdGlvbihzKSBsaWtlIG1lc3NhZ2UgZmxvd3MgYW5kIHJlbmRlciB0aGVtIGFsd2F5cyBvbiB0b3BcbiAgICB7XG4gICAgICB0eXBlOiAnYnBtbjpEYXRhQXNzb2NpYXRpb24nLFxuICAgICAgb3JkZXI6IHtcbiAgICAgICAgbGV2ZWw6IDksXG4gICAgICAgIGNvbnRhaW5lcnM6IFtcbiAgICAgICAgICAnYnBtbjpDb2xsYWJvcmF0aW9uJyxcbiAgICAgICAgICAnYnBtbjpQcm9jZXNzJ1xuICAgICAgICBdXG4gICAgICB9XG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnYnBtbjpNZXNzYWdlRmxvdycsIG9yZGVyOiB7XG4gICAgICAgIGxldmVsOiA5LFxuICAgICAgICBjb250YWluZXJzOiBbICdicG1uOkNvbGxhYm9yYXRpb24nIF1cbiAgICAgIH1cbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdicG1uOkFzc29jaWF0aW9uJyxcbiAgICAgIG9yZGVyOiB7XG4gICAgICAgIGxldmVsOiA2LFxuICAgICAgICBjb250YWluZXJzOiBbXG4gICAgICAgICAgJ2JwbW46UGFydGljaXBhbnQnLFxuICAgICAgICAgICdicG1uOkZsb3dFbGVtZW50c0NvbnRhaW5lcicsXG4gICAgICAgICAgJ2JwbW46Q29sbGFib3JhdGlvbidcbiAgICAgICAgXVxuICAgICAgfVxuICAgIH0sXG4gICAgeyB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50Jywgb3JkZXI6IHsgbGV2ZWw6IDggfSB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdicG1uOkdyb3VwJyxcbiAgICAgIG9yZGVyOiB7XG4gICAgICAgIGxldmVsOiAxMCxcbiAgICAgICAgY29udGFpbmVyczogW1xuICAgICAgICAgICdicG1uOkNvbGxhYm9yYXRpb24nLFxuICAgICAgICAgICdicG1uOlByb2Nlc3MnXG4gICAgICAgIF1cbiAgICAgIH1cbiAgICB9LFxuICAgIHsgdHlwZTogJ2JwbW46Rmxvd0VsZW1lbnQnLCBvcmRlcjogeyBsZXZlbDogNSB9IH0sXG4gICAgeyB0eXBlOiAnYnBtbjpQYXJ0aWNpcGFudCcsIG9yZGVyOiB7IGxldmVsOiAtMiB9IH0sXG4gICAgeyB0eXBlOiAnYnBtbjpMYW5lJywgb3JkZXI6IHsgbGV2ZWw6IC0xIH0gfVxuICBdO1xuXG4gIGZ1bmN0aW9uIGNvbXB1dGVPcmRlcihlbGVtZW50KSB7XG4gICAgaWYgKGVsZW1lbnQubGFiZWxUYXJnZXQpIHtcbiAgICAgIHJldHVybiB7IGxldmVsOiAxMCB9O1xuICAgIH1cblxuICAgIHZhciBlbnRyeSA9IGZpbmQob3JkZXJzLCBmdW5jdGlvbihvKSB7XG4gICAgICByZXR1cm4gaXNBbnkoZWxlbWVudCwgWyBvLnR5cGUgXSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZW50cnkgJiYgZW50cnkub3JkZXIgfHwgeyBsZXZlbDogMSB9O1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0T3JkZXIoZWxlbWVudCkge1xuXG4gICAgdmFyIG9yZGVyID0gZWxlbWVudC5vcmRlcjtcblxuICAgIGlmICghb3JkZXIpIHtcbiAgICAgIGVsZW1lbnQub3JkZXIgPSBvcmRlciA9IGNvbXB1dGVPcmRlcihlbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3JkZXI7XG4gIH1cblxuICBmdW5jdGlvbiBmaW5kQWN0dWFsUGFyZW50KGVsZW1lbnQsIG5ld1BhcmVudCwgY29udGFpbmVycykge1xuXG4gICAgdmFyIGFjdHVhbFBhcmVudCA9IG5ld1BhcmVudDtcblxuICAgIHdoaWxlIChhY3R1YWxQYXJlbnQpIHtcblxuICAgICAgaWYgKGlzQW55KGFjdHVhbFBhcmVudCwgY29udGFpbmVycykpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGFjdHVhbFBhcmVudCA9IGFjdHVhbFBhcmVudC5wYXJlbnQ7XG4gICAgfVxuXG4gICAgaWYgKCFhY3R1YWxQYXJlbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0cmFuc2xhdGUoJ25vIHBhcmVudCBmb3Ige2VsZW1lbnR9IGluIHtwYXJlbnR9Jywge1xuICAgICAgICBlbGVtZW50OiBlbGVtZW50LmlkLFxuICAgICAgICBwYXJlbnQ6IG5ld1BhcmVudC5pZFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIHJldHVybiBhY3R1YWxQYXJlbnQ7XG4gIH1cblxuICB0aGlzLmdldE9yZGVyaW5nID0gZnVuY3Rpb24oZWxlbWVudCwgbmV3UGFyZW50KSB7XG5cbiAgICAvLyByZW5kZXIgbGFiZWxzIGFsd2F5cyBvbiB0b3BcbiAgICBpZiAoZWxlbWVudC5sYWJlbFRhcmdldCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGFyZW50OiBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgICAgaW5kZXg6IC0xXG4gICAgICB9O1xuICAgIH1cblxuICAgIHZhciBlbGVtZW50T3JkZXIgPSBnZXRPcmRlcihlbGVtZW50KTtcblxuXG4gICAgaWYgKGVsZW1lbnRPcmRlci5jb250YWluZXJzKSB7XG4gICAgICBuZXdQYXJlbnQgPSBmaW5kQWN0dWFsUGFyZW50KGVsZW1lbnQsIG5ld1BhcmVudCwgZWxlbWVudE9yZGVyLmNvbnRhaW5lcnMpO1xuICAgIH1cblxuXG4gICAgdmFyIGN1cnJlbnRJbmRleCA9IG5ld1BhcmVudC5jaGlsZHJlbi5pbmRleE9mKGVsZW1lbnQpO1xuXG4gICAgdmFyIGluc2VydEluZGV4ID0gZmluZEluZGV4KG5ld1BhcmVudC5jaGlsZHJlbiwgZnVuY3Rpb24oY2hpbGQpIHtcblxuICAgICAgLy8gZG8gbm90IGNvbXBhcmUgd2l0aCBsYWJlbHMsIHRoZXkgYXJlIGNyZWF0ZWRcbiAgICAgIC8vIGluIHRoZSB3cm9uZyBvcmRlciAocmlnaHQgYWZ0ZXIgZWxlbWVudHMpIGR1cmluZyBpbXBvcnQgYW5kXG4gICAgICAvLyBtZXNzIHVwIHRoZSBwb3NpdGlvbmluZy5cbiAgICAgIGlmICghZWxlbWVudC5sYWJlbFRhcmdldCAmJiBjaGlsZC5sYWJlbFRhcmdldCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlbGVtZW50T3JkZXIubGV2ZWwgPCBnZXRPcmRlcihjaGlsZCkubGV2ZWw7XG4gICAgfSk7XG5cblxuICAgIC8vIGlmIHRoZSBlbGVtZW50IGlzIGFscmVhZHkgaW4gdGhlIGNoaWxkIGxpc3QgYXRcbiAgICAvLyBhIHNtYWxsZXIgaW5kZXgsIHdlIG5lZWQgdG8gYWRqdXN0IHRoZSBpbnNlcnQgaW5kZXguXG4gICAgLy8gdGhpcyB0YWtlcyBpbnRvIGFjY291bnQgdGhhdCB0aGUgZWxlbWVudCBpcyBiZWluZyByZW1vdmVkXG4gICAgLy8gYmVmb3JlIGJlaW5nIHJlLWluc2VydGVkXG4gICAgaWYgKGluc2VydEluZGV4ICE9PSAtMSkge1xuICAgICAgaWYgKGN1cnJlbnRJbmRleCAhPT0gLTEgJiYgY3VycmVudEluZGV4IDwgaW5zZXJ0SW5kZXgpIHtcbiAgICAgICAgaW5zZXJ0SW5kZXggLT0gMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5kZXg6IGluc2VydEluZGV4LFxuICAgICAgcGFyZW50OiBuZXdQYXJlbnRcbiAgICB9O1xuICB9O1xufVxuXG5CcG1uT3JkZXJpbmdQcm92aWRlci4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnLCAnY2FudmFzJywgJ3RyYW5zbGF0ZScgXTtcblxuaW5oZXJpdHMoQnBtbk9yZGVyaW5nUHJvdmlkZXIsIE9yZGVyaW5nUHJvdmlkZXIpOyIsImltcG9ydCB0cmFuc2xhdGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnO1xuXG5pbXBvcnQgQnBtbk9yZGVyaW5nUHJvdmlkZXIgZnJvbSAnLi9CcG1uT3JkZXJpbmdQcm92aWRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICB0cmFuc2xhdGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2JwbW5PcmRlcmluZ1Byb3ZpZGVyJyBdLFxuICBicG1uT3JkZXJpbmdQcm92aWRlcjogWyAndHlwZScsIEJwbW5PcmRlcmluZ1Byb3ZpZGVyIF1cbn07IiwiaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEEgcGFsZXR0ZSBwcm92aWRlciBmb3IgQlBNTiAyLjAgZWxlbWVudHMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFBhbGV0dGVQcm92aWRlcihcbiAgICBwYWxldHRlLCBjcmVhdGUsIGVsZW1lbnRGYWN0b3J5LFxuICAgIHNwYWNlVG9vbCwgbGFzc29Ub29sLCBoYW5kVG9vbCxcbiAgICBnbG9iYWxDb25uZWN0LCB0cmFuc2xhdGUpIHtcblxuICB0aGlzLl9wYWxldHRlID0gcGFsZXR0ZTtcbiAgdGhpcy5fY3JlYXRlID0gY3JlYXRlO1xuICB0aGlzLl9lbGVtZW50RmFjdG9yeSA9IGVsZW1lbnRGYWN0b3J5O1xuICB0aGlzLl9zcGFjZVRvb2wgPSBzcGFjZVRvb2w7XG4gIHRoaXMuX2xhc3NvVG9vbCA9IGxhc3NvVG9vbDtcbiAgdGhpcy5faGFuZFRvb2wgPSBoYW5kVG9vbDtcbiAgdGhpcy5fZ2xvYmFsQ29ubmVjdCA9IGdsb2JhbENvbm5lY3Q7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcblxuICBwYWxldHRlLnJlZ2lzdGVyUHJvdmlkZXIodGhpcyk7XG59XG5cblBhbGV0dGVQcm92aWRlci4kaW5qZWN0ID0gW1xuICAncGFsZXR0ZScsXG4gICdjcmVhdGUnLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnc3BhY2VUb29sJyxcbiAgJ2xhc3NvVG9vbCcsXG4gICdoYW5kVG9vbCcsXG4gICdnbG9iYWxDb25uZWN0JyxcbiAgJ3RyYW5zbGF0ZSdcbl07XG5cblxuUGFsZXR0ZVByb3ZpZGVyLnByb3RvdHlwZS5nZXRQYWxldHRlRW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICB2YXIgYWN0aW9ucyA9IHt9LFxuICAgICAgY3JlYXRlID0gdGhpcy5fY3JlYXRlLFxuICAgICAgZWxlbWVudEZhY3RvcnkgPSB0aGlzLl9lbGVtZW50RmFjdG9yeSxcbiAgICAgIHNwYWNlVG9vbCA9IHRoaXMuX3NwYWNlVG9vbCxcbiAgICAgIGxhc3NvVG9vbCA9IHRoaXMuX2xhc3NvVG9vbCxcbiAgICAgIGhhbmRUb29sID0gdGhpcy5faGFuZFRvb2wsXG4gICAgICBnbG9iYWxDb25uZWN0ID0gdGhpcy5fZ2xvYmFsQ29ubmVjdCxcbiAgICAgIHRyYW5zbGF0ZSA9IHRoaXMuX3RyYW5zbGF0ZTtcblxuICBmdW5jdGlvbiBjcmVhdGVBY3Rpb24odHlwZSwgZ3JvdXAsIGNsYXNzTmFtZSwgdGl0bGUsIG9wdGlvbnMpIHtcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUxpc3RlbmVyKGV2ZW50KSB7XG4gICAgICB2YXIgc2hhcGUgPSBlbGVtZW50RmFjdG9yeS5jcmVhdGVTaGFwZShhc3NpZ24oeyB0eXBlOiB0eXBlIH0sIG9wdGlvbnMpKTtcblxuICAgICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgc2hhcGUuYnVzaW5lc3NPYmplY3QuZGkuaXNFeHBhbmRlZCA9IG9wdGlvbnMuaXNFeHBhbmRlZDtcbiAgICAgIH1cblxuICAgICAgY3JlYXRlLnN0YXJ0KGV2ZW50LCBzaGFwZSk7XG4gICAgfVxuXG4gICAgdmFyIHNob3J0VHlwZSA9IHR5cGUucmVwbGFjZSgvXmJwbW46LywgJycpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGdyb3VwOiBncm91cCxcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgdGl0bGU6IHRpdGxlIHx8IHRyYW5zbGF0ZSgnQ3JlYXRlIHt0eXBlfScsIHsgdHlwZTogc2hvcnRUeXBlIH0pLFxuICAgICAgYWN0aW9uOiB7XG4gICAgICAgIGRyYWdzdGFydDogY3JlYXRlTGlzdGVuZXIsXG4gICAgICAgIGNsaWNrOiBjcmVhdGVMaXN0ZW5lclxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVTdWJwcm9jZXNzKGV2ZW50KSB7XG4gICAgdmFyIHN1YlByb2Nlc3MgPSBlbGVtZW50RmFjdG9yeS5jcmVhdGVTaGFwZSh7XG4gICAgICB0eXBlOiAnYnBtbjpTdWJQcm9jZXNzJyxcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwLFxuICAgICAgaXNFeHBhbmRlZDogdHJ1ZVxuICAgIH0pO1xuXG4gICAgdmFyIHN0YXJ0RXZlbnQgPSBlbGVtZW50RmFjdG9yeS5jcmVhdGVTaGFwZSh7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIHg6IDQwLFxuICAgICAgeTogODIsXG4gICAgICBwYXJlbnQ6IHN1YlByb2Nlc3NcbiAgICB9KTtcblxuICAgIGNyZWF0ZS5zdGFydChldmVudCwgWyBzdWJQcm9jZXNzLCBzdGFydEV2ZW50IF0sIHtcbiAgICAgIGhpbnRzOiB7XG4gICAgICAgIGF1dG9TZWxlY3Q6IFsgc3RhcnRFdmVudCBdXG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVQYXJ0aWNpcGFudChldmVudCkge1xuICAgIGNyZWF0ZS5zdGFydChldmVudCwgZWxlbWVudEZhY3RvcnkuY3JlYXRlUGFydGljaXBhbnRTaGFwZSgpKTtcbiAgfVxuXG4gIGFzc2lnbihhY3Rpb25zLCB7XG4gICAgJ2hhbmQtdG9vbCc6IHtcbiAgICAgIGdyb3VwOiAndG9vbHMnLFxuICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWhhbmQtdG9vbCcsXG4gICAgICB0aXRsZTogdHJhbnNsYXRlKCdBY3RpdmF0ZSB0aGUgaGFuZCB0b29sJyksXG4gICAgICBhY3Rpb246IHtcbiAgICAgICAgY2xpY2s6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgaGFuZFRvb2wuYWN0aXZhdGVIYW5kKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgJ2xhc3NvLXRvb2wnOiB7XG4gICAgICBncm91cDogJ3Rvb2xzJyxcbiAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sYXNzby10b29sJyxcbiAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FjdGl2YXRlIHRoZSBsYXNzbyB0b29sJyksXG4gICAgICBhY3Rpb246IHtcbiAgICAgICAgY2xpY2s6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgbGFzc29Ub29sLmFjdGl2YXRlU2VsZWN0aW9uKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgJ3NwYWNlLXRvb2wnOiB7XG4gICAgICBncm91cDogJ3Rvb2xzJyxcbiAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zcGFjZS10b29sJyxcbiAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FjdGl2YXRlIHRoZSBjcmVhdGUvcmVtb3ZlIHNwYWNlIHRvb2wnKSxcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICBjbGljazogZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICBzcGFjZVRvb2wuYWN0aXZhdGVTZWxlY3Rpb24oZXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICAnZ2xvYmFsLWNvbm5lY3QtdG9vbCc6IHtcbiAgICAgIGdyb3VwOiAndG9vbHMnLFxuICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWNvbm5lY3Rpb24tbXVsdGknLFxuICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQWN0aXZhdGUgdGhlIGdsb2JhbCBjb25uZWN0IHRvb2wnKSxcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICBjbGljazogZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICBnbG9iYWxDb25uZWN0LnRvZ2dsZShldmVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgICd0b29sLXNlcGFyYXRvcic6IHtcbiAgICAgIGdyb3VwOiAndG9vbHMnLFxuICAgICAgc2VwYXJhdG9yOiB0cnVlXG4gICAgfSxcbiAgICAnY3JlYXRlLnN0YXJ0LWV2ZW50JzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46U3RhcnRFdmVudCcsICdldmVudCcsICdicG1uLWljb24tc3RhcnQtZXZlbnQtbm9uZScsXG4gICAgICB0cmFuc2xhdGUoJ0NyZWF0ZSBTdGFydEV2ZW50JylcbiAgICApLFxuICAgICdjcmVhdGUuaW50ZXJtZWRpYXRlLWV2ZW50JzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcsICdldmVudCcsICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LW5vbmUnLFxuICAgICAgdHJhbnNsYXRlKCdDcmVhdGUgSW50ZXJtZWRpYXRlL0JvdW5kYXJ5IEV2ZW50JylcbiAgICApLFxuICAgICdjcmVhdGUuZW5kLWV2ZW50JzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46RW5kRXZlbnQnLCAnZXZlbnQnLCAnYnBtbi1pY29uLWVuZC1ldmVudC1ub25lJyxcbiAgICAgIHRyYW5zbGF0ZSgnQ3JlYXRlIEVuZEV2ZW50JylcbiAgICApLFxuICAgICdjcmVhdGUuZXhjbHVzaXZlLWdhdGV3YXknOiBjcmVhdGVBY3Rpb24oXG4gICAgICAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JywgJ2dhdGV3YXknLCAnYnBtbi1pY29uLWdhdGV3YXktbm9uZScsXG4gICAgICB0cmFuc2xhdGUoJ0NyZWF0ZSBHYXRld2F5JylcbiAgICApLFxuICAgICdjcmVhdGUudGFzayc6IGNyZWF0ZUFjdGlvbihcbiAgICAgICdicG1uOlRhc2snLCAnYWN0aXZpdHknLCAnYnBtbi1pY29uLXRhc2snLFxuICAgICAgdHJhbnNsYXRlKCdDcmVhdGUgVGFzaycpXG4gICAgKSxcbiAgICAnY3JlYXRlLmRhdGEtb2JqZWN0JzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46RGF0YU9iamVjdFJlZmVyZW5jZScsICdkYXRhLW9iamVjdCcsICdicG1uLWljb24tZGF0YS1vYmplY3QnLFxuICAgICAgdHJhbnNsYXRlKCdDcmVhdGUgRGF0YU9iamVjdFJlZmVyZW5jZScpXG4gICAgKSxcbiAgICAnY3JlYXRlLmRhdGEtc3RvcmUnOiBjcmVhdGVBY3Rpb24oXG4gICAgICAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnLCAnZGF0YS1zdG9yZScsICdicG1uLWljb24tZGF0YS1zdG9yZScsXG4gICAgICB0cmFuc2xhdGUoJ0NyZWF0ZSBEYXRhU3RvcmVSZWZlcmVuY2UnKVxuICAgICksXG4gICAgJ2NyZWF0ZS5zdWJwcm9jZXNzLWV4cGFuZGVkJzoge1xuICAgICAgZ3JvdXA6ICdhY3Rpdml0eScsXG4gICAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3VicHJvY2Vzcy1leHBhbmRlZCcsXG4gICAgICB0aXRsZTogdHJhbnNsYXRlKCdDcmVhdGUgZXhwYW5kZWQgU3ViUHJvY2VzcycpLFxuICAgICAgYWN0aW9uOiB7XG4gICAgICAgIGRyYWdzdGFydDogY3JlYXRlU3VicHJvY2VzcyxcbiAgICAgICAgY2xpY2s6IGNyZWF0ZVN1YnByb2Nlc3NcbiAgICAgIH1cbiAgICB9LFxuICAgICdjcmVhdGUucGFydGljaXBhbnQtZXhwYW5kZWQnOiB7XG4gICAgICBncm91cDogJ2NvbGxhYm9yYXRpb24nLFxuICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXBhcnRpY2lwYW50JyxcbiAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0NyZWF0ZSBQb29sL1BhcnRpY2lwYW50JyksXG4gICAgICBhY3Rpb246IHtcbiAgICAgICAgZHJhZ3N0YXJ0OiBjcmVhdGVQYXJ0aWNpcGFudCxcbiAgICAgICAgY2xpY2s6IGNyZWF0ZVBhcnRpY2lwYW50XG4gICAgICB9XG4gICAgfSxcbiAgICAnY3JlYXRlLmdyb3VwJzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46R3JvdXAnLCAnYXJ0aWZhY3QnLCAnYnBtbi1pY29uLWdyb3VwJyxcbiAgICAgIHRyYW5zbGF0ZSgnQ3JlYXRlIEdyb3VwJylcbiAgICApLFxuICB9KTtcblxuICByZXR1cm4gYWN0aW9ucztcbn07XG4iLCJpbXBvcnQgUGFsZXR0ZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wYWxldHRlJztcbmltcG9ydCBDcmVhdGVNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY3JlYXRlJztcbmltcG9ydCBTcGFjZVRvb2xNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc3BhY2UtdG9vbCc7XG5pbXBvcnQgTGFzc29Ub29sTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2xhc3NvLXRvb2wnO1xuaW1wb3J0IEhhbmRUb29sTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2hhbmQtdG9vbCc7XG5pbXBvcnQgR2xvYmFsQ29ubmVjdE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9nbG9iYWwtY29ubmVjdCc7XG5pbXBvcnQgdHJhbnNsYXRlIGZyb20gJ2RpYWdyYW0tanMvbGliL2kxOG4vdHJhbnNsYXRlJztcblxuaW1wb3J0IFBhbGV0dGVQcm92aWRlciBmcm9tICcuL1BhbGV0dGVQcm92aWRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBQYWxldHRlTW9kdWxlLFxuICAgIENyZWF0ZU1vZHVsZSxcbiAgICBTcGFjZVRvb2xNb2R1bGUsXG4gICAgTGFzc29Ub29sTW9kdWxlLFxuICAgIEhhbmRUb29sTW9kdWxlLFxuICAgIEdsb2JhbENvbm5lY3RNb2R1bGUsXG4gICAgdHJhbnNsYXRlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdwYWxldHRlUHJvdmlkZXInIF0sXG4gIHBhbGV0dGVQcm92aWRlcjogWyAndHlwZScsIFBhbGV0dGVQcm92aWRlciBdXG59O1xuIiwiaW1wb3J0IHtcbiAgZ2V0QnVzaW5lc3NPYmplY3QsXG4gIGlzXG59IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgaXNFdmVudFN1YlByb2Nlc3MsXG4gIGlzRXhwYW5kZWRcbn0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0RpZmZlcmVudFR5cGVcbn0gZnJvbSAnLi91dGlsL1R5cGVVdGlsJztcblxuaW1wb3J0IHtcbiAgZm9yRWFjaCxcbiAgZmlsdGVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0ICogYXMgcmVwbGFjZU9wdGlvbnMgZnJvbSAnLi4vcmVwbGFjZS9SZXBsYWNlT3B0aW9ucyc7XG5cblxuLyoqXG4gKiBUaGlzIG1vZHVsZSBpcyBhbiBlbGVtZW50IGFnbm9zdGljIHJlcGxhY2UgbWVudSBwcm92aWRlciBmb3IgdGhlIHBvcHVwIG1lbnUuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlcGxhY2VNZW51UHJvdmlkZXIoXG4gICAgcG9wdXBNZW51LCBtb2RlbGluZywgbW9kZGxlLFxuICAgIGJwbW5SZXBsYWNlLCBydWxlcywgdHJhbnNsYXRlKSB7XG5cbiAgdGhpcy5fcG9wdXBNZW51ID0gcG9wdXBNZW51O1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xuICB0aGlzLl9tb2RkbGUgPSBtb2RkbGU7XG4gIHRoaXMuX2JwbW5SZXBsYWNlID0gYnBtblJlcGxhY2U7XG4gIHRoaXMuX3J1bGVzID0gcnVsZXM7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcblxuICB0aGlzLnJlZ2lzdGVyKCk7XG59XG5cblJlcGxhY2VNZW51UHJvdmlkZXIuJGluamVjdCA9IFtcbiAgJ3BvcHVwTWVudScsXG4gICdtb2RlbGluZycsXG4gICdtb2RkbGUnLFxuICAnYnBtblJlcGxhY2UnLFxuICAncnVsZXMnLFxuICAndHJhbnNsYXRlJ1xuXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVyIHJlcGxhY2UgbWVudSBwcm92aWRlciBpbiB0aGUgcG9wdXAgbWVudVxuICovXG5SZXBsYWNlTWVudVByb3ZpZGVyLnByb3RvdHlwZS5yZWdpc3RlciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9wb3B1cE1lbnUucmVnaXN0ZXJQcm92aWRlcignYnBtbi1yZXBsYWNlJywgdGhpcyk7XG59O1xuXG5cbi8qKlxuICogR2V0IGFsbCBlbnRyaWVzIGZyb20gcmVwbGFjZU9wdGlvbnMgZm9yIHRoZSBnaXZlbiBlbGVtZW50IGFuZCBhcHBseSBmaWx0ZXJzXG4gKiBvbiB0aGVtLiBHZXQgZm9yIGV4YW1wbGUgb25seSBlbGVtZW50cywgd2hpY2ggYXJlIGRpZmZlcmVudCBmcm9tIHRoZSBjdXJyZW50IG9uZS5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn0gYSBsaXN0IG9mIG1lbnUgZW50cnkgaXRlbXNcbiAqL1xuUmVwbGFjZU1lbnVQcm92aWRlci5wcm90b3R5cGUuZ2V0RW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0O1xuXG4gIHZhciBydWxlcyA9IHRoaXMuX3J1bGVzO1xuXG4gIHZhciBlbnRyaWVzO1xuXG4gIGlmICghcnVsZXMuYWxsb3dlZCgnc2hhcGUucmVwbGFjZScsIHsgZWxlbWVudDogZWxlbWVudCB9KSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHZhciBkaWZmZXJlbnRUeXBlID0gaXNEaWZmZXJlbnRUeXBlKGVsZW1lbnQpO1xuXG4gIC8vIHN0YXJ0IGV2ZW50cyBvdXRzaWRlIHN1YiBwcm9jZXNzZXNcbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpTdGFydEV2ZW50JykgJiYgIWlzKGJ1c2luZXNzT2JqZWN0LiRwYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5TVEFSVF9FVkVOVCwgZGlmZmVyZW50VHlwZSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIGV4cGFuZGVkL2NvbGxhcHNlZCBwb29sc1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOlBhcnRpY2lwYW50JykpIHtcblxuICAgIGVudHJpZXMgPSBmaWx0ZXIocmVwbGFjZU9wdGlvbnMuUEFSVElDSVBBTlQsIGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgICByZXR1cm4gaXNFeHBhbmRlZChidXNpbmVzc09iamVjdCkgIT09IGVudHJ5LnRhcmdldC5pc0V4cGFuZGVkO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVudHJpZXMoZWxlbWVudCwgZW50cmllcyk7XG4gIH1cblxuICAvLyBzdGFydCBldmVudHMgaW5zaWRlIGV2ZW50IHN1YiBwcm9jZXNzZXNcbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpTdGFydEV2ZW50JykgJiYgaXNFdmVudFN1YlByb2Nlc3MoYnVzaW5lc3NPYmplY3QuJHBhcmVudCkpIHtcbiAgICBlbnRyaWVzID0gZmlsdGVyKHJlcGxhY2VPcHRpb25zLkVWRU5UX1NVQl9QUk9DRVNTX1NUQVJUX0VWRU5ULCBmdW5jdGlvbihlbnRyeSkge1xuXG4gICAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgICB2YXIgaXNJbnRlcnJ1cHRpbmcgPSB0YXJnZXQuaXNJbnRlcnJ1cHRpbmcgIT09IGZhbHNlO1xuXG4gICAgICB2YXIgaXNJbnRlcnJ1cHRpbmdFcXVhbCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLmlzSW50ZXJydXB0aW5nID09PSBpc0ludGVycnVwdGluZztcblxuICAgICAgLy8gZmlsdGVycyBlbGVtZW50cyB3aGljaCB0eXBlcyBhbmQgZXZlbnQgZGVmaW5pdGlvbiBhcmUgZXF1YWwgYnV0IGhhdmUgaGF2ZSBkaWZmZXJlbnQgaW50ZXJydXB0aW5nIHR5cGVzXG4gICAgICByZXR1cm4gZGlmZmVyZW50VHlwZShlbnRyeSkgfHwgIWRpZmZlcmVudFR5cGUoZW50cnkpICYmICFpc0ludGVycnVwdGluZ0VxdWFsO1xuXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIHN0YXJ0IGV2ZW50cyBpbnNpZGUgc3ViIHByb2Nlc3Nlc1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOlN0YXJ0RXZlbnQnKSAmJiAhaXNFdmVudFN1YlByb2Nlc3MoYnVzaW5lc3NPYmplY3QuJHBhcmVudClcbiAgICAgICYmIGlzKGJ1c2luZXNzT2JqZWN0LiRwYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuICAgIGVudHJpZXMgPSBmaWx0ZXIocmVwbGFjZU9wdGlvbnMuU1RBUlRfRVZFTlRfU1VCX1BST0NFU1MsIGRpZmZlcmVudFR5cGUpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVudHJpZXMoZWxlbWVudCwgZW50cmllcyk7XG4gIH1cblxuICAvLyBlbmQgZXZlbnRzXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46RW5kRXZlbnQnKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5FTkRfRVZFTlQsIGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgICAvLyBoaWRlIGNhbmNlbCBlbmQgZXZlbnRzIG91dHNpZGUgdHJhbnNhY3Rpb25zXG4gICAgICBpZiAodGFyZ2V0LmV2ZW50RGVmaW5pdGlvblR5cGUgPT0gJ2JwbW46Q2FuY2VsRXZlbnREZWZpbml0aW9uJyAmJiAhaXMoYnVzaW5lc3NPYmplY3QuJHBhcmVudCwgJ2JwbW46VHJhbnNhY3Rpb24nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBkaWZmZXJlbnRUeXBlKGVudHJ5KTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbnRyaWVzKGVsZW1lbnQsIGVudHJpZXMpO1xuICB9XG5cbiAgLy8gYm91bmRhcnkgZXZlbnRzXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpKSB7XG5cbiAgICBlbnRyaWVzID0gZmlsdGVyKHJlcGxhY2VPcHRpb25zLkJPVU5EQVJZX0VWRU5ULCBmdW5jdGlvbihlbnRyeSkge1xuXG4gICAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgICBpZiAodGFyZ2V0LmV2ZW50RGVmaW5pdGlvbiA9PSAnYnBtbjpDYW5jZWxFdmVudERlZmluaXRpb24nICYmXG4gICAgICAgICAhaXMoYnVzaW5lc3NPYmplY3QuYXR0YWNoZWRUb1JlZiwgJ2JwbW46VHJhbnNhY3Rpb24nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgY2FuY2VsQWN0aXZpdHkgPSB0YXJnZXQuY2FuY2VsQWN0aXZpdHkgIT09IGZhbHNlO1xuXG4gICAgICB2YXIgaXNDYW5jZWxBY3Rpdml0eUVxdWFsID0gYnVzaW5lc3NPYmplY3QuY2FuY2VsQWN0aXZpdHkgPT0gY2FuY2VsQWN0aXZpdHk7XG5cbiAgICAgIHJldHVybiBkaWZmZXJlbnRUeXBlKGVudHJ5KSB8fCAhZGlmZmVyZW50VHlwZShlbnRyeSkgJiYgIWlzQ2FuY2VsQWN0aXZpdHlFcXVhbDtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbnRyaWVzKGVsZW1lbnQsIGVudHJpZXMpO1xuICB9XG5cbiAgLy8gaW50ZXJtZWRpYXRlIGV2ZW50c1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnKSB8fFxuICAgICAgaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5JTlRFUk1FRElBVEVfRVZFTlQsIGRpZmZlcmVudFR5cGUpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVudHJpZXMoZWxlbWVudCwgZW50cmllcyk7XG4gIH1cblxuICAvLyBnYXRld2F5c1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkdhdGV3YXknKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5HQVRFV0FZLCBkaWZmZXJlbnRUeXBlKTtcblxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbnRyaWVzKGVsZW1lbnQsIGVudHJpZXMpO1xuICB9XG5cbiAgLy8gdHJhbnNhY3Rpb25zXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46VHJhbnNhY3Rpb24nKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5UUkFOU0FDVElPTiwgZGlmZmVyZW50VHlwZSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIGV4cGFuZGVkIGV2ZW50IHN1YiBwcm9jZXNzZXNcbiAgaWYgKGlzRXZlbnRTdWJQcm9jZXNzKGJ1c2luZXNzT2JqZWN0KSAmJiBpc0V4cGFuZGVkKGJ1c2luZXNzT2JqZWN0KSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5FVkVOVF9TVUJfUFJPQ0VTUywgZGlmZmVyZW50VHlwZSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIGV4cGFuZGVkIHN1YiBwcm9jZXNzZXNcbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpTdWJQcm9jZXNzJykgJiYgaXNFeHBhbmRlZChidXNpbmVzc09iamVjdCkpIHtcblxuICAgIGVudHJpZXMgPSBmaWx0ZXIocmVwbGFjZU9wdGlvbnMuU1VCUFJPQ0VTU19FWFBBTkRFRCwgZGlmZmVyZW50VHlwZSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIGNvbGxhcHNlZCBhZCBob2Mgc3ViIHByb2Nlc3Nlc1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkFkSG9jU3ViUHJvY2VzcycpICYmICFpc0V4cGFuZGVkKGJ1c2luZXNzT2JqZWN0KSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5UQVNLLCBmdW5jdGlvbihlbnRyeSkge1xuXG4gICAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgICB2YXIgaXNUYXJnZXRTdWJQcm9jZXNzID0gdGFyZ2V0LnR5cGUgPT09ICdicG1uOlN1YlByb2Nlc3MnO1xuXG4gICAgICB2YXIgaXNUYXJnZXRFeHBhbmRlZCA9IHRhcmdldC5pc0V4cGFuZGVkID09PSB0cnVlO1xuXG4gICAgICByZXR1cm4gaXNEaWZmZXJlbnRUeXBlKGVsZW1lbnQsIHRhcmdldCkgJiYgKCFpc1RhcmdldFN1YlByb2Nlc3MgfHwgaXNUYXJnZXRFeHBhbmRlZCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIHNlcXVlbmNlIGZsb3dzXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46U2VxdWVuY2VGbG93JykpIHtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlU2VxdWVuY2VGbG93RW50cmllcyhlbGVtZW50LCByZXBsYWNlT3B0aW9ucy5TRVFVRU5DRV9GTE9XKTtcbiAgfVxuXG4gIC8vIGZsb3cgbm9kZXNcbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpGbG93Tm9kZScpKSB7XG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5UQVNLLCBkaWZmZXJlbnRUeXBlKTtcblxuICAgIC8vIGNvbGxhcHNlZCBTdWJQcm9jZXNzIGNhbiBub3QgYmUgcmVwbGFjZWQgd2l0aCBpdHNlbGZcbiAgICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOlN1YlByb2Nlc3MnKSAmJiAhaXNFeHBhbmRlZChidXNpbmVzc09iamVjdCkpIHtcbiAgICAgIGVudHJpZXMgPSBmaWx0ZXIoZW50cmllcywgZnVuY3Rpb24oZW50cnkpIHtcbiAgICAgICAgcmV0dXJuIGVudHJ5LmxhYmVsICE9PSAnU3ViIFByb2Nlc3MgKGNvbGxhcHNlZCknO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVudHJpZXMoZWxlbWVudCwgZW50cmllcyk7XG4gIH1cblxuICByZXR1cm4gW107XG59O1xuXG5cbi8qKlxuICogR2V0IGEgbGlzdCBvZiBoZWFkZXIgaXRlbXMgZm9yIHRoZSBnaXZlbiBlbGVtZW50LiBUaGlzIGluY2x1ZGVzIGJ1dHRvbnNcbiAqIGZvciBtdWx0aSBpbnN0YW5jZSBtYXJrZXJzIGFuZCBmb3IgdGhlIGFkIGhvYyBtYXJrZXIuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge0FycmF5PE9iamVjdD59IGEgbGlzdCBvZiBtZW51IGVudHJ5IGl0ZW1zXG4gKi9cblJlcGxhY2VNZW51UHJvdmlkZXIucHJvdG90eXBlLmdldEhlYWRlckVudHJpZXMgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgdmFyIGhlYWRlckVudHJpZXMgPSBbXTtcblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46QWN0aXZpdHknKSAmJiAhaXNFdmVudFN1YlByb2Nlc3MoZWxlbWVudCkpIHtcbiAgICBoZWFkZXJFbnRyaWVzID0gaGVhZGVyRW50cmllcy5jb25jYXQodGhpcy5fZ2V0TG9vcEVudHJpZXMoZWxlbWVudCkpO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJlxuICAgICAgIWlzKGVsZW1lbnQsICdicG1uOlRyYW5zYWN0aW9uJykgJiZcbiAgICAgICFpc0V2ZW50U3ViUHJvY2VzcyhlbGVtZW50KSkge1xuICAgIGhlYWRlckVudHJpZXMucHVzaCh0aGlzLl9nZXRBZEhvY0VudHJ5KGVsZW1lbnQpKTtcbiAgfVxuXG4gIHJldHVybiBoZWFkZXJFbnRyaWVzO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgbWVudSBlbnRyeSBvYmplY3RzIGZvciBhIGdpdmVuIGVsZW1lbnQgYW5kIGZpbHRlcnMgdGhlIHJlcGxhY2VPcHRpb25zXG4gKiBhY2NvcmRpbmcgdG8gYSBmaWx0ZXIgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSAge09iamVjdH0gcmVwbGFjZU9wdGlvbnNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxPYmplY3Q+fSBhIGxpc3Qgb2YgbWVudSBpdGVtc1xuICovXG5SZXBsYWNlTWVudVByb3ZpZGVyLnByb3RvdHlwZS5fY3JlYXRlRW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHJlcGxhY2VPcHRpb25zKSB7XG4gIHZhciBtZW51RW50cmllcyA9IFtdO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmb3JFYWNoKHJlcGxhY2VPcHRpb25zLCBmdW5jdGlvbihkZWZpbml0aW9uKSB7XG4gICAgdmFyIGVudHJ5ID0gc2VsZi5fY3JlYXRlTWVudUVudHJ5KGRlZmluaXRpb24sIGVsZW1lbnQpO1xuXG4gICAgbWVudUVudHJpZXMucHVzaChlbnRyeSk7XG4gIH0pO1xuXG4gIHJldHVybiBtZW51RW50cmllcztcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiBtZW51IGVudHJ5IG9iamVjdHMgZm9yIGEgZ2l2ZW4gc2VxdWVuY2UgZmxvdy5cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtICB7T2JqZWN0fSByZXBsYWNlT3B0aW9uc1xuXG4gKiBAcmV0dXJuIHtBcnJheTxPYmplY3Q+fSBhIGxpc3Qgb2YgbWVudSBpdGVtc1xuICovXG5SZXBsYWNlTWVudVByb3ZpZGVyLnByb3RvdHlwZS5fY3JlYXRlU2VxdWVuY2VGbG93RW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHJlcGxhY2VPcHRpb25zKSB7XG5cbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XG5cbiAgdmFyIG1lbnVFbnRyaWVzID0gW107XG5cbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmcsXG4gICAgICBtb2RkbGUgPSB0aGlzLl9tb2RkbGU7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGZvckVhY2gocmVwbGFjZU9wdGlvbnMsIGZ1bmN0aW9uKGVudHJ5KSB7XG5cbiAgICBzd2l0Y2ggKGVudHJ5LmFjdGlvbk5hbWUpIHtcbiAgICBjYXNlICdyZXBsYWNlLXdpdGgtZGVmYXVsdC1mbG93JzpcbiAgICAgIGlmIChidXNpbmVzc09iamVjdC5zb3VyY2VSZWYuZGVmYXVsdCAhPT0gYnVzaW5lc3NPYmplY3QgJiZcbiAgICAgICAgICAgIChpcyhidXNpbmVzc09iamVjdC5zb3VyY2VSZWYsICdicG1uOkV4Y2x1c2l2ZUdhdGV3YXknKSB8fFxuICAgICAgICAgICAgIGlzKGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiwgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheScpIHx8XG4gICAgICAgICAgICAgaXMoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmLCAnYnBtbjpDb21wbGV4R2F0ZXdheScpIHx8XG4gICAgICAgICAgICAgaXMoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmLCAnYnBtbjpBY3Rpdml0eScpKSkge1xuXG4gICAgICAgIG1lbnVFbnRyaWVzLnB1c2goc2VsZi5fY3JlYXRlTWVudUVudHJ5KGVudHJ5LCBlbGVtZW50LCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBtb2RlbGluZy51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQuc291cmNlLCB7IGRlZmF1bHQ6IGJ1c2luZXNzT2JqZWN0IH0pO1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdyZXBsYWNlLXdpdGgtY29uZGl0aW9uYWwtZmxvdyc6XG4gICAgICBpZiAoIWJ1c2luZXNzT2JqZWN0LmNvbmRpdGlvbkV4cHJlc3Npb24gJiYgaXMoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmLCAnYnBtbjpBY3Rpdml0eScpKSB7XG5cbiAgICAgICAgbWVudUVudHJpZXMucHVzaChzZWxmLl9jcmVhdGVNZW51RW50cnkoZW50cnksIGVsZW1lbnQsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciBjb25kaXRpb25FeHByZXNzaW9uID0gbW9kZGxlLmNyZWF0ZSgnYnBtbjpGb3JtYWxFeHByZXNzaW9uJywgeyBib2R5OiAnJyB9KTtcblxuICAgICAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgeyBjb25kaXRpb25FeHByZXNzaW9uOiBjb25kaXRpb25FeHByZXNzaW9uIH0pO1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuXG4gICAgICAvLyBkZWZhdWx0IGZsb3dzXG4gICAgICBpZiAoaXMoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmLCAnYnBtbjpBY3Rpdml0eScpICYmIGJ1c2luZXNzT2JqZWN0LmNvbmRpdGlvbkV4cHJlc3Npb24pIHtcbiAgICAgICAgcmV0dXJuIG1lbnVFbnRyaWVzLnB1c2goc2VsZi5fY3JlYXRlTWVudUVudHJ5KGVudHJ5LCBlbGVtZW50LCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBtb2RlbGluZy51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHsgY29uZGl0aW9uRXhwcmVzc2lvbjogdW5kZWZpbmVkIH0pO1xuICAgICAgICB9KSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGNvbmRpdGlvbmFsIGZsb3dzXG4gICAgICBpZiAoKGlzKGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiwgJ2JwbW46RXhjbHVzaXZlR2F0ZXdheScpIHx8XG4gICAgICAgICAgIGlzKGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiwgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheScpIHx8XG4gICAgICAgICAgIGlzKGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiwgJ2JwbW46Q29tcGxleEdhdGV3YXknKSB8fFxuICAgICAgICAgICBpcyhidXNpbmVzc09iamVjdC5zb3VyY2VSZWYsICdicG1uOkFjdGl2aXR5JykpICYmXG4gICAgICAgICAgIGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZi5kZWZhdWx0ID09PSBidXNpbmVzc09iamVjdCkge1xuXG4gICAgICAgIHJldHVybiBtZW51RW50cmllcy5wdXNoKHNlbGYuX2NyZWF0ZU1lbnVFbnRyeShlbnRyeSwgZWxlbWVudCwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgbW9kZWxpbmcudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LnNvdXJjZSwgeyBkZWZhdWx0OiB1bmRlZmluZWQgfSk7XG4gICAgICAgIH0pKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBtZW51RW50cmllcztcbn07XG5cblxuLyoqXG4gKiBDcmVhdGVzIGFuZCByZXR1cm5zIGEgc2luZ2xlIG1lbnUgZW50cnkgaXRlbS5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGRlZmluaXRpb24gYSBzaW5nbGUgcmVwbGFjZSBvcHRpb25zIGRlZmluaXRpb24gb2JqZWN0XG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtICB7RnVuY3Rpb259IFthY3Rpb25dIGFuIGFjdGlvbiBjYWxsYmFjayBmdW5jdGlvbiB3aGljaCBnZXRzIGNhbGxlZCB3aGVuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG1lbnUgZW50cnkgaXMgYmVpbmcgdHJpZ2dlcmVkLlxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gbWVudSBlbnRyeSBpdGVtXG4gKi9cblJlcGxhY2VNZW51UHJvdmlkZXIucHJvdG90eXBlLl9jcmVhdGVNZW51RW50cnkgPSBmdW5jdGlvbihkZWZpbml0aW9uLCBlbGVtZW50LCBhY3Rpb24pIHtcbiAgdmFyIHRyYW5zbGF0ZSA9IHRoaXMuX3RyYW5zbGF0ZTtcbiAgdmFyIHJlcGxhY2VFbGVtZW50ID0gdGhpcy5fYnBtblJlcGxhY2UucmVwbGFjZUVsZW1lbnQ7XG5cbiAgdmFyIHJlcGxhY2VBY3Rpb24gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gcmVwbGFjZUVsZW1lbnQoZWxlbWVudCwgZGVmaW5pdGlvbi50YXJnZXQpO1xuICB9O1xuXG4gIGFjdGlvbiA9IGFjdGlvbiB8fCByZXBsYWNlQWN0aW9uO1xuXG4gIHZhciBtZW51RW50cnkgPSB7XG4gICAgbGFiZWw6IHRyYW5zbGF0ZShkZWZpbml0aW9uLmxhYmVsKSxcbiAgICBjbGFzc05hbWU6IGRlZmluaXRpb24uY2xhc3NOYW1lLFxuICAgIGlkOiBkZWZpbml0aW9uLmFjdGlvbk5hbWUsXG4gICAgYWN0aW9uOiBhY3Rpb25cbiAgfTtcblxuICByZXR1cm4gbWVudUVudHJ5O1xufTtcblxuLyoqXG4gKiBHZXQgYSBsaXN0IG9mIG1lbnUgaXRlbXMgY29udGFpbmluZyBidXR0b25zIGZvciBtdWx0aSBpbnN0YW5jZSBtYXJrZXJzXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxPYmplY3Q+fSBhIGxpc3Qgb2YgbWVudSBpdGVtc1xuICovXG5SZXBsYWNlTWVudVByb3ZpZGVyLnByb3RvdHlwZS5fZ2V0TG9vcEVudHJpZXMgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuXG4gIGZ1bmN0aW9uIHRvZ2dsZUxvb3BFbnRyeShldmVudCwgZW50cnkpIHtcbiAgICB2YXIgbG9vcENoYXJhY3RlcmlzdGljcztcblxuICAgIGlmIChlbnRyeS5hY3RpdmUpIHtcbiAgICAgIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSBzZWxmLl9tb2RkbGUuY3JlYXRlKGVudHJ5Lm9wdGlvbnMubG9vcENoYXJhY3RlcmlzdGljcyk7XG5cbiAgICAgIGlmIChlbnRyeS5vcHRpb25zLmlzU2VxdWVudGlhbCkge1xuICAgICAgICBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbCA9IGVudHJ5Lm9wdGlvbnMuaXNTZXF1ZW50aWFsO1xuICAgICAgfVxuICAgIH1cbiAgICBzZWxmLl9tb2RlbGluZy51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHsgbG9vcENoYXJhY3RlcmlzdGljczogbG9vcENoYXJhY3RlcmlzdGljcyB9KTtcbiAgfVxuXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxuICAgICAgbG9vcENoYXJhY3RlcmlzdGljcyA9IGJ1c2luZXNzT2JqZWN0Lmxvb3BDaGFyYWN0ZXJpc3RpY3M7XG5cbiAgdmFyIGlzU2VxdWVudGlhbCxcbiAgICAgIGlzTG9vcCxcbiAgICAgIGlzUGFyYWxsZWw7XG5cbiAgaWYgKGxvb3BDaGFyYWN0ZXJpc3RpY3MpIHtcbiAgICBpc1NlcXVlbnRpYWwgPSBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbDtcbiAgICBpc0xvb3AgPSBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbCA9PT0gdW5kZWZpbmVkO1xuICAgIGlzUGFyYWxsZWwgPSBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbCAhPT0gdW5kZWZpbmVkICYmICFsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbDtcbiAgfVxuXG5cbiAgdmFyIGxvb3BFbnRyaWVzID0gW1xuICAgIHtcbiAgICAgIGlkOiAndG9nZ2xlLXBhcmFsbGVsLW1pJyxcbiAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1wYXJhbGxlbC1taS1tYXJrZXInLFxuICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnUGFyYWxsZWwgTXVsdGkgSW5zdGFuY2UnKSxcbiAgICAgIGFjdGl2ZTogaXNQYXJhbGxlbCxcbiAgICAgIGFjdGlvbjogdG9nZ2xlTG9vcEVudHJ5LFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICBsb29wQ2hhcmFjdGVyaXN0aWNzOiAnYnBtbjpNdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljcycsXG4gICAgICAgIGlzU2VxdWVudGlhbDogZmFsc2VcbiAgICAgIH1cbiAgICB9LFxuICAgIHtcbiAgICAgIGlkOiAndG9nZ2xlLXNlcXVlbnRpYWwtbWknLFxuICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXNlcXVlbnRpYWwtbWktbWFya2VyJyxcbiAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ1NlcXVlbnRpYWwgTXVsdGkgSW5zdGFuY2UnKSxcbiAgICAgIGFjdGl2ZTogaXNTZXF1ZW50aWFsLFxuICAgICAgYWN0aW9uOiB0b2dnbGVMb29wRW50cnksXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIGxvb3BDaGFyYWN0ZXJpc3RpY3M6ICdicG1uOk11bHRpSW5zdGFuY2VMb29wQ2hhcmFjdGVyaXN0aWNzJyxcbiAgICAgICAgaXNTZXF1ZW50aWFsOiB0cnVlXG4gICAgICB9XG4gICAgfSxcbiAgICB7XG4gICAgICBpZDogJ3RvZ2dsZS1sb29wJyxcbiAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sb29wLW1hcmtlcicsXG4gICAgICB0aXRsZTogdHJhbnNsYXRlKCdMb29wJyksXG4gICAgICBhY3RpdmU6IGlzTG9vcCxcbiAgICAgIGFjdGlvbjogdG9nZ2xlTG9vcEVudHJ5LFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICBsb29wQ2hhcmFjdGVyaXN0aWNzOiAnYnBtbjpTdGFuZGFyZExvb3BDaGFyYWN0ZXJpc3RpY3MnXG4gICAgICB9XG4gICAgfVxuICBdO1xuICByZXR1cm4gbG9vcEVudHJpZXM7XG59O1xuXG5cbi8qKlxuICogR2V0IHRoZSBtZW51IGl0ZW1zIGNvbnRhaW5pbmcgYSBidXR0b24gZm9yIHRoZSBhZCBob2MgbWFya2VyXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGEgbWVudSBpdGVtXG4gKi9cblJlcGxhY2VNZW51UHJvdmlkZXIucHJvdG90eXBlLl9nZXRBZEhvY0VudHJ5ID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICB2YXIgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcblxuICB2YXIgaXNBZEhvYyA9IGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpBZEhvY1N1YlByb2Nlc3MnKTtcblxuICB2YXIgcmVwbGFjZUVsZW1lbnQgPSB0aGlzLl9icG1uUmVwbGFjZS5yZXBsYWNlRWxlbWVudDtcblxuICB2YXIgYWRIb2NFbnRyeSA9IHtcbiAgICBpZDogJ3RvZ2dsZS1hZGhvYycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWFkLWhvYy1tYXJrZXInLFxuICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FkLWhvYycpLFxuICAgIGFjdGl2ZTogaXNBZEhvYyxcbiAgICBhY3Rpb246IGZ1bmN0aW9uKGV2ZW50LCBlbnRyeSkge1xuICAgICAgaWYgKGlzQWRIb2MpIHtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VFbGVtZW50KGVsZW1lbnQsIHsgdHlwZTogJ2JwbW46U3ViUHJvY2VzcycgfSwge1xuICAgICAgICAgIGF1dG9SZXNpemU6IGZhbHNlLFxuICAgICAgICAgIGxheW91dENvbm5lY3Rpb246IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VFbGVtZW50KGVsZW1lbnQsIHsgdHlwZTogJ2JwbW46QWRIb2NTdWJQcm9jZXNzJyB9LCB7XG4gICAgICAgICAgYXV0b1Jlc2l6ZTogZmFsc2UsXG4gICAgICAgICAgbGF5b3V0Q29ubmVjdGlvbjogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBhZEhvY0VudHJ5O1xufTtcbiIsImltcG9ydCBQb3B1cE1lbnVNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcG9wdXAtbWVudSc7XG5pbXBvcnQgUmVwbGFjZU1vZHVsZSBmcm9tICcuLi9yZXBsYWNlJztcblxuaW1wb3J0IFJlcGxhY2VNZW51UHJvdmlkZXIgZnJvbSAnLi9SZXBsYWNlTWVudVByb3ZpZGVyJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgUG9wdXBNZW51TW9kdWxlLFxuICAgIFJlcGxhY2VNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ3JlcGxhY2VNZW51UHJvdmlkZXInIF0sXG4gIHJlcGxhY2VNZW51UHJvdmlkZXI6IFsgJ3R5cGUnLCBSZXBsYWNlTWVudVByb3ZpZGVyIF1cbn07IiwiaW1wb3J0IHtcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0V4cGFuZGVkXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvRGlVdGlsJztcblxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSwgaWYgYW4gZWxlbWVudCBpcyBmcm9tIGEgZGlmZmVyZW50IHR5cGVcbiAqIHRoYW4gYSB0YXJnZXQgZGVmaW5pdGlvbi4gVGFrZXMgaW50byBhY2NvdW50IHRoZSB0eXBlLFxuICogZXZlbnQgZGVmaW5pdGlvbiB0eXBlIGFuZCB0cmlnZ2VyZWRCeUV2ZW50IHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEaWZmZXJlbnRUeXBlKGVsZW1lbnQpIHtcblxuICByZXR1cm4gZnVuY3Rpb24oZW50cnkpIHtcbiAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksXG4gICAgICAgIGV2ZW50RGVmaW5pdGlvbiA9IGJ1c2luZXNzT2JqZWN0LmV2ZW50RGVmaW5pdGlvbnMgJiYgYnVzaW5lc3NPYmplY3QuZXZlbnREZWZpbml0aW9uc1swXTtcblxuICAgIHZhciBpc1R5cGVFcXVhbCA9IGJ1c2luZXNzT2JqZWN0LiR0eXBlID09PSB0YXJnZXQudHlwZTtcblxuICAgIHZhciBpc0V2ZW50RGVmaW5pdGlvbkVxdWFsID0gKFxuICAgICAgKGV2ZW50RGVmaW5pdGlvbiAmJiBldmVudERlZmluaXRpb24uJHR5cGUpID09PSB0YXJnZXQuZXZlbnREZWZpbml0aW9uVHlwZVxuICAgICk7XG5cbiAgICB2YXIgaXNUcmlnZ2VyZWRCeUV2ZW50RXF1YWwgPSAoXG4gICAgICBidXNpbmVzc09iamVjdC50cmlnZ2VyZWRCeUV2ZW50ID09PSB0YXJnZXQudHJpZ2dlcmVkQnlFdmVudFxuICAgICk7XG5cbiAgICB2YXIgaXNFeHBhbmRlZEVxdWFsID0gKFxuICAgICAgdGFyZ2V0LmlzRXhwYW5kZWQgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgdGFyZ2V0LmlzRXhwYW5kZWQgPT09IGlzRXhwYW5kZWQoYnVzaW5lc3NPYmplY3QpXG4gICAgKTtcblxuICAgIHJldHVybiAhaXNUeXBlRXF1YWwgfHwgIWlzRXZlbnREZWZpbml0aW9uRXF1YWwgfHwgIWlzVHJpZ2dlcmVkQnlFdmVudEVxdWFsIHx8ICFpc0V4cGFuZGVkRXF1YWw7XG4gIH07XG59IiwiaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBjc3NFc2NhcGUgZnJvbSAnY3NzLmVzY2FwZSc7XG5cbmltcG9ydCB7XG4gIGFzc2lnbixcbiAgZm9yRWFjaFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIHF1ZXJ5IGFzIGRvbVF1ZXJ5XG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICBhdHRyIGFzIHN2Z0F0dHJcbn0gZnJvbSAndGlueS1zdmcnO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gMjUwO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5SZXBsYWNlUHJldmlldyhcbiAgICBldmVudEJ1cywgZWxlbWVudFJlZ2lzdHJ5LCBlbGVtZW50RmFjdG9yeSxcbiAgICBjYW52YXMsIHByZXZpZXdTdXBwb3J0KSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8qKlxuICAgKiBSZXBsYWNlIHRoZSB2aXN1YWxzIG9mIGFsbCBlbGVtZW50cyBpbiB0aGUgY29udGV4dCB3aGljaCBjYW4gYmUgcmVwbGFjZWRcbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBjb250ZXh0XG4gICAqL1xuICBmdW5jdGlvbiByZXBsYWNlVmlzdWFsKGNvbnRleHQpIHtcblxuICAgIHZhciByZXBsYWNlbWVudHMgPSBjb250ZXh0LmNhbkV4ZWN1dGUucmVwbGFjZW1lbnRzO1xuXG4gICAgZm9yRWFjaChyZXBsYWNlbWVudHMsIGZ1bmN0aW9uKHJlcGxhY2VtZW50KSB7XG5cbiAgICAgIHZhciBpZCA9IHJlcGxhY2VtZW50Lm9sZEVsZW1lbnRJZDtcblxuICAgICAgdmFyIG5ld0VsZW1lbnQgPSB7XG4gICAgICAgIHR5cGU6IHJlcGxhY2VtZW50Lm5ld0VsZW1lbnRUeXBlXG4gICAgICB9O1xuXG4gICAgICAvLyBpZiB0aGUgdmlzdWFsIG9mIHRoZSBlbGVtZW50IGlzIGFscmVhZHkgcmVwbGFjZWRcbiAgICAgIGlmIChjb250ZXh0LnZpc3VhbFJlcGxhY2VtZW50c1tpZF0pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgZWxlbWVudCA9IGVsZW1lbnRSZWdpc3RyeS5nZXQoaWQpO1xuXG4gICAgICBhc3NpZ24obmV3RWxlbWVudCwgeyB4OiBlbGVtZW50LngsIHk6IGVsZW1lbnQueSB9KTtcblxuICAgICAgLy8gY3JlYXRlIGEgdGVtcG9yYXJ5IHNoYXBlXG4gICAgICB2YXIgdGVtcFNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUobmV3RWxlbWVudCk7XG5cbiAgICAgIGNhbnZhcy5hZGRTaGFwZSh0ZW1wU2hhcGUsIGVsZW1lbnQucGFyZW50KTtcblxuICAgICAgLy8gc2VsZWN0IHRoZSBvcmlnaW5hbCBTVkcgZWxlbWVudCByZWxhdGVkIHRvIHRoZSBlbGVtZW50IGFuZCBoaWRlIGl0XG4gICAgICB2YXIgZ2Z4ID0gZG9tUXVlcnkoJ1tkYXRhLWVsZW1lbnQtaWQ9XCInICsgY3NzRXNjYXBlKGVsZW1lbnQuaWQpICsgJ1wiXScsIGNvbnRleHQuZHJhZ0dyb3VwKTtcblxuICAgICAgaWYgKGdmeCkge1xuICAgICAgICBzdmdBdHRyKGdmeCwgeyBkaXNwbGF5OiAnbm9uZScgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGNsb25lIHRoZSBnZnggb2YgdGhlIHRlbXBvcmFyeSBzaGFwZSBhbmQgYWRkIGl0IHRvIHRoZSBkcmFnIGdyb3VwXG4gICAgICB2YXIgZHJhZ2dlciA9IHByZXZpZXdTdXBwb3J0LmFkZERyYWdnZXIodGVtcFNoYXBlLCBjb250ZXh0LmRyYWdHcm91cCk7XG5cbiAgICAgIGNvbnRleHQudmlzdWFsUmVwbGFjZW1lbnRzW2lkXSA9IGRyYWdnZXI7XG5cbiAgICAgIGNhbnZhcy5yZW1vdmVTaGFwZSh0ZW1wU2hhcGUpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHZpc3VhbHMgb2YgdGhlIHByZXZpb3VzbHkgcmVwbGFjZWQgZWxlbWVudHNcbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBjb250ZXh0XG4gICAqL1xuICBmdW5jdGlvbiByZXN0b3JlVmlzdWFsKGNvbnRleHQpIHtcblxuICAgIHZhciB2aXN1YWxSZXBsYWNlbWVudHMgPSBjb250ZXh0LnZpc3VhbFJlcGxhY2VtZW50cztcblxuICAgIGZvckVhY2godmlzdWFsUmVwbGFjZW1lbnRzLCBmdW5jdGlvbihkcmFnZ2VyLCBpZCkge1xuXG4gICAgICB2YXIgb3JpZ2luYWxHZnggPSBkb21RdWVyeSgnW2RhdGEtZWxlbWVudC1pZD1cIicgKyBjc3NFc2NhcGUoaWQpICsgJ1wiXScsIGNvbnRleHQuZHJhZ0dyb3VwKTtcblxuICAgICAgaWYgKG9yaWdpbmFsR2Z4KSB7XG4gICAgICAgIHN2Z0F0dHIob3JpZ2luYWxHZngsIHsgZGlzcGxheTogJ2lubGluZScgfSk7XG4gICAgICB9XG5cbiAgICAgIGRyYWdnZXIucmVtb3ZlKCk7XG5cbiAgICAgIGlmICh2aXN1YWxSZXBsYWNlbWVudHNbaWRdKSB7XG4gICAgICAgIGRlbGV0ZSB2aXN1YWxSZXBsYWNlbWVudHNbaWRdO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUubW92ZScsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZTtcblxuICAgIGlmICghY29udGV4dC52aXN1YWxSZXBsYWNlbWVudHMpIHtcbiAgICAgIGNvbnRleHQudmlzdWFsUmVwbGFjZW1lbnRzID0ge307XG4gICAgfVxuXG4gICAgaWYgKGNhbkV4ZWN1dGUgJiYgY2FuRXhlY3V0ZS5yZXBsYWNlbWVudHMpIHtcbiAgICAgIHJlcGxhY2VWaXN1YWwoY29udGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3RvcmVWaXN1YWwoY29udGV4dCk7XG4gICAgfVxuICB9KTtcbn1cblxuQnBtblJlcGxhY2VQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdlbGVtZW50UmVnaXN0cnknLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnY2FudmFzJyxcbiAgJ3ByZXZpZXdTdXBwb3J0J1xuXTtcblxuaW5oZXJpdHMoQnBtblJlcGxhY2VQcmV2aWV3LCBDb21tYW5kSW50ZXJjZXB0b3IpOyIsImltcG9ydCBQcmV2aWV3U3VwcG9ydE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wcmV2aWV3LXN1cHBvcnQnO1xuXG5pbXBvcnQgQnBtblJlcGxhY2VQcmV2aWV3IGZyb20gJy4vQnBtblJlcGxhY2VQcmV2aWV3JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIFByZXZpZXdTdXBwb3J0TW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdicG1uUmVwbGFjZVByZXZpZXcnIF0sXG4gIGJwbW5SZXBsYWNlUHJldmlldzogWyAndHlwZScsIEJwbW5SZXBsYWNlUHJldmlldyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgcGljayxcbiAgYXNzaWduLFxuICBmaWx0ZXIsXG4gIGZvckVhY2gsXG4gIGlzQXJyYXksXG4gIGlzVW5kZWZpbmVkLFxuICBoYXNcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBpcyxcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0FueVxufSBmcm9tICcuLi9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzRXhwYW5kZWQsXG4gIGlzRXZlbnRTdWJQcm9jZXNzXG59IGZyb20gJy4uLy4uL3V0aWwvRGlVdGlsJztcblxuaW1wb3J0IHsgZ2V0UHJvcGVydHlOYW1lcyB9IGZyb20gJy4uL2NvcHktcGFzdGUvTW9kZGxlQ29weSc7XG5cbmZ1bmN0aW9uIGNvcHlQcm9wZXJ0aWVzKHNvdXJjZSwgdGFyZ2V0LCBwcm9wZXJ0aWVzKSB7XG4gIGlmICghaXNBcnJheShwcm9wZXJ0aWVzKSkge1xuICAgIHByb3BlcnRpZXMgPSBbIHByb3BlcnRpZXMgXTtcbiAgfVxuXG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24ocHJvcGVydHkpIHtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKHNvdXJjZVtwcm9wZXJ0eV0pKSB7XG4gICAgICB0YXJnZXRbcHJvcGVydHldID0gc291cmNlW3Byb3BlcnR5XTtcbiAgICB9XG4gIH0pO1xufVxuXG52YXIgQ1VTVE9NX1BST1BFUlRJRVMgPSBbXG4gICdjYW5jZWxBY3Rpdml0eScsXG4gICdpbnN0YW50aWF0ZScsXG4gICdldmVudEdhdGV3YXlUeXBlJyxcbiAgJ3RyaWdnZXJlZEJ5RXZlbnQnLFxuICAnaXNJbnRlcnJ1cHRpbmcnXG5dO1xuXG5cbmZ1bmN0aW9uIHRvZ2dlbGluZyhlbGVtZW50LCB0YXJnZXQpIHtcblxuICB2YXIgb2xkQ29sbGFwc2VkID0gKFxuICAgIGVsZW1lbnQgJiYgaGFzKGVsZW1lbnQsICdjb2xsYXBzZWQnKSA/IGVsZW1lbnQuY29sbGFwc2VkIDogIWlzRXhwYW5kZWQoZWxlbWVudClcbiAgKTtcblxuICB2YXIgdGFyZ2V0Q29sbGFwc2VkO1xuXG4gIGlmICh0YXJnZXQgJiYgKGhhcyh0YXJnZXQsICdjb2xsYXBzZWQnKSB8fCBoYXModGFyZ2V0LCAnaXNFeHBhbmRlZCcpKSkge1xuXG4gICAgLy8gcHJvcGVydHkgaXMgZXhwbGljaXRseSBzZXQgc28gdXNlIGl0XG4gICAgdGFyZ2V0Q29sbGFwc2VkID0gKFxuICAgICAgaGFzKHRhcmdldCwgJ2NvbGxhcHNlZCcpID8gdGFyZ2V0LmNvbGxhcHNlZCA6ICF0YXJnZXQuaXNFeHBhbmRlZFxuICAgICk7XG4gIH0gZWxzZSB7XG5cbiAgICAvLyBrZWVwIG9sZCBzdGF0ZVxuICAgIHRhcmdldENvbGxhcHNlZCA9IG9sZENvbGxhcHNlZDtcbiAgfVxuXG4gIGlmIChvbGRDb2xsYXBzZWQgIT09IHRhcmdldENvbGxhcHNlZCkge1xuICAgIGVsZW1lbnQuY29sbGFwc2VkID0gb2xkQ29sbGFwc2VkO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5cblxuLyoqXG4gKiBUaGlzIG1vZHVsZSB0YWtlcyBjYXJlIG9mIHJlcGxhY2luZyBCUE1OIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5SZXBsYWNlKFxuICAgIGJwbW5GYWN0b3J5LFxuICAgIGVsZW1lbnRGYWN0b3J5LFxuICAgIG1vZGRsZUNvcHksXG4gICAgbW9kZWxpbmcsXG4gICAgcmVwbGFjZSxcbiAgICBzZWxlY3Rpb25cbikge1xuXG4gIC8qKlxuICAgKiBQcmVwYXJlcyBhIG5ldyBidXNpbmVzcyBvYmplY3QgZm9yIHRoZSByZXBsYWNlbWVudCBlbGVtZW50XG4gICAqIGFuZCB0cmlnZ2VycyB0aGUgcmVwbGFjZSBvcGVyYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gICAqIEBwYXJhbSAge09iamVjdH0gdGFyZ2V0XG4gICAqIEBwYXJhbSAge09iamVjdH0gW2hpbnRzXVxuICAgKlxuICAgKiBAcmV0dXJuIHtkanMubW9kZWwuQmFzZX0gdGhlIG5ld2x5IGNyZWF0ZWQgZWxlbWVudFxuICAgKi9cbiAgZnVuY3Rpb24gcmVwbGFjZUVsZW1lbnQoZWxlbWVudCwgdGFyZ2V0LCBoaW50cykge1xuXG4gICAgaGludHMgPSBoaW50cyB8fCB7fTtcblxuICAgIHZhciB0eXBlID0gdGFyZ2V0LnR5cGUsXG4gICAgICAgIG9sZEJ1c2luZXNzT2JqZWN0ID0gZWxlbWVudC5idXNpbmVzc09iamVjdDtcblxuICAgIGlmIChpc1N1YlByb2Nlc3Mob2xkQnVzaW5lc3NPYmplY3QpKSB7XG4gICAgICBpZiAodHlwZSA9PT0gJ2JwbW46U3ViUHJvY2VzcycpIHtcbiAgICAgICAgaWYgKHRvZ2dlbGluZyhlbGVtZW50LCB0YXJnZXQpKSB7XG5cbiAgICAgICAgICAvLyBleHBhbmRpbmcgb3IgY29sbGFwc2luZyBwcm9jZXNzXG4gICAgICAgICAgbW9kZWxpbmcudG9nZ2xlQ29sbGFwc2UoZWxlbWVudCk7XG5cbiAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBuZXdCdXNpbmVzc09iamVjdCA9IGJwbW5GYWN0b3J5LmNyZWF0ZSh0eXBlKTtcblxuICAgIHZhciBuZXdFbGVtZW50ID0ge1xuICAgICAgdHlwZTogdHlwZSxcbiAgICAgIGJ1c2luZXNzT2JqZWN0OiBuZXdCdXNpbmVzc09iamVjdFxuICAgIH07XG5cbiAgICB2YXIgZWxlbWVudFByb3BzID0gZ2V0UHJvcGVydHlOYW1lcyhvbGRCdXNpbmVzc09iamVjdC4kZGVzY3JpcHRvciksXG4gICAgICAgIG5ld0VsZW1lbnRQcm9wcyA9IGdldFByb3BlcnR5TmFtZXMobmV3QnVzaW5lc3NPYmplY3QuJGRlc2NyaXB0b3IsIHRydWUpLFxuICAgICAgICBjb3B5UHJvcHMgPSBpbnRlcnNlY3Rpb24oZWxlbWVudFByb3BzLCBuZXdFbGVtZW50UHJvcHMpO1xuXG4gICAgLy8gaW5pdGlhbGl6ZSBzcGVjaWFsIHByb3BlcnRpZXMgZGVmaW5lZCBpbiB0YXJnZXQgZGVmaW5pdGlvblxuICAgIGFzc2lnbihuZXdCdXNpbmVzc09iamVjdCwgcGljayh0YXJnZXQsIENVU1RPTV9QUk9QRVJUSUVTKSk7XG5cbiAgICB2YXIgcHJvcGVydGllcyA9IGZpbHRlcihjb3B5UHJvcHMsIGZ1bmN0aW9uKHByb3BlcnR5TmFtZSkge1xuXG4gICAgICAvLyBjb3B5aW5nIGV2ZW50IGRlZmluaXRpb25zLCB1bmxlc3Mgd2UgcmVwbGFjZVxuICAgICAgaWYgKHByb3BlcnR5TmFtZSA9PT0gJ2V2ZW50RGVmaW5pdGlvbnMnKSB7XG4gICAgICAgIHJldHVybiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgdGFyZ2V0LmV2ZW50RGVmaW5pdGlvblR5cGUpO1xuICAgICAgfVxuXG4gICAgICAvLyByZXRhaW4gbG9vcCBjaGFyYWN0ZXJpc3RpY3MgaWYgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICAvLyBpcyBub3QgYW4gZXZlbnQgc3ViIHByb2Nlc3NcbiAgICAgIGlmIChwcm9wZXJ0eU5hbWUgPT09ICdsb29wQ2hhcmFjdGVyaXN0aWNzJykge1xuICAgICAgICByZXR1cm4gIWlzRXZlbnRTdWJQcm9jZXNzKG5ld0J1c2luZXNzT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgLy8gc28gdGhlIGFwcGxpZWQgcHJvcGVydGllcyBmcm9tICd0YXJnZXQnIGRvbid0IGdldCBsb3N0XG4gICAgICBpZiAobmV3QnVzaW5lc3NPYmplY3QuaGFzT3duUHJvcGVydHkocHJvcGVydHlOYW1lKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wZXJ0eU5hbWUgPT09ICdwcm9jZXNzUmVmJyAmJiB0YXJnZXQuaXNFeHBhbmRlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcGVydHlOYW1lID09PSAndHJpZ2dlcmVkQnlFdmVudCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcblxuICAgIG5ld0J1c2luZXNzT2JqZWN0ID0gbW9kZGxlQ29weS5jb3B5RWxlbWVudChcbiAgICAgIG9sZEJ1c2luZXNzT2JqZWN0LFxuICAgICAgbmV3QnVzaW5lc3NPYmplY3QsXG4gICAgICBwcm9wZXJ0aWVzXG4gICAgKTtcblxuICAgIC8vIGluaXRpYWxpemUgY3VzdG9tIEJQTU4gZXh0ZW5zaW9uc1xuICAgIGlmICh0YXJnZXQuZXZlbnREZWZpbml0aW9uVHlwZSkge1xuXG4gICAgICAvLyBvbmx5IGluaXRpYWxpemUgd2l0aCBuZXcgZXZlbnREZWZpbml0aW9uXG4gICAgICAvLyBpZiB3ZSBkaWQgbm90IHNldCBhbiBldmVudCBkZWZpbml0aW9uIHlldCxcbiAgICAgIC8vIGkuZS4gYmVjYXVzZSB3ZSBjb3BpZWQgaXRcbiAgICAgIGlmICghaGFzRXZlbnREZWZpbml0aW9uKG5ld0J1c2luZXNzT2JqZWN0LCB0YXJnZXQuZXZlbnREZWZpbml0aW9uVHlwZSkpIHtcbiAgICAgICAgbmV3RWxlbWVudC5ldmVudERlZmluaXRpb25UeXBlID0gdGFyZ2V0LmV2ZW50RGVmaW5pdGlvblR5cGU7XG4gICAgICAgIG5ld0VsZW1lbnQuZXZlbnREZWZpbml0aW9uQXR0cnMgPSB0YXJnZXQuZXZlbnREZWZpbml0aW9uQXR0cnM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzKG9sZEJ1c2luZXNzT2JqZWN0LCAnYnBtbjpBY3Rpdml0eScpKSB7XG5cbiAgICAgIGlmIChpc1N1YlByb2Nlc3Mob2xkQnVzaW5lc3NPYmplY3QpKSB7XG5cbiAgICAgICAgLy8gbm8gdG9nZ2VsaW5nLCBzbyBrZWVwIG9sZCBzdGF0ZVxuICAgICAgICBuZXdFbGVtZW50LmlzRXhwYW5kZWQgPSBpc0V4cGFuZGVkKG9sZEJ1c2luZXNzT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgLy8gZWxzZSBpZiBwcm9wZXJ0eSBpcyBleHBsaWNpdGx5IHNldCwgdXNlIGl0XG4gICAgICBlbHNlIGlmICh0YXJnZXQgJiYgaGFzKHRhcmdldCwgJ2lzRXhwYW5kZWQnKSkge1xuICAgICAgICBuZXdFbGVtZW50LmlzRXhwYW5kZWQgPSB0YXJnZXQuaXNFeHBhbmRlZDtcbiAgICAgIH1cblxuICAgICAgLy8gVE9ETzogbmVlZCBhbHNvIHRvIHJlc3BlY3QgbWluL21heCBTaXplXG4gICAgICAvLyBjb3B5IHNpemUsIGZyb20gYW4gZXhwYW5kZWQgc3VicHJvY2VzcyB0byBhbiBleHBhbmRlZCBhbHRlcm5hdGl2ZSBzdWJwcm9jZXNzXG4gICAgICAvLyBleGNlcHQgYnBtbjpUYXNrLCBiZWNhdXNlIFRhc2sgaXMgYWx3YXlzIGV4cGFuZGVkXG4gICAgICBpZiAoKGlzRXhwYW5kZWQob2xkQnVzaW5lc3NPYmplY3QpICYmICFpcyhvbGRCdXNpbmVzc09iamVjdCwgJ2JwbW46VGFzaycpKSAmJiBuZXdFbGVtZW50LmlzRXhwYW5kZWQpIHtcbiAgICAgICAgbmV3RWxlbWVudC53aWR0aCA9IGVsZW1lbnQud2lkdGg7XG4gICAgICAgIG5ld0VsZW1lbnQuaGVpZ2h0ID0gZWxlbWVudC5oZWlnaHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGNoaWxkcmVuIGlmIG5vdCBleHBhbmRpbmcgc3ViIHByb2Nlc3NcbiAgICBpZiAoaXNTdWJQcm9jZXNzKG9sZEJ1c2luZXNzT2JqZWN0KSAmJiAhaXNTdWJQcm9jZXNzKG5ld0J1c2luZXNzT2JqZWN0KSkge1xuICAgICAgaGludHMubW92ZUNoaWxkcmVuID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gdHJhbnNmb3JtIGNvbGxhcHNlZC9leHBhbmRlZCBwb29sc1xuICAgIGlmIChpcyhvbGRCdXNpbmVzc09iamVjdCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuXG4gICAgICAvLyBjcmVhdGUgZXhwYW5kZWQgcG9vbFxuICAgICAgaWYgKHRhcmdldC5pc0V4cGFuZGVkID09PSB0cnVlKSB7XG4gICAgICAgIG5ld0J1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWYgPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46UHJvY2VzcycpO1xuICAgICAgfSBlbHNlIHtcblxuICAgICAgICAvLyByZW1vdmUgY2hpbGRyZW4gd2hlbiB0cmFuc2Zvcm1pbmcgdG8gY29sbGFwc2VkIHBvb2xcbiAgICAgICAgaGludHMubW92ZUNoaWxkcmVuID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIC8vIGFwcGx5IHNhbWUgd2lkdGggYW5kIGRlZmF1bHQgaGVpZ2h0XG4gICAgICBuZXdFbGVtZW50LndpZHRoID0gZWxlbWVudC53aWR0aDtcbiAgICAgIG5ld0VsZW1lbnQuaGVpZ2h0ID0gZWxlbWVudEZhY3RvcnkuX2dldERlZmF1bHRTaXplKG5ld0J1c2luZXNzT2JqZWN0KS5oZWlnaHQ7XG4gICAgfVxuXG4gICAgbmV3QnVzaW5lc3NPYmplY3QubmFtZSA9IG9sZEJ1c2luZXNzT2JqZWN0Lm5hbWU7XG5cbiAgICAvLyByZXRhaW4gZGVmYXVsdCBmbG93J3MgcmVmZXJlbmNlIGJldHdlZW4gaW5jbHVzaXZlIDwtPiBleGNsdXNpdmUgZ2F0ZXdheXMgYW5kIGFjdGl2aXRpZXNcbiAgICBpZiAoXG4gICAgICBpc0FueShvbGRCdXNpbmVzc09iamVjdCwgW1xuICAgICAgICAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JyxcbiAgICAgICAgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheScsXG4gICAgICAgICdicG1uOkFjdGl2aXR5J1xuICAgICAgXSkgJiZcbiAgICAgIGlzQW55KG5ld0J1c2luZXNzT2JqZWN0LCBbXG4gICAgICAgICdicG1uOkV4Y2x1c2l2ZUdhdGV3YXknLFxuICAgICAgICAnYnBtbjpJbmNsdXNpdmVHYXRld2F5JyxcbiAgICAgICAgJ2JwbW46QWN0aXZpdHknXG4gICAgICBdKVxuICAgICkge1xuICAgICAgbmV3QnVzaW5lc3NPYmplY3QuZGVmYXVsdCA9IG9sZEJ1c2luZXNzT2JqZWN0LmRlZmF1bHQ7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGFyZ2V0Lmhvc3QgJiZcbiAgICAgICFpcyhvbGRCdXNpbmVzc09iamVjdCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmXG4gICAgICBpcyhuZXdCdXNpbmVzc09iamVjdCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpXG4gICAgKSB7XG4gICAgICBuZXdFbGVtZW50Lmhvc3QgPSB0YXJnZXQuaG9zdDtcbiAgICB9XG5cbiAgICBuZXdFbGVtZW50LmRpID0ge307XG5cbiAgICAvLyBmaWxsIGFuZCBzdHJva2Ugd2lsbCBiZSBzZXQgdG8gRElcbiAgICBjb3B5UHJvcGVydGllcyhvbGRCdXNpbmVzc09iamVjdC5kaSwgbmV3RWxlbWVudC5kaSwgW1xuICAgICAgJ2ZpbGwnLFxuICAgICAgJ3N0cm9rZSdcbiAgICBdKTtcblxuICAgIG5ld0VsZW1lbnQgPSByZXBsYWNlLnJlcGxhY2VFbGVtZW50KGVsZW1lbnQsIG5ld0VsZW1lbnQsIGhpbnRzKTtcblxuICAgIGlmIChoaW50cy5zZWxlY3QgIT09IGZhbHNlKSB7XG4gICAgICBzZWxlY3Rpb24uc2VsZWN0KG5ld0VsZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXdFbGVtZW50O1xuICB9XG5cbiAgdGhpcy5yZXBsYWNlRWxlbWVudCA9IHJlcGxhY2VFbGVtZW50O1xufVxuXG5CcG1uUmVwbGFjZS4kaW5qZWN0ID0gW1xuICAnYnBtbkZhY3RvcnknLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnbW9kZGxlQ29weScsXG4gICdtb2RlbGluZycsXG4gICdyZXBsYWNlJyxcbiAgJ3NlbGVjdGlvbidcbl07XG5cblxuZnVuY3Rpb24gaXNTdWJQcm9jZXNzKGJvKSB7XG4gIHJldHVybiBpcyhibywgJ2JwbW46U3ViUHJvY2VzcycpO1xufVxuXG5mdW5jdGlvbiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgdHlwZSkge1xuXG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xuXG4gIHJldHVybiB0eXBlICYmIGJvLmdldCgnZXZlbnREZWZpbml0aW9ucycpLnNvbWUoZnVuY3Rpb24oZGVmaW5pdGlvbikge1xuICAgIHJldHVybiBpcyhkZWZpbml0aW9uLCB0eXBlKTtcbiAgfSk7XG59XG5cbi8qKlxuICogQ29tcHV0ZSBpbnRlcnNlY3Rpb24gYmV0d2VlbiB0d28gYXJyYXlzLlxuICovXG5mdW5jdGlvbiBpbnRlcnNlY3Rpb24oYTEsIGEyKSB7XG4gIHJldHVybiBhMS5maWx0ZXIoZnVuY3Rpb24oZWwpIHtcbiAgICByZXR1cm4gYTIuaW5kZXhPZihlbCkgIT09IC0xO1xuICB9KTtcbn1cbiIsImV4cG9ydCB2YXIgU1RBUlRfRVZFTlQgPSBbXG4gIHtcbiAgICBsYWJlbDogJ1N0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbmUtc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1ub25lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdJbnRlcm1lZGlhdGUgVGhyb3cgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uZS1pbnRlcm1lZGlhdGUtdGhyb3dpbmcnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtbm9uZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnRW5kIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbmUtZW5kJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZW5kLWV2ZW50LW5vbmUnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46RW5kRXZlbnQnXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdNZXNzYWdlIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW1lc3NhZ2Utc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1tZXNzYWdlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1RpbWVyIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXRpbWVyLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtdGltZXInLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpUaW1lckV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0NvbmRpdGlvbmFsIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbmRpdGlvbmFsLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtY29uZGl0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTaWduYWwgU3RhcnQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtc2lnbmFsLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtc2lnbmFsJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfVxuXTtcblxuZXhwb3J0IHZhciBTVEFSVF9FVkVOVF9TVUJfUFJPQ0VTUyA9IFtcbiAge1xuICAgIGxhYmVsOiAnU3RhcnQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uZS1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LW5vbmUnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0ludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLWludGVybWVkaWF0ZS10aHJvd2luZycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1ub25lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFbmQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uZS1lbmQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1lbmQtZXZlbnQtbm9uZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCdcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgSU5URVJNRURJQVRFX0VWRU5UID0gW1xuICB7XG4gICAgbGFiZWw6ICdTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtbm9uZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbmUtaW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LW5vbmUnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0VuZCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLWVuZCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWVuZC1ldmVudC1ub25lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkVuZEV2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnTWVzc2FnZSBJbnRlcm1lZGlhdGUgQ2F0Y2ggRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbWVzc2FnZS1pbnRlcm1lZGlhdGUtY2F0Y2gnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbWVzc2FnZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdNZXNzYWdlIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1tZXNzYWdlLWludGVybWVkaWF0ZS10aHJvdycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC10aHJvdy1tZXNzYWdlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1RpbWVyIEludGVybWVkaWF0ZSBDYXRjaCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC10aW1lci1pbnRlcm1lZGlhdGUtY2F0Y2gnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtdGltZXInLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpUaW1lckV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0VzY2FsYXRpb24gSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVzY2FsYXRpb24taW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LWVzY2FsYXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29uZGl0aW9uYWwgSW50ZXJtZWRpYXRlIENhdGNoIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbmRpdGlvbmFsLWludGVybWVkaWF0ZS1jYXRjaCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb25kaXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0xpbmsgSW50ZXJtZWRpYXRlIENhdGNoIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWxpbmstaW50ZXJtZWRpYXRlLWNhdGNoJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWxpbmsnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpMaW5rRXZlbnREZWZpbml0aW9uJyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvbkF0dHJzOiB7XG4gICAgICAgIG5hbWU6ICcnXG4gICAgICB9XG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdMaW5rIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1saW5rLWludGVybWVkaWF0ZS10aHJvdycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC10aHJvdy1saW5rJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicsXG4gICAgICBldmVudERlZmluaXRpb25BdHRyczoge1xuICAgICAgICBuYW1lOiAnJ1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29tcGVuc2F0aW9uIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb21wZW5zYXRpb24taW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LWNvbXBlbnNhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTaWduYWwgSW50ZXJtZWRpYXRlIENhdGNoIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNpZ25hbC1pbnRlcm1lZGlhdGUtY2F0Y2gnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtc2lnbmFsJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU2lnbmFsIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1zaWduYWwtaW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LXNpZ25hbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgRU5EX0VWRU5UID0gW1xuICB7XG4gICAgbGFiZWw6ICdTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtbm9uZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbmUtaW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LW5vbmUnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0VuZCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLWVuZCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWVuZC1ldmVudC1ub25lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkVuZEV2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnTWVzc2FnZSBFbmQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbWVzc2FnZS1lbmQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1lbmQtZXZlbnQtbWVzc2FnZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpNZXNzYWdlRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnRXNjYWxhdGlvbiBFbmQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZXNjYWxhdGlvbi1lbmQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1lbmQtZXZlbnQtZXNjYWxhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnRXJyb3IgRW5kIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVycm9yLWVuZCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWVuZC1ldmVudC1lcnJvcicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFcnJvckV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0NhbmNlbCBFbmQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtY2FuY2VsLWVuZCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWVuZC1ldmVudC1jYW5jZWwnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46RW5kRXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46Q2FuY2VsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29tcGVuc2F0aW9uIEVuZCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb21wZW5zYXRpb24tZW5kJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZW5kLWV2ZW50LWNvbXBlbnNhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU2lnbmFsIEVuZCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1zaWduYWwtZW5kJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZW5kLWV2ZW50LXNpZ25hbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdUZXJtaW5hdGUgRW5kIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXRlcm1pbmF0ZS1lbmQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1lbmQtZXZlbnQtdGVybWluYXRlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkVuZEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlRlcm1pbmF0ZUV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgR0FURVdBWSA9IFtcbiAge1xuICAgIGxhYmVsOiAnRXhjbHVzaXZlIEdhdGV3YXknLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZXhjbHVzaXZlLWdhdGV3YXknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1nYXRld2F5LXhvcicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFeGNsdXNpdmVHYXRld2F5J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnUGFyYWxsZWwgR2F0ZXdheScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1wYXJhbGxlbC1nYXRld2F5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZ2F0ZXdheS1wYXJhbGxlbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpQYXJhbGxlbEdhdGV3YXknXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdJbmNsdXNpdmUgR2F0ZXdheScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1pbmNsdXNpdmUtZ2F0ZXdheScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWdhdGV3YXktb3InLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW5jbHVzaXZlR2F0ZXdheSdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0NvbXBsZXggR2F0ZXdheScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb21wbGV4LWdhdGV3YXknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1nYXRld2F5LWNvbXBsZXgnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46Q29tcGxleEdhdGV3YXknXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFdmVudCBiYXNlZCBHYXRld2F5JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWV2ZW50LWJhc2VkLWdhdGV3YXknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1nYXRld2F5LWV2ZW50YmFzZWQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46RXZlbnRCYXNlZEdhdGV3YXknLFxuICAgICAgaW5zdGFudGlhdGU6IGZhbHNlLFxuICAgICAgZXZlbnRHYXRld2F5VHlwZTogJ0V4Y2x1c2l2ZSdcbiAgICB9XG4gIH1cblxuICAvLyBHYXRld2F5cyBkZWFjdGl2YXRlZCB1bnRpbCBodHRwczovL2dpdGh1Yi5jb20vYnBtbi1pby9icG1uLWpzL2lzc3Vlcy8xOTRcbiAgLy8ge1xuICAvLyAgIGxhYmVsOiAnRXZlbnQgYmFzZWQgaW5zdGFudGlhdGluZyBHYXRld2F5JyxcbiAgLy8gICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWV4Y2x1c2l2ZS1ldmVudC1iYXNlZC1nYXRld2F5JyxcbiAgLy8gICBjbGFzc05hbWU6ICdicG1uLWljb24tZXhjbHVzaXZlLWV2ZW50LWJhc2VkJyxcbiAgLy8gICB0YXJnZXQ6IHtcbiAgLy8gICAgIHR5cGU6ICdicG1uOkV2ZW50QmFzZWRHYXRld2F5J1xuICAvLyAgIH0sXG4gIC8vICAgb3B0aW9uczoge1xuICAvLyAgICAgYnVzaW5lc3NPYmplY3Q6IHsgaW5zdGFudGlhdGU6IHRydWUsIGV2ZW50R2F0ZXdheVR5cGU6ICdFeGNsdXNpdmUnIH1cbiAgLy8gICB9XG4gIC8vIH0sXG4gIC8vIHtcbiAgLy8gICBsYWJlbDogJ1BhcmFsbGVsIEV2ZW50IGJhc2VkIGluc3RhbnRpYXRpbmcgR2F0ZXdheScsXG4gIC8vICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1wYXJhbGxlbC1ldmVudC1iYXNlZC1pbnN0YW50aWF0ZS1nYXRld2F5JyxcbiAgLy8gICBjbGFzc05hbWU6ICdicG1uLWljb24tcGFyYWxsZWwtZXZlbnQtYmFzZWQtaW5zdGFudGlhdGUtZ2F0ZXdheScsXG4gIC8vICAgdGFyZ2V0OiB7XG4gIC8vICAgICB0eXBlOiAnYnBtbjpFdmVudEJhc2VkR2F0ZXdheSdcbiAgLy8gICB9LFxuICAvLyAgIG9wdGlvbnM6IHtcbiAgLy8gICAgIGJ1c2luZXNzT2JqZWN0OiB7IGluc3RhbnRpYXRlOiB0cnVlLCBldmVudEdhdGV3YXlUeXBlOiAnUGFyYWxsZWwnIH1cbiAgLy8gICB9XG4gIC8vIH1cbl07XG5cbmV4cG9ydCB2YXIgU1VCUFJPQ0VTU19FWFBBTkRFRCA9IFtcbiAge1xuICAgIGxhYmVsOiAnVHJhbnNhY3Rpb24nLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtdHJhbnNhY3Rpb24nLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi10cmFuc2FjdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpUcmFuc2FjdGlvbicsXG4gICAgICBpc0V4cGFuZGVkOiB0cnVlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFdmVudCBTdWIgUHJvY2VzcycsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ldmVudC1zdWJwcm9jZXNzJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZXZlbnQtc3VicHJvY2Vzcy1leHBhbmRlZCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdWJQcm9jZXNzJyxcbiAgICAgIHRyaWdnZXJlZEJ5RXZlbnQ6IHRydWUsXG4gICAgICBpc0V4cGFuZGVkOiB0cnVlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTdWIgUHJvY2VzcyAoY29sbGFwc2VkKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb2xsYXBzZWQtc3VicHJvY2VzcycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN1YnByb2Nlc3MtY29sbGFwc2VkJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN1YlByb2Nlc3MnLFxuICAgICAgaXNFeHBhbmRlZDogZmFsc2VcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgVFJBTlNBQ1RJT04gPSBbXG4gIHtcbiAgICBsYWJlbDogJ1N1YiBQcm9jZXNzJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXN1YnByb2Nlc3MnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdWJwcm9jZXNzLWV4cGFuZGVkJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN1YlByb2Nlc3MnLFxuICAgICAgaXNFeHBhbmRlZDogdHJ1ZVxuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnRXZlbnQgU3ViIFByb2Nlc3MnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZXZlbnQtc3VicHJvY2VzcycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWV2ZW50LXN1YnByb2Nlc3MtZXhwYW5kZWQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3ViUHJvY2VzcycsXG4gICAgICB0cmlnZ2VyZWRCeUV2ZW50OiB0cnVlLFxuICAgICAgaXNFeHBhbmRlZDogdHJ1ZVxuICAgIH1cbiAgfVxuXTtcblxuZXhwb3J0IHZhciBFVkVOVF9TVUJfUFJPQ0VTUyA9IFtcbiAge1xuICAgIGxhYmVsOiAnU3ViIFByb2Nlc3MnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtc3VicHJvY2VzcycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN1YnByb2Nlc3MtZXhwYW5kZWQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3ViUHJvY2VzcycsXG4gICAgICBpc0V4cGFuZGVkOiB0cnVlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdUcmFuc2FjdGlvbicsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC10cmFuc2FjdGlvbicsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXRyYW5zYWN0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlRyYW5zYWN0aW9uJyxcbiAgICAgIGlzRXhwYW5kZWQ6IHRydWVcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgVEFTSyA9IFtcbiAge1xuICAgIGxhYmVsOiAnVGFzaycsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC10YXNrJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tdGFzaycsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpUYXNrJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU2VuZCBUYXNrJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNlbmQtdGFzaycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXNlbmQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U2VuZFRhc2snXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdSZWNlaXZlIFRhc2snLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtcmVjZWl2ZS10YXNrJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tcmVjZWl2ZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpSZWNlaXZlVGFzaydcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1VzZXIgVGFzaycsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC11c2VyLXRhc2snLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi11c2VyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlVzZXJUYXNrJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnTWFudWFsIFRhc2snLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbWFudWFsLXRhc2snLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1tYW51YWwnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46TWFudWFsVGFzaydcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0J1c2luZXNzIFJ1bGUgVGFzaycsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ydWxlLXRhc2snLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1idXNpbmVzcy1ydWxlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJ1c2luZXNzUnVsZVRhc2snXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTZXJ2aWNlIFRhc2snLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtc2VydmljZS10YXNrJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc2VydmljZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTZXJ2aWNlVGFzaydcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1NjcmlwdCBUYXNrJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNjcmlwdC10YXNrJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc2NyaXB0JyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlNjcmlwdFRhc2snXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDYWxsIEFjdGl2aXR5JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNhbGwtYWN0aXZpdHknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jYWxsLWFjdGl2aXR5JyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkNhbGxBY3Rpdml0eSdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1N1YiBQcm9jZXNzIChjb2xsYXBzZWQpJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbGxhcHNlZC1zdWJwcm9jZXNzJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3VicHJvY2Vzcy1jb2xsYXBzZWQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3ViUHJvY2VzcycsXG4gICAgICBpc0V4cGFuZGVkOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU3ViIFByb2Nlc3MgKGV4cGFuZGVkKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1leHBhbmRlZC1zdWJwcm9jZXNzJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3VicHJvY2Vzcy1leHBhbmRlZCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdWJQcm9jZXNzJyxcbiAgICAgIGlzRXhwYW5kZWQ6IHRydWVcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgQk9VTkRBUllfRVZFTlQgPSBbXG4gIHtcbiAgICBsYWJlbDogJ01lc3NhZ2UgQm91bmRhcnkgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbWVzc2FnZS1ib3VuZGFyeScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1tZXNzYWdlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1RpbWVyIEJvdW5kYXJ5IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXRpbWVyLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLXRpbWVyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFc2NhbGF0aW9uIEJvdW5kYXJ5IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVzY2FsYXRpb24tYm91bmRhcnknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtZXNjYWxhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkVzY2FsYXRpb25FdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb25kaXRpb25hbCBCb3VuZGFyeSBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb25kaXRpb25hbC1ib3VuZGFyeScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb25kaXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46Qm91bmRhcnlFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0Vycm9yIEJvdW5kYXJ5IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVycm9yLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWVycm9yJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46RXJyb3JFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDYW5jZWwgQm91bmRhcnkgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtY2FuY2VsLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWNhbmNlbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNhbmNlbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1NpZ25hbCBCb3VuZGFyeSBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1zaWduYWwtYm91bmRhcnknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtc2lnbmFsJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29tcGVuc2F0aW9uIEJvdW5kYXJ5IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbXBlbnNhdGlvbi1ib3VuZGFyeScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb21wZW5zYXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46Qm91bmRhcnlFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnTWVzc2FnZSBCb3VuZGFyeSBFdmVudCAobm9uLWludGVycnVwdGluZyknLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uLWludGVycnVwdGluZy1tZXNzYWdlLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW5vbi1pbnRlcnJ1cHRpbmctbWVzc2FnZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nLFxuICAgICAgY2FuY2VsQWN0aXZpdHk6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdUaW1lciBCb3VuZGFyeSBFdmVudCAobm9uLWludGVycnVwdGluZyknLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uLWludGVycnVwdGluZy10aW1lci1ib3VuZGFyeScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1ub24taW50ZXJydXB0aW5nLXRpbWVyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nLFxuICAgICAgY2FuY2VsQWN0aXZpdHk6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFc2NhbGF0aW9uIEJvdW5kYXJ5IEV2ZW50IChub24taW50ZXJydXB0aW5nKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub24taW50ZXJydXB0aW5nLWVzY2FsYXRpb24tYm91bmRhcnknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbm9uLWludGVycnVwdGluZy1lc2NhbGF0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicsXG4gICAgICBjYW5jZWxBY3Rpdml0eTogZmFsc2VcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0NvbmRpdGlvbmFsIEJvdW5kYXJ5IEV2ZW50IChub24taW50ZXJydXB0aW5nKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub24taW50ZXJydXB0aW5nLWNvbmRpdGlvbmFsLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW5vbi1pbnRlcnJ1cHRpbmctY29uZGl0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nLFxuICAgICAgY2FuY2VsQWN0aXZpdHk6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTaWduYWwgQm91bmRhcnkgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbi1pbnRlcnJ1cHRpbmctc2lnbmFsLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW5vbi1pbnRlcnJ1cHRpbmctc2lnbmFsJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJyxcbiAgICAgIGNhbmNlbEFjdGl2aXR5OiBmYWxzZVxuICAgIH1cbiAgfVxuXTtcblxuZXhwb3J0IHZhciBFVkVOVF9TVUJfUFJPQ0VTU19TVEFSVF9FVkVOVCA9IFtcbiAge1xuICAgIGxhYmVsOiAnTWVzc2FnZSBTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1tZXNzYWdlLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtbWVzc2FnZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdUaW1lciBTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC10aW1lci1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LXRpbWVyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb25kaXRpb25hbCBTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb25kaXRpb25hbC1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LWNvbmRpdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU2lnbmFsIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNpZ25hbC1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LXNpZ25hbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0Vycm9yIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVycm9yLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtZXJyb3InLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFcnJvckV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0VzY2FsYXRpb24gU3RhcnQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZXNjYWxhdGlvbi1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LWVzY2FsYXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29tcGVuc2F0aW9uIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbXBlbnNhdGlvbi1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LWNvbXBlbnNhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdNZXNzYWdlIFN0YXJ0IEV2ZW50IChub24taW50ZXJydXB0aW5nKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub24taW50ZXJydXB0aW5nLW1lc3NhZ2Utc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1ub24taW50ZXJydXB0aW5nLW1lc3NhZ2UnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpNZXNzYWdlRXZlbnREZWZpbml0aW9uJyxcbiAgICAgIGlzSW50ZXJydXB0aW5nOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnVGltZXIgU3RhcnQgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbi1pbnRlcnJ1cHRpbmctdGltZXItc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1ub24taW50ZXJydXB0aW5nLXRpbWVyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nLFxuICAgICAgaXNJbnRlcnJ1cHRpbmc6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb25kaXRpb25hbCBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uLWludGVycnVwdGluZy1jb25kaXRpb25hbC1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LW5vbi1pbnRlcnJ1cHRpbmctY29uZGl0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nLFxuICAgICAgaXNJbnRlcnJ1cHRpbmc6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTaWduYWwgU3RhcnQgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbi1pbnRlcnJ1cHRpbmctc2lnbmFsLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtbm9uLWludGVycnVwdGluZy1zaWduYWwnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nLFxuICAgICAgaXNJbnRlcnJ1cHRpbmc6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFc2NhbGF0aW9uIFN0YXJ0IEV2ZW50IChub24taW50ZXJydXB0aW5nKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub24taW50ZXJydXB0aW5nLWVzY2FsYXRpb24tc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1ub24taW50ZXJydXB0aW5nLWVzY2FsYXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJyxcbiAgICAgIGlzSW50ZXJydXB0aW5nOiBmYWxzZVxuICAgIH1cbiAgfVxuXTtcblxuZXhwb3J0IHZhciBTRVFVRU5DRV9GTE9XID0gW1xuICB7XG4gICAgbGFiZWw6ICdTZXF1ZW5jZSBGbG93JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNlcXVlbmNlLWZsb3cnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jb25uZWN0aW9uJ1xuICB9LFxuICB7XG4gICAgbGFiZWw6ICdEZWZhdWx0IEZsb3cnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZGVmYXVsdC1mbG93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZGVmYXVsdC1mbG93J1xuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb25kaXRpb25hbCBGbG93JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbmRpdGlvbmFsLWZsb3cnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jb25kaXRpb25hbC1mbG93J1xuICB9XG5dO1xuXG5leHBvcnQgdmFyIFBBUlRJQ0lQQU5UID0gW1xuICB7XG4gICAgbGFiZWw6ICdFeHBhbmRlZCBQb29sJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWV4cGFuZGVkLXBvb2wnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1wYXJ0aWNpcGFudCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpQYXJ0aWNpcGFudCcsXG4gICAgICBpc0V4cGFuZGVkOiB0cnVlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb2xsYXBzZWQgUG9vbCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb2xsYXBzZWQtcG9vbCcsXG5cbiAgICAvLyBUT0RPKEBqYW5zdHVlbW1lbCk6IG1heWJlIGRlc2lnbiBuZXcgaWNvblxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sYW5lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAgIGlzRXhwYW5kZWQ6IGZhbHNlXG4gICAgfVxuICB9XG5dO1xuIiwiaW1wb3J0IENvcHlQYXN0ZU1vZHVsZSBmcm9tICcuLi9jb3B5LXBhc3RlJztcbmltcG9ydCBSZXBsYWNlTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3JlcGxhY2UnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zZWxlY3Rpb24nO1xuXG5pbXBvcnQgQnBtblJlcGxhY2UgZnJvbSAnLi9CcG1uUmVwbGFjZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBDb3B5UGFzdGVNb2R1bGUsXG4gICAgUmVwbGFjZU1vZHVsZSxcbiAgICBTZWxlY3Rpb25Nb2R1bGVcbiAgXSxcbiAgYnBtblJlcGxhY2U6IFsgJ3R5cGUnLCBCcG1uUmVwbGFjZSBdXG59O1xuIiwiaW1wb3J0IHtcbiAgZXZlcnksXG4gIGZpbmQsXG4gIGZvckVhY2gsXG4gIHNvbWVcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQge1xuICBpcyxcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRQYXJlbnQsXG4gIGlzQW55XG59IGZyb20gJy4uL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJztcblxuaW1wb3J0IHtcbiAgaXNMYWJlbFxufSBmcm9tICcuLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzRXhwYW5kZWQsXG4gIGlzRXZlbnRTdWJQcm9jZXNzLFxuICBpc0ludGVycnVwdGluZyxcbiAgaGFzRXJyb3JFdmVudERlZmluaXRpb24sXG4gIGhhc0VzY2FsYXRpb25FdmVudERlZmluaXRpb24sXG4gIGhhc0NvbXBlbnNhdGVFdmVudERlZmluaXRpb25cbn0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQgUnVsZVByb3ZpZGVyIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3J1bGVzL1J1bGVQcm92aWRlcic7XG5cbmltcG9ydCB7XG4gIGdldEJvdW5kYXJ5QXR0YWNobWVudCBhcyBpc0JvdW5kYXJ5QXR0YWNobWVudFxufSBmcm9tICcuLi9zbmFwcGluZy9CcG1uU25hcHBpbmdVdGlsJztcblxuXG4vKipcbiAqIEJQTU4gc3BlY2lmaWMgbW9kZWxpbmcgcnVsZVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uUnVsZXMoZXZlbnRCdXMpIHtcbiAgUnVsZVByb3ZpZGVyLmNhbGwodGhpcywgZXZlbnRCdXMpO1xufVxuXG5pbmhlcml0cyhCcG1uUnVsZXMsIFJ1bGVQcm92aWRlcik7XG5cbkJwbW5SdWxlcy4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge1xuXG4gIHRoaXMuYWRkUnVsZSgnY29ubmVjdGlvbi5zdGFydCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgc291cmNlID0gY29udGV4dC5zb3VyY2U7XG5cbiAgICByZXR1cm4gY2FuU3RhcnRDb25uZWN0aW9uKHNvdXJjZSk7XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnY29ubmVjdGlvbi5jcmVhdGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICB0YXJnZXRQYXJlbnQgPSBoaW50cy50YXJnZXRQYXJlbnQsXG4gICAgICAgIHRhcmdldEF0dGFjaCA9IGhpbnRzLnRhcmdldEF0dGFjaDtcblxuICAgIC8vIGRvbid0IGFsbG93IGluY29taW5nIGNvbm5lY3Rpb25zIG9uXG4gICAgLy8gbmV3bHkgY3JlYXRlZCBib3VuZGFyeSBldmVudHNcbiAgICAvLyB0byBib3VuZGFyeSBldmVudHNcbiAgICBpZiAodGFyZ2V0QXR0YWNoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gdGVtcG9yYXJpbHkgc2V0IHRhcmdldCBwYXJlbnQgZm9yIHNjb3BpbmdcbiAgICAvLyBjaGVja3MgdG8gd29ya1xuICAgIGlmICh0YXJnZXRQYXJlbnQpIHtcbiAgICAgIHRhcmdldC5wYXJlbnQgPSB0YXJnZXRQYXJlbnQ7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBjYW5Db25uZWN0KHNvdXJjZSwgdGFyZ2V0KTtcbiAgICB9IGZpbmFsbHkge1xuXG4gICAgICAvLyB1bnNldCB0ZW1wb3JhcnkgdGFyZ2V0IHBhcmVudFxuICAgICAgaWYgKHRhcmdldFBhcmVudCkge1xuICAgICAgICB0YXJnZXQucGFyZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0O1xuXG4gICAgcmV0dXJuIGNhbkNvbm5lY3Qoc291cmNlLCB0YXJnZXQsIGNvbm5lY3Rpb24pO1xuICB9KTtcblxuICB0aGlzLmFkZFJ1bGUoJ2Nvbm5lY3Rpb24udXBkYXRlV2F5cG9pbnRzJywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBjb250ZXh0LmNvbm5lY3Rpb24udHlwZVxuICAgIH07XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnc2hhcGUucmVzaXplJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgbmV3Qm91bmRzID0gY29udGV4dC5uZXdCb3VuZHM7XG5cbiAgICByZXR1cm4gY2FuUmVzaXplKHNoYXBlLCBuZXdCb3VuZHMpO1xuICB9KTtcblxuICB0aGlzLmFkZFJ1bGUoJ2VsZW1lbnRzLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzLFxuICAgICAgICBwb3NpdGlvbiA9IGNvbnRleHQucG9zaXRpb24sXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0O1xuXG4gICAgcmV0dXJuIGV2ZXJ5KGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICBpZiAoaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybiBjYW5Db25uZWN0KGVsZW1lbnQuc291cmNlLCBlbGVtZW50LnRhcmdldCwgZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbGVtZW50Lmhvc3QpIHtcbiAgICAgICAgcmV0dXJuIGNhbkF0dGFjaChlbGVtZW50LCBlbGVtZW50Lmhvc3QsIG51bGwsIHBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNhbkNyZWF0ZShlbGVtZW50LCB0YXJnZXQsIG51bGwsIHBvc2l0aW9uKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgdGhpcy5hZGRSdWxlKCdlbGVtZW50cy5tb3ZlJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgcG9zaXRpb24gPSBjb250ZXh0LnBvc2l0aW9uO1xuXG4gICAgcmV0dXJuIGNhbkF0dGFjaChzaGFwZXMsIHRhcmdldCwgbnVsbCwgcG9zaXRpb24pIHx8XG4gICAgICAgICAgIGNhblJlcGxhY2Uoc2hhcGVzLCB0YXJnZXQsIHBvc2l0aW9uKSB8fFxuICAgICAgICAgICBjYW5Nb3ZlKHNoYXBlcywgdGFyZ2V0LCBwb3NpdGlvbikgfHxcbiAgICAgICAgICAgY2FuSW5zZXJ0KHNoYXBlcywgdGFyZ2V0LCBwb3NpdGlvbik7XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnc2hhcGUuY3JlYXRlJywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHJldHVybiBjYW5DcmVhdGUoXG4gICAgICBjb250ZXh0LnNoYXBlLFxuICAgICAgY29udGV4dC50YXJnZXQsXG4gICAgICBjb250ZXh0LnNvdXJjZSxcbiAgICAgIGNvbnRleHQucG9zaXRpb25cbiAgICApO1xuICB9KTtcblxuICB0aGlzLmFkZFJ1bGUoJ3NoYXBlLmF0dGFjaCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHJldHVybiBjYW5BdHRhY2goXG4gICAgICBjb250ZXh0LnNoYXBlLFxuICAgICAgY29udGV4dC50YXJnZXQsXG4gICAgICBudWxsLFxuICAgICAgY29udGV4dC5wb3NpdGlvblxuICAgICk7XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnZWxlbWVudC5jb3B5JywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHM7XG5cbiAgICByZXR1cm4gY2FuQ29weShlbGVtZW50cywgZWxlbWVudCk7XG4gIH0pO1xufTtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5Db25uZWN0TWVzc2FnZUZsb3cgPSBjYW5Db25uZWN0TWVzc2FnZUZsb3c7XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuY2FuQ29ubmVjdFNlcXVlbmNlRmxvdyA9IGNhbkNvbm5lY3RTZXF1ZW5jZUZsb3c7XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuY2FuQ29ubmVjdERhdGFBc3NvY2lhdGlvbiA9IGNhbkNvbm5lY3REYXRhQXNzb2NpYXRpb247XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuY2FuQ29ubmVjdEFzc29jaWF0aW9uID0gY2FuQ29ubmVjdEFzc29jaWF0aW9uO1xuXG5CcG1uUnVsZXMucHJvdG90eXBlLmNhbk1vdmUgPSBjYW5Nb3ZlO1xuXG5CcG1uUnVsZXMucHJvdG90eXBlLmNhbkF0dGFjaCA9IGNhbkF0dGFjaDtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5SZXBsYWNlID0gY2FuUmVwbGFjZTtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5Ecm9wID0gY2FuRHJvcDtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5JbnNlcnQgPSBjYW5JbnNlcnQ7XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuY2FuQ3JlYXRlID0gY2FuQ3JlYXRlO1xuXG5CcG1uUnVsZXMucHJvdG90eXBlLmNhbkNvbm5lY3QgPSBjYW5Db25uZWN0O1xuXG5CcG1uUnVsZXMucHJvdG90eXBlLmNhblJlc2l6ZSA9IGNhblJlc2l6ZTtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5Db3B5ID0gY2FuQ29weTtcblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9ucyBmb3IgcnVsZSBjaGVja2luZ1xuICovXG5cbi8qKlxuICogQ2hlY2tzIGlmIGdpdmVuIGVsZW1lbnQgY2FuIGJlIHVzZWQgZm9yIHN0YXJ0aW5nIGNvbm5lY3Rpb24uXG4gKlxuICogQHBhcmFtICB7RWxlbWVudH0gc291cmNlXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBjYW5TdGFydENvbm5lY3Rpb24oZWxlbWVudCkge1xuICBpZiAobm9uRXhpc3RpbmdPckxhYmVsKGVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gaXNBbnkoZWxlbWVudCwgW1xuICAgICdicG1uOkZsb3dOb2RlJyxcbiAgICAnYnBtbjpJbnRlcmFjdGlvbk5vZGUnLFxuICAgICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnLFxuICAgICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScsXG4gICAgJ2JwbW46R3JvdXAnXG4gIF0pO1xufVxuXG5mdW5jdGlvbiBub25FeGlzdGluZ09yTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gIWVsZW1lbnQgfHwgaXNMYWJlbChlbGVtZW50KTtcbn1cblxuZnVuY3Rpb24gaXNTYW1lKGEsIGIpIHtcbiAgcmV0dXJuIGEgPT09IGI7XG59XG5cbmZ1bmN0aW9uIGdldE9yZ2FuaXphdGlvbmFsUGFyZW50KGVsZW1lbnQpIHtcblxuICBkbyB7XG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSkge1xuICAgICAgcmV0dXJuIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5wcm9jZXNzUmVmIHx8XG4gICAgICAgIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpXG4gICAgICApO1xuICAgIH1cbiAgfSB3aGlsZSAoKGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudCkpO1xuXG59XG5cbmZ1bmN0aW9uIGlzVGV4dEFubm90YXRpb24oZWxlbWVudCkge1xuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46VGV4dEFubm90YXRpb24nKTtcbn1cblxuZnVuY3Rpb24gaXNHcm91cChlbGVtZW50KSB7XG4gIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpHcm91cCcpICYmICFlbGVtZW50LmxhYmVsVGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBpc0NvbXBlbnNhdGlvbkJvdW5kYXJ5KGVsZW1lbnQpIHtcbiAgcmV0dXJuIGlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJlxuICAgICAgICAgaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nKTtcbn1cblxuZnVuY3Rpb24gaXNGb3JDb21wZW5zYXRpb24oZSkge1xuICByZXR1cm4gZ2V0QnVzaW5lc3NPYmplY3QoZSkuaXNGb3JDb21wZW5zYXRpb247XG59XG5cbmZ1bmN0aW9uIGlzU2FtZU9yZ2FuaXphdGlvbihhLCBiKSB7XG4gIHZhciBwYXJlbnRBID0gZ2V0T3JnYW5pemF0aW9uYWxQYXJlbnQoYSksXG4gICAgICBwYXJlbnRCID0gZ2V0T3JnYW5pemF0aW9uYWxQYXJlbnQoYik7XG5cbiAgcmV0dXJuIHBhcmVudEEgPT09IHBhcmVudEI7XG59XG5cbmZ1bmN0aW9uIGlzTWVzc2FnZUZsb3dTb3VyY2UoZWxlbWVudCkge1xuICByZXR1cm4gKFxuICAgIGlzKGVsZW1lbnQsICdicG1uOkludGVyYWN0aW9uTm9kZScpICYmXG4gICAgIWlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJiAoXG4gICAgICAhaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSB8fCAoXG4gICAgICAgIGlzKGVsZW1lbnQsICdicG1uOlRocm93RXZlbnQnKSAmJlxuICAgICAgICBoYXNFdmVudERlZmluaXRpb25Pck5vbmUoZWxlbWVudCwgJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbicpXG4gICAgICApXG4gICAgKVxuICApO1xufVxuXG5mdW5jdGlvbiBpc01lc3NhZ2VGbG93VGFyZ2V0KGVsZW1lbnQpIHtcbiAgcmV0dXJuIChcbiAgICBpcyhlbGVtZW50LCAnYnBtbjpJbnRlcmFjdGlvbk5vZGUnKSAmJlxuICAgICFpc0ZvckNvbXBlbnNhdGlvbihlbGVtZW50KSAmJiAoXG4gICAgICAhaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSB8fCAoXG4gICAgICAgIGlzKGVsZW1lbnQsICdicG1uOkNhdGNoRXZlbnQnKSAmJlxuICAgICAgICBoYXNFdmVudERlZmluaXRpb25Pck5vbmUoZWxlbWVudCwgJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbicpXG4gICAgICApXG4gICAgKSAmJiAhKFxuICAgICAgaXMoZWxlbWVudCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmXG4gICAgICAhaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKVxuICAgIClcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NvcGVQYXJlbnQoZWxlbWVudCkge1xuXG4gIHZhciBwYXJlbnQgPSBlbGVtZW50O1xuXG4gIHdoaWxlICgocGFyZW50ID0gcGFyZW50LnBhcmVudCkpIHtcblxuICAgIGlmIChpcyhwYXJlbnQsICdicG1uOkZsb3dFbGVtZW50c0NvbnRhaW5lcicpKSB7XG4gICAgICByZXR1cm4gZ2V0QnVzaW5lc3NPYmplY3QocGFyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoaXMocGFyZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgICByZXR1cm4gZ2V0QnVzaW5lc3NPYmplY3QocGFyZW50KS5wcm9jZXNzUmVmO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1NhbWVTY29wZShhLCBiKSB7XG4gIHZhciBzY29wZVBhcmVudEEgPSBnZXRTY29wZVBhcmVudChhKSxcbiAgICAgIHNjb3BlUGFyZW50QiA9IGdldFNjb3BlUGFyZW50KGIpO1xuXG4gIHJldHVybiBzY29wZVBhcmVudEEgPT09IHNjb3BlUGFyZW50Qjtcbn1cblxuZnVuY3Rpb24gaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsIGV2ZW50RGVmaW5pdGlvbikge1xuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcblxuICByZXR1cm4gISFmaW5kKGJvLmV2ZW50RGVmaW5pdGlvbnMgfHwgW10sIGZ1bmN0aW9uKGRlZmluaXRpb24pIHtcbiAgICByZXR1cm4gaXMoZGVmaW5pdGlvbiwgZXZlbnREZWZpbml0aW9uKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGhhc0V2ZW50RGVmaW5pdGlvbk9yTm9uZShlbGVtZW50LCBldmVudERlZmluaXRpb24pIHtcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XG5cbiAgcmV0dXJuIChiby5ldmVudERlZmluaXRpb25zIHx8IFtdKS5ldmVyeShmdW5jdGlvbihkZWZpbml0aW9uKSB7XG4gICAgcmV0dXJuIGlzKGRlZmluaXRpb24sIGV2ZW50RGVmaW5pdGlvbik7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpc1NlcXVlbmNlRmxvd1NvdXJjZShlbGVtZW50KSB7XG4gIHJldHVybiAoXG4gICAgaXMoZWxlbWVudCwgJ2JwbW46Rmxvd05vZGUnKSAmJlxuICAgICFpcyhlbGVtZW50LCAnYnBtbjpFbmRFdmVudCcpICYmXG4gICAgIWlzRXZlbnRTdWJQcm9jZXNzKGVsZW1lbnQpICYmXG4gICAgIShpcyhlbGVtZW50LCAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JykgJiZcbiAgICAgIGhhc0V2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpMaW5rRXZlbnREZWZpbml0aW9uJylcbiAgICApICYmXG4gICAgIWlzQ29tcGVuc2F0aW9uQm91bmRhcnkoZWxlbWVudCkgJiZcbiAgICAhaXNGb3JDb21wZW5zYXRpb24oZWxlbWVudClcbiAgKTtcbn1cblxuZnVuY3Rpb24gaXNTZXF1ZW5jZUZsb3dUYXJnZXQoZWxlbWVudCkge1xuICByZXR1cm4gKFxuICAgIGlzKGVsZW1lbnQsICdicG1uOkZsb3dOb2RlJykgJiZcbiAgICAhaXMoZWxlbWVudCwgJ2JwbW46U3RhcnRFdmVudCcpICYmXG4gICAgIWlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJlxuICAgICFpc0V2ZW50U3ViUHJvY2VzcyhlbGVtZW50KSAmJlxuICAgICEoaXMoZWxlbWVudCwgJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcpICYmXG4gICAgICBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpXG4gICAgKSAmJlxuICAgICFpc0ZvckNvbXBlbnNhdGlvbihlbGVtZW50KVxuICApO1xufVxuXG5mdW5jdGlvbiBpc0V2ZW50QmFzZWRUYXJnZXQoZWxlbWVudCkge1xuICByZXR1cm4gKFxuICAgIGlzKGVsZW1lbnQsICdicG1uOlJlY2VpdmVUYXNrJykgfHwgKFxuICAgICAgaXMoZWxlbWVudCwgJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcpICYmIChcbiAgICAgICAgaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKSB8fFxuICAgICAgICBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nKSB8fFxuICAgICAgICBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nKSB8fFxuICAgICAgICBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJylcbiAgICAgIClcbiAgICApXG4gICk7XG59XG5cbmZ1bmN0aW9uIGlzQ29ubmVjdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiBlbGVtZW50LndheXBvaW50cztcbn1cblxuZnVuY3Rpb24gZ2V0UGFyZW50cyhlbGVtZW50KSB7XG5cbiAgdmFyIHBhcmVudHMgPSBbXTtcblxuICB3aGlsZSAoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudDtcblxuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICBwYXJlbnRzLnB1c2goZWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhcmVudHM7XG59XG5cbmZ1bmN0aW9uIGlzUGFyZW50KHBvc3NpYmxlUGFyZW50LCBlbGVtZW50KSB7XG4gIHZhciBhbGxQYXJlbnRzID0gZ2V0UGFyZW50cyhlbGVtZW50KTtcbiAgcmV0dXJuIGFsbFBhcmVudHMuaW5kZXhPZihwb3NzaWJsZVBhcmVudCkgIT09IC0xO1xufVxuXG5mdW5jdGlvbiBjYW5Db25uZWN0KHNvdXJjZSwgdGFyZ2V0LCBjb25uZWN0aW9uKSB7XG5cbiAgaWYgKG5vbkV4aXN0aW5nT3JMYWJlbChzb3VyY2UpIHx8IG5vbkV4aXN0aW5nT3JMYWJlbCh0YXJnZXQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoIWlzKGNvbm5lY3Rpb24sICdicG1uOkRhdGFBc3NvY2lhdGlvbicpKSB7XG5cbiAgICBpZiAoY2FuQ29ubmVjdE1lc3NhZ2VGbG93KHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogJ2JwbW46TWVzc2FnZUZsb3cnIH07XG4gICAgfVxuXG4gICAgaWYgKGNhbkNvbm5lY3RTZXF1ZW5jZUZsb3coc291cmNlLCB0YXJnZXQpKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiAnYnBtbjpTZXF1ZW5jZUZsb3cnIH07XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbm5lY3REYXRhQXNzb2NpYXRpb24gPSBjYW5Db25uZWN0RGF0YUFzc29jaWF0aW9uKHNvdXJjZSwgdGFyZ2V0KTtcblxuICBpZiAoY29ubmVjdERhdGFBc3NvY2lhdGlvbikge1xuICAgIHJldHVybiBjb25uZWN0RGF0YUFzc29jaWF0aW9uO1xuICB9XG5cbiAgaWYgKGlzQ29tcGVuc2F0aW9uQm91bmRhcnkoc291cmNlKSAmJiBpc0ZvckNvbXBlbnNhdGlvbih0YXJnZXQpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdicG1uOkFzc29jaWF0aW9uJyxcbiAgICAgIGFzc29jaWF0aW9uRGlyZWN0aW9uOiAnT25lJ1xuICAgIH07XG4gIH1cblxuICBpZiAoY2FuQ29ubmVjdEFzc29jaWF0aW9uKHNvdXJjZSwgdGFyZ2V0KSkge1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdicG1uOkFzc29jaWF0aW9uJ1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2FuIGFuIGVsZW1lbnQgYmUgZHJvcHBlZCBpbnRvIHRoZSB0YXJnZXQgZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGNhbkRyb3AoZWxlbWVudCwgdGFyZ2V0LCBwb3NpdGlvbikge1xuXG4gIC8vIGNhbiBtb3ZlIGxhYmVscyBhbmQgZ3JvdXBzIGV2ZXJ5d2hlcmVcbiAgaWYgKGlzTGFiZWwoZWxlbWVudCkgfHwgaXNHcm91cChlbGVtZW50KSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cblxuICAvLyBkaXNhbGxvdyB0byBjcmVhdGUgZWxlbWVudHMgb24gY29sbGFwc2VkIHBvb2xzXG4gIGlmIChpcyh0YXJnZXQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgIWlzRXhwYW5kZWQodGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGFsbG93IHRvIGNyZWF0ZSBuZXcgcGFydGljaXBhbnRzIG9uXG4gIC8vIGV4aXN0aW5nIGNvbGxhYm9yYXRpb24gYW5kIHByb2Nlc3MgZGlhZ3JhbXNcbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICByZXR1cm4gaXModGFyZ2V0LCAnYnBtbjpQcm9jZXNzJykgfHwgaXModGFyZ2V0LCAnYnBtbjpDb2xsYWJvcmF0aW9uJyk7XG4gIH1cblxuICAvLyBhbGxvdyBtb3ZpbmcgRGF0YUlucHV0IC8gRGF0YU91dHB1dCB3aXRoaW4gaXRzIG9yaWdpbmFsIGNvbnRhaW5lciBvbmx5XG4gIGlmIChpc0FueShlbGVtZW50LCBbICdicG1uOkRhdGFJbnB1dCcsICdicG1uOkRhdGFPdXRwdXQnIF0pKSB7XG5cbiAgICBpZiAoZWxlbWVudC5wYXJlbnQpIHtcbiAgICAgIHJldHVybiB0YXJnZXQgPT09IGVsZW1lbnQucGFyZW50O1xuICAgIH1cbiAgfVxuXG4gIC8vIGFsbG93IGNyZWF0aW5nIGxhbmVzIG9uIHBhcnRpY2lwYW50cyBhbmQgb3RoZXIgbGFuZXMgb25seVxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46TGFuZScpKSB7XG4gICAgcmV0dXJuIGlzKHRhcmdldCwgJ2JwbW46UGFydGljaXBhbnQnKSB8fCBpcyh0YXJnZXQsICdicG1uOkxhbmUnKTtcbiAgfVxuXG4gIC8vIGRpc2FsbG93IGRyb3BwaW5nIGJvdW5kYXJ5IGV2ZW50cyB3aGljaCBjYW5ub3QgcmVwbGFjZSB3aXRoIGludGVybWVkaWF0ZSBldmVudFxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmICFpc0Ryb3BwYWJsZUJvdW5kYXJ5RXZlbnQoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBkcm9wIGZsb3cgZWxlbWVudHMgb250byBmbG93IGVsZW1lbnQgY29udGFpbmVyc1xuICAvLyBhbmQgcGFydGljaXBhbnRzXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpGbG93RWxlbWVudCcpICYmICFpcyhlbGVtZW50LCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSkge1xuICAgIGlmIChpcyh0YXJnZXQsICdicG1uOkZsb3dFbGVtZW50c0NvbnRhaW5lcicpKSB7XG4gICAgICByZXR1cm4gaXNFeHBhbmRlZCh0YXJnZXQpO1xuICAgIH1cblxuICAgIHJldHVybiBpc0FueSh0YXJnZXQsIFsgJ2JwbW46UGFydGljaXBhbnQnLCAnYnBtbjpMYW5lJyBdKTtcbiAgfVxuXG4gIC8vIGFjY291bnQgZm9yIHRoZSBmYWN0IHRoYXQgZGF0YSBhc3NvY2lhdGlvbnMgYXJlIGFsd2F5c1xuICAvLyByZW5kZXJlZCBhbmQgbW92ZWQgdG8gdG9wIChQcm9jZXNzIG9yIENvbGxhYm9yYXRpb24gbGV2ZWwpXG4gIC8vXG4gIC8vIGFydGlmYWN0cyBtYXkgYmUgcGxhY2VkIHdoZXJldmVyLCB0b29cbiAgaWYgKGlzQW55KGVsZW1lbnQsIFsgJ2JwbW46QXJ0aWZhY3QnLCAnYnBtbjpEYXRhQXNzb2NpYXRpb24nLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnIF0pKSB7XG4gICAgcmV0dXJuIGlzQW55KHRhcmdldCwgW1xuICAgICAgJ2JwbW46Q29sbGFib3JhdGlvbicsXG4gICAgICAnYnBtbjpMYW5lJyxcbiAgICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAgICdicG1uOlByb2Nlc3MnLFxuICAgICAgJ2JwbW46U3ViUHJvY2VzcycgXSk7XG4gIH1cblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46TWVzc2FnZUZsb3cnKSkge1xuICAgIHJldHVybiBpcyh0YXJnZXQsICdicG1uOkNvbGxhYm9yYXRpb24nKVxuICAgICAgfHwgZWxlbWVudC5zb3VyY2UucGFyZW50ID09IHRhcmdldFxuICAgICAgfHwgZWxlbWVudC50YXJnZXQucGFyZW50ID09IHRhcmdldDtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNEcm9wcGFibGVCb3VuZGFyeUV2ZW50KGV2ZW50KSB7XG4gIHJldHVybiBnZXRCdXNpbmVzc09iamVjdChldmVudCkuY2FuY2VsQWN0aXZpdHkgJiYgKFxuICAgIGhhc05vRXZlbnREZWZpbml0aW9uKGV2ZW50KSB8fCBoYXNDb21tb25Cb3VuZGFyeUludGVybWVkaWF0ZUV2ZW50RGVmaW5pdGlvbihldmVudClcbiAgKTtcbn1cblxuZnVuY3Rpb24gaXNCb3VuZGFyeUV2ZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuICFpc0xhYmVsKGVsZW1lbnQpICYmIGlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKTtcbn1cblxuZnVuY3Rpb24gaXNMYW5lKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGlzKGVsZW1lbnQsICdicG1uOkxhbmUnKTtcbn1cblxuLyoqXG4gKiBXZSB0cmVhdCBJbnRlcm1lZGlhdGVUaHJvd0V2ZW50cyBhcyBib3VuZGFyeSBldmVudHMgZHVyaW5nIGNyZWF0ZSxcbiAqIHRoaXMgbXVzdCBiZSByZWZsZWN0ZWQgaW4gdGhlIHJ1bGVzLlxuICovXG5mdW5jdGlvbiBpc0JvdW5kYXJ5Q2FuZGlkYXRlKGVsZW1lbnQpIHtcbiAgaWYgKGlzQm91bmRhcnlFdmVudChlbGVtZW50KSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnKSAmJiBoYXNOb0V2ZW50RGVmaW5pdGlvbihlbGVtZW50KSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICBpcyhlbGVtZW50LCAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JykgJiZcbiAgICBoYXNDb21tb25Cb3VuZGFyeUludGVybWVkaWF0ZUV2ZW50RGVmaW5pdGlvbihlbGVtZW50KVxuICApO1xufVxuXG5mdW5jdGlvbiBoYXNOb0V2ZW50RGVmaW5pdGlvbihlbGVtZW50KSB7XG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xuXG4gIHJldHVybiBibyAmJiAhKGJvLmV2ZW50RGVmaW5pdGlvbnMgJiYgYm8uZXZlbnREZWZpbml0aW9ucy5sZW5ndGgpO1xufVxuXG5mdW5jdGlvbiBoYXNDb21tb25Cb3VuZGFyeUludGVybWVkaWF0ZUV2ZW50RGVmaW5pdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiBoYXNPbmVPZkV2ZW50RGVmaW5pdGlvbnMoZWxlbWVudCwgW1xuICAgICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nLFxuICAgICdicG1uOlRpbWVyRXZlbnREZWZpbml0aW9uJyxcbiAgICAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nLFxuICAgICdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJ1xuICBdKTtcbn1cblxuZnVuY3Rpb24gaGFzT25lT2ZFdmVudERlZmluaXRpb25zKGVsZW1lbnQsIGV2ZW50RGVmaW5pdGlvbnMpIHtcbiAgcmV0dXJuIGV2ZW50RGVmaW5pdGlvbnMuc29tZShmdW5jdGlvbihkZWZpbml0aW9uKSB7XG4gICAgcmV0dXJuIGhhc0V2ZW50RGVmaW5pdGlvbihlbGVtZW50LCBkZWZpbml0aW9uKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzUmVjZWl2ZVRhc2tBZnRlckV2ZW50QmFzZWRHYXRld2F5KGVsZW1lbnQpIHtcbiAgcmV0dXJuIChcbiAgICBpcyhlbGVtZW50LCAnYnBtbjpSZWNlaXZlVGFzaycpICYmXG4gICAgZmluZChlbGVtZW50LmluY29taW5nLCBmdW5jdGlvbihpbmNvbWluZykge1xuICAgICAgcmV0dXJuIGlzKGluY29taW5nLnNvdXJjZSwgJ2JwbW46RXZlbnRCYXNlZEdhdGV3YXknKTtcbiAgICB9KVxuICApO1xufVxuXG5cbmZ1bmN0aW9uIGNhbkF0dGFjaChlbGVtZW50cywgdGFyZ2V0LCBzb3VyY2UsIHBvc2l0aW9uKSB7XG5cbiAgaWYgKCFBcnJheS5pc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gWyBlbGVtZW50cyBdO1xuICB9XG5cbiAgLy8gb25seSAocmUtKWF0dGFjaCBvbmUgZWxlbWVudCBhdCBhIHRpbWVcbiAgaWYgKGVsZW1lbnRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBlbGVtZW50ID0gZWxlbWVudHNbMF07XG5cbiAgLy8gZG8gbm90IGF0dGFjaCBsYWJlbHNcbiAgaWYgKGlzTGFiZWwoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBvbmx5IGhhbmRsZSBib3VuZGFyeSBldmVudHNcbiAgaWYgKCFpc0JvdW5kYXJ5Q2FuZGlkYXRlKGVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gZGlzYWxsb3cgZHJvcCBvbiBldmVudCBzdWIgcHJvY2Vzc2VzXG4gIGlmIChpc0V2ZW50U3ViUHJvY2Vzcyh0YXJnZXQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gb25seSBhbGxvdyBkcm9wIG9uIG5vbiBjb21wZW5zYXRpb24gYWN0aXZpdGllc1xuICBpZiAoIWlzKHRhcmdldCwgJ2JwbW46QWN0aXZpdHknKSB8fCBpc0ZvckNvbXBlbnNhdGlvbih0YXJnZXQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gb25seSBhdHRhY2ggdG8gc3VicHJvY2VzcyBib3JkZXJcbiAgaWYgKHBvc2l0aW9uICYmICFpc0JvdW5kYXJ5QXR0YWNobWVudChwb3NpdGlvbiwgdGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGRvIG5vdCBhdHRhY2ggb24gcmVjZWl2ZSB0YXNrcyBhZnRlciBldmVudCBiYXNlZCBnYXRld2F5c1xuICBpZiAoaXNSZWNlaXZlVGFza0FmdGVyRXZlbnRCYXNlZEdhdGV3YXkodGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiAnYXR0YWNoJztcbn1cblxuXG4vKipcbiAqIERlZmluZXMgaG93IHRvIHJlcGxhY2UgZWxlbWVudHMgZm9yIGEgZ2l2ZW4gdGFyZ2V0LlxuICpcbiAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgd2hpY2ggd2lsbCBiZSByZXBsYWNlZC5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICBbeyBpZDogJ0ludGVybWVkaWF0ZUV2ZW50XzInLFxuICogICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnXG4gKiAgIH0sXG4gKiAgIHsgaWQ6ICdJbnRlcm1lZGlhdGVFdmVudF81JyxcbiAqICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCdcbiAqICAgfV1cbiAqXG4gKiBAcGFyYW0gIHtBcnJheX0gZWxlbWVudHNcbiAqIEBwYXJhbSAge09iamVjdH0gdGFyZ2V0XG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBhbiBvYmplY3QgY29udGFpbmluZyBhbGwgZWxlbWVudHMgd2hpY2ggaGF2ZSB0byBiZSByZXBsYWNlZFxuICovXG5mdW5jdGlvbiBjYW5SZXBsYWNlKGVsZW1lbnRzLCB0YXJnZXQsIHBvc2l0aW9uKSB7XG5cbiAgaWYgKCF0YXJnZXQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgY2FuRXhlY3V0ZSA9IHtcbiAgICByZXBsYWNlbWVudHM6IFtdXG4gIH07XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgaWYgKCFpc0V2ZW50U3ViUHJvY2Vzcyh0YXJnZXQpKSB7XG5cbiAgICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpTdGFydEV2ZW50JykgJiZcbiAgICAgICAgICBlbGVtZW50LnR5cGUgIT09ICdsYWJlbCcgJiZcbiAgICAgICAgICBjYW5Ecm9wKGVsZW1lbnQsIHRhcmdldCkpIHtcblxuICAgICAgICAvLyByZXBsYWNlIGEgbm9uLWludGVycnVwdGluZyBzdGFydCBldmVudCBieSBhIGJsYW5rIGludGVycnVwdGluZyBzdGFydCBldmVudFxuICAgICAgICAvLyB3aGVuIHRoZSB0YXJnZXQgaXMgbm90IGFuIGV2ZW50IHN1YiBwcm9jZXNzXG4gICAgICAgIGlmICghaXNJbnRlcnJ1cHRpbmcoZWxlbWVudCkpIHtcbiAgICAgICAgICBjYW5FeGVjdXRlLnJlcGxhY2VtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIG9sZEVsZW1lbnRJZDogZWxlbWVudC5pZCxcbiAgICAgICAgICAgIG5ld0VsZW1lbnRUeXBlOiAnYnBtbjpTdGFydEV2ZW50J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVwbGFjZSBhbiBlcnJvci9lc2NhbGF0aW9uL2NvbXBlbnNhdGUgc3RhcnQgZXZlbnQgYnkgYSBibGFuayBpbnRlcnJ1cHRpbmcgc3RhcnQgZXZlbnRcbiAgICAgICAgLy8gd2hlbiB0aGUgdGFyZ2V0IGlzIG5vdCBhbiBldmVudCBzdWIgcHJvY2Vzc1xuICAgICAgICBpZiAoaGFzRXJyb3JFdmVudERlZmluaXRpb24oZWxlbWVudCkgfHxcbiAgICAgICAgICAgIGhhc0VzY2FsYXRpb25FdmVudERlZmluaXRpb24oZWxlbWVudCkgfHxcbiAgICAgICAgICAgIGhhc0NvbXBlbnNhdGVFdmVudERlZmluaXRpb24oZWxlbWVudCkpIHtcbiAgICAgICAgICBjYW5FeGVjdXRlLnJlcGxhY2VtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIG9sZEVsZW1lbnRJZDogZWxlbWVudC5pZCxcbiAgICAgICAgICAgIG5ld0VsZW1lbnRUeXBlOiAnYnBtbjpTdGFydEV2ZW50J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVwbGFjZSBhIHR5cGVkIHN0YXJ0IGV2ZW50IGJ5IGEgYmxhbmsgaW50ZXJydXB0aW5nIHN0YXJ0IGV2ZW50XG4gICAgICAgIC8vIHdoZW4gdGhlIHRhcmdldCBpcyBhIHN1YiBwcm9jZXNzIGJ1dCBub3QgYW4gZXZlbnQgc3ViIHByb2Nlc3NcbiAgICAgICAgaWYgKGhhc09uZU9mRXZlbnREZWZpbml0aW9ucyhlbGVtZW50LFxuICAgICAgICAgIFtcbiAgICAgICAgICAgICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nLFxuICAgICAgICAgICAgJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nLFxuICAgICAgICAgICAgJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJyxcbiAgICAgICAgICAgICdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgICAgICAgIF0pICYmXG4gICAgICAgICAgICBpcyh0YXJnZXQsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuICAgICAgICAgIGNhbkV4ZWN1dGUucmVwbGFjZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgb2xkRWxlbWVudElkOiBlbGVtZW50LmlkLFxuICAgICAgICAgICAgbmV3RWxlbWVudFR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWlzKHRhcmdldCwgJ2JwbW46VHJhbnNhY3Rpb24nKSkge1xuICAgICAgaWYgKGhhc0V2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpDYW5jZWxFdmVudERlZmluaXRpb24nKSAmJlxuICAgICAgICAgIGVsZW1lbnQudHlwZSAhPT0gJ2xhYmVsJykge1xuXG4gICAgICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpFbmRFdmVudCcpICYmIGNhbkRyb3AoZWxlbWVudCwgdGFyZ2V0KSkge1xuICAgICAgICAgIGNhbkV4ZWN1dGUucmVwbGFjZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgb2xkRWxlbWVudElkOiBlbGVtZW50LmlkLFxuICAgICAgICAgICAgbmV3RWxlbWVudFR5cGU6ICdicG1uOkVuZEV2ZW50J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJiBjYW5BdHRhY2goZWxlbWVudCwgdGFyZ2V0LCBudWxsLCBwb3NpdGlvbikpIHtcbiAgICAgICAgICBjYW5FeGVjdXRlLnJlcGxhY2VtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIG9sZEVsZW1lbnRJZDogZWxlbWVudC5pZCxcbiAgICAgICAgICAgIG5ld0VsZW1lbnRUeXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gY2FuRXhlY3V0ZS5yZXBsYWNlbWVudHMubGVuZ3RoID8gY2FuRXhlY3V0ZSA6IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjYW5Nb3ZlKGVsZW1lbnRzLCB0YXJnZXQpIHtcblxuICAvLyBkbyBub3QgbW92ZSBzZWxlY3Rpb24gY29udGFpbmluZyBsYW5lc1xuICBpZiAoc29tZShlbGVtZW50cywgaXNMYW5lKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGFsbG93IGRlZmF1bHQgbW92ZSBjaGVjayB0byBzdGFydCBtb3ZlIG9wZXJhdGlvblxuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnRzLmV2ZXJ5KGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gY2FuRHJvcChlbGVtZW50LCB0YXJnZXQpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY2FuQ3JlYXRlKHNoYXBlLCB0YXJnZXQsIHNvdXJjZSwgcG9zaXRpb24pIHtcblxuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChpc0xhYmVsKHNoYXBlKSB8fCBpc0dyb3VwKHNoYXBlKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGlzU2FtZShzb3VyY2UsIHRhcmdldCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBlbnN1cmUgd2UgZG8gbm90IGRyb3AgdGhlIGVsZW1lbnRcbiAgLy8gaW50byBzb3VyY2VcbiAgaWYgKHNvdXJjZSAmJiBpc1BhcmVudChzb3VyY2UsIHRhcmdldCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gY2FuRHJvcChzaGFwZSwgdGFyZ2V0LCBwb3NpdGlvbikgfHwgY2FuSW5zZXJ0KHNoYXBlLCB0YXJnZXQsIHBvc2l0aW9uKTtcbn1cblxuZnVuY3Rpb24gY2FuUmVzaXplKHNoYXBlLCBuZXdCb3VuZHMpIHtcbiAgaWYgKGlzKHNoYXBlLCAnYnBtbjpTdWJQcm9jZXNzJykpIHtcbiAgICByZXR1cm4gKFxuICAgICAgaXNFeHBhbmRlZChzaGFwZSkgJiYgKFxuICAgICAgICAhbmV3Qm91bmRzIHx8IChuZXdCb3VuZHMud2lkdGggPj0gMTAwICYmIG5ld0JvdW5kcy5oZWlnaHQgPj0gODApXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIGlmIChpcyhzaGFwZSwgJ2JwbW46TGFuZScpKSB7XG4gICAgcmV0dXJuICFuZXdCb3VuZHMgfHwgKG5ld0JvdW5kcy53aWR0aCA+PSAxMzAgJiYgbmV3Qm91bmRzLmhlaWdodCA+PSA2MCk7XG4gIH1cblxuICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICByZXR1cm4gIW5ld0JvdW5kcyB8fCAobmV3Qm91bmRzLndpZHRoID49IDI1MCAmJiBuZXdCb3VuZHMuaGVpZ2h0ID49IDUwKTtcbiAgfVxuXG4gIGlmIChpc1RleHRBbm5vdGF0aW9uKHNoYXBlKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGlzR3JvdXAoc2hhcGUpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2hlY2ssIHdoZXRoZXIgb25lIHNpZGUgb2YgdGhlIHJlbGF0aW9uc2hpcFxuICogaXMgYSB0ZXh0IGFubm90YXRpb24uXG4gKi9cbmZ1bmN0aW9uIGlzT25lVGV4dEFubm90YXRpb24oc291cmNlLCB0YXJnZXQpIHtcblxuICB2YXIgc291cmNlVGV4dEFubm90YXRpb24gPSBpc1RleHRBbm5vdGF0aW9uKHNvdXJjZSksXG4gICAgICB0YXJnZXRUZXh0QW5ub3RhdGlvbiA9IGlzVGV4dEFubm90YXRpb24odGFyZ2V0KTtcblxuICByZXR1cm4gKFxuICAgIChzb3VyY2VUZXh0QW5ub3RhdGlvbiB8fCB0YXJnZXRUZXh0QW5ub3RhdGlvbikgJiZcbiAgICAoc291cmNlVGV4dEFubm90YXRpb24gIT09IHRhcmdldFRleHRBbm5vdGF0aW9uKVxuICApO1xufVxuXG5cbmZ1bmN0aW9uIGNhbkNvbm5lY3RBc3NvY2lhdGlvbihzb3VyY2UsIHRhcmdldCkge1xuXG4gIC8vIGRvIG5vdCBjb25uZWN0IGNvbm5lY3Rpb25zXG4gIGlmIChpc0Nvbm5lY3Rpb24oc291cmNlKSB8fCBpc0Nvbm5lY3Rpb24odGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGNvbXBlbnNhdGlvbiBib3VuZGFyeSBldmVudHMgYXJlIGV4Y2VwdGlvblxuICBpZiAoaXNDb21wZW5zYXRpb25Cb3VuZGFyeShzb3VyY2UpICYmIGlzRm9yQ29tcGVuc2F0aW9uKHRhcmdldCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIGRvbid0IGNvbm5lY3QgcGFyZW50IDwtPiBjaGlsZFxuICBpZiAoaXNQYXJlbnQodGFyZ2V0LCBzb3VyY2UpIHx8IGlzUGFyZW50KHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGFsbG93IGNvbm5lY3Rpb24gb2YgYXNzb2NpYXRpb25zIGJldHdlZW4gPCFUZXh0QW5ub3RhdGlvbj4gYW5kIDxUZXh0QW5ub3RhdGlvbj5cbiAgaWYgKGlzT25lVGV4dEFubm90YXRpb24oc291cmNlLCB0YXJnZXQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBjYW4gY29ubmVjdCBhc3NvY2lhdGlvbnMgd2hlcmUgd2UgY2FuIGNvbm5lY3RcbiAgLy8gZGF0YSBhc3NvY2lhdGlvbnMsIHRvbyAoISlcbiAgcmV0dXJuICEhY2FuQ29ubmVjdERhdGFBc3NvY2lhdGlvbihzb3VyY2UsIHRhcmdldCk7XG59XG5cbmZ1bmN0aW9uIGNhbkNvbm5lY3RNZXNzYWdlRmxvdyhzb3VyY2UsIHRhcmdldCkge1xuXG4gIC8vIGR1cmluZyBjb25uZWN0IHVzZXIgbWlnaHQgbW92ZSBtb3VzZSBvdXQgb2YgY2FudmFzXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9icG1uLWlvL2JwbW4tanMvaXNzdWVzLzEwMzNcbiAgaWYgKGdldFJvb3RFbGVtZW50KHNvdXJjZSkgJiYgIWdldFJvb3RFbGVtZW50KHRhcmdldCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIGlzTWVzc2FnZUZsb3dTb3VyY2Uoc291cmNlKSAmJlxuICAgIGlzTWVzc2FnZUZsb3dUYXJnZXQodGFyZ2V0KSAmJlxuICAgICFpc1NhbWVPcmdhbml6YXRpb24oc291cmNlLCB0YXJnZXQpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNhbkNvbm5lY3RTZXF1ZW5jZUZsb3coc291cmNlLCB0YXJnZXQpIHtcblxuICBpZiAoXG4gICAgaXNFdmVudEJhc2VkVGFyZ2V0KHRhcmdldCkgJiZcbiAgICB0YXJnZXQuaW5jb21pbmcubGVuZ3RoID4gMCAmJlxuICAgIGFyZU91dGdvaW5nRXZlbnRCYXNlZEdhdGV3YXlDb25uZWN0aW9ucyh0YXJnZXQuaW5jb21pbmcpICYmXG4gICAgIWlzKHNvdXJjZSwgJ2JwbW46RXZlbnRCYXNlZEdhdGV3YXknKVxuICApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gaXNTZXF1ZW5jZUZsb3dTb3VyY2Uoc291cmNlKSAmJlxuICAgICAgICAgaXNTZXF1ZW5jZUZsb3dUYXJnZXQodGFyZ2V0KSAmJlxuICAgICAgICAgaXNTYW1lU2NvcGUoc291cmNlLCB0YXJnZXQpICYmXG4gICAgICAgICAhKGlzKHNvdXJjZSwgJ2JwbW46RXZlbnRCYXNlZEdhdGV3YXknKSAmJiAhaXNFdmVudEJhc2VkVGFyZ2V0KHRhcmdldCkpO1xufVxuXG5cbmZ1bmN0aW9uIGNhbkNvbm5lY3REYXRhQXNzb2NpYXRpb24oc291cmNlLCB0YXJnZXQpIHtcblxuICBpZiAoaXNBbnkoc291cmNlLCBbICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnIF0pICYmXG4gICAgICBpc0FueSh0YXJnZXQsIFsgJ2JwbW46QWN0aXZpdHknLCAnYnBtbjpUaHJvd0V2ZW50JyBdKSkge1xuICAgIHJldHVybiB7IHR5cGU6ICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJyB9O1xuICB9XG5cbiAgaWYgKGlzQW55KHRhcmdldCwgWyAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJywgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJyBdKSAmJlxuICAgICAgaXNBbnkoc291cmNlLCBbICdicG1uOkFjdGl2aXR5JywgJ2JwbW46Q2F0Y2hFdmVudCcgXSkpIHtcbiAgICByZXR1cm4geyB0eXBlOiAnYnBtbjpEYXRhT3V0cHV0QXNzb2NpYXRpb24nIH07XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGNhbkluc2VydChzaGFwZSwgZmxvdywgcG9zaXRpb24pIHtcblxuICBpZiAoIWZsb3cpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShzaGFwZSkpIHtcbiAgICBpZiAoc2hhcGUubGVuZ3RoICE9PSAxKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgc2hhcGUgPSBzaGFwZVswXTtcbiAgfVxuXG4gIGlmIChmbG93LnNvdXJjZSA9PT0gc2hhcGUgfHxcbiAgICAgIGZsb3cudGFyZ2V0ID09PSBzaGFwZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIHJldHVybiB0cnVlIGlmIHdlIGNhbiBkcm9wIG9uIHRoZVxuICAvLyB1bmRlcmx5aW5nIGZsb3cgcGFyZW50XG4gIC8vXG4gIC8vIGF0IHRoaXMgcG9pbnQgd2UgYXJlIG5vdCByZWFsbHkgYWJsZSB0byB0YWxrXG4gIC8vIGFib3V0IGNvbm5lY3Rpb24gcnVsZXMgKHlldClcblxuICByZXR1cm4gKFxuICAgIGlzQW55KGZsb3csIFsgJ2JwbW46U2VxdWVuY2VGbG93JywgJ2JwbW46TWVzc2FnZUZsb3cnIF0pICYmXG4gICAgIWlzTGFiZWwoZmxvdykgJiZcbiAgICBpcyhzaGFwZSwgJ2JwbW46Rmxvd05vZGUnKSAmJlxuICAgICFpcyhzaGFwZSwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmXG4gICAgY2FuRHJvcChzaGFwZSwgZmxvdy5wYXJlbnQsIHBvc2l0aW9uKSk7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVzKGVsZW1lbnRzLCBlbGVtZW50KSB7XG4gIHJldHVybiAoZWxlbWVudHMgJiYgZWxlbWVudCkgJiYgZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGNhbkNvcHkoZWxlbWVudHMsIGVsZW1lbnQpIHtcbiAgaWYgKGlzTGFiZWwoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpMYW5lJykgJiYgIWluY2x1ZGVzKGVsZW1lbnRzLCBlbGVtZW50LnBhcmVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNPdXRnb2luZ0V2ZW50QmFzZWRHYXRld2F5Q29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG5cbiAgaWYgKGNvbm5lY3Rpb24gJiYgY29ubmVjdGlvbi5zb3VyY2UpIHtcbiAgICByZXR1cm4gaXMoY29ubmVjdGlvbi5zb3VyY2UsICdicG1uOkV2ZW50QmFzZWRHYXRld2F5Jyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXJlT3V0Z29pbmdFdmVudEJhc2VkR2F0ZXdheUNvbm5lY3Rpb25zKGNvbm5lY3Rpb25zKSB7XG4gIGNvbm5lY3Rpb25zID0gY29ubmVjdGlvbnMgfHwgW107XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb25zLnNvbWUoaXNPdXRnb2luZ0V2ZW50QmFzZWRHYXRld2F5Q29ubmVjdGlvbik7XG59XG5cbmZ1bmN0aW9uIGdldFJvb3RFbGVtZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFBhcmVudChlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgZ2V0UGFyZW50KGVsZW1lbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKTtcbn1cbiIsImltcG9ydCBSdWxlc01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9ydWxlcyc7XG5cbmltcG9ydCBCcG1uUnVsZXMgZnJvbSAnLi9CcG1uUnVsZXMnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgUnVsZXNNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2JwbW5SdWxlcycgXSxcbiAgYnBtblJ1bGVzOiBbICd0eXBlJywgQnBtblJ1bGVzIF1cbn07XG4iLCJpbXBvcnQge1xuICBtYXAsXG4gIGZpbHRlcixcbiAgc29ydEJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0TGFiZWxcbn0gZnJvbSAnLi4vbGFiZWwtZWRpdGluZy9MYWJlbFV0aWwnO1xuXG5cbi8qKlxuICogUHJvdmlkZXMgYWJpbGl0eSB0byBzZWFyY2ggdGhyb3VnaCBCUE1OIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5TZWFyY2hQcm92aWRlcihlbGVtZW50UmVnaXN0cnksIHNlYXJjaFBhZCwgY2FudmFzKSB7XG5cbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG5cbiAgc2VhcmNoUGFkLnJlZ2lzdGVyUHJvdmlkZXIodGhpcyk7XG59XG5cbkJwbW5TZWFyY2hQcm92aWRlci4kaW5qZWN0ID0gW1xuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ3NlYXJjaFBhZCcsXG4gICdjYW52YXMnXG5dO1xuXG5cbi8qKlxuICogRmluZHMgYWxsIGVsZW1lbnRzIHRoYXQgbWF0Y2ggZ2l2ZW4gcGF0dGVyblxuICpcbiAqIDxSZXN1bHQ+IDpcbiAqICB7XG4gKiAgICBwcmltYXJ5VG9rZW5zOiA8QXJyYXk8VG9rZW4+PixcbiAqICAgIHNlY29uZGFyeVRva2VuczogPEFycmF5PFRva2VuPj4sXG4gKiAgICBlbGVtZW50OiA8RWxlbWVudD5cbiAqICB9XG4gKlxuICogPFRva2VuPiA6XG4gKiAge1xuICogICAgbm9ybWFsfG1hdGNoZWQ6IDxzdHJpbmc+XG4gKiAgfVxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gcGF0dGVyblxuICogQHJldHVybiB7QXJyYXk8UmVzdWx0Pn1cbiAqL1xuQnBtblNlYXJjaFByb3ZpZGVyLnByb3RvdHlwZS5maW5kID0gZnVuY3Rpb24ocGF0dGVybikge1xuICB2YXIgcm9vdEVsZW1lbnQgPSB0aGlzLl9jYW52YXMuZ2V0Um9vdEVsZW1lbnQoKTtcblxuICB2YXIgZWxlbWVudHMgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZmlsdGVyKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBpZiAoZWxlbWVudC5sYWJlbFRhcmdldCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSk7XG5cbiAgLy8gZG8gbm90IGluY2x1ZGUgcm9vdCBlbGVtZW50XG4gIGVsZW1lbnRzID0gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQgIT09IHJvb3RFbGVtZW50O1xuICB9KTtcblxuICBlbGVtZW50cyA9IG1hcChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHJldHVybiB7XG4gICAgICBwcmltYXJ5VG9rZW5zOiBtYXRjaEFuZFNwbGl0KGdldExhYmVsKGVsZW1lbnQpLCBwYXR0ZXJuKSxcbiAgICAgIHNlY29uZGFyeVRva2VuczogbWF0Y2hBbmRTcGxpdChlbGVtZW50LmlkLCBwYXR0ZXJuKSxcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnRcbiAgICB9O1xuICB9KTtcblxuICAvLyBleGNsdWRlIG5vbi1tYXRjaGVkIGVsZW1lbnRzXG4gIGVsZW1lbnRzID0gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGhhc01hdGNoZWQoZWxlbWVudC5wcmltYXJ5VG9rZW5zKSB8fCBoYXNNYXRjaGVkKGVsZW1lbnQuc2Vjb25kYXJ5VG9rZW5zKTtcbiAgfSk7XG5cbiAgZWxlbWVudHMgPSBzb3J0QnkoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gZ2V0TGFiZWwoZWxlbWVudC5lbGVtZW50KSArIGVsZW1lbnQuZWxlbWVudC5pZDtcbiAgfSk7XG5cbiAgcmV0dXJuIGVsZW1lbnRzO1xufTtcblxuXG5mdW5jdGlvbiBoYXNNYXRjaGVkKHRva2Vucykge1xuICB2YXIgbWF0Y2hlZCA9IGZpbHRlcih0b2tlbnMsIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gISF0Lm1hdGNoZWQ7XG4gIH0pO1xuXG4gIHJldHVybiBtYXRjaGVkLmxlbmd0aCA+IDA7XG59XG5cblxuZnVuY3Rpb24gbWF0Y2hBbmRTcGxpdCh0ZXh0LCBwYXR0ZXJuKSB7XG4gIHZhciB0b2tlbnMgPSBbXSxcbiAgICAgIG9yaWdpbmFsVGV4dCA9IHRleHQ7XG5cbiAgaWYgKCF0ZXh0KSB7XG4gICAgcmV0dXJuIHRva2VucztcbiAgfVxuXG4gIHRleHQgPSB0ZXh0LnRvTG93ZXJDYXNlKCk7XG4gIHBhdHRlcm4gPSBwYXR0ZXJuLnRvTG93ZXJDYXNlKCk7XG5cbiAgdmFyIGkgPSB0ZXh0LmluZGV4T2YocGF0dGVybik7XG5cbiAgaWYgKGkgPiAtMSkge1xuICAgIGlmIChpICE9PSAwKSB7XG4gICAgICB0b2tlbnMucHVzaCh7XG4gICAgICAgIG5vcm1hbDogb3JpZ2luYWxUZXh0LnN1YnN0cigwLCBpKVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdG9rZW5zLnB1c2goe1xuICAgICAgbWF0Y2hlZDogb3JpZ2luYWxUZXh0LnN1YnN0cihpLCBwYXR0ZXJuLmxlbmd0aClcbiAgICB9KTtcblxuICAgIGlmIChwYXR0ZXJuLmxlbmd0aCArIGkgPCB0ZXh0Lmxlbmd0aCkge1xuICAgICAgdG9rZW5zLnB1c2goe1xuICAgICAgICBub3JtYWw6IG9yaWdpbmFsVGV4dC5zdWJzdHIocGF0dGVybi5sZW5ndGggKyBpLCB0ZXh0Lmxlbmd0aClcbiAgICAgIH0pO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0b2tlbnMucHVzaCh7XG4gICAgICBub3JtYWw6IG9yaWdpbmFsVGV4dFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHRva2Vucztcbn0iLCJpbXBvcnQgU2VhcmNoUGFkTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NlYXJjaC1wYWQnO1xuXG5pbXBvcnQgQnBtblNlYXJjaFByb3ZpZGVyIGZyb20gJy4vQnBtblNlYXJjaFByb3ZpZGVyJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgU2VhcmNoUGFkTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdicG1uU2VhcmNoJ10sXG4gIGJwbW5TZWFyY2g6IFsgJ3R5cGUnLCBCcG1uU2VhcmNoUHJvdmlkZXIgXVxufTtcbiIsImltcG9ydCB7XHJcbiAgbWlkLFxyXG4gIHNldFNuYXBwZWRcclxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0NtZCB9IGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2tleWJvYXJkL0tleWJvYXJkVXRpbCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIGdldE9yaWVudGF0aW9uXHJcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xyXG5cclxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0FueSB9IGZyb20gJy4uL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJztcclxuXHJcbmltcG9ydCB7IHNvbWUgfSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG52YXIgSElHSEVSX1BSSU9SSVRZID0gMTI1MDtcclxuXHJcbnZhciBCT1VOREFSWV9UT19IT1NUX1RIUkVTSE9MRCA9IDQwO1xyXG5cclxudmFyIFRBUkdFVF9CT1VORFNfUEFERElORyA9IDIwLFxyXG4gICAgVEFTS19CT1VORFNfUEFERElORyA9IDEwO1xyXG5cclxudmFyIFRBUkdFVF9DRU5URVJfUEFERElORyA9IDIwO1xyXG5cclxudmFyIEFYRVMgPSBbICd4JywgJ3knIF07XHJcblxyXG52YXIgYWJzID0gTWF0aC5hYnM7XHJcblxyXG4vKipcclxuICogU25hcCBkdXJpbmcgY29ubmVjdC5cclxuICpcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5Db25uZWN0U25hcHBpbmcoZXZlbnRCdXMpIHtcclxuICBldmVudEJ1cy5vbihbXHJcbiAgICAnY29ubmVjdC5ob3ZlcicsXHJcbiAgICAnY29ubmVjdC5tb3ZlJyxcclxuICAgICdjb25uZWN0LmVuZCcsXHJcbiAgXSwgSElHSEVSX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIGNhbkV4ZWN1dGUgPSBjb250ZXh0LmNhbkV4ZWN1dGUsXHJcbiAgICAgICAgc3RhcnQgPSBjb250ZXh0LnN0YXJ0LFxyXG4gICAgICAgIGhvdmVyID0gY29udGV4dC5ob3ZlcixcclxuICAgICAgICBzb3VyY2UgPSBjb250ZXh0LnNvdXJjZSxcclxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcclxuXHJcbiAgICAvLyBkbyBOT1Qgc25hcCBvbiBDTURcclxuICAgIGlmIChldmVudC5vcmlnaW5hbEV2ZW50ICYmIGlzQ21kKGV2ZW50Lm9yaWdpbmFsRXZlbnQpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWNvbnRleHQuaW5pdGlhbENvbm5lY3Rpb25TdGFydCkge1xyXG4gICAgICBjb250ZXh0LmluaXRpYWxDb25uZWN0aW9uU3RhcnQgPSBjb250ZXh0LmNvbm5lY3Rpb25TdGFydDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBzbmFwIGhvdmVyXHJcbiAgICBpZiAoY2FuRXhlY3V0ZSAmJiBob3Zlcikge1xyXG4gICAgICBzbmFwVG9TaGFwZShldmVudCwgaG92ZXIsIGdldFRhcmdldEJvdW5kc1BhZGRpbmcoaG92ZXIpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaG92ZXIgJiYgaXNBbnlUeXBlKGNhbkV4ZWN1dGUsIFtcclxuICAgICAgJ2JwbW46QXNzb2NpYXRpb24nLFxyXG4gICAgICAnYnBtbjpEYXRhSW5wdXRBc3NvY2lhdGlvbicsXHJcbiAgICAgICdicG1uOkRhdGFPdXRwdXRBc3NvY2lhdGlvbicsXHJcbiAgICAgICdicG1uOlNlcXVlbmNlRmxvdydcclxuICAgIF0pKSB7XHJcbiAgICAgIGNvbnRleHQuY29ubmVjdGlvblN0YXJ0ID0gbWlkKHN0YXJ0KTtcclxuXHJcbiAgICAgIC8vIHNuYXAgaG92ZXJcclxuICAgICAgaWYgKGlzQW55KGhvdmVyLCBbICdicG1uOkV2ZW50JywgJ2JwbW46R2F0ZXdheScgXSkpIHtcclxuICAgICAgICBzbmFwVG9Qb3NpdGlvbihldmVudCwgbWlkKGhvdmVyKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHNuYXAgaG92ZXJcclxuICAgICAgaWYgKGlzQW55KGhvdmVyLCBbICdicG1uOlRhc2snLCAnYnBtbjpTdWJQcm9jZXNzJyBdKSkge1xyXG4gICAgICAgIHNuYXBUb1RhcmdldE1pZChldmVudCwgaG92ZXIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBzbmFwIHNvdXJjZSBhbmQgdGFyZ2V0XHJcbiAgICAgIGlmIChpcyhzb3VyY2UsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJiB0YXJnZXQgPT09IHNvdXJjZS5ob3N0KSB7XHJcbiAgICAgICAgc25hcEJvdW5kYXJ5RXZlbnRMb29wKGV2ZW50KTtcclxuICAgICAgfVxyXG5cclxuICAgIH0gZWxzZSBpZiAoaXNUeXBlKGNhbkV4ZWN1dGUsICdicG1uOk1lc3NhZ2VGbG93JykpIHtcclxuXHJcbiAgICAgIGlmIChpcyhzdGFydCwgJ2JwbW46RXZlbnQnKSkge1xyXG5cclxuICAgICAgICAvLyBzbmFwIHN0YXJ0XHJcbiAgICAgICAgY29udGV4dC5jb25uZWN0aW9uU3RhcnQgPSBtaWQoc3RhcnQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXMoaG92ZXIsICdicG1uOkV2ZW50JykpIHtcclxuXHJcbiAgICAgICAgLy8gc25hcCBob3ZlclxyXG4gICAgICAgIHNuYXBUb1Bvc2l0aW9uKGV2ZW50LCBtaWQoaG92ZXIpKTtcclxuICAgICAgfVxyXG5cclxuICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAvLyB1bi1zbmFwIHNvdXJjZVxyXG4gICAgICBjb250ZXh0LmNvbm5lY3Rpb25TdGFydCA9IGNvbnRleHQuaW5pdGlhbENvbm5lY3Rpb25TdGFydDtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuQnBtbkNvbm5lY3RTbmFwcGluZy4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07XHJcblxyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG4vLyBzbmFwIHRvIHRhcmdldCBpZiBldmVudCBpbiB0YXJnZXRcclxuZnVuY3Rpb24gc25hcFRvU2hhcGUoZXZlbnQsIHRhcmdldCwgcGFkZGluZykge1xyXG4gIEFYRVMuZm9yRWFjaChmdW5jdGlvbihheGlzKSB7XHJcbiAgICB2YXIgZGltZW5zaW9uRm9yQXhpcyA9IGdldERpbWVuc2lvbkZvckF4aXMoYXhpcywgdGFyZ2V0KTtcclxuXHJcbiAgICBpZiAoZXZlbnRbIGF4aXMgXSA8IHRhcmdldFsgYXhpcyBdICsgcGFkZGluZykge1xyXG4gICAgICBzZXRTbmFwcGVkKGV2ZW50LCBheGlzLCB0YXJnZXRbIGF4aXMgXSArIHBhZGRpbmcpO1xyXG4gICAgfSBlbHNlIGlmIChldmVudFsgYXhpcyBdID4gdGFyZ2V0WyBheGlzIF0gKyBkaW1lbnNpb25Gb3JBeGlzIC0gcGFkZGluZykge1xyXG4gICAgICBzZXRTbmFwcGVkKGV2ZW50LCBheGlzLCB0YXJnZXRbIGF4aXMgXSArIGRpbWVuc2lvbkZvckF4aXMgLSBwYWRkaW5nKTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuLy8gc25hcCB0byB0YXJnZXQgbWlkIGlmIGV2ZW50IGluIHRhcmdldCBtaWRcclxuZnVuY3Rpb24gc25hcFRvVGFyZ2V0TWlkKGV2ZW50LCB0YXJnZXQpIHtcclxuICB2YXIgdGFyZ2V0TWlkID0gbWlkKHRhcmdldCk7XHJcblxyXG4gIEFYRVMuZm9yRWFjaChmdW5jdGlvbihheGlzKSB7XHJcbiAgICBpZiAoaXNNaWQoZXZlbnQsIHRhcmdldCwgYXhpcykpIHtcclxuICAgICAgc2V0U25hcHBlZChldmVudCwgYXhpcywgdGFyZ2V0TWlkWyBheGlzIF0pO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG4vLyBzbmFwIHRvIHByZXZlbnQgbG9vcCBvdmVybGFwcGluZyBib3VuZGFyeSBldmVudFxyXG5mdW5jdGlvbiBzbmFwQm91bmRhcnlFdmVudExvb3AoZXZlbnQpIHtcclxuICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxyXG4gICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcclxuXHJcbiAgaWYgKGlzUmV2ZXJzZShjb250ZXh0KSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIHNvdXJjZU1pZCA9IG1pZChzb3VyY2UpLFxyXG4gICAgICBvcmllbnRhdGlvbiA9IGdldE9yaWVudGF0aW9uKHNvdXJjZU1pZCwgdGFyZ2V0LCAtMTApLFxyXG4gICAgICBheGVzID0gW107XHJcblxyXG4gIGlmICgvdG9wfGJvdHRvbS8udGVzdChvcmllbnRhdGlvbikpIHtcclxuICAgIGF4ZXMucHVzaCgneCcpO1xyXG4gIH1cclxuXHJcbiAgaWYgKC9sZWZ0fHJpZ2h0Ly50ZXN0KG9yaWVudGF0aW9uKSkge1xyXG4gICAgYXhlcy5wdXNoKCd5Jyk7XHJcbiAgfVxyXG5cclxuICBheGVzLmZvckVhY2goZnVuY3Rpb24oYXhpcykge1xyXG4gICAgdmFyIGNvb3JkaW5hdGUgPSBldmVudFsgYXhpcyBdLCBuZXdDb29yZGluYXRlO1xyXG5cclxuICAgIGlmIChhYnMoY29vcmRpbmF0ZSAtIHNvdXJjZU1pZFsgYXhpcyBdKSA8IEJPVU5EQVJZX1RPX0hPU1RfVEhSRVNIT0xEKSB7XHJcbiAgICAgIGlmIChjb29yZGluYXRlID4gc291cmNlTWlkWyBheGlzIF0pIHtcclxuICAgICAgICBuZXdDb29yZGluYXRlID0gc291cmNlTWlkWyBheGlzIF0gKyBCT1VOREFSWV9UT19IT1NUX1RIUkVTSE9MRDtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICBuZXdDb29yZGluYXRlID0gc291cmNlTWlkWyBheGlzIF0gLSBCT1VOREFSWV9UT19IT1NUX1RIUkVTSE9MRDtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2V0U25hcHBlZChldmVudCwgYXhpcywgbmV3Q29vcmRpbmF0ZSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNuYXBUb1Bvc2l0aW9uKGV2ZW50LCBwb3NpdGlvbikge1xyXG4gIHNldFNuYXBwZWQoZXZlbnQsICd4JywgcG9zaXRpb24ueCk7XHJcbiAgc2V0U25hcHBlZChldmVudCwgJ3knLCBwb3NpdGlvbi55KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNUeXBlKGF0dHJzLCB0eXBlKSB7XHJcbiAgcmV0dXJuIGF0dHJzICYmIGF0dHJzLnR5cGUgPT09IHR5cGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzQW55VHlwZShhdHRycywgdHlwZXMpIHtcclxuICByZXR1cm4gc29tZSh0eXBlcywgZnVuY3Rpb24odHlwZSkge1xyXG4gICAgcmV0dXJuIGlzVHlwZShhdHRycywgdHlwZSk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldERpbWVuc2lvbkZvckF4aXMoYXhpcywgZWxlbWVudCkge1xyXG4gIHJldHVybiBheGlzID09PSAneCcgPyBlbGVtZW50LndpZHRoIDogZWxlbWVudC5oZWlnaHQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldFRhcmdldEJvdW5kc1BhZGRpbmcodGFyZ2V0KSB7XHJcbiAgaWYgKGlzKHRhcmdldCwgJ2JwbW46VGFzaycpKSB7XHJcbiAgICByZXR1cm4gVEFTS19CT1VORFNfUEFERElORztcclxuICB9IGVsc2Uge1xyXG4gICAgcmV0dXJuIFRBUkdFVF9CT1VORFNfUEFERElORztcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTWlkKGV2ZW50LCB0YXJnZXQsIGF4aXMpIHtcclxuICByZXR1cm4gZXZlbnRbIGF4aXMgXSA+IHRhcmdldFsgYXhpcyBdICsgVEFSR0VUX0NFTlRFUl9QQURESU5HXHJcbiAgICAmJiBldmVudFsgYXhpcyBdIDwgdGFyZ2V0WyBheGlzIF0gKyBnZXREaW1lbnNpb25Gb3JBeGlzKGF4aXMsIHRhcmdldCkgLSBUQVJHRVRfQ0VOVEVSX1BBRERJTkc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzUmV2ZXJzZShjb250ZXh0KSB7XHJcbiAgdmFyIGhvdmVyID0gY29udGV4dC5ob3ZlcixcclxuICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2U7XHJcblxyXG4gIHJldHVybiBob3ZlciAmJiBzb3VyY2UgJiYgaG92ZXIgPT09IHNvdXJjZTtcclxufSIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDcmVhdGVNb3ZlU25hcHBpbmcgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc25hcHBpbmcvQ3JlYXRlTW92ZVNuYXBwaW5nJztcblxuaW1wb3J0IHtcbiAgaXNTbmFwcGVkLFxuICBzZXRTbmFwcGVkLFxuICB0b3BMZWZ0LFxuICBib3R0b21SaWdodFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwVXRpbCc7XG5cbmltcG9ydCB7IGlzRXhwYW5kZWQgfSBmcm9tICcuLi8uLi91dGlsL0RpVXRpbCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBhc1RSQkwsXG4gIGdldE1pZFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7IGdldEJvdW5kYXJ5QXR0YWNobWVudCB9IGZyb20gJy4vQnBtblNuYXBwaW5nVXRpbCc7XG5cbmltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cbnZhciBISUdIX1BSSU9SSVRZID0gMTUwMDtcblxuXG4vKipcbiAqIFNuYXAgZHVyaW5nIGNyZWF0ZSBhbmQgbW92ZS5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtJbmplY3Rvcn0gaW5qZWN0b3JcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkNyZWF0ZU1vdmVTbmFwcGluZyhldmVudEJ1cywgaW5qZWN0b3IpIHtcbiAgaW5qZWN0b3IuaW52b2tlKENyZWF0ZU1vdmVTbmFwcGluZywgdGhpcyk7XG5cbiAgLy8gY3JlYXRpbmcgZmlyc3QgcGFydGljaXBhbnRcbiAgZXZlbnRCdXMub24oWyAnY3JlYXRlLm1vdmUnLCAnY3JlYXRlLmVuZCcgXSwgSElHSF9QUklPUklUWSwgc2V0U25hcHBlZElmQ29uc3RyYWluZWQpO1xuXG4gIC8vIHNuYXAgYm91bmRhcnkgZXZlbnRzXG4gIGV2ZW50QnVzLm9uKFtcbiAgICAnY3JlYXRlLm1vdmUnLFxuICAgICdjcmVhdGUuZW5kJyxcbiAgICAnc2hhcGUubW92ZS5tb3ZlJyxcbiAgICAnc2hhcGUubW92ZS5lbmQnXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIHZhciBjYW5BdHRhY2ggPSBjYW5FeGVjdXRlICYmIChjYW5FeGVjdXRlID09PSAnYXR0YWNoJyB8fCBjYW5FeGVjdXRlLmF0dGFjaCk7XG5cbiAgICBpZiAoY2FuQXR0YWNoICYmICFpc1NuYXBwZWQoZXZlbnQpKSB7XG4gICAgICBzbmFwQm91bmRhcnlFdmVudChldmVudCwgdGFyZ2V0KTtcbiAgICB9XG4gIH0pO1xufVxuXG5pbmhlcml0cyhCcG1uQ3JlYXRlTW92ZVNuYXBwaW5nLCBDcmVhdGVNb3ZlU25hcHBpbmcpO1xuXG5CcG1uQ3JlYXRlTW92ZVNuYXBwaW5nLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdpbmplY3Rvcidcbl07XG5cbkJwbW5DcmVhdGVNb3ZlU25hcHBpbmcucHJvdG90eXBlLmluaXRTbmFwID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdmFyIHNuYXBDb250ZXh0ID0gQ3JlYXRlTW92ZVNuYXBwaW5nLnByb3RvdHlwZS5pbml0U25hcC5jYWxsKHRoaXMsIGV2ZW50KTtcblxuICB2YXIgc2hhcGUgPSBldmVudC5zaGFwZTtcblxuICB2YXIgaXNNb3ZlID0gISF0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0KHNoYXBlLmlkKTtcblxuICAvLyBzbmFwIHRvIGRvY2tpbmcgcG9pbnRzXG4gIGZvckVhY2goc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgZG9ja2luZyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzWzBdO1xuXG4gICAgZG9ja2luZyA9IGRvY2tpbmcub3JpZ2luYWwgfHwgZG9ja2luZztcblxuICAgIHNuYXBDb250ZXh0LnNldFNuYXBPcmlnaW4oY29ubmVjdGlvbi5pZCArICctZG9ja2luZycsIGdldERvY2tpbmdTbmFwT3JpZ2luKGRvY2tpbmcsIGlzTW92ZSwgZXZlbnQpKTtcbiAgfSk7XG5cbiAgZm9yRWFjaChzaGFwZS5pbmNvbWluZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgIHZhciBkb2NraW5nID0gY29ubmVjdGlvbi53YXlwb2ludHNbY29ubmVjdGlvbi53YXlwb2ludHMubGVuZ3RoIC0gMV07XG5cbiAgICBkb2NraW5nID0gZG9ja2luZy5vcmlnaW5hbCB8fCBkb2NraW5nO1xuXG4gICAgc25hcENvbnRleHQuc2V0U25hcE9yaWdpbihjb25uZWN0aW9uLmlkICsgJy1kb2NraW5nJywgZ2V0RG9ja2luZ1NuYXBPcmlnaW4oZG9ja2luZywgaXNNb3ZlLCBldmVudCkpO1xuICB9KTtcblxuICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykpIHtcblxuICAgIC8vIHNuYXAgdG8gYm9yZGVycyB3aXRoIGhpZ2hlciBwcmlvcml0eVxuICAgIHNuYXBDb250ZXh0LnNldFNuYXBMb2NhdGlvbnMoWyAndG9wLWxlZnQnLCAnYm90dG9tLXJpZ2h0JywgJ21pZCcgXSk7XG4gIH1cblxuICByZXR1cm4gc25hcENvbnRleHQ7XG59O1xuXG5CcG1uQ3JlYXRlTW92ZVNuYXBwaW5nLnByb3RvdHlwZS5hZGRTbmFwVGFyZ2V0UG9pbnRzID0gZnVuY3Rpb24oc25hcFBvaW50cywgc2hhcGUsIHRhcmdldCkge1xuICBDcmVhdGVNb3ZlU25hcHBpbmcucHJvdG90eXBlLmFkZFNuYXBUYXJnZXRQb2ludHMuY2FsbCh0aGlzLCBzbmFwUG9pbnRzLCBzaGFwZSwgdGFyZ2V0KTtcblxuICB2YXIgc25hcFRhcmdldHMgPSB0aGlzLmdldFNuYXBUYXJnZXRzKHNoYXBlLCB0YXJnZXQpO1xuXG4gIGZvckVhY2goc25hcFRhcmdldHMsIGZ1bmN0aW9uKHNuYXBUYXJnZXQpIHtcblxuICAgIC8vIGhhbmRsZSBUUkJMIGFsaWdubWVudFxuICAgIC8vXG4gICAgLy8gKiB3aXRoIGNvbnRhaW5lciBlbGVtZW50c1xuICAgIC8vICogd2l0aCB0ZXh0IGFubm90YXRpb25zXG4gICAgaWYgKGlzQ29udGFpbmVyKHNuYXBUYXJnZXQpIHx8IGFyZUFsbChbIHNoYXBlLCBzbmFwVGFyZ2V0IF0sICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcbiAgICAgIHNuYXBQb2ludHMuYWRkKCd0b3AtbGVmdCcsIHRvcExlZnQoc25hcFRhcmdldCkpO1xuICAgICAgc25hcFBvaW50cy5hZGQoJ2JvdHRvbS1yaWdodCcsIGJvdHRvbVJpZ2h0KHNuYXBUYXJnZXQpKTtcbiAgICB9XG4gIH0pO1xuXG4gIHZhciBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnk7XG5cbiAgLy8gc25hcCB0byBkb2NraW5nIHBvaW50cyBpZiBub3QgY3JlYXRlIG1vZGVcbiAgZm9yRWFjaChzaGFwZS5pbmNvbWluZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgIGlmIChlbGVtZW50UmVnaXN0cnkuZ2V0KHNoYXBlLmlkKSkge1xuXG4gICAgICBpZiAoIWluY2x1ZGVzKHNuYXBUYXJnZXRzLCBjb25uZWN0aW9uLnNvdXJjZSkpIHtcbiAgICAgICAgc25hcFBvaW50cy5hZGQoJ21pZCcsIGdldE1pZChjb25uZWN0aW9uLnNvdXJjZSkpO1xuICAgICAgfVxuXG4gICAgICB2YXIgZG9ja2luZyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzWzBdO1xuICAgICAgc25hcFBvaW50cy5hZGQoY29ubmVjdGlvbi5pZCArICctZG9ja2luZycsIGRvY2tpbmcub3JpZ2luYWwgfHwgZG9ja2luZyk7XG4gICAgfVxuICB9KTtcblxuICBmb3JFYWNoKHNoYXBlLm91dGdvaW5nLCBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gICAgaWYgKGVsZW1lbnRSZWdpc3RyeS5nZXQoc2hhcGUuaWQpKSB7XG5cbiAgICAgIGlmICghaW5jbHVkZXMoc25hcFRhcmdldHMsIGNvbm5lY3Rpb24udGFyZ2V0KSkge1xuICAgICAgICBzbmFwUG9pbnRzLmFkZCgnbWlkJywgZ2V0TWlkKGNvbm5lY3Rpb24udGFyZ2V0KSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBkb2NraW5nID0gY29ubmVjdGlvbi53YXlwb2ludHNbIGNvbm5lY3Rpb24ud2F5cG9pbnRzLmxlbmd0aCAtIDEgXTtcblxuICAgICAgc25hcFBvaW50cy5hZGQoY29ubmVjdGlvbi5pZCArICctZG9ja2luZycsIGRvY2tpbmcub3JpZ2luYWwgfHwgZG9ja2luZyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBhZGQgc2VxdWVuY2UgZmxvdyBwYXJlbnRzIGFzIHNuYXAgdGFyZ2V0c1xuICBpZiAoaXModGFyZ2V0LCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgIHNuYXBQb2ludHMgPSB0aGlzLmFkZFNuYXBUYXJnZXRQb2ludHMoc25hcFBvaW50cywgc2hhcGUsIHRhcmdldC5wYXJlbnQpO1xuICB9XG5cbiAgcmV0dXJuIHNuYXBQb2ludHM7XG59O1xuXG5CcG1uQ3JlYXRlTW92ZVNuYXBwaW5nLnByb3RvdHlwZS5nZXRTbmFwVGFyZ2V0cyA9IGZ1bmN0aW9uKHNoYXBlLCB0YXJnZXQpIHtcbiAgcmV0dXJuIENyZWF0ZU1vdmVTbmFwcGluZy5wcm90b3R5cGUuZ2V0U25hcFRhcmdldHMuY2FsbCh0aGlzLCBzaGFwZSwgdGFyZ2V0KVxuICAgIC5maWx0ZXIoZnVuY3Rpb24oc25hcFRhcmdldCkge1xuXG4gICAgICAvLyBkbyBub3Qgc25hcCB0byBsYW5lc1xuICAgICAgcmV0dXJuICFpcyhzbmFwVGFyZ2V0LCAnYnBtbjpMYW5lJyk7XG4gICAgfSk7XG59O1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gc25hcEJvdW5kYXJ5RXZlbnQoZXZlbnQsIHRhcmdldCkge1xuICB2YXIgdGFyZ2V0VFJCTCA9IGFzVFJCTCh0YXJnZXQpO1xuXG4gIHZhciBkaXJlY3Rpb24gPSBnZXRCb3VuZGFyeUF0dGFjaG1lbnQoZXZlbnQsIHRhcmdldCk7XG5cbiAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gIHZhciBvZmZzZXQ7XG5cbiAgaWYgKHNoYXBlLnBhcmVudCkge1xuICAgIG9mZnNldCA9IHsgeDogMCwgeTogMCB9O1xuICB9IGVsc2Uge1xuICAgIG9mZnNldCA9IGdldE1pZChzaGFwZSk7XG4gIH1cblxuICBpZiAoL3RvcC8udGVzdChkaXJlY3Rpb24pKSB7XG4gICAgc2V0U25hcHBlZChldmVudCwgJ3knLCB0YXJnZXRUUkJMLnRvcCAtIG9mZnNldC55KTtcbiAgfSBlbHNlIGlmICgvYm90dG9tLy50ZXN0KGRpcmVjdGlvbikpIHtcbiAgICBzZXRTbmFwcGVkKGV2ZW50LCAneScsIHRhcmdldFRSQkwuYm90dG9tIC0gb2Zmc2V0LnkpO1xuICB9XG5cbiAgaWYgKC9sZWZ0Ly50ZXN0KGRpcmVjdGlvbikpIHtcbiAgICBzZXRTbmFwcGVkKGV2ZW50LCAneCcsIHRhcmdldFRSQkwubGVmdCAtIG9mZnNldC54KTtcbiAgfSBlbHNlIGlmICgvcmlnaHQvLnRlc3QoZGlyZWN0aW9uKSkge1xuICAgIHNldFNuYXBwZWQoZXZlbnQsICd4JywgdGFyZ2V0VFJCTC5yaWdodCAtIG9mZnNldC54KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhcmVBbGwoZWxlbWVudHMsIHR5cGUpIHtcbiAgcmV0dXJuIGVsZW1lbnRzLmV2ZXJ5KGZ1bmN0aW9uKGVsKSB7XG4gICAgcmV0dXJuIGlzKGVsLCB0eXBlKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzQ29udGFpbmVyKGVsZW1lbnQpIHtcbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJiBpc0V4cGFuZGVkKGVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKTtcbn1cblxuXG5mdW5jdGlvbiBzZXRTbmFwcGVkSWZDb25zdHJhaW5lZChldmVudCkge1xuICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICBjcmVhdGVDb25zdHJhaW50cyA9IGNvbnRleHQuY3JlYXRlQ29uc3RyYWludHM7XG5cbiAgaWYgKCFjcmVhdGVDb25zdHJhaW50cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciB0b3AgPSBjcmVhdGVDb25zdHJhaW50cy50b3AsXG4gICAgICByaWdodCA9IGNyZWF0ZUNvbnN0cmFpbnRzLnJpZ2h0LFxuICAgICAgYm90dG9tID0gY3JlYXRlQ29uc3RyYWludHMuYm90dG9tLFxuICAgICAgbGVmdCA9IGNyZWF0ZUNvbnN0cmFpbnRzLmxlZnQ7XG5cbiAgaWYgKChsZWZ0ICYmIGxlZnQgPj0gZXZlbnQueCkgfHwgKHJpZ2h0ICYmIHJpZ2h0IDw9IGV2ZW50LngpKSB7XG4gICAgc2V0U25hcHBlZChldmVudCwgJ3gnLCBldmVudC54KTtcbiAgfVxuXG4gIGlmICgodG9wICYmIHRvcCA+PSBldmVudC55KSB8fCAoYm90dG9tICYmIGJvdHRvbSA8PSBldmVudC55KSkge1xuICAgIHNldFNuYXBwZWQoZXZlbnQsICd5JywgZXZlbnQueSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5jbHVkZXMoYXJyYXksIHZhbHVlKSB7XG4gIHJldHVybiBhcnJheS5pbmRleE9mKHZhbHVlKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldERvY2tpbmdTbmFwT3JpZ2luKGRvY2tpbmcsIGlzTW92ZSwgZXZlbnQpIHtcbiAgcmV0dXJuIGlzTW92ZSA/IChcbiAgICB7XG4gICAgICB4OiBkb2NraW5nLnggLSBldmVudC54LFxuICAgICAgeTogZG9ja2luZy55IC0gZXZlbnQueVxuICAgIH1cbiAgKSA6IHtcbiAgICB4OiBkb2NraW5nLngsXG4gICAgeTogZG9ja2luZy55XG4gIH07XG59XG4iLCJpbXBvcnQgeyBnZXRPcmllbnRhdGlvbiB9IGZyb20gJ2RpYWdyYW0tanMvbGliL2xheW91dC9MYXlvdXRVdGlsJztcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRCb3VuZGFyeUF0dGFjaG1lbnQocG9zaXRpb24sIHRhcmdldEJvdW5kcykge1xyXG5cclxuICB2YXIgb3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihwb3NpdGlvbiwgdGFyZ2V0Qm91bmRzLCAtMTUpO1xyXG5cclxuICBpZiAob3JpZW50YXRpb24gIT09ICdpbnRlcnNlY3QnKSB7XHJcbiAgICByZXR1cm4gb3JpZW50YXRpb247XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxufSIsImltcG9ydCBCcG1uQ29ubmVjdFNuYXBwaW5nIGZyb20gJy4vQnBtbkNvbm5lY3RTbmFwcGluZyc7XG5pbXBvcnQgQnBtbkNyZWF0ZU1vdmVTbmFwcGluZyBmcm9tICcuL0JwbW5DcmVhdGVNb3ZlU25hcHBpbmcnO1xuaW1wb3J0IFNuYXBwaW5nTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NuYXBwaW5nJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogWyBTbmFwcGluZ01vZHVsZSBdLFxuICBfX2luaXRfXzogW1xuICAgICdjb25uZWN0U25hcHBpbmcnLFxuICAgICdjcmVhdGVNb3ZlU25hcHBpbmcnXG4gIF0sXG4gIGNvbm5lY3RTbmFwcGluZzogWyAndHlwZScsIEJwbW5Db25uZWN0U25hcHBpbmcgXSxcbiAgY3JlYXRlTW92ZVNuYXBwaW5nOiBbICd0eXBlJywgQnBtbkNyZWF0ZU1vdmVTbmFwcGluZyBdXG59OyIsImltcG9ydCB7XG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0xhYmVsRXh0ZXJuYWwsXG4gIGdldEV4dGVybmFsTGFiZWxCb3VuZHNcbn0gZnJvbSAnLi4vdXRpbC9MYWJlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRNaWRcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0V4cGFuZGVkXG59IGZyb20gJy4uL3V0aWwvRGlVdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0TGFiZWxcbn0gZnJvbSAnLi4vZmVhdHVyZXMvbGFiZWwtZWRpdGluZy9MYWJlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBlbGVtZW50VG9TdHJpbmdcbn0gZnJvbSAnLi9VdGlsJztcblxuXG5mdW5jdGlvbiBlbGVtZW50RGF0YShzZW1hbnRpYywgYXR0cnMpIHtcbiAgcmV0dXJuIGFzc2lnbih7XG4gICAgaWQ6IHNlbWFudGljLmlkLFxuICAgIHR5cGU6IHNlbWFudGljLiR0eXBlLFxuICAgIGJ1c2luZXNzT2JqZWN0OiBzZW1hbnRpY1xuICB9LCBhdHRycyk7XG59XG5cbmZ1bmN0aW9uIGdldFdheXBvaW50cyhibywgc291cmNlLCB0YXJnZXQpIHtcblxuICB2YXIgd2F5cG9pbnRzID0gYm8uZGkud2F5cG9pbnQ7XG5cbiAgaWYgKCF3YXlwb2ludHMgfHwgd2F5cG9pbnRzLmxlbmd0aCA8IDIpIHtcbiAgICByZXR1cm4gWyBnZXRNaWQoc291cmNlKSwgZ2V0TWlkKHRhcmdldCkgXTtcbiAgfVxuXG4gIHJldHVybiB3YXlwb2ludHMubWFwKGZ1bmN0aW9uKHApIHtcbiAgICByZXR1cm4geyB4OiBwLngsIHk6IHAueSB9O1xuICB9KTtcbn1cblxuZnVuY3Rpb24gbm90WWV0RHJhd24odHJhbnNsYXRlLCBzZW1hbnRpYywgcmVmU2VtYW50aWMsIHByb3BlcnR5KSB7XG4gIHJldHVybiBuZXcgRXJyb3IodHJhbnNsYXRlKCdlbGVtZW50IHtlbGVtZW50fSByZWZlcmVuY2VkIGJ5IHtyZWZlcmVuY2VkfSN7cHJvcGVydHl9IG5vdCB5ZXQgZHJhd24nLCB7XG4gICAgZWxlbWVudDogZWxlbWVudFRvU3RyaW5nKHJlZlNlbWFudGljKSxcbiAgICByZWZlcmVuY2VkOiBlbGVtZW50VG9TdHJpbmcoc2VtYW50aWMpLFxuICAgIHByb3BlcnR5OiBwcm9wZXJ0eVxuICB9KSk7XG59XG5cblxuLyoqXG4gKiBBbiBpbXBvcnRlciB0aGF0IGFkZHMgYnBtbiBlbGVtZW50cyB0byB0aGUgY2FudmFzXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7RWxlbWVudEZhY3Rvcnl9IGVsZW1lbnRGYWN0b3J5XG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2xhdGVcbiAqIEBwYXJhbSB7VGV4dFJlbmRlcmVyfSB0ZXh0UmVuZGVyZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkltcG9ydGVyKFxuICAgIGV2ZW50QnVzLCBjYW52YXMsIGVsZW1lbnRGYWN0b3J5LFxuICAgIGVsZW1lbnRSZWdpc3RyeSwgdHJhbnNsYXRlLCB0ZXh0UmVuZGVyZXIpIHtcblxuICB0aGlzLl9ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX2VsZW1lbnRGYWN0b3J5ID0gZWxlbWVudEZhY3Rvcnk7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbiAgdGhpcy5fdHJhbnNsYXRlID0gdHJhbnNsYXRlO1xuICB0aGlzLl90ZXh0UmVuZGVyZXIgPSB0ZXh0UmVuZGVyZXI7XG59XG5cbkJwbW5JbXBvcnRlci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXG4gICd0cmFuc2xhdGUnLFxuICAndGV4dFJlbmRlcmVyJ1xuXTtcblxuXG4vKipcbiAqIEFkZCBicG1uIGVsZW1lbnQgKHNlbWFudGljKSB0byB0aGUgY2FudmFzIG9udG8gdGhlXG4gKiBzcGVjaWZpZWQgcGFyZW50IHNoYXBlLlxuICovXG5CcG1uSW1wb3J0ZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKHNlbWFudGljLCBwYXJlbnRFbGVtZW50KSB7XG5cbiAgdmFyIGRpID0gc2VtYW50aWMuZGksXG4gICAgICBlbGVtZW50LFxuICAgICAgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlLFxuICAgICAgaGlkZGVuO1xuXG4gIHZhciBwYXJlbnRJbmRleDtcblxuICAvLyBST09UIEVMRU1FTlRcbiAgLy8gaGFuZGxlIHRoZSBzcGVjaWFsIGNhc2UgdGhhdCB3ZSBkZWFsIHdpdGggYVxuICAvLyBpbnZpc2libGUgcm9vdCBlbGVtZW50IChwcm9jZXNzIG9yIGNvbGxhYm9yYXRpb24pXG4gIGlmIChpcyhkaSwgJ2JwbW5kaTpCUE1OUGxhbmUnKSkge1xuXG4gICAgLy8gYWRkIGEgdmlydHVhbCBlbGVtZW50IChub3QgYmVpbmcgZHJhd24pXG4gICAgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRGYWN0b3J5LmNyZWF0ZVJvb3QoZWxlbWVudERhdGEoc2VtYW50aWMpKTtcblxuICAgIHRoaXMuX2NhbnZhcy5zZXRSb290RWxlbWVudChlbGVtZW50KTtcbiAgfVxuXG4gIC8vIFNIQVBFXG4gIGVsc2UgaWYgKGlzKGRpLCAnYnBtbmRpOkJQTU5TaGFwZScpKSB7XG5cbiAgICB2YXIgY29sbGFwc2VkID0gIWlzRXhwYW5kZWQoc2VtYW50aWMpLFxuICAgICAgICBpc0ZyYW1lID0gaXNGcmFtZUVsZW1lbnQoc2VtYW50aWMpO1xuICAgIGhpZGRlbiA9IHBhcmVudEVsZW1lbnQgJiYgKHBhcmVudEVsZW1lbnQuaGlkZGVuIHx8IHBhcmVudEVsZW1lbnQuY29sbGFwc2VkKTtcblxuICAgIHZhciBib3VuZHMgPSBzZW1hbnRpYy5kaS5ib3VuZHM7XG5cbiAgICBlbGVtZW50ID0gdGhpcy5fZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoZWxlbWVudERhdGEoc2VtYW50aWMsIHtcbiAgICAgIGNvbGxhcHNlZDogY29sbGFwc2VkLFxuICAgICAgaGlkZGVuOiBoaWRkZW4sXG4gICAgICB4OiBNYXRoLnJvdW5kKGJvdW5kcy54KSxcbiAgICAgIHk6IE1hdGgucm91bmQoYm91bmRzLnkpLFxuICAgICAgd2lkdGg6IE1hdGgucm91bmQoYm91bmRzLndpZHRoKSxcbiAgICAgIGhlaWdodDogTWF0aC5yb3VuZChib3VuZHMuaGVpZ2h0KSxcbiAgICAgIGlzRnJhbWU6IGlzRnJhbWVcbiAgICB9KSk7XG5cbiAgICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSkge1xuICAgICAgdGhpcy5fYXR0YWNoQm91bmRhcnkoc2VtYW50aWMsIGVsZW1lbnQpO1xuICAgIH1cblxuICAgIC8vIGluc2VydCBsYW5lcyBiZWhpbmQgb3RoZXIgZmxvdyBub2RlcyAoY2YuICM3MjcpXG4gICAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpMYW5lJykpIHtcbiAgICAgIHBhcmVudEluZGV4ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpKSB7XG5cbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgZGF0YSBzdG9yZSBpcyBpbnNpZGUgb3VyIG91dHNpZGUgb2YgaXRzIHNlbWFudGljIHBhcmVudFxuICAgICAgaWYgKCFpc1BvaW50SW5zaWRlQkJveChwYXJlbnRFbGVtZW50LCBnZXRNaWQoYm91bmRzKSkpIHtcbiAgICAgICAgcGFyZW50RWxlbWVudCA9IHRoaXMuX2NhbnZhcy5nZXRSb290RWxlbWVudCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2NhbnZhcy5hZGRTaGFwZShlbGVtZW50LCBwYXJlbnRFbGVtZW50LCBwYXJlbnRJbmRleCk7XG4gIH1cblxuICAvLyBDT05ORUNUSU9OXG4gIGVsc2UgaWYgKGlzKGRpLCAnYnBtbmRpOkJQTU5FZGdlJykpIHtcblxuICAgIHZhciBzb3VyY2UgPSB0aGlzLl9nZXRTb3VyY2Uoc2VtYW50aWMpLFxuICAgICAgICB0YXJnZXQgPSB0aGlzLl9nZXRUYXJnZXQoc2VtYW50aWMpO1xuXG4gICAgaGlkZGVuID0gcGFyZW50RWxlbWVudCAmJiAocGFyZW50RWxlbWVudC5oaWRkZW4gfHwgcGFyZW50RWxlbWVudC5jb2xsYXBzZWQpO1xuXG4gICAgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRGYWN0b3J5LmNyZWF0ZUNvbm5lY3Rpb24oZWxlbWVudERhdGEoc2VtYW50aWMsIHtcbiAgICAgIGhpZGRlbjogaGlkZGVuLFxuICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICAgIHdheXBvaW50czogZ2V0V2F5cG9pbnRzKHNlbWFudGljLCBzb3VyY2UsIHRhcmdldClcbiAgICB9KSk7XG5cbiAgICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkRhdGFBc3NvY2lhdGlvbicpKSB7XG5cbiAgICAgIC8vIHJlbmRlciBhbHdheXMgb24gdG9wOyB0aGlzIGVuc3VyZXMgRGF0YUFzc29jaWF0aW9uc1xuICAgICAgLy8gYXJlIHJlbmRlcmVkIGNvcnJlY3RseSBhY3Jvc3MgZGlmZmVyZW50IFwiaGFja3NcIiBwZW9wbGVcbiAgICAgIC8vIGxvdmUgdG8gbW9kZWwgc3VjaCBhcyBjcm9zcyBwYXJ0aWNpcGFudCAvIHN1YiBwcm9jZXNzXG4gICAgICAvLyBhc3NvY2lhdGlvbnNcbiAgICAgIHBhcmVudEVsZW1lbnQgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIGluc2VydCBzZXF1ZW5jZSBmbG93cyBiZWhpbmQgb3RoZXIgZmxvdyBub2RlcyAoY2YuICM3MjcpXG4gICAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgICAgcGFyZW50SW5kZXggPSAwO1xuICAgIH1cblxuICAgIHRoaXMuX2NhbnZhcy5hZGRDb25uZWN0aW9uKGVsZW1lbnQsIHBhcmVudEVsZW1lbnQsIHBhcmVudEluZGV4KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodHJhbnNsYXRlKCd1bmtub3duIGRpIHtkaX0gZm9yIGVsZW1lbnQge3NlbWFudGljfScsIHtcbiAgICAgIGRpOiBlbGVtZW50VG9TdHJpbmcoZGkpLFxuICAgICAgc2VtYW50aWM6IGVsZW1lbnRUb1N0cmluZyhzZW1hbnRpYylcbiAgICB9KSk7XG4gIH1cblxuICAvLyAob3B0aW9uYWwpIExBQkVMXG4gIGlmIChpc0xhYmVsRXh0ZXJuYWwoc2VtYW50aWMpICYmIGdldExhYmVsKGVsZW1lbnQpKSB7XG4gICAgdGhpcy5hZGRMYWJlbChzZW1hbnRpYywgZWxlbWVudCk7XG4gIH1cblxuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ2JwbW5FbGVtZW50LmFkZGVkJywgeyBlbGVtZW50OiBlbGVtZW50IH0pO1xuXG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuXG4vKipcbiAqIEF0dGFjaCB0aGUgYm91bmRhcnkgZWxlbWVudCB0byB0aGUgZ2l2ZW4gaG9zdFxuICpcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gYm91bmRhcnlTZW1hbnRpY1xuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gYm91bmRhcnlFbGVtZW50XG4gKi9cbkJwbW5JbXBvcnRlci5wcm90b3R5cGUuX2F0dGFjaEJvdW5kYXJ5ID0gZnVuY3Rpb24oYm91bmRhcnlTZW1hbnRpYywgYm91bmRhcnlFbGVtZW50KSB7XG4gIHZhciB0cmFuc2xhdGUgPSB0aGlzLl90cmFuc2xhdGU7XG4gIHZhciBob3N0U2VtYW50aWMgPSBib3VuZGFyeVNlbWFudGljLmF0dGFjaGVkVG9SZWY7XG5cbiAgaWYgKCFob3N0U2VtYW50aWMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodHJhbnNsYXRlKCdtaXNzaW5nIHtzZW1hbnRpY30jYXR0YWNoZWRUb1JlZicsIHtcbiAgICAgIHNlbWFudGljOiBlbGVtZW50VG9TdHJpbmcoYm91bmRhcnlTZW1hbnRpYylcbiAgICB9KSk7XG4gIH1cblxuICB2YXIgaG9zdCA9IHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXQoaG9zdFNlbWFudGljLmlkKSxcbiAgICAgIGF0dGFjaGVycyA9IGhvc3QgJiYgaG9zdC5hdHRhY2hlcnM7XG5cbiAgaWYgKCFob3N0KSB7XG4gICAgdGhyb3cgbm90WWV0RHJhd24odHJhbnNsYXRlLCBib3VuZGFyeVNlbWFudGljLCBob3N0U2VtYW50aWMsICdhdHRhY2hlZFRvUmVmJyk7XG4gIH1cblxuICAvLyB3aXJlIGVsZW1lbnQuaG9zdCA8PiBob3N0LmF0dGFjaGVyc1xuICBib3VuZGFyeUVsZW1lbnQuaG9zdCA9IGhvc3Q7XG5cbiAgaWYgKCFhdHRhY2hlcnMpIHtcbiAgICBob3N0LmF0dGFjaGVycyA9IGF0dGFjaGVycyA9IFtdO1xuICB9XG5cbiAgaWYgKGF0dGFjaGVycy5pbmRleE9mKGJvdW5kYXJ5RWxlbWVudCkgPT09IC0xKSB7XG4gICAgYXR0YWNoZXJzLnB1c2goYm91bmRhcnlFbGVtZW50KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIGFkZCBsYWJlbCBmb3IgYW4gZWxlbWVudFxuICovXG5CcG1uSW1wb3J0ZXIucHJvdG90eXBlLmFkZExhYmVsID0gZnVuY3Rpb24oc2VtYW50aWMsIGVsZW1lbnQpIHtcbiAgdmFyIGJvdW5kcyxcbiAgICAgIHRleHQsXG4gICAgICBsYWJlbDtcblxuICBib3VuZHMgPSBnZXRFeHRlcm5hbExhYmVsQm91bmRzKHNlbWFudGljLCBlbGVtZW50KTtcblxuICB0ZXh0ID0gZ2V0TGFiZWwoZWxlbWVudCk7XG5cbiAgaWYgKHRleHQpIHtcblxuICAgIC8vIGdldCBjb3JyZWN0ZWQgYm91bmRzIGZyb20gYWN0dWFsIGxheW91dGVkIHRleHRcbiAgICBib3VuZHMgPSB0aGlzLl90ZXh0UmVuZGVyZXIuZ2V0RXh0ZXJuYWxMYWJlbEJvdW5kcyhib3VuZHMsIHRleHQpO1xuICB9XG5cbiAgbGFiZWwgPSB0aGlzLl9lbGVtZW50RmFjdG9yeS5jcmVhdGVMYWJlbChlbGVtZW50RGF0YShzZW1hbnRpYywge1xuICAgIGlkOiBzZW1hbnRpYy5pZCArICdfbGFiZWwnLFxuICAgIGxhYmVsVGFyZ2V0OiBlbGVtZW50LFxuICAgIHR5cGU6ICdsYWJlbCcsXG4gICAgaGlkZGVuOiBlbGVtZW50LmhpZGRlbiB8fCAhZ2V0TGFiZWwoZWxlbWVudCksXG4gICAgeDogTWF0aC5yb3VuZChib3VuZHMueCksXG4gICAgeTogTWF0aC5yb3VuZChib3VuZHMueSksXG4gICAgd2lkdGg6IE1hdGgucm91bmQoYm91bmRzLndpZHRoKSxcbiAgICBoZWlnaHQ6IE1hdGgucm91bmQoYm91bmRzLmhlaWdodClcbiAgfSkpO1xuXG4gIHJldHVybiB0aGlzLl9jYW52YXMuYWRkU2hhcGUobGFiZWwsIGVsZW1lbnQucGFyZW50KTtcbn07XG5cbi8qKlxuICogUmV0dXJuIHRoZSBkcmF3biBjb25uZWN0aW9uIGVuZCBiYXNlZCBvbiB0aGUgZ2l2ZW4gc2lkZS5cbiAqXG4gKiBAdGhyb3dzIHtFcnJvcn0gaWYgdGhlIGVuZCBpcyBub3QgeWV0IGRyYXduXG4gKi9cbkJwbW5JbXBvcnRlci5wcm90b3R5cGUuX2dldEVuZCA9IGZ1bmN0aW9uKHNlbWFudGljLCBzaWRlKSB7XG5cbiAgdmFyIGVsZW1lbnQsXG4gICAgICByZWZTZW1hbnRpYyxcbiAgICAgIHR5cGUgPSBzZW1hbnRpYy4kdHlwZSxcbiAgICAgIHRyYW5zbGF0ZSA9IHRoaXMuX3RyYW5zbGF0ZTtcblxuICByZWZTZW1hbnRpYyA9IHNlbWFudGljW3NpZGUgKyAnUmVmJ107XG5cbiAgLy8gaGFuZGxlIG15c3RlcmlvdXMgaXNNYW55IERhdGFBc3NvY2lhdGlvbiNzb3VyY2VSZWZcbiAgaWYgKHNpZGUgPT09ICdzb3VyY2UnICYmIHR5cGUgPT09ICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJykge1xuICAgIHJlZlNlbWFudGljID0gcmVmU2VtYW50aWMgJiYgcmVmU2VtYW50aWNbMF07XG4gIH1cblxuICAvLyBmaXggc291cmNlIC8gdGFyZ2V0IGZvciBEYXRhSW5wdXRBc3NvY2lhdGlvbiAvIERhdGFPdXRwdXRBc3NvY2lhdGlvblxuICBpZiAoc2lkZSA9PT0gJ3NvdXJjZScgJiYgdHlwZSA9PT0gJ2JwbW46RGF0YU91dHB1dEFzc29jaWF0aW9uJyB8fFxuICAgICAgc2lkZSA9PT0gJ3RhcmdldCcgJiYgdHlwZSA9PT0gJ2JwbW46RGF0YUlucHV0QXNzb2NpYXRpb24nKSB7XG5cbiAgICByZWZTZW1hbnRpYyA9IHNlbWFudGljLiRwYXJlbnQ7XG4gIH1cblxuICBlbGVtZW50ID0gcmVmU2VtYW50aWMgJiYgdGhpcy5fZ2V0RWxlbWVudChyZWZTZW1hbnRpYyk7XG5cbiAgaWYgKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIGlmIChyZWZTZW1hbnRpYykge1xuICAgIHRocm93IG5vdFlldERyYXduKHRyYW5zbGF0ZSwgc2VtYW50aWMsIHJlZlNlbWFudGljLCBzaWRlICsgJ1JlZicpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcih0cmFuc2xhdGUoJ3tzZW1hbnRpY30je3NpZGV9IFJlZiBub3Qgc3BlY2lmaWVkJywge1xuICAgICAgc2VtYW50aWM6IGVsZW1lbnRUb1N0cmluZyhzZW1hbnRpYyksXG4gICAgICBzaWRlOiBzaWRlXG4gICAgfSkpO1xuICB9XG59O1xuXG5CcG1uSW1wb3J0ZXIucHJvdG90eXBlLl9nZXRTb3VyY2UgPSBmdW5jdGlvbihzZW1hbnRpYykge1xuICByZXR1cm4gdGhpcy5fZ2V0RW5kKHNlbWFudGljLCAnc291cmNlJyk7XG59O1xuXG5CcG1uSW1wb3J0ZXIucHJvdG90eXBlLl9nZXRUYXJnZXQgPSBmdW5jdGlvbihzZW1hbnRpYykge1xuICByZXR1cm4gdGhpcy5fZ2V0RW5kKHNlbWFudGljLCAndGFyZ2V0Jyk7XG59O1xuXG5cbkJwbW5JbXBvcnRlci5wcm90b3R5cGUuX2dldEVsZW1lbnQgPSBmdW5jdGlvbihzZW1hbnRpYykge1xuICByZXR1cm4gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldChzZW1hbnRpYy5pZCk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNQb2ludEluc2lkZUJCb3goYmJveCwgcG9pbnQpIHtcbiAgdmFyIHggPSBwb2ludC54LFxuICAgICAgeSA9IHBvaW50Lnk7XG5cbiAgcmV0dXJuIHggPj0gYmJveC54ICYmXG4gICAgeCA8PSBiYm94LnggKyBiYm94LndpZHRoICYmXG4gICAgeSA+PSBiYm94LnkgJiZcbiAgICB5IDw9IGJib3gueSArIGJib3guaGVpZ2h0O1xufVxuXG5mdW5jdGlvbiBpc0ZyYW1lRWxlbWVudChzZW1hbnRpYykge1xuICByZXR1cm4gaXMoc2VtYW50aWMsICdicG1uOkdyb3VwJyk7XG59IiwiaW1wb3J0IHtcbiAgZmlsdGVyLFxuICBmaW5kLFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IFJlZnMgZnJvbSAnb2JqZWN0LXJlZnMnO1xuXG5pbXBvcnQge1xuICBlbGVtZW50VG9TdHJpbmdcbn0gZnJvbSAnLi9VdGlsJztcblxudmFyIGRpUmVmcyA9IG5ldyBSZWZzKFxuICB7IG5hbWU6ICdicG1uRWxlbWVudCcsIGVudW1lcmFibGU6IHRydWUgfSxcbiAgeyBuYW1lOiAnZGknLCBjb25maWd1cmFibGU6IHRydWUgfVxuKTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgYW4gZWxlbWVudCBoYXMgdGhlIGdpdmVuIG1ldGEtbW9kZWwgdHlwZVxuICpcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnR9ICBlbGVtZW50XG4gKiBAcGFyYW0gIHtzdHJpbmd9ICAgICAgICAgdHlwZVxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzKGVsZW1lbnQsIHR5cGUpIHtcbiAgcmV0dXJuIGVsZW1lbnQuJGluc3RhbmNlT2YodHlwZSk7XG59XG5cblxuLyoqXG4gKiBGaW5kIGEgc3VpdGFibGUgZGlzcGxheSBjYW5kaWRhdGUgZm9yIGRlZmluaXRpb25zIHdoZXJlIHRoZSBESSBkb2VzIG5vdFxuICogY29ycmVjdGx5IHNwZWNpZnkgb25lLlxuICovXG5mdW5jdGlvbiBmaW5kRGlzcGxheUNhbmRpZGF0ZShkZWZpbml0aW9ucykge1xuICByZXR1cm4gZmluZChkZWZpbml0aW9ucy5yb290RWxlbWVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICByZXR1cm4gaXMoZSwgJ2JwbW46UHJvY2VzcycpIHx8IGlzKGUsICdicG1uOkNvbGxhYm9yYXRpb24nKTtcbiAgfSk7XG59XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtblRyZWVXYWxrZXIoaGFuZGxlciwgdHJhbnNsYXRlKSB7XG5cbiAgLy8gbGlzdCBvZiBjb250YWluZXJzIGFscmVhZHkgd2Fsa2VkXG4gIHZhciBoYW5kbGVkRWxlbWVudHMgPSB7fTtcblxuICAvLyBsaXN0IG9mIGVsZW1lbnRzIHRvIGhhbmRsZSBkZWZlcnJlZCB0byBlbnN1cmVcbiAgLy8gcHJlcmVxdWlzaXRlcyBhcmUgZHJhd25cbiAgdmFyIGRlZmVycmVkID0gW107XG5cbiAgLy8gSGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgZnVuY3Rpb24gY29udGV4dHVhbChmbiwgY3R4KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGZuKGUsIGN0eCk7XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZWQoZWxlbWVudCkge1xuICAgIGhhbmRsZWRFbGVtZW50c1tlbGVtZW50LmlkXSA9IGVsZW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiBpc0hhbmRsZWQoZWxlbWVudCkge1xuICAgIHJldHVybiBoYW5kbGVkRWxlbWVudHNbZWxlbWVudC5pZF07XG4gIH1cblxuICBmdW5jdGlvbiB2aXNpdChlbGVtZW50LCBjdHgpIHtcblxuICAgIHZhciBnZnggPSBlbGVtZW50LmdmeDtcblxuICAgIC8vIGF2b2lkIG11bHRpcGxlIHJlbmRlcmluZyBvZiBlbGVtZW50c1xuICAgIGlmIChnZngpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgdHJhbnNsYXRlKCdhbHJlYWR5IHJlbmRlcmVkIHtlbGVtZW50fScsIHsgZWxlbWVudDogZWxlbWVudFRvU3RyaW5nKGVsZW1lbnQpIH0pXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIGNhbGwgaGFuZGxlclxuICAgIHJldHVybiBoYW5kbGVyLmVsZW1lbnQoZWxlbWVudCwgY3R4KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZpc2l0Um9vdChlbGVtZW50LCBkaWFncmFtKSB7XG4gICAgcmV0dXJuIGhhbmRsZXIucm9vdChlbGVtZW50LCBkaWFncmFtKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZpc2l0SWZEaShlbGVtZW50LCBjdHgpIHtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgZ2Z4ID0gZWxlbWVudC5kaSAmJiB2aXNpdChlbGVtZW50LCBjdHgpO1xuXG4gICAgICBoYW5kbGVkKGVsZW1lbnQpO1xuXG4gICAgICByZXR1cm4gZ2Z4O1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZ0Vycm9yKGUubWVzc2FnZSwgeyBlbGVtZW50OiBlbGVtZW50LCBlcnJvcjogZSB9KTtcblxuICAgICAgY29uc29sZS5lcnJvcih0cmFuc2xhdGUoJ2ZhaWxlZCB0byBpbXBvcnQge2VsZW1lbnR9JywgeyBlbGVtZW50OiBlbGVtZW50VG9TdHJpbmcoZWxlbWVudCkgfSkpO1xuICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBsb2dFcnJvcihtZXNzYWdlLCBjb250ZXh0KSB7XG4gICAgaGFuZGxlci5lcnJvcihtZXNzYWdlLCBjb250ZXh0KTtcbiAgfVxuXG4gIC8vIERJIGhhbmRsaW5nIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICBmdW5jdGlvbiByZWdpc3RlckRpKGRpKSB7XG4gICAgdmFyIGJwbW5FbGVtZW50ID0gZGkuYnBtbkVsZW1lbnQ7XG5cbiAgICBpZiAoYnBtbkVsZW1lbnQpIHtcbiAgICAgIGlmIChicG1uRWxlbWVudC5kaSkge1xuICAgICAgICBsb2dFcnJvcihcbiAgICAgICAgICB0cmFuc2xhdGUoJ211bHRpcGxlIERJIGVsZW1lbnRzIGRlZmluZWQgZm9yIHtlbGVtZW50fScsIHtcbiAgICAgICAgICAgIGVsZW1lbnQ6IGVsZW1lbnRUb1N0cmluZyhicG1uRWxlbWVudClcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB7IGVsZW1lbnQ6IGJwbW5FbGVtZW50IH1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpUmVmcy5iaW5kKGJwbW5FbGVtZW50LCAnZGknKTtcbiAgICAgICAgYnBtbkVsZW1lbnQuZGkgPSBkaTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbG9nRXJyb3IoXG4gICAgICAgIHRyYW5zbGF0ZSgnbm8gYnBtbkVsZW1lbnQgcmVmZXJlbmNlZCBpbiB7ZWxlbWVudH0nLCB7XG4gICAgICAgICAgZWxlbWVudDogZWxlbWVudFRvU3RyaW5nKGRpKVxuICAgICAgICB9KSxcbiAgICAgICAgeyBlbGVtZW50OiBkaSB9XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZURpYWdyYW0oZGlhZ3JhbSkge1xuICAgIGhhbmRsZVBsYW5lKGRpYWdyYW0ucGxhbmUpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlUGxhbmUocGxhbmUpIHtcbiAgICByZWdpc3RlckRpKHBsYW5lKTtcblxuICAgIGZvckVhY2gocGxhbmUucGxhbmVFbGVtZW50LCBoYW5kbGVQbGFuZUVsZW1lbnQpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlUGxhbmVFbGVtZW50KHBsYW5lRWxlbWVudCkge1xuICAgIHJlZ2lzdGVyRGkocGxhbmVFbGVtZW50KTtcbiAgfVxuXG5cbiAgLy8gU2VtYW50aWMgaGFuZGxpbmcgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIC8qKlxuICAgKiBIYW5kbGUgZGVmaW5pdGlvbnMgYW5kIHJldHVybiB0aGUgcmVuZGVyZWQgZGlhZ3JhbSAoaWYgYW55KVxuICAgKlxuICAgKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGRlZmluaXRpb25zIHRvIHdhbGsgYW5kIGltcG9ydFxuICAgKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IFtkaWFncmFtXSBzcGVjaWZpYyBkaWFncmFtIHRvIGltcG9ydCBhbmQgZGlzcGxheVxuICAgKlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gaWYgbm8gZGlhZ3JhbSB0byBkaXNwbGF5IGNvdWxkIGJlIGZvdW5kXG4gICAqL1xuICBmdW5jdGlvbiBoYW5kbGVEZWZpbml0aW9ucyhkZWZpbml0aW9ucywgZGlhZ3JhbSkge1xuXG4gICAgLy8gbWFrZSBzdXJlIHdlIHdhbGsgdGhlIGNvcnJlY3QgYnBtbkVsZW1lbnRcblxuICAgIHZhciBkaWFncmFtcyA9IGRlZmluaXRpb25zLmRpYWdyYW1zO1xuXG4gICAgaWYgKGRpYWdyYW0gJiYgZGlhZ3JhbXMuaW5kZXhPZihkaWFncmFtKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0cmFuc2xhdGUoJ2RpYWdyYW0gbm90IHBhcnQgb2YgYnBtbjpEZWZpbml0aW9ucycpKTtcbiAgICB9XG5cbiAgICBpZiAoIWRpYWdyYW0gJiYgZGlhZ3JhbXMgJiYgZGlhZ3JhbXMubGVuZ3RoKSB7XG4gICAgICBkaWFncmFtID0gZGlhZ3JhbXNbMF07XG4gICAgfVxuXG4gICAgLy8gbm8gZGlhZ3JhbSAtPiBub3RoaW5nIHRvIGltcG9ydFxuICAgIGlmICghZGlhZ3JhbSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnbm8gZGlhZ3JhbSB0byBkaXNwbGF5JykpO1xuICAgIH1cblxuICAgIC8vIGxvYWQgREkgZnJvbSBzZWxlY3RlZCBkaWFncmFtIG9ubHlcbiAgICBoYW5kbGVEaWFncmFtKGRpYWdyYW0pO1xuXG5cbiAgICB2YXIgcGxhbmUgPSBkaWFncmFtLnBsYW5lO1xuXG4gICAgaWYgKCFwbGFuZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZShcbiAgICAgICAgJ25vIHBsYW5lIGZvciB7ZWxlbWVudH0nLFxuICAgICAgICB7IGVsZW1lbnQ6IGVsZW1lbnRUb1N0cmluZyhkaWFncmFtKSB9XG4gICAgICApKTtcbiAgICB9XG5cbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBwbGFuZS5icG1uRWxlbWVudDtcblxuICAgIC8vIGVuc3VyZSB3ZSBkZWZhdWx0IHRvIGEgc3VpdGFibGUgZGlzcGxheSBjYW5kaWRhdGUgKHByb2Nlc3Mgb3IgY29sbGFib3JhdGlvbiksXG4gICAgLy8gZXZlbiBpZiBub24gaXMgc3BlY2lmaWVkIGluIERJXG4gICAgaWYgKCFyb290RWxlbWVudCkge1xuICAgICAgcm9vdEVsZW1lbnQgPSBmaW5kRGlzcGxheUNhbmRpZGF0ZShkZWZpbml0aW9ucyk7XG5cbiAgICAgIGlmICghcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnbm8gcHJvY2VzcyBvciBjb2xsYWJvcmF0aW9uIHRvIGRpc3BsYXknKSk7XG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIGxvZ0Vycm9yKFxuICAgICAgICAgIHRyYW5zbGF0ZSgnY29ycmVjdGluZyBtaXNzaW5nIGJwbW5FbGVtZW50IG9uIHtwbGFuZX0gdG8ge3Jvb3RFbGVtZW50fScsIHtcbiAgICAgICAgICAgIHBsYW5lOiBlbGVtZW50VG9TdHJpbmcocGxhbmUpLFxuICAgICAgICAgICAgcm9vdEVsZW1lbnQ6IGVsZW1lbnRUb1N0cmluZyhyb290RWxlbWVudClcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIGNvcnJlY3QgREkgb24gdGhlIGZseVxuICAgICAgICBwbGFuZS5icG1uRWxlbWVudCA9IHJvb3RFbGVtZW50O1xuICAgICAgICByZWdpc3RlckRpKHBsYW5lKTtcbiAgICAgIH1cbiAgICB9XG5cblxuICAgIHZhciBjdHggPSB2aXNpdFJvb3Qocm9vdEVsZW1lbnQsIHBsYW5lKTtcblxuICAgIGlmIChpcyhyb290RWxlbWVudCwgJ2JwbW46UHJvY2VzcycpKSB7XG4gICAgICBoYW5kbGVQcm9jZXNzKHJvb3RFbGVtZW50LCBjdHgpO1xuICAgIH0gZWxzZSBpZiAoaXMocm9vdEVsZW1lbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKSkge1xuICAgICAgaGFuZGxlQ29sbGFib3JhdGlvbihyb290RWxlbWVudCwgY3R4KTtcblxuICAgICAgLy8gZm9yY2UgZHJhd2luZyBvZiBldmVyeXRoaW5nIG5vdCB5ZXQgZHJhd24gdGhhdCBpcyBwYXJ0IG9mIHRoZSB0YXJnZXQgRElcbiAgICAgIGhhbmRsZVVuaGFuZGxlZFByb2Nlc3NlcyhkZWZpbml0aW9ucy5yb290RWxlbWVudHMsIGN0eCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgdHJhbnNsYXRlKCd1bnN1cHBvcnRlZCBicG1uRWxlbWVudCBmb3Ige3BsYW5lfToge3Jvb3RFbGVtZW50fScsIHtcbiAgICAgICAgICBwbGFuZTogZWxlbWVudFRvU3RyaW5nKHBsYW5lKSxcbiAgICAgICAgICByb290RWxlbWVudDogZWxlbWVudFRvU3RyaW5nKHJvb3RFbGVtZW50KVxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBoYW5kbGUgYWxsIGRlZmVycmVkIGVsZW1lbnRzXG4gICAgaGFuZGxlRGVmZXJyZWQoZGVmZXJyZWQpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlRGVmZXJyZWQoKSB7XG5cbiAgICB2YXIgZm47XG5cbiAgICAvLyBkcmFpbiBkZWZlcnJlZCB1bnRpbCBlbXB0eVxuICAgIHdoaWxlIChkZWZlcnJlZC5sZW5ndGgpIHtcbiAgICAgIGZuID0gZGVmZXJyZWQuc2hpZnQoKTtcblxuICAgICAgZm4oKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVQcm9jZXNzKHByb2Nlc3MsIGNvbnRleHQpIHtcbiAgICBoYW5kbGVGbG93RWxlbWVudHNDb250YWluZXIocHJvY2VzcywgY29udGV4dCk7XG4gICAgaGFuZGxlSW9TcGVjaWZpY2F0aW9uKHByb2Nlc3MuaW9TcGVjaWZpY2F0aW9uLCBjb250ZXh0KTtcblxuICAgIGhhbmRsZUFydGlmYWN0cyhwcm9jZXNzLmFydGlmYWN0cywgY29udGV4dCk7XG5cbiAgICAvLyBsb2cgcHJvY2VzcyBoYW5kbGVkXG4gICAgaGFuZGxlZChwcm9jZXNzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVVuaGFuZGxlZFByb2Nlc3Nlcyhyb290RWxlbWVudHMsIGN0eCkge1xuXG4gICAgLy8gd2FsayB0aHJvdWdoIGFsbCBwcm9jZXNzZXMgdGhhdCBoYXZlIG5vdCB5ZXQgYmVlbiBkcmF3biBhbmQgZHJhdyB0aGVtXG4gICAgLy8gaWYgdGhleSBjb250YWluIGxhbmVzIHdpdGggREkgaW5mb3JtYXRpb24uXG4gICAgLy8gd2UgZG8gdGhpcyB0byBwYXNzIHRoZSBmcmVlLWZsb2F0aW5nIGxhbmUgdGVzdCBjYXNlcyBpbiB0aGUgTUlXRyB0ZXN0IHN1aXRlXG4gICAgdmFyIHByb2Nlc3NlcyA9IGZpbHRlcihyb290RWxlbWVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIHJldHVybiAhaXNIYW5kbGVkKGUpICYmIGlzKGUsICdicG1uOlByb2Nlc3MnKSAmJiBlLmxhbmVTZXRzO1xuICAgIH0pO1xuXG4gICAgcHJvY2Vzc2VzLmZvckVhY2goY29udGV4dHVhbChoYW5kbGVQcm9jZXNzLCBjdHgpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZU1lc3NhZ2VGbG93KG1lc3NhZ2VGbG93LCBjb250ZXh0KSB7XG4gICAgdmlzaXRJZkRpKG1lc3NhZ2VGbG93LCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZU1lc3NhZ2VGbG93cyhtZXNzYWdlRmxvd3MsIGNvbnRleHQpIHtcbiAgICBmb3JFYWNoKG1lc3NhZ2VGbG93cywgY29udGV4dHVhbChoYW5kbGVNZXNzYWdlRmxvdywgY29udGV4dCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlRGF0YUFzc29jaWF0aW9uKGFzc29jaWF0aW9uLCBjb250ZXh0KSB7XG4gICAgdmlzaXRJZkRpKGFzc29jaWF0aW9uLCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZURhdGFJbnB1dChkYXRhSW5wdXQsIGNvbnRleHQpIHtcbiAgICB2aXNpdElmRGkoZGF0YUlucHV0LCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZURhdGFPdXRwdXQoZGF0YU91dHB1dCwgY29udGV4dCkge1xuICAgIHZpc2l0SWZEaShkYXRhT3V0cHV0LCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUFydGlmYWN0KGFydGlmYWN0LCBjb250ZXh0KSB7XG5cbiAgICAvLyBicG1uOlRleHRBbm5vdGF0aW9uXG4gICAgLy8gYnBtbjpHcm91cFxuICAgIC8vIGJwbW46QXNzb2NpYXRpb25cblxuICAgIHZpc2l0SWZEaShhcnRpZmFjdCwgY29udGV4dCk7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVBcnRpZmFjdHMoYXJ0aWZhY3RzLCBjb250ZXh0KSB7XG5cbiAgICBmb3JFYWNoKGFydGlmYWN0cywgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKGlzKGUsICdicG1uOkFzc29jaWF0aW9uJykpIHtcbiAgICAgICAgZGVmZXJyZWQucHVzaChmdW5jdGlvbigpIHtcbiAgICAgICAgICBoYW5kbGVBcnRpZmFjdChlLCBjb250ZXh0KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoYW5kbGVBcnRpZmFjdChlLCBjb250ZXh0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUlvU3BlY2lmaWNhdGlvbihpb1NwZWNpZmljYXRpb24sIGNvbnRleHQpIHtcblxuICAgIGlmICghaW9TcGVjaWZpY2F0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yRWFjaChpb1NwZWNpZmljYXRpb24uZGF0YUlucHV0cywgY29udGV4dHVhbChoYW5kbGVEYXRhSW5wdXQsIGNvbnRleHQpKTtcbiAgICBmb3JFYWNoKGlvU3BlY2lmaWNhdGlvbi5kYXRhT3V0cHV0cywgY29udGV4dHVhbChoYW5kbGVEYXRhT3V0cHV0LCBjb250ZXh0KSk7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVTdWJQcm9jZXNzKHN1YlByb2Nlc3MsIGNvbnRleHQpIHtcbiAgICBoYW5kbGVGbG93RWxlbWVudHNDb250YWluZXIoc3ViUHJvY2VzcywgY29udGV4dCk7XG4gICAgaGFuZGxlQXJ0aWZhY3RzKHN1YlByb2Nlc3MuYXJ0aWZhY3RzLCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUZsb3dOb2RlKGZsb3dOb2RlLCBjb250ZXh0KSB7XG4gICAgdmFyIGNoaWxkQ3R4ID0gdmlzaXRJZkRpKGZsb3dOb2RlLCBjb250ZXh0KTtcblxuICAgIGlmIChpcyhmbG93Tm9kZSwgJ2JwbW46U3ViUHJvY2VzcycpKSB7XG4gICAgICBoYW5kbGVTdWJQcm9jZXNzKGZsb3dOb2RlLCBjaGlsZEN0eCB8fCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICBpZiAoaXMoZmxvd05vZGUsICdicG1uOkFjdGl2aXR5JykpIHtcbiAgICAgIGhhbmRsZUlvU3BlY2lmaWNhdGlvbihmbG93Tm9kZS5pb1NwZWNpZmljYXRpb24sIGNvbnRleHQpO1xuICAgIH1cblxuICAgIC8vIGRlZmVyIGhhbmRsaW5nIG9mIGFzc29jaWF0aW9uc1xuICAgIC8vIGFmZmVjdGVkIHR5cGVzOlxuICAgIC8vXG4gICAgLy8gICAqIGJwbW46QWN0aXZpdHlcbiAgICAvLyAgICogYnBtbjpUaHJvd0V2ZW50XG4gICAgLy8gICAqIGJwbW46Q2F0Y2hFdmVudFxuICAgIC8vXG4gICAgZGVmZXJyZWQucHVzaChmdW5jdGlvbigpIHtcbiAgICAgIGZvckVhY2goZmxvd05vZGUuZGF0YUlucHV0QXNzb2NpYXRpb25zLCBjb250ZXh0dWFsKGhhbmRsZURhdGFBc3NvY2lhdGlvbiwgY29udGV4dCkpO1xuICAgICAgZm9yRWFjaChmbG93Tm9kZS5kYXRhT3V0cHV0QXNzb2NpYXRpb25zLCBjb250ZXh0dWFsKGhhbmRsZURhdGFBc3NvY2lhdGlvbiwgY29udGV4dCkpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlU2VxdWVuY2VGbG93KHNlcXVlbmNlRmxvdywgY29udGV4dCkge1xuICAgIHZpc2l0SWZEaShzZXF1ZW5jZUZsb3csIGNvbnRleHQpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlRGF0YUVsZW1lbnQoZGF0YU9iamVjdCwgY29udGV4dCkge1xuICAgIHZpc2l0SWZEaShkYXRhT2JqZWN0LCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUxhbmUobGFuZSwgY29udGV4dCkge1xuXG4gICAgZGVmZXJyZWQucHVzaChmdW5jdGlvbigpIHtcblxuICAgICAgdmFyIG5ld0NvbnRleHQgPSB2aXNpdElmRGkobGFuZSwgY29udGV4dCk7XG5cbiAgICAgIGlmIChsYW5lLmNoaWxkTGFuZVNldCkge1xuICAgICAgICBoYW5kbGVMYW5lU2V0KGxhbmUuY2hpbGRMYW5lU2V0LCBuZXdDb250ZXh0IHx8IGNvbnRleHQpO1xuICAgICAgfVxuXG4gICAgICB3aXJlRmxvd05vZGVSZWZzKGxhbmUpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlTGFuZVNldChsYW5lU2V0LCBjb250ZXh0KSB7XG4gICAgZm9yRWFjaChsYW5lU2V0LmxhbmVzLCBjb250ZXh0dWFsKGhhbmRsZUxhbmUsIGNvbnRleHQpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUxhbmVTZXRzKGxhbmVTZXRzLCBjb250ZXh0KSB7XG4gICAgZm9yRWFjaChsYW5lU2V0cywgY29udGV4dHVhbChoYW5kbGVMYW5lU2V0LCBjb250ZXh0KSk7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVGbG93RWxlbWVudHNDb250YWluZXIoY29udGFpbmVyLCBjb250ZXh0KSB7XG4gICAgaGFuZGxlRmxvd0VsZW1lbnRzKGNvbnRhaW5lci5mbG93RWxlbWVudHMsIGNvbnRleHQpO1xuXG4gICAgaWYgKGNvbnRhaW5lci5sYW5lU2V0cykge1xuICAgICAgaGFuZGxlTGFuZVNldHMoY29udGFpbmVyLmxhbmVTZXRzLCBjb250ZXh0KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVGbG93RWxlbWVudHMoZmxvd0VsZW1lbnRzLCBjb250ZXh0KSB7XG4gICAgZm9yRWFjaChmbG93RWxlbWVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGlmIChpcyhlLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgICAgICBkZWZlcnJlZC5wdXNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGhhbmRsZVNlcXVlbmNlRmxvdyhlLCBjb250ZXh0KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGlzKGUsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSkge1xuICAgICAgICBkZWZlcnJlZC51bnNoaWZ0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGhhbmRsZUZsb3dOb2RlKGUsIGNvbnRleHQpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoaXMoZSwgJ2JwbW46Rmxvd05vZGUnKSkge1xuICAgICAgICBoYW5kbGVGbG93Tm9kZShlLCBjb250ZXh0KTtcbiAgICAgIH0gZWxzZSBpZiAoaXMoZSwgJ2JwbW46RGF0YU9iamVjdCcpKSB7XG5cbiAgICAgICAgLy8gU0tJUCAoYXNzdW1lIGNvcnJlY3QgcmVmZXJlbmNpbmcgdmlhIERhdGFPYmplY3RSZWZlcmVuY2UpXG4gICAgICB9IGVsc2UgaWYgKGlzKGUsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpKSB7XG4gICAgICAgIGhhbmRsZURhdGFFbGVtZW50KGUsIGNvbnRleHQpO1xuICAgICAgfSBlbHNlIGlmIChpcyhlLCAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJykpIHtcbiAgICAgICAgaGFuZGxlRGF0YUVsZW1lbnQoZSwgY29udGV4dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dFcnJvcihcbiAgICAgICAgICB0cmFuc2xhdGUoJ3VucmVjb2duaXplZCBmbG93RWxlbWVudCB7ZWxlbWVudH0gaW4gY29udGV4dCB7Y29udGV4dH0nLCB7XG4gICAgICAgICAgICBlbGVtZW50OiBlbGVtZW50VG9TdHJpbmcoZSksXG4gICAgICAgICAgICBjb250ZXh0OiAoY29udGV4dCA/IGVsZW1lbnRUb1N0cmluZyhjb250ZXh0LmJ1c2luZXNzT2JqZWN0KSA6ICdudWxsJylcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB7IGVsZW1lbnQ6IGUsIGNvbnRleHQ6IGNvbnRleHQgfVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlUGFydGljaXBhbnQocGFydGljaXBhbnQsIGNvbnRleHQpIHtcbiAgICB2YXIgbmV3Q3R4ID0gdmlzaXRJZkRpKHBhcnRpY2lwYW50LCBjb250ZXh0KTtcblxuICAgIHZhciBwcm9jZXNzID0gcGFydGljaXBhbnQucHJvY2Vzc1JlZjtcbiAgICBpZiAocHJvY2Vzcykge1xuICAgICAgaGFuZGxlUHJvY2Vzcyhwcm9jZXNzLCBuZXdDdHggfHwgY29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlQ29sbGFib3JhdGlvbihjb2xsYWJvcmF0aW9uKSB7XG5cbiAgICBmb3JFYWNoKGNvbGxhYm9yYXRpb24ucGFydGljaXBhbnRzLCBjb250ZXh0dWFsKGhhbmRsZVBhcnRpY2lwYW50KSk7XG5cbiAgICBoYW5kbGVBcnRpZmFjdHMoY29sbGFib3JhdGlvbi5hcnRpZmFjdHMpO1xuXG4gICAgLy8gaGFuZGxlIG1lc3NhZ2UgZmxvd3MgbGF0ZXN0IGluIHRoZSBwcm9jZXNzXG4gICAgZGVmZXJyZWQucHVzaChmdW5jdGlvbigpIHtcbiAgICAgIGhhbmRsZU1lc3NhZ2VGbG93cyhjb2xsYWJvcmF0aW9uLm1lc3NhZ2VGbG93cyk7XG4gICAgfSk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHdpcmVGbG93Tm9kZVJlZnMobGFuZSkge1xuXG4gICAgLy8gd2lyZSB0aGUgdmlydHVhbCBmbG93Tm9kZVJlZnMgPC0+IHJlbGF0aW9uc2hpcFxuICAgIGZvckVhY2gobGFuZS5mbG93Tm9kZVJlZiwgZnVuY3Rpb24oZmxvd05vZGUpIHtcbiAgICAgIHZhciBsYW5lcyA9IGZsb3dOb2RlLmdldCgnbGFuZXMnKTtcblxuICAgICAgaWYgKGxhbmVzKSB7XG4gICAgICAgIGxhbmVzLnB1c2gobGFuZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBBUEkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIHJldHVybiB7XG4gICAgaGFuZGxlRGVmZXJyZWQ6IGhhbmRsZURlZmVycmVkLFxuICAgIGhhbmRsZURlZmluaXRpb25zOiBoYW5kbGVEZWZpbml0aW9ucyxcbiAgICBoYW5kbGVTdWJQcm9jZXNzOiBoYW5kbGVTdWJQcm9jZXNzLFxuICAgIHJlZ2lzdGVyRGk6IHJlZ2lzdGVyRGlcbiAgfTtcbn0iLCJpbXBvcnQgQnBtblRyZWVXYWxrZXIgZnJvbSAnLi9CcG1uVHJlZVdhbGtlcic7XG5cblxuLyoqXG4gKiBUaGUgaW1wb3J0QnBtbkRpYWdyYW0gcmVzdWx0LlxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEltcG9ydEJQTU5EaWFncmFtUmVzdWx0XG4gKlxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuICovXG5cbi8qKlxuKiBUaGUgaW1wb3J0QnBtbkRpYWdyYW0gZXJyb3IuXG4qXG4qIEB0eXBlZGVmIHtFcnJvcn0gSW1wb3J0QlBNTkRpYWdyYW1FcnJvclxuKlxuKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IHdhcm5pbmdzXG4qL1xuXG4vKipcbiAqIEltcG9ydCB0aGUgZGVmaW5pdGlvbnMgaW50byBhIGRpYWdyYW0uXG4gKlxuICogRXJyb3JzIGFuZCB3YXJuaW5ncyBhcmUgcmVwb3J0ZWQgdGhyb3VnaCB0aGUgc3BlY2lmaWVkIGNhbGxiYWNrLlxuICpcbiAqIEBwYXJhbSAge2Rqcy5EaWFncmFtfSBkaWFncmFtXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50PERlZmluaXRpb25zPn0gZGVmaW5pdGlvbnNcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnQ8QlBNTkRpYWdyYW0+fSBbYnBtbkRpYWdyYW1dIHRoZSBkaWFncmFtIHRvIGJlIHJlbmRlcmVkXG4gKiAoaWYgbm90IHByb3ZpZGVkLCB0aGUgZmlyc3Qgb25lIHdpbGwgYmUgcmVuZGVyZWQpXG4gKlxuICogUmV0dXJucyB7UHJvbWlzZTxJbXBvcnRCUE1ORGlhZ3JhbVJlc3VsdCwgSW1wb3J0QlBNTkRpYWdyYW1FcnJvcj59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbXBvcnRCcG1uRGlhZ3JhbShkaWFncmFtLCBkZWZpbml0aW9ucywgYnBtbkRpYWdyYW0pIHtcblxuICB2YXIgaW1wb3J0ZXIsXG4gICAgICBldmVudEJ1cyxcbiAgICAgIHRyYW5zbGF0ZTtcblxuICB2YXIgZXJyb3IsXG4gICAgICB3YXJuaW5ncyA9IFtdO1xuXG4gIC8qKlxuICAgKiBXYWxrIHRoZSBkaWFncmFtIHNlbWFudGljYWxseSwgaW1wb3J0aW5nICg9ZHJhd2luZylcbiAgICogYWxsIGVsZW1lbnRzIHlvdSBlbmNvdW50ZXIuXG4gICAqXG4gICAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxEZWZpbml0aW9ucz59IGRlZmluaXRpb25zXG4gICAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxCUE1ORGlhZ3JhbT59IGJwbW5EaWFncmFtXG4gICAqL1xuICBmdW5jdGlvbiByZW5kZXIoZGVmaW5pdGlvbnMsIGJwbW5EaWFncmFtKSB7XG5cbiAgICB2YXIgdmlzaXRvciA9IHtcblxuICAgICAgcm9vdDogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gaW1wb3J0ZXIuYWRkKGVsZW1lbnQpO1xuICAgICAgfSxcblxuICAgICAgZWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgcGFyZW50U2hhcGUpIHtcbiAgICAgICAgcmV0dXJuIGltcG9ydGVyLmFkZChlbGVtZW50LCBwYXJlbnRTaGFwZSk7XG4gICAgICB9LFxuXG4gICAgICBlcnJvcjogZnVuY3Rpb24obWVzc2FnZSwgY29udGV4dCkge1xuICAgICAgICB3YXJuaW5ncy5wdXNoKHsgbWVzc2FnZTogbWVzc2FnZSwgY29udGV4dDogY29udGV4dCB9KTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIHdhbGtlciA9IG5ldyBCcG1uVHJlZVdhbGtlcih2aXNpdG9yLCB0cmFuc2xhdGUpO1xuXG4gICAgLy8gdHJhdmVyc2UgQlBNTiAyLjAgZG9jdW1lbnQgbW9kZWwsXG4gICAgLy8gc3RhcnRpbmcgYXQgZGVmaW5pdGlvbnNcbiAgICB3YWxrZXIuaGFuZGxlRGVmaW5pdGlvbnMoZGVmaW5pdGlvbnMsIGJwbW5EaWFncmFtKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICB0cnkge1xuICAgICAgaW1wb3J0ZXIgPSBkaWFncmFtLmdldCgnYnBtbkltcG9ydGVyJyk7XG4gICAgICBldmVudEJ1cyA9IGRpYWdyYW0uZ2V0KCdldmVudEJ1cycpO1xuICAgICAgdHJhbnNsYXRlID0gZGlhZ3JhbS5nZXQoJ3RyYW5zbGF0ZScpO1xuXG4gICAgICBldmVudEJ1cy5maXJlKCdpbXBvcnQucmVuZGVyLnN0YXJ0JywgeyBkZWZpbml0aW9uczogZGVmaW5pdGlvbnMgfSk7XG5cbiAgICAgIHJlbmRlcihkZWZpbml0aW9ucywgYnBtbkRpYWdyYW0pO1xuXG4gICAgICBldmVudEJ1cy5maXJlKCdpbXBvcnQucmVuZGVyLmNvbXBsZXRlJywge1xuICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgIHdhcm5pbmdzOiB3YXJuaW5nc1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiByZXNvbHZlKHsgd2FybmluZ3M6IHdhcm5pbmdzIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcblxuICAgICAgZS53YXJuaW5ncyA9IHdhcm5pbmdzO1xuICAgICAgcmV0dXJuIHJlamVjdChlKTtcbiAgICB9XG4gIH0pO1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIGVsZW1lbnRUb1N0cmluZyhlKSB7XG4gIGlmICghZSkge1xuICAgIHJldHVybiAnPG51bGw+JztcbiAgfVxuXG4gIHJldHVybiAnPCcgKyBlLiR0eXBlICsgKGUuaWQgPyAnIGlkPVwiJyArIGUuaWQgOiAnJykgKyAnXCIgLz4nO1xufSIsImltcG9ydCB0cmFuc2xhdGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnO1xuXG5pbXBvcnQgQnBtbkltcG9ydGVyIGZyb20gJy4vQnBtbkltcG9ydGVyJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIHRyYW5zbGF0ZVxuICBdLFxuICBicG1uSW1wb3J0ZXI6IFsgJ3R5cGUnLCBCcG1uSW1wb3J0ZXIgXVxufTsiLCJpbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnbWluLWRhc2gnO1xuXG4vLyBUT0RPKG5pa2t1KTogcmVtb3ZlIHdpdGggZnV0dXJlIGJwbW4tanMgdmVyc2lvblxuXG4vKipcbiAqIFdyYXBzIEFQSXMgdG8gY2hlY2s6XG4gKlxuICogMSkgSWYgYSBjYWxsYmFjayBpcyBwYXNzZWQgLT4gV2FybiB1c2VycyBhYm91dCBjYWxsYmFjayBkZXByZWNhdGlvbi5cbiAqIDIpIElmIFByb21pc2UgY2xhc3MgaXMgaW1wbGVtZW50ZWQgaW4gY3VycmVudCBlbnZpcm9ubWVudC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JhcEZvckNvbXBhdGliaWxpdHkoYXBpKSB7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuXG4gICAgaWYgKCF3aW5kb3cuUHJvbWlzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm9taXNlcyBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgZW52aXJvbm1lbnQuIFBsZWFzZSBwb2x5ZmlsbCBQcm9taXNlLicpO1xuICAgIH1cblxuICAgIHZhciBhcmdMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIGlmIChhcmdMZW4gPj0gMSAmJiBpc0Z1bmN0aW9uKGFyZ3VtZW50c1thcmdMZW4gLSAxXSkpIHtcblxuICAgICAgdmFyIGNhbGxiYWNrID0gYXJndW1lbnRzW2FyZ0xlbiAtIDFdO1xuXG4gICAgICBjb25zb2xlLndhcm4obmV3IEVycm9yKFxuICAgICAgICAnUGFzc2luZyBjYWxsYmFja3MgdG8gJyArIGFwaS5uYW1lICsgJyBpcyBkZXByZWNhdGVkIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgbWFqb3IgcmVsZWFzZS4gJyArXG4gICAgICAgICdQbGVhc2Ugc3dpdGNoIHRvIHByb21pc2VzOiBodHRwczovL2JwbW4uaW8vbC9tb3ZpbmctdG8tcHJvbWlzZXMuaHRtbCdcbiAgICAgICkpO1xuXG4gICAgICB2YXIgYXJnc1dpdGhvdXRDYWxsYmFjayA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCwgLTEpO1xuXG4gICAgICBhcGkuYXBwbHkodGhpcywgYXJnc1dpdGhvdXRDYWxsYmFjaykudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcblxuICAgICAgICB2YXIgZmlyc3RLZXkgPSBPYmplY3Qua2V5cyhyZXN1bHQpWzBdO1xuXG4gICAgICAgIC8vIFRoZSBBUElzIHdlIGFyZSB3cmFwcGluZyBhbGwgcmVzb2x2ZSBhIHNpbmdsZSBpdGVtIGRlcGVuZGluZyBvbiB0aGUgQVBJLlxuICAgICAgICAvLyBGb3IgaW5zdGFuY2UsIGltcG9ydFhNTCByZXNvbHZlcyB7IHdhcm5pbmdzIH0gYW5kIHNhdmVYTUwgcmV0dXJucyB7IHhtbCB9LlxuICAgICAgICAvLyBUaGF0J3Mgd2h5IHdlIGNhbiBjYWxsIHRoZSBjYWxsYmFjayB3aXRoIHRoZSBmaXJzdCBpdGVtIG9mIHJlc3VsdC5cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHJlc3VsdFtmaXJzdEtleV0pO1xuXG4gICAgICAgIC8vIFBhc3NpbmcgYSBzZWNvbmQgcGFyYW10ZXIgaW5zdGVhZCBvZiBjYXRjaCBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG9cbiAgICAgICAgLy8gY2F0Y2ggZXJyb3JzIHRocm93biBieSBjYWxsYmFjaygpLlxuICAgICAgfSwgZnVuY3Rpb24oZXJyKSB7XG5cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgZXJyLndhcm5pbmdzKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIHJldHVybiBhcGkuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH07XG59XG4iLCJpbXBvcnQge1xuICBpcyxcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG5leHBvcnQgZnVuY3Rpb24gaXNFeHBhbmRlZChlbGVtZW50KSB7XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkNhbGxBY3Rpdml0eScpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuICAgIHJldHVybiAhIWdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLmRpLmlzRXhwYW5kZWQ7XG4gIH1cblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuICAgIHJldHVybiAhIWdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLnByb2Nlc3NSZWY7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzSW50ZXJydXB0aW5nKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQgJiYgZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkuaXNJbnRlcnJ1cHRpbmcgIT09IGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNFdmVudFN1YlByb2Nlc3MoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudCAmJiAhIWdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLnRyaWdnZXJlZEJ5RXZlbnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgZXZlbnRUeXBlKSB7XG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxuICAgICAgaGFzRXZlbnREZWZpbml0aW9uID0gZmFsc2U7XG5cbiAgaWYgKGJvLmV2ZW50RGVmaW5pdGlvbnMpIHtcbiAgICBmb3JFYWNoKGJvLmV2ZW50RGVmaW5pdGlvbnMsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICBpZiAoaXMoZXZlbnQsIGV2ZW50VHlwZSkpIHtcbiAgICAgICAgaGFzRXZlbnREZWZpbml0aW9uID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBoYXNFdmVudERlZmluaXRpb247XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNFcnJvckV2ZW50RGVmaW5pdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46RXJyb3JFdmVudERlZmluaXRpb24nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0VzY2FsYXRpb25FdmVudERlZmluaXRpb24oZWxlbWVudCkge1xuICByZXR1cm4gaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOkVzY2FsYXRpb25FdmVudERlZmluaXRpb24nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0NvbXBlbnNhdGVFdmVudERlZmluaXRpb24oZWxlbWVudCkge1xuICByZXR1cm4gaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nKTtcbn1cbiIsImltcG9ydCB7XG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi9Nb2RlbFV0aWwnO1xuXG5cbmV4cG9ydCB2YXIgREVGQVVMVF9MQUJFTF9TSVpFID0ge1xuICB3aWR0aDogOTAsXG4gIGhlaWdodDogMjBcbn07XG5cbmV4cG9ydCB2YXIgRkxPV19MQUJFTF9JTkRFTlQgPSAxNTtcblxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2VtYW50aWMgaGFzIGFuIGV4dGVybmFsIGxhYmVsXG4gKlxuICogQHBhcmFtIHtCcG1uRWxlbWVudH0gc2VtYW50aWNcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgaGFzIGxhYmVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0xhYmVsRXh0ZXJuYWwoc2VtYW50aWMpIHtcbiAgcmV0dXJuIGlzKHNlbWFudGljLCAnYnBtbjpFdmVudCcpIHx8XG4gICAgICAgICBpcyhzZW1hbnRpYywgJ2JwbW46R2F0ZXdheScpIHx8XG4gICAgICAgICBpcyhzZW1hbnRpYywgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJykgfHxcbiAgICAgICAgIGlzKHNlbWFudGljLCAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJykgfHxcbiAgICAgICAgIGlzKHNlbWFudGljLCAnYnBtbjpEYXRhSW5wdXQnKSB8fFxuICAgICAgICAgaXMoc2VtYW50aWMsICdicG1uOkRhdGFPdXRwdXQnKSB8fFxuICAgICAgICAgaXMoc2VtYW50aWMsICdicG1uOlNlcXVlbmNlRmxvdycpIHx8XG4gICAgICAgICBpcyhzZW1hbnRpYywgJ2JwbW46TWVzc2FnZUZsb3cnKSB8fFxuICAgICAgICAgaXMoc2VtYW50aWMsICdicG1uOkdyb3VwJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyBhbiBleHRlcm5hbCBsYWJlbFxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLnNoYXBlfSBlbGVtZW50XG4gKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIGhhcyBsYWJlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzRXh0ZXJuYWxMYWJlbChlbGVtZW50KSB7XG4gIHJldHVybiBpc0xhYmVsKGVsZW1lbnQubGFiZWwpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgcG9zaXRpb24gZm9yIHNlcXVlbmNlIGZsb3cgbGFiZWxzXG4gKlxuICogQHBhcmFtICB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAqIEByZXR1cm4ge1BvaW50fSB0aGUgbGFiZWwgcG9zaXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZsb3dMYWJlbFBvc2l0aW9uKHdheXBvaW50cykge1xuXG4gIC8vIGdldCB0aGUgd2F5cG9pbnRzIG1pZFxuICB2YXIgbWlkID0gd2F5cG9pbnRzLmxlbmd0aCAvIDIgLSAxO1xuXG4gIHZhciBmaXJzdCA9IHdheXBvaW50c1tNYXRoLmZsb29yKG1pZCldO1xuICB2YXIgc2Vjb25kID0gd2F5cG9pbnRzW01hdGguY2VpbChtaWQgKyAwLjAxKV07XG5cbiAgLy8gZ2V0IHBvc2l0aW9uXG4gIHZhciBwb3NpdGlvbiA9IGdldFdheXBvaW50c01pZCh3YXlwb2ludHMpO1xuXG4gIC8vIGNhbGN1bGF0ZSBhbmdsZVxuICB2YXIgYW5nbGUgPSBNYXRoLmF0YW4oKHNlY29uZC55IC0gZmlyc3QueSkgLyAoc2Vjb25kLnggLSBmaXJzdC54KSk7XG5cbiAgdmFyIHggPSBwb3NpdGlvbi54LFxuICAgICAgeSA9IHBvc2l0aW9uLnk7XG5cbiAgaWYgKE1hdGguYWJzKGFuZ2xlKSA8IE1hdGguUEkgLyAyKSB7XG4gICAgeSAtPSBGTE9XX0xBQkVMX0lOREVOVDtcbiAgfSBlbHNlIHtcbiAgICB4ICs9IEZMT1dfTEFCRUxfSU5ERU5UO1xuICB9XG5cbiAgcmV0dXJuIHsgeDogeCwgeTogeSB9O1xufVxuXG5cbi8qKlxuICogR2V0IHRoZSBtaWRkbGUgb2YgYSBudW1iZXIgb2Ygd2F5cG9pbnRzXG4gKlxuICogQHBhcmFtICB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAqIEByZXR1cm4ge1BvaW50fSB0aGUgbWlkIHBvaW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRXYXlwb2ludHNNaWQod2F5cG9pbnRzKSB7XG5cbiAgdmFyIG1pZCA9IHdheXBvaW50cy5sZW5ndGggLyAyIC0gMTtcblxuICB2YXIgZmlyc3QgPSB3YXlwb2ludHNbTWF0aC5mbG9vcihtaWQpXTtcbiAgdmFyIHNlY29uZCA9IHdheXBvaW50c1tNYXRoLmNlaWwobWlkICsgMC4wMSldO1xuXG4gIHJldHVybiB7XG4gICAgeDogZmlyc3QueCArIChzZWNvbmQueCAtIGZpcnN0LngpIC8gMixcbiAgICB5OiBmaXJzdC55ICsgKHNlY29uZC55IC0gZmlyc3QueSkgLyAyXG4gIH07XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEV4dGVybmFsTGFiZWxNaWQoZWxlbWVudCkge1xuXG4gIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgIHJldHVybiBnZXRGbG93TGFiZWxQb3NpdGlvbihlbGVtZW50LndheXBvaW50cyk7XG4gIH0gZWxzZSBpZiAoaXMoZWxlbWVudCwgJ2JwbW46R3JvdXAnKSkge1xuICAgIHJldHVybiB7XG4gICAgICB4OiBlbGVtZW50LnggKyBlbGVtZW50LndpZHRoIC8gMixcbiAgICAgIHk6IGVsZW1lbnQueSArIERFRkFVTFRfTEFCRUxfU0laRS5oZWlnaHQgLyAyXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogZWxlbWVudC54ICsgZWxlbWVudC53aWR0aCAvIDIsXG4gICAgICB5OiBlbGVtZW50LnkgKyBlbGVtZW50LmhlaWdodCArIERFRkFVTFRfTEFCRUxfU0laRS5oZWlnaHQgLyAyXG4gICAgfTtcbiAgfVxufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgYm91bmRzIG9mIGFuIGVsZW1lbnRzIGxhYmVsLCBwYXJzZWQgZnJvbSB0aGUgZWxlbWVudHMgREkgb3JcbiAqIGdlbmVyYXRlZCBmcm9tIGl0cyBib3VuZHMuXG4gKlxuICogQHBhcmFtIHtCcG1uRWxlbWVudH0gc2VtYW50aWNcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEV4dGVybmFsTGFiZWxCb3VuZHMoc2VtYW50aWMsIGVsZW1lbnQpIHtcblxuICB2YXIgbWlkLFxuICAgICAgc2l6ZSxcbiAgICAgIGJvdW5kcyxcbiAgICAgIGRpID0gc2VtYW50aWMuZGksXG4gICAgICBsYWJlbCA9IGRpLmxhYmVsO1xuXG4gIGlmIChsYWJlbCAmJiBsYWJlbC5ib3VuZHMpIHtcbiAgICBib3VuZHMgPSBsYWJlbC5ib3VuZHM7XG5cbiAgICBzaXplID0ge1xuICAgICAgd2lkdGg6IE1hdGgubWF4KERFRkFVTFRfTEFCRUxfU0laRS53aWR0aCwgYm91bmRzLndpZHRoKSxcbiAgICAgIGhlaWdodDogYm91bmRzLmhlaWdodFxuICAgIH07XG5cbiAgICBtaWQgPSB7XG4gICAgICB4OiBib3VuZHMueCArIGJvdW5kcy53aWR0aCAvIDIsXG4gICAgICB5OiBib3VuZHMueSArIGJvdW5kcy5oZWlnaHQgLyAyXG4gICAgfTtcbiAgfSBlbHNlIHtcblxuICAgIG1pZCA9IGdldEV4dGVybmFsTGFiZWxNaWQoZWxlbWVudCk7XG5cbiAgICBzaXplID0gREVGQVVMVF9MQUJFTF9TSVpFO1xuICB9XG5cbiAgcmV0dXJuIGFzc2lnbih7XG4gICAgeDogbWlkLnggLSBzaXplLndpZHRoIC8gMixcbiAgICB5OiBtaWQueSAtIHNpemUuaGVpZ2h0IC8gMlxuICB9LCBzaXplKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudCAmJiAhIWVsZW1lbnQubGFiZWxUYXJnZXQ7XG59XG4iLCIvKipcbiAqIElzIGFuIGVsZW1lbnQgb2YgdGhlIGdpdmVuIEJQTU4gdHlwZT9cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZXxNb2RkbGVFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0gIHtzdHJpbmd9IHR5cGVcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXMoZWxlbWVudCwgdHlwZSkge1xuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcblxuICByZXR1cm4gYm8gJiYgKHR5cGVvZiBiby4kaW5zdGFuY2VPZiA9PT0gJ2Z1bmN0aW9uJykgJiYgYm8uJGluc3RhbmNlT2YodHlwZSk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGJ1c2luZXNzIG9iamVjdCBmb3IgYSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfE1vZGRsZUVsZW1lbnR9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkge1xuICByZXR1cm4gKGVsZW1lbnQgJiYgZWxlbWVudC5idXNpbmVzc09iamVjdCkgfHwgZWxlbWVudDtcbn0iLCIvKipcbiAqIFRoaXMgZmlsZSBtdXN0IG5vdCBiZSBjaGFuZ2VkIG9yIGV4Y2hhbmdlZC5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9icG1uLmlvL2xpY2Vuc2UgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKi9cblxuaW1wb3J0IHtcbiAgZG9taWZ5LFxuICBkZWxlZ2F0ZSBhcyBkb21EZWxlZ2F0ZVxufSBmcm9tICdtaW4tZG9tJztcblxuXG4vLyBpbmxpbmVkIC4uLy4uL3Jlc291cmNlcy9sb2dvLnN2Z1xudmFyIEJQTU5JT19MT0dPX1NWRyA9ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE0LjAyIDUuNTdcIiB3aWR0aD1cIjUzXCIgaGVpZ2h0PVwiMjFcIiBzdHlsZT1cInZlcnRpY2FsLWFsaWduOm1pZGRsZVwiPjxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTEuODguOTJ2LjE0YzAgLjQxLS4xMy42OC0uNC44LjMzLjE0LjQ2LjQ0LjQ2Ljg2di4zM2MwIC42MS0uMzMuOTUtLjk1Ljk1SDBWMGguOTVjLjY1IDAgLjkzLjMuOTMuOTJ6TS42My41N3YxLjA2aC4yNGMuMjQgMCAuMzgtLjEuMzgtLjQzVi45OGMwLS4yOC0uMS0uNC0uMzItLjR6bTAgMS42M3YxLjIyaC4zNmMuMiAwIC4zMi0uMS4zMi0uMzl2LS4zNWMwLS4zNy0uMTItLjQ4LS40LS40OEguNjN6TTQuMTguOTl2LjUyYzAgLjY0LS4zMS45OC0uOTQuOThoLS4zVjRoLS42MlYwaC45MmMuNjMgMCAuOTQuMzUuOTQuOTl6TTIuOTQuNTd2MS4zNWguM2MuMiAwIC4zLS4wOS4zLS4zN3YtLjZjMC0uMjktLjEtLjM4LS4zLS4zOGgtLjN6bTIuODkgMi4yN0w2LjI1IDBoLjg4djRoLS42VjEuMTJMNi4xIDMuOTloLS42bC0uNDYtMi44MnYyLjgyaC0uNTVWMGguODd6TTguMTQgMS4xVjRoLS41NlYwaC43OUw5IDIuNFYwaC41NnY0aC0uNjR6bTIuNDkgMi4yOXYuNmgtLjZ2LS42ek0xMi4xMiAxYzAtLjYzLjMzLTEgLjk1LTEgLjYxIDAgLjk1LjM3Ljk1IDF2Mi4wNGMwIC42NC0uMzQgMS0uOTUgMS0uNjIgMC0uOTUtLjM3LS45NS0xem0uNjIgMi4wOGMwIC4yOC4xMy4zOS4zMy4zOXMuMzItLjEuMzItLjRWLjk4YzAtLjI5LS4xMi0uNC0uMzItLjRzLS4zMy4xMS0uMzMuNHpcIi8+PHBhdGggZmlsbD1cImN1cnJlbnRDb2xvclwiIGQ9XCJNMCA0LjUzaDE0LjAydjEuMDRIMHpNMTEuMDggMGguNjN2LjYyaC0uNjN6bS42MyA0VjFoLS42M3YyLjk4elwiLz48L3N2Zz4nO1xuXG5leHBvcnQgdmFyIEJQTU5JT19JTUcgPSBCUE1OSU9fTE9HT19TVkc7XG5cbmZ1bmN0aW9uIGNzcyhhdHRycykge1xuICByZXR1cm4gYXR0cnMuam9pbignOycpO1xufVxuXG5leHBvcnQgdmFyIExJTktfU1RZTEVTID0gY3NzKFtcbiAgJ2NvbG9yOiAjNDA0MDQwJ1xuXSk7XG5cbnZhciBMSUdIVEJPWF9TVFlMRVMgPSBjc3MoW1xuICAnei1pbmRleDogMTAwMScsXG4gICdwb3NpdGlvbjogZml4ZWQnLFxuICAndG9wOiAwJyxcbiAgJ2xlZnQ6IDAnLFxuICAncmlnaHQ6IDAnLFxuICAnYm90dG9tOiAwJ1xuXSk7XG5cbnZhciBCQUNLRFJPUF9TVFlMRVMgPSBjc3MoW1xuICAnd2lkdGg6IDEwMCUnLFxuICAnaGVpZ2h0OiAxMDAlJyxcbiAgJ2JhY2tncm91bmQ6IHJnYmEoNDAsNDAsNDAsMC4yKSdcbl0pO1xuXG52YXIgTk9USUNFX1NUWUxFUyA9IGNzcyhbXG4gICdwb3NpdGlvbjogYWJzb2x1dGUnLFxuICAnbGVmdDogNTAlJyxcbiAgJ3RvcDogNDAlJyxcbiAgJ3RyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUpJyxcbiAgJ3dpZHRoOiAyNjBweCcsXG4gICdwYWRkaW5nOiAxMHB4JyxcbiAgJ2JhY2tncm91bmQ6IHdoaXRlJyxcbiAgJ2JveC1zaGFkb3c6IDAgMXB4IDRweCByZ2JhKDAsMCwwLDAuMyknLFxuICAnZm9udC1mYW1pbHk6IEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYnLFxuICAnZm9udC1zaXplOiAxNHB4JyxcbiAgJ2Rpc3BsYXk6IGZsZXgnLFxuICAnbGluZS1oZWlnaHQ6IDEuMydcbl0pO1xuXG52YXIgTElHSFRCT1hfTUFSS1VQID1cbiAgJzxkaXYgY2xhc3M9XCJianMtcG93ZXJlZC1ieS1saWdodGJveFwiIHN0eWxlPVwiJyArIExJR0hUQk9YX1NUWUxFUyArICdcIj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImJhY2tkcm9wXCIgc3R5bGU9XCInICsgQkFDS0RST1BfU1RZTEVTICsgJ1wiPjwvZGl2PicgK1xuICAgICc8ZGl2IGNsYXNzPVwibm90aWNlXCIgc3R5bGU9XCInICsgTk9USUNFX1NUWUxFUyArICdcIj4nICtcbiAgICAgICc8YSBocmVmPVwiaHR0cHM6Ly9icG1uLmlvXCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9vcGVuZXJcIiBzdHlsZT1cIm1hcmdpbjogMTVweCAyMHB4IDE1cHggMTBweDsgYWxpZ24tc2VsZjogY2VudGVyOycgKyBMSU5LX1NUWUxFUyArICdcIj4nICtcbiAgICAgICAgQlBNTklPX0lNRyArXG4gICAgICAnPC9hPicgK1xuICAgICAgJzxzcGFuPicgK1xuICAgICAgICAnV2ViLWJhc2VkIHRvb2xpbmcgZm9yIEJQTU4sIERNTiBhbmQgQ01NTiBkaWFncmFtcyAnICtcbiAgICAgICAgJ3Bvd2VyZWQgYnkgPGEgaHJlZj1cImh0dHBzOi8vYnBtbi5pb1wiIHRhcmdldD1cIl9ibGFua1wiIHJlbD1cIm5vb3BlbmVyXCI+YnBtbi5pbzwvYT4uJyArXG4gICAgICAnPC9zcGFuPicgK1xuICAgICc8L2Rpdj4nICtcbiAgJzwvZGl2Pic7XG5cblxudmFyIGxpZ2h0Ym94O1xuXG5leHBvcnQgZnVuY3Rpb24gb3BlbigpIHtcblxuICBpZiAoIWxpZ2h0Ym94KSB7XG4gICAgbGlnaHRib3ggPSBkb21pZnkoTElHSFRCT1hfTUFSS1VQKTtcblxuICAgIGRvbURlbGVnYXRlLmJpbmQobGlnaHRib3gsICcuYmFja2Ryb3AnLCAnY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChsaWdodGJveCk7XG4gICAgfSk7XG4gIH1cblxuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxpZ2h0Ym94KTtcbn1cbiIsImV4cG9ydCB7IGRlZmF1bHQgfSBmcm9tICcuL2xpYi9EaWFncmFtJzsiLCJpbXBvcnQgeyBJbmplY3RvciB9IGZyb20gJ2RpZGknO1xuXG5pbXBvcnQgQ29yZU1vZHVsZSBmcm9tICcuL2NvcmUnO1xuXG5cbi8qKlxuICogQm9vdHN0cmFwIGFuIGluamVjdG9yIGZyb20gYSBsaXN0IG9mIG1vZHVsZXMsIGluc3RhbnRpYXRpbmcgYSBudW1iZXIgb2YgZGVmYXVsdCBjb21wb25lbnRzXG4gKlxuICogQGlnbm9yZVxuICogQHBhcmFtIHtBcnJheTxkaWRpLk1vZHVsZT59IGJvb3RzdHJhcE1vZHVsZXNcbiAqXG4gKiBAcmV0dXJuIHtkaWRpLkluamVjdG9yfSBhIGluamVjdG9yIHRvIHVzZSB0byBhY2Nlc3MgdGhlIGNvbXBvbmVudHNcbiAqL1xuZnVuY3Rpb24gYm9vdHN0cmFwKGJvb3RzdHJhcE1vZHVsZXMpIHtcblxuICB2YXIgbW9kdWxlcyA9IFtdLFxuICAgICAgY29tcG9uZW50cyA9IFtdO1xuXG4gIGZ1bmN0aW9uIGhhc01vZHVsZShtKSB7XG4gICAgcmV0dXJuIG1vZHVsZXMuaW5kZXhPZihtKSA+PSAwO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkTW9kdWxlKG0pIHtcbiAgICBtb2R1bGVzLnB1c2gobSk7XG4gIH1cblxuICBmdW5jdGlvbiB2aXNpdChtKSB7XG4gICAgaWYgKGhhc01vZHVsZShtKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIChtLl9fZGVwZW5kc19fIHx8IFtdKS5mb3JFYWNoKHZpc2l0KTtcblxuICAgIGlmIChoYXNNb2R1bGUobSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhZGRNb2R1bGUobSk7XG5cbiAgICAobS5fX2luaXRfXyB8fCBbXSkuZm9yRWFjaChmdW5jdGlvbihjKSB7XG4gICAgICBjb21wb25lbnRzLnB1c2goYyk7XG4gICAgfSk7XG4gIH1cblxuICBib290c3RyYXBNb2R1bGVzLmZvckVhY2godmlzaXQpO1xuXG4gIHZhciBpbmplY3RvciA9IG5ldyBJbmplY3Rvcihtb2R1bGVzKTtcblxuICBjb21wb25lbnRzLmZvckVhY2goZnVuY3Rpb24oYykge1xuXG4gICAgdHJ5IHtcblxuICAgICAgLy8gZWFnZXJseSByZXNvbHZlIGNvbXBvbmVudCAoZm4gb3Igc3RyaW5nKVxuICAgICAgaW5qZWN0b3JbdHlwZW9mIGMgPT09ICdzdHJpbmcnID8gJ2dldCcgOiAnaW52b2tlJ10oYyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGluc3RhbnRpYXRlIGNvbXBvbmVudCcpO1xuICAgICAgY29uc29sZS5lcnJvcihlLnN0YWNrKTtcblxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBpbmplY3Rvcjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGluamVjdG9yIGZyb20gcGFzc2VkIG9wdGlvbnMuXG4gKlxuICogQGlnbm9yZVxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHtkaWRpLkluamVjdG9yfVxuICovXG5mdW5jdGlvbiBjcmVhdGVJbmplY3RvcihvcHRpb25zKSB7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdmFyIGNvbmZpZ01vZHVsZSA9IHtcbiAgICAnY29uZmlnJzogWyd2YWx1ZScsIG9wdGlvbnNdXG4gIH07XG5cbiAgdmFyIG1vZHVsZXMgPSBbIGNvbmZpZ01vZHVsZSwgQ29yZU1vZHVsZSBdLmNvbmNhdChvcHRpb25zLm1vZHVsZXMgfHwgW10pO1xuXG4gIHJldHVybiBib290c3RyYXAobW9kdWxlcyk7XG59XG5cblxuLyoqXG4gKiBUaGUgbWFpbiBkaWFncmFtLWpzIGVudHJ5IHBvaW50IHRoYXQgYm9vdHN0cmFwcyB0aGUgZGlhZ3JhbSB3aXRoIHRoZSBnaXZlblxuICogY29uZmlndXJhdGlvbi5cbiAqXG4gKiBUbyByZWdpc3RlciBleHRlbnNpb25zIHdpdGggdGhlIGRpYWdyYW0sIHBhc3MgdGhlbSBhcyBBcnJheTxkaWRpLk1vZHVsZT4gdG8gdGhlIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBjbGFzcyBkanMuRGlhZ3JhbVxuICogQG1lbWJlck9mIGRqc1xuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiA8Y2FwdGlvbj5DcmVhdGluZyBhIHBsdWctaW4gdGhhdCBsb2dzIHdoZW5ldmVyIGEgc2hhcGUgaXMgYWRkZWQgdG8gdGhlIGNhbnZhcy48L2NhcHRpb24+XG4gKlxuICogLy8gcGx1Zy1pbiBpbXBsZW1lbmVudGF0aW9uXG4gKiBmdW5jdGlvbiBNeUxvZ2dpbmdQbHVnaW4oZXZlbnRCdXMpIHtcbiAqICAgZXZlbnRCdXMub24oJ3NoYXBlLmFkZGVkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgICBjb25zb2xlLmxvZygnc2hhcGUgJywgZXZlbnQuc2hhcGUsICcgd2FzIGFkZGVkIHRvIHRoZSBkaWFncmFtJyk7XG4gKiAgIH0pO1xuICogfVxuICpcbiAqIC8vIGV4cG9ydCBhcyBtb2R1bGVcbiAqIGV4cG9ydCBkZWZhdWx0IHtcbiAqICAgX19pbml0X186IFsgJ215TG9nZ2luZ1BsdWdpbicgXSxcbiAqICAgICBteUxvZ2dpbmdQbHVnaW46IFsgJ3R5cGUnLCBNeUxvZ2dpbmdQbHVnaW4gXVxuICogfTtcbiAqXG4gKlxuICogLy8gaW5zdGFudGlhdGUgdGhlIGRpYWdyYW0gd2l0aCB0aGUgbmV3IHBsdWctaW5cbiAqXG4gKiBpbXBvcnQgTXlMb2dnaW5nTW9kdWxlIGZyb20gJ3BhdGgtdG8tbXktbG9nZ2luZy1wbHVnaW4nO1xuICpcbiAqIHZhciBkaWFncmFtID0gbmV3IERpYWdyYW0oe1xuICogICBtb2R1bGVzOiBbXG4gKiAgICAgTXlMb2dnaW5nTW9kdWxlXG4gKiAgIF1cbiAqIH0pO1xuICpcbiAqIGRpYWdyYW0uaW52b2tlKFsgJ2NhbnZhcycsIGZ1bmN0aW9uKGNhbnZhcykge1xuICogICAvLyBhZGQgc2hhcGUgdG8gZHJhd2luZyBjYW52YXNcbiAqICAgY2FudmFzLmFkZFNoYXBlKHsgeDogMTAsIHk6IDEwIH0pO1xuICogfSk7XG4gKlxuICogLy8gJ3NoYXBlIC4uLiB3YXMgYWRkZWQgdG8gdGhlIGRpYWdyYW0nIGxvZ2dlZCB0byBjb25zb2xlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5tb2R1bGVzXSBleHRlcm5hbCBtb2R1bGVzIHRvIGluc3RhbnRpYXRlIHdpdGggdGhlIGRpYWdyYW1cbiAqIEBwYXJhbSB7ZGlkaS5JbmplY3Rvcn0gW2luamVjdG9yXSBhbiAob3B0aW9uYWwpIGluamVjdG9yIHRvIGJvb3RzdHJhcCB0aGUgZGlhZ3JhbSB3aXRoXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERpYWdyYW0ob3B0aW9ucywgaW5qZWN0b3IpIHtcblxuICAvLyBjcmVhdGUgaW5qZWN0b3IgdW5sZXNzIGV4cGxpY2l0bHkgc3BlY2lmaWVkXG4gIHRoaXMuaW5qZWN0b3IgPSBpbmplY3RvciA9IGluamVjdG9yIHx8IGNyZWF0ZUluamVjdG9yKG9wdGlvbnMpO1xuXG4gIC8vIEFQSVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIGRpYWdyYW0gc2VydmljZVxuICAgKlxuICAgKiBAbWV0aG9kIERpYWdyYW0jZ2V0XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBkaWFncmFtIHNlcnZpY2UgdG8gYmUgcmV0cmlldmVkXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3N0cmljdD10cnVlXSBpZiBmYWxzZSwgcmVzb2x2ZSBtaXNzaW5nIHNlcnZpY2VzIHRvIG51bGxcbiAgICovXG4gIHRoaXMuZ2V0ID0gaW5qZWN0b3IuZ2V0O1xuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyBhIGZ1bmN0aW9uIGludG8gd2hpY2ggZGlhZ3JhbSBzZXJ2aWNlcyBhcmUgaW5qZWN0ZWRcbiAgICpcbiAgICogQG1ldGhvZCBEaWFncmFtI2ludm9rZVxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdFtdfSBmbiB0aGUgZnVuY3Rpb24gdG8gcmVzb2x2ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gbG9jYWxzIGEgbnVtYmVyIG9mIGxvY2FscyB0byB1c2UgdG8gcmVzb2x2ZSBjZXJ0YWluIGRlcGVuZGVuY2llc1xuICAgKi9cbiAgdGhpcy5pbnZva2UgPSBpbmplY3Rvci5pbnZva2U7XG5cbiAgLy8gaW5pdFxuXG4gIC8vIGluZGljYXRlIHZpYSBldmVudFxuXG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhbGwgcGx1Zy1pbnMgYXJlIGxvYWRlZC5cbiAgICpcbiAgICogVXNlIHRoaXMgZXZlbnQgdG8gZmlyZSBvdGhlciBldmVudHMgdG8gaW50ZXJlc3RlZCBwbHVnLWluc1xuICAgKlxuICAgKiBAbWVtYmVyT2YgRGlhZ3JhbVxuICAgKlxuICAgKiBAZXZlbnQgZGlhZ3JhbS5pbml0XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqIGV2ZW50QnVzLm9uKCdkaWFncmFtLmluaXQnLCBmdW5jdGlvbigpIHtcbiAgICogICBldmVudEJ1cy5maXJlKCdteS1jdXN0b20tZXZlbnQnLCB7IGZvbzogJ0JBUicgfSk7XG4gICAqIH0pO1xuICAgKlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgdGhpcy5nZXQoJ2V2ZW50QnVzJykuZmlyZSgnZGlhZ3JhbS5pbml0Jyk7XG59XG5cblxuLyoqXG4gKiBEZXN0cm95cyB0aGUgZGlhZ3JhbVxuICpcbiAqIEBtZXRob2QgIERpYWdyYW0jZGVzdHJveVxuICovXG5EaWFncmFtLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuZ2V0KCdldmVudEJ1cycpLmZpcmUoJ2RpYWdyYW0uZGVzdHJveScpO1xufTtcblxuLyoqXG4gKiBDbGVhciB0aGUgZGlhZ3JhbSwgcmVtb3ZpbmcgYWxsIGNvbnRlbnRzLlxuICovXG5EaWFncmFtLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmdldCgnZXZlbnRCdXMnKS5maXJlKCdkaWFncmFtLmNsZWFyJyk7XG59O1xuIiwiaW1wb3J0IHtcbiAgZm9yRWFjaCxcbiAgaXNGdW5jdGlvbixcbiAgaXNBcnJheSxcbiAgaXNOdW1iZXIsXG4gIGlzT2JqZWN0XG59IGZyb20gJ21pbi1kYXNoJztcblxuXG52YXIgREVGQVVMVF9QUklPUklUWSA9IDEwMDA7XG5cbi8qKlxuICogQSB1dGlsaXR5IHRoYXQgY2FuIGJlIHVzZWQgdG8gcGx1Zy1pbiBpbnRvIHRoZSBjb21tYW5kIGV4ZWN1dGlvbiBmb3JcbiAqIGV4dGVuc2lvbiBhbmQvb3IgdmFsaWRhdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICpcbiAqIEBleGFtcGxlXG4gKlxuICogaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcbiAqXG4gKiBpbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcbiAqXG4gKiBmdW5jdGlvbiBDb21tYW5kTG9nZ2VyKGV2ZW50QnVzKSB7XG4gKiAgIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcbiAqXG4gKiAgIHRoaXMucHJlRXhlY3V0ZShmdW5jdGlvbihldmVudCkge1xuICogICAgIGNvbnNvbGUubG9nKCdjb21tYW5kIHByZS1leGVjdXRlJywgZXZlbnQpO1xuICogICB9KTtcbiAqIH1cbiAqXG4gKiBpbmhlcml0cyhDb21tYW5kTG9nZ2VyLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuICpcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ29tbWFuZEludGVyY2VwdG9yKGV2ZW50QnVzKSB7XG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG59XG5cbkNvbW1hbmRJbnRlcmNlcHRvci4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07XG5cbmZ1bmN0aW9uIHVud3JhcEV2ZW50KGZuLCB0aGF0KSB7XG4gIHJldHVybiBmdW5jdGlvbihldmVudCkge1xuICAgIHJldHVybiBmbi5jYWxsKHRoYXQgfHwgbnVsbCwgZXZlbnQuY29udGV4dCwgZXZlbnQuY29tbWFuZCwgZXZlbnQpO1xuICB9O1xufVxuXG4vKipcbiAqIFJlZ2lzdGVyIGFuIGludGVyY2VwdG9yIGZvciBhIGNvbW1hbmQgZXhlY3V0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gW2V2ZW50c10gbGlzdCBvZiBjb21tYW5kcyB0byByZWdpc3RlciBvblxuICogQHBhcmFtIHtzdHJpbmd9IFtob29rXSBjb21tYW5kIGhvb2ssIGkuZS4gcHJlRXhlY3V0ZSwgZXhlY3V0ZWQgdG8gbGlzdGVuIG9uXG4gKiBAcGFyYW0ge251bWJlcn0gW3ByaW9yaXR5XSB0aGUgcHJpb3JpdHkgb24gd2hpY2ggdG8gaG9vayBpbnRvIHRoZSBleGVjdXRpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJGbiBpbnRlcmNlcHRvciB0byBiZSBpbnZva2VkIHdpdGggKGV2ZW50KVxuICogQHBhcmFtIHtib29sZWFufSB1bndyYXAgaWYgdHJ1ZSwgdW53cmFwIHRoZSBldmVudCBhbmQgcGFzcyAoY29udGV4dCwgY29tbWFuZCwgZXZlbnQpIHRvIHRoZVxuICogICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyIGluc3RlYWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBbdGhhdF0gUGFzcyBjb250ZXh0IChgdGhpc2ApIHRvIHRoZSBoYW5kbGVyIGZ1bmN0aW9uXG4gKi9cbkNvbW1hbmRJbnRlcmNlcHRvci5wcm90b3R5cGUub24gPSBmdW5jdGlvbihldmVudHMsIGhvb2ssIHByaW9yaXR5LCBoYW5kbGVyRm4sIHVud3JhcCwgdGhhdCkge1xuXG4gIGlmIChpc0Z1bmN0aW9uKGhvb2spIHx8IGlzTnVtYmVyKGhvb2spKSB7XG4gICAgdGhhdCA9IHVud3JhcDtcbiAgICB1bndyYXAgPSBoYW5kbGVyRm47XG4gICAgaGFuZGxlckZuID0gcHJpb3JpdHk7XG4gICAgcHJpb3JpdHkgPSBob29rO1xuICAgIGhvb2sgPSBudWxsO1xuICB9XG5cbiAgaWYgKGlzRnVuY3Rpb24ocHJpb3JpdHkpKSB7XG4gICAgdGhhdCA9IHVud3JhcDtcbiAgICB1bndyYXAgPSBoYW5kbGVyRm47XG4gICAgaGFuZGxlckZuID0gcHJpb3JpdHk7XG4gICAgcHJpb3JpdHkgPSBERUZBVUxUX1BSSU9SSVRZO1xuICB9XG5cbiAgaWYgKGlzT2JqZWN0KHVud3JhcCkpIHtcbiAgICB0aGF0ID0gdW53cmFwO1xuICAgIHVud3JhcCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGhhbmRsZXJGbikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2hhbmRsZXJGbiBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIGlmICghaXNBcnJheShldmVudHMpKSB7XG4gICAgZXZlbnRzID0gWyBldmVudHMgXTtcbiAgfVxuXG4gIHZhciBldmVudEJ1cyA9IHRoaXMuX2V2ZW50QnVzO1xuXG4gIGZvckVhY2goZXZlbnRzLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgLy8gY29uY2F0IGNvbW1hbmRTdGFjayguZXZlbnQpPyguaG9vayk/XG4gICAgdmFyIGZ1bGxFdmVudCA9IFsgJ2NvbW1hbmRTdGFjaycsIGV2ZW50LCBob29rIF0uZmlsdGVyKGZ1bmN0aW9uKGUpIHsgcmV0dXJuIGU7IH0pLmpvaW4oJy4nKTtcblxuICAgIGV2ZW50QnVzLm9uKGZ1bGxFdmVudCwgcHJpb3JpdHksIHVud3JhcCA/IHVud3JhcEV2ZW50KGhhbmRsZXJGbiwgdGhhdCkgOiBoYW5kbGVyRm4sIHRoYXQpO1xuICB9KTtcbn07XG5cblxudmFyIGhvb2tzID0gW1xuICAnY2FuRXhlY3V0ZScsXG4gICdwcmVFeGVjdXRlJyxcbiAgJ3ByZUV4ZWN1dGVkJyxcbiAgJ2V4ZWN1dGUnLFxuICAnZXhlY3V0ZWQnLFxuICAncG9zdEV4ZWN1dGUnLFxuICAncG9zdEV4ZWN1dGVkJyxcbiAgJ3JldmVydCcsXG4gICdyZXZlcnRlZCdcbl07XG5cbi8qXG4gKiBJbnN0YWxsIGhvb2sgc2hvcnRjdXRzXG4gKlxuICogVGhpcyB3aWxsIGdlbmVyYXRlIHRoZSBDb21tYW5kSW50ZXJjZXB0b3IjKHByZUV4ZWN1dGV8Li4ufHJldmVydGVkKSBtZXRob2RzXG4gKiB3aGljaCB3aWxsIGluIHRlcm0gZm9yd2FyZCB0byBDb21tYW5kSW50ZXJjZXB0b3Ijb24uXG4gKi9cbmZvckVhY2goaG9va3MsIGZ1bmN0aW9uKGhvb2spIHtcblxuICAvKipcbiAgICoge2NhbkV4ZWN1dGV8cHJlRXhlY3V0ZXxwcmVFeGVjdXRlZHxleGVjdXRlfGV4ZWN1dGVkfHBvc3RFeGVjdXRlfHBvc3RFeGVjdXRlZHxyZXZlcnR8cmV2ZXJ0ZWR9XG4gICAqXG4gICAqIEEgbmFtZWQgaG9vayBmb3IgcGx1Z2dpbmcgaW50byB0aGUgY29tbWFuZCBleGVjdXRpb25cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gW2V2ZW50c10gbGlzdCBvZiBjb21tYW5kcyB0byByZWdpc3RlciBvblxuICAgKiBAcGFyYW0ge251bWJlcn0gW3ByaW9yaXR5XSB0aGUgcHJpb3JpdHkgb24gd2hpY2ggdG8gaG9vayBpbnRvIHRoZSBleGVjdXRpb25cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlckZuIGludGVyY2VwdG9yIHRvIGJlIGludm9rZWQgd2l0aCAoZXZlbnQpXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Vud3JhcD1mYWxzZV0gaWYgdHJ1ZSwgdW53cmFwIHRoZSBldmVudCBhbmQgcGFzcyAoY29udGV4dCwgY29tbWFuZCwgZXZlbnQpIHRvIHRoZVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgaW5zdGVhZFxuICAgKiBAcGFyYW0ge09iamVjdH0gW3RoYXRdIFBhc3MgY29udGV4dCAoYHRoaXNgKSB0byB0aGUgaGFuZGxlciBmdW5jdGlvblxuICAgKi9cbiAgQ29tbWFuZEludGVyY2VwdG9yLnByb3RvdHlwZVtob29rXSA9IGZ1bmN0aW9uKGV2ZW50cywgcHJpb3JpdHksIGhhbmRsZXJGbiwgdW53cmFwLCB0aGF0KSB7XG5cbiAgICBpZiAoaXNGdW5jdGlvbihldmVudHMpIHx8IGlzTnVtYmVyKGV2ZW50cykpIHtcbiAgICAgIHRoYXQgPSB1bndyYXA7XG4gICAgICB1bndyYXAgPSBoYW5kbGVyRm47XG4gICAgICBoYW5kbGVyRm4gPSBwcmlvcml0eTtcbiAgICAgIHByaW9yaXR5ID0gZXZlbnRzO1xuICAgICAgZXZlbnRzID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLm9uKGV2ZW50cywgaG9vaywgcHJpb3JpdHksIGhhbmRsZXJGbiwgdW53cmFwLCB0aGF0KTtcbiAgfTtcbn0pO1xuIiwiaW1wb3J0IHtcbiAgdW5pcXVlQnksXG4gIGlzQXJyYXlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5cbi8qKlxuICogQSBzZXJ2aWNlIHRoYXQgb2ZmZXJzIHVuLSBhbmQgcmVkb2FibGUgZXhlY3V0aW9uIG9mIGNvbW1hbmRzLlxuICpcbiAqIFRoZSBjb21tYW5kIHN0YWNrIGlzIHJlc3BvbnNpYmxlIGZvciBleGVjdXRpbmcgbW9kZWxpbmcgYWN0aW9uc1xuICogaW4gYSB1bi0gYW5kIHJlZG9hYmxlIG1hbm5lci4gVG8gZG8gdGhpcyBpdCBkZWxlZ2F0ZXMgdGhlIGFjdHVhbFxuICogY29tbWFuZCBleGVjdXRpb24gdG8ge0BsaW5rIENvbW1hbmRIYW5kbGVyfXMuXG4gKlxuICogQ29tbWFuZCBoYW5kbGVycyBwcm92aWRlIHtAbGluayBDb21tYW5kSGFuZGxlciNleGVjdXRlKGN0eCl9IGFuZFxuICoge0BsaW5rIENvbW1hbmRIYW5kbGVyI3JldmVydChjdHgpfSBtZXRob2RzIHRvIHVuLSBhbmQgcmVkbyBhIGNvbW1hbmRcbiAqIGlkZW50aWZpZWQgYnkgYSBjb21tYW5kIGNvbnRleHQuXG4gKlxuICpcbiAqICMjIExpZmUtQ3ljbGUgZXZlbnRzXG4gKlxuICogSW4gdGhlIHByb2Nlc3MgdGhlIGNvbW1hbmQgc3RhY2sgZmlyZXMgYSBudW1iZXIgb2YgbGlmZS1jeWNsZSBldmVudHNcbiAqIHRoYXQgb3RoZXIgY29tcG9uZW50cyB0byBwYXJ0aWNpcGF0ZSBpbiB0aGUgY29tbWFuZCBleGVjdXRpb24uXG4gKlxuICogICAgKiBwcmVFeGVjdXRlXG4gKiAgICAqIHByZUV4ZWN1dGVkXG4gKiAgICAqIGV4ZWN1dGVcbiAqICAgICogZXhlY3V0ZWRcbiAqICAgICogcG9zdEV4ZWN1dGVcbiAqICAgICogcG9zdEV4ZWN1dGVkXG4gKiAgICAqIHJldmVydFxuICogICAgKiByZXZlcnRlZFxuICpcbiAqIEEgc3BlY2lhbCBldmVudCBpcyB1c2VkIGZvciB2YWxpZGF0aW5nLCB3aGV0aGVyIGEgY29tbWFuZCBjYW4gYmVcbiAqIHBlcmZvcm1lZCBwcmlvciB0byBpdHMgZXhlY3V0aW9uLlxuICpcbiAqICAgICogY2FuRXhlY3V0ZVxuICpcbiAqIEVhY2ggb2YgdGhlIGV2ZW50cyBpcyBmaXJlZCBhcyBgY29tbWFuZFN0YWNrLntldmVudE5hbWV9YCBhbmRcbiAqIGBjb21tYW5kU3RhY2sue2NvbW1hbmROYW1lfS57ZXZlbnROYW1lfWAsIHJlc3BlY3RpdmVseS4gVGhpcyBnaXZlc1xuICogY29tcG9uZW50cyBmaW5lIGdyYWluZWQgY29udHJvbCBvbiB3aGVyZSB0byBob29rIGludG8uXG4gKlxuICogVGhlIGV2ZW50IG9iamVjdCBmaXJlZCB0cmFuc3BvcnRzIGBjb21tYW5kYCwgdGhlIG5hbWUgb2YgdGhlXG4gKiBjb21tYW5kIGFuZCBgY29udGV4dGAsIHRoZSBjb21tYW5kIGNvbnRleHQuXG4gKlxuICpcbiAqICMjIENyZWF0aW5nIENvbW1hbmQgSGFuZGxlcnNcbiAqXG4gKiBDb21tYW5kIGhhbmRsZXJzIHNob3VsZCBwcm92aWRlIHRoZSB7QGxpbmsgQ29tbWFuZEhhbmRsZXIjZXhlY3V0ZShjdHgpfVxuICogYW5kIHtAbGluayBDb21tYW5kSGFuZGxlciNyZXZlcnQoY3R4KX0gbWV0aG9kcyB0byBpbXBsZW1lbnRcbiAqIHJlZG9pbmcgYW5kIHVuZG9pbmcgb2YgYSBjb21tYW5kLlxuICpcbiAqIEEgY29tbWFuZCBoYW5kbGVyIF9tdXN0XyBlbnN1cmUgdW5kbyBpcyBwZXJmb3JtZWQgcHJvcGVybHkgaW4gb3JkZXJcbiAqIG5vdCB0byBicmVhayB0aGUgdW5kbyBjaGFpbi4gSXQgbXVzdCBhbHNvIHJldHVybiB0aGUgc2hhcGVzIHRoYXRcbiAqIGdvdCBjaGFuZ2VkIGR1cmluZyB0aGUgYGV4ZWN1dGVgIGFuZCBgcmV2ZXJ0YCBvcGVyYXRpb25zLlxuICpcbiAqIENvbW1hbmQgaGFuZGxlcnMgbWF5IGV4ZWN1dGUgb3RoZXIgbW9kZWxpbmcgb3BlcmF0aW9ucyAoYW5kIHRodXNcbiAqIGNvbW1hbmRzKSBpbiB0aGVpciBgcHJlRXhlY3V0ZWAgYW5kIGBwb3N0RXhlY3V0ZWAgcGhhc2VzLiBUaGUgY29tbWFuZFxuICogc3RhY2sgd2lsbCBwcm9wZXJseSBncm91cCBhbGwgY29tbWFuZHMgdG9nZXRoZXIgaW50byBhIGxvZ2ljYWwgdW5pdFxuICogdGhhdCBtYXkgYmUgcmUtIGFuZCB1bmRvbmUgYXRvbWljYWxseS5cbiAqXG4gKiBDb21tYW5kIGhhbmRsZXJzIG11c3Qgbm90IGV4ZWN1dGUgb3RoZXIgY29tbWFuZHMgZnJvbSB3aXRoaW4gdGhlaXJcbiAqIGNvcmUgaW1wbGVtZW50YXRpb24gKGBleGVjdXRlYCwgYHJldmVydGApLlxuICpcbiAqXG4gKiAjIyBDaGFuZ2UgVHJhY2tpbmdcbiAqXG4gKiBEdXJpbmcgdGhlIGV4ZWN1dGlvbiBvZiB0aGUgQ29tbWFuZFN0YWNrIGl0IHdpbGwga2VlcCB0cmFjayBvZiBhbGxcbiAqIGVsZW1lbnRzIHRoYXQgaGF2ZSBiZWVuIHRvdWNoZWQgZHVyaW5nIHRoZSBjb21tYW5kJ3MgZXhlY3V0aW9uLlxuICpcbiAqIEF0IHRoZSBlbmQgb2YgdGhlIENvbW1hbmRTdGFjayBleGVjdXRpb24gaXQgd2lsbCBub3RpZnkgaW50ZXJlc3RlZFxuICogY29tcG9uZW50cyB2aWEgYW4gJ2VsZW1lbnRzLmNoYW5nZWQnIGV2ZW50IHdpdGggYWxsIHRoZSBkaXJ0eVxuICogZWxlbWVudHMuXG4gKlxuICogVGhlIGV2ZW50IGNhbiBiZSBwaWNrZWQgdXAgYnkgY29tcG9uZW50cyB0aGF0IGFyZSBpbnRlcmVzdGVkIGluIHRoZSBmYWN0XG4gKiB0aGF0IGVsZW1lbnRzIGhhdmUgYmVlbiBjaGFuZ2VkLiBPbmUgdXNlIGNhc2UgZm9yIHRoaXMgaXMgdXBkYXRpbmdcbiAqIHRoZWlyIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBhZnRlciBtb3ZpbmcgLyByZXNpemluZyBvciBkZWxldGlvbi5cbiAqXG4gKiBAc2VlIENvbW1hbmRIYW5kbGVyXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvbW1hbmRTdGFjayhldmVudEJ1cywgaW5qZWN0b3IpIHtcblxuICAvKipcbiAgICogQSBtYXAgb2YgYWxsIHJlZ2lzdGVyZWQgY29tbWFuZCBoYW5kbGVycy5cbiAgICpcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHRoaXMuX2hhbmRsZXJNYXAgPSB7fTtcblxuICAvKipcbiAgICogQSBzdGFjayBjb250YWluaW5nIGFsbCByZS91bmRvYWJsZSBhY3Rpb25zIG9uIHRoZSBkaWFncmFtXG4gICAqXG4gICAqIEB0eXBlIHtBcnJheTxPYmplY3Q+fVxuICAgKi9cbiAgdGhpcy5fc3RhY2sgPSBbXTtcblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgaW5kZXggb24gdGhlIHN0YWNrXG4gICAqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICB0aGlzLl9zdGFja0lkeCA9IC0xO1xuXG4gIC8qKlxuICAgKiBDdXJyZW50IGFjdGl2ZSBjb21tYW5kU3RhY2sgZXhlY3V0aW9uXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLl9jdXJyZW50RXhlY3V0aW9uID0ge1xuICAgIGFjdGlvbnM6IFtdLFxuICAgIGRpcnR5OiBbXVxuICB9O1xuXG5cbiAgdGhpcy5faW5qZWN0b3IgPSBpbmplY3RvcjtcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcblxuICB0aGlzLl91aWQgPSAxO1xuXG4gIGV2ZW50QnVzLm9uKFtcbiAgICAnZGlhZ3JhbS5kZXN0cm95JyxcbiAgICAnZGlhZ3JhbS5jbGVhcidcbiAgXSwgZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5jbGVhcihmYWxzZSk7XG4gIH0sIHRoaXMpO1xufVxuXG5Db21tYW5kU3RhY2suJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2luamVjdG9yJyBdO1xuXG5cbi8qKlxuICogRXhlY3V0ZSBhIGNvbW1hbmRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY29tbWFuZCB0aGUgY29tbWFuZCB0byBleGVjdXRlXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCB0aGUgZW52aXJvbm1lbnQgdG8gZXhlY3V0ZSB0aGUgY29tbWFuZCBpblxuICovXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb21tYW5kLCBjb250ZXh0KSB7XG4gIGlmICghY29tbWFuZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY29tbWFuZCByZXF1aXJlZCcpO1xuICB9XG5cbiAgdmFyIGFjdGlvbiA9IHsgY29tbWFuZDogY29tbWFuZCwgY29udGV4dDogY29udGV4dCB9O1xuXG4gIHRoaXMuX3B1c2hBY3Rpb24oYWN0aW9uKTtcbiAgdGhpcy5faW50ZXJuYWxFeGVjdXRlKGFjdGlvbik7XG4gIHRoaXMuX3BvcEFjdGlvbihhY3Rpb24pO1xufTtcblxuXG4vKipcbiAqIEFzayB3aGV0aGVyIGEgZ2l2ZW4gY29tbWFuZCBjYW4gYmUgZXhlY3V0ZWQuXG4gKlxuICogSW1wbGVtZW50b3JzIG1heSBob29rIGludG8gdGhlIG1lY2hhbmlzbSBvbiB0d28gd2F5czpcbiAqXG4gKiAgICogaW4gZXZlbnQgbGlzdGVuZXJzOlxuICpcbiAqICAgICBVc2VycyBtYXkgcHJldmVudCB0aGUgZXhlY3V0aW9uIHZpYSBhbiBldmVudCBsaXN0ZW5lci5cbiAqICAgICBJdCBtdXN0IHByZXZlbnQgdGhlIGRlZmF1bHQgYWN0aW9uIGZvciBgY29tbWFuZFN0YWNrLig8Y29tbWFuZD4uKWNhbkV4ZWN1dGVgIGV2ZW50cy5cbiAqXG4gKiAgICogaW4gY29tbWFuZCBoYW5kbGVyczpcbiAqXG4gKiAgICAgSWYgdGhlIG1ldGhvZCB7QGxpbmsgQ29tbWFuZEhhbmRsZXIjY2FuRXhlY3V0ZX0gaXMgaW1wbGVtZW50ZWQgaW4gYSBoYW5kbGVyXG4gKiAgICAgaXQgd2lsbCBiZSBjYWxsZWQgdG8gZmlndXJlIG91dCB3aGV0aGVyIHRoZSBleGVjdXRpb24gaXMgYWxsb3dlZC5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGNvbW1hbmQgdGhlIGNvbW1hbmQgdG8gZXhlY3V0ZVxuICogQHBhcmFtICB7T2JqZWN0fSBjb250ZXh0IHRoZSBlbnZpcm9ubWVudCB0byBleGVjdXRlIHRoZSBjb21tYW5kIGluXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgY29tbWFuZCBjYW4gYmUgZXhlY3V0ZWRcbiAqL1xuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5jYW5FeGVjdXRlID0gZnVuY3Rpb24oY29tbWFuZCwgY29udGV4dCkge1xuXG4gIHZhciBhY3Rpb24gPSB7IGNvbW1hbmQ6IGNvbW1hbmQsIGNvbnRleHQ6IGNvbnRleHQgfTtcblxuICB2YXIgaGFuZGxlciA9IHRoaXMuX2dldEhhbmRsZXIoY29tbWFuZCk7XG5cbiAgdmFyIHJlc3VsdCA9IHRoaXMuX2ZpcmUoY29tbWFuZCwgJ2NhbkV4ZWN1dGUnLCBhY3Rpb24pO1xuXG4gIC8vIGhhbmRsZXIjY2FuRXhlY3V0ZSB3aWxsIG9ubHkgYmUgY2FsbGVkIGlmIG5vIGxpc3RlbmVyXG4gIC8vIGRlY2lkZWQgb24gYSByZXN1bHQgYWxyZWFkeVxuICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoaGFuZGxlci5jYW5FeGVjdXRlKSB7XG4gICAgICByZXN1bHQgPSBoYW5kbGVyLmNhbkV4ZWN1dGUoY29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cblxuLyoqXG4gKiBDbGVhciB0aGUgY29tbWFuZCBzdGFjaywgZXJhc2luZyBhbGwgdW5kbyAvIHJlZG8gaGlzdG9yeVxuICovXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oZW1pdCkge1xuICB0aGlzLl9zdGFjay5sZW5ndGggPSAwO1xuICB0aGlzLl9zdGFja0lkeCA9IC0xO1xuXG4gIGlmIChlbWl0ICE9PSBmYWxzZSkge1xuICAgIHRoaXMuX2ZpcmUoJ2NoYW5nZWQnKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIFVuZG8gbGFzdCBjb21tYW5kKHMpXG4gKi9cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUudW5kbyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgYWN0aW9uID0gdGhpcy5fZ2V0VW5kb0FjdGlvbigpLFxuICAgICAgbmV4dDtcblxuICBpZiAoYWN0aW9uKSB7XG4gICAgdGhpcy5fcHVzaEFjdGlvbihhY3Rpb24pO1xuXG4gICAgd2hpbGUgKGFjdGlvbikge1xuICAgICAgdGhpcy5faW50ZXJuYWxVbmRvKGFjdGlvbik7XG4gICAgICBuZXh0ID0gdGhpcy5fZ2V0VW5kb0FjdGlvbigpO1xuXG4gICAgICBpZiAoIW5leHQgfHwgbmV4dC5pZCAhPT0gYWN0aW9uLmlkKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBhY3Rpb24gPSBuZXh0O1xuICAgIH1cblxuICAgIHRoaXMuX3BvcEFjdGlvbigpO1xuICB9XG59O1xuXG5cbi8qKlxuICogUmVkbyBsYXN0IGNvbW1hbmQocylcbiAqL1xuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5yZWRvID0gZnVuY3Rpb24oKSB7XG4gIHZhciBhY3Rpb24gPSB0aGlzLl9nZXRSZWRvQWN0aW9uKCksXG4gICAgICBuZXh0O1xuXG4gIGlmIChhY3Rpb24pIHtcbiAgICB0aGlzLl9wdXNoQWN0aW9uKGFjdGlvbik7XG5cbiAgICB3aGlsZSAoYWN0aW9uKSB7XG4gICAgICB0aGlzLl9pbnRlcm5hbEV4ZWN1dGUoYWN0aW9uLCB0cnVlKTtcbiAgICAgIG5leHQgPSB0aGlzLl9nZXRSZWRvQWN0aW9uKCk7XG5cbiAgICAgIGlmICghbmV4dCB8fCBuZXh0LmlkICE9PSBhY3Rpb24uaWQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGFjdGlvbiA9IG5leHQ7XG4gICAgfVxuXG4gICAgdGhpcy5fcG9wQWN0aW9uKCk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBSZWdpc3RlciBhIGhhbmRsZXIgaW5zdGFuY2Ugd2l0aCB0aGUgY29tbWFuZCBzdGFja1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb21tYW5kXG4gKiBAcGFyYW0ge0NvbW1hbmRIYW5kbGVyfSBoYW5kbGVyXG4gKi9cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUucmVnaXN0ZXIgPSBmdW5jdGlvbihjb21tYW5kLCBoYW5kbGVyKSB7XG4gIHRoaXMuX3NldEhhbmRsZXIoY29tbWFuZCwgaGFuZGxlcik7XG59O1xuXG5cbi8qKlxuICogUmVnaXN0ZXIgYSBoYW5kbGVyIHR5cGUgd2l0aCB0aGUgY29tbWFuZCBzdGFja1xuICogYnkgaW5zdGFudGlhdGluZyBpdCBhbmQgaW5qZWN0aW5nIGl0cyBkZXBlbmRlbmNpZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbW1hbmRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGEgY29uc3RydWN0b3IgZm9yIGEge0BsaW5rIENvbW1hbmRIYW5kbGVyfVxuICovXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLnJlZ2lzdGVySGFuZGxlciA9IGZ1bmN0aW9uKGNvbW1hbmQsIGhhbmRsZXJDbHMpIHtcblxuICBpZiAoIWNvbW1hbmQgfHwgIWhhbmRsZXJDbHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbW1hbmQgYW5kIGhhbmRsZXJDbHMgbXVzdCBiZSBkZWZpbmVkJyk7XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IHRoaXMuX2luamVjdG9yLmluc3RhbnRpYXRlKGhhbmRsZXJDbHMpO1xuICB0aGlzLnJlZ2lzdGVyKGNvbW1hbmQsIGhhbmRsZXIpO1xufTtcblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5jYW5VbmRvID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAhIXRoaXMuX2dldFVuZG9BY3Rpb24oKTtcbn07XG5cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUuY2FuUmVkbyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gISF0aGlzLl9nZXRSZWRvQWN0aW9uKCk7XG59O1xuXG4vLyBzdGFjayBhY2Nlc3MgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fZ2V0UmVkb0FjdGlvbiA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fc3RhY2tbdGhpcy5fc3RhY2tJZHggKyAxXTtcbn07XG5cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fZ2V0VW5kb0FjdGlvbiA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fc3RhY2tbdGhpcy5fc3RhY2tJZHhdO1xufTtcblxuXG4vLyBpbnRlcm5hbCBmdW5jdGlvbmFsaXR5IC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5faW50ZXJuYWxVbmRvID0gZnVuY3Rpb24oYWN0aW9uKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgY29tbWFuZCA9IGFjdGlvbi5jb21tYW5kLFxuICAgICAgY29udGV4dCA9IGFjdGlvbi5jb250ZXh0O1xuXG4gIHZhciBoYW5kbGVyID0gdGhpcy5fZ2V0SGFuZGxlcihjb21tYW5kKTtcblxuICAvLyBndWFyZCBhZ2FpbnN0IGlsbGVnYWwgbmVzdGVkIGNvbW1hbmQgc3RhY2sgaW52b2NhdGlvbnNcbiAgdGhpcy5fYXRvbWljRG8oZnVuY3Rpb24oKSB7XG4gICAgc2VsZi5fZmlyZShjb21tYW5kLCAncmV2ZXJ0JywgYWN0aW9uKTtcblxuICAgIGlmIChoYW5kbGVyLnJldmVydCkge1xuICAgICAgc2VsZi5fbWFya0RpcnR5KGhhbmRsZXIucmV2ZXJ0KGNvbnRleHQpKTtcbiAgICB9XG5cbiAgICBzZWxmLl9yZXZlcnRlZEFjdGlvbihhY3Rpb24pO1xuXG4gICAgc2VsZi5fZmlyZShjb21tYW5kLCAncmV2ZXJ0ZWQnLCBhY3Rpb24pO1xuICB9KTtcbn07XG5cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fZmlyZSA9IGZ1bmN0aW9uKGNvbW1hbmQsIHF1YWxpZmllciwgZXZlbnQpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgZXZlbnQgPSBxdWFsaWZpZXI7XG4gICAgcXVhbGlmaWVyID0gbnVsbDtcbiAgfVxuXG4gIHZhciBuYW1lcyA9IHF1YWxpZmllciA/IFsgY29tbWFuZCArICcuJyArIHF1YWxpZmllciwgcXVhbGlmaWVyIF0gOiBbIGNvbW1hbmQgXSxcbiAgICAgIGksIG5hbWUsIHJlc3VsdDtcblxuICBldmVudCA9IHRoaXMuX2V2ZW50QnVzLmNyZWF0ZUV2ZW50KGV2ZW50KTtcblxuICBmb3IgKGkgPSAwOyAobmFtZSA9IG5hbWVzW2ldKTsgaSsrKSB7XG4gICAgcmVzdWx0ID0gdGhpcy5fZXZlbnRCdXMuZmlyZSgnY29tbWFuZFN0YWNrLicgKyBuYW1lLCBldmVudCk7XG5cbiAgICBpZiAoZXZlbnQuY2FuY2VsQnViYmxlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fY3JlYXRlSWQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX3VpZCsrO1xufTtcblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fYXRvbWljRG8gPSBmdW5jdGlvbihmbikge1xuXG4gIHZhciBleGVjdXRpb24gPSB0aGlzLl9jdXJyZW50RXhlY3V0aW9uO1xuXG4gIGV4ZWN1dGlvbi5hdG9taWMgPSB0cnVlO1xuXG4gIHRyeSB7XG4gICAgZm4oKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBleGVjdXRpb24uYXRvbWljID0gZmFsc2U7XG4gIH1cbn07XG5cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUuX2ludGVybmFsRXhlY3V0ZSA9IGZ1bmN0aW9uKGFjdGlvbiwgcmVkbykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGNvbW1hbmQgPSBhY3Rpb24uY29tbWFuZCxcbiAgICAgIGNvbnRleHQgPSBhY3Rpb24uY29udGV4dDtcblxuICB2YXIgaGFuZGxlciA9IHRoaXMuX2dldEhhbmRsZXIoY29tbWFuZCk7XG5cbiAgaWYgKCFoYW5kbGVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdubyBjb21tYW5kIGhhbmRsZXIgcmVnaXN0ZXJlZCBmb3IgPCcgKyBjb21tYW5kICsgJz4nKTtcbiAgfVxuXG4gIHRoaXMuX3B1c2hBY3Rpb24oYWN0aW9uKTtcblxuICBpZiAoIXJlZG8pIHtcbiAgICB0aGlzLl9maXJlKGNvbW1hbmQsICdwcmVFeGVjdXRlJywgYWN0aW9uKTtcblxuICAgIGlmIChoYW5kbGVyLnByZUV4ZWN1dGUpIHtcbiAgICAgIGhhbmRsZXIucHJlRXhlY3V0ZShjb250ZXh0KTtcbiAgICB9XG5cbiAgICB0aGlzLl9maXJlKGNvbW1hbmQsICdwcmVFeGVjdXRlZCcsIGFjdGlvbik7XG4gIH1cblxuICAvLyBndWFyZCBhZ2FpbnN0IGlsbGVnYWwgbmVzdGVkIGNvbW1hbmQgc3RhY2sgaW52b2NhdGlvbnNcbiAgdGhpcy5fYXRvbWljRG8oZnVuY3Rpb24oKSB7XG5cbiAgICBzZWxmLl9maXJlKGNvbW1hbmQsICdleGVjdXRlJywgYWN0aW9uKTtcblxuICAgIGlmIChoYW5kbGVyLmV4ZWN1dGUpIHtcblxuICAgICAgLy8gYWN0dWFsIGV4ZWN1dGUgKyBtYXJrIHJldHVybiByZXN1bHRzIGFzIGRpcnR5XG4gICAgICBzZWxmLl9tYXJrRGlydHkoaGFuZGxlci5leGVjdXRlKGNvbnRleHQpKTtcbiAgICB9XG5cbiAgICAvLyBsb2cgdG8gc3RhY2tcbiAgICBzZWxmLl9leGVjdXRlZEFjdGlvbihhY3Rpb24sIHJlZG8pO1xuXG4gICAgc2VsZi5fZmlyZShjb21tYW5kLCAnZXhlY3V0ZWQnLCBhY3Rpb24pO1xuICB9KTtcblxuICBpZiAoIXJlZG8pIHtcbiAgICB0aGlzLl9maXJlKGNvbW1hbmQsICdwb3N0RXhlY3V0ZScsIGFjdGlvbik7XG5cbiAgICBpZiAoaGFuZGxlci5wb3N0RXhlY3V0ZSkge1xuICAgICAgaGFuZGxlci5wb3N0RXhlY3V0ZShjb250ZXh0KTtcbiAgICB9XG5cbiAgICB0aGlzLl9maXJlKGNvbW1hbmQsICdwb3N0RXhlY3V0ZWQnLCBhY3Rpb24pO1xuICB9XG5cbiAgdGhpcy5fcG9wQWN0aW9uKGFjdGlvbik7XG59O1xuXG5cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUuX3B1c2hBY3Rpb24gPSBmdW5jdGlvbihhY3Rpb24pIHtcblxuICB2YXIgZXhlY3V0aW9uID0gdGhpcy5fY3VycmVudEV4ZWN1dGlvbixcbiAgICAgIGFjdGlvbnMgPSBleGVjdXRpb24uYWN0aW9ucztcblxuICB2YXIgYmFzZUFjdGlvbiA9IGFjdGlvbnNbMF07XG5cbiAgaWYgKGV4ZWN1dGlvbi5hdG9taWMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lsbGVnYWwgaW52b2NhdGlvbiBpbiA8ZXhlY3V0ZT4gb3IgPHJldmVydD4gcGhhc2UgKGFjdGlvbjogJyArIGFjdGlvbi5jb21tYW5kICsgJyknKTtcbiAgfVxuXG4gIGlmICghYWN0aW9uLmlkKSB7XG4gICAgYWN0aW9uLmlkID0gKGJhc2VBY3Rpb24gJiYgYmFzZUFjdGlvbi5pZCkgfHwgdGhpcy5fY3JlYXRlSWQoKTtcbiAgfVxuXG4gIGFjdGlvbnMucHVzaChhY3Rpb24pO1xufTtcblxuXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLl9wb3BBY3Rpb24gPSBmdW5jdGlvbigpIHtcbiAgdmFyIGV4ZWN1dGlvbiA9IHRoaXMuX2N1cnJlbnRFeGVjdXRpb24sXG4gICAgICBhY3Rpb25zID0gZXhlY3V0aW9uLmFjdGlvbnMsXG4gICAgICBkaXJ0eSA9IGV4ZWN1dGlvbi5kaXJ0eTtcblxuICBhY3Rpb25zLnBvcCgpO1xuXG4gIGlmICghYWN0aW9ucy5sZW5ndGgpIHtcbiAgICB0aGlzLl9ldmVudEJ1cy5maXJlKCdlbGVtZW50cy5jaGFuZ2VkJywgeyBlbGVtZW50czogdW5pcXVlQnkoJ2lkJywgZGlydHkucmV2ZXJzZSgpKSB9KTtcblxuICAgIGRpcnR5Lmxlbmd0aCA9IDA7XG5cbiAgICB0aGlzLl9maXJlKCdjaGFuZ2VkJyk7XG4gIH1cbn07XG5cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fbWFya0RpcnR5ID0gZnVuY3Rpb24oZWxlbWVudHMpIHtcbiAgdmFyIGV4ZWN1dGlvbiA9IHRoaXMuX2N1cnJlbnRFeGVjdXRpb247XG5cbiAgaWYgKCFlbGVtZW50cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGVsZW1lbnRzID0gaXNBcnJheShlbGVtZW50cykgPyBlbGVtZW50cyA6IFsgZWxlbWVudHMgXTtcblxuICBleGVjdXRpb24uZGlydHkgPSBleGVjdXRpb24uZGlydHkuY29uY2F0KGVsZW1lbnRzKTtcbn07XG5cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fZXhlY3V0ZWRBY3Rpb24gPSBmdW5jdGlvbihhY3Rpb24sIHJlZG8pIHtcbiAgdmFyIHN0YWNrSWR4ID0gKyt0aGlzLl9zdGFja0lkeDtcblxuICBpZiAoIXJlZG8pIHtcbiAgICB0aGlzLl9zdGFjay5zcGxpY2Uoc3RhY2tJZHgsIHRoaXMuX3N0YWNrLmxlbmd0aCwgYWN0aW9uKTtcbiAgfVxufTtcblxuXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLl9yZXZlcnRlZEFjdGlvbiA9IGZ1bmN0aW9uKGFjdGlvbikge1xuICB0aGlzLl9zdGFja0lkeC0tO1xufTtcblxuXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLl9nZXRIYW5kbGVyID0gZnVuY3Rpb24oY29tbWFuZCkge1xuICByZXR1cm4gdGhpcy5faGFuZGxlck1hcFtjb21tYW5kXTtcbn07XG5cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUuX3NldEhhbmRsZXIgPSBmdW5jdGlvbihjb21tYW5kLCBoYW5kbGVyKSB7XG4gIGlmICghY29tbWFuZCB8fCAhaGFuZGxlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignY29tbWFuZCBhbmQgaGFuZGxlciByZXF1aXJlZCcpO1xuICB9XG5cbiAgaWYgKHRoaXMuX2hhbmRsZXJNYXBbY29tbWFuZF0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ292ZXJyaWRpbmcgaGFuZGxlciBmb3IgY29tbWFuZCA8JyArIGNvbW1hbmQgKyAnPicpO1xuICB9XG5cbiAgdGhpcy5faGFuZGxlck1hcFtjb21tYW5kXSA9IGhhbmRsZXI7XG59O1xuIiwiaW1wb3J0IENvbW1hbmRTdGFjayBmcm9tICcuL0NvbW1hbmRTdGFjayc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgY29tbWFuZFN0YWNrOiBbICd0eXBlJywgQ29tbWFuZFN0YWNrIF1cbn07XG4iLCJpbXBvcnQge1xuICBpc051bWJlcixcbiAgYXNzaWduLFxuICBmb3JFYWNoLFxuICBldmVyeSxcbiAgZGVib3VuY2UsXG4gIGJpbmQsXG4gIHJlZHVjZVxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGFkZCBhcyBjb2xsZWN0aW9uQWRkLFxuICByZW1vdmUgYXMgY29sbGVjdGlvblJlbW92ZVxufSBmcm9tICcuLi91dGlsL0NvbGxlY3Rpb25zJztcblxuaW1wb3J0IHtcbiAgZ2V0VHlwZVxufSBmcm9tICcuLi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjbGFzc2VzIGFzIHN2Z0NsYXNzZXMsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHRyYW5zZm9ybSBhcyBzdmdUcmFuc2Zvcm1cbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQgeyBjcmVhdGVNYXRyaXggYXMgY3JlYXRlTWF0cml4IH0gZnJvbSAndGlueS1zdmcnO1xuXG5cbmZ1bmN0aW9uIHJvdW5kKG51bWJlciwgcmVzb2x1dGlvbikge1xuICByZXR1cm4gTWF0aC5yb3VuZChudW1iZXIgKiByZXNvbHV0aW9uKSAvIHJlc29sdXRpb247XG59XG5cbmZ1bmN0aW9uIGVuc3VyZVB4KG51bWJlcikge1xuICByZXR1cm4gaXNOdW1iZXIobnVtYmVyKSA/IG51bWJlciArICdweCcgOiBudW1iZXI7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIEhUTUwgY29udGFpbmVyIGVsZW1lbnQgZm9yIGEgU1ZHIGVsZW1lbnQgd2l0aFxuICogdGhlIGdpdmVuIGNvbmZpZ3VyYXRpb25cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSB0aGUgY29udGFpbmVyIGVsZW1lbnRcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ29udGFpbmVyKG9wdGlvbnMpIHtcblxuICBvcHRpb25zID0gYXNzaWduKHt9LCB7IHdpZHRoOiAnMTAwJScsIGhlaWdodDogJzEwMCUnIH0sIG9wdGlvbnMpO1xuXG4gIHZhciBjb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lciB8fCBkb2N1bWVudC5ib2R5O1xuXG4gIC8vIGNyZWF0ZSBhIDxkaXY+IGFyb3VuZCB0aGUgc3ZnIGVsZW1lbnQgd2l0aCB0aGUgcmVzcGVjdGl2ZSBzaXplXG4gIC8vIHRoaXMgd2F5IHdlIGNhbiBhbHdheXMgZ2V0IHRoZSBjb3JyZWN0IGNvbnRhaW5lciBzaXplXG4gIC8vICh0aGlzIGlzIGltcG9zc2libGUgZm9yIDxzdmc+IGVsZW1lbnRzIGF0IHRoZSBtb21lbnQpXG4gIHZhciBwYXJlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgcGFyZW50LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnZGpzLWNvbnRhaW5lcicpO1xuXG4gIGFzc2lnbihwYXJlbnQuc3R5bGUsIHtcbiAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJyxcbiAgICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gICAgd2lkdGg6IGVuc3VyZVB4KG9wdGlvbnMud2lkdGgpLFxuICAgIGhlaWdodDogZW5zdXJlUHgob3B0aW9ucy5oZWlnaHQpXG4gIH0pO1xuXG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChwYXJlbnQpO1xuXG4gIHJldHVybiBwYXJlbnQ7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUdyb3VwKHBhcmVudCwgY2xzLCBjaGlsZEluZGV4KSB7XG4gIHZhciBncm91cCA9IHN2Z0NyZWF0ZSgnZycpO1xuICBzdmdDbGFzc2VzKGdyb3VwKS5hZGQoY2xzKTtcblxuICB2YXIgaW5kZXggPSBjaGlsZEluZGV4ICE9PSB1bmRlZmluZWQgPyBjaGlsZEluZGV4IDogcGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoIC0gMTtcblxuICAvLyBtdXN0IGVuc3VyZSBzZWNvbmQgYXJndW1lbnQgaXMgbm9kZSBvciBfbnVsbF9cbiAgLy8gY2YuIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Ob2RlL2luc2VydEJlZm9yZVxuICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGdyb3VwLCBwYXJlbnQuY2hpbGROb2Rlc1tpbmRleF0gfHwgbnVsbCk7XG5cbiAgcmV0dXJuIGdyb3VwO1xufVxuXG52YXIgQkFTRV9MQVlFUiA9ICdiYXNlJztcblxuXG52YXIgUkVRVUlSRURfTU9ERUxfQVRUUlMgPSB7XG4gIHNoYXBlOiBbICd4JywgJ3knLCAnd2lkdGgnLCAnaGVpZ2h0JyBdLFxuICBjb25uZWN0aW9uOiBbICd3YXlwb2ludHMnIF1cbn07XG5cbi8qKlxuICogVGhlIG1haW4gZHJhd2luZyBjYW52YXMuXG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAZW1pdHMgQ2FudmFzI2NhbnZhcy5pbml0XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZ1xuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7R3JhcGhpY3NGYWN0b3J5fSBncmFwaGljc0ZhY3RvcnlcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ2FudmFzKGNvbmZpZywgZXZlbnRCdXMsIGdyYXBoaWNzRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5KSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9ncmFwaGljc0ZhY3RvcnkgPSBncmFwaGljc0ZhY3Rvcnk7XG5cbiAgdGhpcy5faW5pdChjb25maWcgfHwge30pO1xufVxuXG5DYW52YXMuJGluamVjdCA9IFtcbiAgJ2NvbmZpZy5jYW52YXMnLFxuICAnZXZlbnRCdXMnLFxuICAnZ3JhcGhpY3NGYWN0b3J5JyxcbiAgJ2VsZW1lbnRSZWdpc3RyeSdcbl07XG5cblxuQ2FudmFzLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uKGNvbmZpZykge1xuXG4gIHZhciBldmVudEJ1cyA9IHRoaXMuX2V2ZW50QnVzO1xuXG4gIC8vIENyZWF0ZXMgYSA8c3ZnPiBlbGVtZW50IHRoYXQgaXMgd3JhcHBlZCBpbnRvIGEgPGRpdj4uXG4gIC8vIFRoaXMgd2F5IHdlIGFyZSBhbHdheXMgYWJsZSB0byBjb3JyZWN0bHkgZmlndXJlIG91dCB0aGUgc2l6ZSBvZiB0aGUgc3ZnIGVsZW1lbnRcbiAgLy8gYnkgcXVlcnlpbmcgdGhlIHBhcmVudCBub2RlLlxuICAvL1xuICAvLyAoSXQgaXMgbm90IHBvc3NpYmxlIHRvIGdldCB0aGUgc2l6ZSBvZiBhIHN2ZyBlbGVtZW50IGNyb3NzIGJyb3dzZXIgQCAyMDE0LTA0LTAxKVxuICAvL1xuICAvLyA8ZGl2IGNsYXNzPVwiZGpzLWNvbnRhaW5lclwiIHN0eWxlPVwid2lkdGg6IHtkZXNpcmVkLXdpZHRofSwgaGVpZ2h0OiB7ZGVzaXJlZC1oZWlnaHR9XCI+XG4gIC8vICAgPHN2ZyB3aWR0aD1cIjEwMCVcIiBoZWlnaHQ9XCIxMDAlXCI+XG4gIC8vICAgIC4uLlxuICAvLyAgIDwvc3ZnPlxuICAvLyA8L2Rpdj5cblxuICAvLyBodG1sIGNvbnRhaW5lclxuICB2YXIgY29udGFpbmVyID0gdGhpcy5fY29udGFpbmVyID0gY3JlYXRlQ29udGFpbmVyKGNvbmZpZyk7XG5cbiAgdmFyIHN2ZyA9IHRoaXMuX3N2ZyA9IHN2Z0NyZWF0ZSgnc3ZnJyk7XG4gIHN2Z0F0dHIoc3ZnLCB7IHdpZHRoOiAnMTAwJScsIGhlaWdodDogJzEwMCUnIH0pO1xuXG4gIHN2Z0FwcGVuZChjb250YWluZXIsIHN2Zyk7XG5cbiAgdmFyIHZpZXdwb3J0ID0gdGhpcy5fdmlld3BvcnQgPSBjcmVhdGVHcm91cChzdmcsICd2aWV3cG9ydCcpO1xuXG4gIHRoaXMuX2xheWVycyA9IHt9O1xuXG4gIC8vIGRlYm91bmNlIGNhbnZhcy52aWV3Ym94LmNoYW5nZWQgZXZlbnRzXG4gIC8vIGZvciBzbW9vdGhlciBkaWFncmFtIGludGVyYWN0aW9uXG4gIGlmIChjb25maWcuZGVmZXJVcGRhdGUgIT09IGZhbHNlKSB7XG4gICAgdGhpcy5fdmlld2JveENoYW5nZWQgPSBkZWJvdW5jZShiaW5kKHRoaXMuX3ZpZXdib3hDaGFuZ2VkLCB0aGlzKSwgMzAwKTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdkaWFncmFtLmluaXQnLCBmdW5jdGlvbigpIHtcblxuICAgIC8qKlxuICAgICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgY2FudmFzIGlzIHJlYWR5IHRvIGJlIGRyYXduIG9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIENhbnZhc1xuICAgICAqXG4gICAgICogQGV2ZW50IGNhbnZhcy5pbml0XG4gICAgICpcbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gc3ZnIHRoZSBjcmVhdGVkIHN2ZyBlbGVtZW50XG4gICAgICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSB2aWV3cG9ydCB0aGUgZGlyZWN0IHBhcmVudCBvZiBkaWFncmFtIGVsZW1lbnRzIGFuZCBzaGFwZXNcbiAgICAgKi9cbiAgICBldmVudEJ1cy5maXJlKCdjYW52YXMuaW5pdCcsIHtcbiAgICAgIHN2Zzogc3ZnLFxuICAgICAgdmlld3BvcnQ6IHZpZXdwb3J0XG4gICAgfSk7XG5cbiAgfSwgdGhpcyk7XG5cbiAgLy8gcmVzZXQgdmlld2JveCBvbiBzaGFwZSBjaGFuZ2VzIHRvXG4gIC8vIHJlY29tcHV0ZSB0aGUgdmlld2JveFxuICBldmVudEJ1cy5vbihbXG4gICAgJ3NoYXBlLmFkZGVkJyxcbiAgICAnY29ubmVjdGlvbi5hZGRlZCcsXG4gICAgJ3NoYXBlLnJlbW92ZWQnLFxuICAgICdjb25uZWN0aW9uLnJlbW92ZWQnLFxuICAgICdlbGVtZW50cy5jaGFuZ2VkJ1xuICBdLCBmdW5jdGlvbigpIHtcbiAgICBkZWxldGUgdGhpcy5fY2FjaGVkVmlld2JveDtcbiAgfSwgdGhpcyk7XG5cbiAgZXZlbnRCdXMub24oJ2RpYWdyYW0uZGVzdHJveScsIDUwMCwgdGhpcy5fZGVzdHJveSwgdGhpcyk7XG4gIGV2ZW50QnVzLm9uKCdkaWFncmFtLmNsZWFyJywgNTAwLCB0aGlzLl9jbGVhciwgdGhpcyk7XG59O1xuXG5DYW52YXMucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24oZW1pdCkge1xuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjYW52YXMuZGVzdHJveScsIHtcbiAgICBzdmc6IHRoaXMuX3N2ZyxcbiAgICB2aWV3cG9ydDogdGhpcy5fdmlld3BvcnRcbiAgfSk7XG5cbiAgdmFyIHBhcmVudCA9IHRoaXMuX2NvbnRhaW5lci5wYXJlbnROb2RlO1xuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy5fY29udGFpbmVyKTtcbiAgfVxuXG4gIGRlbGV0ZSB0aGlzLl9zdmc7XG4gIGRlbGV0ZSB0aGlzLl9jb250YWluZXI7XG4gIGRlbGV0ZSB0aGlzLl9sYXllcnM7XG4gIGRlbGV0ZSB0aGlzLl9yb290RWxlbWVudDtcbiAgZGVsZXRlIHRoaXMuX3ZpZXdwb3J0O1xufTtcblxuQ2FudmFzLnByb3RvdHlwZS5fY2xlYXIgPSBmdW5jdGlvbigpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGFsbEVsZW1lbnRzID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldEFsbCgpO1xuXG4gIC8vIHJlbW92ZSBhbGwgZWxlbWVudHNcbiAgYWxsRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgdmFyIHR5cGUgPSBnZXRUeXBlKGVsZW1lbnQpO1xuXG4gICAgaWYgKHR5cGUgPT09ICdyb290Jykge1xuICAgICAgc2VsZi5zZXRSb290RWxlbWVudChudWxsLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi5fcmVtb3ZlRWxlbWVudChlbGVtZW50LCB0eXBlKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIGZvcmNlIHJlY29tcHV0YXRpb24gb2YgdmlldyBib3hcbiAgZGVsZXRlIHRoaXMuX2NhY2hlZFZpZXdib3g7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGRlZmF1bHQgbGF5ZXIgb24gd2hpY2hcbiAqIGFsbCBlbGVtZW50cyBhcmUgZHJhd24uXG4gKlxuICogQHJldHVybnMge1NWR0VsZW1lbnR9XG4gKi9cbkNhbnZhcy5wcm90b3R5cGUuZ2V0RGVmYXVsdExheWVyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmdldExheWVyKEJBU0VfTEFZRVIsIDApO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgbGF5ZXIgdGhhdCBpcyB1c2VkIHRvIGRyYXcgZWxlbWVudHNcbiAqIG9yIGFubm90YXRpb25zIG9uIGl0LlxuICpcbiAqIE5vbi1leGlzdGluZyBsYXllcnMgcmV0cmlldmVkIHRocm91Z2ggdGhpcyBtZXRob2RcbiAqIHdpbGwgYmUgY3JlYXRlZC4gRHVyaW5nIGNyZWF0aW9uLCB0aGUgb3B0aW9uYWwgaW5kZXhcbiAqIG1heSBiZSB1c2VkIHRvIGNyZWF0ZSBsYXllcnMgYmVsb3cgb3IgYWJvdmUgZXhpc3RpbmcgbGF5ZXJzLlxuICogQSBsYXllciB3aXRoIGEgY2VydGFpbiBpbmRleCBpcyBhbHdheXMgY3JlYXRlZCBhYm92ZSBhbGxcbiAqIGV4aXN0aW5nIGxheWVycyB3aXRoIHRoZSBzYW1lIGluZGV4LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAqXG4gKiBAcmV0dXJucyB7U1ZHRWxlbWVudH1cbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5nZXRMYXllciA9IGZ1bmN0aW9uKG5hbWUsIGluZGV4KSB7XG5cbiAgaWYgKCFuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtdXN0IHNwZWNpZnkgYSBuYW1lJyk7XG4gIH1cblxuICB2YXIgbGF5ZXIgPSB0aGlzLl9sYXllcnNbbmFtZV07XG5cbiAgaWYgKCFsYXllcikge1xuICAgIGxheWVyID0gdGhpcy5fbGF5ZXJzW25hbWVdID0gdGhpcy5fY3JlYXRlTGF5ZXIobmFtZSwgaW5kZXgpO1xuICB9XG5cbiAgLy8gdGhyb3cgYW4gZXJyb3IgaWYgbGF5ZXIgY3JlYXRpb24gLyByZXRyaXZhbCBpc1xuICAvLyByZXF1ZXN0ZWQgb24gZGlmZmVyZW50IGluZGV4XG4gIGlmICh0eXBlb2YgaW5kZXggIT09ICd1bmRlZmluZWQnICYmIGxheWVyLmluZGV4ICE9PSBpbmRleCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbGF5ZXIgPCcgKyBuYW1lICsgJz4gYWxyZWFkeSBjcmVhdGVkIGF0IGluZGV4IDwnICsgaW5kZXggKyAnPicpO1xuICB9XG5cbiAgcmV0dXJuIGxheWVyLmdyb3VwO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZ2l2ZW4gbGF5ZXIgYW5kIHJldHVybnMgaXQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBbaW5kZXg9MF1cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGxheWVyIGRlc2NyaXB0b3Igd2l0aCB7IGluZGV4LCBncm91cDogU1ZHR3JvdXAgfVxuICovXG5DYW52YXMucHJvdG90eXBlLl9jcmVhdGVMYXllciA9IGZ1bmN0aW9uKG5hbWUsIGluZGV4KSB7XG5cbiAgaWYgKCFpbmRleCkge1xuICAgIGluZGV4ID0gMDtcbiAgfVxuXG4gIHZhciBjaGlsZEluZGV4ID0gcmVkdWNlKHRoaXMuX2xheWVycywgZnVuY3Rpb24oY2hpbGRJbmRleCwgbGF5ZXIpIHtcbiAgICBpZiAoaW5kZXggPj0gbGF5ZXIuaW5kZXgpIHtcbiAgICAgIGNoaWxkSW5kZXgrKztcbiAgICB9XG5cbiAgICByZXR1cm4gY2hpbGRJbmRleDtcbiAgfSwgMCk7XG5cbiAgcmV0dXJuIHtcbiAgICBncm91cDogY3JlYXRlR3JvdXAodGhpcy5fdmlld3BvcnQsICdsYXllci0nICsgbmFtZSwgY2hpbGRJbmRleCksXG4gICAgaW5kZXg6IGluZGV4XG4gIH07XG5cbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgaHRtbCBlbGVtZW50IHRoYXQgZW5jbG9zZXMgdGhlXG4gKiBkcmF3aW5nIGNhbnZhcy5cbiAqXG4gKiBAcmV0dXJuIHtET01Ob2RlfVxuICovXG5DYW52YXMucHJvdG90eXBlLmdldENvbnRhaW5lciA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fY29udGFpbmVyO1xufTtcblxuXG4vLyBtYXJrZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQ2FudmFzLnByb3RvdHlwZS5fdXBkYXRlTWFya2VyID0gZnVuY3Rpb24oZWxlbWVudCwgbWFya2VyLCBhZGQpIHtcbiAgdmFyIGNvbnRhaW5lcjtcblxuICBpZiAoIWVsZW1lbnQuaWQpIHtcbiAgICBlbGVtZW50ID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldChlbGVtZW50KTtcbiAgfVxuXG4gIC8vIHdlIG5lZWQgdG8gYWNjZXNzIGFsbFxuICBjb250YWluZXIgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuX2VsZW1lbnRzW2VsZW1lbnQuaWRdO1xuXG4gIGlmICghY29udGFpbmVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZm9yRWFjaChbIGNvbnRhaW5lci5nZngsIGNvbnRhaW5lci5zZWNvbmRhcnlHZnggXSwgZnVuY3Rpb24oZ2Z4KSB7XG4gICAgaWYgKGdmeCkge1xuXG4gICAgICAvLyBpbnZva2UgZWl0aGVyIGFkZENsYXNzIG9yIHJlbW92ZUNsYXNzIGJhc2VkIG9uIG1vZGVcbiAgICAgIGlmIChhZGQpIHtcbiAgICAgICAgc3ZnQ2xhc3NlcyhnZngpLmFkZChtYXJrZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3ZnQ2xhc3NlcyhnZngpLnJlbW92ZShtYXJrZXIpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhIG1hcmtlciBoYXMgYmVlbiB1cGRhdGVkIGZvciBhbiBlbGVtZW50XG4gICAqXG4gICAqIEBldmVudCBlbGVtZW50Lm1hcmtlci51cGRhdGVcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQHByb3BlcnR5IHtkanMubW9kZWwuRWxlbWVudH0gZWxlbWVudCB0aGUgc2hhcGVcbiAgICogQHByb3BlcnR5IHtPYmplY3R9IGdmeCB0aGUgZ3JhcGhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzaGFwZVxuICAgKiBAcHJvcGVydHkge3N0cmluZ30gbWFya2VyXG4gICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gYWRkIHRydWUgaWYgdGhlIG1hcmtlciB3YXMgYWRkZWQsIGZhbHNlIGlmIGl0IGdvdCByZW1vdmVkXG4gICAqL1xuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdlbGVtZW50Lm1hcmtlci51cGRhdGUnLCB7IGVsZW1lbnQ6IGVsZW1lbnQsIGdmeDogY29udGFpbmVyLmdmeCwgbWFya2VyOiBtYXJrZXIsIGFkZDogISFhZGQgfSk7XG59O1xuXG5cbi8qKlxuICogQWRkcyBhIG1hcmtlciB0byBhbiBlbGVtZW50IChiYXNpY2FsbHkgYSBjc3MgY2xhc3MpLlxuICpcbiAqIEZpcmVzIHRoZSBlbGVtZW50Lm1hcmtlci51cGRhdGUgZXZlbnQsIG1ha2luZyBpdCBwb3NzaWJsZSB0b1xuICogaW50ZWdyYXRlIGV4dGVuc2lvbiBpbnRvIHRoZSBtYXJrZXIgbGlmZS1jeWNsZSwgdG9vLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjYW52YXMuYWRkTWFya2VyKCdmb28nLCAnc29tZS1tYXJrZXInKTtcbiAqXG4gKiB2YXIgZm9vR2Z4ID0gY2FudmFzLmdldEdyYXBoaWNzKCdmb28nKTtcbiAqXG4gKiBmb29HZng7IC8vIDxnIGNsYXNzPVwiLi4uIHNvbWUtbWFya2VyXCI+IC4uLiA8L2c+XG4gKlxuICogQHBhcmFtIHtzdHJpbmd8ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtYXJrZXJcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5hZGRNYXJrZXIgPSBmdW5jdGlvbihlbGVtZW50LCBtYXJrZXIpIHtcbiAgdGhpcy5fdXBkYXRlTWFya2VyKGVsZW1lbnQsIG1hcmtlciwgdHJ1ZSk7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlIGEgbWFya2VyIGZyb20gYW4gZWxlbWVudC5cbiAqXG4gKiBGaXJlcyB0aGUgZWxlbWVudC5tYXJrZXIudXBkYXRlIGV2ZW50LCBtYWtpbmcgaXQgcG9zc2libGUgdG9cbiAqIGludGVncmF0ZSBleHRlbnNpb24gaW50byB0aGUgbWFya2VyIGxpZmUtY3ljbGUsIHRvby5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd8ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSAge3N0cmluZ30gbWFya2VyXG4gKi9cbkNhbnZhcy5wcm90b3R5cGUucmVtb3ZlTWFya2VyID0gZnVuY3Rpb24oZWxlbWVudCwgbWFya2VyKSB7XG4gIHRoaXMuX3VwZGF0ZU1hcmtlcihlbGVtZW50LCBtYXJrZXIsIGZhbHNlKTtcbn07XG5cbi8qKlxuICogQ2hlY2sgdGhlIGV4aXN0ZW5jZSBvZiBhIG1hcmtlciBvbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ3xkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtICB7c3RyaW5nfSBtYXJrZXJcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5oYXNNYXJrZXIgPSBmdW5jdGlvbihlbGVtZW50LCBtYXJrZXIpIHtcbiAgaWYgKCFlbGVtZW50LmlkKSB7XG4gICAgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXQoZWxlbWVudCk7XG4gIH1cblxuICB2YXIgZ2Z4ID0gdGhpcy5nZXRHcmFwaGljcyhlbGVtZW50KTtcblxuICByZXR1cm4gc3ZnQ2xhc3NlcyhnZngpLmhhcyhtYXJrZXIpO1xufTtcblxuLyoqXG4gKiBUb2dnbGVzIGEgbWFya2VyIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogRmlyZXMgdGhlIGVsZW1lbnQubWFya2VyLnVwZGF0ZSBldmVudCwgbWFraW5nIGl0IHBvc3NpYmxlIHRvXG4gKiBpbnRlZ3JhdGUgZXh0ZW5zaW9uIGludG8gdGhlIG1hcmtlciBsaWZlLWN5Y2xlLCB0b28uXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfGRqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0gIHtzdHJpbmd9IG1hcmtlclxuICovXG5DYW52YXMucHJvdG90eXBlLnRvZ2dsZU1hcmtlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIG1hcmtlcikge1xuICBpZiAodGhpcy5oYXNNYXJrZXIoZWxlbWVudCwgbWFya2VyKSkge1xuICAgIHRoaXMucmVtb3ZlTWFya2VyKGVsZW1lbnQsIG1hcmtlcik7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5hZGRNYXJrZXIoZWxlbWVudCwgbWFya2VyKTtcbiAgfVxufTtcblxuQ2FudmFzLnByb3RvdHlwZS5nZXRSb290RWxlbWVudCA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgdGhpcy5zZXRSb290RWxlbWVudCh7IGlkOiAnX19pbXBsaWNpdHJvb3QnLCBjaGlsZHJlbjogW10gfSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG59O1xuXG5cblxuLy8gcm9vdCBlbGVtZW50IGhhbmRsaW5nIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBTZXRzIGEgZ2l2ZW4gZWxlbWVudCBhcyB0aGUgbmV3IHJvb3QgZWxlbWVudCBmb3IgdGhlIGNhbnZhc1xuICogYW5kIHJldHVybnMgdGhlIG5ldyByb290IGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8ZGpzLm1vZGVsLlJvb3R9IGVsZW1lbnRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW292ZXJyaWRlXSB3aGV0aGVyIHRvIG92ZXJyaWRlIHRoZSBjdXJyZW50IHJvb3QgZWxlbWVudCwgaWYgYW55XG4gKlxuICogQHJldHVybiB7T2JqZWN0fGRqcy5tb2RlbC5Sb290fSBuZXcgcm9vdCBlbGVtZW50XG4gKi9cbkNhbnZhcy5wcm90b3R5cGUuc2V0Um9vdEVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50LCBvdmVycmlkZSkge1xuXG4gIGlmIChlbGVtZW50KSB7XG4gICAgdGhpcy5fZW5zdXJlVmFsaWQoJ3Jvb3QnLCBlbGVtZW50KTtcbiAgfVxuXG4gIHZhciBjdXJyZW50Um9vdCA9IHRoaXMuX3Jvb3RFbGVtZW50LFxuICAgICAgZWxlbWVudFJlZ2lzdHJ5ID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LFxuICAgICAgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICBpZiAoY3VycmVudFJvb3QpIHtcbiAgICBpZiAoIW92ZXJyaWRlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Jvb3RFbGVtZW50IGFscmVhZHkgc2V0LCBuZWVkIHRvIHNwZWNpZnkgb3ZlcnJpZGUnKTtcbiAgICB9XG5cbiAgICAvLyBzaW11bGF0ZSBlbGVtZW50IHJlbW92ZSBldmVudCBzZXF1ZW5jZVxuICAgIGV2ZW50QnVzLmZpcmUoJ3Jvb3QucmVtb3ZlJywgeyBlbGVtZW50OiBjdXJyZW50Um9vdCB9KTtcbiAgICBldmVudEJ1cy5maXJlKCdyb290LnJlbW92ZWQnLCB7IGVsZW1lbnQ6IGN1cnJlbnRSb290IH0pO1xuXG4gICAgZWxlbWVudFJlZ2lzdHJ5LnJlbW92ZShjdXJyZW50Um9vdCk7XG4gIH1cblxuICBpZiAoZWxlbWVudCkge1xuICAgIHZhciBnZnggPSB0aGlzLmdldERlZmF1bHRMYXllcigpO1xuXG4gICAgLy8gcmVzZW1ibGUgZWxlbWVudCBhZGQgZXZlbnQgc2VxdWVuY2VcbiAgICBldmVudEJ1cy5maXJlKCdyb290LmFkZCcsIHsgZWxlbWVudDogZWxlbWVudCB9KTtcblxuICAgIGVsZW1lbnRSZWdpc3RyeS5hZGQoZWxlbWVudCwgZ2Z4LCB0aGlzLl9zdmcpO1xuXG4gICAgZXZlbnRCdXMuZmlyZSgncm9vdC5hZGRlZCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH1cblxuICB0aGlzLl9yb290RWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuXG5cblxuLy8gYWRkIGZ1bmN0aW9uYWxpdHkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5DYW52YXMucHJvdG90eXBlLl9lbnN1cmVWYWxpZCA9IGZ1bmN0aW9uKHR5cGUsIGVsZW1lbnQpIHtcbiAgaWYgKCFlbGVtZW50LmlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbGVtZW50IG11c3QgaGF2ZSBhbiBpZCcpO1xuICB9XG5cbiAgaWYgKHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXQoZWxlbWVudC5pZCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2VsZW1lbnQgd2l0aCBpZCAnICsgZWxlbWVudC5pZCArICcgYWxyZWFkeSBleGlzdHMnKTtcbiAgfVxuXG4gIHZhciByZXF1aXJlZEF0dHJzID0gUkVRVUlSRURfTU9ERUxfQVRUUlNbdHlwZV07XG5cbiAgdmFyIHZhbGlkID0gZXZlcnkocmVxdWlyZWRBdHRycywgZnVuY3Rpb24oYXR0cikge1xuICAgIHJldHVybiB0eXBlb2YgZWxlbWVudFthdHRyXSAhPT0gJ3VuZGVmaW5lZCc7XG4gIH0pO1xuXG4gIGlmICghdmFsaWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnbXVzdCBzdXBwbHkgeyAnICsgcmVxdWlyZWRBdHRycy5qb2luKCcsICcpICsgJyB9IHdpdGggJyArIHR5cGUpO1xuICB9XG59O1xuXG5DYW52YXMucHJvdG90eXBlLl9zZXRQYXJlbnQgPSBmdW5jdGlvbihlbGVtZW50LCBwYXJlbnQsIHBhcmVudEluZGV4KSB7XG4gIGNvbGxlY3Rpb25BZGQocGFyZW50LmNoaWxkcmVuLCBlbGVtZW50LCBwYXJlbnRJbmRleCk7XG4gIGVsZW1lbnQucGFyZW50ID0gcGFyZW50O1xufTtcblxuLyoqXG4gKiBBZGRzIGFuIGVsZW1lbnQgdG8gdGhlIGNhbnZhcy5cbiAqXG4gKiBUaGlzIHdpcmVzIHRoZSBwYXJlbnQgPC0+IGNoaWxkIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBlbGVtZW50IGFuZFxuICogYSBleHBsaWNpdGx5IHNwZWNpZmllZCBwYXJlbnQgb3IgYW4gaW1wbGljaXQgcm9vdCBlbGVtZW50LlxuICpcbiAqIER1cmluZyBhZGQgaXQgZW1pdHMgdGhlIGV2ZW50c1xuICpcbiAqICAqIDx7dHlwZX0uYWRkPiAoZWxlbWVudCwgcGFyZW50KVxuICogICogPHt0eXBlfS5hZGRlZD4gKGVsZW1lbnQsIGdmeClcbiAqXG4gKiBFeHRlbnNpb25zIG1heSBob29rIGludG8gdGhlc2UgZXZlbnRzIHRvIHBlcmZvcm0gdGhlaXIgbWFnaWMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7T2JqZWN0fGRqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdHxkanMubW9kZWwuQmFzZX0gW3BhcmVudF1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbcGFyZW50SW5kZXhdXG4gKlxuICogQHJldHVybiB7T2JqZWN0fGRqcy5tb2RlbC5CYXNlfSB0aGUgYWRkZWQgZWxlbWVudFxuICovXG5DYW52YXMucHJvdG90eXBlLl9hZGRFbGVtZW50ID0gZnVuY3Rpb24odHlwZSwgZWxlbWVudCwgcGFyZW50LCBwYXJlbnRJbmRleCkge1xuXG4gIHBhcmVudCA9IHBhcmVudCB8fCB0aGlzLmdldFJvb3RFbGVtZW50KCk7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXMsXG4gICAgICBncmFwaGljc0ZhY3RvcnkgPSB0aGlzLl9ncmFwaGljc0ZhY3Rvcnk7XG5cbiAgdGhpcy5fZW5zdXJlVmFsaWQodHlwZSwgZWxlbWVudCk7XG5cbiAgZXZlbnRCdXMuZmlyZSh0eXBlICsgJy5hZGQnLCB7IGVsZW1lbnQ6IGVsZW1lbnQsIHBhcmVudDogcGFyZW50IH0pO1xuXG4gIHRoaXMuX3NldFBhcmVudChlbGVtZW50LCBwYXJlbnQsIHBhcmVudEluZGV4KTtcblxuICAvLyBjcmVhdGUgZ3JhcGhpY3NcbiAgdmFyIGdmeCA9IGdyYXBoaWNzRmFjdG9yeS5jcmVhdGUodHlwZSwgZWxlbWVudCwgcGFyZW50SW5kZXgpO1xuXG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5hZGQoZWxlbWVudCwgZ2Z4KTtcblxuICAvLyB1cGRhdGUgaXRzIHZpc3VhbFxuICBncmFwaGljc0ZhY3RvcnkudXBkYXRlKHR5cGUsIGVsZW1lbnQsIGdmeCk7XG5cbiAgZXZlbnRCdXMuZmlyZSh0eXBlICsgJy5hZGRlZCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuXG4vKipcbiAqIEFkZHMgYSBzaGFwZSB0byB0aGUgY2FudmFzXG4gKlxuICogQHBhcmFtIHtPYmplY3R8ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZSB0byBhZGQgdG8gdGhlIGRpYWdyYW1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtwYXJlbnRdXG4gKiBAcGFyYW0ge251bWJlcn0gW3BhcmVudEluZGV4XVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5TaGFwZX0gdGhlIGFkZGVkIHNoYXBlXG4gKi9cbkNhbnZhcy5wcm90b3R5cGUuYWRkU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgcGFyZW50LCBwYXJlbnRJbmRleCkge1xuICByZXR1cm4gdGhpcy5fYWRkRWxlbWVudCgnc2hhcGUnLCBzaGFwZSwgcGFyZW50LCBwYXJlbnRJbmRleCk7XG59O1xuXG4vKipcbiAqIEFkZHMgYSBjb25uZWN0aW9uIHRvIHRoZSBjYW52YXNcbiAqXG4gKiBAcGFyYW0ge09iamVjdHxkanMubW9kZWwuQ29ubmVjdGlvbn0gY29ubmVjdGlvbiB0byBhZGQgdG8gdGhlIGRpYWdyYW1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtwYXJlbnRdXG4gKiBAcGFyYW0ge251bWJlcn0gW3BhcmVudEluZGV4XVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5Db25uZWN0aW9ufSB0aGUgYWRkZWQgY29ubmVjdGlvblxuICovXG5DYW52YXMucHJvdG90eXBlLmFkZENvbm5lY3Rpb24gPSBmdW5jdGlvbihjb25uZWN0aW9uLCBwYXJlbnQsIHBhcmVudEluZGV4KSB7XG4gIHJldHVybiB0aGlzLl9hZGRFbGVtZW50KCdjb25uZWN0aW9uJywgY29ubmVjdGlvbiwgcGFyZW50LCBwYXJlbnRJbmRleCk7XG59O1xuXG5cbi8qKlxuICogSW50ZXJuYWwgcmVtb3ZlIGVsZW1lbnRcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5fcmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHR5cGUpIHtcblxuICB2YXIgZWxlbWVudFJlZ2lzdHJ5ID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LFxuICAgICAgZ3JhcGhpY3NGYWN0b3J5ID0gdGhpcy5fZ3JhcGhpY3NGYWN0b3J5LFxuICAgICAgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICBlbGVtZW50ID0gZWxlbWVudFJlZ2lzdHJ5LmdldChlbGVtZW50LmlkIHx8IGVsZW1lbnQpO1xuXG4gIGlmICghZWxlbWVudCkge1xuXG4gICAgLy8gZWxlbWVudCB3YXMgcmVtb3ZlZCBhbHJlYWR5XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZXZlbnRCdXMuZmlyZSh0eXBlICsgJy5yZW1vdmUnLCB7IGVsZW1lbnQ6IGVsZW1lbnQgfSk7XG5cbiAgZ3JhcGhpY3NGYWN0b3J5LnJlbW92ZShlbGVtZW50KTtcblxuICAvLyB1bnNldCBwYXJlbnQgPC0+IGNoaWxkIHJlbGF0aW9uc2hpcFxuICBjb2xsZWN0aW9uUmVtb3ZlKGVsZW1lbnQucGFyZW50ICYmIGVsZW1lbnQucGFyZW50LmNoaWxkcmVuLCBlbGVtZW50KTtcbiAgZWxlbWVudC5wYXJlbnQgPSBudWxsO1xuXG4gIGV2ZW50QnVzLmZpcmUodHlwZSArICcucmVtb3ZlZCcsIHsgZWxlbWVudDogZWxlbWVudCB9KTtcblxuICBlbGVtZW50UmVnaXN0cnkucmVtb3ZlKGVsZW1lbnQpO1xuXG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuXG4vKipcbiAqIFJlbW92ZXMgYSBzaGFwZSBmcm9tIHRoZSBjYW52YXNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xkanMubW9kZWwuU2hhcGV9IHNoYXBlIG9yIHNoYXBlIGlkIHRvIGJlIHJlbW92ZWRcbiAqXG4gKiBAcmV0dXJuIHtkanMubW9kZWwuU2hhcGV9IHRoZSByZW1vdmVkIHNoYXBlXG4gKi9cbkNhbnZhcy5wcm90b3R5cGUucmVtb3ZlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSkge1xuXG4gIC8qKlxuICAgKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgYSBzaGFwZSBpcyBhYm91dCB0byBiZSByZW1vdmVkIGZyb20gdGhlIGNhbnZhcy5cbiAgICpcbiAgICogQG1lbWJlck9mIENhbnZhc1xuICAgKlxuICAgKiBAZXZlbnQgc2hhcGUucmVtb3ZlXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLlNoYXBlfSBlbGVtZW50IHRoZSBzaGFwZSBkZXNjcmlwdG9yXG4gICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBnZnggdGhlIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgc2hhcGVcbiAgICovXG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhIHNoYXBlIGhhcyBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgY2FudmFzLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgQ2FudmFzXG4gICAqXG4gICAqIEBldmVudCBzaGFwZS5yZW1vdmVkXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLlNoYXBlfSBlbGVtZW50IHRoZSBzaGFwZSBkZXNjcmlwdG9yXG4gICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBnZnggdGhlIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgc2hhcGVcbiAgICovXG4gIHJldHVybiB0aGlzLl9yZW1vdmVFbGVtZW50KHNoYXBlLCAnc2hhcGUnKTtcbn07XG5cblxuLyoqXG4gKiBSZW1vdmVzIGEgY29ubmVjdGlvbiBmcm9tIHRoZSBjYW52YXNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xkanMubW9kZWwuQ29ubmVjdGlvbn0gY29ubmVjdGlvbiBvciBjb25uZWN0aW9uIGlkIHRvIGJlIHJlbW92ZWRcbiAqXG4gKiBAcmV0dXJuIHtkanMubW9kZWwuQ29ubmVjdGlvbn0gdGhlIHJlbW92ZWQgY29ubmVjdGlvblxuICovXG5DYW52YXMucHJvdG90eXBlLnJlbW92ZUNvbm5lY3Rpb24gPSBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhIGNvbm5lY3Rpb24gaXMgYWJvdXQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoZSBjYW52YXMuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBDYW52YXNcbiAgICpcbiAgICogQGV2ZW50IGNvbm5lY3Rpb24ucmVtb3ZlXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkNvbm5lY3Rpb259IGVsZW1lbnQgdGhlIGNvbm5lY3Rpb24gZGVzY3JpcHRvclxuICAgKiBAcHJvcGVydHkge09iamVjdH0gZ2Z4IHRoZSBncmFwaGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbm5lY3Rpb25cbiAgICovXG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhIGNvbm5lY3Rpb24gaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBjYW52YXMuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBDYW52YXNcbiAgICpcbiAgICogQGV2ZW50IGNvbm5lY3Rpb24ucmVtb3ZlZFxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5Db25uZWN0aW9ufSBlbGVtZW50IHRoZSBjb25uZWN0aW9uIGRlc2NyaXB0b3JcbiAgICogQHByb3BlcnR5IHtPYmplY3R9IGdmeCB0aGUgZ3JhcGhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb25uZWN0aW9uXG4gICAqL1xuICByZXR1cm4gdGhpcy5fcmVtb3ZlRWxlbWVudChjb25uZWN0aW9uLCAnY29ubmVjdGlvbicpO1xufTtcblxuXG4vKipcbiAqIFJldHVybiB0aGUgZ3JhcGhpY2FsIG9iamVjdCB1bmRlcmxheWluZyBhIGNlcnRhaW4gZGlhZ3JhbSBlbGVtZW50XG4gKlxuICogQHBhcmFtIHtzdHJpbmd8ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnQgZGVzY3JpcHRvciBvZiB0aGUgZWxlbWVudFxuICogQHBhcmFtIHtib29sZWFufSBbc2Vjb25kYXJ5PWZhbHNlXSB3aGV0aGVyIHRvIHJldHVybiB0aGUgc2Vjb25kYXJ5IGNvbm5lY3RlZCBlbGVtZW50XG4gKlxuICogQHJldHVybiB7U1ZHRWxlbWVudH1cbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5nZXRHcmFwaGljcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHNlY29uZGFyeSkge1xuICByZXR1cm4gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGVsZW1lbnQsIHNlY29uZGFyeSk7XG59O1xuXG5cbi8qKlxuICogUGVyZm9ybSBhIHZpZXdib3ggdXBkYXRlIHZpYSBhIGdpdmVuIGNoYW5nZSBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjaGFuZ2VGblxuICovXG5DYW52YXMucHJvdG90eXBlLl9jaGFuZ2VWaWV3Ym94ID0gZnVuY3Rpb24oY2hhbmdlRm4pIHtcblxuICAvLyBub3RpZnkgb3RoZXJzIG9mIHRoZSB1cGNvbWluZyB2aWV3Ym94IGNoYW5nZVxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjYW52YXMudmlld2JveC5jaGFuZ2luZycpO1xuXG4gIC8vIHBlcmZvcm0gYWN0dWFsIGNoYW5nZVxuICBjaGFuZ2VGbi5hcHBseSh0aGlzKTtcblxuICAvLyByZXNldCB0aGUgY2FjaGVkIHZpZXdib3ggc28gdGhhdFxuICAvLyBhIG5ldyBnZXQgb3BlcmF0aW9uIG9uIHZpZXdib3ggb3Igem9vbVxuICAvLyB0cmlnZ2VycyBhIHZpZXdib3ggcmUtY29tcHV0YXRpb25cbiAgdGhpcy5fY2FjaGVkVmlld2JveCA9IG51bGw7XG5cbiAgLy8gbm90aWZ5IG90aGVycyBvZiB0aGUgY2hhbmdlOyB0aGlzIHN0ZXBcbiAgLy8gbWF5IG9yIG1heSBub3QgYmUgZGVib3VuY2VkXG4gIHRoaXMuX3ZpZXdib3hDaGFuZ2VkKCk7XG59O1xuXG5DYW52YXMucHJvdG90eXBlLl92aWV3Ym94Q2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjYW52YXMudmlld2JveC5jaGFuZ2VkJywgeyB2aWV3Ym94OiB0aGlzLnZpZXdib3goKSB9KTtcbn07XG5cblxuLyoqXG4gKiBHZXRzIG9yIHNldHMgdGhlIHZpZXcgYm94IG9mIHRoZSBjYW52YXMsIGkuZS4gdGhlXG4gKiBhcmVhIHRoYXQgaXMgY3VycmVudGx5IGRpc3BsYXllZC5cbiAqXG4gKiBUaGUgZ2V0dGVyIG1heSByZXR1cm4gYSBjYWNoZWQgdmlld2JveCAoaWYgaXQgaXMgY3VycmVudGx5XG4gKiBjaGFuZ2luZykuIFRvIGZvcmNlIGEgcmVjb21wdXRhdGlvbiwgcGFzcyBgZmFsc2VgIGFzIHRoZSBmaXJzdCBhcmd1bWVudC5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIGNhbnZhcy52aWV3Ym94KHsgeDogMTAwLCB5OiAxMDAsIHdpZHRoOiA1MDAsIGhlaWdodDogNTAwIH0pXG4gKlxuICogLy8gc2V0cyB0aGUgdmlzaWJsZSBhcmVhIG9mIHRoZSBkaWFncmFtIHRvICgxMDB8MTAwKSAtPiAoNjAwfDEwMClcbiAqIC8vIGFuZCBhbmQgc2NhbGVzIGl0IGFjY29yZGluZyB0byB0aGUgZGlhZ3JhbSB3aWR0aFxuICpcbiAqIHZhciB2aWV3Ym94ID0gY2FudmFzLnZpZXdib3goKTsgLy8gcGFzcyBgZmFsc2VgIHRvIGZvcmNlIHJlY29tcHV0aW5nIHRoZSBib3guXG4gKlxuICogY29uc29sZS5sb2codmlld2JveCk7XG4gKiAvLyB7XG4gKiAvLyAgIGlubmVyOiBEaW1lbnNpb25zLFxuICogLy8gICBvdXRlcjogRGltZW5zaW9ucyxcbiAqIC8vICAgc2NhbGUsXG4gKiAvLyAgIHgsIHksXG4gKiAvLyAgIHdpZHRoLCBoZWlnaHRcbiAqIC8vIH1cbiAqXG4gKiAvLyBpZiB0aGUgY3VycmVudCBkaWFncmFtIGlzIHpvb21lZCBhbmQgc2Nyb2xsZWQsIHlvdSBtYXkgcmVzZXQgaXQgdG8gdGhlXG4gKiAvLyBkZWZhdWx0IHpvb20gdmlhIHRoaXMgbWV0aG9kLCB0b286XG4gKlxuICogdmFyIHpvb21lZEFuZFNjcm9sbGVkVmlld2JveCA9IGNhbnZhcy52aWV3Ym94KCk7XG4gKlxuICogY2FudmFzLnZpZXdib3goe1xuICogICB4OiAwLFxuICogICB5OiAwLFxuICogICB3aWR0aDogem9vbWVkQW5kU2Nyb2xsZWRWaWV3Ym94Lm91dGVyLndpZHRoLFxuICogICBoZWlnaHQ6IHpvb21lZEFuZFNjcm9sbGVkVmlld2JveC5vdXRlci5oZWlnaHRcbiAqIH0pO1xuICpcbiAqIEBwYXJhbSAge09iamVjdH0gW2JveF0gdGhlIG5ldyB2aWV3IGJveCB0byBzZXRcbiAqIEBwYXJhbSAge251bWJlcn0gYm94LnggdGhlIHRvcCBsZWZ0IFggY29vcmRpbmF0ZSBvZiB0aGUgY2FudmFzIHZpc2libGUgaW4gdmlldyBib3hcbiAqIEBwYXJhbSAge251bWJlcn0gYm94LnkgdGhlIHRvcCBsZWZ0IFkgY29vcmRpbmF0ZSBvZiB0aGUgY2FudmFzIHZpc2libGUgaW4gdmlldyBib3hcbiAqIEBwYXJhbSAge251bWJlcn0gYm94LndpZHRoIHRoZSB2aXNpYmxlIHdpZHRoXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGJveC5oZWlnaHRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSBjdXJyZW50IHZpZXcgYm94XG4gKi9cbkNhbnZhcy5wcm90b3R5cGUudmlld2JveCA9IGZ1bmN0aW9uKGJveCkge1xuXG4gIGlmIChib3ggPT09IHVuZGVmaW5lZCAmJiB0aGlzLl9jYWNoZWRWaWV3Ym94KSB7XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlZFZpZXdib3g7XG4gIH1cblxuICB2YXIgdmlld3BvcnQgPSB0aGlzLl92aWV3cG9ydCxcbiAgICAgIGlubmVyQm94LFxuICAgICAgb3V0ZXJCb3ggPSB0aGlzLmdldFNpemUoKSxcbiAgICAgIG1hdHJpeCxcbiAgICAgIHRyYW5zZm9ybSxcbiAgICAgIHNjYWxlLFxuICAgICAgeCwgeTtcblxuICBpZiAoIWJveCkge1xuXG4gICAgLy8gY29tcHV0ZSB0aGUgaW5uZXIgYm94IGJhc2VkIG9uIHRoZVxuICAgIC8vIGRpYWdyYW1zIGRlZmF1bHQgbGF5ZXIuIFRoaXMgYWxsb3dzIHVzIHRvIGV4Y2x1ZGVcbiAgICAvLyBleHRlcm5hbCBjb21wb25lbnRzLCBzdWNoIGFzIG92ZXJsYXlzXG4gICAgaW5uZXJCb3ggPSB0aGlzLmdldERlZmF1bHRMYXllcigpLmdldEJCb3goKTtcblxuICAgIHRyYW5zZm9ybSA9IHN2Z1RyYW5zZm9ybSh2aWV3cG9ydCk7XG4gICAgbWF0cml4ID0gdHJhbnNmb3JtID8gdHJhbnNmb3JtLm1hdHJpeCA6IGNyZWF0ZU1hdHJpeCgpO1xuICAgIHNjYWxlID0gcm91bmQobWF0cml4LmEsIDEwMDApO1xuXG4gICAgeCA9IHJvdW5kKC1tYXRyaXguZSB8fCAwLCAxMDAwKTtcbiAgICB5ID0gcm91bmQoLW1hdHJpeC5mIHx8IDAsIDEwMDApO1xuXG4gICAgYm94ID0gdGhpcy5fY2FjaGVkVmlld2JveCA9IHtcbiAgICAgIHg6IHggPyB4IC8gc2NhbGUgOiAwLFxuICAgICAgeTogeSA/IHkgLyBzY2FsZSA6IDAsXG4gICAgICB3aWR0aDogb3V0ZXJCb3gud2lkdGggLyBzY2FsZSxcbiAgICAgIGhlaWdodDogb3V0ZXJCb3guaGVpZ2h0IC8gc2NhbGUsXG4gICAgICBzY2FsZTogc2NhbGUsXG4gICAgICBpbm5lcjoge1xuICAgICAgICB3aWR0aDogaW5uZXJCb3gud2lkdGgsXG4gICAgICAgIGhlaWdodDogaW5uZXJCb3guaGVpZ2h0LFxuICAgICAgICB4OiBpbm5lckJveC54LFxuICAgICAgICB5OiBpbm5lckJveC55XG4gICAgICB9LFxuICAgICAgb3V0ZXI6IG91dGVyQm94XG4gICAgfTtcblxuICAgIHJldHVybiBib3g7XG4gIH0gZWxzZSB7XG5cbiAgICB0aGlzLl9jaGFuZ2VWaWV3Ym94KGZ1bmN0aW9uKCkge1xuICAgICAgc2NhbGUgPSBNYXRoLm1pbihvdXRlckJveC53aWR0aCAvIGJveC53aWR0aCwgb3V0ZXJCb3guaGVpZ2h0IC8gYm94LmhlaWdodCk7XG5cbiAgICAgIHZhciBtYXRyaXggPSB0aGlzLl9zdmcuY3JlYXRlU1ZHTWF0cml4KClcbiAgICAgICAgLnNjYWxlKHNjYWxlKVxuICAgICAgICAudHJhbnNsYXRlKC1ib3gueCwgLWJveC55KTtcblxuICAgICAgc3ZnVHJhbnNmb3JtKHZpZXdwb3J0LCBtYXRyaXgpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGJveDtcbn07XG5cblxuLyoqXG4gKiBHZXRzIG9yIHNldHMgdGhlIHNjcm9sbCBvZiB0aGUgY2FudmFzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbZGVsdGFdIHRoZSBuZXcgc2Nyb2xsIHRvIGFwcGx5LlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbZGVsdGEuZHhdXG4gKiBAcGFyYW0ge251bWJlcn0gW2RlbHRhLmR5XVxuICovXG5DYW52YXMucHJvdG90eXBlLnNjcm9sbCA9IGZ1bmN0aW9uKGRlbHRhKSB7XG5cbiAgdmFyIG5vZGUgPSB0aGlzLl92aWV3cG9ydDtcbiAgdmFyIG1hdHJpeCA9IG5vZGUuZ2V0Q1RNKCk7XG5cbiAgaWYgKGRlbHRhKSB7XG4gICAgdGhpcy5fY2hhbmdlVmlld2JveChmdW5jdGlvbigpIHtcbiAgICAgIGRlbHRhID0gYXNzaWduKHsgZHg6IDAsIGR5OiAwIH0sIGRlbHRhIHx8IHt9KTtcblxuICAgICAgbWF0cml4ID0gdGhpcy5fc3ZnLmNyZWF0ZVNWR01hdHJpeCgpLnRyYW5zbGF0ZShkZWx0YS5keCwgZGVsdGEuZHkpLm11bHRpcGx5KG1hdHJpeCk7XG5cbiAgICAgIHNldENUTShub2RlLCBtYXRyaXgpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHsgeDogbWF0cml4LmUsIHk6IG1hdHJpeC5mIH07XG59O1xuXG5cbi8qKlxuICogR2V0cyBvciBzZXRzIHRoZSBjdXJyZW50IHpvb20gb2YgdGhlIGNhbnZhcywgb3B0aW9uYWxseSB6b29taW5nXG4gKiB0byB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLlxuICpcbiAqIFRoZSBnZXR0ZXIgbWF5IHJldHVybiBhIGNhY2hlZCB6b29tIGxldmVsLiBDYWxsIGl0IHdpdGggYGZhbHNlYCBhc1xuICogdGhlIGZpcnN0IGFyZ3VtZW50IHRvIGZvcmNlIHJlY29tcHV0YXRpb24gb2YgdGhlIGN1cnJlbnQgbGV2ZWwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBbbmV3U2NhbGVdIHRoZSBuZXcgem9vbSBsZXZlbCwgZWl0aGVyIGEgbnVtYmVyLCBpLmUuIDAuOSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBgZml0LXZpZXdwb3J0YCB0byBhZGp1c3QgdGhlIHNpemUgdG8gZml0IHRoZSBjdXJyZW50IHZpZXdwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ3xQb2ludH0gW2NlbnRlcl0gdGhlIHJlZmVyZW5jZSBwb2ludCB7IHg6IC4uLCB5OiAuLn0gdG8gem9vbSB0bywgJ2F1dG8nIHRvIHpvb20gaW50byBtaWQgb3IgbnVsbFxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gdGhlIGN1cnJlbnQgc2NhbGVcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS56b29tID0gZnVuY3Rpb24obmV3U2NhbGUsIGNlbnRlcikge1xuXG4gIGlmICghbmV3U2NhbGUpIHtcbiAgICByZXR1cm4gdGhpcy52aWV3Ym94KG5ld1NjYWxlKS5zY2FsZTtcbiAgfVxuXG4gIGlmIChuZXdTY2FsZSA9PT0gJ2ZpdC12aWV3cG9ydCcpIHtcbiAgICByZXR1cm4gdGhpcy5fZml0Vmlld3BvcnQoY2VudGVyKTtcbiAgfVxuXG4gIHZhciBvdXRlcixcbiAgICAgIG1hdHJpeDtcblxuICB0aGlzLl9jaGFuZ2VWaWV3Ym94KGZ1bmN0aW9uKCkge1xuXG4gICAgaWYgKHR5cGVvZiBjZW50ZXIgIT09ICdvYmplY3QnKSB7XG4gICAgICBvdXRlciA9IHRoaXMudmlld2JveCgpLm91dGVyO1xuXG4gICAgICBjZW50ZXIgPSB7XG4gICAgICAgIHg6IG91dGVyLndpZHRoIC8gMixcbiAgICAgICAgeTogb3V0ZXIuaGVpZ2h0IC8gMlxuICAgICAgfTtcbiAgICB9XG5cbiAgICBtYXRyaXggPSB0aGlzLl9zZXRab29tKG5ld1NjYWxlLCBjZW50ZXIpO1xuICB9KTtcblxuICByZXR1cm4gcm91bmQobWF0cml4LmEsIDEwMDApO1xufTtcblxuZnVuY3Rpb24gc2V0Q1RNKG5vZGUsIG0pIHtcbiAgdmFyIG1zdHIgPSAnbWF0cml4KCcgKyBtLmEgKyAnLCcgKyBtLmIgKyAnLCcgKyBtLmMgKyAnLCcgKyBtLmQgKyAnLCcgKyBtLmUgKyAnLCcgKyBtLmYgKyAnKSc7XG4gIG5vZGUuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLCBtc3RyKTtcbn1cblxuQ2FudmFzLnByb3RvdHlwZS5fZml0Vmlld3BvcnQgPSBmdW5jdGlvbihjZW50ZXIpIHtcblxuICB2YXIgdmJveCA9IHRoaXMudmlld2JveCgpLFxuICAgICAgb3V0ZXIgPSB2Ym94Lm91dGVyLFxuICAgICAgaW5uZXIgPSB2Ym94LmlubmVyLFxuICAgICAgbmV3U2NhbGUsXG4gICAgICBuZXdWaWV3Ym94O1xuXG4gIC8vIGRpc3BsYXkgdGhlIGNvbXBsZXRlIGRpYWdyYW0gd2l0aG91dCB6b29taW5nIGluLlxuICAvLyBpbnN0ZWFkIG9mIHJlbHlpbmcgb24gaW50ZXJuYWwgem9vbSwgd2UgcGVyZm9ybSBhXG4gIC8vIGhhcmQgcmVzZXQgb24gdGhlIGNhbnZhcyB2aWV3Ym94IHRvIHJlYWxpemUgdGhpc1xuICAvL1xuICAvLyBpZiBkaWFncmFtIGRvZXMgbm90IG5lZWQgdG8gYmUgem9vbWVkIGluLCB3ZSBmb2N1cyBpdCBhcm91bmRcbiAgLy8gdGhlIGRpYWdyYW0gb3JpZ2luIGluc3RlYWRcblxuICBpZiAoaW5uZXIueCA+PSAwICYmXG4gICAgICBpbm5lci55ID49IDAgJiZcbiAgICAgIGlubmVyLnggKyBpbm5lci53aWR0aCA8PSBvdXRlci53aWR0aCAmJlxuICAgICAgaW5uZXIueSArIGlubmVyLmhlaWdodCA8PSBvdXRlci5oZWlnaHQgJiZcbiAgICAgICFjZW50ZXIpIHtcblxuICAgIG5ld1ZpZXdib3ggPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMCxcbiAgICAgIHdpZHRoOiBNYXRoLm1heChpbm5lci53aWR0aCArIGlubmVyLngsIG91dGVyLndpZHRoKSxcbiAgICAgIGhlaWdodDogTWF0aC5tYXgoaW5uZXIuaGVpZ2h0ICsgaW5uZXIueSwgb3V0ZXIuaGVpZ2h0KVxuICAgIH07XG4gIH0gZWxzZSB7XG5cbiAgICBuZXdTY2FsZSA9IE1hdGgubWluKDEsIG91dGVyLndpZHRoIC8gaW5uZXIud2lkdGgsIG91dGVyLmhlaWdodCAvIGlubmVyLmhlaWdodCk7XG4gICAgbmV3Vmlld2JveCA9IHtcbiAgICAgIHg6IGlubmVyLnggKyAoY2VudGVyID8gaW5uZXIud2lkdGggLyAyIC0gb3V0ZXIud2lkdGggLyBuZXdTY2FsZSAvIDIgOiAwKSxcbiAgICAgIHk6IGlubmVyLnkgKyAoY2VudGVyID8gaW5uZXIuaGVpZ2h0IC8gMiAtIG91dGVyLmhlaWdodCAvIG5ld1NjYWxlIC8gMiA6IDApLFxuICAgICAgd2lkdGg6IG91dGVyLndpZHRoIC8gbmV3U2NhbGUsXG4gICAgICBoZWlnaHQ6IG91dGVyLmhlaWdodCAvIG5ld1NjYWxlXG4gICAgfTtcbiAgfVxuXG4gIHRoaXMudmlld2JveChuZXdWaWV3Ym94KTtcblxuICByZXR1cm4gdGhpcy52aWV3Ym94KGZhbHNlKS5zY2FsZTtcbn07XG5cblxuQ2FudmFzLnByb3RvdHlwZS5fc2V0Wm9vbSA9IGZ1bmN0aW9uKHNjYWxlLCBjZW50ZXIpIHtcblxuICB2YXIgc3ZnID0gdGhpcy5fc3ZnLFxuICAgICAgdmlld3BvcnQgPSB0aGlzLl92aWV3cG9ydDtcblxuICB2YXIgbWF0cml4ID0gc3ZnLmNyZWF0ZVNWR01hdHJpeCgpO1xuICB2YXIgcG9pbnQgPSBzdmcuY3JlYXRlU1ZHUG9pbnQoKTtcblxuICB2YXIgY2VudGVyUG9pbnQsXG4gICAgICBvcmlnaW5hbFBvaW50LFxuICAgICAgY3VycmVudE1hdHJpeCxcbiAgICAgIHNjYWxlTWF0cml4LFxuICAgICAgbmV3TWF0cml4O1xuXG4gIGN1cnJlbnRNYXRyaXggPSB2aWV3cG9ydC5nZXRDVE0oKTtcblxuICB2YXIgY3VycmVudFNjYWxlID0gY3VycmVudE1hdHJpeC5hO1xuXG4gIGlmIChjZW50ZXIpIHtcbiAgICBjZW50ZXJQb2ludCA9IGFzc2lnbihwb2ludCwgY2VudGVyKTtcblxuICAgIC8vIHJldmVydCBhcHBsaWVkIHZpZXdwb3J0IHRyYW5zZm9ybWF0aW9uc1xuICAgIG9yaWdpbmFsUG9pbnQgPSBjZW50ZXJQb2ludC5tYXRyaXhUcmFuc2Zvcm0oY3VycmVudE1hdHJpeC5pbnZlcnNlKCkpO1xuXG4gICAgLy8gY3JlYXRlIHNjYWxlIG1hdHJpeFxuICAgIHNjYWxlTWF0cml4ID0gbWF0cml4XG4gICAgICAudHJhbnNsYXRlKG9yaWdpbmFsUG9pbnQueCwgb3JpZ2luYWxQb2ludC55KVxuICAgICAgLnNjYWxlKDEgLyBjdXJyZW50U2NhbGUgKiBzY2FsZSlcbiAgICAgIC50cmFuc2xhdGUoLW9yaWdpbmFsUG9pbnQueCwgLW9yaWdpbmFsUG9pbnQueSk7XG5cbiAgICBuZXdNYXRyaXggPSBjdXJyZW50TWF0cml4Lm11bHRpcGx5KHNjYWxlTWF0cml4KTtcbiAgfSBlbHNlIHtcbiAgICBuZXdNYXRyaXggPSBtYXRyaXguc2NhbGUoc2NhbGUpO1xuICB9XG5cbiAgc2V0Q1RNKHRoaXMuX3ZpZXdwb3J0LCBuZXdNYXRyaXgpO1xuXG4gIHJldHVybiBuZXdNYXRyaXg7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgY2FudmFzXG4gKlxuICogQHJldHVybiB7RGltZW5zaW9uc31cbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5nZXRTaXplID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHRoaXMuX2NvbnRhaW5lci5jbGllbnRXaWR0aCxcbiAgICBoZWlnaHQ6IHRoaXMuX2NvbnRhaW5lci5jbGllbnRIZWlnaHRcbiAgfTtcbn07XG5cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGFic29sdXRlIGJvdW5kaW5nIGJveCBmb3IgdGhlIGdpdmVuIGVsZW1lbnRcbiAqXG4gKiBUaGUgYWJzb2x1dGUgYm91bmRpbmcgYm94IG1heSBiZSB1c2VkIHRvIGRpc3BsYXkgb3ZlcmxheXMgaW4gdGhlXG4gKiBjYWxsZXJzIChicm93c2VyKSBjb29yZGluYXRlIHN5c3RlbSByYXRoZXIgdGhhbiB0aGUgem9vbWVkIGluL291dFxuICogY2FudmFzIGNvb3JkaW5hdGVzLlxuICpcbiAqIEBwYXJhbSAge0VsZW1lbnREZXNjcmlwdG9yfSBlbGVtZW50XG4gKiBAcmV0dXJuIHtCb3VuZHN9IHRoZSBhYnNvbHV0ZSBib3VuZGluZyBib3hcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5nZXRBYnNvbHV0ZUJCb3ggPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciB2Ym94ID0gdGhpcy52aWV3Ym94KCk7XG4gIHZhciBiYm94O1xuXG4gIC8vIGNvbm5lY3Rpb25cbiAgLy8gdXNlIHN2ZyBiYm94XG4gIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgIHZhciBnZnggPSB0aGlzLmdldEdyYXBoaWNzKGVsZW1lbnQpO1xuXG4gICAgYmJveCA9IGdmeC5nZXRCQm94KCk7XG4gIH1cblxuICAvLyBzaGFwZXNcbiAgLy8gdXNlIGRhdGFcbiAgZWxzZSB7XG4gICAgYmJveCA9IGVsZW1lbnQ7XG4gIH1cblxuICB2YXIgeCA9IGJib3gueCAqIHZib3guc2NhbGUgLSB2Ym94LnggKiB2Ym94LnNjYWxlO1xuICB2YXIgeSA9IGJib3gueSAqIHZib3guc2NhbGUgLSB2Ym94LnkgKiB2Ym94LnNjYWxlO1xuXG4gIHZhciB3aWR0aCA9IGJib3gud2lkdGggKiB2Ym94LnNjYWxlO1xuICB2YXIgaGVpZ2h0ID0gYmJveC5oZWlnaHQgKiB2Ym94LnNjYWxlO1xuXG4gIHJldHVybiB7XG4gICAgeDogeCxcbiAgICB5OiB5LFxuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodFxuICB9O1xufTtcblxuLyoqXG4gKiBGaXJlcyBhbiBldmVudCBpbiBvcmRlciBvdGhlciBtb2R1bGVzIGNhbiByZWFjdCB0byB0aGVcbiAqIGNhbnZhcyByZXNpemluZ1xuICovXG5DYW52YXMucHJvdG90eXBlLnJlc2l6ZWQgPSBmdW5jdGlvbigpIHtcblxuICAvLyBmb3JjZSByZWNvbXB1dGF0aW9uIG9mIHZpZXcgYm94XG4gIGRlbGV0ZSB0aGlzLl9jYWNoZWRWaWV3Ym94O1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ2NhbnZhcy5yZXNpemVkJyk7XG59O1xuIiwiaW1wb3J0IHtcbiAgY3JlYXRlXG59IGZyb20gJy4uL21vZGVsJztcblxuaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnbWluLWRhc2gnO1xuXG4vKipcbiAqIEEgZmFjdG9yeSBmb3IgZGlhZ3JhbS1qcyBzaGFwZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRWxlbWVudEZhY3RvcnkoKSB7XG4gIHRoaXMuX3VpZCA9IDEyO1xufVxuXG5cbkVsZW1lbnRGYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVSb290ID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgcmV0dXJuIHRoaXMuY3JlYXRlKCdyb290JywgYXR0cnMpO1xufTtcblxuRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZUxhYmVsID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgcmV0dXJuIHRoaXMuY3JlYXRlKCdsYWJlbCcsIGF0dHJzKTtcbn07XG5cbkVsZW1lbnRGYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVTaGFwZSA9IGZ1bmN0aW9uKGF0dHJzKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnc2hhcGUnLCBhdHRycyk7XG59O1xuXG5FbGVtZW50RmFjdG9yeS5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKGF0dHJzKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnY29ubmVjdGlvbicsIGF0dHJzKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgbW9kZWwgZWxlbWVudCB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZFxuICogYSBudW1iZXIgb2YgcHJlLXNldCBhdHRyaWJ1dGVzLlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gdHlwZVxuICogQHBhcmFtICB7T2JqZWN0fSBhdHRyc1xuICogQHJldHVybiB7ZGpzLm1vZGVsLkJhc2V9IHRoZSBuZXdseSBjcmVhdGVkIG1vZGVsIGluc3RhbmNlXG4gKi9cbkVsZW1lbnRGYWN0b3J5LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbih0eXBlLCBhdHRycykge1xuXG4gIGF0dHJzID0gYXNzaWduKHt9LCBhdHRycyB8fCB7fSk7XG5cbiAgaWYgKCFhdHRycy5pZCkge1xuICAgIGF0dHJzLmlkID0gdHlwZSArICdfJyArICh0aGlzLl91aWQrKyk7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlKHR5cGUsIGF0dHJzKTtcbn07IiwidmFyIEVMRU1FTlRfSUQgPSAnZGF0YS1lbGVtZW50LWlkJztcblxuaW1wb3J0IHsgYXR0ciBhcyBzdmdBdHRyIH0gZnJvbSAndGlueS1zdmcnO1xuXG5cbi8qKlxuICogQGNsYXNzXG4gKlxuICogQSByZWdpc3RyeSB0aGF0IGtlZXBzIHRyYWNrIG9mIGFsbCBzaGFwZXMgaW4gdGhlIGRpYWdyYW0uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEVsZW1lbnRSZWdpc3RyeShldmVudEJ1cykge1xuICB0aGlzLl9lbGVtZW50cyA9IHt9O1xuXG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG59XG5cbkVsZW1lbnRSZWdpc3RyeS4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07XG5cbi8qKlxuICogUmVnaXN0ZXIgYSBwYWlyIG9mIChlbGVtZW50LCBnZngsIChzZWNvbmRhcnlHZngpKS5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGdmeFxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBbc2Vjb25kYXJ5R2Z4XSBvcHRpb25hbCBvdGhlciBlbGVtZW50IHRvIHJlZ2lzdGVyLCB0b29cbiAqL1xuRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihlbGVtZW50LCBnZngsIHNlY29uZGFyeUdmeCkge1xuXG4gIHZhciBpZCA9IGVsZW1lbnQuaWQ7XG5cbiAgdGhpcy5fdmFsaWRhdGVJZChpZCk7XG5cbiAgLy8gYXNzb2NpYXRlIGRvbSBub2RlIHdpdGggZWxlbWVudFxuICBzdmdBdHRyKGdmeCwgRUxFTUVOVF9JRCwgaWQpO1xuXG4gIGlmIChzZWNvbmRhcnlHZngpIHtcbiAgICBzdmdBdHRyKHNlY29uZGFyeUdmeCwgRUxFTUVOVF9JRCwgaWQpO1xuICB9XG5cbiAgdGhpcy5fZWxlbWVudHNbaWRdID0geyBlbGVtZW50OiBlbGVtZW50LCBnZng6IGdmeCwgc2Vjb25kYXJ5R2Z4OiBzZWNvbmRhcnlHZnggfTtcbn07XG5cbi8qKlxuICogUmVtb3ZlcyBhbiBlbGVtZW50IGZyb20gdGhlIHJlZ2lzdHJ5LlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqL1xuRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciBlbGVtZW50cyA9IHRoaXMuX2VsZW1lbnRzLFxuICAgICAgaWQgPSBlbGVtZW50LmlkIHx8IGVsZW1lbnQsXG4gICAgICBjb250YWluZXIgPSBpZCAmJiBlbGVtZW50c1tpZF07XG5cbiAgaWYgKGNvbnRhaW5lcikge1xuXG4gICAgLy8gdW5zZXQgZWxlbWVudCBpZCBvbiBnZnhcbiAgICBzdmdBdHRyKGNvbnRhaW5lci5nZngsIEVMRU1FTlRfSUQsICcnKTtcblxuICAgIGlmIChjb250YWluZXIuc2Vjb25kYXJ5R2Z4KSB7XG4gICAgICBzdmdBdHRyKGNvbnRhaW5lci5zZWNvbmRhcnlHZngsIEVMRU1FTlRfSUQsICcnKTtcbiAgICB9XG5cbiAgICBkZWxldGUgZWxlbWVudHNbaWRdO1xuICB9XG59O1xuXG4vKipcbiAqIFVwZGF0ZSB0aGUgaWQgb2YgYW4gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBuZXdJZFxuICovXG5FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLnVwZGF0ZUlkID0gZnVuY3Rpb24oZWxlbWVudCwgbmV3SWQpIHtcblxuICB0aGlzLl92YWxpZGF0ZUlkKG5ld0lkKTtcblxuICBpZiAodHlwZW9mIGVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgZWxlbWVudCA9IHRoaXMuZ2V0KGVsZW1lbnQpO1xuICB9XG5cbiAgdGhpcy5fZXZlbnRCdXMuZmlyZSgnZWxlbWVudC51cGRhdGVJZCcsIHtcbiAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgIG5ld0lkOiBuZXdJZFxuICB9KTtcblxuICB2YXIgZ2Z4ID0gdGhpcy5nZXRHcmFwaGljcyhlbGVtZW50KSxcbiAgICAgIHNlY29uZGFyeUdmeCA9IHRoaXMuZ2V0R3JhcGhpY3MoZWxlbWVudCwgdHJ1ZSk7XG5cbiAgdGhpcy5yZW1vdmUoZWxlbWVudCk7XG5cbiAgZWxlbWVudC5pZCA9IG5ld0lkO1xuXG4gIHRoaXMuYWRkKGVsZW1lbnQsIGdmeCwgc2Vjb25kYXJ5R2Z4KTtcbn07XG5cbi8qKlxuICogUmV0dXJuIHRoZSBtb2RlbCBlbGVtZW50IGZvciBhIGdpdmVuIGlkIG9yIGdyYXBoaWNzLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogZWxlbWVudFJlZ2lzdHJ5LmdldCgnU29tZUVsZW1lbnRJZF8xJyk7XG4gKiBlbGVtZW50UmVnaXN0cnkuZ2V0KGdmeCk7XG4gKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfFNWR0VsZW1lbnR9IGZpbHRlciBmb3Igc2VsZWN0aW5nIHRoZSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGVsLkJhc2V9XG4gKi9cbkVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oZmlsdGVyKSB7XG4gIHZhciBpZDtcblxuICBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ3N0cmluZycpIHtcbiAgICBpZCA9IGZpbHRlcjtcbiAgfSBlbHNlIHtcbiAgICBpZCA9IGZpbHRlciAmJiBzdmdBdHRyKGZpbHRlciwgRUxFTUVOVF9JRCk7XG4gIH1cblxuICB2YXIgY29udGFpbmVyID0gdGhpcy5fZWxlbWVudHNbaWRdO1xuICByZXR1cm4gY29udGFpbmVyICYmIGNvbnRhaW5lci5lbGVtZW50O1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYWxsIGVsZW1lbnRzIHRoYXQgbWF0Y2ggYSBnaXZlbiBmaWx0ZXIgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuQmFzZT59XG4gKi9cbkVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGUuZmlsdGVyID0gZnVuY3Rpb24oZm4pIHtcblxuICB2YXIgZmlsdGVyZWQgPSBbXTtcblxuICB0aGlzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG4gICAgaWYgKGZuKGVsZW1lbnQsIGdmeCkpIHtcbiAgICAgIGZpbHRlcmVkLnB1c2goZWxlbWVudCk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gZmlsdGVyZWQ7XG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IHNhdGlzZmllcyB0aGUgcHJvdmlkZWQgdGVzdGluZyBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5CYXNlfVxuICovXG5FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLmZpbmQgPSBmdW5jdGlvbihmbikge1xuICB2YXIgbWFwID0gdGhpcy5fZWxlbWVudHMsXG4gICAgICBrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaWQgPSBrZXlzW2ldLFxuICAgICAgICBjb250YWluZXIgPSBtYXBbaWRdLFxuICAgICAgICBlbGVtZW50ID0gY29udGFpbmVyLmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGNvbnRhaW5lci5nZng7XG5cbiAgICBpZiAoZm4oZWxlbWVudCwgZ2Z4KSkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFJldHVybiBhbGwgcmVuZGVyZWQgbW9kZWwgZWxlbWVudHMuXG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fVxuICovXG5FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLmdldEFsbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5maWx0ZXIoZnVuY3Rpb24oZSkgeyByZXR1cm4gZTsgfSk7XG59O1xuXG4vKipcbiAqIEl0ZXJhdGUgb3ZlciBhbGwgZGlhZ3JhbSBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICovXG5FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbihmbikge1xuXG4gIHZhciBtYXAgPSB0aGlzLl9lbGVtZW50cztcblxuICBPYmplY3Qua2V5cyhtYXApLmZvckVhY2goZnVuY3Rpb24oaWQpIHtcbiAgICB2YXIgY29udGFpbmVyID0gbWFwW2lkXSxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRhaW5lci5lbGVtZW50LFxuICAgICAgICBnZnggPSBjb250YWluZXIuZ2Z4O1xuXG4gICAgcmV0dXJuIGZuKGVsZW1lbnQsIGdmeCk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gdGhlIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBvZiBhbiBlbGVtZW50IG9yIGl0cyBpZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKCdTb21lRWxlbWVudElkXzEnKTtcbiAqIGVsZW1lbnRSZWdpc3RyeS5nZXRHcmFwaGljcyhyb290RWxlbWVudCk7IC8vIDxnIC4uLj5cbiAqXG4gKiBlbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3Mocm9vdEVsZW1lbnQsIHRydWUpOyAvLyA8c3ZnIC4uLj5cbiAqXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8ZGpzLm1vZGVsLkJhc2V9IGZpbHRlclxuICogQHBhcmFtIHtib29sZWFufSBbc2Vjb25kYXJ5PWZhbHNlXSB3aGV0aGVyIHRvIHJldHVybiB0aGUgc2Vjb25kYXJ5IGNvbm5lY3RlZCBlbGVtZW50XG4gKlxuICogQHJldHVybiB7U1ZHRWxlbWVudH1cbiAqL1xuRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5nZXRHcmFwaGljcyA9IGZ1bmN0aW9uKGZpbHRlciwgc2Vjb25kYXJ5KSB7XG4gIHZhciBpZCA9IGZpbHRlci5pZCB8fCBmaWx0ZXI7XG5cbiAgdmFyIGNvbnRhaW5lciA9IHRoaXMuX2VsZW1lbnRzW2lkXTtcbiAgcmV0dXJuIGNvbnRhaW5lciAmJiAoc2Vjb25kYXJ5ID8gY29udGFpbmVyLnNlY29uZGFyeUdmeCA6IGNvbnRhaW5lci5nZngpO1xufTtcblxuLyoqXG4gKiBWYWxpZGF0ZSB0aGUgc3VpdGFiaWxpdHkgb2YgdGhlIGdpdmVuIGlkIGFuZCBzaWduYWxzIGEgcHJvYmxlbVxuICogd2l0aCBhbiBleGNlcHRpb24uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlkXG4gKlxuICogQHRocm93cyB7RXJyb3J9IGlmIGlkIGlzIGVtcHR5IG9yIGFscmVhZHkgYXNzaWduZWRcbiAqL1xuRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5fdmFsaWRhdGVJZCA9IGZ1bmN0aW9uKGlkKSB7XG4gIGlmICghaWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2VsZW1lbnQgbXVzdCBoYXZlIGFuIGlkJyk7XG4gIH1cblxuICBpZiAodGhpcy5fZWxlbWVudHNbaWRdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbGVtZW50IHdpdGggaWQgJyArIGlkICsgJyBhbHJlYWR5IGFkZGVkJyk7XG4gIH1cbn07XG4iLCJpbXBvcnQge1xuICBpc0Z1bmN0aW9uLFxuICBpc0FycmF5LFxuICBpc051bWJlcixcbiAgYmluZCxcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIEZOX1JFRiA9ICdfX2ZuJztcblxudmFyIERFRkFVTFRfUFJJT1JJVFkgPSAxMDAwO1xuXG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbi8qKlxuICogQSBnZW5lcmFsIHB1cnBvc2UgZXZlbnQgYnVzLlxuICpcbiAqIFRoaXMgY29tcG9uZW50IGlzIHVzZWQgdG8gY29tbXVuaWNhdGUgYWNyb3NzIGEgZGlhZ3JhbSBpbnN0YW5jZS5cbiAqIE90aGVyIHBhcnRzIG9mIGEgZGlhZ3JhbSBjYW4gdXNlIGl0IHRvIGxpc3RlbiB0byBhbmQgYnJvYWRjYXN0IGV2ZW50cy5cbiAqXG4gKlxuICogIyMgUmVnaXN0ZXJpbmcgZm9yIEV2ZW50c1xuICpcbiAqIFRoZSBldmVudCBidXMgcHJvdmlkZXMgdGhlIHtAbGluayBFdmVudEJ1cyNvbn0gYW5kIHtAbGluayBFdmVudEJ1cyNvbmNlfVxuICogbWV0aG9kcyB0byByZWdpc3RlciBmb3IgZXZlbnRzLiB7QGxpbmsgRXZlbnRCdXMjb2ZmfSBjYW4gYmUgdXNlZCB0b1xuICogcmVtb3ZlIGV2ZW50IHJlZ2lzdHJhdGlvbnMuIExpc3RlbmVycyByZWNlaXZlIGFuIGluc3RhbmNlIG9mIHtAbGluayBFdmVudH1cbiAqIGFzIHRoZSBmaXJzdCBhcmd1bWVudC4gSXQgYWxsb3dzIHRoZW0gdG8gaG9vayBpbnRvIHRoZSBldmVudCBleGVjdXRpb24uXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICpcbiAqIC8vIGxpc3RlbiBmb3IgZXZlbnRcbiAqIGV2ZW50QnVzLm9uKCdmb28nLCBmdW5jdGlvbihldmVudCkge1xuICpcbiAqICAgLy8gYWNjZXNzIGV2ZW50IHR5cGVcbiAqICAgZXZlbnQudHlwZTsgLy8gJ2ZvbydcbiAqXG4gKiAgIC8vIHN0b3AgcHJvcGFnYXRpb24gdG8gb3RoZXIgbGlzdGVuZXJzXG4gKiAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICpcbiAqICAgLy8gcHJldmVudCBldmVudCBkZWZhdWx0XG4gKiAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gKiB9KTtcbiAqXG4gKiAvLyBsaXN0ZW4gZm9yIGV2ZW50IHdpdGggY3VzdG9tIHBheWxvYWRcbiAqIGV2ZW50QnVzLm9uKCdiYXInLCBmdW5jdGlvbihldmVudCwgcGF5bG9hZCkge1xuICogICBjb25zb2xlLmxvZyhwYXlsb2FkKTtcbiAqIH0pO1xuICpcbiAqIC8vIGxpc3RlbiBmb3IgZXZlbnQgcmV0dXJuaW5nIHZhbHVlXG4gKiBldmVudEJ1cy5vbignZm9vYmFyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqXG4gKiAgIC8vIHN0b3AgZXZlbnQgcHJvcGFnYXRpb24gKyBwcmV2ZW50IGRlZmF1bHRcbiAqICAgcmV0dXJuIGZhbHNlO1xuICpcbiAqICAgLy8gc3RvcCBldmVudCBwcm9wYWdhdGlvbiArIHJldHVybiBjdXN0b20gcmVzdWx0XG4gKiAgIHJldHVybiB7XG4gKiAgICAgY29tcGxleDogJ2xpc3RlbmluZyByZXN1bHQnXG4gKiAgIH07XG4gKiB9KTtcbiAqXG4gKlxuICogLy8gbGlzdGVuIHdpdGggY3VzdG9tIHByaW9yaXR5IChkZWZhdWx0PTEwMDAsIGhpZ2hlciBpcyBiZXR0ZXIpXG4gKiBldmVudEJ1cy5vbigncHJpb3JpdHlmb28nLCAxNTAwLCBmdW5jdGlvbihldmVudCkge1xuICogICBjb25zb2xlLmxvZygnaW52b2tlZCBmaXJzdCEnKTtcbiAqIH0pO1xuICpcbiAqXG4gKiAvLyBsaXN0ZW4gZm9yIGV2ZW50IGFuZCBwYXNzIHRoZSBjb250ZXh0IChgdGhpc2ApXG4gKiBldmVudEJ1cy5vbignZm9vYmFyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgdGhpcy5mb28oKTtcbiAqIH0sIHRoaXMpO1xuICogYGBgXG4gKlxuICpcbiAqICMjIEVtaXR0aW5nIEV2ZW50c1xuICpcbiAqIEV2ZW50cyBjYW4gYmUgZW1pdHRlZCB2aWEgdGhlIGV2ZW50IGJ1cyB1c2luZyB7QGxpbmsgRXZlbnRCdXMjZmlyZX0uXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICpcbiAqIC8vIGZhbHNlIGluZGljYXRlcyB0aGF0IHRoZSBkZWZhdWx0IGFjdGlvblxuICogLy8gd2FzIHByZXZlbnRlZCBieSBsaXN0ZW5lcnNcbiAqIGlmIChldmVudEJ1cy5maXJlKCdmb28nKSA9PT0gZmFsc2UpIHtcbiAqICAgY29uc29sZS5sb2coJ2RlZmF1bHQgaGFzIGJlZW4gcHJldmVudGVkIScpO1xuICogfTtcbiAqXG4gKlxuICogLy8gY3VzdG9tIGFyZ3MgKyByZXR1cm4gdmFsdWUgbGlzdGVuZXJcbiAqIGV2ZW50QnVzLm9uKCdzdW0nLCBmdW5jdGlvbihldmVudCwgYSwgYikge1xuICogICByZXR1cm4gYSArIGI7XG4gKiB9KTtcbiAqXG4gKiAvLyB5b3UgY2FuIHBhc3MgY3VzdG9tIGFyZ3VtZW50cyArIHJldHJpZXZlIHJlc3VsdCB2YWx1ZXMuXG4gKiB2YXIgc3VtID0gZXZlbnRCdXMuZmlyZSgnc3VtJywgMSwgMik7XG4gKiBjb25zb2xlLmxvZyhzdW0pOyAvLyAzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRXZlbnRCdXMoKSB7XG4gIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xuXG4gIC8vIGNsZWFudXAgb24gZGVzdHJveSBvbiBsb3dlc3QgcHJpb3JpdHkgdG8gYWxsb3dcbiAgLy8gbWVzc2FnZSBwYXNzaW5nIHVudGlsIHRoZSBiaXR0ZXIgZW5kXG4gIHRoaXMub24oJ2RpYWdyYW0uZGVzdHJveScsIDEsIHRoaXMuX2Rlc3Ryb3ksIHRoaXMpO1xufVxuXG5cbi8qKlxuICogUmVnaXN0ZXIgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIGV2ZW50cyB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICpcbiAqIFRoZSBjYWxsYmFjayB3aWxsIGJlIGludm9rZWQgd2l0aCBgZXZlbnQsIC4uLmFkZGl0aW9uYWxBcmd1bWVudHNgXG4gKiB0aGF0IGhhdmUgYmVlbiBwYXNzZWQgdG8ge0BsaW5rIEV2ZW50QnVzI2ZpcmV9LlxuICpcbiAqIFJldHVybmluZyBmYWxzZSBmcm9tIGEgbGlzdGVuZXIgd2lsbCBwcmV2ZW50IHRoZSBldmVudHMgZGVmYXVsdCBhY3Rpb25cbiAqIChpZiBhbnkgaXMgc3BlY2lmaWVkKS4gVG8gc3RvcCBhbiBldmVudCBmcm9tIGJlaW5nIHByb2Nlc3NlZCBmdXJ0aGVyIGluXG4gKiBvdGhlciBsaXN0ZW5lcnMgZXhlY3V0ZSB7QGxpbmsgRXZlbnQjc3RvcFByb3BhZ2F0aW9ufS5cbiAqXG4gKiBSZXR1cm5pbmcgYW55dGhpbmcgYnV0IGB1bmRlZmluZWRgIGZyb20gYSBsaXN0ZW5lciB3aWxsIHN0b3AgdGhlIGxpc3RlbmVyIHByb3BhZ2F0aW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfEFycmF5PHN0cmluZz59IGV2ZW50c1xuICogQHBhcmFtIHtudW1iZXJ9IFtwcmlvcml0eT0xMDAwXSB0aGUgcHJpb3JpdHkgaW4gd2hpY2ggdGhpcyBsaXN0ZW5lciBpcyBjYWxsZWQsIGxhcmdlciBpcyBoaWdoZXJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcGFyYW0ge09iamVjdH0gW3RoYXRdIFBhc3MgY29udGV4dCAoYHRoaXNgKSB0byB0aGUgY2FsbGJhY2tcbiAqL1xuRXZlbnRCdXMucHJvdG90eXBlLm9uID0gZnVuY3Rpb24oZXZlbnRzLCBwcmlvcml0eSwgY2FsbGJhY2ssIHRoYXQpIHtcblxuICBldmVudHMgPSBpc0FycmF5KGV2ZW50cykgPyBldmVudHMgOiBbIGV2ZW50cyBdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKHByaW9yaXR5KSkge1xuICAgIHRoYXQgPSBjYWxsYmFjaztcbiAgICBjYWxsYmFjayA9IHByaW9yaXR5O1xuICAgIHByaW9yaXR5ID0gREVGQVVMVF9QUklPUklUWTtcbiAgfVxuXG4gIGlmICghaXNOdW1iZXIocHJpb3JpdHkpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcmlvcml0eSBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIH1cblxuICB2YXIgYWN0dWFsQ2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICBpZiAodGhhdCkge1xuICAgIGFjdHVhbENhbGxiYWNrID0gYmluZChjYWxsYmFjaywgdGhhdCk7XG5cbiAgICAvLyBtYWtlIHN1cmUgd2UgcmVtZW1iZXIgYW5kIGFyZSBhYmxlIHRvIHJlbW92ZVxuICAgIC8vIGJvdW5kIGNhbGxiYWNrcyB2aWEge0BsaW5rICNvZmZ9IHVzaW5nIHRoZSBvcmlnaW5hbFxuICAgIC8vIGNhbGxiYWNrXG4gICAgYWN0dWFsQ2FsbGJhY2tbRk5fUkVGXSA9IGNhbGxiYWNrW0ZOX1JFRl0gfHwgY2FsbGJhY2s7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24oZSkge1xuICAgIHNlbGYuX2FkZExpc3RlbmVyKGUsIHtcbiAgICAgIHByaW9yaXR5OiBwcmlvcml0eSxcbiAgICAgIGNhbGxiYWNrOiBhY3R1YWxDYWxsYmFjayxcbiAgICAgIG5leHQ6IG51bGxcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmVnaXN0ZXIgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBpcyBleGVjdXRlZCBvbmx5IG9uY2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IHRoZSBldmVudCBuYW1lIHRvIHJlZ2lzdGVyIGZvclxuICogQHBhcmFtIHtudW1iZXJ9IFtwcmlvcml0eT0xMDAwXSB0aGUgcHJpb3JpdHkgaW4gd2hpY2ggdGhpcyBsaXN0ZW5lciBpcyBjYWxsZWQsIGxhcmdlciBpcyBoaWdoZXJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRoZSBjYWxsYmFjayB0byBleGVjdXRlXG4gKiBAcGFyYW0ge09iamVjdH0gW3RoYXRdIFBhc3MgY29udGV4dCAoYHRoaXNgKSB0byB0aGUgY2FsbGJhY2tcbiAqL1xuRXZlbnRCdXMucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgcHJpb3JpdHksIGNhbGxiYWNrLCB0aGF0KSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAoaXNGdW5jdGlvbihwcmlvcml0eSkpIHtcbiAgICB0aGF0ID0gY2FsbGJhY2s7XG4gICAgY2FsbGJhY2sgPSBwcmlvcml0eTtcbiAgICBwcmlvcml0eSA9IERFRkFVTFRfUFJJT1JJVFk7XG4gIH1cblxuICBpZiAoIWlzTnVtYmVyKHByaW9yaXR5KSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJpb3JpdHkgbXVzdCBiZSBhIG51bWJlcicpO1xuICB9XG5cbiAgZnVuY3Rpb24gd3JhcHBlZENhbGxiYWNrKCkge1xuICAgIHZhciByZXN1bHQgPSBjYWxsYmFjay5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuXG4gICAgc2VsZi5vZmYoZXZlbnQsIHdyYXBwZWRDYWxsYmFjayk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gbWFrZSBzdXJlIHdlIHJlbWVtYmVyIGFuZCBhcmUgYWJsZSB0byByZW1vdmVcbiAgLy8gYm91bmQgY2FsbGJhY2tzIHZpYSB7QGxpbmsgI29mZn0gdXNpbmcgdGhlIG9yaWdpbmFsXG4gIC8vIGNhbGxiYWNrXG4gIHdyYXBwZWRDYWxsYmFja1tGTl9SRUZdID0gY2FsbGJhY2s7XG5cbiAgdGhpcy5vbihldmVudCwgcHJpb3JpdHksIHdyYXBwZWRDYWxsYmFjayk7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlcyBldmVudCBsaXN0ZW5lcnMgYnkgZXZlbnQgYW5kIGNhbGxiYWNrLlxuICpcbiAqIElmIG5vIGNhbGxiYWNrIGlzIGdpdmVuLCBhbGwgbGlzdGVuZXJzIGZvciBhIGdpdmVuIGV2ZW50IG5hbWUgYXJlIGJlaW5nIHJlbW92ZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gZXZlbnRzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdXG4gKi9cbkV2ZW50QnVzLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbihldmVudHMsIGNhbGxiYWNrKSB7XG5cbiAgZXZlbnRzID0gaXNBcnJheShldmVudHMpID8gZXZlbnRzIDogWyBldmVudHMgXTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBzZWxmLl9yZW1vdmVMaXN0ZW5lcihldmVudCwgY2FsbGJhY2spO1xuICB9KTtcblxufTtcblxuXG4vKipcbiAqIENyZWF0ZSBhbiBFdmVudEJ1cyBldmVudC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gZXZlbnQsIHJlY29nbml6ZWQgYnkgdGhlIGV2ZW50QnVzXG4gKi9cbkV2ZW50QnVzLnByb3RvdHlwZS5jcmVhdGVFdmVudCA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgdmFyIGV2ZW50ID0gbmV3IEludGVybmFsRXZlbnQoKTtcblxuICBldmVudC5pbml0KGRhdGEpO1xuXG4gIHJldHVybiBldmVudDtcbn07XG5cblxuLyoqXG4gKiBGaXJlcyBhIG5hbWVkIGV2ZW50LlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gZmlyZSBldmVudCBieSBuYW1lXG4gKiBldmVudHMuZmlyZSgnZm9vJyk7XG4gKlxuICogLy8gZmlyZSBldmVudCBvYmplY3Qgd2l0aCBuZXN0ZWQgdHlwZVxuICogdmFyIGV2ZW50ID0geyB0eXBlOiAnZm9vJyB9O1xuICogZXZlbnRzLmZpcmUoZXZlbnQpO1xuICpcbiAqIC8vIGZpcmUgZXZlbnQgd2l0aCBleHBsaWNpdCB0eXBlXG4gKiB2YXIgZXZlbnQgPSB7IHg6IDEwLCB5OiAyMCB9O1xuICogZXZlbnRzLmZpcmUoJ2VsZW1lbnQubW92ZWQnLCBldmVudCk7XG4gKlxuICogLy8gcGFzcyBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byB0aGUgZXZlbnRcbiAqIGV2ZW50cy5vbignZm9vJywgZnVuY3Rpb24oZXZlbnQsIGJhcikge1xuICogICBhbGVydChiYXIpO1xuICogfSk7XG4gKlxuICogZXZlbnRzLmZpcmUoeyB0eXBlOiAnZm9vJyB9LCAnSSBhbSBiYXIhJyk7XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtuYW1lXSB0aGUgb3B0aW9uYWwgZXZlbnQgbmFtZVxuICogQHBhcmFtIHtPYmplY3R9IFtldmVudF0gdGhlIGV2ZW50IG9iamVjdFxuICogQHBhcmFtIHsuLi5PYmplY3R9IGFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byB0aGUgY2FsbGJhY2sgZnVuY3Rpb25zXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gdGhlIGV2ZW50cyByZXR1cm4gdmFsdWUsIGlmIHNwZWNpZmllZCBvciBmYWxzZSBpZiB0aGVcbiAqICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgYWN0aW9uIHdhcyBwcmV2ZW50ZWQgYnkgbGlzdGVuZXJzXG4gKi9cbkV2ZW50QnVzLnByb3RvdHlwZS5maXJlID0gZnVuY3Rpb24odHlwZSwgZGF0YSkge1xuICB2YXIgZXZlbnQsXG4gICAgICBmaXJzdExpc3RlbmVyLFxuICAgICAgcmV0dXJuVmFsdWUsXG4gICAgICBhcmdzO1xuXG4gIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0Jykge1xuICAgIGRhdGEgPSB0eXBlO1xuICAgIHR5cGUgPSBkYXRhLnR5cGU7XG4gIH1cblxuICBpZiAoIXR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGV2ZW50IHR5cGUgc3BlY2lmaWVkJyk7XG4gIH1cblxuICBmaXJzdExpc3RlbmVyID0gdGhpcy5fbGlzdGVuZXJzW3R5cGVdO1xuXG4gIGlmICghZmlyc3RMaXN0ZW5lcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIHdlIG1ha2Ugc3VyZSB3ZSBmaXJlIGluc3RhbmNlcyBvZiBvdXIgaG9tZSBtYWRlXG4gIC8vIGV2ZW50cyBoZXJlLiBXZSB3cmFwIHRoZW0gb25seSBvbmNlLCB0aG91Z2hcbiAgaWYgKGRhdGEgaW5zdGFuY2VvZiBJbnRlcm5hbEV2ZW50KSB7XG5cbiAgICAvLyB3ZSBhcmUgZmluZSwgd2UgYWxyZWFkIGhhdmUgYW4gZXZlbnRcbiAgICBldmVudCA9IGRhdGE7XG4gIH0gZWxzZSB7XG4gICAgZXZlbnQgPSB0aGlzLmNyZWF0ZUV2ZW50KGRhdGEpO1xuICB9XG5cbiAgLy8gZW5zdXJlIHdlIHBhc3MgdGhlIGV2ZW50IGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXJcbiAgYXJnc1swXSA9IGV2ZW50O1xuXG4gIC8vIG9yaWdpbmFsIGV2ZW50IHR5cGUgKGluIGNhc2Ugd2UgZGVsZWdhdGUpXG4gIHZhciBvcmlnaW5hbFR5cGUgPSBldmVudC50eXBlO1xuXG4gIC8vIHVwZGF0ZSBldmVudCB0eXBlIGJlZm9yZSBkZWxlZ2F0aW9uXG4gIGlmICh0eXBlICE9PSBvcmlnaW5hbFR5cGUpIHtcbiAgICBldmVudC50eXBlID0gdHlwZTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuVmFsdWUgPSB0aGlzLl9pbnZva2VMaXN0ZW5lcnMoZXZlbnQsIGFyZ3MsIGZpcnN0TGlzdGVuZXIpO1xuICB9IGZpbmFsbHkge1xuXG4gICAgLy8gcmVzZXQgZXZlbnQgdHlwZSBhZnRlciBkZWxlZ2F0aW9uXG4gICAgaWYgKHR5cGUgIT09IG9yaWdpbmFsVHlwZSkge1xuICAgICAgZXZlbnQudHlwZSA9IG9yaWdpbmFsVHlwZTtcbiAgICB9XG4gIH1cblxuICAvLyBzZXQgdGhlIHJldHVybiB2YWx1ZSB0byBmYWxzZSBpZiB0aGUgZXZlbnQgZGVmYXVsdFxuICAvLyBnb3QgcHJldmVudGVkIGFuZCBubyBvdGhlciByZXR1cm4gdmFsdWUgZXhpc3RzXG4gIGlmIChyZXR1cm5WYWx1ZSA9PT0gdW5kZWZpbmVkICYmIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICByZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHJldHVyblZhbHVlO1xufTtcblxuXG5FdmVudEJ1cy5wcm90b3R5cGUuaGFuZGxlRXJyb3IgPSBmdW5jdGlvbihlcnJvcikge1xuICByZXR1cm4gdGhpcy5maXJlKCdlcnJvcicsIHsgZXJyb3I6IGVycm9yIH0pID09PSBmYWxzZTtcbn07XG5cblxuRXZlbnRCdXMucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xufTtcblxuRXZlbnRCdXMucHJvdG90eXBlLl9pbnZva2VMaXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCwgYXJncywgbGlzdGVuZXIpIHtcblxuICB2YXIgcmV0dXJuVmFsdWU7XG5cbiAgd2hpbGUgKGxpc3RlbmVyKSB7XG5cbiAgICAvLyBoYW5kbGUgc3RvcHBlZCBwcm9wYWdhdGlvblxuICAgIGlmIChldmVudC5jYW5jZWxCdWJibGUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVyblZhbHVlID0gdGhpcy5faW52b2tlTGlzdGVuZXIoZXZlbnQsIGFyZ3MsIGxpc3RlbmVyKTtcblxuICAgIGxpc3RlbmVyID0gbGlzdGVuZXIubmV4dDtcbiAgfVxuXG4gIHJldHVybiByZXR1cm5WYWx1ZTtcbn07XG5cbkV2ZW50QnVzLnByb3RvdHlwZS5faW52b2tlTGlzdGVuZXIgPSBmdW5jdGlvbihldmVudCwgYXJncywgbGlzdGVuZXIpIHtcblxuICB2YXIgcmV0dXJuVmFsdWU7XG5cbiAgdHJ5IHtcblxuICAgIC8vIHJldHVybmluZyBmYWxzZSBwcmV2ZW50cyB0aGUgZGVmYXVsdCBhY3Rpb25cbiAgICByZXR1cm5WYWx1ZSA9IGludm9rZUZ1bmN0aW9uKGxpc3RlbmVyLmNhbGxiYWNrLCBhcmdzKTtcblxuICAgIC8vIHN0b3AgcHJvcGFnYXRpb24gb24gcmV0dXJuIHZhbHVlXG4gICAgaWYgKHJldHVyblZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGV2ZW50LnJldHVyblZhbHVlID0gcmV0dXJuVmFsdWU7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICAvLyBwcmV2ZW50IGRlZmF1bHQgb24gcmV0dXJuIGZhbHNlXG4gICAgaWYgKHJldHVyblZhbHVlID09PSBmYWxzZSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoIXRoaXMuaGFuZGxlRXJyb3IoZSkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ3VuaGFuZGxlZCBlcnJvciBpbiBldmVudCBsaXN0ZW5lcicpO1xuICAgICAgY29uc29sZS5lcnJvcihlLnN0YWNrKTtcblxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmV0dXJuVmFsdWU7XG59O1xuXG4vKlxuICogQWRkIG5ldyBsaXN0ZW5lciB3aXRoIGEgY2VydGFpbiBwcmlvcml0eSB0byB0aGUgbGlzdFxuICogb2YgbGlzdGVuZXJzIChmb3IgdGhlIGdpdmVuIGV2ZW50KS5cbiAqXG4gKiBUaGUgc2VtYW50aWNzIG9mIGxpc3RlbmVyIHJlZ2lzdHJhdGlvbiAvIGxpc3RlbmVyIGV4ZWN1dGlvbiBhcmVcbiAqIGZpcnN0IHJlZ2lzdGVyLCBmaXJzdCBzZXJ2ZTogTmV3IGxpc3RlbmVycyB3aWxsIGFsd2F5cyBiZSBpbnNlcnRlZFxuICogYWZ0ZXIgZXhpc3RpbmcgbGlzdGVuZXJzIHdpdGggdGhlIHNhbWUgcHJpb3JpdHkuXG4gKlxuICogRXhhbXBsZTogSW5zZXJ0aW5nIHR3byBsaXN0ZW5lcnMgd2l0aCBwcmlvcml0eSAxMDAwIGFuZCAxMzAwXG4gKlxuICogICAgKiBiZWZvcmU6IFsgMTUwMCwgMTUwMCwgMTAwMCwgMTAwMCBdXG4gKiAgICAqIGFmdGVyOiBbIDE1MDAsIDE1MDAsIChuZXc9MTMwMCksIDEwMDAsIDEwMDAsIChuZXc9MTAwMCkgXVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtPYmplY3R9IGxpc3RlbmVyIHsgcHJpb3JpdHksIGNhbGxiYWNrIH1cbiAqL1xuRXZlbnRCdXMucHJvdG90eXBlLl9hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBuZXdMaXN0ZW5lcikge1xuXG4gIHZhciBsaXN0ZW5lciA9IHRoaXMuX2dldExpc3RlbmVycyhldmVudCksXG4gICAgICBwcmV2aW91c0xpc3RlbmVyO1xuXG4gIC8vIG5vIHByaW9yIGxpc3RlbmVyc1xuICBpZiAoIWxpc3RlbmVyKSB7XG4gICAgdGhpcy5fc2V0TGlzdGVuZXJzKGV2ZW50LCBuZXdMaXN0ZW5lcik7XG5cbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBlbnN1cmUgd2Ugb3JkZXIgbGlzdGVuZXJzIGJ5IHByaW9yaXR5IGZyb21cbiAgLy8gMCAoaGlnaCkgdG8gbiA+IDAgKGxvdylcbiAgd2hpbGUgKGxpc3RlbmVyKSB7XG5cbiAgICBpZiAobGlzdGVuZXIucHJpb3JpdHkgPCBuZXdMaXN0ZW5lci5wcmlvcml0eSkge1xuXG4gICAgICBuZXdMaXN0ZW5lci5uZXh0ID0gbGlzdGVuZXI7XG5cbiAgICAgIGlmIChwcmV2aW91c0xpc3RlbmVyKSB7XG4gICAgICAgIHByZXZpb3VzTGlzdGVuZXIubmV4dCA9IG5ld0xpc3RlbmVyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fc2V0TGlzdGVuZXJzKGV2ZW50LCBuZXdMaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwcmV2aW91c0xpc3RlbmVyID0gbGlzdGVuZXI7XG4gICAgbGlzdGVuZXIgPSBsaXN0ZW5lci5uZXh0O1xuICB9XG5cbiAgLy8gYWRkIG5ldyBsaXN0ZW5lciB0byBiYWNrXG4gIHByZXZpb3VzTGlzdGVuZXIubmV4dCA9IG5ld0xpc3RlbmVyO1xufTtcblxuXG5FdmVudEJ1cy5wcm90b3R5cGUuX2dldExpc3RlbmVycyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuIHRoaXMuX2xpc3RlbmVyc1tuYW1lXTtcbn07XG5cbkV2ZW50QnVzLnByb3RvdHlwZS5fc2V0TGlzdGVuZXJzID0gZnVuY3Rpb24obmFtZSwgbGlzdGVuZXIpIHtcbiAgdGhpcy5fbGlzdGVuZXJzW25hbWVdID0gbGlzdGVuZXI7XG59O1xuXG5FdmVudEJ1cy5wcm90b3R5cGUuX3JlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGNhbGxiYWNrKSB7XG5cbiAgdmFyIGxpc3RlbmVyID0gdGhpcy5fZ2V0TGlzdGVuZXJzKGV2ZW50KSxcbiAgICAgIG5leHRMaXN0ZW5lcixcbiAgICAgIHByZXZpb3VzTGlzdGVuZXIsXG4gICAgICBsaXN0ZW5lckNhbGxiYWNrO1xuXG4gIGlmICghY2FsbGJhY2spIHtcblxuICAgIC8vIGNsZWFyIGxpc3RlbmVyc1xuICAgIHRoaXMuX3NldExpc3RlbmVycyhldmVudCwgbnVsbCk7XG5cbiAgICByZXR1cm47XG4gIH1cblxuICB3aGlsZSAobGlzdGVuZXIpIHtcblxuICAgIG5leHRMaXN0ZW5lciA9IGxpc3RlbmVyLm5leHQ7XG5cbiAgICBsaXN0ZW5lckNhbGxiYWNrID0gbGlzdGVuZXIuY2FsbGJhY2s7XG5cbiAgICBpZiAobGlzdGVuZXJDYWxsYmFjayA9PT0gY2FsbGJhY2sgfHwgbGlzdGVuZXJDYWxsYmFja1tGTl9SRUZdID09PSBjYWxsYmFjaykge1xuICAgICAgaWYgKHByZXZpb3VzTGlzdGVuZXIpIHtcbiAgICAgICAgcHJldmlvdXNMaXN0ZW5lci5uZXh0ID0gbmV4dExpc3RlbmVyO1xuICAgICAgfSBlbHNlIHtcblxuICAgICAgICAvLyBuZXcgZmlyc3QgbGlzdGVuZXJcbiAgICAgICAgdGhpcy5fc2V0TGlzdGVuZXJzKGV2ZW50LCBuZXh0TGlzdGVuZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByZXZpb3VzTGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgICBsaXN0ZW5lciA9IG5leHRMaXN0ZW5lcjtcbiAgfVxufTtcblxuLyoqXG4gKiBBIGV2ZW50IHRoYXQgaXMgZW1pdHRlZCB2aWEgdGhlIGV2ZW50IGJ1cy5cbiAqL1xuZnVuY3Rpb24gSW50ZXJuYWxFdmVudCgpIHsgfVxuXG5JbnRlcm5hbEV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24gPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5jYW5jZWxCdWJibGUgPSB0cnVlO1xufTtcblxuSW50ZXJuYWxFdmVudC5wcm90b3R5cGUucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5kZWZhdWx0UHJldmVudGVkID0gdHJ1ZTtcbn07XG5cbkludGVybmFsRXZlbnQucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbihkYXRhKSB7XG4gIGFzc2lnbih0aGlzLCBkYXRhIHx8IHt9KTtcbn07XG5cblxuLyoqXG4gKiBJbnZva2UgZnVuY3Rpb24uIEJlIGZhc3QuLi5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBhcmdzXG4gKlxuICogQHJldHVybiB7QW55fVxuICovXG5mdW5jdGlvbiBpbnZva2VGdW5jdGlvbihmbiwgYXJncykge1xuICByZXR1cm4gZm4uYXBwbHkobnVsbCwgYXJncyk7XG59XG4iLCJpbXBvcnQge1xuICBmb3JFYWNoLFxuICByZWR1Y2Vcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRDaGlsZHJlbixcbiAgZ2V0VmlzdWFsXG59IGZyb20gJy4uL3V0aWwvR3JhcGhpY3NVdGlsJztcblxuaW1wb3J0IHsgdHJhbnNsYXRlIH0gZnJvbSAnLi4vdXRpbC9TdmdUcmFuc2Zvcm1VdGlsJztcblxuaW1wb3J0IHsgY2xlYXIgYXMgZG9tQ2xlYXIgfSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjbGFzc2VzIGFzIHN2Z0NsYXNzZXMsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICBpc0ZyYW1lRWxlbWVudFxufSBmcm9tICcuLi91dGlsL0VsZW1lbnRzJztcblxuLyoqXG4gKiBBIGZhY3RvcnkgdGhhdCBjcmVhdGVzIGdyYXBoaWNhbCBlbGVtZW50c1xuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEdyYXBoaWNzRmFjdG9yeShldmVudEJ1cywgZWxlbWVudFJlZ2lzdHJ5KSB7XG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbn1cblxuR3JhcGhpY3NGYWN0b3J5LiRpbmplY3QgPSBbICdldmVudEJ1cycgLCAnZWxlbWVudFJlZ2lzdHJ5JyBdO1xuXG5cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUuX2dldENoaWxkcmVuQ29udGFpbmVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gIHZhciBnZnggPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZWxlbWVudCk7XG5cbiAgdmFyIGNoaWxkcmVuR2Z4O1xuXG4gIC8vIHJvb3QgZWxlbWVudFxuICBpZiAoIWVsZW1lbnQucGFyZW50KSB7XG4gICAgY2hpbGRyZW5HZnggPSBnZng7XG4gIH0gZWxzZSB7XG4gICAgY2hpbGRyZW5HZnggPSBnZXRDaGlsZHJlbihnZngpO1xuICAgIGlmICghY2hpbGRyZW5HZngpIHtcbiAgICAgIGNoaWxkcmVuR2Z4ID0gc3ZnQ3JlYXRlKCdnJyk7XG4gICAgICBzdmdDbGFzc2VzKGNoaWxkcmVuR2Z4KS5hZGQoJ2Rqcy1jaGlsZHJlbicpO1xuXG4gICAgICBzdmdBcHBlbmQoZ2Z4LnBhcmVudE5vZGUsIGNoaWxkcmVuR2Z4KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY2hpbGRyZW5HZng7XG59O1xuXG4vKipcbiAqIENsZWFycyB0aGUgZ3JhcGhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbGVtZW50IGFuZCByZXR1cm5zIHRoZVxuICogY2xlYXJlZCB2aXN1YWwgKHRoZSA8ZyBjbGFzcz1cImRqcy12aXN1YWxcIiAvPiBlbGVtZW50KS5cbiAqL1xuR3JhcGhpY3NGYWN0b3J5LnByb3RvdHlwZS5fY2xlYXIgPSBmdW5jdGlvbihnZngpIHtcbiAgdmFyIHZpc3VhbCA9IGdldFZpc3VhbChnZngpO1xuXG4gIGRvbUNsZWFyKHZpc3VhbCk7XG5cbiAgcmV0dXJuIHZpc3VhbDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGdmeCBjb250YWluZXIgZm9yIHNoYXBlcyBhbmQgY29ubmVjdGlvbnNcbiAqXG4gKiBUaGUgbGF5b3V0IGlzIGFzIGZvbGxvd3M6XG4gKlxuICogPGcgY2xhc3M9XCJkanMtZ3JvdXBcIj5cbiAqXG4gKiAgIDwhLS0gdGhlIGdmeCAtLT5cbiAqICAgPGcgY2xhc3M9XCJkanMtZWxlbWVudCBkanMtKHNoYXBlfGNvbm5lY3Rpb258ZnJhbWUpXCI+XG4gKiAgICAgPGcgY2xhc3M9XCJkanMtdmlzdWFsXCI+XG4gKiAgICAgICA8IS0tIHRoZSByZW5kZXJlciBkcmF3cyBpbiBoZXJlIC0tPlxuICogICAgIDwvZz5cbiAqXG4gKiAgICAgPCEtLSBleHRlbnNpb25zIChvdmVybGF5cywgY2xpY2sgYm94LCAuLi4pIGdvZXMgaGVyZVxuICogICA8L2c+XG4gKlxuICogICA8IS0tIHRoZSBnZnggY2hpbGQgbm9kZXMgLS0+XG4gKiAgIDxnIGNsYXNzPVwiZGpzLWNoaWxkcmVuXCI+PC9nPlxuICogPC9nPlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIHRoZSB0eXBlIG9mIHRoZSBlbGVtZW50LCBpLmUuIHNoYXBlIHwgY29ubmVjdGlvblxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBbY2hpbGRyZW5HZnhdXG4gKiBAcGFyYW0ge251bWJlcn0gW3BhcmVudEluZGV4XSBwb3NpdGlvbiB0byBjcmVhdGUgY29udGFpbmVyIGluIHBhcmVudFxuICogQHBhcmFtIHtib29sZWFufSBbaXNGcmFtZV0gaXMgZnJhbWUgZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge1NWR0VsZW1lbnR9XG4gKi9cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUuX2NyZWF0ZUNvbnRhaW5lciA9IGZ1bmN0aW9uKFxuICAgIHR5cGUsIGNoaWxkcmVuR2Z4LCBwYXJlbnRJbmRleCwgaXNGcmFtZVxuKSB7XG4gIHZhciBvdXRlckdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuICBzdmdDbGFzc2VzKG91dGVyR2Z4KS5hZGQoJ2Rqcy1ncm91cCcpO1xuXG4gIC8vIGluc2VydCBub2RlIGF0IHBvc2l0aW9uXG4gIGlmICh0eXBlb2YgcGFyZW50SW5kZXggIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcHJlcGVuZFRvKG91dGVyR2Z4LCBjaGlsZHJlbkdmeCwgY2hpbGRyZW5HZnguY2hpbGROb2Rlc1twYXJlbnRJbmRleF0pO1xuICB9IGVsc2Uge1xuICAgIHN2Z0FwcGVuZChjaGlsZHJlbkdmeCwgb3V0ZXJHZngpO1xuICB9XG5cbiAgdmFyIGdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuICBzdmdDbGFzc2VzKGdmeCkuYWRkKCdkanMtZWxlbWVudCcpO1xuICBzdmdDbGFzc2VzKGdmeCkuYWRkKCdkanMtJyArIHR5cGUpO1xuXG4gIGlmIChpc0ZyYW1lKSB7XG4gICAgc3ZnQ2xhc3NlcyhnZngpLmFkZCgnZGpzLWZyYW1lJyk7XG4gIH1cblxuICBzdmdBcHBlbmQob3V0ZXJHZngsIGdmeCk7XG5cbiAgLy8gY3JlYXRlIHZpc3VhbFxuICB2YXIgdmlzdWFsID0gc3ZnQ3JlYXRlKCdnJyk7XG4gIHN2Z0NsYXNzZXModmlzdWFsKS5hZGQoJ2Rqcy12aXN1YWwnKTtcblxuICBzdmdBcHBlbmQoZ2Z4LCB2aXN1YWwpO1xuXG4gIHJldHVybiBnZng7XG59O1xuXG5HcmFwaGljc0ZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uKHR5cGUsIGVsZW1lbnQsIHBhcmVudEluZGV4KSB7XG4gIHZhciBjaGlsZHJlbkdmeCA9IHRoaXMuX2dldENoaWxkcmVuQ29udGFpbmVyKGVsZW1lbnQucGFyZW50KTtcbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUNvbnRhaW5lcih0eXBlLCBjaGlsZHJlbkdmeCwgcGFyZW50SW5kZXgsIGlzRnJhbWVFbGVtZW50KGVsZW1lbnQpKTtcbn07XG5cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUudXBkYXRlQ29udGFpbm1lbnRzID0gZnVuY3Rpb24oZWxlbWVudHMpIHtcblxuICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnksXG4gICAgICBwYXJlbnRzO1xuXG4gIHBhcmVudHMgPSByZWR1Y2UoZWxlbWVudHMsIGZ1bmN0aW9uKG1hcCwgZSkge1xuXG4gICAgaWYgKGUucGFyZW50KSB7XG4gICAgICBtYXBbZS5wYXJlbnQuaWRdID0gZS5wYXJlbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcDtcbiAgfSwge30pO1xuXG4gIC8vIHVwZGF0ZSBhbGwgcGFyZW50cyBvZiBjaGFuZ2VkIGFuZCByZW9yZ2FuaXplZCB0aGVpciBjaGlsZHJlblxuICAvLyBpbiB0aGUgY29ycmVjdCBvcmRlciAoYXMgaW5kaWNhdGVkIGluIG91ciBtb2RlbClcbiAgZm9yRWFjaChwYXJlbnRzLCBmdW5jdGlvbihwYXJlbnQpIHtcblxuICAgIHZhciBjaGlsZHJlbiA9IHBhcmVudC5jaGlsZHJlbjtcblxuICAgIGlmICghY2hpbGRyZW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY2hpbGRyZW5HZnggPSBzZWxmLl9nZXRDaGlsZHJlbkNvbnRhaW5lcihwYXJlbnQpO1xuXG4gICAgZm9yRWFjaChjaGlsZHJlbi5zbGljZSgpLnJldmVyc2UoKSwgZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgIHZhciBjaGlsZEdmeCA9IGVsZW1lbnRSZWdpc3RyeS5nZXRHcmFwaGljcyhjaGlsZCk7XG5cbiAgICAgIHByZXBlbmRUbyhjaGlsZEdmeC5wYXJlbnROb2RlLCBjaGlsZHJlbkdmeCk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuR3JhcGhpY3NGYWN0b3J5LnByb3RvdHlwZS5kcmF3U2hhcGUgPSBmdW5jdGlvbih2aXN1YWwsIGVsZW1lbnQpIHtcbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgcmV0dXJuIGV2ZW50QnVzLmZpcmUoJ3JlbmRlci5zaGFwZScsIHsgZ2Z4OiB2aXN1YWwsIGVsZW1lbnQ6IGVsZW1lbnQgfSk7XG59O1xuXG5HcmFwaGljc0ZhY3RvcnkucHJvdG90eXBlLmdldFNoYXBlUGF0aCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgcmV0dXJuIGV2ZW50QnVzLmZpcmUoJ3JlbmRlci5nZXRTaGFwZVBhdGgnLCBlbGVtZW50KTtcbn07XG5cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUuZHJhd0Nvbm5lY3Rpb24gPSBmdW5jdGlvbih2aXN1YWwsIGVsZW1lbnQpIHtcbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgcmV0dXJuIGV2ZW50QnVzLmZpcmUoJ3JlbmRlci5jb25uZWN0aW9uJywgeyBnZng6IHZpc3VhbCwgZWxlbWVudDogZWxlbWVudCB9KTtcbn07XG5cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUuZ2V0Q29ubmVjdGlvblBhdGggPSBmdW5jdGlvbih3YXlwb2ludHMpIHtcbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgcmV0dXJuIGV2ZW50QnVzLmZpcmUoJ3JlbmRlci5nZXRDb25uZWN0aW9uUGF0aCcsIHdheXBvaW50cyk7XG59O1xuXG5HcmFwaGljc0ZhY3RvcnkucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKHR5cGUsIGVsZW1lbnQsIGdmeCkge1xuXG4gIC8vIGRvIE5PVCB1cGRhdGUgcm9vdCBlbGVtZW50XG4gIGlmICghZWxlbWVudC5wYXJlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgdmlzdWFsID0gdGhpcy5fY2xlYXIoZ2Z4KTtcblxuICAvLyByZWRyYXdcbiAgaWYgKHR5cGUgPT09ICdzaGFwZScpIHtcbiAgICB0aGlzLmRyYXdTaGFwZSh2aXN1YWwsIGVsZW1lbnQpO1xuXG4gICAgLy8gdXBkYXRlIHBvc2l0aW9uaW5nXG4gICAgdHJhbnNsYXRlKGdmeCwgZWxlbWVudC54LCBlbGVtZW50LnkpO1xuICB9IGVsc2VcbiAgaWYgKHR5cGUgPT09ICdjb25uZWN0aW9uJykge1xuICAgIHRoaXMuZHJhd0Nvbm5lY3Rpb24odmlzdWFsLCBlbGVtZW50KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gdHlwZTogJyArIHR5cGUpO1xuICB9XG5cbiAgaWYgKGVsZW1lbnQuaGlkZGVuKSB7XG4gICAgc3ZnQXR0cihnZngsICdkaXNwbGF5JywgJ25vbmUnKTtcbiAgfSBlbHNlIHtcbiAgICBzdmdBdHRyKGdmeCwgJ2Rpc3BsYXknLCAnYmxvY2snKTtcbiAgfVxufTtcblxuR3JhcGhpY3NGYWN0b3J5LnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciBnZnggPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZWxlbWVudCk7XG5cbiAgLy8gcmVtb3ZlXG4gIHN2Z1JlbW92ZShnZngucGFyZW50Tm9kZSk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBwcmVwZW5kVG8obmV3Tm9kZSwgcGFyZW50Tm9kZSwgc2libGluZ05vZGUpIHtcbiAgdmFyIG5vZGUgPSBzaWJsaW5nTm9kZSB8fCBwYXJlbnROb2RlLmZpcnN0Q2hpbGQ7XG5cbiAgLy8gZG8gbm90IHByZXBlbmQgbm9kZSB0byBpdHNlbGYgdG8gcHJldmVudCBJRSBmcm9tIGNyYXNoaW5nXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9icG1uLWlvL2JwbW4tanMvaXNzdWVzLzc0NlxuICBpZiAobmV3Tm9kZSA9PT0gbm9kZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld05vZGUsIG5vZGUpO1xufVxuIiwiaW1wb3J0IERyYXdNb2R1bGUgZnJvbSAnLi4vZHJhdyc7XG5cbmltcG9ydCBDYW52YXMgZnJvbSAnLi9DYW52YXMnO1xuaW1wb3J0IEVsZW1lbnRSZWdpc3RyeSBmcm9tICcuL0VsZW1lbnRSZWdpc3RyeSc7XG5pbXBvcnQgRWxlbWVudEZhY3RvcnkgZnJvbSAnLi9FbGVtZW50RmFjdG9yeSc7XG5pbXBvcnQgRXZlbnRCdXMgZnJvbSAnLi9FdmVudEJ1cyc7XG5pbXBvcnQgR3JhcGhpY3NGYWN0b3J5IGZyb20gJy4vR3JhcGhpY3NGYWN0b3J5JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogWyBEcmF3TW9kdWxlIF0sXG4gIF9faW5pdF9fOiBbICdjYW52YXMnIF0sXG4gIGNhbnZhczogWyAndHlwZScsIENhbnZhcyBdLFxuICBlbGVtZW50UmVnaXN0cnk6IFsgJ3R5cGUnLCBFbGVtZW50UmVnaXN0cnkgXSxcbiAgZWxlbWVudEZhY3Rvcnk6IFsgJ3R5cGUnLCBFbGVtZW50RmFjdG9yeSBdLFxuICBldmVudEJ1czogWyAndHlwZScsIEV2ZW50QnVzIF0sXG4gIGdyYXBoaWNzRmFjdG9yeTogWyAndHlwZScsIEdyYXBoaWNzRmFjdG9yeSBdXG59OyIsInZhciBERUZBVUxUX1JFTkRFUl9QUklPUklUWSA9IDEwMDA7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2Ygc2hhcGUgYW5kIGNvbm5lY3Rpb24gcmVuZGVyZXJzLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge251bWJlcn0gW3JlbmRlclByaW9yaXR5PTEwMDBdXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJhc2VSZW5kZXJlcihldmVudEJ1cywgcmVuZGVyUHJpb3JpdHkpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHJlbmRlclByaW9yaXR5ID0gcmVuZGVyUHJpb3JpdHkgfHwgREVGQVVMVF9SRU5ERVJfUFJJT1JJVFk7XG5cbiAgZXZlbnRCdXMub24oWyAncmVuZGVyLnNoYXBlJywgJ3JlbmRlci5jb25uZWN0aW9uJyBdLCByZW5kZXJQcmlvcml0eSwgZnVuY3Rpb24oZXZ0LCBjb250ZXh0KSB7XG4gICAgdmFyIHR5cGUgPSBldnQudHlwZSxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcbiAgICAgICAgdmlzdWFscyA9IGNvbnRleHQuZ2Z4O1xuXG4gICAgaWYgKHNlbGYuY2FuUmVuZGVyKGVsZW1lbnQpKSB7XG4gICAgICBpZiAodHlwZSA9PT0gJ3JlbmRlci5zaGFwZScpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuZHJhd1NoYXBlKHZpc3VhbHMsIGVsZW1lbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuZHJhd0Nvbm5lY3Rpb24odmlzdWFscywgZWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdyZW5kZXIuZ2V0U2hhcGVQYXRoJywgJ3JlbmRlci5nZXRDb25uZWN0aW9uUGF0aCddLCByZW5kZXJQcmlvcml0eSwgZnVuY3Rpb24oZXZ0LCBlbGVtZW50KSB7XG4gICAgaWYgKHNlbGYuY2FuUmVuZGVyKGVsZW1lbnQpKSB7XG4gICAgICBpZiAoZXZ0LnR5cGUgPT09ICdyZW5kZXIuZ2V0U2hhcGVQYXRoJykge1xuICAgICAgICByZXR1cm4gc2VsZi5nZXRTaGFwZVBhdGgoZWxlbWVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gc2VsZi5nZXRDb25uZWN0aW9uUGF0aChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIFNob3VsZCBjaGVjayB3aGV0aGVyICp0aGlzKiByZW5kZXJlciBjYW4gcmVuZGVyXG4gKiB0aGUgZWxlbWVudC9jb25uZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7ZWxlbWVudH0gZWxlbWVudFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5CYXNlUmVuZGVyZXIucHJvdG90eXBlLmNhblJlbmRlciA9IGZ1bmN0aW9uKCkge307XG5cbi8qKlxuICogUHJvdmlkZXMgdGhlIHNoYXBlJ3Mgc25hcCBzdmcgZWxlbWVudCB0byBiZSBkcmF3biBvbiB0aGUgYGNhbnZhc2AuXG4gKlxuICogQHBhcmFtIHtkanMuR3JhcGhpY3N9IHZpc3VhbHNcbiAqIEBwYXJhbSB7U2hhcGV9IHNoYXBlXG4gKlxuICogQHJldHVybnMge1NuYXAuc3ZnfSBbcmV0dXJucyBhIFNuYXAuc3ZnIHBhcGVyIGVsZW1lbnQgXVxuICovXG5CYXNlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdTaGFwZSA9IGZ1bmN0aW9uKCkge307XG5cbi8qKlxuICogUHJvdmlkZXMgdGhlIHNoYXBlJ3Mgc25hcCBzdmcgZWxlbWVudCB0byBiZSBkcmF3biBvbiB0aGUgYGNhbnZhc2AuXG4gKlxuICogQHBhcmFtIHtkanMuR3JhcGhpY3N9IHZpc3VhbHNcbiAqIEBwYXJhbSB7Q29ubmVjdGlvbn0gY29ubmVjdGlvblxuICpcbiAqIEByZXR1cm5zIHtTbmFwLnN2Z30gW3JldHVybnMgYSBTbmFwLnN2ZyBwYXBlciBlbGVtZW50IF1cbiAqL1xuQmFzZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3Q29ubmVjdGlvbiA9IGZ1bmN0aW9uKCkge307XG5cbi8qKlxuICogR2V0cyB0aGUgU1ZHIHBhdGggb2YgYSBzaGFwZSB0aGF0IHJlcHJlc2VudHMgaXQncyB2aXN1YWwgYm91bmRzLlxuICpcbiAqIEBwYXJhbSB7U2hhcGV9IHNoYXBlXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSBzdmcgcGF0aFxuICovXG5CYXNlUmVuZGVyZXIucHJvdG90eXBlLmdldFNoYXBlUGF0aCA9IGZ1bmN0aW9uKCkge307XG5cbi8qKlxuICogR2V0cyB0aGUgU1ZHIHBhdGggb2YgYSBjb25uZWN0aW9uIHRoYXQgcmVwcmVzZW50cyBpdCdzIHZpc3VhbCBib3VuZHMuXG4gKlxuICogQHBhcmFtIHtDb25uZWN0aW9ufSBjb25uZWN0aW9uXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSBzdmcgcGF0aFxuICovXG5CYXNlUmVuZGVyZXIucHJvdG90eXBlLmdldENvbm5lY3Rpb25QYXRoID0gZnVuY3Rpb24oKSB7fTtcbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBCYXNlUmVuZGVyZXIgZnJvbSAnLi9CYXNlUmVuZGVyZXInO1xuXG5pbXBvcnQge1xuICBjb21wb25lbnRzVG9QYXRoLFxuICBjcmVhdGVMaW5lXG59IGZyb20gJy4uL3V0aWwvUmVuZGVyVXRpbCc7XG5cbmltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY3JlYXRlIGFzIHN2Z0NyZWF0ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7XG4gIGlzRnJhbWVFbGVtZW50XG59IGZyb20gJy4uL3V0aWwvRWxlbWVudHMnO1xuXG4vLyBhcHBseSBkZWZhdWx0IHJlbmRlcmVyIHdpdGggbG93ZXN0IHBvc3NpYmxlIHByaW9yaXR5XG4vLyBzbyB0aGF0IGl0IG9ubHkga2lja3MgaW4gaWYgbm9vbmUgZWxzZSBjb3VsZCByZW5kZXJcbnZhciBERUZBVUxUX1JFTkRFUl9QUklPUklUWSA9IDE7XG5cbi8qKlxuICogVGhlIGRlZmF1bHQgcmVuZGVyZXIgdXNlZCBmb3Igc2hhcGVzIGFuZCBjb25uZWN0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtTdHlsZXN9IHN0eWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEZWZhdWx0UmVuZGVyZXIoZXZlbnRCdXMsIHN0eWxlcykge1xuXG4gIC8vXG4gIEJhc2VSZW5kZXJlci5jYWxsKHRoaXMsIGV2ZW50QnVzLCBERUZBVUxUX1JFTkRFUl9QUklPUklUWSk7XG5cbiAgdGhpcy5DT05ORUNUSU9OX1NUWUxFID0gc3R5bGVzLnN0eWxlKFsgJ25vLWZpbGwnIF0sIHsgc3Ryb2tlV2lkdGg6IDUsIHN0cm9rZTogJ2Z1Y2hzaWEnIH0pO1xuICB0aGlzLlNIQVBFX1NUWUxFID0gc3R5bGVzLnN0eWxlKHsgZmlsbDogJ3doaXRlJywgc3Ryb2tlOiAnZnVjaHNpYScsIHN0cm9rZVdpZHRoOiAyIH0pO1xuICB0aGlzLkZSQU1FX1NUWUxFID0gc3R5bGVzLnN0eWxlKFsgJ25vLWZpbGwnIF0sIHsgc3Ryb2tlOiAnZnVjaHNpYScsIHN0cm9rZURhc2hhcnJheTogNCwgc3Ryb2tlV2lkdGg6IDIgfSk7XG59XG5cbmluaGVyaXRzKERlZmF1bHRSZW5kZXJlciwgQmFzZVJlbmRlcmVyKTtcblxuXG5EZWZhdWx0UmVuZGVyZXIucHJvdG90eXBlLmNhblJlbmRlciA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkRlZmF1bHRSZW5kZXJlci5wcm90b3R5cGUuZHJhd1NoYXBlID0gZnVuY3Rpb24gZHJhd1NoYXBlKHZpc3VhbHMsIGVsZW1lbnQpIHtcbiAgdmFyIHJlY3QgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcblxuICBzdmdBdHRyKHJlY3QsIHtcbiAgICB4OiAwLFxuICAgIHk6IDAsXG4gICAgd2lkdGg6IGVsZW1lbnQud2lkdGggfHwgMCxcbiAgICBoZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0IHx8IDBcbiAgfSk7XG5cbiAgaWYgKGlzRnJhbWVFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgc3ZnQXR0cihyZWN0LCB0aGlzLkZSQU1FX1NUWUxFKTtcbiAgfSBlbHNlIHtcbiAgICBzdmdBdHRyKHJlY3QsIHRoaXMuU0hBUEVfU1RZTEUpO1xuICB9XG5cbiAgc3ZnQXBwZW5kKHZpc3VhbHMsIHJlY3QpO1xuXG4gIHJldHVybiByZWN0O1xufTtcblxuRGVmYXVsdFJlbmRlcmVyLnByb3RvdHlwZS5kcmF3Q29ubmVjdGlvbiA9IGZ1bmN0aW9uIGRyYXdDb25uZWN0aW9uKHZpc3VhbHMsIGNvbm5lY3Rpb24pIHtcblxuICB2YXIgbGluZSA9IGNyZWF0ZUxpbmUoY29ubmVjdGlvbi53YXlwb2ludHMsIHRoaXMuQ09OTkVDVElPTl9TVFlMRSk7XG4gIHN2Z0FwcGVuZCh2aXN1YWxzLCBsaW5lKTtcblxuICByZXR1cm4gbGluZTtcbn07XG5cbkRlZmF1bHRSZW5kZXJlci5wcm90b3R5cGUuZ2V0U2hhcGVQYXRoID0gZnVuY3Rpb24gZ2V0U2hhcGVQYXRoKHNoYXBlKSB7XG5cbiAgdmFyIHggPSBzaGFwZS54LFxuICAgICAgeSA9IHNoYXBlLnksXG4gICAgICB3aWR0aCA9IHNoYXBlLndpZHRoLFxuICAgICAgaGVpZ2h0ID0gc2hhcGUuaGVpZ2h0O1xuXG4gIHZhciBzaGFwZVBhdGggPSBbXG4gICAgWydNJywgeCwgeV0sXG4gICAgWydsJywgd2lkdGgsIDBdLFxuICAgIFsnbCcsIDAsIGhlaWdodF0sXG4gICAgWydsJywgLXdpZHRoLCAwXSxcbiAgICBbJ3onXVxuICBdO1xuXG4gIHJldHVybiBjb21wb25lbnRzVG9QYXRoKHNoYXBlUGF0aCk7XG59O1xuXG5EZWZhdWx0UmVuZGVyZXIucHJvdG90eXBlLmdldENvbm5lY3Rpb25QYXRoID0gZnVuY3Rpb24gZ2V0Q29ubmVjdGlvblBhdGgoY29ubmVjdGlvbikge1xuICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG5cbiAgdmFyIGlkeCwgcG9pbnQsIGNvbm5lY3Rpb25QYXRoID0gW107XG5cbiAgZm9yIChpZHggPSAwOyAocG9pbnQgPSB3YXlwb2ludHNbaWR4XSk7IGlkeCsrKSB7XG5cbiAgICAvLyB0YWtlIGludmlzaWJsZSBkb2NraW5nIGludG8gYWNjb3VudFxuICAgIC8vIHdoZW4gY3JlYXRpbmcgdGhlIHBhdGhcbiAgICBwb2ludCA9IHBvaW50Lm9yaWdpbmFsIHx8IHBvaW50O1xuXG4gICAgY29ubmVjdGlvblBhdGgucHVzaChbIGlkeCA9PT0gMCA/ICdNJyA6ICdMJywgcG9pbnQueCwgcG9pbnQueSBdKTtcbiAgfVxuXG4gIHJldHVybiBjb21wb25lbnRzVG9QYXRoKGNvbm5lY3Rpb25QYXRoKTtcbn07XG5cblxuRGVmYXVsdFJlbmRlcmVyLiRpbmplY3QgPSBbICdldmVudEJ1cycsICdzdHlsZXMnIF07XG4iLCJpbXBvcnQge1xuICBpc0FycmF5LFxuICBhc3NpZ24sXG4gIHJlZHVjZVxufSBmcm9tICdtaW4tZGFzaCc7XG5cblxuLyoqXG4gKiBBIGNvbXBvbmVudCB0aGF0IG1hbmFnZXMgc2hhcGUgc3R5bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFN0eWxlcygpIHtcblxuICB2YXIgZGVmYXVsdFRyYWl0cyA9IHtcblxuICAgICduby1maWxsJzoge1xuICAgICAgZmlsbDogJ25vbmUnXG4gICAgfSxcbiAgICAnbm8tYm9yZGVyJzoge1xuICAgICAgc3Ryb2tlT3BhY2l0eTogMC4wXG4gICAgfSxcbiAgICAnbm8tZXZlbnRzJzoge1xuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnXG4gICAgfVxuICB9O1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvKipcbiAgICogQnVpbGRzIGEgc3R5bGUgZGVmaW5pdGlvbiBmcm9tIGEgY2xhc3NOYW1lLCBhIGxpc3Qgb2YgdHJhaXRzIGFuZCBhbiBvYmplY3Qgb2YgYWRkaXRpb25hbCBhdHRyaWJ1dGVzLlxuICAgKlxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IGNsYXNzTmFtZVxuICAgKiBAcGFyYW0gIHtBcnJheTxzdHJpbmc+fSB0cmFpdHNcbiAgICogQHBhcmFtICB7T2JqZWN0fSBhZGRpdGlvbmFsQXR0cnNcbiAgICpcbiAgICogQHJldHVybiB7T2JqZWN0fSB0aGUgc3R5bGUgZGVmaW50aW9uXG4gICAqL1xuICB0aGlzLmNscyA9IGZ1bmN0aW9uKGNsYXNzTmFtZSwgdHJhaXRzLCBhZGRpdGlvbmFsQXR0cnMpIHtcbiAgICB2YXIgYXR0cnMgPSB0aGlzLnN0eWxlKHRyYWl0cywgYWRkaXRpb25hbEF0dHJzKTtcblxuICAgIHJldHVybiBhc3NpZ24oYXR0cnMsIHsgJ2NsYXNzJzogY2xhc3NOYW1lIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBzdHlsZSBkZWZpbml0aW9uIGZyb20gYSBsaXN0IG9mIHRyYWl0cyBhbmQgYW4gb2JqZWN0IG9mIGFkZGl0aW9uYWwgYXR0cmlidXRlcy5cbiAgICpcbiAgICogQHBhcmFtICB7QXJyYXk8c3RyaW5nPn0gdHJhaXRzXG4gICAqIEBwYXJhbSAge09iamVjdH0gYWRkaXRpb25hbEF0dHJzXG4gICAqXG4gICAqIEByZXR1cm4ge09iamVjdH0gdGhlIHN0eWxlIGRlZmludGlvblxuICAgKi9cbiAgdGhpcy5zdHlsZSA9IGZ1bmN0aW9uKHRyYWl0cywgYWRkaXRpb25hbEF0dHJzKSB7XG5cbiAgICBpZiAoIWlzQXJyYXkodHJhaXRzKSAmJiAhYWRkaXRpb25hbEF0dHJzKSB7XG4gICAgICBhZGRpdGlvbmFsQXR0cnMgPSB0cmFpdHM7XG4gICAgICB0cmFpdHMgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgYXR0cnMgPSByZWR1Y2UodHJhaXRzLCBmdW5jdGlvbihhdHRycywgdCkge1xuICAgICAgcmV0dXJuIGFzc2lnbihhdHRycywgZGVmYXVsdFRyYWl0c1t0XSB8fCB7fSk7XG4gICAgfSwge30pO1xuXG4gICAgcmV0dXJuIGFkZGl0aW9uYWxBdHRycyA/IGFzc2lnbihhdHRycywgYWRkaXRpb25hbEF0dHJzKSA6IGF0dHJzO1xuICB9O1xuXG4gIHRoaXMuY29tcHV0ZVN0eWxlID0gZnVuY3Rpb24oY3VzdG9tLCB0cmFpdHMsIGRlZmF1bHRTdHlsZXMpIHtcbiAgICBpZiAoIWlzQXJyYXkodHJhaXRzKSkge1xuICAgICAgZGVmYXVsdFN0eWxlcyA9IHRyYWl0cztcbiAgICAgIHRyYWl0cyA9IFtdO1xuICAgIH1cblxuICAgIHJldHVybiBzZWxmLnN0eWxlKHRyYWl0cyB8fCBbXSwgYXNzaWduKHt9LCBkZWZhdWx0U3R5bGVzLCBjdXN0b20gfHwge30pKTtcbiAgfTtcbn1cbiIsImltcG9ydCBEZWZhdWx0UmVuZGVyZXIgZnJvbSAnLi9EZWZhdWx0UmVuZGVyZXInO1xuaW1wb3J0IFN0eWxlcyBmcm9tICcuL1N0eWxlcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2RlZmF1bHRSZW5kZXJlcicgXSxcbiAgZGVmYXVsdFJlbmRlcmVyOiBbICd0eXBlJywgRGVmYXVsdFJlbmRlcmVyIF0sXG4gIHN0eWxlczogWyAndHlwZScsIFN0eWxlcyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgZmlsdGVyLFxuICBmb3JFYWNoLFxuICBzb3J0Qnlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5mdW5jdGlvbiBsYXN0KGFycikge1xuICByZXR1cm4gYXJyICYmIGFyclthcnIubGVuZ3RoIC0gMV07XG59XG5cbmZ1bmN0aW9uIHNvcnRUb3BPck1pZGRsZShlbGVtZW50KSB7XG4gIHJldHVybiBlbGVtZW50Lnk7XG59XG5cbmZ1bmN0aW9uIHNvcnRMZWZ0T3JDZW50ZXIoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudC54O1xufVxuXG4vKipcbiAqIFNvcnRpbmcgZnVuY3Rpb25zIGZvciBkaWZmZXJlbnQgdHlwZXMgb2YgYWxpZ25tZW50XG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xudmFyIEFMSUdOTUVOVF9TT1JUSU5HID0ge1xuICBsZWZ0OiBzb3J0TGVmdE9yQ2VudGVyLFxuICBjZW50ZXI6IHNvcnRMZWZ0T3JDZW50ZXIsXG4gIHJpZ2h0OiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGg7XG4gIH0sXG4gIHRvcDogc29ydFRvcE9yTWlkZGxlLFxuICBtaWRkbGU6IHNvcnRUb3BPck1pZGRsZSxcbiAgYm90dG9tOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQueSArIGVsZW1lbnQuaGVpZ2h0O1xuICB9XG59O1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFsaWduRWxlbWVudHMobW9kZWxpbmcpIHtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbn1cblxuQWxpZ25FbGVtZW50cy4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cblxuLyoqXG4gKiBHZXQgdGhlIHJlbGV2YW50IFwiYXhpc1wiIGFuZCBcImRpbWVuc2lvblwiIHJlbGF0ZWQgdG8gdGhlIGN1cnJlbnQgdHlwZSBvZiBhbGlnbm1lbnRcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHR5cGUgbGVmdHxyaWdodHxjZW50ZXJ8dG9wfGJvdHRvbXxtaWRkbGVcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHsgYXhpcywgZGltZW5zaW9uIH1cbiAqL1xuQWxpZ25FbGVtZW50cy5wcm90b3R5cGUuX2dldE9yaWVudGF0aW9uRGV0YWlscyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIHZlcnRpY2FsID0gWyAndG9wJywgJ2JvdHRvbScsICdtaWRkbGUnIF0sXG4gICAgICBheGlzID0gJ3gnLFxuICAgICAgZGltZW5zaW9uID0gJ3dpZHRoJztcblxuICBpZiAodmVydGljYWwuaW5kZXhPZih0eXBlKSAhPT0gLTEpIHtcbiAgICBheGlzID0gJ3knO1xuICAgIGRpbWVuc2lvbiA9ICdoZWlnaHQnO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBheGlzOiBheGlzLFxuICAgIGRpbWVuc2lvbjogZGltZW5zaW9uXG4gIH07XG59O1xuXG5BbGlnbkVsZW1lbnRzLnByb3RvdHlwZS5faXNUeXBlID0gZnVuY3Rpb24odHlwZSwgdHlwZXMpIHtcbiAgcmV0dXJuIHR5cGVzLmluZGV4T2YodHlwZSkgIT09IC0xO1xufTtcblxuLyoqXG4gKiBHZXQgYSBwb2ludCBvbiB0aGUgcmVsZXZhbnQgYXhpcyB3aGVyZSBlbGVtZW50cyBzaG91bGQgYWxpZ24gdG9cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHR5cGUgbGVmdHxyaWdodHxjZW50ZXJ8dG9wfGJvdHRvbXxtaWRkbGVcbiAqIEBwYXJhbSAge0FycmF5fSBzb3J0ZWRFbGVtZW50c1xuICpcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuQWxpZ25FbGVtZW50cy5wcm90b3R5cGUuX2FsaWdubWVudFBvc2l0aW9uID0gZnVuY3Rpb24odHlwZSwgc29ydGVkRWxlbWVudHMpIHtcbiAgdmFyIG9yaWVudGF0aW9uID0gdGhpcy5fZ2V0T3JpZW50YXRpb25EZXRhaWxzKHR5cGUpLFxuICAgICAgYXhpcyA9IG9yaWVudGF0aW9uLmF4aXMsXG4gICAgICBkaW1lbnNpb24gPSBvcmllbnRhdGlvbi5kaW1lbnNpb24sXG4gICAgICBhbGlnbm1lbnQgPSB7fSxcbiAgICAgIGNlbnRlcnMgPSB7fSxcbiAgICAgIGhhc1NoYXJlZENlbnRlcnMgPSBmYWxzZSxcbiAgICAgIGNlbnRlcmVkRWxlbWVudHMsXG4gICAgICBmaXJzdEVsZW1lbnQsXG4gICAgICBsYXN0RWxlbWVudDtcblxuICBmdW5jdGlvbiBnZXRNaWRkbGVPclRvcChmaXJzdCwgbGFzdCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKChmaXJzdFtheGlzXSArIGxhc3RbYXhpc10gKyBsYXN0W2RpbWVuc2lvbl0pIC8gMik7XG4gIH1cblxuICBpZiAodGhpcy5faXNUeXBlKHR5cGUsIFsgJ2xlZnQnLCAndG9wJyBdKSkge1xuICAgIGFsaWdubWVudFt0eXBlXSA9IHNvcnRlZEVsZW1lbnRzWzBdW2F4aXNdO1xuXG4gIH0gZWxzZSBpZiAodGhpcy5faXNUeXBlKHR5cGUsIFsgJ3JpZ2h0JywgJ2JvdHRvbScgXSkpIHtcbiAgICBsYXN0RWxlbWVudCA9IGxhc3Qoc29ydGVkRWxlbWVudHMpO1xuXG4gICAgYWxpZ25tZW50W3R5cGVdID0gbGFzdEVsZW1lbnRbYXhpc10gKyBsYXN0RWxlbWVudFtkaW1lbnNpb25dO1xuXG4gIH0gZWxzZSBpZiAodGhpcy5faXNUeXBlKHR5cGUsIFsgJ2NlbnRlcicsICdtaWRkbGUnIF0pKSB7XG5cbiAgICAvLyBjaGVjayBpZiB0aGVyZSBpcyBhIGNlbnRlciBzaGFyZWQgYnkgbW9yZSB0aGFuIG9uZSBzaGFwZVxuICAgIC8vIGlmIG5vdCwganVzdCB0YWtlIHRoZSBtaWRkbGUgb2YgdGhlIHJhbmdlXG4gICAgZm9yRWFjaChzb3J0ZWRFbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgdmFyIGNlbnRlciA9IGVsZW1lbnRbYXhpc10gKyBNYXRoLnJvdW5kKGVsZW1lbnRbZGltZW5zaW9uXSAvIDIpO1xuXG4gICAgICBpZiAoY2VudGVyc1tjZW50ZXJdKSB7XG4gICAgICAgIGNlbnRlcnNbY2VudGVyXS5lbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2VudGVyc1tjZW50ZXJdID0ge1xuICAgICAgICAgIGVsZW1lbnRzOiBbIGVsZW1lbnQgXSxcbiAgICAgICAgICBjZW50ZXI6IGNlbnRlclxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY2VudGVyZWRFbGVtZW50cyA9IHNvcnRCeShjZW50ZXJzLCBmdW5jdGlvbihjZW50ZXIpIHtcbiAgICAgIGlmIChjZW50ZXIuZWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBoYXNTaGFyZWRDZW50ZXJzID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNlbnRlci5lbGVtZW50cy5sZW5ndGg7XG4gICAgfSk7XG5cbiAgICBpZiAoaGFzU2hhcmVkQ2VudGVycykge1xuICAgICAgYWxpZ25tZW50W3R5cGVdID0gbGFzdChjZW50ZXJlZEVsZW1lbnRzKS5jZW50ZXI7XG5cbiAgICAgIHJldHVybiBhbGlnbm1lbnQ7XG4gICAgfVxuXG4gICAgZmlyc3RFbGVtZW50ID0gc29ydGVkRWxlbWVudHNbMF07XG5cbiAgICBzb3J0ZWRFbGVtZW50cyA9IHNvcnRCeShzb3J0ZWRFbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnRbYXhpc10gKyBlbGVtZW50W2RpbWVuc2lvbl07XG4gICAgfSk7XG5cbiAgICBsYXN0RWxlbWVudCA9IGxhc3Qoc29ydGVkRWxlbWVudHMpO1xuXG4gICAgYWxpZ25tZW50W3R5cGVdID0gZ2V0TWlkZGxlT3JUb3AoZmlyc3RFbGVtZW50LCBsYXN0RWxlbWVudCk7XG4gIH1cblxuICByZXR1cm4gYWxpZ25tZW50O1xufTtcblxuLyoqXG4gKiBFeGVjdXRlcyB0aGUgYWxpZ25tZW50IG9mIGEgc2VsZWN0aW9uIG9mIGVsZW1lbnRzXG4gKlxuICogQHBhcmFtICB7QXJyYXl9IGVsZW1lbnRzIFtkZXNjcmlwdGlvbl1cbiAqIEBwYXJhbSAge3N0cmluZ30gdHlwZSBsZWZ0fHJpZ2h0fGNlbnRlcnx0b3B8Ym90dG9tfG1pZGRsZVxuICovXG5BbGlnbkVsZW1lbnRzLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oZWxlbWVudHMsIHR5cGUpIHtcbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmc7XG5cbiAgdmFyIGZpbHRlcmVkRWxlbWVudHMgPSBmaWx0ZXIoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gIShlbGVtZW50LndheXBvaW50cyB8fCBlbGVtZW50Lmhvc3QgfHwgZWxlbWVudC5sYWJlbFRhcmdldCk7XG4gIH0pO1xuXG4gIHZhciBzb3J0Rm4gPSBBTElHTk1FTlRfU09SVElOR1t0eXBlXTtcblxuICB2YXIgc29ydGVkRWxlbWVudHMgPSBzb3J0QnkoZmlsdGVyZWRFbGVtZW50cywgc29ydEZuKTtcblxuICB2YXIgYWxpZ25tZW50ID0gdGhpcy5fYWxpZ25tZW50UG9zaXRpb24odHlwZSwgc29ydGVkRWxlbWVudHMpO1xuXG4gIG1vZGVsaW5nLmFsaWduRWxlbWVudHMoc29ydGVkRWxlbWVudHMsIGFsaWdubWVudCk7XG59O1xuIiwiaW1wb3J0IEFsaWduRWxlbWVudHMgZnJvbSAnLi9BbGlnbkVsZW1lbnRzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnYWxpZ25FbGVtZW50cycgXSxcbiAgYWxpZ25FbGVtZW50czogWyAndHlwZScsIEFsaWduRWxlbWVudHMgXVxufTtcbiIsImltcG9ydCB7XG4gIGZsYXR0ZW4sXG4gIGZpbHRlcixcbiAgZm9yRWFjaCxcbiAgZ3JvdXBCeSxcbiAgbWFwLFxuICB1bmlvbkJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgc2F2ZUNsZWFyIH0gZnJvbSAnLi4vLi4vdXRpbC9SZW1vdmFsJztcblxuaW1wb3J0IHsgZ2V0TmV3QXR0YWNoU2hhcGVEZWx0YSB9IGZyb20gJy4uLy4uL3V0aWwvQXR0YWNoVXRpbCc7XG5cbmltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnLi4vLi4vY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gMjUxLFxuICAgIEhJR0hfUFJJT1JJVFkgPSAxNDAxO1xuXG52YXIgTUFSS0VSX0FUVEFDSCA9ICdhdHRhY2gtb2snO1xuXG5cbi8qKlxuICogQWRkcyB0aGUgbm90aW9uIG9mIGF0dGFjaGVkIGVsZW1lbnRzIHRvIHRoZSBtb2RlbGVyLlxuICpcbiAqIE9wdGlvbmFsbHkgZGVwZW5kcyBvbiBgZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW92ZWAgdG8gcmVuZGVyXG4gKiB0aGUgYXR0YWNoZWQgZWxlbWVudHMgZHVyaW5nIG1vdmUgcHJldmlldy5cbiAqXG4gKiBPcHRpb25hbGx5IGRlcGVuZHMgb24gYGRpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2xhYmVsLXN1cHBvcnRgXG4gKiB0byByZW5kZXIgYXR0YWNoZWQgbGFiZWxzIGR1cmluZyBtb3ZlIHByZXZpZXcuXG4gKlxuICogQHBhcmFtIHtkaWRpLkluamVjdG9yfSBpbmplY3RvclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBdHRhY2hTdXBwb3J0KGluamVjdG9yLCBldmVudEJ1cywgY2FudmFzLCBydWxlcywgbW9kZWxpbmcpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdmFyIG1vdmVQcmV2aWV3ID0gaW5qZWN0b3IuZ2V0KCdtb3ZlUHJldmlldycsIGZhbHNlKTtcblxuXG4gIC8vIHJlbW92ZSBhbGwgdGhlIGF0dGFjaGVkIGVsZW1lbnRzIGZyb20gdGhlIHNoYXBlcyB0byBiZSB2YWxpZGF0ZWRcbiAgLy8gYWRkIGFsbCB0aGUgYXR0YWNoZWQgc2hhcGVzIHRvIHRoZSBvdmVyYWxsIGxpc3Qgb2YgbW92ZWQgc2hhcGVzXG4gIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLnN0YXJ0JywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzLFxuICAgICAgICB2YWxpZGF0ZWRTaGFwZXMgPSBjb250ZXh0LnZhbGlkYXRlZFNoYXBlcztcblxuICAgIGNvbnRleHQuc2hhcGVzID0gYWRkQXR0YWNoZWQoc2hhcGVzKTtcblxuICAgIGNvbnRleHQudmFsaWRhdGVkU2hhcGVzID0gcmVtb3ZlQXR0YWNoZWQodmFsaWRhdGVkU2hhcGVzKTtcbiAgfSk7XG5cbiAgLy8gYWRkIGF0dGFjaGVycyB0byB0aGUgdmlzdWFsJ3MgZ3JvdXBcbiAgbW92ZVByZXZpZXcgJiYgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUuc3RhcnQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgYXR0YWNoZXJzID0gZ2V0QXR0YWNoZXJzKHNoYXBlcyk7XG5cbiAgICBmb3JFYWNoKGF0dGFjaGVycywgZnVuY3Rpb24oYXR0YWNoZXIpIHtcbiAgICAgIG1vdmVQcmV2aWV3Lm1ha2VEcmFnZ2FibGUoY29udGV4dCwgYXR0YWNoZXIsIHRydWUpO1xuXG4gICAgICBmb3JFYWNoKGF0dGFjaGVyLmxhYmVscywgZnVuY3Rpb24obGFiZWwpIHtcbiAgICAgICAgbW92ZVByZXZpZXcubWFrZURyYWdnYWJsZShjb250ZXh0LCBsYWJlbCwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gYWRkIGF0dGFjaC1vayBtYXJrZXIgdG8gY3VycmVudCBob3N0XG4gIG1vdmVQcmV2aWV3ICYmIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzO1xuXG4gICAgaWYgKHNoYXBlcy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgc2hhcGUgPSBzaGFwZXNbMF07XG5cbiAgICB2YXIgaG9zdCA9IHNoYXBlLmhvc3Q7XG5cbiAgICBpZiAoaG9zdCkge1xuICAgICAgY2FudmFzLmFkZE1hcmtlcihob3N0LCBNQVJLRVJfQVRUQUNIKTtcblxuICAgICAgZXZlbnRCdXMub25jZShbXG4gICAgICAgICdzaGFwZS5tb3ZlLm91dCcsXG4gICAgICAgICdzaGFwZS5tb3ZlLmNsZWFudXAnXG4gICAgICBdLCBmdW5jdGlvbigpIHtcbiAgICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3N0LCBNQVJLRVJfQVRUQUNIKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWRkIGFsbCBhdHRhY2hlcnMgdG8gbW92ZSBjbG9zdXJlXG4gIHRoaXMucHJlRXhlY3V0ZWQoJ2VsZW1lbnRzLm1vdmUnLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIGNsb3N1cmUgPSBjb250ZXh0LmNsb3N1cmUsXG4gICAgICAgIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzLFxuICAgICAgICBhdHRhY2hlcnMgPSBnZXRBdHRhY2hlcnMoc2hhcGVzKTtcblxuICAgIGZvckVhY2goYXR0YWNoZXJzLCBmdW5jdGlvbihhdHRhY2hlcikge1xuICAgICAgY2xvc3VyZS5hZGQoYXR0YWNoZXIsIGNsb3N1cmUudG9wTGV2ZWxbYXR0YWNoZXIuaG9zdC5pZF0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBwZXJmb3JtIHRoZSBhdHRhY2hpbmcgYWZ0ZXIgc2hhcGVzIGFyZSBkb25lIG1vdmluZ1xuICB0aGlzLnBvc3RFeGVjdXRlZCgnZWxlbWVudHMubW92ZScsIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgbmV3SG9zdCA9IGNvbnRleHQubmV3SG9zdCxcbiAgICAgICAgYXR0YWNoZXJzO1xuXG4gICAgLy8gb25seSBzaW5nbGUgZWxlbWVudHMgY2FuIGJlIGF0dGFjaGVkXG4gICAgLy8gbXVsdGlwbHkgZWxlbWVudHMgY2FuIGJlIGRldGFjaGVkXG4gICAgaWYgKG5ld0hvc3QgJiYgc2hhcGVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChuZXdIb3N0KSB7XG4gICAgICBhdHRhY2hlcnMgPSBzaGFwZXM7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gZmluZCBhdHRhY2hlcnMgbW92ZWQgd2l0aG91dCBob3N0XG4gICAgICBhdHRhY2hlcnMgPSBmaWx0ZXIoc2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgICAgICB2YXIgaG9zdCA9IHNoYXBlLmhvc3Q7XG5cbiAgICAgICAgcmV0dXJuIGlzQXR0YWNoZXIoc2hhcGUpICYmICFpbmNsdWRlcyhzaGFwZXMsIGhvc3QpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZm9yRWFjaChhdHRhY2hlcnMsIGZ1bmN0aW9uKGF0dGFjaGVyKSB7XG4gICAgICBtb2RlbGluZy51cGRhdGVBdHRhY2htZW50KGF0dGFjaGVyLCBuZXdIb3N0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gZW5zdXJlIGludmFsaWQgYXR0YWNobWVudCBjb25uZWN0aW9ucyBhcmUgcmVtb3ZlZFxuICB0aGlzLnBvc3RFeGVjdXRlZCgnZWxlbWVudHMubW92ZScsIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBzaGFwZXMgPSBlLmNvbnRleHQuc2hhcGVzO1xuXG4gICAgZm9yRWFjaChzaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG5cbiAgICAgIGZvckVhY2goc2hhcGUuYXR0YWNoZXJzLCBmdW5jdGlvbihhdHRhY2hlcikge1xuXG4gICAgICAgIC8vIHJlbW92ZSBpbnZhbGlkIG91dGdvaW5nIGNvbm5lY3Rpb25zXG4gICAgICAgIGZvckVhY2goYXR0YWNoZXIub3V0Z29pbmcuc2xpY2UoKSwgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgICAgIHZhciBhbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCB7XG4gICAgICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgICAgICAgICAgc291cmNlOiBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgICAgIHRhcmdldDogY29ubmVjdGlvbi50YXJnZXRcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmICghYWxsb3dlZCkge1xuICAgICAgICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihjb25uZWN0aW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIHJlbW92ZSBpbnZhbGlkIGluY29taW5nIGNvbm5lY3Rpb25zXG4gICAgICAgIGZvckVhY2goYXR0YWNoZXIuaW5jb21pbmcuc2xpY2UoKSwgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgICAgIHZhciBhbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCB7XG4gICAgICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgICAgICAgICAgc291cmNlOiBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgICAgIHRhcmdldDogY29ubmVjdGlvbi50YXJnZXRcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmICghYWxsb3dlZCkge1xuICAgICAgICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihjb25uZWN0aW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBob3N0ID0gY29udGV4dC5ob3N0O1xuXG4gICAgaWYgKGhvc3QpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZUF0dGFjaG1lbnQoc2hhcGUsIGhvc3QpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gdXBkYXRlIGF0dGFjaG1lbnRzIGlmIHRoZSBob3N0IGlzIHJlcGxhY2VkXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ3NoYXBlLnJlcGxhY2UnLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgb2xkU2hhcGUgPSBjb250ZXh0Lm9sZFNoYXBlLFxuICAgICAgICBuZXdTaGFwZSA9IGNvbnRleHQubmV3U2hhcGU7XG5cbiAgICAvLyBtb3ZlIHRoZSBhdHRhY2hlcnMgdG8gdGhlIG5ldyBob3N0XG4gICAgc2F2ZUNsZWFyKG9sZFNoYXBlLmF0dGFjaGVycywgZnVuY3Rpb24oYXR0YWNoZXIpIHtcbiAgICAgIHZhciBhbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMubW92ZScsIHtcbiAgICAgICAgdGFyZ2V0OiBuZXdTaGFwZSxcbiAgICAgICAgc2hhcGVzOiBbYXR0YWNoZXJdXG4gICAgICB9KTtcblxuICAgICAgaWYgKGFsbG93ZWQgPT09ICdhdHRhY2gnKSB7XG4gICAgICAgIG1vZGVsaW5nLnVwZGF0ZUF0dGFjaG1lbnQoYXR0YWNoZXIsIG5ld1NoYXBlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1vZGVsaW5nLnJlbW92ZVNoYXBlKGF0dGFjaGVyKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIG1vdmUgYXR0YWNoZXJzIGlmIG5ldyBob3N0IGhhcyBkaWZmZXJlbnQgc2l6ZVxuICAgIGlmIChuZXdTaGFwZS5hdHRhY2hlcnMubGVuZ3RoKSB7XG5cbiAgICAgIGZvckVhY2gobmV3U2hhcGUuYXR0YWNoZXJzLCBmdW5jdGlvbihhdHRhY2hlcikge1xuICAgICAgICB2YXIgZGVsdGEgPSBnZXROZXdBdHRhY2hTaGFwZURlbHRhKGF0dGFjaGVyLCBvbGRTaGFwZSwgbmV3U2hhcGUpO1xuICAgICAgICBtb2RlbGluZy5tb3ZlU2hhcGUoYXR0YWNoZXIsIGRlbHRhLCBhdHRhY2hlci5wYXJlbnQpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gIH0pO1xuXG4gIC8vIG1vdmUgc2hhcGUgb24gaG9zdCByZXNpemVcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUucmVzaXplJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgb2xkQm91bmRzID0gY29udGV4dC5vbGRCb3VuZHMsXG4gICAgICAgIG5ld0JvdW5kcyA9IGNvbnRleHQubmV3Qm91bmRzLFxuICAgICAgICBhdHRhY2hlcnMgPSBzaGFwZS5hdHRhY2hlcnMsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fTtcblxuICAgIGlmIChoaW50cy5hdHRhY2hTdXBwb3J0ID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvckVhY2goYXR0YWNoZXJzLCBmdW5jdGlvbihhdHRhY2hlcikge1xuICAgICAgdmFyIGRlbHRhID0gZ2V0TmV3QXR0YWNoU2hhcGVEZWx0YShhdHRhY2hlciwgb2xkQm91bmRzLCBuZXdCb3VuZHMpO1xuXG4gICAgICBtb2RlbGluZy5tb3ZlU2hhcGUoYXR0YWNoZXIsIGRlbHRhLCBhdHRhY2hlci5wYXJlbnQpO1xuXG4gICAgICBmb3JFYWNoKGF0dGFjaGVyLmxhYmVscywgZnVuY3Rpb24obGFiZWwpIHtcbiAgICAgICAgbW9kZWxpbmcubW92ZVNoYXBlKGxhYmVsLCBkZWx0YSwgbGFiZWwucGFyZW50KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyByZW1vdmUgYXR0YWNobWVudHNcbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5kZWxldGUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIHNoYXBlID0gZXZlbnQuY29udGV4dC5zaGFwZTtcblxuICAgIHNhdmVDbGVhcihzaGFwZS5hdHRhY2hlcnMsIGZ1bmN0aW9uKGF0dGFjaGVyKSB7XG4gICAgICBtb2RlbGluZy5yZW1vdmVTaGFwZShhdHRhY2hlcik7XG4gICAgfSk7XG5cbiAgICBpZiAoc2hhcGUuaG9zdCkge1xuICAgICAgbW9kZWxpbmcudXBkYXRlQXR0YWNobWVudChzaGFwZSwgbnVsbCk7XG4gICAgfVxuICB9KTtcbn1cblxuaW5oZXJpdHMoQXR0YWNoU3VwcG9ydCwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuQXR0YWNoU3VwcG9ydC4kaW5qZWN0ID0gW1xuICAnaW5qZWN0b3InLFxuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3J1bGVzJyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuXG4vKipcbiAqIFJldHVybiBhdHRhY2hlcnMgb2YgdGhlIGdpdmVuIHNoYXBlc1xuICpcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBzaGFwZXNcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn1cbiAqL1xuZnVuY3Rpb24gZ2V0QXR0YWNoZXJzKHNoYXBlcykge1xuICByZXR1cm4gZmxhdHRlbihtYXAoc2hhcGVzLCBmdW5jdGlvbihzKSB7XG4gICAgcmV0dXJuIHMuYXR0YWNoZXJzIHx8IFtdO1xuICB9KSk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgY29tYmluZWQgbGlzdCBvZiBlbGVtZW50cyBhbmRcbiAqIGF0dGFjaGVycy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHNcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZmlsdGVyZWRcbiAqL1xuZnVuY3Rpb24gYWRkQXR0YWNoZWQoZWxlbWVudHMpIHtcbiAgdmFyIGF0dGFjaGVycyA9IGdldEF0dGFjaGVycyhlbGVtZW50cyk7XG5cbiAgcmV0dXJuIHVuaW9uQnkoJ2lkJywgZWxlbWVudHMsIGF0dGFjaGVycyk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgZmlsdGVyZWQgbGlzdCBvZiBlbGVtZW50cyB0aGF0IGRvIG5vdFxuICogY29udGFpbiBhdHRhY2hlZCBlbGVtZW50cyB3aXRoIGhvc3RzIGJlaW5nIHBhcnRcbiAqIG9mIHRoZSBzZWxlY3Rpb24uXG4gKlxuICogQHBhcmFtICB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICpcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZmlsdGVyZWRcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlQXR0YWNoZWQoZWxlbWVudHMpIHtcblxuICB2YXIgaWRzID0gZ3JvdXBCeShlbGVtZW50cywgJ2lkJyk7XG5cbiAgcmV0dXJuIGZpbHRlcihlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHdoaWxlIChlbGVtZW50KSB7XG5cbiAgICAgIC8vIGhvc3QgaW4gc2VsZWN0aW9uXG4gICAgICBpZiAoZWxlbWVudC5ob3N0ICYmIGlkc1tlbGVtZW50Lmhvc3QuaWRdKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50O1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gaXNBdHRhY2hlcihzaGFwZSkge1xuICByZXR1cm4gISFzaGFwZS5ob3N0O1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlcyhhcnJheSwgaXRlbSkge1xuICByZXR1cm4gYXJyYXkuaW5kZXhPZihpdGVtKSAhPT0gLTE7XG59IiwiaW1wb3J0IFJ1bGVzTW9kdWxlIGZyb20gJy4uL3J1bGVzJztcblxuaW1wb3J0IEF0dGFjaFN1cHBvcnQgZnJvbSAnLi9BdHRhY2hTdXBwb3J0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIFJ1bGVzTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdhdHRhY2hTdXBwb3J0JyBdLFxuICBhdHRhY2hTdXBwb3J0OiBbICd0eXBlJywgQXR0YWNoU3VwcG9ydCBdXG59O1xuIiwiaW1wb3J0IHtcbiAgYXNUUkJMLFxuICBnZXRNaWRcbn0gZnJvbSAnLi4vLi4vbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQgeyBERUZBVUxUX0RJU1RBTkNFIH0gZnJvbSAnLi9BdXRvUGxhY2VVdGlsJztcblxudmFyIExPV19QUklPUklUWSA9IDEwMDtcblxuXG4vKipcbiAqIEEgc2VydmljZSB0aGF0IHBsYWNlcyBlbGVtZW50cyBjb25uZWN0ZWQgdG8gZXhpc3Rpbmcgb25lc1xuICogdG8gYW4gYXBwcm9wcmlhdGUgcG9zaXRpb24gaW4gYW4gX2F1dG9tYXRlZF8gZmFzaGlvbi5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1BsYWNlKGV2ZW50QnVzLCBtb2RlbGluZykge1xuXG4gIGV2ZW50QnVzLm9uKCdhdXRvUGxhY2UnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBzb3VyY2UgPSBjb250ZXh0LnNvdXJjZTtcblxuICAgIHJldHVybiBnZXROZXdTaGFwZVBvc2l0aW9uKHNvdXJjZSwgc2hhcGUpO1xuICB9KTtcblxuICAvKipcbiAgICogQXBwZW5kIHNoYXBlIHRvIHNvdXJjZSBhdCBhcHByb3ByaWF0ZSBwb3NpdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHNvdXJjZVxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAgICpcbiAgICogQHJldHVybiB7ZGpzLm1vZGVsLlNoYXBlfSBhcHBlbmRlZCBzaGFwZVxuICAgKi9cbiAgdGhpcy5hcHBlbmQgPSBmdW5jdGlvbihzb3VyY2UsIHNoYXBlLCBoaW50cykge1xuXG4gICAgZXZlbnRCdXMuZmlyZSgnYXV0b1BsYWNlLnN0YXJ0Jywge1xuICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICBzaGFwZTogc2hhcGVcbiAgICB9KTtcblxuICAgIC8vIGFsbG93IG90aGVycyB0byBwcm92aWRlIHRoZSBwb3NpdGlvblxuICAgIHZhciBwb3NpdGlvbiA9IGV2ZW50QnVzLmZpcmUoJ2F1dG9QbGFjZScsIHtcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgc2hhcGU6IHNoYXBlXG4gICAgfSk7XG5cbiAgICB2YXIgbmV3U2hhcGUgPSBtb2RlbGluZy5hcHBlbmRTaGFwZShzb3VyY2UsIHNoYXBlLCBwb3NpdGlvbiwgc291cmNlLnBhcmVudCwgaGludHMpO1xuXG4gICAgZXZlbnRCdXMuZmlyZSgnYXV0b1BsYWNlLmVuZCcsIHtcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgc2hhcGU6IG5ld1NoYXBlXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbmV3U2hhcGU7XG4gIH07XG5cbn1cblxuQXV0b1BsYWNlLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG4vKipcbiAqIEZpbmQgdGhlIG5ldyBwb3NpdGlvbiBmb3IgdGhlIHRhcmdldCBlbGVtZW50IHRvXG4gKiBjb25uZWN0IHRvIHNvdXJjZS5cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuU2hhcGV9IHNvdXJjZVxuICogQHBhcmFtICB7ZGpzLm1vZGVsLlNoYXBlfSBlbGVtZW50XG4gKiBAcGFyYW0gIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSAge09iamVjdH0gW2hpbnRzLmRlZmF1bHREaXN0YW5jZV1cbiAqXG4gKiBAcmV0dXJucyB7UG9pbnR9XG4gKi9cbmZ1bmN0aW9uIGdldE5ld1NoYXBlUG9zaXRpb24oc291cmNlLCBlbGVtZW50LCBoaW50cykge1xuICBpZiAoIWhpbnRzKSB7XG4gICAgaGludHMgPSB7fTtcbiAgfVxuXG4gIHZhciBkaXN0YW5jZSA9IGhpbnRzLmRlZmF1bHREaXN0YW5jZSB8fCBERUZBVUxUX0RJU1RBTkNFO1xuXG4gIHZhciBzb3VyY2VNaWQgPSBnZXRNaWQoc291cmNlKSxcbiAgICAgIHNvdXJjZVRyYmwgPSBhc1RSQkwoc291cmNlKTtcblxuICAvLyBzaW1wbHkgcHV0IGVsZW1lbnQgcmlnaHQgbmV4dCB0byBzb3VyY2VcbiAgcmV0dXJuIHtcbiAgICB4OiBzb3VyY2VUcmJsLnJpZ2h0ICsgZGlzdGFuY2UgKyBlbGVtZW50LndpZHRoIC8gMixcbiAgICB5OiBzb3VyY2VNaWQueVxuICB9O1xufSIsIi8qKlxuICogU2VsZWN0IGVsZW1lbnQgYWZ0ZXIgYXV0byBwbGFjZW1lbnQuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7U2VsZWN0aW9ufSBzZWxlY3Rpb25cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1BsYWNlU2VsZWN0aW9uQmVoYXZpb3IoZXZlbnRCdXMsIHNlbGVjdGlvbikge1xuXG4gIGV2ZW50QnVzLm9uKCdhdXRvUGxhY2UuZW5kJywgNTAwLCBmdW5jdGlvbihlKSB7XG4gICAgc2VsZWN0aW9uLnNlbGVjdChlLnNoYXBlKTtcbiAgfSk7XG5cbn1cblxuQXV0b1BsYWNlU2VsZWN0aW9uQmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ3NlbGVjdGlvbidcbl07IiwiaW1wb3J0IHtcbiAgYXNUUkJMLFxuICBnZXRPcmllbnRhdGlvbixcbiAgZ2V0TWlkXG59IGZyb20gJy4uLy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgZmluZCxcbiAgcmVkdWNlXG59IGZyb20gJ21pbi1kYXNoJztcblxuLy8gcGFkZGluZyB0byBkZXRlY3QgZWxlbWVudCBwbGFjZW1lbnRcbnZhciBQTEFDRU1FTlRfREVURUNUSU9OX1BBRCA9IDEwO1xuXG5leHBvcnQgdmFyIERFRkFVTFRfRElTVEFOQ0UgPSA1MDtcblxudmFyIERFRkFVTFRfTUFYX0RJU1RBTkNFID0gMjUwO1xuXG5cbi8qKlxuICogR2V0IGZyZWUgcG9zaXRpb24gc3RhcnRpbmcgZnJvbSBnaXZlbiBwb3NpdGlvbi5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc291cmNlXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gZWxlbWVudFxuICogQHBhcmFtIHtQb2ludH0gcG9zaXRpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGdldE5leHRQb3NpdGlvblxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZEZyZWVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQsIHBvc2l0aW9uLCBnZXROZXh0UG9zaXRpb24pIHtcbiAgdmFyIGNvbm5lY3RlZEF0UG9zaXRpb247XG5cbiAgd2hpbGUgKChjb25uZWN0ZWRBdFBvc2l0aW9uID0gZ2V0Q29ubmVjdGVkQXRQb3NpdGlvbihzb3VyY2UsIHBvc2l0aW9uLCBlbGVtZW50KSkpIHtcbiAgICBwb3NpdGlvbiA9IGdldE5leHRQb3NpdGlvbihlbGVtZW50LCBwb3NpdGlvbiwgY29ubmVjdGVkQXRQb3NpdGlvbik7XG4gIH1cblxuICByZXR1cm4gcG9zaXRpb247XG59XG5cbi8qKlxuICogUmV0dXJucyBmdW5jdGlvbiB0aGF0IHJldHVybnMgbmV4dCBwb3NpdGlvbi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbmV4dFBvc2l0aW9uRGlyZWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gW25leHRQb3NpdGlvbkRpcmVjdGlvbi54XVxuICogQHBhcmFtIHtPYmplY3R9IFtuZXh0UG9zaXRpb25EaXJlY3Rpb24ueV1cbiAqXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUdldE5leHRQb3NpdGlvbihuZXh0UG9zaXRpb25EaXJlY3Rpb24pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIHByZXZpb3VzUG9zaXRpb24sIGNvbm5lY3RlZEF0UG9zaXRpb24pIHtcbiAgICB2YXIgbmV4dFBvc2l0aW9uID0ge1xuICAgICAgeDogcHJldmlvdXNQb3NpdGlvbi54LFxuICAgICAgeTogcHJldmlvdXNQb3NpdGlvbi55XG4gICAgfTtcblxuICAgIFsgJ3gnLCAneScgXS5mb3JFYWNoKGZ1bmN0aW9uKGF4aXMpIHtcblxuICAgICAgdmFyIG5leHRQb3NpdGlvbkRpcmVjdGlvbkZvckF4aXMgPSBuZXh0UG9zaXRpb25EaXJlY3Rpb25bIGF4aXMgXTtcblxuICAgICAgaWYgKCFuZXh0UG9zaXRpb25EaXJlY3Rpb25Gb3JBeGlzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGRpbWVuc2lvbiA9IGF4aXMgPT09ICd4JyA/ICd3aWR0aCcgOiAnaGVpZ2h0JztcblxuICAgICAgdmFyIG1hcmdpbiA9IG5leHRQb3NpdGlvbkRpcmVjdGlvbkZvckF4aXMubWFyZ2luLFxuICAgICAgICAgIG1pbkRpc3RhbmNlID0gbmV4dFBvc2l0aW9uRGlyZWN0aW9uRm9yQXhpcy5taW5EaXN0YW5jZTtcblxuICAgICAgaWYgKG1hcmdpbiA8IDApIHtcbiAgICAgICAgbmV4dFBvc2l0aW9uWyBheGlzIF0gPSBNYXRoLm1pbihcbiAgICAgICAgICBjb25uZWN0ZWRBdFBvc2l0aW9uWyBheGlzIF0gKyBtYXJnaW4gLSBlbGVtZW50WyBkaW1lbnNpb24gXSAvIDIsXG4gICAgICAgICAgcHJldmlvdXNQb3NpdGlvblsgYXhpcyBdIC0gbWluRGlzdGFuY2UgKyBtYXJnaW5cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRQb3NpdGlvblsgYXhpcyBdID0gTWF0aC5tYXgoXG4gICAgICAgICAgY29ubmVjdGVkQXRQb3NpdGlvblsgYXhpcyBdICsgY29ubmVjdGVkQXRQb3NpdGlvblsgZGltZW5zaW9uIF0gKyBtYXJnaW4gKyBlbGVtZW50WyBkaW1lbnNpb24gXSAvIDIsXG4gICAgICAgICAgcHJldmlvdXNQb3NpdGlvblsgYXhpcyBdICsgbWluRGlzdGFuY2UgKyBtYXJnaW5cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBuZXh0UG9zaXRpb247XG4gIH07XG59XG5cbi8qKlxuICogUmV0dXJuIHRhcmdldCBhdCBnaXZlbiBwb3NpdGlvbiwgaWYgZGVmaW5lZC5cbiAqXG4gKiBUaGlzIHRha2VzIGNvbm5lY3RlZCBlbGVtZW50cyBmcm9tIGhvc3QgYW5kIGF0dGFjaGVyc1xuICogaW50byBhY2NvdW50LCB0b28uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb25uZWN0ZWRBdFBvc2l0aW9uKHNvdXJjZSwgcG9zaXRpb24sIGVsZW1lbnQpIHtcblxuICB2YXIgYm91bmRzID0ge1xuICAgIHg6IHBvc2l0aW9uLnggLSAoZWxlbWVudC53aWR0aCAvIDIpLFxuICAgIHk6IHBvc2l0aW9uLnkgLSAoZWxlbWVudC5oZWlnaHQgLyAyKSxcbiAgICB3aWR0aDogZWxlbWVudC53aWR0aCxcbiAgICBoZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0XG4gIH07XG5cbiAgdmFyIGNsb3N1cmUgPSBnZXRBdXRvUGxhY2VDbG9zdXJlKHNvdXJjZSwgZWxlbWVudCk7XG5cbiAgcmV0dXJuIGZpbmQoY2xvc3VyZSwgZnVuY3Rpb24odGFyZ2V0KSB7XG5cbiAgICBpZiAodGFyZ2V0ID09PSBlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIG9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24odGFyZ2V0LCBib3VuZHMsIFBMQUNFTUVOVF9ERVRFQ1RJT05fUEFEKTtcblxuICAgIHJldHVybiBvcmllbnRhdGlvbiA9PT0gJ2ludGVyc2VjdCc7XG4gIH0pO1xufVxuXG4vKipcbiogQ29tcHV0ZSBvcHRpbWFsIGRpc3RhbmNlIGJldHdlZW4gc291cmNlIGFuZCB0YXJnZXQgYmFzZWQgb24gZXhpc3RpbmcgY29ubmVjdGlvbnMgdG8gYW5kIGZyb20gc291cmNlLlxuKiBBc3N1bWVzIGxlZnQtdG8tcmlnaHQgYW5kIHRvcC10by1kb3duIG1vZGVsaW5nLlxuKlxuKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc291cmNlXG4qIEBwYXJhbSB7T2JqZWN0fSBbaGludHNdXG4qIEBwYXJhbSB7bnVtYmVyfSBbaGludHMuZGVmYXVsdERpc3RhbmNlXVxuKiBAcGFyYW0ge3N0cmluZ30gW2hpbnRzLmRpcmVjdGlvbl1cbiogQHBhcmFtIHtGdW5jdGlvbn0gW2hpbnRzLmZpbHRlcl1cbiogQHBhcmFtIHtGdW5jdGlvbn0gW2hpbnRzLmdldFdlaWdodF1cbiogQHBhcmFtIHtudW1iZXJ9IFtoaW50cy5tYXhEaXN0YW5jZV1cbiogQHBhcmFtIHtzdHJpbmd9IFtoaW50cy5yZWZlcmVuY2VdXG4qXG4qIEByZXR1cm4ge251bWJlcn1cbiovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29ubmVjdGVkRGlzdGFuY2Uoc291cmNlLCBoaW50cykge1xuICBpZiAoIWhpbnRzKSB7XG4gICAgaGludHMgPSB7fTtcbiAgfVxuXG4gIC8vIHRhcmdldHMgPiBzb3VyY2VzIGJ5IGRlZmF1bHRcbiAgZnVuY3Rpb24gZ2V0RGVmYXVsdFdlaWdodChjb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuIGNvbm5lY3Rpb24uc291cmNlID09PSBzb3VyY2UgPyAxIDogLTE7XG4gIH1cblxuICB2YXIgZGVmYXVsdERpc3RhbmNlID0gaGludHMuZGVmYXVsdERpc3RhbmNlIHx8IERFRkFVTFRfRElTVEFOQ0UsXG4gICAgICBkaXJlY3Rpb24gPSBoaW50cy5kaXJlY3Rpb24gfHwgJ2UnLFxuICAgICAgZmlsdGVyID0gaGludHMuZmlsdGVyLFxuICAgICAgZ2V0V2VpZ2h0ID0gaGludHMuZ2V0V2VpZ2h0IHx8IGdldERlZmF1bHRXZWlnaHQsXG4gICAgICBtYXhEaXN0YW5jZSA9IGhpbnRzLm1heERpc3RhbmNlIHx8IERFRkFVTFRfTUFYX0RJU1RBTkNFLFxuICAgICAgcmVmZXJlbmNlID0gaGludHMucmVmZXJlbmNlIHx8ICdzdGFydCc7XG5cbiAgaWYgKCFmaWx0ZXIpIHtcbiAgICBmaWx0ZXIgPSBub25lRmlsdGVyO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0RGlzdGFuY2UoYSwgYikge1xuICAgIGlmIChkaXJlY3Rpb24gPT09ICduJykge1xuICAgICAgaWYgKHJlZmVyZW5jZSA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICByZXR1cm4gYXNUUkJMKGEpLnRvcCAtIGFzVFJCTChiKS5ib3R0b207XG4gICAgICB9IGVsc2UgaWYgKHJlZmVyZW5jZSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgcmV0dXJuIGFzVFJCTChhKS50b3AgLSBnZXRNaWQoYikueTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhc1RSQkwoYSkudG9wIC0gYXNUUkJMKGIpLnRvcDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ3cnKSB7XG4gICAgICBpZiAocmVmZXJlbmNlID09PSAnc3RhcnQnKSB7XG4gICAgICAgIHJldHVybiBhc1RSQkwoYSkubGVmdCAtIGFzVFJCTChiKS5yaWdodDtcbiAgICAgIH0gZWxzZSBpZiAocmVmZXJlbmNlID09PSAnY2VudGVyJykge1xuICAgICAgICByZXR1cm4gYXNUUkJMKGEpLmxlZnQgLSBnZXRNaWQoYikueDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhc1RSQkwoYSkubGVmdCAtIGFzVFJCTChiKS5sZWZ0O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAncycpIHtcbiAgICAgIGlmIChyZWZlcmVuY2UgPT09ICdzdGFydCcpIHtcbiAgICAgICAgcmV0dXJuIGFzVFJCTChiKS50b3AgLSBhc1RSQkwoYSkuYm90dG9tO1xuICAgICAgfSBlbHNlIGlmIChyZWZlcmVuY2UgPT09ICdjZW50ZXInKSB7XG4gICAgICAgIHJldHVybiBnZXRNaWQoYikueSAtIGFzVFJCTChhKS5ib3R0b207XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gYXNUUkJMKGIpLmJvdHRvbSAtIGFzVFJCTChhKS5ib3R0b207XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChyZWZlcmVuY2UgPT09ICdzdGFydCcpIHtcbiAgICAgICAgcmV0dXJuIGFzVFJCTChiKS5sZWZ0IC0gYXNUUkJMKGEpLnJpZ2h0O1xuICAgICAgfSBlbHNlIGlmIChyZWZlcmVuY2UgPT09ICdjZW50ZXInKSB7XG4gICAgICAgIHJldHVybiBnZXRNaWQoYikueCAtIGFzVFJCTChhKS5yaWdodDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhc1RSQkwoYikucmlnaHQgLSBhc1RSQkwoYSkucmlnaHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHNvdXJjZXNEaXN0YW5jZXMgPSBzb3VyY2UuaW5jb21pbmdcbiAgICAuZmlsdGVyKGZpbHRlcilcbiAgICAubWFwKGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgIHZhciB3ZWlnaHQgPSBnZXRXZWlnaHQoY29ubmVjdGlvbik7XG5cbiAgICAgIHZhciBkaXN0YW5jZSA9IHdlaWdodCA8IDBcbiAgICAgICAgPyBnZXREaXN0YW5jZShjb25uZWN0aW9uLnNvdXJjZSwgc291cmNlKVxuICAgICAgICA6IGdldERpc3RhbmNlKHNvdXJjZSwgY29ubmVjdGlvbi5zb3VyY2UpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBpZDogY29ubmVjdGlvbi5zb3VyY2UuaWQsXG4gICAgICAgIGRpc3RhbmNlOiBkaXN0YW5jZSxcbiAgICAgICAgd2VpZ2h0OiB3ZWlnaHRcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgdmFyIHRhcmdldHNEaXN0YW5jZXMgPSBzb3VyY2Uub3V0Z29pbmdcbiAgICAuZmlsdGVyKGZpbHRlcilcbiAgICAubWFwKGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgIHZhciB3ZWlnaHQgPSBnZXRXZWlnaHQoY29ubmVjdGlvbik7XG5cbiAgICAgIHZhciBkaXN0YW5jZSA9IHdlaWdodCA+IDBcbiAgICAgICAgPyBnZXREaXN0YW5jZShzb3VyY2UsIGNvbm5lY3Rpb24udGFyZ2V0KVxuICAgICAgICA6IGdldERpc3RhbmNlKGNvbm5lY3Rpb24udGFyZ2V0LCBzb3VyY2UpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBpZDogY29ubmVjdGlvbi50YXJnZXQuaWQsXG4gICAgICAgIGRpc3RhbmNlOiBkaXN0YW5jZSxcbiAgICAgICAgd2VpZ2h0OiB3ZWlnaHRcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgdmFyIGRpc3RhbmNlcyA9IHNvdXJjZXNEaXN0YW5jZXMuY29uY2F0KHRhcmdldHNEaXN0YW5jZXMpLnJlZHVjZShmdW5jdGlvbihhY2N1bXVsYXRvciwgY3VycmVudFZhbHVlKSB7XG4gICAgYWNjdW11bGF0b3JbIGN1cnJlbnRWYWx1ZS5pZCArICdfX3dlaWdodF8nICsgY3VycmVudFZhbHVlLndlaWdodCBdID0gY3VycmVudFZhbHVlO1xuXG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9LCB7fSk7XG5cbiAgdmFyIGRpc3RhbmNlc0dyb3VwZWQgPSByZWR1Y2UoZGlzdGFuY2VzLCBmdW5jdGlvbihhY2N1bXVsYXRvciwgY3VycmVudFZhbHVlKSB7XG4gICAgdmFyIGRpc3RhbmNlID0gY3VycmVudFZhbHVlLmRpc3RhbmNlLFxuICAgICAgICB3ZWlnaHQgPSBjdXJyZW50VmFsdWUud2VpZ2h0O1xuXG4gICAgaWYgKGRpc3RhbmNlIDwgMCB8fCBkaXN0YW5jZSA+IG1heERpc3RhbmNlKSB7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgaWYgKCFhY2N1bXVsYXRvclsgU3RyaW5nKGRpc3RhbmNlKSBdKSB7XG4gICAgICBhY2N1bXVsYXRvclsgU3RyaW5nKGRpc3RhbmNlKSBdID0gMDtcbiAgICB9XG5cbiAgICBhY2N1bXVsYXRvclsgU3RyaW5nKGRpc3RhbmNlKSBdICs9IDEgKiB3ZWlnaHQ7XG5cbiAgICBpZiAoIWFjY3VtdWxhdG9yLmRpc3RhbmNlIHx8IGFjY3VtdWxhdG9yWyBhY2N1bXVsYXRvci5kaXN0YW5jZSBdIDwgYWNjdW11bGF0b3JbIFN0cmluZyhkaXN0YW5jZSkgXSkge1xuICAgICAgYWNjdW11bGF0b3IuZGlzdGFuY2UgPSBkaXN0YW5jZTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gIH0sIHt9KTtcblxuICByZXR1cm4gZGlzdGFuY2VzR3JvdXBlZC5kaXN0YW5jZSB8fCBkZWZhdWx0RGlzdGFuY2U7XG59XG5cbi8qKlxuICogUmV0dXJucyBhbGwgY29ubmVjdGVkIGVsZW1lbnRzIGFyb3VuZCB0aGUgZ2l2ZW4gc291cmNlLlxuICpcbiAqIFRoaXMgaW5jbHVkZXM6XG4gKlxuICogICAtIGNvbm5lY3RlZCBlbGVtZW50c1xuICogICAtIGhvc3QgY29ubmVjdGVkIGVsZW1lbnRzXG4gKiAgIC0gYXR0YWNoZXJzIGNvbm5lY3RlZCBlbGVtZW50c1xuICpcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5TaGFwZX0gc291cmNlXG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLlNoYXBlPn1cbiAqL1xuZnVuY3Rpb24gZ2V0QXV0b1BsYWNlQ2xvc3VyZShzb3VyY2UpIHtcblxuICB2YXIgYWxsQ29ubmVjdGVkID0gZ2V0Q29ubmVjdGVkKHNvdXJjZSk7XG5cbiAgaWYgKHNvdXJjZS5ob3N0KSB7XG4gICAgYWxsQ29ubmVjdGVkID0gYWxsQ29ubmVjdGVkLmNvbmNhdChnZXRDb25uZWN0ZWQoc291cmNlLmhvc3QpKTtcbiAgfVxuXG4gIGlmIChzb3VyY2UuYXR0YWNoZXJzKSB7XG4gICAgYWxsQ29ubmVjdGVkID0gYWxsQ29ubmVjdGVkLmNvbmNhdChzb3VyY2UuYXR0YWNoZXJzLnJlZHVjZShmdW5jdGlvbihzaGFwZXMsIGF0dGFjaGVyKSB7XG4gICAgICByZXR1cm4gc2hhcGVzLmNvbmNhdChnZXRDb25uZWN0ZWQoYXR0YWNoZXIpKTtcbiAgICB9LCBbXSkpO1xuICB9XG5cbiAgcmV0dXJuIGFsbENvbm5lY3RlZDtcbn1cblxuZnVuY3Rpb24gZ2V0Q29ubmVjdGVkKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFRhcmdldHMoZWxlbWVudCkuY29uY2F0KGdldFNvdXJjZXMoZWxlbWVudCkpO1xufVxuXG5mdW5jdGlvbiBnZXRTb3VyY2VzKHNoYXBlKSB7XG4gIHJldHVybiBzaGFwZS5pbmNvbWluZy5tYXAoZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgIHJldHVybiBjb25uZWN0aW9uLnNvdXJjZTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFRhcmdldHMoc2hhcGUpIHtcbiAgcmV0dXJuIHNoYXBlLm91dGdvaW5nLm1hcChmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuIGNvbm5lY3Rpb24udGFyZ2V0O1xuICB9KTtcbn1cblxuZnVuY3Rpb24gbm9uZUZpbHRlcigpIHtcbiAgcmV0dXJuIHRydWU7XG59XG4iLCJpbXBvcnQgQXV0b1BsYWNlIGZyb20gJy4vQXV0b1BsYWNlJztcbmltcG9ydCBBdXRvUGxhY2VTZWxlY3Rpb25CZWhhdmlvciBmcm9tICcuL0F1dG9QbGFjZVNlbGVjdGlvbkJlaGF2aW9yJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnYXV0b1BsYWNlU2VsZWN0aW9uQmVoYXZpb3InIF0sXG4gIGF1dG9QbGFjZTogWyAndHlwZScsIEF1dG9QbGFjZSBdLFxuICBhdXRvUGxhY2VTZWxlY3Rpb25CZWhhdmlvcjogWyAndHlwZScsIEF1dG9QbGFjZVNlbGVjdGlvbkJlaGF2aW9yIF1cbn07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHsgZ2V0QkJveCBhcyBnZXRCb3VuZGluZ0JveCB9IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG5pbXBvcnQge1xuICBhc1RSQkwsXG4gIGFzQm91bmRzXG59IGZyb20gJy4uLy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmbGF0dGVuLFxuICBmaW5kLFxuICBmb3JFYWNoLFxuICBncm91cEJ5LFxuICBpc0FycmF5LFxuICBtYXRjaFBhdHRlcm4sXG4gIHBpY2ssXG4gIHZhbHVlc1xufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnLi4vLi4vY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5cbi8qKlxuICogQW4gYXV0byByZXNpemUgY29tcG9uZW50IHRoYXQgdGFrZXMgY2FyZSBvZiBleHBhbmRpbmcgYSBwYXJlbnQgZWxlbWVudFxuICogaWYgY2hpbGQgZWxlbWVudHMgYXJlIGNyZWF0ZWQgb3IgbW92ZWQgY2xvc2UgdGhlIHBhcmVudHMgZWRnZS5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtFbGVtZW50UmVnaXN0cnl9IGVsZW1lbnRSZWdpc3RyeVxuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEF1dG9SZXNpemUoZXZlbnRCdXMsIGVsZW1lbnRSZWdpc3RyeSwgbW9kZWxpbmcsIHJ1bGVzKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fcnVsZXMgPSBydWxlcztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoWyAnc2hhcGUuY3JlYXRlJyBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50IHx8IGNvbnRleHQubmV3UGFyZW50O1xuXG4gICAgaWYgKGhpbnRzLmF1dG9SZXNpemUgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc2VsZi5fZXhwYW5kKFsgc2hhcGUgXSwgcGFyZW50KTtcbiAgfSk7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoWyAnZWxlbWVudHMubW92ZScgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnRzID0gZmxhdHRlbih2YWx1ZXMoY29udGV4dC5jbG9zdXJlLnRvcExldmVsKSksXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cztcblxuICAgIHZhciBhdXRvUmVzaXplID0gaGludHMgPyBoaW50cy5hdXRvUmVzaXplIDogdHJ1ZTtcblxuICAgIGlmIChhdXRvUmVzaXplID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBleHBhbmRpbmdzID0gZ3JvdXBCeShlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQucGFyZW50LmlkO1xuICAgIH0pO1xuXG4gICAgZm9yRWFjaChleHBhbmRpbmdzLCBmdW5jdGlvbihlbGVtZW50cywgcGFyZW50SWQpIHtcblxuICAgICAgLy8gb3B0aW9uYWxseSBmaWx0ZXIgZWxlbWVudHMgdG8gYmUgY29uc2lkZXJlZCB3aGVuIHJlc2l6aW5nXG4gICAgICBpZiAoaXNBcnJheShhdXRvUmVzaXplKSkge1xuICAgICAgICBlbGVtZW50cyA9IGVsZW1lbnRzLmZpbHRlcihmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGZpbmQoYXV0b1Jlc2l6ZSwgbWF0Y2hQYXR0ZXJuKHsgaWQ6IGVsZW1lbnQuaWQgfSkpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgc2VsZi5fZXhwYW5kKGVsZW1lbnRzLCBwYXJlbnRJZCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKFsgJ3NoYXBlLnRvZ2dsZUNvbGxhcHNlJyBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzLFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaGludHMgJiYgaGludHMuYXV0b1Jlc2l6ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoc2hhcGUuY29sbGFwc2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc2VsZi5fZXhwYW5kKHNoYXBlLmNoaWxkcmVuIHx8IFtdLCBzaGFwZSk7XG4gIH0pO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKFsgJ3NoYXBlLnJlc2l6ZScgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBwYXJlbnQgPSBzaGFwZS5wYXJlbnQ7XG5cbiAgICBpZiAoaGludHMgJiYgaGludHMuYXV0b1Jlc2l6ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFyZW50KSB7XG4gICAgICBzZWxmLl9leHBhbmQoWyBzaGFwZSBdLCBwYXJlbnQpO1xuICAgIH1cbiAgfSk7XG5cbn1cblxuQXV0b1Jlc2l6ZS4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ21vZGVsaW5nJyxcbiAgJ3J1bGVzJ1xuXTtcblxuaW5oZXJpdHMoQXV0b1Jlc2l6ZSwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgbmV3IGJvdW5kcyBvZiB0aGUgdGFyZ2V0IHNoYXBlLCBnaXZlblxuICogYSBudW1iZXIgb2YgZWxlbWVudHMgaGF2ZSBiZWVuIG1vdmVkIG9yIGFkZGVkIGludG8gdGhlIHBhcmVudC5cbiAqXG4gKiBUaGlzIG1ldGhvZCBjb25zaWRlcnMgdGhlIGN1cnJlbnQgc2l6ZSwgdGhlIGFkZGVkIGVsZW1lbnRzIGFzIHdlbGwgYXNcbiAqIHRoZSBwcm92aWRlZCBwYWRkaW5nIGZvciB0aGUgbmV3IGJvdW5kcy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gdGFyZ2V0XG4gKi9cbkF1dG9SZXNpemUucHJvdG90eXBlLl9nZXRPcHRpbWFsQm91bmRzID0gZnVuY3Rpb24oZWxlbWVudHMsIHRhcmdldCkge1xuXG4gIHZhciBvZmZzZXQgPSB0aGlzLmdldE9mZnNldCh0YXJnZXQpLFxuICAgICAgcGFkZGluZyA9IHRoaXMuZ2V0UGFkZGluZyh0YXJnZXQpO1xuXG4gIHZhciBlbGVtZW50c1RyYmwgPSBhc1RSQkwoZ2V0Qm91bmRpbmdCb3goZWxlbWVudHMpKSxcbiAgICAgIHRhcmdldFRyYmwgPSBhc1RSQkwodGFyZ2V0KTtcblxuICB2YXIgbmV3VHJibCA9IHt9O1xuXG4gIGlmIChlbGVtZW50c1RyYmwudG9wIC0gdGFyZ2V0VHJibC50b3AgPCBwYWRkaW5nLnRvcCkge1xuICAgIG5ld1RyYmwudG9wID0gZWxlbWVudHNUcmJsLnRvcCAtIG9mZnNldC50b3A7XG4gIH1cblxuICBpZiAoZWxlbWVudHNUcmJsLmxlZnQgLSB0YXJnZXRUcmJsLmxlZnQgPCBwYWRkaW5nLmxlZnQpIHtcbiAgICBuZXdUcmJsLmxlZnQgPSBlbGVtZW50c1RyYmwubGVmdCAtIG9mZnNldC5sZWZ0O1xuICB9XG5cbiAgaWYgKHRhcmdldFRyYmwucmlnaHQgLSBlbGVtZW50c1RyYmwucmlnaHQgPCBwYWRkaW5nLnJpZ2h0KSB7XG4gICAgbmV3VHJibC5yaWdodCA9IGVsZW1lbnRzVHJibC5yaWdodCArIG9mZnNldC5yaWdodDtcbiAgfVxuXG4gIGlmICh0YXJnZXRUcmJsLmJvdHRvbSAtIGVsZW1lbnRzVHJibC5ib3R0b20gPCBwYWRkaW5nLmJvdHRvbSkge1xuICAgIG5ld1RyYmwuYm90dG9tID0gZWxlbWVudHNUcmJsLmJvdHRvbSArIG9mZnNldC5ib3R0b207XG4gIH1cblxuICByZXR1cm4gYXNCb3VuZHMoYXNzaWduKHt9LCB0YXJnZXRUcmJsLCBuZXdUcmJsKSk7XG59O1xuXG5cbi8qKlxuICogRXhwYW5kIHRoZSB0YXJnZXQgc2hhcGUgcmVzcGVjdGluZyBydWxlcywgb2Zmc2V0IGFuZCBwYWRkaW5nXG4gKlxuICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuU2hhcGU+fSBlbGVtZW50c1xuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV8c3RyaW5nfSB0YXJnZXR8dGFyZ2V0SWRcbiAqL1xuQXV0b1Jlc2l6ZS5wcm90b3R5cGUuX2V4cGFuZCA9IGZ1bmN0aW9uKGVsZW1lbnRzLCB0YXJnZXQpIHtcblxuICBpZiAodHlwZW9mIHRhcmdldCA9PT0gJ3N0cmluZycpIHtcbiAgICB0YXJnZXQgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0KHRhcmdldCk7XG4gIH1cblxuICB2YXIgYWxsb3dlZCA9IHRoaXMuX3J1bGVzLmFsbG93ZWQoJ2VsZW1lbnQuYXV0b1Jlc2l6ZScsIHtcbiAgICBlbGVtZW50czogZWxlbWVudHMsXG4gICAgdGFyZ2V0OiB0YXJnZXRcbiAgfSk7XG5cbiAgaWYgKCFhbGxvd2VkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gY2FsY3VsYXRlIHRoZSBuZXcgYm91bmRzXG4gIHZhciBuZXdCb3VuZHMgPSB0aGlzLl9nZXRPcHRpbWFsQm91bmRzKGVsZW1lbnRzLCB0YXJnZXQpO1xuXG4gIGlmICghYm91bmRzQ2hhbmdlZChuZXdCb3VuZHMsIHRhcmdldCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcmVzaXplRGlyZWN0aW9ucyA9IGdldFJlc2l6ZURpcmVjdGlvbnMocGljayh0YXJnZXQsIFsgJ3gnLCAneScsICd3aWR0aCcsICdoZWlnaHQnIF0pLCBuZXdCb3VuZHMpO1xuXG4gIC8vIHJlc2l6ZSB0aGUgcGFyZW50IHNoYXBlXG4gIHRoaXMucmVzaXplKHRhcmdldCwgbmV3Qm91bmRzLCB7XG4gICAgYXV0b1Jlc2l6ZTogcmVzaXplRGlyZWN0aW9uc1xuICB9KTtcblxuICB2YXIgcGFyZW50ID0gdGFyZ2V0LnBhcmVudDtcblxuICAvLyByZWN1cnNpdmVseSBleHBhbmQgcGFyZW50IGVsZW1lbnRzXG4gIGlmIChwYXJlbnQpIHtcbiAgICB0aGlzLl9leHBhbmQoWyB0YXJnZXQgXSwgcGFyZW50KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEdldCB0aGUgYW1vdW50IHRvIGV4cGFuZCB0aGUgZ2l2ZW4gc2hhcGUgaW4gZWFjaCBkaXJlY3Rpb24uXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHNoYXBlXG4gKlxuICogQHJldHVybiB7VFJCTH1cbiAqL1xuQXV0b1Jlc2l6ZS5wcm90b3R5cGUuZ2V0T2Zmc2V0ID0gZnVuY3Rpb24oc2hhcGUpIHtcbiAgcmV0dXJuIHsgdG9wOiA2MCwgYm90dG9tOiA2MCwgbGVmdDogMTAwLCByaWdodDogMTAwIH07XG59O1xuXG5cbi8qKlxuICogR2V0IHRoZSBhY3RpdmF0aW9uIHRocmVzaG9sZCBmb3IgZWFjaCBzaWRlIGZvciB3aGljaFxuICogcmVzaXplIHRyaWdnZXJzLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICpcbiAqIEByZXR1cm4ge1RSQkx9XG4gKi9cbkF1dG9SZXNpemUucHJvdG90eXBlLmdldFBhZGRpbmcgPSBmdW5jdGlvbihzaGFwZSkge1xuICByZXR1cm4geyB0b3A6IDIsIGJvdHRvbTogMiwgbGVmdDogMTUsIHJpZ2h0OiAxNSB9O1xufTtcblxuXG4vKipcbiAqIFBlcmZvcm0gdGhlIGFjdHVhbCByZXNpemUgb3BlcmF0aW9uLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICogQHBhcmFtIHtCb3VuZHN9IG5ld0JvdW5kc1xuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7c3RyaW5nfSBbaGludHMuYXV0b1Jlc2l6ZV1cbiAqL1xuQXV0b1Jlc2l6ZS5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24oc2hhcGUsIG5ld0JvdW5kcywgaGludHMpIHtcbiAgdGhpcy5fbW9kZWxpbmcucmVzaXplU2hhcGUoc2hhcGUsIG5ld0JvdW5kcywgbnVsbCwgaGludHMpO1xufTtcblxuXG5mdW5jdGlvbiBib3VuZHNDaGFuZ2VkKG5ld0JvdW5kcywgb2xkQm91bmRzKSB7XG4gIHJldHVybiAoXG4gICAgbmV3Qm91bmRzLnggIT09IG9sZEJvdW5kcy54IHx8XG4gICAgbmV3Qm91bmRzLnkgIT09IG9sZEJvdW5kcy55IHx8XG4gICAgbmV3Qm91bmRzLndpZHRoICE9PSBvbGRCb3VuZHMud2lkdGggfHxcbiAgICBuZXdCb3VuZHMuaGVpZ2h0ICE9PSBvbGRCb3VuZHMuaGVpZ2h0XG4gICk7XG59XG5cbi8qKlxuICogR2V0IGRpcmVjdGlvbnMgb2YgcmVzaXplIGFzIHtufHd8c3xlfSBlLmcuIFwibndcIi5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc30gb2xkQm91bmRzXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gUmVzaXplIGRpcmVjdGlvbnMgYXMge258d3xzfGV9LlxuICovXG5mdW5jdGlvbiBnZXRSZXNpemVEaXJlY3Rpb25zKG9sZEJvdW5kcywgbmV3Qm91bmRzKSB7XG4gIHZhciBkaXJlY3Rpb25zID0gJyc7XG5cbiAgb2xkQm91bmRzID0gYXNUUkJMKG9sZEJvdW5kcyk7XG4gIG5ld0JvdW5kcyA9IGFzVFJCTChuZXdCb3VuZHMpO1xuXG4gIGlmIChvbGRCb3VuZHMudG9wID4gbmV3Qm91bmRzLnRvcCkge1xuICAgIGRpcmVjdGlvbnMgPSBkaXJlY3Rpb25zLmNvbmNhdCgnbicpO1xuICB9XG5cbiAgaWYgKG9sZEJvdW5kcy5yaWdodCA8IG5ld0JvdW5kcy5yaWdodCkge1xuICAgIGRpcmVjdGlvbnMgPSBkaXJlY3Rpb25zLmNvbmNhdCgndycpO1xuICB9XG5cbiAgaWYgKG9sZEJvdW5kcy5ib3R0b20gPCBuZXdCb3VuZHMuYm90dG9tKSB7XG4gICAgZGlyZWN0aW9ucyA9IGRpcmVjdGlvbnMuY29uY2F0KCdzJyk7XG4gIH1cblxuICBpZiAob2xkQm91bmRzLmxlZnQgPiBuZXdCb3VuZHMubGVmdCkge1xuICAgIGRpcmVjdGlvbnMgPSBkaXJlY3Rpb25zLmNvbmNhdCgnZScpO1xuICB9XG5cbiAgcmV0dXJuIGRpcmVjdGlvbnM7XG59IiwiaW1wb3J0IFJ1bGVQcm92aWRlciBmcm9tICcuLi9ydWxlcy9SdWxlUHJvdmlkZXInO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG4vKipcbiAqIFRoaXMgaXMgYSBiYXNlIHJ1bGUgcHJvdmlkZXIgZm9yIHRoZSBlbGVtZW50LmF1dG9SZXNpemUgcnVsZS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1Jlc2l6ZVByb3ZpZGVyKGV2ZW50QnVzKSB7XG5cbiAgUnVsZVByb3ZpZGVyLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLmFkZFJ1bGUoJ2VsZW1lbnQuYXV0b1Jlc2l6ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICByZXR1cm4gc2VsZi5jYW5SZXNpemUoY29udGV4dC5lbGVtZW50cywgY29udGV4dC50YXJnZXQpO1xuICB9KTtcbn1cblxuQXV0b1Jlc2l6ZVByb3ZpZGVyLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTtcblxuaW5oZXJpdHMoQXV0b1Jlc2l6ZVByb3ZpZGVyLCBSdWxlUHJvdmlkZXIpO1xuXG4vKipcbiAqIE5lZWRzIHRvIGJlIGltcGxlbWVudGVkIGJ5IHN1YiBjbGFzc2VzIHRvIGFsbG93IGFjdHVhbCBhdXRvIHJlc2l6ZVxuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuU2hhcGV9IHRhcmdldFxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbkF1dG9SZXNpemVQcm92aWRlci5wcm90b3R5cGUuY2FuUmVzaXplID0gZnVuY3Rpb24oZWxlbWVudHMsIHRhcmdldCkge1xuICByZXR1cm4gZmFsc2U7XG59OyIsImltcG9ydCB7IGFzc2lnbiB9IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgdG9Qb2ludFxufSBmcm9tICcuLi8uLi91dGlsL0V2ZW50JztcblxuXG4vKipcbiAqIEluaXRpYXRlcyBjYW52YXMgc2Nyb2xsaW5nIGlmIGN1cnJlbnQgY3Vyc29yIHBvaW50IGlzIGNsb3NlIHRvIGEgYm9yZGVyLlxuICogQ2FuY2VsbGVkIHdoZW4gY3VycmVudCBwb2ludCBtb3ZlcyBiYWNrIGluc2lkZSB0aGUgc2Nyb2xsaW5nIGJvcmRlcnNcbiAqIG9yIGNhbmNlbGxlZCBtYW51YWxseS5cbiAqXG4gKiBEZWZhdWx0IG9wdGlvbnMgOlxuICogICBzY3JvbGxUaHJlc2hvbGRJbjogWyAyMCwgMjAsIDIwLCAyMCBdLFxuICogICBzY3JvbGxUaHJlc2hvbGRPdXQ6IFsgMCwgMCwgMCwgMCBdLFxuICogICBzY3JvbGxSZXBlYXRUaW1lb3V0OiAxNSxcbiAqICAgc2Nyb2xsU3RlcDogMTBcbiAqXG4gKiBUaHJlc2hvbGQgb3JkZXI6XG4gKiAgIFsgbGVmdCwgdG9wLCByaWdodCwgYm90dG9tIF1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1Njcm9sbChjb25maWcsIGV2ZW50QnVzLCBjYW52YXMpIHtcblxuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG5cbiAgdGhpcy5fb3B0cyA9IGFzc2lnbih7XG4gICAgc2Nyb2xsVGhyZXNob2xkSW46IFsgMjAsIDIwLCAyMCwgMjAgXSxcbiAgICBzY3JvbGxUaHJlc2hvbGRPdXQ6IFsgMCwgMCwgMCwgMCBdLFxuICAgIHNjcm9sbFJlcGVhdFRpbWVvdXQ6IDE1LFxuICAgIHNjcm9sbFN0ZXA6IDEwXG4gIH0sIGNvbmZpZyk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGV2ZW50QnVzLm9uKCdkcmFnLm1vdmUnLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIHBvaW50ID0gc2VsZi5fdG9Cb3JkZXJQb2ludChlKTtcblxuICAgIHNlbGYuc3RhcnRTY3JvbGwocG9pbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdkcmFnLmNsZWFudXAnIF0sIGZ1bmN0aW9uKCkge1xuICAgIHNlbGYuc3RvcFNjcm9sbCgpO1xuICB9KTtcbn1cblxuQXV0b1Njcm9sbC4kaW5qZWN0ID0gW1xuICAnY29uZmlnLmF1dG9TY3JvbGwnLFxuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJ1xuXTtcblxuXG4vKipcbiAqIFN0YXJ0cyBzY3JvbGxpbmcgbG9vcC5cbiAqIFBvaW50IGlzIGdpdmVuIGluIGdsb2JhbCBzY2FsZSBpbiBjYW52YXMgY29udGFpbmVyIGJveCBwbGFuZS5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IHBvaW50IHsgeDogWCwgeTogWSB9XG4gKi9cbkF1dG9TY3JvbGwucHJvdG90eXBlLnN0YXJ0U2Nyb2xsID0gZnVuY3Rpb24ocG9pbnQpIHtcblxuICB2YXIgY2FudmFzID0gdGhpcy5fY2FudmFzO1xuICB2YXIgb3B0cyA9IHRoaXMuX29wdHM7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgY2xpZW50UmVjdCA9IGNhbnZhcy5nZXRDb250YWluZXIoKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICB2YXIgZGlmZiA9IFtcbiAgICBwb2ludC54LFxuICAgIHBvaW50LnksXG4gICAgY2xpZW50UmVjdC53aWR0aCAtIHBvaW50LngsXG4gICAgY2xpZW50UmVjdC5oZWlnaHQgLSBwb2ludC55XG4gIF07XG5cbiAgdGhpcy5zdG9wU2Nyb2xsKCk7XG5cbiAgdmFyIGR4ID0gMCxcbiAgICAgIGR5ID0gMDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIGlmIChiZXR3ZWVuKGRpZmZbaV0sIG9wdHMuc2Nyb2xsVGhyZXNob2xkT3V0W2ldLCBvcHRzLnNjcm9sbFRocmVzaG9sZEluW2ldKSkge1xuICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgZHggPSBvcHRzLnNjcm9sbFN0ZXA7XG4gICAgICB9IGVsc2UgaWYgKGkgPT0gMSkge1xuICAgICAgICBkeSA9IG9wdHMuc2Nyb2xsU3RlcDtcbiAgICAgIH0gZWxzZSBpZiAoaSA9PSAyKSB7XG4gICAgICAgIGR4ID0gLW9wdHMuc2Nyb2xsU3RlcDtcbiAgICAgIH0gZWxzZSBpZiAoaSA9PSAzKSB7XG4gICAgICAgIGR5ID0gLW9wdHMuc2Nyb2xsU3RlcDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoZHggIT09IDAgfHwgZHkgIT09IDApIHtcbiAgICBjYW52YXMuc2Nyb2xsKHsgZHg6IGR4LCBkeTogZHkgfSk7XG5cbiAgICB0aGlzLl9zY3JvbGxpbmcgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgc2VsZi5zdGFydFNjcm9sbChwb2ludCk7XG4gICAgfSwgb3B0cy5zY3JvbGxSZXBlYXRUaW1lb3V0KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYmV0d2Vlbih2YWwsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0IDwgdmFsICYmIHZhbCA8IGVuZCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5cbi8qKlxuICogU3RvcHMgc2Nyb2xsaW5nIGxvb3AuXG4gKi9cbkF1dG9TY3JvbGwucHJvdG90eXBlLnN0b3BTY3JvbGwgPSBmdW5jdGlvbigpIHtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3Njcm9sbGluZyk7XG59O1xuXG5cbi8qKlxuICogT3ZlcnJpZGVzIGRlZmF1bHRzIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gKi9cbkF1dG9TY3JvbGwucHJvdG90eXBlLnNldE9wdGlvbnMgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gIHRoaXMuX29wdHMgPSBhc3NpZ24oe30sIHRoaXMuX29wdHMsIG9wdGlvbnMpO1xufTtcblxuXG4vKipcbiAqIENvbnZlcnRzIGV2ZW50IHRvIGEgcG9pbnQgaW4gY2FudmFzIGNvbnRhaW5lciBwbGFuZSBpbiBnbG9iYWwgc2NhbGUuXG4gKlxuICogQHBhcmFtICB7RXZlbnR9IGV2ZW50XG4gKiBAcmV0dXJuIHtQb2ludH1cbiAqL1xuQXV0b1Njcm9sbC5wcm90b3R5cGUuX3RvQm9yZGVyUG9pbnQgPSBmdW5jdGlvbihldmVudCkge1xuICB2YXIgY2xpZW50UmVjdCA9IHRoaXMuX2NhbnZhcy5fY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gIHZhciBnbG9iYWxQb3NpdGlvbiA9IHRvUG9pbnQoZXZlbnQub3JpZ2luYWxFdmVudCk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBnbG9iYWxQb3NpdGlvbi54IC0gY2xpZW50UmVjdC5sZWZ0LFxuICAgIHk6IGdsb2JhbFBvc2l0aW9uLnkgLSBjbGllbnRSZWN0LnRvcFxuICB9O1xufTsiLCJpbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuXG5pbXBvcnQgQXV0b1Njcm9sbCBmcm9tICcuL0F1dG9TY3JvbGwnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBEcmFnZ2luZ01vZHVsZSxcbiAgXSxcbiAgX19pbml0X186IFsgJ2F1dG9TY3JvbGwnIF0sXG4gIGF1dG9TY3JvbGw6IFsgJ3R5cGUnLCBBdXRvU2Nyb2xsIF1cbn07IiwiaW1wb3J0IHsgZmlsdGVyUmVkdW5kYW50V2F5cG9pbnRzIH0gZnJvbSAnLi4vLi4vbGF5b3V0L0xheW91dFV0aWwnO1xuXG52YXIgcm91bmQgPSBNYXRoLnJvdW5kO1xuXG52YXIgUkVDT05ORUNUX1NUQVJUID0gJ3JlY29ubmVjdFN0YXJ0JyxcbiAgICBSRUNPTk5FQ1RfRU5EID0gJ3JlY29ubmVjdEVuZCcsXG4gICAgVVBEQVRFX1dBWVBPSU5UUyA9ICd1cGRhdGVXYXlwb2ludHMnO1xuXG5cbi8qKlxuICogTW92ZSBiZW5kcG9pbnRzIHRocm91Z2ggZHJhZyBhbmQgZHJvcCB0byBhZGQvcmVtb3ZlIGJlbmRwb2ludHMgb3IgcmVjb25uZWN0IGNvbm5lY3Rpb24uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJlbmRwb2ludE1vdmUoaW5qZWN0b3IsIGV2ZW50QnVzLCBjYW52YXMsIGRyYWdnaW5nLCBydWxlcywgbW9kZWxpbmcpIHtcbiAgdGhpcy5faW5qZWN0b3IgPSBpbmplY3RvcjtcblxuICB0aGlzLnN0YXJ0ID0gZnVuY3Rpb24oZXZlbnQsIGNvbm5lY3Rpb24sIGJlbmRwb2ludEluZGV4LCBpbnNlcnQpIHtcbiAgICB2YXIgZ2Z4ID0gY2FudmFzLmdldEdyYXBoaWNzKGNvbm5lY3Rpb24pLFxuICAgICAgICBzb3VyY2UgPSBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIHdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzLFxuICAgICAgICB0eXBlO1xuXG4gICAgaWYgKCFpbnNlcnQgJiYgYmVuZHBvaW50SW5kZXggPT09IDApIHtcbiAgICAgIHR5cGUgPSBSRUNPTk5FQ1RfU1RBUlQ7XG4gICAgfSBlbHNlXG4gICAgaWYgKCFpbnNlcnQgJiYgYmVuZHBvaW50SW5kZXggPT09IHdheXBvaW50cy5sZW5ndGggLSAxKSB7XG4gICAgICB0eXBlID0gUkVDT05ORUNUX0VORDtcbiAgICB9IGVsc2Uge1xuICAgICAgdHlwZSA9IFVQREFURV9XQVlQT0lOVFM7XG4gICAgfVxuXG4gICAgdmFyIGNvbW1hbmQgPSB0eXBlID09PSBVUERBVEVfV0FZUE9JTlRTID8gJ2Nvbm5lY3Rpb24udXBkYXRlV2F5cG9pbnRzJyA6ICdjb25uZWN0aW9uLnJlY29ubmVjdCc7XG5cbiAgICB2YXIgYWxsb3dlZCA9IHJ1bGVzLmFsbG93ZWQoY29tbWFuZCwge1xuICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICB9KTtcblxuICAgIGlmIChhbGxvd2VkID09PSBmYWxzZSkge1xuICAgICAgYWxsb3dlZCA9IHJ1bGVzLmFsbG93ZWQoY29tbWFuZCwge1xuICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgICAgICBzb3VyY2U6IHRhcmdldCxcbiAgICAgICAgdGFyZ2V0OiBzb3VyY2VcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChhbGxvd2VkID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRyYWdnaW5nLmluaXQoZXZlbnQsICdiZW5kcG9pbnQubW92ZScsIHtcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgICAgY29ubmVjdGlvbkdmeDogZ2Z4LFxuICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgYWxsb3dlZDogYWxsb3dlZCxcbiAgICAgICAgICBiZW5kcG9pbnRJbmRleDogYmVuZHBvaW50SW5kZXgsXG4gICAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgICAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICAgICAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICAgICAgICBpbnNlcnQ6IGluc2VydCxcbiAgICAgICAgICB0eXBlOiB0eXBlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICBldmVudEJ1cy5vbignYmVuZHBvaW50Lm1vdmUuaG92ZXInLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0LFxuICAgICAgICBob3ZlciA9IGV2ZW50LmhvdmVyLFxuICAgICAgICB0eXBlID0gY29udGV4dC50eXBlO1xuXG4gICAgLy8gY2FjaGUgaG92ZXIgc3RhdGVcbiAgICBjb250ZXh0LmhvdmVyID0gaG92ZXI7XG5cbiAgICB2YXIgYWxsb3dlZDtcblxuICAgIGlmICghaG92ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY29tbWFuZCA9IHR5cGUgPT09IFVQREFURV9XQVlQT0lOVFMgPyAnY29ubmVjdGlvbi51cGRhdGVXYXlwb2ludHMnIDogJ2Nvbm5lY3Rpb24ucmVjb25uZWN0JztcblxuICAgIGFsbG93ZWQgPSBjb250ZXh0LmFsbG93ZWQgPSBydWxlcy5hbGxvd2VkKGNvbW1hbmQsIHtcbiAgICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgICBzb3VyY2U6IHR5cGUgPT09IFJFQ09OTkVDVF9TVEFSVCA/IGhvdmVyIDogc291cmNlLFxuICAgICAgdGFyZ2V0OiB0eXBlID09PSBSRUNPTk5FQ1RfRU5EID8gaG92ZXIgOiB0YXJnZXRcbiAgICB9KTtcblxuICAgIGlmIChhbGxvd2VkKSB7XG4gICAgICBjb250ZXh0LnNvdXJjZSA9IHR5cGUgPT09IFJFQ09OTkVDVF9TVEFSVCA/IGhvdmVyIDogc291cmNlO1xuICAgICAgY29udGV4dC50YXJnZXQgPSB0eXBlID09PSBSRUNPTk5FQ1RfRU5EID8gaG92ZXIgOiB0YXJnZXQ7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoYWxsb3dlZCA9PT0gZmFsc2UpIHtcbiAgICAgIGFsbG93ZWQgPSBjb250ZXh0LmFsbG93ZWQgPSBydWxlcy5hbGxvd2VkKGNvbW1hbmQsIHtcbiAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgICAgc291cmNlOiB0eXBlID09PSBSRUNPTk5FQ1RfRU5EID8gaG92ZXIgOiB0YXJnZXQsXG4gICAgICAgIHRhcmdldDogdHlwZSA9PT0gUkVDT05ORUNUX1NUQVJUID8gaG92ZXIgOiBzb3VyY2VcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChhbGxvd2VkKSB7XG4gICAgICBjb250ZXh0LnNvdXJjZSA9IHR5cGUgPT09IFJFQ09OTkVDVF9FTkQgPyBob3ZlciA6IHRhcmdldDtcbiAgICAgIGNvbnRleHQudGFyZ2V0ID0gdHlwZSA9PT0gUkVDT05ORUNUX1NUQVJUID8gaG92ZXIgOiBzb3VyY2U7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdiZW5kcG9pbnQubW92ZS5vdXQnLCAnYmVuZHBvaW50Lm1vdmUuY2xlYW51cCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQ7XG5cbiAgICBjb250ZXh0LmhvdmVyID0gbnVsbDtcbiAgICBjb250ZXh0LnNvdXJjZSA9IG51bGw7XG4gICAgY29udGV4dC50YXJnZXQgPSBudWxsO1xuXG4gICAgY29udGV4dC5hbGxvd2VkID0gZmFsc2U7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdiZW5kcG9pbnQubW92ZS5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgYWxsb3dlZCA9IGNvbnRleHQuYWxsb3dlZCxcbiAgICAgICAgYmVuZHBvaW50SW5kZXggPSBjb250ZXh0LmJlbmRwb2ludEluZGV4LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBpbnNlcnQgPSBjb250ZXh0Lmluc2VydCxcbiAgICAgICAgbmV3V2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHMuc2xpY2UoKSxcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICB0eXBlID0gY29udGV4dC50eXBlLFxuICAgICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgICAvLyBlbnN1cmUgaW50ZWdlciB2YWx1ZXMgKGltcG9ydGFudCBpZiB6b29tIGxldmVsIHdhcyA+IDEgZHVyaW5nIG1vdmUpXG4gICAgdmFyIGRvY2tpbmcgPSB7XG4gICAgICB4OiByb3VuZChldmVudC54KSxcbiAgICAgIHk6IHJvdW5kKGV2ZW50LnkpXG4gICAgfTtcblxuICAgIGlmICghYWxsb3dlZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSBVUERBVEVfV0FZUE9JTlRTKSB7XG4gICAgICBpZiAoaW5zZXJ0KSB7XG5cbiAgICAgICAgLy8gaW5zZXJ0IG5ldyBiZW5kcG9pbnRcbiAgICAgICAgbmV3V2F5cG9pbnRzLnNwbGljZShiZW5kcG9pbnRJbmRleCwgMCwgZG9ja2luZyk7XG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIC8vIHN3YXAgcHJldmlvdXMgd2F5cG9pbnQgd2l0aCBtb3ZlZCBvbmVcbiAgICAgICAgbmV3V2F5cG9pbnRzW2JlbmRwb2ludEluZGV4XSA9IGRvY2tpbmc7XG4gICAgICB9XG5cbiAgICAgIC8vIHBhc3MgaGludHMgYWJvdXQgYWN0dWFsIG1vdmVkIGJlbmRwb2ludFxuICAgICAgLy8gdXNlZnVsIGZvciBjb25uZWN0aW9uL2xhYmVsIGxheW91dFxuICAgICAgaGludHMuYmVuZHBvaW50TW92ZSA9IHtcbiAgICAgICAgaW5zZXJ0OiBpbnNlcnQsXG4gICAgICAgIGJlbmRwb2ludEluZGV4OiBiZW5kcG9pbnRJbmRleFxuICAgICAgfTtcblxuICAgICAgbmV3V2F5cG9pbnRzID0gdGhpcy5jcm9wV2F5cG9pbnRzKGNvbm5lY3Rpb24sIG5ld1dheXBvaW50cyk7XG5cbiAgICAgIG1vZGVsaW5nLnVwZGF0ZVdheXBvaW50cyhjb25uZWN0aW9uLCBmaWx0ZXJSZWR1bmRhbnRXYXlwb2ludHMobmV3V2F5cG9pbnRzKSwgaGludHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodHlwZSA9PT0gUkVDT05ORUNUX1NUQVJUKSB7XG4gICAgICAgIGhpbnRzLmRvY2tpbmcgPSAnc291cmNlJztcblxuICAgICAgICBpZiAoaXNSZXZlcnNlKGNvbnRleHQpKSB7XG4gICAgICAgICAgaGludHMuZG9ja2luZyA9ICd0YXJnZXQnO1xuXG4gICAgICAgICAgaGludHMubmV3V2F5cG9pbnRzID0gbmV3V2F5cG9pbnRzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBSRUNPTk5FQ1RfRU5EKSB7XG4gICAgICAgIGhpbnRzLmRvY2tpbmcgPSAndGFyZ2V0JztcblxuICAgICAgICBpZiAoaXNSZXZlcnNlKGNvbnRleHQpKSB7XG4gICAgICAgICAgaGludHMuZG9ja2luZyA9ICdzb3VyY2UnO1xuXG4gICAgICAgICAgaGludHMubmV3V2F5cG9pbnRzID0gbmV3V2F5cG9pbnRzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBtb2RlbGluZy5yZWNvbm5lY3QoY29ubmVjdGlvbiwgc291cmNlLCB0YXJnZXQsIGRvY2tpbmcsIGhpbnRzKTtcbiAgICB9XG4gIH0sIHRoaXMpO1xufVxuXG5CZW5kcG9pbnRNb3ZlLiRpbmplY3QgPSBbXG4gICdpbmplY3RvcicsXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnLFxuICAnZHJhZ2dpbmcnLFxuICAncnVsZXMnLFxuICAnbW9kZWxpbmcnXG5dO1xuXG5CZW5kcG9pbnRNb3ZlLnByb3RvdHlwZS5jcm9wV2F5cG9pbnRzID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgbmV3V2F5cG9pbnRzKSB7XG4gIHZhciBjb25uZWN0aW9uRG9ja2luZyA9IHRoaXMuX2luamVjdG9yLmdldCgnY29ubmVjdGlvbkRvY2tpbmcnLCBmYWxzZSk7XG5cbiAgaWYgKCFjb25uZWN0aW9uRG9ja2luZykge1xuICAgIHJldHVybiBuZXdXYXlwb2ludHM7XG4gIH1cblxuICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG5cbiAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBuZXdXYXlwb2ludHM7XG5cbiAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBjb25uZWN0aW9uRG9ja2luZy5nZXRDcm9wcGVkV2F5cG9pbnRzKGNvbm5lY3Rpb24pO1xuXG4gIG5ld1dheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzO1xuXG4gIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gd2F5cG9pbnRzO1xuXG4gIHJldHVybiBuZXdXYXlwb2ludHM7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXZlcnNlKGNvbnRleHQpIHtcbiAgdmFyIGhvdmVyID0gY29udGV4dC5ob3ZlcixcbiAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgdGFyZ2V0ID0gY29udGV4dC50YXJnZXQsXG4gICAgICB0eXBlID0gY29udGV4dC50eXBlO1xuXG4gIGlmICh0eXBlID09PSBSRUNPTk5FQ1RfU1RBUlQpIHtcbiAgICByZXR1cm4gaG92ZXIgJiYgdGFyZ2V0ICYmIGhvdmVyID09PSB0YXJnZXQgJiYgc291cmNlICE9PSB0YXJnZXQ7XG4gIH1cblxuICBpZiAodHlwZSA9PT0gUkVDT05ORUNUX0VORCkge1xuICAgIHJldHVybiBob3ZlciAmJiBzb3VyY2UgJiYgaG92ZXIgPT09IHNvdXJjZSAmJiBzb3VyY2UgIT09IHRhcmdldDtcbiAgfVxufSIsImltcG9ydCB7XG4gIGNsYXNzZXMgYXMgc3ZnQ2xhc3NlcyxcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7IGFkZEJlbmRwb2ludCB9IGZyb20gJy4vQmVuZHBvaW50VXRpbCc7XG5cbmltcG9ydCB7IHRyYW5zbGF0ZSB9IGZyb20gJy4uLy4uL3V0aWwvU3ZnVHJhbnNmb3JtVXRpbCc7XG5cbmltcG9ydCB7IGlzUmV2ZXJzZSB9IGZyb20gJy4vQmVuZHBvaW50TW92ZSc7XG5cbnZhciBSRUNPTk5FQ1RfU1RBUlQgPSAncmVjb25uZWN0U3RhcnQnLFxuICAgIFJFQ09OTkVDVF9FTkQgPSAncmVjb25uZWN0RW5kJyxcbiAgICBVUERBVEVfV0FZUE9JTlRTID0gJ3VwZGF0ZVdheXBvaW50cyc7XG5cbnZhciBNQVJLRVJfT0sgPSAnY29ubmVjdC1vaycsXG4gICAgTUFSS0VSX05PVF9PSyA9ICdjb25uZWN0LW5vdC1vaycsXG4gICAgTUFSS0VSX0NPTk5FQ1RfSE9WRVIgPSAnY29ubmVjdC1ob3ZlcicsXG4gICAgTUFSS0VSX0NPTk5FQ1RfVVBEQVRJTkcgPSAnZGpzLXVwZGF0aW5nJyxcbiAgICBNQVJLRVJfRUxFTUVOVF9ISURERU4gPSAnZGpzLWVsZW1lbnQtaGlkZGVuJztcblxudmFyIEhJR0hfUFJJT1JJVFkgPSAxMTAwO1xuXG4vKipcbiAqIFByZXZpZXcgY29ubmVjdGlvbiB3aGlsZSBtb3ZpbmcgYmVuZHBvaW50cy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmVuZHBvaW50TW92ZVByZXZpZXcoYmVuZHBvaW50TW92ZSwgaW5qZWN0b3IsIGV2ZW50QnVzLCBjYW52YXMpIHtcbiAgdGhpcy5faW5qZWN0b3IgPSBpbmplY3RvcjtcblxuICB2YXIgY29ubmVjdGlvblByZXZpZXcgPSBpbmplY3Rvci5nZXQoJ2Nvbm5lY3Rpb25QcmV2aWV3JywgZmFsc2UpO1xuXG4gIGV2ZW50QnVzLm9uKCdiZW5kcG9pbnQubW92ZS5zdGFydCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBiZW5kcG9pbnRJbmRleCA9IGNvbnRleHQuYmVuZHBvaW50SW5kZXgsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIGluc2VydCA9IGNvbnRleHQuaW5zZXJ0LFxuICAgICAgICB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgICAgbmV3V2F5cG9pbnRzID0gd2F5cG9pbnRzLnNsaWNlKCk7XG5cbiAgICBjb250ZXh0LndheXBvaW50cyA9IHdheXBvaW50cztcblxuICAgIGlmIChpbnNlcnQpIHtcblxuICAgICAgLy8gaW5zZXJ0IHBsYWNlaG9sZGVyIGZvciBuZXcgYmVuZHBvaW50XG4gICAgICBuZXdXYXlwb2ludHMuc3BsaWNlKGJlbmRwb2ludEluZGV4LCAwLCB7IHg6IGV2ZW50LngsIHk6IGV2ZW50LnkgfSk7XG4gICAgfVxuXG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBuZXdXYXlwb2ludHM7XG5cbiAgICAvLyBhZGQgZHJhZ2dlciBnZnhcbiAgICB2YXIgZHJhZ2dlckdmeCA9IGNvbnRleHQuZHJhZ2dlckdmeCA9IGFkZEJlbmRwb2ludChjYW52YXMuZ2V0TGF5ZXIoJ292ZXJsYXlzJykpO1xuXG4gICAgc3ZnQ2xhc3NlcyhkcmFnZ2VyR2Z4KS5hZGQoJ2Rqcy1kcmFnZ2luZycpO1xuXG4gICAgY2FudmFzLmFkZE1hcmtlcihjb25uZWN0aW9uLCBNQVJLRVJfRUxFTUVOVF9ISURERU4pO1xuICAgIGNhbnZhcy5hZGRNYXJrZXIoY29ubmVjdGlvbiwgTUFSS0VSX0NPTk5FQ1RfVVBEQVRJTkcpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignYmVuZHBvaW50Lm1vdmUuaG92ZXInLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgYWxsb3dlZCA9IGNvbnRleHQuYWxsb3dlZCxcbiAgICAgICAgaG92ZXIgPSBjb250ZXh0LmhvdmVyLFxuICAgICAgICB0eXBlID0gY29udGV4dC50eXBlO1xuXG4gICAgaWYgKGhvdmVyKSB7XG4gICAgICBjYW52YXMuYWRkTWFya2VyKGhvdmVyLCBNQVJLRVJfQ09OTkVDVF9IT1ZFUik7XG5cbiAgICAgIGlmICh0eXBlID09PSBVUERBVEVfV0FZUE9JTlRTKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGFsbG93ZWQpIHtcbiAgICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgTUFSS0VSX05PVF9PSyk7XG4gICAgICAgIGNhbnZhcy5hZGRNYXJrZXIoaG92ZXIsIE1BUktFUl9PSyk7XG4gICAgICB9IGVsc2UgaWYgKGFsbG93ZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoaG92ZXIsIE1BUktFUl9PSyk7XG4gICAgICAgIGNhbnZhcy5hZGRNYXJrZXIoaG92ZXIsIE1BUktFUl9OT1RfT0spO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oW1xuICAgICdiZW5kcG9pbnQubW92ZS5vdXQnLFxuICAgICdiZW5kcG9pbnQubW92ZS5jbGVhbnVwJ1xuICBdLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgaG92ZXIgPSBjb250ZXh0LmhvdmVyLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIGlmIChob3Zlcikge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgTUFSS0VSX0NPTk5FQ1RfSE9WRVIpO1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgdGFyZ2V0ID8gTUFSS0VSX09LIDogTUFSS0VSX05PVF9PSyk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignYmVuZHBvaW50Lm1vdmUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBhbGxvd2VkID0gY29udGV4dC5hbGxvd2VkLFxuICAgICAgICBiZW5kcG9pbnRJbmRleCA9IGNvbnRleHQuYmVuZHBvaW50SW5kZXgsXG4gICAgICAgIGRyYWdnZXJHZnggPSBjb250ZXh0LmRyYWdnZXJHZngsXG4gICAgICAgIGhvdmVyID0gY29udGV4dC5ob3ZlcixcbiAgICAgICAgdHlwZSA9IGNvbnRleHQudHlwZSxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0LFxuICAgICAgICBuZXdXYXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cy5zbGljZSgpLFxuICAgICAgICBiZW5kcG9pbnQgPSB7IHg6IGV2ZW50LngsIHk6IGV2ZW50LnkgfSxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICBkcmF3UHJldmlld0hpbnRzID0ge307XG5cbiAgICBpZiAoY29ubmVjdGlvblByZXZpZXcpIHtcbiAgICAgIGlmIChoaW50cy5jb25uZWN0aW9uU3RhcnQpIHtcbiAgICAgICAgZHJhd1ByZXZpZXdIaW50cy5jb25uZWN0aW9uU3RhcnQgPSBoaW50cy5jb25uZWN0aW9uU3RhcnQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChoaW50cy5jb25uZWN0aW9uRW5kKSB7XG4gICAgICAgIGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvbkVuZCA9IGhpbnRzLmNvbm5lY3Rpb25FbmQ7XG4gICAgICB9XG5cblxuICAgICAgaWYgKHR5cGUgPT09IFJFQ09OTkVDVF9TVEFSVCkge1xuICAgICAgICBpZiAoaXNSZXZlcnNlKGNvbnRleHQpKSB7XG4gICAgICAgICAgZHJhd1ByZXZpZXdIaW50cy5jb25uZWN0aW9uRW5kID0gZHJhd1ByZXZpZXdIaW50cy5jb25uZWN0aW9uRW5kIHx8IGJlbmRwb2ludDtcblxuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMuc291cmNlID0gdGFyZ2V0O1xuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMudGFyZ2V0ID0gaG92ZXIgfHwgc291cmNlO1xuXG4gICAgICAgICAgbmV3V2F5cG9pbnRzID0gbmV3V2F5cG9pbnRzLnJldmVyc2UoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkcmF3UHJldmlld0hpbnRzLmNvbm5lY3Rpb25TdGFydCA9IGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvblN0YXJ0IHx8IGJlbmRwb2ludDtcblxuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMuc291cmNlID0gaG92ZXIgfHwgc291cmNlO1xuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFJFQ09OTkVDVF9FTkQpIHtcbiAgICAgICAgaWYgKGlzUmV2ZXJzZShjb250ZXh0KSkge1xuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvblN0YXJ0ID0gZHJhd1ByZXZpZXdIaW50cy5jb25uZWN0aW9uU3RhcnQgfHwgYmVuZHBvaW50O1xuXG4gICAgICAgICAgZHJhd1ByZXZpZXdIaW50cy5zb3VyY2UgPSBob3ZlciB8fCB0YXJnZXQ7XG4gICAgICAgICAgZHJhd1ByZXZpZXdIaW50cy50YXJnZXQgPSBzb3VyY2U7XG5cbiAgICAgICAgICBuZXdXYXlwb2ludHMgPSBuZXdXYXlwb2ludHMucmV2ZXJzZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvbkVuZCA9IGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvbkVuZCB8fCBiZW5kcG9pbnQ7XG5cbiAgICAgICAgICBkcmF3UHJldmlld0hpbnRzLnNvdXJjZSA9IHNvdXJjZTtcbiAgICAgICAgICBkcmF3UHJldmlld0hpbnRzLnRhcmdldCA9IGhvdmVyIHx8IHRhcmdldDtcbiAgICAgICAgfVxuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkcmF3UHJldmlld0hpbnRzLm5vQ3JvcHBpbmcgPSB0cnVlO1xuICAgICAgICBkcmF3UHJldmlld0hpbnRzLm5vTGF5b3V0ID0gdHJ1ZTtcbiAgICAgICAgbmV3V2F5cG9pbnRzWyBiZW5kcG9pbnRJbmRleCBdID0gYmVuZHBvaW50O1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZSA9PT0gVVBEQVRFX1dBWVBPSU5UUykge1xuICAgICAgICBuZXdXYXlwb2ludHMgPSBiZW5kcG9pbnRNb3ZlLmNyb3BXYXlwb2ludHMoY29ubmVjdGlvbiwgbmV3V2F5cG9pbnRzKTtcbiAgICAgIH1cblxuICAgICAgZHJhd1ByZXZpZXdIaW50cy53YXlwb2ludHMgPSBuZXdXYXlwb2ludHM7XG5cbiAgICAgIGNvbm5lY3Rpb25QcmV2aWV3LmRyYXdQcmV2aWV3KGNvbnRleHQsIGFsbG93ZWQsIGRyYXdQcmV2aWV3SGludHMpO1xuICAgIH1cblxuICAgIHRyYW5zbGF0ZShkcmFnZ2VyR2Z4LCBldmVudC54LCBldmVudC55KTtcbiAgfSwgdGhpcyk7XG5cbiAgZXZlbnRCdXMub24oW1xuICAgICdiZW5kcG9pbnQubW92ZS5lbmQnLFxuICAgICdiZW5kcG9pbnQubW92ZS5jYW5jZWwnXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBkcmFnZ2VyR2Z4ID0gY29udGV4dC5kcmFnZ2VyR2Z4LFxuICAgICAgICBob3ZlciA9IGNvbnRleHQuaG92ZXIsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICB3YXlwb2ludHMgPSBjb250ZXh0LndheXBvaW50cztcblxuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gd2F5cG9pbnRzO1xuXG4gICAgLy8gcmVtb3ZlIGRyYWdnZXIgZ2Z4XG4gICAgc3ZnUmVtb3ZlKGRyYWdnZXJHZngpO1xuXG4gICAgY2FudmFzLnJlbW92ZU1hcmtlcihjb25uZWN0aW9uLCBNQVJLRVJfQ09OTkVDVF9VUERBVElORyk7XG4gICAgY2FudmFzLnJlbW92ZU1hcmtlcihjb25uZWN0aW9uLCBNQVJLRVJfRUxFTUVOVF9ISURERU4pO1xuXG4gICAgaWYgKGhvdmVyKSB7XG4gICAgICBjYW52YXMucmVtb3ZlTWFya2VyKGhvdmVyLCBNQVJLRVJfT0spO1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgdGFyZ2V0ID8gTUFSS0VSX09LIDogTUFSS0VSX05PVF9PSyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbm5lY3Rpb25QcmV2aWV3KSB7XG4gICAgICBjb25uZWN0aW9uUHJldmlldy5jbGVhblVwKGNvbnRleHQpO1xuICAgIH1cbiAgfSk7XG59XG5cbkJlbmRwb2ludE1vdmVQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdiZW5kcG9pbnRNb3ZlJyxcbiAgJ2luamVjdG9yJyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcydcbl07IiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmb3JFYWNoLFxuICBpc0FycmF5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgc2V0U25hcHBlZCB9IGZyb20gJy4uL3NuYXBwaW5nL1NuYXBVdGlsJztcblxudmFyIGFicz0gTWF0aC5hYnMsXG4gICAgcm91bmQgPSBNYXRoLnJvdW5kO1xuXG52YXIgVE9MRVJBTkNFID0gMTA7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmVuZHBvaW50U25hcHBpbmcoZXZlbnRCdXMpIHtcblxuICBmdW5jdGlvbiBzbmFwVG8odmFsdWVzLCB2YWx1ZSkge1xuXG4gICAgaWYgKGlzQXJyYXkodmFsdWVzKSkge1xuICAgICAgdmFyIGkgPSB2YWx1ZXMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoaS0tKSBpZiAoYWJzKHZhbHVlc1tpXSAtIHZhbHVlKSA8PSBUT0xFUkFOQ0UpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlc1tpXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWVzID0gK3ZhbHVlcztcbiAgICAgIHZhciByZW0gPSB2YWx1ZSAlIHZhbHVlcztcblxuICAgICAgaWYgKHJlbSA8IFRPTEVSQU5DRSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgLSByZW07XG4gICAgICB9XG5cbiAgICAgIGlmIChyZW0gPiB2YWx1ZXMgLSBUT0xFUkFOQ0UpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlIC0gcmVtICsgdmFsdWVzO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1pZChlbGVtZW50KSB7XG4gICAgaWYgKGVsZW1lbnQud2lkdGgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHg6IHJvdW5kKGVsZW1lbnQud2lkdGggLyAyICsgZWxlbWVudC54KSxcbiAgICAgICAgeTogcm91bmQoZWxlbWVudC5oZWlnaHQgLyAyICsgZWxlbWVudC55KVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvLyBjb25uZWN0aW9uIHNlZ21lbnQgc25hcHBpbmcgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIGZ1bmN0aW9uIGdldENvbm5lY3Rpb25TZWdtZW50U25hcHMoY29udGV4dCkge1xuXG4gICAgdmFyIHNuYXBQb2ludHMgPSBjb250ZXh0LnNuYXBQb2ludHMsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzLFxuICAgICAgICBzZWdtZW50U3RhcnQgPSBjb250ZXh0LnNlZ21lbnRTdGFydCxcbiAgICAgICAgc2VnbWVudFN0YXJ0SW5kZXggPSBjb250ZXh0LnNlZ21lbnRTdGFydEluZGV4LFxuICAgICAgICBzZWdtZW50RW5kID0gY29udGV4dC5zZWdtZW50RW5kLFxuICAgICAgICBzZWdtZW50RW5kSW5kZXggPSBjb250ZXh0LnNlZ21lbnRFbmRJbmRleCxcbiAgICAgICAgYXhpcyA9IGNvbnRleHQuYXhpcztcblxuICAgIGlmIChzbmFwUG9pbnRzKSB7XG4gICAgICByZXR1cm4gc25hcFBvaW50cztcbiAgICB9XG5cbiAgICB2YXIgcmVmZXJlbmNlV2F5cG9pbnRzID0gW1xuICAgICAgd2F5cG9pbnRzW3NlZ21lbnRTdGFydEluZGV4IC0gMV0sXG4gICAgICBzZWdtZW50U3RhcnQsXG4gICAgICBzZWdtZW50RW5kLFxuICAgICAgd2F5cG9pbnRzW3NlZ21lbnRFbmRJbmRleCArIDFdXG4gICAgXTtcblxuICAgIGlmIChzZWdtZW50U3RhcnRJbmRleCA8IDIpIHtcbiAgICAgIHJlZmVyZW5jZVdheXBvaW50cy51bnNoaWZ0KG1pZChjb25uZWN0aW9uLnNvdXJjZSkpO1xuICAgIH1cblxuICAgIGlmIChzZWdtZW50RW5kSW5kZXggPiB3YXlwb2ludHMubGVuZ3RoIC0gMykge1xuICAgICAgcmVmZXJlbmNlV2F5cG9pbnRzLnVuc2hpZnQobWlkKGNvbm5lY3Rpb24udGFyZ2V0KSk7XG4gICAgfVxuXG4gICAgY29udGV4dC5zbmFwUG9pbnRzID0gc25hcFBvaW50cyA9IHsgaG9yaXpvbnRhbDogW10gLCB2ZXJ0aWNhbDogW10gfTtcblxuICAgIGZvckVhY2gocmVmZXJlbmNlV2F5cG9pbnRzLCBmdW5jdGlvbihwKSB7XG5cbiAgICAgIC8vIHdlIHNuYXAgb24gZXhpc3RpbmcgYmVuZHBvaW50cyBvbmx5LFxuICAgICAgLy8gbm90IHBsYWNlaG9sZGVycyB0aGF0IGFyZSBpbnNlcnRlZCBkdXJpbmcgYWRkXG4gICAgICBpZiAocCkge1xuICAgICAgICBwID0gcC5vcmlnaW5hbCB8fCBwO1xuXG4gICAgICAgIGlmIChheGlzID09PSAneScpIHtcbiAgICAgICAgICBzbmFwUG9pbnRzLmhvcml6b250YWwucHVzaChwLnkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGF4aXMgPT09ICd4Jykge1xuICAgICAgICAgIHNuYXBQb2ludHMudmVydGljYWwucHVzaChwLngpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc25hcFBvaW50cztcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjb25uZWN0aW9uU2VnbWVudC5tb3ZlLm1vdmUnLCAxNTAwLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc25hcFBvaW50cyA9IGdldENvbm5lY3Rpb25TZWdtZW50U25hcHMoY29udGV4dCksXG4gICAgICAgIHggPSBldmVudC54LFxuICAgICAgICB5ID0gZXZlbnQueSxcbiAgICAgICAgc3gsIHN5O1xuXG4gICAgaWYgKCFzbmFwUG9pbnRzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc25hcFxuICAgIHN4ID0gc25hcFRvKHNuYXBQb2ludHMudmVydGljYWwsIHgpO1xuICAgIHN5ID0gc25hcFRvKHNuYXBQb2ludHMuaG9yaXpvbnRhbCwgeSk7XG5cblxuICAgIC8vIGNvcnJlY3Rpb24geC95XG4gICAgdmFyIGN4ID0gKHggLSBzeCksXG4gICAgICAgIGN5ID0gKHkgLSBzeSk7XG5cbiAgICAvLyB1cGRhdGUgZGVsdGFcbiAgICBhc3NpZ24oZXZlbnQsIHtcbiAgICAgIGR4OiBldmVudC5keCAtIGN4LFxuICAgICAgZHk6IGV2ZW50LmR5IC0gY3ksXG4gICAgICB4OiBzeCxcbiAgICAgIHk6IHN5XG4gICAgfSk7XG5cbiAgICAvLyBvbmx5IHNldCBzbmFwcGVkIGlmIGFjdHVhbGx5IHNuYXBwZWRcbiAgICBpZiAoY3ggfHwgc25hcFBvaW50cy52ZXJ0aWNhbC5pbmRleE9mKHgpICE9PSAtMSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgJ3gnLCBzeCk7XG4gICAgfVxuXG4gICAgaWYgKGN5IHx8IHNuYXBQb2ludHMuaG9yaXpvbnRhbC5pbmRleE9mKHkpICE9PSAtMSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgJ3knLCBzeSk7XG4gICAgfVxuICB9KTtcblxuXG4gIC8vIGJlbmRwb2ludCBzbmFwcGluZyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgZnVuY3Rpb24gZ2V0QmVuZHBvaW50U25hcHMoY29udGV4dCkge1xuXG4gICAgdmFyIHNuYXBQb2ludHMgPSBjb250ZXh0LnNuYXBQb2ludHMsXG4gICAgICAgIHdheXBvaW50cyA9IGNvbnRleHQuY29ubmVjdGlvbi53YXlwb2ludHMsXG4gICAgICAgIGJlbmRwb2ludEluZGV4ID0gY29udGV4dC5iZW5kcG9pbnRJbmRleDtcblxuICAgIGlmIChzbmFwUG9pbnRzKSB7XG4gICAgICByZXR1cm4gc25hcFBvaW50cztcbiAgICB9XG5cbiAgICB2YXIgcmVmZXJlbmNlV2F5cG9pbnRzID0gWyB3YXlwb2ludHNbYmVuZHBvaW50SW5kZXggLSAxXSwgd2F5cG9pbnRzW2JlbmRwb2ludEluZGV4ICsgMV0gXTtcblxuICAgIGNvbnRleHQuc25hcFBvaW50cyA9IHNuYXBQb2ludHMgPSB7IGhvcml6b250YWw6IFtdICwgdmVydGljYWw6IFtdIH07XG5cbiAgICBmb3JFYWNoKHJlZmVyZW5jZVdheXBvaW50cywgZnVuY3Rpb24ocCkge1xuXG4gICAgICAvLyB3ZSBzbmFwIG9uIGV4aXN0aW5nIGJlbmRwb2ludHMgb25seSxcbiAgICAgIC8vIG5vdCBwbGFjZWhvbGRlcnMgdGhhdCBhcmUgaW5zZXJ0ZWQgZHVyaW5nIGFkZFxuICAgICAgaWYgKHApIHtcbiAgICAgICAgcCA9IHAub3JpZ2luYWwgfHwgcDtcblxuICAgICAgICBzbmFwUG9pbnRzLmhvcml6b250YWwucHVzaChwLnkpO1xuICAgICAgICBzbmFwUG9pbnRzLnZlcnRpY2FsLnB1c2gocC54KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBzbmFwUG9pbnRzO1xuICB9XG5cblxuICBldmVudEJ1cy5vbihbICdiZW5kcG9pbnQubW92ZS5tb3ZlJywgJ2JlbmRwb2ludC5tb3ZlLmVuZCcgXSwgMTUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc25hcFBvaW50cyA9IGdldEJlbmRwb2ludFNuYXBzKGNvbnRleHQpLFxuICAgICAgICBob3ZlciA9IGNvbnRleHQuaG92ZXIsXG4gICAgICAgIGhvdmVyTWlkID0gaG92ZXIgJiYgbWlkKGhvdmVyKSxcbiAgICAgICAgeCA9IGV2ZW50LngsXG4gICAgICAgIHkgPSBldmVudC55LFxuICAgICAgICBzeCwgc3k7XG5cbiAgICBpZiAoIXNuYXBQb2ludHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBzbmFwIHRvIGhvdmVyIG1pZFxuICAgIHN4ID0gc25hcFRvKGhvdmVyTWlkID8gc25hcFBvaW50cy52ZXJ0aWNhbC5jb25jYXQoWyBob3Zlck1pZC54IF0pIDogc25hcFBvaW50cy52ZXJ0aWNhbCwgeCk7XG4gICAgc3kgPSBzbmFwVG8oaG92ZXJNaWQgPyBzbmFwUG9pbnRzLmhvcml6b250YWwuY29uY2F0KFsgaG92ZXJNaWQueSBdKSA6IHNuYXBQb2ludHMuaG9yaXpvbnRhbCwgeSk7XG5cbiAgICAvLyBjb3JyZWN0aW9uIHgveVxuICAgIHZhciBjeCA9ICh4IC0gc3gpLFxuICAgICAgICBjeSA9ICh5IC0gc3kpO1xuXG4gICAgLy8gdXBkYXRlIGRlbHRhXG4gICAgYXNzaWduKGV2ZW50LCB7XG4gICAgICBkeDogZXZlbnQuZHggLSBjeCxcbiAgICAgIGR5OiBldmVudC5keSAtIGN5LFxuICAgICAgeDogZXZlbnQueCAtIGN4LFxuICAgICAgeTogZXZlbnQueSAtIGN5XG4gICAgfSk7XG5cbiAgICAvLyBvbmx5IHNldCBzbmFwcGVkIGlmIGFjdHVhbGx5IHNuYXBwZWRcbiAgICBpZiAoY3ggfHwgc25hcFBvaW50cy52ZXJ0aWNhbC5pbmRleE9mKHgpICE9PSAtMSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgJ3gnLCBzeCk7XG4gICAgfVxuXG4gICAgaWYgKGN5IHx8IHNuYXBQb2ludHMuaG9yaXpvbnRhbC5pbmRleE9mKHkpICE9PSAtMSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgJ3knLCBzeSk7XG4gICAgfVxuICB9KTtcbn1cblxuXG5CZW5kcG9pbnRTbmFwcGluZy4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07IiwiaW1wb3J0IHtcbiAgdG9Qb2ludFxufSBmcm9tICcuLi8uLi91dGlsL0V2ZW50JztcblxuaW1wb3J0IHtcbiAgZ2V0TWlkUG9pbnQsXG4gIHBvaW50c0FsaWduZWRcbn0gZnJvbSAnLi4vLi4vdXRpbC9HZW9tZXRyeSc7XG5cbmltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxuaW1wb3J0IHtcbiAgcm90YXRlLFxuICB0cmFuc2xhdGVcbn0gZnJvbSAnLi4vLi4vdXRpbC9TdmdUcmFuc2Zvcm1VdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0QXBwcm94SW50ZXJzZWN0aW9uXG59IGZyb20gJy4uLy4uL3V0aWwvTGluZUludGVyc2VjdGlvbic7XG5cbmV4cG9ydCB2YXIgQkVORFBPSU5UX0NMUyA9ICdkanMtYmVuZHBvaW50JztcbmV4cG9ydCB2YXIgU0VHTUVOVF9EUkFHR0VSX0NMUyA9ICdkanMtc2VnbWVudC1kcmFnZ2VyJztcblxuZXhwb3J0IGZ1bmN0aW9uIHRvQ2FudmFzQ29vcmRpbmF0ZXMoY2FudmFzLCBldmVudCkge1xuXG4gIHZhciBwb3NpdGlvbiA9IHRvUG9pbnQoZXZlbnQpLFxuICAgICAgY2xpZW50UmVjdCA9IGNhbnZhcy5fY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgb2Zmc2V0O1xuXG4gIC8vIGNhbnZhcyByZWxhdGl2ZSBwb3NpdGlvblxuXG4gIG9mZnNldCA9IHtcbiAgICB4OiBjbGllbnRSZWN0LmxlZnQsXG4gICAgeTogY2xpZW50UmVjdC50b3BcbiAgfTtcblxuICAvLyB1cGRhdGUgYWN0dWFsIGV2ZW50IHBheWxvYWQgd2l0aCBjYW52YXMgcmVsYXRpdmUgbWVhc3VyZXNcblxuICB2YXIgdmlld2JveCA9IGNhbnZhcy52aWV3Ym94KCk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiB2aWV3Ym94LnggKyAocG9zaXRpb24ueCAtIG9mZnNldC54KSAvIHZpZXdib3guc2NhbGUsXG4gICAgeTogdmlld2JveC55ICsgKHBvc2l0aW9uLnkgLSBvZmZzZXQueSkgLyB2aWV3Ym94LnNjYWxlXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb25uZWN0aW9uSW50ZXJzZWN0aW9uKGNhbnZhcywgd2F5cG9pbnRzLCBldmVudCkge1xuICB2YXIgbG9jYWxQb3NpdGlvbiA9IHRvQ2FudmFzQ29vcmRpbmF0ZXMoY2FudmFzLCBldmVudCksXG4gICAgICBpbnRlcnNlY3Rpb24gPSBnZXRBcHByb3hJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCBsb2NhbFBvc2l0aW9uKTtcblxuICByZXR1cm4gaW50ZXJzZWN0aW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkQmVuZHBvaW50KHBhcmVudEdmeCwgY2xzKSB7XG4gIHZhciBncm91cEdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuICBzdmdDbGFzc2VzKGdyb3VwR2Z4KS5hZGQoQkVORFBPSU5UX0NMUyk7XG5cbiAgc3ZnQXBwZW5kKHBhcmVudEdmeCwgZ3JvdXBHZngpO1xuXG4gIHZhciB2aXN1YWwgPSBzdmdDcmVhdGUoJ2NpcmNsZScpO1xuICBzdmdBdHRyKHZpc3VhbCwge1xuICAgIGN4OiAwLFxuICAgIGN5OiAwLFxuICAgIHI6IDRcbiAgfSk7XG4gIHN2Z0NsYXNzZXModmlzdWFsKS5hZGQoJ2Rqcy12aXN1YWwnKTtcblxuICBzdmdBcHBlbmQoZ3JvdXBHZngsIHZpc3VhbCk7XG5cbiAgdmFyIGhpdCA9IHN2Z0NyZWF0ZSgnY2lyY2xlJyk7XG4gIHN2Z0F0dHIoaGl0LCB7XG4gICAgY3g6IDAsXG4gICAgY3k6IDAsXG4gICAgcjogMTBcbiAgfSk7XG4gIHN2Z0NsYXNzZXMoaGl0KS5hZGQoJ2Rqcy1oaXQnKTtcblxuICBzdmdBcHBlbmQoZ3JvdXBHZngsIGhpdCk7XG5cbiAgaWYgKGNscykge1xuICAgIHN2Z0NsYXNzZXMoZ3JvdXBHZngpLmFkZChjbHMpO1xuICB9XG5cbiAgcmV0dXJuIGdyb3VwR2Z4O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVQYXJhbGxlbERyYWdnZXIocGFyZW50R2Z4LCBzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQsIGFsaWdubWVudCkge1xuICB2YXIgZHJhZ2dlckdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuXG4gIHN2Z0FwcGVuZChwYXJlbnRHZngsIGRyYWdnZXJHZngpO1xuXG4gIHZhciB3aWR0aCA9IDE0LFxuICAgICAgaGVpZ2h0ID0gMyxcbiAgICAgIHBhZGRpbmcgPSAxMSxcbiAgICAgIGhpdFdpZHRoID0gY2FsY3VsYXRlSGl0V2lkdGgoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kLCBhbGlnbm1lbnQpLFxuICAgICAgaGl0SGVpZ2h0ID0gaGVpZ2h0ICsgcGFkZGluZztcblxuICB2YXIgdmlzdWFsID0gc3ZnQ3JlYXRlKCdyZWN0Jyk7XG4gIHN2Z0F0dHIodmlzdWFsLCB7XG4gICAgeDogLXdpZHRoIC8gMixcbiAgICB5OiAtaGVpZ2h0IC8gMixcbiAgICB3aWR0aDogd2lkdGgsXG4gICAgaGVpZ2h0OiBoZWlnaHRcbiAgfSk7XG4gIHN2Z0NsYXNzZXModmlzdWFsKS5hZGQoJ2Rqcy12aXN1YWwnKTtcblxuICBzdmdBcHBlbmQoZHJhZ2dlckdmeCwgdmlzdWFsKTtcblxuICB2YXIgaGl0ID0gc3ZnQ3JlYXRlKCdyZWN0Jyk7XG4gIHN2Z0F0dHIoaGl0LCB7XG4gICAgeDogLWhpdFdpZHRoIC8gMixcbiAgICB5OiAtaGl0SGVpZ2h0IC8gMixcbiAgICB3aWR0aDogaGl0V2lkdGgsXG4gICAgaGVpZ2h0OiBoaXRIZWlnaHRcbiAgfSk7XG4gIHN2Z0NsYXNzZXMoaGl0KS5hZGQoJ2Rqcy1oaXQnKTtcblxuICBzdmdBcHBlbmQoZHJhZ2dlckdmeCwgaGl0KTtcblxuICByb3RhdGUoZHJhZ2dlckdmeCwgYWxpZ25tZW50ID09PSAndicgPyA5MCA6IDAsIDAsIDApO1xuXG4gIHJldHVybiBkcmFnZ2VyR2Z4O1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRTZWdtZW50RHJhZ2dlcihwYXJlbnRHZngsIHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCkge1xuXG4gIHZhciBncm91cEdmeCA9IHN2Z0NyZWF0ZSgnZycpLFxuICAgICAgbWlkID0gZ2V0TWlkUG9pbnQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKSxcbiAgICAgIGFsaWdubWVudCA9IHBvaW50c0FsaWduZWQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKTtcblxuICBzdmdBcHBlbmQocGFyZW50R2Z4LCBncm91cEdmeCk7XG5cbiAgY3JlYXRlUGFyYWxsZWxEcmFnZ2VyKGdyb3VwR2Z4LCBzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQsIGFsaWdubWVudCk7XG5cbiAgc3ZnQ2xhc3Nlcyhncm91cEdmeCkuYWRkKFNFR01FTlRfRFJBR0dFUl9DTFMpO1xuICBzdmdDbGFzc2VzKGdyb3VwR2Z4KS5hZGQoYWxpZ25tZW50ID09PSAnaCcgPyAnaG9yaXpvbnRhbCcgOiAndmVydGljYWwnKTtcblxuICB0cmFuc2xhdGUoZ3JvdXBHZngsIG1pZC54LCBtaWQueSk7XG5cbiAgcmV0dXJuIGdyb3VwR2Z4O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgcmVnaW9uIGZvciBzZWdtZW50IG1vdmUgd2hpY2ggaXMgMi8zIG9mIHRoZSBmdWxsIHNlZ21lbnQgbGVuZ3RoXG4gKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudExlbmd0aFxuICpcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVNlZ21lbnRNb3ZlUmVnaW9uKHNlZ21lbnRMZW5ndGgpIHtcbiAgcmV0dXJuIE1hdGguYWJzKE1hdGgucm91bmQoc2VnbWVudExlbmd0aCAqIDIgLyAzKSk7XG59XG5cbi8vIGhlbHBlciAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZUhpdFdpZHRoKHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCwgYWxpZ25tZW50KSB7XG4gIHZhciBzZWdtZW50TGVuZ3RoWEF4aXMgPSBzZWdtZW50RW5kLnggLSBzZWdtZW50U3RhcnQueCxcbiAgICAgIHNlZ21lbnRMZW5ndGhZQXhpcyA9IHNlZ21lbnRFbmQueSAtIHNlZ21lbnRTdGFydC55O1xuXG4gIHJldHVybiBhbGlnbm1lbnQgPT09ICdoJyA/XG4gICAgY2FsY3VsYXRlU2VnbWVudE1vdmVSZWdpb24oc2VnbWVudExlbmd0aFhBeGlzKSA6XG4gICAgY2FsY3VsYXRlU2VnbWVudE1vdmVSZWdpb24oc2VnbWVudExlbmd0aFlBeGlzKTtcbn1cbiIsImltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50LFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgcXVlcnlBbGwgYXMgZG9tUXVlcnlBbGxcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIEJFTkRQT0lOVF9DTFMsXG4gIFNFR01FTlRfRFJBR0dFUl9DTFMsXG4gIGFkZEJlbmRwb2ludCxcbiAgYWRkU2VnbWVudERyYWdnZXIsXG4gIGNhbGN1bGF0ZVNlZ21lbnRNb3ZlUmVnaW9uLFxuICBnZXRDb25uZWN0aW9uSW50ZXJzZWN0aW9uXG59IGZyb20gJy4vQmVuZHBvaW50VXRpbCc7XG5cbmltcG9ydCB7XG4gIGVzY2FwZUNTU1xufSBmcm9tICcuLi8uLi91dGlsL0VzY2FwZVV0aWwnO1xuXG5pbXBvcnQge1xuICBwb2ludHNBbGlnbmVkLFxuICBnZXRNaWRQb2ludFxufSBmcm9tICcuLi8uLi91dGlsL0dlb21ldHJ5JztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjbGFzc2VzIGFzIHN2Z0NsYXNzZXMsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICB0cmFuc2xhdGVcbn0gZnJvbSAnLi4vLi4vdXRpbC9TdmdUcmFuc2Zvcm1VdGlsJztcblxuXG4vKipcbiAqIEEgc2VydmljZSB0aGF0IGFkZHMgZWRpdGFibGUgYmVuZHBvaW50cyB0byBjb25uZWN0aW9ucy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmVuZHBvaW50cyhcbiAgICBldmVudEJ1cywgY2FudmFzLCBpbnRlcmFjdGlvbkV2ZW50cyxcbiAgICBiZW5kcG9pbnRNb3ZlLCBjb25uZWN0aW9uU2VnbWVudE1vdmUpIHtcblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIGludGVyc2VjdGlvbiBwb2ludCBpcyBpbnNpZGUgbWlkZGxlIHJlZ2lvbiBvZiBzZWdtZW50LCBhZGp1c3RlZCBieVxuICAgKiBvcHRpb25hbCB0aHJlc2hvbGRcbiAgICovXG4gIGZ1bmN0aW9uIGlzSW50ZXJzZWN0aW9uTWlkZGxlKGludGVyc2VjdGlvbiwgd2F5cG9pbnRzLCB0cmVzaG9sZCkge1xuICAgIHZhciBpZHggPSBpbnRlcnNlY3Rpb24uaW5kZXgsXG4gICAgICAgIHAgPSBpbnRlcnNlY3Rpb24ucG9pbnQsXG4gICAgICAgIHAwLCBwMSwgbWlkLCBhbGlnbmVkLCB4RGVsdGEsIHlEZWx0YTtcblxuICAgIGlmIChpZHggPD0gMCB8fCBpbnRlcnNlY3Rpb24uYmVuZHBvaW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcDAgPSB3YXlwb2ludHNbaWR4IC0gMV07XG4gICAgcDEgPSB3YXlwb2ludHNbaWR4XTtcbiAgICBtaWQgPSBnZXRNaWRQb2ludChwMCwgcDEpLFxuICAgIGFsaWduZWQgPSBwb2ludHNBbGlnbmVkKHAwLCBwMSk7XG4gICAgeERlbHRhID0gTWF0aC5hYnMocC54IC0gbWlkLngpO1xuICAgIHlEZWx0YSA9IE1hdGguYWJzKHAueSAtIG1pZC55KTtcblxuICAgIHJldHVybiBhbGlnbmVkICYmIHhEZWx0YSA8PSB0cmVzaG9sZCAmJiB5RGVsdGEgPD0gdHJlc2hvbGQ7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgdGhyZXNob2xkIGZyb20gYSBjb25uZWN0aW9uJ3MgbWlkZGxlIHdoaWNoIGZpdHMgdGhlIHR3by10aGlyZC1yZWdpb25cbiAgICovXG4gIGZ1bmN0aW9uIGNhbGN1bGF0ZUludGVyc2VjdGlvblRocmVzaG9sZChjb25uZWN0aW9uLCBpbnRlcnNlY3Rpb24pIHtcbiAgICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHMsXG4gICAgICAgIHJlbGV2YW50U2VnbWVudCwgYWxpZ25tZW50LCBzZWdtZW50TGVuZ3RoLCB0aHJlc2hvbGQ7XG5cbiAgICBpZiAoaW50ZXJzZWN0aW9uLmluZGV4IDw9IDAgfHwgaW50ZXJzZWN0aW9uLmJlbmRwb2ludCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gc2VnbWVudCByZWxhdGl2ZSB0byBjb25uZWN0aW9uIGludGVyc2VjdGlvblxuICAgIHJlbGV2YW50U2VnbWVudCA9IHtcbiAgICAgIHN0YXJ0OiB3YXlwb2ludHNbaW50ZXJzZWN0aW9uLmluZGV4IC0gMV0sXG4gICAgICBlbmQ6IHdheXBvaW50c1tpbnRlcnNlY3Rpb24uaW5kZXhdXG4gICAgfTtcblxuICAgIGFsaWdubWVudCA9IHBvaW50c0FsaWduZWQocmVsZXZhbnRTZWdtZW50LnN0YXJ0LCByZWxldmFudFNlZ21lbnQuZW5kKTtcblxuICAgIGlmICghYWxpZ25tZW50KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoYWxpZ25tZW50ID09PSAnaCcpIHtcbiAgICAgIHNlZ21lbnRMZW5ndGggPSByZWxldmFudFNlZ21lbnQuZW5kLnggLSByZWxldmFudFNlZ21lbnQuc3RhcnQueDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VnbWVudExlbmd0aCA9IHJlbGV2YW50U2VnbWVudC5lbmQueSAtIHJlbGV2YW50U2VnbWVudC5zdGFydC55O1xuICAgIH1cblxuICAgIC8vIGNhbGN1bGF0ZSB0aHJlc2hvbGQgcmVsYXRpdmUgdG8gMi8zIG9mIHNlZ21lbnQgbGVuZ3RoXG4gICAgdGhyZXNob2xkID0gY2FsY3VsYXRlU2VnbWVudE1vdmVSZWdpb24oc2VnbWVudExlbmd0aCkgLyAyO1xuXG4gICAgcmV0dXJuIHRocmVzaG9sZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFjdGl2YXRlQmVuZHBvaW50TW92ZShldmVudCwgY29ubmVjdGlvbikge1xuICAgIHZhciB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgICAgaW50ZXJzZWN0aW9uID0gZ2V0Q29ubmVjdGlvbkludGVyc2VjdGlvbihjYW52YXMsIHdheXBvaW50cywgZXZlbnQpLFxuICAgICAgICB0aHJlc2hvbGQ7XG5cbiAgICBpZiAoIWludGVyc2VjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRocmVzaG9sZCA9IGNhbGN1bGF0ZUludGVyc2VjdGlvblRocmVzaG9sZChjb25uZWN0aW9uLCBpbnRlcnNlY3Rpb24pO1xuXG4gICAgaWYgKGlzSW50ZXJzZWN0aW9uTWlkZGxlKGludGVyc2VjdGlvbiwgd2F5cG9pbnRzLCB0aHJlc2hvbGQpKSB7XG4gICAgICBjb25uZWN0aW9uU2VnbWVudE1vdmUuc3RhcnQoZXZlbnQsIGNvbm5lY3Rpb24sIGludGVyc2VjdGlvbi5pbmRleCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJlbmRwb2ludE1vdmUuc3RhcnQoZXZlbnQsIGNvbm5lY3Rpb24sIGludGVyc2VjdGlvbi5pbmRleCwgIWludGVyc2VjdGlvbi5iZW5kcG9pbnQpO1xuICAgIH1cblxuICAgIC8vIHdlJ3ZlIGhhbmRsZWQgdGhlIGV2ZW50XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiBiaW5kSW50ZXJhY3Rpb25FdmVudHMobm9kZSwgZXZlbnROYW1lLCBlbGVtZW50KSB7XG5cbiAgICBkb21FdmVudC5iaW5kKG5vZGUsIGV2ZW50TmFtZSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIGludGVyYWN0aW9uRXZlbnRzLnRyaWdnZXJNb3VzZUV2ZW50KGV2ZW50TmFtZSwgZXZlbnQsIGVsZW1lbnQpO1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRCZW5kcG9pbnRzQ29udGFpbmVyKGVsZW1lbnQsIGNyZWF0ZSkge1xuXG4gICAgdmFyIGxheWVyID0gY2FudmFzLmdldExheWVyKCdvdmVybGF5cycpLFxuICAgICAgICBnZnggPSBkb21RdWVyeSgnLmRqcy1iZW5kcG9pbnRzW2RhdGEtZWxlbWVudC1pZD1cIicgKyBlc2NhcGVDU1MoZWxlbWVudC5pZCkgKyAnXCJdJywgbGF5ZXIpO1xuXG4gICAgaWYgKCFnZnggJiYgY3JlYXRlKSB7XG4gICAgICBnZnggPSBzdmdDcmVhdGUoJ2cnKTtcbiAgICAgIHN2Z0F0dHIoZ2Z4LCB7ICdkYXRhLWVsZW1lbnQtaWQnOiBlbGVtZW50LmlkIH0pO1xuICAgICAgc3ZnQ2xhc3NlcyhnZngpLmFkZCgnZGpzLWJlbmRwb2ludHMnKTtcblxuICAgICAgc3ZnQXBwZW5kKGxheWVyLCBnZngpO1xuXG4gICAgICBiaW5kSW50ZXJhY3Rpb25FdmVudHMoZ2Z4LCAnbW91c2Vkb3duJywgZWxlbWVudCk7XG4gICAgICBiaW5kSW50ZXJhY3Rpb25FdmVudHMoZ2Z4LCAnY2xpY2snLCBlbGVtZW50KTtcbiAgICAgIGJpbmRJbnRlcmFjdGlvbkV2ZW50cyhnZngsICdkYmxjbGljaycsIGVsZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBnZng7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTZWdtZW50RHJhZ2dlcihpZHgsIHBhcmVudEdmeCkge1xuICAgIHJldHVybiBkb21RdWVyeShcbiAgICAgICcuZGpzLXNlZ21lbnQtZHJhZ2dlcltkYXRhLXNlZ21lbnQtaWR4PVwiJyArIGlkeCArICdcIl0nLFxuICAgICAgcGFyZW50R2Z4XG4gICAgKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUJlbmRwb2ludHMoZ2Z4LCBjb25uZWN0aW9uKSB7XG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMuZm9yRWFjaChmdW5jdGlvbihwLCBpZHgpIHtcbiAgICAgIHZhciBiZW5kcG9pbnQgPSBhZGRCZW5kcG9pbnQoZ2Z4KTtcblxuICAgICAgc3ZnQXBwZW5kKGdmeCwgYmVuZHBvaW50KTtcblxuICAgICAgdHJhbnNsYXRlKGJlbmRwb2ludCwgcC54LCBwLnkpO1xuICAgIH0pO1xuXG4gICAgLy8gYWRkIGZsb2F0aW5nIGJlbmRwb2ludFxuICAgIGFkZEJlbmRwb2ludChnZngsICdmbG9hdGluZycpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlU2VnbWVudERyYWdnZXJzKGdmeCwgY29ubmVjdGlvbikge1xuXG4gICAgdmFyIHdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzO1xuXG4gICAgdmFyIHNlZ21lbnRTdGFydCxcbiAgICAgICAgc2VnbWVudEVuZCxcbiAgICAgICAgc2VnbWVudERyYWdnZXJHZng7XG5cbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IHdheXBvaW50cy5sZW5ndGg7IGkrKykge1xuXG4gICAgICBzZWdtZW50U3RhcnQgPSB3YXlwb2ludHNbaSAtIDFdO1xuICAgICAgc2VnbWVudEVuZCA9IHdheXBvaW50c1tpXTtcblxuICAgICAgaWYgKHBvaW50c0FsaWduZWQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKSkge1xuICAgICAgICBzZWdtZW50RHJhZ2dlckdmeCA9IGFkZFNlZ21lbnREcmFnZ2VyKGdmeCwgc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKTtcblxuICAgICAgICBzdmdBdHRyKHNlZ21lbnREcmFnZ2VyR2Z4LCB7ICdkYXRhLXNlZ21lbnQtaWR4JzogaSB9KTtcblxuICAgICAgICBiaW5kSW50ZXJhY3Rpb25FdmVudHMoc2VnbWVudERyYWdnZXJHZngsICdtb3VzZW1vdmUnLCBjb25uZWN0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjbGVhckJlbmRwb2ludHMoZ2Z4KSB7XG4gICAgZm9yRWFjaChkb21RdWVyeUFsbCgnLicgKyBCRU5EUE9JTlRfQ0xTLCBnZngpLCBmdW5jdGlvbihub2RlKSB7XG4gICAgICBzdmdSZW1vdmUobm9kZSk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBjbGVhclNlZ21lbnREcmFnZ2VycyhnZngpIHtcbiAgICBmb3JFYWNoKGRvbVF1ZXJ5QWxsKCcuJyArIFNFR01FTlRfRFJBR0dFUl9DTFMsIGdmeCksIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHN2Z1JlbW92ZShub2RlKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZEhhbmRsZXMoY29ubmVjdGlvbikge1xuXG4gICAgdmFyIGdmeCA9IGdldEJlbmRwb2ludHNDb250YWluZXIoY29ubmVjdGlvbik7XG5cbiAgICBpZiAoIWdmeCkge1xuICAgICAgZ2Z4ID0gZ2V0QmVuZHBvaW50c0NvbnRhaW5lcihjb25uZWN0aW9uLCB0cnVlKTtcblxuICAgICAgY3JlYXRlQmVuZHBvaW50cyhnZngsIGNvbm5lY3Rpb24pO1xuICAgICAgY3JlYXRlU2VnbWVudERyYWdnZXJzKGdmeCwgY29ubmVjdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdmeDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUhhbmRsZXMoY29ubmVjdGlvbikge1xuXG4gICAgdmFyIGdmeCA9IGdldEJlbmRwb2ludHNDb250YWluZXIoY29ubmVjdGlvbik7XG5cbiAgICBpZiAoZ2Z4KSB7XG4gICAgICBjbGVhclNlZ21lbnREcmFnZ2VycyhnZngpO1xuICAgICAgY2xlYXJCZW5kcG9pbnRzKGdmeCk7XG4gICAgICBjcmVhdGVTZWdtZW50RHJhZ2dlcnMoZ2Z4LCBjb25uZWN0aW9uKTtcbiAgICAgIGNyZWF0ZUJlbmRwb2ludHMoZ2Z4LCBjb25uZWN0aW9uKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVGbG9hdGluZ0JlbmRwb2ludFBvc2l0aW9uKHBhcmVudEdmeCwgaW50ZXJzZWN0aW9uKSB7XG4gICAgdmFyIGZsb2F0aW5nID0gZG9tUXVlcnkoJy5mbG9hdGluZycsIHBhcmVudEdmeCksXG4gICAgICAgIHBvaW50ID0gaW50ZXJzZWN0aW9uLnBvaW50O1xuXG4gICAgaWYgKCFmbG9hdGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyYW5zbGF0ZShmbG9hdGluZywgcG9pbnQueCwgcG9pbnQueSk7XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVNlZ21lbnREcmFnZ2VyUG9zaXRpb24ocGFyZW50R2Z4LCBpbnRlcnNlY3Rpb24sIHdheXBvaW50cykge1xuXG4gICAgdmFyIGRyYWdnZXJHZnggPSBnZXRTZWdtZW50RHJhZ2dlcihpbnRlcnNlY3Rpb24uaW5kZXgsIHBhcmVudEdmeCksXG4gICAgICAgIHNlZ21lbnRTdGFydCA9IHdheXBvaW50c1tpbnRlcnNlY3Rpb24uaW5kZXggLSAxXSxcbiAgICAgICAgc2VnbWVudEVuZCA9IHdheXBvaW50c1tpbnRlcnNlY3Rpb24uaW5kZXhdLFxuICAgICAgICBwb2ludCA9IGludGVyc2VjdGlvbi5wb2ludCxcbiAgICAgICAgbWlkID0gZ2V0TWlkUG9pbnQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKSxcbiAgICAgICAgYWxpZ25tZW50ID0gcG9pbnRzQWxpZ25lZChzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQpLFxuICAgICAgICBkcmFnZ2VyVmlzdWFsLCByZWxhdGl2ZVBvc2l0aW9uO1xuXG4gICAgaWYgKCFkcmFnZ2VyR2Z4KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZHJhZ2dlclZpc3VhbCA9IGdldERyYWdnZXJWaXN1YWwoZHJhZ2dlckdmeCk7XG5cbiAgICByZWxhdGl2ZVBvc2l0aW9uID0ge1xuICAgICAgeDogcG9pbnQueCAtIG1pZC54LFxuICAgICAgeTogcG9pbnQueSAtIG1pZC55XG4gICAgfTtcblxuICAgIGlmIChhbGlnbm1lbnQgPT09ICd2Jykge1xuXG4gICAgICAvLyByb3RhdGUgcG9zaXRpb25cbiAgICAgIHJlbGF0aXZlUG9zaXRpb24gPSB7XG4gICAgICAgIHg6IHJlbGF0aXZlUG9zaXRpb24ueSxcbiAgICAgICAgeTogcmVsYXRpdmVQb3NpdGlvbi54XG4gICAgICB9O1xuICAgIH1cblxuICAgIHRyYW5zbGF0ZShkcmFnZ2VyVmlzdWFsLCByZWxhdGl2ZVBvc2l0aW9uLngsIHJlbGF0aXZlUG9zaXRpb24ueSk7XG4gIH1cblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvbi5jaGFuZ2VkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB1cGRhdGVIYW5kbGVzKGV2ZW50LmVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvbi5yZW1vdmUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBnZnggPSBnZXRCZW5kcG9pbnRzQ29udGFpbmVyKGV2ZW50LmVsZW1lbnQpO1xuXG4gICAgaWYgKGdmeCkge1xuICAgICAgc3ZnUmVtb3ZlKGdmeCk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tYXJrZXIudXBkYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBlbGVtZW50ID0gZXZlbnQuZWxlbWVudCxcbiAgICAgICAgYmVuZHBvaW50c0dmeDtcblxuICAgIGlmICghZWxlbWVudC53YXlwb2ludHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBiZW5kcG9pbnRzR2Z4ID0gYWRkSGFuZGxlcyhlbGVtZW50KTtcblxuICAgIGlmIChldmVudC5hZGQpIHtcbiAgICAgIHN2Z0NsYXNzZXMoYmVuZHBvaW50c0dmeCkuYWRkKGV2ZW50Lm1hcmtlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN2Z0NsYXNzZXMoYmVuZHBvaW50c0dmeCkucmVtb3ZlKGV2ZW50Lm1hcmtlcik7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tb3VzZW1vdmUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICB3YXlwb2ludHMgPSBlbGVtZW50LndheXBvaW50cyxcbiAgICAgICAgYmVuZHBvaW50c0dmeCxcbiAgICAgICAgaW50ZXJzZWN0aW9uO1xuXG4gICAgaWYgKHdheXBvaW50cykge1xuICAgICAgYmVuZHBvaW50c0dmeCA9IGdldEJlbmRwb2ludHNDb250YWluZXIoZWxlbWVudCwgdHJ1ZSk7XG5cbiAgICAgIGludGVyc2VjdGlvbiA9IGdldENvbm5lY3Rpb25JbnRlcnNlY3Rpb24oY2FudmFzLCB3YXlwb2ludHMsIGV2ZW50Lm9yaWdpbmFsRXZlbnQpO1xuXG4gICAgICBpZiAoIWludGVyc2VjdGlvbikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHVwZGF0ZUZsb2F0aW5nQmVuZHBvaW50UG9zaXRpb24oYmVuZHBvaW50c0dmeCwgaW50ZXJzZWN0aW9uKTtcblxuICAgICAgaWYgKCFpbnRlcnNlY3Rpb24uYmVuZHBvaW50KSB7XG4gICAgICAgIHVwZGF0ZVNlZ21lbnREcmFnZ2VyUG9zaXRpb24oYmVuZHBvaW50c0dmeCwgaW50ZXJzZWN0aW9uLCB3YXlwb2ludHMpO1xuICAgICAgfVxuXG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tb3VzZWRvd24nLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIG9yaWdpbmFsRXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50LFxuICAgICAgICBlbGVtZW50ID0gZXZlbnQuZWxlbWVudDtcblxuICAgIGlmICghZWxlbWVudC53YXlwb2ludHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZXR1cm4gYWN0aXZhdGVCZW5kcG9pbnRNb3ZlKG9yaWdpbmFsRXZlbnQsIGVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignc2VsZWN0aW9uLmNoYW5nZWQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBuZXdTZWxlY3Rpb24gPSBldmVudC5uZXdTZWxlY3Rpb24sXG4gICAgICAgIHByaW1hcnkgPSBuZXdTZWxlY3Rpb25bMF07XG5cbiAgICBpZiAocHJpbWFyeSAmJiBwcmltYXJ5LndheXBvaW50cykge1xuICAgICAgYWRkSGFuZGxlcyhwcmltYXJ5KTtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudC53YXlwb2ludHMpIHtcbiAgICAgIGFkZEhhbmRsZXMoZWxlbWVudCk7XG4gICAgICBpbnRlcmFjdGlvbkV2ZW50cy5yZWdpc3RlckV2ZW50KGV2ZW50LmdmeCwgJ21vdXNlbW92ZScsICdlbGVtZW50Lm1vdXNlbW92ZScpO1xuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQub3V0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBpbnRlcmFjdGlvbkV2ZW50cy51bnJlZ2lzdGVyRXZlbnQoZXZlbnQuZ2Z4LCAnbW91c2Vtb3ZlJywgJ2VsZW1lbnQubW91c2Vtb3ZlJyk7XG4gIH0pO1xuXG4gIC8vIHVwZGF0ZSBiZW5kcG9pbnQgY29udGFpbmVyIGRhdGEgYXR0cmlidXRlIG9uIGVsZW1lbnQgSUQgY2hhbmdlXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LnVwZGF0ZUlkJywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBuZXdJZCA9IGNvbnRleHQubmV3SWQ7XG5cbiAgICBpZiAoZWxlbWVudC53YXlwb2ludHMpIHtcbiAgICAgIHZhciBiZW5kcG9pbnRDb250YWluZXIgPSBnZXRCZW5kcG9pbnRzQ29udGFpbmVyKGVsZW1lbnQpO1xuXG4gICAgICBpZiAoYmVuZHBvaW50Q29udGFpbmVyKSB7XG4gICAgICAgIHN2Z0F0dHIoYmVuZHBvaW50Q29udGFpbmVyLCB7ICdkYXRhLWVsZW1lbnQtaWQnOiBuZXdJZCB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIEFQSVxuXG4gIHRoaXMuYWRkSGFuZGxlcyA9IGFkZEhhbmRsZXM7XG4gIHRoaXMudXBkYXRlSGFuZGxlcyA9IHVwZGF0ZUhhbmRsZXM7XG4gIHRoaXMuZ2V0QmVuZHBvaW50c0NvbnRhaW5lciA9IGdldEJlbmRwb2ludHNDb250YWluZXI7XG4gIHRoaXMuZ2V0U2VnbWVudERyYWdnZXIgPSBnZXRTZWdtZW50RHJhZ2dlcjtcbn1cblxuQmVuZHBvaW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ2ludGVyYWN0aW9uRXZlbnRzJyxcbiAgJ2JlbmRwb2ludE1vdmUnLFxuICAnY29ubmVjdGlvblNlZ21lbnRNb3ZlJ1xuXTtcblxuXG5cbi8vIGhlbHBlciAvLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldERyYWdnZXJWaXN1YWwoZHJhZ2dlckdmeCkge1xuICByZXR1cm4gZG9tUXVlcnkoJy5kanMtdmlzdWFsJywgZHJhZ2dlckdmeCk7XG59IiwiaW1wb3J0IHtcbiAgcG9pbnRzQWxpZ25lZCxcbiAgcG9pbnRzT25MaW5lXG59IGZyb20gJy4uLy4uL3V0aWwvR2VvbWV0cnknO1xuXG5pbXBvcnQge1xuICBhZGRTZWdtZW50RHJhZ2dlcixcbiAgZ2V0Q29ubmVjdGlvbkludGVyc2VjdGlvblxufSBmcm9tICcuL0JlbmRwb2ludFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRNaWQsXG4gIGdldE9yaWVudGF0aW9uXG59IGZyb20gJy4uLy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxudmFyIE1BUktFUl9DT05ORUNUX0hPVkVSID0gJ2Nvbm5lY3QtaG92ZXInLFxuICAgIE1BUktFUl9DT05ORUNUX1VQREFUSU5HID0gJ2Rqcy11cGRhdGluZyc7XG5cbmltcG9ydCB7XG4gIGNsYXNzZXMgYXMgc3ZnQ2xhc3NlcyxcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7XG4gIHRyYW5zbGF0ZVxufSBmcm9tICcuLi8uLi91dGlsL1N2Z1RyYW5zZm9ybVV0aWwnO1xuXG5cbmZ1bmN0aW9uIGF4aXNBZGQocG9pbnQsIGF4aXMsIGRlbHRhKSB7XG4gIHJldHVybiBheGlzU2V0KHBvaW50LCBheGlzLCBwb2ludFtheGlzXSArIGRlbHRhKTtcbn1cblxuZnVuY3Rpb24gYXhpc1NldChwb2ludCwgYXhpcywgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiAoYXhpcyA9PT0gJ3gnID8gdmFsdWUgOiBwb2ludC54KSxcbiAgICB5OiAoYXhpcyA9PT0gJ3knID8gdmFsdWUgOiBwb2ludC55KVxuICB9O1xufVxuXG5mdW5jdGlvbiBheGlzRmVuY2VkKHBvc2l0aW9uLCBzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQsIGF4aXMpIHtcblxuICB2YXIgbWF4VmFsdWUgPSBNYXRoLm1heChzZWdtZW50U3RhcnRbYXhpc10sIHNlZ21lbnRFbmRbYXhpc10pLFxuICAgICAgbWluVmFsdWUgPSBNYXRoLm1pbihzZWdtZW50U3RhcnRbYXhpc10sIHNlZ21lbnRFbmRbYXhpc10pO1xuXG4gIHZhciBwYWRkaW5nID0gMjA7XG5cbiAgdmFyIGZlbmNlZFZhbHVlID0gTWF0aC5taW4oTWF0aC5tYXgobWluVmFsdWUgKyBwYWRkaW5nLCBwb3NpdGlvbltheGlzXSksIG1heFZhbHVlIC0gcGFkZGluZyk7XG5cbiAgcmV0dXJuIGF4aXNTZXQoc2VnbWVudFN0YXJ0LCBheGlzLCBmZW5jZWRWYWx1ZSk7XG59XG5cbmZ1bmN0aW9uIGZsaXBBeGlzKGF4aXMpIHtcbiAgcmV0dXJuIGF4aXMgPT09ICd4JyA/ICd5JyA6ICd4Jztcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGRvY2tpbmcgcG9pbnQgb24gdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogQ29tcHV0ZSBhIHJlYXNvbmFibGUgZG9ja2luZywgaWYgbm9uIGV4aXN0cy5cbiAqXG4gKiBAcGFyYW0gIHtQb2ludH0gcG9pbnRcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5TaGFwZX0gcmVmZXJlbmNlRWxlbWVudFxuICogQHBhcmFtICB7c3RyaW5nfSBtb3ZlQXhpcyAoeHx5KVxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5mdW5jdGlvbiBnZXREb2NraW5nKHBvaW50LCByZWZlcmVuY2VFbGVtZW50LCBtb3ZlQXhpcykge1xuXG4gIHZhciByZWZlcmVuY2VNaWQsXG4gICAgICBpbnZlcnNlQXhpcztcblxuICBpZiAocG9pbnQub3JpZ2luYWwpIHtcbiAgICByZXR1cm4gcG9pbnQub3JpZ2luYWw7XG4gIH0gZWxzZSB7XG4gICAgcmVmZXJlbmNlTWlkID0gZ2V0TWlkKHJlZmVyZW5jZUVsZW1lbnQpO1xuICAgIGludmVyc2VBeGlzID0gZmxpcEF4aXMobW92ZUF4aXMpO1xuXG4gICAgcmV0dXJuIGF4aXNTZXQocG9pbnQsIGludmVyc2VBeGlzLCByZWZlcmVuY2VNaWRbaW52ZXJzZUF4aXNdKTtcbiAgfVxufVxuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgaW1wbGVtZW50cyBtb3Zpbmcgb2YgYmVuZHBvaW50c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDb25uZWN0aW9uU2VnbWVudE1vdmUoXG4gICAgaW5qZWN0b3IsIGV2ZW50QnVzLCBjYW52YXMsXG4gICAgZHJhZ2dpbmcsIGdyYXBoaWNzRmFjdG9yeSwgbW9kZWxpbmcpIHtcblxuICAvLyBvcHRpb25hbCBjb25uZWN0aW9uIGRvY2tpbmcgaW50ZWdyYXRpb25cbiAgdmFyIGNvbm5lY3Rpb25Eb2NraW5nID0gaW5qZWN0b3IuZ2V0KCdjb25uZWN0aW9uRG9ja2luZycsIGZhbHNlKTtcblxuXG4gIC8vIEFQSVxuXG4gIHRoaXMuc3RhcnQgPSBmdW5jdGlvbihldmVudCwgY29ubmVjdGlvbiwgaWR4KSB7XG5cbiAgICB2YXIgY29udGV4dCxcbiAgICAgICAgZ2Z4ID0gY2FudmFzLmdldEdyYXBoaWNzKGNvbm5lY3Rpb24pLFxuICAgICAgICBzZWdtZW50U3RhcnRJbmRleCA9IGlkeCAtIDEsXG4gICAgICAgIHNlZ21lbnRFbmRJbmRleCA9IGlkeCxcbiAgICAgICAgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHMsXG4gICAgICAgIHNlZ21lbnRTdGFydCA9IHdheXBvaW50c1tzZWdtZW50U3RhcnRJbmRleF0sXG4gICAgICAgIHNlZ21lbnRFbmQgPSB3YXlwb2ludHNbc2VnbWVudEVuZEluZGV4XSxcbiAgICAgICAgaW50ZXJzZWN0aW9uID0gZ2V0Q29ubmVjdGlvbkludGVyc2VjdGlvbihjYW52YXMsIHdheXBvaW50cywgZXZlbnQpLFxuICAgICAgICBkaXJlY3Rpb24sIGF4aXMsIGRyYWdQb3NpdGlvbjtcblxuICAgIGRpcmVjdGlvbiA9IHBvaW50c0FsaWduZWQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKTtcblxuICAgIC8vIGRvIG5vdCBtb3ZlIGRpYWdvbmFsIGNvbm5lY3Rpb25cbiAgICBpZiAoIWRpcmVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHRoZSBheGlzIHdoZXJlIHdlIGFyZSBnb2luZyB0byBtb3ZlIHRoaW5nc1xuICAgIGF4aXMgPSBkaXJlY3Rpb24gPT09ICd2JyA/ICd4JyA6ICd5JztcblxuICAgIGlmIChzZWdtZW50U3RhcnRJbmRleCA9PT0gMCkge1xuICAgICAgc2VnbWVudFN0YXJ0ID0gZ2V0RG9ja2luZyhzZWdtZW50U3RhcnQsIGNvbm5lY3Rpb24uc291cmNlLCBheGlzKTtcbiAgICB9XG5cbiAgICBpZiAoc2VnbWVudEVuZEluZGV4ID09PSB3YXlwb2ludHMubGVuZ3RoIC0gMSkge1xuICAgICAgc2VnbWVudEVuZCA9IGdldERvY2tpbmcoc2VnbWVudEVuZCwgY29ubmVjdGlvbi50YXJnZXQsIGF4aXMpO1xuICAgIH1cblxuICAgIGlmIChpbnRlcnNlY3Rpb24pIHtcbiAgICAgIGRyYWdQb3NpdGlvbiA9IGludGVyc2VjdGlvbi5wb2ludDtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBzZXQgdG8gc2VnbWVudCBjZW50ZXIgYXMgZGVmYXVsdFxuICAgICAgZHJhZ1Bvc2l0aW9uID0ge1xuICAgICAgICB4OiAoc2VnbWVudFN0YXJ0LnggKyBzZWdtZW50RW5kLngpIC8gMixcbiAgICAgICAgeTogKHNlZ21lbnRTdGFydC55ICsgc2VnbWVudEVuZC55KSAvIDJcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29udGV4dCA9IHtcbiAgICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgICBzZWdtZW50U3RhcnRJbmRleDogc2VnbWVudFN0YXJ0SW5kZXgsXG4gICAgICBzZWdtZW50RW5kSW5kZXg6IHNlZ21lbnRFbmRJbmRleCxcbiAgICAgIHNlZ21lbnRTdGFydDogc2VnbWVudFN0YXJ0LFxuICAgICAgc2VnbWVudEVuZDogc2VnbWVudEVuZCxcbiAgICAgIGF4aXM6IGF4aXMsXG4gICAgICBkcmFnUG9zaXRpb246IGRyYWdQb3NpdGlvblxuICAgIH07XG5cbiAgICBkcmFnZ2luZy5pbml0KGV2ZW50LCBkcmFnUG9zaXRpb24sICdjb25uZWN0aW9uU2VnbWVudC5tb3ZlJywge1xuICAgICAgY3Vyc29yOiBheGlzID09PSAneCcgPyAncmVzaXplLWV3JyA6ICdyZXNpemUtbnMnLFxuICAgICAgZGF0YToge1xuICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgICAgICBjb25uZWN0aW9uR2Z4OiBnZngsXG4gICAgICAgIGNvbnRleHQ6IGNvbnRleHRcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogQ3JvcCBjb25uZWN0aW9uIGlmIGNvbm5lY3Rpb24gY3JvcHBpbmcgaXMgcHJvdmlkZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7Q29ubmVjdGlvbn0gY29ubmVjdGlvblxuICAgKiBAcGFyYW0ge0FycmF5PFBvaW50Pn0gbmV3V2F5cG9pbnRzXG4gICAqXG4gICAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gY3JvcHBlZCBjb25uZWN0aW9uIHdheXBvaW50c1xuICAgKi9cbiAgZnVuY3Rpb24gY3JvcENvbm5lY3Rpb24oY29ubmVjdGlvbiwgbmV3V2F5cG9pbnRzKSB7XG5cbiAgICAvLyBjcm9wIGNvbm5lY3Rpb24sIGlmIGRvY2tpbmcgc2VydmljZSBpcyBwcm92aWRlZCBvbmx5XG4gICAgaWYgKCFjb25uZWN0aW9uRG9ja2luZykge1xuICAgICAgcmV0dXJuIG5ld1dheXBvaW50cztcbiAgICB9XG5cbiAgICB2YXIgb2xkV2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHMsXG4gICAgICAgIGNyb3BwZWRXYXlwb2ludHM7XG5cbiAgICAvLyB0ZW1wb3Jhcnkgc2V0IG5ldyB3YXlwb2ludHNcbiAgICBjb25uZWN0aW9uLndheXBvaW50cyA9IG5ld1dheXBvaW50cztcblxuICAgIGNyb3BwZWRXYXlwb2ludHMgPSBjb25uZWN0aW9uRG9ja2luZy5nZXRDcm9wcGVkV2F5cG9pbnRzKGNvbm5lY3Rpb24pO1xuXG4gICAgLy8gcmVzdG9yZSBvbGQgd2F5cG9pbnRzXG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBvbGRXYXlwb2ludHM7XG5cbiAgICByZXR1cm4gY3JvcHBlZFdheXBvaW50cztcbiAgfVxuXG4gIC8vIERSQUdHSU5HIElNUExFTUVOVEFUSU9OXG5cbiAgZnVuY3Rpb24gcmVkcmF3Q29ubmVjdGlvbihkYXRhKSB7XG4gICAgZ3JhcGhpY3NGYWN0b3J5LnVwZGF0ZSgnY29ubmVjdGlvbicsIGRhdGEuY29ubmVjdGlvbiwgZGF0YS5jb25uZWN0aW9uR2Z4KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZURyYWdnZXIoY29udGV4dCwgc2VnbWVudE9mZnNldCwgZXZlbnQpIHtcblxuICAgIHZhciBuZXdXYXlwb2ludHMgPSBjb250ZXh0Lm5ld1dheXBvaW50cyxcbiAgICAgICAgc2VnbWVudFN0YXJ0SW5kZXggPSBjb250ZXh0LnNlZ21lbnRTdGFydEluZGV4ICsgc2VnbWVudE9mZnNldCxcbiAgICAgICAgc2VnbWVudFN0YXJ0ID0gbmV3V2F5cG9pbnRzW3NlZ21lbnRTdGFydEluZGV4XSxcbiAgICAgICAgc2VnbWVudEVuZEluZGV4ID0gY29udGV4dC5zZWdtZW50RW5kSW5kZXggKyBzZWdtZW50T2Zmc2V0LFxuICAgICAgICBzZWdtZW50RW5kID0gbmV3V2F5cG9pbnRzW3NlZ21lbnRFbmRJbmRleF0sXG4gICAgICAgIGF4aXMgPSBmbGlwQXhpcyhjb250ZXh0LmF4aXMpO1xuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBkcmFnZ2VyIGRvZXMgbm90IG1vdmVcbiAgICAvLyBvdXRzaWRlIHRoZSBjb25uZWN0aW9uXG4gICAgdmFyIGRyYWdnZXJQb3NpdGlvbiA9IGF4aXNGZW5jZWQoZXZlbnQsIHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCwgYXhpcyk7XG5cbiAgICAvLyB1cGRhdGUgZHJhZ2dlclxuICAgIHRyYW5zbGF0ZShjb250ZXh0LmRyYWdnZXJHZngsIGRyYWdnZXJQb3NpdGlvbi54LCBkcmFnZ2VyUG9zaXRpb24ueSk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVyIHdheXBvaW50cyBmb3IgcmVkdW5kYW50IG9uZXMgKGkuZS4gb24gdGhlIHNhbWUgYXhpcykuXG4gICAqIFJldHVybnMgdGhlIGZpbHRlcmVkIHdheXBvaW50cyBhbmQgdGhlIG9mZnNldCByZWxhdGVkIHRvIHRoZSBzZWdtZW50IG1vdmUuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBzZWdtZW50U3RhcnRJbmRleCBvZiBtb3ZlZCBzZWdtZW50IHN0YXJ0XG4gICAqXG4gICAqIEByZXR1cm4ge09iamVjdH0geyBmaWx0ZXJlZFdheXBvaW50cywgc2VnbWVudE9mZnNldCB9XG4gICAqL1xuICBmdW5jdGlvbiBmaWx0ZXJSZWR1bmRhbnRXYXlwb2ludHMod2F5cG9pbnRzLCBzZWdtZW50U3RhcnRJbmRleCkge1xuXG4gICAgdmFyIHNlZ21lbnRPZmZzZXQgPSAwO1xuXG4gICAgdmFyIGZpbHRlcmVkV2F5cG9pbnRzID0gd2F5cG9pbnRzLmZpbHRlcihmdW5jdGlvbihyLCBpZHgpIHtcbiAgICAgIGlmIChwb2ludHNPbkxpbmUod2F5cG9pbnRzW2lkeCAtIDFdLCB3YXlwb2ludHNbaWR4ICsgMV0sIHIpKSB7XG5cbiAgICAgICAgLy8gcmVtb3ZlIHBvaW50IGFuZCBpbmNyZW1lbnQgb2Zmc2V0XG4gICAgICAgIHNlZ21lbnRPZmZzZXQgPSBpZHggPD0gc2VnbWVudFN0YXJ0SW5kZXggPyBzZWdtZW50T2Zmc2V0IC0gMSA6IHNlZ21lbnRPZmZzZXQ7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gZG9udCByZW1vdmUgcG9pbnRcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHdheXBvaW50czogZmlsdGVyZWRXYXlwb2ludHMsXG4gICAgICBzZWdtZW50T2Zmc2V0OiBzZWdtZW50T2Zmc2V0XG4gICAgfTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjb25uZWN0aW9uU2VnbWVudC5tb3ZlLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGV2ZW50LmNvbm5lY3Rpb24sXG4gICAgICAgIGxheWVyID0gY2FudmFzLmdldExheWVyKCdvdmVybGF5cycpO1xuXG4gICAgY29udGV4dC5vcmlnaW5hbFdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzLnNsaWNlKCk7XG5cbiAgICAvLyBhZGQgZHJhZ2dlciBnZnhcbiAgICBjb250ZXh0LmRyYWdnZXJHZnggPSBhZGRTZWdtZW50RHJhZ2dlcihsYXllciwgY29udGV4dC5zZWdtZW50U3RhcnQsIGNvbnRleHQuc2VnbWVudEVuZCk7XG4gICAgc3ZnQ2xhc3Nlcyhjb250ZXh0LmRyYWdnZXJHZngpLmFkZCgnZGpzLWRyYWdnaW5nJyk7XG5cbiAgICBjYW52YXMuYWRkTWFya2VyKGNvbm5lY3Rpb24sIE1BUktFUl9DT05ORUNUX1VQREFUSU5HKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHNlZ21lbnRTdGFydEluZGV4ID0gY29udGV4dC5zZWdtZW50U3RhcnRJbmRleCxcbiAgICAgICAgc2VnbWVudEVuZEluZGV4ID0gY29udGV4dC5zZWdtZW50RW5kSW5kZXgsXG4gICAgICAgIHNlZ21lbnRTdGFydCA9IGNvbnRleHQuc2VnbWVudFN0YXJ0LFxuICAgICAgICBzZWdtZW50RW5kID0gY29udGV4dC5zZWdtZW50RW5kLFxuICAgICAgICBheGlzID0gY29udGV4dC5heGlzO1xuXG4gICAgdmFyIG5ld1dheXBvaW50cyA9IGNvbnRleHQub3JpZ2luYWxXYXlwb2ludHMuc2xpY2UoKSxcbiAgICAgICAgbmV3U2VnbWVudFN0YXJ0ID0gYXhpc0FkZChzZWdtZW50U3RhcnQsIGF4aXMsIGV2ZW50WydkJyArIGF4aXNdKSxcbiAgICAgICAgbmV3U2VnbWVudEVuZCA9IGF4aXNBZGQoc2VnbWVudEVuZCwgYXhpcywgZXZlbnRbJ2QnICsgYXhpc10pO1xuXG4gICAgLy8gb3JpZ2luYWwgd2F5cG9pbnQgY291bnQgYW5kIGFkZGVkIC8gcmVtb3ZlZFxuICAgIC8vIGZyb20gc3RhcnQgd2F5cG9pbnQgZGVsdGEuIFdlIHVzZSB0aGUgbGF0ZXJcbiAgICAvLyB0byByZXRyaWV2ZSB0aGUgdXBkYXRlZCBzZWdtZW50U3RhcnRJbmRleCAvIHNlZ21lbnRFbmRJbmRleFxuICAgIHZhciB3YXlwb2ludENvdW50ID0gbmV3V2F5cG9pbnRzLmxlbmd0aCxcbiAgICAgICAgc2VnbWVudE9mZnNldCA9IDA7XG5cbiAgICAvLyBtb3ZlIHNlZ21lbnQgc3RhcnQgLyBlbmQgYnkgYXhpcyBkZWx0YVxuICAgIG5ld1dheXBvaW50c1tzZWdtZW50U3RhcnRJbmRleF0gPSBuZXdTZWdtZW50U3RhcnQ7XG4gICAgbmV3V2F5cG9pbnRzW3NlZ21lbnRFbmRJbmRleF0gPSBuZXdTZWdtZW50RW5kO1xuXG4gICAgdmFyIHNvdXJjZVRvU2VnbWVudE9yaWVudGF0aW9uLFxuICAgICAgICB0YXJnZXRUb1NlZ21lbnRPcmllbnRhdGlvbjtcblxuICAgIC8vIGhhbmRsZSBmaXJzdCBzZWdtZW50XG4gICAgaWYgKHNlZ21lbnRTdGFydEluZGV4IDwgMikge1xuICAgICAgc291cmNlVG9TZWdtZW50T3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihjb25uZWN0aW9uLnNvdXJjZSwgbmV3U2VnbWVudFN0YXJ0KTtcblxuICAgICAgLy8gZmlyc3QgYmVuZHBvaW50LCByZW1vdmUgZmlyc3Qgc2VnbWVudCBpZiBpbnRlcnNlY3RpbmdcbiAgICAgIGlmIChzZWdtZW50U3RhcnRJbmRleCA9PT0gMSkge1xuXG4gICAgICAgIGlmIChzb3VyY2VUb1NlZ21lbnRPcmllbnRhdGlvbiA9PT0gJ2ludGVyc2VjdCcpIHtcbiAgICAgICAgICBuZXdXYXlwb2ludHMuc2hpZnQoKTtcbiAgICAgICAgICBuZXdXYXlwb2ludHNbMF0gPSBuZXdTZWdtZW50U3RhcnQ7XG4gICAgICAgICAgc2VnbWVudE9mZnNldC0tO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGRvY2tpbmcgcG9pbnQsIGFkZCBzZWdtZW50IGlmIG5vdCBpbnRlcnNlY3RpbmcgYW55bW9yZVxuICAgICAgZWxzZSB7XG4gICAgICAgIGlmIChzb3VyY2VUb1NlZ21lbnRPcmllbnRhdGlvbiAhPT0gJ2ludGVyc2VjdCcpIHtcbiAgICAgICAgICBuZXdXYXlwb2ludHMudW5zaGlmdChzZWdtZW50U3RhcnQpO1xuICAgICAgICAgIHNlZ21lbnRPZmZzZXQrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGhhbmRsZSBsYXN0IHNlZ21lbnRcbiAgICBpZiAoc2VnbWVudEVuZEluZGV4ID4gd2F5cG9pbnRDb3VudCAtIDMpIHtcbiAgICAgIHRhcmdldFRvU2VnbWVudE9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24oY29ubmVjdGlvbi50YXJnZXQsIG5ld1NlZ21lbnRFbmQpO1xuXG4gICAgICAvLyBsYXN0IGJlbmRwb2ludCwgcmVtb3ZlIGxhc3Qgc2VnbWVudCBpZiBpbnRlcnNlY3RpbmdcbiAgICAgIGlmIChzZWdtZW50RW5kSW5kZXggPT09IHdheXBvaW50Q291bnQgLSAyKSB7XG5cbiAgICAgICAgaWYgKHRhcmdldFRvU2VnbWVudE9yaWVudGF0aW9uID09PSAnaW50ZXJzZWN0Jykge1xuICAgICAgICAgIG5ld1dheXBvaW50cy5wb3AoKTtcbiAgICAgICAgICBuZXdXYXlwb2ludHNbbmV3V2F5cG9pbnRzLmxlbmd0aCAtIDFdID0gbmV3U2VnbWVudEVuZDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBsYXN0IGJlbmRwb2ludCwgcmVtb3ZlIGxhc3Qgc2VnbWVudCBpZiBpbnRlcnNlY3RpbmdcbiAgICAgIGVsc2Uge1xuICAgICAgICBpZiAodGFyZ2V0VG9TZWdtZW50T3JpZW50YXRpb24gIT09ICdpbnRlcnNlY3QnKSB7XG4gICAgICAgICAgbmV3V2F5cG9pbnRzLnB1c2goc2VnbWVudEVuZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB1cGRhdGUgY29ubmVjdGlvbiB3YXlwb2ludHNcbiAgICBjb250ZXh0Lm5ld1dheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gY3JvcENvbm5lY3Rpb24oY29ubmVjdGlvbiwgbmV3V2F5cG9pbnRzKTtcblxuICAgIC8vIHVwZGF0ZSBkcmFnZ2VyIHBvc2l0aW9uXG4gICAgdXBkYXRlRHJhZ2dlcihjb250ZXh0LCBzZWdtZW50T2Zmc2V0LCBldmVudCk7XG5cbiAgICAvLyBzYXZlIHNlZ21lbnRPZmZzZXQgaW4gY29udGV4dFxuICAgIGNvbnRleHQubmV3U2VnbWVudFN0YXJ0SW5kZXggPSBzZWdtZW50U3RhcnRJbmRleCArIHNlZ21lbnRPZmZzZXQ7XG5cbiAgICAvLyByZWRyYXcgY29ubmVjdGlvblxuICAgIHJlZHJhd0Nvbm5lY3Rpb24oZXZlbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvblNlZ21lbnQubW92ZS5ob3ZlcicsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICBldmVudC5jb250ZXh0LmhvdmVyID0gZXZlbnQuaG92ZXI7XG4gICAgY2FudmFzLmFkZE1hcmtlcihldmVudC5ob3ZlciwgTUFSS0VSX0NPTk5FQ1RfSE9WRVIpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbXG4gICAgJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUub3V0JyxcbiAgICAnY29ubmVjdGlvblNlZ21lbnQubW92ZS5jbGVhbnVwJ1xuICBdLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgLy8gcmVtb3ZlIGNvbm5lY3QgbWFya2VyXG4gICAgLy8gaWYgaXQgd2FzIGFkZGVkXG4gICAgdmFyIGhvdmVyID0gZXZlbnQuY29udGV4dC5ob3ZlcjtcblxuICAgIGlmIChob3Zlcikge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgTUFSS0VSX0NPTk5FQ1RfSE9WRVIpO1xuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUuY2xlYW51cCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb247XG5cbiAgICAvLyByZW1vdmUgZHJhZ2dlciBnZnhcbiAgICBpZiAoY29udGV4dC5kcmFnZ2VyR2Z4KSB7XG4gICAgICBzdmdSZW1vdmUoY29udGV4dC5kcmFnZ2VyR2Z4KTtcbiAgICB9XG5cbiAgICBjYW52YXMucmVtb3ZlTWFya2VyKGNvbm5lY3Rpb24sIE1BUktFUl9DT05ORUNUX1VQREFUSU5HKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oW1xuICAgICdjb25uZWN0aW9uU2VnbWVudC5tb3ZlLmNhbmNlbCcsXG4gICAgJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUuZW5kJ1xuICBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbjtcblxuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gY29udGV4dC5vcmlnaW5hbFdheXBvaW50cztcblxuICAgIHJlZHJhd0Nvbm5lY3Rpb24oZXZlbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvblNlZ21lbnQubW92ZS5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBuZXdXYXlwb2ludHMgPSBjb250ZXh0Lm5ld1dheXBvaW50cyxcbiAgICAgICAgbmV3U2VnbWVudFN0YXJ0SW5kZXggPSBjb250ZXh0Lm5ld1NlZ21lbnRTdGFydEluZGV4O1xuXG4gICAgLy8gZW5zdXJlIHdlIGhhdmUgYWN0dWFsIHBpeGVsIHZhbHVlcyBiZW5kcG9pbnRcbiAgICAvLyBjb29yZGluYXRlcyAoaW1wb3J0YW50IHdoZW4gem9vbSBsZXZlbCB3YXMgPiAxIGR1cmluZyBtb3ZlKVxuICAgIG5ld1dheXBvaW50cyA9IG5ld1dheXBvaW50cy5tYXAoZnVuY3Rpb24ocCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3JpZ2luYWw6IHAub3JpZ2luYWwsXG4gICAgICAgIHg6IE1hdGgucm91bmQocC54KSxcbiAgICAgICAgeTogTWF0aC5yb3VuZChwLnkpXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gYXBwbHkgZmlsdGVyIHJlZHVuYW50IHdheXBvaW50c1xuICAgIHZhciBmaWx0ZXJlZCA9IGZpbHRlclJlZHVuZGFudFdheXBvaW50cyhuZXdXYXlwb2ludHMsIG5ld1NlZ21lbnRTdGFydEluZGV4KTtcblxuICAgIC8vIGdldCBmaWx0ZXJlZCB3YXlwb2ludHNcbiAgICB2YXIgZmlsdGVyZWRXYXlwb2ludHMgPSBmaWx0ZXJlZC53YXlwb2ludHMsXG4gICAgICAgIGNyb3BwZWRXYXlwb2ludHMgPSBjcm9wQ29ubmVjdGlvbihjb25uZWN0aW9uLCBmaWx0ZXJlZFdheXBvaW50cyksXG4gICAgICAgIHNlZ21lbnRPZmZzZXQgPSBmaWx0ZXJlZC5zZWdtZW50T2Zmc2V0O1xuXG4gICAgdmFyIGhpbnRzID0ge1xuICAgICAgc2VnbWVudE1vdmU6IHtcbiAgICAgICAgc2VnbWVudFN0YXJ0SW5kZXg6IGNvbnRleHQuc2VnbWVudFN0YXJ0SW5kZXgsXG4gICAgICAgIG5ld1NlZ21lbnRTdGFydEluZGV4OiBuZXdTZWdtZW50U3RhcnRJbmRleCArIHNlZ21lbnRPZmZzZXRcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgbW9kZWxpbmcudXBkYXRlV2F5cG9pbnRzKGNvbm5lY3Rpb24sIGNyb3BwZWRXYXlwb2ludHMsIGhpbnRzKTtcbiAgfSk7XG59XG5cbkNvbm5lY3Rpb25TZWdtZW50TW92ZS4kaW5qZWN0ID0gW1xuICAnaW5qZWN0b3InLFxuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ2RyYWdnaW5nJyxcbiAgJ2dyYXBoaWNzRmFjdG9yeScsXG4gICdtb2RlbGluZydcbl07XG4iLCJpbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuaW1wb3J0IFJ1bGVzTW9kdWxlIGZyb20gJy4uL3J1bGVzJztcblxuaW1wb3J0IEJlbmRwb2ludHMgZnJvbSAnLi9CZW5kcG9pbnRzJztcbmltcG9ydCBCZW5kcG9pbnRNb3ZlIGZyb20gJy4vQmVuZHBvaW50TW92ZSc7XG5pbXBvcnQgQmVuZHBvaW50TW92ZVByZXZpZXcgZnJvbSAnLi9CZW5kcG9pbnRNb3ZlUHJldmlldyc7XG5pbXBvcnQgQ29ubmVjdGlvblNlZ21lbnRNb3ZlIGZyb20gJy4vQ29ubmVjdGlvblNlZ21lbnRNb3ZlJztcbmltcG9ydCBCZW5kcG9pbnRTbmFwcGluZyBmcm9tICcuL0JlbmRwb2ludFNuYXBwaW5nJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgRHJhZ2dpbmdNb2R1bGUsXG4gICAgUnVsZXNNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2JlbmRwb2ludHMnLCAnYmVuZHBvaW50U25hcHBpbmcnLCAnYmVuZHBvaW50TW92ZVByZXZpZXcnIF0sXG4gIGJlbmRwb2ludHM6IFsgJ3R5cGUnLCBCZW5kcG9pbnRzIF0sXG4gIGJlbmRwb2ludE1vdmU6IFsgJ3R5cGUnLCBCZW5kcG9pbnRNb3ZlIF0sXG4gIGJlbmRwb2ludE1vdmVQcmV2aWV3OiBbICd0eXBlJywgQmVuZHBvaW50TW92ZVByZXZpZXcgXSxcbiAgY29ubmVjdGlvblNlZ21lbnRNb3ZlOiBbICd0eXBlJywgQ29ubmVjdGlvblNlZ21lbnRNb3ZlIF0sXG4gIGJlbmRwb2ludFNuYXBwaW5nOiBbICd0eXBlJywgQmVuZHBvaW50U25hcHBpbmcgXVxufTtcbiIsImltcG9ydCB7XG4gIGdldFR5cGUgYXMgZ2V0RWxlbWVudFR5cGVcbn0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbi8qKlxuICogQWRkcyBjaGFuZ2Ugc3VwcG9ydCB0byB0aGUgZGlhZ3JhbSwgaW5jbHVkaW5nXG4gKlxuICogPHVsPlxuICogICA8bGk+cmVkcmF3aW5nIHNoYXBlcyBhbmQgY29ubmVjdGlvbnMgb24gY2hhbmdlPC9saT5cbiAqIDwvdWw+XG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcbiAqIEBwYXJhbSB7R3JhcGhpY3NGYWN0b3J5fSBncmFwaGljc0ZhY3RvcnlcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ2hhbmdlU3VwcG9ydChcbiAgICBldmVudEJ1cywgY2FudmFzLCBlbGVtZW50UmVnaXN0cnksXG4gICAgZ3JhcGhpY3NGYWN0b3J5KSB7XG5cblxuICAvLyByZWRyYXcgc2hhcGVzIC8gY29ubmVjdGlvbnMgb24gY2hhbmdlXG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQuY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQ7XG5cbiAgICAvLyBlbGVtZW50IG1pZ2h0IGhhdmUgYmVlbiBkZWxldGVkIGFuZCByZXBsYWNlZCBieSBuZXcgZWxlbWVudCB3aXRoIHNhbWUgSURcbiAgICAvLyB0aHVzIGNoZWNrIGZvciBwYXJlbnQgb2YgZWxlbWVudCBleGNlcHQgZm9yIHJvb3QgZWxlbWVudFxuICAgIGlmIChlbGVtZW50LnBhcmVudCB8fCBlbGVtZW50ID09PSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSkge1xuICAgICAgZXZlbnQuZ2Z4ID0gZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIC8vIHNoYXBlICsgZ2Z4IG1heSBoYXZlIGJlZW4gZGVsZXRlZFxuICAgIGlmICghZXZlbnQuZ2Z4KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZXZlbnRCdXMuZmlyZShnZXRFbGVtZW50VHlwZShlbGVtZW50KSArICcuY2hhbmdlZCcsIGV2ZW50KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnRzLmNoYW5nZWQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGVsZW1lbnRzID0gZXZlbnQuZWxlbWVudHM7XG5cbiAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGUpIHtcbiAgICAgIGV2ZW50QnVzLmZpcmUoJ2VsZW1lbnQuY2hhbmdlZCcsIHsgZWxlbWVudDogZSB9KTtcbiAgICB9KTtcblxuICAgIGdyYXBoaWNzRmFjdG9yeS51cGRhdGVDb250YWlubWVudHMoZWxlbWVudHMpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignc2hhcGUuY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZ3JhcGhpY3NGYWN0b3J5LnVwZGF0ZSgnc2hhcGUnLCBldmVudC5lbGVtZW50LCBldmVudC5nZngpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvbi5jaGFuZ2VkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBncmFwaGljc0ZhY3RvcnkudXBkYXRlKCdjb25uZWN0aW9uJywgZXZlbnQuZWxlbWVudCwgZXZlbnQuZ2Z4KTtcbiAgfSk7XG59XG5cbkNoYW5nZVN1cHBvcnQuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcycsXG4gICdlbGVtZW50UmVnaXN0cnknLFxuICAnZ3JhcGhpY3NGYWN0b3J5J1xuXTsiLCJpbXBvcnQgQ2hhbmdlU3VwcG9ydCBmcm9tICcuL0NoYW5nZVN1cHBvcnQnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdjaGFuZ2VTdXBwb3J0J10sXG4gIGNoYW5nZVN1cHBvcnQ6IFsgJ3R5cGUnLCBDaGFuZ2VTdXBwb3J0IF1cbn07IiwiLyoqXG4gKiBBIGNsaXAgYm9hcmQgc3R1YlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDbGlwYm9hcmQoKSB7fVxuXG5cbkNsaXBib2FyZC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9kYXRhO1xufTtcblxuQ2xpcGJvYXJkLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbihkYXRhKSB7XG4gIHRoaXMuX2RhdGEgPSBkYXRhO1xufTtcblxuQ2xpcGJvYXJkLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7XG5cbiAgZGVsZXRlIHRoaXMuX2RhdGE7XG5cbiAgcmV0dXJuIGRhdGE7XG59O1xuXG5DbGlwYm9hcmQucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuICF0aGlzLl9kYXRhO1xufTsiLCJpbXBvcnQgQ2xpcGJvYXJkIGZyb20gJy4vQ2xpcGJvYXJkJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBjbGlwYm9hcmQ6IFsgJ3R5cGUnLCBDbGlwYm9hcmQgXVxufTtcbiIsImltcG9ydCB7XG4gIGdldE1pZFxufSBmcm9tICcuLi8uLi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzTmlsLFxuICBpc09iamVjdFxufSBmcm9tICdtaW4tZGFzaCc7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ29ubmVjdChldmVudEJ1cywgZHJhZ2dpbmcsIG1vZGVsaW5nLCBydWxlcykge1xuXG4gIC8vIHJ1bGVzXG5cbiAgZnVuY3Rpb24gY2FuQ29ubmVjdChzb3VyY2UsIHRhcmdldCkge1xuICAgIHJldHVybiBydWxlcy5hbGxvd2VkKCdjb25uZWN0aW9uLmNyZWF0ZScsIHtcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbkNvbm5lY3RSZXZlcnNlKHNvdXJjZSwgdGFyZ2V0KSB7XG4gICAgcmV0dXJuIGNhbkNvbm5lY3QodGFyZ2V0LCBzb3VyY2UpO1xuICB9XG5cblxuICAvLyBldmVudCBoYW5kbGVyc1xuXG4gIGV2ZW50QnVzLm9uKCdjb25uZWN0LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHN0YXJ0ID0gY29udGV4dC5zdGFydCxcbiAgICAgICAgaG92ZXIgPSBldmVudC5ob3ZlcixcbiAgICAgICAgY2FuRXhlY3V0ZTtcblxuICAgIC8vIGNhY2hlIGhvdmVyIHN0YXRlXG4gICAgY29udGV4dC5ob3ZlciA9IGhvdmVyO1xuXG4gICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSA9IGNhbkNvbm5lY3Qoc3RhcnQsIGhvdmVyKTtcblxuICAgIC8vIGlnbm9yZSBob3ZlclxuICAgIGlmIChpc05pbChjYW5FeGVjdXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjYW5FeGVjdXRlICE9PSBmYWxzZSkge1xuICAgICAgY29udGV4dC5zb3VyY2UgPSBzdGFydDtcbiAgICAgIGNvbnRleHQudGFyZ2V0ID0gaG92ZXI7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlID0gY2FuQ29ubmVjdFJldmVyc2Uoc3RhcnQsIGhvdmVyKTtcblxuICAgIC8vIGlnbm9yZSBob3ZlclxuICAgIGlmIChpc05pbChjYW5FeGVjdXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjYW5FeGVjdXRlICE9PSBmYWxzZSkge1xuICAgICAgY29udGV4dC5zb3VyY2UgPSBob3ZlcjtcbiAgICAgIGNvbnRleHQudGFyZ2V0ID0gc3RhcnQ7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdjb25uZWN0Lm91dCcsICdjb25uZWN0LmNsZWFudXAnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0O1xuXG4gICAgY29udGV4dC5ob3ZlciA9IG51bGw7XG4gICAgY29udGV4dC5zb3VyY2UgPSBudWxsO1xuICAgIGNvbnRleHQudGFyZ2V0ID0gbnVsbDtcblxuICAgIGNvbnRleHQuY2FuRXhlY3V0ZSA9IGZhbHNlO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdC5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSxcbiAgICAgICAgY29ubmVjdGlvblN0YXJ0ID0gY29udGV4dC5jb25uZWN0aW9uU3RhcnQsXG4gICAgICAgIGNvbm5lY3Rpb25FbmQgPSB7XG4gICAgICAgICAgeDogZXZlbnQueCxcbiAgICAgICAgICB5OiBldmVudC55XG4gICAgICAgIH0sXG4gICAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIGlmICghY2FuRXhlY3V0ZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBhdHRycyA9IG51bGwsXG4gICAgICAgIGhpbnRzID0ge1xuICAgICAgICAgIGNvbm5lY3Rpb25TdGFydDogaXNSZXZlcnNlKGNvbnRleHQpID8gY29ubmVjdGlvbkVuZCA6IGNvbm5lY3Rpb25TdGFydCxcbiAgICAgICAgICBjb25uZWN0aW9uRW5kOiBpc1JldmVyc2UoY29udGV4dCkgPyBjb25uZWN0aW9uU3RhcnQgOiBjb25uZWN0aW9uRW5kXG4gICAgICAgIH07XG5cbiAgICBpZiAoaXNPYmplY3QoY2FuRXhlY3V0ZSkpIHtcbiAgICAgIGF0dHJzID0gY2FuRXhlY3V0ZTtcbiAgICB9XG5cbiAgICBtb2RlbGluZy5jb25uZWN0KHNvdXJjZSwgdGFyZ2V0LCBhdHRycywgaGludHMpO1xuICB9KTtcblxuXG4gIC8vIEFQSVxuXG4gIC8qKlxuICAgKiBTdGFydCBjb25uZWN0IG9wZXJhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtET01FdmVudH0gZXZlbnRcbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gc3RhcnRcbiAgICogQHBhcmFtIHtQb2ludH0gW2Nvbm5lY3Rpb25TdGFydF1cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXV0b0FjdGl2YXRlPWZhbHNlXVxuICAgKi9cbiAgdGhpcy5zdGFydCA9IGZ1bmN0aW9uKGV2ZW50LCBzdGFydCwgY29ubmVjdGlvblN0YXJ0LCBhdXRvQWN0aXZhdGUpIHtcbiAgICBpZiAoIWlzT2JqZWN0KGNvbm5lY3Rpb25TdGFydCkpIHtcbiAgICAgIGF1dG9BY3RpdmF0ZSA9IGNvbm5lY3Rpb25TdGFydDtcbiAgICAgIGNvbm5lY3Rpb25TdGFydCA9IGdldE1pZChzdGFydCk7XG4gICAgfVxuXG4gICAgZHJhZ2dpbmcuaW5pdChldmVudCwgJ2Nvbm5lY3QnLCB7XG4gICAgICBhdXRvQWN0aXZhdGU6IGF1dG9BY3RpdmF0ZSxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgc2hhcGU6IHN0YXJ0LFxuICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgIGNvbm5lY3Rpb25TdGFydDogY29ubmVjdGlvblN0YXJ0XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn1cblxuQ29ubmVjdC4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZHJhZ2dpbmcnLFxuICAnbW9kZWxpbmcnLFxuICAncnVsZXMnXG5dO1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXZlcnNlKGNvbnRleHQpIHtcbiAgdmFyIGhvdmVyID0gY29udGV4dC5ob3ZlcixcbiAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgdGFyZ2V0ID0gY29udGV4dC50YXJnZXQ7XG5cbiAgcmV0dXJuIGhvdmVyICYmIHNvdXJjZSAmJiBob3ZlciA9PT0gc291cmNlICYmIHNvdXJjZSAhPT0gdGFyZ2V0O1xufSIsImltcG9ydCB7IGlzUmV2ZXJzZSB9IGZyb20gJy4vQ29ubmVjdCc7XG5cbnZhciBISUdIX1BSSU9SSVRZID0gMTEwMCxcbiAgICBMT1dfUFJJT1JJVFkgPSA5MDA7XG5cbnZhciBNQVJLRVJfT0sgPSAnY29ubmVjdC1vaycsXG4gICAgTUFSS0VSX05PVF9PSyA9ICdjb25uZWN0LW5vdC1vayc7XG5cbi8qKlxuICogU2hvd3MgY29ubmVjdGlvbiBwcmV2aWV3IGR1cmluZyBjb25uZWN0LlxuICpcbiAqIEBwYXJhbSB7ZGlkaS5JbmplY3Rvcn0gaW5qZWN0b3JcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvbm5lY3RQcmV2aWV3KGluamVjdG9yLCBldmVudEJ1cywgY2FudmFzKSB7XG4gIHZhciBjb25uZWN0aW9uUHJldmlldyA9IGluamVjdG9yLmdldCgnY29ubmVjdGlvblByZXZpZXcnLCBmYWxzZSk7XG5cbiAgY29ubmVjdGlvblByZXZpZXcgJiYgZXZlbnRCdXMub24oJ2Nvbm5lY3QubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjYW5Db25uZWN0ID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBob3ZlciA9IGNvbnRleHQuaG92ZXIsXG4gICAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgICBzdGFydCA9IGNvbnRleHQuc3RhcnQsXG4gICAgICAgIHN0YXJ0UG9zaXRpb24gPSBjb250ZXh0LnN0YXJ0UG9zaXRpb24sXG4gICAgICAgIGNvbm5lY3Rpb25TdGFydCA9IGNvbnRleHQuY29ubmVjdGlvblN0YXJ0LFxuICAgICAgICBjb25uZWN0aW9uRW5kID0gY29udGV4dC5jb25uZWN0aW9uRW5kLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIGlmICghY29ubmVjdGlvblN0YXJ0KSB7XG4gICAgICBjb25uZWN0aW9uU3RhcnQgPSBpc1JldmVyc2UoY29udGV4dCkgPyB7XG4gICAgICAgIHg6IGV2ZW50LngsXG4gICAgICAgIHk6IGV2ZW50LnlcbiAgICAgIH0gOiBzdGFydFBvc2l0aW9uO1xuICAgIH1cblxuICAgIGlmICghY29ubmVjdGlvbkVuZCkge1xuICAgICAgY29ubmVjdGlvbkVuZCA9IGlzUmV2ZXJzZShjb250ZXh0KSA/IHN0YXJ0UG9zaXRpb24gOiB7XG4gICAgICAgIHg6IGV2ZW50LngsXG4gICAgICAgIHk6IGV2ZW50LnlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29ubmVjdGlvblByZXZpZXcuZHJhd1ByZXZpZXcoY29udGV4dCwgY2FuQ29ubmVjdCwge1xuICAgICAgc291cmNlOiBzb3VyY2UgfHwgc3RhcnQsXG4gICAgICB0YXJnZXQ6IHRhcmdldCB8fCBob3ZlcixcbiAgICAgIGNvbm5lY3Rpb25TdGFydDogY29ubmVjdGlvblN0YXJ0LFxuICAgICAgY29ubmVjdGlvbkVuZDogY29ubmVjdGlvbkVuZFxuICAgIH0pO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdC5ob3ZlcicsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGhvdmVyID0gZXZlbnQuaG92ZXIsXG4gICAgICAgIGNhbkV4ZWN1dGUgPSBjb250ZXh0LmNhbkV4ZWN1dGU7XG5cbiAgICAvLyBpZ25vcmUgaG92ZXJcbiAgICBpZiAoY2FuRXhlY3V0ZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNhbnZhcy5hZGRNYXJrZXIoaG92ZXIsIGNhbkV4ZWN1dGUgPyBNQVJLRVJfT0sgOiBNQVJLRVJfTk9UX09LKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oW1xuICAgICdjb25uZWN0Lm91dCcsXG4gICAgJ2Nvbm5lY3QuY2xlYW51cCdcbiAgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgaG92ZXIgPSBldmVudC5ob3ZlcjtcblxuICAgIGlmIChob3Zlcikge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgTUFSS0VSX09LKTtcbiAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoaG92ZXIsIE1BUktFUl9OT1RfT0spO1xuICAgIH1cbiAgfSk7XG5cbiAgY29ubmVjdGlvblByZXZpZXcgJiYgZXZlbnRCdXMub24oJ2Nvbm5lY3QuY2xlYW51cCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgY29ubmVjdGlvblByZXZpZXcuY2xlYW5VcChldmVudC5jb250ZXh0KTtcbiAgfSk7XG59XG5cbkNvbm5lY3RQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdpbmplY3RvcicsXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnXG5dO1xuIiwiaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuaW1wb3J0IFJ1bGVzTW9kdWxlIGZyb20gJy4uL3J1bGVzJztcbmltcG9ydCBEcmFnZ2luZ01vZHVsZSBmcm9tICcuLi9kcmFnZ2luZyc7XG5cbmltcG9ydCBDb25uZWN0IGZyb20gJy4vQ29ubmVjdCc7XG5pbXBvcnQgQ29ubmVjdFByZXZpZXcgZnJvbSAnLi9Db25uZWN0UHJldmlldyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBTZWxlY3Rpb25Nb2R1bGUsXG4gICAgUnVsZXNNb2R1bGUsXG4gICAgRHJhZ2dpbmdNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFtcbiAgICAnY29ubmVjdFByZXZpZXcnXG4gIF0sXG4gIGNvbm5lY3Q6IFsgJ3R5cGUnLCBDb25uZWN0IF0sXG4gIGNvbm5lY3RQcmV2aWV3OiBbICd0eXBlJywgQ29ubmVjdFByZXZpZXcgXVxufTtcbiIsImltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICByZW1vdmUgYXMgc3ZnUmVtb3ZlLFxuICBjbGVhciBhcyBzdmdDbGVhclxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7XG4gIGlzT2JqZWN0XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0RWxlbWVudExpbmVJbnRlcnNlY3Rpb24sXG4gIGdldE1pZFxufSBmcm9tICcuLi8uLi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cblxudmFyIE1BUktFUl9DT05ORUNUSU9OX1BSRVZJRVcgPSAnZGpzLWNvbm5lY3Rpb24tcHJldmlldyc7XG5cbi8qKlxuICogRHJhd3MgY29ubmVjdGlvbiBwcmV2aWV3LiBPcHRpb25hbGx5LCB0aGlzIGNhbiB1c2UgbGF5b3V0ZXIgYW5kIGNvbm5lY3Rpb24gZG9ja2luZyB0byBkcmF3XG4gKiBiZXR0ZXIgbG9va2luZyBwcmV2aWV3cy5cbiAqXG4gKiBAcGFyYW0ge2RpZGkuSW5qZWN0b3J9IGluamVjdG9yXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge0dyYXBoaWNzRmFjdG9yeX0gZ3JhcGhpY3NGYWN0b3J5XG4gKiBAcGFyYW0ge0VsZW1lbnRGYWN0b3J5fSBlbGVtZW50RmFjdG9yeVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDb25uZWN0aW9uUHJldmlldyhcbiAgICBpbmplY3RvcixcbiAgICBjYW52YXMsXG4gICAgZ3JhcGhpY3NGYWN0b3J5LFxuICAgIGVsZW1lbnRGYWN0b3J5XG4pIHtcbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xuICB0aGlzLl9ncmFwaGljc0ZhY3RvcnkgPSBncmFwaGljc0ZhY3Rvcnk7XG4gIHRoaXMuX2VsZW1lbnRGYWN0b3J5ID0gZWxlbWVudEZhY3Rvcnk7XG5cbiAgLy8gb3B0aW9uYWwgY29tcG9uZW50c1xuICB0aGlzLl9jb25uZWN0aW9uRG9ja2luZyA9IGluamVjdG9yLmdldCgnY29ubmVjdGlvbkRvY2tpbmcnLCBmYWxzZSk7XG4gIHRoaXMuX2xheW91dGVyID0gaW5qZWN0b3IuZ2V0KCdsYXlvdXRlcicsIGZhbHNlKTtcbn1cblxuQ29ubmVjdGlvblByZXZpZXcuJGluamVjdCA9IFtcbiAgJ2luamVjdG9yJyxcbiAgJ2NhbnZhcycsXG4gICdncmFwaGljc0ZhY3RvcnknLFxuICAnZWxlbWVudEZhY3RvcnknXG5dO1xuXG4vKipcbiAqIERyYXcgY29ubmVjdGlvbiBwcmV2aWV3LlxuICpcbiAqIFByb3ZpZGUgYXQgbGVhc3Qgb25lIG9mIDxzb3VyY2UsIGNvbm5lY3Rpb25TdGFydD4gYW5kIDx0YXJnZXQsIGNvbm5lY3Rpb25FbmQ+IHRvIGNyZWF0ZSBhIHByZXZpZXcuXG4gKiBJbiB0aGUgY2xlYW4gdXAgc3RhZ2UsIGNhbGwgYGNvbm5lY3Rpb25QcmV2aWV3I2NsZWFuVXBgIHdpdGggdGhlIGNvbnRleHQgdG8gcmVtb3ZlIHByZXZpZXcuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7T2JqZWN0fGJvb2xlYW59IGNhbkNvbm5lY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBoaW50c1xuICogQHBhcmFtIHtkanMubW9kZWwuc2hhcGV9IFtoaW50cy5zb3VyY2VdIHNvdXJjZSBlbGVtZW50XG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5zaGFwZX0gW2hpbnRzLnRhcmdldF0gdGFyZ2V0IGVsZW1lbnRcbiAqIEBwYXJhbSB7UG9pbnR9IFtoaW50cy5jb25uZWN0aW9uU3RhcnRdIGNvbm5lY3Rpb24gcHJldmlldyBzdGFydFxuICogQHBhcmFtIHtQb2ludH0gW2hpbnRzLmNvbm5lY3Rpb25FbmRdIGNvbm5lY3Rpb24gcHJldmlldyBlbmRcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSBbaGludHMud2F5cG9pbnRzXSBwcm92aWRlZCB3YXlwb2ludHMgZm9yIHByZXZpZXdcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2hpbnRzLm5vTGF5b3V0XSB0cnVlIGlmIHByZXZpZXcgc2hvdWxkIG5vdCBiZSBsYWlkIG91dFxuICogQHBhcmFtIHtib29sZWFufSBbaGludHMubm9Dcm9wcGluZ10gdHJ1ZSBpZiBwcmV2aWV3IHNob3VsZCBub3QgYmUgY3JvcHBlZFxuICogQHBhcmFtIHtib29sZWFufSBbaGludHMubm9Ob29wXSB0cnVlIGlmIHNpbXBsZSBjb25uZWN0aW9uIHNob3VsZCBub3QgYmUgZHJhd25cbiAqL1xuQ29ubmVjdGlvblByZXZpZXcucHJvdG90eXBlLmRyYXdQcmV2aWV3ID0gZnVuY3Rpb24oY29udGV4dCwgY2FuQ29ubmVjdCwgaGludHMpIHtcblxuICBoaW50cyA9IGhpbnRzIHx8IHt9O1xuXG4gIHZhciBjb25uZWN0aW9uUHJldmlld0dmeCA9IGNvbnRleHQuY29ubmVjdGlvblByZXZpZXdHZngsXG4gICAgICBnZXRDb25uZWN0aW9uID0gY29udGV4dC5nZXRDb25uZWN0aW9uLFxuICAgICAgc291cmNlID0gaGludHMuc291cmNlLFxuICAgICAgdGFyZ2V0ID0gaGludHMudGFyZ2V0LFxuICAgICAgd2F5cG9pbnRzID0gaGludHMud2F5cG9pbnRzLFxuICAgICAgY29ubmVjdGlvblN0YXJ0ID0gaGludHMuY29ubmVjdGlvblN0YXJ0LFxuICAgICAgY29ubmVjdGlvbkVuZCA9IGhpbnRzLmNvbm5lY3Rpb25FbmQsXG4gICAgICBub0xheW91dCA9IGhpbnRzLm5vTGF5b3V0LFxuICAgICAgbm9Dcm9wcGluZyA9IGhpbnRzLm5vQ3JvcHBpbmcsXG4gICAgICBub05vb3AgPSBoaW50cy5ub05vb3AsXG4gICAgICBjb25uZWN0aW9uO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAoIWNvbm5lY3Rpb25QcmV2aWV3R2Z4KSB7XG4gICAgY29ubmVjdGlvblByZXZpZXdHZnggPSBjb250ZXh0LmNvbm5lY3Rpb25QcmV2aWV3R2Z4ID0gdGhpcy5jcmVhdGVDb25uZWN0aW9uUHJldmlld0dmeCgpO1xuICB9XG5cbiAgc3ZnQ2xlYXIoY29ubmVjdGlvblByZXZpZXdHZngpO1xuXG4gIGlmICghZ2V0Q29ubmVjdGlvbikge1xuICAgIGdldENvbm5lY3Rpb24gPSBjb250ZXh0LmdldENvbm5lY3Rpb24gPSBjYWNoZVJldHVyblZhbHVlcyhmdW5jdGlvbihjYW5Db25uZWN0LCBzb3VyY2UsIHRhcmdldCkge1xuICAgICAgcmV0dXJuIHNlbGYuZ2V0Q29ubmVjdGlvbihjYW5Db25uZWN0LCBzb3VyY2UsIHRhcmdldCk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoY2FuQ29ubmVjdCkge1xuICAgIGNvbm5lY3Rpb24gPSBnZXRDb25uZWN0aW9uKGNhbkNvbm5lY3QsIHNvdXJjZSwgdGFyZ2V0KTtcbiAgfVxuXG4gIGlmICghY29ubmVjdGlvbikge1xuICAgICFub05vb3AgJiYgdGhpcy5kcmF3Tm9vcFByZXZpZXcoY29ubmVjdGlvblByZXZpZXdHZngsIGhpbnRzKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25uZWN0aW9uLndheXBvaW50cyA9IHdheXBvaW50cyB8fCBbXTtcblxuICAvLyBvcHRpb25hbCBsYXlvdXRcbiAgaWYgKHRoaXMuX2xheW91dGVyICYmICFub0xheW91dCkge1xuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gdGhpcy5fbGF5b3V0ZXIubGF5b3V0Q29ubmVjdGlvbihjb25uZWN0aW9uLCB7XG4gICAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICAgIHRhcmdldDogdGFyZ2V0LFxuICAgICAgY29ubmVjdGlvblN0YXJ0OiBjb25uZWN0aW9uU3RhcnQsXG4gICAgICBjb25uZWN0aW9uRW5kOiBjb25uZWN0aW9uRW5kLFxuICAgICAgd2F5cG9pbnRzOiBoaW50cy53YXlwb2ludHMgfHwgY29ubmVjdGlvbi53YXlwb2ludHNcbiAgICB9KTtcbiAgfVxuXG4gIC8vIGZhbGxiYWNrIGlmIG5vIHdheXBvaW50cyB3ZXJlIHByb3ZpZGVkIG5vciBjcmVhdGVkIHdpdGggbGF5b3V0ZXJcbiAgaWYgKCFjb25uZWN0aW9uLndheXBvaW50cyB8fCAhY29ubmVjdGlvbi53YXlwb2ludHMubGVuZ3RoKSB7XG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBbXG4gICAgICBzb3VyY2UgPyBnZXRNaWQoc291cmNlKSA6IGNvbm5lY3Rpb25TdGFydCxcbiAgICAgIHRhcmdldCA/IGdldE1pZCh0YXJnZXQpIDogY29ubmVjdGlvbkVuZFxuICAgIF07XG4gIH1cblxuICAvLyBvcHRpb25hbCBjcm9wcGluZ1xuICBpZiAodGhpcy5fY29ubmVjdGlvbkRvY2tpbmcgJiYgKHNvdXJjZSB8fCB0YXJnZXQpICYmICFub0Nyb3BwaW5nKSB7XG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSB0aGlzLl9jb25uZWN0aW9uRG9ja2luZy5nZXRDcm9wcGVkV2F5cG9pbnRzKGNvbm5lY3Rpb24sIHNvdXJjZSwgdGFyZ2V0KTtcbiAgfVxuXG4gIHRoaXMuX2dyYXBoaWNzRmFjdG9yeS5kcmF3Q29ubmVjdGlvbihjb25uZWN0aW9uUHJldmlld0dmeCwgY29ubmVjdGlvbik7XG59O1xuXG4vKipcbiAqIERyYXcgc2ltcGxlIGNvbm5lY3Rpb24gYmV0d2VlbiBzb3VyY2UgYW5kIHRhcmdldCBvciBwcm92aWRlZCBwb2ludHMuXG4gKlxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBjb25uZWN0aW9uUHJldmlld0dmeCBjb250YWluZXIgZm9yIHRoZSBjb25uZWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gaGludHNcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLnNoYXBlfSBbaGludHMuc291cmNlXSBzb3VyY2UgZWxlbWVudFxuICogQHBhcmFtIHtkanMubW9kZWwuc2hhcGV9IFtoaW50cy50YXJnZXRdIHRhcmdldCBlbGVtZW50XG4gKiBAcGFyYW0ge1BvaW50fSBbaGludHMuY29ubmVjdGlvblN0YXJ0XSByZXF1aXJlZCBpZiBzb3VyY2UgaXMgbm90IHByb3ZpZGVkXG4gKiBAcGFyYW0ge1BvaW50fSBbaGludHMuY29ubmVjdGlvbkVuZF0gcmVxdWlyZWQgaWYgdGFyZ2V0IGlzIG5vdCBwcm92aWRlZFxuICovXG5Db25uZWN0aW9uUHJldmlldy5wcm90b3R5cGUuZHJhd05vb3BQcmV2aWV3ID0gZnVuY3Rpb24oY29ubmVjdGlvblByZXZpZXdHZngsIGhpbnRzKSB7XG4gIHZhciBzb3VyY2UgPSBoaW50cy5zb3VyY2UsXG4gICAgICB0YXJnZXQgPSBoaW50cy50YXJnZXQsXG4gICAgICBzdGFydCA9IGhpbnRzLmNvbm5lY3Rpb25TdGFydCB8fCBnZXRNaWQoc291cmNlKSxcbiAgICAgIGVuZCA9IGhpbnRzLmNvbm5lY3Rpb25FbmQgfHwgZ2V0TWlkKHRhcmdldCk7XG5cbiAgdmFyIHdheXBvaW50cyA9IHRoaXMuY3JvcFdheXBvaW50cyhzdGFydCwgZW5kLCBzb3VyY2UsIHRhcmdldCk7XG5cbiAgdmFyIGNvbm5lY3Rpb24gPSB0aGlzLmNyZWF0ZU5vb3BDb25uZWN0aW9uKHdheXBvaW50c1swXSwgd2F5cG9pbnRzWzFdKTtcblxuICBzdmdBcHBlbmQoY29ubmVjdGlvblByZXZpZXdHZngsIGNvbm5lY3Rpb24pO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gY3JvcHBlZCB3YXlwb2ludHMuXG4gKlxuICogQHBhcmFtIHtQb2ludH0gc3RhcnRcbiAqIEBwYXJhbSB7UG9pbnR9IGVuZFxuICogQHBhcmFtIHtkanMubW9kZWwuc2hhcGV9IHNvdXJjZVxuICogQHBhcmFtIHtkanMubW9kZWwuc2hhcGV9IHRhcmdldFxuICpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqL1xuQ29ubmVjdGlvblByZXZpZXcucHJvdG90eXBlLmNyb3BXYXlwb2ludHMgPSBmdW5jdGlvbihzdGFydCwgZW5kLCBzb3VyY2UsIHRhcmdldCkge1xuICB2YXIgZ3JhcGhpY3NGYWN0b3J5ID0gdGhpcy5fZ3JhcGhpY3NGYWN0b3J5LFxuICAgICAgc291cmNlUGF0aCA9IHNvdXJjZSAmJiBncmFwaGljc0ZhY3RvcnkuZ2V0U2hhcGVQYXRoKHNvdXJjZSksXG4gICAgICB0YXJnZXRQYXRoID0gdGFyZ2V0ICYmIGdyYXBoaWNzRmFjdG9yeS5nZXRTaGFwZVBhdGgodGFyZ2V0KSxcbiAgICAgIGNvbm5lY3Rpb25QYXRoID0gZ3JhcGhpY3NGYWN0b3J5LmdldENvbm5lY3Rpb25QYXRoKHsgd2F5cG9pbnRzOiBbIHN0YXJ0LCBlbmQgXSB9KTtcblxuICBzdGFydCA9IChzb3VyY2UgJiYgZ2V0RWxlbWVudExpbmVJbnRlcnNlY3Rpb24oc291cmNlUGF0aCwgY29ubmVjdGlvblBhdGgsIHRydWUpKSB8fCBzdGFydDtcbiAgZW5kID0gKHRhcmdldCAmJiBnZXRFbGVtZW50TGluZUludGVyc2VjdGlvbih0YXJnZXRQYXRoLCBjb25uZWN0aW9uUGF0aCwgZmFsc2UpKSB8fCBlbmQ7XG5cbiAgcmV0dXJuIFsgc3RhcnQsIGVuZCBdO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgY29ubmVjdGlvbiBwcmV2aWV3IGNvbnRhaW5lciBpZiBpdCBleGlzdHMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtjb250ZXh0XVxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBbY29udGV4dC5jb25uZWN0aW9uUHJldmlld0dmeF0gcHJldmlldyBjb250YWluZXJcbiAqL1xuQ29ubmVjdGlvblByZXZpZXcucHJvdG90eXBlLmNsZWFuVXAgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIGlmIChjb250ZXh0ICYmIGNvbnRleHQuY29ubmVjdGlvblByZXZpZXdHZngpIHtcbiAgICBzdmdSZW1vdmUoY29udGV4dC5jb25uZWN0aW9uUHJldmlld0dmeCk7XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGNvbm5lY3Rpb24gdGhhdCBjb25uZWN0cyBzb3VyY2UgYW5kIHRhcmdldC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxib29sZWFufSBjYW5Db25uZWN0XG4gKlxuICogQHJldHVybnMge2Rqcy5tb2RlbC5jb25uZWN0aW9ufVxuICovXG5Db25uZWN0aW9uUHJldmlldy5wcm90b3R5cGUuZ2V0Q29ubmVjdGlvbiA9IGZ1bmN0aW9uKGNhbkNvbm5lY3QpIHtcbiAgdmFyIGF0dHJzID0gZW5zdXJlQ29ubmVjdGlvbkF0dHJzKGNhbkNvbm5lY3QpO1xuXG4gIHJldHVybiB0aGlzLl9lbGVtZW50RmFjdG9yeS5jcmVhdGVDb25uZWN0aW9uKGF0dHJzKTtcbn07XG5cblxuLyoqXG4gKiBBZGQgYW5kIHJldHVybiBwcmV2aWV3IGdyYXBoaWNzLlxuICpcbiAqIEByZXR1cm5zIHtTVkdFbGVtZW50fVxuICovXG5Db25uZWN0aW9uUHJldmlldy5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvblByZXZpZXdHZnggPSBmdW5jdGlvbigpIHtcbiAgdmFyIGdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuXG4gIHN2Z0F0dHIoZ2Z4LCB7XG4gICAgcG9pbnRlckV2ZW50czogJ25vbmUnXG4gIH0pO1xuXG4gIHN2Z0NsYXNzZXMoZ2Z4KS5hZGQoTUFSS0VSX0NPTk5FQ1RJT05fUFJFVklFVyk7XG5cbiAgc3ZnQXBwZW5kKHRoaXMuX2NhbnZhcy5nZXREZWZhdWx0TGF5ZXIoKSwgZ2Z4KTtcblxuICByZXR1cm4gZ2Z4O1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYW5kIHJldHVybiBzaW1wbGUgY29ubmVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBzdGFydFxuICogQHBhcmFtIHtQb2ludH0gZW5kXG4gKlxuICogQHJldHVybnMge1NWR0VsZW1lbnR9XG4gKi9cbkNvbm5lY3Rpb25QcmV2aWV3LnByb3RvdHlwZS5jcmVhdGVOb29wQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGNvbm5lY3Rpb24gPSBzdmdDcmVhdGUoJ3BvbHlsaW5lJyk7XG5cbiAgc3ZnQXR0cihjb25uZWN0aW9uLCB7XG4gICAgJ3N0cm9rZSc6ICcjMzMzJyxcbiAgICAnc3Ryb2tlRGFzaGFycmF5JzogWyAxIF0sXG4gICAgJ3N0cm9rZVdpZHRoJzogMixcbiAgICAncG9pbnRlci1ldmVudHMnOiAnbm9uZSdcbiAgfSk7XG5cbiAgc3ZnQXR0cihjb25uZWN0aW9uLCB7ICdwb2ludHMnOiBbIHN0YXJ0LngsIHN0YXJ0LnksIGVuZC54LCBlbmQueSBdIH0pO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTtcblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbi8qKlxuICogUmV0dXJucyBmdW5jdGlvbiB0aGF0IHJldHVybnMgY2FjaGVkIHJldHVybiB2YWx1ZXMgcmVmZXJlbmNlZCBieSBzdHJpbmdpZmllZCBmaXJzdCBhcmd1bWVudC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICpcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBjYWNoZVJldHVyblZhbHVlcyhmbikge1xuICB2YXIgcmV0dXJuVmFsdWVzID0ge307XG5cbiAgLyoqXG4gICAqIFJldHVybiBjYWNoZWQgcmV0dXJuIHZhbHVlIHJlZmVyZW5jZWQgYnkgc3RyaW5naWZpZWQgZmlyc3QgYXJndW1lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgcmV0dXJuIGZ1bmN0aW9uKGZpcnN0QXJndW1lbnQpIHtcbiAgICB2YXIga2V5ID0gSlNPTi5zdHJpbmdpZnkoZmlyc3RBcmd1bWVudCk7XG5cbiAgICB2YXIgcmV0dXJuVmFsdWUgPSByZXR1cm5WYWx1ZXNba2V5XTtcblxuICAgIGlmICghcmV0dXJuVmFsdWUpIHtcbiAgICAgIHJldHVyblZhbHVlID0gcmV0dXJuVmFsdWVzW2tleV0gPSBmbi5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgfTtcbn1cblxuLyoqXG4gKiBFbnN1cmUgY29ubmVjdGlvbiBhdHRyaWJ1dGVzIGlzIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxib29sZWFufSBjYW5Db25uZWN0XG4gKlxuICogQHJldHVybnMge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZW5zdXJlQ29ubmVjdGlvbkF0dHJzKGNhbkNvbm5lY3QpIHtcbiAgaWYgKGlzT2JqZWN0KGNhbkNvbm5lY3QpKSB7XG4gICAgcmV0dXJuIGNhbkNvbm5lY3Q7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG59XG4iLCJpbXBvcnQgQ29ubmVjdGlvblByZXZpZXcgZnJvbSAnLi9Db25uZWN0aW9uUHJldmlldyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2Nvbm5lY3Rpb25QcmV2aWV3JyBdLFxuICBjb25uZWN0aW9uUHJldmlldzogWyAndHlwZScsIENvbm5lY3Rpb25QcmV2aWV3IF1cbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGlzRnVuY3Rpb24sXG4gIGlzQXJyYXksXG4gIGZvckVhY2gsXG4gIGlzRGVmaW5lZFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBldmVudCBhcyBkb21FdmVudCxcbiAgYXR0ciBhcyBkb21BdHRyLFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgY2xhc3NlcyBhcyBkb21DbGFzc2VzLFxuICBkb21pZnkgYXMgZG9taWZ5XG59IGZyb20gJ21pbi1kb20nO1xuXG52YXIgZW50cnlTZWxlY3RvciA9ICcuZW50cnknO1xuXG52YXIgREVGQVVMVF9QUklPUklUWSA9IDEwMDA7XG5cblxuLyoqXG4gKiBBIGNvbnRleHQgcGFkIHRoYXQgZGlzcGxheXMgZWxlbWVudCBzcGVjaWZpYywgY29udGV4dHVhbCBhY3Rpb25zIG5leHRcbiAqIHRvIGEgZGlhZ3JhbSBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWdcbiAqIEBwYXJhbSB7Ym9vbGVhbnxPYmplY3R9IFtjb25maWcuc2NhbGU9eyBtaW46IDEuMCwgbWF4OiAxLjUgfV1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbY29uZmlnLnNjYWxlLm1pbl1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbY29uZmlnLnNjYWxlLm1heF1cbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge092ZXJsYXlzfSBvdmVybGF5c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDb250ZXh0UGFkKGNvbmZpZywgZXZlbnRCdXMsIG92ZXJsYXlzKSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fb3ZlcmxheXMgPSBvdmVybGF5cztcblxuICB2YXIgc2NhbGUgPSBpc0RlZmluZWQoY29uZmlnICYmIGNvbmZpZy5zY2FsZSkgPyBjb25maWcuc2NhbGUgOiB7XG4gICAgbWluOiAxLFxuICAgIG1heDogMS41XG4gIH07XG5cbiAgdGhpcy5fb3ZlcmxheXNDb25maWcgPSB7XG4gICAgcG9zaXRpb246IHtcbiAgICAgIHJpZ2h0OiAtOSxcbiAgICAgIHRvcDogLTZcbiAgICB9LFxuICAgIHNjYWxlOiBzY2FsZVxuICB9O1xuXG4gIHRoaXMuX2N1cnJlbnQgPSBudWxsO1xuXG4gIHRoaXMuX2luaXQoKTtcbn1cblxuQ29udGV4dFBhZC4kaW5qZWN0ID0gW1xuICAnY29uZmlnLmNvbnRleHRQYWQnLFxuICAnZXZlbnRCdXMnLFxuICAnb3ZlcmxheXMnXG5dO1xuXG5cbi8qKlxuICogUmVnaXN0ZXJzIGV2ZW50cyBuZWVkZWQgZm9yIGludGVyYWN0aW9uIHdpdGggb3RoZXIgY29tcG9uZW50c1xuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBldmVudEJ1cyA9IHRoaXMuX2V2ZW50QnVzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbignc2VsZWN0aW9uLmNoYW5nZWQnLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgc2VsZWN0aW9uID0gZS5uZXdTZWxlY3Rpb247XG5cbiAgICBpZiAoc2VsZWN0aW9uLmxlbmd0aCA9PT0gMSkge1xuICAgICAgc2VsZi5vcGVuKHNlbGVjdGlvblswXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGYuY2xvc2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50cy5kZWxldGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBlbGVtZW50cyA9IGV2ZW50LmVsZW1lbnRzO1xuXG4gICAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKHNlbGYuaXNPcGVuKGUpKSB7XG4gICAgICAgIHNlbGYuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQuY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBjdXJyZW50ID0gc2VsZi5fY3VycmVudDtcblxuICAgIC8vIGZvcmNlIHJlb3BlbiBpZiBlbGVtZW50IGZvciB3aGljaCB3ZSBhcmUgY3VycmVudGx5IG9wZW5lZCBjaGFuZ2VkXG4gICAgaWYgKGN1cnJlbnQgJiYgY3VycmVudC5lbGVtZW50ID09PSBlbGVtZW50KSB7XG4gICAgICBzZWxmLm9wZW4oZWxlbWVudCwgdHJ1ZSk7XG4gICAgfVxuICB9KTtcbn07XG5cblxuLyoqXG4gKiBSZWdpc3RlciBhIHByb3ZpZGVyIHdpdGggdGhlIGNvbnRleHQgcGFkXG4gKlxuICogQHBhcmFtICB7bnVtYmVyfSBbcHJpb3JpdHk9MTAwMF1cbiAqIEBwYXJhbSAge0NvbnRleHRQYWRQcm92aWRlcn0gcHJvdmlkZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY29udGV4dFBhZFByb3ZpZGVyID0ge1xuICAqICAgZ2V0Q29udGV4dFBhZEVudHJpZXM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgKiAgICAgcmV0dXJuIGZ1bmN0aW9uKGVudHJpZXMpIHtcbiAgKiAgICAgICByZXR1cm4ge1xuICAqICAgICAgICAgLi4uZW50cmllcyxcbiAgKiAgICAgICAgICdlbnRyeS0xJzoge1xuICAqICAgICAgICAgICBsYWJlbDogJ015IEVudHJ5JyxcbiAgKiAgICAgICAgICAgYWN0aW9uOiBmdW5jdGlvbigpIHsgYWxlcnQoXCJJIGhhdmUgYmVlbiBjbGlja2VkIVwiKTsgfVxuICAqICAgICAgICAgfVxuICAqICAgICAgIH07XG4gICogICAgIH1cbiAgKiAgIH1cbiAgKiB9O1xuICAqXG4gKiBjb250ZXh0UGFkLnJlZ2lzdGVyUHJvdmlkZXIoODAwLCBjb250ZXh0UGFkUHJvdmlkZXIpO1xuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS5yZWdpc3RlclByb3ZpZGVyID0gZnVuY3Rpb24ocHJpb3JpdHksIHByb3ZpZGVyKSB7XG4gIGlmICghcHJvdmlkZXIpIHtcbiAgICBwcm92aWRlciA9IHByaW9yaXR5O1xuICAgIHByaW9yaXR5ID0gREVGQVVMVF9QUklPUklUWTtcbiAgfVxuXG4gIHRoaXMuX2V2ZW50QnVzLm9uKCdjb250ZXh0UGFkLmdldFByb3ZpZGVycycsIHByaW9yaXR5LCBmdW5jdGlvbihldmVudCkge1xuICAgIGV2ZW50LnByb3ZpZGVycy5wdXNoKHByb3ZpZGVyKTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgY29udGV4dCBwYWQgZW50cmllcyBmb3IgYSBnaXZlbiBlbGVtZW50XG4gKlxuICogQHBhcmFtIHtkanMuZWxlbWVudC5CYXNlfSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7QXJyYXk8Q29udGV4dFBhZEVudHJ5RGVzY3JpcHRvcj59IGxpc3Qgb2YgZW50cmllc1xuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS5nZXRFbnRyaWVzID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICB2YXIgcHJvdmlkZXJzID0gdGhpcy5fZ2V0UHJvdmlkZXJzKCk7XG5cbiAgdmFyIGVudHJpZXMgPSB7fTtcblxuICAvLyBsb29wIHRocm91Z2ggYWxsIHByb3ZpZGVycyBhbmQgdGhlaXIgZW50cmllcy5cbiAgLy8gZ3JvdXAgZW50cmllcyBieSBpZCBzbyB0aGF0IG92ZXJyaWRpbmcgYW4gZW50cnkgaXMgcG9zc2libGVcbiAgZm9yRWFjaChwcm92aWRlcnMsIGZ1bmN0aW9uKHByb3ZpZGVyKSB7XG4gICAgdmFyIGVudHJpZXNPclVwZGF0ZXIgPSBwcm92aWRlci5nZXRDb250ZXh0UGFkRW50cmllcyhlbGVtZW50KTtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGVudHJpZXNPclVwZGF0ZXIpKSB7XG4gICAgICBlbnRyaWVzID0gZW50cmllc09yVXBkYXRlcihlbnRyaWVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yRWFjaChlbnRyaWVzT3JVcGRhdGVyLCBmdW5jdGlvbihlbnRyeSwgaWQpIHtcbiAgICAgICAgZW50cmllc1tpZF0gPSBlbnRyeTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGVudHJpZXM7XG59O1xuXG5cbi8qKlxuICogVHJpZ2dlciBhbiBhY3Rpb24gYXZhaWxhYmxlIG9uIHRoZSBvcGVuZWQgY29udGV4dCBwYWRcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGFjdGlvblxuICogQHBhcmFtICB7RXZlbnR9IGV2ZW50XG4gKiBAcGFyYW0gIHtib29sZWFufSBbYXV0b0FjdGl2YXRlPWZhbHNlXVxuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oYWN0aW9uLCBldmVudCwgYXV0b0FjdGl2YXRlKSB7XG5cbiAgdmFyIGVsZW1lbnQgPSB0aGlzLl9jdXJyZW50LmVsZW1lbnQsXG4gICAgICBlbnRyaWVzID0gdGhpcy5fY3VycmVudC5lbnRyaWVzLFxuICAgICAgZW50cnksXG4gICAgICBoYW5kbGVyLFxuICAgICAgb3JpZ2luYWxFdmVudCxcbiAgICAgIGJ1dHRvbiA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0IHx8IGV2ZW50LnRhcmdldDtcblxuICBpZiAoIWJ1dHRvbikge1xuICAgIHJldHVybiBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgZW50cnkgPSBlbnRyaWVzW2RvbUF0dHIoYnV0dG9uLCAnZGF0YS1hY3Rpb24nKV07XG4gIGhhbmRsZXIgPSBlbnRyeS5hY3Rpb247XG5cbiAgb3JpZ2luYWxFdmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQ7XG5cbiAgLy8gc2ltcGxlIGFjdGlvbiAodmlhIGNhbGxiYWNrIGZ1bmN0aW9uKVxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIGlmIChhY3Rpb24gPT09ICdjbGljaycpIHtcbiAgICAgIHJldHVybiBoYW5kbGVyKG9yaWdpbmFsRXZlbnQsIGVsZW1lbnQsIGF1dG9BY3RpdmF0ZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChoYW5kbGVyW2FjdGlvbl0pIHtcbiAgICAgIHJldHVybiBoYW5kbGVyW2FjdGlvbl0ob3JpZ2luYWxFdmVudCwgZWxlbWVudCwgYXV0b0FjdGl2YXRlKTtcbiAgICB9XG4gIH1cblxuICAvLyBzaWxlbmNlIG90aGVyIGFjdGlvbnNcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbn07XG5cblxuLyoqXG4gKiBPcGVuIHRoZSBjb250ZXh0IHBhZCBmb3IgdGhlIGdpdmVuIGVsZW1lbnRcbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0ge2Jvb2xlYW59IGZvcmNlIGlmIHRydWUsIGZvcmNlIHJlb3BlbmluZyB0aGUgY29udGV4dCBwYWRcbiAqL1xuQ29udGV4dFBhZC5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uKGVsZW1lbnQsIGZvcmNlKSB7XG4gIGlmICghZm9yY2UgJiYgdGhpcy5pc09wZW4oZWxlbWVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLmNsb3NlKCk7XG4gIHRoaXMuX3VwZGF0ZUFuZE9wZW4oZWxlbWVudCk7XG59O1xuXG5Db250ZXh0UGFkLnByb3RvdHlwZS5fZ2V0UHJvdmlkZXJzID0gZnVuY3Rpb24oaWQpIHtcblxuICB2YXIgZXZlbnQgPSB0aGlzLl9ldmVudEJ1cy5jcmVhdGVFdmVudCh7XG4gICAgdHlwZTogJ2NvbnRleHRQYWQuZ2V0UHJvdmlkZXJzJyxcbiAgICBwcm92aWRlcnM6IFtdXG4gIH0pO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoZXZlbnQpO1xuXG4gIHJldHVybiBldmVudC5wcm92aWRlcnM7XG59O1xuXG5Db250ZXh0UGFkLnByb3RvdHlwZS5fdXBkYXRlQW5kT3BlbiA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICB2YXIgZW50cmllcyA9IHRoaXMuZ2V0RW50cmllcyhlbGVtZW50KSxcbiAgICAgIHBhZCA9IHRoaXMuZ2V0UGFkKGVsZW1lbnQpLFxuICAgICAgaHRtbCA9IHBhZC5odG1sO1xuXG4gIGZvckVhY2goZW50cmllcywgZnVuY3Rpb24oZW50cnksIGlkKSB7XG4gICAgdmFyIGdyb3VwaW5nID0gZW50cnkuZ3JvdXAgfHwgJ2RlZmF1bHQnLFxuICAgICAgICBjb250cm9sID0gZG9taWZ5KGVudHJ5Lmh0bWwgfHwgJzxkaXYgY2xhc3M9XCJlbnRyeVwiIGRyYWdnYWJsZT1cInRydWVcIj48L2Rpdj4nKSxcbiAgICAgICAgY29udGFpbmVyO1xuXG4gICAgZG9tQXR0cihjb250cm9sLCAnZGF0YS1hY3Rpb24nLCBpZCk7XG5cbiAgICBjb250YWluZXIgPSBkb21RdWVyeSgnW2RhdGEtZ3JvdXA9JyArIGdyb3VwaW5nICsgJ10nLCBodG1sKTtcbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgY29udGFpbmVyID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiZ3JvdXBcIiBkYXRhLWdyb3VwPVwiJyArIGdyb3VwaW5nICsgJ1wiPjwvZGl2PicpO1xuICAgICAgaHRtbC5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICAgIH1cblxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChjb250cm9sKTtcblxuICAgIGlmIChlbnRyeS5jbGFzc05hbWUpIHtcbiAgICAgIGFkZENsYXNzZXMoY29udHJvbCwgZW50cnkuY2xhc3NOYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoZW50cnkudGl0bGUpIHtcbiAgICAgIGRvbUF0dHIoY29udHJvbCwgJ3RpdGxlJywgZW50cnkudGl0bGUpO1xuICAgIH1cblxuICAgIGlmIChlbnRyeS5pbWFnZVVybCkge1xuICAgICAgY29udHJvbC5hcHBlbmRDaGlsZChkb21pZnkoJzxpbWcgc3JjPVwiJyArIGVudHJ5LmltYWdlVXJsICsgJ1wiPicpKTtcbiAgICB9XG4gIH0pO1xuXG4gIGRvbUNsYXNzZXMoaHRtbCkuYWRkKCdvcGVuJyk7XG5cbiAgdGhpcy5fY3VycmVudCA9IHtcbiAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgIHBhZDogcGFkLFxuICAgIGVudHJpZXM6IGVudHJpZXNcbiAgfTtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb250ZXh0UGFkLm9wZW4nLCB7IGN1cnJlbnQ6IHRoaXMuX2N1cnJlbnQgfSk7XG59O1xuXG5cbkNvbnRleHRQYWQucHJvdG90eXBlLmdldFBhZCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudC5wYWQ7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIG92ZXJsYXlzID0gdGhpcy5fb3ZlcmxheXM7XG5cbiAgdmFyIGh0bWwgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJkanMtY29udGV4dC1wYWRcIj48L2Rpdj4nKTtcblxuICB2YXIgb3ZlcmxheXNDb25maWcgPSBhc3NpZ24oe1xuICAgIGh0bWw6IGh0bWxcbiAgfSwgdGhpcy5fb3ZlcmxheXNDb25maWcpO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQoaHRtbCwgZW50cnlTZWxlY3RvciwgJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBzZWxmLnRyaWdnZXIoJ2NsaWNrJywgZXZlbnQpO1xuICB9KTtcblxuICBkb21EZWxlZ2F0ZS5iaW5kKGh0bWwsIGVudHJ5U2VsZWN0b3IsICdkcmFnc3RhcnQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHNlbGYudHJpZ2dlcignZHJhZ3N0YXJ0JywgZXZlbnQpO1xuICB9KTtcblxuICAvLyBzdG9wIHByb3BhZ2F0aW9uIG9mIG1vdXNlIGV2ZW50c1xuICBkb21FdmVudC5iaW5kKGh0bWwsICdtb3VzZWRvd24nLCBmdW5jdGlvbihldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9KTtcblxuICB0aGlzLl9vdmVybGF5SWQgPSBvdmVybGF5cy5hZGQoZWxlbWVudCwgJ2NvbnRleHQtcGFkJywgb3ZlcmxheXNDb25maWcpO1xuXG4gIHZhciBwYWQgPSBvdmVybGF5cy5nZXQodGhpcy5fb3ZlcmxheUlkKTtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb250ZXh0UGFkLmNyZWF0ZScsIHsgZWxlbWVudDogZWxlbWVudCwgcGFkOiBwYWQgfSk7XG5cbiAgcmV0dXJuIHBhZDtcbn07XG5cblxuLyoqXG4gKiBDbG9zZSB0aGUgY29udGV4dCBwYWRcbiAqL1xuQ29udGV4dFBhZC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLmlzT3BlbigpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fb3ZlcmxheXMucmVtb3ZlKHRoaXMuX292ZXJsYXlJZCk7XG5cbiAgdGhpcy5fb3ZlcmxheUlkID0gbnVsbDtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb250ZXh0UGFkLmNsb3NlJywgeyBjdXJyZW50OiB0aGlzLl9jdXJyZW50IH0pO1xuXG4gIHRoaXMuX2N1cnJlbnQgPSBudWxsO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBwYWQgaXMgb3Blbi4gSWYgZWxlbWVudCBpcyBnaXZlbiwgd2lsbCBjaGVja1xuICogaWYgcGFkIGlzIG9wZW5lZCB3aXRoIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS5pc09wZW4gPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiAhIXRoaXMuX2N1cnJlbnQgJiYgKCFlbGVtZW50ID8gdHJ1ZSA6IHRoaXMuX2N1cnJlbnQuZWxlbWVudCA9PT0gZWxlbWVudCk7XG59O1xuXG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gYWRkQ2xhc3NlcyhlbGVtZW50LCBjbGFzc05hbWVzKSB7XG5cbiAgdmFyIGNsYXNzZXMgPSBkb21DbGFzc2VzKGVsZW1lbnQpO1xuXG4gIHZhciBhY3R1YWxDbGFzc05hbWVzID0gaXNBcnJheShjbGFzc05hbWVzKSA/IGNsYXNzTmFtZXMgOiBjbGFzc05hbWVzLnNwbGl0KC9cXHMrL2cpO1xuICBhY3R1YWxDbGFzc05hbWVzLmZvckVhY2goZnVuY3Rpb24oY2xzKSB7XG4gICAgY2xhc3Nlcy5hZGQoY2xzKTtcbiAgfSk7XG59IiwiaW1wb3J0IEludGVyYWN0aW9uRXZlbnRzTW9kdWxlIGZyb20gJy4uL2ludGVyYWN0aW9uLWV2ZW50cyc7XG5pbXBvcnQgT3ZlcmxheXNNb2R1bGUgZnJvbSAnLi4vb3ZlcmxheXMnO1xuXG5pbXBvcnQgQ29udGV4dFBhZCBmcm9tICcuL0NvbnRleHRQYWQnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSxcbiAgICBPdmVybGF5c01vZHVsZVxuICBdLFxuICBjb250ZXh0UGFkOiBbICd0eXBlJywgQ29udGV4dFBhZCBdXG59OyIsImltcG9ydCB7XG4gIGFzc2lnbixcbiAgZmluZCxcbiAgZm9yRWFjaCxcbiAgaXNBcnJheSxcbiAgaXNOdW1iZXIsXG4gIG1hcCxcbiAgbWF0Y2hQYXR0ZXJuLFxuICBvbWl0LFxuICBzb3J0Qnlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRCQm94LFxuICBnZXRQYXJlbnRzXG59IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG5pbXBvcnQgeyBlYWNoRWxlbWVudCB9IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtGdW5jdGlvbn0gPGNvcHlQYXN0ZS5jYW5Db3B5RWxlbWVudHM+IGxpc3RlbmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBjb250ZXh0LmVsZW1lbnRzXG4gKlxuICogQHJldHVybnMge0FycmF5PGRqcy5tb2RlbC5CYXNlPnxib29sZWFufSAtIFJldHVybiBlbGVtZW50cyB0byBiZSBjb3BpZWQgb3IgZmFsc2UgdG8gZGlzYWxsb3dcbiAqIGNvcHlpbmcuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7RnVuY3Rpb259IDxjb3B5UGFzdGUuY29weUVsZW1lbnQ+IGxpc3RlbmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LmRlc2NyaXB0b3JcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGNvbnRleHQuZWxlbWVudFxuICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGNvbnRleHQuZWxlbWVudHNcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtGdW5jdGlvbn0gPGNvcHlQYXN0ZS5lbGVtZW50c0NvcGllZD4gbGlzdGVuZXJcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQuZWxlbWVudHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LnRyZWVcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtGdW5jdGlvbn0gPGNvcHlQYXN0ZS5wYXN0ZUVsZW1lbnQ+IGxpc3RlbmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LmNhY2hlIC0gQWxyZWFkeSBjcmVhdGVkIGVsZW1lbnRzLlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQuZGVzY3JpcHRvclxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge0Z1bmN0aW9ufSA8Y29weVBhc3RlLnBhc3RlRWxlbWVudHM+IGxpc3RlbmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LmhpbnRzIC0gQWRkIGhpbnRzIGJlZm9yZSBwYXN0aW5nLlxuICovXG5cbi8qKlxuICogQ29weSBhbmQgcGFzdGUgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICogQHBhcmFtIHtDcmVhdGV9IGNyZWF0ZVxuICogQHBhcmFtIHtDbGlwYm9hcmR9IGNsaXBib2FyZFxuICogQHBhcmFtIHtFbGVtZW50RmFjdG9yeX0gZWxlbWVudEZhY3RvcnlcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICogQHBhcmFtIHtNb3VzZX0gbW91c2VcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvcHlQYXN0ZShcbiAgICBjYW52YXMsXG4gICAgY3JlYXRlLFxuICAgIGNsaXBib2FyZCxcbiAgICBlbGVtZW50RmFjdG9yeSxcbiAgICBldmVudEJ1cyxcbiAgICBtb2RlbGluZyxcbiAgICBtb3VzZSxcbiAgICBydWxlc1xuKSB7XG5cbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xuICB0aGlzLl9jcmVhdGUgPSBjcmVhdGU7XG4gIHRoaXMuX2NsaXBib2FyZCA9IGNsaXBib2FyZDtcbiAgdGhpcy5fZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fbW91c2UgPSBtb3VzZTtcbiAgdGhpcy5fcnVsZXMgPSBydWxlcztcblxuICBldmVudEJ1cy5vbignY29weVBhc3RlLmNvcHlFbGVtZW50JywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBkZXNjcmlwdG9yID0gY29udGV4dC5kZXNjcmlwdG9yLFxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHM7XG5cbiAgICAvLyBkZWZhdWx0IHByaW9yaXR5IChwcmlvcml0eSA9IDEpXG4gICAgZGVzY3JpcHRvci5wcmlvcml0eSA9IDE7XG5cbiAgICBkZXNjcmlwdG9yLmlkID0gZWxlbWVudC5pZDtcblxuICAgIHZhciBwYXJlbnRDb3BpZWQgPSBmaW5kKGVsZW1lbnRzLCBmdW5jdGlvbihlKSB7XG4gICAgICByZXR1cm4gZSA9PT0gZWxlbWVudC5wYXJlbnQ7XG4gICAgfSk7XG5cbiAgICAvLyBkbyBOT1QgcmVmZXJlbmNlIHBhcmVudCBpZiBwYXJlbnQgd2Fzbid0IGNvcGllZFxuICAgIGlmIChwYXJlbnRDb3BpZWQpIHtcbiAgICAgIGRlc2NyaXB0b3IucGFyZW50ID0gZWxlbWVudC5wYXJlbnQuaWQ7XG4gICAgfVxuXG4gICAgLy8gYXR0YWNoZXJzIChwcmlvcml0eSA9IDIpXG4gICAgaWYgKGlzQXR0YWNoZXIoZWxlbWVudCkpIHtcbiAgICAgIGRlc2NyaXB0b3IucHJpb3JpdHkgPSAyO1xuXG4gICAgICBkZXNjcmlwdG9yLmhvc3QgPSBlbGVtZW50Lmhvc3QuaWQ7XG4gICAgfVxuXG4gICAgLy8gY29ubmVjdGlvbnMgKHByaW9yaXR5ID0gMylcbiAgICBpZiAoaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICBkZXNjcmlwdG9yLnByaW9yaXR5ID0gMztcblxuICAgICAgZGVzY3JpcHRvci5zb3VyY2UgPSBlbGVtZW50LnNvdXJjZS5pZDtcbiAgICAgIGRlc2NyaXB0b3IudGFyZ2V0ID0gZWxlbWVudC50YXJnZXQuaWQ7XG5cbiAgICAgIGRlc2NyaXB0b3Iud2F5cG9pbnRzID0gY29weVdheXBvaW50cyhlbGVtZW50KTtcbiAgICB9XG5cbiAgICAvLyBsYWJlbHMgKHByaW9yaXR5ID0gNClcbiAgICBpZiAoaXNMYWJlbChlbGVtZW50KSkge1xuICAgICAgZGVzY3JpcHRvci5wcmlvcml0eSA9IDQ7XG5cbiAgICAgIGRlc2NyaXB0b3IubGFiZWxUYXJnZXQgPSBlbGVtZW50LmxhYmVsVGFyZ2V0LmlkO1xuICAgIH1cblxuICAgIGZvckVhY2goWyAneCcsICd5JywgJ3dpZHRoJywgJ2hlaWdodCcgXSwgZnVuY3Rpb24ocHJvcGVydHkpIHtcbiAgICAgIGlmIChpc051bWJlcihlbGVtZW50WyBwcm9wZXJ0eSBdKSkge1xuICAgICAgICBkZXNjcmlwdG9yWyBwcm9wZXJ0eSBdID0gZWxlbWVudFsgcHJvcGVydHkgXTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGRlc2NyaXB0b3IuaGlkZGVuID0gZWxlbWVudC5oaWRkZW47XG4gICAgZGVzY3JpcHRvci5jb2xsYXBzZWQgPSBlbGVtZW50LmNvbGxhcHNlZDtcblxuICB9KTtcblxuICBldmVudEJ1cy5vbignY29weVBhc3RlLnBhc3RlRWxlbWVudHMnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIGhpbnRzID0gY29udGV4dC5oaW50cztcblxuICAgIGFzc2lnbihoaW50cywge1xuICAgICAgY3JlYXRlRWxlbWVudHNCZWhhdmlvcjogZmFsc2VcbiAgICB9KTtcbiAgfSk7XG59XG5cbkNvcHlQYXN0ZS4kaW5qZWN0ID0gW1xuICAnY2FudmFzJyxcbiAgJ2NyZWF0ZScsXG4gICdjbGlwYm9hcmQnLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnZXZlbnRCdXMnLFxuICAnbW9kZWxpbmcnLFxuICAnbW91c2UnLFxuICAncnVsZXMnXG5dO1xuXG5cbi8qKlxuICogQ29weSBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHNcbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxuICovXG5Db3B5UGFzdGUucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbihlbGVtZW50cykge1xuICB2YXIgYWxsb3dlZCxcbiAgICAgIHRyZWU7XG5cbiAgaWYgKCFpc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gZWxlbWVudHMgPyBbIGVsZW1lbnRzIF0gOiBbXTtcbiAgfVxuXG4gIGFsbG93ZWQgPSB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb3B5UGFzdGUuY2FuQ29weUVsZW1lbnRzJywge1xuICAgIGVsZW1lbnRzOiBlbGVtZW50c1xuICB9KTtcblxuICBpZiAoYWxsb3dlZCA9PT0gZmFsc2UpIHtcbiAgICB0cmVlID0ge307XG4gIH0gZWxzZSB7XG4gICAgdHJlZSA9IHRoaXMuY3JlYXRlVHJlZShpc0FycmF5KGFsbG93ZWQpID8gYWxsb3dlZCA6IGVsZW1lbnRzKTtcbiAgfVxuXG4gIC8vIHdlIHNldCBhbiBlbXB0eSB0cmVlLCBzZWxlY3Rpb24gb2YgZWxlbWVudHNcbiAgLy8gdG8gY29weSB3YXMgZW1wdHkuXG4gIHRoaXMuX2NsaXBib2FyZC5zZXQodHJlZSk7XG5cbiAgdGhpcy5fZXZlbnRCdXMuZmlyZSgnY29weVBhc3RlLmVsZW1lbnRzQ29waWVkJywge1xuICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICB0cmVlOiB0cmVlXG4gIH0pO1xuXG4gIHJldHVybiB0cmVlO1xufTtcblxuLyoqXG4gKiBQYXN0ZSBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW2NvbnRleHRdXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5iYXNlfSBbY29udGV4dC5lbGVtZW50XSAtIFBhcmVudC5cbiAqIEBwYXJhbSB7UG9pbnR9IFtjb250ZXh0LnBvaW50XSAtIFBvc2l0aW9uLlxuICogQHBhcmFtIHtPYmplY3R9IFtjb250ZXh0LmhpbnRzXSAtIEhpbnRzLlxuICovXG5Db3B5UGFzdGUucHJvdG90eXBlLnBhc3RlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgdHJlZSA9IHRoaXMuX2NsaXBib2FyZC5nZXQoKTtcblxuICBpZiAodGhpcy5fY2xpcGJvYXJkLmlzRW1wdHkoKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBoaW50cyA9IGNvbnRleHQgJiYgY29udGV4dC5oaW50cyB8fCB7fTtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb3B5UGFzdGUucGFzdGVFbGVtZW50cycsIHtcbiAgICBoaW50czogaGludHNcbiAgfSk7XG5cbiAgdmFyIGVsZW1lbnRzID0gdGhpcy5fY3JlYXRlRWxlbWVudHModHJlZSk7XG5cbiAgLy8gcGFzdGUgZGlyZWN0bHlcbiAgaWYgKGNvbnRleHQgJiYgY29udGV4dC5lbGVtZW50ICYmIGNvbnRleHQucG9pbnQpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFzdGUoZWxlbWVudHMsIGNvbnRleHQuZWxlbWVudCwgY29udGV4dC5wb2ludCwgaGludHMpO1xuICB9XG5cbiAgdGhpcy5fY3JlYXRlLnN0YXJ0KHRoaXMuX21vdXNlLmdldExhc3RNb3ZlRXZlbnQoKSwgZWxlbWVudHMsIHtcbiAgICBoaW50czogaGludHMgfHwge31cbiAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3RlIGVsZW1lbnRzIGRpcmVjdGx5LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICogQHBhcmFtIHtkanMubW9kZWwuYmFzZX0gdGFyZ2V0XG4gKiBAcGFyYW0ge1BvaW50fSBwb3NpdGlvblxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqL1xuQ29weVBhc3RlLnByb3RvdHlwZS5fcGFzdGUgPSBmdW5jdGlvbihlbGVtZW50cywgdGFyZ2V0LCBwb3NpdGlvbiwgaGludHMpIHtcblxuICAvLyBtYWtlIHN1cmUgZWFjaCBlbGVtZW50IGhhcyB4IGFuZCB5XG4gIGZvckVhY2goZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBpZiAoIWlzTnVtYmVyKGVsZW1lbnQueCkpIHtcbiAgICAgIGVsZW1lbnQueCA9IDA7XG4gICAgfVxuXG4gICAgaWYgKCFpc051bWJlcihlbGVtZW50LnkpKSB7XG4gICAgICBlbGVtZW50LnkgPSAwO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIGJib3ggPSBnZXRCQm94KGVsZW1lbnRzKTtcblxuICAvLyBjZW50ZXIgZWxlbWVudHMgYXJvdW5kIGN1cnNvclxuICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgaWYgKGlzQ29ubmVjdGlvbihlbGVtZW50KSkge1xuICAgICAgZWxlbWVudC53YXlwb2ludHMgPSBtYXAoZWxlbWVudC53YXlwb2ludHMsIGZ1bmN0aW9uKHdheXBvaW50KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgeDogd2F5cG9pbnQueCAtIGJib3gueCAtIGJib3gud2lkdGggLyAyLFxuICAgICAgICAgIHk6IHdheXBvaW50LnkgLSBiYm94LnkgLSBiYm94LmhlaWdodCAvIDJcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzc2lnbihlbGVtZW50LCB7XG4gICAgICB4OiBlbGVtZW50LnggLSBiYm94LnggLSBiYm94LndpZHRoIC8gMixcbiAgICAgIHk6IGVsZW1lbnQueSAtIGJib3gueSAtIGJib3guaGVpZ2h0IC8gMlxuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gdGhpcy5fbW9kZWxpbmcuY3JlYXRlRWxlbWVudHMoZWxlbWVudHMsIHBvc2l0aW9uLCB0YXJnZXQsIGFzc2lnbih7fSwgaGludHMpKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGVsZW1lbnRzIGZyb20gdHJlZS5cbiAqL1xuQ29weVBhc3RlLnByb3RvdHlwZS5fY3JlYXRlRWxlbWVudHMgPSBmdW5jdGlvbih0cmVlKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICB2YXIgY2FjaGUgPSB7fTtcblxuICB2YXIgZWxlbWVudHMgPSBbXTtcblxuICBmb3JFYWNoKHRyZWUsIGZ1bmN0aW9uKGJyYW5jaCwgZGVwdGgpIHtcblxuICAgIGRlcHRoID0gcGFyc2VJbnQoZGVwdGgsIDEwKTtcblxuICAgIC8vIHNvcnQgYnkgcHJpb3JpdHlcbiAgICBicmFuY2ggPSBzb3J0QnkoYnJhbmNoLCAncHJpb3JpdHknKTtcblxuICAgIGZvckVhY2goYnJhbmNoLCBmdW5jdGlvbihkZXNjcmlwdG9yKSB7XG5cbiAgICAgIC8vIHJlbW92ZSBwcmlvcml0eVxuICAgICAgdmFyIGF0dHJzID0gYXNzaWduKHt9LCBvbWl0KGRlc2NyaXB0b3IsIFsgJ3ByaW9yaXR5JyBdKSk7XG5cbiAgICAgIGlmIChjYWNoZVsgZGVzY3JpcHRvci5wYXJlbnQgXSkge1xuICAgICAgICBhdHRycy5wYXJlbnQgPSBjYWNoZVsgZGVzY3JpcHRvci5wYXJlbnQgXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSBhdHRycy5wYXJlbnQ7XG4gICAgICB9XG5cbiAgICAgIGV2ZW50QnVzLmZpcmUoJ2NvcHlQYXN0ZS5wYXN0ZUVsZW1lbnQnLCB7XG4gICAgICAgIGNhY2hlOiBjYWNoZSxcbiAgICAgICAgZGVzY3JpcHRvcjogYXR0cnNcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZWxlbWVudDtcblxuICAgICAgaWYgKGlzQ29ubmVjdGlvbihhdHRycykpIHtcbiAgICAgICAgYXR0cnMuc291cmNlID0gY2FjaGVbIGRlc2NyaXB0b3Iuc291cmNlIF07XG4gICAgICAgIGF0dHJzLnRhcmdldCA9IGNhY2hlWyBkZXNjcmlwdG9yLnRhcmdldCBdO1xuXG4gICAgICAgIGVsZW1lbnQgPSBjYWNoZVsgZGVzY3JpcHRvci5pZCBdID0gc2VsZi5jcmVhdGVDb25uZWN0aW9uKGF0dHJzKTtcblxuICAgICAgICBlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTGFiZWwoYXR0cnMpKSB7XG4gICAgICAgIGF0dHJzLmxhYmVsVGFyZ2V0ID0gY2FjaGVbIGF0dHJzLmxhYmVsVGFyZ2V0IF07XG5cbiAgICAgICAgZWxlbWVudCA9IGNhY2hlWyBkZXNjcmlwdG9yLmlkIF0gPSBzZWxmLmNyZWF0ZUxhYmVsKGF0dHJzKTtcblxuICAgICAgICBlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGF0dHJzLmhvc3QpIHtcbiAgICAgICAgYXR0cnMuaG9zdCA9IGNhY2hlWyBhdHRycy5ob3N0IF07XG4gICAgICB9XG5cbiAgICAgIGVsZW1lbnQgPSBjYWNoZVsgZGVzY3JpcHRvci5pZCBdID0gc2VsZi5jcmVhdGVTaGFwZShhdHRycyk7XG5cbiAgICAgIGVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgfSk7XG5cbiAgfSk7XG5cbiAgcmV0dXJuIGVsZW1lbnRzO1xufTtcblxuQ29weVBhc3RlLnByb3RvdHlwZS5jcmVhdGVDb25uZWN0aW9uID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgdmFyIGNvbm5lY3Rpb24gPSB0aGlzLl9lbGVtZW50RmFjdG9yeS5jcmVhdGVDb25uZWN0aW9uKG9taXQoYXR0cnMsIFsgJ2lkJyBdKSk7XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59O1xuXG5Db3B5UGFzdGUucHJvdG90eXBlLmNyZWF0ZUxhYmVsID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgdmFyIGxhYmVsID0gdGhpcy5fZWxlbWVudEZhY3RvcnkuY3JlYXRlTGFiZWwob21pdChhdHRycywgWyAnaWQnIF0pKTtcblxuICByZXR1cm4gbGFiZWw7XG59O1xuXG5Db3B5UGFzdGUucHJvdG90eXBlLmNyZWF0ZVNoYXBlID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgdmFyIHNoYXBlID0gdGhpcy5fZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUob21pdChhdHRycywgWyAnaWQnIF0pKTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG4vKipcbiAqIENoZWNrIHdldGhlciBlbGVtZW50IGhhcyByZWxhdGlvbnMgdG8gb3RoZXIgZWxlbWVudHMgZS5nLiBhdHRhY2hlcnMsIGxhYmVscyBhbmQgY29ubmVjdGlvbnMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBlbGVtZW50XG4gKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGVsZW1lbnRzXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkNvcHlQYXN0ZS5wcm90b3R5cGUuaGFzUmVsYXRpb25zID0gZnVuY3Rpb24oZWxlbWVudCwgZWxlbWVudHMpIHtcbiAgdmFyIGxhYmVsVGFyZ2V0LFxuICAgICAgc291cmNlLFxuICAgICAgdGFyZ2V0O1xuXG4gIGlmIChpc0Nvbm5lY3Rpb24oZWxlbWVudCkpIHtcbiAgICBzb3VyY2UgPSBmaW5kKGVsZW1lbnRzLCBtYXRjaFBhdHRlcm4oeyBpZDogZWxlbWVudC5zb3VyY2UuaWQgfSkpO1xuICAgIHRhcmdldCA9IGZpbmQoZWxlbWVudHMsIG1hdGNoUGF0dGVybih7IGlkOiBlbGVtZW50LnRhcmdldC5pZCB9KSk7XG5cbiAgICBpZiAoIXNvdXJjZSB8fCAhdGFyZ2V0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzTGFiZWwoZWxlbWVudCkpIHtcbiAgICBsYWJlbFRhcmdldCA9IGZpbmQoZWxlbWVudHMsIG1hdGNoUGF0dGVybih7IGlkOiBlbGVtZW50LmxhYmVsVGFyZ2V0LmlkIH0pKTtcblxuICAgIGlmICghbGFiZWxUYXJnZXQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgdHJlZS1saWtlIHN0cnVjdHVyZSBmcm9tIGVsZW1lbnRzLlxuICpcbiAqIEBleGFtcGxlXG4gKiB0cmVlOiB7XG4gICogIDA6IFtcbiAgKiAgICB7IGlkOiAnU2hhcGVfMScsIHByaW9yaXR5OiAxLCAuLi4gfSxcbiAgKiAgICB7IGlkOiAnU2hhcGVfMicsIHByaW9yaXR5OiAxLCAuLi4gfSxcbiAgKiAgICB7IGlkOiAnQ29ubmVjdGlvbl8xJywgc291cmNlOiAnU2hhcGVfMScsIHRhcmdldDogJ1NoYXBlXzInLCBwcmlvcml0eTogMywgLi4uIH0sXG4gICogICAgLi4uXG4gICogIF0sXG4gICogIDE6IFtcbiAgKiAgICB7IGlkOiAnU2hhcGVfMycsIHBhcmVudDogJ1NoYXBlMScsIHByaW9yaXR5OiAxLCAuLi4gfSxcbiAgKiAgICAuLi5cbiAgKiAgXVxuICAqIH07XG4gICpcbiAgKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuYmFzZT59IGVsZW1lbnRzXG4gICpcbiAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICovXG5Db3B5UGFzdGUucHJvdG90eXBlLmNyZWF0ZVRyZWUgPSBmdW5jdGlvbihlbGVtZW50cykge1xuICB2YXIgcnVsZXMgPSB0aGlzLl9ydWxlcyxcbiAgICAgIHNlbGYgPSB0aGlzO1xuXG4gIHZhciB0cmVlID0ge30sXG4gICAgICBlbGVtZW50c0RhdGEgPSBbXTtcblxuICB2YXIgcGFyZW50cyA9IGdldFBhcmVudHMoZWxlbWVudHMpO1xuXG4gIGZ1bmN0aW9uIGNhbkNvcHkoZWxlbWVudCwgZWxlbWVudHMpIHtcbiAgICByZXR1cm4gcnVsZXMuYWxsb3dlZCgnZWxlbWVudC5jb3B5Jywge1xuICAgICAgZWxlbWVudDogZWxlbWVudCxcbiAgICAgIGVsZW1lbnRzOiBlbGVtZW50c1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkRWxlbWVudERhdGEoZWxlbWVudCwgZGVwdGgpIHtcblxuICAgIC8vICgxKSBjaGVjayB3ZXRoZXIgZWxlbWVudCBoYXMgYWxyZWFkeSBiZWVuIGFkZGVkXG4gICAgdmFyIGZvdW5kRWxlbWVudERhdGEgPSBmaW5kKGVsZW1lbnRzRGF0YSwgZnVuY3Rpb24oZWxlbWVudHNEYXRhKSB7XG4gICAgICByZXR1cm4gZWxlbWVudCA9PT0gZWxlbWVudHNEYXRhLmVsZW1lbnQ7XG4gICAgfSk7XG5cbiAgICAvLyAoMikgYWRkIGVsZW1lbnQgaWYgbm90IGFscmVhZHkgYWRkZWRcbiAgICBpZiAoIWZvdW5kRWxlbWVudERhdGEpIHtcbiAgICAgIGVsZW1lbnRzRGF0YS5wdXNoKHtcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZGVwdGg6IGRlcHRoXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vICgzKSB1cGRhdGUgZGVwdGhcbiAgICBpZiAoZm91bmRFbGVtZW50RGF0YS5kZXB0aCA8IGRlcHRoKSB7XG4gICAgICBlbGVtZW50c0RhdGEgPSByZW1vdmVFbGVtZW50RGF0YShmb3VuZEVsZW1lbnREYXRhLCBlbGVtZW50c0RhdGEpO1xuXG4gICAgICBlbGVtZW50c0RhdGEucHVzaCh7XG4gICAgICAgIGVsZW1lbnQ6IGZvdW5kRWxlbWVudERhdGEuZWxlbWVudCxcbiAgICAgICAgZGVwdGg6IGRlcHRoXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVFbGVtZW50RGF0YShlbGVtZW50RGF0YSwgZWxlbWVudHNEYXRhKSB7XG4gICAgdmFyIGluZGV4ID0gZWxlbWVudHNEYXRhLmluZGV4T2YoZWxlbWVudERhdGEpO1xuXG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgZWxlbWVudHNEYXRhLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsZW1lbnRzRGF0YTtcbiAgfVxuXG4gIC8vICgxKSBhZGQgZWxlbWVudHNcbiAgZWFjaEVsZW1lbnQocGFyZW50cywgZnVuY3Rpb24oZWxlbWVudCwgX2luZGV4LCBkZXB0aCkge1xuXG4gICAgLy8gZG8gTk9UIGFkZCBleHRlcm5hbCBsYWJlbHMgZGlyZWN0bHlcbiAgICBpZiAoaXNMYWJlbChlbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGFsd2F5cyBjb3B5IGV4dGVybmFsIGxhYmVsc1xuICAgIGZvckVhY2goZWxlbWVudC5sYWJlbHMsIGZ1bmN0aW9uKGxhYmVsKSB7XG4gICAgICBhZGRFbGVtZW50RGF0YShsYWJlbCwgZGVwdGgpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYWRkUmVsYXRlZEVsZW1lbnRzKGVsZW1lbnRzKSB7XG4gICAgICBlbGVtZW50cyAmJiBlbGVtZW50cy5sZW5ndGggJiYgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgICAgIC8vIGFkZCBleHRlcm5hbCBsYWJlbHNcbiAgICAgICAgZm9yRWFjaChlbGVtZW50LmxhYmVscywgZnVuY3Rpb24obGFiZWwpIHtcbiAgICAgICAgICBhZGRFbGVtZW50RGF0YShsYWJlbCwgZGVwdGgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBhZGRFbGVtZW50RGF0YShlbGVtZW50LCBkZXB0aCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmb3JFYWNoKFsgZWxlbWVudC5hdHRhY2hlcnMsIGVsZW1lbnQuaW5jb21pbmcsIGVsZW1lbnQub3V0Z29pbmcgXSwgYWRkUmVsYXRlZEVsZW1lbnRzKTtcblxuICAgIGFkZEVsZW1lbnREYXRhKGVsZW1lbnQsIGRlcHRoKTtcblxuICAgIHJldHVybiBlbGVtZW50LmNoaWxkcmVuO1xuICB9KTtcblxuICBlbGVtZW50cyA9IG1hcChlbGVtZW50c0RhdGEsIGZ1bmN0aW9uKGVsZW1lbnREYXRhKSB7XG4gICAgcmV0dXJuIGVsZW1lbnREYXRhLmVsZW1lbnQ7XG4gIH0pO1xuXG4gIC8vICgyKSBjb3B5IGVsZW1lbnRzXG4gIGVsZW1lbnRzRGF0YSA9IG1hcChlbGVtZW50c0RhdGEsIGZ1bmN0aW9uKGVsZW1lbnREYXRhKSB7XG4gICAgZWxlbWVudERhdGEuZGVzY3JpcHRvciA9IHt9O1xuXG4gICAgc2VsZi5fZXZlbnRCdXMuZmlyZSgnY29weVBhc3RlLmNvcHlFbGVtZW50Jywge1xuICAgICAgZGVzY3JpcHRvcjogZWxlbWVudERhdGEuZGVzY3JpcHRvcixcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnREYXRhLmVsZW1lbnQsXG4gICAgICBlbGVtZW50czogZWxlbWVudHNcbiAgICB9KTtcblxuICAgIHJldHVybiBlbGVtZW50RGF0YTtcbiAgfSk7XG5cbiAgLy8gKDMpIHNvcnQgZWxlbWVudHMgYnkgcHJpb3JpdHlcbiAgZWxlbWVudHNEYXRhID0gc29ydEJ5KGVsZW1lbnRzRGF0YSwgZnVuY3Rpb24oZWxlbWVudERhdGEpIHtcbiAgICByZXR1cm4gZWxlbWVudERhdGEuZGVzY3JpcHRvci5wcmlvcml0eTtcbiAgfSk7XG5cbiAgZWxlbWVudHMgPSBtYXAoZWxlbWVudHNEYXRhLCBmdW5jdGlvbihlbGVtZW50RGF0YSkge1xuICAgIHJldHVybiBlbGVtZW50RGF0YS5lbGVtZW50O1xuICB9KTtcblxuICAvLyAoNCkgY3JlYXRlIHRyZWVcbiAgZm9yRWFjaChlbGVtZW50c0RhdGEsIGZ1bmN0aW9uKGVsZW1lbnREYXRhKSB7XG4gICAgdmFyIGRlcHRoID0gZWxlbWVudERhdGEuZGVwdGg7XG5cbiAgICBpZiAoIXNlbGYuaGFzUmVsYXRpb25zKGVsZW1lbnREYXRhLmVsZW1lbnQsIGVsZW1lbnRzKSkge1xuICAgICAgcmVtb3ZlRWxlbWVudChlbGVtZW50RGF0YS5lbGVtZW50LCBlbGVtZW50cyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWNhbkNvcHkoZWxlbWVudERhdGEuZWxlbWVudCwgZWxlbWVudHMpKSB7XG4gICAgICByZW1vdmVFbGVtZW50KGVsZW1lbnREYXRhLmVsZW1lbnQsIGVsZW1lbnRzKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdHJlZVtkZXB0aF0pIHtcbiAgICAgIHRyZWVbZGVwdGhdID0gW107XG4gICAgfVxuXG4gICAgdHJlZVtkZXB0aF0ucHVzaChlbGVtZW50RGF0YS5kZXNjcmlwdG9yKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHRyZWU7XG59O1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNBdHRhY2hlcihlbGVtZW50KSB7XG4gIHJldHVybiAhIWVsZW1lbnQuaG9zdDtcbn1cblxuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuICEhZWxlbWVudC53YXlwb2ludHM7XG59XG5cbmZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gISFlbGVtZW50LmxhYmVsVGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBjb3B5V2F5cG9pbnRzKGVsZW1lbnQpIHtcbiAgcmV0dXJuIG1hcChlbGVtZW50LndheXBvaW50cywgZnVuY3Rpb24od2F5cG9pbnQpIHtcblxuICAgIHdheXBvaW50ID0gY29weVdheXBvaW50KHdheXBvaW50KTtcblxuICAgIGlmICh3YXlwb2ludC5vcmlnaW5hbCkge1xuICAgICAgd2F5cG9pbnQub3JpZ2luYWwgPSBjb3B5V2F5cG9pbnQod2F5cG9pbnQub3JpZ2luYWwpO1xuICAgIH1cblxuICAgIHJldHVybiB3YXlwb2ludDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvcHlXYXlwb2ludCh3YXlwb2ludCkge1xuICByZXR1cm4gYXNzaWduKHt9LCB3YXlwb2ludCk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUVsZW1lbnQoZWxlbWVudCwgZWxlbWVudHMpIHtcbiAgdmFyIGluZGV4ID0gZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KTtcblxuICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgcmV0dXJuIGVsZW1lbnRzO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnRzLnNwbGljZShpbmRleCwgMSk7XG59XG4iLCJpbXBvcnQgQ2xpcGJvYXJkTW9kdWxlIGZyb20gJy4uL2NsaXBib2FyZCc7XG5pbXBvcnQgQ3JlYXRlTW9kdWxlIGZyb20gJy4uL2NyZWF0ZSc7XG5pbXBvcnQgTW91c2VNb2R1bGUgZnJvbSAnLi4vbW91c2UnO1xuaW1wb3J0IFJ1bGVzTW9kdWxlIGZyb20gJy4uL3J1bGVzJztcblxuaW1wb3J0IENvcHlQYXN0ZSBmcm9tICcuL0NvcHlQYXN0ZSc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIENsaXBib2FyZE1vZHVsZSxcbiAgICBDcmVhdGVNb2R1bGUsXG4gICAgTW91c2VNb2R1bGUsXG4gICAgUnVsZXNNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2NvcHlQYXN0ZScgXSxcbiAgY29weVBhc3RlOiBbICd0eXBlJywgQ29weVBhc3RlIF1cbn07XG4iLCJ2YXIgTUFSS0VSX09LID0gJ2Ryb3Atb2snLFxuICAgIE1BUktFUl9OT1RfT0sgPSAnZHJvcC1ub3Qtb2snLFxuICAgIE1BUktFUl9BVFRBQ0ggPSAnYXR0YWNoLW9rJyxcbiAgICBNQVJLRVJfTkVXX1BBUkVOVCA9ICduZXctcGFyZW50JztcblxuaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaWx0ZXIsXG4gIGZpbmQsXG4gIGZvckVhY2gsXG4gIGlzQXJyYXksXG4gIGlzTnVtYmVyLFxuICBtYXBcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgeyBnZXRCQm94IH0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbnZhciBQUkVGSVggPSAnY3JlYXRlJztcblxudmFyIEhJR0hfUFJJT1JJVFkgPSAyMDAwO1xuXG5cbi8qKlxuICogQ3JlYXRlIG5ldyBlbGVtZW50cyB0aHJvdWdoIGRyYWcgYW5kIGRyb3AuXG4gKlxuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICogQHBhcmFtIHtEcmFnZ2luZ30gZHJhZ2dpbmdcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICogQHBhcmFtIHtSdWxlc30gcnVsZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ3JlYXRlKFxuICAgIGNhbnZhcyxcbiAgICBkcmFnZ2luZyxcbiAgICBldmVudEJ1cyxcbiAgICBtb2RlbGluZyxcbiAgICBydWxlc1xuKSB7XG5cbiAgLy8gcnVsZXMgLy8vLy8vLy8vL1xuXG4gIC8qKlxuICAgKiBDaGVjayB3ZXRoZXIgZWxlbWVudHMgY2FuIGJlIGNyZWF0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSB0YXJnZXRcbiAgICogQHBhcmFtIHtQb2ludH0gcG9zaXRpb25cbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gW3NvdXJjZV1cbiAgICpcbiAgICogQHJldHVybnMge2Jvb2xlYW58bnVsbHxPYmplY3R9XG4gICAqL1xuICBmdW5jdGlvbiBjYW5DcmVhdGUoZWxlbWVudHMsIHRhcmdldCwgcG9zaXRpb24sIHNvdXJjZSwgaGludHMpIHtcbiAgICBpZiAoIXRhcmdldCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIGlnbm9yZSBjaGlsZCBlbGVtZW50cyBhbmQgZXh0ZXJuYWwgbGFiZWxzXG4gICAgZWxlbWVudHMgPSBmaWx0ZXIoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgIHZhciBsYWJlbFRhcmdldCA9IGVsZW1lbnQubGFiZWxUYXJnZXQ7XG5cbiAgICAgIHJldHVybiAhZWxlbWVudC5wYXJlbnQgJiYgIShpc0xhYmVsKGVsZW1lbnQpICYmIGVsZW1lbnRzLmluZGV4T2YobGFiZWxUYXJnZXQpICE9PSAtMSk7XG4gICAgfSk7XG5cbiAgICB2YXIgc2hhcGUgPSBmaW5kKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gIWlzQ29ubmVjdGlvbihlbGVtZW50KTtcbiAgICB9KTtcblxuICAgIHZhciBhdHRhY2ggPSBmYWxzZSxcbiAgICAgICAgY29ubmVjdCA9IGZhbHNlLFxuICAgICAgICBjcmVhdGUgPSBmYWxzZTtcblxuICAgIC8vICgxKSBhdHRhY2hpbmcgc2luZ2xlIHNoYXBlc1xuICAgIGlmIChpc1NpbmdsZVNoYXBlKGVsZW1lbnRzKSkge1xuICAgICAgYXR0YWNoID0gcnVsZXMuYWxsb3dlZCgnc2hhcGUuYXR0YWNoJywge1xuICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgIHNoYXBlOiBzaGFwZSxcbiAgICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICghYXR0YWNoKSB7XG5cbiAgICAgIC8vICgyKSBjcmVhdGluZyBlbGVtZW50c1xuICAgICAgaWYgKGlzU2luZ2xlU2hhcGUoZWxlbWVudHMpKSB7XG4gICAgICAgIGNyZWF0ZSA9IHJ1bGVzLmFsbG93ZWQoJ3NoYXBlLmNyZWF0ZScsIHtcbiAgICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgICAgc2hhcGU6IHNoYXBlLFxuICAgICAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgICAgIHRhcmdldDogdGFyZ2V0XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3JlYXRlID0gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMuY3JlYXRlJywge1xuICAgICAgICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICB9XG5cbiAgICB2YXIgY29ubmVjdGlvblRhcmdldCA9IGhpbnRzLmNvbm5lY3Rpb25UYXJnZXQ7XG5cbiAgICAvLyAoMykgYXBwZW5kaW5nIHNpbmdsZSBzaGFwZXNcbiAgICBpZiAoY3JlYXRlIHx8IGF0dGFjaCkge1xuICAgICAgaWYgKHNoYXBlICYmIHNvdXJjZSkge1xuICAgICAgICBjb25uZWN0ID0gcnVsZXMuYWxsb3dlZCgnY29ubmVjdGlvbi5jcmVhdGUnLCB7XG4gICAgICAgICAgc291cmNlOiBjb25uZWN0aW9uVGFyZ2V0ID09PSBzb3VyY2UgPyBzaGFwZSA6IHNvdXJjZSxcbiAgICAgICAgICB0YXJnZXQ6IGNvbm5lY3Rpb25UYXJnZXQgPT09IHNvdXJjZSA/IHNvdXJjZSA6IHNoYXBlLFxuICAgICAgICAgIGhpbnRzOiB7XG4gICAgICAgICAgICB0YXJnZXRQYXJlbnQ6IHRhcmdldCxcbiAgICAgICAgICAgIHRhcmdldEF0dGFjaDogYXR0YWNoXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXR0YWNoOiBhdHRhY2gsXG4gICAgICAgIGNvbm5lY3Q6IGNvbm5lY3RcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gaWdub3JlIHdldGhlciBvciBub3QgZWxlbWVudHMgY2FuIGJlIGNyZWF0ZWRcbiAgICBpZiAoY3JlYXRlID09PSBudWxsIHx8IGF0dGFjaCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0TWFya2VyKGVsZW1lbnQsIG1hcmtlcikge1xuICAgIFsgTUFSS0VSX0FUVEFDSCwgTUFSS0VSX09LLCBNQVJLRVJfTk9UX09LLCBNQVJLRVJfTkVXX1BBUkVOVCBdLmZvckVhY2goZnVuY3Rpb24obSkge1xuXG4gICAgICBpZiAobSA9PT0gbWFya2VyKSB7XG4gICAgICAgIGNhbnZhcy5hZGRNYXJrZXIoZWxlbWVudCwgbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYW52YXMucmVtb3ZlTWFya2VyKGVsZW1lbnQsIG0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gZXZlbnQgaGFuZGxpbmcgLy8vLy8vLy8vL1xuXG4gIGV2ZW50QnVzLm9uKFsgJ2NyZWF0ZS5tb3ZlJywgJ2NyZWF0ZS5ob3ZlcicgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnRzID0gY29udGV4dC5lbGVtZW50cyxcbiAgICAgICAgaG92ZXIgPSBldmVudC5ob3ZlcixcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fTtcblxuICAgIGlmICghaG92ZXIpIHtcbiAgICAgIGNvbnRleHQuY2FuRXhlY3V0ZSA9IGZhbHNlO1xuICAgICAgY29udGV4dC50YXJnZXQgPSBudWxsO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZW5zdXJlQ29uc3RyYWludHMoZXZlbnQpO1xuXG4gICAgdmFyIHBvc2l0aW9uID0ge1xuICAgICAgeDogZXZlbnQueCxcbiAgICAgIHk6IGV2ZW50LnlcbiAgICB9O1xuXG4gICAgdmFyIGNhbkV4ZWN1dGUgPSBjb250ZXh0LmNhbkV4ZWN1dGUgPSBob3ZlciAmJiBjYW5DcmVhdGUoZWxlbWVudHMsIGhvdmVyLCBwb3NpdGlvbiwgc291cmNlLCBoaW50cyk7XG5cbiAgICBpZiAoaG92ZXIgJiYgY2FuRXhlY3V0ZSAhPT0gbnVsbCkge1xuICAgICAgY29udGV4dC50YXJnZXQgPSBob3ZlcjtcblxuICAgICAgaWYgKGNhbkV4ZWN1dGUgJiYgY2FuRXhlY3V0ZS5hdHRhY2gpIHtcbiAgICAgICAgc2V0TWFya2VyKGhvdmVyLCBNQVJLRVJfQVRUQUNIKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldE1hcmtlcihob3ZlciwgY2FuRXhlY3V0ZSA/IE1BUktFUl9ORVdfUEFSRU5UIDogTUFSS0VSX05PVF9PSyk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdjcmVhdGUuZW5kJywgJ2NyZWF0ZS5vdXQnLCAnY3JlYXRlLmNsZWFudXAnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGhvdmVyID0gZXZlbnQuaG92ZXI7XG5cbiAgICBpZiAoaG92ZXIpIHtcbiAgICAgIHNldE1hcmtlcihob3ZlciwgbnVsbCk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignY3JlYXRlLmVuZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzb3VyY2UgPSBjb250ZXh0LnNvdXJjZSxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBhdHRhY2ggPSBjYW5FeGVjdXRlICYmIGNhbkV4ZWN1dGUuYXR0YWNoLFxuICAgICAgICBjb25uZWN0ID0gY2FuRXhlY3V0ZSAmJiBjYW5FeGVjdXRlLmNvbm5lY3QsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fTtcblxuICAgIGlmIChjYW5FeGVjdXRlID09PSBmYWxzZSB8fCAhdGFyZ2V0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZW5zdXJlQ29uc3RyYWludHMoZXZlbnQpO1xuXG4gICAgdmFyIHBvc2l0aW9uID0ge1xuICAgICAgeDogZXZlbnQueCxcbiAgICAgIHk6IGV2ZW50LnlcbiAgICB9O1xuXG4gICAgaWYgKGNvbm5lY3QpIHtcbiAgICAgIHNoYXBlID0gbW9kZWxpbmcuYXBwZW5kU2hhcGUoc291cmNlLCBzaGFwZSwgcG9zaXRpb24sIHRhcmdldCwge1xuICAgICAgICBhdHRhY2g6IGF0dGFjaCxcbiAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdCA9PT0gdHJ1ZSA/IHt9IDogY29ubmVjdCxcbiAgICAgICAgY29ubmVjdGlvblRhcmdldDogaGludHMuY29ubmVjdGlvblRhcmdldFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnRzID0gbW9kZWxpbmcuY3JlYXRlRWxlbWVudHMoZWxlbWVudHMsIHBvc2l0aW9uLCB0YXJnZXQsIGFzc2lnbih7fSwgaGludHMsIHtcbiAgICAgICAgYXR0YWNoOiBhdHRhY2hcbiAgICAgIH0pKTtcblxuICAgICAgLy8gdXBkYXRlIHNoYXBlXG4gICAgICBzaGFwZSA9IGZpbmQoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuICFpc0Nvbm5lY3Rpb24oZWxlbWVudCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyB1cGRhdGUgZWxlbWVudHMgYW5kIHNoYXBlXG4gICAgYXNzaWduKGNvbnRleHQsIHtcbiAgICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICAgIHNoYXBlOiBzaGFwZVxuICAgIH0pO1xuXG4gICAgYXNzaWduKGV2ZW50LCB7XG4gICAgICBlbGVtZW50czogZWxlbWVudHMsXG4gICAgICBzaGFwZTogc2hhcGVcbiAgICB9KTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gY2FuY2VsKCkge1xuICAgIHZhciBjb250ZXh0ID0gZHJhZ2dpbmcuY29udGV4dCgpO1xuXG4gICAgaWYgKGNvbnRleHQgJiYgY29udGV4dC5wcmVmaXggPT09IFBSRUZJWCkge1xuICAgICAgZHJhZ2dpbmcuY2FuY2VsKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gY2FuY2VsIG9uIDxlbGVtZW50cy5jaGFuZ2VkPiB0aGF0IGlzIG5vdCByZXN1bHQgb2YgPGRyYWcuZW5kPlxuICBldmVudEJ1cy5vbignY3JlYXRlLmluaXQnLCBmdW5jdGlvbigpIHtcbiAgICBldmVudEJ1cy5vbignZWxlbWVudHMuY2hhbmdlZCcsIGNhbmNlbCk7XG5cbiAgICBldmVudEJ1cy5vbmNlKFsgJ2NyZWF0ZS5jYW5jZWwnLCAnY3JlYXRlLmVuZCcgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oKSB7XG4gICAgICBldmVudEJ1cy5vZmYoJ2VsZW1lbnRzLmNoYW5nZWQnLCBjYW5jZWwpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBBUEkgLy8vLy8vLy8vL1xuXG4gIHRoaXMuc3RhcnQgPSBmdW5jdGlvbihldmVudCwgZWxlbWVudHMsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzQXJyYXkoZWxlbWVudHMpKSB7XG4gICAgICBlbGVtZW50cyA9IFsgZWxlbWVudHMgXTtcbiAgICB9XG5cbiAgICB2YXIgc2hhcGUgPSBmaW5kKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gIWlzQ29ubmVjdGlvbihlbGVtZW50KTtcbiAgICB9KTtcblxuICAgIGlmICghc2hhcGUpIHtcblxuICAgICAgLy8gYXQgbGVhc3Qgb25lIHNoYXBlIGlzIHJlcXVpcmVkXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29udGV4dCA9IGFzc2lnbih7XG4gICAgICBlbGVtZW50czogZWxlbWVudHMsXG4gICAgICBoaW50czoge30sXG4gICAgICBzaGFwZTogc2hhcGVcbiAgICB9LCBjb250ZXh0IHx8IHt9KTtcblxuICAgIC8vIG1ha2Ugc3VyZSBlYWNoIGVsZW1lbnQgaGFzIHggYW5kIHlcbiAgICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICBpZiAoIWlzTnVtYmVyKGVsZW1lbnQueCkpIHtcbiAgICAgICAgZWxlbWVudC54ID0gMDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc051bWJlcihlbGVtZW50LnkpKSB7XG4gICAgICAgIGVsZW1lbnQueSA9IDA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB2YXIgYmJveCA9IGdldEJCb3goZWxlbWVudHMpO1xuXG4gICAgLy8gY2VudGVyIGVsZW1lbnRzIGFyb3VuZCBjdXJzb3JcbiAgICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICBpZiAoaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICAgIGVsZW1lbnQud2F5cG9pbnRzID0gbWFwKGVsZW1lbnQud2F5cG9pbnRzLCBmdW5jdGlvbih3YXlwb2ludCkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB3YXlwb2ludC54IC0gYmJveC54IC0gYmJveC53aWR0aCAvIDIsXG4gICAgICAgICAgICB5OiB3YXlwb2ludC55IC0gYmJveC55IC0gYmJveC5oZWlnaHQgLyAyXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGFzc2lnbihlbGVtZW50LCB7XG4gICAgICAgIHg6IGVsZW1lbnQueCAtIGJib3gueCAtIGJib3gud2lkdGggLyAyLFxuICAgICAgICB5OiBlbGVtZW50LnkgLSBiYm94LnkgLSBiYm94LmhlaWdodCAvIDJcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZHJhZ2dpbmcuaW5pdChldmVudCwgUFJFRklYLCB7XG4gICAgICBjdXJzb3I6ICdncmFiYmluZycsXG4gICAgICBhdXRvQWN0aXZhdGU6IHRydWUsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIHNoYXBlOiBzaGFwZSxcbiAgICAgICAgZWxlbWVudHM6IGVsZW1lbnRzLFxuICAgICAgICBjb250ZXh0OiBjb250ZXh0XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59XG5cbkNyZWF0ZS4kaW5qZWN0ID0gW1xuICAnY2FudmFzJyxcbiAgJ2RyYWdnaW5nJyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGVsaW5nJyxcbiAgJ3J1bGVzJ1xuXTtcblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGVuc3VyZUNvbnN0cmFpbnRzKGV2ZW50KSB7XG4gIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgIGNyZWF0ZUNvbnN0cmFpbnRzID0gY29udGV4dC5jcmVhdGVDb25zdHJhaW50cztcblxuICBpZiAoIWNyZWF0ZUNvbnN0cmFpbnRzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGNyZWF0ZUNvbnN0cmFpbnRzLmxlZnQpIHtcbiAgICBldmVudC54ID0gTWF0aC5tYXgoZXZlbnQueCwgY3JlYXRlQ29uc3RyYWludHMubGVmdCk7XG4gIH1cblxuICBpZiAoY3JlYXRlQ29uc3RyYWludHMucmlnaHQpIHtcbiAgICBldmVudC54ID0gTWF0aC5taW4oZXZlbnQueCwgY3JlYXRlQ29uc3RyYWludHMucmlnaHQpO1xuICB9XG5cbiAgaWYgKGNyZWF0ZUNvbnN0cmFpbnRzLnRvcCkge1xuICAgIGV2ZW50LnkgPSBNYXRoLm1heChldmVudC55LCBjcmVhdGVDb25zdHJhaW50cy50b3ApO1xuICB9XG5cbiAgaWYgKGNyZWF0ZUNvbnN0cmFpbnRzLmJvdHRvbSkge1xuICAgIGV2ZW50LnkgPSBNYXRoLm1pbihldmVudC55LCBjcmVhdGVDb25zdHJhaW50cy5ib3R0b20pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ29ubmVjdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiAhIWVsZW1lbnQud2F5cG9pbnRzO1xufVxuXG5mdW5jdGlvbiBpc1NpbmdsZVNoYXBlKGVsZW1lbnRzKSB7XG4gIHJldHVybiBlbGVtZW50cyAmJiBlbGVtZW50cy5sZW5ndGggPT09IDEgJiYgIWlzQ29ubmVjdGlvbihlbGVtZW50c1swXSk7XG59XG5cbmZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gISFlbGVtZW50LmxhYmVsVGFyZ2V0O1xufVxuIiwiaW1wb3J0IHtcclxuICB0cmFuc2xhdGVcclxufSBmcm9tICcuLi8uLi91dGlsL1N2Z1RyYW5zZm9ybVV0aWwnO1xyXG5cclxuaW1wb3J0IHsgZ2V0VmlzdWFsIH0gZnJvbSAnLi4vLi4vdXRpbC9HcmFwaGljc1V0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxyXG4gIGF0dHIgYXMgc3ZnQXR0cixcclxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxyXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcclxufSBmcm9tICd0aW55LXN2Zyc7XHJcblxyXG52YXIgTE9XX1BSSU9SSVRZID0gNzUwO1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENyZWF0ZVByZXZpZXcoXHJcbiAgICBjYW52YXMsXHJcbiAgICBldmVudEJ1cyxcclxuICAgIGdyYXBoaWNzRmFjdG9yeSxcclxuICAgIHByZXZpZXdTdXBwb3J0LFxyXG4gICAgc3R5bGVzXHJcbikge1xyXG4gIGZ1bmN0aW9uIGNyZWF0ZURyYWdHcm91cChlbGVtZW50cykge1xyXG4gICAgdmFyIGRyYWdHcm91cCA9IHN2Z0NyZWF0ZSgnZycpO1xyXG5cclxuICAgIHN2Z0F0dHIoZHJhZ0dyb3VwLCBzdHlsZXMuY2xzKCdkanMtZHJhZy1ncm91cCcsIFsgJ25vLWV2ZW50cycgXSkpO1xyXG5cclxuICAgIHZhciBjaGlsZHJlbkdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xyXG5cclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cclxuICAgICAgLy8gY3JlYXRlIGdyYXBoaWNzXHJcbiAgICAgIHZhciBnZng7XHJcblxyXG4gICAgICBpZiAoZWxlbWVudC5oaWRkZW4pIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChlbGVtZW50LndheXBvaW50cykge1xyXG4gICAgICAgIGdmeCA9IGdyYXBoaWNzRmFjdG9yeS5fY3JlYXRlQ29udGFpbmVyKCdjb25uZWN0aW9uJywgY2hpbGRyZW5HZngpO1xyXG5cclxuICAgICAgICBncmFwaGljc0ZhY3RvcnkuZHJhd0Nvbm5lY3Rpb24oZ2V0VmlzdWFsKGdmeCksIGVsZW1lbnQpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGdmeCA9IGdyYXBoaWNzRmFjdG9yeS5fY3JlYXRlQ29udGFpbmVyKCdzaGFwZScsIGNoaWxkcmVuR2Z4KTtcclxuXHJcbiAgICAgICAgZ3JhcGhpY3NGYWN0b3J5LmRyYXdTaGFwZShnZXRWaXN1YWwoZ2Z4KSwgZWxlbWVudCk7XHJcblxyXG4gICAgICAgIHRyYW5zbGF0ZShnZngsIGVsZW1lbnQueCwgZWxlbWVudC55KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gYWRkIHByZXZpZXdcclxuICAgICAgcHJldmlld1N1cHBvcnQuYWRkRHJhZ2dlcihlbGVtZW50LCBkcmFnR3JvdXAsIGdmeCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gZHJhZ0dyb3VwO1xyXG4gIH1cclxuXHJcbiAgZXZlbnRCdXMub24oJ2NyZWF0ZS5tb3ZlJywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xyXG5cclxuICAgIHZhciBob3ZlciA9IGV2ZW50LmhvdmVyLFxyXG4gICAgICAgIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIGVsZW1lbnRzID0gY29udGV4dC5lbGVtZW50cyxcclxuICAgICAgICBkcmFnR3JvdXAgPSBjb250ZXh0LmRyYWdHcm91cDtcclxuXHJcbiAgICAvLyBsYXppbHkgY3JlYXRlIHByZXZpZXdzXHJcbiAgICBpZiAoIWRyYWdHcm91cCkge1xyXG4gICAgICBkcmFnR3JvdXAgPSBjb250ZXh0LmRyYWdHcm91cCA9IGNyZWF0ZURyYWdHcm91cChlbGVtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGRlZmF1bHRMYXllcjtcclxuXHJcbiAgICBpZiAoaG92ZXIpIHtcclxuICAgICAgaWYgKCFkcmFnR3JvdXAucGFyZW50Tm9kZSkge1xyXG4gICAgICAgIGRlZmF1bHRMYXllciA9IGNhbnZhcy5nZXREZWZhdWx0TGF5ZXIoKTtcclxuXHJcbiAgICAgICAgc3ZnQXBwZW5kKGRlZmF1bHRMYXllciwgZHJhZ0dyb3VwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdHJhbnNsYXRlKGRyYWdHcm91cCwgZXZlbnQueCwgZXZlbnQueSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzdmdSZW1vdmUoZHJhZ0dyb3VwKTtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgZXZlbnRCdXMub24oJ2NyZWF0ZS5jbGVhbnVwJywgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBkcmFnR3JvdXAgPSBjb250ZXh0LmRyYWdHcm91cDtcclxuXHJcbiAgICBpZiAoZHJhZ0dyb3VwKSB7XHJcbiAgICAgIHN2Z1JlbW92ZShkcmFnR3JvdXApO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5DcmVhdGVQcmV2aWV3LiRpbmplY3QgPSBbXHJcbiAgJ2NhbnZhcycsXHJcbiAgJ2V2ZW50QnVzJyxcclxuICAnZ3JhcGhpY3NGYWN0b3J5JyxcclxuICAncHJldmlld1N1cHBvcnQnLFxyXG4gICdzdHlsZXMnXHJcbl07XHJcbiIsImltcG9ydCBEcmFnZ2luZ01vZHVsZSBmcm9tICcuLi9kcmFnZ2luZyc7XG5pbXBvcnQgUHJldmlld1N1cHBvcnRNb2R1bGUgZnJvbSAnLi4vcHJldmlldy1zdXBwb3J0JztcbmltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgU2VsZWN0aW9uTW9kdWxlIGZyb20gJy4uL3NlbGVjdGlvbic7XG5cbmltcG9ydCBDcmVhdGUgZnJvbSAnLi9DcmVhdGUnO1xuaW1wb3J0IENyZWF0ZVByZXZpZXcgZnJvbSAnLi9DcmVhdGVQcmV2aWV3JztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgRHJhZ2dpbmdNb2R1bGUsXG4gICAgUHJldmlld1N1cHBvcnRNb2R1bGUsXG4gICAgUnVsZXNNb2R1bGUsXG4gICAgU2VsZWN0aW9uTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbXG4gICAgJ2NyZWF0ZScsXG4gICAgJ2NyZWF0ZVByZXZpZXcnXG4gIF0sXG4gIGNyZWF0ZTogWyAndHlwZScsIENyZWF0ZSBdLFxuICBjcmVhdGVQcmV2aWV3OiBbICd0eXBlJywgQ3JlYXRlUHJldmlldyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgc29ydEJ5LFxuICBmb3JFYWNoLFxuICBmaWx0ZXJcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgQVhJU19ESU1FTlNJT05TID0ge1xuICBob3Jpem9udGFsOiBbICd4JywgJ3dpZHRoJyBdLFxuICB2ZXJ0aWNhbDogWyAneScsICdoZWlnaHQnIF1cbn07XG5cbnZhciBUSFJFU0hPTEQgPSA1O1xuXG5cbi8qKlxuICogR3JvdXBzIGFuZCBmaWx0ZXJzIGVsZW1lbnRzIGFuZCB0aGVuIHRyaWdnZXIgZXZlbiBkaXN0cmlidXRpb24uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERpc3RyaWJ1dGVFbGVtZW50cyhtb2RlbGluZykge1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xuXG4gIHRoaXMuX2ZpbHRlcnMgPSBbXTtcblxuICAvLyByZWdpc3RlciBmaWx0ZXIgZm9yIGZpbHRlcmluZyBiaWcgZWxlbWVudHNcbiAgdGhpcy5yZWdpc3RlckZpbHRlcihmdW5jdGlvbihlbGVtZW50cywgYXhpcywgZGltZW5zaW9uKSB7XG4gICAgdmFyIGVsZW1lbnRzU2l6ZSA9IDAsXG4gICAgICAgIG51bU9mU2hhcGVzID0gMCxcbiAgICAgICAgYXZnRGltZW5zaW9uO1xuXG4gICAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzIHx8IGVsZW1lbnQubGFiZWxUYXJnZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBlbGVtZW50c1NpemUgKz0gZWxlbWVudFtkaW1lbnNpb25dO1xuXG4gICAgICBudW1PZlNoYXBlcyArPSAxO1xuICAgIH0pO1xuXG4gICAgYXZnRGltZW5zaW9uID0gTWF0aC5yb3VuZChlbGVtZW50c1NpemUgLyBudW1PZlNoYXBlcyk7XG5cbiAgICByZXR1cm4gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZWxlbWVudFtkaW1lbnNpb25dIDwgKGF2Z0RpbWVuc2lvbiArIDUwKTtcbiAgICB9KTtcbiAgfSk7XG5cbn1cblxuRGlzdHJpYnV0ZUVsZW1lbnRzLiRpbmplY3QgPSBbICdtb2RlbGluZycgXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVycyBmaWx0ZXIgZnVuY3Rpb25zIHRoYXQgYWxsb3cgZXh0ZXJuYWwgcGFydGllcyB0byBmaWx0ZXJcbiAqIG91dCBjZXJ0YWluIGVsZW1lbnRzLlxuICpcbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmaWx0ZXJGblxuICovXG5EaXN0cmlidXRlRWxlbWVudHMucHJvdG90eXBlLnJlZ2lzdGVyRmlsdGVyID0gZnVuY3Rpb24oZmlsdGVyRm4pIHtcbiAgaWYgKHR5cGVvZiBmaWx0ZXJGbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcigndGhlIGZpbHRlciBoYXMgdG8gYmUgYSBmdW5jdGlvbicpO1xuICB9XG5cbiAgdGhpcy5fZmlsdGVycy5wdXNoKGZpbHRlckZuKTtcbn07XG5cbi8qKlxuICogRGlzdHJpYnV0ZXMgdGhlIGVsZW1lbnRzIHdpdGggYSBnaXZlbiBvcmllbnRhdGlvblxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBlbGVtZW50cyAgICBbZGVzY3JpcHRpb25dXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9yaWVudGF0aW9uIFtkZXNjcmlwdGlvbl1cbiAqL1xuRGlzdHJpYnV0ZUVsZW1lbnRzLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oZWxlbWVudHMsIG9yaWVudGF0aW9uKSB7XG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nO1xuXG4gIHZhciBncm91cHMsXG4gICAgICBkaXN0cmlidXRhYmxlRWxlbWVudHM7XG5cbiAgaWYgKGVsZW1lbnRzLmxlbmd0aCA8IDMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9zZXRPcmllbnRhdGlvbihvcmllbnRhdGlvbik7XG5cbiAgZGlzdHJpYnV0YWJsZUVsZW1lbnRzID0gdGhpcy5fZmlsdGVyRWxlbWVudHMoZWxlbWVudHMpO1xuXG4gIGdyb3VwcyA9IHRoaXMuX2NyZWF0ZUdyb3VwcyhkaXN0cmlidXRhYmxlRWxlbWVudHMpO1xuXG4gIC8vIG5vdGhpbmcgdG8gZGlzdHJpYnV0ZVxuICBpZiAoZ3JvdXBzLmxlbmd0aCA8PSAyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbW9kZWxpbmcuZGlzdHJpYnV0ZUVsZW1lbnRzKGdyb3VwcywgdGhpcy5fYXhpcywgdGhpcy5fZGltZW5zaW9uKTtcblxuICByZXR1cm4gZ3JvdXBzO1xufTtcblxuLyoqXG4gKiBGaWx0ZXJzIHRoZSBlbGVtZW50cyB3aXRoIHByb3ZpZGVkIGZpbHRlcnMgYnkgZXh0ZXJuYWwgcGFydGllc1xuICpcbiAqIEBwYXJhbSAge0FycmF5W0VsZW1lbnRzXX0gZWxlbWVudHNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheVtFbGVtZW50c119XG4gKi9cbkRpc3RyaWJ1dGVFbGVtZW50cy5wcm90b3R5cGUuX2ZpbHRlckVsZW1lbnRzID0gZnVuY3Rpb24oZWxlbWVudHMpIHtcbiAgdmFyIGZpbHRlcnMgPSB0aGlzLl9maWx0ZXJzLFxuICAgICAgYXhpcyA9IHRoaXMuX2F4aXMsXG4gICAgICBkaW1lbnNpb24gPSB0aGlzLl9kaW1lbnNpb24sXG4gICAgICBkaXN0cmlidXRhYmxlRWxlbWVudHMgPSBbXS5jb25jYXQoZWxlbWVudHMpO1xuXG4gIGlmICghZmlsdGVycy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZWxlbWVudHM7XG4gIH1cblxuICBmb3JFYWNoKGZpbHRlcnMsIGZ1bmN0aW9uKGZpbHRlckZuKSB7XG4gICAgZGlzdHJpYnV0YWJsZUVsZW1lbnRzID0gZmlsdGVyRm4oZGlzdHJpYnV0YWJsZUVsZW1lbnRzLCBheGlzLCBkaW1lbnNpb24pO1xuICB9KTtcblxuICByZXR1cm4gZGlzdHJpYnV0YWJsZUVsZW1lbnRzO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZSByYW5nZSAobWluLCBtYXgpIGdyb3Vwcy4gQWxzbyB0cmllcyB0byBncm91cCBlbGVtZW50c1xuICogdG9nZXRoZXIgdGhhdCBzaGFyZSB0aGUgc2FtZSByYW5nZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogXHR2YXIgZGlzdHJpYnV0YWJsZUVsZW1lbnRzID0gW1xuICogXHRcdHtcbiAqIFx0XHRcdHJhbmdlOiB7XG4gKiBcdFx0XHRcdG1pbjogMTAwLFxuICogXHRcdFx0XHRtYXg6IDIwMFxuICogXHRcdFx0fSxcbiAqIFx0XHRcdGVsZW1lbnRzOiBbIHsgaWQ6ICdzaGFwZTEnLCAuLiB9XVxuICogXHRcdH1cbiAqIFx0XVxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBlbGVtZW50c1xuICpcbiAqIEByZXR1cm4ge0FycmF5W09iamVjdHNdfVxuICovXG5EaXN0cmlidXRlRWxlbWVudHMucHJvdG90eXBlLl9jcmVhdGVHcm91cHMgPSBmdW5jdGlvbihlbGVtZW50cykge1xuICB2YXIgcmFuZ2VHcm91cHMgPSBbXSxcbiAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgYXhpcyA9IHRoaXMuX2F4aXMsXG4gICAgICBkaW1lbnNpb24gPSB0aGlzLl9kaW1lbnNpb247XG5cbiAgaWYgKCFheGlzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtdXN0IGhhdmUgYSBkZWZpbmVkIFwiYXhpc1wiIGFuZCBcImRpbWVuc2lvblwiJyk7XG4gIH1cblxuICAvLyBzb3J0IGJ5ICdsZWZ0LT5yaWdodCcgb3IgJ3RvcC0+Ym90dG9tJ1xuICB2YXIgc29ydGVkRWxlbWVudHMgPSBzb3J0QnkoZWxlbWVudHMsIGF4aXMpO1xuXG4gIGZvckVhY2goc29ydGVkRWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQsIGlkeCkge1xuICAgIHZhciBlbGVtZW50UmFuZ2UgPSBzZWxmLl9maW5kUmFuZ2UoZWxlbWVudCwgYXhpcywgZGltZW5zaW9uKSxcbiAgICAgICAgcmFuZ2U7XG5cbiAgICB2YXIgcHJldmlvdXMgPSByYW5nZUdyb3Vwc1tyYW5nZUdyb3Vwcy5sZW5ndGggLSAxXTtcblxuICAgIGlmIChwcmV2aW91cyAmJiBzZWxmLl9oYXNJbnRlcnNlY3Rpb24ocHJldmlvdXMucmFuZ2UsIGVsZW1lbnRSYW5nZSkpIHtcbiAgICAgIHJhbmdlR3JvdXBzW3JhbmdlR3JvdXBzLmxlbmd0aCAtIDFdLmVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJhbmdlID0geyByYW5nZTogZWxlbWVudFJhbmdlLCBlbGVtZW50czogWyBlbGVtZW50IF0gfTtcblxuICAgICAgcmFuZ2VHcm91cHMucHVzaChyYW5nZSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmFuZ2VHcm91cHM7XG59O1xuXG5cbi8qKlxuICogTWFwcyBhIGRpcmVjdGlvbiB0byB0aGUgYWNjb3JkaW5nIGF4aXMgYW5kIGRpbWVuc2lvblxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gZGlyZWN0aW9uICdob3Jpem9udGFsJyBvciAndmVydGljYWwnXG4gKi9cbkRpc3RyaWJ1dGVFbGVtZW50cy5wcm90b3R5cGUuX3NldE9yaWVudGF0aW9uID0gZnVuY3Rpb24oZGlyZWN0aW9uKSB7XG4gIHZhciBvcmllbnRhdGlvbiA9IEFYSVNfRElNRU5TSU9OU1tkaXJlY3Rpb25dO1xuXG4gIHRoaXMuX2F4aXMgPSBvcmllbnRhdGlvblswXTtcbiAgdGhpcy5fZGltZW5zaW9uID0gb3JpZW50YXRpb25bMV07XG59O1xuXG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSB0d28gcmFuZ2VzIGludGVyY2VwdCBlYWNoIG90aGVyXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSByYW5nZUEge21pbiwgbWF4fVxuICogQHBhcmFtICB7T2JqZWN0fSByYW5nZUIge21pbiwgbWF4fVxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbkRpc3RyaWJ1dGVFbGVtZW50cy5wcm90b3R5cGUuX2hhc0ludGVyc2VjdGlvbiA9IGZ1bmN0aW9uKHJhbmdlQSwgcmFuZ2VCKSB7XG4gIHJldHVybiBNYXRoLm1heChyYW5nZUEubWluLCByYW5nZUEubWF4KSA+PSBNYXRoLm1pbihyYW5nZUIubWluLCByYW5nZUIubWF4KSAmJlxuICAgICAgICAgTWF0aC5taW4ocmFuZ2VBLm1pbiwgcmFuZ2VBLm1heCkgPD0gTWF0aC5tYXgocmFuZ2VCLm1pbiwgcmFuZ2VCLm1heCk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWluIGFuZCBtYXggdmFsdWVzIGZvciBhbiBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7W3R5cGVdfSBlbGVtZW50ICAgW2Rlc2NyaXB0aW9uXVxuICogQHBhcmFtICB7W3R5cGVdfSBheGlzICAgICAgW2Rlc2NyaXB0aW9uXVxuICogQHBhcmFtICB7W3R5cGVdfSBkaW1lbnNpb24gW2Rlc2NyaXB0aW9uXVxuICpcbiAqIEByZXR1cm4ge1t0eXBlXX0gICAgICAgICAgIFtkZXNjcmlwdGlvbl1cbiAqL1xuRGlzdHJpYnV0ZUVsZW1lbnRzLnByb3RvdHlwZS5fZmluZFJhbmdlID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICB2YXIgYXhpcyA9IGVsZW1lbnRbdGhpcy5fYXhpc10sXG4gICAgICBkaW1lbnNpb24gPSBlbGVtZW50W3RoaXMuX2RpbWVuc2lvbl07XG5cbiAgcmV0dXJuIHtcbiAgICBtaW46IGF4aXMgKyBUSFJFU0hPTEQsXG4gICAgbWF4OiBheGlzICsgZGltZW5zaW9uIC0gVEhSRVNIT0xEXG4gIH07XG59O1xuIiwiaW1wb3J0IERpc3RyaWJ1dGVFbGVtZW50cyBmcm9tICcuL0Rpc3RyaWJ1dGVFbGVtZW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2Rpc3RyaWJ1dGVFbGVtZW50cycgXSxcbiAgZGlzdHJpYnV0ZUVsZW1lbnRzOiBbICd0eXBlJywgRGlzdHJpYnV0ZUVsZW1lbnRzIF1cbn07XG4iLCIvKiBnbG9iYWwgVG91Y2hFdmVudCAqL1xuXG52YXIgcm91bmQgPSBNYXRoLnJvdW5kO1xuXG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50XG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICBnZXRPcmlnaW5hbCxcbiAgdG9Qb2ludCxcbiAgc3RvcFByb3BhZ2F0aW9uXG59IGZyb20gJy4uLy4uL3V0aWwvRXZlbnQnO1xuXG5pbXBvcnQge1xuICBzZXQgYXMgY3Vyc29yU2V0LFxuICB1bnNldCBhcyBjdXJzb3JVbnNldFxufSBmcm9tICcuLi8uLi91dGlsL0N1cnNvcic7XG5cbmltcG9ydCB7XG4gIGluc3RhbGwgYXMgaW5zdGFsbENsaWNrVHJhcFxufSBmcm9tICcuLi8uLi91dGlsL0NsaWNrVHJhcCc7XG5cbmltcG9ydCB7XG4gIGRlbHRhIGFzIGRlbHRhUG9zXG59IGZyb20gJy4uLy4uL3V0aWwvUG9zaXRpb25VdGlsJztcblxudmFyIERSQUdfQUNUSVZFX0NMUyA9ICdkanMtZHJhZy1hY3RpdmUnO1xuXG5cbmZ1bmN0aW9uIHByZXZlbnREZWZhdWx0KGV2ZW50KSB7XG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG59XG5cbmZ1bmN0aW9uIGlzVG91Y2hFdmVudChldmVudCkge1xuXG4gIC8vIGNoZWNrIGZvciBUb3VjaEV2ZW50IGJlaW5nIGF2YWlsYWJsZSBmaXJzdFxuICAvLyAoaS5lLiBub3QgYXZhaWxhYmxlIG9uIGRlc2t0b3AgRmlyZWZveClcbiAgcmV0dXJuIHR5cGVvZiBUb3VjaEV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBldmVudCBpbnN0YW5jZW9mIFRvdWNoRXZlbnQ7XG59XG5cbmZ1bmN0aW9uIGdldExlbmd0aChwb2ludCkge1xuICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHBvaW50LngsIDIpICsgTWF0aC5wb3cocG9pbnQueSwgMikpO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIHRoYXQgZmlyZXMgY2FudmFzIGxvY2FsaXplZCBkcmFnIGV2ZW50cyBhbmQgcmVhbGl6ZXNcbiAqIHRoZSBnZW5lcmFsIFwiZHJhZy1hbmQtZHJvcFwiIGxvb2sgYW5kIGZlZWwuXG4gKlxuICogQ2FsbGluZyB7QGxpbmsgRHJhZ2dpbmcjYWN0aXZhdGV9IGFjdGl2YXRlcyBkcmFnZ2luZyBvbiBhIGNhbnZhcy5cbiAqXG4gKiBJdCBwcm92aWRlcyB0aGUgZm9sbG93aW5nOlxuICpcbiAqICAgKiBlbWl0cyBsaWZlIGN5Y2xlIGV2ZW50cywgbmFtZXNwYWNlZCB3aXRoIGEgcHJlZml4IGFzc2lnbmVkXG4gKiAgICAgZHVyaW5nIGRyYWdnaW5nIGFjdGl2YXRpb25cbiAqICAgKiBzZXRzIGFuZCByZXN0b3JlcyB0aGUgY3Vyc29yXG4gKiAgICogc2V0cyBhbmQgcmVzdG9yZXMgdGhlIHNlbGVjdGlvbiBpZiBlbGVtZW50cyBzdGlsbCBleGlzdFxuICogICAqIGVuc3VyZXMgdGhlcmUgY2FuIGJlIG9ubHkgb25lIGRyYWcgb3BlcmF0aW9uIGFjdGl2ZSBhdCBhIHRpbWVcbiAqXG4gKiBEcmFnZ2luZyBtYXkgYmUgY2FuY2VsZWQgbWFudWFsbHkgYnkgY2FsbGluZyB7QGxpbmsgRHJhZ2dpbmcjY2FuY2VsfVxuICogb3IgYnkgcHJlc3NpbmcgRVNDLlxuICpcbiAqXG4gKiAjIyBMaWZlLWN5Y2xlIGV2ZW50c1xuICpcbiAqIERyYWdnaW5nIGNhbiBiZSBpbiB0aHJlZSBkaWZmZXJlbnQgc3RhdGVzLCBvZmYsIGluaXRpYWxpemVkXG4gKiBhbmQgYWN0aXZlLlxuICpcbiAqICgxKSBvZmY6IG5vIGRyYWdnaW5nIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzc1xuICogKDIpIGluaXRpYWxpemVkOiBhIG5ldyBkcmFnIG9wZXJhdGlvbiBnb3QgaW5pdGlhbGl6ZWQgYnV0IG5vdCB5ZXRcbiAqICAgICAgICAgICAgICAgICAgc3RhcnRlZCAoaS5lLiBiZWNhdXNlIG9mIG5vIGluaXRpYWwgbW92ZSlcbiAqICgzKSBzdGFydGVkOiBkcmFnZ2luZyBpcyBpbiBwcm9ncmVzc1xuICpcbiAqIEV2ZW50dWFsbHkgZHJhZ2dpbmcgd2lsbCBiZSBvZmYgYWdhaW4gYWZ0ZXIgYSBkcmFnIG9wZXJhdGlvbiBoYXNcbiAqIGJlZW4gZW5kZWQgb3IgY2FuY2VsZWQgdmlhIHVzZXIgY2xpY2sgb3IgRVNDIGtleSBwcmVzcy5cbiAqXG4gKiBUbyBpbmRpY2F0ZSB0cmFuc2l0aW9ucyBiZXR3ZWVuIHRoZXNlIHN0YXRlcyBkcmFnZ2luZyBlbWl0cyBnZW5lcmljXG4gKiBsaWZlLWN5Y2xlIGV2ZW50cyB3aXRoIHRoZSBgZHJhZy5gIHByZWZpeCBfYW5kXyBldmVudHMgbmFtZXNwYWNlZFxuICogdG8gYSBwcmVmaXggY2hvb3NlbiBieSBhIHVzZXIgZHVyaW5nIGRyYWcgaW5pdGlhbGl6YXRpb24uXG4gKlxuICogVGhlIGZvbGxvd2luZyBldmVudHMgYXJlIGVtaXR0ZWQgKGFwcHJvcHJpYXRlbHkgcHJlZml4ZWQpIHZpYVxuICogdGhlIHtAbGluayBFdmVudEJ1c30uXG4gKlxuICogKiBgaW5pdGBcbiAqICogYHN0YXJ0YFxuICogKiBgbW92ZWBcbiAqICogYGVuZGBcbiAqICogYGVuZGVkYCAoZHJhZ2dpbmcgYWxyZWFkeSBpbiBvZmYgc3RhdGUpXG4gKiAqIGBjYW5jZWxgIChvbmx5IGlmIHByZXZpb3VzbHkgc3RhcnRlZClcbiAqICogYGNhbmNlbGVkYCAoZHJhZ2dpbmcgYWxyZWFkeSBpbiBvZmYgc3RhdGUsIG9ubHkgaWYgcHJldmlvdXNseSBzdGFydGVkKVxuICogKiBgY2xlYW51cGBcbiAqXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBNeURyYWdDb21wb25lbnQoZXZlbnRCdXMsIGRyYWdnaW5nKSB7XG4gKlxuICogICBldmVudEJ1cy5vbignbXlkcmFnLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgICBjb25zb2xlLmxvZygneWVzLCB3ZSBzdGFydCBkcmFnZ2luZycpO1xuICogICB9KTtcbiAqXG4gKiAgIGV2ZW50QnVzLm9uKCdteWRyYWcubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gKiAgICAgY29uc29sZS5sb2coJ2NhbnZhcyBsb2NhbCBjb29yZGluYXRlcycsIGV2ZW50LngsIGV2ZW50LnksIGV2ZW50LmR4LCBldmVudC5keSk7XG4gKlxuICogICAgIC8vIGxvY2FsIGRyYWcgZGF0YSBpcyBwYXNzZWQgd2l0aCB0aGUgZXZlbnRcbiAqICAgICBldmVudC5jb250ZXh0LmZvbzsgLy8gXCJCQVJcIlxuICpcbiAqICAgICAvLyB0aGUgb3JpZ2luYWwgbW91c2UgZXZlbnQsIHRvb1xuICogICAgIGV2ZW50Lm9yaWdpbmFsRXZlbnQ7IC8vIE1vdXNlRXZlbnQoLi4uKVxuICogICB9KTtcbiAqXG4gKiAgIGV2ZW50QnVzLm9uKCdlbGVtZW50LmNsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgICBkcmFnZ2luZy5pbml0KGV2ZW50LCAnbXlkcmFnJywge1xuICogICAgICAgY3Vyc29yOiAnZ3JhYmJpbmcnLFxuICogICAgICAgZGF0YToge1xuICogICAgICAgICBjb250ZXh0OiB7XG4gKiAgICAgICAgICAgZm9vOiBcIkJBUlwiXG4gKiAgICAgICAgIH1cbiAqICAgICAgIH1cbiAqICAgICB9KTtcbiAqICAgfSk7XG4gKiB9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERyYWdnaW5nKGV2ZW50QnVzLCBjYW52YXMsIHNlbGVjdGlvbiwgZWxlbWVudFJlZ2lzdHJ5KSB7XG5cbiAgdmFyIGRlZmF1bHRPcHRpb25zID0ge1xuICAgIHRocmVzaG9sZDogNSxcbiAgICB0cmFwQ2xpY2s6IHRydWVcbiAgfTtcblxuICAvLyB0aGUgY3VycmVudGx5IGFjdGl2ZSBkcmFnIG9wZXJhdGlvblxuICAvLyBkcmFnZ2luZyBpcyBhY3RpdmUgYXMgc29vbiBhcyB0aGlzIGNvbnRleHQgZXhpc3RzLlxuICAvL1xuICAvLyBpdCBpcyB2aXN1YWxseSBfYWN0aXZlXyBvbmx5IHdoZW4gYSBjb250ZXh0LmFjdGl2ZSBmbGFnIGlzIHNldCB0byB0cnVlLlxuICB2YXIgY29udGV4dDtcblxuICAvKiBjb252ZXJ0IGEgZ2xvYmFsIGV2ZW50IGludG8gbG9jYWwgY29vcmRpbmF0ZXMgKi9cbiAgZnVuY3Rpb24gdG9Mb2NhbFBvaW50KGdsb2JhbFBvc2l0aW9uKSB7XG5cbiAgICB2YXIgdmlld2JveCA9IGNhbnZhcy52aWV3Ym94KCk7XG5cbiAgICB2YXIgY2xpZW50UmVjdCA9IGNhbnZhcy5fY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHZpZXdib3gueCArIChnbG9iYWxQb3NpdGlvbi54IC0gY2xpZW50UmVjdC5sZWZ0KSAvIHZpZXdib3guc2NhbGUsXG4gICAgICB5OiB2aWV3Ym94LnkgKyAoZ2xvYmFsUG9zaXRpb24ueSAtIGNsaWVudFJlY3QudG9wKSAvIHZpZXdib3guc2NhbGVcbiAgICB9O1xuICB9XG5cbiAgLy8gaGVscGVyc1xuXG4gIGZ1bmN0aW9uIGZpcmUodHlwZSwgZHJhZ0NvbnRleHQpIHtcbiAgICBkcmFnQ29udGV4dCA9IGRyYWdDb250ZXh0IHx8IGNvbnRleHQ7XG5cbiAgICB2YXIgZXZlbnQgPSBldmVudEJ1cy5jcmVhdGVFdmVudChcbiAgICAgIGFzc2lnbihcbiAgICAgICAge30sXG4gICAgICAgIGRyYWdDb250ZXh0LnBheWxvYWQsXG4gICAgICAgIGRyYWdDb250ZXh0LmRhdGEsXG4gICAgICAgIHsgaXNUb3VjaDogZHJhZ0NvbnRleHQuaXNUb3VjaCB9XG4gICAgICApXG4gICAgKTtcblxuICAgIC8vIGRlZmF1bHQgaW50ZWdyYXRpb25cbiAgICBpZiAoZXZlbnRCdXMuZmlyZSgnZHJhZy4nICsgdHlwZSwgZXZlbnQpID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiBldmVudEJ1cy5maXJlKGRyYWdDb250ZXh0LnByZWZpeCArICcuJyArIHR5cGUsIGV2ZW50KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc3RvcmVTZWxlY3Rpb24ocHJldmlvdXNTZWxlY3Rpb24pIHtcbiAgICB2YXIgZXhpc3RpbmdTZWxlY3Rpb24gPSBwcmV2aW91c1NlbGVjdGlvbi5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnRSZWdpc3RyeS5nZXQoZWxlbWVudC5pZCk7XG4gICAgfSk7XG5cbiAgICBleGlzdGluZ1NlbGVjdGlvbi5sZW5ndGggJiYgc2VsZWN0aW9uLnNlbGVjdChleGlzdGluZ1NlbGVjdGlvbik7XG4gIH1cblxuICAvLyBldmVudCBsaXN0ZW5lcnNcblxuICBmdW5jdGlvbiBtb3ZlKGV2ZW50LCBhY3RpdmF0ZSkge1xuICAgIHZhciBwYXlsb2FkID0gY29udGV4dC5wYXlsb2FkLFxuICAgICAgICBkaXNwbGFjZW1lbnQgPSBjb250ZXh0LmRpc3BsYWNlbWVudDtcblxuICAgIHZhciBnbG9iYWxTdGFydCA9IGNvbnRleHQuZ2xvYmFsU3RhcnQsXG4gICAgICAgIGdsb2JhbEN1cnJlbnQgPSB0b1BvaW50KGV2ZW50KSxcbiAgICAgICAgZ2xvYmFsRGVsdGEgPSBkZWx0YVBvcyhnbG9iYWxDdXJyZW50LCBnbG9iYWxTdGFydCk7XG5cbiAgICB2YXIgbG9jYWxTdGFydCA9IGNvbnRleHQubG9jYWxTdGFydCxcbiAgICAgICAgbG9jYWxDdXJyZW50ID0gdG9Mb2NhbFBvaW50KGdsb2JhbEN1cnJlbnQpLFxuICAgICAgICBsb2NhbERlbHRhID0gZGVsdGFQb3MobG9jYWxDdXJyZW50LCBsb2NhbFN0YXJ0KTtcblxuXG4gICAgLy8gYWN0aXZhdGUgY29udGV4dCBleHBsaWNpdGx5IG9yIG9uY2UgdGhyZXNob2xkIGlzIHJlYWNoZWRcbiAgICBpZiAoIWNvbnRleHQuYWN0aXZlICYmIChhY3RpdmF0ZSB8fCBnZXRMZW5ndGgoZ2xvYmFsRGVsdGEpID4gY29udGV4dC50aHJlc2hvbGQpKSB7XG5cbiAgICAgIC8vIGZpcmUgc3RhcnQgZXZlbnQgd2l0aCBvcmlnaW5hbFxuICAgICAgLy8gc3RhcnRpbmcgY29vcmRpbmF0ZXNcblxuICAgICAgYXNzaWduKHBheWxvYWQsIHtcbiAgICAgICAgeDogcm91bmQobG9jYWxTdGFydC54ICsgZGlzcGxhY2VtZW50LngpLFxuICAgICAgICB5OiByb3VuZChsb2NhbFN0YXJ0LnkgKyBkaXNwbGFjZW1lbnQueSksXG4gICAgICAgIGR4OiAwLFxuICAgICAgICBkeTogMFxuICAgICAgfSwgeyBvcmlnaW5hbEV2ZW50OiBldmVudCB9KTtcblxuICAgICAgaWYgKGZhbHNlID09PSBmaXJlKCdzdGFydCcpKSB7XG4gICAgICAgIHJldHVybiBjYW5jZWwoKTtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5hY3RpdmUgPSB0cnVlO1xuXG4gICAgICAvLyB1bnNldCBzZWxlY3Rpb24gYW5kIHJlbWVtYmVyIG9sZCBzZWxlY3Rpb25cbiAgICAgIC8vIHRoZSBwcmV2aW91cyAob2xkKSBzZWxlY3Rpb24gd2lsbCBhbHdheXMgcGFzc2VkXG4gICAgICAvLyB3aXRoIHRoZSBldmVudCB2aWEgdGhlIGV2ZW50LnByZXZpb3VzU2VsZWN0aW9uIHByb3BlcnR5XG4gICAgICBpZiAoIWNvbnRleHQua2VlcFNlbGVjdGlvbikge1xuICAgICAgICBwYXlsb2FkLnByZXZpb3VzU2VsZWN0aW9uID0gc2VsZWN0aW9uLmdldCgpO1xuICAgICAgICBzZWxlY3Rpb24uc2VsZWN0KG51bGwpO1xuICAgICAgfVxuXG4gICAgICAvLyBhbGxvdyBjdXN0b20gY3Vyc29yXG4gICAgICBpZiAoY29udGV4dC5jdXJzb3IpIHtcbiAgICAgICAgY3Vyc29yU2V0KGNvbnRleHQuY3Vyc29yKTtcbiAgICAgIH1cblxuICAgICAgLy8gaW5kaWNhdGUgZHJhZ2dpbmcgdmlhIG1hcmtlciBvbiByb290IGVsZW1lbnRcbiAgICAgIGNhbnZhcy5hZGRNYXJrZXIoY2FudmFzLmdldFJvb3RFbGVtZW50KCksIERSQUdfQUNUSVZFX0NMUyk7XG4gICAgfVxuXG4gICAgc3RvcFByb3BhZ2F0aW9uKGV2ZW50KTtcblxuICAgIGlmIChjb250ZXh0LmFjdGl2ZSkge1xuXG4gICAgICAvLyB1cGRhdGUgcGF5bG9hZCB3aXRoIGFjdHVhbCBjb29yZGluYXRlc1xuICAgICAgYXNzaWduKHBheWxvYWQsIHtcbiAgICAgICAgeDogcm91bmQobG9jYWxDdXJyZW50LnggKyBkaXNwbGFjZW1lbnQueCksXG4gICAgICAgIHk6IHJvdW5kKGxvY2FsQ3VycmVudC55ICsgZGlzcGxhY2VtZW50LnkpLFxuICAgICAgICBkeDogcm91bmQobG9jYWxEZWx0YS54KSxcbiAgICAgICAgZHk6IHJvdW5kKGxvY2FsRGVsdGEueSlcbiAgICAgIH0sIHsgb3JpZ2luYWxFdmVudDogZXZlbnQgfSk7XG5cbiAgICAgIC8vIGVtaXQgbW92ZSBldmVudFxuICAgICAgZmlyZSgnbW92ZScpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGVuZChldmVudCkge1xuICAgIHZhciBwcmV2aW91c0NvbnRleHQsXG4gICAgICAgIHJldHVyblZhbHVlID0gdHJ1ZTtcblxuICAgIGlmIChjb250ZXh0LmFjdGl2ZSkge1xuXG4gICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgY29udGV4dC5wYXlsb2FkLm9yaWdpbmFsRXZlbnQgPSBldmVudDtcblxuICAgICAgICAvLyBzdXBwcmVzcyBvcmlnaW5hbCBldmVudCAoY2xpY2ssIC4uLilcbiAgICAgICAgLy8gYmVjYXVzZSB3ZSBqdXN0IGVuZGVkIGEgZHJhZyBvcGVyYXRpb25cbiAgICAgICAgc3RvcFByb3BhZ2F0aW9uKGV2ZW50KTtcbiAgICAgIH1cblxuICAgICAgLy8gaW1wbGVtZW50YXRpb25zIG1heSBzdG9wIHJlc3RvcmluZyB0aGVcbiAgICAgIC8vIG9yaWdpbmFsIHN0YXRlIChzZWxlY3Rpb25zLCAuLi4pIGJ5IHByZXZlbnRpbmcgdGhlXG4gICAgICAvLyBlbmQgZXZlbnRzIGRlZmF1bHQgYWN0aW9uXG4gICAgICByZXR1cm5WYWx1ZSA9IGZpcmUoJ2VuZCcpO1xuICAgIH1cblxuICAgIGlmIChyZXR1cm5WYWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgIGZpcmUoJ3JlamVjdGVkJyk7XG4gICAgfVxuXG4gICAgcHJldmlvdXNDb250ZXh0ID0gY2xlYW51cChyZXR1cm5WYWx1ZSAhPT0gdHJ1ZSk7XG5cbiAgICAvLyBsYXN0IGV2ZW50IHRvIGJlIGZpcmVkIHdoZW4gYWxsIGRyYWcgb3BlcmF0aW9ucyBhcmUgZG9uZVxuICAgIC8vIGF0IHRoaXMgcG9pbnQgaW4gdGltZSBubyBkcmFnIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcyBhbnltb3JlXG4gICAgZmlyZSgnZW5kZWQnLCBwcmV2aW91c0NvbnRleHQpO1xuICB9XG5cblxuICAvLyBjYW5jZWwgYWN0aXZlIGRyYWcgb3BlcmF0aW9uIGlmIHRoZSB1c2VyIHByZXNzZXNcbiAgLy8gdGhlIEVTQyBrZXkgb24gdGhlIGtleWJvYXJkXG5cbiAgZnVuY3Rpb24gY2hlY2tDYW5jZWwoZXZlbnQpIHtcblxuICAgIGlmIChldmVudC53aGljaCA9PT0gMjcpIHtcbiAgICAgIHByZXZlbnREZWZhdWx0KGV2ZW50KTtcblxuICAgICAgY2FuY2VsKCk7XG4gICAgfVxuICB9XG5cblxuICAvLyBwcmV2ZW50IGdob3N0IGNsaWNrIHRoYXQgbWlnaHQgb2NjdXIgYWZ0ZXIgYSBmaW5pc2hlZFxuICAvLyBkcmFnIGFuZCBkcm9wIHNlc3Npb25cblxuICBmdW5jdGlvbiB0cmFwQ2xpY2tBbmRFbmQoZXZlbnQpIHtcblxuICAgIHZhciB1bnRyYXA7XG5cbiAgICAvLyB0cmFwIHRoZSBjbGljayBpbiBjYXNlIHdlIGFyZSBwYXJ0IG9mIGFuIGFjdGl2ZVxuICAgIC8vIGRyYWcgb3BlcmF0aW9uLiBUaGlzIHdpbGwgZWZmZWN0aXZlbHkgcHJldmVudFxuICAgIC8vIHRoZSBnaG9zdCBjbGljayB0aGF0IGNhbm5vdCBiZSBjYW5jZWxlZCBvdGhlcndpc2UuXG4gICAgaWYgKGNvbnRleHQuYWN0aXZlKSB7XG5cbiAgICAgIHVudHJhcCA9IGluc3RhbGxDbGlja1RyYXAoZXZlbnRCdXMpO1xuXG4gICAgICAvLyByZW1vdmUgdHJhcCBhZnRlciBtaW5pbWFsIGRlbGF5XG4gICAgICBzZXRUaW1lb3V0KHVudHJhcCwgNDAwKTtcblxuICAgICAgLy8gcHJldmVudCBkZWZhdWx0IGFjdGlvbiAoY2xpY2spXG4gICAgICBwcmV2ZW50RGVmYXVsdChldmVudCk7XG4gICAgfVxuXG4gICAgZW5kKGV2ZW50KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYXBUb3VjaChldmVudCkge1xuICAgIG1vdmUoZXZlbnQpO1xuICB9XG5cbiAgLy8gdXBkYXRlIHRoZSBkcmFnIGV2ZW50cyBob3ZlciAoZGpzLm1vZGVsLkJhc2UpIGFuZCBob3ZlckdmeCAoU25hcDxTVkdFbGVtZW50PilcbiAgLy8gcHJvcGVydGllcyBkdXJpbmcgaG92ZXIgYW5kIG91dCBhbmQgZmlyZSB7cHJlZml4fS5ob3ZlciBhbmQge3ByZWZpeH0ub3V0IHByb3BlcnRpZXNcbiAgLy8gcmVzcGVjdGl2ZWx5XG5cbiAgZnVuY3Rpb24gaG92ZXIoZXZlbnQpIHtcbiAgICB2YXIgcGF5bG9hZCA9IGNvbnRleHQucGF5bG9hZDtcblxuICAgIHBheWxvYWQuaG92ZXJHZnggPSBldmVudC5nZng7XG4gICAgcGF5bG9hZC5ob3ZlciA9IGV2ZW50LmVsZW1lbnQ7XG5cbiAgICBmaXJlKCdob3ZlcicpO1xuICB9XG5cbiAgZnVuY3Rpb24gb3V0KGV2ZW50KSB7XG4gICAgZmlyZSgnb3V0Jyk7XG5cbiAgICB2YXIgcGF5bG9hZCA9IGNvbnRleHQucGF5bG9hZDtcblxuICAgIHBheWxvYWQuaG92ZXJHZnggPSBudWxsO1xuICAgIHBheWxvYWQuaG92ZXIgPSBudWxsO1xuICB9XG5cblxuICAvLyBsaWZlLWN5Y2xlIG1ldGhvZHNcblxuICBmdW5jdGlvbiBjYW5jZWwocmVzdG9yZSkge1xuICAgIHZhciBwcmV2aW91c0NvbnRleHQ7XG5cbiAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgd2FzQWN0aXZlID0gY29udGV4dC5hY3RpdmU7XG5cbiAgICBpZiAod2FzQWN0aXZlKSB7XG4gICAgICBmaXJlKCdjYW5jZWwnKTtcbiAgICB9XG5cbiAgICBwcmV2aW91c0NvbnRleHQgPSBjbGVhbnVwKHJlc3RvcmUpO1xuXG4gICAgaWYgKHdhc0FjdGl2ZSkge1xuXG4gICAgICAvLyBsYXN0IGV2ZW50IHRvIGJlIGZpcmVkIHdoZW4gYWxsIGRyYWcgb3BlcmF0aW9ucyBhcmUgZG9uZVxuICAgICAgLy8gYXQgdGhpcyBwb2ludCBpbiB0aW1lIG5vIGRyYWcgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzIGFueW1vcmVcbiAgICAgIGZpcmUoJ2NhbmNlbGVkJywgcHJldmlvdXNDb250ZXh0KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjbGVhbnVwKHJlc3RvcmUpIHtcbiAgICB2YXIgcHJldmlvdXNDb250ZXh0LFxuICAgICAgICBlbmREcmFnO1xuXG4gICAgZmlyZSgnY2xlYW51cCcpO1xuXG4gICAgLy8gcmVzZXQgY3Vyc29yXG4gICAgY3Vyc29yVW5zZXQoKTtcblxuICAgIGlmIChjb250ZXh0LnRyYXBDbGljaykge1xuICAgICAgZW5kRHJhZyA9IHRyYXBDbGlja0FuZEVuZDtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5kRHJhZyA9IGVuZDtcbiAgICB9XG5cbiAgICAvLyByZXNldCBkb20gbGlzdGVuZXJzXG4gICAgZG9tRXZlbnQudW5iaW5kKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgbW92ZSk7XG5cbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdkcmFnc3RhcnQnLCBwcmV2ZW50RGVmYXVsdCk7XG4gICAgZG9tRXZlbnQudW5iaW5kKGRvY3VtZW50LCAnc2VsZWN0c3RhcnQnLCBwcmV2ZW50RGVmYXVsdCk7XG5cbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdtb3VzZWRvd24nLCBlbmREcmFnLCB0cnVlKTtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdtb3VzZXVwJywgZW5kRHJhZywgdHJ1ZSk7XG5cbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdrZXl1cCcsIGNoZWNrQ2FuY2VsKTtcblxuICAgIGRvbUV2ZW50LnVuYmluZChkb2N1bWVudCwgJ3RvdWNoc3RhcnQnLCB0cmFwVG91Y2gsIHRydWUpO1xuICAgIGRvbUV2ZW50LnVuYmluZChkb2N1bWVudCwgJ3RvdWNoY2FuY2VsJywgY2FuY2VsLCB0cnVlKTtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICd0b3VjaG1vdmUnLCBtb3ZlLCB0cnVlKTtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICd0b3VjaGVuZCcsIGVuZCwgdHJ1ZSk7XG5cbiAgICBldmVudEJ1cy5vZmYoJ2VsZW1lbnQuaG92ZXInLCBob3Zlcik7XG4gICAgZXZlbnRCdXMub2ZmKCdlbGVtZW50Lm91dCcsIG91dCk7XG5cbiAgICAvLyByZW1vdmUgZHJhZyBtYXJrZXIgb24gcm9vdCBlbGVtZW50XG4gICAgY2FudmFzLnJlbW92ZU1hcmtlcihjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSwgRFJBR19BQ1RJVkVfQ0xTKTtcblxuICAgIC8vIHJlc3RvcmUgc2VsZWN0aW9uLCB1bmxlc3MgaXQgaGFzIGNoYW5nZWRcbiAgICB2YXIgcHJldmlvdXNTZWxlY3Rpb24gPSBjb250ZXh0LnBheWxvYWQucHJldmlvdXNTZWxlY3Rpb247XG5cbiAgICBpZiAocmVzdG9yZSAhPT0gZmFsc2UgJiYgcHJldmlvdXNTZWxlY3Rpb24gJiYgIXNlbGVjdGlvbi5nZXQoKS5sZW5ndGgpIHtcbiAgICAgIHJlc3RvcmVTZWxlY3Rpb24ocHJldmlvdXNTZWxlY3Rpb24pO1xuICAgIH1cblxuICAgIHByZXZpb3VzQ29udGV4dCA9IGNvbnRleHQ7XG5cbiAgICBjb250ZXh0ID0gbnVsbDtcblxuICAgIHJldHVybiBwcmV2aW91c0NvbnRleHQ7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhIGRyYWcgb3BlcmF0aW9uLlxuICAgKlxuICAgKiBJZiBgbG9jYWxQb3NpdGlvbmAgaXMgZ2l2ZW4sIGRyYWcgZXZlbnRzIHdpbGwgYmUgZW1pdHRlZFxuICAgKiByZWxhdGl2ZSB0byBpdC5cbiAgICpcbiAgICogQHBhcmFtIHtNb3VzZUV2ZW50fFRvdWNoRXZlbnR9IFtldmVudF1cbiAgICogQHBhcmFtIHtQb2ludH0gW2xvY2FsUG9zaXRpb25dIGFjdHVhbCBkaWFncmFtIGxvY2FsIHBvc2l0aW9uIHRoaXMgZHJhZyBvcGVyYXRpb24gc2hvdWxkIHN0YXJ0IGF0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcmVmaXhcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKi9cbiAgZnVuY3Rpb24gaW5pdChldmVudCwgcmVsYXRpdmVUbywgcHJlZml4LCBvcHRpb25zKSB7XG5cbiAgICAvLyBvbmx5IG9uZSBkcmFnIG9wZXJhdGlvbiBtYXkgYmUgYWN0aXZlLCBhdCBhIHRpbWVcbiAgICBpZiAoY29udGV4dCkge1xuICAgICAgY2FuY2VsKGZhbHNlKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJlbGF0aXZlVG8gPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zID0gcHJlZml4O1xuICAgICAgcHJlZml4ID0gcmVsYXRpdmVUbztcbiAgICAgIHJlbGF0aXZlVG8gPSBudWxsO1xuICAgIH1cblxuICAgIG9wdGlvbnMgPSBhc3NpZ24oe30sIGRlZmF1bHRPcHRpb25zLCBvcHRpb25zIHx8IHt9KTtcblxuICAgIHZhciBkYXRhID0gb3B0aW9ucy5kYXRhIHx8IHt9LFxuICAgICAgICBvcmlnaW5hbEV2ZW50LFxuICAgICAgICBnbG9iYWxTdGFydCxcbiAgICAgICAgbG9jYWxTdGFydCxcbiAgICAgICAgZW5kRHJhZyxcbiAgICAgICAgaXNUb3VjaDtcblxuICAgIGlmIChvcHRpb25zLnRyYXBDbGljaykge1xuICAgICAgZW5kRHJhZyA9IHRyYXBDbGlja0FuZEVuZDtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5kRHJhZyA9IGVuZDtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIG9yaWdpbmFsRXZlbnQgPSBnZXRPcmlnaW5hbChldmVudCkgfHwgZXZlbnQ7XG4gICAgICBnbG9iYWxTdGFydCA9IHRvUG9pbnQoZXZlbnQpO1xuXG4gICAgICBzdG9wUHJvcGFnYXRpb24oZXZlbnQpO1xuXG4gICAgICAvLyBwcmV2ZW50IGRlZmF1bHQgYnJvd3NlciBkcmFnZ2luZyBiZWhhdmlvclxuICAgICAgaWYgKG9yaWdpbmFsRXZlbnQudHlwZSA9PT0gJ2RyYWdzdGFydCcpIHtcbiAgICAgICAgcHJldmVudERlZmF1bHQob3JpZ2luYWxFdmVudCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG9yaWdpbmFsRXZlbnQgPSBudWxsO1xuICAgICAgZ2xvYmFsU3RhcnQgPSB7IHg6IDAsIHk6IDAgfTtcbiAgICB9XG5cbiAgICBsb2NhbFN0YXJ0ID0gdG9Mb2NhbFBvaW50KGdsb2JhbFN0YXJ0KTtcblxuICAgIGlmICghcmVsYXRpdmVUbykge1xuICAgICAgcmVsYXRpdmVUbyA9IGxvY2FsU3RhcnQ7XG4gICAgfVxuXG4gICAgaXNUb3VjaCA9IGlzVG91Y2hFdmVudChvcmlnaW5hbEV2ZW50KTtcblxuICAgIGNvbnRleHQgPSBhc3NpZ24oe1xuICAgICAgcHJlZml4OiBwcmVmaXgsXG4gICAgICBkYXRhOiBkYXRhLFxuICAgICAgcGF5bG9hZDoge30sXG4gICAgICBnbG9iYWxTdGFydDogZ2xvYmFsU3RhcnQsXG4gICAgICBkaXNwbGFjZW1lbnQ6IGRlbHRhUG9zKHJlbGF0aXZlVG8sIGxvY2FsU3RhcnQpLFxuICAgICAgbG9jYWxTdGFydDogbG9jYWxTdGFydCxcbiAgICAgIGlzVG91Y2g6IGlzVG91Y2hcbiAgICB9LCBvcHRpb25zKTtcblxuICAgIC8vIHNraXAgZG9tIHJlZ2lzdHJhdGlvbiBpZiB0cmlnZ2VyXG4gICAgLy8gaXMgc2V0IHRvIG1hbnVhbCAoZHVyaW5nIHRlc3RpbmcpXG4gICAgaWYgKCFvcHRpb25zLm1hbnVhbCkge1xuXG4gICAgICAvLyBhZGQgZG9tIGxpc3RlbmVyc1xuXG4gICAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgICBkb21FdmVudC5iaW5kKGRvY3VtZW50LCAndG91Y2hzdGFydCcsIHRyYXBUb3VjaCwgdHJ1ZSk7XG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICd0b3VjaGNhbmNlbCcsIGNhbmNlbCwgdHJ1ZSk7XG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICd0b3VjaG1vdmUnLCBtb3ZlLCB0cnVlKTtcbiAgICAgICAgZG9tRXZlbnQuYmluZChkb2N1bWVudCwgJ3RvdWNoZW5kJywgZW5kLCB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gYXNzdW1lIHdlIHVzZSB0aGUgbW91c2UgdG8gaW50ZXJhY3QgcGVyIGRlZmF1bHRcbiAgICAgICAgZG9tRXZlbnQuYmluZChkb2N1bWVudCwgJ21vdXNlbW92ZScsIG1vdmUpO1xuXG4gICAgICAgIC8vIHByZXZlbnQgZGVmYXVsdCBicm93c2VyIGRyYWcgYW5kIHRleHQgc2VsZWN0aW9uIGJlaGF2aW9yXG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICdkcmFnc3RhcnQnLCBwcmV2ZW50RGVmYXVsdCk7XG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICdzZWxlY3RzdGFydCcsIHByZXZlbnREZWZhdWx0KTtcblxuICAgICAgICBkb21FdmVudC5iaW5kKGRvY3VtZW50LCAnbW91c2Vkb3duJywgZW5kRHJhZywgdHJ1ZSk7XG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICdtb3VzZXVwJywgZW5kRHJhZywgdHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICdrZXl1cCcsIGNoZWNrQ2FuY2VsKTtcblxuICAgICAgZXZlbnRCdXMub24oJ2VsZW1lbnQuaG92ZXInLCBob3Zlcik7XG4gICAgICBldmVudEJ1cy5vbignZWxlbWVudC5vdXQnLCBvdXQpO1xuICAgIH1cblxuICAgIGZpcmUoJ2luaXQnKTtcblxuICAgIGlmIChvcHRpb25zLmF1dG9BY3RpdmF0ZSkge1xuICAgICAgbW92ZShldmVudCwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gY2FuY2VsIG9uIGRpYWdyYW0gZGVzdHJ1Y3Rpb25cbiAgZXZlbnRCdXMub24oJ2RpYWdyYW0uZGVzdHJveScsIGNhbmNlbCk7XG5cblxuICAvLyBBUElcblxuICB0aGlzLmluaXQgPSBpbml0O1xuICB0aGlzLm1vdmUgPSBtb3ZlO1xuICB0aGlzLmhvdmVyID0gaG92ZXI7XG4gIHRoaXMub3V0ID0gb3V0O1xuICB0aGlzLmVuZCA9IGVuZDtcblxuICB0aGlzLmNhbmNlbCA9IGNhbmNlbDtcblxuICAvLyBmb3IgaW50cm9zcGVjdGlvblxuXG4gIHRoaXMuY29udGV4dCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBjb250ZXh0O1xuICB9O1xuXG4gIHRoaXMuc2V0T3B0aW9ucyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICBhc3NpZ24oZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpO1xuICB9O1xufVxuXG5EcmFnZ2luZy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3NlbGVjdGlvbicsXG4gICdlbGVtZW50UmVnaXN0cnknXG5dO1xuIiwiaW1wb3J0IHtcbiAgY2xvc2VzdCBhcyBkb21DbG9zZXN0XG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICB0b1BvaW50XG59IGZyb20gJy4uLy4uL3V0aWwvRXZlbnQnO1xuXG52YXIgSElHSF9QUklPUklUWSA9IDE1MDA7XG5cblxuLyoqXG4gKiBCcm93c2VycyBtYXkgc3dhbGxvdyBjZXJ0YWluIGV2ZW50cyAoaG92ZXIsIG91dCAuLi4pIGlmIHVzZXJzIGFyZSB0b1xuICogZmFzdCB3aXRoIHRoZSBtb3VzZS5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzQ0ODQ2OC93aHktY2FudC1pLXJlbGlhYmx5LWNhcHR1cmUtYS1tb3VzZW91dC1ldmVudFxuICpcbiAqIFRoZSBmaXggaW1wbGVtZW50ZWQgaW4gdGhpcyBjb21wb25lbnQgZW5zdXJlIHRoYXQgd2VcbiAqXG4gKiAxKSBoYXZlIGEgaG92ZXIgc3RhdGUgYWZ0ZXIgYSBzdWNjZXNzZnVsIGRyYWcubW92ZSBldmVudFxuICogMikgaGF2ZSBhbiBvdXQgZXZlbnQgd2hlbiBkcmFnZ2luZyBsZWF2ZXMgYW4gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0RyYWdnaW5nfSBkcmFnZ2luZ1xuICogQHBhcmFtIHtFbGVtZW50UmVnaXN0cnl9IGVsZW1lbnRSZWdpc3RyeVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBIb3ZlckZpeChldmVudEJ1cywgZHJhZ2dpbmcsIGVsZW1lbnRSZWdpc3RyeSkge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvKipcbiAgICogTWFrZSBzdXJlIHdlIGFyZSBnb2QgZGFtbiBob3ZlcmluZyFcbiAgICpcbiAgICogQHBhcmFtIHtFdmVudH0gZHJhZ2dpbmcgZXZlbnRcbiAgICovXG4gIGZ1bmN0aW9uIGVuc3VyZUhvdmVyKGV2ZW50KSB7XG5cbiAgICBpZiAoZXZlbnQuaG92ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgb3JpZ2luYWxFdmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG5cbiAgICB2YXIgZ2Z4ID0gc2VsZi5fZmluZFRhcmdldEdmeChvcmlnaW5hbEV2ZW50KTtcblxuICAgIHZhciBlbGVtZW50ID0gZ2Z4ICYmIGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcblxuICAgIGlmIChnZnggJiYgZWxlbWVudCkge1xuXG4gICAgICAvLyAxKSBjYW5jZWwgY3VycmVudCBtb3VzZW1vdmVcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAvLyAyKSBlbWl0IGZha2UgaG92ZXIgZm9yIG5ldyB0YXJnZXRcbiAgICAgIGRyYWdnaW5nLmhvdmVyKHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG5cbiAgICAgIC8vIDMpIHJlLXRyaWdnZXIgbW92ZSBldmVudFxuICAgICAgZHJhZ2dpbmcubW92ZShvcmlnaW5hbEV2ZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV2Ugd2FpdCBmb3IgYSBzcGVjaWZpYyBzZXF1ZW5jZSBvZiBldmVudHMgYmVmb3JlXG4gICAqIGVtaXR0aW5nIGEgZmFrZSBkcmFnLmhvdmVyIGV2ZW50LlxuICAgKlxuICAgKiBFdmVudCBTZXF1ZW5jZTpcbiAgICpcbiAgICogZHJhZy5zdGFydFxuICAgKiBkcmFnLm1vdmUgPj4gZW5zdXJlIHdlIGFyZSBob3ZlcmluZ1xuICAgKi9cbiAgZXZlbnRCdXMub24oJ2RyYWcuc3RhcnQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgZXZlbnRCdXMub25jZSgnZHJhZy5tb3ZlJywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgICAgZW5zdXJlSG92ZXIoZXZlbnQpO1xuXG4gICAgfSk7XG5cbiAgfSk7XG5cblxuICAvKipcbiAgICogV2UgbWFrZSBzdXJlIHRoYXQgZHJhZy5vdXQgaXMgYWx3YXlzIGZpcmVkLCBldmVuIGlmIHRoZVxuICAgKiBicm93c2VyIHN3YWxsb3dzIGFuIGVsZW1lbnQub3V0IGV2ZW50LlxuICAgKlxuICAgKiBFdmVudCBzZXF1ZW5jZTpcbiAgICpcbiAgICogZHJhZy5ob3ZlclxuICAgKiAoZWxlbWVudC5vdXQgPj4gc29tZXRpbWVzIHN3YWxsb3dlZClcbiAgICogZWxlbWVudC5ob3ZlciA+PiBlbnN1cmUgd2UgZmlyZWQgZHJhZy5vdXRcbiAgICovXG4gIGV2ZW50QnVzLm9uKCdkcmFnLmluaXQnLCBmdW5jdGlvbigpIHtcblxuICAgIHZhciBob3ZlciwgaG92ZXJHZng7XG5cbiAgICBmdW5jdGlvbiBzZXREcmFnSG92ZXIoZXZlbnQpIHtcbiAgICAgIGhvdmVyID0gZXZlbnQuaG92ZXI7XG4gICAgICBob3ZlckdmeCA9IGV2ZW50LmhvdmVyR2Z4O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVuc2V0SG92ZXIoKSB7XG4gICAgICBob3ZlciA9IG51bGw7XG4gICAgICBob3ZlckdmeCA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZW5zdXJlT3V0KCkge1xuXG4gICAgICBpZiAoIWhvdmVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGVsZW1lbnQgPSBob3ZlcixcbiAgICAgICAgICBnZnggPSBob3ZlckdmeDtcblxuICAgICAgaG92ZXIgPSBudWxsO1xuICAgICAgaG92ZXJHZnggPSBudWxsO1xuXG4gICAgICAvLyBlbWl0IHN5bnRoZXRpYyBvdXQgZXZlbnRcbiAgICAgIGRyYWdnaW5nLm91dCh7XG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGdmeDogZ2Z4XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBldmVudEJ1cy5vbignZHJhZy5ob3ZlcicsIHNldERyYWdIb3Zlcik7XG4gICAgZXZlbnRCdXMub24oJ2VsZW1lbnQub3V0JywgdW5zZXRIb3Zlcik7XG4gICAgZXZlbnRCdXMub24oJ2VsZW1lbnQuaG92ZXInLCBISUdIX1BSSU9SSVRZLCBlbnN1cmVPdXQpO1xuXG4gICAgZXZlbnRCdXMub25jZSgnZHJhZy5jbGVhbnVwJywgZnVuY3Rpb24oKSB7XG4gICAgICBldmVudEJ1cy5vZmYoJ2RyYWcuaG92ZXInLCBzZXREcmFnSG92ZXIpO1xuICAgICAgZXZlbnRCdXMub2ZmKCdlbGVtZW50Lm91dCcsIHVuc2V0SG92ZXIpO1xuICAgICAgZXZlbnRCdXMub2ZmKCdlbGVtZW50LmhvdmVyJywgZW5zdXJlT3V0KTtcbiAgICB9KTtcblxuICB9KTtcblxuICB0aGlzLl9maW5kVGFyZ2V0R2Z4ID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgcG9zaXRpb24sXG4gICAgICAgIHRhcmdldDtcblxuICAgIGlmICghKGV2ZW50IGluc3RhbmNlb2YgTW91c2VFdmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwb3NpdGlvbiA9IHRvUG9pbnQoZXZlbnQpO1xuXG4gICAgLy8gZGFtbiBleHBlbnNpdmUgb3BlcmF0aW9uLCBvdWNoIVxuICAgIHRhcmdldCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQocG9zaXRpb24ueCwgcG9zaXRpb24ueSk7XG5cbiAgICByZXR1cm4gZ2V0R2Z4KHRhcmdldCk7XG4gIH07XG5cbn1cblxuSG92ZXJGaXguJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2RyYWdnaW5nJyxcbiAgJ2VsZW1lbnRSZWdpc3RyeSdcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZ2V0R2Z4KHRhcmdldCkge1xuICByZXR1cm4gZG9tQ2xvc2VzdCh0YXJnZXQsICdzdmcsIC5kanMtZWxlbWVudCcsIHRydWUpO1xufSIsImltcG9ydCBTZWxlY3Rpb25Nb2R1bGUgZnJvbSAnLi4vc2VsZWN0aW9uJztcblxuaW1wb3J0IERyYWdnaW5nIGZyb20gJy4vRHJhZ2dpbmcnO1xuaW1wb3J0IEhvdmVyRml4IGZyb20gJy4vSG92ZXJGaXgnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbXG4gICAgJ2hvdmVyRml4J1xuICBdLFxuICBfX2RlcGVuZHNfXzogW1xuICAgIFNlbGVjdGlvbk1vZHVsZVxuICBdLFxuICBkcmFnZ2luZzogWyAndHlwZScsIERyYWdnaW5nIF0sXG4gIGhvdmVyRml4OiBbICd0eXBlJywgSG92ZXJGaXggXVxufTsiLCJpbXBvcnQge1xuICBmb3JFYWNoLFxuICBpc0FycmF5XG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIE5PVF9SRUdJU1RFUkVEX0VSUk9SID0gJ2lzIG5vdCBhIHJlZ2lzdGVyZWQgYWN0aW9uJyxcbiAgICBJU19SRUdJU1RFUkVEX0VSUk9SID0gJ2lzIGFscmVhZHkgcmVnaXN0ZXJlZCc7XG5cblxuLyoqXG4gKiBBbiBpbnRlcmZhY2UgdGhhdCBwcm92aWRlcyBhY2Nlc3MgdG8gbW9kZWxpbmcgYWN0aW9ucyBieSBkZWNvdXBsaW5nXG4gKiB0aGUgb25lIHdobyByZXF1ZXN0cyB0aGUgYWN0aW9uIHRvIGJlIHRyaWdnZXJlZCBhbmQgdGhlIHRyaWdnZXIgaXRzZWxmLlxuICpcbiAqIEl0J3MgcG9zc2libGUgdG8gYWRkIG5ldyBhY3Rpb25zIGJ5IHJlZ2lzdGVyaW5nIHRoZW0gd2l0aCDCtHJlZ2lzdGVyQWN0aW9uwrRcbiAqIGFuZCBsaWtld2lzZSB1bnJlZ2lzdGVyIGV4aXN0aW5nIG9uZXMgd2l0aCDCtHVucmVnaXN0ZXJBY3Rpb27CtC5cbiAqXG4gKlxuICogIyMgTGlmZS1DeWNsZSBhbmQgY29uZmlndXJhdGlvblxuICpcbiAqIFRoZSBlZGl0b3IgYWN0aW9ucyB3aWxsIHdhaXQgZm9yIGRpYWdyYW0gaW5pdGlhbGl6YXRpb24gYmVmb3JlXG4gKiByZWdpc3RlcmluZyBkZWZhdWx0IGFjdGlvbnMgX2FuZF8gZmlyaW5nIGFuIGBlZGl0b3JBY3Rpb25zLmluaXRgIGV2ZW50LlxuICpcbiAqIEludGVyZXN0ZWQgcGFydGllcyBtYXkgbGlzdGVuIHRvIHRoZSBgZWRpdG9yQWN0aW9ucy5pbml0YCBldmVudCB3aXRoXG4gKiBsb3cgcHJpb3JpdHkgdG8gY2hlY2ssIHdoaWNoIGFjdGlvbnMgZ290IHJlZ2lzdGVyZWQuIE90aGVyIGNvbXBvbmVudHNcbiAqIG1heSB1c2UgdGhlIGV2ZW50IHRvIHJlZ2lzdGVyIHRoZWlyIG93biBhY3Rpb25zIHZpYSBgcmVnaXN0ZXJBY3Rpb25gLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0luamVjdG9yfSBpbmplY3RvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBFZGl0b3JBY3Rpb25zKGV2ZW50QnVzLCBpbmplY3Rvcikge1xuXG4gIC8vIGluaXRpYWxpemUgYWN0aW9uc1xuICB0aGlzLl9hY3Rpb25zID0ge307XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGV2ZW50QnVzLm9uKCdkaWFncmFtLmluaXQnLCBmdW5jdGlvbigpIHtcblxuICAgIC8vIGFsbCBkaWFncmFtIG1vZHVsZXMgZ290IGxvYWRlZDsgY2hlY2sgd2hpY2ggb25lc1xuICAgIC8vIGFyZSBhdmFpbGFibGUgYW5kIHJlZ2lzdGVyIHRoZSByZXNwZWN0aXZlIGRlZmF1bHQgYWN0aW9uc1xuICAgIHNlbGYuX3JlZ2lzdGVyRGVmYXVsdEFjdGlvbnMoaW5qZWN0b3IpO1xuXG4gICAgLy8gYXNrIGludGVyZXN0ZWQgcGFydGllcyB0byByZWdpc3RlciBhdmFpbGFibGUgZWRpdG9yXG4gICAgLy8gYWN0aW9ucyBvbiBkaWFncmFtIGluaXRpYWxpemF0aW9uXG4gICAgZXZlbnRCdXMuZmlyZSgnZWRpdG9yQWN0aW9ucy5pbml0Jywge1xuICAgICAgZWRpdG9yQWN0aW9uczogc2VsZlxuICAgIH0pO1xuICB9KTtcblxufVxuXG5FZGl0b3JBY3Rpb25zLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdpbmplY3Rvcidcbl07XG5cbi8qKlxuICogUmVnaXN0ZXIgZGVmYXVsdCBhY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKi9cbkVkaXRvckFjdGlvbnMucHJvdG90eXBlLl9yZWdpc3RlckRlZmF1bHRBY3Rpb25zID0gZnVuY3Rpb24oaW5qZWN0b3IpIHtcblxuICAvLyAoMSkgcmV0cmlldmUgb3B0aW9uYWwgY29tcG9uZW50cyB0byBpbnRlZ3JhdGUgd2l0aFxuXG4gIHZhciBjb21tYW5kU3RhY2sgPSBpbmplY3Rvci5nZXQoJ2NvbW1hbmRTdGFjaycsIGZhbHNlKTtcbiAgdmFyIG1vZGVsaW5nID0gaW5qZWN0b3IuZ2V0KCdtb2RlbGluZycsIGZhbHNlKTtcbiAgdmFyIHNlbGVjdGlvbiA9IGluamVjdG9yLmdldCgnc2VsZWN0aW9uJywgZmFsc2UpO1xuICB2YXIgem9vbVNjcm9sbCA9IGluamVjdG9yLmdldCgnem9vbVNjcm9sbCcsIGZhbHNlKTtcbiAgdmFyIGNvcHlQYXN0ZSA9IGluamVjdG9yLmdldCgnY29weVBhc3RlJywgZmFsc2UpO1xuICB2YXIgY2FudmFzID0gaW5qZWN0b3IuZ2V0KCdjYW52YXMnLCBmYWxzZSk7XG4gIHZhciBydWxlcyA9IGluamVjdG9yLmdldCgncnVsZXMnLCBmYWxzZSk7XG4gIHZhciBrZXlib2FyZE1vdmUgPSBpbmplY3Rvci5nZXQoJ2tleWJvYXJkTW92ZScsIGZhbHNlKTtcbiAgdmFyIGtleWJvYXJkTW92ZVNlbGVjdGlvbiA9IGluamVjdG9yLmdldCgna2V5Ym9hcmRNb3ZlU2VsZWN0aW9uJywgZmFsc2UpO1xuXG4gIC8vICgyKSBjaGVjayBjb21wb25lbnRzIGFuZCByZWdpc3RlciBhY3Rpb25zXG5cbiAgaWYgKGNvbW1hbmRTdGFjaykge1xuICAgIHRoaXMucmVnaXN0ZXIoJ3VuZG8nLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbW1hbmRTdGFjay51bmRvKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyKCdyZWRvJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb21tYW5kU3RhY2sucmVkbygpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGNvcHlQYXN0ZSAmJiBzZWxlY3Rpb24pIHtcbiAgICB0aGlzLnJlZ2lzdGVyKCdjb3B5JywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgc2VsZWN0ZWRFbGVtZW50cyA9IHNlbGVjdGlvbi5nZXQoKTtcblxuICAgICAgY29weVBhc3RlLmNvcHkoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoY29weVBhc3RlKSB7XG4gICAgdGhpcy5yZWdpc3RlcigncGFzdGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvcHlQYXN0ZS5wYXN0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHpvb21TY3JvbGwpIHtcbiAgICB0aGlzLnJlZ2lzdGVyKCdzdGVwWm9vbScsIGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgIHpvb21TY3JvbGwuc3RlcFpvb20ob3B0cy52YWx1ZSk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoY2FudmFzKSB7XG4gICAgdGhpcy5yZWdpc3Rlcignem9vbScsIGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgIGNhbnZhcy56b29tKG9wdHMudmFsdWUpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKG1vZGVsaW5nICYmIHNlbGVjdGlvbiAmJiBydWxlcykge1xuICAgIHRoaXMucmVnaXN0ZXIoJ3JlbW92ZVNlbGVjdGlvbicsIGZ1bmN0aW9uKCkge1xuXG4gICAgICB2YXIgc2VsZWN0ZWRFbGVtZW50cyA9IHNlbGVjdGlvbi5nZXQoKTtcblxuICAgICAgaWYgKCFzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBhbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMuZGVsZXRlJywgeyBlbGVtZW50czogc2VsZWN0ZWRFbGVtZW50cyB9KSxcbiAgICAgICAgICByZW1vdmFibGVFbGVtZW50cztcblxuICAgICAgaWYgKGFsbG93ZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGlzQXJyYXkoYWxsb3dlZCkpIHtcbiAgICAgICAgcmVtb3ZhYmxlRWxlbWVudHMgPSBhbGxvd2VkO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHJlbW92YWJsZUVsZW1lbnRzID0gc2VsZWN0ZWRFbGVtZW50cztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlbW92YWJsZUVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICBtb2RlbGluZy5yZW1vdmVFbGVtZW50cyhyZW1vdmFibGVFbGVtZW50cy5zbGljZSgpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChrZXlib2FyZE1vdmUpIHtcbiAgICB0aGlzLnJlZ2lzdGVyKCdtb3ZlQ2FudmFzJywgZnVuY3Rpb24ob3B0cykge1xuICAgICAga2V5Ym9hcmRNb3ZlLm1vdmVDYW52YXMob3B0cyk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoa2V5Ym9hcmRNb3ZlU2VsZWN0aW9uKSB7XG4gICAgdGhpcy5yZWdpc3RlcignbW92ZVNlbGVjdGlvbicsIGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgIGtleWJvYXJkTW92ZVNlbGVjdGlvbi5tb3ZlU2VsZWN0aW9uKG9wdHMuZGlyZWN0aW9uLCBvcHRzLmFjY2VsZXJhdGVkKTtcbiAgICB9KTtcbiAgfVxuXG59O1xuXG5cbi8qKlxuICogVHJpZ2dlcnMgYSByZWdpc3RlcmVkIGFjdGlvblxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gYWN0aW9uXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdHNcbiAqXG4gKiBAcmV0dXJuIHtVbmtub3dufSBSZXR1cm5zIHdoYXQgdGhlIHJlZ2lzdGVyZWQgbGlzdGVuZXIgcmV0dXJuc1xuICovXG5FZGl0b3JBY3Rpb25zLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oYWN0aW9uLCBvcHRzKSB7XG4gIGlmICghdGhpcy5fYWN0aW9uc1thY3Rpb25dKSB7XG4gICAgdGhyb3cgZXJyb3IoYWN0aW9uLCBOT1RfUkVHSVNURVJFRF9FUlJPUik7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fYWN0aW9uc1thY3Rpb25dKG9wdHMpO1xufTtcblxuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGNvbGxlY3Rpb25zIG9mIGFjdGlvbnMuXG4gKiBUaGUga2V5IG9mIHRoZSBvYmplY3Qgd2lsbCBiZSB0aGUgbmFtZSBvZiB0aGUgYWN0aW9uLlxuICpcbiAqIEBleGFtcGxlXG4gKiDCtMK0wrRcbiAqIHZhciBhY3Rpb25zID0ge1xuICogICBzcGFjZVRvb2w6IGZ1bmN0aW9uKCkge1xuICogICAgIHNwYWNlVG9vbC5hY3RpdmF0ZVNlbGVjdGlvbigpO1xuICogICB9LFxuICogICBsYXNzb1Rvb2w6IGZ1bmN0aW9uKCkge1xuICogICAgIGxhc3NvVG9vbC5hY3RpdmF0ZVNlbGVjdGlvbigpO1xuICogICB9XG4gKiBdO1xuICpcbiAqIGVkaXRvckFjdGlvbnMucmVnaXN0ZXIoYWN0aW9ucyk7XG4gKlxuICogZWRpdG9yQWN0aW9ucy5pc1JlZ2lzdGVyZWQoJ3NwYWNlVG9vbCcpOyAvLyB0cnVlXG4gKiDCtMK0wrRcbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGFjdGlvbnNcbiAqL1xuRWRpdG9yQWN0aW9ucy5wcm90b3R5cGUucmVnaXN0ZXIgPSBmdW5jdGlvbihhY3Rpb25zLCBsaXN0ZW5lcikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHR5cGVvZiBhY3Rpb25zID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB0aGlzLl9yZWdpc3RlckFjdGlvbihhY3Rpb25zLCBsaXN0ZW5lcik7XG4gIH1cblxuICBmb3JFYWNoKGFjdGlvbnMsIGZ1bmN0aW9uKGxpc3RlbmVyLCBhY3Rpb24pIHtcbiAgICBzZWxmLl9yZWdpc3RlckFjdGlvbihhY3Rpb24sIGxpc3RlbmVyKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGxpc3RlbmVyIHRvIGFuIGFjdGlvbiBrZXlcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGFjdGlvblxuICogQHBhcmFtICB7RnVuY3Rpb259IGxpc3RlbmVyXG4gKi9cbkVkaXRvckFjdGlvbnMucHJvdG90eXBlLl9yZWdpc3RlckFjdGlvbiA9IGZ1bmN0aW9uKGFjdGlvbiwgbGlzdGVuZXIpIHtcbiAgaWYgKHRoaXMuaXNSZWdpc3RlcmVkKGFjdGlvbikpIHtcbiAgICB0aHJvdyBlcnJvcihhY3Rpb24sIElTX1JFR0lTVEVSRURfRVJST1IpO1xuICB9XG5cbiAgdGhpcy5fYWN0aW9uc1thY3Rpb25dID0gbGlzdGVuZXI7XG59O1xuXG4vKipcbiAqIFVucmVnaXN0ZXIgYW4gZXhpc3RpbmcgYWN0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvblxuICovXG5FZGl0b3JBY3Rpb25zLnByb3RvdHlwZS51bnJlZ2lzdGVyID0gZnVuY3Rpb24oYWN0aW9uKSB7XG4gIGlmICghdGhpcy5pc1JlZ2lzdGVyZWQoYWN0aW9uKSkge1xuICAgIHRocm93IGVycm9yKGFjdGlvbiwgTk9UX1JFR0lTVEVSRURfRVJST1IpO1xuICB9XG5cbiAgdGhpcy5fYWN0aW9uc1thY3Rpb25dID0gdW5kZWZpbmVkO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYWN0aW9ucyB0aGF0IGFyZSBjdXJyZW50bHkgcmVnaXN0ZXJlZFxuICpcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuRWRpdG9yQWN0aW9ucy5wcm90b3R5cGUuZ2V0QWN0aW9ucyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fYWN0aW9ucyk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3ZXRoZXIgdGhlIGdpdmVuIGFjdGlvbiBpcyByZWdpc3RlcmVkXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvblxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbkVkaXRvckFjdGlvbnMucHJvdG90eXBlLmlzUmVnaXN0ZXJlZCA9IGZ1bmN0aW9uKGFjdGlvbikge1xuICByZXR1cm4gISF0aGlzLl9hY3Rpb25zW2FjdGlvbl07XG59O1xuXG5cbmZ1bmN0aW9uIGVycm9yKGFjdGlvbiwgbWVzc2FnZSkge1xuICByZXR1cm4gbmV3IEVycm9yKGFjdGlvbiArICcgJyArIG1lc3NhZ2UpO1xufVxuIiwiaW1wb3J0IEVkaXRvckFjdGlvbnMgZnJvbSAnLi9FZGl0b3JBY3Rpb25zJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnZWRpdG9yQWN0aW9ucycgXSxcbiAgZWRpdG9yQWN0aW9uczogWyAndHlwZScsIEVkaXRvckFjdGlvbnMgXVxufTtcbiIsInZhciBNQVJLRVJfT0sgPSAnY29ubmVjdC1vaycsXG4gICAgTUFSS0VSX05PVF9PSyA9ICdjb25uZWN0LW5vdC1vayc7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtEcmFnZ2luZ30gZHJhZ2dpbmdcbiAqIEBwYXJhbSB7Q29ubmVjdH0gY29ubmVjdFxuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICogQHBhcmFtIHtUb29sTWFuYWdlcn0gdG9vbE1hbmFnZXJcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEdsb2JhbENvbm5lY3QoXG4gICAgZXZlbnRCdXMsIGRyYWdnaW5nLCBjb25uZWN0LFxuICAgIGNhbnZhcywgdG9vbE1hbmFnZXIsIHJ1bGVzKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMuX2RyYWdnaW5nID0gZHJhZ2dpbmc7XG4gIHRoaXMuX3J1bGVzID0gcnVsZXM7XG5cbiAgdG9vbE1hbmFnZXIucmVnaXN0ZXJUb29sKCdnbG9iYWwtY29ubmVjdCcsIHtcbiAgICB0b29sOiAnZ2xvYmFsLWNvbm5lY3QnLFxuICAgIGRyYWdnaW5nOiAnZ2xvYmFsLWNvbm5lY3QuZHJhZydcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2dsb2JhbC1jb25uZWN0LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHN0YXJ0VGFyZ2V0ID0gZXZlbnQuaG92ZXI7XG5cbiAgICB2YXIgY2FuU3RhcnRDb25uZWN0ID0gY29udGV4dC5jYW5TdGFydENvbm5lY3QgPSBzZWxmLmNhblN0YXJ0Q29ubmVjdChzdGFydFRhcmdldCk7XG5cbiAgICAvLyBzaW1wbHkgaWdub3JlIGhvdmVyXG4gICAgaWYgKGNhblN0YXJ0Q29ubmVjdCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnRleHQuc3RhcnRUYXJnZXQgPSBzdGFydFRhcmdldDtcblxuICAgIGNhbnZhcy5hZGRNYXJrZXIoc3RhcnRUYXJnZXQsIGNhblN0YXJ0Q29ubmVjdCA/IE1BUktFUl9PSyA6IE1BUktFUl9OT1RfT0spO1xuICB9KTtcblxuXG4gIGV2ZW50QnVzLm9uKFsgJ2dsb2JhbC1jb25uZWN0Lm91dCcsICdnbG9iYWwtY29ubmVjdC5jbGVhbnVwJyBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBzdGFydFRhcmdldCA9IGV2ZW50LmNvbnRleHQuc3RhcnRUYXJnZXQsXG4gICAgICAgIGNhblN0YXJ0Q29ubmVjdCA9IGV2ZW50LmNvbnRleHQuY2FuU3RhcnRDb25uZWN0O1xuXG4gICAgaWYgKHN0YXJ0VGFyZ2V0KSB7XG4gICAgICBjYW52YXMucmVtb3ZlTWFya2VyKHN0YXJ0VGFyZ2V0LCBjYW5TdGFydENvbm5lY3QgPyBNQVJLRVJfT0sgOiBNQVJLRVJfTk9UX09LKTtcbiAgICB9XG4gIH0pO1xuXG5cbiAgZXZlbnRCdXMub24oWyAnZ2xvYmFsLWNvbm5lY3QuZW5kZWQnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzdGFydFRhcmdldCA9IGNvbnRleHQuc3RhcnRUYXJnZXQsXG4gICAgICAgIHN0YXJ0UG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogZXZlbnQueCxcbiAgICAgICAgICB5OiBldmVudC55XG4gICAgICAgIH07XG5cbiAgICB2YXIgY2FuU3RhcnRDb25uZWN0ID0gc2VsZi5jYW5TdGFydENvbm5lY3Qoc3RhcnRUYXJnZXQpO1xuXG4gICAgaWYgKCFjYW5TdGFydENvbm5lY3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBldmVudEJ1cy5vbmNlKCdlbGVtZW50Lm91dCcsIGZ1bmN0aW9uKCkge1xuICAgICAgZXZlbnRCdXMub25jZShbICdjb25uZWN0LmVuZGVkJywgJ2Nvbm5lY3QuY2FuY2VsZWQnIF0sIGZ1bmN0aW9uKCkge1xuICAgICAgICBldmVudEJ1cy5maXJlKCdnbG9iYWwtY29ubmVjdC5kcmFnLmVuZGVkJyk7XG4gICAgICB9KTtcblxuICAgICAgY29ubmVjdC5zdGFydChudWxsLCBzdGFydFRhcmdldCwgc3RhcnRQb3NpdGlvbik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pO1xufVxuXG5HbG9iYWxDb25uZWN0LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdkcmFnZ2luZycsXG4gICdjb25uZWN0JyxcbiAgJ2NhbnZhcycsXG4gICd0b29sTWFuYWdlcicsXG4gICdydWxlcydcbl07XG5cbi8qKlxuICogSW5pdGlhdGVzIHRvb2wgYWN0aXZpdHkuXG4gKi9cbkdsb2JhbENvbm5lY3QucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdGhpcy5fZHJhZ2dpbmcuaW5pdChldmVudCwgJ2dsb2JhbC1jb25uZWN0Jywge1xuICAgIHRyYXBDbGljazogZmFsc2UsXG4gICAgZGF0YToge1xuICAgICAgY29udGV4dDoge31cbiAgICB9XG4gIH0pO1xufTtcblxuR2xvYmFsQ29ubmVjdC5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLmlzQWN0aXZlKCkpIHtcbiAgICB0aGlzLl9kcmFnZ2luZy5jYW5jZWwoKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnN0YXJ0KCk7XG4gIH1cbn07XG5cbkdsb2JhbENvbm5lY3QucHJvdG90eXBlLmlzQWN0aXZlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjb250ZXh0ID0gdGhpcy5fZHJhZ2dpbmcuY29udGV4dCgpO1xuXG4gIHJldHVybiBjb250ZXh0ICYmIC9eZ2xvYmFsLWNvbm5lY3QvLnRlc3QoY29udGV4dC5wcmVmaXgpO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBzb3VyY2Ugc2hhcGUgY2FuIGluaXRpYXRlIGNvbm5lY3Rpb24uXG4gKlxuICogQHBhcmFtICB7U2hhcGV9IHN0YXJ0VGFyZ2V0XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5HbG9iYWxDb25uZWN0LnByb3RvdHlwZS5jYW5TdGFydENvbm5lY3QgPSBmdW5jdGlvbihzdGFydFRhcmdldCkge1xuICByZXR1cm4gdGhpcy5fcnVsZXMuYWxsb3dlZCgnY29ubmVjdGlvbi5zdGFydCcsIHsgc291cmNlOiBzdGFydFRhcmdldCB9KTtcbn07XG4iLCJpbXBvcnQgQ29ubmVjdE1vZHVsZSBmcm9tICcuLi9jb25uZWN0JztcbmltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuaW1wb3J0IFRvb2xNYW5hZ2VyTW9kdWxlIGZyb20gJy4uL3Rvb2wtbWFuYWdlcic7XG5cbmltcG9ydCBHbG9iYWxDb25uZWN0IGZyb20gJy4vR2xvYmFsQ29ubmVjdCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBDb25uZWN0TW9kdWxlLFxuICAgIFJ1bGVzTW9kdWxlLFxuICAgIERyYWdnaW5nTW9kdWxlLFxuICAgIFRvb2xNYW5hZ2VyTW9kdWxlXG4gIF0sXG4gIGdsb2JhbENvbm5lY3Q6IFsgJ3R5cGUnLCBHbG9iYWxDb25uZWN0IF1cbn07XG4iLCJpbXBvcnQge1xyXG4gIHNldFNuYXBwZWQsXHJcbiAgaXNTbmFwcGVkXHJcbn0gZnJvbSAnLi4vc25hcHBpbmcvU25hcFV0aWwnO1xyXG5cclxuaW1wb3J0IHsgaXNDbWQgfSBmcm9tICcuLi9rZXlib2FyZC9LZXlib2FyZFV0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBhc3NpZ24sXHJcbiAgaXNOdW1iZXJcclxufSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIFNQQUNJTkcsXHJcbiAgcXVhbnRpemVcclxufSBmcm9tICcuL0dyaWRVdGlsJztcclxuXHJcbnZhciBMT1dFUl9QUklPUklUWSA9IDEyMDA7XHJcbnZhciBMT1dfUFJJT1JJVFkgPSA4MDA7XHJcblxyXG4vKipcclxuICogQmFzaWMgZ3JpZCBzbmFwcGluZyB0aGF0IGNvdmVycyBjb25uZWN0aW5nLCBjcmVhdGluZywgbW92aW5nLCByZXNpemluZyBzaGFwZXMsIG1vdmluZyBiZW5kcG9pbnRzXHJcbiAqIGFuZCBjb25uZWN0aW9uIHNlZ21lbnRzLlxyXG4gKi9cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gR3JpZFNuYXBwaW5nKGVsZW1lbnRSZWdpc3RyeSwgZXZlbnRCdXMsIGNvbmZpZykge1xyXG5cclxuICB2YXIgYWN0aXZlID0gIWNvbmZpZyB8fCBjb25maWcuYWN0aXZlICE9PSBmYWxzZTtcclxuXHJcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcclxuXHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5pbml0JywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbigpIHtcclxuICAgIHNlbGYuc2V0QWN0aXZlKGFjdGl2ZSk7XHJcbiAgfSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKFtcclxuICAgICdjcmVhdGUubW92ZScsXHJcbiAgICAnY3JlYXRlLmVuZCcsXHJcbiAgICAnYmVuZHBvaW50Lm1vdmUubW92ZScsXHJcbiAgICAnYmVuZHBvaW50Lm1vdmUuZW5kJyxcclxuICAgICdjb25uZWN0Lm1vdmUnLFxyXG4gICAgJ2Nvbm5lY3QuZW5kJyxcclxuICAgICdjb25uZWN0aW9uU2VnbWVudC5tb3ZlLm1vdmUnLFxyXG4gICAgJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUuZW5kJyxcclxuICAgICdyZXNpemUubW92ZScsXHJcbiAgICAncmVzaXplLmVuZCcsXHJcbiAgICAnc2hhcGUubW92ZS5tb3ZlJyxcclxuICAgICdzaGFwZS5tb3ZlLmVuZCdcclxuICBdLCBMT1dFUl9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBvcmlnaW5hbEV2ZW50ID0gZXZlbnQub3JpZ2luYWxFdmVudDtcclxuXHJcbiAgICBpZiAoIXNlbGYuYWN0aXZlIHx8IChvcmlnaW5hbEV2ZW50ICYmIGlzQ21kKG9yaWdpbmFsRXZlbnQpKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIGdyaWRTbmFwcGluZ0NvbnRleHQgPSBjb250ZXh0LmdyaWRTbmFwcGluZ0NvbnRleHQ7XHJcblxyXG4gICAgaWYgKCFncmlkU25hcHBpbmdDb250ZXh0KSB7XHJcbiAgICAgIGdyaWRTbmFwcGluZ0NvbnRleHQgPSBjb250ZXh0LmdyaWRTbmFwcGluZ0NvbnRleHQgPSB7fTtcclxuICAgIH1cclxuXHJcbiAgICBbICd4JywgJ3knIF0uZm9yRWFjaChmdW5jdGlvbihheGlzKSB7XHJcbiAgICAgIHZhciBvcHRpb25zID0ge307XHJcblxyXG4gICAgICAvLyBhbGxvdyBzbmFwcGluZyB3aXRoIG9mZnNldFxyXG4gICAgICB2YXIgc25hcE9mZnNldCA9IGdldFNuYXBPZmZzZXQoZXZlbnQsIGF4aXMsIGVsZW1lbnRSZWdpc3RyeSk7XHJcblxyXG4gICAgICBpZiAoc25hcE9mZnNldCkge1xyXG4gICAgICAgIG9wdGlvbnMub2Zmc2V0ID0gc25hcE9mZnNldDtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gYWxsb3cgc25hcHBpbmcgd2l0aCBtaW4gYW5kIG1heFxyXG4gICAgICB2YXIgc25hcENvbnN0cmFpbnRzID0gZ2V0U25hcENvbnN0cmFpbnRzKGV2ZW50LCBheGlzKTtcclxuXHJcbiAgICAgIGlmIChzbmFwQ29uc3RyYWludHMpIHtcclxuICAgICAgICBhc3NpZ24ob3B0aW9ucywgc25hcENvbnN0cmFpbnRzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFpc1NuYXBwZWQoZXZlbnQsIGF4aXMpKSB7XHJcbiAgICAgICAgc2VsZi5zbmFwRXZlbnQoZXZlbnQsIGF4aXMsIG9wdGlvbnMpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFNuYXAgYW4gZXZlbnRzIHggb3IgeSB3aXRoIG9wdGlvbmFsIG1pbiwgbWF4IGFuZCBvZmZzZXQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gYXhpc1xyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWluXVxyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4XVxyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMub2Zmc2V0XVxyXG4gKi9cclxuR3JpZFNuYXBwaW5nLnByb3RvdHlwZS5zbmFwRXZlbnQgPSBmdW5jdGlvbihldmVudCwgYXhpcywgb3B0aW9ucykge1xyXG4gIHZhciBzbmFwcGVkVmFsdWUgPSB0aGlzLnNuYXBWYWx1ZShldmVudFsgYXhpcyBdLCBvcHRpb25zKTtcclxuXHJcbiAgc2V0U25hcHBlZChldmVudCwgYXhpcywgc25hcHBlZFZhbHVlKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBFeHBvc2UgZ3JpZCBzcGFjaW5nIGZvciB0aGlyZCBwYXJ0aWVzIChpLmUuIGV4dGVuc2lvbnMpLlxyXG4gKlxyXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHNwYWNpbmcgb2YgZ3JpZCBkb3RzXHJcbiAqL1xyXG5HcmlkU25hcHBpbmcucHJvdG90eXBlLmdldEdyaWRTcGFjaW5nID0gZnVuY3Rpb24oKSB7XHJcbiAgcmV0dXJuIFNQQUNJTkc7XHJcbn07XHJcblxyXG4vKipcclxuICogU25hcCB2YWx1ZSB3aXRoIG9wdGlvbmFsIG1pbiwgbWF4IGFuZCBvZmZzZXQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWluXVxyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4XVxyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMub2Zmc2V0XVxyXG4gKi9cclxuR3JpZFNuYXBwaW5nLnByb3RvdHlwZS5zbmFwVmFsdWUgPSBmdW5jdGlvbih2YWx1ZSwgb3B0aW9ucykge1xyXG4gIHZhciBvZmZzZXQgPSAwO1xyXG5cclxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLm9mZnNldCkge1xyXG4gICAgb2Zmc2V0ID0gb3B0aW9ucy5vZmZzZXQ7XHJcbiAgfVxyXG5cclxuICB2YWx1ZSArPSBvZmZzZXQ7XHJcblxyXG4gIHZhbHVlID0gcXVhbnRpemUodmFsdWUsIFNQQUNJTkcpO1xyXG5cclxuICB2YXIgbWluLCBtYXg7XHJcblxyXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMubWluKSB7XHJcbiAgICBtaW4gPSBvcHRpb25zLm1pbjtcclxuXHJcbiAgICBpZiAoaXNOdW1iZXIobWluKSkge1xyXG4gICAgICBtaW4gPSBxdWFudGl6ZShtaW4gKyBvZmZzZXQsIFNQQUNJTkcsICdjZWlsJyk7XHJcblxyXG4gICAgICB2YWx1ZSA9IE1hdGgubWF4KHZhbHVlLCBtaW4pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5tYXgpIHtcclxuICAgIG1heCA9IG9wdGlvbnMubWF4O1xyXG5cclxuICAgIGlmIChpc051bWJlcihtYXgpKSB7XHJcbiAgICAgIG1heCA9IHF1YW50aXplKG1heCArIG9mZnNldCwgU1BBQ0lORywgJ2Zsb29yJyk7XHJcblxyXG4gICAgICB2YWx1ZSA9IE1hdGgubWluKHZhbHVlLCBtYXgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdmFsdWUgLT0gb2Zmc2V0O1xyXG5cclxuICByZXR1cm4gdmFsdWU7XHJcbn07XHJcblxyXG5HcmlkU25hcHBpbmcucHJvdG90eXBlLmlzQWN0aXZlID0gZnVuY3Rpb24oKSB7XHJcbiAgcmV0dXJuIHRoaXMuYWN0aXZlO1xyXG59O1xyXG5cclxuR3JpZFNuYXBwaW5nLnByb3RvdHlwZS5zZXRBY3RpdmUgPSBmdW5jdGlvbihhY3RpdmUpIHtcclxuICB0aGlzLmFjdGl2ZSA9IGFjdGl2ZTtcclxuXHJcbiAgdGhpcy5fZXZlbnRCdXMuZmlyZSgnZ3JpZFNuYXBwaW5nLnRvZ2dsZScsIHsgYWN0aXZlOiBhY3RpdmUgfSk7XHJcbn07XHJcblxyXG5HcmlkU25hcHBpbmcucHJvdG90eXBlLnRvZ2dsZUFjdGl2ZSA9IGZ1bmN0aW9uKCkge1xyXG4gIHRoaXMuc2V0QWN0aXZlKCF0aGlzLmFjdGl2ZSk7XHJcbn07XHJcblxyXG5HcmlkU25hcHBpbmcuJGluamVjdCA9IFtcclxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcclxuICAnZXZlbnRCdXMnLFxyXG4gICdjb25maWcuZ3JpZFNuYXBwaW5nJ1xyXG5dO1xyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG4vKipcclxuICogR2V0IG1pbmltdW0gYW5kIG1heGltdW0gc25hcCBjb25zdHJhaW50cy5cclxuICogQ29uc3RyYWludHMgYXJlIGNhY2hlZC5cclxuICpcclxuICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5jb250ZXh0XHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtib29sZWFufE9iamVjdH1cclxuICovXHJcbmZ1bmN0aW9uIGdldFNuYXBDb25zdHJhaW50cyhldmVudCwgYXhpcykge1xyXG4gIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgY3JlYXRlQ29uc3RyYWludHMgPSBjb250ZXh0LmNyZWF0ZUNvbnN0cmFpbnRzLFxyXG4gICAgICByZXNpemVDb25zdHJhaW50cyA9IGNvbnRleHQucmVzaXplQ29uc3RyYWludHMgfHwge30sXHJcbiAgICAgIGdyaWRTbmFwcGluZ0NvbnRleHQgPSBjb250ZXh0LmdyaWRTbmFwcGluZ0NvbnRleHQsXHJcbiAgICAgIHNuYXBDb25zdHJhaW50cyA9IGdyaWRTbmFwcGluZ0NvbnRleHQuc25hcENvbnN0cmFpbnRzO1xyXG5cclxuICAvLyBjYWNoZSBzbmFwIGNvbnN0cmFpbnRzXHJcbiAgaWYgKHNuYXBDb25zdHJhaW50cyAmJiBzbmFwQ29uc3RyYWludHNbIGF4aXMgXSkge1xyXG4gICAgcmV0dXJuIHNuYXBDb25zdHJhaW50c1sgYXhpcyBdO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFzbmFwQ29uc3RyYWludHMpIHtcclxuICAgIHNuYXBDb25zdHJhaW50cyA9IGdyaWRTbmFwcGluZ0NvbnRleHQuc25hcENvbnN0cmFpbnRzID0ge307XHJcbiAgfVxyXG5cclxuICBpZiAoIXNuYXBDb25zdHJhaW50c1sgYXhpcyBdKSB7XHJcbiAgICBzbmFwQ29uc3RyYWludHNbIGF4aXMgXSA9IHt9O1xyXG4gIH1cclxuXHJcbiAgdmFyIGRpcmVjdGlvbiA9IGNvbnRleHQuZGlyZWN0aW9uO1xyXG5cclxuICAvLyBjcmVhdGVcclxuICBpZiAoY3JlYXRlQ29uc3RyYWludHMpIHtcclxuICAgIGlmIChpc0hvcml6b250YWwoYXhpcykpIHtcclxuICAgICAgc25hcENvbnN0cmFpbnRzLngubWluID0gY3JlYXRlQ29uc3RyYWludHMubGVmdDtcclxuICAgICAgc25hcENvbnN0cmFpbnRzLngubWF4ID0gY3JlYXRlQ29uc3RyYWludHMucmlnaHQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzbmFwQ29uc3RyYWludHMueS5taW4gPSBjcmVhdGVDb25zdHJhaW50cy50b3A7XHJcbiAgICAgIHNuYXBDb25zdHJhaW50cy55Lm1heCA9IGNyZWF0ZUNvbnN0cmFpbnRzLmJvdHRvbTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIHJlc2l6ZVxyXG4gIHZhciBtaW5SZXNpemVDb25zdHJhaW50cyA9IHJlc2l6ZUNvbnN0cmFpbnRzLm1pbixcclxuICAgICAgbWF4UmVzaXplQ29uc3RyYWludHMgPSByZXNpemVDb25zdHJhaW50cy5tYXg7XHJcblxyXG4gIGlmIChtaW5SZXNpemVDb25zdHJhaW50cykge1xyXG4gICAgaWYgKGlzSG9yaXpvbnRhbChheGlzKSkge1xyXG5cclxuICAgICAgaWYgKGlzV2VzdChkaXJlY3Rpb24pKSB7XHJcbiAgICAgICAgc25hcENvbnN0cmFpbnRzLngubWF4ID0gbWluUmVzaXplQ29uc3RyYWludHMubGVmdDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzbmFwQ29uc3RyYWludHMueC5taW4gPSBtaW5SZXNpemVDb25zdHJhaW50cy5yaWdodDtcclxuICAgICAgfVxyXG5cclxuICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICBpZiAoaXNOb3J0aChkaXJlY3Rpb24pKSB7XHJcbiAgICAgICAgc25hcENvbnN0cmFpbnRzLnkubWF4ID0gbWluUmVzaXplQ29uc3RyYWludHMudG9wO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNuYXBDb25zdHJhaW50cy55Lm1pbiA9IG1pblJlc2l6ZUNvbnN0cmFpbnRzLmJvdHRvbTtcclxuICAgICAgfVxyXG5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChtYXhSZXNpemVDb25zdHJhaW50cykge1xyXG4gICAgaWYgKGlzSG9yaXpvbnRhbChheGlzKSkge1xyXG5cclxuICAgICAgaWYgKGlzV2VzdChkaXJlY3Rpb24pKSB7XHJcbiAgICAgICAgc25hcENvbnN0cmFpbnRzLngubWluID0gbWF4UmVzaXplQ29uc3RyYWludHMubGVmdDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzbmFwQ29uc3RyYWludHMueC5tYXggPSBtYXhSZXNpemVDb25zdHJhaW50cy5yaWdodDtcclxuICAgICAgfVxyXG5cclxuICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICBpZiAoaXNOb3J0aChkaXJlY3Rpb24pKSB7XHJcbiAgICAgICAgc25hcENvbnN0cmFpbnRzLnkubWluID0gbWF4UmVzaXplQ29uc3RyYWludHMudG9wO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNuYXBDb25zdHJhaW50cy55Lm1heCA9IG1heFJlc2l6ZUNvbnN0cmFpbnRzLmJvdHRvbTtcclxuICAgICAgfVxyXG5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBzbmFwQ29uc3RyYWludHNbIGF4aXMgXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBzbmFwIG9mZnNldC5cclxuICogT2Zmc2V0IGlzIGNhY2hlZC5cclxuICpcclxuICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzXHJcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcclxuICpcclxuICogQHJldHVybnMge251bWJlcn1cclxuICovXHJcbmZ1bmN0aW9uIGdldFNuYXBPZmZzZXQoZXZlbnQsIGF4aXMsIGVsZW1lbnRSZWdpc3RyeSkge1xyXG4gIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgc2hhcGUgPSBldmVudC5zaGFwZSxcclxuICAgICAgZ3JpZFNuYXBwaW5nQ29udGV4dCA9IGNvbnRleHQuZ3JpZFNuYXBwaW5nQ29udGV4dCxcclxuICAgICAgc25hcExvY2F0aW9uID0gZ3JpZFNuYXBwaW5nQ29udGV4dC5zbmFwTG9jYXRpb24sXHJcbiAgICAgIHNuYXBPZmZzZXQgPSBncmlkU25hcHBpbmdDb250ZXh0LnNuYXBPZmZzZXQ7XHJcblxyXG4gIC8vIGNhY2hlIHNuYXAgb2Zmc2V0XHJcbiAgaWYgKHNuYXBPZmZzZXQgJiYgaXNOdW1iZXIoc25hcE9mZnNldFsgYXhpcyBdKSkge1xyXG4gICAgcmV0dXJuIHNuYXBPZmZzZXRbIGF4aXMgXTtcclxuICB9XHJcblxyXG4gIGlmICghc25hcE9mZnNldCkge1xyXG4gICAgc25hcE9mZnNldCA9IGdyaWRTbmFwcGluZ0NvbnRleHQuc25hcE9mZnNldCA9IHt9O1xyXG4gIH1cclxuXHJcbiAgaWYgKCFpc051bWJlcihzbmFwT2Zmc2V0WyBheGlzIF0pKSB7XHJcbiAgICBzbmFwT2Zmc2V0WyBheGlzIF0gPSAwO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFzaGFwZSkge1xyXG4gICAgcmV0dXJuIHNuYXBPZmZzZXRbIGF4aXMgXTtcclxuICB9XHJcblxyXG4gIGlmICghZWxlbWVudFJlZ2lzdHJ5LmdldChzaGFwZS5pZCkpIHtcclxuXHJcbiAgICBpZiAoaXNIb3Jpem9udGFsKGF4aXMpKSB7XHJcbiAgICAgIHNuYXBPZmZzZXRbIGF4aXMgXSArPSBzaGFwZVsgYXhpcyBdICsgc2hhcGUud2lkdGggLyAyO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc25hcE9mZnNldFsgYXhpcyBdICs9IHNoYXBlWyBheGlzIF0gKyBzaGFwZS5oZWlnaHQgLyAyO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKCFzbmFwTG9jYXRpb24pIHtcclxuICAgIHJldHVybiBzbmFwT2Zmc2V0WyBheGlzIF07XHJcbiAgfVxyXG5cclxuICBpZiAoYXhpcyA9PT0gJ3gnKSB7XHJcbiAgICBpZiAoL2xlZnQvLnRlc3Qoc25hcExvY2F0aW9uKSkge1xyXG4gICAgICBzbmFwT2Zmc2V0WyBheGlzIF0gLT0gc2hhcGUud2lkdGggLyAyO1xyXG4gICAgfSBlbHNlIGlmICgvcmlnaHQvLnRlc3Qoc25hcExvY2F0aW9uKSkge1xyXG4gICAgICBzbmFwT2Zmc2V0WyBheGlzIF0gKz0gc2hhcGUud2lkdGggLyAyO1xyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICBpZiAoL3RvcC8udGVzdChzbmFwTG9jYXRpb24pKSB7XHJcbiAgICAgIHNuYXBPZmZzZXRbIGF4aXMgXSAtPSBzaGFwZS5oZWlnaHQgLyAyO1xyXG4gICAgfSBlbHNlIGlmICgvYm90dG9tLy50ZXN0KHNuYXBMb2NhdGlvbikpIHtcclxuICAgICAgc25hcE9mZnNldFsgYXhpcyBdICs9IHNoYXBlLmhlaWdodCAvIDI7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gc25hcE9mZnNldFsgYXhpcyBdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0hvcml6b250YWwoYXhpcykge1xyXG4gIHJldHVybiBheGlzID09PSAneCc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTm9ydGgoZGlyZWN0aW9uKSB7XHJcbiAgcmV0dXJuIGRpcmVjdGlvbi5pbmRleE9mKCduJykgIT09IC0xO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc1dlc3QoZGlyZWN0aW9uKSB7XHJcbiAgcmV0dXJuIGRpcmVjdGlvbi5pbmRleE9mKCd3JykgIT09IC0xO1xyXG59IiwiZXhwb3J0IHZhciBTUEFDSU5HID0gMTA7XG5cbmV4cG9ydCBmdW5jdGlvbiBxdWFudGl6ZSh2YWx1ZSwgcXVhbnR1bSwgZm4pIHtcbiAgaWYgKCFmbikge1xuICAgIGZuID0gJ3JvdW5kJztcbiAgfVxuXG4gIHJldHVybiBNYXRoWyBmbiBdKHZhbHVlIC8gcXVhbnR1bSkgKiBxdWFudHVtO1xufSIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XHJcblxyXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJy4uLy4uLy4uL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcclxuXHJcbmltcG9ydCB7XHJcbiAgYXNzaWduLFxyXG4gIGlzU3RyaW5nXHJcbn0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBJbnRlZ3JhdGVzIHJlc2l6aW5nIHdpdGggZ3JpZCBzbmFwcGluZy5cclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlc2l6ZUJlaGF2aW9yKGV2ZW50QnVzLCBncmlkU25hcHBpbmcpIHtcclxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XHJcblxyXG4gIHRoaXMuX2dyaWRTbmFwcGluZyA9IGdyaWRTbmFwcGluZztcclxuXHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICB0aGlzLnByZUV4ZWN1dGUoJ3NoYXBlLnJlc2l6ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxyXG4gICAgICAgIGF1dG9SZXNpemUgPSBoaW50cy5hdXRvUmVzaXplO1xyXG5cclxuICAgIGlmICghYXV0b1Jlc2l6ZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcclxuICAgICAgICBuZXdCb3VuZHMgPSBjb250ZXh0Lm5ld0JvdW5kcztcclxuXHJcbiAgICBpZiAoaXNTdHJpbmcoYXV0b1Jlc2l6ZSkpIHtcclxuICAgICAgY29udGV4dC5uZXdCb3VuZHMgPSBzZWxmLnNuYXBDb21wbGV4KG5ld0JvdW5kcywgYXV0b1Jlc2l6ZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0Lm5ld0JvdW5kcyA9IHNlbGYuc25hcFNpbXBsZShzaGFwZSwgbmV3Qm91bmRzKTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuUmVzaXplQmVoYXZpb3IuJGluamVjdCA9IFtcclxuICAnZXZlbnRCdXMnLFxyXG4gICdncmlkU25hcHBpbmcnLFxyXG4gICdtb2RlbGluZydcclxuXTtcclxuXHJcbmluaGVyaXRzKFJlc2l6ZUJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xyXG5cclxuLyoqXHJcbiAqIFNuYXAgd2lkdGggYW5kIGhlaWdodCBpbiByZWxhdGlvbiB0byBjZW50ZXIuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLnNoYXBlfSBzaGFwZVxyXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtCb3VuZHN9IFNuYXBwZWQgYm91bmRzLlxyXG4gKi9cclxuUmVzaXplQmVoYXZpb3IucHJvdG90eXBlLnNuYXBTaW1wbGUgPSBmdW5jdGlvbihzaGFwZSwgbmV3Qm91bmRzKSB7XHJcbiAgdmFyIGdyaWRTbmFwcGluZyA9IHRoaXMuX2dyaWRTbmFwcGluZztcclxuXHJcbiAgbmV3Qm91bmRzLndpZHRoID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShuZXdCb3VuZHMud2lkdGgsIHtcclxuICAgIG1pbjogbmV3Qm91bmRzLndpZHRoXHJcbiAgfSk7XHJcblxyXG4gIG5ld0JvdW5kcy5oZWlnaHQgPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKG5ld0JvdW5kcy5oZWlnaHQsIHtcclxuICAgIG1pbjogbmV3Qm91bmRzLmhlaWdodFxyXG4gIH0pO1xyXG5cclxuICBuZXdCb3VuZHMueCA9IHNoYXBlLnggKyAoc2hhcGUud2lkdGggLyAyKSAtIChuZXdCb3VuZHMud2lkdGggLyAyKTtcclxuICBuZXdCb3VuZHMueSA9IHNoYXBlLnkgKyAoc2hhcGUuaGVpZ2h0IC8gMikgLSAobmV3Qm91bmRzLmhlaWdodCAvIDIpO1xyXG5cclxuICByZXR1cm4gbmV3Qm91bmRzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFNuYXAgeCwgeSwgd2lkdGggYW5kIGhlaWdodCBhY2NvcmRpbmcgdG8gZ2l2ZW4gZGlyZWN0aW9ucy5cclxuICpcclxuICogQHBhcmFtIHtCb3VuZHN9IG5ld0JvdW5kc1xyXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlyZWN0aW9ucyAtIERpcmVjdGlvbnMgYXMge258d3xzfGV9LlxyXG4gKlxyXG4gKiBAcmV0dXJucyB7Qm91bmRzfSBTbmFwcGVkIGJvdW5kcy5cclxuICovXHJcblJlc2l6ZUJlaGF2aW9yLnByb3RvdHlwZS5zbmFwQ29tcGxleCA9IGZ1bmN0aW9uKG5ld0JvdW5kcywgZGlyZWN0aW9ucykge1xyXG4gIGlmICgvd3xlLy50ZXN0KGRpcmVjdGlvbnMpKSB7XHJcbiAgICBuZXdCb3VuZHMgPSB0aGlzLnNuYXBIb3Jpem9udGFsbHkobmV3Qm91bmRzLCBkaXJlY3Rpb25zKTtcclxuICB9XHJcblxyXG4gIGlmICgvbnxzLy50ZXN0KGRpcmVjdGlvbnMpKSB7XHJcbiAgICBuZXdCb3VuZHMgPSB0aGlzLnNuYXBWZXJ0aWNhbGx5KG5ld0JvdW5kcywgZGlyZWN0aW9ucyk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbmV3Qm91bmRzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFNuYXAgaW4gb25lIG9yIGJvdGggZGlyZWN0aW9ucyBob3Jpem9udGFsbHkuXHJcbiAqXHJcbiAqIEBwYXJhbSB7Qm91bmRzfSBuZXdCb3VuZHNcclxuICogQHBhcmFtIHtzdHJpbmd9IGRpcmVjdGlvbnMgLSBEaXJlY3Rpb25zIGFzIHtufHd8c3xlfS5cclxuICpcclxuICogQHJldHVybnMge0JvdW5kc30gU25hcHBlZCBib3VuZHMuXHJcbiAqL1xyXG5SZXNpemVCZWhhdmlvci5wcm90b3R5cGUuc25hcEhvcml6b250YWxseSA9IGZ1bmN0aW9uKG5ld0JvdW5kcywgZGlyZWN0aW9ucykge1xyXG4gIHZhciBncmlkU25hcHBpbmcgPSB0aGlzLl9ncmlkU25hcHBpbmcsXHJcbiAgICAgIHdlc3QgPSAvdy8udGVzdChkaXJlY3Rpb25zKSxcclxuICAgICAgZWFzdCA9IC9lLy50ZXN0KGRpcmVjdGlvbnMpO1xyXG5cclxuICB2YXIgc25hcHBlZE5ld0JvdW5kcyA9IHt9O1xyXG5cclxuICBzbmFwcGVkTmV3Qm91bmRzLndpZHRoID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShuZXdCb3VuZHMud2lkdGgsIHtcclxuICAgIG1pbjogbmV3Qm91bmRzLndpZHRoXHJcbiAgfSk7XHJcblxyXG4gIGlmIChlYXN0KSB7XHJcblxyXG4gICAgLy8gaGFuZGxlIDx3ZT5cclxuICAgIGlmICh3ZXN0KSB7XHJcbiAgICAgIHNuYXBwZWROZXdCb3VuZHMueCA9IGdyaWRTbmFwcGluZy5zbmFwVmFsdWUobmV3Qm91bmRzLngsIHtcclxuICAgICAgICBtYXg6IG5ld0JvdW5kcy54XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgc25hcHBlZE5ld0JvdW5kcy53aWR0aCArPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKG5ld0JvdW5kcy54IC0gc25hcHBlZE5ld0JvdW5kcy54LCB7XHJcbiAgICAgICAgbWluOiBuZXdCb3VuZHMueCAtIHNuYXBwZWROZXdCb3VuZHMueFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBoYW5kbGUgPGU+XHJcbiAgICBlbHNlIHtcclxuICAgICAgbmV3Qm91bmRzLnggPSBuZXdCb3VuZHMueCArIG5ld0JvdW5kcy53aWR0aCAtIHNuYXBwZWROZXdCb3VuZHMud2lkdGg7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBhc3NpZ24gc25hcHBlZCB4IGFuZCB3aWR0aFxyXG4gIGFzc2lnbihuZXdCb3VuZHMsIHNuYXBwZWROZXdCb3VuZHMpO1xyXG5cclxuICByZXR1cm4gbmV3Qm91bmRzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFNuYXAgaW4gb25lIG9yIGJvdGggZGlyZWN0aW9ucyB2ZXJ0aWNhbGx5LlxyXG4gKlxyXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXJlY3Rpb25zIC0gRGlyZWN0aW9ucyBhcyB7bnx3fHN8ZX0uXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtCb3VuZHN9IFNuYXBwZWQgYm91bmRzLlxyXG4gKi9cclxuUmVzaXplQmVoYXZpb3IucHJvdG90eXBlLnNuYXBWZXJ0aWNhbGx5ID0gZnVuY3Rpb24obmV3Qm91bmRzLCBkaXJlY3Rpb25zKSB7XHJcbiAgdmFyIGdyaWRTbmFwcGluZyA9IHRoaXMuX2dyaWRTbmFwcGluZyxcclxuICAgICAgbm9ydGggPSAvbi8udGVzdChkaXJlY3Rpb25zKSxcclxuICAgICAgc291dGggPSAvcy8udGVzdChkaXJlY3Rpb25zKTtcclxuXHJcbiAgdmFyIHNuYXBwZWROZXdCb3VuZHMgPSB7fTtcclxuXHJcbiAgc25hcHBlZE5ld0JvdW5kcy5oZWlnaHQgPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKG5ld0JvdW5kcy5oZWlnaHQsIHtcclxuICAgIG1pbjogbmV3Qm91bmRzLmhlaWdodFxyXG4gIH0pO1xyXG5cclxuICBpZiAobm9ydGgpIHtcclxuXHJcbiAgICAvLyBoYW5kbGUgPG5zPlxyXG4gICAgaWYgKHNvdXRoKSB7XHJcbiAgICAgIHNuYXBwZWROZXdCb3VuZHMueSA9IGdyaWRTbmFwcGluZy5zbmFwVmFsdWUobmV3Qm91bmRzLnksIHtcclxuICAgICAgICBtYXg6IG5ld0JvdW5kcy55XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgc25hcHBlZE5ld0JvdW5kcy5oZWlnaHQgKz0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShuZXdCb3VuZHMueSAtIHNuYXBwZWROZXdCb3VuZHMueSwge1xyXG4gICAgICAgIG1pbjogbmV3Qm91bmRzLnkgLSBzbmFwcGVkTmV3Qm91bmRzLnlcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaGFuZGxlIDxuPlxyXG4gICAgZWxzZSB7XHJcbiAgICAgIG5ld0JvdW5kcy55ID0gbmV3Qm91bmRzLnkgKyBuZXdCb3VuZHMuaGVpZ2h0IC0gc25hcHBlZE5ld0JvdW5kcy5oZWlnaHQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBhc3NpZ24gc25hcHBlZCB5IGFuZCBoZWlnaHRcclxuICBhc3NpZ24obmV3Qm91bmRzLCBzbmFwcGVkTmV3Qm91bmRzKTtcclxuXHJcbiAgcmV0dXJuIG5ld0JvdW5kcztcclxufTsiLCJ2YXIgSElHSF9QUklPUklUWSA9IDIwMDA7XHJcblxyXG4vKipcclxuICogSW50ZWdyYXRlcyBzcGFjZSB0b29sIHdpdGggZ3JpZCBzbmFwcGluZy5cclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNwYWNlVG9vbEJlaGF2aW9yKGV2ZW50QnVzLCBncmlkU25hcHBpbmcpIHtcclxuICBldmVudEJ1cy5vbihbXHJcbiAgICAnc3BhY2VUb29sLm1vdmUnLFxyXG4gICAgJ3NwYWNlVG9vbC5lbmQnXHJcbiAgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dDtcclxuXHJcbiAgICBpZiAoIWNvbnRleHQuaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBheGlzID0gY29udGV4dC5heGlzO1xyXG5cclxuICAgIHZhciBzbmFwcGVkO1xyXG5cclxuICAgIGlmIChheGlzID09PSAneCcpIHtcclxuXHJcbiAgICAgIC8vIHNuYXAgZGVsdGEgeCB0byBtdWx0aXBsZSBvZiAxMFxyXG4gICAgICBzbmFwcGVkID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShldmVudC5keCk7XHJcblxyXG4gICAgICBldmVudC54ID0gZXZlbnQueCArIHNuYXBwZWQgLSBldmVudC5keDtcclxuICAgICAgZXZlbnQuZHggPSBzbmFwcGVkO1xyXG4gICAgfSBlbHNlIHtcclxuXHJcbiAgICAgIC8vIHNuYXAgZGVsdGEgeSB0byBtdWx0aXBsZSBvZiAxMFxyXG4gICAgICBzbmFwcGVkID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShldmVudC5keSk7XHJcblxyXG4gICAgICBldmVudC55ID0gZXZlbnQueSArIHNuYXBwZWQgLSBldmVudC5keTtcclxuICAgICAgZXZlbnQuZHkgPSBzbmFwcGVkO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5TcGFjZVRvb2xCZWhhdmlvci4kaW5qZWN0ID0gW1xyXG4gICdldmVudEJ1cycsXHJcbiAgJ2dyaWRTbmFwcGluZydcclxuXTsiLCJpbXBvcnQgUmVzaXplQmVoYXZpb3IgZnJvbSAnLi9SZXNpemVCZWhhdmlvcic7XHJcbmltcG9ydCBTcGFjZVRvb2xCZWhhdmlvciBmcm9tICcuL1NwYWNlVG9vbEJlaGF2aW9yJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBfX2luaXRfXzogW1xyXG4gICAgJ2dyaWRTbmFwcGluZ1Jlc2l6ZUJlaGF2aW9yJyxcclxuICAgICdncmlkU25hcHBpbmdTcGFjZVRvb2xCZWhhdmlvcidcclxuICBdLFxyXG4gIGdyaWRTbmFwcGluZ1Jlc2l6ZUJlaGF2aW9yOiBbICd0eXBlJywgUmVzaXplQmVoYXZpb3IgXSxcclxuICBncmlkU25hcHBpbmdTcGFjZVRvb2xCZWhhdmlvcjogWyAndHlwZScsIFNwYWNlVG9vbEJlaGF2aW9yIF1cclxufTsiLCJpbXBvcnQgR3JpZFNuYXBwaW5nIGZyb20gJy4vR3JpZFNuYXBwaW5nJztcclxuXHJcbmltcG9ydCBHcmlkU25hcHBpbmdCZWhhdmlvck1vZHVsZSBmcm9tICcuL2JlaGF2aW9yJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBfX2RlcGVuZHNfXzogWyBHcmlkU25hcHBpbmdCZWhhdmlvck1vZHVsZSBdLFxyXG4gIF9faW5pdF9fOiBbICdncmlkU25hcHBpbmcnIF0sXHJcbiAgZ3JpZFNuYXBwaW5nOiBbICd0eXBlJywgR3JpZFNuYXBwaW5nIF1cclxufTsiLCJpbXBvcnQgeyBoYXNQcmltYXJ5TW9kaWZpZXIgfSBmcm9tICcuLi8uLi91dGlsL01vdXNlJztcblxuaW1wb3J0IHsgaXNLZXkgfSBmcm9tICcuLi8uLi9mZWF0dXJlcy9rZXlib2FyZC9LZXlib2FyZFV0aWwnO1xuXG52YXIgSElHSF9QUklPUklUWSA9IDE1MDA7XG52YXIgSEFORF9DVVJTT1IgPSAnZ3JhYic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gSGFuZFRvb2woZXZlbnRCdXMsIGNhbnZhcywgZHJhZ2dpbmcsIGluamVjdG9yLCB0b29sTWFuYWdlcikge1xuICB0aGlzLl9kcmFnZ2luZyA9IGRyYWdnaW5nO1xuXG4gIHZhciBzZWxmID0gdGhpcyxcbiAgICAgIGtleWJvYXJkID0gaW5qZWN0b3IuZ2V0KCdrZXlib2FyZCcsIGZhbHNlKTtcblxuICB0b29sTWFuYWdlci5yZWdpc3RlclRvb2woJ2hhbmQnLCB7XG4gICAgdG9vbDogJ2hhbmQnLFxuICAgIGRyYWdnaW5nOiAnaGFuZC5tb3ZlJ1xuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tb3VzZWRvd24nLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIGlmIChoYXNQcmltYXJ5TW9kaWZpZXIoZXZlbnQpKSB7XG4gICAgICB0aGlzLmFjdGl2YXRlTW92ZShldmVudC5vcmlnaW5hbEV2ZW50KTtcblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSwgdGhpcyk7XG5cbiAga2V5Ym9hcmQgJiYga2V5Ym9hcmQuYWRkTGlzdGVuZXIoSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZSkge1xuICAgIGlmICghaXNTcGFjZShlLmtleUV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzZWxmLmlzQWN0aXZlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhY3RpdmF0ZU1vdmUoZXZlbnQpIHtcbiAgICAgIHNlbGYuYWN0aXZhdGVNb3ZlKGV2ZW50KTtcblxuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGFjdGl2YXRlTW92ZSk7XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGFjdGl2YXRlTW92ZSk7XG5cbiAgICBmdW5jdGlvbiBkZWFjdGl2YXRlTW92ZShlKSB7XG4gICAgICBpZiAoIWlzU3BhY2UoZS5rZXlFdmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgYWN0aXZhdGVNb3ZlKTtcblxuICAgICAga2V5Ym9hcmQucmVtb3ZlTGlzdGVuZXIoZGVhY3RpdmF0ZU1vdmUsICdrZXlib2FyZC5rZXl1cCcpO1xuXG4gICAgICBkcmFnZ2luZy5jYW5jZWwoKTtcbiAgICB9XG5cbiAgICBrZXlib2FyZC5hZGRMaXN0ZW5lcihISUdIX1BSSU9SSVRZLCBkZWFjdGl2YXRlTW92ZSwgJ2tleWJvYXJkLmtleXVwJyk7XG4gIH0sICdrZXlib2FyZC5rZXlkb3duJyk7XG5cbiAgZXZlbnRCdXMub24oJ2hhbmQuZW5kJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gZXZlbnQub3JpZ2luYWxFdmVudC50YXJnZXQ7XG5cbiAgICAvLyBvbmx5IHJlYWN0aXZlIG9uIGRpYWdyYW0gY2xpY2tcbiAgICAvLyBvbiBzb21lIG9jY2FzaW9ucywgZXZlbnQuaG92ZXIgaXMgbm90IHNldCBhbmQgd2UgaGF2ZSB0byBjaGVjayBpZiB0aGUgdGFyZ2V0IGlzIGFuIHN2Z1xuICAgIGlmICghZXZlbnQuaG92ZXIgJiYgISh0YXJnZXQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGV2ZW50QnVzLm9uY2UoJ2hhbmQuZW5kZWQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuYWN0aXZhdGVNb3ZlKGV2ZW50Lm9yaWdpbmFsRXZlbnQsIHsgcmVhY3RpdmF0ZTogdHJ1ZSB9KTtcbiAgICB9LCB0aGlzKTtcblxuICB9LCB0aGlzKTtcblxuXG4gIGV2ZW50QnVzLm9uKCdoYW5kLm1vdmUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIHNjYWxlID0gY2FudmFzLnZpZXdib3goKS5zY2FsZTtcblxuICAgIGNhbnZhcy5zY3JvbGwoe1xuICAgICAgZHg6IGV2ZW50LmR4ICogc2NhbGUsXG4gICAgICBkeTogZXZlbnQuZHkgKiBzY2FsZVxuICAgIH0pO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignaGFuZC5tb3ZlLmVuZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICByZWFjdGl2YXRlID0gY29udGV4dC5yZWFjdGl2YXRlO1xuXG4gICAgLy8gRG9uJ3QgcmVhY3RpdmF0ZSBpZiB0aGUgdXNlciBpcyB1c2luZyB0aGUga2V5Ym9hcmQga2V5YmluZGluZ1xuICAgIGlmICghaGFzUHJpbWFyeU1vZGlmaWVyKGV2ZW50KSAmJiByZWFjdGl2YXRlKSB7XG5cbiAgICAgIGV2ZW50QnVzLm9uY2UoJ2hhbmQubW92ZS5lbmRlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuYWN0aXZhdGVIYW5kKGV2ZW50Lm9yaWdpbmFsRXZlbnQsIHRydWUsIHRydWUpO1xuICAgICAgfSwgdGhpcyk7XG5cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sIHRoaXMpO1xuXG59XG5cbkhhbmRUb29sLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnLFxuICAnZHJhZ2dpbmcnLFxuICAnaW5qZWN0b3InLFxuICAndG9vbE1hbmFnZXInXG5dO1xuXG5cbkhhbmRUb29sLnByb3RvdHlwZS5hY3RpdmF0ZU1vdmUgPSBmdW5jdGlvbihldmVudCwgYXV0b0FjdGl2YXRlLCBjb250ZXh0KSB7XG4gIGlmICh0eXBlb2YgYXV0b0FjdGl2YXRlID09PSAnb2JqZWN0Jykge1xuICAgIGNvbnRleHQgPSBhdXRvQWN0aXZhdGU7XG4gICAgYXV0b0FjdGl2YXRlID0gZmFsc2U7XG4gIH1cblxuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnaGFuZC5tb3ZlJywge1xuICAgIGF1dG9BY3RpdmF0ZTogYXV0b0FjdGl2YXRlLFxuICAgIGN1cnNvcjogSEFORF9DVVJTT1IsXG4gICAgZGF0YToge1xuICAgICAgY29udGV4dDogY29udGV4dCB8fCB7fVxuICAgIH1cbiAgfSk7XG59O1xuXG5IYW5kVG9vbC5wcm90b3R5cGUuYWN0aXZhdGVIYW5kID0gZnVuY3Rpb24oZXZlbnQsIGF1dG9BY3RpdmF0ZSwgcmVhY3RpdmF0ZSkge1xuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnaGFuZCcsIHtcbiAgICB0cmFwQ2xpY2s6IGZhbHNlLFxuICAgIGF1dG9BY3RpdmF0ZTogYXV0b0FjdGl2YXRlLFxuICAgIGN1cnNvcjogSEFORF9DVVJTT1IsXG4gICAgZGF0YToge1xuICAgICAgY29udGV4dDoge1xuICAgICAgICByZWFjdGl2YXRlOiByZWFjdGl2YXRlXG4gICAgICB9XG4gICAgfVxuICB9KTtcbn07XG5cbkhhbmRUb29sLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuaXNBY3RpdmUoKSkge1xuICAgIHRoaXMuX2RyYWdnaW5nLmNhbmNlbCgpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuYWN0aXZhdGVIYW5kKCk7XG4gIH1cbn07XG5cbkhhbmRUb29sLnByb3RvdHlwZS5pc0FjdGl2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29udGV4dCA9IHRoaXMuX2RyYWdnaW5nLmNvbnRleHQoKTtcblxuICBpZiAoY29udGV4dCkge1xuICAgIHJldHVybiAvXihoYW5kfGhhbmRcXC5tb3ZlKSQvLnRlc3QoY29udGV4dC5wcmVmaXgpO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGlzU3BhY2Uoa2V5RXZlbnQpIHtcbiAgcmV0dXJuIGlzS2V5KCcgJywga2V5RXZlbnQpO1xufSIsImltcG9ydCBUb29sTWFuYWdlck1vZHVsZSBmcm9tICcuLi90b29sLW1hbmFnZXInO1xuXG5pbXBvcnQgSGFuZFRvb2wgZnJvbSAnLi9IYW5kVG9vbCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBUb29sTWFuYWdlck1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogWyAnaGFuZFRvb2wnIF0sXG4gIGhhbmRUb29sOiBbICd0eXBlJywgSGFuZFRvb2wgXVxufTtcbiIsImltcG9ydCB7XG4gIGZvckVhY2gsXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgcXVlcnlBbGwgYXMgZG9tUXVlcnlBbGxcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7IGlzUHJpbWFyeUJ1dHRvbiB9IGZyb20gJy4uLy4uL3V0aWwvTW91c2UnO1xuXG5pbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVMaW5lLFxuICB1cGRhdGVMaW5lXG59IGZyb20gJy4uLy4uL3V0aWwvUmVuZGVyVXRpbCc7XG5cbmZ1bmN0aW9uIGFsbG93QWxsKGUpIHsgcmV0dXJuIHRydWU7IH1cblxudmFyIExPV19QUklPUklUWSA9IDUwMDtcblxuXG4vKipcbiAqIEEgcGx1Z2luIHRoYXQgcHJvdmlkZXMgaW50ZXJhY3Rpb24gZXZlbnRzIGZvciBkaWFncmFtIGVsZW1lbnRzLlxuICpcbiAqIEl0IGVtaXRzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICpcbiAqICAgKiBlbGVtZW50LmNsaWNrXG4gKiAgICogZWxlbWVudC5jb250ZXh0bWVudVxuICogICAqIGVsZW1lbnQuZGJsY2xpY2tcbiAqICAgKiBlbGVtZW50LmhvdmVyXG4gKiAgICogZWxlbWVudC5tb3VzZWRvd25cbiAqICAgKiBlbGVtZW50Lm1vdXNlbW92ZVxuICogICAqIGVsZW1lbnQubW91c2V1cFxuICogICAqIGVsZW1lbnQub3V0XG4gKlxuICogRWFjaCBldmVudCBpcyBhIHR1cGxlIHsgZWxlbWVudCwgZ2Z4LCBvcmlnaW5hbEV2ZW50IH0uXG4gKlxuICogQ2FuY2VsaW5nIHRoZSBldmVudCB2aWEgRXZlbnQjcHJldmVudERlZmF1bHQoKVxuICogcHJldmVudHMgdGhlIG9yaWdpbmFsIERPTSBvcGVyYXRpb24uXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gSW50ZXJhY3Rpb25FdmVudHMoZXZlbnRCdXMsIGVsZW1lbnRSZWdpc3RyeSwgc3R5bGVzKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8qKlxuICAgKiBGaXJlIGFuIGludGVyYWN0aW9uIGV2ZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBsb2NhbCBldmVudCBuYW1lLCBlLmcuIGVsZW1lbnQuY2xpY2suXG4gICAqIEBwYXJhbSB7RE9NRXZlbnR9IGV2ZW50IG5hdGl2ZSBldmVudFxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBbZWxlbWVudF0gdGhlIGRpYWdyYW0gZWxlbWVudCB0byBlbWl0IHRoZSBldmVudCBvbjtcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzIHRvIHRoZSBldmVudCB0YXJnZXRcbiAgICovXG4gIGZ1bmN0aW9uIGZpcmUodHlwZSwgZXZlbnQsIGVsZW1lbnQpIHtcblxuICAgIGlmIChpc0lnbm9yZWQodHlwZSwgZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRhcmdldCwgZ2Z4LCByZXR1cm5WYWx1ZTtcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgdGFyZ2V0ID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQgfHwgZXZlbnQudGFyZ2V0O1xuXG4gICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgIGdmeCA9IHRhcmdldDtcbiAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZ2Z4ID0gZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGlmICghZ2Z4IHx8ICFlbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuVmFsdWUgPSBldmVudEJ1cy5maXJlKHR5cGUsIHtcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBnZng6IGdmeCxcbiAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2ZW50XG4gICAgfSk7XG5cbiAgICBpZiAocmV0dXJuVmFsdWUgPT09IGZhbHNlKSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVE9ETyhuaWtrdSk6IGRvY3VtZW50IHRoaXNcbiAgdmFyIGhhbmRsZXJzID0ge307XG5cbiAgZnVuY3Rpb24gbW91c2VIYW5kbGVyKGxvY2FsRXZlbnROYW1lKSB7XG4gICAgcmV0dXJuIGhhbmRsZXJzW2xvY2FsRXZlbnROYW1lXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSWdub3JlZChsb2NhbEV2ZW50TmFtZSwgZXZlbnQpIHtcblxuICAgIHZhciBmaWx0ZXIgPSBpZ25vcmVkRmlsdGVyc1tsb2NhbEV2ZW50TmFtZV0gfHwgaXNQcmltYXJ5QnV0dG9uO1xuXG4gICAgLy8gb25seSByZWFjdCBvbiBsZWZ0IG1vdXNlIGJ1dHRvbiBpbnRlcmFjdGlvbnNcbiAgICAvLyBleGNlcHQgZm9yIGludGVyYWN0aW9uIGV2ZW50cyB0aGF0IGFyZSBlbmFibGVkXG4gICAgLy8gZm9yIHNlY3VuZGFyeSBtb3VzZSBidXR0b25cbiAgICByZXR1cm4gIWZpbHRlcihldmVudCk7XG4gIH1cblxuICB2YXIgYmluZGluZ3MgPSB7XG4gICAgY2xpY2s6ICdlbGVtZW50LmNsaWNrJyxcbiAgICBjb250ZXh0bWVudTogJ2VsZW1lbnQuY29udGV4dG1lbnUnLFxuICAgIGRibGNsaWNrOiAnZWxlbWVudC5kYmxjbGljaycsXG4gICAgbW91c2Vkb3duOiAnZWxlbWVudC5tb3VzZWRvd24nLFxuICAgIG1vdXNlbW92ZTogJ2VsZW1lbnQubW91c2Vtb3ZlJyxcbiAgICBtb3VzZW92ZXI6ICdlbGVtZW50LmhvdmVyJyxcbiAgICBtb3VzZW91dDogJ2VsZW1lbnQub3V0JyxcbiAgICBtb3VzZXVwOiAnZWxlbWVudC5tb3VzZXVwJyxcbiAgfTtcblxuICB2YXIgaWdub3JlZEZpbHRlcnMgPSB7XG4gICAgJ2VsZW1lbnQuY29udGV4dG1lbnUnOiBhbGxvd0FsbFxuICB9O1xuXG5cbiAgLy8gbWFudWFsIGV2ZW50IHRyaWdnZXIgLy8vLy8vLy8vL1xuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIGFuIGludGVyYWN0aW9uIGV2ZW50IChiYXNlZCBvbiBhIG5hdGl2ZSBkb20gZXZlbnQpXG4gICAqIG9uIHRoZSB0YXJnZXQgc2hhcGUgb3IgY29ubmVjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSB0aGUgbmFtZSBvZiB0aGUgdHJpZ2dlcmVkIERPTSBldmVudFxuICAgKiBAcGFyYW0ge01vdXNlRXZlbnR9IGV2ZW50XG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IHRhcmdldEVsZW1lbnRcbiAgICovXG4gIGZ1bmN0aW9uIHRyaWdnZXJNb3VzZUV2ZW50KGV2ZW50TmFtZSwgZXZlbnQsIHRhcmdldEVsZW1lbnQpIHtcblxuICAgIC8vIGkuZS4gZWxlbWVudC5tb3VzZWRvd24uLi5cbiAgICB2YXIgbG9jYWxFdmVudE5hbWUgPSBiaW5kaW5nc1tldmVudE5hbWVdO1xuXG4gICAgaWYgKCFsb2NhbEV2ZW50TmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bm1hcHBlZCBET00gZXZlbnQgbmFtZSA8JyArIGV2ZW50TmFtZSArICc+Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpcmUobG9jYWxFdmVudE5hbWUsIGV2ZW50LCB0YXJnZXRFbGVtZW50KTtcbiAgfVxuXG5cbiAgdmFyIEVMRU1FTlRfU0VMRUNUT1IgPSAnc3ZnLCAuZGpzLWVsZW1lbnQnO1xuXG4gIC8vIGV2ZW50IGhhbmRsaW5nIC8vLy8vLy9cblxuICBmdW5jdGlvbiByZWdpc3RlckV2ZW50KG5vZGUsIGV2ZW50LCBsb2NhbEV2ZW50LCBpZ25vcmVkRmlsdGVyKSB7XG5cbiAgICB2YXIgaGFuZGxlciA9IGhhbmRsZXJzW2xvY2FsRXZlbnRdID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIGZpcmUobG9jYWxFdmVudCwgZXZlbnQpO1xuICAgIH07XG5cbiAgICBpZiAoaWdub3JlZEZpbHRlcikge1xuICAgICAgaWdub3JlZEZpbHRlcnNbbG9jYWxFdmVudF0gPSBpZ25vcmVkRmlsdGVyO1xuICAgIH1cblxuICAgIGhhbmRsZXIuJGRlbGVnYXRlID0gZG9tRGVsZWdhdGUuYmluZChub2RlLCBFTEVNRU5UX1NFTEVDVE9SLCBldmVudCwgaGFuZGxlcik7XG4gIH1cblxuICBmdW5jdGlvbiB1bnJlZ2lzdGVyRXZlbnQobm9kZSwgZXZlbnQsIGxvY2FsRXZlbnQpIHtcblxuICAgIHZhciBoYW5kbGVyID0gbW91c2VIYW5kbGVyKGxvY2FsRXZlbnQpO1xuXG4gICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZG9tRGVsZWdhdGUudW5iaW5kKG5vZGUsIGV2ZW50LCBoYW5kbGVyLiRkZWxlZ2F0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiByZWdpc3RlckV2ZW50cyhzdmcpIHtcbiAgICBmb3JFYWNoKGJpbmRpbmdzLCBmdW5jdGlvbih2YWwsIGtleSkge1xuICAgICAgcmVnaXN0ZXJFdmVudChzdmcsIGtleSwgdmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVucmVnaXN0ZXJFdmVudHMoc3ZnKSB7XG4gICAgZm9yRWFjaChiaW5kaW5ncywgZnVuY3Rpb24odmFsLCBrZXkpIHtcbiAgICAgIHVucmVnaXN0ZXJFdmVudChzdmcsIGtleSwgdmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuZGVzdHJveScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdW5yZWdpc3RlckV2ZW50cyhldmVudC5zdmcpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY2FudmFzLmluaXQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHJlZ2lzdGVyRXZlbnRzKGV2ZW50LnN2Zyk7XG4gIH0pO1xuXG5cbiAgLy8gaGl0IGJveCB1cGRhdGluZyAvLy8vLy8vLy8vLy8vLy8vXG5cbiAgZXZlbnRCdXMub24oWyAnc2hhcGUuYWRkZWQnLCAnY29ubmVjdGlvbi5hZGRlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUhpdCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH0pO1xuXG4gIC8vIFVwZGF0ZSBkanMtaGl0IG9uIGNoYW5nZS5cbiAgLy8gQSBsb3cgcHJpb3J0aXR5IGlzIG5lY2Vzc2FyeSwgYmVjYXVzZSBkanMtaGl0IG9mIGxhYmVscyBoYXMgdG8gYmUgdXBkYXRlZFxuICAvLyBhZnRlciB0aGUgbGFiZWwgYm91bmRzIGhhdmUgYmVlbiB1cGRhdGVkIGluIHRoZSByZW5kZXJlci5cbiAgZXZlbnRCdXMub24oW1xuICAgICdzaGFwZS5jaGFuZ2VkJyxcbiAgICAnY29ubmVjdGlvbi5jaGFuZ2VkJ1xuICBdLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdpbnRlcmFjdGlvbkV2ZW50cy5jcmVhdGVIaXQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICBzZWxmLmNyZWF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICBzZWxmLnVwZGF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgfSk7XG5cblxuICAvLyBoaXQgc3R5bGVzIC8vLy8vLy8vLy8vL1xuXG4gIHZhciBTVFJPS0VfSElUX1NUWUxFID0gY3JlYXRlSGl0U3R5bGUoJ2Rqcy1oaXQgZGpzLWhpdC1zdHJva2UnKTtcblxuICB2YXIgQ0xJQ0tfU1RST0tFX0hJVF9TVFlMRSA9IGNyZWF0ZUhpdFN0eWxlKCdkanMtaGl0IGRqcy1oaXQtY2xpY2stc3Ryb2tlJyk7XG5cbiAgdmFyIEFMTF9ISVRfU1RZTEUgPSBjcmVhdGVIaXRTdHlsZSgnZGpzLWhpdCBkanMtaGl0LWFsbCcpO1xuXG4gIHZhciBISVRfVFlQRVMgPSB7XG4gICAgJ2FsbCc6IEFMTF9ISVRfU1RZTEUsXG4gICAgJ2NsaWNrLXN0cm9rZSc6IENMSUNLX1NUUk9LRV9ISVRfU1RZTEUsXG4gICAgJ3N0cm9rZSc6IFNUUk9LRV9ISVRfU1RZTEVcbiAgfTtcblxuICBmdW5jdGlvbiBjcmVhdGVIaXRTdHlsZShjbGFzc05hbWVzLCBhdHRycykge1xuXG4gICAgYXR0cnMgPSBhc3NpZ24oe1xuICAgICAgc3Ryb2tlOiAnd2hpdGUnLFxuICAgICAgc3Ryb2tlV2lkdGg6IDE1XG4gICAgfSwgYXR0cnMgfHwge30pO1xuXG4gICAgcmV0dXJuIHN0eWxlcy5jbHMoY2xhc3NOYW1lcywgWyAnbm8tZmlsbCcsICduby1ib3JkZXInIF0sIGF0dHJzKTtcbiAgfVxuXG5cbiAgLy8gc3R5bGUgaGVscGVycyAvLy8vLy8vLy8vLy8vLy9cblxuICBmdW5jdGlvbiBhcHBseVN0eWxlKGhpdCwgdHlwZSkge1xuXG4gICAgdmFyIGF0dHJzID0gSElUX1RZUEVTW3R5cGVdO1xuXG4gICAgaWYgKCFhdHRycykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGhpdCB0eXBlIDwnICsgdHlwZSArICc+Jyk7XG4gICAgfVxuXG4gICAgc3ZnQXR0cihoaXQsIGF0dHJzKTtcblxuICAgIHJldHVybiBoaXQ7XG4gIH1cblxuICBmdW5jdGlvbiBhcHBlbmRIaXQoZ2Z4LCBoaXQpIHtcbiAgICBzdmdBcHBlbmQoZ2Z4LCBoaXQpO1xuICB9XG5cblxuICAvLyBBUElcblxuICAvKipcbiAgICogUmVtb3ZlIGhpbnRzIG9uIHRoZSBnaXZlbiBncmFwaGljcy5cbiAgICpcbiAgICogQHBhcmFtIHtTVkdFbGVtZW50fSBnZnhcbiAgICovXG4gIHRoaXMucmVtb3ZlSGl0cyA9IGZ1bmN0aW9uKGdmeCkge1xuICAgIHZhciBoaXRzID0gZG9tUXVlcnlBbGwoJy5kanMtaGl0JywgZ2Z4KTtcblxuICAgIGZvckVhY2goaGl0cywgc3ZnUmVtb3ZlKTtcbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGRlZmF1bHQgaGl0IGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGdmeFxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSBjcmVhdGVkIGhpdFxuICAgKi9cbiAgdGhpcy5jcmVhdGVEZWZhdWx0SGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG4gICAgdmFyIHdheXBvaW50cyA9IGVsZW1lbnQud2F5cG9pbnRzLFxuICAgICAgICBpc0ZyYW1lID0gZWxlbWVudC5pc0ZyYW1lLFxuICAgICAgICBib3hUeXBlO1xuXG4gICAgaWYgKHdheXBvaW50cykge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlV2F5cG9pbnRzSGl0KGdmeCwgd2F5cG9pbnRzKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICBib3hUeXBlID0gaXNGcmFtZSA/ICdzdHJva2UnIDogJ2FsbCc7XG5cbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUJveEhpdChnZngsIGJveFR5cGUsIHtcbiAgICAgICAgd2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGhlaWdodDogZWxlbWVudC5oZWlnaHRcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGhpdHMgZm9yIHRoZSBnaXZlbiB3YXlwb2ludHMuXG4gICAqXG4gICAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ2Z4XG4gICAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAgICpcbiAgICogQHJldHVybiB7U1ZHRWxlbWVudH1cbiAgICovXG4gIHRoaXMuY3JlYXRlV2F5cG9pbnRzSGl0ID0gZnVuY3Rpb24oZ2Z4LCB3YXlwb2ludHMpIHtcblxuICAgIHZhciBoaXQgPSBjcmVhdGVMaW5lKHdheXBvaW50cyk7XG5cbiAgICBhcHBseVN0eWxlKGhpdCwgJ3N0cm9rZScpO1xuXG4gICAgYXBwZW5kSGl0KGdmeCwgaGl0KTtcblxuICAgIHJldHVybiBoaXQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBoaXRzIGZvciBhIGJveC5cbiAgICpcbiAgICogQHBhcmFtIHtTVkdFbGVtZW50fSBnZnhcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhpdFR5cGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGF0dHJzXG4gICAqXG4gICAqIEByZXR1cm4ge1NWR0VsZW1lbnR9XG4gICAqL1xuICB0aGlzLmNyZWF0ZUJveEhpdCA9IGZ1bmN0aW9uKGdmeCwgdHlwZSwgYXR0cnMpIHtcblxuICAgIGF0dHJzID0gYXNzaWduKHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwXG4gICAgfSwgYXR0cnMpO1xuXG4gICAgdmFyIGhpdCA9IHN2Z0NyZWF0ZSgncmVjdCcpO1xuXG4gICAgYXBwbHlTdHlsZShoaXQsIHR5cGUpO1xuXG4gICAgc3ZnQXR0cihoaXQsIGF0dHJzKTtcblxuICAgIGFwcGVuZEhpdChnZngsIGhpdCk7XG5cbiAgICByZXR1cm4gaGl0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgZGVmYXVsdCBoaXQgb2YgdGhlIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gICAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IGdmeFxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSB1cGRhdGVkIGhpdFxuICAgKi9cbiAgdGhpcy51cGRhdGVEZWZhdWx0SGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG5cbiAgICB2YXIgaGl0ID0gZG9tUXVlcnkoJy5kanMtaGl0JywgZ2Z4KTtcblxuICAgIGlmICghaGl0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICB1cGRhdGVMaW5lKGhpdCwgZWxlbWVudC53YXlwb2ludHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdmdBdHRyKGhpdCwge1xuICAgICAgICB3aWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhpdDtcbiAgfTtcblxuICB0aGlzLmZpcmUgPSBmaXJlO1xuXG4gIHRoaXMudHJpZ2dlck1vdXNlRXZlbnQgPSB0cmlnZ2VyTW91c2VFdmVudDtcblxuICB0aGlzLm1vdXNlSGFuZGxlciA9IG1vdXNlSGFuZGxlcjtcblxuICB0aGlzLnJlZ2lzdGVyRXZlbnQgPSByZWdpc3RlckV2ZW50O1xuICB0aGlzLnVucmVnaXN0ZXJFdmVudCA9IHVucmVnaXN0ZXJFdmVudDtcbn1cblxuXG5JbnRlcmFjdGlvbkV2ZW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ3N0eWxlcydcbl07XG5cblxuLyoqXG4gKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vdXNlIGhvdmVyZWQgb3ZlciBhbiBlbGVtZW50XG4gKlxuICogQGV2ZW50IGVsZW1lbnQuaG92ZXJcbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSBnZnhcbiAqIEBwcm9wZXJ0eSB7RXZlbnR9IG9yaWdpbmFsRXZlbnRcbiAqL1xuXG4vKipcbiAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgbW91c2UgaGFzIGxlZnQgYW4gZWxlbWVudFxuICpcbiAqIEBldmVudCBlbGVtZW50Lm91dFxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBtb3VzZSBoYXMgY2xpY2tlZCBhbiBlbGVtZW50XG4gKlxuICogQGV2ZW50IGVsZW1lbnQuY2xpY2tcbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSBnZnhcbiAqIEBwcm9wZXJ0eSB7RXZlbnR9IG9yaWdpbmFsRXZlbnRcbiAqL1xuXG4vKipcbiAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgbW91c2UgaGFzIGRvdWJsZSBjbGlja2VkIGFuIGVsZW1lbnRcbiAqXG4gKiBAZXZlbnQgZWxlbWVudC5kYmxjbGlja1xuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBtb3VzZSBoYXMgZ29uZSBkb3duIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogQGV2ZW50IGVsZW1lbnQubW91c2Vkb3duXG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gZ2Z4XG4gKiBAcHJvcGVydHkge0V2ZW50fSBvcmlnaW5hbEV2ZW50XG4gKi9cblxuLyoqXG4gKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vdXNlIGhhcyBnb25lIHVwIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogQGV2ZW50IGVsZW1lbnQubW91c2V1cFxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBjb250ZXh0IG1lbnUgYWN0aW9uIGlzIHRyaWdnZXJlZFxuICogdmlhIG1vdXNlIG9yIHRvdWNoIGNvbnRyb2xzLlxuICpcbiAqIEBldmVudCBlbGVtZW50LmNvbnRleHRtZW51XG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gZ2Z4XG4gKiBAcHJvcGVydHkge0V2ZW50fSBvcmlnaW5hbEV2ZW50XG4gKi8iLCJpbXBvcnQgSW50ZXJhY3Rpb25FdmVudHMgZnJvbSAnLi9JbnRlcmFjdGlvbkV2ZW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2ludGVyYWN0aW9uRXZlbnRzJyBdLFxuICBpbnRlcmFjdGlvbkV2ZW50czogWyAndHlwZScsIEludGVyYWN0aW9uRXZlbnRzIF1cbn07IiwiaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG52YXIgREVGQVVMVF9DT05GSUcgPSB7XG4gIG1vdmVTcGVlZDogMSxcbiAgbW92ZVNwZWVkQWNjZWxlcmF0ZWQ6IDEwXG59O1xuXG52YXIgSElHSEVSX1BSSU9SSVRZID0gMTUwMDtcblxudmFyIExFRlQgPSAnbGVmdCc7XG52YXIgVVAgPSAndXAnO1xudmFyIFJJR0hUID0gJ3JpZ2h0JztcbnZhciBET1dOID0gJ2Rvd24nO1xuXG52YXIgS0VZX1RPX0RJUkVDVElPTiA9IHtcbiAgQXJyb3dMZWZ0OiBMRUZULFxuICBMZWZ0OiBMRUZULFxuICBBcnJvd1VwOiBVUCxcbiAgVXA6IFVQLFxuICBBcnJvd1JpZ2h0OiBSSUdIVCxcbiAgUmlnaHQ6IFJJR0hULFxuICBBcnJvd0Rvd246IERPV04sXG4gIERvd246IERPV05cbn07XG5cbnZhciBESVJFQ1RJT05TX0RFTFRBID0ge1xuICBsZWZ0OiBmdW5jdGlvbihzcGVlZCkge1xuICAgIHJldHVybiB7XG4gICAgICB4OiAtc3BlZWQsXG4gICAgICB5OiAwXG4gICAgfTtcbiAgfSxcbiAgdXA6IGZ1bmN0aW9uKHNwZWVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAtc3BlZWRcbiAgICB9O1xuICB9LFxuICByaWdodDogZnVuY3Rpb24oc3BlZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogc3BlZWQsXG4gICAgICB5OiAwXG4gICAgfTtcbiAgfSxcbiAgZG93bjogZnVuY3Rpb24oc3BlZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IHNwZWVkXG4gICAgfTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEVuYWJsZXMgdG8gbW92ZSBzZWxlY3Rpb24gd2l0aCBrZXlib2FyZCBhcnJvd3MuXG4gKiBVc2Ugd2l0aCBTaGlmdCBmb3IgbW9kaWZpZWQgc3BlZWQgKGRlZmF1bHQ9MSwgd2l0aCBTaGlmdD0xMCkuXG4gKiBQcmVzc2VkIENtZC9DdHJsIHR1cm5zIHRoZSBmZWF0dXJlIG9mZi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmZpZy5tb3ZlU3BlZWQ9MV1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbY29uZmlnLm1vdmVTcGVlZEFjY2VsZXJhdGVkPTEwXVxuICogQHBhcmFtIHtLZXlib2FyZH0ga2V5Ym9hcmRcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKiBAcGFyYW0ge1NlbGVjdGlvbn0gc2VsZWN0aW9uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEtleWJvYXJkTW92ZVNlbGVjdGlvbihcbiAgICBjb25maWcsXG4gICAga2V5Ym9hcmQsXG4gICAgbW9kZWxpbmcsXG4gICAgcnVsZXMsXG4gICAgc2VsZWN0aW9uXG4pIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5fY29uZmlnID0gYXNzaWduKHt9LCBERUZBVUxUX0NPTkZJRywgY29uZmlnIHx8IHt9KTtcblxuICBrZXlib2FyZC5hZGRMaXN0ZW5lcihISUdIRVJfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIga2V5RXZlbnQgPSBldmVudC5rZXlFdmVudDtcblxuICAgIHZhciBkaXJlY3Rpb24gPSBLRVlfVE9fRElSRUNUSU9OW2tleUV2ZW50LmtleV07XG5cbiAgICBpZiAoIWRpcmVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChrZXlib2FyZC5pc0NtZChrZXlFdmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgYWNjZWxlcmF0ZWQgPSBrZXlib2FyZC5pc1NoaWZ0KGtleUV2ZW50KTtcblxuICAgIHNlbGYubW92ZVNlbGVjdGlvbihkaXJlY3Rpb24sIGFjY2VsZXJhdGVkKTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcblxuXG4gIC8qKlxuICAgKiBNb3ZlIHNlbGVjdGVkIGVsZW1lbnRzIGluIHRoZSBnaXZlbiBkaXJlY3Rpb24sXG4gICAqIG9wdGlvbmFsbHkgc3BlY2lmeWluZyBhY2NlbGVyYXRlZCBtb3ZlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGRpcmVjdGlvblxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthY2NlbGVyYXRlZD1mYWxzZV1cbiAgICovXG4gIHRoaXMubW92ZVNlbGVjdGlvbiA9IGZ1bmN0aW9uKGRpcmVjdGlvbiwgYWNjZWxlcmF0ZWQpIHtcblxuICAgIHZhciBzZWxlY3RlZEVsZW1lbnRzID0gc2VsZWN0aW9uLmdldCgpO1xuXG4gICAgaWYgKCFzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBzcGVlZCA9IHRoaXMuX2NvbmZpZ1tcbiAgICAgIGFjY2VsZXJhdGVkID9cbiAgICAgICAgJ21vdmVTcGVlZEFjY2VsZXJhdGVkJyA6XG4gICAgICAgICdtb3ZlU3BlZWQnXG4gICAgXTtcblxuICAgIHZhciBkZWx0YSA9IERJUkVDVElPTlNfREVMVEFbZGlyZWN0aW9uXShzcGVlZCk7XG5cbiAgICB2YXIgY2FuTW92ZSA9IHJ1bGVzLmFsbG93ZWQoJ2VsZW1lbnRzLm1vdmUnLCB7XG4gICAgICBzaGFwZXM6IHNlbGVjdGVkRWxlbWVudHNcbiAgICB9KTtcblxuICAgIGlmIChjYW5Nb3ZlKSB7XG4gICAgICBtb2RlbGluZy5tb3ZlRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cywgZGVsdGEpO1xuICAgIH1cbiAgfTtcblxufVxuXG5LZXlib2FyZE1vdmVTZWxlY3Rpb24uJGluamVjdCA9IFtcbiAgJ2NvbmZpZy5rZXlib2FyZE1vdmVTZWxlY3Rpb24nLFxuICAna2V5Ym9hcmQnLFxuICAnbW9kZWxpbmcnLFxuICAncnVsZXMnLFxuICAnc2VsZWN0aW9uJ1xuXTsiLCJpbXBvcnQgS2V5Ym9hcmRNb2R1bGUgZnJvbSAnLi4va2V5Ym9hcmQnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuXG5pbXBvcnQgS2V5Ym9hcmRNb3ZlU2VsZWN0aW9uIGZyb20gJy4vS2V5Ym9hcmRNb3ZlU2VsZWN0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIEtleWJvYXJkTW9kdWxlLFxuICAgIFNlbGVjdGlvbk1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogW1xuICAgICdrZXlib2FyZE1vdmVTZWxlY3Rpb24nXG4gIF0sXG4gIGtleWJvYXJkTW92ZVNlbGVjdGlvbjogWyAndHlwZScsIEtleWJvYXJkTW92ZVNlbGVjdGlvbiBdXG59O1xuIiwiaW1wb3J0IHtcbiAgaXNGdW5jdGlvblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50LFxuICBtYXRjaGVzIGFzIGRvbU1hdGNoZXNcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIGhhc01vZGlmaWVyLFxuICBpc0NtZCxcbiAgaXNLZXksXG4gIGlzU2hpZnRcbn0gZnJvbSAnLi9LZXlib2FyZFV0aWwnO1xuXG52YXIgS0VZRE9XTl9FVkVOVCA9ICdrZXlib2FyZC5rZXlkb3duJyxcbiAgICBLRVlVUF9FVkVOVCA9ICdrZXlib2FyZC5rZXl1cCc7XG5cbnZhciBERUZBVUxUX1BSSU9SSVRZID0gMTAwMDtcblxuXG4vKipcbiAqIEEga2V5Ym9hcmQgYWJzdHJhY3Rpb24gdGhhdCBtYXkgYmUgYWN0aXZhdGVkIGFuZFxuICogZGVhY3RpdmF0ZWQgYnkgdXNlcnMgYXQgd2lsbCwgY29uc3VtaW5nIGtleSBldmVudHNcbiAqIGFuZCB0cmlnZ2VyaW5nIGRpYWdyYW0gYWN0aW9ucy5cbiAqXG4gKiBGb3Iga2V5cyBwcmVzc2VkIGRvd24sIGtleWJvYXJkIGZpcmVzIGBrZXlib2FyZC5rZXlkb3duYCBldmVudC5cbiAqIFRoZSBldmVudCBjb250ZXh0IGNvbnRhaW5zIG9uZSBmaWVsZCB3aGljaCBpcyBgS2V5Ym9hcmRFdmVudGAgZXZlbnQuXG4gKlxuICogVGhlIGltcGxlbWVudGF0aW9uIGZpcmVzIHRoZSBmb2xsb3dpbmcga2V5IGV2ZW50cyB0aGF0IGFsbG93XG4gKiBvdGhlciBjb21wb25lbnRzIHRvIGhvb2sgaW50byBrZXkgaGFuZGxpbmc6XG4gKlxuICogIC0ga2V5Ym9hcmQuYmluZFxuICogIC0ga2V5Ym9hcmQudW5iaW5kXG4gKiAgLSBrZXlib2FyZC5pbml0XG4gKiAgLSBrZXlib2FyZC5kZXN0cm95XG4gKlxuICogQWxsIGV2ZW50cyBjb250YWluIG9uZSBmaWVsZCB3aGljaCBpcyBub2RlLlxuICpcbiAqIEEgZGVmYXVsdCBiaW5kaW5nIGZvciB0aGUga2V5Ym9hcmQgbWF5IGJlIHNwZWNpZmllZCB2aWEgdGhlXG4gKiBga2V5Ym9hcmQuYmluZFRvYCBjb25maWd1cmF0aW9uIG9wdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0NvbmZpZ30gY29uZmlnXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBLZXlib2FyZChjb25maWcsIGV2ZW50QnVzKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9jb25maWcgPSBjb25maWcgfHwge307XG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG5cbiAgdGhpcy5fa2V5ZG93bkhhbmRsZXIgPSB0aGlzLl9rZXlkb3duSGFuZGxlci5iaW5kKHRoaXMpO1xuICB0aGlzLl9rZXl1cEhhbmRsZXIgPSB0aGlzLl9rZXl1cEhhbmRsZXIuYmluZCh0aGlzKTtcblxuICAvLyBwcm9wZXJseSBjbGVhbiBkb20gcmVnaXN0cmF0aW9uc1xuICBldmVudEJ1cy5vbignZGlhZ3JhbS5kZXN0cm95JywgZnVuY3Rpb24oKSB7XG4gICAgc2VsZi5fZmlyZSgnZGVzdHJveScpO1xuXG4gICAgc2VsZi51bmJpbmQoKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2RpYWdyYW0uaW5pdCcsIGZ1bmN0aW9uKCkge1xuICAgIHNlbGYuX2ZpcmUoJ2luaXQnKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2F0dGFjaCcsIGZ1bmN0aW9uKCkge1xuICAgIGlmIChjb25maWcgJiYgY29uZmlnLmJpbmRUbykge1xuICAgICAgc2VsZi5iaW5kKGNvbmZpZy5iaW5kVG8pO1xuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2RldGFjaCcsIGZ1bmN0aW9uKCkge1xuICAgIHNlbGYudW5iaW5kKCk7XG4gIH0pO1xufVxuXG5LZXlib2FyZC4kaW5qZWN0ID0gW1xuICAnY29uZmlnLmtleWJvYXJkJyxcbiAgJ2V2ZW50QnVzJ1xuXTtcblxuS2V5Ym9hcmQucHJvdG90eXBlLl9rZXlkb3duSGFuZGxlciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2tleUhhbmRsZXIoZXZlbnQsIEtFWURPV05fRVZFTlQpO1xufTtcblxuS2V5Ym9hcmQucHJvdG90eXBlLl9rZXl1cEhhbmRsZXIgPSBmdW5jdGlvbihldmVudCkge1xuICB0aGlzLl9rZXlIYW5kbGVyKGV2ZW50LCBLRVlVUF9FVkVOVCk7XG59O1xuXG5LZXlib2FyZC5wcm90b3R5cGUuX2tleUhhbmRsZXIgPSBmdW5jdGlvbihldmVudCwgdHlwZSkge1xuICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0LFxuICAgICAgZXZlbnRCdXNSZXN1bHQ7XG5cbiAgaWYgKGlzSW5wdXQodGFyZ2V0KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGtleUV2ZW50OiBldmVudFxuICB9O1xuXG4gIGV2ZW50QnVzUmVzdWx0ID0gdGhpcy5fZXZlbnRCdXMuZmlyZSh0eXBlIHx8IEtFWURPV05fRVZFTlQsIGNvbnRleHQpO1xuXG4gIGlmIChldmVudEJ1c1Jlc3VsdCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cbn07XG5cbktleWJvYXJkLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24obm9kZSkge1xuXG4gIC8vIG1ha2Ugc3VyZSB0aGF0IHRoZSBrZXlib2FyZCBpcyBvbmx5IGJvdW5kIG9uY2UgdG8gdGhlIERPTVxuICB0aGlzLnVuYmluZCgpO1xuXG4gIHRoaXMuX25vZGUgPSBub2RlO1xuXG4gIC8vIGJpbmQga2V5IGV2ZW50c1xuICBkb21FdmVudC5iaW5kKG5vZGUsICdrZXlkb3duJywgdGhpcy5fa2V5ZG93bkhhbmRsZXIsIHRydWUpO1xuICBkb21FdmVudC5iaW5kKG5vZGUsICdrZXl1cCcsIHRoaXMuX2tleXVwSGFuZGxlciwgdHJ1ZSk7XG5cbiAgdGhpcy5fZmlyZSgnYmluZCcpO1xufTtcblxuS2V5Ym9hcmQucHJvdG90eXBlLmdldEJpbmRpbmcgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX25vZGU7XG59O1xuXG5LZXlib2FyZC5wcm90b3R5cGUudW5iaW5kID0gZnVuY3Rpb24oKSB7XG4gIHZhciBub2RlID0gdGhpcy5fbm9kZTtcblxuICBpZiAobm9kZSkge1xuICAgIHRoaXMuX2ZpcmUoJ3VuYmluZCcpO1xuXG4gICAgLy8gdW5iaW5kIGtleSBldmVudHNcbiAgICBkb21FdmVudC51bmJpbmQobm9kZSwgJ2tleWRvd24nLCB0aGlzLl9rZXlkb3duSGFuZGxlciwgdHJ1ZSk7XG4gICAgZG9tRXZlbnQudW5iaW5kKG5vZGUsICdrZXl1cCcsIHRoaXMuX2tleXVwSGFuZGxlciwgdHJ1ZSk7XG4gIH1cblxuICB0aGlzLl9ub2RlID0gbnVsbDtcbn07XG5cbktleWJvYXJkLnByb3RvdHlwZS5fZmlyZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ2tleWJvYXJkLicgKyBldmVudCwgeyBub2RlOiB0aGlzLl9ub2RlIH0pO1xufTtcblxuLyoqXG4gKiBBZGQgYSBsaXN0ZW5lciBmdW5jdGlvbiB0aGF0IGlzIG5vdGlmaWVkIHdpdGggYEtleWJvYXJkRXZlbnRgIHdoZW5ldmVyXG4gKiB0aGUga2V5Ym9hcmQgaXMgYm91bmQgYW5kIHRoZSB1c2VyIHByZXNzZXMgYSBrZXkuIElmIG5vIHByaW9yaXR5IGlzXG4gKiBwcm92aWRlZCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgMTAwMCBpcyB1c2VkLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbcHJpb3JpdHldXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lclxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqL1xuS2V5Ym9hcmQucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24ocHJpb3JpdHksIGxpc3RlbmVyLCB0eXBlKSB7XG4gIGlmIChpc0Z1bmN0aW9uKHByaW9yaXR5KSkge1xuICAgIHR5cGUgPSBsaXN0ZW5lcjtcbiAgICBsaXN0ZW5lciA9IHByaW9yaXR5O1xuICAgIHByaW9yaXR5ID0gREVGQVVMVF9QUklPUklUWTtcbiAgfVxuXG4gIHRoaXMuX2V2ZW50QnVzLm9uKHR5cGUgfHwgS0VZRE9XTl9FVkVOVCwgcHJpb3JpdHksIGxpc3RlbmVyKTtcbn07XG5cbktleWJvYXJkLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKGxpc3RlbmVyLCB0eXBlKSB7XG4gIHRoaXMuX2V2ZW50QnVzLm9mZih0eXBlIHx8IEtFWURPV05fRVZFTlQsIGxpc3RlbmVyKTtcbn07XG5cbktleWJvYXJkLnByb3RvdHlwZS5oYXNNb2RpZmllciA9IGhhc01vZGlmaWVyO1xuS2V5Ym9hcmQucHJvdG90eXBlLmlzQ21kID0gaXNDbWQ7XG5LZXlib2FyZC5wcm90b3R5cGUuaXNTaGlmdCA9IGlzU2hpZnQ7XG5LZXlib2FyZC5wcm90b3R5cGUuaXNLZXkgPSBpc0tleTtcblxuXG5cbi8vIGhlbHBlcnMgLy8vLy8vL1xuXG5mdW5jdGlvbiBpc0lucHV0KHRhcmdldCkge1xuICByZXR1cm4gdGFyZ2V0ICYmIChkb21NYXRjaGVzKHRhcmdldCwgJ2lucHV0LCB0ZXh0YXJlYScpIHx8IHRhcmdldC5jb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyk7XG59XG4iLCJpbXBvcnQge1xuICBpc0NtZCxcbiAgaXNLZXksXG4gIGlzU2hpZnRcbn0gZnJvbSAnLi9LZXlib2FyZFV0aWwnO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gNTAwO1xuXG5leHBvcnQgdmFyIEtFWUNPREVfQyA9IDY3O1xuZXhwb3J0IHZhciBLRVlDT0RFX1YgPSA4NjtcbmV4cG9ydCB2YXIgS0VZQ09ERV9ZID0gODk7XG5leHBvcnQgdmFyIEtFWUNPREVfWiA9IDkwO1xuXG5leHBvcnQgdmFyIEtFWVNfQ09QWSA9IFsnYycsICdDJywgS0VZQ09ERV9DIF07XG5leHBvcnQgdmFyIEtFWVNfUEFTVEUgPSBbICd2JywgJ1YnLCBLRVlDT0RFX1YgXTtcbmV4cG9ydCB2YXIgS0VZU19SRURPID0gWyAneScsICdZJywgS0VZQ09ERV9ZIF07XG5leHBvcnQgdmFyIEtFWVNfVU5ETyA9IFsgJ3onLCAnWicsIEtFWUNPREVfWiBdO1xuXG5cbi8qKlxuICogQWRkcyBkZWZhdWx0IGtleWJvYXJkIGJpbmRpbmdzLlxuICpcbiAqIFRoaXMgZG9lcyBub3QgcHVsbCBpbiBhbnkgZmVhdHVyZXMgd2lsbCBiaW5kIG9ubHkgYWN0aW9ucyB0aGF0XG4gKiBoYXZlIHByZXZpb3VzbHkgYmVlbiByZWdpc3RlcmVkIGFnYWluc3QgdGhlIGVkaXRvckFjdGlvbnMgY29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0tleWJvYXJkfSBrZXlib2FyZFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBLZXlib2FyZEJpbmRpbmdzKGV2ZW50QnVzLCBrZXlib2FyZCkge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbignZWRpdG9yQWN0aW9ucy5pbml0JywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGVkaXRvckFjdGlvbnMgPSBldmVudC5lZGl0b3JBY3Rpb25zO1xuXG4gICAgc2VsZi5yZWdpc3RlckJpbmRpbmdzKGtleWJvYXJkLCBlZGl0b3JBY3Rpb25zKTtcbiAgfSk7XG59XG5cbktleWJvYXJkQmluZGluZ3MuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2tleWJvYXJkJ1xuXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVyIGF2YWlsYWJsZSBrZXlib2FyZCBiaW5kaW5ncy5cbiAqXG4gKiBAcGFyYW0ge0tleWJvYXJkfSBrZXlib2FyZFxuICogQHBhcmFtIHtFZGl0b3JBY3Rpb25zfSBlZGl0b3JBY3Rpb25zXG4gKi9cbktleWJvYXJkQmluZGluZ3MucHJvdG90eXBlLnJlZ2lzdGVyQmluZGluZ3MgPSBmdW5jdGlvbihrZXlib2FyZCwgZWRpdG9yQWN0aW9ucykge1xuXG4gIC8qKlxuICAgKiBBZGQga2V5Ym9hcmQgYmluZGluZyBpZiByZXNwZWN0aXZlIGVkaXRvciBhY3Rpb25cbiAgICogaXMgcmVnaXN0ZXJlZC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbiBuYW1lXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIHRoYXQgaW1wbGVtZW50cyB0aGUga2V5IGJpbmRpbmdcbiAgICovXG4gIGZ1bmN0aW9uIGFkZExpc3RlbmVyKGFjdGlvbiwgZm4pIHtcblxuICAgIGlmIChlZGl0b3JBY3Rpb25zLmlzUmVnaXN0ZXJlZChhY3Rpb24pKSB7XG4gICAgICBrZXlib2FyZC5hZGRMaXN0ZW5lcihmbik7XG4gICAgfVxuICB9XG5cblxuICAvLyB1bmRvXG4gIC8vIChDVFJMfENNRCkgKyBaXG4gIGFkZExpc3RlbmVyKCd1bmRvJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGV2ZW50ID0gY29udGV4dC5rZXlFdmVudDtcblxuICAgIGlmIChpc0NtZChldmVudCkgJiYgIWlzU2hpZnQoZXZlbnQpICYmIGlzS2V5KEtFWVNfVU5ETywgZXZlbnQpKSB7XG4gICAgICBlZGl0b3JBY3Rpb25zLnRyaWdnZXIoJ3VuZG8nKTtcblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9KTtcblxuICAvLyByZWRvXG4gIC8vIENUUkwgKyBZXG4gIC8vIENNRCArIFNISUZUICsgWlxuICBhZGRMaXN0ZW5lcigncmVkbycsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNDbWQoZXZlbnQpICYmIChpc0tleShLRVlTX1JFRE8sIGV2ZW50KSB8fCAoaXNLZXkoS0VZU19VTkRPLCBldmVudCkgJiYgaXNTaGlmdChldmVudCkpKSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdyZWRvJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gY29weVxuICAvLyBDVFJML0NNRCArIENcbiAgYWRkTGlzdGVuZXIoJ2NvcHknLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGlzQ21kKGV2ZW50KSAmJiBpc0tleShLRVlTX0NPUFksIGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdjb3B5Jyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gcGFzdGVcbiAgLy8gQ1RSTC9DTUQgKyBWXG4gIGFkZExpc3RlbmVyKCdwYXN0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNDbWQoZXZlbnQpICYmIGlzS2V5KEtFWVNfUEFTVEUsIGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdwYXN0ZScpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHpvb20gaW4gb25lIHN0ZXBcbiAgLy8gQ1RSTC9DTUQgKyArXG4gIGFkZExpc3RlbmVyKCdzdGVwWm9vbScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNLZXkoWyAnKycsICdBZGQnIF0sIGV2ZW50KSAmJiBpc0NtZChldmVudCkpIHtcbiAgICAgIGVkaXRvckFjdGlvbnMudHJpZ2dlcignc3RlcFpvb20nLCB7IHZhbHVlOiAxIH0pO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHpvb20gb3V0IG9uZSBzdGVwXG4gIC8vIENUUkwgKyAtXG4gIGFkZExpc3RlbmVyKCdzdGVwWm9vbScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNLZXkoWyAnLScsICdTdWJ0cmFjdCcgXSwgZXZlbnQpICYmIGlzQ21kKGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdzdGVwWm9vbScsIHsgdmFsdWU6IC0xIH0pO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHpvb20gdG8gdGhlIGRlZmF1bHQgbGV2ZWxcbiAgLy8gQ1RSTCArIDBcbiAgYWRkTGlzdGVuZXIoJ3pvb20nLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGlzS2V5KCcwJywgZXZlbnQpICYmIGlzQ21kKGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCd6b29tJywgeyB2YWx1ZTogMSB9KTtcblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9KTtcblxuICAvLyBkZWxldGUgc2VsZWN0ZWQgZWxlbWVudFxuICAvLyBERUxcbiAgYWRkTGlzdGVuZXIoJ3JlbW92ZVNlbGVjdGlvbicsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNLZXkoWydCYWNrc3BhY2UnLCAnRGVsZXRlJywgJ0RlbCcgXSwgZXZlbnQpKSB7XG4gICAgICBlZGl0b3JBY3Rpb25zLnRyaWdnZXIoJ3JlbW92ZVNlbGVjdGlvbicpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xufTsiLCJpbXBvcnQgeyBpc0FycmF5IH0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdHJ1ZSBpZiBldmVudCB3YXMgdHJpZ2dlcmVkIHdpdGggYW55IG1vZGlmaWVyXHJcbiAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudH0gZXZlbnRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBoYXNNb2RpZmllcihldmVudCkge1xyXG4gIHJldHVybiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5IHx8IGV2ZW50LnNoaWZ0S2V5IHx8IGV2ZW50LmFsdEtleSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge0tleWJvYXJkRXZlbnR9IGV2ZW50XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNDbWQoZXZlbnQpIHtcclxuXHJcbiAgLy8gZW5zdXJlIHdlIGRvbid0IHJlYWN0IHRvIEFsdEdyXHJcbiAgLy8gKG1hcHBlZCB0byBDVFJMICsgQUxUKVxyXG4gIGlmIChldmVudC5hbHRLZXkpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIHJldHVybiBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgaWYga2V5IHByZXNzZWQgaXMgb25lIG9mIHByb3ZpZGVkIGtleXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfEFycmF5PHN0cmluZz59IGtleXNcclxuICogQHBhcmFtIHtLZXlib2FyZEV2ZW50fSBldmVudFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGlzS2V5KGtleXMsIGV2ZW50KSB7XHJcbiAga2V5cyA9IGlzQXJyYXkoa2V5cykgPyBrZXlzIDogWyBrZXlzIF07XHJcblxyXG4gIHJldHVybiBrZXlzLmluZGV4T2YoZXZlbnQua2V5KSAhPT0gLTEgfHwga2V5cy5pbmRleE9mKGV2ZW50LmtleUNvZGUpICE9PSAtMTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudH0gZXZlbnRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc1NoaWZ0KGV2ZW50KSB7XHJcbiAgcmV0dXJuIGV2ZW50LnNoaWZ0S2V5O1xyXG59IiwiaW1wb3J0IEtleWJvYXJkIGZyb20gJy4vS2V5Ym9hcmQnO1xuaW1wb3J0IEtleWJvYXJkQmluZGluZ3MgZnJvbSAnLi9LZXlib2FyZEJpbmRpbmdzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAna2V5Ym9hcmQnLCAna2V5Ym9hcmRCaW5kaW5ncycgXSxcbiAga2V5Ym9hcmQ6IFsgJ3R5cGUnLCBLZXlib2FyZCBdLFxuICBrZXlib2FyZEJpbmRpbmdzOiBbICd0eXBlJywgS2V5Ym9hcmRCaW5kaW5ncyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgZm9yRWFjaCxcbiAgZmlsdGVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxudmFyIExPV19QUklPUklUWSA9IDI1MCxcbiAgICBISUdIX1BSSU9SSVRZID0gMTQwMDtcblxuaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIGluZGV4T2YgYXMgY29sbGVjdGlvbklkeFxufSBmcm9tICcuLi8uLi91dGlsL0NvbGxlY3Rpb25zJztcblxuaW1wb3J0IHsgc2F2ZUNsZWFyIH0gZnJvbSAnLi4vLi4vdXRpbC9SZW1vdmFsJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICcuLi8uLi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBtYWtlcyBzdXJlIGxhYmVscyBhcmUgcHJvcGVybHkgbW92ZWQgd2l0aFxuICogdGhlaXIgbGFiZWwgdGFyZ2V0cy5cbiAqXG4gKiBAcGFyYW0ge2RpZGkuSW5qZWN0b3J9IGluamVjdG9yXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGFiZWxTdXBwb3J0KGluamVjdG9yLCBldmVudEJ1cywgbW9kZWxpbmcpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdmFyIG1vdmVQcmV2aWV3ID0gaW5qZWN0b3IuZ2V0KCdtb3ZlUHJldmlldycsIGZhbHNlKTtcblxuICAvLyByZW1vdmUgbGFiZWxzIGZyb20gdGhlIGNvbGxlY3Rpb24gdGhhdCBhcmUgYmVpbmdcbiAgLy8gbW92ZWQgd2l0aCBvdGhlciBlbGVtZW50cyBhbnl3YXlcbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUuc3RhcnQnLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgc2hhcGVzID0gY29udGV4dC5zaGFwZXMsXG4gICAgICAgIHZhbGlkYXRlZFNoYXBlcyA9IGNvbnRleHQudmFsaWRhdGVkU2hhcGVzO1xuXG4gICAgY29udGV4dC5zaGFwZXMgPSByZW1vdmVMYWJlbHMoc2hhcGVzKTtcbiAgICBjb250ZXh0LnZhbGlkYXRlZFNoYXBlcyA9IHJlbW92ZUxhYmVscyh2YWxpZGF0ZWRTaGFwZXMpO1xuICB9KTtcblxuICAvLyBhZGQgbGFiZWxzIHRvIHZpc3VhbCdzIGdyb3VwXG4gIG1vdmVQcmV2aWV3ICYmIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLnN0YXJ0JywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgc2hhcGVzID0gY29udGV4dC5zaGFwZXM7XG5cbiAgICB2YXIgbGFiZWxzID0gW107XG5cbiAgICBmb3JFYWNoKHNoYXBlcywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgICBmb3JFYWNoKGVsZW1lbnQubGFiZWxzLCBmdW5jdGlvbihsYWJlbCkge1xuXG4gICAgICAgIGlmICghbGFiZWwuaGlkZGVuICYmIGNvbnRleHQuc2hhcGVzLmluZGV4T2YobGFiZWwpID09PSAtMSkge1xuICAgICAgICAgIGxhYmVscy5wdXNoKGxhYmVsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbGVtZW50LmxhYmVsVGFyZ2V0KSB7XG4gICAgICAgICAgbGFiZWxzLnB1c2goZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZm9yRWFjaChsYWJlbHMsIGZ1bmN0aW9uKGxhYmVsKSB7XG4gICAgICBtb3ZlUHJldmlldy5tYWtlRHJhZ2dhYmxlKGNvbnRleHQsIGxhYmVsLCB0cnVlKTtcbiAgICB9KTtcblxuICB9KTtcblxuICAvLyBhZGQgYWxsIGxhYmVscyB0byBtb3ZlIGNsb3N1cmVcbiAgdGhpcy5wcmVFeGVjdXRlZCgnZWxlbWVudHMubW92ZScsIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgY2xvc3VyZSA9IGNvbnRleHQuY2xvc3VyZSxcbiAgICAgICAgZW5jbG9zZWRFbGVtZW50cyA9IGNsb3N1cmUuZW5jbG9zZWRFbGVtZW50cztcblxuICAgIHZhciBlbmNsb3NlZExhYmVscyA9IFtdO1xuXG4gICAgLy8gZmluZCBsYWJlbHMgdGhhdCBhcmUgbm90IHBhcnQgb2ZcbiAgICAvLyBtb3ZlIGNsb3N1cmUgeWV0IGFuZCBhZGQgdGhlbVxuICAgIGZvckVhY2goZW5jbG9zZWRFbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgZm9yRWFjaChlbGVtZW50LmxhYmVscywgZnVuY3Rpb24obGFiZWwpIHtcblxuICAgICAgICBpZiAoIWVuY2xvc2VkRWxlbWVudHNbbGFiZWwuaWRdKSB7XG4gICAgICAgICAgZW5jbG9zZWRMYWJlbHMucHVzaChsYWJlbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgY2xvc3VyZS5hZGRBbGwoZW5jbG9zZWRMYWJlbHMpO1xuICB9KTtcblxuXG4gIHRoaXMucHJlRXhlY3V0ZShbXG4gICAgJ2Nvbm5lY3Rpb24uZGVsZXRlJyxcbiAgICAnc2hhcGUuZGVsZXRlJ1xuICBdLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuY29ubmVjdGlvbiB8fCBjb250ZXh0LnNoYXBlO1xuXG4gICAgc2F2ZUNsZWFyKGVsZW1lbnQubGFiZWxzLCBmdW5jdGlvbihsYWJlbCkge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlU2hhcGUobGFiZWwsIHsgbmVzdGVkOiB0cnVlIH0pO1xuICAgIH0pO1xuICB9KTtcblxuXG4gIHRoaXMuZXhlY3V0ZSgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgbGFiZWxUYXJnZXQgPSBzaGFwZS5sYWJlbFRhcmdldDtcblxuICAgIC8vIHVuc2V0IGxhYmVsVGFyZ2V0XG4gICAgaWYgKGxhYmVsVGFyZ2V0KSB7XG4gICAgICBjb250ZXh0LmxhYmVsVGFyZ2V0SW5kZXggPSBjb2xsZWN0aW9uSWR4KGxhYmVsVGFyZ2V0LmxhYmVscywgc2hhcGUpO1xuICAgICAgY29udGV4dC5sYWJlbFRhcmdldCA9IGxhYmVsVGFyZ2V0O1xuXG4gICAgICBzaGFwZS5sYWJlbFRhcmdldCA9IG51bGw7XG4gICAgfVxuICB9KTtcblxuICB0aGlzLnJldmVydCgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgbGFiZWxUYXJnZXQgPSBjb250ZXh0LmxhYmVsVGFyZ2V0LFxuICAgICAgICBsYWJlbFRhcmdldEluZGV4ID0gY29udGV4dC5sYWJlbFRhcmdldEluZGV4O1xuXG4gICAgLy8gcmVzdG9yZSBsYWJlbFRhcmdldFxuICAgIGlmIChsYWJlbFRhcmdldCkge1xuICAgICAgY29sbGVjdGlvbkFkZChsYWJlbFRhcmdldC5sYWJlbHMsIHNoYXBlLCBsYWJlbFRhcmdldEluZGV4KTtcblxuICAgICAgc2hhcGUubGFiZWxUYXJnZXQgPSBsYWJlbFRhcmdldDtcbiAgICB9XG4gIH0pO1xuXG59XG5cbmluaGVyaXRzKExhYmVsU3VwcG9ydCwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuTGFiZWxTdXBwb3J0LiRpbmplY3QgPSBbXG4gICdpbmplY3RvcicsXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLyoqXG4gKiBSZXR1cm4gYSBmaWx0ZXJlZCBsaXN0IG9mIGVsZW1lbnRzIHRoYXQgZG8gbm90XG4gKiBjb250YWluIGF0dGFjaGVkIGVsZW1lbnRzIHdpdGggaG9zdHMgYmVpbmcgcGFydFxuICogb2YgdGhlIHNlbGVjdGlvbi5cbiAqXG4gKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGVsZW1lbnRzXG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBmaWx0ZXJlZFxuICovXG5mdW5jdGlvbiByZW1vdmVMYWJlbHMoZWxlbWVudHMpIHtcblxuICByZXR1cm4gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgICAvLyBmaWx0ZXIgb3V0IGxhYmVscyB0aGF0IGFyZSBtb3ZlIHRvZ2V0aGVyXG4gICAgLy8gd2l0aCB0aGVpciBsYWJlbCB0YXJnZXRzXG4gICAgcmV0dXJuIGVsZW1lbnRzLmluZGV4T2YoZWxlbWVudC5sYWJlbFRhcmdldCkgPT09IC0xO1xuICB9KTtcbn1cbiIsImltcG9ydCBMYWJlbFN1cHBvcnQgZnJvbSAnLi9MYWJlbFN1cHBvcnQnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdsYWJlbFN1cHBvcnQnXSxcbiAgbGFiZWxTdXBwb3J0OiBbICd0eXBlJywgTGFiZWxTdXBwb3J0IF1cbn07XG4iLCJpbXBvcnQgeyB2YWx1ZXMgfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IGdldEVuY2xvc2VkRWxlbWVudHMgfSBmcm9tICcuLi8uLi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IHsgaGFzU2Vjb25kYXJ5TW9kaWZpZXIgfSBmcm9tICcuLi8uLi91dGlsL01vdXNlJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICByZW1vdmUgYXMgc3ZnUmVtb3ZlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxudmFyIExBU1NPX1RPT0xfQ1VSU09SID0gJ2Nyb3NzaGFpcic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGFzc29Ub29sKFxuICAgIGV2ZW50QnVzLCBjYW52YXMsIGRyYWdnaW5nLFxuICAgIGVsZW1lbnRSZWdpc3RyeSwgc2VsZWN0aW9uLCB0b29sTWFuYWdlcikge1xuXG4gIHRoaXMuX3NlbGVjdGlvbiA9IHNlbGVjdGlvbjtcbiAgdGhpcy5fZHJhZ2dpbmcgPSBkcmFnZ2luZztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgLy8gbGFzc28gdmlzdWFscyBpbXBsZW1lbnRhdGlvblxuXG4gIC8qKlxuICAqIEEgaGVscGVyIHRoYXQgcmVhbGl6ZXMgdGhlIHNlbGVjdGlvbiBib3ggdmlzdWFsXG4gICovXG4gIHZhciB2aXN1YWxzID0ge1xuXG4gICAgY3JlYXRlOiBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgICB2YXIgY29udGFpbmVyID0gY2FudmFzLmdldERlZmF1bHRMYXllcigpLFxuICAgICAgICAgIGZyYW1lO1xuXG4gICAgICBmcmFtZSA9IGNvbnRleHQuZnJhbWUgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcbiAgICAgIHN2Z0F0dHIoZnJhbWUsIHtcbiAgICAgICAgY2xhc3M6ICdkanMtbGFzc28tb3ZlcmxheScsXG4gICAgICAgIHdpZHRoOiAgMSxcbiAgICAgICAgaGVpZ2h0OiAxLFxuICAgICAgICB4OiAwLFxuICAgICAgICB5OiAwXG4gICAgICB9KTtcblxuICAgICAgc3ZnQXBwZW5kKGNvbnRhaW5lciwgZnJhbWUpO1xuICAgIH0sXG5cbiAgICB1cGRhdGU6IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICAgIHZhciBmcmFtZSA9IGNvbnRleHQuZnJhbWUsXG4gICAgICAgICAgYmJveCA9IGNvbnRleHQuYmJveDtcblxuICAgICAgc3ZnQXR0cihmcmFtZSwge1xuICAgICAgICB4OiBiYm94LngsXG4gICAgICAgIHk6IGJib3gueSxcbiAgICAgICAgd2lkdGg6IGJib3gud2lkdGgsXG4gICAgICAgIGhlaWdodDogYmJveC5oZWlnaHRcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICByZW1vdmU6IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgICAgaWYgKGNvbnRleHQuZnJhbWUpIHtcbiAgICAgICAgc3ZnUmVtb3ZlKGNvbnRleHQuZnJhbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB0b29sTWFuYWdlci5yZWdpc3RlclRvb2woJ2xhc3NvJywge1xuICAgIHRvb2w6ICdsYXNzby5zZWxlY3Rpb24nLFxuICAgIGRyYWdnaW5nOiAnbGFzc28nXG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdsYXNzby5zZWxlY3Rpb24uZW5kJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gZXZlbnQub3JpZ2luYWxFdmVudC50YXJnZXQ7XG5cbiAgICAvLyBvbmx5IHJlYWN0aXZlIG9uIGRpYWdyYW0gY2xpY2tcbiAgICAvLyBvbiBzb21lIG9jY2FzaW9ucywgZXZlbnQuaG92ZXIgaXMgbm90IHNldCBhbmQgd2UgaGF2ZSB0byBjaGVjayBpZiB0aGUgdGFyZ2V0IGlzIGFuIHN2Z1xuICAgIGlmICghZXZlbnQuaG92ZXIgJiYgISh0YXJnZXQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGV2ZW50QnVzLm9uY2UoJ2xhc3NvLnNlbGVjdGlvbi5lbmRlZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgc2VsZi5hY3RpdmF0ZUxhc3NvKGV2ZW50Lm9yaWdpbmFsRXZlbnQsIHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBsYXNzbyBpbnRlcmFjdGlvbiBpbXBsZW1lbnRhdGlvblxuXG4gIGV2ZW50QnVzLm9uKCdsYXNzby5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGJib3ggPSB0b0JCb3goZXZlbnQpO1xuXG4gICAgdmFyIGVsZW1lbnRzID0gZWxlbWVudFJlZ2lzdHJ5LmZpbHRlcihmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9KTtcblxuICAgIHNlbGYuc2VsZWN0KGVsZW1lbnRzLCBiYm94KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2xhc3NvLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dDtcblxuICAgIGNvbnRleHQuYmJveCA9IHRvQkJveChldmVudCk7XG4gICAgdmlzdWFscy5jcmVhdGUoY29udGV4dCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdsYXNzby5tb3ZlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dDtcblxuICAgIGNvbnRleHQuYmJveCA9IHRvQkJveChldmVudCk7XG4gICAgdmlzdWFscy51cGRhdGUoY29udGV4dCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdsYXNzby5jbGVhbnVwJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dDtcblxuICAgIHZpc3VhbHMucmVtb3ZlKGNvbnRleHQpO1xuICB9KTtcblxuXG4gIC8vIGV2ZW50IGludGVncmF0aW9uXG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQubW91c2Vkb3duJywgMTUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIGlmIChoYXNTZWNvbmRhcnlNb2RpZmllcihldmVudCkpIHtcbiAgICAgIHNlbGYuYWN0aXZhdGVMYXNzbyhldmVudC5vcmlnaW5hbEV2ZW50KTtcblxuICAgICAgLy8gd2UndmUgaGFuZGxlZCB0aGUgZXZlbnRcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG59XG5cbkxhc3NvVG9vbC4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ2RyYWdnaW5nJyxcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXG4gICdzZWxlY3Rpb24nLFxuICAndG9vbE1hbmFnZXInXG5dO1xuXG5cbkxhc3NvVG9vbC5wcm90b3R5cGUuYWN0aXZhdGVMYXNzbyA9IGZ1bmN0aW9uKGV2ZW50LCBhdXRvQWN0aXZhdGUpIHtcblxuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnbGFzc28nLCB7XG4gICAgYXV0b0FjdGl2YXRlOiBhdXRvQWN0aXZhdGUsXG4gICAgY3Vyc29yOiBMQVNTT19UT09MX0NVUlNPUixcbiAgICBkYXRhOiB7XG4gICAgICBjb250ZXh0OiB7fVxuICAgIH1cbiAgfSk7XG59O1xuXG5MYXNzb1Rvb2wucHJvdG90eXBlLmFjdGl2YXRlU2VsZWN0aW9uID0gZnVuY3Rpb24oZXZlbnQpIHtcblxuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnbGFzc28uc2VsZWN0aW9uJywge1xuICAgIHRyYXBDbGljazogZmFsc2UsXG4gICAgY3Vyc29yOiBMQVNTT19UT09MX0NVUlNPUixcbiAgICBkYXRhOiB7XG4gICAgICBjb250ZXh0OiB7fVxuICAgIH1cbiAgfSk7XG59O1xuXG5MYXNzb1Rvb2wucHJvdG90eXBlLnNlbGVjdCA9IGZ1bmN0aW9uKGVsZW1lbnRzLCBiYm94KSB7XG4gIHZhciBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0RW5jbG9zZWRFbGVtZW50cyhlbGVtZW50cywgYmJveCk7XG5cbiAgdGhpcy5fc2VsZWN0aW9uLnNlbGVjdCh2YWx1ZXMoc2VsZWN0ZWRFbGVtZW50cykpO1xufTtcblxuTGFzc29Ub29sLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuaXNBY3RpdmUoKSkge1xuICAgIHRoaXMuX2RyYWdnaW5nLmNhbmNlbCgpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuYWN0aXZhdGVTZWxlY3Rpb24oKTtcbiAgfVxufTtcblxuTGFzc29Ub29sLnByb3RvdHlwZS5pc0FjdGl2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29udGV4dCA9IHRoaXMuX2RyYWdnaW5nLmNvbnRleHQoKTtcblxuICByZXR1cm4gY29udGV4dCAmJiAvXmxhc3NvLy50ZXN0KGNvbnRleHQucHJlZml4KTtcbn07XG5cblxuXG5mdW5jdGlvbiB0b0JCb3goZXZlbnQpIHtcblxuICB2YXIgc3RhcnQgPSB7XG5cbiAgICB4OiBldmVudC54IC0gZXZlbnQuZHgsXG4gICAgeTogZXZlbnQueSAtIGV2ZW50LmR5XG4gIH07XG5cbiAgdmFyIGVuZCA9IHtcbiAgICB4OiBldmVudC54LFxuICAgIHk6IGV2ZW50LnlcbiAgfTtcblxuICB2YXIgYmJveDtcblxuICBpZiAoKHN0YXJ0LnggPD0gZW5kLnggJiYgc3RhcnQueSA8IGVuZC55KSB8fFxuICAgICAgKHN0YXJ0LnggPCBlbmQueCAmJiBzdGFydC55IDw9IGVuZC55KSkge1xuXG4gICAgYmJveCA9IHtcbiAgICAgIHg6IHN0YXJ0LngsXG4gICAgICB5OiBzdGFydC55LFxuICAgICAgd2lkdGg6ICBlbmQueCAtIHN0YXJ0LngsXG4gICAgICBoZWlnaHQ6IGVuZC55IC0gc3RhcnQueVxuICAgIH07XG4gIH0gZWxzZSBpZiAoKHN0YXJ0LnggPj0gZW5kLnggJiYgc3RhcnQueSA8IGVuZC55KSB8fFxuICAgICAgICAgICAgIChzdGFydC54ID4gZW5kLnggJiYgc3RhcnQueSA8PSBlbmQueSkpIHtcblxuICAgIGJib3ggPSB7XG4gICAgICB4OiBlbmQueCxcbiAgICAgIHk6IHN0YXJ0LnksXG4gICAgICB3aWR0aDogIHN0YXJ0LnggLSBlbmQueCxcbiAgICAgIGhlaWdodDogZW5kLnkgLSBzdGFydC55XG4gICAgfTtcbiAgfSBlbHNlIGlmICgoc3RhcnQueCA8PSBlbmQueCAmJiBzdGFydC55ID4gZW5kLnkpIHx8XG4gICAgICAgICAgICAgKHN0YXJ0LnggPCBlbmQueCAmJiBzdGFydC55ID49IGVuZC55KSkge1xuXG4gICAgYmJveCA9IHtcbiAgICAgIHg6IHN0YXJ0LngsXG4gICAgICB5OiBlbmQueSxcbiAgICAgIHdpZHRoOiAgZW5kLnggLSBzdGFydC54LFxuICAgICAgaGVpZ2h0OiBzdGFydC55IC0gZW5kLnlcbiAgICB9O1xuICB9IGVsc2UgaWYgKChzdGFydC54ID49IGVuZC54ICYmIHN0YXJ0LnkgPiBlbmQueSkgfHxcbiAgICAgICAgICAgICAoc3RhcnQueCA+IGVuZC54ICYmIHN0YXJ0LnkgPj0gZW5kLnkpKSB7XG5cbiAgICBiYm94ID0ge1xuICAgICAgeDogZW5kLngsXG4gICAgICB5OiBlbmQueSxcbiAgICAgIHdpZHRoOiAgc3RhcnQueCAtIGVuZC54LFxuICAgICAgaGVpZ2h0OiBzdGFydC55IC0gZW5kLnlcbiAgICB9O1xuICB9IGVsc2Uge1xuXG4gICAgYmJveCA9IHtcbiAgICAgIHg6IGVuZC54LFxuICAgICAgeTogZW5kLnksXG4gICAgICB3aWR0aDogIDAsXG4gICAgICBoZWlnaHQ6IDBcbiAgICB9O1xuICB9XG4gIHJldHVybiBiYm94O1xufVxuIiwiaW1wb3J0IFRvb2xNYW5hZ2VyTW9kdWxlIGZyb20gJy4uL3Rvb2wtbWFuYWdlcic7XG5cbmltcG9ydCBMYXNzb1Rvb2wgZnJvbSAnLi9MYXNzb1Rvb2wnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgVG9vbE1hbmFnZXJNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2xhc3NvVG9vbCcgXSxcbiAgbGFzc29Ub29sOiBbICd0eXBlJywgTGFzc29Ub29sIF1cbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIGlzQXJyYXlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBCYXNlXG59IGZyb20gJy4uLy4uL21vZGVsJztcblxuaW1wb3J0IEFsaWduRWxlbWVudHNIYW5kbGVyIGZyb20gJy4vY21kL0FsaWduRWxlbWVudHNIYW5kbGVyJztcbmltcG9ydCBBcHBlbmRTaGFwZUhhbmRsZXIgZnJvbSAnLi9jbWQvQXBwZW5kU2hhcGVIYW5kbGVyJztcbmltcG9ydCBDcmVhdGVDb25uZWN0aW9uSGFuZGxlciBmcm9tICcuL2NtZC9DcmVhdGVDb25uZWN0aW9uSGFuZGxlcic7XG5pbXBvcnQgQ3JlYXRlRWxlbWVudHNIYW5kbGVyIGZyb20gJy4vY21kL0NyZWF0ZUVsZW1lbnRzSGFuZGxlcic7XG5pbXBvcnQgQ3JlYXRlTGFiZWxIYW5kbGVyIGZyb20gJy4vY21kL0NyZWF0ZUxhYmVsSGFuZGxlcic7XG5pbXBvcnQgQ3JlYXRlU2hhcGVIYW5kbGVyIGZyb20gJy4vY21kL0NyZWF0ZVNoYXBlSGFuZGxlcic7XG5pbXBvcnQgRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXIgZnJvbSAnLi9jbWQvRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXInO1xuaW1wb3J0IERlbGV0ZUVsZW1lbnRzSGFuZGxlciBmcm9tICcuL2NtZC9EZWxldGVFbGVtZW50c0hhbmRsZXInO1xuaW1wb3J0IERlbGV0ZVNoYXBlSGFuZGxlciBmcm9tICcuL2NtZC9EZWxldGVTaGFwZUhhbmRsZXInO1xuaW1wb3J0IERpc3RyaWJ1dGVFbGVtZW50c0hhbmRsZXIgZnJvbSAnLi9jbWQvRGlzdHJpYnV0ZUVsZW1lbnRzSGFuZGxlcic7XG5pbXBvcnQgTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXIgZnJvbSAnLi9jbWQvTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXInO1xuaW1wb3J0IE1vdmVDb25uZWN0aW9uSGFuZGxlciBmcm9tICcuL2NtZC9Nb3ZlQ29ubmVjdGlvbkhhbmRsZXInO1xuaW1wb3J0IE1vdmVFbGVtZW50c0hhbmRsZXIgZnJvbSAnLi9jbWQvTW92ZUVsZW1lbnRzSGFuZGxlcic7XG5pbXBvcnQgTW92ZVNoYXBlSGFuZGxlciBmcm9tICcuL2NtZC9Nb3ZlU2hhcGVIYW5kbGVyJztcbmltcG9ydCBSZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlciBmcm9tICcuL2NtZC9SZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlcic7XG5pbXBvcnQgUmVwbGFjZVNoYXBlSGFuZGxlciBmcm9tICcuL2NtZC9SZXBsYWNlU2hhcGVIYW5kbGVyJztcbmltcG9ydCBSZXNpemVTaGFwZUhhbmRsZXIgZnJvbSAnLi9jbWQvUmVzaXplU2hhcGVIYW5kbGVyJztcbmltcG9ydCBTcGFjZVRvb2xIYW5kbGVyIGZyb20gJy4vY21kL1NwYWNlVG9vbEhhbmRsZXInO1xuaW1wb3J0IFRvZ2dsZVNoYXBlQ29sbGFwc2VIYW5kbGVyIGZyb20gJy4vY21kL1RvZ2dsZVNoYXBlQ29sbGFwc2VIYW5kbGVyJztcbmltcG9ydCBVcGRhdGVBdHRhY2htZW50SGFuZGxlciBmcm9tICcuL2NtZC9VcGRhdGVBdHRhY2htZW50SGFuZGxlcic7XG5pbXBvcnQgVXBkYXRlV2F5cG9pbnRzSGFuZGxlciBmcm9tICcuL2NtZC9VcGRhdGVXYXlwb2ludHNIYW5kbGVyJztcblxuXG4vKipcbiAqIFRoZSBiYXNpYyBtb2RlbGluZyBlbnRyeSBwb2ludC5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtFbGVtZW50RmFjdG9yeX0gZWxlbWVudEZhY3RvcnlcbiAqIEBwYXJhbSB7Q29tbWFuZFN0YWNrfSBjb21tYW5kU3RhY2tcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW9kZWxpbmcoZXZlbnRCdXMsIGVsZW1lbnRGYWN0b3J5LCBjb21tYW5kU3RhY2spIHtcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcbiAgdGhpcy5fY29tbWFuZFN0YWNrID0gY29tbWFuZFN0YWNrO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5pbml0JywgZnVuY3Rpb24oKSB7XG5cbiAgICAvLyByZWdpc3RlciBtb2RlbGluZyBoYW5kbGVyc1xuICAgIHNlbGYucmVnaXN0ZXJIYW5kbGVycyhjb21tYW5kU3RhY2spO1xuICB9KTtcbn1cblxuTW9kZWxpbmcuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2VsZW1lbnRGYWN0b3J5JywgJ2NvbW1hbmRTdGFjaycgXTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUuZ2V0SGFuZGxlcnMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHtcbiAgICAnc2hhcGUuYXBwZW5kJzogQXBwZW5kU2hhcGVIYW5kbGVyLFxuICAgICdzaGFwZS5jcmVhdGUnOiBDcmVhdGVTaGFwZUhhbmRsZXIsXG4gICAgJ3NoYXBlLmRlbGV0ZSc6IERlbGV0ZVNoYXBlSGFuZGxlcixcbiAgICAnc2hhcGUubW92ZSc6IE1vdmVTaGFwZUhhbmRsZXIsXG4gICAgJ3NoYXBlLnJlc2l6ZSc6IFJlc2l6ZVNoYXBlSGFuZGxlcixcbiAgICAnc2hhcGUucmVwbGFjZSc6IFJlcGxhY2VTaGFwZUhhbmRsZXIsXG4gICAgJ3NoYXBlLnRvZ2dsZUNvbGxhcHNlJzogVG9nZ2xlU2hhcGVDb2xsYXBzZUhhbmRsZXIsXG5cbiAgICAnc3BhY2VUb29sJzogU3BhY2VUb29sSGFuZGxlcixcblxuICAgICdsYWJlbC5jcmVhdGUnOiBDcmVhdGVMYWJlbEhhbmRsZXIsXG5cbiAgICAnY29ubmVjdGlvbi5jcmVhdGUnOiBDcmVhdGVDb25uZWN0aW9uSGFuZGxlcixcbiAgICAnY29ubmVjdGlvbi5kZWxldGUnOiBEZWxldGVDb25uZWN0aW9uSGFuZGxlcixcbiAgICAnY29ubmVjdGlvbi5tb3ZlJzogTW92ZUNvbm5lY3Rpb25IYW5kbGVyLFxuICAgICdjb25uZWN0aW9uLmxheW91dCc6IExheW91dENvbm5lY3Rpb25IYW5kbGVyLFxuXG4gICAgJ2Nvbm5lY3Rpb24udXBkYXRlV2F5cG9pbnRzJzogVXBkYXRlV2F5cG9pbnRzSGFuZGxlcixcblxuICAgICdjb25uZWN0aW9uLnJlY29ubmVjdCc6IFJlY29ubmVjdENvbm5lY3Rpb25IYW5kbGVyLFxuXG4gICAgJ2VsZW1lbnRzLmNyZWF0ZSc6IENyZWF0ZUVsZW1lbnRzSGFuZGxlcixcbiAgICAnZWxlbWVudHMubW92ZSc6IE1vdmVFbGVtZW50c0hhbmRsZXIsXG4gICAgJ2VsZW1lbnRzLmRlbGV0ZSc6IERlbGV0ZUVsZW1lbnRzSGFuZGxlcixcblxuICAgICdlbGVtZW50cy5kaXN0cmlidXRlJzogRGlzdHJpYnV0ZUVsZW1lbnRzSGFuZGxlcixcbiAgICAnZWxlbWVudHMuYWxpZ24nOiBBbGlnbkVsZW1lbnRzSGFuZGxlcixcblxuICAgICdlbGVtZW50LnVwZGF0ZUF0dGFjaG1lbnQnOiBVcGRhdGVBdHRhY2htZW50SGFuZGxlclxuICB9O1xufTtcblxuLyoqXG4gKiBSZWdpc3RlciBoYW5kbGVycyB3aXRoIHRoZSBjb21tYW5kIHN0YWNrXG4gKlxuICogQHBhcmFtIHtDb21tYW5kU3RhY2t9IGNvbW1hbmRTdGFja1xuICovXG5Nb2RlbGluZy5wcm90b3R5cGUucmVnaXN0ZXJIYW5kbGVycyA9IGZ1bmN0aW9uKGNvbW1hbmRTdGFjaykge1xuICBmb3JFYWNoKHRoaXMuZ2V0SGFuZGxlcnMoKSwgZnVuY3Rpb24oaGFuZGxlciwgaWQpIHtcbiAgICBjb21tYW5kU3RhY2sucmVnaXN0ZXJIYW5kbGVyKGlkLCBoYW5kbGVyKTtcbiAgfSk7XG59O1xuXG5cbi8vIG1vZGVsaW5nIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5Nb2RlbGluZy5wcm90b3R5cGUubW92ZVNoYXBlID0gZnVuY3Rpb24oc2hhcGUsIGRlbHRhLCBuZXdQYXJlbnQsIG5ld1BhcmVudEluZGV4LCBoaW50cykge1xuXG4gIGlmICh0eXBlb2YgbmV3UGFyZW50SW5kZXggPT09ICdvYmplY3QnKSB7XG4gICAgaGludHMgPSBuZXdQYXJlbnRJbmRleDtcbiAgICBuZXdQYXJlbnRJbmRleCA9IG51bGw7XG4gIH1cblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBzaGFwZTogc2hhcGUsXG4gICAgZGVsdGE6ICBkZWx0YSxcbiAgICBuZXdQYXJlbnQ6IG5ld1BhcmVudCxcbiAgICBuZXdQYXJlbnRJbmRleDogbmV3UGFyZW50SW5kZXgsXG4gICAgaGludHM6IGhpbnRzIHx8IHt9XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3NoYXBlLm1vdmUnLCBjb250ZXh0KTtcbn07XG5cblxuLyoqXG4gKiBVcGRhdGUgdGhlIGF0dGFjaG1lbnQgb2YgdGhlIGdpdmVuIHNoYXBlLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGUuQmFzZX0gc2hhcGVcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtuZXdIb3N0XVxuICovXG5Nb2RlbGluZy5wcm90b3R5cGUudXBkYXRlQXR0YWNobWVudCA9IGZ1bmN0aW9uKHNoYXBlLCBuZXdIb3N0KSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIHNoYXBlOiBzaGFwZSxcbiAgICBuZXdIb3N0OiBuZXdIb3N0XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnQudXBkYXRlQXR0YWNobWVudCcsIGNvbnRleHQpO1xufTtcblxuXG4vKipcbiAqIE1vdmUgYSBudW1iZXIgb2Ygc2hhcGVzIHRvIGEgbmV3IHRhcmdldCwgZWl0aGVyIHNldHRpbmcgaXQgYXNcbiAqIHRoZSBuZXcgcGFyZW50IG9yIGF0dGFjaGluZyBpdC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlLkJhc2U+fSBzaGFwZXNcbiAqIEBwYXJhbSB7UG9pbnR9IGRlbHRhXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBbdGFyZ2V0XVxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2hpbnRzLmF0dGFjaD1mYWxzZV1cbiAqL1xuTW9kZWxpbmcucHJvdG90eXBlLm1vdmVFbGVtZW50cyA9IGZ1bmN0aW9uKHNoYXBlcywgZGVsdGEsIHRhcmdldCwgaGludHMpIHtcblxuICBoaW50cyA9IGhpbnRzIHx8IHt9O1xuXG4gIHZhciBhdHRhY2ggPSBoaW50cy5hdHRhY2g7XG5cbiAgdmFyIG5ld1BhcmVudCA9IHRhcmdldCxcbiAgICAgIG5ld0hvc3Q7XG5cbiAgaWYgKGF0dGFjaCA9PT0gdHJ1ZSkge1xuICAgIG5ld0hvc3QgPSB0YXJnZXQ7XG4gICAgbmV3UGFyZW50ID0gdGFyZ2V0LnBhcmVudDtcbiAgfSBlbHNlXG5cbiAgaWYgKGF0dGFjaCA9PT0gZmFsc2UpIHtcbiAgICBuZXdIb3N0ID0gbnVsbDtcbiAgfVxuXG4gIHZhciBjb250ZXh0ID0ge1xuICAgIHNoYXBlczogc2hhcGVzLFxuICAgIGRlbHRhOiBkZWx0YSxcbiAgICBuZXdQYXJlbnQ6IG5ld1BhcmVudCxcbiAgICBuZXdIb3N0OiBuZXdIb3N0LFxuICAgIGhpbnRzOiBoaW50c1xuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdlbGVtZW50cy5tb3ZlJywgY29udGV4dCk7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5tb3ZlQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIGRlbHRhLCBuZXdQYXJlbnQsIG5ld1BhcmVudEluZGV4LCBoaW50cykge1xuXG4gIGlmICh0eXBlb2YgbmV3UGFyZW50SW5kZXggPT09ICdvYmplY3QnKSB7XG4gICAgaGludHMgPSBuZXdQYXJlbnRJbmRleDtcbiAgICBuZXdQYXJlbnRJbmRleCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgZGVsdGE6IGRlbHRhLFxuICAgIG5ld1BhcmVudDogbmV3UGFyZW50LFxuICAgIG5ld1BhcmVudEluZGV4OiBuZXdQYXJlbnRJbmRleCxcbiAgICBoaW50czogaGludHMgfHwge31cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnY29ubmVjdGlvbi5tb3ZlJywgY29udGV4dCk7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5sYXlvdXRDb25uZWN0aW9uID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgaGludHMpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICBoaW50czogaGludHMgfHwge31cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnY29ubmVjdGlvbi5sYXlvdXQnLCBjb250ZXh0KTtcbn07XG5cblxuLyoqXG4gKiBDcmVhdGUgY29ubmVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBzb3VyY2VcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IHRhcmdldFxuICogQHBhcmFtIHtudW1iZXJ9IFtwYXJlbnRJbmRleF1cbiAqIEBwYXJhbSB7T2JqZWN0fGRqcy5tb2RlbC5Db25uZWN0aW9ufSBjb25uZWN0aW9uXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBwYXJlbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBoaW50c1xuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5Db25uZWN0aW9ufSB0aGUgY3JlYXRlZCBjb25uZWN0aW9uLlxuICovXG5Nb2RlbGluZy5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBwYXJlbnRJbmRleCwgY29ubmVjdGlvbiwgcGFyZW50LCBoaW50cykge1xuXG4gIGlmICh0eXBlb2YgcGFyZW50SW5kZXggPT09ICdvYmplY3QnKSB7XG4gICAgaGludHMgPSBwYXJlbnQ7XG4gICAgcGFyZW50ID0gY29ubmVjdGlvbjtcbiAgICBjb25uZWN0aW9uID0gcGFyZW50SW5kZXg7XG4gICAgcGFyZW50SW5kZXggPSB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25uZWN0aW9uID0gdGhpcy5fY3JlYXRlKCdjb25uZWN0aW9uJywgY29ubmVjdGlvbik7XG5cbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgc291cmNlOiBzb3VyY2UsXG4gICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgcGFyZW50OiBwYXJlbnQsXG4gICAgcGFyZW50SW5kZXg6IHBhcmVudEluZGV4LFxuICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgaGludHM6IGhpbnRzXG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2Nvbm5lY3Rpb24uY3JlYXRlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuY29ubmVjdGlvbjtcbn07XG5cblxuLyoqXG4gKiBDcmVhdGUgYSBzaGFwZSBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfE9iamVjdH0gc2hhcGVcbiAqIEBwYXJhbSB7UG9pbnR9IHBvc2l0aW9uXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZXxkanMubW9kZWwuUm9vdH0gdGFyZ2V0XG4gKiBAcGFyYW0ge251bWJlcn0gW3BhcmVudEluZGV4XSBwb3NpdGlvbiBpbiBwYXJlbnRzIGNoaWxkcmVuIGxpc3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBbaGludHNdXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtoaW50cy5hdHRhY2hdIHdoZXRoZXIgdG8gYXR0YWNoIHRvIHRhcmdldCBvciBiZWNvbWUgYSBjaGlsZFxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5TaGFwZX0gdGhlIGNyZWF0ZWQgc2hhcGVcbiAqL1xuTW9kZWxpbmcucHJvdG90eXBlLmNyZWF0ZVNoYXBlID0gZnVuY3Rpb24oc2hhcGUsIHBvc2l0aW9uLCB0YXJnZXQsIHBhcmVudEluZGV4LCBoaW50cykge1xuXG4gIGlmICh0eXBlb2YgcGFyZW50SW5kZXggIT09ICdudW1iZXInKSB7XG4gICAgaGludHMgPSBwYXJlbnRJbmRleDtcbiAgICBwYXJlbnRJbmRleCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGhpbnRzID0gaGludHMgfHwge307XG5cbiAgdmFyIGF0dGFjaCA9IGhpbnRzLmF0dGFjaCxcbiAgICAgIHBhcmVudCxcbiAgICAgIGhvc3Q7XG5cbiAgc2hhcGUgPSB0aGlzLl9jcmVhdGUoJ3NoYXBlJywgc2hhcGUpO1xuXG4gIGlmIChhdHRhY2gpIHtcbiAgICBwYXJlbnQgPSB0YXJnZXQucGFyZW50O1xuICAgIGhvc3QgPSB0YXJnZXQ7XG4gIH0gZWxzZSB7XG4gICAgcGFyZW50ID0gdGFyZ2V0O1xuICB9XG5cbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgIHNoYXBlOiBzaGFwZSxcbiAgICBwYXJlbnQ6IHBhcmVudCxcbiAgICBwYXJlbnRJbmRleDogcGFyZW50SW5kZXgsXG4gICAgaG9zdDogaG9zdCxcbiAgICBoaW50czogaGludHNcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnc2hhcGUuY3JlYXRlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuc2hhcGU7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5jcmVhdGVFbGVtZW50cyA9IGZ1bmN0aW9uKGVsZW1lbnRzLCBwb3NpdGlvbiwgcGFyZW50LCBwYXJlbnRJbmRleCwgaGludHMpIHtcbiAgaWYgKCFpc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gWyBlbGVtZW50cyBdO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJlbnRJbmRleCAhPT0gJ251bWJlcicpIHtcbiAgICBoaW50cyA9IHBhcmVudEluZGV4O1xuICAgIHBhcmVudEluZGV4ID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaGludHMgPSBoaW50cyB8fCB7fTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgZWxlbWVudHM6IGVsZW1lbnRzLFxuICAgIHBhcmVudDogcGFyZW50LFxuICAgIHBhcmVudEluZGV4OiBwYXJlbnRJbmRleCxcbiAgICBoaW50czogaGludHNcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnZWxlbWVudHMuY3JlYXRlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuZWxlbWVudHM7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5jcmVhdGVMYWJlbCA9IGZ1bmN0aW9uKGxhYmVsVGFyZ2V0LCBwb3NpdGlvbiwgbGFiZWwsIHBhcmVudCkge1xuXG4gIGxhYmVsID0gdGhpcy5fY3JlYXRlKCdsYWJlbCcsIGxhYmVsKTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBsYWJlbFRhcmdldDogbGFiZWxUYXJnZXQsXG4gICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgIHBhcmVudDogcGFyZW50IHx8IGxhYmVsVGFyZ2V0LnBhcmVudCxcbiAgICBzaGFwZTogbGFiZWxcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnbGFiZWwuY3JlYXRlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuc2hhcGU7XG59O1xuXG5cbi8qKlxuICogQXBwZW5kIHNoYXBlIHRvIGdpdmVuIHNvdXJjZSwgZHJhd2luZyBhIGNvbm5lY3Rpb25cbiAqIGJldHdlZW4gc291cmNlIGFuZCB0aGUgbmV3bHkgY3JlYXRlZCBzaGFwZS5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc291cmNlXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZXxPYmplY3R9IHNoYXBlXG4gKiBAcGFyYW0ge1BvaW50fSBwb3NpdGlvblxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHRhcmdldFxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2hpbnRzLmF0dGFjaF1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkNvbm5lY3Rpb258T2JqZWN0fSBbaGludHMuY29ubmVjdGlvbl1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtoaW50cy5jb25uZWN0aW9uUGFyZW50XVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5TaGFwZX0gdGhlIG5ld2x5IGNyZWF0ZWQgc2hhcGVcbiAqL1xuTW9kZWxpbmcucHJvdG90eXBlLmFwcGVuZFNoYXBlID0gZnVuY3Rpb24oc291cmNlLCBzaGFwZSwgcG9zaXRpb24sIHRhcmdldCwgaGludHMpIHtcblxuICBoaW50cyA9IGhpbnRzIHx8IHt9O1xuXG4gIHNoYXBlID0gdGhpcy5fY3JlYXRlKCdzaGFwZScsIHNoYXBlKTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgc2hhcGU6IHNoYXBlLFxuICAgIGNvbm5lY3Rpb246IGhpbnRzLmNvbm5lY3Rpb24sXG4gICAgY29ubmVjdGlvblBhcmVudDogaGludHMuY29ubmVjdGlvblBhcmVudCxcbiAgICBoaW50czogaGludHNcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnc2hhcGUuYXBwZW5kJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuc2hhcGU7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5yZW1vdmVFbGVtZW50cyA9IGZ1bmN0aW9uKGVsZW1lbnRzKSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGVsZW1lbnRzOiBlbGVtZW50c1xuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdlbGVtZW50cy5kZWxldGUnLCBjb250ZXh0KTtcbn07XG5cblxuTW9kZWxpbmcucHJvdG90eXBlLmRpc3RyaWJ1dGVFbGVtZW50cyA9IGZ1bmN0aW9uKGdyb3VwcywgYXhpcywgZGltZW5zaW9uKSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGdyb3VwczogZ3JvdXBzLFxuICAgIGF4aXM6IGF4aXMsXG4gICAgZGltZW5zaW9uOiBkaW1lbnNpb25cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnZWxlbWVudHMuZGlzdHJpYnV0ZScsIGNvbnRleHQpO1xufTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUucmVtb3ZlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgaGludHMpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgc2hhcGU6IHNoYXBlLFxuICAgIGhpbnRzOiBoaW50cyB8fCB7fVxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdzaGFwZS5kZWxldGUnLCBjb250ZXh0KTtcbn07XG5cblxuTW9kZWxpbmcucHJvdG90eXBlLnJlbW92ZUNvbm5lY3Rpb24gPSBmdW5jdGlvbihjb25uZWN0aW9uLCBoaW50cykge1xuICB2YXIgY29udGV4dCA9IHtcbiAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgIGhpbnRzOiBoaW50cyB8fCB7fVxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdjb25uZWN0aW9uLmRlbGV0ZScsIGNvbnRleHQpO1xufTtcblxuTW9kZWxpbmcucHJvdG90eXBlLnJlcGxhY2VTaGFwZSA9IGZ1bmN0aW9uKG9sZFNoYXBlLCBuZXdTaGFwZSwgaGludHMpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgb2xkU2hhcGU6IG9sZFNoYXBlLFxuICAgIG5ld0RhdGE6IG5ld1NoYXBlLFxuICAgIGhpbnRzOiBoaW50cyB8fCB7fVxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdzaGFwZS5yZXBsYWNlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQubmV3U2hhcGU7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUuYWxpZ25FbGVtZW50cyA9IGZ1bmN0aW9uKGVsZW1lbnRzLCBhbGlnbm1lbnQpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgZWxlbWVudHM6IGVsZW1lbnRzLFxuICAgIGFsaWdubWVudDogYWxpZ25tZW50XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnRzLmFsaWduJywgY29udGV4dCk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUucmVzaXplU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgbmV3Qm91bmRzLCBtaW5Cb3VuZHMsIGhpbnRzKSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIHNoYXBlOiBzaGFwZSxcbiAgICBuZXdCb3VuZHM6IG5ld0JvdW5kcyxcbiAgICBtaW5Cb3VuZHM6IG1pbkJvdW5kcyxcbiAgICBoaW50czogaGludHNcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnc2hhcGUucmVzaXplJywgY29udGV4dCk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUuY3JlYXRlU3BhY2UgPSBmdW5jdGlvbihtb3ZpbmdTaGFwZXMsIHJlc2l6aW5nU2hhcGVzLCBkZWx0YSwgZGlyZWN0aW9uLCBzdGFydCkge1xuICB2YXIgY29udGV4dCA9IHtcbiAgICBkZWx0YTogZGVsdGEsXG4gICAgZGlyZWN0aW9uOiBkaXJlY3Rpb24sXG4gICAgbW92aW5nU2hhcGVzOiBtb3ZpbmdTaGFwZXMsXG4gICAgcmVzaXppbmdTaGFwZXM6IHJlc2l6aW5nU2hhcGVzLFxuICAgIHN0YXJ0OiBzdGFydFxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdzcGFjZVRvb2wnLCBjb250ZXh0KTtcbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS51cGRhdGVXYXlwb2ludHMgPSBmdW5jdGlvbihjb25uZWN0aW9uLCBuZXdXYXlwb2ludHMsIGhpbnRzKSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgbmV3V2F5cG9pbnRzOiBuZXdXYXlwb2ludHMsXG4gICAgaGludHM6IGhpbnRzIHx8IHt9XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2Nvbm5lY3Rpb24udXBkYXRlV2F5cG9pbnRzJywgY29udGV4dCk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgc291cmNlLCB0YXJnZXQsIGRvY2tpbmdPclBvaW50cywgaGludHMpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICBuZXdTb3VyY2U6IHNvdXJjZSxcbiAgICBuZXdUYXJnZXQ6IHRhcmdldCxcbiAgICBkb2NraW5nT3JQb2ludHM6IGRvY2tpbmdPclBvaW50cyxcbiAgICBoaW50czogaGludHMgfHwge31cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCBjb250ZXh0KTtcbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS5yZWNvbm5lY3RTdGFydCA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIG5ld1NvdXJjZSwgZG9ja2luZ09yUG9pbnRzLCBoaW50cykge1xuICBpZiAoIWhpbnRzKSB7XG4gICAgaGludHMgPSB7fTtcbiAgfVxuXG4gIHRoaXMucmVjb25uZWN0KGNvbm5lY3Rpb24sIG5ld1NvdXJjZSwgY29ubmVjdGlvbi50YXJnZXQsIGRvY2tpbmdPclBvaW50cywgYXNzaWduKGhpbnRzLCB7XG4gICAgZG9ja2luZzogJ3NvdXJjZSdcbiAgfSkpO1xufTtcblxuTW9kZWxpbmcucHJvdG90eXBlLnJlY29ubmVjdEVuZCA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIG5ld1RhcmdldCwgZG9ja2luZ09yUG9pbnRzLCBoaW50cykge1xuICBpZiAoIWhpbnRzKSB7XG4gICAgaGludHMgPSB7fTtcbiAgfVxuXG4gIHRoaXMucmVjb25uZWN0KGNvbm5lY3Rpb24sIGNvbm5lY3Rpb24uc291cmNlLCBuZXdUYXJnZXQsIGRvY2tpbmdPclBvaW50cywgYXNzaWduKGhpbnRzLCB7XG4gICAgZG9ja2luZzogJ3RhcmdldCdcbiAgfSkpO1xufTtcblxuTW9kZWxpbmcucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbihzb3VyY2UsIHRhcmdldCwgYXR0cnMsIGhpbnRzKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZUNvbm5lY3Rpb24oc291cmNlLCB0YXJnZXQsIGF0dHJzIHx8IHt9LCBzb3VyY2UucGFyZW50LCBoaW50cyk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUuX2NyZWF0ZSA9IGZ1bmN0aW9uKHR5cGUsIGF0dHJzKSB7XG4gIGlmIChhdHRycyBpbnN0YW5jZW9mIEJhc2UpIHtcbiAgICByZXR1cm4gYXR0cnM7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRoaXMuX2VsZW1lbnRGYWN0b3J5LmNyZWF0ZSh0eXBlLCBhdHRycyk7XG4gIH1cbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS50b2dnbGVDb2xsYXBzZSA9IGZ1bmN0aW9uKHNoYXBlLCBoaW50cykge1xuICB2YXIgY29udGV4dCA9IHtcbiAgICBzaGFwZTogc2hhcGUsXG4gICAgaGludHM6IGhpbnRzIHx8IHt9XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3NoYXBlLnRvZ2dsZUNvbGxhcHNlJywgY29udGV4dCk7XG59O1xuIiwiaW1wb3J0IHsgZm9yRWFjaCB9IGZyb20gJ21pbi1kYXNoJztcblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBhbGlnbiBlbGVtZW50cyBpbiBhIGNlcnRhaW4gd2F5LlxuICpcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQWxpZ25FbGVtZW50cyhtb2RlbGluZywgY2FudmFzKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbn1cblxuQWxpZ25FbGVtZW50cy4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnLCAnY2FudmFzJyBdO1xuXG5cbkFsaWduRWxlbWVudHMucHJvdG90eXBlLnByZUV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nO1xuXG4gIHZhciBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXG4gICAgICBhbGlnbm1lbnQgPSBjb250ZXh0LmFsaWdubWVudDtcblxuXG4gIGZvckVhY2goZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICB2YXIgZGVsdGEgPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMFxuICAgIH07XG5cbiAgICBpZiAoYWxpZ25tZW50LmxlZnQpIHtcbiAgICAgIGRlbHRhLnggPSBhbGlnbm1lbnQubGVmdCAtIGVsZW1lbnQueDtcblxuICAgIH0gZWxzZSBpZiAoYWxpZ25tZW50LnJpZ2h0KSB7XG4gICAgICBkZWx0YS54ID0gKGFsaWdubWVudC5yaWdodCAtIGVsZW1lbnQud2lkdGgpIC0gZWxlbWVudC54O1xuXG4gICAgfSBlbHNlIGlmIChhbGlnbm1lbnQuY2VudGVyKSB7XG4gICAgICBkZWx0YS54ID0gKGFsaWdubWVudC5jZW50ZXIgLSBNYXRoLnJvdW5kKGVsZW1lbnQud2lkdGggLyAyKSkgLSBlbGVtZW50Lng7XG5cbiAgICB9IGVsc2UgaWYgKGFsaWdubWVudC50b3ApIHtcbiAgICAgIGRlbHRhLnkgPSBhbGlnbm1lbnQudG9wIC0gZWxlbWVudC55O1xuXG4gICAgfSBlbHNlIGlmIChhbGlnbm1lbnQuYm90dG9tKSB7XG4gICAgICBkZWx0YS55ID0gKGFsaWdubWVudC5ib3R0b20gLSBlbGVtZW50LmhlaWdodCkgLSBlbGVtZW50Lnk7XG5cbiAgICB9IGVsc2UgaWYgKGFsaWdubWVudC5taWRkbGUpIHtcbiAgICAgIGRlbHRhLnkgPSAoYWxpZ25tZW50Lm1pZGRsZSAtIE1hdGgucm91bmQoZWxlbWVudC5oZWlnaHQgLyAyKSkgLSBlbGVtZW50Lnk7XG4gICAgfVxuXG4gICAgbW9kZWxpbmcubW92ZUVsZW1lbnRzKFsgZWxlbWVudCBdLCBkZWx0YSwgZWxlbWVudC5wYXJlbnQpO1xuICB9KTtcbn07XG5cbkFsaWduRWxlbWVudHMucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG59O1xuIiwiaW1wb3J0IHsgc29tZSB9IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgcmV2ZXJzaWJsZSBhcHBlbmRpbmcgb2Ygc2hhcGVzXG4gKiB0byBhIHNvdXJjZSBzaGFwZS5cbiAqXG4gKiBAcGFyYW0ge2NhbnZhc30gQ2FudmFzXG4gKiBAcGFyYW0ge2VsZW1lbnRGYWN0b3J5fSBFbGVtZW50RmFjdG9yeVxuICogQHBhcmFtIHttb2RlbGluZ30gTW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwZW5kU2hhcGVIYW5kbGVyKG1vZGVsaW5nKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cbkFwcGVuZFNoYXBlSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc2hhcGVcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtFbGVtZW50RGVzY3JpcHRvcn0gY29udGV4dC5zaGFwZSB0aGUgbmV3IHNoYXBlXG4gKiBAcGFyYW0ge0VsZW1lbnREZXNjcmlwdG9yfSBjb250ZXh0LnNvdXJjZSB0aGUgc291cmNlIG9iamVjdFxuICogQHBhcmFtIHtFbGVtZW50RGVzY3JpcHRvcn0gY29udGV4dC5wYXJlbnQgdGhlIHBhcmVudCBvYmplY3RcbiAqIEBwYXJhbSB7UG9pbnR9IGNvbnRleHQucG9zaXRpb24gcG9zaXRpb24gb2YgdGhlIG5ldyBlbGVtZW50XG4gKi9cbkFwcGVuZFNoYXBlSGFuZGxlci5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgc291cmNlID0gY29udGV4dC5zb3VyY2U7XG5cbiAgaWYgKCFzb3VyY2UpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSByZXF1aXJlZCcpO1xuICB9XG5cbiAgdmFyIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0IHx8IHNvdXJjZS5wYXJlbnQsXG4gICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgc2hhcGUgPSBjb250ZXh0LnNoYXBlID1cbiAgICB0aGlzLl9tb2RlbGluZy5jcmVhdGVTaGFwZShcbiAgICAgIHNoYXBlLFxuICAgICAgY29udGV4dC5wb3NpdGlvbixcbiAgICAgIHRhcmdldCwgeyBhdHRhY2g6IGhpbnRzLmF0dGFjaCB9KTtcblxuICBjb250ZXh0LnNoYXBlID0gc2hhcGU7XG59O1xuXG5BcHBlbmRTaGFwZUhhbmRsZXIucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gIGlmICghZXhpc3RzQ29ubmVjdGlvbihjb250ZXh0LnNvdXJjZSwgY29udGV4dC5zaGFwZSkpIHtcblxuICAgIC8vIGNyZWF0ZSBjb25uZWN0aW9uXG4gICAgaWYgKGhpbnRzLmNvbm5lY3Rpb25UYXJnZXQgPT09IGNvbnRleHQuc291cmNlKSB7XG4gICAgICB0aGlzLl9tb2RlbGluZy5jb25uZWN0KGNvbnRleHQuc2hhcGUsIGNvbnRleHQuc291cmNlLCBjb250ZXh0LmNvbm5lY3Rpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9tb2RlbGluZy5jb25uZWN0KGNvbnRleHQuc291cmNlLCBjb250ZXh0LnNoYXBlLCBjb250ZXh0LmNvbm5lY3Rpb24pO1xuICAgIH1cbiAgfVxufTtcblxuXG5mdW5jdGlvbiBleGlzdHNDb25uZWN0aW9uKHNvdXJjZSwgdGFyZ2V0KSB7XG4gIHJldHVybiBzb21lKHNvdXJjZS5vdXRnb2luZywgZnVuY3Rpb24oYykge1xuICAgIHJldHVybiBjLnRhcmdldCA9PT0gdGFyZ2V0O1xuICB9KTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVDb25uZWN0aW9uSGFuZGxlcihjYW52YXMsIGxheW91dGVyKSB7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fbGF5b3V0ZXIgPSBsYXlvdXRlcjtcbn1cblxuQ3JlYXRlQ29ubmVjdGlvbkhhbmRsZXIuJGluamVjdCA9IFsgJ2NhbnZhcycsICdsYXlvdXRlcicgXTtcblxuXG4vLyBhcGkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5cbi8qKlxuICogQXBwZW5kcyBhIHNoYXBlIHRvIGEgdGFyZ2V0IHNoYXBlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7ZGpzLmVsZW1lbnQuQmFzZX0gY29udGV4dC5zb3VyY2UgdGhlIHNvdXJjZSBvYmplY3RcbiAqIEBwYXJhbSB7ZGpzLmVsZW1lbnQuQmFzZX0gY29udGV4dC50YXJnZXQgdGhlIHBhcmVudCBvYmplY3RcbiAqIEBwYXJhbSB7UG9pbnR9IGNvbnRleHQucG9zaXRpb24gcG9zaXRpb24gb2YgdGhlIG5ldyBlbGVtZW50XG4gKi9cbkNyZWF0ZUNvbm5lY3Rpb25IYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldCxcbiAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxuICAgICAgcGFyZW50SW5kZXggPSBjb250ZXh0LnBhcmVudEluZGV4LFxuICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzO1xuXG4gIGlmICghc291cmNlIHx8ICF0YXJnZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBhbmQgdGFyZ2V0IHJlcXVpcmVkJyk7XG4gIH1cblxuICBpZiAoIXBhcmVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcigncGFyZW50IHJlcXVpcmVkJyk7XG4gIH1cblxuICBjb25uZWN0aW9uLnNvdXJjZSA9IHNvdXJjZTtcbiAgY29ubmVjdGlvbi50YXJnZXQgPSB0YXJnZXQ7XG5cbiAgaWYgKCFjb25uZWN0aW9uLndheXBvaW50cykge1xuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gdGhpcy5fbGF5b3V0ZXIubGF5b3V0Q29ubmVjdGlvbihjb25uZWN0aW9uLCBoaW50cyk7XG4gIH1cblxuICAvLyBhZGQgY29ubmVjdGlvblxuICB0aGlzLl9jYW52YXMuYWRkQ29ubmVjdGlvbihjb25uZWN0aW9uLCBwYXJlbnQsIHBhcmVudEluZGV4KTtcblxuICByZXR1cm4gY29ubmVjdGlvbjtcbn07XG5cbkNyZWF0ZUNvbm5lY3Rpb25IYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uO1xuXG4gIHRoaXMuX2NhbnZhcy5yZW1vdmVDb25uZWN0aW9uKGNvbm5lY3Rpb24pO1xuXG4gIGNvbm5lY3Rpb24uc291cmNlID0gbnVsbDtcbiAgY29ubmVjdGlvbi50YXJnZXQgPSBudWxsO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTsiLCJpbXBvcnQge1xyXG4gIGFzc2lnbixcclxuICBmb3JFYWNoLFxyXG4gIGlzTnVtYmVyLFxyXG4gIG1hcCxcclxuICBwaWNrLFxyXG4gIHZhbHVlc1xyXG59IGZyb20gJ21pbi1kYXNoJztcclxuXHJcbmltcG9ydCB7XHJcbiAgZ2V0QkJveCxcclxuICBnZXRQYXJlbnRzXHJcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9FbGVtZW50cyc7XHJcblxyXG52YXIgcm91bmQgPSBNYXRoLnJvdW5kO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ3JlYXRlRWxlbWVudHNIYW5kbGVyKG1vZGVsaW5nKSB7XHJcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcclxufVxyXG5cclxuQ3JlYXRlRWxlbWVudHNIYW5kbGVyLiRpbmplY3QgPSBbXHJcbiAgJ21vZGVsaW5nJ1xyXG5dO1xyXG5cclxuQ3JlYXRlRWxlbWVudHNIYW5kbGVyLnByb3RvdHlwZS5wcmVFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xyXG4gIHZhciBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXHJcbiAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxyXG4gICAgICBwYXJlbnRJbmRleCA9IGNvbnRleHQucGFyZW50SW5kZXgsXHJcbiAgICAgIHBvc2l0aW9uID0gY29udGV4dC5wb3NpdGlvbixcclxuICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzO1xyXG5cclxuICB2YXIgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcclxuXHJcbiAgLy8gbWFrZSBzdXJlIGVhY2ggZWxlbWVudCBoYXMgeCBhbmQgeVxyXG4gIGZvckVhY2goZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgIGlmICghaXNOdW1iZXIoZWxlbWVudC54KSkge1xyXG4gICAgICBlbGVtZW50LnggPSAwO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghaXNOdW1iZXIoZWxlbWVudC55KSkge1xyXG4gICAgICBlbGVtZW50LnkgPSAwO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICB2YXIgYmJveCA9IGdldEJCb3goZWxlbWVudHMpO1xyXG5cclxuICAvLyBjZW50ZXIgZWxlbWVudHMgYXJvdW5kIHBvc2l0aW9uXHJcbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgaWYgKGlzQ29ubmVjdGlvbihlbGVtZW50KSkge1xyXG4gICAgICBlbGVtZW50LndheXBvaW50cyA9IG1hcChlbGVtZW50LndheXBvaW50cywgZnVuY3Rpb24od2F5cG9pbnQpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgeDogcm91bmQod2F5cG9pbnQueCAtIGJib3gueCAtIGJib3gud2lkdGggLyAyICsgcG9zaXRpb24ueCksXHJcbiAgICAgICAgICB5OiByb3VuZCh3YXlwb2ludC55IC0gYmJveC55IC0gYmJveC5oZWlnaHQgLyAyICsgcG9zaXRpb24ueSlcclxuICAgICAgICB9O1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBhc3NpZ24oZWxlbWVudCwge1xyXG4gICAgICB4OiByb3VuZChlbGVtZW50LnggLSBiYm94LnggLSBiYm94LndpZHRoIC8gMiArIHBvc2l0aW9uLngpLFxyXG4gICAgICB5OiByb3VuZChlbGVtZW50LnkgLSBiYm94LnkgLSBiYm94LmhlaWdodCAvIDIgKyBwb3NpdGlvbi55KVxyXG4gICAgfSk7XHJcbiAgfSk7XHJcblxyXG4gIHZhciBwYXJlbnRzID0gZ2V0UGFyZW50cyhlbGVtZW50cyk7XHJcblxyXG4gIHZhciBjYWNoZSA9IHt9O1xyXG5cclxuICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICBpZiAoaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XHJcbiAgICAgIGNhY2hlWyBlbGVtZW50LmlkIF0gPSBpc051bWJlcihwYXJlbnRJbmRleCkgP1xyXG4gICAgICAgIG1vZGVsaW5nLmNyZWF0ZUNvbm5lY3Rpb24oXHJcbiAgICAgICAgICBjYWNoZVsgZWxlbWVudC5zb3VyY2UuaWQgXSxcclxuICAgICAgICAgIGNhY2hlWyBlbGVtZW50LnRhcmdldC5pZCBdLFxyXG4gICAgICAgICAgcGFyZW50SW5kZXgsXHJcbiAgICAgICAgICBlbGVtZW50LFxyXG4gICAgICAgICAgZWxlbWVudC5wYXJlbnQgfHwgcGFyZW50LFxyXG4gICAgICAgICAgaGludHNcclxuICAgICAgICApIDpcclxuICAgICAgICBtb2RlbGluZy5jcmVhdGVDb25uZWN0aW9uKFxyXG4gICAgICAgICAgY2FjaGVbIGVsZW1lbnQuc291cmNlLmlkIF0sXHJcbiAgICAgICAgICBjYWNoZVsgZWxlbWVudC50YXJnZXQuaWQgXSxcclxuICAgICAgICAgIGVsZW1lbnQsXHJcbiAgICAgICAgICBlbGVtZW50LnBhcmVudCB8fCBwYXJlbnQsXHJcbiAgICAgICAgICBoaW50c1xyXG4gICAgICAgICk7XHJcblxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGNyZWF0ZVNoYXBlSGludHMgPSBhc3NpZ24oe30sIGhpbnRzKTtcclxuXHJcbiAgICBpZiAocGFyZW50cy5pbmRleE9mKGVsZW1lbnQpID09PSAtMSkge1xyXG4gICAgICBjcmVhdGVTaGFwZUhpbnRzLmF1dG9SZXNpemUgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBjYWNoZVsgZWxlbWVudC5pZCBdID0gaXNOdW1iZXIocGFyZW50SW5kZXgpID9cclxuICAgICAgbW9kZWxpbmcuY3JlYXRlU2hhcGUoXHJcbiAgICAgICAgZWxlbWVudCxcclxuICAgICAgICBwaWNrKGVsZW1lbnQsIFsgJ3gnLCAneScsICd3aWR0aCcsICdoZWlnaHQnIF0pLFxyXG4gICAgICAgIGVsZW1lbnQucGFyZW50IHx8IHBhcmVudCxcclxuICAgICAgICBwYXJlbnRJbmRleCxcclxuICAgICAgICBjcmVhdGVTaGFwZUhpbnRzXHJcbiAgICAgICkgOlxyXG4gICAgICBtb2RlbGluZy5jcmVhdGVTaGFwZShcclxuICAgICAgICBlbGVtZW50LFxyXG4gICAgICAgIHBpY2soZWxlbWVudCwgWyAneCcsICd5JywgJ3dpZHRoJywgJ2hlaWdodCcgXSksXHJcbiAgICAgICAgZWxlbWVudC5wYXJlbnQgfHwgcGFyZW50LFxyXG4gICAgICAgIGNyZWF0ZVNoYXBlSGludHNcclxuICAgICAgKTtcclxuICB9KTtcclxuXHJcbiAgY29udGV4dC5lbGVtZW50cyA9IHZhbHVlcyhjYWNoZSk7XHJcbn07XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIGlzQ29ubmVjdGlvbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuICEhZWxlbWVudC53YXlwb2ludHM7XHJcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ3JlYXRlU2hhcGVIYW5kbGVyIGZyb20gJy4vQ3JlYXRlU2hhcGVIYW5kbGVyJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGF0dGFjaGVzIGEgbGFiZWwgdG8gYSBnaXZlbiB0YXJnZXQgc2hhcGUuXG4gKlxuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVMYWJlbEhhbmRsZXIoY2FudmFzKSB7XG4gIENyZWF0ZVNoYXBlSGFuZGxlci5jYWxsKHRoaXMsIGNhbnZhcyk7XG59XG5cbmluaGVyaXRzKENyZWF0ZUxhYmVsSGFuZGxlciwgQ3JlYXRlU2hhcGVIYW5kbGVyKTtcblxuQ3JlYXRlTGFiZWxIYW5kbGVyLiRpbmplY3QgPSBbICdjYW52YXMnIF07XG5cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuXG52YXIgb3JpZ2luYWxFeGVjdXRlID0gQ3JlYXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlO1xuXG4vKipcbiAqIEFwcGVuZHMgYSBsYWJlbCB0byBhIHRhcmdldCBzaGFwZS5cbiAqXG4gKiBAbWV0aG9kIENyZWF0ZUxhYmVsSGFuZGxlciNleGVjdXRlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7RWxlbWVudERlc2NyaXB0b3J9IGNvbnRleHQudGFyZ2V0IHRoZSBlbGVtZW50IHRoZSBsYWJlbCBpcyBhdHRhY2hlZCB0b1xuICogQHBhcmFtIHtFbGVtZW50RGVzY3JpcHRvcn0gY29udGV4dC5wYXJlbnQgdGhlIHBhcmVudCBvYmplY3RcbiAqIEBwYXJhbSB7UG9pbnR9IGNvbnRleHQucG9zaXRpb24gcG9zaXRpb24gb2YgdGhlIG5ldyBlbGVtZW50XG4gKi9cbkNyZWF0ZUxhYmVsSGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgbGFiZWwgPSBjb250ZXh0LnNoYXBlO1xuXG4gIGVuc3VyZVZhbGlkRGltZW5zaW9ucyhsYWJlbCk7XG5cbiAgbGFiZWwubGFiZWxUYXJnZXQgPSBjb250ZXh0LmxhYmVsVGFyZ2V0O1xuXG4gIHJldHVybiBvcmlnaW5hbEV4ZWN1dGUuY2FsbCh0aGlzLCBjb250ZXh0KTtcbn07XG5cbnZhciBvcmlnaW5hbFJldmVydCA9IENyZWF0ZVNoYXBlSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0O1xuXG4vKipcbiAqIFVuZG8gYXBwZW5kIGJ5IHJlbW92aW5nIHRoZSBzaGFwZVxuICovXG5DcmVhdGVMYWJlbEhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgY29udGV4dC5zaGFwZS5sYWJlbFRhcmdldCA9IG51bGw7XG5cbiAgcmV0dXJuIG9yaWdpbmFsUmV2ZXJ0LmNhbGwodGhpcywgY29udGV4dCk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBlbnN1cmVWYWxpZERpbWVuc2lvbnMobGFiZWwpIHtcblxuICAvLyBtYWtlIHN1cmUgYSBsYWJlbCBoYXMgdmFsaWQgeyB3aWR0aCwgaGVpZ2h0IH0gZGltZW5zaW9uc1xuICBbICd3aWR0aCcsICdoZWlnaHQnIF0uZm9yRWFjaChmdW5jdGlvbihwcm9wKSB7XG4gICAgaWYgKHR5cGVvZiBsYWJlbFtwcm9wXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxhYmVsW3Byb3BdID0gMDtcbiAgICB9XG4gIH0pO1xufSIsImltcG9ydCB7IGFzc2lnbiB9IGZyb20gJ21pbi1kYXNoJztcblxudmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgcmV2ZXJzaWJsZSBhZGRpdGlvbiBvZiBzaGFwZXMuXG4gKlxuICogQHBhcmFtIHtjYW52YXN9IENhbnZhc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVTaGFwZUhhbmRsZXIoY2FudmFzKSB7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbn1cblxuQ3JlYXRlU2hhcGVIYW5kbGVyLiRpbmplY3QgPSBbICdjYW52YXMnIF07XG5cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuXG4vKipcbiAqIEFwcGVuZHMgYSBzaGFwZSB0byBhIHRhcmdldCBzaGFwZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBjb250ZXh0LnBhcmVudCB0aGUgcGFyZW50IG9iamVjdFxuICogQHBhcmFtIHtQb2ludH0gY29udGV4dC5wb3NpdGlvbiBwb3NpdGlvbiBvZiB0aGUgbmV3IGVsZW1lbnRcbiAqL1xuQ3JlYXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBwb3NpdGlvbk9yQm91bmRzID0gY29udGV4dC5wb3NpdGlvbixcbiAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxuICAgICAgcGFyZW50SW5kZXggPSBjb250ZXh0LnBhcmVudEluZGV4O1xuXG4gIGlmICghcGFyZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwYXJlbnQgcmVxdWlyZWQnKTtcbiAgfVxuXG4gIGlmICghcG9zaXRpb25PckJvdW5kcykge1xuICAgIHRocm93IG5ldyBFcnJvcigncG9zaXRpb24gcmVxdWlyZWQnKTtcbiAgfVxuXG4gIC8vICgxKSBhZGQgYXQgZXZlbnQgY2VudGVyIHBvc2l0aW9uIF9vcl8gYXQgZ2l2ZW4gYm91bmRzXG4gIGlmIChwb3NpdGlvbk9yQm91bmRzLndpZHRoICE9PSB1bmRlZmluZWQpIHtcbiAgICBhc3NpZ24oc2hhcGUsIHBvc2l0aW9uT3JCb3VuZHMpO1xuICB9IGVsc2Uge1xuICAgIGFzc2lnbihzaGFwZSwge1xuICAgICAgeDogcG9zaXRpb25PckJvdW5kcy54IC0gcm91bmQoc2hhcGUud2lkdGggLyAyKSxcbiAgICAgIHk6IHBvc2l0aW9uT3JCb3VuZHMueSAtIHJvdW5kKHNoYXBlLmhlaWdodCAvIDIpXG4gICAgfSk7XG4gIH1cblxuICAvLyAoMikgYWRkIHRvIGNhbnZhc1xuICB0aGlzLl9jYW52YXMuYWRkU2hhcGUoc2hhcGUsIHBhcmVudCwgcGFyZW50SW5kZXgpO1xuXG4gIHJldHVybiBzaGFwZTtcbn07XG5cblxuLyoqXG4gKiBVbmRvIGFwcGVuZCBieSByZW1vdmluZyB0aGUgc2hhcGVcbiAqL1xuQ3JlYXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZTtcblxuICAvLyAoMykgcmVtb3ZlIGZvcm0gY2FudmFzXG4gIHRoaXMuX2NhbnZhcy5yZW1vdmVTaGFwZShzaGFwZSk7XG5cbiAgcmV0dXJuIHNoYXBlO1xufTsiLCJpbXBvcnQge1xuICBhZGQgYXMgY29sbGVjdGlvbkFkZCxcbiAgaW5kZXhPZiBhcyBjb2xsZWN0aW9uSWR4XG59IGZyb20gJy4uLy4uLy4uL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyByZXZlcnNpYmxlIGRlbGV0aW9uIG9mIENvbm5lY3Rpb25zLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEZWxldGVDb25uZWN0aW9uSGFuZGxlcihjYW52YXMsIG1vZGVsaW5nKSB7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbn1cblxuRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXIuJGluamVjdCA9IFtcbiAgJ2NhbnZhcycsXG4gICdtb2RlbGluZydcbl07XG5cblxuRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICBwYXJlbnQgPSBjb25uZWN0aW9uLnBhcmVudDtcblxuICBjb250ZXh0LnBhcmVudCA9IHBhcmVudDtcblxuICAvLyByZW1lbWJlciBjb250YWlubWVudFxuICBjb250ZXh0LnBhcmVudEluZGV4ID0gY29sbGVjdGlvbklkeChwYXJlbnQuY2hpbGRyZW4sIGNvbm5lY3Rpb24pO1xuXG4gIGNvbnRleHQuc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2U7XG4gIGNvbnRleHQudGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQ7XG5cbiAgdGhpcy5fY2FudmFzLnJlbW92ZUNvbm5lY3Rpb24oY29ubmVjdGlvbik7XG5cbiAgY29ubmVjdGlvbi5zb3VyY2UgPSBudWxsO1xuICBjb25uZWN0aW9uLnRhcmdldCA9IG51bGw7XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59O1xuXG4vKipcbiAqIENvbW1hbmQgcmV2ZXJ0IGltcGxlbWVudGF0aW9uLlxuICovXG5EZWxldGVDb25uZWN0aW9uSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICBwYXJlbnRJbmRleCA9IGNvbnRleHQucGFyZW50SW5kZXg7XG5cbiAgY29ubmVjdGlvbi5zb3VyY2UgPSBjb250ZXh0LnNvdXJjZTtcbiAgY29ubmVjdGlvbi50YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAvLyByZXN0b3JlIGNvbnRhaW5tZW50XG4gIGNvbGxlY3Rpb25BZGQocGFyZW50LmNoaWxkcmVuLCBjb25uZWN0aW9uLCBwYXJlbnRJbmRleCk7XG5cbiAgdGhpcy5fY2FudmFzLmFkZENvbm5lY3Rpb24oY29ubmVjdGlvbiwgcGFyZW50KTtcblxuICByZXR1cm4gY29ubmVjdGlvbjtcbn07XG4iLCJpbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERlbGV0ZUVsZW1lbnRzSGFuZGxlcihtb2RlbGluZywgZWxlbWVudFJlZ2lzdHJ5KSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbn1cblxuRGVsZXRlRWxlbWVudHNIYW5kbGVyLiRpbmplY3QgPSBbXG4gICdtb2RlbGluZycsXG4gICdlbGVtZW50UmVnaXN0cnknXG5dO1xuXG5cbkRlbGV0ZUVsZW1lbnRzSGFuZGxlci5wcm90b3R5cGUucG9zdEV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmcsXG4gICAgICBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnksXG4gICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHM7XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgLy8gZWxlbWVudCBtYXkgaGF2ZSBiZWVuIHJlbW92ZWQgd2l0aCBwcmV2aW91c1xuICAgIC8vIHJlbW92ZSBvcGVyYXRpb25zIGFscmVhZHkgKGUuZy4gaW4gY2FzZSBvZiBuZXN0aW5nKVxuICAgIGlmICghZWxlbWVudFJlZ2lzdHJ5LmdldChlbGVtZW50LmlkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihlbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlU2hhcGUoZWxlbWVudCk7XG4gICAgfVxuICB9KTtcbn07IiwiaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIGluZGV4T2YgYXMgY29sbGVjdGlvbklkeFxufSBmcm9tICcuLi8uLi8uLi91dGlsL0NvbGxlY3Rpb25zJztcblxuaW1wb3J0IHsgc2F2ZUNsZWFyIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9SZW1vdmFsJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgcmV2ZXJzaWJsZSBkZWxldGlvbiBvZiBzaGFwZXMuXG4gKlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEZWxldGVTaGFwZUhhbmRsZXIoY2FudmFzLCBtb2RlbGluZykge1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cbkRlbGV0ZVNoYXBlSGFuZGxlci4kaW5qZWN0ID0gWyAnY2FudmFzJywgJ21vZGVsaW5nJyBdO1xuXG5cbi8qKlxuICogLSBSZW1vdmUgY29ubmVjdGlvbnNcbiAqIC0gUmVtb3ZlIGFsbCBkaXJlY3QgY2hpbGRyZW5cbiAqL1xuRGVsZXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5wcmVFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nO1xuXG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgLy8gcmVtb3ZlIGNvbm5lY3Rpb25zXG4gIHNhdmVDbGVhcihzaGFwZS5pbmNvbWluZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuXG4gICAgLy8gVG8gbWFrZSBzdXJlIHRoYXQgdGhlIGNvbm5lY3Rpb24gaXNuJ3QgcmVtb3ZlZCB0d2ljZVxuICAgIC8vIEZvciBleGFtcGxlIGlmIGEgY29udGFpbmVyIGlzIHJlbW92ZWRcbiAgICBtb2RlbGluZy5yZW1vdmVDb25uZWN0aW9uKGNvbm5lY3Rpb24sIHsgbmVzdGVkOiB0cnVlIH0pO1xuICB9KTtcblxuICBzYXZlQ2xlYXIoc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICBtb2RlbGluZy5yZW1vdmVDb25uZWN0aW9uKGNvbm5lY3Rpb24sIHsgbmVzdGVkOiB0cnVlIH0pO1xuICB9KTtcblxuICAvLyByZW1vdmUgY2hpbGQgc2hhcGVzIGFuZCBjb25uZWN0aW9uc1xuICBzYXZlQ2xlYXIoc2hhcGUuY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgaWYgKGlzQ29ubmVjdGlvbihjaGlsZCkpIHtcbiAgICAgIG1vZGVsaW5nLnJlbW92ZUNvbm5lY3Rpb24oY2hpbGQsIHsgbmVzdGVkOiB0cnVlIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBtb2RlbGluZy5yZW1vdmVTaGFwZShjaGlsZCwgeyBuZXN0ZWQ6IHRydWUgfSk7XG4gICAgfVxuICB9KTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIHNoYXBlIGFuZCByZW1lbWJlciB0aGUgcGFyZW50XG4gKi9cbkRlbGV0ZVNoYXBlSGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIGNhbnZhcyA9IHRoaXMuX2NhbnZhcztcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgb2xkUGFyZW50ID0gc2hhcGUucGFyZW50O1xuXG4gIGNvbnRleHQub2xkUGFyZW50ID0gb2xkUGFyZW50O1xuXG4gIC8vIHJlbW92ZSBjb250YWlubWVudFxuICBjb250ZXh0Lm9sZFBhcmVudEluZGV4ID0gY29sbGVjdGlvbklkeChvbGRQYXJlbnQuY2hpbGRyZW4sIHNoYXBlKTtcblxuICAvLyByZW1vdmUgc2hhcGVcbiAgY2FudmFzLnJlbW92ZVNoYXBlKHNoYXBlKTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG5cbi8qKlxuICogQ29tbWFuZCByZXZlcnQgaW1wbGVtZW50YXRpb25cbiAqL1xuRGVsZXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGNhbnZhcyA9IHRoaXMuX2NhbnZhcztcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgb2xkUGFyZW50ID0gY29udGV4dC5vbGRQYXJlbnQsXG4gICAgICBvbGRQYXJlbnRJbmRleCA9IGNvbnRleHQub2xkUGFyZW50SW5kZXg7XG5cbiAgLy8gcmVzdG9yZSBjb250YWlubWVudFxuICBjb2xsZWN0aW9uQWRkKG9sZFBhcmVudC5jaGlsZHJlbiwgc2hhcGUsIG9sZFBhcmVudEluZGV4KTtcblxuICBjYW52YXMuYWRkU2hhcGUoc2hhcGUsIG9sZFBhcmVudCk7XG5cbiAgcmV0dXJuIHNoYXBlO1xufTtcblxuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQud2F5cG9pbnRzO1xufVxuIiwiaW1wb3J0IHtcbiAgZm9yRWFjaCxcbiAgc29ydEJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGRpc3RyaWJ1dGVzIGVsZW1lbnRzIGV2ZW5seS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRGlzdHJpYnV0ZUVsZW1lbnRzKG1vZGVsaW5nKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cbkRpc3RyaWJ1dGVFbGVtZW50cy4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cbnZhciBPRkZfQVhJUyA9IHtcbiAgeDogJ3knLFxuICB5OiAneCdcbn07XG5cbkRpc3RyaWJ1dGVFbGVtZW50cy5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmc7XG5cbiAgdmFyIGdyb3VwcyA9IGNvbnRleHQuZ3JvdXBzLFxuICAgICAgYXhpcyA9IGNvbnRleHQuYXhpcyxcbiAgICAgIGRpbWVuc2lvbiA9IGNvbnRleHQuZGltZW5zaW9uO1xuXG4gIGZ1bmN0aW9uIHVwZGF0ZVJhbmdlKGdyb3VwLCBlbGVtZW50KSB7XG4gICAgZ3JvdXAucmFuZ2UubWluID0gTWF0aC5taW4oZWxlbWVudFtheGlzXSwgZ3JvdXAucmFuZ2UubWluKTtcbiAgICBncm91cC5yYW5nZS5tYXggPSBNYXRoLm1heChlbGVtZW50W2F4aXNdICsgZWxlbWVudFtkaW1lbnNpb25dLCBncm91cC5yYW5nZS5tYXgpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2VudGVyKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gZWxlbWVudFtheGlzXSArIGVsZW1lbnRbZGltZW5zaW9uXSAvIDI7XG4gIH1cblxuICBmdW5jdGlvbiBsYXN0SWR4KGFycikge1xuICAgIHJldHVybiBhcnIubGVuZ3RoIC0gMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJhbmdlRGlmZihyYW5nZSkge1xuICAgIHJldHVybiByYW5nZS5tYXggLSByYW5nZS5taW47XG4gIH1cblxuICBmdW5jdGlvbiBjZW50ZXJFbGVtZW50KHJlZkNlbnRlciwgZWxlbWVudCkge1xuICAgIHZhciBkZWx0YSA9IHsgeTogMCB9O1xuXG4gICAgZGVsdGFbYXhpc10gPSByZWZDZW50ZXIgLSBjZW50ZXIoZWxlbWVudCk7XG5cbiAgICBpZiAoZGVsdGFbYXhpc10pIHtcblxuICAgICAgZGVsdGFbT0ZGX0FYSVNbYXhpc11dID0gMDtcblxuICAgICAgbW9kZWxpbmcubW92ZUVsZW1lbnRzKFsgZWxlbWVudCBdLCBkZWx0YSwgZWxlbWVudC5wYXJlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBmaXJzdEdyb3VwID0gZ3JvdXBzWzBdLFxuICAgICAgbGFzdEdyb3VwSWR4ID0gbGFzdElkeChncm91cHMpLFxuICAgICAgbGFzdEdyb3VwID0gZ3JvdXBzWyBsYXN0R3JvdXBJZHggXTtcblxuICB2YXIgbWFyZ2luLFxuICAgICAgc3BhY2VJbkJldHdlZW4sXG4gICAgICBncm91cHNTaXplID0gMDsgLy8gdGhlIHNpemUgb2YgZWFjaCByYW5nZVxuXG4gIGZvckVhY2goZ3JvdXBzLCBmdW5jdGlvbihncm91cCwgaWR4KSB7XG4gICAgdmFyIHNvcnRlZEVsZW1lbnRzLFxuICAgICAgICByZWZFbGVtLFxuICAgICAgICByZWZDZW50ZXI7XG5cbiAgICBpZiAoZ3JvdXAuZWxlbWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgaWYgKGlkeCAmJiBpZHggIT09IGdyb3Vwcy5sZW5ndGggLSAxKSB7XG4gICAgICAgIHVwZGF0ZVJhbmdlKGdyb3VwLCBncm91cC5lbGVtZW50c1swXSk7XG5cbiAgICAgICAgZ3JvdXBzU2l6ZSArPSByYW5nZURpZmYoZ3JvdXAucmFuZ2UpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNvcnRlZEVsZW1lbnRzID0gc29ydEJ5KGdyb3VwLmVsZW1lbnRzLCBheGlzKTtcblxuICAgIHJlZkVsZW0gPSBzb3J0ZWRFbGVtZW50c1swXTtcblxuICAgIGlmIChpZHggPT09IGxhc3RHcm91cElkeCkge1xuICAgICAgcmVmRWxlbSA9IHNvcnRlZEVsZW1lbnRzW2xhc3RJZHgoc29ydGVkRWxlbWVudHMpXTtcbiAgICB9XG5cbiAgICByZWZDZW50ZXIgPSBjZW50ZXIocmVmRWxlbSk7XG5cbiAgICAvLyB3YW5uYSB1cGRhdGUgdGhlIHJhbmdlcyBhZnRlciB0aGUgc2hhcGVzIGhhdmUgYmVlbiBjZW50ZXJlZFxuICAgIGdyb3VwLnJhbmdlID0gbnVsbDtcblxuICAgIGZvckVhY2goc29ydGVkRWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICAgICAgY2VudGVyRWxlbWVudChyZWZDZW50ZXIsIGVsZW1lbnQpO1xuXG4gICAgICBpZiAoZ3JvdXAucmFuZ2UgPT09IG51bGwpIHtcbiAgICAgICAgZ3JvdXAucmFuZ2UgPSB7XG4gICAgICAgICAgbWluOiBlbGVtZW50W2F4aXNdLFxuICAgICAgICAgIG1heDogZWxlbWVudFtheGlzXSArIGVsZW1lbnRbZGltZW5zaW9uXVxuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gdXBkYXRlIGdyb3VwJ3MgcmFuZ2UgYWZ0ZXIgY2VudGVyaW5nIHRoZSByYW5nZSBlbGVtZW50c1xuICAgICAgdXBkYXRlUmFuZ2UoZ3JvdXAsIGVsZW1lbnQpO1xuICAgIH0pO1xuXG4gICAgaWYgKGlkeCAmJiBpZHggIT09IGdyb3Vwcy5sZW5ndGggLSAxKSB7XG4gICAgICBncm91cHNTaXplICs9IHJhbmdlRGlmZihncm91cC5yYW5nZSk7XG4gICAgfVxuICB9KTtcblxuICBzcGFjZUluQmV0d2VlbiA9IE1hdGguYWJzKGxhc3RHcm91cC5yYW5nZS5taW4gLSBmaXJzdEdyb3VwLnJhbmdlLm1heCk7XG5cbiAgbWFyZ2luID0gTWF0aC5yb3VuZCgoc3BhY2VJbkJldHdlZW4gLSBncm91cHNTaXplKSAvIChncm91cHMubGVuZ3RoIC0gMSkpO1xuXG4gIGlmIChtYXJnaW4gPCBncm91cHMubGVuZ3RoIC0gMSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvckVhY2goZ3JvdXBzLCBmdW5jdGlvbihncm91cCwgZ3JvdXBJZHgpIHtcbiAgICB2YXIgZGVsdGEgPSB7fSxcbiAgICAgICAgcHJldkdyb3VwO1xuXG4gICAgaWYgKGdyb3VwID09PSBmaXJzdEdyb3VwIHx8IGdyb3VwID09PSBsYXN0R3JvdXApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwcmV2R3JvdXAgPSBncm91cHNbZ3JvdXBJZHggLSAxXTtcblxuICAgIGdyb3VwLnJhbmdlLm1heCA9IDA7XG5cbiAgICBmb3JFYWNoKGdyb3VwLmVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50LCBpZHgpIHtcbiAgICAgIGRlbHRhW09GRl9BWElTW2F4aXNdXSA9IDA7XG4gICAgICBkZWx0YVtheGlzXSA9IChwcmV2R3JvdXAucmFuZ2UubWF4IC0gZWxlbWVudFtheGlzXSkgKyBtYXJnaW47XG5cbiAgICAgIGlmIChncm91cC5yYW5nZS5taW4gIT09IGVsZW1lbnRbYXhpc10pIHtcbiAgICAgICAgZGVsdGFbYXhpc10gKz0gZWxlbWVudFtheGlzXSAtIGdyb3VwLnJhbmdlLm1pbjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRlbHRhW2F4aXNdKSB7XG4gICAgICAgIG1vZGVsaW5nLm1vdmVFbGVtZW50cyhbIGVsZW1lbnQgXSwgZGVsdGEsIGVsZW1lbnQucGFyZW50KTtcbiAgICAgIH1cblxuICAgICAgZ3JvdXAucmFuZ2UubWF4ID0gTWF0aC5tYXgoZWxlbWVudFtheGlzXSArIGVsZW1lbnRbZGltZW5zaW9uXSwgaWR4ID8gZ3JvdXAucmFuZ2UubWF4IDogMCk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuRGlzdHJpYnV0ZUVsZW1lbnRzLnByb3RvdHlwZS5wb3N0RXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxufTtcbiIsImltcG9ydCB7IGFzc2lnbiB9IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgcmV2ZXJzaWJsZSBtb3Zpbmcgb2Ygc2hhcGVzLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBMYXlvdXRDb25uZWN0aW9uSGFuZGxlcihsYXlvdXRlciwgY2FudmFzKSB7XG4gIHRoaXMuX2xheW91dGVyID0gbGF5b3V0ZXI7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbn1cblxuTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXIuJGluamVjdCA9IFsgJ2xheW91dGVyJywgJ2NhbnZhcycgXTtcblxuTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb247XG5cbiAgdmFyIG9sZFdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzO1xuXG4gIGFzc2lnbihjb250ZXh0LCB7XG4gICAgb2xkV2F5cG9pbnRzOiBvbGRXYXlwb2ludHNcbiAgfSk7XG5cbiAgY29ubmVjdGlvbi53YXlwb2ludHMgPSB0aGlzLl9sYXlvdXRlci5sYXlvdXRDb25uZWN0aW9uKGNvbm5lY3Rpb24sIGNvbnRleHQuaGludHMpO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTtcblxuTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbjtcblxuICBjb25uZWN0aW9uLndheXBvaW50cyA9IGNvbnRleHQub2xkV2F5cG9pbnRzO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTtcbiIsImltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cblxuaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIHJlbW92ZSBhcyBjb2xsZWN0aW9uUmVtb3ZlXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyByZXZlcnNpYmxlIG1vdmluZyBvZiBjb25uZWN0aW9ucy5cbiAqXG4gKiBUaGUgaGFuZGxlciBkaWZmZXJzIGZyb20gdGhlIGxheW91dCBjb25uZWN0aW9uIGhhbmRsZXIgaW4gYSBzZW5zZVxuICogdGhhdCBpdCBwcmVzZXJ2ZXMgdGhlIGNvbm5lY3Rpb24gbGF5b3V0LlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb3ZlQ29ubmVjdGlvbkhhbmRsZXIoKSB7IH1cblxuXG5Nb3ZlQ29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICBkZWx0YSA9IGNvbnRleHQuZGVsdGE7XG5cbiAgdmFyIG5ld1BhcmVudCA9IGNvbnRleHQubmV3UGFyZW50IHx8IGNvbm5lY3Rpb24ucGFyZW50LFxuICAgICAgbmV3UGFyZW50SW5kZXggPSBjb250ZXh0Lm5ld1BhcmVudEluZGV4LFxuICAgICAgb2xkUGFyZW50ID0gY29ubmVjdGlvbi5wYXJlbnQ7XG5cbiAgLy8gc2F2ZSBvbGQgcGFyZW50IGluIGNvbnRleHRcbiAgY29udGV4dC5vbGRQYXJlbnQgPSBvbGRQYXJlbnQ7XG4gIGNvbnRleHQub2xkUGFyZW50SW5kZXggPSBjb2xsZWN0aW9uUmVtb3ZlKG9sZFBhcmVudC5jaGlsZHJlbiwgY29ubmVjdGlvbik7XG5cbiAgLy8gYWRkIHRvIG5ldyBwYXJlbnQgYXQgcG9zaXRpb25cbiAgY29sbGVjdGlvbkFkZChuZXdQYXJlbnQuY2hpbGRyZW4sIGNvbm5lY3Rpb24sIG5ld1BhcmVudEluZGV4KTtcblxuICAvLyB1cGRhdGUgcGFyZW50XG4gIGNvbm5lY3Rpb24ucGFyZW50ID0gbmV3UGFyZW50O1xuXG4gIC8vIHVwZGF0ZSB3YXlwb2ludCBwb3NpdGlvbnNcbiAgZm9yRWFjaChjb25uZWN0aW9uLndheXBvaW50cywgZnVuY3Rpb24ocCkge1xuICAgIHAueCArPSBkZWx0YS54O1xuICAgIHAueSArPSBkZWx0YS55O1xuXG4gICAgaWYgKHAub3JpZ2luYWwpIHtcbiAgICAgIHAub3JpZ2luYWwueCArPSBkZWx0YS54O1xuICAgICAgcC5vcmlnaW5hbC55ICs9IGRlbHRhLnk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gY29ubmVjdGlvbjtcbn07XG5cbk1vdmVDb25uZWN0aW9uSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgbmV3UGFyZW50ID0gY29ubmVjdGlvbi5wYXJlbnQsXG4gICAgICBvbGRQYXJlbnQgPSBjb250ZXh0Lm9sZFBhcmVudCxcbiAgICAgIG9sZFBhcmVudEluZGV4ID0gY29udGV4dC5vbGRQYXJlbnRJbmRleCxcbiAgICAgIGRlbHRhID0gY29udGV4dC5kZWx0YTtcblxuICAvLyByZW1vdmUgZnJvbSBuZXdQYXJlbnRcbiAgY29sbGVjdGlvblJlbW92ZShuZXdQYXJlbnQuY2hpbGRyZW4sIGNvbm5lY3Rpb24pO1xuXG4gIC8vIHJlc3RvcmUgcHJldmlvdXMgbG9jYXRpb24gaW4gb2xkIHBhcmVudFxuICBjb2xsZWN0aW9uQWRkKG9sZFBhcmVudC5jaGlsZHJlbiwgY29ubmVjdGlvbiwgb2xkUGFyZW50SW5kZXgpO1xuXG4gIC8vIHJlc3RvcmUgcGFyZW50XG4gIGNvbm5lY3Rpb24ucGFyZW50ID0gb2xkUGFyZW50O1xuXG4gIC8vIHJldmVydCB0byBvbGQgd2F5cG9pbnQgcG9zaXRpb25zXG4gIGZvckVhY2goY29ubmVjdGlvbi53YXlwb2ludHMsIGZ1bmN0aW9uKHApIHtcbiAgICBwLnggLT0gZGVsdGEueDtcbiAgICBwLnkgLT0gZGVsdGEueTtcblxuICAgIGlmIChwLm9yaWdpbmFsKSB7XG4gICAgICBwLm9yaWdpbmFsLnggLT0gZGVsdGEueDtcbiAgICAgIHAub3JpZ2luYWwueSAtPSBkZWx0YS55O1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59OyIsImltcG9ydCBNb3ZlSGVscGVyIGZyb20gJy4vaGVscGVyL01vdmVIZWxwZXInO1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyByZXZlcnNpYmxlIG1vdmluZyBvZiBzaGFwZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1vdmVFbGVtZW50c0hhbmRsZXIobW9kZWxpbmcpIHtcbiAgdGhpcy5faGVscGVyID0gbmV3IE1vdmVIZWxwZXIobW9kZWxpbmcpO1xufVxuXG5Nb3ZlRWxlbWVudHNIYW5kbGVyLiRpbmplY3QgPSBbICdtb2RlbGluZycgXTtcblxuTW92ZUVsZW1lbnRzSGFuZGxlci5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgY29udGV4dC5jbG9zdXJlID0gdGhpcy5faGVscGVyLmdldENsb3N1cmUoY29udGV4dC5zaGFwZXMpO1xufTtcblxuTW92ZUVsZW1lbnRzSGFuZGxlci5wcm90b3R5cGUucG9zdEV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGhpbnRzID0gY29udGV4dC5oaW50cyxcbiAgICAgIHByaW1hcnlTaGFwZTtcblxuICBpZiAoaGludHMgJiYgaGludHMucHJpbWFyeVNoYXBlKSB7XG4gICAgcHJpbWFyeVNoYXBlID0gaGludHMucHJpbWFyeVNoYXBlO1xuICAgIGhpbnRzLm9sZFBhcmVudCA9IHByaW1hcnlTaGFwZS5wYXJlbnQ7XG4gIH1cblxuICB0aGlzLl9oZWxwZXIubW92ZUNsb3N1cmUoXG4gICAgY29udGV4dC5jbG9zdXJlLFxuICAgIGNvbnRleHQuZGVsdGEsXG4gICAgY29udGV4dC5uZXdQYXJlbnQsXG4gICAgY29udGV4dC5uZXdIb3N0LFxuICAgIHByaW1hcnlTaGFwZVxuICApO1xufTsiLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIHBpY2tcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgTW92ZUhlbHBlciBmcm9tICcuL2hlbHBlci9Nb3ZlSGVscGVyJztcblxuaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIHJlbW92ZSBhcyBjb2xsZWN0aW9uUmVtb3ZlXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5pbXBvcnQge1xuICBnZXRNb3ZlZFNvdXJjZUFuY2hvcixcbiAgZ2V0TW92ZWRUYXJnZXRBbmNob3Jcbn0gZnJvbSAnLi9oZWxwZXIvQW5jaG9yc0hlbHBlcic7XG5cblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBpbXBsZW1lbnRzIHJldmVyc2libGUgbW92aW5nIG9mIHNoYXBlcy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW92ZVNoYXBlSGFuZGxlcihtb2RlbGluZykge1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xuXG4gIHRoaXMuX2hlbHBlciA9IG5ldyBNb3ZlSGVscGVyKG1vZGVsaW5nKTtcbn1cblxuTW92ZVNoYXBlSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cblxuTW92ZVNoYXBlSGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgZGVsdGEgPSBjb250ZXh0LmRlbHRhLFxuICAgICAgbmV3UGFyZW50ID0gY29udGV4dC5uZXdQYXJlbnQgfHwgc2hhcGUucGFyZW50LFxuICAgICAgbmV3UGFyZW50SW5kZXggPSBjb250ZXh0Lm5ld1BhcmVudEluZGV4LFxuICAgICAgb2xkUGFyZW50ID0gc2hhcGUucGFyZW50O1xuXG4gIGNvbnRleHQub2xkQm91bmRzID0gcGljayhzaGFwZSwgWyAneCcsICd5JywgJ3dpZHRoJywgJ2hlaWdodCddKTtcblxuICAvLyBzYXZlIG9sZCBwYXJlbnQgaW4gY29udGV4dFxuICBjb250ZXh0Lm9sZFBhcmVudCA9IG9sZFBhcmVudDtcbiAgY29udGV4dC5vbGRQYXJlbnRJbmRleCA9IGNvbGxlY3Rpb25SZW1vdmUob2xkUGFyZW50LmNoaWxkcmVuLCBzaGFwZSk7XG5cbiAgLy8gYWRkIHRvIG5ldyBwYXJlbnQgYXQgcG9zaXRpb25cbiAgY29sbGVjdGlvbkFkZChuZXdQYXJlbnQuY2hpbGRyZW4sIHNoYXBlLCBuZXdQYXJlbnRJbmRleCk7XG5cbiAgLy8gdXBkYXRlIHNoYXBlIHBhcmVudCArIHBvc2l0aW9uXG4gIGFzc2lnbihzaGFwZSwge1xuICAgIHBhcmVudDogbmV3UGFyZW50LFxuICAgIHg6IHNoYXBlLnggKyBkZWx0YS54LFxuICAgIHk6IHNoYXBlLnkgKyBkZWx0YS55XG4gIH0pO1xuXG4gIHJldHVybiBzaGFwZTtcbn07XG5cbk1vdmVTaGFwZUhhbmRsZXIucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBkZWx0YSA9IGNvbnRleHQuZGVsdGEsXG4gICAgICBoaW50cyA9IGNvbnRleHQuaGludHM7XG5cbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmc7XG5cbiAgaWYgKGhpbnRzLmxheW91dCAhPT0gZmFsc2UpIHtcblxuICAgIGZvckVhY2goc2hhcGUuaW5jb21pbmcsIGZ1bmN0aW9uKGMpIHtcbiAgICAgIG1vZGVsaW5nLmxheW91dENvbm5lY3Rpb24oYywge1xuICAgICAgICBjb25uZWN0aW9uRW5kOiBnZXRNb3ZlZFRhcmdldEFuY2hvcihjLCBzaGFwZSwgZGVsdGEpXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGZvckVhY2goc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGMpIHtcbiAgICAgIG1vZGVsaW5nLmxheW91dENvbm5lY3Rpb24oYywge1xuICAgICAgICBjb25uZWN0aW9uU3RhcnQ6IGdldE1vdmVkU291cmNlQW5jaG9yKGMsIHNoYXBlLCBkZWx0YSlcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGhpbnRzLnJlY3Vyc2UgIT09IGZhbHNlKSB7XG4gICAgdGhpcy5tb3ZlQ2hpbGRyZW4oY29udGV4dCk7XG4gIH1cbn07XG5cbk1vdmVTaGFwZUhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgb2xkUGFyZW50ID0gY29udGV4dC5vbGRQYXJlbnQsXG4gICAgICBvbGRQYXJlbnRJbmRleCA9IGNvbnRleHQub2xkUGFyZW50SW5kZXgsXG4gICAgICBkZWx0YSA9IGNvbnRleHQuZGVsdGE7XG5cbiAgLy8gcmVzdG9yZSBwcmV2aW91cyBsb2NhdGlvbiBpbiBvbGQgcGFyZW50XG4gIGNvbGxlY3Rpb25BZGQob2xkUGFyZW50LmNoaWxkcmVuLCBzaGFwZSwgb2xkUGFyZW50SW5kZXgpO1xuXG4gIC8vIHJldmVydCB0byBvbGQgcG9zaXRpb24gYW5kIHBhcmVudFxuICBhc3NpZ24oc2hhcGUsIHtcbiAgICBwYXJlbnQ6IG9sZFBhcmVudCxcbiAgICB4OiBzaGFwZS54IC0gZGVsdGEueCxcbiAgICB5OiBzaGFwZS55IC0gZGVsdGEueVxuICB9KTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG5Nb3ZlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5tb3ZlQ2hpbGRyZW4gPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGRlbHRhID0gY29udGV4dC5kZWx0YSxcbiAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZTtcblxuICB0aGlzLl9oZWxwZXIubW92ZVJlY3Vyc2l2ZShzaGFwZS5jaGlsZHJlbiwgZGVsdGEsIG51bGwpO1xufTtcblxuTW92ZVNoYXBlSGFuZGxlci5wcm90b3R5cGUuZ2V0TmV3UGFyZW50ID0gZnVuY3Rpb24oY29udGV4dCkge1xuICByZXR1cm4gY29udGV4dC5uZXdQYXJlbnQgfHwgY29udGV4dC5zaGFwZS5wYXJlbnQ7XG59O1xuIiwiaW1wb3J0IHsgaXNBcnJheSB9IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIFJlY29ubmVjdCBjb25uZWN0aW9uIGhhbmRsZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVjb25uZWN0Q29ubmVjdGlvbkhhbmRsZXIobW9kZWxpbmcpIHtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbn1cblxuUmVjb25uZWN0Q29ubmVjdGlvbkhhbmRsZXIuJGluamVjdCA9IFsgJ21vZGVsaW5nJyBdO1xuXG5SZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIG5ld1NvdXJjZSA9IGNvbnRleHQubmV3U291cmNlLFxuICAgICAgbmV3VGFyZ2V0ID0gY29udGV4dC5uZXdUYXJnZXQsXG4gICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgZG9ja2luZ09yUG9pbnRzID0gY29udGV4dC5kb2NraW5nT3JQb2ludHM7XG5cbiAgaWYgKCFuZXdTb3VyY2UgJiYgIW5ld1RhcmdldCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbmV3U291cmNlIG9yIG5ld1RhcmdldCByZXF1aXJlZCcpO1xuICB9XG5cbiAgaWYgKGlzQXJyYXkoZG9ja2luZ09yUG9pbnRzKSkge1xuICAgIGNvbnRleHQub2xkV2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBkb2NraW5nT3JQb2ludHM7XG4gIH1cblxuICBpZiAobmV3U291cmNlKSB7XG4gICAgY29udGV4dC5vbGRTb3VyY2UgPSBjb25uZWN0aW9uLnNvdXJjZTtcbiAgICBjb25uZWN0aW9uLnNvdXJjZSA9IG5ld1NvdXJjZTtcbiAgfVxuXG4gIGlmIChuZXdUYXJnZXQpIHtcbiAgICBjb250ZXh0Lm9sZFRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0O1xuICAgIGNvbm5lY3Rpb24udGFyZ2V0ID0gbmV3VGFyZ2V0O1xuICB9XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59O1xuXG5SZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlci5wcm90b3R5cGUucG9zdEV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgbmV3U291cmNlID0gY29udGV4dC5uZXdTb3VyY2UsXG4gICAgICBuZXdUYXJnZXQgPSBjb250ZXh0Lm5ld1RhcmdldCxcbiAgICAgIGRvY2tpbmdPclBvaW50cyA9IGNvbnRleHQuZG9ja2luZ09yUG9pbnRzLFxuICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gIHZhciBsYXlvdXRDb25uZWN0aW9uSGludHMgPSB7fTtcblxuICBpZiAoaGludHMuY29ubmVjdGlvblN0YXJ0KSB7XG4gICAgbGF5b3V0Q29ubmVjdGlvbkhpbnRzLmNvbm5lY3Rpb25TdGFydCA9IGhpbnRzLmNvbm5lY3Rpb25TdGFydDtcbiAgfVxuXG4gIGlmIChoaW50cy5jb25uZWN0aW9uRW5kKSB7XG4gICAgbGF5b3V0Q29ubmVjdGlvbkhpbnRzLmNvbm5lY3Rpb25FbmQgPSBoaW50cy5jb25uZWN0aW9uRW5kO1xuICB9XG5cbiAgaWYgKGhpbnRzLmxheW91dENvbm5lY3Rpb24gPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKG5ld1NvdXJjZSAmJiAoIW5ld1RhcmdldCB8fCBoaW50cy5kb2NraW5nID09PSAnc291cmNlJykpIHtcbiAgICBsYXlvdXRDb25uZWN0aW9uSGludHMuY29ubmVjdGlvblN0YXJ0ID0gbGF5b3V0Q29ubmVjdGlvbkhpbnRzLmNvbm5lY3Rpb25TdGFydFxuICAgICAgfHwgZ2V0RG9ja2luZyhpc0FycmF5KGRvY2tpbmdPclBvaW50cykgPyBkb2NraW5nT3JQb2ludHNbIDAgXSA6IGRvY2tpbmdPclBvaW50cyk7XG4gIH1cblxuICBpZiAobmV3VGFyZ2V0ICYmICghbmV3U291cmNlIHx8IGhpbnRzLmRvY2tpbmcgPT09ICd0YXJnZXQnKSkge1xuICAgIGxheW91dENvbm5lY3Rpb25IaW50cy5jb25uZWN0aW9uRW5kID0gbGF5b3V0Q29ubmVjdGlvbkhpbnRzLmNvbm5lY3Rpb25FbmRcbiAgICAgIHx8IGdldERvY2tpbmcoaXNBcnJheShkb2NraW5nT3JQb2ludHMpID8gZG9ja2luZ09yUG9pbnRzWyBkb2NraW5nT3JQb2ludHMubGVuZ3RoIC0gMSBdIDogZG9ja2luZ09yUG9pbnRzKTtcbiAgfVxuXG4gIGlmIChoaW50cy5uZXdXYXlwb2ludHMpIHtcbiAgICBsYXlvdXRDb25uZWN0aW9uSGludHMud2F5cG9pbnRzID0gaGludHMubmV3V2F5cG9pbnRzO1xuICB9XG5cbiAgdGhpcy5fbW9kZWxpbmcubGF5b3V0Q29ubmVjdGlvbihjb25uZWN0aW9uLCBsYXlvdXRDb25uZWN0aW9uSGludHMpO1xufTtcblxuUmVjb25uZWN0Q29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIG9sZFNvdXJjZSA9IGNvbnRleHQub2xkU291cmNlLFxuICAgICAgb2xkVGFyZ2V0ID0gY29udGV4dC5vbGRUYXJnZXQsXG4gICAgICBvbGRXYXlwb2ludHMgPSBjb250ZXh0Lm9sZFdheXBvaW50cyxcbiAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb247XG5cbiAgaWYgKG9sZFNvdXJjZSkge1xuICAgIGNvbm5lY3Rpb24uc291cmNlID0gb2xkU291cmNlO1xuICB9XG5cbiAgaWYgKG9sZFRhcmdldCkge1xuICAgIGNvbm5lY3Rpb24udGFyZ2V0ID0gb2xkVGFyZ2V0O1xuICB9XG5cbiAgaWYgKG9sZFdheXBvaW50cykge1xuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gb2xkV2F5cG9pbnRzO1xuICB9XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59O1xuXG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldERvY2tpbmcocG9pbnQpIHtcbiAgcmV0dXJuIHBvaW50Lm9yaWdpbmFsIHx8IHBvaW50O1xufSIsImltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGdldFJlc2l6ZWRTb3VyY2VBbmNob3IsXG4gIGdldFJlc2l6ZWRUYXJnZXRBbmNob3Jcbn0gZnJvbSAnLi9oZWxwZXIvQW5jaG9yc0hlbHBlcic7XG5cbi8qKlxuICogUmVwbGFjZSBzaGFwZSBieSBhZGRpbmcgbmV3IHNoYXBlIGFuZCByZW1vdmluZyBvbGQgc2hhcGUuIEluY29taW5nIGFuZCBvdXRnb2luZyBjb25uZWN0aW9ucyB3aWxsXG4gKiBiZSBrZXB0IGlmIHBvc3NpYmxlLlxuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlcGxhY2VTaGFwZUhhbmRsZXIobW9kZWxpbmcsIHJ1bGVzKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX3J1bGVzID0gcnVsZXM7XG59XG5cblJlcGxhY2VTaGFwZUhhbmRsZXIuJGluamVjdCA9IFsgJ21vZGVsaW5nJywgJ3J1bGVzJyBdO1xuXG5cbi8qKlxuICogQWRkIG5ldyBzaGFwZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IGNvbnRleHQub2xkU2hhcGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0Lm5ld0RhdGFcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZXh0Lm5ld0RhdGEudHlwZVxuICogQHBhcmFtIHtudW1iZXJ9IGNvbnRleHQubmV3RGF0YS54XG4gKiBAcGFyYW0ge251bWJlcn0gY29udGV4dC5uZXdEYXRhLnlcbiAqIEBwYXJhbSB7T2JqZWN0fSBbaGludHNdXG4gKi9cblJlcGxhY2VTaGFwZUhhbmRsZXIucHJvdG90eXBlLnByZUV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBzZWxmID0gdGhpcyxcbiAgICAgIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmcsXG4gICAgICBydWxlcyA9IHRoaXMuX3J1bGVzO1xuXG4gIHZhciBvbGRTaGFwZSA9IGNvbnRleHQub2xkU2hhcGUsXG4gICAgICBuZXdEYXRhID0gY29udGV4dC5uZXdEYXRhLFxuICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgbmV3U2hhcGU7XG5cbiAgZnVuY3Rpb24gY2FuUmVjb25uZWN0KHNvdXJjZSwgdGFyZ2V0LCBjb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuIHJ1bGVzLmFsbG93ZWQoJ2Nvbm5lY3Rpb24ucmVjb25uZWN0Jywge1xuICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICB9KTtcbiAgfVxuXG4gIC8vICgxKSBhZGQgbmV3IHNoYXBlIGF0IGdpdmVuIHBvc2l0aW9uXG4gIHZhciBwb3NpdGlvbiA9IHtcbiAgICB4OiBuZXdEYXRhLngsXG4gICAgeTogbmV3RGF0YS55XG4gIH07XG5cbiAgdmFyIG9sZEJvdW5kcyA9IHtcbiAgICB4OiBvbGRTaGFwZS54LFxuICAgIHk6IG9sZFNoYXBlLnksXG4gICAgd2lkdGg6IG9sZFNoYXBlLndpZHRoLFxuICAgIGhlaWdodDogb2xkU2hhcGUuaGVpZ2h0XG4gIH07XG5cbiAgbmV3U2hhcGUgPSBjb250ZXh0Lm5ld1NoYXBlID1cbiAgICBjb250ZXh0Lm5ld1NoYXBlIHx8XG4gICAgc2VsZi5jcmVhdGVTaGFwZShuZXdEYXRhLCBwb3NpdGlvbiwgb2xkU2hhcGUucGFyZW50LCBoaW50cyk7XG5cbiAgLy8gKDIpIHVwZGF0ZSBob3N0XG4gIGlmIChvbGRTaGFwZS5ob3N0KSB7XG4gICAgbW9kZWxpbmcudXBkYXRlQXR0YWNobWVudChuZXdTaGFwZSwgb2xkU2hhcGUuaG9zdCk7XG4gIH1cblxuICAvLyAoMykgYWRvcHQgYWxsIGNoaWxkcmVuIGZyb20gb2xkIHNoYXBlXG4gIHZhciBjaGlsZHJlbjtcblxuICBpZiAoaGludHMubW92ZUNoaWxkcmVuICE9PSBmYWxzZSkge1xuICAgIGNoaWxkcmVuID0gb2xkU2hhcGUuY2hpbGRyZW4uc2xpY2UoKTtcblxuICAgIG1vZGVsaW5nLm1vdmVFbGVtZW50cyhjaGlsZHJlbiwgeyB4OiAwLCB5OiAwIH0sIG5ld1NoYXBlLCBoaW50cyk7XG4gIH1cblxuICAvLyAoNCkgcmVjb25uZWN0IGNvbm5lY3Rpb25zIHRvIG5ldyBzaGFwZSBpZiBwb3NzaWJsZVxuICB2YXIgaW5jb21pbmcgPSBvbGRTaGFwZS5pbmNvbWluZy5zbGljZSgpLFxuICAgICAgb3V0Z29pbmcgPSBvbGRTaGFwZS5vdXRnb2luZy5zbGljZSgpO1xuXG4gIGZvckVhY2goaW5jb21pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2UsXG4gICAgICAgIGFsbG93ZWQgPSBjYW5SZWNvbm5lY3Qoc291cmNlLCBuZXdTaGFwZSwgY29ubmVjdGlvbik7XG5cbiAgICBpZiAoYWxsb3dlZCkge1xuICAgICAgc2VsZi5yZWNvbm5lY3RFbmQoXG4gICAgICAgIGNvbm5lY3Rpb24sIG5ld1NoYXBlLFxuICAgICAgICBnZXRSZXNpemVkVGFyZ2V0QW5jaG9yKGNvbm5lY3Rpb24sIG5ld1NoYXBlLCBvbGRCb3VuZHMpLFxuICAgICAgICBoaW50c1xuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuXG4gIGZvckVhY2gob3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIGFsbG93ZWQgPSBjYW5SZWNvbm5lY3QobmV3U2hhcGUsIHRhcmdldCwgY29ubmVjdGlvbik7XG5cbiAgICBpZiAoYWxsb3dlZCkge1xuICAgICAgc2VsZi5yZWNvbm5lY3RTdGFydChcbiAgICAgICAgY29ubmVjdGlvbiwgbmV3U2hhcGUsXG4gICAgICAgIGdldFJlc2l6ZWRTb3VyY2VBbmNob3IoY29ubmVjdGlvbiwgbmV3U2hhcGUsIG9sZEJvdW5kcyksXG4gICAgICAgIGhpbnRzXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlIG9sZCBzaGFwZS5cbiAqL1xuUmVwbGFjZVNoYXBlSGFuZGxlci5wcm90b3R5cGUucG9zdEV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBvbGRTaGFwZSA9IGNvbnRleHQub2xkU2hhcGU7XG5cbiAgdGhpcy5fbW9kZWxpbmcucmVtb3ZlU2hhcGUob2xkU2hhcGUpO1xufTtcblxuXG5SZXBsYWNlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge307XG5cblxuUmVwbGFjZVNoYXBlSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge307XG5cblxuUmVwbGFjZVNoYXBlSGFuZGxlci5wcm90b3R5cGUuY3JlYXRlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgcG9zaXRpb24sIHRhcmdldCwgaGludHMpIHtcbiAgcmV0dXJuIHRoaXMuX21vZGVsaW5nLmNyZWF0ZVNoYXBlKHNoYXBlLCBwb3NpdGlvbiwgdGFyZ2V0LCBoaW50cyk7XG59O1xuXG5cblJlcGxhY2VTaGFwZUhhbmRsZXIucHJvdG90eXBlLnJlY29ubmVjdFN0YXJ0ID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgbmV3U291cmNlLCBkb2NraW5nUG9pbnQsIGhpbnRzKSB7XG4gIHRoaXMuX21vZGVsaW5nLnJlY29ubmVjdFN0YXJ0KGNvbm5lY3Rpb24sIG5ld1NvdXJjZSwgZG9ja2luZ1BvaW50LCBoaW50cyk7XG59O1xuXG5cblJlcGxhY2VTaGFwZUhhbmRsZXIucHJvdG90eXBlLnJlY29ubmVjdEVuZCA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIG5ld1RhcmdldCwgZG9ja2luZ1BvaW50LCBoaW50cykge1xuICB0aGlzLl9tb2RlbGluZy5yZWNvbm5lY3RFbmQoY29ubmVjdGlvbiwgbmV3VGFyZ2V0LCBkb2NraW5nUG9pbnQsIGhpbnRzKTtcbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRSZXNpemVkU291cmNlQW5jaG9yLFxuICBnZXRSZXNpemVkVGFyZ2V0QW5jaG9yXG59IGZyb20gJy4vaGVscGVyL0FuY2hvcnNIZWxwZXInO1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyByZXZlcnNpYmxlIHJlc2l6aW5nIG9mIHNoYXBlcy5cbiAqXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSZXNpemVTaGFwZUhhbmRsZXIobW9kZWxpbmcpIHtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbn1cblxuUmVzaXplU2hhcGVIYW5kbGVyLiRpbmplY3QgPSBbICdtb2RlbGluZycgXTtcblxuLyoqXG4gKiB7XG4gKiAgIHNoYXBlOiB7Li4uLn1cbiAqICAgbmV3Qm91bmRzOiB7XG4gKiAgICAgd2lkdGg6ICAyMCxcbiAqICAgICBoZWlnaHQ6IDQwLFxuICogICAgIHg6ICAgICAgIDUsXG4gKiAgICAgeTogICAgICAxMFxuICogICB9XG4gKlxuICogfVxuICovXG5SZXNpemVTaGFwZUhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBuZXdCb3VuZHMgPSBjb250ZXh0Lm5ld0JvdW5kcyxcbiAgICAgIG1pbkJvdW5kcyA9IGNvbnRleHQubWluQm91bmRzO1xuXG4gIGlmIChuZXdCb3VuZHMueCA9PT0gdW5kZWZpbmVkIHx8IG5ld0JvdW5kcy55ID09PSB1bmRlZmluZWQgfHxcbiAgICAgIG5ld0JvdW5kcy53aWR0aCA9PT0gdW5kZWZpbmVkIHx8IG5ld0JvdW5kcy5oZWlnaHQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbmV3Qm91bmRzIG11c3QgaGF2ZSB7eCwgeSwgd2lkdGgsIGhlaWdodH0gcHJvcGVydGllcycpO1xuICB9XG5cbiAgaWYgKG1pbkJvdW5kcyAmJiAobmV3Qm91bmRzLndpZHRoIDwgbWluQm91bmRzLndpZHRoXG4gICAgfHwgbmV3Qm91bmRzLmhlaWdodCA8IG1pbkJvdW5kcy5oZWlnaHQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd3aWR0aCBhbmQgaGVpZ2h0IGNhbm5vdCBiZSBsZXNzIHRoYW4gbWluaW11bSBoZWlnaHQgYW5kIHdpZHRoJyk7XG4gIH0gZWxzZSBpZiAoIW1pbkJvdW5kc1xuICAgICYmIG5ld0JvdW5kcy53aWR0aCA8IDEwIHx8IG5ld0JvdW5kcy5oZWlnaHQgPCAxMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignd2lkdGggYW5kIGhlaWdodCBjYW5ub3QgYmUgbGVzcyB0aGFuIDEwcHgnKTtcbiAgfVxuXG4gIC8vIHNhdmUgb2xkIGJib3ggaW4gY29udGV4dFxuICBjb250ZXh0Lm9sZEJvdW5kcyA9IHtcbiAgICB3aWR0aDogIHNoYXBlLndpZHRoLFxuICAgIGhlaWdodDogc2hhcGUuaGVpZ2h0LFxuICAgIHg6ICAgICAgc2hhcGUueCxcbiAgICB5OiAgICAgIHNoYXBlLnlcbiAgfTtcblxuICAvLyB1cGRhdGUgc2hhcGVcbiAgYXNzaWduKHNoYXBlLCB7XG4gICAgd2lkdGg6ICBuZXdCb3VuZHMud2lkdGgsXG4gICAgaGVpZ2h0OiBuZXdCb3VuZHMuaGVpZ2h0LFxuICAgIHg6ICAgICAgbmV3Qm91bmRzLngsXG4gICAgeTogICAgICBuZXdCb3VuZHMueVxuICB9KTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG5SZXNpemVTaGFwZUhhbmRsZXIucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgb2xkQm91bmRzID0gY29udGV4dC5vbGRCb3VuZHMsXG4gICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgaWYgKGhpbnRzLmxheW91dCA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3JFYWNoKHNoYXBlLmluY29taW5nLCBmdW5jdGlvbihjKSB7XG4gICAgbW9kZWxpbmcubGF5b3V0Q29ubmVjdGlvbihjLCB7XG4gICAgICBjb25uZWN0aW9uRW5kOiBnZXRSZXNpemVkVGFyZ2V0QW5jaG9yKGMsIHNoYXBlLCBvbGRCb3VuZHMpXG4gICAgfSk7XG4gIH0pO1xuXG4gIGZvckVhY2goc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGMpIHtcbiAgICBtb2RlbGluZy5sYXlvdXRDb25uZWN0aW9uKGMsIHtcbiAgICAgIGNvbm5lY3Rpb25TdGFydDogZ2V0UmVzaXplZFNvdXJjZUFuY2hvcihjLCBzaGFwZSwgb2xkQm91bmRzKVxuICAgIH0pO1xuICB9KTtcblxufTtcblxuUmVzaXplU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG9sZEJvdW5kcyA9IGNvbnRleHQub2xkQm91bmRzO1xuXG4gIC8vIHJlc3RvcmUgcHJldmlvdXMgYmJveFxuICBhc3NpZ24oc2hhcGUsIHtcbiAgICB3aWR0aDogIG9sZEJvdW5kcy53aWR0aCxcbiAgICBoZWlnaHQ6IG9sZEJvdW5kcy5oZWlnaHQsXG4gICAgeDogICAgICBvbGRCb3VuZHMueCxcbiAgICB5OiAgICAgIG9sZEJvdW5kcy55XG4gIH0pO1xuXG4gIHJldHVybiBzaGFwZTtcbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIG1hcFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGdldFdheXBvaW50c1VwZGF0aW5nQ29ubmVjdGlvbnMsXG4gIHJlc2l6ZUJvdW5kc1xufSBmcm9tICcuLi8uLi9zcGFjZS10b29sL1NwYWNlVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldE1vdmVkU291cmNlQW5jaG9yLFxuICBnZXRNb3ZlZFRhcmdldEFuY2hvcixcbiAgZ2V0UmVzaXplZFNvdXJjZUFuY2hvcixcbiAgZ2V0UmVzaXplZFRhcmdldEFuY2hvclxufSBmcm9tICcuL2hlbHBlci9BbmNob3JzSGVscGVyJztcblxuXG4vKipcbiAqIEFkZCBvciByZW1vdmUgc3BhY2UgYnkgbW92aW5nIGFuZCByZXNpemluZyBzaGFwZXMgYW5kIHVwZGF0aW5nIGNvbm5lY3Rpb24gd2F5cG9pbnRzLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBTcGFjZVRvb2xIYW5kbGVyKG1vZGVsaW5nKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cblNwYWNlVG9vbEhhbmRsZXIuJGluamVjdCA9IFsgJ21vZGVsaW5nJyBdO1xuXG5TcGFjZVRvb2xIYW5kbGVyLnByb3RvdHlwZS5wcmVFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgZGVsdGEgPSBjb250ZXh0LmRlbHRhLFxuICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXG4gICAgICBtb3ZpbmdTaGFwZXMgPSBjb250ZXh0Lm1vdmluZ1NoYXBlcyxcbiAgICAgIHJlc2l6aW5nU2hhcGVzID0gY29udGV4dC5yZXNpemluZ1NoYXBlcyxcbiAgICAgIHN0YXJ0ID0gY29udGV4dC5zdGFydCxcbiAgICAgIG9sZEJvdW5kcyA9IHt9O1xuXG4gIC8vICgxKSBtb3ZlIHNoYXBlc1xuICB0aGlzLm1vdmVTaGFwZXMobW92aW5nU2hhcGVzLCBkZWx0YSk7XG5cbiAgLy8gKDJhKSBzYXZlIG9sZCBib3VuZHMgb2YgcmVzaXplZCBzaGFwZXNcbiAgZm9yRWFjaChyZXNpemluZ1NoYXBlcywgZnVuY3Rpb24oc2hhcGUpIHtcbiAgICBvbGRCb3VuZHNbc2hhcGUuaWRdID0gZ2V0Qm91bmRzKHNoYXBlKTtcbiAgfSk7XG5cbiAgLy8gKDJiKSByZXNpemUgc2hhcGVzXG4gIHRoaXMucmVzaXplU2hhcGVzKHJlc2l6aW5nU2hhcGVzLCBkZWx0YSwgZGlyZWN0aW9uKTtcblxuICAvLyAoMykgdXBkYXRlIGNvbm5lY3Rpb24gd2F5cG9pbnRzXG4gIHRoaXMudXBkYXRlQ29ubmVjdGlvbldheXBvaW50cyhcbiAgICBnZXRXYXlwb2ludHNVcGRhdGluZ0Nvbm5lY3Rpb25zKG1vdmluZ1NoYXBlcywgcmVzaXppbmdTaGFwZXMpLFxuICAgIGRlbHRhLFxuICAgIGRpcmVjdGlvbixcbiAgICBzdGFydCxcbiAgICBtb3ZpbmdTaGFwZXMsXG4gICAgcmVzaXppbmdTaGFwZXMsXG4gICAgb2xkQm91bmRzXG4gICk7XG59O1xuXG5TcGFjZVRvb2xIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oKSB7fTtcblNwYWNlVG9vbEhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKCkge307XG5cblNwYWNlVG9vbEhhbmRsZXIucHJvdG90eXBlLm1vdmVTaGFwZXMgPSBmdW5jdGlvbihzaGFwZXMsIGRlbHRhKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmb3JFYWNoKHNoYXBlcywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHNlbGYuX21vZGVsaW5nLm1vdmVTaGFwZShlbGVtZW50LCBkZWx0YSwgbnVsbCwge1xuICAgICAgYXV0b1Jlc2l6ZTogZmFsc2UsXG4gICAgICBsYXlvdXQ6IGZhbHNlLFxuICAgICAgcmVjdXJzZTogZmFsc2VcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5TcGFjZVRvb2xIYW5kbGVyLnByb3RvdHlwZS5yZXNpemVTaGFwZXMgPSBmdW5jdGlvbihzaGFwZXMsIGRlbHRhLCBkaXJlY3Rpb24pIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGZvckVhY2goc2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgIHZhciBuZXdCb3VuZHMgPSByZXNpemVCb3VuZHMoc2hhcGUsIGRpcmVjdGlvbiwgZGVsdGEpO1xuXG4gICAgc2VsZi5fbW9kZWxpbmcucmVzaXplU2hhcGUoc2hhcGUsIG5ld0JvdW5kcywgbnVsbCwge1xuICAgICAgYXR0YWNoU3VwcG9ydDogZmFsc2UsXG4gICAgICBhdXRvUmVzaXplOiBmYWxzZSxcbiAgICAgIGxheW91dDogZmFsc2VcbiAgICB9KTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIFVwZGF0ZSBjb25uZWN0aW9ucyB3YXlwb2ludHMgYWNjb3JkaW5nIHRvIHRoZSBydWxlczpcbiAqICAgMS4gQm90aCBzb3VyY2UgYW5kIHRhcmdldCBhcmUgbW92ZWQvcmVzaXplZCA9PiBtb3ZlIHdheXBvaW50cyBieSB0aGUgZGVsdGFcbiAqICAgMi4gT25seSBvbmUgb2Ygc291cmNlIGFuZCB0YXJnZXQgaXMgbW92ZWQvcmVzaXplZCA9PiByZS1sYXlvdXQgY29ubmVjdGlvbiB3aXRoIG1vdmVkIHN0YXJ0L2VuZFxuICovXG5TcGFjZVRvb2xIYW5kbGVyLnByb3RvdHlwZS51cGRhdGVDb25uZWN0aW9uV2F5cG9pbnRzID0gZnVuY3Rpb24oXG4gICAgY29ubmVjdGlvbnMsXG4gICAgZGVsdGEsXG4gICAgZGlyZWN0aW9uLFxuICAgIHN0YXJ0LFxuICAgIG1vdmluZ1NoYXBlcyxcbiAgICByZXNpemluZ1NoYXBlcyxcbiAgICBvbGRCb3VuZHNcbikge1xuICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICBhZmZlY3RlZFNoYXBlcyA9IG1vdmluZ1NoYXBlcy5jb25jYXQocmVzaXppbmdTaGFwZXMpO1xuXG4gIGZvckVhY2goY29ubmVjdGlvbnMsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0LFxuICAgICAgICB3YXlwb2ludHMgPSBjb3B5V2F5cG9pbnRzKGNvbm5lY3Rpb24pLFxuICAgICAgICBheGlzID0gZ2V0QXhpc0Zyb21EaXJlY3Rpb24oZGlyZWN0aW9uKSxcbiAgICAgICAgbGF5b3V0SGludHMgPSB7XG4gICAgICAgICAgbGFiZWxCZWhhdmlvcjogZmFsc2VcbiAgICAgICAgfTtcblxuICAgIGlmIChpbmNsdWRlcyhhZmZlY3RlZFNoYXBlcywgc291cmNlKSAmJiBpbmNsdWRlcyhhZmZlY3RlZFNoYXBlcywgdGFyZ2V0KSkge1xuXG4gICAgICAvLyBtb3ZlIHdheXBvaW50c1xuICAgICAgd2F5cG9pbnRzID0gbWFwKHdheXBvaW50cywgZnVuY3Rpb24od2F5cG9pbnQpIHtcbiAgICAgICAgaWYgKHNob3VsZE1vdmVXYXlwb2ludCh3YXlwb2ludCwgc3RhcnQsIGRpcmVjdGlvbikpIHtcblxuICAgICAgICAgIC8vIG1vdmUgd2F5cG9pbnRcbiAgICAgICAgICB3YXlwb2ludFsgYXhpcyBdID0gd2F5cG9pbnRbIGF4aXMgXSArIGRlbHRhWyBheGlzIF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAod2F5cG9pbnQub3JpZ2luYWwgJiYgc2hvdWxkTW92ZVdheXBvaW50KHdheXBvaW50Lm9yaWdpbmFsLCBzdGFydCwgZGlyZWN0aW9uKSkge1xuXG4gICAgICAgICAgLy8gbW92ZSB3YXlwb2ludCBvcmlnaW5hbFxuICAgICAgICAgIHdheXBvaW50Lm9yaWdpbmFsWyBheGlzIF0gPSB3YXlwb2ludC5vcmlnaW5hbFsgYXhpcyBdICsgZGVsdGFbIGF4aXMgXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB3YXlwb2ludDtcbiAgICAgIH0pO1xuXG4gICAgICBzZWxmLl9tb2RlbGluZy51cGRhdGVXYXlwb2ludHMoY29ubmVjdGlvbiwgd2F5cG9pbnRzLCB7XG4gICAgICAgIGxhYmVsQmVoYXZpb3I6IGZhbHNlXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGluY2x1ZGVzKGFmZmVjdGVkU2hhcGVzLCBzb3VyY2UpIHx8IGluY2x1ZGVzKGFmZmVjdGVkU2hhcGVzLCB0YXJnZXQpKSB7XG5cbiAgICAgIC8vIHJlLWxheW91dCBjb25uZWN0aW9uIHdpdGggbW92ZWQgc3RhcnQvZW5kXG4gICAgICBpZiAoaW5jbHVkZXMobW92aW5nU2hhcGVzLCBzb3VyY2UpKSB7XG4gICAgICAgIGxheW91dEhpbnRzLmNvbm5lY3Rpb25TdGFydCA9IGdldE1vdmVkU291cmNlQW5jaG9yKGNvbm5lY3Rpb24sIHNvdXJjZSwgZGVsdGEpO1xuICAgICAgfSBlbHNlIGlmIChpbmNsdWRlcyhtb3ZpbmdTaGFwZXMsIHRhcmdldCkpIHtcbiAgICAgICAgbGF5b3V0SGludHMuY29ubmVjdGlvbkVuZCA9IGdldE1vdmVkVGFyZ2V0QW5jaG9yKGNvbm5lY3Rpb24sIHRhcmdldCwgZGVsdGEpO1xuICAgICAgfSBlbHNlIGlmIChpbmNsdWRlcyhyZXNpemluZ1NoYXBlcywgc291cmNlKSkge1xuICAgICAgICBsYXlvdXRIaW50cy5jb25uZWN0aW9uU3RhcnQgPSBnZXRSZXNpemVkU291cmNlQW5jaG9yKFxuICAgICAgICAgIGNvbm5lY3Rpb24sIHNvdXJjZSwgb2xkQm91bmRzW3NvdXJjZS5pZF1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoaW5jbHVkZXMocmVzaXppbmdTaGFwZXMsIHRhcmdldCkpIHtcbiAgICAgICAgbGF5b3V0SGludHMuY29ubmVjdGlvbkVuZCA9IGdldFJlc2l6ZWRUYXJnZXRBbmNob3IoXG4gICAgICAgICAgY29ubmVjdGlvbiwgdGFyZ2V0LCBvbGRCb3VuZHNbdGFyZ2V0LmlkXVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBzZWxmLl9tb2RlbGluZy5sYXlvdXRDb25uZWN0aW9uKGNvbm5lY3Rpb24sIGxheW91dEhpbnRzKTtcbiAgICB9XG4gIH0pO1xufTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gY29weVdheXBvaW50KHdheXBvaW50KSB7XG4gIHJldHVybiBhc3NpZ24oe30sIHdheXBvaW50KTtcbn1cblxuZnVuY3Rpb24gY29weVdheXBvaW50cyhjb25uZWN0aW9uKSB7XG4gIHJldHVybiBtYXAoY29ubmVjdGlvbi53YXlwb2ludHMsIGZ1bmN0aW9uKHdheXBvaW50KSB7XG5cbiAgICB3YXlwb2ludCA9IGNvcHlXYXlwb2ludCh3YXlwb2ludCk7XG5cbiAgICBpZiAod2F5cG9pbnQub3JpZ2luYWwpIHtcbiAgICAgIHdheXBvaW50Lm9yaWdpbmFsID0gY29weVdheXBvaW50KHdheXBvaW50Lm9yaWdpbmFsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gd2F5cG9pbnQ7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRBeGlzRnJvbURpcmVjdGlvbihkaXJlY3Rpb24pIHtcbiAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgY2FzZSAnbic6XG4gICAgcmV0dXJuICd5JztcbiAgY2FzZSAndyc6XG4gICAgcmV0dXJuICd4JztcbiAgY2FzZSAncyc6XG4gICAgcmV0dXJuICd5JztcbiAgY2FzZSAnZSc6XG4gICAgcmV0dXJuICd4JztcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRNb3ZlV2F5cG9pbnQod2F5cG9pbnQsIHN0YXJ0LCBkaXJlY3Rpb24pIHtcbiAgdmFyIHJlbGV2YW50QXhpcyA9IGdldEF4aXNGcm9tRGlyZWN0aW9uKGRpcmVjdGlvbik7XG5cbiAgaWYgKC9lfHMvLnRlc3QoZGlyZWN0aW9uKSkge1xuICAgIHJldHVybiB3YXlwb2ludFsgcmVsZXZhbnRBeGlzIF0gPiBzdGFydDtcbiAgfSBlbHNlIGlmICgvbnx3Ly50ZXN0KGRpcmVjdGlvbikpIHtcbiAgICByZXR1cm4gd2F5cG9pbnRbIHJlbGV2YW50QXhpcyBdIDwgc3RhcnQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5jbHVkZXMoYXJyYXksIGl0ZW0pIHtcbiAgcmV0dXJuIGFycmF5LmluZGV4T2YoaXRlbSkgIT09IC0xO1xufVxuXG5mdW5jdGlvbiBnZXRCb3VuZHMoc2hhcGUpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBzaGFwZS54LFxuICAgIHk6IHNoYXBlLnksXG4gICAgaGVpZ2h0OiBzaGFwZS5oZWlnaHQsXG4gICAgd2lkdGg6IHNoYXBlLndpZHRoXG4gIH07XG59XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IHRvZ2dsZXMgdGhlIGNvbGxhcHNlZCBzdGF0ZSBvZiBhbiBlbGVtZW50XG4gKiBhbmQgdGhlIHZpc2liaWxpdHkgb2YgYWxsIGl0cyBjaGlsZHJlbi5cbiAqXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBUb2dnbGVTaGFwZUNvbGxhcHNlSGFuZGxlcihtb2RlbGluZykge1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xufVxuXG5Ub2dnbGVTaGFwZUNvbGxhcHNlSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cblxuVG9nZ2xlU2hhcGVDb2xsYXBzZUhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIGNoaWxkcmVuID0gc2hhcGUuY2hpbGRyZW47XG5cbiAgLy8gcmVjdXJzaXZlbHkgcmVtZW1iZXIgcHJldmlvdXMgdmlzaWJpbGl0eSBvZiBjaGlsZHJlblxuICBjb250ZXh0Lm9sZENoaWxkcmVuVmlzaWJpbGl0eSA9IGdldEVsZW1lbnRzVmlzaWJpbGl0eVJlY3Vyc2l2ZShjaGlsZHJlbik7XG5cbiAgLy8gdG9nZ2xlIHN0YXRlXG4gIHNoYXBlLmNvbGxhcHNlZCA9ICFzaGFwZS5jb2xsYXBzZWQ7XG5cbiAgLy8gcmVjdXJzaXZlbHkgaGlkZS9zaG93IGNoaWxkcmVuXG4gIHZhciByZXN1bHQgPSBzZXRIaWRkZW5SZWN1cnNpdmUoY2hpbGRyZW4sIHNoYXBlLmNvbGxhcHNlZCk7XG5cbiAgcmV0dXJuIFtzaGFwZV0uY29uY2F0KHJlc3VsdCk7XG59O1xuXG5cblRvZ2dsZVNoYXBlQ29sbGFwc2VIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG9sZENoaWxkcmVuVmlzaWJpbGl0eSA9IGNvbnRleHQub2xkQ2hpbGRyZW5WaXNpYmlsaXR5O1xuXG4gIHZhciBjaGlsZHJlbiA9IHNoYXBlLmNoaWxkcmVuO1xuXG4gIC8vIHJlY3Vyc2l2ZWx5IHNldCBvbGQgdmlzYWJpbGl0eSBvZiBjaGlsZHJlblxuICB2YXIgcmVzdWx0ID0gcmVzdG9yZVZpc2liaWxpdHlSZWN1cnNpdmUoY2hpbGRyZW4sIG9sZENoaWxkcmVuVmlzaWJpbGl0eSk7XG5cbiAgLy8gcmV0b2dnbGUgc3RhdGVcbiAgc2hhcGUuY29sbGFwc2VkID0gIXNoYXBlLmNvbGxhcHNlZDtcblxuICByZXR1cm4gW3NoYXBlXS5jb25jYXQocmVzdWx0KTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogUmV0dXJuIGEgbWFwIHsgZWxlbWVudElkIC0+IGhpZGRlblN0YXRlfS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBnZXRFbGVtZW50c1Zpc2liaWxpdHlSZWN1cnNpdmUoZWxlbWVudHMpIHtcblxuICB2YXIgcmVzdWx0ID0ge307XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHJlc3VsdFtlbGVtZW50LmlkXSA9IGVsZW1lbnQuaGlkZGVuO1xuXG4gICAgaWYgKGVsZW1lbnQuY2hpbGRyZW4pIHtcbiAgICAgIHJlc3VsdCA9IGFzc2lnbih7fSwgcmVzdWx0LCBnZXRFbGVtZW50c1Zpc2liaWxpdHlSZWN1cnNpdmUoZWxlbWVudC5jaGlsZHJlbikpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG5mdW5jdGlvbiBzZXRIaWRkZW5SZWN1cnNpdmUoZWxlbWVudHMsIG5ld0hpZGRlbikge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIGZvckVhY2goZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBlbGVtZW50LmhpZGRlbiA9IG5ld0hpZGRlbjtcblxuICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQoZWxlbWVudCk7XG5cbiAgICBpZiAoZWxlbWVudC5jaGlsZHJlbikge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdChzZXRIaWRkZW5SZWN1cnNpdmUoZWxlbWVudC5jaGlsZHJlbiwgZWxlbWVudC5jb2xsYXBzZWQgfHwgbmV3SGlkZGVuKSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiByZXN0b3JlVmlzaWJpbGl0eVJlY3Vyc2l2ZShlbGVtZW50cywgbGFzdFN0YXRlKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGVsZW1lbnQuaGlkZGVuID0gbGFzdFN0YXRlW2VsZW1lbnQuaWRdO1xuXG4gICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdChlbGVtZW50KTtcblxuICAgIGlmIChlbGVtZW50LmNoaWxkcmVuKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQuY29uY2F0KHJlc3RvcmVWaXNpYmlsaXR5UmVjdXJzaXZlKGVsZW1lbnQuY2hpbGRyZW4sIGxhc3RTdGF0ZSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsImltcG9ydCB7XG4gIGFkZCBhcyBjb2xsZWN0aW9uQWRkLFxuICByZW1vdmUgYXMgY29sbGVjdGlvblJlbW92ZVxufSBmcm9tICcuLi8uLi8uLi91dGlsL0NvbGxlY3Rpb25zJztcblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBpbXBsZW1lbnRzIHJldmVyc2libGUgYXR0YWNoaW5nL2RldGFjaGluZyBvZiBzaGFwZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFVwZGF0ZUF0dGFjaG1lbnRIYW5kbGVyKG1vZGVsaW5nKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cblVwZGF0ZUF0dGFjaG1lbnRIYW5kbGVyLiRpbmplY3QgPSBbICdtb2RlbGluZycgXTtcblxuXG5VcGRhdGVBdHRhY2htZW50SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG5ld0hvc3QgPSBjb250ZXh0Lm5ld0hvc3QsXG4gICAgICBvbGRIb3N0ID0gc2hhcGUuaG9zdDtcblxuICAvLyAoMCkgZGV0YWNoIGZyb20gb2xkIGhvc3RcbiAgY29udGV4dC5vbGRIb3N0ID0gb2xkSG9zdDtcbiAgY29udGV4dC5hdHRhY2hlcklkeCA9IHJlbW92ZUF0dGFjaGVyKG9sZEhvc3QsIHNoYXBlKTtcblxuICAvLyAoMSkgYXR0YWNoIHRvIG5ldyBob3N0XG4gIGFkZEF0dGFjaGVyKG5ld0hvc3QsIHNoYXBlKTtcblxuICAvLyAoMikgdXBkYXRlIGhvc3RcbiAgc2hhcGUuaG9zdCA9IG5ld0hvc3Q7XG5cbiAgcmV0dXJuIHNoYXBlO1xufTtcblxuVXBkYXRlQXR0YWNobWVudEhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG5ld0hvc3QgPSBjb250ZXh0Lm5ld0hvc3QsXG4gICAgICBvbGRIb3N0ID0gY29udGV4dC5vbGRIb3N0LFxuICAgICAgYXR0YWNoZXJJZHggPSBjb250ZXh0LmF0dGFjaGVySWR4O1xuXG4gIC8vICgyKSB1cGRhdGUgaG9zdFxuICBzaGFwZS5ob3N0ID0gb2xkSG9zdDtcblxuICAvLyAoMSkgYXR0YWNoIHRvIG5ldyBob3N0XG4gIHJlbW92ZUF0dGFjaGVyKG5ld0hvc3QsIHNoYXBlKTtcblxuICAvLyAoMCkgZGV0YWNoIGZyb20gb2xkIGhvc3RcbiAgYWRkQXR0YWNoZXIob2xkSG9zdCwgc2hhcGUsIGF0dGFjaGVySWR4KTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG5cbmZ1bmN0aW9uIHJlbW92ZUF0dGFjaGVyKGhvc3QsIGF0dGFjaGVyKSB7XG5cbiAgLy8gcmVtb3ZlIGF0dGFjaGVyIGZyb20gaG9zdFxuICByZXR1cm4gY29sbGVjdGlvblJlbW92ZShob3N0ICYmIGhvc3QuYXR0YWNoZXJzLCBhdHRhY2hlcik7XG59XG5cbmZ1bmN0aW9uIGFkZEF0dGFjaGVyKGhvc3QsIGF0dGFjaGVyLCBpZHgpIHtcblxuICBpZiAoIWhvc3QpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgYXR0YWNoZXJzID0gaG9zdC5hdHRhY2hlcnM7XG5cbiAgaWYgKCFhdHRhY2hlcnMpIHtcbiAgICBob3N0LmF0dGFjaGVycyA9IGF0dGFjaGVycyA9IFtdO1xuICB9XG5cbiAgY29sbGVjdGlvbkFkZChhdHRhY2hlcnMsIGF0dGFjaGVyLCBpZHgpO1xufVxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVXBkYXRlV2F5cG9pbnRzSGFuZGxlcigpIHsgfVxuXG5VcGRhdGVXYXlwb2ludHNIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgbmV3V2F5cG9pbnRzID0gY29udGV4dC5uZXdXYXlwb2ludHM7XG5cbiAgY29udGV4dC5vbGRXYXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cztcblxuICBjb25uZWN0aW9uLndheXBvaW50cyA9IG5ld1dheXBvaW50cztcblxuICByZXR1cm4gY29ubmVjdGlvbjtcbn07XG5cblVwZGF0ZVdheXBvaW50c0hhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgIG9sZFdheXBvaW50cyA9IGNvbnRleHQub2xkV2F5cG9pbnRzO1xuXG4gIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gb2xkV2F5cG9pbnRzO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTsiLCJpbXBvcnQge1xuICBnZXROZXdBdHRhY2hQb2ludFxufSBmcm9tICcuLi8uLi8uLi8uLi91dGlsL0F0dGFjaFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRPcmllbnRhdGlvblxufSBmcm9tICcuLi8uLi8uLi8uLi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7XG4gIGZpbHRlcixcbiAgbWFwXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVzaXplZFNvdXJjZUFuY2hvcihjb25uZWN0aW9uLCBzaGFwZSwgb2xkQm91bmRzKSB7XG5cbiAgdmFyIHdheXBvaW50cyA9IHNhZmVHZXRXYXlwb2ludHMoY29ubmVjdGlvbiksXG4gICAgICB3YXlwb2ludHNJbnNpZGVOZXdCb3VuZHMgPSBnZXRXYXlwb2ludHNJbnNpZGVCb3VuZHMod2F5cG9pbnRzLCBzaGFwZSksXG4gICAgICBvbGRBbmNob3IgPSB3YXlwb2ludHNbMF07XG5cbiAgLy8gbmV3IGFuY2hvciBpcyB0aGUgbGFzdCB3YXlwb2ludCBlbmNsb3NlZCBiZSByZXNpemVkIHNvdXJjZVxuICBpZiAod2F5cG9pbnRzSW5zaWRlTmV3Qm91bmRzLmxlbmd0aCkge1xuICAgIHJldHVybiB3YXlwb2ludHNJbnNpZGVOZXdCb3VuZHNbIHdheXBvaW50c0luc2lkZU5ld0JvdW5kcy5sZW5ndGggLSAxIF07XG4gIH1cblxuICByZXR1cm4gZ2V0TmV3QXR0YWNoUG9pbnQob2xkQW5jaG9yLm9yaWdpbmFsIHx8IG9sZEFuY2hvciwgb2xkQm91bmRzLCBzaGFwZSk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlc2l6ZWRUYXJnZXRBbmNob3IoY29ubmVjdGlvbiwgc2hhcGUsIG9sZEJvdW5kcykge1xuXG4gIHZhciB3YXlwb2ludHMgPSBzYWZlR2V0V2F5cG9pbnRzKGNvbm5lY3Rpb24pLFxuICAgICAgd2F5cG9pbnRzSW5zaWRlTmV3Qm91bmRzID0gZ2V0V2F5cG9pbnRzSW5zaWRlQm91bmRzKHdheXBvaW50cywgc2hhcGUpLFxuICAgICAgb2xkQW5jaG9yID0gd2F5cG9pbnRzW3dheXBvaW50cy5sZW5ndGggLSAxXTtcblxuICAvLyBuZXcgYW5jaG9yIGlzIHRoZSBmaXJzdCB3YXlwb2ludCBlbmNsb3NlZCBiZSByZXNpemVkIHRhcmdldFxuICBpZiAod2F5cG9pbnRzSW5zaWRlTmV3Qm91bmRzLmxlbmd0aCkge1xuICAgIHJldHVybiB3YXlwb2ludHNJbnNpZGVOZXdCb3VuZHNbIDAgXTtcbiAgfVxuXG4gIHJldHVybiBnZXROZXdBdHRhY2hQb2ludChvbGRBbmNob3Iub3JpZ2luYWwgfHwgb2xkQW5jaG9yLCBvbGRCb3VuZHMsIHNoYXBlKTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TW92ZWRTb3VyY2VBbmNob3IoY29ubmVjdGlvbiwgc291cmNlLCBtb3ZlRGVsdGEpIHtcblxuICB2YXIgd2F5cG9pbnRzID0gc2FmZUdldFdheXBvaW50cyhjb25uZWN0aW9uKSxcbiAgICAgIG9sZEJvdW5kcyA9IHN1YnRyYWN0KHNvdXJjZSwgbW92ZURlbHRhKSxcbiAgICAgIG9sZEFuY2hvciA9IHdheXBvaW50c1sgMCBdO1xuXG4gIHJldHVybiBnZXROZXdBdHRhY2hQb2ludChvbGRBbmNob3Iub3JpZ2luYWwgfHwgb2xkQW5jaG9yLCBvbGRCb3VuZHMsIHNvdXJjZSk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1vdmVkVGFyZ2V0QW5jaG9yKGNvbm5lY3Rpb24sIHRhcmdldCwgbW92ZURlbHRhKSB7XG5cbiAgdmFyIHdheXBvaW50cyA9IHNhZmVHZXRXYXlwb2ludHMoY29ubmVjdGlvbiksXG4gICAgICBvbGRCb3VuZHMgPSBzdWJ0cmFjdCh0YXJnZXQsIG1vdmVEZWx0YSksXG4gICAgICBvbGRBbmNob3IgPSB3YXlwb2ludHNbIHdheXBvaW50cy5sZW5ndGggLSAxIF07XG5cbiAgcmV0dXJuIGdldE5ld0F0dGFjaFBvaW50KG9sZEFuY2hvci5vcmlnaW5hbCB8fCBvbGRBbmNob3IsIG9sZEJvdW5kcywgdGFyZ2V0KTtcbn1cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gc3VidHJhY3QoYm91bmRzLCBkZWx0YSkge1xuICByZXR1cm4ge1xuICAgIHg6IGJvdW5kcy54IC0gZGVsdGEueCxcbiAgICB5OiBib3VuZHMueSAtIGRlbHRhLnksXG4gICAgd2lkdGg6IGJvdW5kcy53aWR0aCxcbiAgICBoZWlnaHQ6IGJvdW5kcy5oZWlnaHRcbiAgfTtcbn1cblxuXG4vKipcbiAqIFJldHVybiB3YXlwb2ludHMgb2YgZ2l2ZW4gY29ubmVjdGlvbjsgdGhyb3cgaWYgbm9uIGV4aXN0cyAoc2hvdWxkIG5vdCBoYXBwZW4hISkuXG4gKlxuICogQHBhcmFtIHtDb25uZWN0aW9ufSBjb25uZWN0aW9uXG4gKlxuICogQHJldHVybiB7QXJyYXk8UG9pbnQ+fVxuICovXG5mdW5jdGlvbiBzYWZlR2V0V2F5cG9pbnRzKGNvbm5lY3Rpb24pIHtcblxuICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG5cbiAgaWYgKCF3YXlwb2ludHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjb25uZWN0aW9uIycgKyBjb25uZWN0aW9uLmlkICsgJzogbm8gd2F5cG9pbnRzJyk7XG4gIH1cblxuICByZXR1cm4gd2F5cG9pbnRzO1xufVxuXG5mdW5jdGlvbiBnZXRXYXlwb2ludHNJbnNpZGVCb3VuZHMod2F5cG9pbnRzLCBib3VuZHMpIHtcbiAgdmFyIG9yaWdpbmFsV2F5cG9pbnRzID0gbWFwKHdheXBvaW50cywgZ2V0T3JpZ2luYWwpO1xuXG4gIHJldHVybiBmaWx0ZXIob3JpZ2luYWxXYXlwb2ludHMsIGZ1bmN0aW9uKHdheXBvaW50KSB7XG4gICAgcmV0dXJuIGlzSW5zaWRlQm91bmRzKHdheXBvaW50LCBib3VuZHMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgcG9pbnQgaXMgaW5zaWRlIGJvdW5kcywgaW5jbC4gZWRnZXMuXG4gKlxuICogQHBhcmFtIHtQb2ludH0gcG9pbnRcbiAqIEBwYXJhbSB7Qm91bmRzfSBib3VuZHNcbiAqL1xuZnVuY3Rpb24gaXNJbnNpZGVCb3VuZHMocG9pbnQsIGJvdW5kcykge1xuICByZXR1cm4gZ2V0T3JpZW50YXRpb24oYm91bmRzLCBwb2ludCwgMSkgPT09ICdpbnRlcnNlY3QnO1xufVxuXG5mdW5jdGlvbiBnZXRPcmlnaW5hbChwb2ludCkge1xuICByZXR1cm4gcG9pbnQub3JpZ2luYWwgfHwgcG9pbnQ7XG59XG4iLCJpbXBvcnQge1xuICBhc3NpZ25cbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRDbG9zdXJlXG59IGZyb20gJy4uLy4uLy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1vdmVDbG9zdXJlKCkge1xuXG4gIHRoaXMuYWxsU2hhcGVzID0ge307XG4gIHRoaXMuYWxsQ29ubmVjdGlvbnMgPSB7fTtcblxuICB0aGlzLmVuY2xvc2VkRWxlbWVudHMgPSB7fTtcbiAgdGhpcy5lbmNsb3NlZENvbm5lY3Rpb25zID0ge307XG5cbiAgdGhpcy50b3BMZXZlbCA9IHt9O1xufVxuXG5cbk1vdmVDbG9zdXJlLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihlbGVtZW50LCBpc1RvcExldmVsKSB7XG4gIHJldHVybiB0aGlzLmFkZEFsbChbIGVsZW1lbnQgXSwgaXNUb3BMZXZlbCk7XG59O1xuXG5cbk1vdmVDbG9zdXJlLnByb3RvdHlwZS5hZGRBbGwgPSBmdW5jdGlvbihlbGVtZW50cywgaXNUb3BMZXZlbCkge1xuXG4gIHZhciBuZXdDbG9zdXJlID0gZ2V0Q2xvc3VyZShlbGVtZW50cywgISFpc1RvcExldmVsLCB0aGlzKTtcblxuICBhc3NpZ24odGhpcywgbmV3Q2xvc3VyZSk7XG5cbiAgcmV0dXJuIHRoaXM7XG59OyIsImltcG9ydCB7XG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRNb3ZlZFNvdXJjZUFuY2hvcixcbiAgZ2V0TW92ZWRUYXJnZXRBbmNob3Jcbn0gZnJvbSAnLi9BbmNob3JzSGVscGVyJztcblxuaW1wb3J0IE1vdmVDbG9zdXJlIGZyb20gJy4vTW92ZUNsb3N1cmUnO1xuXG5cbi8qKlxuICogQSBoZWxwZXIgdGhhdCBpcyBhYmxlIHRvIGNhcnJ5IG91dCBzZXJpYWxpemVkIG1vdmVcbiAqIG9wZXJhdGlvbnMgb24gbXVsdGlwbGUgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW92ZUhlbHBlcihtb2RlbGluZykge1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xufVxuXG4vKipcbiAqIE1vdmUgdGhlIHNwZWNpZmllZCBlbGVtZW50cyBhbmQgYWxsIGNoaWxkcmVuIGJ5IHRoZSBnaXZlbiBkZWx0YS5cbiAqXG4gKiBUaGlzIG1vdmVzIGFsbCBlbmNsb3NlZCBjb25uZWN0aW9ucywgdG9vIGFuZCBsYXlvdXRzIGFsbCBhZmZlY3RlZFxuICogZXh0ZXJuYWwgY29ubmVjdGlvbnMuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICogQHBhcmFtICB7UG9pbnR9IGRlbHRhXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gbmV3UGFyZW50IGFwcGxpZWQgdG8gdGhlIGZpcnN0IGxldmVsIG9mIHNoYXBlc1xuICpcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gbGlzdCBvZiB0b3VjaGVkIGVsZW1lbnRzXG4gKi9cbk1vdmVIZWxwZXIucHJvdG90eXBlLm1vdmVSZWN1cnNpdmUgPSBmdW5jdGlvbihlbGVtZW50cywgZGVsdGEsIG5ld1BhcmVudCkge1xuICBpZiAoIWVsZW1lbnRzKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzLm1vdmVDbG9zdXJlKHRoaXMuZ2V0Q2xvc3VyZShlbGVtZW50cyksIGRlbHRhLCBuZXdQYXJlbnQpO1xuICB9XG59O1xuXG4vKipcbiAqIE1vdmUgdGhlIGdpdmVuIGNsb3N1cmUgb2YgZWxtZW1lbnRzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjbG9zdXJlXG4gKiBAcGFyYW0ge1BvaW50fSBkZWx0YVxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gW25ld1BhcmVudF1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtuZXdIb3N0XVxuICovXG5Nb3ZlSGVscGVyLnByb3RvdHlwZS5tb3ZlQ2xvc3VyZSA9IGZ1bmN0aW9uKGNsb3N1cmUsIGRlbHRhLCBuZXdQYXJlbnQsIG5ld0hvc3QsIHByaW1hcnlTaGFwZSkge1xuICB2YXIgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcblxuICB2YXIgYWxsU2hhcGVzID0gY2xvc3VyZS5hbGxTaGFwZXMsXG4gICAgICBhbGxDb25uZWN0aW9ucyA9IGNsb3N1cmUuYWxsQ29ubmVjdGlvbnMsXG4gICAgICBlbmNsb3NlZENvbm5lY3Rpb25zID0gY2xvc3VyZS5lbmNsb3NlZENvbm5lY3Rpb25zLFxuICAgICAgdG9wTGV2ZWwgPSBjbG9zdXJlLnRvcExldmVsLFxuICAgICAga2VlcFBhcmVudCA9IGZhbHNlO1xuXG4gIGlmIChwcmltYXJ5U2hhcGUgJiYgcHJpbWFyeVNoYXBlLnBhcmVudCA9PT0gbmV3UGFyZW50KSB7XG4gICAga2VlcFBhcmVudCA9IHRydWU7XG4gIH1cblxuICAvLyBtb3ZlIGFsbCBzaGFwZXNcbiAgZm9yRWFjaChhbGxTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG5cbiAgICAvLyBtb3ZlIHRoZSBlbGVtZW50IGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gZGVsdGFcbiAgICBtb2RlbGluZy5tb3ZlU2hhcGUoc2hhcGUsIGRlbHRhLCB0b3BMZXZlbFtzaGFwZS5pZF0gJiYgIWtlZXBQYXJlbnQgJiYgbmV3UGFyZW50LCB7XG4gICAgICByZWN1cnNlOiBmYWxzZSxcbiAgICAgIGxheW91dDogZmFsc2VcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gbW92ZSBhbGwgY2hpbGQgY29ubmVjdGlvbnMgLyBsYXlvdXQgZXh0ZXJuYWwgY29ubmVjdGlvbnNcbiAgZm9yRWFjaChhbGxDb25uZWN0aW9ucywgZnVuY3Rpb24oYykge1xuXG4gICAgdmFyIHNvdXJjZU1vdmVkID0gISFhbGxTaGFwZXNbYy5zb3VyY2UuaWRdLFxuICAgICAgICB0YXJnZXRNb3ZlZCA9ICEhYWxsU2hhcGVzW2MudGFyZ2V0LmlkXTtcblxuICAgIGlmIChlbmNsb3NlZENvbm5lY3Rpb25zW2MuaWRdICYmIHNvdXJjZU1vdmVkICYmIHRhcmdldE1vdmVkKSB7XG4gICAgICBtb2RlbGluZy5tb3ZlQ29ubmVjdGlvbihjLCBkZWx0YSwgdG9wTGV2ZWxbYy5pZF0gJiYgIWtlZXBQYXJlbnQgJiYgbmV3UGFyZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbW9kZWxpbmcubGF5b3V0Q29ubmVjdGlvbihjLCB7XG4gICAgICAgIGNvbm5lY3Rpb25TdGFydDogc291cmNlTW92ZWQgJiYgZ2V0TW92ZWRTb3VyY2VBbmNob3IoYywgYy5zb3VyY2UsIGRlbHRhKSxcbiAgICAgICAgY29ubmVjdGlvbkVuZDogdGFyZ2V0TW92ZWQgJiYgZ2V0TW92ZWRUYXJnZXRBbmNob3IoYywgYy50YXJnZXQsIGRlbHRhKVxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY2xvc3VyZSBmb3IgdGhlIHNlbGVjdGVkIGVsZW1lbnRzXG4gKlxuICogQHBhcmFtICB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICogQHJldHVybiB7TW92ZUNsb3N1cmV9IGNsb3N1cmVcbiAqL1xuTW92ZUhlbHBlci5wcm90b3R5cGUuZ2V0Q2xvc3VyZSA9IGZ1bmN0aW9uKGVsZW1lbnRzKSB7XG4gIHJldHVybiBuZXcgTW92ZUNsb3N1cmUoKS5hZGRBbGwoZWxlbWVudHMsIHRydWUpO1xufTsiLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb3VzZShldmVudEJ1cykge1xyXG4gIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgdGhpcy5fbGFzdE1vdmVFdmVudCA9IG51bGw7XHJcblxyXG4gIGZ1bmN0aW9uIHNldExhc3RNb3ZlRXZlbnQobW91c2Vtb3ZlRXZlbnQpIHtcclxuICAgIHNlbGYuX2xhc3RNb3ZlRXZlbnQgPSBtb3VzZW1vdmVFdmVudDtcclxuICB9XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuaW5pdCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIHZhciBzdmcgPSBzZWxmLl9zdmcgPSBjb250ZXh0LnN2ZztcclxuXHJcbiAgICBzdmcuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgc2V0TGFzdE1vdmVFdmVudCk7XHJcbiAgfSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuZGVzdHJveScsIGZ1bmN0aW9uKCkge1xyXG4gICAgc2VsZi5fbGFzdE1vdXNlRXZlbnQgPSBudWxsO1xyXG5cclxuICAgIHNlbGYuX3N2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBzZXRMYXN0TW92ZUV2ZW50KTtcclxuICB9KTtcclxufVxyXG5cclxuTW91c2UuJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdO1xyXG5cclxuTW91c2UucHJvdG90eXBlLmdldExhc3RNb3ZlRXZlbnQgPSBmdW5jdGlvbigpIHtcclxuICByZXR1cm4gdGhpcy5fbGFzdE1vdmVFdmVudCB8fCBjcmVhdGVNb3ZlRXZlbnQoMCwgMCk7XHJcbn07XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNb3ZlRXZlbnQoeCwgeSkge1xyXG4gIHZhciBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50Jyk7XHJcblxyXG4gIHZhciBzY3JlZW5YID0geCxcclxuICAgICAgc2NyZWVuWSA9IHksXHJcbiAgICAgIGNsaWVudFggPSB4LFxyXG4gICAgICBjbGllbnRZID0geTtcclxuXHJcbiAgaWYgKGV2ZW50LmluaXRNb3VzZUV2ZW50KSB7XHJcbiAgICBldmVudC5pbml0TW91c2VFdmVudChcclxuICAgICAgJ21vdXNlbW92ZScsXHJcbiAgICAgIHRydWUsXHJcbiAgICAgIHRydWUsXHJcbiAgICAgIHdpbmRvdyxcclxuICAgICAgMCxcclxuICAgICAgc2NyZWVuWCxcclxuICAgICAgc2NyZWVuWSxcclxuICAgICAgY2xpZW50WCxcclxuICAgICAgY2xpZW50WSxcclxuICAgICAgZmFsc2UsXHJcbiAgICAgIGZhbHNlLFxyXG4gICAgICBmYWxzZSxcclxuICAgICAgZmFsc2UsXHJcbiAgICAgIDAsXHJcbiAgICAgIG51bGxcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZXZlbnQ7XHJcbn0iLCJpbXBvcnQgTW91c2UgZnJvbSAnLi9Nb3VzZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ21vdXNlJyBdLFxuICBtb3VzZTogWyAndHlwZScsIE1vdXNlIF1cbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZpbHRlcixcbiAgZ3JvdXBCeSxcbiAgaXNPYmplY3Rcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gNTAwLFxuICAgIE1FRElVTV9QUklPUklUWSA9IDEyNTAsXG4gICAgSElHSF9QUklPUklUWSA9IDE1MDA7XG5cbmltcG9ydCB7IGdldE9yaWdpbmFsIGFzIGdldE9yaWdpbmFsRXZlbnQgfSBmcm9tICcuLi8uLi91dGlsL0V2ZW50JztcblxudmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcblxuZnVuY3Rpb24gbWlkKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBlbGVtZW50LnggKyByb3VuZChlbGVtZW50LndpZHRoIC8gMiksXG4gICAgeTogZWxlbWVudC55ICsgcm91bmQoZWxlbWVudC5oZWlnaHQgLyAyKVxuICB9O1xufVxuXG4vKipcbiAqIEEgcGx1Z2luIHRoYXQgbWFrZXMgc2hhcGVzIGRyYWdnYWJsZSAvIGRyb3BwYWJsZS5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtEcmFnZ2luZ30gZHJhZ2dpbmdcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKiBAcGFyYW0ge1NlbGVjdGlvbn0gc2VsZWN0aW9uXG4gKiBAcGFyYW0ge1J1bGVzfSBydWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb3ZlRXZlbnRzKFxuICAgIGV2ZW50QnVzLCBkcmFnZ2luZywgbW9kZWxpbmcsXG4gICAgc2VsZWN0aW9uLCBydWxlcykge1xuXG4gIC8vIHJ1bGVzXG5cbiAgZnVuY3Rpb24gY2FuTW92ZShzaGFwZXMsIGRlbHRhLCBwb3NpdGlvbiwgdGFyZ2V0KSB7XG5cbiAgICByZXR1cm4gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMubW92ZScsIHtcbiAgICAgIHNoYXBlczogc2hhcGVzLFxuICAgICAgZGVsdGE6IGRlbHRhLFxuICAgICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICB9KTtcbiAgfVxuXG5cbiAgLy8gbW92ZSBldmVudHNcblxuICAvLyBhc3NpZ24gYSBoaWdoIHByaW9yaXR5IHRvIHRoaXMgaGFuZGxlciB0byBzZXR1cCB0aGUgZW52aXJvbm1lbnRcbiAgLy8gb3RoZXJzIG1heSBob29rIHVwIGxhdGVyLCBlLmcuIGF0IGRlZmF1bHQgcHJpb3JpdHkgYW5kIG1vZGlmeVxuICAvLyB0aGUgbW92ZSBlbnZpcm9ubWVudC5cbiAgLy9cbiAgLy8gVGhpcyBzZXRzIHVwIHRoZSBjb250ZXh0IHdpdGhcbiAgLy9cbiAgLy8gKiBzaGFwZTogdGhlIHByaW1hcnkgc2hhcGUgYmVpbmcgbW92ZWRcbiAgLy8gKiBzaGFwZXM6IGEgbGlzdCBvZiBzaGFwZXMgdG8gYmUgbW92ZWRcbiAgLy8gKiB2YWxpZGF0ZWRTaGFwZXM6IGEgbGlzdCBvZiBzaGFwZXMgdGhhdCBhcmUgYmVpbmcgY2hlY2tlZFxuICAvLyAgICAgICAgICAgICAgICAgICAgYWdhaW5zdCB0aGUgcnVsZXMgYmVmb3JlIGFuZCBkdXJpbmcgbW92ZVxuICAvL1xuICBldmVudEJ1cy5vbignc2hhcGUubW92ZS5zdGFydCcsIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gZXZlbnQuc2hhcGUsXG4gICAgICAgIHNoYXBlcyA9IHNlbGVjdGlvbi5nZXQoKS5zbGljZSgpO1xuXG4gICAgLy8gbW92ZSBvbmx5IHNpbmdsZSBzaGFwZSBpZiB0aGUgZHJhZ2dlZCBlbGVtZW50XG4gICAgLy8gaXMgbm90IHBhcnQgb2YgdGhlIGN1cnJlbnQgc2VsZWN0aW9uXG4gICAgaWYgKHNoYXBlcy5pbmRleE9mKHNoYXBlKSA9PT0gLTEpIHtcbiAgICAgIHNoYXBlcyA9IFsgc2hhcGUgXTtcbiAgICB9XG5cbiAgICAvLyBlbnN1cmUgd2UgcmVtb3ZlIG5lc3RlZCBlbGVtZW50cyBpbiB0aGUgY29sbGVjdGlvblxuICAgIC8vIGFuZCBhZGQgYXR0YWNoZXJzIGZvciBhIHByb3BlciBkcmFnZ2VyXG4gICAgc2hhcGVzID0gcmVtb3ZlTmVzdGVkKHNoYXBlcyk7XG5cbiAgICAvLyBhdHRhY2ggc2hhcGVzIHRvIGRyYWcgY29udGV4dFxuICAgIGFzc2lnbihjb250ZXh0LCB7XG4gICAgICBzaGFwZXM6IHNoYXBlcyxcbiAgICAgIHZhbGlkYXRlZFNoYXBlczogc2hhcGVzLFxuICAgICAgc2hhcGU6IHNoYXBlXG4gICAgfSk7XG4gIH0pO1xuXG5cbiAgLy8gYXNzaWduIGEgaGlnaCBwcmlvcml0eSB0byB0aGlzIGhhbmRsZXIgdG8gc2V0dXAgdGhlIGVudmlyb25tZW50XG4gIC8vIG90aGVycyBtYXkgaG9vayB1cCBsYXRlciwgZS5nLiBhdCBkZWZhdWx0IHByaW9yaXR5IGFuZCBtb2RpZnlcbiAgLy8gdGhlIG1vdmUgZW52aXJvbm1lbnRcbiAgLy9cbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUuc3RhcnQnLCBNRURJVU1fUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHZhbGlkYXRlZFNoYXBlcyA9IGNvbnRleHQudmFsaWRhdGVkU2hhcGVzLFxuICAgICAgICBjYW5FeGVjdXRlO1xuXG4gICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSA9IGNhbk1vdmUodmFsaWRhdGVkU2hhcGVzKTtcblxuICAgIC8vIGNoZWNrIGlmIHdlIGNhbiBtb3ZlIHRoZSBlbGVtZW50c1xuICAgIGlmICghY2FuRXhlY3V0ZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYXNzaWduIGEgbG93IHByaW9yaXR5IHRvIHRoaXMgaGFuZGxlclxuICAvLyB0byBsZXQgb3RoZXJzIG1vZGlmeSB0aGUgbW92ZSBldmVudCBiZWZvcmUgd2UgdXBkYXRlXG4gIC8vIHRoZSBjb250ZXh0XG4gIC8vXG4gIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLm1vdmUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHZhbGlkYXRlZFNoYXBlcyA9IGNvbnRleHQudmFsaWRhdGVkU2hhcGVzLFxuICAgICAgICBob3ZlciA9IGV2ZW50LmhvdmVyLFxuICAgICAgICBkZWx0YSA9IHsgeDogZXZlbnQuZHgsIHk6IGV2ZW50LmR5IH0sXG4gICAgICAgIHBvc2l0aW9uID0geyB4OiBldmVudC54LCB5OiBldmVudC55IH0sXG4gICAgICAgIGNhbkV4ZWN1dGU7XG5cbiAgICAvLyBjaGVjayBpZiB3ZSBjYW4gbW92ZSB0aGUgZWxlbWVudHNcbiAgICBjYW5FeGVjdXRlID0gY2FuTW92ZSh2YWxpZGF0ZWRTaGFwZXMsIGRlbHRhLCBwb3NpdGlvbiwgaG92ZXIpO1xuXG4gICAgY29udGV4dC5kZWx0YSA9IGRlbHRhO1xuICAgIGNvbnRleHQuY2FuRXhlY3V0ZSA9IGNhbkV4ZWN1dGU7XG5cbiAgICAvLyBzaW1wbHkgaWdub3JlIG1vdmUgb3ZlclxuICAgIGlmIChjYW5FeGVjdXRlID09PSBudWxsKSB7XG4gICAgICBjb250ZXh0LnRhcmdldCA9IG51bGw7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb250ZXh0LnRhcmdldCA9IGhvdmVyO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignc2hhcGUubW92ZS5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0O1xuXG4gICAgdmFyIGRlbHRhID0gY29udGV4dC5kZWx0YSxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSxcbiAgICAgICAgaXNBdHRhY2ggPSBjYW5FeGVjdXRlID09PSAnYXR0YWNoJyxcbiAgICAgICAgc2hhcGVzID0gY29udGV4dC5zaGFwZXM7XG5cbiAgICBpZiAoY2FuRXhlY3V0ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBlbnN1cmUgd2UgaGF2ZSBhY3R1YWwgcGl4ZWwgdmFsdWVzIGRlbHRhc1xuICAgIC8vIChpbXBvcnRhbnQgd2hlbiB6b29tIGxldmVsIHdhcyA+IDEgZHVyaW5nIG1vdmUpXG4gICAgZGVsdGEueCA9IHJvdW5kKGRlbHRhLngpO1xuICAgIGRlbHRhLnkgPSByb3VuZChkZWx0YS55KTtcblxuICAgIGlmIChkZWx0YS54ID09PSAwICYmIGRlbHRhLnkgPT09IDApIHtcblxuICAgICAgLy8gZGlkbid0IG1vdmVcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBtb2RlbGluZy5tb3ZlRWxlbWVudHMoc2hhcGVzLCBkZWx0YSwgY29udGV4dC50YXJnZXQsIHtcbiAgICAgIHByaW1hcnlTaGFwZTogY29udGV4dC5zaGFwZSxcbiAgICAgIGF0dGFjaDogaXNBdHRhY2hcbiAgICB9KTtcbiAgfSk7XG5cblxuICAvLyBtb3ZlIGFjdGl2YXRpb25cblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tb3VzZWRvd24nLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIG9yaWdpbmFsRXZlbnQgPSBnZXRPcmlnaW5hbEV2ZW50KGV2ZW50KTtcblxuICAgIGlmICghb3JpZ2luYWxFdmVudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtdXN0IHN1cHBseSBET00gbW91c2Vkb3duIGV2ZW50Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXJ0KG9yaWdpbmFsRXZlbnQsIGV2ZW50LmVsZW1lbnQpO1xuICB9KTtcblxuICAvKipcbiAgICogU3RhcnQgbW92ZS5cbiAgICpcbiAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBldmVudFxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAgICogQHBhcmFtIHtib29sZWFufSBbYWN0aXZhdGVdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dF1cbiAgICovXG4gIGZ1bmN0aW9uIHN0YXJ0KGV2ZW50LCBlbGVtZW50LCBhY3RpdmF0ZSwgY29udGV4dCkge1xuICAgIGlmIChpc09iamVjdChhY3RpdmF0ZSkpIHtcbiAgICAgIGNvbnRleHQgPSBhY3RpdmF0ZTtcbiAgICAgIGFjdGl2YXRlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gZG8gbm90IG1vdmUgY29ubmVjdGlvbnMgb3IgdGhlIHJvb3QgZWxlbWVudFxuICAgIGlmIChlbGVtZW50LndheXBvaW50cyB8fCAhZWxlbWVudC5wYXJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcmVmZXJlbmNlUG9pbnQgPSBtaWQoZWxlbWVudCk7XG5cbiAgICBkcmFnZ2luZy5pbml0KGV2ZW50LCByZWZlcmVuY2VQb2ludCwgJ3NoYXBlLm1vdmUnLCB7XG4gICAgICBjdXJzb3I6ICdncmFiYmluZycsXG4gICAgICBhdXRvQWN0aXZhdGU6IGFjdGl2YXRlLFxuICAgICAgZGF0YToge1xuICAgICAgICBzaGFwZTogZWxlbWVudCxcbiAgICAgICAgY29udGV4dDogY29udGV4dCB8fCB7fVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gd2UndmUgaGFuZGxlZCB0aGUgZXZlbnRcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIEFQSVxuXG4gIHRoaXMuc3RhcnQgPSBzdGFydDtcbn1cblxuTW92ZUV2ZW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZHJhZ2dpbmcnLFxuICAnbW9kZWxpbmcnLFxuICAnc2VsZWN0aW9uJyxcbiAgJ3J1bGVzJ1xuXTtcblxuXG4vKipcbiAqIFJldHVybiBhIGZpbHRlcmVkIGxpc3Qgb2YgZWxlbWVudHMgdGhhdCBkbyBub3QgY29udGFpblxuICogdGhvc2UgbmVzdGVkIGludG8gb3RoZXJzLlxuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGZpbHRlcmVkXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZU5lc3RlZChlbGVtZW50cykge1xuXG4gIHZhciBpZHMgPSBncm91cEJ5KGVsZW1lbnRzLCAnaWQnKTtcblxuICByZXR1cm4gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgd2hpbGUgKChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnQpKSB7XG5cbiAgICAgIC8vIHBhcmVudCBpbiBzZWxlY3Rpb25cbiAgICAgIGlmIChpZHNbZWxlbWVudC5pZF0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcbn1cbiIsImltcG9ydCB7XG4gIGZsYXR0ZW4sXG4gIGZvckVhY2gsXG4gIGZpbHRlcixcbiAgZmluZCxcbiAgZ3JvdXBCeSxcbiAgbWFwLFxuICBtYXRjaFBhdHRlcm4sXG4gIHNpemVcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBzZWxmQW5kQWxsQ2hpbGRyZW5cbn0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbmltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY3JlYXRlIGFzIHN2Z0NyZWF0ZSxcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7IHRyYW5zbGF0ZSB9IGZyb20gJy4uLy4uL3V0aWwvU3ZnVHJhbnNmb3JtVXRpbCc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSA0OTk7XG5cbnZhciBNQVJLRVJfRFJBR0dJTkcgPSAnZGpzLWRyYWdnaW5nJyxcbiAgICBNQVJLRVJfT0sgPSAnZHJvcC1vaycsXG4gICAgTUFSS0VSX05PVF9PSyA9ICdkcm9wLW5vdC1vaycsXG4gICAgTUFSS0VSX05FV19QQVJFTlQgPSAnbmV3LXBhcmVudCcsXG4gICAgTUFSS0VSX0FUVEFDSCA9ICdhdHRhY2gtb2snO1xuXG5cbi8qKlxuICogUHJvdmlkZXMgcHJldmlld3MgZm9yIG1vdmluZyBzaGFwZXMgd2hlbiBtb3ZpbmcuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7U3R5bGVzfSBzdHlsZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW92ZVByZXZpZXcoXG4gICAgZXZlbnRCdXMsIGNhbnZhcywgc3R5bGVzLCBwcmV2aWV3U3VwcG9ydCkge1xuXG4gIGZ1bmN0aW9uIGdldFZpc3VhbERyYWdTaGFwZXMoc2hhcGVzKSB7XG4gICAgdmFyIGVsZW1lbnRzID0gZ2V0QWxsRHJhZ2dlZEVsZW1lbnRzKHNoYXBlcyk7XG5cbiAgICB2YXIgZmlsdGVyZWRFbGVtZW50cyA9IHJlbW92ZUVkZ2VzKGVsZW1lbnRzKTtcblxuICAgIHJldHVybiBmaWx0ZXJlZEVsZW1lbnRzO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0QWxsRHJhZ2dlZEVsZW1lbnRzKHNoYXBlcykge1xuICAgIHZhciBhbGxTaGFwZXMgPSBzZWxmQW5kQWxsQ2hpbGRyZW4oc2hhcGVzLCB0cnVlKTtcblxuICAgIHZhciBhbGxDb25uZWN0aW9ucyA9IG1hcChhbGxTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICByZXR1cm4gKHNoYXBlLmluY29taW5nIHx8IFtdKS5jb25jYXQoc2hhcGUub3V0Z29pbmcgfHwgW10pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZsYXR0ZW4oYWxsU2hhcGVzLmNvbmNhdChhbGxDb25uZWN0aW9ucykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgZHJvcCBtYXJrZXIgb24gYW4gZWxlbWVudC5cbiAgICovXG4gIGZ1bmN0aW9uIHNldE1hcmtlcihlbGVtZW50LCBtYXJrZXIpIHtcblxuICAgIFsgTUFSS0VSX0FUVEFDSCwgTUFSS0VSX09LLCBNQVJLRVJfTk9UX09LLCBNQVJLRVJfTkVXX1BBUkVOVCBdLmZvckVhY2goZnVuY3Rpb24obSkge1xuXG4gICAgICBpZiAobSA9PT0gbWFya2VyKSB7XG4gICAgICAgIGNhbnZhcy5hZGRNYXJrZXIoZWxlbWVudCwgbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYW52YXMucmVtb3ZlTWFya2VyKGVsZW1lbnQsIG0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgYW4gZWxlbWVudCBkcmFnZ2FibGUuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtib29sZWFufSBhZGRNYXJrZXJcbiAgICovXG4gIGZ1bmN0aW9uIG1ha2VEcmFnZ2FibGUoY29udGV4dCwgZWxlbWVudCwgYWRkTWFya2VyKSB7XG5cbiAgICBwcmV2aWV3U3VwcG9ydC5hZGREcmFnZ2VyKGVsZW1lbnQsIGNvbnRleHQuZHJhZ0dyb3VwKTtcblxuICAgIGlmIChhZGRNYXJrZXIpIHtcbiAgICAgIGNhbnZhcy5hZGRNYXJrZXIoZWxlbWVudCwgTUFSS0VSX0RSQUdHSU5HKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dC5hbGxEcmFnZ2VkRWxlbWVudHMpIHtcbiAgICAgIGNvbnRleHQuYWxsRHJhZ2dlZEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRleHQuYWxsRHJhZ2dlZEVsZW1lbnRzID0gWyBlbGVtZW50IF07XG4gICAgfVxuICB9XG5cbiAgLy8gYXNzaWduIGEgbG93IHByaW9yaXR5IHRvIHRoaXMgaGFuZGxlclxuICAvLyB0byBsZXQgb3RoZXJzIG1vZGlmeSB0aGUgbW92ZSBjb250ZXh0IGJlZm9yZVxuICAvLyB3ZSBkcmF3IHRoaW5nc1xuICBldmVudEJ1cy5vbignc2hhcGUubW92ZS5zdGFydCcsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGRyYWdTaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgYWxsRHJhZ2dlZEVsZW1lbnRzID0gY29udGV4dC5hbGxEcmFnZ2VkRWxlbWVudHM7XG5cbiAgICB2YXIgdmlzdWFsbHlEcmFnZ2VkU2hhcGVzID0gZ2V0VmlzdWFsRHJhZ1NoYXBlcyhkcmFnU2hhcGVzKTtcblxuICAgIGlmICghY29udGV4dC5kcmFnR3JvdXApIHtcbiAgICAgIHZhciBkcmFnR3JvdXAgPSBzdmdDcmVhdGUoJ2cnKTtcblxuICAgICAgc3ZnQXR0cihkcmFnR3JvdXAsIHN0eWxlcy5jbHMoJ2Rqcy1kcmFnLWdyb3VwJywgWyAnbm8tZXZlbnRzJyBdKSk7XG5cbiAgICAgIHZhciBkZWZhdWx0TGF5ZXIgPSBjYW52YXMuZ2V0RGVmYXVsdExheWVyKCk7XG5cbiAgICAgIHN2Z0FwcGVuZChkZWZhdWx0TGF5ZXIsIGRyYWdHcm91cCk7XG5cbiAgICAgIGNvbnRleHQuZHJhZ0dyb3VwID0gZHJhZ0dyb3VwO1xuICAgIH1cblxuICAgIC8vIGFkZCBwcmV2aWV3c1xuICAgIHZpc3VhbGx5RHJhZ2dlZFNoYXBlcy5mb3JFYWNoKGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICBwcmV2aWV3U3VwcG9ydC5hZGREcmFnZ2VyKHNoYXBlLCBjb250ZXh0LmRyYWdHcm91cCk7XG4gICAgfSk7XG5cbiAgICAvLyBjYWNoZSBhbGwgZHJhZ2dlZCBlbGVtZW50cyAvIGdmeFxuICAgIC8vIHNvIHRoYXQgd2UgY2FuIHF1aWNrbHkgdW5kbyB0aGVpciBzdGF0ZSBjaGFuZ2VzIGxhdGVyXG4gICAgaWYgKCFhbGxEcmFnZ2VkRWxlbWVudHMpIHtcbiAgICAgIGFsbERyYWdnZWRFbGVtZW50cyA9IGdldEFsbERyYWdnZWRFbGVtZW50cyhkcmFnU2hhcGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxsRHJhZ2dlZEVsZW1lbnRzID0gZmxhdHRlbihbXG4gICAgICAgIGFsbERyYWdnZWRFbGVtZW50cyxcbiAgICAgICAgZ2V0QWxsRHJhZ2dlZEVsZW1lbnRzKGRyYWdTaGFwZXMpXG4gICAgICBdKTtcbiAgICB9XG5cbiAgICAvLyBhZGQgZHJhZ2dpbmcgbWFya2VyXG4gICAgZm9yRWFjaChhbGxEcmFnZ2VkRWxlbWVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGNhbnZhcy5hZGRNYXJrZXIoZSwgTUFSS0VSX0RSQUdHSU5HKTtcbiAgICB9KTtcblxuICAgIGNvbnRleHQuYWxsRHJhZ2dlZEVsZW1lbnRzID0gYWxsRHJhZ2dlZEVsZW1lbnRzO1xuXG4gICAgLy8gZGV0ZXJtaW5lLCBpZiBhbnkgb2YgdGhlIGRyYWdnZWQgZWxlbWVudHMgaGF2ZSBkaWZmZXJlbnQgcGFyZW50c1xuICAgIGNvbnRleHQuZGlmZmVyZW50UGFyZW50cyA9IGhhdmVEaWZmZXJlbnRQYXJlbnRzKGRyYWdTaGFwZXMpO1xuICB9KTtcblxuICAvLyB1cGRhdGUgcHJldmlld3NcbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUubW92ZScsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgZHJhZ0dyb3VwID0gY29udGV4dC5kcmFnR3JvdXAsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICBwYXJlbnQgPSBjb250ZXh0LnNoYXBlLnBhcmVudCxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZTtcblxuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgIGlmIChjYW5FeGVjdXRlID09PSAnYXR0YWNoJykge1xuICAgICAgICBzZXRNYXJrZXIodGFyZ2V0LCBNQVJLRVJfQVRUQUNIKTtcbiAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5jYW5FeGVjdXRlICYmIHRhcmdldCAmJiB0YXJnZXQuaWQgIT09IHBhcmVudC5pZCkge1xuICAgICAgICBzZXRNYXJrZXIodGFyZ2V0LCBNQVJLRVJfTkVXX1BBUkVOVCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRNYXJrZXIodGFyZ2V0LCBjb250ZXh0LmNhbkV4ZWN1dGUgPyBNQVJLRVJfT0sgOiBNQVJLRVJfTk9UX09LKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0cmFuc2xhdGUoZHJhZ0dyb3VwLCBldmVudC5keCwgZXZlbnQuZHkpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdzaGFwZS5tb3ZlLm91dCcsICdzaGFwZS5tb3ZlLmNsZWFudXAnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgIHNldE1hcmtlcih0YXJnZXQsIG51bGwpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gcmVtb3ZlIHByZXZpZXdzXG4gIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLmNsZWFudXAnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBhbGxEcmFnZ2VkRWxlbWVudHMgPSBjb250ZXh0LmFsbERyYWdnZWRFbGVtZW50cyxcbiAgICAgICAgZHJhZ0dyb3VwID0gY29udGV4dC5kcmFnR3JvdXA7XG5cblxuICAgIC8vIHJlbW92ZSBkcmFnZ2luZyBtYXJrZXJcbiAgICBmb3JFYWNoKGFsbERyYWdnZWRFbGVtZW50cywgZnVuY3Rpb24oZSkge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihlLCBNQVJLRVJfRFJBR0dJTkcpO1xuICAgIH0pO1xuXG4gICAgaWYgKGRyYWdHcm91cCkge1xuICAgICAgc3ZnUmVtb3ZlKGRyYWdHcm91cCk7XG4gICAgfVxuICB9KTtcblxuXG4gIC8vIEFQSSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgLyoqXG4gICAqIE1ha2UgYW4gZWxlbWVudCBkcmFnZ2FibGUuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtib29sZWFufSBhZGRNYXJrZXJcbiAgICovXG4gIHRoaXMubWFrZURyYWdnYWJsZSA9IG1ha2VEcmFnZ2FibGU7XG59XG5cbk1vdmVQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnLFxuICAnc3R5bGVzJyxcbiAgJ3ByZXZpZXdTdXBwb3J0J1xuXTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiByZXR1cm5zIGVsZW1lbnRzIG1pbnVzIGFsbCBjb25uZWN0aW9uc1xuICogd2hlcmUgc291cmNlIG9yIHRhcmdldCBpcyBub3QgZWxlbWVudHNcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlRWRnZXMoZWxlbWVudHMpIHtcblxuICB2YXIgZmlsdGVyZWRFbGVtZW50cyA9IGZpbHRlcihlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgaWYgKCFpc0Nvbm5lY3Rpb24oZWxlbWVudCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIHJldHVybiAoXG4gICAgICAgIGZpbmQoZWxlbWVudHMsIG1hdGNoUGF0dGVybih7IGlkOiBlbGVtZW50LnNvdXJjZS5pZCB9KSkgJiZcbiAgICAgICAgZmluZChlbGVtZW50cywgbWF0Y2hQYXR0ZXJuKHsgaWQ6IGVsZW1lbnQudGFyZ2V0LmlkIH0pKVxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBmaWx0ZXJlZEVsZW1lbnRzO1xufVxuXG5mdW5jdGlvbiBoYXZlRGlmZmVyZW50UGFyZW50cyhlbGVtZW50cykge1xuICByZXR1cm4gc2l6ZShncm91cEJ5KGVsZW1lbnRzLCBmdW5jdGlvbihlKSB7IHJldHVybiBlLnBhcmVudCAmJiBlLnBhcmVudC5pZDsgfSkpICE9PSAxO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhbiBlbGVtZW50IGlzIGEgY29ubmVjdGlvbi5cbiAqL1xuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQud2F5cG9pbnRzO1xufVxuIiwiaW1wb3J0IEludGVyYWN0aW9uRXZlbnRzTW9kdWxlIGZyb20gJy4uL2ludGVyYWN0aW9uLWV2ZW50cyc7XG5pbXBvcnQgU2VsZWN0aW9uTW9kdWxlIGZyb20gJy4uL3NlbGVjdGlvbic7XG5pbXBvcnQgT3V0bGluZU1vZHVsZSBmcm9tICcuLi9vdXRsaW5lJztcbmltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuaW1wb3J0IFByZXZpZXdTdXBwb3J0TW9kdWxlIGZyb20gJy4uL3ByZXZpZXctc3VwcG9ydCc7XG5cbmltcG9ydCBNb3ZlIGZyb20gJy4vTW92ZSc7XG5pbXBvcnQgTW92ZVByZXZpZXcgZnJvbSAnLi9Nb3ZlUHJldmlldyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSxcbiAgICBTZWxlY3Rpb25Nb2R1bGUsXG4gICAgT3V0bGluZU1vZHVsZSxcbiAgICBSdWxlc01vZHVsZSxcbiAgICBEcmFnZ2luZ01vZHVsZSxcbiAgICBQcmV2aWV3U3VwcG9ydE1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogW1xuICAgICdtb3ZlJyxcbiAgICAnbW92ZVByZXZpZXcnXG4gIF0sXG4gIG1vdmU6IFsgJ3R5cGUnLCBNb3ZlIF0sXG4gIG1vdmVQcmV2aWV3OiBbICd0eXBlJywgTW92ZVByZXZpZXcgXVxufTtcbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnLi4vLi4vY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5cbi8qKlxuICogQW4gYWJzdHJhY3QgcHJvdmlkZXIgdGhhdCBhbGxvd3MgbW9kZWxlcnMgdG8gaW1wbGVtZW50IGEgY3VzdG9tXG4gKiBvcmRlcmluZyBvZiBkaWFncmFtIGVsZW1lbnRzIG9uIHRoZSBjYW52YXMuXG4gKlxuICogSXQgbWFrZXMgc3VyZSB0aGF0IHRoZSBvcmRlciBpcyBhbHdheXMgcHJlc2VydmVkIGR1cmluZyBlbGVtZW50XG4gKiBjcmVhdGlvbiBhbmQgbW92ZSBvcGVyYXRpb25zLlxuICpcbiAqIEluIG9yZGVyIHRvIHVzZSB0aGlzIGJlaGF2aW9yLCBpbmhlcml0IGZyb20gaXQgYW5kIG92ZXJyaWRlXG4gKiB0aGUgbWV0aG9kIHtAbGluayBPcmRlcmluZ1Byb3ZpZGVyI2dldE9yZGVyaW5nfS5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGZ1bmN0aW9uIEN1c3RvbU9yZGVyaW5nUHJvdmlkZXIoZXZlbnRCdXMpIHtcbiAqICAgT3JkZXJpbmdQcm92aWRlci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcbiAqXG4gKiAgIHRoaXMuZ2V0T3JkZXJpbmcgPSBmdW5jdGlvbihlbGVtZW50LCBuZXdQYXJlbnQpIHtcbiAqICAgICAvLyBhbHdheXMgaW5zZXJ0IGVsZW1lbnRzIGF0IHRoZSBmcm9udFxuICogICAgIC8vIHdoZW4gbW92aW5nXG4gKiAgICAgcmV0dXJuIHtcbiAqICAgICAgIGluZGV4OiAwLFxuICogICAgICAgcGFyZW50OiBuZXdQYXJlbnRcbiAqICAgICB9O1xuICogICB9O1xuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gT3JkZXJpbmdQcm92aWRlcihldmVudEJ1cykge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLnByZUV4ZWN1dGUoWyAnc2hhcGUuY3JlYXRlJywgJ2Nvbm5lY3Rpb24uY3JlYXRlJyBdLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5zaGFwZSB8fCBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50O1xuXG4gICAgdmFyIG9yZGVyaW5nID0gc2VsZi5nZXRPcmRlcmluZyhlbGVtZW50LCBwYXJlbnQpO1xuXG4gICAgaWYgKG9yZGVyaW5nKSB7XG5cbiAgICAgIGlmIChvcmRlcmluZy5wYXJlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250ZXh0LnBhcmVudCA9IG9yZGVyaW5nLnBhcmVudDtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5wYXJlbnRJbmRleCA9IG9yZGVyaW5nLmluZGV4O1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5wcmVFeGVjdXRlKFsgJ3NoYXBlLm1vdmUnLCAnY29ubmVjdGlvbi5tb3ZlJyBdLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5zaGFwZSB8fCBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHBhcmVudCA9IGNvbnRleHQubmV3UGFyZW50IHx8IGVsZW1lbnQucGFyZW50O1xuXG4gICAgdmFyIG9yZGVyaW5nID0gc2VsZi5nZXRPcmRlcmluZyhlbGVtZW50LCBwYXJlbnQpO1xuXG4gICAgaWYgKG9yZGVyaW5nKSB7XG5cbiAgICAgIGlmIChvcmRlcmluZy5wYXJlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250ZXh0Lm5ld1BhcmVudCA9IG9yZGVyaW5nLnBhcmVudDtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5uZXdQYXJlbnRJbmRleCA9IG9yZGVyaW5nLmluZGV4O1xuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgY3VzdG9tIG9yZGVyaW5nIG9mIHRoZSBlbGVtZW50LCBib3RoIGluIHRlcm1zXG4gKiBvZiBwYXJlbnQgZWxlbWVudCBhbmQgaW5kZXggaW4gdGhlIG5ldyBwYXJlbnQuXG4gKlxuICogSW1wbGVtZW50b3JzIG9mIHRoaXMgbWV0aG9kIG11c3QgcmV0dXJuIGFuIG9iamVjdCB3aXRoXG4gKiBgcGFyZW50YCBfYW5kXyBgaW5kZXhgIGluIGl0LlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBuZXdQYXJlbnRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IG9yZGVyaW5nIGRlc2NyaXB0b3JcbiAqL1xuT3JkZXJpbmdQcm92aWRlci5wcm90b3R5cGUuZ2V0T3JkZXJpbmcgPSBmdW5jdGlvbihlbGVtZW50LCBuZXdQYXJlbnQpIHtcbiAgcmV0dXJuIG51bGw7XG59O1xuXG5pbmhlcml0cyhPcmRlcmluZ1Byb3ZpZGVyLCBDb21tYW5kSW50ZXJjZXB0b3IpOyIsImltcG9ydCB7IGdldEJCb3ggfSBmcm9tICcuLi8uLi91dGlsL0VsZW1lbnRzJztcblxudmFyIExPV19QUklPUklUWSA9IDUwMDtcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxuaW1wb3J0IHtcbiAgcXVlcnkgYXMgZG9tUXVlcnlcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBBIHBsdWdpbiB0aGF0IGFkZHMgYW4gb3V0bGluZSB0byBzaGFwZXMgYW5kIGNvbm5lY3Rpb25zIHRoYXQgbWF5IGJlIGFjdGl2YXRlZCBhbmQgc3R5bGVkXG4gKiB2aWEgQ1NTIGNsYXNzZXMuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7U3R5bGVzfSBzdHlsZXNcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gT3V0bGluZShldmVudEJ1cywgc3R5bGVzLCBlbGVtZW50UmVnaXN0cnkpIHtcblxuICB0aGlzLm9mZnNldCA9IDY7XG5cbiAgdmFyIE9VVExJTkVfU1RZTEUgPSBzdHlsZXMuY2xzKCdkanMtb3V0bGluZScsIFsgJ25vLWZpbGwnIF0pO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmdW5jdGlvbiBjcmVhdGVPdXRsaW5lKGdmeCwgYm91bmRzKSB7XG4gICAgdmFyIG91dGxpbmUgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcblxuICAgIHN2Z0F0dHIob3V0bGluZSwgYXNzaWduKHtcbiAgICAgIHg6IDEwLFxuICAgICAgeTogMTAsXG4gICAgICB3aWR0aDogMTAwLFxuICAgICAgaGVpZ2h0OiAxMDBcbiAgICB9LCBPVVRMSU5FX1NUWUxFKSk7XG5cbiAgICBzdmdBcHBlbmQoZ2Z4LCBvdXRsaW5lKTtcblxuICAgIHJldHVybiBvdXRsaW5lO1xuICB9XG5cbiAgLy8gQSBsb3cgcHJpb3J0aXR5IGlzIG5lY2Vzc2FyeSwgYmVjYXVzZSBvdXRsaW5lcyBvZiBsYWJlbHMgaGF2ZSB0byBiZSB1cGRhdGVkXG4gIC8vIGFmdGVyIHRoZSBsYWJlbCBib3VuZHMgaGF2ZSBiZWVuIHVwZGF0ZWQgaW4gdGhlIHJlbmRlcmVyLlxuICBldmVudEJ1cy5vbihbICdzaGFwZS5hZGRlZCcsICdzaGFwZS5jaGFuZ2VkJyBdLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICB2YXIgb3V0bGluZSA9IGRvbVF1ZXJ5KCcuZGpzLW91dGxpbmUnLCBnZngpO1xuXG4gICAgaWYgKCFvdXRsaW5lKSB7XG4gICAgICBvdXRsaW5lID0gY3JlYXRlT3V0bGluZShnZngsIGVsZW1lbnQpO1xuICAgIH1cblxuICAgIHNlbGYudXBkYXRlU2hhcGVPdXRsaW5lKG91dGxpbmUsIGVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdjb25uZWN0aW9uLmFkZGVkJywgJ2Nvbm5lY3Rpb24uY2hhbmdlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIHZhciBvdXRsaW5lID0gZG9tUXVlcnkoJy5kanMtb3V0bGluZScsIGdmeCk7XG5cbiAgICBpZiAoIW91dGxpbmUpIHtcbiAgICAgIG91dGxpbmUgPSBjcmVhdGVPdXRsaW5lKGdmeCwgZWxlbWVudCk7XG4gICAgfVxuXG4gICAgc2VsZi51cGRhdGVDb25uZWN0aW9uT3V0bGluZShvdXRsaW5lLCBlbGVtZW50KTtcbiAgfSk7XG59XG5cblxuLyoqXG4gKiBVcGRhdGVzIHRoZSBvdXRsaW5lIG9mIGEgc2hhcGUgcmVzcGVjdGluZyB0aGUgZGltZW5zaW9uIG9mIHRoZVxuICogZWxlbWVudCBhbmQgYW4gb3V0bGluZSBvZmZzZXQuXG4gKlxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gb3V0bGluZVxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqL1xuT3V0bGluZS5wcm90b3R5cGUudXBkYXRlU2hhcGVPdXRsaW5lID0gZnVuY3Rpb24ob3V0bGluZSwgZWxlbWVudCkge1xuXG4gIHN2Z0F0dHIob3V0bGluZSwge1xuICAgIHg6IC10aGlzLm9mZnNldCxcbiAgICB5OiAtdGhpcy5vZmZzZXQsXG4gICAgd2lkdGg6IGVsZW1lbnQud2lkdGggKyB0aGlzLm9mZnNldCAqIDIsXG4gICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodCArIHRoaXMub2Zmc2V0ICogMlxuICB9KTtcblxufTtcblxuXG4vKipcbiAqIFVwZGF0ZXMgdGhlIG91dGxpbmUgb2YgYSBjb25uZWN0aW9uIHJlc3BlY3RpbmcgdGhlIGJvdW5kaW5nIGJveCBvZlxuICogdGhlIGNvbm5lY3Rpb24gYW5kIGFuIG91dGxpbmUgb2Zmc2V0LlxuICpcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IG91dGxpbmVcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKi9cbk91dGxpbmUucHJvdG90eXBlLnVwZGF0ZUNvbm5lY3Rpb25PdXRsaW5lID0gZnVuY3Rpb24ob3V0bGluZSwgY29ubmVjdGlvbikge1xuXG4gIHZhciBiYm94ID0gZ2V0QkJveChjb25uZWN0aW9uKTtcblxuICBzdmdBdHRyKG91dGxpbmUsIHtcbiAgICB4OiBiYm94LnggLSB0aGlzLm9mZnNldCxcbiAgICB5OiBiYm94LnkgLSB0aGlzLm9mZnNldCxcbiAgICB3aWR0aDogYmJveC53aWR0aCArIHRoaXMub2Zmc2V0ICogMixcbiAgICBoZWlnaHQ6IGJib3guaGVpZ2h0ICsgdGhpcy5vZmZzZXQgKiAyXG4gIH0pO1xuXG59O1xuXG5cbk91dGxpbmUuJGluamVjdCA9IFsnZXZlbnRCdXMnLCAnc3R5bGVzJywgJ2VsZW1lbnRSZWdpc3RyeSddOyIsImltcG9ydCBPdXRsaW5lIGZyb20gJy4vT3V0bGluZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ291dGxpbmUnIF0sXG4gIG91dGxpbmU6IFsgJ3R5cGUnLCBPdXRsaW5lIF1cbn07IiwiaW1wb3J0IHtcbiAgaXNBcnJheSxcbiAgaXNTdHJpbmcsXG4gIGlzT2JqZWN0LFxuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIGZpbmQsXG4gIGZpbHRlcixcbiAgbWF0Y2hQYXR0ZXJuLFxuICBpc0RlZmluZWRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBkb21pZnksXG4gIGNsYXNzZXMgYXMgZG9tQ2xhc3NlcyxcbiAgYXR0ciBhcyBkb21BdHRyLFxuICByZW1vdmUgYXMgZG9tUmVtb3ZlLFxuICBjbGVhciBhcyBkb21DbGVhclxufSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IHtcbiAgZ2V0QkJveFxufSBmcm9tICcuLi8uLi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IElkcyBmcm9tICcuLi8uLi91dGlsL0lkR2VuZXJhdG9yJztcblxuLy8gZG9jdW1lbnQgd2lkZSB1bmlxdWUgb3ZlcmxheSBpZHNcbnZhciBpZHMgPSBuZXcgSWRzKCdvdicpO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gNTAwO1xuXG5cbi8qKlxuICogQSBzZXJ2aWNlIHRoYXQgYWxsb3dzIHVzZXJzIHRvIGF0dGFjaCBvdmVybGF5cyB0byBkaWFncmFtIGVsZW1lbnRzLlxuICpcbiAqIFRoZSBvdmVybGF5IHNlcnZpY2Ugd2lsbCB0YWtlIGNhcmUgb2Ygb3ZlcmxheSBwb3NpdGlvbmluZyBkdXJpbmcgdXBkYXRlcy5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIGFkZCBhIHBpbmsgYmFkZ2Ugb24gdGhlIHRvcCBsZWZ0IG9mIHRoZSBzaGFwZVxuICogb3ZlcmxheXMuYWRkKHNvbWVTaGFwZSwge1xuICogICBwb3NpdGlvbjoge1xuICogICAgIHRvcDogLTUsXG4gKiAgICAgbGVmdDogLTVcbiAqICAgfSxcbiAqICAgaHRtbDogJzxkaXYgc3R5bGU9XCJ3aWR0aDogMTBweDsgYmFja2dyb3VuZDogZnVjaHNpYTsgY29sb3I6IHdoaXRlO1wiPjA8L2Rpdj4nXG4gKiB9KTtcbiAqXG4gKiAvLyBvciBhZGQgdmlhIHNoYXBlIGlkXG4gKlxuICogb3ZlcmxheXMuYWRkKCdzb21lLWVsZW1lbnQtaWQnLCB7XG4gKiAgIHBvc2l0aW9uOiB7XG4gKiAgICAgdG9wOiAtNSxcbiAqICAgICBsZWZ0OiAtNVxuICogICB9XG4gKiAgIGh0bWw6ICc8ZGl2IHN0eWxlPVwid2lkdGg6IDEwcHg7IGJhY2tncm91bmQ6IGZ1Y2hzaWE7IGNvbG9yOiB3aGl0ZTtcIj4wPC9kaXY+J1xuICogfSk7XG4gKlxuICogLy8gb3IgYWRkIHdpdGggb3B0aW9uYWwgdHlwZVxuICpcbiAqIG92ZXJsYXlzLmFkZChzb21lU2hhcGUsICdiYWRnZScsIHtcbiAqICAgcG9zaXRpb246IHtcbiAqICAgICB0b3A6IC01LFxuICogICAgIGxlZnQ6IC01XG4gKiAgIH1cbiAqICAgaHRtbDogJzxkaXYgc3R5bGU9XCJ3aWR0aDogMTBweDsgYmFja2dyb3VuZDogZnVjaHNpYTsgY29sb3I6IHdoaXRlO1wiPjA8L2Rpdj4nXG4gKiB9KTtcbiAqXG4gKlxuICogLy8gcmVtb3ZlIGFuIG92ZXJsYXlcbiAqXG4gKiB2YXIgaWQgPSBvdmVybGF5cy5hZGQoLi4uKTtcbiAqIG92ZXJsYXlzLnJlbW92ZShpZCk7XG4gKlxuICpcbiAqIFlvdSBtYXkgY29uZmlndXJlIG92ZXJsYXkgZGVmYXVsdHMgZHVyaW5nIHRvb2wgYnkgcHJvdmlkaW5nIGEgYGNvbmZpZ2AgbW9kdWxlXG4gKiB3aXRoIGBvdmVybGF5cy5kZWZhdWx0c2AgYXMgYW4gZW50cnk6XG4gKlxuICoge1xuICogICBvdmVybGF5czoge1xuICogICAgIGRlZmF1bHRzOiB7XG4gKiAgICAgICBzaG93OiB7XG4gKiAgICAgICAgIG1pblpvb206IDAuNyxcbiAqICAgICAgICAgbWF4Wm9vbTogNS4wXG4gKiAgICAgICB9LFxuICogICAgICAgc2NhbGU6IHtcbiAqICAgICAgICAgbWluOiAxXG4gKiAgICAgICB9XG4gKiAgICAgfVxuICogfVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWdcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE92ZXJsYXlzKGNvbmZpZywgZXZlbnRCdXMsIGNhbnZhcywgZWxlbWVudFJlZ2lzdHJ5KSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xuICB0aGlzLl9lbGVtZW50UmVnaXN0cnkgPSBlbGVtZW50UmVnaXN0cnk7XG5cbiAgdGhpcy5faWRzID0gaWRzO1xuXG4gIHRoaXMuX292ZXJsYXlEZWZhdWx0cyA9IGFzc2lnbih7XG5cbiAgICAvLyBubyBzaG93IGNvbnN0cmFpbnRzXG4gICAgc2hvdzogbnVsbCxcblxuICAgIC8vIGFsd2F5cyBzY2FsZVxuICAgIHNjYWxlOiB0cnVlXG4gIH0sIGNvbmZpZyAmJiBjb25maWcuZGVmYXVsdHMpO1xuXG4gIC8qKlxuICAgKiBNYXBwaW5nIG92ZXJsYXlJZCAtPiBvdmVybGF5XG4gICAqL1xuICB0aGlzLl9vdmVybGF5cyA9IHt9O1xuXG4gIC8qKlxuICAgKiBNYXBwaW5nIGVsZW1lbnRJZCAtPiBvdmVybGF5IGNvbnRhaW5lclxuICAgKi9cbiAgdGhpcy5fb3ZlcmxheUNvbnRhaW5lcnMgPSBbXTtcblxuICAvLyByb290IGh0bWwgZWxlbWVudCBmb3IgYWxsIG92ZXJsYXlzXG4gIHRoaXMuX292ZXJsYXlSb290ID0gY3JlYXRlUm9vdChjYW52YXMuZ2V0Q29udGFpbmVyKCkpO1xuXG4gIHRoaXMuX2luaXQoKTtcbn1cblxuXG5PdmVybGF5cy4kaW5qZWN0ID0gW1xuICAnY29uZmlnLm92ZXJsYXlzJyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcycsXG4gICdlbGVtZW50UmVnaXN0cnknXG5dO1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgb3ZlcmxheSB3aXRoIHRoZSBzcGVjaWZpZWQgaWQgb3IgYSBsaXN0IG9mIG92ZXJsYXlzXG4gKiBmb3IgYW4gZWxlbWVudCB3aXRoIGEgZ2l2ZW4gdHlwZS5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIHJldHVybiB0aGUgc2luZ2xlIG92ZXJsYXkgd2l0aCB0aGUgZ2l2ZW4gaWRcbiAqIG92ZXJsYXlzLmdldCgnc29tZS1pZCcpO1xuICpcbiAqIC8vIHJldHVybiBhbGwgb3ZlcmxheXMgZm9yIHRoZSBzaGFwZVxuICogb3ZlcmxheXMuZ2V0KHsgZWxlbWVudDogc29tZVNoYXBlIH0pO1xuICpcbiAqIC8vIHJldHVybiBhbGwgb3ZlcmxheXMgb24gc2hhcGUgd2l0aCB0eXBlICdiYWRnZSdcbiAqIG92ZXJsYXlzLmdldCh7IGVsZW1lbnQ6IHNvbWVTaGFwZSwgdHlwZTogJ2JhZGdlJyB9KTtcbiAqXG4gKiAvLyBzaGFwZSBjYW4gYWxzbyBiZSBzcGVjaWZpZWQgYXMgaWRcbiAqIG92ZXJsYXlzLmdldCh7IGVsZW1lbnQ6ICdlbGVtZW50LWlkJywgdHlwZTogJ2JhZGdlJyB9KTtcbiAqXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlYXJjaFxuICogQHBhcmFtIHtzdHJpbmd9IFtzZWFyY2guaWRdXG4gKiBAcGFyYW0ge3N0cmluZ3xkanMubW9kZWwuQmFzZX0gW3NlYXJjaC5lbGVtZW50XVxuICogQHBhcmFtIHtzdHJpbmd9IFtzZWFyY2gudHlwZV1cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R8QXJyYXk8T2JqZWN0Pn0gdGhlIG92ZXJsYXkocylcbiAqL1xuT3ZlcmxheXMucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHNlYXJjaCkge1xuXG4gIGlmIChpc1N0cmluZyhzZWFyY2gpKSB7XG4gICAgc2VhcmNoID0geyBpZDogc2VhcmNoIH07XG4gIH1cblxuICBpZiAoaXNTdHJpbmcoc2VhcmNoLmVsZW1lbnQpKSB7XG4gICAgc2VhcmNoLmVsZW1lbnQgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0KHNlYXJjaC5lbGVtZW50KTtcbiAgfVxuXG4gIGlmIChzZWFyY2guZWxlbWVudCkge1xuICAgIHZhciBjb250YWluZXIgPSB0aGlzLl9nZXRPdmVybGF5Q29udGFpbmVyKHNlYXJjaC5lbGVtZW50LCB0cnVlKTtcblxuICAgIC8vIHJldHVybiBhIGxpc3Qgb2Ygb3ZlcmxheXMgd2hlbiBzZWFyY2hpbmcgYnkgZWxlbWVudCAoK3R5cGUpXG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgcmV0dXJuIHNlYXJjaC50eXBlID8gZmlsdGVyKGNvbnRhaW5lci5vdmVybGF5cywgbWF0Y2hQYXR0ZXJuKHsgdHlwZTogc2VhcmNoLnR5cGUgfSkpIDogY29udGFpbmVyLm92ZXJsYXlzLnNsaWNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH0gZWxzZVxuICBpZiAoc2VhcmNoLnR5cGUpIHtcbiAgICByZXR1cm4gZmlsdGVyKHRoaXMuX292ZXJsYXlzLCBtYXRjaFBhdHRlcm4oeyB0eXBlOiBzZWFyY2gudHlwZSB9KSk7XG4gIH0gZWxzZSB7XG5cbiAgICAvLyByZXR1cm4gc2luZ2xlIGVsZW1lbnQgd2hlbiBzZWFyY2hpbmcgYnkgaWRcbiAgICByZXR1cm4gc2VhcmNoLmlkID8gdGhpcy5fb3ZlcmxheXNbc2VhcmNoLmlkXSA6IG51bGw7XG4gIH1cbn07XG5cbi8qKlxuICogQWRkcyBhIEhUTUwgb3ZlcmxheSB0byBhbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfGRqcy5tb2RlbC5CYXNlfSAgIGVsZW1lbnQgICBhdHRhY2ggb3ZlcmxheSB0byB0aGlzIHNoYXBlXG4gKiBAcGFyYW0ge3N0cmluZ30gICAgICAgICAgICAgICAgICBbdHlwZV0gICAgb3B0aW9uYWwgdHlwZSB0byBhc3NpZ24gdG8gdGhlIG92ZXJsYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSAgICAgICAgICAgICAgICAgIG92ZXJsYXkgICB0aGUgb3ZlcmxheSBjb25maWd1cmF0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8RE9NRWxlbWVudH0gICAgICAgb3ZlcmxheS5odG1sICAgICAgICAgICAgICAgICBodG1sIGVsZW1lbnQgdG8gdXNlIGFzIGFuIG92ZXJsYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSAgICAgICAgICAgICAgICAgIFtvdmVybGF5LnNob3ddICAgICAgICAgICAgICAgc2hvdyBjb25maWd1cmF0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICAgICBbb3ZlcmxheS5zaG93Lm1pblpvb21dICAgICAgIG1pbmltYWwgem9vbSBsZXZlbCB0byBzaG93IHRoZSBvdmVybGF5XG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICAgICBbb3ZlcmxheS5zaG93Lm1heFpvb21dICAgICAgIG1heGltdW0gem9vbSBsZXZlbCB0byBzaG93IHRoZSBvdmVybGF5XG4gKiBAcGFyYW0ge09iamVjdH0gICAgICAgICAgICAgICAgICBvdmVybGF5LnBvc2l0aW9uICAgICAgICAgICAgIHdoZXJlIHRvIGF0dGFjaCB0aGUgb3ZlcmxheVxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgICAgW292ZXJsYXkucG9zaXRpb24ubGVmdF0gICAgICByZWxhdGl2ZSB0byBlbGVtZW50IGJib3ggbGVmdCBhdHRhY2htZW50XG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICAgICBbb3ZlcmxheS5wb3NpdGlvbi50b3BdICAgICAgIHJlbGF0aXZlIHRvIGVsZW1lbnQgYmJveCB0b3AgYXR0YWNobWVudFxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgICAgW292ZXJsYXkucG9zaXRpb24uYm90dG9tXSAgICByZWxhdGl2ZSB0byBlbGVtZW50IGJib3ggYm90dG9tIGF0dGFjaG1lbnRcbiAqIEBwYXJhbSB7bnVtYmVyfSAgICAgICAgICAgICAgICAgIFtvdmVybGF5LnBvc2l0aW9uLnJpZ2h0XSAgICAgcmVsYXRpdmUgdG8gZWxlbWVudCBiYm94IHJpZ2h0IGF0dGFjaG1lbnRcbiAqIEBwYXJhbSB7Ym9vbGVhbnxPYmplY3R9ICAgICAgICAgIFtvdmVybGF5LnNjYWxlPXRydWVdICAgICAgICAgZmFsc2UgdG8gcHJlc2VydmUgdGhlIHNhbWUgc2l6ZSByZWdhcmRsZXNzIG9mXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdyYW0gem9vbVxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgICAgW292ZXJsYXkuc2NhbGUubWluXVxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgICAgW292ZXJsYXkuc2NhbGUubWF4XVxuICpcbiAqIEByZXR1cm4ge3N0cmluZ30gICAgICAgICAgICAgICAgIGlkIHRoYXQgbWF5IGJlIHVzZWQgdG8gcmVmZXJlbmNlIHRoZSBvdmVybGF5IGZvciB1cGRhdGUgb3IgcmVtb3ZhbFxuICovXG5PdmVybGF5cy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24oZWxlbWVudCwgdHlwZSwgb3ZlcmxheSkge1xuXG4gIGlmIChpc09iamVjdCh0eXBlKSkge1xuICAgIG92ZXJsYXkgPSB0eXBlO1xuICAgIHR5cGUgPSBudWxsO1xuICB9XG5cbiAgaWYgKCFlbGVtZW50LmlkKSB7XG4gICAgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXQoZWxlbWVudCk7XG4gIH1cblxuICBpZiAoIW92ZXJsYXkucG9zaXRpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ211c3Qgc3BlY2lmaXkgb3ZlcmxheSBwb3NpdGlvbicpO1xuICB9XG5cbiAgaWYgKCFvdmVybGF5Lmh0bWwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ211c3Qgc3BlY2lmaXkgb3ZlcmxheSBodG1sJyk7XG4gIH1cblxuICBpZiAoIWVsZW1lbnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgZWxlbWVudCBzcGVjaWZpZWQnKTtcbiAgfVxuXG4gIHZhciBpZCA9IHRoaXMuX2lkcy5uZXh0KCk7XG5cbiAgb3ZlcmxheSA9IGFzc2lnbih7fSwgdGhpcy5fb3ZlcmxheURlZmF1bHRzLCBvdmVybGF5LCB7XG4gICAgaWQ6IGlkLFxuICAgIHR5cGU6IHR5cGUsXG4gICAgZWxlbWVudDogZWxlbWVudCxcbiAgICBodG1sOiBvdmVybGF5Lmh0bWxcbiAgfSk7XG5cbiAgdGhpcy5fYWRkT3ZlcmxheShvdmVybGF5KTtcblxuICByZXR1cm4gaWQ7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlIGFuIG92ZXJsYXkgd2l0aCB0aGUgZ2l2ZW4gaWQgb3IgYWxsIG92ZXJsYXlzIG1hdGNoaW5nIHRoZSBnaXZlbiBmaWx0ZXIuXG4gKlxuICogQHNlZSBPdmVybGF5cyNnZXQgZm9yIGZpbHRlciBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbaWRdXG4gKiBAcGFyYW0ge09iamVjdH0gW2ZpbHRlcl1cbiAqL1xuT3ZlcmxheXMucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKGZpbHRlcikge1xuXG4gIHZhciBvdmVybGF5cyA9IHRoaXMuZ2V0KGZpbHRlcikgfHwgW107XG5cbiAgaWYgKCFpc0FycmF5KG92ZXJsYXlzKSkge1xuICAgIG92ZXJsYXlzID0gWyBvdmVybGF5cyBdO1xuICB9XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGZvckVhY2gob3ZlcmxheXMsIGZ1bmN0aW9uKG92ZXJsYXkpIHtcblxuICAgIHZhciBjb250YWluZXIgPSBzZWxmLl9nZXRPdmVybGF5Q29udGFpbmVyKG92ZXJsYXkuZWxlbWVudCwgdHJ1ZSk7XG5cbiAgICBpZiAob3ZlcmxheSkge1xuICAgICAgZG9tUmVtb3ZlKG92ZXJsYXkuaHRtbCk7XG4gICAgICBkb21SZW1vdmUob3ZlcmxheS5odG1sQ29udGFpbmVyKTtcblxuICAgICAgZGVsZXRlIG92ZXJsYXkuaHRtbENvbnRhaW5lcjtcbiAgICAgIGRlbGV0ZSBvdmVybGF5LmVsZW1lbnQ7XG5cbiAgICAgIGRlbGV0ZSBzZWxmLl9vdmVybGF5c1tvdmVybGF5LmlkXTtcbiAgICB9XG5cbiAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICB2YXIgaWR4ID0gY29udGFpbmVyLm92ZXJsYXlzLmluZGV4T2Yob3ZlcmxheSk7XG4gICAgICBpZiAoaWR4ICE9PSAtMSkge1xuICAgICAgICBjb250YWluZXIub3ZlcmxheXMuc3BsaWNlKGlkeCwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxufTtcblxuXG5PdmVybGF5cy5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uKCkge1xuICBzZXRWaXNpYmxlKHRoaXMuX292ZXJsYXlSb290KTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbigpIHtcbiAgc2V0VmlzaWJsZSh0aGlzLl9vdmVybGF5Um9vdCwgZmFsc2UpO1xufTtcblxuT3ZlcmxheXMucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX292ZXJsYXlzID0ge307XG5cbiAgdGhpcy5fb3ZlcmxheUNvbnRhaW5lcnMgPSBbXTtcblxuICBkb21DbGVhcih0aGlzLl9vdmVybGF5Um9vdCk7XG59O1xuXG5PdmVybGF5cy5wcm90b3R5cGUuX3VwZGF0ZU92ZXJsYXlDb250YWluZXIgPSBmdW5jdGlvbihjb250YWluZXIpIHtcbiAgdmFyIGVsZW1lbnQgPSBjb250YWluZXIuZWxlbWVudCxcbiAgICAgIGh0bWwgPSBjb250YWluZXIuaHRtbDtcblxuICAvLyB1cGRhdGUgY29udGFpbmVyIGxlZnQsdG9wIGFjY29yZGluZyB0byB0aGUgZWxlbWVudHMgeCx5IGNvb3JkaW5hdGVzXG4gIC8vIHRoaXMgZW5zdXJlcyB3ZSBjYW4gYXR0YWNoIGNoaWxkIGVsZW1lbnRzIHJlbGF0aXZlIHRvIHRoaXMgY29udGFpbmVyXG5cbiAgdmFyIHggPSBlbGVtZW50LngsXG4gICAgICB5ID0gZWxlbWVudC55O1xuXG4gIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgIHZhciBiYm94ID0gZ2V0QkJveChlbGVtZW50KTtcbiAgICB4ID0gYmJveC54O1xuICAgIHkgPSBiYm94Lnk7XG4gIH1cblxuICBzZXRQb3NpdGlvbihodG1sLCB4LCB5KTtcblxuICBkb21BdHRyKGNvbnRhaW5lci5odG1sLCAnZGF0YS1jb250YWluZXItaWQnLCBlbGVtZW50LmlkKTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl91cGRhdGVPdmVybGF5ID0gZnVuY3Rpb24ob3ZlcmxheSkge1xuXG4gIHZhciBwb3NpdGlvbiA9IG92ZXJsYXkucG9zaXRpb24sXG4gICAgICBodG1sQ29udGFpbmVyID0gb3ZlcmxheS5odG1sQ29udGFpbmVyLFxuICAgICAgZWxlbWVudCA9IG92ZXJsYXkuZWxlbWVudDtcblxuICAvLyB1cGRhdGUgb3ZlcmxheSBodG1sIHJlbGF0aXZlIHRvIHNoYXBlIGJlY2F1c2VcbiAgLy8gaXQgaXMgYWxyZWFkeSBwb3NpdGlvbmVkIG9uIHRoZSBlbGVtZW50XG5cbiAgLy8gdXBkYXRlIHJlbGF0aXZlXG4gIHZhciBsZWZ0ID0gcG9zaXRpb24ubGVmdCxcbiAgICAgIHRvcCA9IHBvc2l0aW9uLnRvcDtcblxuICBpZiAocG9zaXRpb24ucmlnaHQgIT09IHVuZGVmaW5lZCkge1xuXG4gICAgdmFyIHdpZHRoO1xuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICB3aWR0aCA9IGdldEJCb3goZWxlbWVudCkud2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpZHRoID0gZWxlbWVudC53aWR0aDtcbiAgICB9XG5cbiAgICBsZWZ0ID0gcG9zaXRpb24ucmlnaHQgKiAtMSArIHdpZHRoO1xuICB9XG5cbiAgaWYgKHBvc2l0aW9uLmJvdHRvbSAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICB2YXIgaGVpZ2h0O1xuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICBoZWlnaHQgPSBnZXRCQm94KGVsZW1lbnQpLmhlaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgaGVpZ2h0ID0gZWxlbWVudC5oZWlnaHQ7XG4gICAgfVxuXG4gICAgdG9wID0gcG9zaXRpb24uYm90dG9tICogLTEgKyBoZWlnaHQ7XG4gIH1cblxuICBzZXRQb3NpdGlvbihodG1sQ29udGFpbmVyLCBsZWZ0IHx8IDAsIHRvcCB8fCAwKTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl9jcmVhdGVPdmVybGF5Q29udGFpbmVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICB2YXIgaHRtbCA9IGRvbWlmeSgnPGRpdiBjbGFzcz1cImRqcy1vdmVybGF5c1wiIHN0eWxlPVwicG9zaXRpb246IGFic29sdXRlXCIgLz4nKTtcblxuICB0aGlzLl9vdmVybGF5Um9vdC5hcHBlbmRDaGlsZChodG1sKTtcblxuICB2YXIgY29udGFpbmVyID0ge1xuICAgIGh0bWw6IGh0bWwsXG4gICAgZWxlbWVudDogZWxlbWVudCxcbiAgICBvdmVybGF5czogW11cbiAgfTtcblxuICB0aGlzLl91cGRhdGVPdmVybGF5Q29udGFpbmVyKGNvbnRhaW5lcik7XG5cbiAgdGhpcy5fb3ZlcmxheUNvbnRhaW5lcnMucHVzaChjb250YWluZXIpO1xuXG4gIHJldHVybiBjb250YWluZXI7XG59O1xuXG5cbk92ZXJsYXlzLnByb3RvdHlwZS5fdXBkYXRlUm9vdCA9IGZ1bmN0aW9uKHZpZXdib3gpIHtcbiAgdmFyIHNjYWxlID0gdmlld2JveC5zY2FsZSB8fCAxO1xuXG4gIHZhciBtYXRyaXggPSAnbWF0cml4KCcgK1xuICBbXG4gICAgc2NhbGUsXG4gICAgMCxcbiAgICAwLFxuICAgIHNjYWxlLFxuICAgIC0xICogdmlld2JveC54ICogc2NhbGUsXG4gICAgLTEgKiB2aWV3Ym94LnkgKiBzY2FsZVxuICBdLmpvaW4oJywnKSArXG4gICcpJztcblxuICBzZXRUcmFuc2Zvcm0odGhpcy5fb3ZlcmxheVJvb3QsIG1hdHJpeCk7XG59O1xuXG5cbk92ZXJsYXlzLnByb3RvdHlwZS5fZ2V0T3ZlcmxheUNvbnRhaW5lciA9IGZ1bmN0aW9uKGVsZW1lbnQsIHJhdykge1xuICB2YXIgY29udGFpbmVyID0gZmluZCh0aGlzLl9vdmVybGF5Q29udGFpbmVycywgZnVuY3Rpb24oYykge1xuICAgIHJldHVybiBjLmVsZW1lbnQgPT09IGVsZW1lbnQ7XG4gIH0pO1xuXG5cbiAgaWYgKCFjb250YWluZXIgJiYgIXJhdykge1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVPdmVybGF5Q29udGFpbmVyKGVsZW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRhaW5lcjtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl9hZGRPdmVybGF5ID0gZnVuY3Rpb24ob3ZlcmxheSkge1xuXG4gIHZhciBpZCA9IG92ZXJsYXkuaWQsXG4gICAgICBlbGVtZW50ID0gb3ZlcmxheS5lbGVtZW50LFxuICAgICAgaHRtbCA9IG92ZXJsYXkuaHRtbCxcbiAgICAgIGh0bWxDb250YWluZXIsXG4gICAgICBvdmVybGF5Q29udGFpbmVyO1xuXG4gIC8vIHVud3JhcCBqcXVlcnkgKGZvciB0aG9zZSB3aG8gbmVlZCBpdClcbiAgaWYgKGh0bWwuZ2V0ICYmIGh0bWwuY29uc3RydWN0b3IucHJvdG90eXBlLmpxdWVyeSkge1xuICAgIGh0bWwgPSBodG1sLmdldCgwKTtcbiAgfVxuXG4gIC8vIGNyZWF0ZSBwcm9wZXIgaHRtbCBlbGVtZW50cyBmcm9tXG4gIC8vIG92ZXJsYXkgSFRNTCBzdHJpbmdzXG4gIGlmIChpc1N0cmluZyhodG1sKSkge1xuICAgIGh0bWwgPSBkb21pZnkoaHRtbCk7XG4gIH1cblxuICBvdmVybGF5Q29udGFpbmVyID0gdGhpcy5fZ2V0T3ZlcmxheUNvbnRhaW5lcihlbGVtZW50KTtcblxuICBodG1sQ29udGFpbmVyID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiZGpzLW92ZXJsYXlcIiBkYXRhLW92ZXJsYXktaWQ9XCInICsgaWQgKyAnXCIgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGVcIj4nKTtcblxuICBodG1sQ29udGFpbmVyLmFwcGVuZENoaWxkKGh0bWwpO1xuXG4gIGlmIChvdmVybGF5LnR5cGUpIHtcbiAgICBkb21DbGFzc2VzKGh0bWxDb250YWluZXIpLmFkZCgnZGpzLW92ZXJsYXktJyArIG92ZXJsYXkudHlwZSk7XG4gIH1cblxuICBvdmVybGF5Lmh0bWxDb250YWluZXIgPSBodG1sQ29udGFpbmVyO1xuXG4gIG92ZXJsYXlDb250YWluZXIub3ZlcmxheXMucHVzaChvdmVybGF5KTtcbiAgb3ZlcmxheUNvbnRhaW5lci5odG1sLmFwcGVuZENoaWxkKGh0bWxDb250YWluZXIpO1xuXG4gIHRoaXMuX292ZXJsYXlzW2lkXSA9IG92ZXJsYXk7XG5cbiAgdGhpcy5fdXBkYXRlT3ZlcmxheShvdmVybGF5KTtcbiAgdGhpcy5fdXBkYXRlT3ZlcmxheVZpc2liaWx0eShvdmVybGF5LCB0aGlzLl9jYW52YXMudmlld2JveCgpKTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl91cGRhdGVPdmVybGF5VmlzaWJpbHR5ID0gZnVuY3Rpb24ob3ZlcmxheSwgdmlld2JveCkge1xuICB2YXIgc2hvdyA9IG92ZXJsYXkuc2hvdyxcbiAgICAgIG1pblpvb20gPSBzaG93ICYmIHNob3cubWluWm9vbSxcbiAgICAgIG1heFpvb20gPSBzaG93ICYmIHNob3cubWF4Wm9vbSxcbiAgICAgIGh0bWxDb250YWluZXIgPSBvdmVybGF5Lmh0bWxDb250YWluZXIsXG4gICAgICB2aXNpYmxlID0gdHJ1ZTtcblxuICBpZiAoc2hvdykge1xuICAgIGlmIChcbiAgICAgIChpc0RlZmluZWQobWluWm9vbSkgJiYgbWluWm9vbSA+IHZpZXdib3guc2NhbGUpIHx8XG4gICAgICAoaXNEZWZpbmVkKG1heFpvb20pICYmIG1heFpvb20gPCB2aWV3Ym94LnNjYWxlKVxuICAgICkge1xuICAgICAgdmlzaWJsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIHNldFZpc2libGUoaHRtbENvbnRhaW5lciwgdmlzaWJsZSk7XG4gIH1cblxuICB0aGlzLl91cGRhdGVPdmVybGF5U2NhbGUob3ZlcmxheSwgdmlld2JveCk7XG59O1xuXG5cbk92ZXJsYXlzLnByb3RvdHlwZS5fdXBkYXRlT3ZlcmxheVNjYWxlID0gZnVuY3Rpb24ob3ZlcmxheSwgdmlld2JveCkge1xuICB2YXIgc2hvdWxkU2NhbGUgPSBvdmVybGF5LnNjYWxlLFxuICAgICAgbWluU2NhbGUsXG4gICAgICBtYXhTY2FsZSxcbiAgICAgIGh0bWxDb250YWluZXIgPSBvdmVybGF5Lmh0bWxDb250YWluZXI7XG5cbiAgdmFyIHNjYWxlLCB0cmFuc2Zvcm0gPSAnJztcblxuICBpZiAoc2hvdWxkU2NhbGUgIT09IHRydWUpIHtcblxuICAgIGlmIChzaG91bGRTY2FsZSA9PT0gZmFsc2UpIHtcbiAgICAgIG1pblNjYWxlID0gMTtcbiAgICAgIG1heFNjYWxlID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWluU2NhbGUgPSBzaG91bGRTY2FsZS5taW47XG4gICAgICBtYXhTY2FsZSA9IHNob3VsZFNjYWxlLm1heDtcbiAgICB9XG5cbiAgICBpZiAoaXNEZWZpbmVkKG1pblNjYWxlKSAmJiB2aWV3Ym94LnNjYWxlIDwgbWluU2NhbGUpIHtcbiAgICAgIHNjYWxlID0gKDEgLyB2aWV3Ym94LnNjYWxlIHx8IDEpICogbWluU2NhbGU7XG4gICAgfVxuXG4gICAgaWYgKGlzRGVmaW5lZChtYXhTY2FsZSkgJiYgdmlld2JveC5zY2FsZSA+IG1heFNjYWxlKSB7XG4gICAgICBzY2FsZSA9ICgxIC8gdmlld2JveC5zY2FsZSB8fCAxKSAqIG1heFNjYWxlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc0RlZmluZWQoc2NhbGUpKSB7XG4gICAgdHJhbnNmb3JtID0gJ3NjYWxlKCcgKyBzY2FsZSArICcsJyArIHNjYWxlICsgJyknO1xuICB9XG5cbiAgc2V0VHJhbnNmb3JtKGh0bWxDb250YWluZXIsIHRyYW5zZm9ybSk7XG59O1xuXG5cbk92ZXJsYXlzLnByb3RvdHlwZS5fdXBkYXRlT3ZlcmxheXNWaXNpYmlsdHkgPSBmdW5jdGlvbih2aWV3Ym94KSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGZvckVhY2godGhpcy5fb3ZlcmxheXMsIGZ1bmN0aW9uKG92ZXJsYXkpIHtcbiAgICBzZWxmLl91cGRhdGVPdmVybGF5VmlzaWJpbHR5KG92ZXJsYXksIHZpZXdib3gpO1xuICB9KTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG5cbiAgLy8gc2Nyb2xsL3pvb20gaW50ZWdyYXRpb25cblxuICBmdW5jdGlvbiB1cGRhdGVWaWV3Ym94KHZpZXdib3gpIHtcbiAgICBzZWxmLl91cGRhdGVSb290KHZpZXdib3gpO1xuICAgIHNlbGYuX3VwZGF0ZU92ZXJsYXlzVmlzaWJpbHR5KHZpZXdib3gpO1xuXG4gICAgc2VsZi5zaG93KCk7XG4gIH1cblxuICBldmVudEJ1cy5vbignY2FudmFzLnZpZXdib3guY2hhbmdpbmcnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHNlbGYuaGlkZSgpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY2FudmFzLnZpZXdib3guY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdXBkYXRlVmlld2JveChldmVudC52aWV3Ym94KTtcbiAgfSk7XG5cblxuICAvLyByZW1vdmUgaW50ZWdyYXRpb25cblxuICBldmVudEJ1cy5vbihbICdzaGFwZS5yZW1vdmUnLCAnY29ubmVjdGlvbi5yZW1vdmUnIF0sIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbWVudCA9IGUuZWxlbWVudDtcbiAgICB2YXIgb3ZlcmxheXMgPSBzZWxmLmdldCh7IGVsZW1lbnQ6IGVsZW1lbnQgfSk7XG5cbiAgICBmb3JFYWNoKG92ZXJsYXlzLCBmdW5jdGlvbihvKSB7XG4gICAgICBzZWxmLnJlbW92ZShvLmlkKTtcbiAgICB9KTtcblxuICAgIHZhciBjb250YWluZXIgPSBzZWxmLl9nZXRPdmVybGF5Q29udGFpbmVyKGVsZW1lbnQpO1xuXG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgZG9tUmVtb3ZlKGNvbnRhaW5lci5odG1sKTtcbiAgICAgIHZhciBpID0gc2VsZi5fb3ZlcmxheUNvbnRhaW5lcnMuaW5kZXhPZihjb250YWluZXIpO1xuICAgICAgaWYgKGkgIT09IC0xKSB7XG4gICAgICAgIHNlbGYuX292ZXJsYXlDb250YWluZXJzLnNwbGljZShpLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG5cbiAgLy8gbW92ZSBpbnRlZ3JhdGlvblxuXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LmNoYW5nZWQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbWVudCA9IGUuZWxlbWVudDtcblxuICAgIHZhciBjb250YWluZXIgPSBzZWxmLl9nZXRPdmVybGF5Q29udGFpbmVyKGVsZW1lbnQsIHRydWUpO1xuXG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgZm9yRWFjaChjb250YWluZXIub3ZlcmxheXMsIGZ1bmN0aW9uKG92ZXJsYXkpIHtcbiAgICAgICAgc2VsZi5fdXBkYXRlT3ZlcmxheShvdmVybGF5KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZWxmLl91cGRhdGVPdmVybGF5Q29udGFpbmVyKGNvbnRhaW5lcik7XG4gICAgfVxuICB9KTtcblxuXG4gIC8vIG1hcmtlciBpbnRlZ3JhdGlvbiwgc2ltcGx5IGFkZCB0aGVtIG9uIHRoZSBvdmVybGF5cyBhcyBjbGFzc2VzLCB0b28uXG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQubWFya2VyLnVwZGF0ZScsIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgY29udGFpbmVyID0gc2VsZi5fZ2V0T3ZlcmxheUNvbnRhaW5lcihlLmVsZW1lbnQsIHRydWUpO1xuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgIGRvbUNsYXNzZXMoY29udGFpbmVyLmh0bWwpW2UuYWRkID8gJ2FkZCcgOiAncmVtb3ZlJ10oZS5tYXJrZXIpO1xuICAgIH1cbiAgfSk7XG5cblxuICAvLyBjbGVhciBvdmVybGF5cyB3aXRoIGRpYWdyYW1cblxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5jbGVhcicsIHRoaXMuY2xlYXIsIHRoaXMpO1xufTtcblxuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gY3JlYXRlUm9vdChwYXJlbnROb2RlKSB7XG4gIHZhciByb290ID0gZG9taWZ5KFxuICAgICc8ZGl2IGNsYXNzPVwiZGpzLW92ZXJsYXktY29udGFpbmVyXCIgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IHdpZHRoOiAwOyBoZWlnaHQ6IDA7XCIgLz4nXG4gICk7XG5cbiAgcGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUocm9vdCwgcGFyZW50Tm9kZS5maXJzdENoaWxkKTtcblxuICByZXR1cm4gcm9vdDtcbn1cblxuZnVuY3Rpb24gc2V0UG9zaXRpb24oZWwsIHgsIHkpIHtcbiAgYXNzaWduKGVsLnN0eWxlLCB7IGxlZnQ6IHggKyAncHgnLCB0b3A6IHkgKyAncHgnIH0pO1xufVxuXG5mdW5jdGlvbiBzZXRWaXNpYmxlKGVsLCB2aXNpYmxlKSB7XG4gIGVsLnN0eWxlLmRpc3BsYXkgPSB2aXNpYmxlID09PSBmYWxzZSA/ICdub25lJyA6ICcnO1xufVxuXG5mdW5jdGlvbiBzZXRUcmFuc2Zvcm0oZWwsIHRyYW5zZm9ybSkge1xuXG4gIGVsLnN0eWxlWyd0cmFuc2Zvcm0tb3JpZ2luJ10gPSAndG9wIGxlZnQnO1xuXG4gIFsgJycsICctbXMtJywgJy13ZWJraXQtJyBdLmZvckVhY2goZnVuY3Rpb24ocHJlZml4KSB7XG4gICAgZWwuc3R5bGVbcHJlZml4ICsgJ3RyYW5zZm9ybSddID0gdHJhbnNmb3JtO1xuICB9KTtcbn0iLCJpbXBvcnQgT3ZlcmxheXMgZnJvbSAnLi9PdmVybGF5cyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ292ZXJsYXlzJyBdLFxuICBvdmVybGF5czogWyAndHlwZScsIE92ZXJsYXlzIF1cbn07IiwiaW1wb3J0IHtcbiAgaXNBcnJheSxcbiAgaXNGdW5jdGlvbixcbiAgZm9yRWFjaFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRvbWlmeSxcbiAgcXVlcnkgYXMgZG9tUXVlcnksXG4gIGF0dHIgYXMgZG9tQXR0cixcbiAgY2xlYXIgYXMgZG9tQ2xlYXIsXG4gIGNsYXNzZXMgYXMgZG9tQ2xhc3NlcyxcbiAgbWF0Y2hlcyBhcyBkb21NYXRjaGVzLFxuICBkZWxlZ2F0ZSBhcyBkb21EZWxlZ2F0ZSxcbiAgZXZlbnQgYXMgZG9tRXZlbnRcbn0gZnJvbSAnbWluLWRvbSc7XG5cblxudmFyIFRPR0dMRV9TRUxFQ1RPUiA9ICcuZGpzLXBhbGV0dGUtdG9nZ2xlJyxcbiAgICBFTlRSWV9TRUxFQ1RPUiA9ICcuZW50cnknLFxuICAgIEVMRU1FTlRfU0VMRUNUT1IgPSBUT0dHTEVfU0VMRUNUT1IgKyAnLCAnICsgRU5UUllfU0VMRUNUT1I7XG5cbnZhciBQQUxFVFRFX09QRU5fQ0xTID0gJ29wZW4nLFxuICAgIFBBTEVUVEVfVFdPX0NPTFVNTl9DTFMgPSAndHdvLWNvbHVtbic7XG5cbnZhciBERUZBVUxUX1BSSU9SSVRZID0gMTAwMDtcblxuXG4vKipcbiAqIEEgcGFsZXR0ZSBjb250YWluaW5nIG1vZGVsaW5nIGVsZW1lbnRzLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBQYWxldHRlKGV2ZW50QnVzLCBjYW52YXMpIHtcblxuICB0aGlzLl9ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGV2ZW50QnVzLm9uKCd0b29sLW1hbmFnZXIudXBkYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgdG9vbCA9IGV2ZW50LnRvb2w7XG5cbiAgICBzZWxmLnVwZGF0ZVRvb2xIaWdobGlnaHQodG9vbCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdpMThuLmNoYW5nZWQnLCBmdW5jdGlvbigpIHtcbiAgICBzZWxmLl91cGRhdGUoKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2RpYWdyYW0uaW5pdCcsIGZ1bmN0aW9uKCkge1xuXG4gICAgc2VsZi5fZGlhZ3JhbUluaXRpYWxpemVkID0gdHJ1ZTtcblxuICAgIHNlbGYuX3JlYnVpbGQoKTtcbiAgfSk7XG59XG5cblBhbGV0dGUuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2NhbnZhcycgXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVyIGEgcHJvdmlkZXIgd2l0aCB0aGUgcGFsZXR0ZVxuICpcbiAqIEBwYXJhbSAge251bWJlcn0gW3ByaW9yaXR5PTEwMDBdXG4gKiBAcGFyYW0gIHtQYWxldHRlUHJvdmlkZXJ9IHByb3ZpZGVyXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBhbGV0dGVQcm92aWRlciA9IHtcbiAqICAgZ2V0UGFsZXR0ZUVudHJpZXM6IGZ1bmN0aW9uKCkge1xuICogICAgIHJldHVybiBmdW5jdGlvbihlbnRyaWVzKSB7XG4gKiAgICAgICByZXR1cm4ge1xuICogICAgICAgICAuLi5lbnRyaWVzLFxuICogICAgICAgICAnZW50cnktMSc6IHtcbiAqICAgICAgICAgICBsYWJlbDogJ015IEVudHJ5JyxcbiAqICAgICAgICAgICBhY3Rpb246IGZ1bmN0aW9uKCkgeyBhbGVydChcIkkgaGF2ZSBiZWVuIGNsaWNrZWQhXCIpOyB9XG4gKiAgICAgICAgIH1cbiAqICAgICAgIH07XG4gKiAgICAgfVxuICogICB9XG4gKiB9O1xuICpcbiAqIHBhbGV0dGUucmVnaXN0ZXJQcm92aWRlcig4MDAsIHBhbGV0dGVQcm92aWRlcik7XG4gKi9cblBhbGV0dGUucHJvdG90eXBlLnJlZ2lzdGVyUHJvdmlkZXIgPSBmdW5jdGlvbihwcmlvcml0eSwgcHJvdmlkZXIpIHtcbiAgaWYgKCFwcm92aWRlcikge1xuICAgIHByb3ZpZGVyID0gcHJpb3JpdHk7XG4gICAgcHJpb3JpdHkgPSBERUZBVUxUX1BSSU9SSVRZO1xuICB9XG5cbiAgdGhpcy5fZXZlbnRCdXMub24oJ3BhbGV0dGUuZ2V0UHJvdmlkZXJzJywgcHJpb3JpdHksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZXZlbnQucHJvdmlkZXJzLnB1c2gocHJvdmlkZXIpO1xuICB9KTtcblxuICB0aGlzLl9yZWJ1aWxkKCk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgcGFsZXR0ZSBlbnRyaWVzXG4gKlxuICogQHJldHVybiB7T2JqZWN0PHN0cmluZywgUGFsZXR0ZUVudHJ5RGVzY3JpcHRvcj59IG1hcCBvZiBlbnRyaWVzXG4gKi9cblBhbGV0dGUucHJvdG90eXBlLmdldEVudHJpZXMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHByb3ZpZGVycyA9IHRoaXMuX2dldFByb3ZpZGVycygpO1xuXG4gIHJldHVybiBwcm92aWRlcnMucmVkdWNlKGFkZFBhbGV0dGVFbnRyaWVzLCB7fSk7XG59O1xuXG5QYWxldHRlLnByb3RvdHlwZS5fcmVidWlsZCA9IGZ1bmN0aW9uKCkge1xuXG4gIGlmICghdGhpcy5fZGlhZ3JhbUluaXRpYWxpemVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHByb3ZpZGVycyA9IHRoaXMuX2dldFByb3ZpZGVycygpO1xuXG4gIGlmICghcHJvdmlkZXJzLmxlbmd0aCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghdGhpcy5fY29udGFpbmVyKSB7XG4gICAgdGhpcy5faW5pdCgpO1xuICB9XG5cbiAgdGhpcy5fdXBkYXRlKCk7XG59O1xuXG4vKipcbiAqIEluaXRpYWxpemVcbiAqL1xuUGFsZXR0ZS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbigpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgdmFyIHBhcmVudENvbnRhaW5lciA9IHRoaXMuX2dldFBhcmVudENvbnRhaW5lcigpO1xuXG4gIHZhciBjb250YWluZXIgPSB0aGlzLl9jb250YWluZXIgPSBkb21pZnkoUGFsZXR0ZS5IVE1MX01BUktVUCk7XG5cbiAgcGFyZW50Q29udGFpbmVyLmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgZG9tRGVsZWdhdGUuYmluZChjb250YWluZXIsIEVMRU1FTlRfU0VMRUNUT1IsICdjbGljaycsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgdGFyZ2V0ID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQ7XG5cbiAgICBpZiAoZG9tTWF0Y2hlcyh0YXJnZXQsIFRPR0dMRV9TRUxFQ1RPUikpIHtcbiAgICAgIHJldHVybiBzZWxmLnRvZ2dsZSgpO1xuICAgIH1cblxuICAgIHNlbGYudHJpZ2dlcignY2xpY2snLCBldmVudCk7XG4gIH0pO1xuXG4gIC8vIHByZXZlbnQgZHJhZyBwcm9wYWdhdGlvblxuICBkb21FdmVudC5iaW5kKGNvbnRhaW5lciwgJ21vdXNlZG93bicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH0pO1xuXG4gIC8vIHByZXZlbnQgZHJhZyBwcm9wYWdhdGlvblxuICBkb21EZWxlZ2F0ZS5iaW5kKGNvbnRhaW5lciwgRU5UUllfU0VMRUNUT1IsICdkcmFnc3RhcnQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHNlbGYudHJpZ2dlcignZHJhZ3N0YXJ0JywgZXZlbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY2FudmFzLnJlc2l6ZWQnLCB0aGlzLl9sYXlvdXRDaGFuZ2VkLCB0aGlzKTtcblxuICBldmVudEJ1cy5maXJlKCdwYWxldHRlLmNyZWF0ZScsIHtcbiAgICBjb250YWluZXI6IGNvbnRhaW5lclxuICB9KTtcbn07XG5cblBhbGV0dGUucHJvdG90eXBlLl9nZXRQcm92aWRlcnMgPSBmdW5jdGlvbihpZCkge1xuXG4gIHZhciBldmVudCA9IHRoaXMuX2V2ZW50QnVzLmNyZWF0ZUV2ZW50KHtcbiAgICB0eXBlOiAncGFsZXR0ZS5nZXRQcm92aWRlcnMnLFxuICAgIHByb3ZpZGVyczogW11cbiAgfSk7XG5cbiAgdGhpcy5fZXZlbnRCdXMuZmlyZShldmVudCk7XG5cbiAgcmV0dXJuIGV2ZW50LnByb3ZpZGVycztcbn07XG5cbi8qKlxuICogVXBkYXRlIHBhbGV0dGUgc3RhdGUuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBbc3RhdGVdIHsgb3BlbiwgdHdvQ29sdW1uIH1cbiAqL1xuUGFsZXR0ZS5wcm90b3R5cGUuX3RvZ2dsZVN0YXRlID0gZnVuY3Rpb24oc3RhdGUpIHtcblxuICBzdGF0ZSA9IHN0YXRlIHx8IHt9O1xuXG4gIHZhciBwYXJlbnQgPSB0aGlzLl9nZXRQYXJlbnRDb250YWluZXIoKSxcbiAgICAgIGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lcjtcblxuICB2YXIgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICB2YXIgdHdvQ29sdW1uO1xuXG4gIHZhciBjbHMgPSBkb21DbGFzc2VzKGNvbnRhaW5lcik7XG5cbiAgaWYgKCd0d29Db2x1bW4nIGluIHN0YXRlKSB7XG4gICAgdHdvQ29sdW1uID0gc3RhdGUudHdvQ29sdW1uO1xuICB9IGVsc2Uge1xuICAgIHR3b0NvbHVtbiA9IHRoaXMuX25lZWRzQ29sbGFwc2UocGFyZW50LmNsaWVudEhlaWdodCwgdGhpcy5fZW50cmllcyB8fCB7fSk7XG4gIH1cblxuICAvLyBhbHdheXMgdXBkYXRlIHR3byBjb2x1bW5cbiAgY2xzLnRvZ2dsZShQQUxFVFRFX1RXT19DT0xVTU5fQ0xTLCB0d29Db2x1bW4pO1xuXG4gIGlmICgnb3BlbicgaW4gc3RhdGUpIHtcbiAgICBjbHMudG9nZ2xlKFBBTEVUVEVfT1BFTl9DTFMsIHN0YXRlLm9wZW4pO1xuICB9XG5cbiAgZXZlbnRCdXMuZmlyZSgncGFsZXR0ZS5jaGFuZ2VkJywge1xuICAgIHR3b0NvbHVtbjogdHdvQ29sdW1uLFxuICAgIG9wZW46IHRoaXMuaXNPcGVuKClcbiAgfSk7XG59O1xuXG5QYWxldHRlLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIGVudHJpZXNDb250YWluZXIgPSBkb21RdWVyeSgnLmRqcy1wYWxldHRlLWVudHJpZXMnLCB0aGlzLl9jb250YWluZXIpLFxuICAgICAgZW50cmllcyA9IHRoaXMuX2VudHJpZXMgPSB0aGlzLmdldEVudHJpZXMoKTtcblxuICBkb21DbGVhcihlbnRyaWVzQ29udGFpbmVyKTtcblxuICBmb3JFYWNoKGVudHJpZXMsIGZ1bmN0aW9uKGVudHJ5LCBpZCkge1xuXG4gICAgdmFyIGdyb3VwaW5nID0gZW50cnkuZ3JvdXAgfHwgJ2RlZmF1bHQnO1xuXG4gICAgdmFyIGNvbnRhaW5lciA9IGRvbVF1ZXJ5KCdbZGF0YS1ncm91cD0nICsgZ3JvdXBpbmcgKyAnXScsIGVudHJpZXNDb250YWluZXIpO1xuICAgIGlmICghY29udGFpbmVyKSB7XG4gICAgICBjb250YWluZXIgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJncm91cFwiIGRhdGEtZ3JvdXA9XCInICsgZ3JvdXBpbmcgKyAnXCI+PC9kaXY+Jyk7XG4gICAgICBlbnRyaWVzQ29udGFpbmVyLmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG4gICAgfVxuXG4gICAgdmFyIGh0bWwgPSBlbnRyeS5odG1sIHx8IChcbiAgICAgIGVudHJ5LnNlcGFyYXRvciA/XG4gICAgICAgICc8aHIgY2xhc3M9XCJzZXBhcmF0b3JcIiAvPicgOlxuICAgICAgICAnPGRpdiBjbGFzcz1cImVudHJ5XCIgZHJhZ2dhYmxlPVwidHJ1ZVwiPjwvZGl2PicpO1xuXG5cbiAgICB2YXIgY29udHJvbCA9IGRvbWlmeShodG1sKTtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY29udHJvbCk7XG5cbiAgICBpZiAoIWVudHJ5LnNlcGFyYXRvcikge1xuICAgICAgZG9tQXR0cihjb250cm9sLCAnZGF0YS1hY3Rpb24nLCBpZCk7XG5cbiAgICAgIGlmIChlbnRyeS50aXRsZSkge1xuICAgICAgICBkb21BdHRyKGNvbnRyb2wsICd0aXRsZScsIGVudHJ5LnRpdGxlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVudHJ5LmNsYXNzTmFtZSkge1xuICAgICAgICBhZGRDbGFzc2VzKGNvbnRyb2wsIGVudHJ5LmNsYXNzTmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbnRyeS5pbWFnZVVybCkge1xuICAgICAgICBjb250cm9sLmFwcGVuZENoaWxkKGRvbWlmeSgnPGltZyBzcmM9XCInICsgZW50cnkuaW1hZ2VVcmwgKyAnXCI+JykpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgLy8gb3BlbiBhZnRlciB1cGRhdGVcbiAgdGhpcy5vcGVuKCk7XG59O1xuXG5cbi8qKlxuICogVHJpZ2dlciBhbiBhY3Rpb24gYXZhaWxhYmxlIG9uIHRoZSBwYWxldHRlXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBhY3Rpb25cbiAqIEBwYXJhbSAge0V2ZW50fSBldmVudFxuICovXG5QYWxldHRlLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oYWN0aW9uLCBldmVudCwgYXV0b0FjdGl2YXRlKSB7XG4gIHZhciBlbnRyaWVzID0gdGhpcy5fZW50cmllcyxcbiAgICAgIGVudHJ5LFxuICAgICAgaGFuZGxlcixcbiAgICAgIG9yaWdpbmFsRXZlbnQsXG4gICAgICBidXR0b24gPSBldmVudC5kZWxlZ2F0ZVRhcmdldCB8fCBldmVudC50YXJnZXQ7XG5cbiAgaWYgKCFidXR0b24pIHtcbiAgICByZXR1cm4gZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIGVudHJ5ID0gZW50cmllc1tkb21BdHRyKGJ1dHRvbiwgJ2RhdGEtYWN0aW9uJyldO1xuXG4gIC8vIHdoZW4gdXNlciBjbGlja3Mgb24gdGhlIHBhbGV0dGUgYW5kIG5vdCBvbiBhbiBhY3Rpb25cbiAgaWYgKCFlbnRyeSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGhhbmRsZXIgPSBlbnRyeS5hY3Rpb247XG5cbiAgb3JpZ2luYWxFdmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQ7XG5cbiAgLy8gc2ltcGxlIGFjdGlvbiAodmlhIGNhbGxiYWNrIGZ1bmN0aW9uKVxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIGlmIChhY3Rpb24gPT09ICdjbGljaycpIHtcbiAgICAgIGhhbmRsZXIob3JpZ2luYWxFdmVudCwgYXV0b0FjdGl2YXRlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGhhbmRsZXJbYWN0aW9uXSkge1xuICAgICAgaGFuZGxlclthY3Rpb25dKG9yaWdpbmFsRXZlbnQsIGF1dG9BY3RpdmF0ZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gc2lsZW5jZSBvdGhlciBhY3Rpb25zXG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG59O1xuXG5QYWxldHRlLnByb3RvdHlwZS5fbGF5b3V0Q2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl90b2dnbGVTdGF0ZSh7fSk7XG59O1xuXG4vKipcbiAqIERvIHdlIG5lZWQgdG8gY29sbGFwc2UgdG8gdHdvIGNvbHVtbnM/XG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGF2YWlsYWJsZUhlaWdodFxuICogQHBhcmFtIHtPYmplY3R9IGVudHJpZXNcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5QYWxldHRlLnByb3RvdHlwZS5fbmVlZHNDb2xsYXBzZSA9IGZ1bmN0aW9uKGF2YWlsYWJsZUhlaWdodCwgZW50cmllcykge1xuXG4gIC8vIHRvcCBtYXJnaW4gKyBib3R0b20gdG9nZ2xlICsgYm90dG9tIG1hcmdpblxuICAvLyBpbXBsZW1lbnRvcnMgbXVzdCBvdmVycmlkZSB0aGlzIG1ldGhvZCBpZiB0aGV5XG4gIC8vIGNoYW5nZSB0aGUgcGFsZXR0ZSBzdHlsZXNcbiAgdmFyIG1hcmdpbiA9IDIwICsgMTAgKyAyMDtcblxuICB2YXIgZW50cmllc0hlaWdodCA9IE9iamVjdC5rZXlzKGVudHJpZXMpLmxlbmd0aCAqIDQ2O1xuXG4gIHJldHVybiBhdmFpbGFibGVIZWlnaHQgPCBlbnRyaWVzSGVpZ2h0ICsgbWFyZ2luO1xufTtcblxuLyoqXG4gKiBDbG9zZSB0aGUgcGFsZXR0ZVxuICovXG5QYWxldHRlLnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuXG4gIHRoaXMuX3RvZ2dsZVN0YXRlKHtcbiAgICBvcGVuOiBmYWxzZSxcbiAgICB0d29Db2x1bW46IGZhbHNlXG4gIH0pO1xufTtcblxuXG4vKipcbiAqIE9wZW4gdGhlIHBhbGV0dGVcbiAqL1xuUGFsZXR0ZS5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl90b2dnbGVTdGF0ZSh7IG9wZW46IHRydWUgfSk7XG59O1xuXG5cblBhbGV0dGUucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uKG9wZW4pIHtcbiAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICB0aGlzLmNsb3NlKCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5vcGVuKCk7XG4gIH1cbn07XG5cblBhbGV0dGUucHJvdG90eXBlLmlzQWN0aXZlVG9vbCA9IGZ1bmN0aW9uKHRvb2wpIHtcbiAgcmV0dXJuIHRvb2wgJiYgdGhpcy5fYWN0aXZlVG9vbCA9PT0gdG9vbDtcbn07XG5cblBhbGV0dGUucHJvdG90eXBlLnVwZGF0ZVRvb2xIaWdobGlnaHQgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHZhciBlbnRyaWVzQ29udGFpbmVyLFxuICAgICAgdG9vbHNDb250YWluZXI7XG5cbiAgaWYgKCF0aGlzLl90b29sc0NvbnRhaW5lcikge1xuICAgIGVudHJpZXNDb250YWluZXIgPSBkb21RdWVyeSgnLmRqcy1wYWxldHRlLWVudHJpZXMnLCB0aGlzLl9jb250YWluZXIpO1xuXG4gICAgdGhpcy5fdG9vbHNDb250YWluZXIgPSBkb21RdWVyeSgnW2RhdGEtZ3JvdXA9dG9vbHNdJywgZW50cmllc0NvbnRhaW5lcik7XG4gIH1cblxuICB0b29sc0NvbnRhaW5lciA9IHRoaXMuX3Rvb2xzQ29udGFpbmVyO1xuXG4gIGZvckVhY2godG9vbHNDb250YWluZXIuY2hpbGRyZW4sIGZ1bmN0aW9uKHRvb2wpIHtcbiAgICB2YXIgYWN0aW9uTmFtZSA9IHRvb2wuZ2V0QXR0cmlidXRlKCdkYXRhLWFjdGlvbicpO1xuXG4gICAgaWYgKCFhY3Rpb25OYW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRvb2xDbGFzc2VzID0gZG9tQ2xhc3Nlcyh0b29sKTtcblxuICAgIGFjdGlvbk5hbWUgPSBhY3Rpb25OYW1lLnJlcGxhY2UoJy10b29sJywgJycpO1xuXG4gICAgaWYgKHRvb2xDbGFzc2VzLmNvbnRhaW5zKCdlbnRyeScpICYmIGFjdGlvbk5hbWUgPT09IG5hbWUpIHtcbiAgICAgIHRvb2xDbGFzc2VzLmFkZCgnaGlnaGxpZ2h0ZWQtZW50cnknKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdG9vbENsYXNzZXMucmVtb3ZlKCdoaWdobGlnaHRlZC1lbnRyeScpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJuIHRydWUgaWYgdGhlIHBhbGV0dGUgaXMgb3BlbmVkLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogcGFsZXR0ZS5vcGVuKCk7XG4gKlxuICogaWYgKHBhbGV0dGUuaXNPcGVuKCkpIHtcbiAqICAgLy8geWVzLCB3ZSBhcmUgb3BlblxuICogfVxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgcGFsZXR0ZSBpcyBvcGVuZWRcbiAqL1xuUGFsZXR0ZS5wcm90b3R5cGUuaXNPcGVuID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBkb21DbGFzc2VzKHRoaXMuX2NvbnRhaW5lcikuaGFzKFBBTEVUVEVfT1BFTl9DTFMpO1xufTtcblxuLyoqXG4gKiBHZXQgY29udGFpbmVyIHRoZSBwYWxldHRlIGxpdmVzIGluLlxuICpcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cblBhbGV0dGUucHJvdG90eXBlLl9nZXRQYXJlbnRDb250YWluZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX2NhbnZhcy5nZXRDb250YWluZXIoKTtcbn07XG5cblxuLyogbWFya3VwIGRlZmluaXRpb24gKi9cblxuUGFsZXR0ZS5IVE1MX01BUktVUCA9XG4gICc8ZGl2IGNsYXNzPVwiZGpzLXBhbGV0dGVcIj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImRqcy1wYWxldHRlLWVudHJpZXNcIj48L2Rpdj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImRqcy1wYWxldHRlLXRvZ2dsZVwiPjwvZGl2PicgK1xuICAnPC9kaXY+JztcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gYWRkQ2xhc3NlcyhlbGVtZW50LCBjbGFzc05hbWVzKSB7XG5cbiAgdmFyIGNsYXNzZXMgPSBkb21DbGFzc2VzKGVsZW1lbnQpO1xuXG4gIHZhciBhY3R1YWxDbGFzc05hbWVzID0gaXNBcnJheShjbGFzc05hbWVzKSA/IGNsYXNzTmFtZXMgOiBjbGFzc05hbWVzLnNwbGl0KC9cXHMrL2cpO1xuICBhY3R1YWxDbGFzc05hbWVzLmZvckVhY2goZnVuY3Rpb24oY2xzKSB7XG4gICAgY2xhc3Nlcy5hZGQoY2xzKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZFBhbGV0dGVFbnRyaWVzKGVudHJpZXMsIHByb3ZpZGVyKSB7XG5cbiAgdmFyIGVudHJpZXNPclVwZGF0ZXIgPSBwcm92aWRlci5nZXRQYWxldHRlRW50cmllcygpO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGVudHJpZXNPclVwZGF0ZXIpKSB7XG4gICAgcmV0dXJuIGVudHJpZXNPclVwZGF0ZXIoZW50cmllcyk7XG4gIH1cblxuICBmb3JFYWNoKGVudHJpZXNPclVwZGF0ZXIsIGZ1bmN0aW9uKGVudHJ5LCBpZCkge1xuICAgIGVudHJpZXNbaWRdID0gZW50cnk7XG4gIH0pO1xuXG4gIHJldHVybiBlbnRyaWVzO1xufSIsImltcG9ydCBQYWxldHRlIGZyb20gJy4vUGFsZXR0ZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ3BhbGV0dGUnIF0sXG4gIHBhbGV0dGU6IFsgJ3R5cGUnLCBQYWxldHRlIF1cbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIGlzRnVuY3Rpb24sXG4gIGlzRGVmaW5lZCxcbiAgb21pdCxcbiAgc2l6ZVxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBkb21pZnkgYXMgZG9taWZ5LFxuICBjbGFzc2VzIGFzIGRvbUNsYXNzZXMsXG4gIGF0dHIgYXMgZG9tQXR0cixcbiAgcmVtb3ZlIGFzIGRvbVJlbW92ZVxufSBmcm9tICdtaW4tZG9tJztcblxudmFyIERBVEFfUkVGID0gJ2RhdGEtaWQnO1xuXG52YXIgQ0xPU0VfRVZFTlRTID0gW1xuICAnY29udGV4dFBhZC5jbG9zZScsXG4gICdjYW52YXMudmlld2JveC5jaGFuZ2luZycsXG4gICdjb21tYW5kU3RhY2suY2hhbmdlZCdcbl07XG5cbnZhciBERUZBVUxUX1BSSU9SSVRZID0gMTAwMDtcblxuXG4vKipcbiAqIEEgcG9wdXAgbWVudSB0aGF0IGNhbiBiZSB1c2VkIHRvIGRpc3BsYXkgYSBsaXN0IG9mIGFjdGlvbnMgYW55d2hlcmUgaW4gdGhlIGNhbnZhcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge2Jvb2xlYW58T2JqZWN0fSBbY29uZmlnLnNjYWxlPXsgbWluOiAxLjAsIG1heDogMS41IH1dXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmZpZy5zY2FsZS5taW5dXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmZpZy5zY2FsZS5tYXhdXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFBvcHVwTWVudShjb25maWcsIGV2ZW50QnVzLCBjYW52YXMpIHtcblxuICB2YXIgc2NhbGUgPSBpc0RlZmluZWQoY29uZmlnICYmIGNvbmZpZy5zY2FsZSkgPyBjb25maWcuc2NhbGUgOiB7XG4gICAgbWluOiAxLFxuICAgIG1heDogMS41XG4gIH07XG5cbiAgdGhpcy5fY29uZmlnID0ge1xuICAgIHNjYWxlOiBzY2FsZVxuICB9O1xuXG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fcHJvdmlkZXJzID0ge307XG4gIHRoaXMuX2N1cnJlbnQgPSB7fTtcbn1cblxuUG9wdXBNZW51LiRpbmplY3QgPSBbXG4gICdjb25maWcucG9wdXBNZW51JyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcydcbl07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgcG9wdXAgbWVudSBwcm92aWRlclxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gaWRcbiAqIEBwYXJhbSB7bnVtYmVyfSBbcHJpb3JpdHk9MTAwMF1cbiAqIEBwYXJhbSAge09iamVjdH0gcHJvdmlkZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcG9wdXBNZW51UHJvdmlkZXIgPSB7XG4gKiAgIGdldFBvcHVwTWVudUVudHJpZXM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAqICAgICByZXR1cm4ge1xuICogICAgICAgJ2VudHJ5LTEnOiB7XG4gKiAgICAgICAgIGxhYmVsOiAnTXkgRW50cnknLFxuICogICAgICAgICBhY3Rpb246IGZ1bmN0aW9uKCkgeyBhbGVydChcIkkgaGF2ZSBiZWVuIGNsaWNrZWQhXCIpOyB9XG4gKiAgICAgICB9XG4gKiAgICAgfVxuICogICB9XG4gKiB9O1xuICpcbiAqIHBvcHVwTWVudS5yZWdpc3RlclByb3ZpZGVyKCdteU1lbnVJRCcsIHBvcHVwTWVudVByb3ZpZGVyKTtcbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5yZWdpc3RlclByb3ZpZGVyID0gZnVuY3Rpb24oaWQsIHByaW9yaXR5LCBwcm92aWRlcikge1xuICBpZiAoIXByb3ZpZGVyKSB7XG4gICAgcHJvdmlkZXIgPSBwcmlvcml0eTtcbiAgICBwcmlvcml0eSA9IERFRkFVTFRfUFJJT1JJVFk7XG4gIH1cblxuICB0aGlzLl9ldmVudEJ1cy5vbigncG9wdXBNZW51LmdldFByb3ZpZGVycy4nICsgaWQsIHByaW9yaXR5LCBmdW5jdGlvbihldmVudCkge1xuICAgIGV2ZW50LnByb3ZpZGVycy5wdXNoKHByb3ZpZGVyKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIERldGVybWluZSBpZiB0aGUgcG9wdXAgbWVudSBoYXMgZW50cmllcy5cbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIGVtcHR5XG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHByb3ZpZGVySWQpIHtcbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbGVtZW50IHBhcmFtZXRlciBpcyBtaXNzaW5nJyk7XG4gIH1cblxuICBpZiAoIXByb3ZpZGVySWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb3ZpZGVySWQgcGFyYW1ldGVyIGlzIG1pc3NpbmcnKTtcbiAgfVxuXG4gIHZhciBwcm92aWRlcnMgPSB0aGlzLl9nZXRQcm92aWRlcnMocHJvdmlkZXJJZCk7XG5cbiAgaWYgKCFwcm92aWRlcnMpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHZhciBlbnRyaWVzID0gdGhpcy5fZ2V0RW50cmllcyhlbGVtZW50LCBwcm92aWRlcnMpLFxuICAgICAgaGVhZGVyRW50cmllcyA9IHRoaXMuX2dldEhlYWRlckVudHJpZXMoZWxlbWVudCwgcHJvdmlkZXJzKTtcblxuICB2YXIgaGFzRW50cmllcyA9IHNpemUoZW50cmllcykgPiAwLFxuICAgICAgaGFzSGVhZGVyRW50cmllcyA9IGhlYWRlckVudHJpZXMgJiYgc2l6ZShoZWFkZXJFbnRyaWVzKSA+IDA7XG5cbiAgcmV0dXJuICFoYXNFbnRyaWVzICYmICFoYXNIZWFkZXJFbnRyaWVzO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZSBlbnRyaWVzIGFuZCBvcGVuIHBvcHVwIG1lbnUgYXQgZ2l2ZW4gcG9zaXRpb25cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGVsZW1lbnRcbiAqIEBwYXJhbSAge3N0cmluZ30gaWQgcHJvdmlkZXIgaWRcbiAqIEBwYXJhbSAge09iamVjdH0gcG9zaXRpb25cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHBvcHVwIG1lbnUgaW5zdGFuY2VcbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24oZWxlbWVudCwgaWQsIHBvc2l0aW9uKSB7XG5cbiAgdmFyIHByb3ZpZGVycyA9IHRoaXMuX2dldFByb3ZpZGVycyhpZCk7XG5cbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFbGVtZW50IGlzIG1pc3NpbmcnKTtcbiAgfVxuXG4gIGlmICghcHJvdmlkZXJzIHx8ICFwcm92aWRlcnMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyByZWdpc3RlcmVkIHByb3ZpZGVycyBmb3I6ICcgKyBpZCk7XG4gIH1cblxuICBpZiAoIXBvc2l0aW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgcG9zaXRpb24gYXJndW1lbnQgaXMgbWlzc2luZycpO1xuICB9XG5cbiAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICB0aGlzLmNsb3NlKCk7XG4gIH1cblxuICB0aGlzLl9lbWl0KCdvcGVuJyk7XG5cbiAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50ID0ge1xuICAgIGNsYXNzTmFtZTogaWQsXG4gICAgZWxlbWVudDogZWxlbWVudCxcbiAgICBwb3NpdGlvbjogcG9zaXRpb25cbiAgfTtcblxuICB2YXIgZW50cmllcyA9IHRoaXMuX2dldEVudHJpZXMoZWxlbWVudCwgcHJvdmlkZXJzKSxcbiAgICAgIGhlYWRlckVudHJpZXMgPSB0aGlzLl9nZXRIZWFkZXJFbnRyaWVzKGVsZW1lbnQsIHByb3ZpZGVycyk7XG5cbiAgY3VycmVudC5lbnRyaWVzID0gYXNzaWduKHt9LCBlbnRyaWVzLCBoZWFkZXJFbnRyaWVzKTtcblxuICBjdXJyZW50LmNvbnRhaW5lciA9IHRoaXMuX2NyZWF0ZUNvbnRhaW5lcigpO1xuXG4gIGlmIChzaXplKGhlYWRlckVudHJpZXMpKSB7XG4gICAgY3VycmVudC5jb250YWluZXIuYXBwZW5kQ2hpbGQoXG4gICAgICB0aGlzLl9jcmVhdGVFbnRyaWVzKGhlYWRlckVudHJpZXMsICdkanMtcG9wdXAtaGVhZGVyJylcbiAgICApO1xuICB9XG5cbiAgaWYgKHNpemUoZW50cmllcykpIHtcbiAgICBjdXJyZW50LmNvbnRhaW5lci5hcHBlbmRDaGlsZChcbiAgICAgIHRoaXMuX2NyZWF0ZUVudHJpZXMoZW50cmllcywgJ2Rqcy1wb3B1cC1ib2R5JylcbiAgICApO1xuICB9XG5cbiAgdmFyIGNhbnZhcyA9IHRoaXMuX2NhbnZhcyxcbiAgICAgIHBhcmVudCA9IGNhbnZhcy5nZXRDb250YWluZXIoKTtcblxuICB0aGlzLl9hdHRhY2hDb250YWluZXIoY3VycmVudC5jb250YWluZXIsIHBhcmVudCwgcG9zaXRpb24uY3Vyc29yKTtcbiAgdGhpcy5fYmluZEF1dG9DbG9zZSgpO1xufTtcblxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIHBvcHVwIG1lbnUgYW5kIHVuYmluZHMgdGhlIGV2ZW50IGhhbmRsZXJzLlxuICovXG5Qb3B1cE1lbnUucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG5cbiAgaWYgKCF0aGlzLmlzT3BlbigpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fZW1pdCgnY2xvc2UnKTtcblxuICB0aGlzLl91bmJpbmRBdXRvQ2xvc2UoKTtcbiAgZG9tUmVtb3ZlKHRoaXMuX2N1cnJlbnQuY29udGFpbmVyKTtcbiAgdGhpcy5fY3VycmVudC5jb250YWluZXIgPSBudWxsO1xufTtcblxuXG4vKipcbiAqIERldGVybWluZSBpZiBhbiBvcGVuIHBvcHVwIG1lbnUgZXhpc3QuXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gdHJ1ZSBpZiBvcGVuXG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuaXNPcGVuID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAhIXRoaXMuX2N1cnJlbnQuY29udGFpbmVyO1xufTtcblxuXG4vKipcbiAqIFRyaWdnZXIgYW4gYWN0aW9uIGFzc29jaWF0ZWQgd2l0aCBhbiBlbnRyeS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAqXG4gKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGFjdGlvbiBjYWxsYmFjaywgaWYgYW55XG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUudHJpZ2dlciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgLy8gc2lsZW5jZSBvdGhlciBhY3Rpb25zXG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgdmFyIGVsZW1lbnQgPSBldmVudC5kZWxlZ2F0ZVRhcmdldCB8fCBldmVudC50YXJnZXQsXG4gICAgICBlbnRyeUlkID0gZG9tQXR0cihlbGVtZW50LCBEQVRBX1JFRik7XG5cbiAgdmFyIGVudHJ5ID0gdGhpcy5fZ2V0RW50cnkoZW50cnlJZCk7XG5cbiAgaWYgKGVudHJ5LmFjdGlvbikge1xuICAgIHJldHVybiBlbnRyeS5hY3Rpb24uY2FsbChudWxsLCBldmVudCwgZW50cnkpO1xuICB9XG59O1xuXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9nZXRQcm92aWRlcnMgPSBmdW5jdGlvbihpZCkge1xuXG4gIHZhciBldmVudCA9IHRoaXMuX2V2ZW50QnVzLmNyZWF0ZUV2ZW50KHtcbiAgICB0eXBlOiAncG9wdXBNZW51LmdldFByb3ZpZGVycy4nICsgaWQsXG4gICAgcHJvdmlkZXJzOiBbXVxuICB9KTtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKGV2ZW50KTtcblxuICByZXR1cm4gZXZlbnQucHJvdmlkZXJzO1xufTtcblxuUG9wdXBNZW51LnByb3RvdHlwZS5fZ2V0RW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHByb3ZpZGVycykge1xuXG4gIHZhciBlbnRyaWVzID0ge307XG5cbiAgZm9yRWFjaChwcm92aWRlcnMsIGZ1bmN0aW9uKHByb3ZpZGVyKSB7XG5cbiAgICAvLyBoYW5kbGUgbGVnYWN5IG1ldGhvZFxuICAgIGlmICghcHJvdmlkZXIuZ2V0UG9wdXBNZW51RW50cmllcykge1xuICAgICAgZm9yRWFjaChwcm92aWRlci5nZXRFbnRyaWVzKGVsZW1lbnQpLCBmdW5jdGlvbihlbnRyeSkge1xuICAgICAgICB2YXIgaWQgPSBlbnRyeS5pZDtcblxuICAgICAgICBpZiAoIWlkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdldmVyeSBlbnRyeSBtdXN0IGhhdmUgdGhlIGlkIHByb3BlcnR5IHNldCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgZW50cmllc1tpZF0gPSBvbWl0KGVudHJ5LCBbICdpZCcgXSk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBlbnRyaWVzT3JVcGRhdGVyID0gcHJvdmlkZXIuZ2V0UG9wdXBNZW51RW50cmllcyhlbGVtZW50KTtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGVudHJpZXNPclVwZGF0ZXIpKSB7XG4gICAgICBlbnRyaWVzID0gZW50cmllc09yVXBkYXRlcihlbnRyaWVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yRWFjaChlbnRyaWVzT3JVcGRhdGVyLCBmdW5jdGlvbihlbnRyeSwgaWQpIHtcbiAgICAgICAgZW50cmllc1tpZF0gPSBlbnRyeTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGVudHJpZXM7XG59O1xuXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9nZXRIZWFkZXJFbnRyaWVzID0gZnVuY3Rpb24oZWxlbWVudCwgcHJvdmlkZXJzKSB7XG5cbiAgdmFyIGVudHJpZXMgPSB7fTtcblxuICBmb3JFYWNoKHByb3ZpZGVycywgZnVuY3Rpb24ocHJvdmlkZXIpIHtcblxuICAgIC8vIGhhbmRsZSBsZWdhY3kgbWV0aG9kXG4gICAgaWYgKCFwcm92aWRlci5nZXRQb3B1cE1lbnVIZWFkZXJFbnRyaWVzKSB7XG4gICAgICBpZiAoIXByb3ZpZGVyLmdldEhlYWRlckVudHJpZXMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBmb3JFYWNoKHByb3ZpZGVyLmdldEhlYWRlckVudHJpZXMoZWxlbWVudCksIGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgICAgIHZhciBpZCA9IGVudHJ5LmlkO1xuXG4gICAgICAgIGlmICghaWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V2ZXJ5IGVudHJ5IG11c3QgaGF2ZSB0aGUgaWQgcHJvcGVydHkgc2V0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBlbnRyaWVzW2lkXSA9IG9taXQoZW50cnksIFsgJ2lkJyBdKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGVudHJpZXNPclVwZGF0ZXIgPSBwcm92aWRlci5nZXRQb3B1cE1lbnVIZWFkZXJFbnRyaWVzKGVsZW1lbnQpO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24oZW50cmllc09yVXBkYXRlcikpIHtcbiAgICAgIGVudHJpZXMgPSBlbnRyaWVzT3JVcGRhdGVyKGVudHJpZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3JFYWNoKGVudHJpZXNPclVwZGF0ZXIsIGZ1bmN0aW9uKGVudHJ5LCBpZCkge1xuICAgICAgICBlbnRyaWVzW2lkXSA9IGVudHJ5O1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gZW50cmllcztcblxuXG59O1xuXG4vKipcbiAqIEdldHMgYW4gZW50cnkgaW5zdGFuY2UgKGVpdGhlciBlbnRyeSBvciBoZWFkZXJFbnRyeSkgYnkgaWQuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBlbnRyeUlkXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBlbnRyeSBpbnN0YW5jZVxuICovXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9nZXRFbnRyeSA9IGZ1bmN0aW9uKGVudHJ5SWQpIHtcblxuICB2YXIgZW50cnkgPSB0aGlzLl9jdXJyZW50LmVudHJpZXNbZW50cnlJZF07XG5cbiAgaWYgKCFlbnRyeSkge1xuICAgIHRocm93IG5ldyBFcnJvcignZW50cnkgbm90IGZvdW5kJyk7XG4gIH1cblxuICByZXR1cm4gZW50cnk7XG59O1xuXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9lbWl0ID0gZnVuY3Rpb24oZXZlbnROYW1lKSB7XG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3BvcHVwTWVudS4nICsgZXZlbnROYW1lKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgcG9wdXAgbWVudSBjb250YWluZXIuXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBhIERPTSBjb250YWluZXJcbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5fY3JlYXRlQ29udGFpbmVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjb250YWluZXIgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJkanMtcG9wdXBcIj4nKSxcbiAgICAgIHBvc2l0aW9uID0gdGhpcy5fY3VycmVudC5wb3NpdGlvbixcbiAgICAgIGNsYXNzTmFtZSA9IHRoaXMuX2N1cnJlbnQuY2xhc3NOYW1lO1xuXG4gIGFzc2lnbihjb250YWluZXIuc3R5bGUsIHtcbiAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICBsZWZ0OiBwb3NpdGlvbi54ICsgJ3B4JyxcbiAgICB0b3A6IHBvc2l0aW9uLnkgKyAncHgnLFxuICAgIHZpc2liaWxpdHk6ICdoaWRkZW4nXG4gIH0pO1xuXG4gIGRvbUNsYXNzZXMoY29udGFpbmVyKS5hZGQoY2xhc3NOYW1lKTtcblxuICByZXR1cm4gY29udGFpbmVyO1xufTtcblxuXG4vKipcbiAqIEF0dGFjaGVzIHRoZSBjb250YWluZXIgdG8gdGhlIERPTS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGFpbmVyXG4gKiBAcGFyYW0ge09iamVjdH0gcGFyZW50XG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuX2F0dGFjaENvbnRhaW5lciA9IGZ1bmN0aW9uKGNvbnRhaW5lciwgcGFyZW50LCBjdXJzb3IpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vIEV2ZW50IGhhbmRsZXJcbiAgZG9tRGVsZWdhdGUuYmluZChjb250YWluZXIsICcuZW50cnknICwnY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgIHNlbGYudHJpZ2dlcihldmVudCk7XG4gIH0pO1xuXG4gIHRoaXMuX3VwZGF0ZVNjYWxlKGNvbnRhaW5lcik7XG5cbiAgLy8gQXR0YWNoIHRvIERPTVxuICBwYXJlbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICBpZiAoY3Vyc29yKSB7XG4gICAgdGhpcy5fYXNzdXJlSXNJbmJvdW5kcyhjb250YWluZXIsIGN1cnNvcik7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBVcGRhdGVzIHBvcHVwIHN0eWxlLnRyYW5zZm9ybSB3aXRoIHJlc3BlY3QgdG8gdGhlIGNvbmZpZyBhbmQgem9vbSBsZXZlbC5cbiAqXG4gKiBAbWV0aG9kIF91cGRhdGVTY2FsZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250YWluZXJcbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5fdXBkYXRlU2NhbGUgPSBmdW5jdGlvbihjb250YWluZXIpIHtcbiAgdmFyIHpvb20gPSB0aGlzLl9jYW52YXMuem9vbSgpO1xuXG4gIHZhciBzY2FsZUNvbmZpZyA9IHRoaXMuX2NvbmZpZy5zY2FsZSxcbiAgICAgIG1pblNjYWxlLFxuICAgICAgbWF4U2NhbGUsXG4gICAgICBzY2FsZSA9IHpvb207XG5cbiAgaWYgKHNjYWxlQ29uZmlnICE9PSB0cnVlKSB7XG5cbiAgICBpZiAoc2NhbGVDb25maWcgPT09IGZhbHNlKSB7XG4gICAgICBtaW5TY2FsZSA9IDE7XG4gICAgICBtYXhTY2FsZSA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1pblNjYWxlID0gc2NhbGVDb25maWcubWluO1xuICAgICAgbWF4U2NhbGUgPSBzY2FsZUNvbmZpZy5tYXg7XG4gICAgfVxuXG4gICAgaWYgKGlzRGVmaW5lZChtaW5TY2FsZSkgJiYgem9vbSA8IG1pblNjYWxlKSB7XG4gICAgICBzY2FsZSA9IG1pblNjYWxlO1xuICAgIH1cblxuICAgIGlmIChpc0RlZmluZWQobWF4U2NhbGUpICYmIHpvb20gPiBtYXhTY2FsZSkge1xuICAgICAgc2NhbGUgPSBtYXhTY2FsZTtcbiAgICB9XG5cbiAgfVxuXG4gIHNldFRyYW5zZm9ybShjb250YWluZXIsICdzY2FsZSgnICsgc2NhbGUgKyAnKScpO1xufTtcblxuXG4vKipcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoZSBtZW51IGlzIGFsd2F5cyBmdWxseSBzaG93blxuICpcbiAqIEBtZXRob2QgZnVuY3Rpb25cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGNvbnRhaW5lclxuICogQHBhcmFtICB7UG9zaXRpb259IGN1cnNvciB7eCwgeX1cbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5fYXNzdXJlSXNJbmJvdW5kcyA9IGZ1bmN0aW9uKGNvbnRhaW5lciwgY3Vyc29yKSB7XG4gIHZhciBjYW52YXMgPSB0aGlzLl9jYW52YXMsXG4gICAgICBjbGllbnRSZWN0ID0gY2FudmFzLl9jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgdmFyIGNvbnRhaW5lclggPSBjb250YWluZXIub2Zmc2V0TGVmdCxcbiAgICAgIGNvbnRhaW5lclkgPSBjb250YWluZXIub2Zmc2V0VG9wLFxuICAgICAgY29udGFpbmVyV2lkdGggPSBjb250YWluZXIuc2Nyb2xsV2lkdGgsXG4gICAgICBjb250YWluZXJIZWlnaHQgPSBjb250YWluZXIuc2Nyb2xsSGVpZ2h0LFxuICAgICAgb3ZlckF4aXMgPSB7fSxcbiAgICAgIGxlZnQsIHRvcDtcblxuICB2YXIgY3Vyc29yUG9zaXRpb24gPSB7XG4gICAgeDogY3Vyc29yLnggLSBjbGllbnRSZWN0LmxlZnQsXG4gICAgeTogY3Vyc29yLnkgLSBjbGllbnRSZWN0LnRvcFxuICB9O1xuXG4gIGlmIChjb250YWluZXJYICsgY29udGFpbmVyV2lkdGggPiBjbGllbnRSZWN0LndpZHRoKSB7XG4gICAgb3ZlckF4aXMueCA9IHRydWU7XG4gIH1cblxuICBpZiAoY29udGFpbmVyWSArIGNvbnRhaW5lckhlaWdodCA+IGNsaWVudFJlY3QuaGVpZ2h0KSB7XG4gICAgb3ZlckF4aXMueSA9IHRydWU7XG4gIH1cblxuICBpZiAob3ZlckF4aXMueCAmJiBvdmVyQXhpcy55KSB7XG4gICAgbGVmdCA9IGN1cnNvclBvc2l0aW9uLnggLSBjb250YWluZXJXaWR0aCArICdweCc7XG4gICAgdG9wID0gY3Vyc29yUG9zaXRpb24ueSAtIGNvbnRhaW5lckhlaWdodCArICdweCc7XG4gIH0gZWxzZSBpZiAob3ZlckF4aXMueCkge1xuICAgIGxlZnQgPSBjdXJzb3JQb3NpdGlvbi54IC0gY29udGFpbmVyV2lkdGggKyAncHgnO1xuICAgIHRvcCA9IGN1cnNvclBvc2l0aW9uLnkgKyAncHgnO1xuICB9IGVsc2UgaWYgKG92ZXJBeGlzLnkgJiYgY3Vyc29yUG9zaXRpb24ueSA8IGNvbnRhaW5lckhlaWdodCkge1xuICAgIGxlZnQgPSBjdXJzb3JQb3NpdGlvbi54ICsgJ3B4JztcbiAgICB0b3AgPSAxMCArICdweCc7XG4gIH0gZWxzZSBpZiAob3ZlckF4aXMueSkge1xuICAgIGxlZnQgPSBjdXJzb3JQb3NpdGlvbi54ICsgJ3B4JztcbiAgICB0b3AgPSBjdXJzb3JQb3NpdGlvbi55IC0gY29udGFpbmVySGVpZ2h0ICsgJ3B4JztcbiAgfVxuXG4gIGFzc2lnbihjb250YWluZXIuc3R5bGUsIHsgbGVmdDogbGVmdCwgdG9wOiB0b3AgfSwgeyB2aXNpYmlsaXR5OiAndmlzaWJsZScsICd6LWluZGV4JzogMTAwMCB9KTtcbn07XG5cblxuLyoqXG4gKiBDcmVhdGVzIGEgbGlzdCBvZiBlbnRyaWVzIGFuZCByZXR1cm5zIHRoZW0gYXMgYSBET00gY29udGFpbmVyLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gZW50cmllcyBhbiBhcnJheSBvZiBlbnRyeSBvYmplY3RzXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lIHRoZSBjbGFzcyBuYW1lIG9mIHRoZSBlbnRyeSBjb250YWluZXJcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGEgRE9NIGNvbnRhaW5lclxuICovXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9jcmVhdGVFbnRyaWVzID0gZnVuY3Rpb24oZW50cmllcywgY2xhc3NOYW1lKSB7XG5cbiAgdmFyIGVudHJpZXNDb250YWluZXIgPSBkb21pZnkoJzxkaXY+JyksXG4gICAgICBzZWxmID0gdGhpcztcblxuICBkb21DbGFzc2VzKGVudHJpZXNDb250YWluZXIpLmFkZChjbGFzc05hbWUpO1xuXG4gIGZvckVhY2goZW50cmllcywgZnVuY3Rpb24oZW50cnksIGlkKSB7XG4gICAgdmFyIGVudHJ5Q29udGFpbmVyID0gc2VsZi5fY3JlYXRlRW50cnkoZW50cnksIGlkKTtcbiAgICBlbnRyaWVzQ29udGFpbmVyLmFwcGVuZENoaWxkKGVudHJ5Q29udGFpbmVyKTtcbiAgfSk7XG5cbiAgcmV0dXJuIGVudHJpZXNDb250YWluZXI7XG59O1xuXG5cbi8qKlxuICogQ3JlYXRlcyBhIHNpbmdsZSBlbnRyeSBhbmQgcmV0dXJucyBpdCBhcyBhIERPTSBjb250YWluZXIuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBlbnRyeVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gYSBET00gY29udGFpbmVyXG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuX2NyZWF0ZUVudHJ5ID0gZnVuY3Rpb24oZW50cnksIGlkKSB7XG5cbiAgdmFyIGVudHJ5Q29udGFpbmVyID0gZG9taWZ5KCc8ZGl2PicpLFxuICAgICAgZW50cnlDbGFzc2VzID0gZG9tQ2xhc3NlcyhlbnRyeUNvbnRhaW5lcik7XG5cbiAgZW50cnlDbGFzc2VzLmFkZCgnZW50cnknKTtcblxuICBpZiAoZW50cnkuY2xhc3NOYW1lKSB7XG4gICAgZW50cnkuY2xhc3NOYW1lLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcbiAgICAgIGVudHJ5Q2xhc3Nlcy5hZGQoY2xhc3NOYW1lKTtcbiAgICB9KTtcbiAgfVxuXG4gIGRvbUF0dHIoZW50cnlDb250YWluZXIsIERBVEFfUkVGLCBpZCk7XG5cbiAgaWYgKGVudHJ5LmxhYmVsKSB7XG4gICAgdmFyIGxhYmVsID0gZG9taWZ5KCc8c3Bhbj4nKTtcbiAgICBsYWJlbC50ZXh0Q29udGVudCA9IGVudHJ5LmxhYmVsO1xuICAgIGVudHJ5Q29udGFpbmVyLmFwcGVuZENoaWxkKGxhYmVsKTtcbiAgfVxuXG4gIGlmIChlbnRyeS5pbWFnZVVybCkge1xuICAgIGVudHJ5Q29udGFpbmVyLmFwcGVuZENoaWxkKGRvbWlmeSgnPGltZyBzcmM9XCInICsgZW50cnkuaW1hZ2VVcmwgKyAnXCIgLz4nKSk7XG4gIH1cblxuICBpZiAoZW50cnkuYWN0aXZlID09PSB0cnVlKSB7XG4gICAgZW50cnlDbGFzc2VzLmFkZCgnYWN0aXZlJyk7XG4gIH1cblxuICBpZiAoZW50cnkuZGlzYWJsZWQgPT09IHRydWUpIHtcbiAgICBlbnRyeUNsYXNzZXMuYWRkKCdkaXNhYmxlZCcpO1xuICB9XG5cbiAgaWYgKGVudHJ5LnRpdGxlKSB7XG4gICAgZW50cnlDb250YWluZXIudGl0bGUgPSBlbnRyeS50aXRsZTtcbiAgfVxuXG4gIHJldHVybiBlbnRyeUNvbnRhaW5lcjtcbn07XG5cblxuLyoqXG4gKiBTZXQgdXAgbGlzdGVuZXIgdG8gY2xvc2UgcG9wdXAgYXV0b21hdGljYWxseSBvbiBjZXJ0YWluIGV2ZW50cy5cbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5fYmluZEF1dG9DbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9ldmVudEJ1cy5vbmNlKENMT1NFX0VWRU5UUywgdGhpcy5jbG9zZSwgdGhpcyk7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlIHRoZSBhdXRvLWNsb3NpbmcgbGlzdGVuZXIuXG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuX3VuYmluZEF1dG9DbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9ldmVudEJ1cy5vZmYoQ0xPU0VfRVZFTlRTLCB0aGlzLmNsb3NlLCB0aGlzKTtcbn07XG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIHNldFRyYW5zZm9ybShlbGVtZW50LCB0cmFuc2Zvcm0pIHtcbiAgZWxlbWVudC5zdHlsZVsndHJhbnNmb3JtLW9yaWdpbiddID0gJ3RvcCBsZWZ0JztcblxuICBbICcnLCAnLW1zLScsICctd2Via2l0LScgXS5mb3JFYWNoKGZ1bmN0aW9uKHByZWZpeCkge1xuICAgIGVsZW1lbnQuc3R5bGVbcHJlZml4ICsgJ3RyYW5zZm9ybSddID0gdHJhbnNmb3JtO1xuICB9KTtcbn0iLCJpbXBvcnQgUG9wdXBNZW51IGZyb20gJy4vUG9wdXBNZW51JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAncG9wdXBNZW51JyBdLFxuICBwb3B1cE1lbnU6IFsgJ3R5cGUnLCBQb3B1cE1lbnUgXVxufTtcbiIsImltcG9ydCB7XHJcbiAgZm9yRWFjaFxyXG59IGZyb20gJ21pbi1kYXNoJztcclxuXHJcbmltcG9ydCB7XHJcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcclxuICBhdHRyIGFzIHN2Z0F0dHIsXHJcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzLFxyXG4gIGNsb25lIGFzIHN2Z0Nsb25lLFxyXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXHJcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxyXG59IGZyb20gJ3Rpbnktc3ZnJztcclxuXHJcbmltcG9ydCB7IHF1ZXJ5IGFzIGRvbVF1ZXJ5IH0gZnJvbSAnbWluLWRvbSc7XHJcblxyXG5pbXBvcnQgeyBnZXRWaXN1YWwgfSBmcm9tICcuLi8uLi91dGlsL0dyYXBoaWNzVXRpbCc7XHJcblxyXG52YXIgTUFSS0VSX1RZUEVTID0gW1xyXG4gICdtYXJrZXItc3RhcnQnLFxyXG4gICdtYXJrZXItbWlkJyxcclxuICAnbWFya2VyLWVuZCdcclxuXTtcclxuXHJcbnZhciBOT0RFU19DQU5fSEFWRV9NQVJLRVIgPSBbXHJcbiAgJ2NpcmNsZScsXHJcbiAgJ2VsbGlwc2UnLFxyXG4gICdsaW5lJyxcclxuICAncGF0aCcsXHJcbiAgJ3BvbHlnb24nLFxyXG4gICdwb2x5bGluZScsXHJcbiAgJ3JlY3QnXHJcbl07XHJcblxyXG5cclxuLyoqXHJcbiAqIEFkZHMgc3VwcG9ydCBmb3IgcHJldmlld3Mgb2YgbW92aW5nL3Jlc2l6aW5nIGVsZW1lbnRzLlxyXG4gKi9cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUHJldmlld1N1cHBvcnQoZWxlbWVudFJlZ2lzdHJ5LCBldmVudEJ1cywgY2FudmFzLCBzdHlsZXMpIHtcclxuICB0aGlzLl9lbGVtZW50UmVnaXN0cnkgPSBlbGVtZW50UmVnaXN0cnk7XHJcbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xyXG4gIHRoaXMuX3N0eWxlcyA9IHN0eWxlcztcclxuXHJcbiAgdGhpcy5fY2xvbmVkTWFya2VycyA9IHt9O1xyXG5cclxuICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdkcmFnLmNsZWFudXAnLCBmdW5jdGlvbigpIHtcclxuICAgIGZvckVhY2goc2VsZi5fY2xvbmVkTWFya2VycywgZnVuY3Rpb24oY2xvbmVkTWFya2VyKSB7XHJcbiAgICAgIHN2Z1JlbW92ZShjbG9uZWRNYXJrZXIpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgc2VsZi5fY2xvbmVkTWFya2VycyA9IHt9O1xyXG4gIH0pO1xyXG59XHJcblxyXG5QcmV2aWV3U3VwcG9ydC4kaW5qZWN0ID0gW1xyXG4gICdlbGVtZW50UmVnaXN0cnknLFxyXG4gICdldmVudEJ1cycsXHJcbiAgJ2NhbnZhcycsXHJcbiAgJ3N0eWxlcydcclxuXTtcclxuXHJcblxyXG4vKipcclxuICogUmV0dXJucyBncmFwaGljcyBvZiBhbiBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge1NWR0VsZW1lbnR9XHJcbiAqL1xyXG5QcmV2aWV3U3VwcG9ydC5wcm90b3R5cGUuZ2V0R2Z4ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZWxlbWVudCk7XHJcbn07XHJcblxyXG4vKipcclxuICogQWRkcyBhIG1vdmUgcHJldmlldyBvZiBhIGdpdmVuIHNoYXBlIHRvIGEgZ2l2ZW4gc3ZnIGdyb3VwLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ3JvdXBcclxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBbZ2Z4XVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtTVkdFbGVtZW50fSBkcmFnZ2VyXHJcbiAqL1xyXG5QcmV2aWV3U3VwcG9ydC5wcm90b3R5cGUuYWRkRHJhZ2dlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIGdyb3VwLCBnZngpIHtcclxuICBnZnggPSBnZnggfHwgdGhpcy5nZXRHZngoZWxlbWVudCk7XHJcblxyXG4gIHZhciBkcmFnZ2VyID0gc3ZnQ2xvbmUoZ2Z4KTtcclxuICB2YXIgYmJveCA9IGdmeC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgdGhpcy5fY2xvbmVNYXJrZXJzKGdldFZpc3VhbChkcmFnZ2VyKSk7XHJcblxyXG4gIHN2Z0F0dHIoZHJhZ2dlciwgdGhpcy5fc3R5bGVzLmNscygnZGpzLWRyYWdnZXInLCBbXSwge1xyXG4gICAgeDogYmJveC50b3AsXHJcbiAgICB5OiBiYm94LmxlZnRcclxuICB9KSk7XHJcblxyXG4gIHN2Z0FwcGVuZChncm91cCwgZHJhZ2dlcik7XHJcblxyXG4gIHJldHVybiBkcmFnZ2VyO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEFkZHMgYSByZXNpemUgcHJldmlldyBvZiBhIGdpdmVuIHNoYXBlIHRvIGEgZ2l2ZW4gc3ZnIGdyb3VwLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ3JvdXBcclxuICpcclxuICogQHJldHVybiB7U1ZHRWxlbWVudH0gZnJhbWVcclxuICovXHJcblByZXZpZXdTdXBwb3J0LnByb3RvdHlwZS5hZGRGcmFtZSA9IGZ1bmN0aW9uKHNoYXBlLCBncm91cCkge1xyXG5cclxuICB2YXIgZnJhbWUgPSBzdmdDcmVhdGUoJ3JlY3QnLCB7XHJcbiAgICBjbGFzczogJ2Rqcy1yZXNpemUtb3ZlcmxheScsXHJcbiAgICB3aWR0aDogIHNoYXBlLndpZHRoLFxyXG4gICAgaGVpZ2h0OiBzaGFwZS5oZWlnaHQsXHJcbiAgICB4OiBzaGFwZS54LFxyXG4gICAgeTogc2hhcGUueVxyXG4gIH0pO1xyXG5cclxuICBzdmdBcHBlbmQoZ3JvdXAsIGZyYW1lKTtcclxuXHJcbiAgcmV0dXJuIGZyYW1lO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENsb25lIGFsbCBtYXJrZXJzIHJlZmVyZW5jZWQgYnkgYSBub2RlIGFuZCBpdHMgY2hpbGQgbm9kZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ2Z4XHJcbiAqL1xyXG5QcmV2aWV3U3VwcG9ydC5wcm90b3R5cGUuX2Nsb25lTWFya2VycyA9IGZ1bmN0aW9uKGdmeCkge1xyXG4gIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgaWYgKGdmeC5jaGlsZE5vZGVzKSB7XHJcblxyXG4gICAgLy8gVE9ETzogdXNlIGZvckVhY2ggb25jZSB3ZSBkcm9wIFBoYW50b21KU1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBnZnguY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xyXG5cclxuICAgICAgLy8gcmVjdXJzaXZlbHkgY2xvbmUgbWFya2VycyBvZiBjaGlsZCBub2Rlc1xyXG4gICAgICBzZWxmLl9jbG9uZU1hcmtlcnMoZ2Z4LmNoaWxkTm9kZXNbIGkgXSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZiAoIWNhbkhhdmVNYXJrZXIoZ2Z4KSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgTUFSS0VSX1RZUEVTLmZvckVhY2goZnVuY3Rpb24obWFya2VyVHlwZSkge1xyXG4gICAgaWYgKHN2Z0F0dHIoZ2Z4LCBtYXJrZXJUeXBlKSkge1xyXG4gICAgICB2YXIgbWFya2VyID0gZ2V0TWFya2VyKGdmeCwgbWFya2VyVHlwZSwgc2VsZi5fY2FudmFzLmdldENvbnRhaW5lcigpKTtcclxuXHJcbiAgICAgIHNlbGYuX2Nsb25lTWFya2VyKGdmeCwgbWFya2VyLCBtYXJrZXJUeXBlKTtcclxuICAgIH1cclxuICB9KTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDbG9uZSBtYXJrZXIgcmVmZXJlbmNlZCBieSBhbiBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGdmeFxyXG4gKiBAcGFyYW0ge1NWR0VsZW1lbnR9IG1hcmtlclxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbWFya2VyVHlwZVxyXG4gKi9cclxuUHJldmlld1N1cHBvcnQucHJvdG90eXBlLl9jbG9uZU1hcmtlciA9IGZ1bmN0aW9uKGdmeCwgbWFya2VyLCBtYXJrZXJUeXBlKSB7XHJcbiAgdmFyIG1hcmtlcklkID0gbWFya2VyLmlkO1xyXG5cclxuICB2YXIgY2xvbmVkTWFya2VyID0gdGhpcy5fY2xvbmVkTWFya2Vyc1sgbWFya2VySWQgXTtcclxuXHJcbiAgaWYgKCFjbG9uZWRNYXJrZXIpIHtcclxuICAgIGNsb25lZE1hcmtlciA9IHN2Z0Nsb25lKG1hcmtlcik7XHJcblxyXG4gICAgdmFyIGNsb25lZE1hcmtlcklkID0gbWFya2VySWQgKyAnLWNsb25lJztcclxuXHJcbiAgICBjbG9uZWRNYXJrZXIuaWQgPSBjbG9uZWRNYXJrZXJJZDtcclxuXHJcbiAgICBzdmdDbGFzc2VzKGNsb25lZE1hcmtlcilcclxuICAgICAgLmFkZCgnZGpzLWRyYWdnZXInKVxyXG4gICAgICAuYWRkKCdkanMtZHJhZ2dlci1tYXJrZXInKTtcclxuXHJcbiAgICB0aGlzLl9jbG9uZWRNYXJrZXJzWyBtYXJrZXJJZCBdID0gY2xvbmVkTWFya2VyO1xyXG5cclxuICAgIHZhciBkZWZzID0gZG9tUXVlcnkoJ2RlZnMnLCB0aGlzLl9jYW52YXMuX3N2Zyk7XHJcblxyXG4gICAgaWYgKCFkZWZzKSB7XHJcbiAgICAgIGRlZnMgPSBzdmdDcmVhdGUoJ2RlZnMnKTtcclxuXHJcbiAgICAgIHN2Z0FwcGVuZCh0aGlzLl9jYW52YXMuX3N2ZywgZGVmcyk7XHJcbiAgICB9XHJcblxyXG4gICAgc3ZnQXBwZW5kKGRlZnMsIGNsb25lZE1hcmtlcik7XHJcbiAgfVxyXG5cclxuICB2YXIgcmVmZXJlbmNlID0gaWRUb1JlZmVyZW5jZSh0aGlzLl9jbG9uZWRNYXJrZXJzWyBtYXJrZXJJZCBdLmlkKTtcclxuXHJcbiAgc3ZnQXR0cihnZngsIG1hcmtlclR5cGUsIHJlZmVyZW5jZSk7XHJcbn07XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbi8qKlxyXG4gKiBHZXQgbWFya2VyIG9mIGdpdmVuIHR5cGUgcmVmZXJlbmNlZCBieSBub2RlLlxyXG4gKlxyXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcclxuICogQHBhcmFtIHtzdHJpbmd9IG1hcmtlclR5cGVcclxuICogQHBhcmFtIHtOb2RlfSBbcGFyZW50Tm9kZV1cclxuICpcclxuICogQHBhcmFtIHtOb2RlfVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0TWFya2VyKG5vZGUsIG1hcmtlclR5cGUsIHBhcmVudE5vZGUpIHtcclxuICB2YXIgaWQgPSByZWZlcmVuY2VUb0lkKHN2Z0F0dHIobm9kZSwgbWFya2VyVHlwZSkpO1xyXG5cclxuICByZXR1cm4gZG9tUXVlcnkoJ21hcmtlciMnICsgaWQsIHBhcmVudE5vZGUgfHwgZG9jdW1lbnQpO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IElEIG9mIGZyYWdtZW50IHdpdGhpbiBjdXJyZW50IGRvY3VtZW50IGZyb20gaXRzIGZ1bmN0aW9uYWwgSVJJIHJlZmVyZW5jZS5cclxuICogUmVmZXJlbmNlcyBtYXkgdXNlIHNpbmdsZSBvciBkb3VibGUgcXVvdGVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVmZXJlbmNlXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9XHJcbiAqL1xyXG5mdW5jdGlvbiByZWZlcmVuY2VUb0lkKHJlZmVyZW5jZSkge1xyXG4gIHJldHVybiByZWZlcmVuY2UubWF0Y2goL3VybFxcKFsnXCJdPyMoW14nXCJdKilbJ1wiXT9cXCkvKVsxXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBmdW5jdGlvbmFsIElSSSByZWZlcmVuY2UgZm9yIGdpdmVuIElEIG9mIGZyYWdtZW50IHdpdGhpbiBjdXJyZW50IGRvY3VtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRcclxuICpcclxuICogQHJldHVybnMge3N0cmluZ31cclxuICovXHJcbmZ1bmN0aW9uIGlkVG9SZWZlcmVuY2UoaWQpIHtcclxuICByZXR1cm4gJ3VybCgjJyArIGlkICsgJyknO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2sgd2V0aGVyIG5vZGUgdHlwZSBjYW4gaGF2ZSBtYXJrZXIgYXR0cmlidXRlcy5cclxuICpcclxuICogQHBhcmFtIHtOb2RlfSBub2RlXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuZnVuY3Rpb24gY2FuSGF2ZU1hcmtlcihub2RlKSB7XHJcbiAgcmV0dXJuIE5PREVTX0NBTl9IQVZFX01BUktFUi5pbmRleE9mKG5vZGUubm9kZU5hbWUpICE9PSAtMTtcclxufSIsImltcG9ydCBQcmV2aWV3U3VwcG9ydCBmcm9tICcuL1ByZXZpZXdTdXBwb3J0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAncHJldmlld1N1cHBvcnQnIF0sXG4gIHByZXZpZXdTdXBwb3J0OiBbICd0eXBlJywgUHJldmlld1N1cHBvcnQgXVxufTtcbiIsImltcG9ydCB7XG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbnZhciByb3VuZCA9IE1hdGgucm91bmQ7XG5cbi8qKlxuICogU2VydmljZSB0aGF0IGFsbG93IHJlcGxhY2luZyBvZiBlbGVtZW50cy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVwbGFjZShtb2RlbGluZykge1xuXG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cblJlcGxhY2UuJGluamVjdCA9IFsgJ21vZGVsaW5nJyBdO1xuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gb2xkRWxlbWVudCAtIEVsZW1lbnQgdG8gYmUgcmVwbGFjZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSAgbmV3RWxlbWVudERhdGEgLSBDb250YWluaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBuZXcgZWxlbWVudCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgZXhhbXBsZSB0aGUgbmV3IGJvdW5kcyBhbmQgdHlwZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSAgb3B0aW9ucyAtIEN1c3RvbSBvcHRpb25zIHRoYXQgd2lsbCBiZSBhdHRhY2hlZCB0byB0aGUgY29udGV4dC4gSXQgY2FuIGJlIHVzZWQgdG8gaW5qZWN0IGRhdGFcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQgaXMgbmVlZGVkIGluIHRoZSBjb21tYW5kIGNoYWluLiBGb3IgZXhhbXBsZSBpdCBjb3VsZCBiZSB1c2VkIGluXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudGJ1cy5vbignY29tbWFuZFN0YWNrLnNoYXBlLnJlcGxhY2UucG9zdEV4ZWN1dGUnKSB0byBjaGFuZ2Ugc2hhcGUgYXR0cmlidXRlcyBhZnRlclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGUgY3JlYXRpb24uXG4gKi9cblJlcGxhY2UucHJvdG90eXBlLnJlcGxhY2VFbGVtZW50ID0gZnVuY3Rpb24ob2xkRWxlbWVudCwgbmV3RWxlbWVudERhdGEsIG9wdGlvbnMpIHtcblxuICBpZiAob2xkRWxlbWVudC53YXlwb2ludHMpIHtcblxuICAgIC8vIFRPRE8obmlra3UpOiB3ZSBkbyBub3QgcmVwbGFjZSBjb25uZWN0aW9ucywgeWV0XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcblxuICB2YXIgd2lkdGggPSBuZXdFbGVtZW50RGF0YS53aWR0aCB8fCBvbGRFbGVtZW50LndpZHRoLFxuICAgICAgaGVpZ2h0ID0gbmV3RWxlbWVudERhdGEuaGVpZ2h0IHx8IG9sZEVsZW1lbnQuaGVpZ2h0LFxuICAgICAgeCA9IG5ld0VsZW1lbnREYXRhLnggfHwgb2xkRWxlbWVudC54LFxuICAgICAgeSA9IG5ld0VsZW1lbnREYXRhLnkgfHwgb2xkRWxlbWVudC55LFxuICAgICAgY2VudGVyWCA9IHJvdW5kKHggKyB3aWR0aCAvIDIpLFxuICAgICAgY2VudGVyWSA9IHJvdW5kKHkgKyBoZWlnaHQgLyAyKTtcblxuICAvLyBtb2RlbGluZyBBUEkgcmVxdWlyZXMgY2VudGVyIGNvb3JkaW5hdGVzLFxuICAvLyBhY2NvdW50IGZvciB0aGF0IHdoZW4gaGFuZGxpbmcgc2hhcGUgYm91bmRzXG5cbiAgcmV0dXJuIG1vZGVsaW5nLnJlcGxhY2VTaGFwZShcbiAgICBvbGRFbGVtZW50LFxuICAgIGFzc2lnbihcbiAgICAgIHt9LFxuICAgICAgbmV3RWxlbWVudERhdGEsXG4gICAgICB7XG4gICAgICAgIHg6IGNlbnRlclgsXG4gICAgICAgIHk6IGNlbnRlclksXG4gICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHRcbiAgICAgIH1cbiAgICApLFxuICAgIG9wdGlvbnNcbiAgKTtcbn07XG4iLCJpbXBvcnQgUmVwbGFjZSBmcm9tICcuL1JlcGxhY2UnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdyZXBsYWNlJyBdLFxuICByZXBsYWNlOiBbICd0eXBlJywgUmVwbGFjZSBdXG59OyIsImltcG9ydCB7XG4gIHBpY2ssXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIHJlc2l6ZUJvdW5kcyxcbiAgZW5zdXJlQ29uc3RyYWludHMsXG4gIGNvbXB1dGVDaGlsZHJlbkJCb3gsXG4gIGdldE1pblJlc2l6ZUJvdW5kc1xufSBmcm9tICcuL1Jlc2l6ZVV0aWwnO1xuXG5pbXBvcnQge1xuICBhc1RSQkwsXG4gIGdldE1pZCxcbiAgcm91bmRCb3VuZHNcbn0gZnJvbSAnLi4vLi4vbGF5b3V0L0xheW91dFV0aWwnO1xuXG52YXIgREVGQVVMVF9NSU5fV0lEVEggPSAxMDtcblxuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgcHJvdmlkZXMgcmVzaXppbmcgb2Ygc2hhcGVzIG9uIHRoZSBjYW52YXMuXG4gKlxuICogVGhlIGZvbGxvd2luZyBjb21wb25lbnRzIGFyZSBwYXJ0IG9mIHNoYXBlIHJlc2l6ZTpcbiAqXG4gKiAgKiBhZGRpbmcgcmVzaXplIGhhbmRsZXMsXG4gKiAgKiBjcmVhdGluZyBhIHZpc3VhbCBkdXJpbmcgcmVzaXplXG4gKiAgKiBjaGVja2luZyByZXNpemUgcnVsZXNcbiAqICAqIGNvbW1pdHRpbmcgYSBjaGFuZ2Ugb25jZSBmaW5pc2hlZFxuICpcbiAqXG4gKiAjIyBDdXN0b21pemluZ1xuICpcbiAqIEl0J3MgcG9zc2libGUgdG8gY3VzdG9taXplIHRoZSByZXNpemluZyBiZWhhdmlvdXIgYnkgaW50ZXJjZXB0aW5nICdyZXNpemUuc3RhcnQnXG4gKiBhbmQgcHJvdmlkaW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVycyB0aHJvdWdoIHRoZSAnY29udGV4dCc6XG4gKlxuICogICAqIG1pbkRpbWVuc2lvbnMgKHsgd2lkdGgsIGhlaWdodCB9KTogbWluaW11bSBzaGFwZSBkaW1lbnNpb25zXG4gKlxuICogICAqIGNoaWxkcmVuQm94UGFkZGluZyAoeyBsZWZ0LCB0b3AsIGJvdHRvbSwgcmlnaHQgfSB8fCBudW1iZXIpOlxuICogICAgIGdhcCBiZXR3ZWVuIHRoZSBtaW5pbXVtIGJvdW5kaW5nIGJveCBhbmQgdGhlIGNvbnRhaW5lclxuICpcbiAqIGYuZXg6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogZXZlbnRCdXMub24oJ3Jlc2l6ZS5zdGFydCcsIDE1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gKiAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAqXG4gKiAgY29udGV4dC5taW5EaW1lbnNpb25zID0geyB3aWR0aDogMTQwLCBoZWlnaHQ6IDEyMCB9O1xuICpcbiAqICAvLyBQYXNzaW5nIGdlbmVyYWwgcGFkZGluZ1xuICogIGNvbnRleHQuY2hpbGRyZW5Cb3hQYWRkaW5nID0gMzA7XG4gKlxuICogIC8vIFBhc3NpbmcgcGFkZGluZyB0byBhIHNwZWNpZmljIHNpZGVcbiAqICBjb250ZXh0LmNoaWxkcmVuQm94UGFkZGluZy5sZWZ0ID0gMjA7XG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSZXNpemUoZXZlbnRCdXMsIHJ1bGVzLCBtb2RlbGluZywgZHJhZ2dpbmcpIHtcblxuICB0aGlzLl9kcmFnZ2luZyA9IGRyYWdnaW5nO1xuICB0aGlzLl9ydWxlcyA9IHJ1bGVzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuXG4gIC8qKlxuICAgKiBIYW5kbGUgcmVzaXplIG1vdmUgYnkgc3BlY2lmaWVkIGRlbHRhLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICAgKiBAcGFyYW0ge1BvaW50fSBkZWx0YVxuICAgKi9cbiAgZnVuY3Rpb24gaGFuZGxlTW92ZShjb250ZXh0LCBkZWx0YSkge1xuXG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXG4gICAgICAgIHJlc2l6ZUNvbnN0cmFpbnRzID0gY29udGV4dC5yZXNpemVDb25zdHJhaW50cyxcbiAgICAgICAgbmV3Qm91bmRzO1xuXG4gICAgY29udGV4dC5kZWx0YSA9IGRlbHRhO1xuXG4gICAgbmV3Qm91bmRzID0gcmVzaXplQm91bmRzKHNoYXBlLCBkaXJlY3Rpb24sIGRlbHRhKTtcblxuICAgIC8vIGVuc3VyZSBjb25zdHJhaW50cyBkdXJpbmcgcmVzaXplXG4gICAgY29udGV4dC5uZXdCb3VuZHMgPSBlbnN1cmVDb25zdHJhaW50cyhuZXdCb3VuZHMsIHJlc2l6ZUNvbnN0cmFpbnRzKTtcblxuICAgIC8vIHVwZGF0ZSArIGNhY2hlIGV4ZWN1dGFibGUgc3RhdGVcbiAgICBjb250ZXh0LmNhbkV4ZWN1dGUgPSBzZWxmLmNhblJlc2l6ZShjb250ZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgcmVzaXplIHN0YXJ0LlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IGNvbnRleHRcbiAgICovXG4gIGZ1bmN0aW9uIGhhbmRsZVN0YXJ0KGNvbnRleHQpIHtcblxuICAgIHZhciByZXNpemVDb25zdHJhaW50cyA9IGNvbnRleHQucmVzaXplQ29uc3RyYWludHMsXG5cbiAgICAgICAgLy8gZXZhbHVhdGUgbWluQm91bmRzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuICAgICAgICBtaW5Cb3VuZHMgPSBjb250ZXh0Lm1pbkJvdW5kcztcblxuICAgIGlmIChyZXNpemVDb25zdHJhaW50cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG1pbkJvdW5kcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBtaW5Cb3VuZHMgPSBzZWxmLmNvbXB1dGVNaW5SZXNpemVCb3goY29udGV4dCk7XG4gICAgfVxuXG4gICAgY29udGV4dC5yZXNpemVDb25zdHJhaW50cyA9IHtcbiAgICAgIG1pbjogYXNUUkJMKG1pbkJvdW5kcylcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSByZXNpemUgZW5kLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IGNvbnRleHRcbiAgICovXG4gIGZ1bmN0aW9uIGhhbmRsZUVuZChjb250ZXh0KSB7XG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSxcbiAgICAgICAgbmV3Qm91bmRzID0gY29udGV4dC5uZXdCb3VuZHM7XG5cbiAgICBpZiAoY2FuRXhlY3V0ZSkge1xuXG4gICAgICAvLyBlbnN1cmUgd2UgaGF2ZSBhY3R1YWwgcGl4ZWwgdmFsdWVzIGZvciBuZXcgYm91bmRzXG4gICAgICAvLyAoaW1wb3J0YW50IHdoZW4gem9vbSBsZXZlbCB3YXMgPiAxIGR1cmluZyBtb3ZlKVxuICAgICAgbmV3Qm91bmRzID0gcm91bmRCb3VuZHMobmV3Qm91bmRzKTtcblxuICAgICAgaWYgKCFib3VuZHNDaGFuZ2VkKHNoYXBlLCBuZXdCb3VuZHMpKSB7XG5cbiAgICAgICAgLy8gbm8gcmVzaXplIG5lY2Vzc2FyeVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIHBlcmZvcm0gdGhlIGFjdHVhbCByZXNpemVcbiAgICAgIG1vZGVsaW5nLnJlc2l6ZVNoYXBlKHNoYXBlLCBuZXdCb3VuZHMpO1xuICAgIH1cbiAgfVxuXG5cbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5zdGFydCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaGFuZGxlU3RhcnQoZXZlbnQuY29udGV4dCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdyZXNpemUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGRlbHRhID0ge1xuICAgICAgeDogZXZlbnQuZHgsXG4gICAgICB5OiBldmVudC5keVxuICAgIH07XG5cbiAgICBoYW5kbGVNb3ZlKGV2ZW50LmNvbnRleHQsIGRlbHRhKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIGhhbmRsZUVuZChldmVudC5jb250ZXh0KTtcbiAgfSk7XG5cbn1cblxuXG5SZXNpemUucHJvdG90eXBlLmNhblJlc2l6ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIHJ1bGVzID0gdGhpcy5fcnVsZXM7XG5cbiAgdmFyIGN0eCA9IHBpY2soY29udGV4dCwgWyAnbmV3Qm91bmRzJywgJ3NoYXBlJywgJ2RlbHRhJywgJ2RpcmVjdGlvbicgXSk7XG5cbiAgcmV0dXJuIHJ1bGVzLmFsbG93ZWQoJ3NoYXBlLnJlc2l6ZScsIGN0eCk7XG59O1xuXG4vKipcbiAqIEFjdGl2YXRlIGEgcmVzaXplIG9wZXJhdGlvbi5cbiAqXG4gKiBZb3UgbWF5IHNwZWNpZnkgYWRkaXRpb25hbCBjb250ZXh0dWFsIGluZm9ybWF0aW9uIGFuZCBtdXN0IHNwZWNpZnkgYVxuICogcmVzaXplIGRpcmVjdGlvbiBkdXJpbmcgYWN0aXZhdGlvbiBvZiB0aGUgcmVzaXplIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7TW91c2VFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICogQHBhcmFtIHtPYmplY3R8c3RyaW5nfSBjb250ZXh0T3JEaXJlY3Rpb25cbiAqL1xuUmVzaXplLnByb3RvdHlwZS5hY3RpdmF0ZSA9IGZ1bmN0aW9uKGV2ZW50LCBzaGFwZSwgY29udGV4dE9yRGlyZWN0aW9uKSB7XG4gIHZhciBkcmFnZ2luZyA9IHRoaXMuX2RyYWdnaW5nLFxuICAgICAgY29udGV4dCxcbiAgICAgIGRpcmVjdGlvbjtcblxuICBpZiAodHlwZW9mIGNvbnRleHRPckRpcmVjdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICBjb250ZXh0T3JEaXJlY3Rpb24gPSB7XG4gICAgICBkaXJlY3Rpb246IGNvbnRleHRPckRpcmVjdGlvblxuICAgIH07XG4gIH1cblxuICBjb250ZXh0ID0gYXNzaWduKHsgc2hhcGU6IHNoYXBlIH0sIGNvbnRleHRPckRpcmVjdGlvbik7XG5cbiAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb247XG5cbiAgaWYgKCFkaXJlY3Rpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ211c3QgcHJvdmlkZSBhIGRpcmVjdGlvbiAobnx3fHN8ZXxud3xzZXxuZXxzdyknKTtcbiAgfVxuXG4gIGRyYWdnaW5nLmluaXQoZXZlbnQsIGdldFJlZmVyZW5jZVBvaW50KHNoYXBlLCBkaXJlY3Rpb24pLCAncmVzaXplJywge1xuICAgIGF1dG9BY3RpdmF0ZTogdHJ1ZSxcbiAgICBjdXJzb3I6IGdldEN1cnNvcihkaXJlY3Rpb24pLFxuICAgIGRhdGE6IHtcbiAgICAgIHNoYXBlOiBzaGFwZSxcbiAgICAgIGNvbnRleHQ6IGNvbnRleHRcbiAgICB9XG4gIH0pO1xufTtcblxuUmVzaXplLnByb3RvdHlwZS5jb21wdXRlTWluUmVzaXplQm94ID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXG4gICAgICBtaW5EaW1lbnNpb25zLFxuICAgICAgY2hpbGRyZW5Cb3VuZHM7XG5cbiAgbWluRGltZW5zaW9ucyA9IGNvbnRleHQubWluRGltZW5zaW9ucyB8fCB7XG4gICAgd2lkdGg6IERFRkFVTFRfTUlOX1dJRFRILFxuICAgIGhlaWdodDogREVGQVVMVF9NSU5fV0lEVEhcbiAgfTtcblxuICAvLyBnZXQgY2hpbGRyZW4gYm91bmRzXG4gIGNoaWxkcmVuQm91bmRzID0gY29tcHV0ZUNoaWxkcmVuQkJveChzaGFwZSwgY29udGV4dC5jaGlsZHJlbkJveFBhZGRpbmcpO1xuXG4gIC8vIGdldCBjb3JyZWN0IG1pbmltdW0gYm91bmRzIGZyb20gZ2l2ZW4gcmVzaXplIGRpcmVjdGlvblxuICAvLyBiYXNpY2FsbHkgZW5zdXJlcyB0aGF0IHRoZSBtaW5Cb3VuZHMgaXMgbWF4KGNoaWxkcmVuQm91bmRzLCBtaW5EaW1lbnNpb25zKVxuICByZXR1cm4gZ2V0TWluUmVzaXplQm91bmRzKGRpcmVjdGlvbiwgc2hhcGUsIG1pbkRpbWVuc2lvbnMsIGNoaWxkcmVuQm91bmRzKTtcbn07XG5cblxuUmVzaXplLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdydWxlcycsXG4gICdtb2RlbGluZycsXG4gICdkcmFnZ2luZydcbl07XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBib3VuZHNDaGFuZ2VkKHNoYXBlLCBuZXdCb3VuZHMpIHtcbiAgcmV0dXJuIHNoYXBlLnggIT09IG5ld0JvdW5kcy54IHx8XG4gICAgc2hhcGUueSAhPT0gbmV3Qm91bmRzLnkgfHxcbiAgICBzaGFwZS53aWR0aCAhPT0gbmV3Qm91bmRzLndpZHRoIHx8XG4gICAgc2hhcGUuaGVpZ2h0ICE9PSBuZXdCb3VuZHMuaGVpZ2h0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlUG9pbnQoc2hhcGUsIGRpcmVjdGlvbikge1xuICB2YXIgbWlkID0gZ2V0TWlkKHNoYXBlKSxcbiAgICAgIHRyYmwgPSBhc1RSQkwoc2hhcGUpO1xuXG4gIHZhciByZWZlcmVuY2VQb2ludCA9IHtcbiAgICB4OiBtaWQueCxcbiAgICB5OiBtaWQueVxuICB9O1xuXG4gIGlmIChkaXJlY3Rpb24uaW5kZXhPZignbicpICE9PSAtMSkge1xuICAgIHJlZmVyZW5jZVBvaW50LnkgPSB0cmJsLnRvcDtcbiAgfSBlbHNlIGlmIChkaXJlY3Rpb24uaW5kZXhPZigncycpICE9PSAtMSkge1xuICAgIHJlZmVyZW5jZVBvaW50LnkgPSB0cmJsLmJvdHRvbTtcbiAgfVxuXG4gIGlmIChkaXJlY3Rpb24uaW5kZXhPZignZScpICE9PSAtMSkge1xuICAgIHJlZmVyZW5jZVBvaW50LnggPSB0cmJsLnJpZ2h0O1xuICB9IGVsc2UgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCd3JykgIT09IC0xKSB7XG4gICAgcmVmZXJlbmNlUG9pbnQueCA9IHRyYmwubGVmdDtcbiAgfVxuXG4gIHJldHVybiByZWZlcmVuY2VQb2ludDtcbn1cblxuZnVuY3Rpb24gZ2V0Q3Vyc29yKGRpcmVjdGlvbikge1xuICB2YXIgcHJlZml4ID0gJ3Jlc2l6ZS0nO1xuXG4gIGlmIChkaXJlY3Rpb24gPT09ICduJyB8fCBkaXJlY3Rpb24gPT09ICdzJykge1xuICAgIHJldHVybiBwcmVmaXggKyAnbnMnO1xuICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ2UnIHx8IGRpcmVjdGlvbiA9PT0gJ3cnKSB7XG4gICAgcmV0dXJuIHByZWZpeCArICdldyc7XG4gIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAnbncnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgIHJldHVybiBwcmVmaXggKyAnbndzZSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHByZWZpeCArICduZXN3JztcbiAgfVxufSIsImltcG9ydCB7XG4gIGJpbmQsXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNsYXNzZXMgYXMgc3ZnQ2xhc3NlcyxcbiAgY2xlYXIgYXMgc3ZnQ2xlYXIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICBldmVudCBhcyBkb21FdmVudFxufSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IHtcbiAgaXNQcmltYXJ5QnV0dG9uXG59IGZyb20gJy4uLy4uL3V0aWwvTW91c2UnO1xuXG5pbXBvcnQge1xuICB0cmFuc2Zvcm1cbn0gZnJvbSAnLi4vLi4vdXRpbC9TdmdUcmFuc2Zvcm1VdGlsJztcblxuaW1wb3J0IHsgZ2V0UmVmZXJlbmNlUG9pbnQgfSBmcm9tICcuL1Jlc2l6ZSc7XG5cbnZhciBIQU5ETEVfT0ZGU0VUID0gLTYsXG4gICAgSEFORExFX1NJWkUgPSA0LFxuICAgIEhBTkRMRV9ISVRfU0laRSA9IDIwO1xuXG52YXIgQ0xTX1JFU0laRVIgPSAnZGpzLXJlc2l6ZXInO1xuXG52YXIgZGlyZWN0aW9ucyA9IFsgJ24nLCAndycsICdzJywgJ2UnLCAnbncnLCAnbmUnLCAnc2UnLCAnc3cnIF07XG5cblxuLyoqXG4gKiBUaGlzIGNvbXBvbmVudCBpcyByZXNwb25zaWJsZSBmb3IgYWRkaW5nIHJlc2l6ZSBoYW5kbGVzLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge1NlbGVjdGlvbn0gc2VsZWN0aW9uXG4gKiBAcGFyYW0ge1Jlc2l6ZX0gcmVzaXplXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlc2l6ZUhhbmRsZXMoZXZlbnRCdXMsIGNhbnZhcywgc2VsZWN0aW9uLCByZXNpemUpIHtcblxuICB0aGlzLl9yZXNpemUgPSByZXNpemU7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZXZlbnRCdXMub24oJ3NlbGVjdGlvbi5jaGFuZ2VkJywgZnVuY3Rpb24oZSkge1xuICAgIHZhciBuZXdTZWxlY3Rpb24gPSBlLm5ld1NlbGVjdGlvbjtcblxuICAgIC8vIHJlbW92ZSBvbGQgc2VsZWN0aW9uIG1hcmtlcnNcbiAgICBzZWxmLnJlbW92ZVJlc2l6ZXJzKCk7XG5cbiAgICAvLyBhZGQgbmV3IHNlbGVjdGlvbiBtYXJrZXJzIE9OTFkgaWYgc2luZ2xlIHNlbGVjdGlvblxuICAgIGlmIChuZXdTZWxlY3Rpb24ubGVuZ3RoID09PSAxKSB7XG4gICAgICBmb3JFYWNoKG5ld1NlbGVjdGlvbiwgYmluZChzZWxmLmFkZFJlc2l6ZXIsIHNlbGYpKTtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdzaGFwZS5jaGFuZ2VkJywgZnVuY3Rpb24oZSkge1xuICAgIHZhciBzaGFwZSA9IGUuZWxlbWVudDtcblxuICAgIGlmIChzZWxlY3Rpb24uaXNTZWxlY3RlZChzaGFwZSkpIHtcbiAgICAgIHNlbGYucmVtb3ZlUmVzaXplcnMoKTtcblxuICAgICAgc2VsZi5hZGRSZXNpemVyKHNoYXBlKTtcbiAgICB9XG4gIH0pO1xufVxuXG5cblJlc2l6ZUhhbmRsZXMucHJvdG90eXBlLm1ha2VEcmFnZ2FibGUgPSBmdW5jdGlvbihlbGVtZW50LCBnZngsIGRpcmVjdGlvbikge1xuICB2YXIgcmVzaXplID0gdGhpcy5fcmVzaXplO1xuXG4gIGZ1bmN0aW9uIHN0YXJ0UmVzaXplKGV2ZW50KSB7XG5cbiAgICAvLyBvbmx5IHRyaWdnZXIgb24gbGVmdCBtb3VzZSBidXR0b25cbiAgICBpZiAoaXNQcmltYXJ5QnV0dG9uKGV2ZW50KSkge1xuICAgICAgcmVzaXplLmFjdGl2YXRlKGV2ZW50LCBlbGVtZW50LCBkaXJlY3Rpb24pO1xuICAgIH1cbiAgfVxuXG4gIGRvbUV2ZW50LmJpbmQoZ2Z4LCAnbW91c2Vkb3duJywgc3RhcnRSZXNpemUpO1xuICBkb21FdmVudC5iaW5kKGdmeCwgJ3RvdWNoc3RhcnQnLCBzdGFydFJlc2l6ZSk7XG59O1xuXG5cblJlc2l6ZUhhbmRsZXMucHJvdG90eXBlLl9jcmVhdGVSZXNpemVyID0gZnVuY3Rpb24oZWxlbWVudCwgeCwgeSwgZGlyZWN0aW9uKSB7XG4gIHZhciByZXNpemVyc1BhcmVudCA9IHRoaXMuX2dldFJlc2l6ZXJzUGFyZW50KCk7XG5cbiAgdmFyIG9mZnNldCA9IGdldEhhbmRsZU9mZnNldChkaXJlY3Rpb24pO1xuXG4gIHZhciBncm91cCA9IHN2Z0NyZWF0ZSgnZycpO1xuXG4gIHN2Z0NsYXNzZXMoZ3JvdXApLmFkZChDTFNfUkVTSVpFUik7XG4gIHN2Z0NsYXNzZXMoZ3JvdXApLmFkZChDTFNfUkVTSVpFUiArICctJyArIGVsZW1lbnQuaWQpO1xuICBzdmdDbGFzc2VzKGdyb3VwKS5hZGQoQ0xTX1JFU0laRVIgKyAnLScgKyBkaXJlY3Rpb24pO1xuXG4gIHN2Z0FwcGVuZChyZXNpemVyc1BhcmVudCwgZ3JvdXApO1xuXG4gIHZhciB2aXN1YWwgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcblxuICBzdmdBdHRyKHZpc3VhbCwge1xuICAgIHg6IC1IQU5ETEVfU0laRSAvIDIgKyBvZmZzZXQueCxcbiAgICB5OiAtSEFORExFX1NJWkUgLyAyICsgb2Zmc2V0LnksXG4gICAgd2lkdGg6IEhBTkRMRV9TSVpFLFxuICAgIGhlaWdodDogSEFORExFX1NJWkVcbiAgfSk7XG5cbiAgc3ZnQ2xhc3Nlcyh2aXN1YWwpLmFkZChDTFNfUkVTSVpFUiArICctdmlzdWFsJyk7XG5cbiAgc3ZnQXBwZW5kKGdyb3VwLCB2aXN1YWwpO1xuXG4gIHZhciBoaXQgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcblxuICBzdmdBdHRyKGhpdCwge1xuICAgIHg6IC1IQU5ETEVfSElUX1NJWkUgLyAyICsgb2Zmc2V0LngsXG4gICAgeTogLUhBTkRMRV9ISVRfU0laRSAvIDIgKyBvZmZzZXQueSxcbiAgICB3aWR0aDogSEFORExFX0hJVF9TSVpFLFxuICAgIGhlaWdodDogSEFORExFX0hJVF9TSVpFXG4gIH0pO1xuXG4gIHN2Z0NsYXNzZXMoaGl0KS5hZGQoQ0xTX1JFU0laRVIgKyAnLWhpdCcpO1xuXG4gIHN2Z0FwcGVuZChncm91cCwgaGl0KTtcblxuICB0cmFuc2Zvcm0oZ3JvdXAsIHgsIHkpO1xuXG4gIHJldHVybiBncm91cDtcbn07XG5cblJlc2l6ZUhhbmRsZXMucHJvdG90eXBlLmNyZWF0ZVJlc2l6ZXIgPSBmdW5jdGlvbihlbGVtZW50LCBkaXJlY3Rpb24pIHtcbiAgdmFyIHBvaW50ID0gZ2V0UmVmZXJlbmNlUG9pbnQoZWxlbWVudCwgZGlyZWN0aW9uKTtcblxuICB2YXIgcmVzaXplciA9IHRoaXMuX2NyZWF0ZVJlc2l6ZXIoZWxlbWVudCwgcG9pbnQueCwgcG9pbnQueSwgZGlyZWN0aW9uKTtcblxuICB0aGlzLm1ha2VEcmFnZ2FibGUoZWxlbWVudCwgcmVzaXplciwgZGlyZWN0aW9uKTtcbn07XG5cbi8vIHJlc2l6ZSBoYW5kbGVzIGltcGxlbWVudGF0aW9uIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBBZGQgcmVzaXplcnMgZm9yIGEgZ2l2ZW4gZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAqL1xuUmVzaXplSGFuZGxlcy5wcm90b3R5cGUuYWRkUmVzaXplciA9IGZ1bmN0aW9uKHNoYXBlKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgcmVzaXplID0gdGhpcy5fcmVzaXplO1xuXG4gIGlmICghcmVzaXplLmNhblJlc2l6ZSh7IHNoYXBlOiBzaGFwZSB9KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvckVhY2goZGlyZWN0aW9ucywgZnVuY3Rpb24oZGlyZWN0aW9uKSB7XG4gICAgc2VsZi5jcmVhdGVSZXNpemVyKHNoYXBlLCBkaXJlY3Rpb24pO1xuICB9KTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFsbCByZXNpemVyc1xuICovXG5SZXNpemVIYW5kbGVzLnByb3RvdHlwZS5yZW1vdmVSZXNpemVycyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmVzaXplcnNQYXJlbnQgPSB0aGlzLl9nZXRSZXNpemVyc1BhcmVudCgpO1xuXG4gIHN2Z0NsZWFyKHJlc2l6ZXJzUGFyZW50KTtcbn07XG5cblJlc2l6ZUhhbmRsZXMucHJvdG90eXBlLl9nZXRSZXNpemVyc1BhcmVudCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fY2FudmFzLmdldExheWVyKCdyZXNpemVycycpO1xufTtcblxuUmVzaXplSGFuZGxlcy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3NlbGVjdGlvbicsXG4gICdyZXNpemUnXG5dO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZ2V0SGFuZGxlT2Zmc2V0KGRpcmVjdGlvbikge1xuICB2YXIgb2Zmc2V0ID0ge1xuICAgIHg6IDAsXG4gICAgeTogMFxuICB9O1xuXG4gIGlmIChkaXJlY3Rpb24uaW5kZXhPZignZScpICE9PSAtMSkge1xuICAgIG9mZnNldC54ID0gLUhBTkRMRV9PRkZTRVQ7XG4gIH0gZWxzZSBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ3cnKSAhPT0gLTEpIHtcbiAgICBvZmZzZXQueCA9IEhBTkRMRV9PRkZTRVQ7XG4gIH1cblxuICBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ3MnKSAhPT0gLTEpIHtcbiAgICBvZmZzZXQueSA9IC1IQU5ETEVfT0ZGU0VUO1xuICB9IGVsc2UgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCduJykgIT09IC0xKSB7XG4gICAgb2Zmc2V0LnkgPSBIQU5ETEVfT0ZGU0VUO1xuICB9XG5cbiAgcmV0dXJuIG9mZnNldDtcbn0iLCJ2YXIgTUFSS0VSX1JFU0laSU5HID0gJ2Rqcy1yZXNpemluZycsXG4gICAgTUFSS0VSX1JFU0laRV9OT1RfT0sgPSAncmVzaXplLW5vdC1vayc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cbmltcG9ydCB7XG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZSxcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzXG59IGZyb20gJ3Rpbnktc3ZnJztcblxuXG4vKipcbiAqIFByb3ZpZGVzIHByZXZpZXdzIGZvciByZXNpemluZyBzaGFwZXMgd2hlbiByZXNpemluZy5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICogQHBhcmFtIHtQcmV2aWV3U3VwcG9ydH0gcHJldmlld1N1cHBvcnRcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVzaXplUHJldmlldyhldmVudEJ1cywgY2FudmFzLCBwcmV2aWV3U3VwcG9ydCkge1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgcmVzaXplciBmcmFtZS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAgICovXG4gIGZ1bmN0aW9uIHVwZGF0ZUZyYW1lKGNvbnRleHQpIHtcblxuICAgIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIGJvdW5kcyA9IGNvbnRleHQubmV3Qm91bmRzLFxuICAgICAgICBmcmFtZSA9IGNvbnRleHQuZnJhbWU7XG5cbiAgICBpZiAoIWZyYW1lKSB7XG4gICAgICBmcmFtZSA9IGNvbnRleHQuZnJhbWUgPSBwcmV2aWV3U3VwcG9ydC5hZGRGcmFtZShzaGFwZSwgY2FudmFzLmdldERlZmF1bHRMYXllcigpKTtcblxuICAgICAgY2FudmFzLmFkZE1hcmtlcihzaGFwZSwgTUFSS0VSX1JFU0laSU5HKTtcbiAgICB9XG5cbiAgICBpZiAoYm91bmRzLndpZHRoID4gNSkge1xuICAgICAgc3ZnQXR0cihmcmFtZSwgeyB4OiBib3VuZHMueCwgd2lkdGg6IGJvdW5kcy53aWR0aCB9KTtcbiAgICB9XG5cbiAgICBpZiAoYm91bmRzLmhlaWdodCA+IDUpIHtcbiAgICAgIHN2Z0F0dHIoZnJhbWUsIHsgeTogYm91bmRzLnksIGhlaWdodDogYm91bmRzLmhlaWdodCB9KTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dC5jYW5FeGVjdXRlKSB7XG4gICAgICBzdmdDbGFzc2VzKGZyYW1lKS5yZW1vdmUoTUFSS0VSX1JFU0laRV9OT1RfT0spO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdmdDbGFzc2VzKGZyYW1lKS5hZGQoTUFSS0VSX1JFU0laRV9OT1RfT0spO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgcmVzaXplciBmcmFtZS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAgICovXG4gIGZ1bmN0aW9uIHJlbW92ZUZyYW1lKGNvbnRleHQpIHtcbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBmcmFtZSA9IGNvbnRleHQuZnJhbWU7XG5cbiAgICBpZiAoZnJhbWUpIHtcbiAgICAgIHN2Z1JlbW92ZShjb250ZXh0LmZyYW1lKTtcbiAgICB9XG5cbiAgICBjYW52YXMucmVtb3ZlTWFya2VyKHNoYXBlLCBNQVJLRVJfUkVTSVpJTkcpO1xuICB9XG5cbiAgLy8gYWRkIGFuZCB1cGRhdGUgcHJldmlld3NcbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5tb3ZlJywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIHVwZGF0ZUZyYW1lKGV2ZW50LmNvbnRleHQpO1xuICB9KTtcblxuICAvLyByZW1vdmUgcHJldmlld3NcbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5jbGVhbnVwJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICByZW1vdmVGcmFtZShldmVudC5jb250ZXh0KTtcbiAgfSk7XG5cbn1cblxuUmVzaXplUHJldmlldy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3ByZXZpZXdTdXBwb3J0J1xuXTsiLCJpbXBvcnQge1xuICBmaWx0ZXIsXG4gIGlzTnVtYmVyXG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIG1heCA9IE1hdGgubWF4LFxuICAgIG1pbiA9IE1hdGgubWluO1xuXG52YXIgREVGQVVMVF9DSElMRF9CT1hfUEFERElORyA9IDIwO1xuXG5pbXBvcnQge1xuICBnZXRCQm94XG59IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG5pbXBvcnQge1xuICBhc1RSQkwsXG4gIGFzQm91bmRzXG59IGZyb20gJy4uLy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxuXG4vKipcbiAqIFN1YnN0cmFjdCBhIFRSQkwgZnJvbSBhbm90aGVyXG4gKlxuICogQHBhcmFtICB7VFJCTH0gdHJibEFcbiAqIEBwYXJhbSAge1RSQkx9IHRyYmxCXG4gKlxuICogQHJldHVybiB7VFJCTH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1YnN0cmFjdFRSQkwodHJibEEsIHRyYmxCKSB7XG4gIHJldHVybiB7XG4gICAgdG9wOiB0cmJsQS50b3AgLSB0cmJsQi50b3AsXG4gICAgcmlnaHQ6IHRyYmxBLnJpZ2h0IC0gdHJibEIucmlnaHQsXG4gICAgYm90dG9tOiB0cmJsQS5ib3R0b20gLSB0cmJsQi5ib3R0b20sXG4gICAgbGVmdDogdHJibEEubGVmdCAtIHRyYmxCLmxlZnRcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNpemUgdGhlIGdpdmVuIGJvdW5kcyBieSB0aGUgc3BlY2lmaWVkIGRlbHRhIGZyb20gYSBnaXZlbiBhbmNob3IgcG9pbnQuXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IGJvdW5kcyB0aGUgYm91bmRpbmcgYm94IHRoYXQgc2hvdWxkIGJlIHJlc2l6ZWRcbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXJlY3Rpb24gaW4gd2hpY2ggdGhlIGVsZW1lbnQgaXMgcmVzaXplZCAobncsIG5lLCBzZSwgc3cpXG4gKiBAcGFyYW0ge1BvaW50fSBkZWx0YSBvZiB0aGUgcmVzaXplIG9wZXJhdGlvblxuICpcbiAqIEByZXR1cm4ge0JvdW5kc30gcmVzaXplZCBib3VuZGluZyBib3hcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc2l6ZUJvdW5kcyhib3VuZHMsIGRpcmVjdGlvbiwgZGVsdGEpIHtcbiAgdmFyIGR4ID0gZGVsdGEueCxcbiAgICAgIGR5ID0gZGVsdGEueTtcblxuICB2YXIgbmV3Qm91bmRzID0ge1xuICAgIHg6IGJvdW5kcy54LFxuICAgIHk6IGJvdW5kcy55LFxuICAgIHdpZHRoOiBib3VuZHMud2lkdGgsXG4gICAgaGVpZ2h0OiBib3VuZHMuaGVpZ2h0XG4gIH07XG5cbiAgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCduJykgIT09IC0xKSB7XG4gICAgbmV3Qm91bmRzLnkgPSBib3VuZHMueSArIGR5O1xuICAgIG5ld0JvdW5kcy5oZWlnaHQgPSBib3VuZHMuaGVpZ2h0IC0gZHk7XG4gIH0gZWxzZSBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ3MnKSAhPT0gLTEpIHtcbiAgICBuZXdCb3VuZHMuaGVpZ2h0ID0gYm91bmRzLmhlaWdodCArIGR5O1xuICB9XG5cbiAgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCdlJykgIT09IC0xKSB7XG4gICAgbmV3Qm91bmRzLndpZHRoID0gYm91bmRzLndpZHRoICsgZHg7XG4gIH0gZWxzZSBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ3cnKSAhPT0gLTEpIHtcbiAgICBuZXdCb3VuZHMueCA9IGJvdW5kcy54ICsgZHg7XG4gICAgbmV3Qm91bmRzLndpZHRoID0gYm91bmRzLndpZHRoIC0gZHg7XG4gIH1cblxuICByZXR1cm4gbmV3Qm91bmRzO1xufVxuXG5cbi8qKlxuICogUmVzaXplIHRoZSBnaXZlbiBib3VuZHMgYnkgYXBwbHlpbmcgdGhlIHBhc3NlZFxuICogeyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQgfSBkZWx0YS5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc30gYm91bmRzXG4gKiBAcGFyYW0ge1RSQkx9IHRyYmxSZXNpemVcbiAqXG4gKiBAcmV0dXJuIHtCb3VuZHN9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNpemVUUkJMKGJvdW5kcywgcmVzaXplKSB7XG4gIHJldHVybiB7XG4gICAgeDogYm91bmRzLnggKyAocmVzaXplLmxlZnQgfHwgMCksXG4gICAgeTogYm91bmRzLnkgKyAocmVzaXplLnRvcCB8fCAwKSxcbiAgICB3aWR0aDogYm91bmRzLndpZHRoIC0gKHJlc2l6ZS5sZWZ0IHx8IDApICsgKHJlc2l6ZS5yaWdodCB8fCAwKSxcbiAgICBoZWlnaHQ6IGJvdW5kcy5oZWlnaHQgLSAocmVzaXplLnRvcCB8fCAwKSArIChyZXNpemUuYm90dG9tIHx8IDApXG4gIH07XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHJlYXR0YWNoUG9pbnQoYm91bmRzLCBuZXdCb3VuZHMsIHBvaW50KSB7XG5cbiAgdmFyIHN4ID0gYm91bmRzLndpZHRoIC8gbmV3Qm91bmRzLndpZHRoLFxuICAgICAgc3kgPSBib3VuZHMuaGVpZ2h0IC8gbmV3Qm91bmRzLmhlaWdodDtcblxuICByZXR1cm4ge1xuICAgIHg6IE1hdGgucm91bmQoKG5ld0JvdW5kcy54ICsgbmV3Qm91bmRzLndpZHRoIC8gMikpIC0gTWF0aC5mbG9vcigoKGJvdW5kcy54ICsgYm91bmRzLndpZHRoIC8gMikgLSBwb2ludC54KSAvIHN4KSxcbiAgICB5OiBNYXRoLnJvdW5kKChuZXdCb3VuZHMueSArIG5ld0JvdW5kcy5oZWlnaHQgLyAyKSkgLSBNYXRoLmZsb29yKCgoYm91bmRzLnkgKyBib3VuZHMuaGVpZ2h0IC8gMikgLSBwb2ludC55KSAvIHN5KVxuICB9O1xufVxuXG5cbmZ1bmN0aW9uIGFwcGx5Q29uc3RyYWludHMoYXR0ciwgdHJibCwgcmVzaXplQ29uc3RyYWludHMpIHtcblxuICB2YXIgdmFsdWUgPSB0cmJsW2F0dHJdLFxuICAgICAgbWluVmFsdWUgPSByZXNpemVDb25zdHJhaW50cy5taW4gJiYgcmVzaXplQ29uc3RyYWludHMubWluW2F0dHJdLFxuICAgICAgbWF4VmFsdWUgPSByZXNpemVDb25zdHJhaW50cy5tYXggJiYgcmVzaXplQ29uc3RyYWludHMubWF4W2F0dHJdO1xuXG4gIGlmIChpc051bWJlcihtaW5WYWx1ZSkpIHtcbiAgICB2YWx1ZSA9ICgvdG9wfGxlZnQvLnRlc3QoYXR0cikgPyBtaW4gOiBtYXgpKHZhbHVlLCBtaW5WYWx1ZSk7XG4gIH1cblxuICBpZiAoaXNOdW1iZXIobWF4VmFsdWUpKSB7XG4gICAgdmFsdWUgPSAoL3RvcHxsZWZ0Ly50ZXN0KGF0dHIpID8gbWF4IDogbWluKSh2YWx1ZSwgbWF4VmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlQ29uc3RyYWludHMoY3VycmVudEJvdW5kcywgcmVzaXplQ29uc3RyYWludHMpIHtcblxuICBpZiAoIXJlc2l6ZUNvbnN0cmFpbnRzKSB7XG4gICAgcmV0dXJuIGN1cnJlbnRCb3VuZHM7XG4gIH1cblxuICB2YXIgY3VycmVudFRyYmwgPSBhc1RSQkwoY3VycmVudEJvdW5kcyk7XG5cbiAgcmV0dXJuIGFzQm91bmRzKHtcbiAgICB0b3A6IGFwcGx5Q29uc3RyYWludHMoJ3RvcCcsIGN1cnJlbnRUcmJsLCByZXNpemVDb25zdHJhaW50cyksXG4gICAgcmlnaHQ6IGFwcGx5Q29uc3RyYWludHMoJ3JpZ2h0JywgY3VycmVudFRyYmwsIHJlc2l6ZUNvbnN0cmFpbnRzKSxcbiAgICBib3R0b206IGFwcGx5Q29uc3RyYWludHMoJ2JvdHRvbScsIGN1cnJlbnRUcmJsLCByZXNpemVDb25zdHJhaW50cyksXG4gICAgbGVmdDogYXBwbHlDb25zdHJhaW50cygnbGVmdCcsIGN1cnJlbnRUcmJsLCByZXNpemVDb25zdHJhaW50cylcbiAgfSk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1pblJlc2l6ZUJvdW5kcyhkaXJlY3Rpb24sIGN1cnJlbnRCb3VuZHMsIG1pbkRpbWVuc2lvbnMsIGNoaWxkcmVuQm91bmRzKSB7XG5cbiAgdmFyIGN1cnJlbnRCb3ggPSBhc1RSQkwoY3VycmVudEJvdW5kcyk7XG5cbiAgdmFyIG1pbkJveCA9IHtcbiAgICB0b3A6IC9uLy50ZXN0KGRpcmVjdGlvbikgPyBjdXJyZW50Qm94LmJvdHRvbSAtIG1pbkRpbWVuc2lvbnMuaGVpZ2h0IDogY3VycmVudEJveC50b3AsXG4gICAgbGVmdDogL3cvLnRlc3QoZGlyZWN0aW9uKSA/IGN1cnJlbnRCb3gucmlnaHQgLSBtaW5EaW1lbnNpb25zLndpZHRoIDogY3VycmVudEJveC5sZWZ0LFxuICAgIGJvdHRvbTogL3MvLnRlc3QoZGlyZWN0aW9uKSA/IGN1cnJlbnRCb3gudG9wICsgbWluRGltZW5zaW9ucy5oZWlnaHQgOiBjdXJyZW50Qm94LmJvdHRvbSxcbiAgICByaWdodDogL2UvLnRlc3QoZGlyZWN0aW9uKSA/IGN1cnJlbnRCb3gubGVmdCArIG1pbkRpbWVuc2lvbnMud2lkdGggOiBjdXJyZW50Qm94LnJpZ2h0XG4gIH07XG5cbiAgdmFyIGNoaWxkcmVuQm94ID0gY2hpbGRyZW5Cb3VuZHMgPyBhc1RSQkwoY2hpbGRyZW5Cb3VuZHMpIDogbWluQm94O1xuXG4gIHZhciBjb21iaW5lZEJveCA9IHtcbiAgICB0b3A6IG1pbihtaW5Cb3gudG9wLCBjaGlsZHJlbkJveC50b3ApLFxuICAgIGxlZnQ6IG1pbihtaW5Cb3gubGVmdCwgY2hpbGRyZW5Cb3gubGVmdCksXG4gICAgYm90dG9tOiBtYXgobWluQm94LmJvdHRvbSwgY2hpbGRyZW5Cb3guYm90dG9tKSxcbiAgICByaWdodDogbWF4KG1pbkJveC5yaWdodCwgY2hpbGRyZW5Cb3gucmlnaHQpXG4gIH07XG5cbiAgcmV0dXJuIGFzQm91bmRzKGNvbWJpbmVkQm94KTtcbn1cblxuZnVuY3Rpb24gYXNQYWRkaW5nKG1heUJlUGFkZGluZywgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh0eXBlb2YgbWF5QmVQYWRkaW5nICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBtYXlCZVBhZGRpbmc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIERFRkFVTFRfQ0hJTERfQk9YX1BBRERJTkc7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFBhZGRpbmcoYmJveCwgcGFkZGluZykge1xuICB2YXIgbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tO1xuXG4gIGlmICh0eXBlb2YgcGFkZGluZyA9PT0gJ29iamVjdCcpIHtcbiAgICBsZWZ0ID0gYXNQYWRkaW5nKHBhZGRpbmcubGVmdCk7XG4gICAgcmlnaHQgPSBhc1BhZGRpbmcocGFkZGluZy5yaWdodCk7XG4gICAgdG9wID0gYXNQYWRkaW5nKHBhZGRpbmcudG9wKTtcbiAgICBib3R0b20gPSBhc1BhZGRpbmcocGFkZGluZy5ib3R0b20pO1xuICB9IGVsc2Uge1xuICAgIGxlZnQgPSByaWdodCA9IHRvcCA9IGJvdHRvbSA9IGFzUGFkZGluZyhwYWRkaW5nKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgeDogYmJveC54IC0gbGVmdCxcbiAgICB5OiBiYm94LnkgLSB0b3AsXG4gICAgd2lkdGg6IGJib3gud2lkdGggKyBsZWZ0ICsgcmlnaHQsXG4gICAgaGVpZ2h0OiBiYm94LmhlaWdodCArIHRvcCArIGJvdHRvbVxuICB9O1xufVxuXG5cbi8qKlxuICogSXMgdGhlIGdpdmVuIGVsZW1lbnQgcGFydCBvZiB0aGUgcmVzaXplXG4gKiB0YXJnZXRzIG1pbiBib3VuZGFyeSBib3g/XG4gKlxuICogVGhpcyBpcyB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB3aGljaCBleGNsdWRlc1xuICogY29ubmVjdGlvbnMgYW5kIGxhYmVscy5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGlzQkJveENoaWxkKGVsZW1lbnQpIHtcblxuICAvLyBleGNsdWRlIGNvbm5lY3Rpb25zXG4gIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGV4Y2x1ZGUgbGFiZWxzXG4gIGlmIChlbGVtZW50LnR5cGUgPT09ICdsYWJlbCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gY2hpbGRyZW4gYm91bmRpbmcgY29tcHV0ZWQgZnJvbSBhIHNoYXBlcyBjaGlsZHJlblxuICogb3IgYSBsaXN0IG9mIHByZWZpbHRlcmVkIGNoaWxkcmVuLlxuICpcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5TaGFwZXxBcnJheTxkanMubW9kZWwuU2hhcGU+fSBzaGFwZU9yQ2hpbGRyZW5cbiAqIEBwYXJhbSAge251bWJlcnxPYmplY3R9IHBhZGRpbmdcbiAqXG4gKiBAcmV0dXJuIHtCb3VuZHN9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlQ2hpbGRyZW5CQm94KHNoYXBlT3JDaGlsZHJlbiwgcGFkZGluZykge1xuXG4gIHZhciBlbGVtZW50cztcblxuICAvLyBjb21wdXRlIGJhc2VkIG9uIHNoYXBlXG4gIGlmIChzaGFwZU9yQ2hpbGRyZW4ubGVuZ3RoID09PSB1bmRlZmluZWQpIHtcblxuICAgIC8vIGdyYWIgYWxsIHRoZSBjaGlsZHJlbiB0aGF0IGFyZSBwYXJ0IG9mIHRoZVxuICAgIC8vIHBhcmVudHMgY2hpbGRyZW4gYm94XG4gICAgZWxlbWVudHMgPSBmaWx0ZXIoc2hhcGVPckNoaWxkcmVuLmNoaWxkcmVuLCBpc0JCb3hDaGlsZCk7XG5cbiAgfSBlbHNlIHtcbiAgICBlbGVtZW50cyA9IHNoYXBlT3JDaGlsZHJlbjtcbiAgfVxuXG4gIGlmIChlbGVtZW50cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gYWRkUGFkZGluZyhnZXRCQm94KGVsZW1lbnRzKSwgcGFkZGluZyk7XG4gIH1cbn1cbiIsImltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuaW1wb3J0IFByZXZpZXdTdXBwb3J0TW9kdWxlIGZyb20gJy4uL3ByZXZpZXctc3VwcG9ydCc7XG5cbmltcG9ydCBSZXNpemUgZnJvbSAnLi9SZXNpemUnO1xuaW1wb3J0IFJlc2l6ZVByZXZpZXcgZnJvbSAnLi9SZXNpemVQcmV2aWV3JztcbmltcG9ydCBSZXNpemVIYW5kbGVzIGZyb20gJy4vUmVzaXplSGFuZGxlcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBSdWxlc01vZHVsZSxcbiAgICBEcmFnZ2luZ01vZHVsZSxcbiAgICBQcmV2aWV3U3VwcG9ydE1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogW1xuICAgICdyZXNpemUnLFxuICAgICdyZXNpemVQcmV2aWV3JyxcbiAgICAncmVzaXplSGFuZGxlcydcbiAgXSxcbiAgcmVzaXplOiBbICd0eXBlJywgUmVzaXplIF0sXG4gIHJlc2l6ZVByZXZpZXc6IFsgJ3R5cGUnLCBSZXNpemVQcmV2aWV3IF0sXG4gIHJlc2l6ZUhhbmRsZXM6IFsgJ3R5cGUnLCBSZXNpemVIYW5kbGVzIF1cbn07XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJy4uLy4uL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuLyoqXG4gKiBBIGJhc2ljIHByb3ZpZGVyIHRoYXQgbWF5IGJlIGV4dGVuZGVkIHRvIGltcGxlbWVudCBtb2RlbGluZyBydWxlcy5cbiAqXG4gKiBFeHRlbnNpb25zIHNob3VsZCBpbXBsZW1lbnQgdGhlIGluaXQgbWV0aG9kIHRvIGFjdHVhbGx5IGFkZCB0aGVpciBjdXN0b21cbiAqIG1vZGVsaW5nIGNoZWNrcy4gQ2hlY2tzIG1heSBiZSBhZGRlZCB2aWEgdGhlICNhZGRSdWxlKGFjdGlvbiwgZm4pIG1ldGhvZC5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSdWxlUHJvdmlkZXIoZXZlbnRCdXMpIHtcbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuaW5pdCgpO1xufVxuXG5SdWxlUHJvdmlkZXIuJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdO1xuXG5pbmhlcml0cyhSdWxlUHJvdmlkZXIsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cblxuLyoqXG4gKiBBZGRzIGEgbW9kZWxpbmcgcnVsZSBmb3IgdGhlIGdpdmVuIGFjdGlvbiwgaW1wbGVtZW50ZWQgdGhyb3VnaFxuICogYSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gd2lsbCByZWNlaXZlIHRoZSBtb2RlbGluZyBzcGVjaWZpYyBhY3Rpb24gY29udGV4dFxuICogdG8gcGVyZm9ybSBpdHMgY2hlY2suIEl0IG11c3QgcmV0dXJuIGBmYWxzZWAgdG8gZGlzYWxsb3cgdGhlXG4gKiBhY3Rpb24gZnJvbSBoYXBwZW5pbmcgb3IgYHRydWVgIHRvIGFsbG93IHRoZSBhY3Rpb24uXG4gKlxuICogQSBydWxlIHByb3ZpZGVyIG1heSBwYXNzIG92ZXIgdGhlIGV2YWx1YXRpb24gdG8gbG93ZXIgcHJpb3JpdHlcbiAqIHJ1bGVzIGJ5IHJldHVybmluZyByZXR1cm4gbm90aGluZyAob3IgPGNvZGU+dW5kZWZpbmVkPC9jb2RlPikuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBSZXNpemFibGVSdWxlcy5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge1xuICpcbiAqICAgXFwvKipcbiAqICAgICogUmV0dXJuIGB0cnVlYCwgYGZhbHNlYCBvciBub3RoaW5nIHRvIGRlbm90ZVxuICogICAgKiBfYWxsb3dlZF8sIF9ub3QgYWxsb3dlZF8gYW5kIF9jb250aW51ZSBldmFsdWF0aW5nXy5cbiAqICAgICpcXC9cbiAqICAgdGhpcy5hZGRSdWxlKCdzaGFwZS5yZXNpemUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gKlxuICogICAgIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG4gKlxuICogICAgIGlmICghY29udGV4dC5uZXdCb3VuZHMpIHtcbiAqICAgICAgIC8vIGNoZWNrIGdlbmVyYWwgcmVzaXphYmlsaXR5XG4gKiAgICAgICBpZiAoIXNoYXBlLnJlc2l6YWJsZSkge1xuICogICAgICAgICByZXR1cm4gZmFsc2U7XG4gKiAgICAgICB9XG4gKlxuICogICAgICAgLy8gbm90IHJldHVybmluZyBhbnl0aGluZyAocmVhZDogdW5kZWZpbmVkKVxuICogICAgICAgLy8gd2lsbCBjb250aW51ZSB0aGUgZXZhbHVhdGlvbiBvZiBvdGhlciBydWxlc1xuICogICAgICAgLy8gKHdpdGggbG93ZXIgcHJpb3JpdHkpXG4gKiAgICAgICByZXR1cm47XG4gKiAgICAgfSBlbHNlIHtcbiAqICAgICAgIC8vIGVsZW1lbnQgbXVzdCBoYXZlIG1pbmltdW0gc2l6ZSBvZiAxMCoxMCBwb2ludHNcbiAqICAgICAgIHJldHVybiBjb250ZXh0Lm5ld0JvdW5kcy53aWR0aCA+IDEwICYmIGNvbnRleHQubmV3Qm91bmRzLmhlaWdodCA+IDEwO1xuICogICAgIH1cbiAqICAgfSk7XG4gKiB9O1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfEFycmF5PHN0cmluZz59IGFjdGlvbnMgdGhlIGlkZW50aWZpZXIgZm9yIHRoZSBtb2RlbGluZyBhY3Rpb24gdG8gY2hlY2tcbiAqIEBwYXJhbSB7bnVtYmVyfSBbcHJpb3JpdHldIHRoZSBwcmlvcml0eSBhdCB3aGljaCB0aGlzIHJ1bGUgaXMgYmVpbmcgYXBwbGllZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgdGhlIGFjdHVhbCBjaGVja1xuICovXG5SdWxlUHJvdmlkZXIucHJvdG90eXBlLmFkZFJ1bGUgPSBmdW5jdGlvbihhY3Rpb25zLCBwcmlvcml0eSwgZm4pIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHR5cGVvZiBhY3Rpb25zID09PSAnc3RyaW5nJykge1xuICAgIGFjdGlvbnMgPSBbIGFjdGlvbnMgXTtcbiAgfVxuXG4gIGFjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihhY3Rpb24pIHtcblxuICAgIHNlbGYuY2FuRXhlY3V0ZShhY3Rpb24sIHByaW9yaXR5LCBmdW5jdGlvbihjb250ZXh0LCBhY3Rpb24sIGV2ZW50KSB7XG4gICAgICByZXR1cm4gZm4oY29udGV4dCk7XG4gICAgfSwgdHJ1ZSk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBJbXBsZW1lbnQgdGhpcyBtZXRob2QgdG8gYWRkIG5ldyBydWxlcyBkdXJpbmcgcHJvdmlkZXIgaW5pdGlhbGl6YXRpb24uXG4gKi9cblJ1bGVQcm92aWRlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge307IiwiLyoqXG4gKiBBIHNlcnZpY2UgdGhhdCBwcm92aWRlcyBydWxlcyBmb3IgY2VydGFpbiBkaWFncmFtIGFjdGlvbnMuXG4gKlxuICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd2lsbCBob29rIGludG8gdGhlIHtAbGluayBDb21tYW5kU3RhY2t9XG4gKiB0byBwZXJmb3JtIHRoZSBhY3R1YWwgcnVsZSBldmFsdWF0aW9uLiBNYWtlIHN1cmUgdG8gcHJvdmlkZSB0aGVcbiAqIGBjb21tYW5kU3RhY2tgIHNlcnZpY2Ugd2l0aCB0aGlzIG1vZHVsZSBpZiB5b3UgcGxhbiB0byB1c2UgaXQuXG4gKlxuICogVG9nZXRoZXIgd2l0aCB0aGlzIGltcGxlbWVudGF0aW9uIHlvdSBtYXkgdXNlIHRoZSB7QGxpbmsgUnVsZVByb3ZpZGVyfVxuICogdG8gaW1wbGVtZW50IHlvdXIgb3duIHJ1bGUgY2hlY2tlcnMuXG4gKlxuICogVGhpcyBtb2R1bGUgaXMgbWVudCB0byBiZSBlYXNpbHkgcmVwbGFjZWQsIHRodXMgdGhlIHRpbnkgZm9vdCBwcmludC5cbiAqXG4gKiBAcGFyYW0ge0luamVjdG9yfSBpbmplY3RvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSdWxlcyhpbmplY3Rvcikge1xuICB0aGlzLl9jb21tYW5kU3RhY2sgPSBpbmplY3Rvci5nZXQoJ2NvbW1hbmRTdGFjaycsIGZhbHNlKTtcbn1cblxuUnVsZXMuJGluamVjdCA9IFsgJ2luamVjdG9yJyBdO1xuXG5cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCBhIGdpdmVuIG1vZGVsaW5nIGFjdGlvbiBjYW4gYmUgZXhlY3V0ZWRcbiAqIGluIHRoZSBzcGVjaWZpZWQgY29udGV4dC5cbiAqXG4gKiBUaGlzIGltcGxlbWVudGF0aW9uIHdpbGwgcmVzcG9uZCB3aXRoIGFsbG93IHVubGVzcyBhbnlvbmVcbiAqIG9iamVjdHMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbiB0aGUgYWN0aW9uIHRvIGJlIGNoZWNrZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dF0gdGhlIGNvbnRleHQgdG8gY2hlY2sgdGhlIGFjdGlvbiBpblxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHJldHVybnMgdHJ1ZSwgZmFsc2Ugb3IgbnVsbCBkZXBlbmRpbmcgb24gd2hldGhlciB0aGVcbiAqICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBhbGxvd2VkLCBub3QgYWxsb3dlZCBvciBzaG91bGQgYmUgaWdub3JlZC5cbiAqL1xuUnVsZXMucHJvdG90eXBlLmFsbG93ZWQgPSBmdW5jdGlvbihhY3Rpb24sIGNvbnRleHQpIHtcbiAgdmFyIGFsbG93ZWQgPSB0cnVlO1xuXG4gIHZhciBjb21tYW5kU3RhY2sgPSB0aGlzLl9jb21tYW5kU3RhY2s7XG5cbiAgaWYgKGNvbW1hbmRTdGFjaykge1xuICAgIGFsbG93ZWQgPSBjb21tYW5kU3RhY2suY2FuRXhlY3V0ZShhY3Rpb24sIGNvbnRleHQpO1xuICB9XG5cbiAgLy8gbWFwIHVuZGVmaW5lZCB0byB0cnVlLCBpLmUuIG5vIHJ1bGVzXG4gIHJldHVybiBhbGxvd2VkID09PSB1bmRlZmluZWQgPyB0cnVlIDogYWxsb3dlZDtcbn07IiwiaW1wb3J0IFJ1bGVzIGZyb20gJy4vUnVsZXMnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdydWxlcycgXSxcbiAgcnVsZXM6IFsgJ3R5cGUnLCBSdWxlcyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgY2xlYXIgYXMgZG9tQ2xlYXIsXG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgY2xhc3NlcyBhcyBkb21DbGFzc2VzLFxuICBhdHRyIGFzIGRvbUF0dHIsXG4gIGRvbWlmeSBhcyBkb21pZnlcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIGdldEJCb3ggYXMgZ2V0Qm91bmRpbmdCb3hcbn0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbmltcG9ydCB7XG4gIGVzY2FwZUhUTUxcbn0gZnJvbSAnLi4vLi4vdXRpbC9Fc2NhcGVVdGlsJztcblxuLyoqXG4gKiBQcm92aWRlcyBzZWFyY2hpbmcgaW5mcmFzdHJ1Y3R1cmVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gU2VhcmNoUGFkKGNhbnZhcywgZXZlbnRCdXMsIG92ZXJsYXlzLCBzZWxlY3Rpb24pIHtcbiAgdGhpcy5fb3BlbiA9IGZhbHNlO1xuICB0aGlzLl9yZXN1bHRzID0gW107XG4gIHRoaXMuX2V2ZW50TWFwcyA9IFtdO1xuXG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fb3ZlcmxheXMgPSBvdmVybGF5cztcbiAgdGhpcy5fc2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuXG4gIC8vIHNldHVwIGVsZW1lbnRzXG4gIHRoaXMuX2NvbnRhaW5lciA9IGRvbWlmeShTZWFyY2hQYWQuQk9YX0hUTUwpO1xuICB0aGlzLl9zZWFyY2hJbnB1dCA9IGRvbVF1ZXJ5KFNlYXJjaFBhZC5JTlBVVF9TRUxFQ1RPUiwgdGhpcy5fY29udGFpbmVyKTtcbiAgdGhpcy5fcmVzdWx0c0NvbnRhaW5lciA9IGRvbVF1ZXJ5KFNlYXJjaFBhZC5SRVNVTFRTX0NPTlRBSU5FUl9TRUxFQ1RPUiwgdGhpcy5fY29udGFpbmVyKTtcblxuICAvLyBhdHRhY2ggc2VhcmNoIHBhZFxuICB0aGlzLl9jYW52YXMuZ2V0Q29udGFpbmVyKCkuYXBwZW5kQ2hpbGQodGhpcy5fY29udGFpbmVyKTtcblxuICAvLyBjbGVhbnVwIG9uIGRlc3Ryb3lcbiAgZXZlbnRCdXMub24oWyAnY2FudmFzLmRlc3Ryb3knLCAnZGlhZ3JhbS5kZXN0cm95JyBdLCB0aGlzLmNsb3NlLCB0aGlzKTtcbn1cblxuXG5TZWFyY2hQYWQuJGluamVjdCA9IFtcbiAgJ2NhbnZhcycsXG4gICdldmVudEJ1cycsXG4gICdvdmVybGF5cycsXG4gICdzZWxlY3Rpb24nXG5dO1xuXG5cbi8qKlxuICogQmluZHMgYW5kIGtlZXBzIHRyYWNrIG9mIGFsbCBldmVudCBsaXN0ZXJlbmVyc1xuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLl9iaW5kRXZlbnRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmdW5jdGlvbiBsaXN0ZW4oZWwsIHNlbGVjdG9yLCB0eXBlLCBmbikge1xuICAgIHNlbGYuX2V2ZW50TWFwcy5wdXNoKHtcbiAgICAgIGVsOiBlbCxcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgICBsaXN0ZW5lcjogZG9tRGVsZWdhdGUuYmluZChlbCwgc2VsZWN0b3IsIHR5cGUsIGZuKVxuICAgIH0pO1xuICB9XG5cbiAgLy8gY2xvc2Ugc2VhcmNoIG9uIGNsaWNraW5nIGFueXdoZXJlIG91dHNpZGVcbiAgbGlzdGVuKGRvY3VtZW50LCAnaHRtbCcsICdjbGljaycsIGZ1bmN0aW9uKGUpIHtcbiAgICBzZWxmLmNsb3NlKCk7XG4gIH0pO1xuXG4gIC8vIHN0b3AgZXZlbnQgZnJvbSBwcm9wYWdhdGluZyBhbmQgY2xvc2luZyBzZWFyY2hcbiAgLy8gZm9jdXMgb24gaW5wdXRcbiAgbGlzdGVuKHRoaXMuX2NvbnRhaW5lciwgU2VhcmNoUGFkLklOUFVUX1NFTEVDVE9SLCAnY2xpY2snLCBmdW5jdGlvbihlKSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBlLmRlbGVnYXRlVGFyZ2V0LmZvY3VzKCk7XG4gIH0pO1xuXG4gIC8vIHByZXNlbGVjdCByZXN1bHQgb24gaG92ZXJcbiAgbGlzdGVuKHRoaXMuX2NvbnRhaW5lciwgU2VhcmNoUGFkLlJFU1VMVF9TRUxFQ1RPUiwgJ21vdXNlb3ZlcicsIGZ1bmN0aW9uKGUpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHNlbGYuX3Njcm9sbFRvTm9kZShlLmRlbGVnYXRlVGFyZ2V0KTtcbiAgICBzZWxmLl9wcmVzZWxlY3QoZS5kZWxlZ2F0ZVRhcmdldCk7XG4gIH0pO1xuXG4gIC8vIHNlbGVjdHMgZGVzaXJlZCByZXN1bHQgb24gbW91c2UgY2xpY2tcbiAgbGlzdGVuKHRoaXMuX2NvbnRhaW5lciwgU2VhcmNoUGFkLlJFU1VMVF9TRUxFQ1RPUiwgJ2NsaWNrJywgZnVuY3Rpb24oZSkge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgc2VsZi5fc2VsZWN0KGUuZGVsZWdhdGVUYXJnZXQpO1xuICB9KTtcblxuICAvLyBwcmV2ZW50IGN1cnNvciBpbiBpbnB1dCBmcm9tIGdvaW5nIGxlZnQgYW5kIHJpZ2h0IHdoZW4gdXNpbmcgdXAvZG93biB0b1xuICAvLyBuYXZpZ2F0ZSByZXN1bHRzXG4gIGxpc3Rlbih0aGlzLl9jb250YWluZXIsIFNlYXJjaFBhZC5JTlBVVF9TRUxFQ1RPUiwgJ2tleWRvd24nLCBmdW5jdGlvbihlKSB7XG5cbiAgICAvLyB1cFxuICAgIGlmIChlLmtleUNvZGUgPT09IDM4KSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgLy8gZG93blxuICAgIGlmIChlLmtleUNvZGUgPT09IDQwKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBoYW5kbGUga2V5Ym9hcmQgaW5wdXRcbiAgbGlzdGVuKHRoaXMuX2NvbnRhaW5lciwgU2VhcmNoUGFkLklOUFVUX1NFTEVDVE9SLCAna2V5dXAnLCBmdW5jdGlvbihlKSB7XG5cbiAgICAvLyBlc2NhcGVcbiAgICBpZiAoZS5rZXlDb2RlID09PSAyNykge1xuICAgICAgcmV0dXJuIHNlbGYuY2xvc2UoKTtcbiAgICB9XG5cbiAgICAvLyBlbnRlclxuICAgIGlmIChlLmtleUNvZGUgPT09IDEzKSB7XG4gICAgICB2YXIgc2VsZWN0ZWQgPSBzZWxmLl9nZXRDdXJyZW50UmVzdWx0KCk7XG5cbiAgICAgIHJldHVybiBzZWxlY3RlZCA/IHNlbGYuX3NlbGVjdChzZWxlY3RlZCkgOiBzZWxmLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgLy8gdXBcbiAgICBpZiAoZS5rZXlDb2RlID09PSAzOCkge1xuICAgICAgcmV0dXJuIHNlbGYuX3Njcm9sbFRvRGlyZWN0aW9uKHRydWUpO1xuICAgIH1cblxuICAgIC8vIGRvd25cbiAgICBpZiAoZS5rZXlDb2RlID09PSA0MCkge1xuICAgICAgcmV0dXJuIHNlbGYuX3Njcm9sbFRvRGlyZWN0aW9uKCk7XG4gICAgfVxuXG4gICAgLy8gbGVmdCAmJiByaWdodFxuICAgIC8vIGRvIG5vdCBzZWFyY2ggd2hpbGUgbmF2aWdhdGluZyB0ZXh0IGlucHV0XG4gICAgaWYgKGUua2V5Q29kZSA9PT0gMzcgfHwgZS5rZXlDb2RlID09PSAzOSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGFueXRoaW5nIGVsc2VcbiAgICBzZWxmLl9zZWFyY2goZS5kZWxlZ2F0ZVRhcmdldC52YWx1ZSk7XG4gIH0pO1xufTtcblxuXG4vKipcbiAqIFVuYmluZHMgYWxsIHByZXZpb3VzbHkgZXN0YWJsaXNoZWQgbGlzdGVuZXJzXG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuX3VuYmluZEV2ZW50cyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9ldmVudE1hcHMuZm9yRWFjaChmdW5jdGlvbihtKSB7XG4gICAgZG9tRGVsZWdhdGUudW5iaW5kKG0uZWwsIG0udHlwZSwgbS5saXN0ZW5lcik7XG4gIH0pO1xufTtcblxuXG4vKipcbiAqIFBlcmZvcm1zIGEgc2VhcmNoIGZvciB0aGUgZ2l2ZW4gcGF0dGVybi5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHBhdHRlcm5cbiAqL1xuU2VhcmNoUGFkLnByb3RvdHlwZS5fc2VhcmNoID0gZnVuY3Rpb24ocGF0dGVybikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5fY2xlYXJSZXN1bHRzKCk7XG5cbiAgLy8gZG8gbm90IHNlYXJjaCBvbiBlbXB0eSBxdWVyeVxuICBpZiAoIXBhdHRlcm4gfHwgcGF0dGVybiA9PT0gJycpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgc2VhcmNoUmVzdWx0cyA9IHRoaXMuX3NlYXJjaFByb3ZpZGVyLmZpbmQocGF0dGVybik7XG5cbiAgaWYgKCFzZWFyY2hSZXN1bHRzLmxlbmd0aCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGFwcGVuZCBuZXcgcmVzdWx0c1xuICBzZWFyY2hSZXN1bHRzLmZvckVhY2goZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgdmFyIGlkID0gcmVzdWx0LmVsZW1lbnQuaWQ7XG4gICAgdmFyIG5vZGUgPSBzZWxmLl9jcmVhdGVSZXN1bHROb2RlKHJlc3VsdCwgaWQpO1xuICAgIHNlbGYuX3Jlc3VsdHNbaWRdID0ge1xuICAgICAgZWxlbWVudDogcmVzdWx0LmVsZW1lbnQsXG4gICAgICBub2RlOiBub2RlXG4gICAgfTtcbiAgfSk7XG5cbiAgLy8gcHJlc2VsZWN0IGZpcnN0IHJlc3VsdFxuICB2YXIgbm9kZSA9IGRvbVF1ZXJ5KFNlYXJjaFBhZC5SRVNVTFRfU0VMRUNUT1IsIHRoaXMuX3Jlc3VsdHNDb250YWluZXIpO1xuICB0aGlzLl9zY3JvbGxUb05vZGUobm9kZSk7XG4gIHRoaXMuX3ByZXNlbGVjdChub2RlKTtcbn07XG5cblxuLyoqXG4gKiBOYXZpZ2F0ZSB0byB0aGUgcHJldmlvdXMvbmV4dCByZXN1bHQuIERlZmF1bHRzIHRvIG5leHQgcmVzdWx0LlxuICogQHBhcmFtICB7Ym9vbGVhbn0gcHJldmlvdXNcbiAqL1xuU2VhcmNoUGFkLnByb3RvdHlwZS5fc2Nyb2xsVG9EaXJlY3Rpb24gPSBmdW5jdGlvbihwcmV2aW91cykge1xuICB2YXIgc2VsZWN0ZWQgPSB0aGlzLl9nZXRDdXJyZW50UmVzdWx0KCk7XG4gIGlmICghc2VsZWN0ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbm9kZSA9IHByZXZpb3VzID8gc2VsZWN0ZWQucHJldmlvdXNFbGVtZW50U2libGluZyA6IHNlbGVjdGVkLm5leHRFbGVtZW50U2libGluZztcbiAgaWYgKG5vZGUpIHtcbiAgICB0aGlzLl9zY3JvbGxUb05vZGUobm9kZSk7XG4gICAgdGhpcy5fcHJlc2VsZWN0KG5vZGUpO1xuICB9XG59O1xuXG5cbi8qKlxuICogU2Nyb2xsIHRvIHRoZSBub2RlIGlmIGl0IGlzIG5vdCB2aXNpYmxlLlxuICpcbiAqIEBwYXJhbSAge0VsZW1lbnR9IG5vZGVcbiAqL1xuU2VhcmNoUGFkLnByb3RvdHlwZS5fc2Nyb2xsVG9Ob2RlID0gZnVuY3Rpb24obm9kZSkge1xuICBpZiAoIW5vZGUgfHwgbm9kZSA9PT0gdGhpcy5fZ2V0Q3VycmVudFJlc3VsdCgpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG5vZGVPZmZzZXQgPSBub2RlLm9mZnNldFRvcDtcbiAgdmFyIGNvbnRhaW5lclNjcm9sbCA9IHRoaXMuX3Jlc3VsdHNDb250YWluZXIuc2Nyb2xsVG9wO1xuXG4gIHZhciBib3R0b21TY3JvbGwgPSBub2RlT2Zmc2V0IC0gdGhpcy5fcmVzdWx0c0NvbnRhaW5lci5jbGllbnRIZWlnaHQgKyBub2RlLmNsaWVudEhlaWdodDtcblxuICBpZiAobm9kZU9mZnNldCA8IGNvbnRhaW5lclNjcm9sbCkge1xuICAgIHRoaXMuX3Jlc3VsdHNDb250YWluZXIuc2Nyb2xsVG9wID0gbm9kZU9mZnNldDtcbiAgfSBlbHNlIGlmIChjb250YWluZXJTY3JvbGwgPCBib3R0b21TY3JvbGwpIHtcbiAgICB0aGlzLl9yZXN1bHRzQ29udGFpbmVyLnNjcm9sbFRvcCA9IGJvdHRvbVNjcm9sbDtcbiAgfVxufTtcblxuXG4vKipcbiAqIENsZWFycyBhbGwgcmVzdWx0cyBkYXRhLlxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLl9jbGVhclJlc3VsdHMgPSBmdW5jdGlvbigpIHtcbiAgZG9tQ2xlYXIodGhpcy5fcmVzdWx0c0NvbnRhaW5lcik7XG5cbiAgdGhpcy5fcmVzdWx0cyA9IFtdO1xuXG4gIHRoaXMuX3Jlc2V0T3ZlcmxheSgpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5jbGVhcmVkJyk7XG59O1xuXG5cbi8qKlxuICogR2V0IGN1cnJlbnRseSBzZWxlY3RlZCByZXN1bHQuXG4gKlxuICogQHJldHVybiB7RWxlbWVudH1cbiAqL1xuU2VhcmNoUGFkLnByb3RvdHlwZS5fZ2V0Q3VycmVudFJlc3VsdCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gZG9tUXVlcnkoU2VhcmNoUGFkLlJFU1VMVF9TRUxFQ1RFRF9TRUxFQ1RPUiwgdGhpcy5fcmVzdWx0c0NvbnRhaW5lcik7XG59O1xuXG5cbi8qKlxuICogQ3JlYXRlIHJlc3VsdCBET00gZWxlbWVudCB3aXRoaW4gcmVzdWx0cyBjb250YWluZXJcbiAqIHRoYXQgY29ycmVzcG9uZHMgdG8gYSBzZWFyY2ggcmVzdWx0LlxuICpcbiAqICdyZXN1bHQnIDogb25lIG9mIHRoZSBlbGVtZW50cyByZXR1cm5lZCBieSBTZWFyY2hQcm92aWRlclxuICogJ2lkJyA6IGlkIGF0dHJpYnV0ZSB2YWx1ZSB0byBhc3NpZ24gdG8gdGhlIG5ldyBET00gbm9kZVxuICogcmV0dXJuIDogY3JlYXRlZCBET00gZWxlbWVudFxuICpcbiAqIEBwYXJhbSAge1NlYXJjaFJlc3VsdH0gcmVzdWx0XG4gKiBAcGFyYW0gIHtzdHJpbmd9IGlkXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLl9jcmVhdGVSZXN1bHROb2RlID0gZnVuY3Rpb24ocmVzdWx0LCBpZCkge1xuICB2YXIgbm9kZSA9IGRvbWlmeShTZWFyY2hQYWQuUkVTVUxUX0hUTUwpO1xuXG4gIC8vIGNyZWF0ZSBvbmx5IGlmIGF2YWlsYWJsZVxuICBpZiAocmVzdWx0LnByaW1hcnlUb2tlbnMubGVuZ3RoID4gMCkge1xuICAgIGNyZWF0ZUlubmVyVGV4dE5vZGUobm9kZSwgcmVzdWx0LnByaW1hcnlUb2tlbnMsIFNlYXJjaFBhZC5SRVNVTFRfUFJJTUFSWV9IVE1MKTtcbiAgfVxuXG4gIC8vIHNlY29uZGFyeSB0b2tlbnMgKHJlcHJlc2VudCBlbGVtZW50IElEKSBhcmUgYWxsd2F5cyBhdmFpbGFibGVcbiAgY3JlYXRlSW5uZXJUZXh0Tm9kZShub2RlLCByZXN1bHQuc2Vjb25kYXJ5VG9rZW5zLCBTZWFyY2hQYWQuUkVTVUxUX1NFQ09OREFSWV9IVE1MKTtcblxuICBkb21BdHRyKG5vZGUsIFNlYXJjaFBhZC5SRVNVTFRfSURfQVRUUklCVVRFLCBpZCk7XG5cbiAgdGhpcy5fcmVzdWx0c0NvbnRhaW5lci5hcHBlbmRDaGlsZChub2RlKTtcblxuICByZXR1cm4gbm9kZTtcbn07XG5cblxuLyoqXG4gKiBSZWdpc3RlciBzZWFyY2ggZWxlbWVudCBwcm92aWRlci5cbiAqXG4gKiBTZWFyY2hQcm92aWRlci5maW5kIC0gcHJvdmlkZXMgc2VhcmNoIGZ1bmN0aW9uIG92ZXIgb3duIGVsZW1lbnRzXG4gKiAgKHBhdHRlcm4pID0+IFt7IHRleHQ6IDxTdHJpbmc+LCBlbGVtZW50OiA8RWxlbWVudD59LCAuLi5dXG4gKlxuICogQHBhcmFtICB7U2VhcmNoUHJvdmlkZXJ9IHByb3ZpZGVyXG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUucmVnaXN0ZXJQcm92aWRlciA9IGZ1bmN0aW9uKHByb3ZpZGVyKSB7XG4gIHRoaXMuX3NlYXJjaFByb3ZpZGVyID0gcHJvdmlkZXI7XG59O1xuXG5cbi8qKlxuICogT3BlbiBzZWFyY2ggcGFkLlxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLl9zZWFyY2hQcm92aWRlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignbm8gc2VhcmNoIHByb3ZpZGVyIHJlZ2lzdGVyZWQnKTtcbiAgfVxuXG4gIGlmICh0aGlzLmlzT3BlbigpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fYmluZEV2ZW50cygpO1xuXG4gIHRoaXMuX29wZW4gPSB0cnVlO1xuXG4gIGRvbUNsYXNzZXModGhpcy5fY29udGFpbmVyKS5hZGQoJ29wZW4nKTtcblxuICB0aGlzLl9zZWFyY2hJbnB1dC5mb2N1cygpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5vcGVuZWQnKTtcbn07XG5cblxuLyoqXG4gKiBDbG9zZSBzZWFyY2ggcGFkLlxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5pc09wZW4oKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRoaXMuX3VuYmluZEV2ZW50cygpO1xuXG4gIHRoaXMuX29wZW4gPSBmYWxzZTtcblxuICBkb21DbGFzc2VzKHRoaXMuX2NvbnRhaW5lcikucmVtb3ZlKCdvcGVuJyk7XG5cbiAgdGhpcy5fY2xlYXJSZXN1bHRzKCk7XG5cbiAgdGhpcy5fc2VhcmNoSW5wdXQudmFsdWUgPSAnJztcbiAgdGhpcy5fc2VhcmNoSW5wdXQuYmx1cigpO1xuXG4gIHRoaXMuX3Jlc2V0T3ZlcmxheSgpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5jbG9zZWQnKTtcbn07XG5cblxuLyoqXG4gKiBUb2dnbGVzIHNlYXJjaCBwYWQgb24vb2ZmLlxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmlzT3BlbigpID8gdGhpcy5jbG9zZSgpIDogdGhpcy5vcGVuKCk7XG59O1xuXG5cbi8qKlxuICogUmVwb3J0IHN0YXRlIG9mIHNlYXJjaCBwYWQuXG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuaXNPcGVuID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9vcGVuO1xufTtcblxuXG4vKipcbiAqIFByZXNlbGVjdCByZXN1bHQgZW50cnkuXG4gKlxuICogQHBhcmFtICB7RWxlbWVudH0gZWxlbWVudFxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLl9wcmVzZWxlY3QgPSBmdW5jdGlvbihub2RlKSB7XG4gIHZhciBzZWxlY3RlZE5vZGUgPSB0aGlzLl9nZXRDdXJyZW50UmVzdWx0KCk7XG5cbiAgLy8gYWxyZWFkeSBzZWxlY3RlZFxuICBpZiAobm9kZSA9PT0gc2VsZWN0ZWROb2RlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gcmVtb3ZpbmcgcHJlc2VsZWN0aW9uIGZyb20gY3VycmVudCBub2RlXG4gIGlmIChzZWxlY3RlZE5vZGUpIHtcbiAgICBkb21DbGFzc2VzKHNlbGVjdGVkTm9kZSkucmVtb3ZlKFNlYXJjaFBhZC5SRVNVTFRfU0VMRUNURURfQ0xBU1MpO1xuICB9XG5cbiAgdmFyIGlkID0gZG9tQXR0cihub2RlLCBTZWFyY2hQYWQuUkVTVUxUX0lEX0FUVFJJQlVURSk7XG4gIHZhciBlbGVtZW50ID0gdGhpcy5fcmVzdWx0c1tpZF0uZWxlbWVudDtcblxuICBkb21DbGFzc2VzKG5vZGUpLmFkZChTZWFyY2hQYWQuUkVTVUxUX1NFTEVDVEVEX0NMQVNTKTtcblxuICB0aGlzLl9yZXNldE92ZXJsYXkoZWxlbWVudCk7XG5cbiAgdGhpcy5fY2VudGVyVmlld2JveChlbGVtZW50KTtcblxuICB0aGlzLl9zZWxlY3Rpb24uc2VsZWN0KGVsZW1lbnQpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5wcmVzZWxlY3RlZCcsIGVsZW1lbnQpO1xufTtcblxuXG4vKipcbiAqIFNlbGVjdCByZXN1bHQgbm9kZS5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBlbGVtZW50XG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuX3NlbGVjdCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgdmFyIGlkID0gZG9tQXR0cihub2RlLCBTZWFyY2hQYWQuUkVTVUxUX0lEX0FUVFJJQlVURSk7XG4gIHZhciBlbGVtZW50ID0gdGhpcy5fcmVzdWx0c1tpZF0uZWxlbWVudDtcblxuICB0aGlzLmNsb3NlKCk7XG5cbiAgdGhpcy5fcmVzZXRPdmVybGF5KCk7XG5cbiAgdGhpcy5fY2VudGVyVmlld2JveChlbGVtZW50KTtcblxuICB0aGlzLl9zZWxlY3Rpb24uc2VsZWN0KGVsZW1lbnQpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5zZWxlY3RlZCcsIGVsZW1lbnQpO1xufTtcblxuXG4vKipcbiAqIENlbnRlciB2aWV3Ym94IG9uIHRoZSBlbGVtZW50IG1pZGRsZSBwb2ludC5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBlbGVtZW50XG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuX2NlbnRlclZpZXdib3ggPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciB2aWV3Ym94ID0gdGhpcy5fY2FudmFzLnZpZXdib3goKTtcblxuICB2YXIgYm94ID0gZ2V0Qm91bmRpbmdCb3goZWxlbWVudCk7XG5cbiAgdmFyIG5ld1ZpZXdib3ggPSB7XG4gICAgeDogKGJveC54ICsgYm94LndpZHRoLzIpIC0gdmlld2JveC5vdXRlci53aWR0aC8yLFxuICAgIHk6IChib3gueSArIGJveC5oZWlnaHQvMikgLSB2aWV3Ym94Lm91dGVyLmhlaWdodC8yLFxuICAgIHdpZHRoOiB2aWV3Ym94Lm91dGVyLndpZHRoLFxuICAgIGhlaWdodDogdmlld2JveC5vdXRlci5oZWlnaHRcbiAgfTtcblxuICB0aGlzLl9jYW52YXMudmlld2JveChuZXdWaWV3Ym94KTtcblxuICB0aGlzLl9jYW52YXMuem9vbSh2aWV3Ym94LnNjYWxlKTtcbn07XG5cblxuLyoqXG4gKiBSZXNldCBvdmVybGF5IHJlbW92ZXMgYW5kLCBvcHRpb25hbGx5LCBzZXRcbiAqIG92ZXJsYXkgdG8gYSBuZXcgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBlbGVtZW50XG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuX3Jlc2V0T3ZlcmxheSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgaWYgKHRoaXMuX292ZXJsYXlJZCkge1xuICAgIHRoaXMuX292ZXJsYXlzLnJlbW92ZSh0aGlzLl9vdmVybGF5SWQpO1xuICB9XG5cbiAgaWYgKGVsZW1lbnQpIHtcbiAgICB2YXIgYm94ID0gZ2V0Qm91bmRpbmdCb3goZWxlbWVudCk7XG4gICAgdmFyIG92ZXJsYXkgPSBjb25zdHJ1Y3RPdmVybGF5KGJveCk7XG4gICAgdGhpcy5fb3ZlcmxheUlkID0gdGhpcy5fb3ZlcmxheXMuYWRkKGVsZW1lbnQsIG92ZXJsYXkpO1xuICB9XG59O1xuXG5cbi8qKlxuICogQ29uc3RydWN0IG92ZXJsYXkgb2JqZWN0IGZvciB0aGUgZ2l2ZW4gYm91bmRpbmcgYm94LlxuICpcbiAqIEBwYXJhbSAge0JvdW5kaW5nQm94fSBib3hcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gY29uc3RydWN0T3ZlcmxheShib3gpIHtcblxuICB2YXIgb2Zmc2V0ID0gNjtcbiAgdmFyIHcgPSBib3gud2lkdGggKyBvZmZzZXQgKiAyO1xuICB2YXIgaCA9IGJveC5oZWlnaHQgKyBvZmZzZXQgKiAyO1xuXG4gIHZhciBzdHlsZXMgPSBbXG4gICAgJ3dpZHRoOiAnKyB3ICsncHgnLFxuICAgICdoZWlnaHQ6ICcrIGggKyAncHgnXG4gIF0uam9pbignOyAnKTtcblxuICByZXR1cm4ge1xuICAgIHBvc2l0aW9uOiB7XG4gICAgICBib3R0b206IGggLSBvZmZzZXQsXG4gICAgICByaWdodDogdyAtIG9mZnNldFxuICAgIH0sXG4gICAgc2hvdzogdHJ1ZSxcbiAgICBodG1sOiAnPGRpdiBzdHlsZT1cIicgKyBzdHlsZXMgKyAnXCIgY2xhc3M9XCInICsgU2VhcmNoUGFkLk9WRVJMQVlfQ0xBU1MgKyAnXCI+PC9kaXY+J1xuICB9O1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhbmQgYXBwZW5kcyBjaGlsZCBub2RlIGZyb20gcmVzdWx0IHRva2VucyBhbmQgSFRNTCB0ZW1wbGF0ZS5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBub2RlXG4gKiBAcGFyYW0gIHtBcnJheTxPYmplY3Q+fSB0b2tlbnNcbiAqIEBwYXJhbSAge3N0cmluZ30gdGVtcGxhdGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5uZXJUZXh0Tm9kZShwYXJlbnROb2RlLCB0b2tlbnMsIHRlbXBsYXRlKSB7XG4gIHZhciB0ZXh0ID0gY3JlYXRlSHRtbFRleHQodG9rZW5zKTtcbiAgdmFyIGNoaWxkTm9kZSA9IGRvbWlmeSh0ZW1wbGF0ZSk7XG4gIGNoaWxkTm9kZS5pbm5lckhUTUwgPSB0ZXh0O1xuICBwYXJlbnROb2RlLmFwcGVuZENoaWxkKGNoaWxkTm9kZSk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGludGVybmFsIEhUTUwgbWFya3VwIGZyb20gcmVzdWx0IHRva2Vucy5cbiAqIENhdGVycyBmb3IgaGlnaGxpZ2h0aW5nIHBhdHRlcm4gbWF0Y2hlZCB0b2tlbnMuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8T2JqZWN0Pn0gdG9rZW5zXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUh0bWxUZXh0KHRva2Vucykge1xuICB2YXIgaHRtbFRleHQgPSAnJztcblxuICB0b2tlbnMuZm9yRWFjaChmdW5jdGlvbih0KSB7XG4gICAgaWYgKHQubWF0Y2hlZCkge1xuICAgICAgaHRtbFRleHQgKz0gJzxzdHJvbmcgY2xhc3M9XCInICsgU2VhcmNoUGFkLlJFU1VMVF9ISUdITElHSFRfQ0xBU1MgKyAnXCI+JyArIGVzY2FwZUhUTUwodC5tYXRjaGVkKSArICc8L3N0cm9uZz4nO1xuICAgIH0gZWxzZSB7XG4gICAgICBodG1sVGV4dCArPSBlc2NhcGVIVE1MKHQubm9ybWFsKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBodG1sVGV4dCAhPT0gJycgPyBodG1sVGV4dCA6IG51bGw7XG59XG5cblxuLyoqXG4gKiBDT05TVEFOVFNcbiAqL1xuU2VhcmNoUGFkLkNPTlRBSU5FUl9TRUxFQ1RPUiA9ICcuZGpzLXNlYXJjaC1jb250YWluZXInO1xuU2VhcmNoUGFkLklOUFVUX1NFTEVDVE9SID0gJy5kanMtc2VhcmNoLWlucHV0IGlucHV0JztcblNlYXJjaFBhZC5SRVNVTFRTX0NPTlRBSU5FUl9TRUxFQ1RPUiA9ICcuZGpzLXNlYXJjaC1yZXN1bHRzJztcblNlYXJjaFBhZC5SRVNVTFRfU0VMRUNUT1IgPSAnLmRqcy1zZWFyY2gtcmVzdWx0JztcblNlYXJjaFBhZC5SRVNVTFRfU0VMRUNURURfQ0xBU1MgPSAnZGpzLXNlYXJjaC1yZXN1bHQtc2VsZWN0ZWQnO1xuU2VhcmNoUGFkLlJFU1VMVF9TRUxFQ1RFRF9TRUxFQ1RPUiA9ICcuJyArIFNlYXJjaFBhZC5SRVNVTFRfU0VMRUNURURfQ0xBU1M7XG5TZWFyY2hQYWQuUkVTVUxUX0lEX0FUVFJJQlVURSA9ICdkYXRhLXJlc3VsdC1pZCc7XG5TZWFyY2hQYWQuUkVTVUxUX0hJR0hMSUdIVF9DTEFTUyA9ICdkanMtc2VhcmNoLWhpZ2hsaWdodCc7XG5TZWFyY2hQYWQuT1ZFUkxBWV9DTEFTUyA9ICdkanMtc2VhcmNoLW92ZXJsYXknO1xuXG5TZWFyY2hQYWQuQk9YX0hUTUwgPVxuICAnPGRpdiBjbGFzcz1cImRqcy1zZWFyY2gtY29udGFpbmVyIGRqcy1kcmFnZ2FibGUgZGpzLXNjcm9sbGFibGVcIj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImRqcy1zZWFyY2gtaW5wdXRcIj4nICtcbiAgICAgICc8aW5wdXQgdHlwZT1cInRleHRcIi8+JyArXG4gICAgJzwvZGl2PicgK1xuICAgICc8ZGl2IGNsYXNzPVwiZGpzLXNlYXJjaC1yZXN1bHRzXCI+PC9kaXY+JyArXG4gICc8L2Rpdj4nO1xuXG5TZWFyY2hQYWQuUkVTVUxUX0hUTUwgPVxuICAnPGRpdiBjbGFzcz1cImRqcy1zZWFyY2gtcmVzdWx0XCI+PC9kaXY+JztcblxuU2VhcmNoUGFkLlJFU1VMVF9QUklNQVJZX0hUTUwgPVxuICAnPGRpdiBjbGFzcz1cImRqcy1zZWFyY2gtcmVzdWx0LXByaW1hcnlcIj48L2Rpdj4nO1xuXG5TZWFyY2hQYWQuUkVTVUxUX1NFQ09OREFSWV9IVE1MID1cbiAgJzxwIGNsYXNzPVwiZGpzLXNlYXJjaC1yZXN1bHQtc2Vjb25kYXJ5XCI+PC9wPic7XG4iLCJpbXBvcnQgT3ZlcmxheXNNb2R1bGUgZnJvbSAnLi4vb3ZlcmxheXMnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuXG5pbXBvcnQgU2VhcmNoUGFkIGZyb20gJy4vU2VhcmNoUGFkJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIE92ZXJsYXlzTW9kdWxlLFxuICAgIFNlbGVjdGlvbk1vZHVsZVxuICBdLFxuICBzZWFyY2hQYWQ6IFsgJ3R5cGUnLCBTZWFyY2hQYWQgXVxufTtcbiIsImltcG9ydCB7XG4gIGlzQXJyYXksXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5cbi8qKlxuICogQSBzZXJ2aWNlIHRoYXQgb2ZmZXJzIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpbiBhIGRpYWdyYW0uXG4gKiBPZmZlcnMgdGhlIGFwaSB0byBjb250cm9sIHRoZSBzZWxlY3Rpb24sIHRvby5cbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1cyB0aGUgZXZlbnQgYnVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNlbGVjdGlvbihldmVudEJ1cykge1xuXG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG5cbiAgdGhpcy5fc2VsZWN0ZWRFbGVtZW50cyA9IFtdO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbihbICdzaGFwZS5yZW1vdmUnLCAnY29ubmVjdGlvbi5yZW1vdmUnIF0sIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbWVudCA9IGUuZWxlbWVudDtcbiAgICBzZWxmLmRlc2VsZWN0KGVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdkaWFncmFtLmNsZWFyJyBdLCBmdW5jdGlvbihlKSB7XG4gICAgc2VsZi5zZWxlY3QobnVsbCk7XG4gIH0pO1xufVxuXG5TZWxlY3Rpb24uJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdO1xuXG5cblNlbGVjdGlvbi5wcm90b3R5cGUuZGVzZWxlY3QgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciBzZWxlY3RlZEVsZW1lbnRzID0gdGhpcy5fc2VsZWN0ZWRFbGVtZW50cztcblxuICB2YXIgaWR4ID0gc2VsZWN0ZWRFbGVtZW50cy5pbmRleE9mKGVsZW1lbnQpO1xuXG4gIGlmIChpZHggIT09IC0xKSB7XG4gICAgdmFyIG9sZFNlbGVjdGlvbiA9IHNlbGVjdGVkRWxlbWVudHMuc2xpY2UoKTtcblxuICAgIHNlbGVjdGVkRWxlbWVudHMuc3BsaWNlKGlkeCwgMSk7XG5cbiAgICB0aGlzLl9ldmVudEJ1cy5maXJlKCdzZWxlY3Rpb24uY2hhbmdlZCcsIHsgb2xkU2VsZWN0aW9uOiBvbGRTZWxlY3Rpb24sIG5ld1NlbGVjdGlvbjogc2VsZWN0ZWRFbGVtZW50cyB9KTtcbiAgfVxufTtcblxuXG5TZWxlY3Rpb24ucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRFbGVtZW50cztcbn07XG5cblNlbGVjdGlvbi5wcm90b3R5cGUuaXNTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkRWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTE7XG59O1xuXG5cbi8qKlxuICogVGhpcyBtZXRob2Qgc2VsZWN0cyBvbmUgb3IgbW9yZSBlbGVtZW50cyBvbiB0aGUgZGlhZ3JhbS5cbiAqXG4gKiBCeSBwYXNzaW5nIGFuIGFkZGl0aW9uYWwgYWRkIHBhcmFtZXRlciB5b3UgY2FuIGRlY2lkZSB3aGV0aGVyIG9yIG5vdCB0aGUgZWxlbWVudChzKVxuICogc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSBhbHJlYWR5IGV4aXN0aW5nIHNlbGVjdGlvbiBvciBub3QuXG4gKlxuICogQG1ldGhvZCBTZWxlY3Rpb24jc2VsZWN0XG4gKlxuICogQHBhcmFtICB7T2JqZWN0fE9iamVjdFtdfSBlbGVtZW50cyBlbGVtZW50IG9yIGFycmF5IG9mIGVsZW1lbnRzIHRvIGJlIHNlbGVjdGVkXG4gKiBAcGFyYW0gIHtib29sZWFufSBbYWRkXSB3aGV0aGVyIHRoZSBlbGVtZW50KHMpIHNob3VsZCBiZSBhcHBlbmRlZCB0byB0aGUgY3VycmVudCBzZWxlY3Rpb24sIGRlZmF1bHRzIHRvIGZhbHNlXG4gKi9cblNlbGVjdGlvbi5wcm90b3R5cGUuc2VsZWN0ID0gZnVuY3Rpb24oZWxlbWVudHMsIGFkZCkge1xuICB2YXIgc2VsZWN0ZWRFbGVtZW50cyA9IHRoaXMuX3NlbGVjdGVkRWxlbWVudHMsXG4gICAgICBvbGRTZWxlY3Rpb24gPSBzZWxlY3RlZEVsZW1lbnRzLnNsaWNlKCk7XG5cbiAgaWYgKCFpc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gZWxlbWVudHMgPyBbIGVsZW1lbnRzIF0gOiBbXTtcbiAgfVxuXG4gIC8vIHNlbGVjdGlvbiBtYXkgYmUgY2xlYXJlZCBieSBwYXNzaW5nIGFuIGVtcHR5IGFycmF5IG9yIG51bGxcbiAgLy8gdG8gdGhlIG1ldGhvZFxuICBpZiAoYWRkKSB7XG4gICAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTEpIHtcblxuICAgICAgICAvLyBhbHJlYWR5IHNlbGVjdGVkXG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9zZWxlY3RlZEVsZW1lbnRzID0gc2VsZWN0ZWRFbGVtZW50cyA9IGVsZW1lbnRzLnNsaWNlKCk7XG4gIH1cblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdzZWxlY3Rpb24uY2hhbmdlZCcsIHsgb2xkU2VsZWN0aW9uOiBvbGRTZWxlY3Rpb24sIG5ld1NlbGVjdGlvbjogc2VsZWN0ZWRFbGVtZW50cyB9KTtcbn07XG4iLCJpbXBvcnQge1xuICBoYXNQcmltYXJ5TW9kaWZpZXIsXG4gIGhhc1NlY29uZGFyeU1vZGlmaWVyXG59IGZyb20gJy4uLy4uL3V0aWwvTW91c2UnO1xuXG5pbXBvcnQge1xuICBmaW5kLFxuICBpc0FycmF5XG59IGZyb20gJ21pbi1kYXNoJztcblxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBTZWxlY3Rpb25CZWhhdmlvcihldmVudEJ1cywgc2VsZWN0aW9uLCBjYW52YXMsIGVsZW1lbnRSZWdpc3RyeSkge1xuXG4gIC8vIFNlbGVjdCBlbGVtZW50cyBvbiBjcmVhdGVcbiAgZXZlbnRCdXMub24oJ2NyZWF0ZS5lbmQnLCA1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fSxcbiAgICAgICAgYXV0b1NlbGVjdCA9IGhpbnRzLmF1dG9TZWxlY3Q7XG5cbiAgICBpZiAoY2FuRXhlY3V0ZSkge1xuICAgICAgaWYgKGF1dG9TZWxlY3QgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgLy8gU2VsZWN0IG5vIGVsZW1lbnRzXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXkoYXV0b1NlbGVjdCkpIHtcbiAgICAgICAgc2VsZWN0aW9uLnNlbGVjdChhdXRvU2VsZWN0KTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gU2VsZWN0IGFsbCBlbGVtZW50cyBieSBkZWZhdWx0XG4gICAgICAgIHNlbGVjdGlvbi5zZWxlY3QoZWxlbWVudHMuZmlsdGVyKGlzU2hvd24pKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIFNlbGVjdCBjb25uZWN0aW9uIHRhcmdldHMgb24gY29ubmVjdFxuICBldmVudEJ1cy5vbignY29ubmVjdC5lbmQnLCA1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBob3ZlciA9IGNvbnRleHQuaG92ZXI7XG5cbiAgICBpZiAoY2FuRXhlY3V0ZSAmJiBob3Zlcikge1xuICAgICAgc2VsZWN0aW9uLnNlbGVjdChob3Zlcik7XG4gICAgfVxuICB9KTtcblxuICAvLyBTZWxlY3Qgc2hhcGVzIG9uIG1vdmVcbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUuZW5kJywgNTAwLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBwcmV2aW91c1NlbGVjdGlvbiA9IGV2ZW50LnByZXZpb3VzU2VsZWN0aW9uIHx8IFtdO1xuXG4gICAgdmFyIHNoYXBlID0gZWxlbWVudFJlZ2lzdHJ5LmdldChldmVudC5jb250ZXh0LnNoYXBlLmlkKTtcblxuICAgIC8vIEFsd2F5cyBzZWxlY3QgbWFpbiBzaGFwZSBvbiBtb3ZlXG4gICAgdmFyIGlzU2VsZWN0ZWQgPSBmaW5kKHByZXZpb3VzU2VsZWN0aW9uLCBmdW5jdGlvbihzZWxlY3RlZFNoYXBlKSB7XG4gICAgICByZXR1cm4gc2hhcGUuaWQgPT09IHNlbGVjdGVkU2hhcGUuaWQ7XG4gICAgfSk7XG5cbiAgICBpZiAoIWlzU2VsZWN0ZWQpIHtcbiAgICAgIHNlbGVjdGlvbi5zZWxlY3Qoc2hhcGUpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gU2VsZWN0IGVsZW1lbnRzIG9uIGNsaWNrXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LmNsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudCA9PT0gY2FudmFzLmdldFJvb3RFbGVtZW50KCkpIHtcbiAgICAgIGVsZW1lbnQgPSBudWxsO1xuICAgIH1cblxuICAgIHZhciBpc1NlbGVjdGVkID0gc2VsZWN0aW9uLmlzU2VsZWN0ZWQoZWxlbWVudCksXG4gICAgICAgIGlzTXVsdGlTZWxlY3QgPSBzZWxlY3Rpb24uZ2V0KCkubGVuZ3RoID4gMTtcblxuICAgIC8vIEFkZCB0byBzZWxlY3Rpb24gaWYgQ1RSTCBvciBTSElGVCBwcmVzc2VkXG4gICAgdmFyIGFkZCA9IGhhc1ByaW1hcnlNb2RpZmllcihldmVudCkgfHwgaGFzU2Vjb25kYXJ5TW9kaWZpZXIoZXZlbnQpO1xuXG4gICAgaWYgKGlzU2VsZWN0ZWQgJiYgaXNNdWx0aVNlbGVjdCkge1xuICAgICAgaWYgKGFkZCkge1xuXG4gICAgICAgIC8vIERlc2VsZWN0IGVsZW1lbnRcbiAgICAgICAgcmV0dXJuIHNlbGVjdGlvbi5kZXNlbGVjdChlbGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gU2VsZWN0IGVsZW1lbnQgb25seVxuICAgICAgICByZXR1cm4gc2VsZWN0aW9uLnNlbGVjdChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFpc1NlbGVjdGVkKSB7XG5cbiAgICAgIC8vIFNlbGVjdCBlbGVtZW50XG4gICAgICBzZWxlY3Rpb24uc2VsZWN0KGVsZW1lbnQsIGFkZCk7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gRGVzZWxlY3QgZWxlbWVudFxuICAgICAgc2VsZWN0aW9uLmRlc2VsZWN0KGVsZW1lbnQpO1xuICAgIH1cbiAgfSk7XG59XG5cblNlbGVjdGlvbkJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdzZWxlY3Rpb24nLFxuICAnY2FudmFzJyxcbiAgJ2VsZW1lbnRSZWdpc3RyeSdcbl07XG5cblxuZnVuY3Rpb24gaXNTaG93bihlbGVtZW50KSB7XG4gIHJldHVybiAhZWxlbWVudC5oaWRkZW47XG59XG4iLCJpbXBvcnQge1xuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIE1BUktFUl9IT1ZFUiA9ICdob3ZlcicsXG4gICAgTUFSS0VSX1NFTEVDVEVEID0gJ3NlbGVjdGVkJztcblxuXG4vKipcbiAqIEEgcGx1Z2luIHRoYXQgYWRkcyBhIHZpc2libGUgc2VsZWN0aW9uIFVJIHRvIHNoYXBlcyBhbmQgY29ubmVjdGlvbnNcbiAqIGJ5IGFwcGVuZGluZyB0aGUgPGNvZGU+aG92ZXI8L2NvZGU+IGFuZCA8Y29kZT5zZWxlY3RlZDwvY29kZT4gY2xhc3NlcyB0byB0aGVtLlxuICpcbiAqIEBjbGFzc1xuICpcbiAqIE1ha2VzIGVsZW1lbnRzIHNlbGVjdGFibGUsIHRvby5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudHNcbiAqIEBwYXJhbSB7U2VsZWN0aW9uU2VydmljZX0gc2VsZWN0aW9uXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNlbGVjdGlvblZpc3VhbHMoZXZlbnRzLCBjYW52YXMsIHNlbGVjdGlvbiwgc3R5bGVzKSB7XG5cbiAgdGhpcy5fbXVsdGlTZWxlY3Rpb25Cb3ggPSBudWxsO1xuXG4gIGZ1bmN0aW9uIGFkZE1hcmtlcihlLCBjbHMpIHtcbiAgICBjYW52YXMuYWRkTWFya2VyKGUsIGNscyk7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVNYXJrZXIoZSwgY2xzKSB7XG4gICAgY2FudmFzLnJlbW92ZU1hcmtlcihlLCBjbHMpO1xuICB9XG5cbiAgZXZlbnRzLm9uKCdlbGVtZW50LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBhZGRNYXJrZXIoZXZlbnQuZWxlbWVudCwgTUFSS0VSX0hPVkVSKTtcbiAgfSk7XG5cbiAgZXZlbnRzLm9uKCdlbGVtZW50Lm91dCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgcmVtb3ZlTWFya2VyKGV2ZW50LmVsZW1lbnQsIE1BUktFUl9IT1ZFUik7XG4gIH0pO1xuXG4gIGV2ZW50cy5vbignc2VsZWN0aW9uLmNoYW5nZWQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgZnVuY3Rpb24gZGVzZWxlY3Qocykge1xuICAgICAgcmVtb3ZlTWFya2VyKHMsIE1BUktFUl9TRUxFQ1RFRCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2VsZWN0KHMpIHtcbiAgICAgIGFkZE1hcmtlcihzLCBNQVJLRVJfU0VMRUNURUQpO1xuICAgIH1cblxuICAgIHZhciBvbGRTZWxlY3Rpb24gPSBldmVudC5vbGRTZWxlY3Rpb24sXG4gICAgICAgIG5ld1NlbGVjdGlvbiA9IGV2ZW50Lm5ld1NlbGVjdGlvbjtcblxuICAgIGZvckVhY2gob2xkU2VsZWN0aW9uLCBmdW5jdGlvbihlKSB7XG4gICAgICBpZiAobmV3U2VsZWN0aW9uLmluZGV4T2YoZSkgPT09IC0xKSB7XG4gICAgICAgIGRlc2VsZWN0KGUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZm9yRWFjaChuZXdTZWxlY3Rpb24sIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGlmIChvbGRTZWxlY3Rpb24uaW5kZXhPZihlKSA9PT0gLTEpIHtcbiAgICAgICAgc2VsZWN0KGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuU2VsZWN0aW9uVmlzdWFscy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3NlbGVjdGlvbicsXG4gICdzdHlsZXMnXG5dOyIsImltcG9ydCBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSBmcm9tICcuLi9pbnRlcmFjdGlvbi1ldmVudHMnO1xuaW1wb3J0IE91dGxpbmVNb2R1bGUgZnJvbSAnLi4vb3V0bGluZSc7XG5cbmltcG9ydCBTZWxlY3Rpb24gZnJvbSAnLi9TZWxlY3Rpb24nO1xuaW1wb3J0IFNlbGVjdGlvblZpc3VhbHMgZnJvbSAnLi9TZWxlY3Rpb25WaXN1YWxzJztcbmltcG9ydCBTZWxlY3Rpb25CZWhhdmlvciBmcm9tICcuL1NlbGVjdGlvbkJlaGF2aW9yJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdzZWxlY3Rpb25WaXN1YWxzJywgJ3NlbGVjdGlvbkJlaGF2aW9yJyBdLFxuICBfX2RlcGVuZHNfXzogW1xuICAgIEludGVyYWN0aW9uRXZlbnRzTW9kdWxlLFxuICAgIE91dGxpbmVNb2R1bGVcbiAgXSxcbiAgc2VsZWN0aW9uOiBbICd0eXBlJywgU2VsZWN0aW9uIF0sXG4gIHNlbGVjdGlvblZpc3VhbHM6IFsgJ3R5cGUnLCBTZWxlY3Rpb25WaXN1YWxzIF0sXG4gIHNlbGVjdGlvbkJlaGF2aW9yOiBbICd0eXBlJywgU2VsZWN0aW9uQmVoYXZpb3IgXVxufTtcbiIsImltcG9ydCBTbmFwQ29udGV4dCBmcm9tICcuL1NuYXBDb250ZXh0JztcclxuXHJcbmltcG9ydCB7XHJcbiAgZ2V0Q2hpbGRyZW4sXHJcbiAgaXNTbmFwcGVkLFxyXG4gIG1pZFxyXG59IGZyb20gJy4vU25hcFV0aWwnO1xyXG5cclxuaW1wb3J0IHsgaXNDbWQgfSBmcm9tICcuLi9rZXlib2FyZC9LZXlib2FyZFV0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBmb3JFYWNoLFxyXG4gIGlzTnVtYmVyXHJcbn0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxudmFyIEhJR0hFUl9QUklPUklUWSA9IDEyNTA7XHJcblxyXG5cclxuLyoqXHJcbiAqIFNuYXAgZHVyaW5nIGNyZWF0ZSBhbmQgbW92ZS5cclxuICpcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZWxlbWVudFJlZ2lzdHJ5XHJcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXHJcbiAqIEBwYXJhbSB7U25hcHBpbmd9IHNuYXBwaW5nXHJcbiAqL1xyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVNb3ZlU25hcHBpbmcoZWxlbWVudFJlZ2lzdHJ5LCBldmVudEJ1cywgc25hcHBpbmcpIHtcclxuICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcclxuXHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2NyZWF0ZS5zdGFydCcsXHJcbiAgICAnc2hhcGUubW92ZS5zdGFydCdcclxuICBdLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgc2VsZi5pbml0U25hcChldmVudCk7XHJcbiAgfSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKFtcclxuICAgICdjcmVhdGUubW92ZScsXHJcbiAgICAnY3JlYXRlLmVuZCcsXHJcbiAgICAnc2hhcGUubW92ZS5tb3ZlJyxcclxuICAgICdzaGFwZS5tb3ZlLmVuZCdcclxuICBdLCBISUdIRVJfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxyXG4gICAgICAgIHNuYXBDb250ZXh0ID0gY29udGV4dC5zbmFwQ29udGV4dCxcclxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcclxuXHJcbiAgICBpZiAoZXZlbnQub3JpZ2luYWxFdmVudCAmJiBpc0NtZChldmVudC5vcmlnaW5hbEV2ZW50KSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzU25hcHBlZChldmVudCkgfHwgIXRhcmdldCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHNuYXBQb2ludHMgPSBzbmFwQ29udGV4dC5wb2ludHNGb3JUYXJnZXQodGFyZ2V0KTtcclxuXHJcbiAgICBpZiAoIXNuYXBQb2ludHMuaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgc25hcFBvaW50cyA9IHNlbGYuYWRkU25hcFRhcmdldFBvaW50cyhzbmFwUG9pbnRzLCBzaGFwZSwgdGFyZ2V0KTtcclxuXHJcbiAgICAgIHNuYXBQb2ludHMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHNuYXBwaW5nLnNuYXAoZXZlbnQsIHNuYXBQb2ludHMpO1xyXG4gIH0pO1xyXG5cclxuICBldmVudEJ1cy5vbihbXHJcbiAgICAnY3JlYXRlLmNsZWFudXAnLFxyXG4gICAgJ3NoYXBlLm1vdmUuY2xlYW51cCdcclxuICBdLCBmdW5jdGlvbigpIHtcclxuICAgIHNuYXBwaW5nLmhpZGUoKTtcclxuICB9KTtcclxufVxyXG5cclxuQ3JlYXRlTW92ZVNuYXBwaW5nLiRpbmplY3QgPSBbXHJcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXHJcbiAgJ2V2ZW50QnVzJyxcclxuICAnc25hcHBpbmcnXHJcbl07XHJcblxyXG5DcmVhdGVNb3ZlU25hcHBpbmcucHJvdG90eXBlLmluaXRTbmFwID0gZnVuY3Rpb24oZXZlbnQpIHtcclxuICB2YXIgZWxlbWVudFJlZ2lzdHJ5ID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5O1xyXG5cclxuICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcclxuICAgICAgc25hcENvbnRleHQgPSBjb250ZXh0LnNuYXBDb250ZXh0O1xyXG5cclxuICBpZiAoIXNuYXBDb250ZXh0KSB7XHJcbiAgICBzbmFwQ29udGV4dCA9IGNvbnRleHQuc25hcENvbnRleHQgPSBuZXcgU25hcENvbnRleHQoKTtcclxuICB9XHJcblxyXG4gIHZhciBzaGFwZU1pZDtcclxuXHJcbiAgaWYgKGVsZW1lbnRSZWdpc3RyeS5nZXQoc2hhcGUuaWQpKSB7XHJcblxyXG4gICAgLy8gbW92ZVxyXG4gICAgc2hhcGVNaWQgPSBtaWQoc2hhcGUsIGV2ZW50KTtcclxuICB9IGVsc2Uge1xyXG5cclxuICAgIC8vIGNyZWF0ZVxyXG4gICAgc2hhcGVNaWQgPSB7XHJcbiAgICAgIHg6IGV2ZW50LnggKyBtaWQoc2hhcGUpLngsXHJcbiAgICAgIHk6IGV2ZW50LnkgKyBtaWQoc2hhcGUpLnlcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICB2YXIgc2hhcGVUb3BMZWZ0ID0ge1xyXG4gICAgICAgIHg6IHNoYXBlTWlkLnggLSBzaGFwZS53aWR0aCAvIDIsXHJcbiAgICAgICAgeTogc2hhcGVNaWQueSAtIHNoYXBlLmhlaWdodCAvIDJcclxuICAgICAgfSxcclxuICAgICAgc2hhcGVCb3R0b21SaWdodCA9IHtcclxuICAgICAgICB4OiBzaGFwZU1pZC54ICsgc2hhcGUud2lkdGggLyAyLFxyXG4gICAgICAgIHk6IHNoYXBlTWlkLnkgKyBzaGFwZS5oZWlnaHQgLyAyXHJcbiAgICAgIH07XHJcblxyXG4gIHNuYXBDb250ZXh0LnNldFNuYXBPcmlnaW4oJ21pZCcsIHtcclxuICAgIHg6IHNoYXBlTWlkLnggLSBldmVudC54LFxyXG4gICAgeTogc2hhcGVNaWQueSAtIGV2ZW50LnlcclxuICB9KTtcclxuXHJcbiAgLy8gc25hcCBsYWJlbHMgdG8gbWlkIG9ubHlcclxuICBpZiAoaXNMYWJlbChzaGFwZSkpIHtcclxuICAgIHJldHVybiBzbmFwQ29udGV4dDtcclxuICB9XHJcblxyXG4gIHNuYXBDb250ZXh0LnNldFNuYXBPcmlnaW4oJ3RvcC1sZWZ0Jywge1xyXG4gICAgeDogc2hhcGVUb3BMZWZ0LnggLSBldmVudC54LFxyXG4gICAgeTogc2hhcGVUb3BMZWZ0LnkgLSBldmVudC55XHJcbiAgfSk7XHJcblxyXG4gIHNuYXBDb250ZXh0LnNldFNuYXBPcmlnaW4oJ2JvdHRvbS1yaWdodCcsIHtcclxuICAgIHg6IHNoYXBlQm90dG9tUmlnaHQueCAtIGV2ZW50LngsXHJcbiAgICB5OiBzaGFwZUJvdHRvbVJpZ2h0LnkgLSBldmVudC55XHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBzbmFwQ29udGV4dDtcclxufTtcclxuXHJcbkNyZWF0ZU1vdmVTbmFwcGluZy5wcm90b3R5cGUuYWRkU25hcFRhcmdldFBvaW50cyA9IGZ1bmN0aW9uKHNuYXBQb2ludHMsIHNoYXBlLCB0YXJnZXQpIHtcclxuICB2YXIgc25hcFRhcmdldHMgPSB0aGlzLmdldFNuYXBUYXJnZXRzKHNoYXBlLCB0YXJnZXQpO1xyXG5cclxuICBmb3JFYWNoKHNuYXBUYXJnZXRzLCBmdW5jdGlvbihzbmFwVGFyZ2V0KSB7XHJcblxyXG4gICAgLy8gaGFuZGxlIGxhYmVsc1xyXG4gICAgaWYgKGlzTGFiZWwoc25hcFRhcmdldCkpIHtcclxuXHJcbiAgICAgIGlmIChpc0xhYmVsKHNoYXBlKSkge1xyXG4gICAgICAgIHNuYXBQb2ludHMuYWRkKCdtaWQnLCBtaWQoc25hcFRhcmdldCkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaGFuZGxlIGNvbm5lY3Rpb25zXHJcbiAgICBpZiAoaXNDb25uZWN0aW9uKHNuYXBUYXJnZXQpKSB7XHJcblxyXG4gICAgICAvLyBpZ25vcmUgc2luZ2xlIHNlZ21lbnQgY29ubmVjdGlvbnNcclxuICAgICAgaWYgKHNuYXBUYXJnZXQud2F5cG9pbnRzLmxlbmd0aCA8IDMpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIGlnbm9yZSBmaXJzdCBhbmQgbGFzdCB3YXlwb2ludFxyXG4gICAgICB2YXIgd2F5cG9pbnRzID0gc25hcFRhcmdldC53YXlwb2ludHMuc2xpY2UoMSwgLTEpO1xyXG5cclxuICAgICAgZm9yRWFjaCh3YXlwb2ludHMsIGZ1bmN0aW9uKHdheXBvaW50KSB7XHJcbiAgICAgICAgc25hcFBvaW50cy5hZGQoJ21pZCcsIHdheXBvaW50KTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaGFuZGxlIHNoYXBlc1xyXG4gICAgc25hcFBvaW50cy5hZGQoJ21pZCcsIG1pZChzbmFwVGFyZ2V0KSk7XHJcbiAgfSk7XHJcblxyXG4gIGlmICghaXNOdW1iZXIoc2hhcGUueCkgfHwgIWlzTnVtYmVyKHNoYXBlLnkpKSB7XHJcbiAgICByZXR1cm4gc25hcFBvaW50cztcclxuICB9XHJcblxyXG4gIC8vIHNuYXAgdG8gb3JpZ2luYWwgcG9zaXRpb24gd2hlbiBtb3ZpbmdcclxuICBpZiAodGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldChzaGFwZS5pZCkpIHtcclxuICAgIHNuYXBQb2ludHMuYWRkKCdtaWQnLCBtaWQoc2hhcGUpKTtcclxuICB9XHJcblxyXG4gIHJldHVybiBzbmFwUG9pbnRzO1xyXG59O1xyXG5cclxuQ3JlYXRlTW92ZVNuYXBwaW5nLnByb3RvdHlwZS5nZXRTbmFwVGFyZ2V0cyA9IGZ1bmN0aW9uKHNoYXBlLCB0YXJnZXQpIHtcclxuICByZXR1cm4gZ2V0Q2hpbGRyZW4odGFyZ2V0KS5maWx0ZXIoZnVuY3Rpb24oY2hpbGQpIHtcclxuICAgIHJldHVybiAhaXNIaWRkZW4oY2hpbGQpO1xyXG4gIH0pO1xyXG59O1xyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBpc0Nvbm5lY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiAhIWVsZW1lbnQud2F5cG9pbnRzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0hpZGRlbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuICEhZWxlbWVudC5oaWRkZW47XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xyXG4gIHJldHVybiAhIWVsZW1lbnQubGFiZWxUYXJnZXQ7XHJcbn0iLCJpbXBvcnQgU25hcENvbnRleHQgZnJvbSAnLi9TbmFwQ29udGV4dCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIGJvdHRvbVJpZ2h0LFxyXG4gIGdldENoaWxkcmVuLFxyXG4gIGlzU25hcHBlZCxcclxuICBzZXRTbmFwcGVkLFxyXG4gIHRvcExlZnQsXHJcbn0gZnJvbSAnLi9TbmFwVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0NtZCB9IGZyb20gJy4uL2tleWJvYXJkL0tleWJvYXJkVXRpbCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIGFzVFJCTCxcclxuICBnZXRNaWRcclxufSBmcm9tICcuLi8uLi9sYXlvdXQvTGF5b3V0VXRpbCc7XHJcblxyXG5pbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxudmFyIEhJR0hFUl9QUklPUklUWSA9IDEyNTA7XHJcblxyXG5cclxuLyoqXHJcbiAqIFNuYXAgZHVyaW5nIHJlc2l6ZS5cclxuICpcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcclxuICogQHBhcmFtIHtTbmFwcGluZ30gc25hcHBpbmdcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlc2l6ZVNuYXBwaW5nKGV2ZW50QnVzLCBzbmFwcGluZykge1xyXG4gIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgZXZlbnRCdXMub24oWyAncmVzaXplLnN0YXJ0JyBdLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgc2VsZi5pbml0U25hcChldmVudCk7XHJcbiAgfSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKFtcclxuICAgICdyZXNpemUubW92ZScsXHJcbiAgICAncmVzaXplLmVuZCcsXHJcbiAgXSwgSElHSEVSX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcclxuICAgICAgICBwYXJlbnQgPSBzaGFwZS5wYXJlbnQsXHJcbiAgICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXHJcbiAgICAgICAgc25hcENvbnRleHQgPSBjb250ZXh0LnNuYXBDb250ZXh0O1xyXG5cclxuICAgIGlmIChldmVudC5vcmlnaW5hbEV2ZW50ICYmIGlzQ21kKGV2ZW50Lm9yaWdpbmFsRXZlbnQpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaXNTbmFwcGVkKGV2ZW50KSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHNuYXBQb2ludHMgPSBzbmFwQ29udGV4dC5wb2ludHNGb3JUYXJnZXQocGFyZW50KTtcclxuXHJcbiAgICBpZiAoIXNuYXBQb2ludHMuaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgc25hcFBvaW50cyA9IHNlbGYuYWRkU25hcFRhcmdldFBvaW50cyhzbmFwUG9pbnRzLCBzaGFwZSwgcGFyZW50LCBkaXJlY3Rpb24pO1xyXG5cclxuICAgICAgc25hcFBvaW50cy5pbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzSG9yaXpvbnRhbChkaXJlY3Rpb24pKSB7XHJcbiAgICAgIHNldFNuYXBwZWQoZXZlbnQsICd4JywgZXZlbnQueCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzVmVydGljYWwoZGlyZWN0aW9uKSkge1xyXG4gICAgICBzZXRTbmFwcGVkKGV2ZW50LCAneScsIGV2ZW50LnkpO1xyXG4gICAgfVxyXG5cclxuICAgIHNuYXBwaW5nLnNuYXAoZXZlbnQsIHNuYXBQb2ludHMpO1xyXG4gIH0pO1xyXG5cclxuICBldmVudEJ1cy5vbihbICdyZXNpemUuY2xlYW51cCcgXSwgZnVuY3Rpb24oKSB7XHJcbiAgICBzbmFwcGluZy5oaWRlKCk7XHJcbiAgfSk7XHJcbn1cclxuXHJcblJlc2l6ZVNuYXBwaW5nLnByb3RvdHlwZS5pbml0U25hcCA9IGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXHJcbiAgICAgIGRpcmVjdGlvbiA9IGNvbnRleHQuZGlyZWN0aW9uLFxyXG4gICAgICBzbmFwQ29udGV4dCA9IGNvbnRleHQuc25hcENvbnRleHQ7XHJcblxyXG4gIGlmICghc25hcENvbnRleHQpIHtcclxuICAgIHNuYXBDb250ZXh0ID0gY29udGV4dC5zbmFwQ29udGV4dCA9IG5ldyBTbmFwQ29udGV4dCgpO1xyXG4gIH1cclxuXHJcbiAgdmFyIHNuYXBPcmlnaW4gPSBnZXRTbmFwT3JpZ2luKHNoYXBlLCBkaXJlY3Rpb24pO1xyXG5cclxuICBzbmFwQ29udGV4dC5zZXRTbmFwT3JpZ2luKCdjb3JuZXInLCB7XHJcbiAgICB4OiBzbmFwT3JpZ2luLnggLSBldmVudC54LFxyXG4gICAgeTogc25hcE9yaWdpbi55IC0gZXZlbnQueVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gc25hcENvbnRleHQ7XHJcbn07XHJcblxyXG5SZXNpemVTbmFwcGluZy5wcm90b3R5cGUuYWRkU25hcFRhcmdldFBvaW50cyA9IGZ1bmN0aW9uKHNuYXBQb2ludHMsIHNoYXBlLCB0YXJnZXQsIGRpcmVjdGlvbikge1xyXG4gIHZhciBzbmFwVGFyZ2V0cyA9IHRoaXMuZ2V0U25hcFRhcmdldHMoc2hhcGUsIHRhcmdldCk7XHJcblxyXG4gIGZvckVhY2goc25hcFRhcmdldHMsIGZ1bmN0aW9uKHNuYXBUYXJnZXQpIHtcclxuICAgIHNuYXBQb2ludHMuYWRkKCdjb3JuZXInLCBib3R0b21SaWdodChzbmFwVGFyZ2V0KSk7XHJcbiAgICBzbmFwUG9pbnRzLmFkZCgnY29ybmVyJywgdG9wTGVmdChzbmFwVGFyZ2V0KSk7XHJcbiAgfSk7XHJcblxyXG4gIHNuYXBQb2ludHMuYWRkKCdjb3JuZXInLCBnZXRTbmFwT3JpZ2luKHNoYXBlLCBkaXJlY3Rpb24pKTtcclxuXHJcbiAgcmV0dXJuIHNuYXBQb2ludHM7XHJcbn07XHJcblxyXG5SZXNpemVTbmFwcGluZy4kaW5qZWN0ID0gW1xyXG4gICdldmVudEJ1cycsXHJcbiAgJ3NuYXBwaW5nJ1xyXG5dO1xyXG5cclxuUmVzaXplU25hcHBpbmcucHJvdG90eXBlLmdldFNuYXBUYXJnZXRzID0gZnVuY3Rpb24oc2hhcGUsIHRhcmdldCkge1xyXG4gIHJldHVybiBnZXRDaGlsZHJlbih0YXJnZXQpLmZpbHRlcihmdW5jdGlvbihjaGlsZCkge1xyXG4gICAgcmV0dXJuICFpc0F0dGFjaGVkKGNoaWxkLCBzaGFwZSlcclxuICAgICAgJiYgIWlzQ29ubmVjdGlvbihjaGlsZClcclxuICAgICAgJiYgIWlzSGlkZGVuKGNoaWxkKVxyXG4gICAgICAmJiAhaXNMYWJlbChjaGlsZCk7XHJcbiAgfSk7XHJcbn07XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIGdldFNuYXBPcmlnaW4oc2hhcGUsIGRpcmVjdGlvbikge1xyXG4gIHZhciBtaWQgPSBnZXRNaWQoc2hhcGUpLFxyXG4gICAgICB0cmJsID0gYXNUUkJMKHNoYXBlKTtcclxuXHJcbiAgdmFyIHNuYXBPcmlnaW4gPSB7XHJcbiAgICB4OiBtaWQueCxcclxuICAgIHk6IG1pZC55XHJcbiAgfTtcclxuXHJcbiAgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCduJykgIT09IC0xKSB7XHJcbiAgICBzbmFwT3JpZ2luLnkgPSB0cmJsLnRvcDtcclxuICB9IGVsc2UgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCdzJykgIT09IC0xKSB7XHJcbiAgICBzbmFwT3JpZ2luLnkgPSB0cmJsLmJvdHRvbTtcclxuICB9XHJcblxyXG4gIGlmIChkaXJlY3Rpb24uaW5kZXhPZignZScpICE9PSAtMSkge1xyXG4gICAgc25hcE9yaWdpbi54ID0gdHJibC5yaWdodDtcclxuICB9IGVsc2UgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCd3JykgIT09IC0xKSB7XHJcbiAgICBzbmFwT3JpZ2luLnggPSB0cmJsLmxlZnQ7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gc25hcE9yaWdpbjtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNBdHRhY2hlZChlbGVtZW50LCBob3N0KSB7XHJcbiAgcmV0dXJuIGVsZW1lbnQuaG9zdCA9PT0gaG9zdDtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gISFlbGVtZW50LndheXBvaW50cztcclxufVxyXG5cclxuZnVuY3Rpb24gaXNIaWRkZW4oZWxlbWVudCkge1xyXG4gIHJldHVybiAhIWVsZW1lbnQuaGlkZGVuO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0xhYmVsKGVsZW1lbnQpIHtcclxuICByZXR1cm4gISFlbGVtZW50LmxhYmVsVGFyZ2V0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0hvcml6b250YWwoZGlyZWN0aW9uKSB7XHJcbiAgcmV0dXJuIGRpcmVjdGlvbiA9PT0gJ24nIHx8IGRpcmVjdGlvbiA9PT0gJ3MnO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc1ZlcnRpY2FsKGRpcmVjdGlvbikge1xyXG4gIHJldHVybiBkaXJlY3Rpb24gPT09ICdlJyB8fCBkaXJlY3Rpb24gPT09ICd3JztcclxufSIsImltcG9ydCB7XG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBzbmFwVG9cbn0gZnJvbSAnLi9TbmFwVXRpbCc7XG5cblxuLyoqXG4gKiBBIHNuYXAgY29udGV4dCwgY29udGFpbmluZyB0aGUgKHBvc3NpYmx5IGluY29tcGxldGUpXG4gKiBtYXBwaW5ncyBvZiBkcm9wIHRhcmdldHMgKHRvIGlkZW50aWZ5IHRoZSBzbmFwcGluZylcbiAqIHRvIGNvbXB1dGVkIHNuYXAgcG9pbnRzLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBTbmFwQ29udGV4dCgpIHtcblxuICAvKipcbiAgICogTWFwPFN0cmluZywgU25hcFBvaW50cz4gbWFwcGluZyBkcm9wIHRhcmdldHMgdG9cbiAgICogYSBsaXN0IG9mIHBvc3NpYmxlIHNuYXBwaW5ncy5cbiAgICpcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHRoaXMuX3RhcmdldHMgPSB7fTtcblxuICAvKipcbiAgICogTWFwPFN0cmluZywgUG9pbnQ+IGluaXRpYWwgcG9zaXRpb25pbmcgb2YgZWxlbWVudFxuICAgKiByZWdhcmRpbmcgdmFyaW91cyBzbmFwIGRpcmVjdGlvbnMuXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLl9zbmFwT3JpZ2lucyA9IHt9O1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIHNuYXAgbG9jYXRpb25zXG4gICAqXG4gICAqIEB0eXBlIHtBcnJheTxzdHJpbmc+fVxuICAgKi9cbiAgdGhpcy5fc25hcExvY2F0aW9ucyA9IFtdO1xuXG4gIC8qKlxuICAgKiBNYXA8U3RyaW5nLCBBcnJheTxQb2ludD4+IG9mIGRlZmF1bHQgc25hcHBpbmcgbG9jYXRpb25zXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLl9kZWZhdWx0U25hcHMgPSB7fTtcbn1cblxuXG5TbmFwQ29udGV4dC5wcm90b3R5cGUuZ2V0U25hcE9yaWdpbiA9IGZ1bmN0aW9uKHNuYXBMb2NhdGlvbikge1xuICByZXR1cm4gdGhpcy5fc25hcE9yaWdpbnNbc25hcExvY2F0aW9uXTtcbn07XG5cblxuU25hcENvbnRleHQucHJvdG90eXBlLnNldFNuYXBPcmlnaW4gPSBmdW5jdGlvbihzbmFwTG9jYXRpb24sIGluaXRpYWxWYWx1ZSkge1xuICB0aGlzLl9zbmFwT3JpZ2luc1tzbmFwTG9jYXRpb25dID0gaW5pdGlhbFZhbHVlO1xuXG4gIGlmICh0aGlzLl9zbmFwTG9jYXRpb25zLmluZGV4T2Yoc25hcExvY2F0aW9uKSA9PT0gLTEpIHtcbiAgICB0aGlzLl9zbmFwTG9jYXRpb25zLnB1c2goc25hcExvY2F0aW9uKTtcbiAgfVxufTtcblxuXG5TbmFwQ29udGV4dC5wcm90b3R5cGUuYWRkRGVmYXVsdFNuYXAgPSBmdW5jdGlvbih0eXBlLCBwb2ludCkge1xuXG4gIHZhciBzbmFwVmFsdWVzID0gdGhpcy5fZGVmYXVsdFNuYXBzW3R5cGVdO1xuXG4gIGlmICghc25hcFZhbHVlcykge1xuICAgIHNuYXBWYWx1ZXMgPSB0aGlzLl9kZWZhdWx0U25hcHNbdHlwZV0gPSBbXTtcbiAgfVxuXG4gIHNuYXBWYWx1ZXMucHVzaChwb2ludCk7XG59O1xuXG4vKipcbiAqIFJldHVybiBhIG51bWJlciBvZiBpbml0aWFsaXplZCBzbmFwcywgaS5lLiBzbmFwIGxvY2F0aW9ucyBzdWNoIGFzXG4gKiB0b3AtbGVmdCwgbWlkLCBib3R0b20tcmlnaHQgYW5kIHNvIGZvcnRoLlxuICpcbiAqIEByZXR1cm4ge0FycmF5PHN0cmluZz59IHNuYXBMb2NhdGlvbnNcbiAqL1xuU25hcENvbnRleHQucHJvdG90eXBlLmdldFNuYXBMb2NhdGlvbnMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX3NuYXBMb2NhdGlvbnM7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgc25hcCBsb2NhdGlvbnMgZm9yIHRoaXMgY29udGV4dC5cbiAqXG4gKiBUaGUgb3JkZXIgb2YgbG9jYXRpb25zIGRldGVybWluZXMgcHJlY2VkZW5jZS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IHNuYXBMb2NhdGlvbnNcbiAqL1xuU25hcENvbnRleHQucHJvdG90eXBlLnNldFNuYXBMb2NhdGlvbnMgPSBmdW5jdGlvbihzbmFwTG9jYXRpb25zKSB7XG4gIHRoaXMuX3NuYXBMb2NhdGlvbnMgPSBzbmFwTG9jYXRpb25zO1xufTtcblxuLyoqXG4gKiBHZXQgc25hcCBwb2ludHMgZm9yIGEgZ2l2ZW4gdGFyZ2V0XG4gKlxuICogQHBhcmFtIHtFbGVtZW50fHN0cmluZ30gdGFyZ2V0XG4gKi9cblNuYXBDb250ZXh0LnByb3RvdHlwZS5wb2ludHNGb3JUYXJnZXQgPSBmdW5jdGlvbih0YXJnZXQpIHtcblxuICB2YXIgdGFyZ2V0SWQgPSB0YXJnZXQuaWQgfHwgdGFyZ2V0O1xuXG4gIHZhciBzbmFwUG9pbnRzID0gdGhpcy5fdGFyZ2V0c1t0YXJnZXRJZF07XG5cbiAgaWYgKCFzbmFwUG9pbnRzKSB7XG4gICAgc25hcFBvaW50cyA9IHRoaXMuX3RhcmdldHNbdGFyZ2V0SWRdID0gbmV3IFNuYXBQb2ludHMoKTtcbiAgICBzbmFwUG9pbnRzLmluaXREZWZhdWx0cyh0aGlzLl9kZWZhdWx0U25hcHMpO1xuICB9XG5cbiAgcmV0dXJuIHNuYXBQb2ludHM7XG59O1xuXG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgc25hcCBwb2ludHMgYW5kIGluaXRpYWxpemVzIHRoZW0gd2l0aCB0aGVcbiAqIGdpdmVuIGRlZmF1bHQgdmFsdWVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgQXJyYXk8UG9pbnQ+Pn0gW2RlZmF1bHRQb2ludHNdXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBTbmFwUG9pbnRzKGRlZmF1bHRTbmFwcykge1xuXG4gIC8qKlxuICAgKiBNYXA8U3RyaW5nLCBNYXA8KHh8eSksIEFycmF5PG51bWJlcj4+PiBtYXBwaW5nIHNuYXAgbG9jYXRpb25zLFxuICAgKiBpLmUuIHRvcC1sZWZ0LCBib3R0b20tcmlnaHQsIGNlbnRlciB0byBhY3R1YWwgc25hcCB2YWx1ZXMuXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLl9zbmFwVmFsdWVzID0ge307XG59XG5cblNuYXBQb2ludHMucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKHNuYXBMb2NhdGlvbiwgcG9pbnQpIHtcblxuICB2YXIgc25hcFZhbHVlcyA9IHRoaXMuX3NuYXBWYWx1ZXNbc25hcExvY2F0aW9uXTtcblxuICBpZiAoIXNuYXBWYWx1ZXMpIHtcbiAgICBzbmFwVmFsdWVzID0gdGhpcy5fc25hcFZhbHVlc1tzbmFwTG9jYXRpb25dID0geyB4OiBbXSwgeTogW10gfTtcbiAgfVxuXG4gIGlmIChzbmFwVmFsdWVzLnguaW5kZXhPZihwb2ludC54KSA9PT0gLTEpIHtcbiAgICBzbmFwVmFsdWVzLngucHVzaChwb2ludC54KTtcbiAgfVxuXG4gIGlmIChzbmFwVmFsdWVzLnkuaW5kZXhPZihwb2ludC55KSA9PT0gLTEpIHtcbiAgICBzbmFwVmFsdWVzLnkucHVzaChwb2ludC55KTtcbiAgfVxufTtcblxuXG5TbmFwUG9pbnRzLnByb3RvdHlwZS5zbmFwID0gZnVuY3Rpb24ocG9pbnQsIHNuYXBMb2NhdGlvbiwgYXhpcywgdG9sZXJhbmNlKSB7XG4gIHZhciBzbmFwcGluZ1ZhbHVlcyA9IHRoaXMuX3NuYXBWYWx1ZXNbc25hcExvY2F0aW9uXTtcblxuICByZXR1cm4gc25hcHBpbmdWYWx1ZXMgJiYgc25hcFRvKHBvaW50W2F4aXNdLCBzbmFwcGluZ1ZhbHVlc1theGlzXSwgdG9sZXJhbmNlKTtcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG51bWJlciBvZiBkZWZhdWx0IHNuYXBwaW5nIHBvaW50cy5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGRlZmF1bHRTbmFwc1xuICovXG5TbmFwUG9pbnRzLnByb3RvdHlwZS5pbml0RGVmYXVsdHMgPSBmdW5jdGlvbihkZWZhdWx0U25hcHMpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZm9yRWFjaChkZWZhdWx0U25hcHMgfHwge30sIGZ1bmN0aW9uKHNuYXBQb2ludHMsIHNuYXBMb2NhdGlvbikge1xuICAgIGZvckVhY2goc25hcFBvaW50cywgZnVuY3Rpb24ocG9pbnQpIHtcbiAgICAgIHNlbGYuYWRkKHNuYXBMb2NhdGlvbiwgcG9pbnQpO1xuICAgIH0pO1xuICB9KTtcbn07IiwidmFyIGFicyA9IE1hdGguYWJzLFxuICAgIHJvdW5kID0gTWF0aC5yb3VuZDtcblxuXG4vKipcbiAqIFNuYXAgdmFsdWUgdG8gYSBjb2xsZWN0aW9uIG9mIHJlZmVyZW5jZSB2YWx1ZXMuXG4gKlxuICogQHBhcmFtICB7bnVtYmVyfSB2YWx1ZVxuICogQHBhcmFtICB7QXJyYXk8bnVtYmVyPn0gdmFsdWVzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IFt0b2xlcmFuY2U9MTBdXG4gKlxuICogQHJldHVybiB7bnVtYmVyfSB0aGUgdmFsdWUgd2Ugc25hcHBlZCB0byBvciBudWxsLCBpZiBub25lIHNuYXBwZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNuYXBUbyh2YWx1ZSwgdmFsdWVzLCB0b2xlcmFuY2UpIHtcbiAgdG9sZXJhbmNlID0gdG9sZXJhbmNlID09PSB1bmRlZmluZWQgPyAxMCA6IHRvbGVyYW5jZTtcblxuICB2YXIgaWR4LCBzbmFwVmFsdWU7XG5cbiAgZm9yIChpZHggPSAwOyBpZHggPCB2YWx1ZXMubGVuZ3RoOyBpZHgrKykge1xuICAgIHNuYXBWYWx1ZSA9IHZhbHVlc1tpZHhdO1xuXG4gICAgaWYgKGFicyhzbmFwVmFsdWUgLSB2YWx1ZSkgPD0gdG9sZXJhbmNlKSB7XG4gICAgICByZXR1cm4gc25hcFZhbHVlO1xuICAgIH1cbiAgfVxufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiB0b3BMZWZ0KGJvdW5kcykge1xuICByZXR1cm4ge1xuICAgIHg6IGJvdW5kcy54LFxuICAgIHk6IGJvdW5kcy55XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b3BSaWdodChib3VuZHMpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBib3VuZHMueCArIGJvdW5kcy53aWR0aCxcbiAgICB5OiBib3VuZHMueVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYm90dG9tTGVmdChib3VuZHMpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBib3VuZHMueCxcbiAgICB5OiBib3VuZHMueSArIGJvdW5kcy5oZWlnaHRcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJvdHRvbVJpZ2h0KGJvdW5kcykge1xuICByZXR1cm4ge1xuICAgIHg6IGJvdW5kcy54ICsgYm91bmRzLndpZHRoLFxuICAgIHk6IGJvdW5kcy55ICsgYm91bmRzLmhlaWdodFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWlkKGJvdW5kcywgZGVmYXVsdFZhbHVlKSB7XG5cbiAgaWYgKCFib3VuZHMgfHwgaXNOYU4oYm91bmRzLngpIHx8IGlzTmFOKGJvdW5kcy55KSkge1xuICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHg6IHJvdW5kKGJvdW5kcy54ICsgYm91bmRzLndpZHRoIC8gMiksXG4gICAgeTogcm91bmQoYm91bmRzLnkgKyBib3VuZHMuaGVpZ2h0IC8gMilcbiAgfTtcbn1cblxuXG4vKipcbiAqIFJldHJpZXZlIHRoZSBzbmFwIHN0YXRlIG9mIHRoZSBnaXZlbiBldmVudC5cbiAqXG4gKiBAcGFyYW0gIHtFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSAge3N0cmluZ30gYXhpc1xuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHRoZSBzbmFwcGVkIHN0YXRlXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTbmFwcGVkKGV2ZW50LCBheGlzKSB7XG4gIHZhciBzbmFwcGVkID0gZXZlbnQuc25hcHBlZDtcblxuICBpZiAoIXNuYXBwZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIGF4aXMgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHNuYXBwZWRbYXhpc107XG4gIH1cblxuICByZXR1cm4gc25hcHBlZC54ICYmIHNuYXBwZWQueTtcbn1cblxuXG4vKipcbiAqIFNldCB0aGUgZ2l2ZW4gZXZlbnQgYXMgc25hcHBlZC5cbiAqXG4gKiBUaGlzIG1ldGhvZCBtYXkgY2hhbmdlIHRoZSB4IGFuZC9vciB5IHBvc2l0aW9uIG9mIHRoZSBzaGFwZVxuICogZnJvbSB0aGUgZ2l2ZW4gZXZlbnQhXG4gKlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzXG4gKiBAcGFyYW0ge251bWJlcnxib29sZWFufSB2YWx1ZVxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gb2xkIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRTbmFwcGVkKGV2ZW50LCBheGlzLCB2YWx1ZSkge1xuICBpZiAodHlwZW9mIGF4aXMgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdheGlzIG11c3QgYmUgaW4gW3gsIHldJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyAmJiB2YWx1ZSAhPT0gZmFsc2UpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbHVlIG11c3QgYmUgTnVtYmVyIG9yIGZhbHNlJyk7XG4gIH1cblxuICB2YXIgZGVsdGEsXG4gICAgICBwcmV2aW91c1ZhbHVlID0gZXZlbnRbYXhpc107XG5cbiAgdmFyIHNuYXBwZWQgPSBldmVudC5zbmFwcGVkID0gKGV2ZW50LnNuYXBwZWQgfHwge30pO1xuXG5cbiAgaWYgKHZhbHVlID09PSBmYWxzZSkge1xuICAgIHNuYXBwZWRbYXhpc10gPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICBzbmFwcGVkW2F4aXNdID0gdHJ1ZTtcblxuICAgIGRlbHRhID0gdmFsdWUgLSBwcmV2aW91c1ZhbHVlO1xuXG4gICAgZXZlbnRbYXhpc10gKz0gZGVsdGE7XG4gICAgZXZlbnRbJ2QnICsgYXhpc10gKz0gZGVsdGE7XG4gIH1cblxuICByZXR1cm4gcHJldmlvdXNWYWx1ZTtcbn1cblxuLyoqXG4gKiBHZXQgY2hpbGRyZW4gb2YgYSBzaGFwZS5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gcGFyZW50XG4gKlxuICogQHJldHVybnMge0FycmF5PGRqcy5tb2RlbC5TaGFwZXxkanMubW9kZWwuQ29ubmVjdGlvbj59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGlsZHJlbihwYXJlbnQpIHtcbiAgcmV0dXJuIHBhcmVudC5jaGlsZHJlbiB8fCBbXTtcbn0iLCJpbXBvcnQge1xuICBiaW5kLFxuICBkZWJvdW5jZSxcbiAgZm9yRWFjaCxcbiAgaXNOdW1iZXIsXG4gIGlzT2JqZWN0XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgaXNTbmFwcGVkLFxuICBzZXRTbmFwcGVkXG59IGZyb20gJy4vU25hcFV0aWwnO1xuXG5pbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNsYXNzZXMgYXMgc3ZnQ2xhc3NlcyxcbiAgY3JlYXRlIGFzIHN2Z0NyZWF0ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbnZhciBTTkFQX1RPTEVSQU5DRSA9IDc7XG5cbmV4cG9ydCB2YXIgU05BUF9MSU5FX0hJREVfREVMQVkgPSAxMDAwO1xuXG5cbi8qKlxuICogR2VuZXJpYyBzbmFwcGluZyBmZWF0dXJlLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNuYXBwaW5nKGNhbnZhcykge1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG5cbiAgLy8gZGVsYXkgaGlkZSBieSAxMDAwIHNlY29uZHMgc2luY2UgbGFzdCBzbmFwXG4gIHRoaXMuX2FzeW5jSGlkZSA9IGRlYm91bmNlKGJpbmQodGhpcy5oaWRlLCB0aGlzKSwgU05BUF9MSU5FX0hJREVfREVMQVkpO1xufVxuXG5TbmFwcGluZy4kaW5qZWN0ID0gWyAnY2FudmFzJyBdO1xuXG4vKipcbiAqIFNuYXAgYW4gZXZlbnQgdG8gZ2l2ZW4gc25hcCBwb2ludHMuXG4gKlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7U25hcFBvaW50c30gc25hcFBvaW50c1xuICovXG5TbmFwcGluZy5wcm90b3R5cGUuc25hcCA9IGZ1bmN0aW9uKGV2ZW50LCBzbmFwUG9pbnRzKSB7XG4gIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgIHNuYXBDb250ZXh0ID0gY29udGV4dC5zbmFwQ29udGV4dCxcbiAgICAgIHNuYXBMb2NhdGlvbnMgPSBzbmFwQ29udGV4dC5nZXRTbmFwTG9jYXRpb25zKCk7XG5cbiAgdmFyIHNuYXBwaW5nID0ge1xuICAgIHg6IGlzU25hcHBlZChldmVudCwgJ3gnKSxcbiAgICB5OiBpc1NuYXBwZWQoZXZlbnQsICd5JylcbiAgfTtcblxuICBmb3JFYWNoKHNuYXBMb2NhdGlvbnMsIGZ1bmN0aW9uKGxvY2F0aW9uKSB7XG4gICAgdmFyIHNuYXBPcmlnaW4gPSBzbmFwQ29udGV4dC5nZXRTbmFwT3JpZ2luKGxvY2F0aW9uKTtcblxuICAgIHZhciBzbmFwQ3VycmVudCA9IHtcbiAgICAgIHg6IGV2ZW50LnggKyBzbmFwT3JpZ2luLngsXG4gICAgICB5OiBldmVudC55ICsgc25hcE9yaWdpbi55XG4gICAgfTtcblxuICAgIC8vIHNuYXAgYm90aCBheGlzIGlmIG5vdCBzbmFwcGVkIGFscmVhZHlcbiAgICBmb3JFYWNoKFsgJ3gnLCAneScgXSwgZnVuY3Rpb24oYXhpcykge1xuICAgICAgdmFyIGxvY2F0aW9uU25hcHBpbmc7XG5cbiAgICAgIGlmICghc25hcHBpbmdbYXhpc10pIHtcbiAgICAgICAgbG9jYXRpb25TbmFwcGluZyA9IHNuYXBQb2ludHMuc25hcChzbmFwQ3VycmVudCwgbG9jYXRpb24sIGF4aXMsIFNOQVBfVE9MRVJBTkNFKTtcblxuICAgICAgICBpZiAobG9jYXRpb25TbmFwcGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgc25hcHBpbmdbYXhpc10gPSB7XG4gICAgICAgICAgICB2YWx1ZTogbG9jYXRpb25TbmFwcGluZyxcbiAgICAgICAgICAgIG9yaWdpblZhbHVlOiBsb2NhdGlvblNuYXBwaW5nIC0gc25hcE9yaWdpbltheGlzXVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIG5vIG5lZWQgdG8gY29udGludWUgc25hcHBpbmdcbiAgICBpZiAoc25hcHBpbmcueCAmJiBzbmFwcGluZy55KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcblxuICAvLyBzaG93IHNuYXAgbGluZXNcbiAgdGhpcy5zaG93U25hcExpbmUoJ3ZlcnRpY2FsJywgc25hcHBpbmcueCAmJiBzbmFwcGluZy54LnZhbHVlKTtcbiAgdGhpcy5zaG93U25hcExpbmUoJ2hvcml6b250YWwnLCBzbmFwcGluZy55ICYmIHNuYXBwaW5nLnkudmFsdWUpO1xuXG4gIC8vIHNuYXAgZXZlbnRcbiAgZm9yRWFjaChbICd4JywgJ3knIF0sIGZ1bmN0aW9uKGF4aXMpIHtcbiAgICB2YXIgYXhpc1NuYXBwaW5nID0gc25hcHBpbmdbYXhpc107XG5cbiAgICBpZiAoaXNPYmplY3QoYXhpc1NuYXBwaW5nKSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgYXhpcywgYXhpc1NuYXBwaW5nLm9yaWdpblZhbHVlKTtcbiAgICB9XG4gIH0pO1xufTtcblxuU25hcHBpbmcucHJvdG90eXBlLl9jcmVhdGVMaW5lID0gZnVuY3Rpb24ob3JpZW50YXRpb24pIHtcbiAgdmFyIHJvb3QgPSB0aGlzLl9jYW52YXMuZ2V0TGF5ZXIoJ3NuYXAnKTtcblxuICB2YXIgbGluZSA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuXG4gIHN2Z0F0dHIobGluZSwgeyBkOiAnTTAsMCBMMCwwJyB9KTtcblxuICBzdmdDbGFzc2VzKGxpbmUpLmFkZCgnZGpzLXNuYXAtbGluZScpO1xuXG4gIHN2Z0FwcGVuZChyb290LCBsaW5lKTtcblxuICByZXR1cm4ge1xuICAgIHVwZGF0ZTogZnVuY3Rpb24ocG9zaXRpb24pIHtcblxuICAgICAgaWYgKCFpc051bWJlcihwb3NpdGlvbikpIHtcbiAgICAgICAgc3ZnQXR0cihsaW5lLCB7IGRpc3BsYXk6ICdub25lJyB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChvcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgICAgc3ZnQXR0cihsaW5lLCB7XG4gICAgICAgICAgICBkOiAnTS0xMDAwMDAsJyArIHBvc2l0aW9uICsgJyBMKzEwMDAwMCwnICsgcG9zaXRpb24sXG4gICAgICAgICAgICBkaXNwbGF5OiAnJ1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN2Z0F0dHIobGluZSwge1xuICAgICAgICAgICAgZDogJ00gJyArIHBvc2l0aW9uICsgJywtMTAwMDAwIEwgJyArIHBvc2l0aW9uICsgJywgKzEwMDAwMCcsXG4gICAgICAgICAgICBkaXNwbGF5OiAnJ1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xufTtcblxuU25hcHBpbmcucHJvdG90eXBlLl9jcmVhdGVTbmFwTGluZXMgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fc25hcExpbmVzID0ge1xuICAgIGhvcml6b250YWw6IHRoaXMuX2NyZWF0ZUxpbmUoJ2hvcml6b250YWwnKSxcbiAgICB2ZXJ0aWNhbDogdGhpcy5fY3JlYXRlTGluZSgndmVydGljYWwnKVxuICB9O1xufTtcblxuU25hcHBpbmcucHJvdG90eXBlLnNob3dTbmFwTGluZSA9IGZ1bmN0aW9uKG9yaWVudGF0aW9uLCBwb3NpdGlvbikge1xuXG4gIHZhciBsaW5lID0gdGhpcy5nZXRTbmFwTGluZShvcmllbnRhdGlvbik7XG5cbiAgaWYgKGxpbmUpIHtcbiAgICBsaW5lLnVwZGF0ZShwb3NpdGlvbik7XG4gIH1cblxuICB0aGlzLl9hc3luY0hpZGUoKTtcbn07XG5cblNuYXBwaW5nLnByb3RvdHlwZS5nZXRTbmFwTGluZSA9IGZ1bmN0aW9uKG9yaWVudGF0aW9uKSB7XG4gIGlmICghdGhpcy5fc25hcExpbmVzKSB7XG4gICAgdGhpcy5fY3JlYXRlU25hcExpbmVzKCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fc25hcExpbmVzW29yaWVudGF0aW9uXTtcbn07XG5cblNuYXBwaW5nLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24oKSB7XG4gIGZvckVhY2godGhpcy5fc25hcExpbmVzLCBmdW5jdGlvbihzbmFwTGluZSkge1xuICAgIHNuYXBMaW5lLnVwZGF0ZSgpO1xuICB9KTtcbn07XG4iLCJpbXBvcnQgQ3JlYXRlTW92ZVNuYXBwaW5nIGZyb20gJy4vQ3JlYXRlTW92ZVNuYXBwaW5nJztcbmltcG9ydCBSZXNpemVTbmFwcGluZyBmcm9tICcuL1Jlc2l6ZVNuYXBwaW5nJztcbmltcG9ydCBTbmFwcGluZyBmcm9tICcuL1NuYXBwaW5nJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogW1xuICAgICdjcmVhdGVNb3ZlU25hcHBpbmcnLFxuICAgICdyZXNpemVTbmFwcGluZycsXG4gICAgJ3NuYXBwaW5nJ1xuICBdLFxuICBjcmVhdGVNb3ZlU25hcHBpbmc6IFsgJ3R5cGUnLCBDcmVhdGVNb3ZlU25hcHBpbmcgXSxcbiAgcmVzaXplU25hcHBpbmc6IFsgJ3R5cGUnLCBSZXNpemVTbmFwcGluZyBdLFxuICBzbmFwcGluZzogWyAndHlwZScsIFNuYXBwaW5nIF1cbn07IiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaWx0ZXIsXG4gIGZvckVhY2gsXG4gIGlzTnVtYmVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgYXNUUkJMIH0gZnJvbSAnLi4vLi4vbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQgeyBnZXRCQm94IH0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbmltcG9ydCB7IGdldERpcmVjdGlvbiB9IGZyb20gJy4vU3BhY2VVdGlsJztcblxuaW1wb3J0IHsgaGFzUHJpbWFyeU1vZGlmaWVyIH0gZnJvbSAnLi4vLi4vdXRpbC9Nb3VzZSc7XG5cbmltcG9ydCB7IHNldCBhcyBzZXRDdXJzb3IgfSBmcm9tICcuLi8uLi91dGlsL0N1cnNvcic7XG5cbmltcG9ydCB7IHNlbGZBbmRBbGxDaGlsZHJlbiB9IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG52YXIgYWJzID0gTWF0aC5hYnMsXG4gICAgcm91bmQgPSBNYXRoLnJvdW5kO1xuXG52YXIgQVhJU19UT19ESU1FTlNJT04gPSB7XG4gIHg6ICd3aWR0aCcsXG4gIHk6ICdoZWlnaHQnXG59O1xuXG52YXIgQ1VSU09SX0NST1NTSEFJUiA9ICdjcm9zc2hhaXInO1xuXG52YXIgRElSRUNUSU9OX1RPX1RSQkwgPSB7XG4gIG46ICd0b3AnLFxuICB3OiAnbGVmdCcsXG4gIHM6ICdib3R0b20nLFxuICBlOiAncmlnaHQnXG59O1xuXG52YXIgSElHSF9QUklPUklUWSA9IDE1MDA7XG5cbnZhciBESVJFQ1RJT05fVE9fT1BQT1NJVEUgPSB7XG4gIG46ICdzJyxcbiAgdzogJ2UnLFxuICBzOiAnbicsXG4gIGU6ICd3J1xufTtcblxudmFyIFBBRERJTkcgPSAyMDtcblxuXG4vKipcbiAqIEFkZCBvciByZW1vdmUgc3BhY2UgYnkgbW92aW5nIGFuZCByZXNpemluZyBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge0RyYWdnaW5nfSBkcmFnZ2luZ1xuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKiBAcGFyYW0ge1J1bGVzfSBydWxlc1xuICogQHBhcmFtIHt0b29sTWFuYWdlcn0gdG9vbE1hbmFnZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gU3BhY2VUb29sKGNhbnZhcywgZHJhZ2dpbmcsIGV2ZW50QnVzLCBtb2RlbGluZywgcnVsZXMsIHRvb2xNYW5hZ2VyKSB7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fZHJhZ2dpbmcgPSBkcmFnZ2luZztcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fcnVsZXMgPSBydWxlcztcbiAgdGhpcy5fdG9vbE1hbmFnZXIgPSB0b29sTWFuYWdlcjtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdG9vbE1hbmFnZXIucmVnaXN0ZXJUb29sKCdzcGFjZScsIHtcbiAgICB0b29sOiAnc3BhY2VUb29sLnNlbGVjdGlvbicsXG4gICAgZHJhZ2dpbmc6ICdzcGFjZVRvb2wnXG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdzcGFjZVRvb2wuc2VsZWN0aW9uLmVuZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZXZlbnRCdXMub25jZSgnc3BhY2VUb29sLnNlbGVjdGlvbi5lbmRlZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgc2VsZi5hY3RpdmF0ZU1ha2VTcGFjZShldmVudC5vcmlnaW5hbEV2ZW50KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ3NwYWNlVG9vbC5tb3ZlJywgSElHSF9QUklPUklUWSAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBpbml0aWFsaXplZCA9IGNvbnRleHQuaW5pdGlhbGl6ZWQ7XG5cbiAgICBpZiAoIWluaXRpYWxpemVkKSB7XG4gICAgICBpbml0aWFsaXplZCA9IGNvbnRleHQuaW5pdGlhbGl6ZWQgPSBzZWxmLmluaXQoZXZlbnQsIGNvbnRleHQpO1xuICAgIH1cblxuICAgIGlmIChpbml0aWFsaXplZCkge1xuICAgICAgZW5zdXJlQ29uc3RyYWludHMoZXZlbnQpO1xuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ3NwYWNlVG9vbC5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgYXhpcyA9IGNvbnRleHQuYXhpcyxcbiAgICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXG4gICAgICAgIG1vdmluZ1NoYXBlcyA9IGNvbnRleHQubW92aW5nU2hhcGVzLFxuICAgICAgICByZXNpemluZ1NoYXBlcyA9IGNvbnRleHQucmVzaXppbmdTaGFwZXMsXG4gICAgICAgIHN0YXJ0ID0gY29udGV4dC5zdGFydDtcblxuICAgIGlmICghY29udGV4dC5pbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGVuc3VyZUNvbnN0cmFpbnRzKGV2ZW50KTtcblxuICAgIHZhciBkZWx0YSA9IHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwXG4gICAgfTtcblxuICAgIGRlbHRhWyBheGlzIF0gPSByb3VuZChldmVudFsgJ2QnICsgYXhpcyBdKTtcblxuICAgIHNlbGYubWFrZVNwYWNlKG1vdmluZ1NoYXBlcywgcmVzaXppbmdTaGFwZXMsIGRlbHRhLCBkaXJlY3Rpb24sIHN0YXJ0KTtcblxuICAgIGV2ZW50QnVzLm9uY2UoJ3NwYWNlVG9vbC5lbmRlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICAgIC8vIGFjdGl2YXRlIHNwYWNlIHRvb2wgc2VsZWN0aW9uIGFmdGVyIG1ha2Ugc3BhY2VcbiAgICAgIHNlbGYuYWN0aXZhdGVTZWxlY3Rpb24oZXZlbnQub3JpZ2luYWxFdmVudCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5TcGFjZVRvb2wuJGluamVjdCA9IFtcbiAgJ2NhbnZhcycsXG4gICdkcmFnZ2luZycsXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZycsXG4gICdydWxlcycsXG4gICd0b29sTWFuYWdlcidcbl07XG5cbi8qKlxuICogQWN0aXZhdGUgc3BhY2UgdG9vbCBzZWxlY3Rpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XG4gKiBAcGFyYW0ge2Jvb2xlYW59IGF1dG9BY3RpdmF0ZVxuICovXG5TcGFjZVRvb2wucHJvdG90eXBlLmFjdGl2YXRlU2VsZWN0aW9uID0gZnVuY3Rpb24oZXZlbnQsIGF1dG9BY3RpdmF0ZSwgcmVhY3RpdmF0ZSkge1xuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnc3BhY2VUb29sLnNlbGVjdGlvbicsIHtcbiAgICBhdXRvQWN0aXZhdGU6IGF1dG9BY3RpdmF0ZSxcbiAgICBjdXJzb3I6IENVUlNPUl9DUk9TU0hBSVIsXG4gICAgZGF0YToge1xuICAgICAgY29udGV4dDoge1xuICAgICAgICByZWFjdGl2YXRlOiByZWFjdGl2YXRlXG4gICAgICB9XG4gICAgfSxcbiAgICB0cmFwQ2xpY2s6IGZhbHNlXG4gIH0pO1xufTtcblxuLyoqXG4gKiBBY3RpdmF0ZSBzcGFjZSB0b29sIG1ha2Ugc3BhY2UuXG4gKlxuICogQHBhcmFtICB7TW91c2VFdmVudH0gZXZlbnRcbiAqL1xuU3BhY2VUb29sLnByb3RvdHlwZS5hY3RpdmF0ZU1ha2VTcGFjZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2RyYWdnaW5nLmluaXQoZXZlbnQsICdzcGFjZVRvb2wnLCB7XG4gICAgYXV0b0FjdGl2YXRlOiB0cnVlLFxuICAgIGN1cnNvcjogQ1VSU09SX0NST1NTSEFJUixcbiAgICBkYXRhOiB7XG4gICAgICBjb250ZXh0OiB7fVxuICAgIH1cbiAgfSk7XG59O1xuXG4vKipcbiAqIE1ha2Ugc3BhY2UuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8ZGpzLm1vZGVsLlNoYXBlPn0gbW92aW5nU2hhcGVzXG4gKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuU2hhcGU+fSByZXNpemluZ1NoYXBlc1xuICogQHBhcmFtICB7T2JqZWN0fSBkZWx0YVxuICogQHBhcmFtICB7bnVtYmVyfSBkZWx0YS54XG4gKiBAcGFyYW0gIHtudW1iZXJ9IGRlbHRhLnlcbiAqIEBwYXJhbSAge3N0cmluZ30gZGlyZWN0aW9uXG4gKiBAcGFyYW0gIHtudW1iZXJ9IHN0YXJ0XG4gKi9cblNwYWNlVG9vbC5wcm90b3R5cGUubWFrZVNwYWNlID0gZnVuY3Rpb24obW92aW5nU2hhcGVzLCByZXNpemluZ1NoYXBlcywgZGVsdGEsIGRpcmVjdGlvbiwgc3RhcnQpIHtcbiAgcmV0dXJuIHRoaXMuX21vZGVsaW5nLmNyZWF0ZVNwYWNlKG1vdmluZ1NoYXBlcywgcmVzaXppbmdTaGFwZXMsIGRlbHRhLCBkaXJlY3Rpb24sIHN0YXJ0KTtcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBtYWtlIHNwYWNlIGFuZCByZXR1cm4gdHJ1ZSBpZiB0aGF0IHdhcyBzdWNjZXNzZnVsLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5TcGFjZVRvb2wucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbihldmVudCwgY29udGV4dCkge1xuICB2YXIgYXhpcyA9IGFicyhldmVudC5keCkgPiBhYnMoZXZlbnQuZHkpID8gJ3gnIDogJ3knLFxuICAgICAgZGVsdGEgPSBldmVudFsgJ2QnICsgYXhpcyBdLFxuICAgICAgc3RhcnQgPSBldmVudFsgYXhpcyBdIC0gZGVsdGE7XG5cbiAgaWYgKGFicyhkZWx0YSkgPCA1KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gaW52ZXJ0IGRlbHRhIHRvIHJlbW92ZSBzcGFjZSB3aGVuIG1vdmluZyBsZWZ0XG4gIGlmIChkZWx0YSA8IDApIHtcbiAgICBkZWx0YSAqPSAtMTtcbiAgfVxuXG4gIC8vIGludmVydCBkZWx0YSB0byBhZGQvcmVtb3ZlIHNwYWNlIHdoZW4gcmVtb3ZpbmcvYWRkaW5nIHNwYWNlIGlmIG1vZGlmaWVyIGtleSBpcyBwcmVzc2VkXG4gIGlmIChoYXNQcmltYXJ5TW9kaWZpZXIoZXZlbnQpKSB7XG4gICAgZGVsdGEgKj0gLTE7XG4gIH1cblxuICB2YXIgZGlyZWN0aW9uID0gZ2V0RGlyZWN0aW9uKGF4aXMsIGRlbHRhKTtcblxuICB2YXIgcm9vdCA9IHRoaXMuX2NhbnZhcy5nZXRSb290RWxlbWVudCgpO1xuXG4gIHZhciBjaGlsZHJlbiA9IHNlbGZBbmRBbGxDaGlsZHJlbihyb290LCB0cnVlKTtcblxuICB2YXIgZWxlbWVudHMgPSB0aGlzLmNhbGN1bGF0ZUFkanVzdG1lbnRzKGNoaWxkcmVuLCBheGlzLCBkZWx0YSwgc3RhcnQpO1xuXG4gIHZhciBtaW5EaW1lbnNpb25zID0gdGhpcy5fZXZlbnRCdXMuZmlyZSgnc3BhY2VUb29sLmdldE1pbkRpbWVuc2lvbnMnLCB7XG4gICAgYXhpczogYXhpcyxcbiAgICBkaXJlY3Rpb246IGRpcmVjdGlvbixcbiAgICBzaGFwZXM6IGVsZW1lbnRzLnJlc2l6aW5nU2hhcGVzLFxuICAgIHN0YXJ0OiBzdGFydFxuICB9KTtcblxuICB2YXIgc3BhY2VUb29sQ29uc3RyYWludHMgPSBnZXRTcGFjZVRvb2xDb25zdHJhaW50cyhlbGVtZW50cywgYXhpcywgZGlyZWN0aW9uLCBzdGFydCwgbWluRGltZW5zaW9ucyk7XG5cbiAgYXNzaWduKFxuICAgIGNvbnRleHQsXG4gICAgZWxlbWVudHMsXG4gICAge1xuICAgICAgYXhpczogYXhpcyxcbiAgICAgIGRpcmVjdGlvbjogZGlyZWN0aW9uLFxuICAgICAgc3BhY2VUb29sQ29uc3RyYWludHM6IHNwYWNlVG9vbENvbnN0cmFpbnRzLFxuICAgICAgc3RhcnQ6IHN0YXJ0XG4gICAgfVxuICApO1xuXG4gIHNldEN1cnNvcigncmVzaXplLScgKyAoYXhpcyA9PT0gJ3gnID8gJ2V3JyA6ICducycpKTtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogR2V0IGVsZW1lbnRzIHRvIGJlIG1vdmVkIGFuZCByZXNpemVkLlxuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGF4aXNcbiAqIEBwYXJhbSAge251bWJlcn0gZGVsdGFcbiAqIEBwYXJhbSAge251bWJlcn0gc3RhcnRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cblNwYWNlVG9vbC5wcm90b3R5cGUuY2FsY3VsYXRlQWRqdXN0bWVudHMgPSBmdW5jdGlvbihlbGVtZW50cywgYXhpcywgZGVsdGEsIHN0YXJ0KSB7XG4gIHZhciBydWxlcyA9IHRoaXMuX3J1bGVzO1xuXG4gIHZhciBtb3ZpbmdTaGFwZXMgPSBbXSxcbiAgICAgIHJlc2l6aW5nU2hhcGVzID0gW107XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGlmICghZWxlbWVudC5wYXJlbnQgfHwgaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNoYXBlU3RhcnQgPSBlbGVtZW50WyBheGlzIF0sXG4gICAgICAgIHNoYXBlRW5kID0gc2hhcGVTdGFydCArIGVsZW1lbnRbIEFYSVNfVE9fRElNRU5TSU9OWyBheGlzIF0gXTtcblxuICAgIC8vIHNoYXBlIHRvIGJlIG1vdmVkXG4gICAgaWYgKChkZWx0YSA+IDAgJiYgc2hhcGVTdGFydCA+IHN0YXJ0KSB8fCAoZGVsdGEgPCAwICYmIHNoYXBlRW5kIDwgc3RhcnQpKSB7XG4gICAgICByZXR1cm4gbW92aW5nU2hhcGVzLnB1c2goZWxlbWVudCk7XG4gICAgfVxuXG4gICAgLy8gc2hhcGUgdG8gYmUgcmVzaXplZFxuICAgIGlmIChzaGFwZVN0YXJ0IDwgc3RhcnQgJiZcbiAgICAgIHNoYXBlRW5kID4gc3RhcnQgJiZcbiAgICAgIHJ1bGVzLmFsbG93ZWQoJ3NoYXBlLnJlc2l6ZScsIHsgc2hhcGU6IGVsZW1lbnQgfSlcbiAgICApIHtcblxuICAgICAgcmV0dXJuIHJlc2l6aW5nU2hhcGVzLnB1c2goZWxlbWVudCk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIG1vdmluZ1NoYXBlczogbW92aW5nU2hhcGVzLFxuICAgIHJlc2l6aW5nU2hhcGVzOiByZXNpemluZ1NoYXBlc1xuICB9O1xufTtcblxuU3BhY2VUb29sLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuaXNBY3RpdmUoKSkge1xuICAgIHRoaXMuX2RyYWdnaW5nLmNhbmNlbCgpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuYWN0aXZhdGVTZWxlY3Rpb24oKTtcbiAgfVxufTtcblxuU3BhY2VUb29sLnByb3RvdHlwZS5pc0FjdGl2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29udGV4dCA9IHRoaXMuX2RyYWdnaW5nLmNvbnRleHQoKTtcblxuICByZXR1cm4gY29udGV4dCAmJiAvXnNwYWNlVG9vbC8udGVzdChjb250ZXh0LnByZWZpeCk7XG59O1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gYWRkUGFkZGluZyh0cmJsKSB7XG4gIHJldHVybiB7XG4gICAgdG9wOiB0cmJsLnRvcCAtIFBBRERJTkcsXG4gICAgcmlnaHQ6IHRyYmwucmlnaHQgKyBQQURESU5HLFxuICAgIGJvdHRvbTogdHJibC5ib3R0b20gKyBQQURESU5HLFxuICAgIGxlZnQ6IHRyYmwubGVmdCAtIFBBRERJTkdcbiAgfTtcbn1cblxuZnVuY3Rpb24gZW5zdXJlQ29uc3RyYWludHMoZXZlbnQpIHtcbiAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMgPSBjb250ZXh0LnNwYWNlVG9vbENvbnN0cmFpbnRzO1xuXG4gIGlmICghc3BhY2VUb29sQ29uc3RyYWludHMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgeCwgeTtcblxuICBpZiAoaXNOdW1iZXIoc3BhY2VUb29sQ29uc3RyYWludHMubGVmdCkpIHtcbiAgICB4ID0gTWF0aC5tYXgoZXZlbnQueCwgc3BhY2VUb29sQ29uc3RyYWludHMubGVmdCk7XG5cbiAgICBldmVudC5keCA9IGV2ZW50LmR4ICsgeCAtIGV2ZW50Lng7XG4gICAgZXZlbnQueCA9IHg7XG4gIH1cblxuICBpZiAoaXNOdW1iZXIoc3BhY2VUb29sQ29uc3RyYWludHMucmlnaHQpKSB7XG4gICAgeCA9IE1hdGgubWluKGV2ZW50LngsIHNwYWNlVG9vbENvbnN0cmFpbnRzLnJpZ2h0KTtcblxuICAgIGV2ZW50LmR4ID0gZXZlbnQuZHggKyB4IC0gZXZlbnQueDtcbiAgICBldmVudC54ID0geDtcbiAgfVxuXG4gIGlmIChpc051bWJlcihzcGFjZVRvb2xDb25zdHJhaW50cy50b3ApKSB7XG4gICAgeSA9IE1hdGgubWF4KGV2ZW50LnksIHNwYWNlVG9vbENvbnN0cmFpbnRzLnRvcCk7XG5cbiAgICBldmVudC5keSA9IGV2ZW50LmR5ICsgeSAtIGV2ZW50Lnk7XG4gICAgZXZlbnQueSA9IHk7XG4gIH1cblxuICBpZiAoaXNOdW1iZXIoc3BhY2VUb29sQ29uc3RyYWludHMuYm90dG9tKSkge1xuICAgIHkgPSBNYXRoLm1pbihldmVudC55LCBzcGFjZVRvb2xDb25zdHJhaW50cy5ib3R0b20pO1xuXG4gICAgZXZlbnQuZHkgPSBldmVudC5keSArIHkgLSBldmVudC55O1xuICAgIGV2ZW50LnkgPSB5O1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFNwYWNlVG9vbENvbnN0cmFpbnRzKGVsZW1lbnRzLCBheGlzLCBkaXJlY3Rpb24sIHN0YXJ0LCBtaW5EaW1lbnNpb25zKSB7XG4gIHZhciBtb3ZpbmdTaGFwZXMgPSBlbGVtZW50cy5tb3ZpbmdTaGFwZXMsXG4gICAgICByZXNpemluZ1NoYXBlcyA9IGVsZW1lbnRzLnJlc2l6aW5nU2hhcGVzO1xuXG4gIGlmICghcmVzaXppbmdTaGFwZXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHNwYWNlVG9vbENvbnN0cmFpbnRzID0ge30sXG4gICAgICBtaW4sXG4gICAgICBtYXg7XG5cbiAgZm9yRWFjaChyZXNpemluZ1NoYXBlcywgZnVuY3Rpb24ocmVzaXppbmdTaGFwZSkge1xuICAgIHZhciByZXNpemluZ1NoYXBlQkJveCA9IGFzVFJCTChyZXNpemluZ1NoYXBlKTtcblxuICAgIC8vIGZpbmQgY2hpbGRyZW4gdGhhdCBhcmUgbm90IG1vdmluZyBvciByZXNpemluZ1xuICAgIHZhciBub25Nb3ZpbmdSZXNpemluZ0NoaWxkcmVuID0gZmlsdGVyKHJlc2l6aW5nU2hhcGUuY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICByZXR1cm4gIWlzQ29ubmVjdGlvbihjaGlsZCkgJiZcbiAgICAgICAgIWlzTGFiZWwoY2hpbGQpICYmXG4gICAgICAgICFpbmNsdWRlcyhtb3ZpbmdTaGFwZXMsIGNoaWxkKSAmJlxuICAgICAgICAhaW5jbHVkZXMocmVzaXppbmdTaGFwZXMsIGNoaWxkKTtcbiAgICB9KTtcblxuICAgIC8vIGZpbmQgY2hpbGRyZW4gdGhhdCBhcmUgbW92aW5nXG4gICAgdmFyIG1vdmluZ0NoaWxkcmVuID0gZmlsdGVyKHJlc2l6aW5nU2hhcGUuY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICByZXR1cm4gIWlzQ29ubmVjdGlvbihjaGlsZCkgJiYgIWlzTGFiZWwoY2hpbGQpICYmIGluY2x1ZGVzKG1vdmluZ1NoYXBlcywgY2hpbGQpO1xuICAgIH0pO1xuXG4gICAgdmFyIG1pbk9yTWF4LFxuICAgICAgICBub25Nb3ZpbmdSZXNpemluZ0NoaWxkcmVuQkJveCxcbiAgICAgICAgbW92aW5nQ2hpbGRyZW5CQm94O1xuXG4gICAgaWYgKG5vbk1vdmluZ1Jlc2l6aW5nQ2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICBub25Nb3ZpbmdSZXNpemluZ0NoaWxkcmVuQkJveCA9IGFkZFBhZGRpbmcoYXNUUkJMKGdldEJCb3gobm9uTW92aW5nUmVzaXppbmdDaGlsZHJlbikpKTtcblxuICAgICAgbWluT3JNYXggPSBzdGFydCAtXG4gICAgICAgIHJlc2l6aW5nU2hhcGVCQm94WyBESVJFQ1RJT05fVE9fVFJCTFsgZGlyZWN0aW9uIF0gXSArXG4gICAgICAgIG5vbk1vdmluZ1Jlc2l6aW5nQ2hpbGRyZW5CQm94WyBESVJFQ1RJT05fVE9fVFJCTFsgZGlyZWN0aW9uIF0gXTtcblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ24nKSB7XG4gICAgICAgIHNwYWNlVG9vbENvbnN0cmFpbnRzLmJvdHRvbSA9IG1heCA9IGlzTnVtYmVyKG1heCkgPyBNYXRoLm1pbihtYXgsIG1pbk9yTWF4KSA6IG1pbk9yTWF4O1xuICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT09ICd3Jykge1xuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy5yaWdodCA9IG1heCA9IGlzTnVtYmVyKG1heCkgPyBNYXRoLm1pbihtYXgsIG1pbk9yTWF4KSA6IG1pbk9yTWF4O1xuICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT09ICdzJykge1xuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy50b3AgPSBtaW4gPSBpc051bWJlcihtaW4pID8gTWF0aC5tYXgobWluLCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAnZScpIHtcbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMubGVmdCA9IG1pbiA9IGlzTnVtYmVyKG1pbikgPyBNYXRoLm1heChtaW4sIG1pbk9yTWF4KSA6IG1pbk9yTWF4O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtb3ZpbmdDaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIG1vdmluZ0NoaWxkcmVuQkJveCA9IGFkZFBhZGRpbmcoYXNUUkJMKGdldEJCb3gobW92aW5nQ2hpbGRyZW4pKSk7XG5cbiAgICAgIG1pbk9yTWF4ID0gc3RhcnQgLVxuICAgICAgICBtb3ZpbmdDaGlsZHJlbkJCb3hbIERJUkVDVElPTl9UT19UUkJMWyBESVJFQ1RJT05fVE9fT1BQT1NJVEVbIGRpcmVjdGlvbiBdIF0gXSArXG4gICAgICAgIHJlc2l6aW5nU2hhcGVCQm94WyBESVJFQ1RJT05fVE9fVFJCTFsgRElSRUNUSU9OX1RPX09QUE9TSVRFWyBkaXJlY3Rpb24gXSBdIF07XG5cbiAgICAgIGlmIChkaXJlY3Rpb24gPT09ICduJykge1xuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy5ib3R0b20gPSBtYXggPSBpc051bWJlcihtYXgpID8gTWF0aC5taW4obWF4LCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAndycpIHtcbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMucmlnaHQgPSBtYXggPSBpc051bWJlcihtYXgpID8gTWF0aC5taW4obWF4LCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAncycpIHtcbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMudG9wID0gbWluID0gaXNOdW1iZXIobWluKSA/IE1hdGgubWF4KG1pbiwgbWluT3JNYXgpIDogbWluT3JNYXg7XG4gICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ2UnKSB7XG4gICAgICAgIHNwYWNlVG9vbENvbnN0cmFpbnRzLmxlZnQgPSBtaW4gPSBpc051bWJlcihtaW4pID8gTWF0aC5tYXgobWluLCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVzaXppbmdTaGFwZU1pbkRpbWVuc2lvbnMgPSBtaW5EaW1lbnNpb25zICYmIG1pbkRpbWVuc2lvbnNbIHJlc2l6aW5nU2hhcGUuaWQgXTtcblxuICAgIGlmIChyZXNpemluZ1NoYXBlTWluRGltZW5zaW9ucykge1xuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ24nKSB7XG4gICAgICAgIG1pbk9yTWF4ID0gc3RhcnQgK1xuICAgICAgICAgIHJlc2l6aW5nU2hhcGVbIEFYSVNfVE9fRElNRU5TSU9OIFsgYXhpcyBdIF0gLVxuICAgICAgICAgIHJlc2l6aW5nU2hhcGVNaW5EaW1lbnNpb25zWyBBWElTX1RPX0RJTUVOU0lPTlsgYXhpcyBdIF07XG5cbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMuYm90dG9tID0gbWF4ID0gaXNOdW1iZXIobWF4KSA/IE1hdGgubWluKG1heCwgbWluT3JNYXgpIDogbWluT3JNYXg7XG4gICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ3cnKSB7XG4gICAgICAgIG1pbk9yTWF4ID0gc3RhcnQgK1xuICAgICAgICAgIHJlc2l6aW5nU2hhcGVbIEFYSVNfVE9fRElNRU5TSU9OIFsgYXhpcyBdIF0gLVxuICAgICAgICAgIHJlc2l6aW5nU2hhcGVNaW5EaW1lbnNpb25zWyBBWElTX1RPX0RJTUVOU0lPTlsgYXhpcyBdIF07XG5cbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMucmlnaHQgPSBtYXggPSBpc051bWJlcihtYXgpID8gTWF0aC5taW4obWF4LCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAncycpIHtcbiAgICAgICAgbWluT3JNYXggPSBzdGFydCAtXG4gICAgICAgICAgcmVzaXppbmdTaGFwZVsgQVhJU19UT19ESU1FTlNJT04gWyBheGlzIF0gXSArXG4gICAgICAgICAgcmVzaXppbmdTaGFwZU1pbkRpbWVuc2lvbnNbIEFYSVNfVE9fRElNRU5TSU9OWyBheGlzIF0gXTtcblxuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy50b3AgPSBtaW4gPSBpc051bWJlcihtaW4pID8gTWF0aC5tYXgobWluLCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAnZScpIHtcbiAgICAgICAgbWluT3JNYXggPSBzdGFydCAtXG4gICAgICAgICAgcmVzaXppbmdTaGFwZVsgQVhJU19UT19ESU1FTlNJT04gWyBheGlzIF0gXSArXG4gICAgICAgICAgcmVzaXppbmdTaGFwZU1pbkRpbWVuc2lvbnNbIEFYSVNfVE9fRElNRU5TSU9OWyBheGlzIF0gXTtcblxuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy5sZWZ0ID0gbWluID0gaXNOdW1iZXIobWluKSA/IE1hdGgubWF4KG1pbiwgbWluT3JNYXgpIDogbWluT3JNYXg7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gc3BhY2VUb29sQ29uc3RyYWludHM7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVzKGFycmF5LCBpdGVtKSB7XG4gIHJldHVybiBhcnJheS5pbmRleE9mKGl0ZW0pICE9PSAtMTtcbn1cblxuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuICEhZWxlbWVudC53YXlwb2ludHM7XG59XG5cbmZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gISFlbGVtZW50LmxhYmVsVGFyZ2V0O1xufSIsImltcG9ydCB7XG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgTUFSS0VSX0RSQUdHSU5HID0gJ2Rqcy1kcmFnZ2luZycsXG4gICAgTUFSS0VSX1JFU0laSU5HID0gJ2Rqcy1yZXNpemluZyc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSAyNTA7XG5cbmltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICByZW1vdmUgYXMgc3ZnUmVtb3ZlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxuaW1wb3J0IHtcbiAgdHJhbnNsYXRlXG59IGZyb20gJy4uLy4uL3V0aWwvU3ZnVHJhbnNmb3JtVXRpbCc7XG5cbnZhciBtYXggPSBNYXRoLm1heDtcblxuXG4vKipcbiAqIFByb3ZpZGVzIHByZXZpZXdzIGZvciBzZWxlY3RpbmcvbW92aW5nL3Jlc2l6aW5nIHNoYXBlcyB3aGVuIGNyZWF0aW5nL3JlbW92aW5nIHNwYWNlLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge1N0eWxlc30gc3R5bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNwYWNlVG9vbFByZXZpZXcoXG4gICAgZXZlbnRCdXMsIGVsZW1lbnRSZWdpc3RyeSwgY2FudmFzLFxuICAgIHN0eWxlcywgcHJldmlld1N1cHBvcnQpIHtcblxuICBmdW5jdGlvbiBhZGRQcmV2aWV3R2Z4KGNvbGxlY3Rpb24sIGRyYWdHcm91cCkge1xuICAgIGZvckVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcHJldmlld1N1cHBvcnQuYWRkRHJhZ2dlcihlbGVtZW50LCBkcmFnR3JvdXApO1xuXG4gICAgICBjYW52YXMuYWRkTWFya2VyKGVsZW1lbnQsIE1BUktFUl9EUkFHR0lORyk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgY3Jvc3NoYWlyXG4gIGV2ZW50QnVzLm9uKCdzcGFjZVRvb2wuc2VsZWN0aW9uLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgc3BhY2UgPSBjYW52YXMuZ2V0TGF5ZXIoJ3NwYWNlJyksXG4gICAgICAgIGNvbnRleHQgPSBldmVudC5jb250ZXh0O1xuXG4gICAgdmFyIG9yaWVudGF0aW9uID0ge1xuICAgICAgeDogJ00gMCwtMTAwMDAgTCAwLDEwMDAwJyxcbiAgICAgIHk6ICdNIC0xMDAwMCwwIEwgMTAwMDAsMCdcbiAgICB9O1xuXG4gICAgdmFyIGNyb3NzaGFpckdyb3VwID0gc3ZnQ3JlYXRlKCdnJyk7XG4gICAgc3ZnQXR0cihjcm9zc2hhaXJHcm91cCwgc3R5bGVzLmNscygnZGpzLWNyb3NzaGFpci1ncm91cCcsIFsgJ25vLWV2ZW50cycgXSkpO1xuXG4gICAgc3ZnQXBwZW5kKHNwYWNlLCBjcm9zc2hhaXJHcm91cCk7XG5cbiAgICAvLyBob3Jpem9udGFsIHBhdGhcbiAgICB2YXIgcGF0aFggPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICBzdmdBdHRyKHBhdGhYLCAnZCcsIG9yaWVudGF0aW9uLngpO1xuICAgIHN2Z0NsYXNzZXMocGF0aFgpLmFkZCgnZGpzLWNyb3NzaGFpcicpO1xuXG4gICAgc3ZnQXBwZW5kKGNyb3NzaGFpckdyb3VwLCBwYXRoWCk7XG5cbiAgICAvLyB2ZXJ0aWNhbCBwYXRoXG4gICAgdmFyIHBhdGhZID0gc3ZnQ3JlYXRlKCdwYXRoJyk7XG4gICAgc3ZnQXR0cihwYXRoWSwgJ2QnLCBvcmllbnRhdGlvbi55KTtcbiAgICBzdmdDbGFzc2VzKHBhdGhZKS5hZGQoJ2Rqcy1jcm9zc2hhaXInKTtcblxuICAgIHN2Z0FwcGVuZChjcm9zc2hhaXJHcm91cCwgcGF0aFkpO1xuXG4gICAgY29udGV4dC5jcm9zc2hhaXJHcm91cCA9IGNyb3NzaGFpckdyb3VwO1xuICB9KTtcblxuICAvLyB1cGRhdGUgY3Jvc3NoYWlyXG4gIGV2ZW50QnVzLm9uKCdzcGFjZVRvb2wuc2VsZWN0aW9uLm1vdmUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjcm9zc2hhaXJHcm91cCA9IGV2ZW50LmNvbnRleHQuY3Jvc3NoYWlyR3JvdXA7XG5cbiAgICB0cmFuc2xhdGUoY3Jvc3NoYWlyR3JvdXAsIGV2ZW50LngsIGV2ZW50LnkpO1xuICB9KTtcblxuICAvLyByZW1vdmUgY3Jvc3NoYWlyXG4gIGV2ZW50QnVzLm9uKCdzcGFjZVRvb2wuc2VsZWN0aW9uLmNsZWFudXAnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY3Jvc3NoYWlyR3JvdXAgPSBjb250ZXh0LmNyb3NzaGFpckdyb3VwO1xuXG4gICAgaWYgKGNyb3NzaGFpckdyb3VwKSB7XG4gICAgICBzdmdSZW1vdmUoY3Jvc3NoYWlyR3JvdXApO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWRkIGFuZCB1cGRhdGUgbW92ZS9yZXNpemUgcHJldmlld3NcbiAgZXZlbnRCdXMub24oJ3NwYWNlVG9vbC5tb3ZlJywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBsaW5lID0gY29udGV4dC5saW5lLFxuICAgICAgICBheGlzID0gY29udGV4dC5heGlzLFxuICAgICAgICBtb3ZpbmdTaGFwZXMgPSBjb250ZXh0Lm1vdmluZ1NoYXBlcyxcbiAgICAgICAgcmVzaXppbmdTaGFwZXMgPSBjb250ZXh0LnJlc2l6aW5nU2hhcGVzO1xuXG4gICAgaWYgKCFjb250ZXh0LmluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjb250ZXh0LmRyYWdHcm91cCkge1xuICAgICAgdmFyIHNwYWNlTGF5ZXIgPSBjYW52YXMuZ2V0TGF5ZXIoJ3NwYWNlJyk7XG5cbiAgICAgIGxpbmUgPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICAgIHN2Z0F0dHIobGluZSwgJ2QnLCAnTTAsMCBMMCwwJyk7XG4gICAgICBzdmdDbGFzc2VzKGxpbmUpLmFkZCgnZGpzLWNyb3NzaGFpcicpO1xuXG4gICAgICBzdmdBcHBlbmQoc3BhY2VMYXllciwgbGluZSk7XG5cbiAgICAgIGNvbnRleHQubGluZSA9IGxpbmU7XG5cbiAgICAgIHZhciBkcmFnR3JvdXAgPSBzdmdDcmVhdGUoJ2cnKTtcbiAgICAgIHN2Z0F0dHIoZHJhZ0dyb3VwLCBzdHlsZXMuY2xzKCdkanMtZHJhZy1ncm91cCcsIFsgJ25vLWV2ZW50cycgXSkpO1xuXG4gICAgICBzdmdBcHBlbmQoY2FudmFzLmdldERlZmF1bHRMYXllcigpLCBkcmFnR3JvdXApO1xuXG4gICAgICAvLyBzaGFwZXNcbiAgICAgIGFkZFByZXZpZXdHZngobW92aW5nU2hhcGVzLCBkcmFnR3JvdXApO1xuXG4gICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgdmFyIG1vdmluZ0Nvbm5lY3Rpb25zID0gY29udGV4dC5tb3ZpbmdDb25uZWN0aW9ucyA9IGVsZW1lbnRSZWdpc3RyeS5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICB2YXIgc291cmNlSXNNb3ZpbmcgPSBmYWxzZTtcblxuICAgICAgICBmb3JFYWNoKG1vdmluZ1NoYXBlcywgZnVuY3Rpb24oc2hhcGUpIHtcbiAgICAgICAgICBmb3JFYWNoKHNoYXBlLm91dGdvaW5nLCBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICBzb3VyY2VJc01vdmluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHZhciB0YXJnZXRJc01vdmluZyA9IGZhbHNlO1xuXG4gICAgICAgIGZvckVhY2gobW92aW5nU2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgICAgICAgIGZvckVhY2goc2hhcGUuaW5jb21pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50ID09PSBjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgIHRhcmdldElzTW92aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHNvdXJjZUlzUmVzaXppbmcgPSBmYWxzZTtcblxuICAgICAgICBmb3JFYWNoKHJlc2l6aW5nU2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgICAgICAgIGZvckVhY2goc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50ID09PSBjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgIHNvdXJjZUlzUmVzaXppbmcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICB2YXIgdGFyZ2V0SXNSZXNpemluZyA9IGZhbHNlO1xuXG4gICAgICAgIGZvckVhY2gocmVzaXppbmdTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICAgICAgZm9yRWFjaChzaGFwZS5pbmNvbWluZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT09IGNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgdGFyZ2V0SXNSZXNpemluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBpc0Nvbm5lY3Rpb24oZWxlbWVudClcbiAgICAgICAgICAmJiAoc291cmNlSXNNb3ZpbmcgfHwgc291cmNlSXNSZXNpemluZylcbiAgICAgICAgICAmJiAodGFyZ2V0SXNNb3ZpbmcgfHwgdGFyZ2V0SXNSZXNpemluZyk7XG4gICAgICB9KTtcblxuXG4gICAgICBhZGRQcmV2aWV3R2Z4KG1vdmluZ0Nvbm5lY3Rpb25zLCBkcmFnR3JvdXApO1xuXG4gICAgICBjb250ZXh0LmRyYWdHcm91cCA9IGRyYWdHcm91cDtcbiAgICB9XG5cbiAgICBpZiAoIWNvbnRleHQuZnJhbWVHcm91cCkge1xuICAgICAgdmFyIGZyYW1lR3JvdXAgPSBzdmdDcmVhdGUoJ2cnKTtcbiAgICAgIHN2Z0F0dHIoZnJhbWVHcm91cCwgc3R5bGVzLmNscygnZGpzLWZyYW1lLWdyb3VwJywgWyAnbm8tZXZlbnRzJyBdKSk7XG5cbiAgICAgIHN2Z0FwcGVuZChjYW52YXMuZ2V0RGVmYXVsdExheWVyKCksIGZyYW1lR3JvdXApO1xuXG4gICAgICB2YXIgZnJhbWVzID0gW107XG5cbiAgICAgIGZvckVhY2gocmVzaXppbmdTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICAgIHZhciBmcmFtZSA9IHByZXZpZXdTdXBwb3J0LmFkZEZyYW1lKHNoYXBlLCBmcmFtZUdyb3VwKTtcblxuICAgICAgICB2YXIgaW5pdGlhbEJvdW5kcyA9IGZyYW1lLmdldEJCb3goKTtcblxuICAgICAgICBmcmFtZXMucHVzaCh7XG4gICAgICAgICAgZWxlbWVudDogZnJhbWUsXG4gICAgICAgICAgaW5pdGlhbEJvdW5kczogaW5pdGlhbEJvdW5kc1xuICAgICAgICB9KTtcblxuICAgICAgICBjYW52YXMuYWRkTWFya2VyKHNoYXBlLCBNQVJLRVJfUkVTSVpJTkcpO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnRleHQuZnJhbWVHcm91cCA9IGZyYW1lR3JvdXA7XG4gICAgICBjb250ZXh0LmZyYW1lcyA9IGZyYW1lcztcbiAgICB9XG5cbiAgICB2YXIgb3JpZW50YXRpb24gPSB7XG4gICAgICB4OiAnTScgKyBldmVudC54ICsgJywgLTEwMDAwIEwnICsgZXZlbnQueCArICcsIDEwMDAwJyxcbiAgICAgIHk6ICdNIC0xMDAwMCwgJyArIGV2ZW50LnkgKyAnIEwgMTAwMDAsICcgKyBldmVudC55XG4gICAgfTtcblxuICAgIHN2Z0F0dHIobGluZSwgeyBkOiBvcmllbnRhdGlvblsgYXhpcyBdIH0pO1xuXG4gICAgdmFyIG9wcG9zaXRlID0geyB4OiAneScsIHk6ICd4JyB9O1xuICAgIHZhciBkZWx0YSA9IHsgeDogZXZlbnQuZHgsIHk6IGV2ZW50LmR5IH07XG4gICAgZGVsdGFbIG9wcG9zaXRlWyBjb250ZXh0LmF4aXMgXSBdID0gMDtcblxuICAgIC8vIHVwZGF0ZSBtb3ZlIHByZXZpZXdzXG4gICAgdHJhbnNsYXRlKGNvbnRleHQuZHJhZ0dyb3VwLCBkZWx0YS54LCBkZWx0YS55KTtcblxuICAgIC8vIHVwZGF0ZSByZXNpemUgcHJldmlld3NcbiAgICBmb3JFYWNoKGNvbnRleHQuZnJhbWVzLCBmdW5jdGlvbihmcmFtZSkge1xuICAgICAgdmFyIGVsZW1lbnQgPSBmcmFtZS5lbGVtZW50LFxuICAgICAgICAgIGluaXRpYWxCb3VuZHMgPSBmcmFtZS5pbml0aWFsQm91bmRzLFxuICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgIGhlaWdodDtcblxuICAgICAgaWYgKGNvbnRleHQuZGlyZWN0aW9uID09PSAnZScpIHtcbiAgICAgICAgc3ZnQXR0cihlbGVtZW50LCB7XG4gICAgICAgICAgd2lkdGg6IG1heChpbml0aWFsQm91bmRzLndpZHRoICsgZGVsdGEueCwgNSlcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aWR0aCA9IG1heChpbml0aWFsQm91bmRzLndpZHRoIC0gZGVsdGEueCwgNSk7XG5cbiAgICAgICAgc3ZnQXR0cihlbGVtZW50LCB7XG4gICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgIHg6IGluaXRpYWxCb3VuZHMueCArIGluaXRpYWxCb3VuZHMud2lkdGggLSB3aWR0aFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRleHQuZGlyZWN0aW9uID09PSAncycpIHtcbiAgICAgICAgc3ZnQXR0cihlbGVtZW50LCB7XG4gICAgICAgICAgaGVpZ2h0OiBtYXgoaW5pdGlhbEJvdW5kcy5oZWlnaHQgKyBkZWx0YS55LCA1KVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhlaWdodCA9IG1heChpbml0aWFsQm91bmRzLmhlaWdodCAtIGRlbHRhLnksIDUpO1xuXG4gICAgICAgIHN2Z0F0dHIoZWxlbWVudCwge1xuICAgICAgICAgIGhlaWdodDogaGVpZ2h0LFxuICAgICAgICAgIHk6IGluaXRpYWxCb3VuZHMueSArIGluaXRpYWxCb3VuZHMuaGVpZ2h0IC0gaGVpZ2h0XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gIH0pO1xuXG4gIC8vIHJlbW92ZSBtb3ZlL3Jlc2l6ZSBwcmV2aWV3c1xuICBldmVudEJ1cy5vbignc3BhY2VUb29sLmNsZWFudXAnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBtb3ZpbmdTaGFwZXMgPSBjb250ZXh0Lm1vdmluZ1NoYXBlcyxcbiAgICAgICAgbW92aW5nQ29ubmVjdGlvbnMgPSBjb250ZXh0Lm1vdmluZ0Nvbm5lY3Rpb25zLFxuICAgICAgICByZXNpemluZ1NoYXBlcyA9IGNvbnRleHQucmVzaXppbmdTaGFwZXMsXG4gICAgICAgIGxpbmUgPSBjb250ZXh0LmxpbmUsXG4gICAgICAgIGRyYWdHcm91cCA9IGNvbnRleHQuZHJhZ0dyb3VwLFxuICAgICAgICBmcmFtZUdyb3VwID0gY29udGV4dC5mcmFtZUdyb3VwO1xuXG4gICAgLy8gbW92aW5nIHNoYXBlc1xuICAgIGZvckVhY2gobW92aW5nU2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihzaGFwZSwgTUFSS0VSX0RSQUdHSU5HKTtcbiAgICB9KTtcblxuICAgIC8vIG1vdmluZyBjb25uZWN0aW9uc1xuICAgIGZvckVhY2gobW92aW5nQ29ubmVjdGlvbnMsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoY29ubmVjdGlvbiwgTUFSS0VSX0RSQUdHSU5HKTtcbiAgICB9KTtcblxuICAgIGlmIChkcmFnR3JvdXApIHtcbiAgICAgIHN2Z1JlbW92ZShsaW5lKTtcbiAgICAgIHN2Z1JlbW92ZShkcmFnR3JvdXApO1xuICAgIH1cblxuICAgIGZvckVhY2gocmVzaXppbmdTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICBjYW52YXMucmVtb3ZlTWFya2VyKHNoYXBlLCBNQVJLRVJfUkVTSVpJTkcpO1xuICAgIH0pO1xuXG4gICAgaWYgKGZyYW1lR3JvdXApIHtcbiAgICAgIHN2Z1JlbW92ZShmcmFtZUdyb3VwKTtcbiAgICB9XG4gIH0pO1xufVxuXG5TcGFjZVRvb2xQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdlbGVtZW50UmVnaXN0cnknLFxuICAnY2FudmFzJyxcbiAgJ3N0eWxlcycsXG4gICdwcmV2aWV3U3VwcG9ydCdcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQ2hlY2tzIGlmIGFuIGVsZW1lbnQgaXMgYSBjb25uZWN0aW9uLlxuICovXG5mdW5jdGlvbiBpc0Nvbm5lY3Rpb24oZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudC53YXlwb2ludHM7XG59XG4iLCJpbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xuXG4vKipcbiAqIFJldHVybiBkaXJlY3Rpb24gZ2l2ZW4gYXhpcyBhbmQgZGVsdGEuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGF4aXNcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YVxuICpcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERpcmVjdGlvbihheGlzLCBkZWx0YSkge1xuXG4gIGlmIChheGlzID09PSAneCcpIHtcbiAgICBpZiAoZGVsdGEgPiAwKSB7XG4gICAgICByZXR1cm4gJ2UnO1xuICAgIH1cblxuICAgIGlmIChkZWx0YSA8IDApIHtcbiAgICAgIHJldHVybiAndyc7XG4gICAgfVxuICB9XG5cbiAgaWYgKGF4aXMgPT09ICd5Jykge1xuICAgIGlmIChkZWx0YSA+IDApIHtcbiAgICAgIHJldHVybiAncyc7XG4gICAgfVxuXG4gICAgaWYgKGRlbHRhIDwgMCkge1xuICAgICAgcmV0dXJuICduJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGNvbm5lY3Rpb25zIHdob3NlIHdheXBvaW50cyBhcmUgdG8gYmUgdXBkYXRlZC4gV2F5cG9pbnRzIGFyZSB0byBiZSB1cGRhdGVkIGlmIHN0YXJ0XG4gKiBvciBlbmQgaXMgdG8gYmUgbW92ZWQgb3IgcmVzaXplZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZX0gbW92aW5nU2hhcGVzXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZX0gcmVzaXppbmdTaGFwZXNcbiAqXG4gKiBAcmV0dXJucyB7QXJyYXk8ZGpzLm1vZGVsLkNvbm5lY3Rpb24+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0V2F5cG9pbnRzVXBkYXRpbmdDb25uZWN0aW9ucyhtb3ZpbmdTaGFwZXMsIHJlc2l6aW5nU2hhcGVzKSB7XG4gIHZhciB3YXlwb2ludHNVcGRhdGluZ0Nvbm5lY3Rpb25zID0gW107XG5cbiAgZm9yRWFjaChtb3ZpbmdTaGFwZXMuY29uY2F0KHJlc2l6aW5nU2hhcGVzKSwgZnVuY3Rpb24oc2hhcGUpIHtcbiAgICB2YXIgaW5jb21pbmcgPSBzaGFwZS5pbmNvbWluZyxcbiAgICAgICAgb3V0Z29pbmcgPSBzaGFwZS5vdXRnb2luZztcblxuICAgIGZvckVhY2goaW5jb21pbmcuY29uY2F0KG91dGdvaW5nKSwgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgdmFyIHNvdXJjZSA9IGNvbm5lY3Rpb24uc291cmNlLFxuICAgICAgICAgIHRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0O1xuXG4gICAgICBpZiAoaW5jbHVkZXMobW92aW5nU2hhcGVzLCBzb3VyY2UpIHx8XG4gICAgICAgIGluY2x1ZGVzKG1vdmluZ1NoYXBlcywgdGFyZ2V0KSB8fFxuICAgICAgICBpbmNsdWRlcyhyZXNpemluZ1NoYXBlcywgc291cmNlKSB8fFxuICAgICAgICBpbmNsdWRlcyhyZXNpemluZ1NoYXBlcywgdGFyZ2V0KSkge1xuXG4gICAgICAgIGlmICghaW5jbHVkZXMod2F5cG9pbnRzVXBkYXRpbmdDb25uZWN0aW9ucywgY29ubmVjdGlvbikpIHtcbiAgICAgICAgICB3YXlwb2ludHNVcGRhdGluZ0Nvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgcmV0dXJuIHdheXBvaW50c1VwZGF0aW5nQ29ubmVjdGlvbnM7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVzKGFycmF5LCBpdGVtKSB7XG4gIHJldHVybiBhcnJheS5pbmRleE9mKGl0ZW0pICE9PSAtMTtcbn1cblxuLyoqXG4gKiBSZXNpemUgYm91bmRzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBib3VuZHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBib3VuZHMueFxuICogQHBhcmFtIHtudW1iZXJ9IGJvdW5kcy55XG4gKiBAcGFyYW0ge251bWJlcn0gYm91bmRzLndpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gYm91bmRzLmhlaWdodFxuICogQHBhcmFtIHtzdHJpbmd9IGRpcmVjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IGRlbHRhXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsdGEueFxuICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhLnlcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNpemVCb3VuZHMoYm91bmRzLCBkaXJlY3Rpb24sIGRlbHRhKSB7XG4gIHZhciB4ID0gYm91bmRzLngsXG4gICAgICB5ID0gYm91bmRzLnksXG4gICAgICB3aWR0aCA9IGJvdW5kcy53aWR0aCxcbiAgICAgIGhlaWdodCA9IGJvdW5kcy5oZWlnaHQsXG4gICAgICBkeCA9IGRlbHRhLngsXG4gICAgICBkeSA9IGRlbHRhLnk7XG5cbiAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgY2FzZSAnbic6XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5ICsgZHksXG4gICAgICB3aWR0aDogd2lkdGgsXG4gICAgICBoZWlnaHQ6IGhlaWdodCAtIGR5XG4gICAgfTtcbiAgY2FzZSAncyc6XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5LFxuICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgaGVpZ2h0OiBoZWlnaHQgKyBkeVxuICAgIH07XG4gIGNhc2UgJ3cnOlxuICAgIHJldHVybiB7XG4gICAgICB4OiB4ICsgZHgsXG4gICAgICB5OiB5LFxuICAgICAgd2lkdGg6IHdpZHRoIC0gZHgsXG4gICAgICBoZWlnaHQ6IGhlaWdodFxuICAgIH07XG4gIGNhc2UgJ2UnOlxuICAgIHJldHVybiB7XG4gICAgICB4OiB4LFxuICAgICAgeTogeSxcbiAgICAgIHdpZHRoOiB3aWR0aCArIGR4LFxuICAgICAgaGVpZ2h0OiBoZWlnaHRcbiAgICB9O1xuICBkZWZhdWx0OlxuICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBkaXJlY3Rpb246ICcgKyBkaXJlY3Rpb24pO1xuICB9XG59IiwiaW1wb3J0IERyYWdnaW5nTW9kdWxlIGZyb20gJy4uL2RyYWdnaW5nJztcbmltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgVG9vbE1hbmFnZXJNb2R1bGUgZnJvbSAnLi4vdG9vbC1tYW5hZ2VyJztcbmltcG9ydCBQcmV2aWV3U3VwcG9ydE1vZHVsZSBmcm9tICcuLi9wcmV2aWV3LXN1cHBvcnQnO1xuXG5pbXBvcnQgU3BhY2VUb29sIGZyb20gJy4vU3BhY2VUb29sJztcbmltcG9ydCBTcGFjZVRvb2xQcmV2aWV3IGZyb20gJy4vU3BhY2VUb29sUHJldmlldyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsnc3BhY2VUb29sUHJldmlldyddLFxuICBfX2RlcGVuZHNfXzogW1xuICAgIERyYWdnaW5nTW9kdWxlLFxuICAgIFJ1bGVzTW9kdWxlLFxuICAgIFRvb2xNYW5hZ2VyTW9kdWxlLFxuICAgIFByZXZpZXdTdXBwb3J0TW9kdWxlXG4gIF0sXG4gIHNwYWNlVG9vbDogWyd0eXBlJywgU3BhY2VUb29sIF0sXG4gIHNwYWNlVG9vbFByZXZpZXc6IFsndHlwZScsIFNwYWNlVG9vbFByZXZpZXcgXVxufTtcbiIsImltcG9ydCB7XG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBjbG9zZXN0IGFzIGRvbUNsb3Nlc3Rcbn0gZnJvbSAnbWluLWRvbSc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSAyNTA7XG5cbi8qKlxuICogVGhlIHRvb2wgbWFuYWdlciBhY3RzIGFzIG1pZGRsZS1tYW4gYmV0d2VlbiB0aGUgYXZhaWxhYmxlIHRvb2wncyBhbmQgdGhlIFBhbGV0dGUsXG4gKiBpdCB0YWtlcyBjYXJlIG9mIG1ha2luZyBzdXJlIHRoYXQgdGhlIGNvcnJlY3QgYWN0aXZlIHN0YXRlIGlzIHNldC5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgIGV2ZW50QnVzXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgIGRyYWdnaW5nXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRvb2xNYW5hZ2VyKGV2ZW50QnVzLCBkcmFnZ2luZykge1xuICB0aGlzLl9ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICB0aGlzLl9kcmFnZ2luZyA9IGRyYWdnaW5nO1xuXG4gIHRoaXMuX3Rvb2xzID0gW107XG4gIHRoaXMuX2FjdGl2ZSA9IG51bGw7XG59XG5cblRvb2xNYW5hZ2VyLiRpbmplY3QgPSBbICdldmVudEJ1cycsICdkcmFnZ2luZycgXTtcblxuVG9vbE1hbmFnZXIucHJvdG90eXBlLnJlZ2lzdGVyVG9vbCA9IGZ1bmN0aW9uKG5hbWUsIGV2ZW50cykge1xuICB2YXIgdG9vbHMgPSB0aGlzLl90b29scztcblxuICBpZiAoIWV2ZW50cykge1xuICAgIHRocm93IG5ldyBFcnJvcignQSB0b29sIGhhcyB0byBiZSByZWdpc3RlcmVkIHdpdGggaXRcXCdzIFwiZXZlbnRzXCInKTtcbiAgfVxuXG4gIHRvb2xzLnB1c2gobmFtZSk7XG5cbiAgdGhpcy5iaW5kRXZlbnRzKG5hbWUsIGV2ZW50cyk7XG59O1xuXG5Ub29sTWFuYWdlci5wcm90b3R5cGUuaXNBY3RpdmUgPSBmdW5jdGlvbih0b29sKSB7XG4gIHJldHVybiB0b29sICYmIHRoaXMuX2FjdGl2ZSA9PT0gdG9vbDtcbn07XG5cblRvb2xNYW5hZ2VyLnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbih0b29sKSB7XG4gIHJldHVybiB0aGlzLl90b29scy5sZW5ndGg7XG59O1xuXG5Ub29sTWFuYWdlci5wcm90b3R5cGUuc2V0QWN0aXZlID0gZnVuY3Rpb24odG9vbCkge1xuICB2YXIgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICBpZiAodGhpcy5fYWN0aXZlICE9PSB0b29sKSB7XG4gICAgdGhpcy5fYWN0aXZlID0gdG9vbDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ3Rvb2wtbWFuYWdlci51cGRhdGUnLCB7IHRvb2w6IHRvb2wgfSk7XG4gIH1cbn07XG5cblRvb2xNYW5hZ2VyLnByb3RvdHlwZS5iaW5kRXZlbnRzID0gZnVuY3Rpb24obmFtZSwgZXZlbnRzKSB7XG4gIHZhciBldmVudEJ1cyA9IHRoaXMuX2V2ZW50QnVzLFxuICAgICAgZHJhZ2dpbmcgPSB0aGlzLl9kcmFnZ2luZztcblxuICB2YXIgZXZlbnRzVG9SZWdpc3RlciA9IFtdO1xuXG4gIGV2ZW50QnVzLm9uKGV2ZW50cy50b29sICsgJy5pbml0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQ7XG5cbiAgICAvLyBBY3RpdmUgdG9vbHMgdGhhdCB3YW50IHRvIHJlYWN0aXZhdGUgdGhlbXNlbHZlcyBtdXN0IGRvIHRoaXMgZXhwbGljaXRseVxuICAgIGlmICghY29udGV4dC5yZWFjdGl2YXRlICYmIHRoaXMuaXNBY3RpdmUobmFtZSkpIHtcbiAgICAgIHRoaXMuc2V0QWN0aXZlKG51bGwpO1xuXG4gICAgICBkcmFnZ2luZy5jYW5jZWwoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldEFjdGl2ZShuYW1lKTtcblxuICB9LCB0aGlzKTtcblxuICAvLyBUb2RvW3JpY2FyZG9dOiBhZGQgdGVzdCBjYXNlc1xuICBmb3JFYWNoKGV2ZW50cywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBldmVudHNUb1JlZ2lzdGVyLnB1c2goZXZlbnQgKyAnLmVuZGVkJyk7XG4gICAgZXZlbnRzVG9SZWdpc3Rlci5wdXNoKGV2ZW50ICsgJy5jYW5jZWxlZCcpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihldmVudHNUb1JlZ2lzdGVyLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIG9yaWdpbmFsRXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50O1xuXG4gICAgLy8gV2UgZGVmZXIgdGhlIGRlLWFjdGl2YXRpb24gb2YgdGhlIHRvb2wgdG8gdGhlIC5hY3RpdmF0ZSBwaGFzZSxcbiAgICAvLyBzbyB3ZSdyZSBhYmxlIHRvIGNoZWNrIGlmIHdlIHdhbnQgdG8gdG9nZ2xlIG9mZiB0aGUgY3VycmVudFxuICAgIC8vIGFjdGl2ZSB0b29sIG9yIHN3aXRjaCB0byBhIG5ldyBvbmVcbiAgICBpZiAoIXRoaXMuX2FjdGl2ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChvcmlnaW5hbEV2ZW50ICYmIGRvbUNsb3Nlc3Qob3JpZ2luYWxFdmVudC50YXJnZXQsICcuZ3JvdXBbZGF0YS1ncm91cD1cInRvb2xzXCJdJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldEFjdGl2ZShudWxsKTtcbiAgfSwgdGhpcyk7XG59O1xuIiwiaW1wb3J0IERyYWdnaW5nTW9kdWxlIGZyb20gJy4uL2RyYWdnaW5nJztcblxuaW1wb3J0IFRvb2xNYW5hZ2VyIGZyb20gJy4vVG9vbE1hbmFnZXInO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgRHJhZ2dpbmdNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ3Rvb2xNYW5hZ2VyJyBdLFxuICB0b29sTWFuYWdlcjogWyAndHlwZScsIFRvb2xNYW5hZ2VyIF1cbn07XG4iLCJpbXBvcnQge1xuICBpc1N0cmluZyxcbiAgYXNzaWduLFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZG9taWZ5LFxuICBhdHRyIGFzIGRvbUF0dHIsXG4gIGNsYXNzZXMgYXMgZG9tQ2xhc3NlcyxcbiAgcmVtb3ZlIGFzIGRvbVJlbW92ZSxcbiAgZGVsZWdhdGUgYXMgZG9tRGVsZWdhdGVcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCBJZHMgZnJvbSAnLi4vLi4vdXRpbC9JZEdlbmVyYXRvcic7XG5cbi8vIGRvY3VtZW50IHdpZGUgdW5pcXVlIHRvb2x0aXAgaWRzXG52YXIgaWRzID0gbmV3IElkcygndHQnKTtcblxuXG5mdW5jdGlvbiBjcmVhdGVSb290KHBhcmVudE5vZGUpIHtcbiAgdmFyIHJvb3QgPSBkb21pZnkoXG4gICAgJzxkaXYgY2xhc3M9XCJkanMtdG9vbHRpcC1jb250YWluZXJcIiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDA7IGhlaWdodDogMDtcIiAvPidcbiAgKTtcblxuICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShyb290LCBwYXJlbnROb2RlLmZpcnN0Q2hpbGQpO1xuXG4gIHJldHVybiByb290O1xufVxuXG5cbmZ1bmN0aW9uIHNldFBvc2l0aW9uKGVsLCB4LCB5KSB7XG4gIGFzc2lnbihlbC5zdHlsZSwgeyBsZWZ0OiB4ICsgJ3B4JywgdG9wOiB5ICsgJ3B4JyB9KTtcbn1cblxuZnVuY3Rpb24gc2V0VmlzaWJsZShlbCwgdmlzaWJsZSkge1xuICBlbC5zdHlsZS5kaXNwbGF5ID0gdmlzaWJsZSA9PT0gZmFsc2UgPyAnbm9uZScgOiAnJztcbn1cblxuXG52YXIgdG9vbHRpcENsYXNzID0gJ2Rqcy10b29sdGlwJyxcbiAgICB0b29sdGlwU2VsZWN0b3IgPSAnLicgKyB0b29sdGlwQ2xhc3M7XG5cbi8qKlxuICogQSBzZXJ2aWNlIHRoYXQgYWxsb3dzIHVzZXJzIHRvIHJlbmRlciB0b29sIHRpcHMgb24gdGhlIGRpYWdyYW0uXG4gKlxuICogVGhlIHRvb2x0aXAgc2VydmljZSB3aWxsIHRha2UgY2FyZSBvZiB1cGRhdGluZyB0aGUgdG9vbHRpcCBwb3NpdGlvbmluZ1xuICogZHVyaW5nIG5hdmlnYXRpb24gKyB6b29taW5nLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICpcbiAqIC8vIGFkZCBhIHBpbmsgYmFkZ2Ugb24gdGhlIHRvcCBsZWZ0IG9mIHRoZSBzaGFwZVxuICogdG9vbHRpcHMuYWRkKHtcbiAqICAgcG9zaXRpb246IHtcbiAqICAgICB4OiA1MCxcbiAqICAgICB5OiAxMDBcbiAqICAgfSxcbiAqICAgaHRtbDogJzxkaXYgc3R5bGU9XCJ3aWR0aDogMTBweDsgYmFja2dyb3VuZDogZnVjaHNpYTsgY29sb3I6IHdoaXRlO1wiPjA8L2Rpdj4nXG4gKiB9KTtcbiAqXG4gKiAvLyBvciB3aXRoIG9wdGlvbmFsIGxpZmUgc3BhblxuICogdG9vbHRpcHMuYWRkKHtcbiAqICAgcG9zaXRpb246IHtcbiAqICAgICB0b3A6IC01LFxuICogICAgIGxlZnQ6IC01XG4gKiAgIH0sXG4gKiAgIGh0bWw6ICc8ZGl2IHN0eWxlPVwid2lkdGg6IDEwcHg7IGJhY2tncm91bmQ6IGZ1Y2hzaWE7IGNvbG9yOiB3aGl0ZTtcIj4wPC9kaXY+JyxcbiAqICAgdHRsOiAyMDAwXG4gKiB9KTtcbiAqXG4gKiAvLyByZW1vdmUgYSB0b29sIHRpcFxuICogdmFyIGlkID0gdG9vbHRpcHMuYWRkKC4uLik7XG4gKiB0b29sdGlwcy5yZW1vdmUoaWQpO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVG9vbHRpcHMoZXZlbnRCdXMsIGNhbnZhcykge1xuXG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcblxuICB0aGlzLl9pZHMgPSBpZHM7XG5cbiAgdGhpcy5fdG9vbHRpcERlZmF1bHRzID0ge1xuICAgIHNob3c6IHtcbiAgICAgIG1pblpvb206IDAuNyxcbiAgICAgIG1heFpvb206IDUuMFxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogTWFwcGluZyB0b29sdGlwSWQgLT4gdG9vbHRpcFxuICAgKi9cbiAgdGhpcy5fdG9vbHRpcHMgPSB7fTtcblxuICAvLyByb290IGh0bWwgZWxlbWVudCBmb3IgYWxsIHRvb2x0aXBzXG4gIHRoaXMuX3Rvb2x0aXBSb290ID0gY3JlYXRlUm9vdChjYW52YXMuZ2V0Q29udGFpbmVyKCkpO1xuXG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQodGhpcy5fdG9vbHRpcFJvb3QsIHRvb2x0aXBTZWxlY3RvciwgJ21vdXNlZG93bicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH0pO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQodGhpcy5fdG9vbHRpcFJvb3QsIHRvb2x0aXBTZWxlY3RvciwgJ21vdXNlb3ZlcicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgc2VsZi50cmlnZ2VyKCdtb3VzZW92ZXInLCBldmVudCk7XG4gIH0pO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQodGhpcy5fdG9vbHRpcFJvb3QsIHRvb2x0aXBTZWxlY3RvciwgJ21vdXNlb3V0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBzZWxmLnRyaWdnZXIoJ21vdXNlb3V0JywgZXZlbnQpO1xuICB9KTtcblxuICB0aGlzLl9pbml0KCk7XG59XG5cblxuVG9vbHRpcHMuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2NhbnZhcycgXTtcblxuXG4vKipcbiAqIEFkZHMgYSBIVE1MIHRvb2x0aXAgdG8gdGhlIGRpYWdyYW1cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gICAgICAgICAgICAgICB0b29sdGlwICAgdGhlIHRvb2x0aXAgY29uZmlndXJhdGlvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfERPTUVsZW1lbnR9ICAgIHRvb2x0aXAuaHRtbCAgICAgICAgICAgICAgICAgaHRtbCBlbGVtZW50IHRvIHVzZSBhcyBhbiB0b29sdGlwXG4gKiBAcGFyYW0ge09iamVjdH0gICAgICAgICAgICAgICBbdG9vbHRpcC5zaG93XSAgICAgICAgICAgICAgIHNob3cgY29uZmlndXJhdGlvblxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgW3Rvb2x0aXAuc2hvdy5taW5ab29tXSAgICAgICBtaW5pbWFsIHpvb20gbGV2ZWwgdG8gc2hvdyB0aGUgdG9vbHRpcFxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgW3Rvb2x0aXAuc2hvdy5tYXhab29tXSAgICAgICBtYXhpbXVtIHpvb20gbGV2ZWwgdG8gc2hvdyB0aGUgdG9vbHRpcFxuICogQHBhcmFtIHtPYmplY3R9ICAgICAgICAgICAgICAgdG9vbHRpcC5wb3NpdGlvbiAgICAgICAgICAgICB3aGVyZSB0byBhdHRhY2ggdGhlIHRvb2x0aXBcbiAqIEBwYXJhbSB7bnVtYmVyfSAgICAgICAgICAgICAgIFt0b29sdGlwLnBvc2l0aW9uLmxlZnRdICAgICAgcmVsYXRpdmUgdG8gZWxlbWVudCBiYm94IGxlZnQgYXR0YWNobWVudFxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgW3Rvb2x0aXAucG9zaXRpb24udG9wXSAgICAgICByZWxhdGl2ZSB0byBlbGVtZW50IGJib3ggdG9wIGF0dGFjaG1lbnRcbiAqIEBwYXJhbSB7bnVtYmVyfSAgICAgICAgICAgICAgIFt0b29sdGlwLnBvc2l0aW9uLmJvdHRvbV0gICAgcmVsYXRpdmUgdG8gZWxlbWVudCBiYm94IGJvdHRvbSBhdHRhY2htZW50XG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICBbdG9vbHRpcC5wb3NpdGlvbi5yaWdodF0gICAgIHJlbGF0aXZlIHRvIGVsZW1lbnQgYmJveCByaWdodCBhdHRhY2htZW50XG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICBbdG9vbHRpcC50aW1lb3V0PS0xXVxuICpcbiAqIEByZXR1cm4ge3N0cmluZ30gICAgICAgICAgICAgIGlkIHRoYXQgbWF5IGJlIHVzZWQgdG8gcmVmZXJlbmNlIHRoZSB0b29sdGlwIGZvciB1cGRhdGUgb3IgcmVtb3ZhbFxuICovXG5Ub29sdGlwcy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24odG9vbHRpcCkge1xuXG4gIGlmICghdG9vbHRpcC5wb3NpdGlvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignbXVzdCBzcGVjaWZpeSB0b29sdGlwIHBvc2l0aW9uJyk7XG4gIH1cblxuICBpZiAoIXRvb2x0aXAuaHRtbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbXVzdCBzcGVjaWZpeSB0b29sdGlwIGh0bWwnKTtcbiAgfVxuXG4gIHZhciBpZCA9IHRoaXMuX2lkcy5uZXh0KCk7XG5cbiAgdG9vbHRpcCA9IGFzc2lnbih7fSwgdGhpcy5fdG9vbHRpcERlZmF1bHRzLCB0b29sdGlwLCB7XG4gICAgaWQ6IGlkXG4gIH0pO1xuXG4gIHRoaXMuX2FkZFRvb2x0aXAodG9vbHRpcCk7XG5cbiAgaWYgKHRvb2x0aXAudGltZW91dCkge1xuICAgIHRoaXMuc2V0VGltZW91dCh0b29sdGlwKTtcbiAgfVxuXG4gIHJldHVybiBpZDtcbn07XG5cblRvb2x0aXBzLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oYWN0aW9uLCBldmVudCkge1xuXG4gIHZhciBub2RlID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQgfHwgZXZlbnQudGFyZ2V0O1xuXG4gIHZhciB0b29sdGlwID0gdGhpcy5nZXQoZG9tQXR0cihub2RlLCAnZGF0YS10b29sdGlwLWlkJykpO1xuXG4gIGlmICghdG9vbHRpcCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChhY3Rpb24gPT09ICdtb3VzZW92ZXInICYmIHRvb2x0aXAudGltZW91dCkge1xuICAgIHRoaXMuY2xlYXJUaW1lb3V0KHRvb2x0aXApO1xuICB9XG5cbiAgaWYgKGFjdGlvbiA9PT0gJ21vdXNlb3V0JyAmJiB0b29sdGlwLnRpbWVvdXQpIHtcblxuICAgIC8vIGN1dCB0aW1lb3V0IGFmdGVyIG1vdXNlIG91dFxuICAgIHRvb2x0aXAudGltZW91dCA9IDEwMDA7XG5cbiAgICB0aGlzLnNldFRpbWVvdXQodG9vbHRpcCk7XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGEgdG9vbHRpcCB3aXRoIHRoZSBnaXZlbiBpZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuICovXG5Ub29sdGlwcy5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oaWQpIHtcblxuICBpZiAodHlwZW9mIGlkICE9PSAnc3RyaW5nJykge1xuICAgIGlkID0gaWQuaWQ7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fdG9vbHRpcHNbaWRdO1xufTtcblxuVG9vbHRpcHMucHJvdG90eXBlLmNsZWFyVGltZW91dCA9IGZ1bmN0aW9uKHRvb2x0aXApIHtcblxuICB0b29sdGlwID0gdGhpcy5nZXQodG9vbHRpcCk7XG5cbiAgaWYgKCF0b29sdGlwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHJlbW92ZVRpbWVyID0gdG9vbHRpcC5yZW1vdmVUaW1lcjtcblxuICBpZiAocmVtb3ZlVGltZXIpIHtcbiAgICBjbGVhclRpbWVvdXQocmVtb3ZlVGltZXIpO1xuICAgIHRvb2x0aXAucmVtb3ZlVGltZXIgPSBudWxsO1xuICB9XG59O1xuXG5Ub29sdGlwcy5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uKHRvb2x0aXApIHtcblxuICB0b29sdGlwID0gdGhpcy5nZXQodG9vbHRpcCk7XG5cbiAgaWYgKCF0b29sdGlwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5jbGVhclRpbWVvdXQodG9vbHRpcCk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRvb2x0aXAucmVtb3ZlVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIHNlbGYucmVtb3ZlKHRvb2x0aXApO1xuICB9LCB0b29sdGlwLnRpbWVvdXQpO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgYW4gdG9vbHRpcCB3aXRoIHRoZSBnaXZlbiBpZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuICovXG5Ub29sdGlwcy5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oaWQpIHtcblxuICB2YXIgdG9vbHRpcCA9IHRoaXMuZ2V0KGlkKTtcblxuICBpZiAodG9vbHRpcCkge1xuICAgIGRvbVJlbW92ZSh0b29sdGlwLmh0bWwpO1xuICAgIGRvbVJlbW92ZSh0b29sdGlwLmh0bWxDb250YWluZXIpO1xuXG4gICAgZGVsZXRlIHRvb2x0aXAuaHRtbENvbnRhaW5lcjtcblxuICAgIGRlbGV0ZSB0aGlzLl90b29sdGlwc1t0b29sdGlwLmlkXTtcbiAgfVxufTtcblxuXG5Ub29sdGlwcy5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uKCkge1xuICBzZXRWaXNpYmxlKHRoaXMuX3Rvb2x0aXBSb290KTtcbn07XG5cblxuVG9vbHRpcHMucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbigpIHtcbiAgc2V0VmlzaWJsZSh0aGlzLl90b29sdGlwUm9vdCwgZmFsc2UpO1xufTtcblxuXG5Ub29sdGlwcy5wcm90b3R5cGUuX3VwZGF0ZVJvb3QgPSBmdW5jdGlvbih2aWV3Ym94KSB7XG4gIHZhciBhID0gdmlld2JveC5zY2FsZSB8fCAxO1xuICB2YXIgZCA9IHZpZXdib3guc2NhbGUgfHwgMTtcblxuICB2YXIgbWF0cml4ID0gJ21hdHJpeCgnICsgYSArICcsMCwwLCcgKyBkICsgJywnICsgKC0xICogdmlld2JveC54ICogYSkgKyAnLCcgKyAoLTEgKiB2aWV3Ym94LnkgKiBkKSArICcpJztcblxuICB0aGlzLl90b29sdGlwUm9vdC5zdHlsZS50cmFuc2Zvcm0gPSBtYXRyaXg7XG4gIHRoaXMuX3Rvb2x0aXBSb290LnN0eWxlWyctbXMtdHJhbnNmb3JtJ10gPSBtYXRyaXg7XG59O1xuXG5cblRvb2x0aXBzLnByb3RvdHlwZS5fYWRkVG9vbHRpcCA9IGZ1bmN0aW9uKHRvb2x0aXApIHtcblxuICB2YXIgaWQgPSB0b29sdGlwLmlkLFxuICAgICAgaHRtbCA9IHRvb2x0aXAuaHRtbCxcbiAgICAgIGh0bWxDb250YWluZXIsXG4gICAgICB0b29sdGlwUm9vdCA9IHRoaXMuX3Rvb2x0aXBSb290O1xuXG4gIC8vIHVud3JhcCBqcXVlcnkgKGZvciB0aG9zZSB3aG8gbmVlZCBpdClcbiAgaWYgKGh0bWwuZ2V0ICYmIGh0bWwuY29uc3RydWN0b3IucHJvdG90eXBlLmpxdWVyeSkge1xuICAgIGh0bWwgPSBodG1sLmdldCgwKTtcbiAgfVxuXG4gIC8vIGNyZWF0ZSBwcm9wZXIgaHRtbCBlbGVtZW50cyBmcm9tXG4gIC8vIHRvb2x0aXAgSFRNTCBzdHJpbmdzXG4gIGlmIChpc1N0cmluZyhodG1sKSkge1xuICAgIGh0bWwgPSBkb21pZnkoaHRtbCk7XG4gIH1cblxuICBodG1sQ29udGFpbmVyID0gZG9taWZ5KCc8ZGl2IGRhdGEtdG9vbHRpcC1pZD1cIicgKyBpZCArICdcIiBjbGFzcz1cIicgKyB0b29sdGlwQ2xhc3MgKyAnXCIgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGVcIj4nKTtcblxuICBodG1sQ29udGFpbmVyLmFwcGVuZENoaWxkKGh0bWwpO1xuXG4gIGlmICh0b29sdGlwLnR5cGUpIHtcbiAgICBkb21DbGFzc2VzKGh0bWxDb250YWluZXIpLmFkZCgnZGpzLXRvb2x0aXAtJyArIHRvb2x0aXAudHlwZSk7XG4gIH1cblxuICBpZiAodG9vbHRpcC5jbGFzc05hbWUpIHtcbiAgICBkb21DbGFzc2VzKGh0bWxDb250YWluZXIpLmFkZCh0b29sdGlwLmNsYXNzTmFtZSk7XG4gIH1cblxuICB0b29sdGlwLmh0bWxDb250YWluZXIgPSBodG1sQ29udGFpbmVyO1xuXG4gIHRvb2x0aXBSb290LmFwcGVuZENoaWxkKGh0bWxDb250YWluZXIpO1xuXG4gIHRoaXMuX3Rvb2x0aXBzW2lkXSA9IHRvb2x0aXA7XG5cbiAgdGhpcy5fdXBkYXRlVG9vbHRpcCh0b29sdGlwKTtcbn07XG5cblxuVG9vbHRpcHMucHJvdG90eXBlLl91cGRhdGVUb29sdGlwID0gZnVuY3Rpb24odG9vbHRpcCkge1xuXG4gIHZhciBwb3NpdGlvbiA9IHRvb2x0aXAucG9zaXRpb24sXG4gICAgICBodG1sQ29udGFpbmVyID0gdG9vbHRpcC5odG1sQ29udGFpbmVyO1xuXG4gIC8vIHVwZGF0ZSBvdmVybGF5IGh0bWwgYmFzZWQgb24gdG9vbHRpcCB4LCB5XG5cbiAgc2V0UG9zaXRpb24oaHRtbENvbnRhaW5lciwgcG9zaXRpb24ueCwgcG9zaXRpb24ueSk7XG59O1xuXG5cblRvb2x0aXBzLnByb3RvdHlwZS5fdXBkYXRlVG9vbHRpcFZpc2liaWx0eSA9IGZ1bmN0aW9uKHZpZXdib3gpIHtcblxuICBmb3JFYWNoKHRoaXMuX3Rvb2x0aXBzLCBmdW5jdGlvbih0b29sdGlwKSB7XG4gICAgdmFyIHNob3cgPSB0b29sdGlwLnNob3csXG4gICAgICAgIGh0bWxDb250YWluZXIgPSB0b29sdGlwLmh0bWxDb250YWluZXIsXG4gICAgICAgIHZpc2libGUgPSB0cnVlO1xuXG4gICAgaWYgKHNob3cpIHtcbiAgICAgIGlmIChzaG93Lm1pblpvb20gPiB2aWV3Ym94LnNjYWxlIHx8XG4gICAgICAgICAgc2hvdy5tYXhab29tIDwgdmlld2JveC5zY2FsZSkge1xuICAgICAgICB2aXNpYmxlID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHNldFZpc2libGUoaHRtbENvbnRhaW5lciwgdmlzaWJsZSk7XG4gICAgfVxuICB9KTtcbn07XG5cblRvb2x0aXBzLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvLyBzY3JvbGwvem9vbSBpbnRlZ3JhdGlvblxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVZpZXdib3godmlld2JveCkge1xuICAgIHNlbGYuX3VwZGF0ZVJvb3Qodmlld2JveCk7XG4gICAgc2VsZi5fdXBkYXRlVG9vbHRpcFZpc2liaWx0eSh2aWV3Ym94KTtcblxuICAgIHNlbGYuc2hvdygpO1xuICB9XG5cbiAgdGhpcy5fZXZlbnRCdXMub24oJ2NhbnZhcy52aWV3Ym94LmNoYW5naW5nJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBzZWxmLmhpZGUoKTtcbiAgfSk7XG5cbiAgdGhpcy5fZXZlbnRCdXMub24oJ2NhbnZhcy52aWV3Ym94LmNoYW5nZWQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHVwZGF0ZVZpZXdib3goZXZlbnQudmlld2JveCk7XG4gIH0pO1xufTtcbiIsImltcG9ydCBUb29sdGlwcyBmcm9tICcuL1Rvb2x0aXBzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAndG9vbHRpcHMnIF0sXG4gIHRvb2x0aXBzOiBbICd0eXBlJywgVG9vbHRpcHMgXVxufTsiLCJpbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRvdWNoRml4KGNhbnZhcywgZXZlbnRCdXMpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZXZlbnRCdXMub24oJ2NhbnZhcy5pbml0JywgZnVuY3Rpb24oZSkge1xuICAgIHNlbGYuYWRkQkJveE1hcmtlcihlLnN2Zyk7XG4gIH0pO1xufVxuXG5Ub3VjaEZpeC4kaW5qZWN0ID0gWyAnY2FudmFzJywgJ2V2ZW50QnVzJyBdO1xuXG5cbi8qKlxuICogU2FmYXJpIG1vYmlsZSAoaU9TIDcpIGRvZXMgbm90IGZpcmUgdG91Y2hzdGFydCBldmVudCBpbiA8U1ZHPiBlbGVtZW50XG4gKiBpZiB0aGVyZSBpcyBubyBzaGFwZSBiZXR3ZWVuIDAsMCBhbmQgdmlld3BvcnQgZWxlbWVudHMgb3JpZ2luLlxuICpcbiAqIFNvIHRvdWNoc3RhcnQgZXZlbnQgaXMgb25seSBmaXJlZCB3aGVuIHRoZSA8ZyBjbGFzcz1cInZpZXdwb3J0XCI+IGVsZW1lbnQgd2FzIGhpdC5cbiAqIFB1dHRpbmcgYW4gZWxlbWVudCBvdmVyIGFuZCBiZWxvdyB0aGUgJ3ZpZXdwb3J0JyBmaXhlcyB0aGF0IGJlaGF2aW9yLlxuICovXG5Ub3VjaEZpeC5wcm90b3R5cGUuYWRkQkJveE1hcmtlciA9IGZ1bmN0aW9uKHN2Zykge1xuXG4gIHZhciBtYXJrZXJTdHlsZSA9IHtcbiAgICBmaWxsOiAnbm9uZScsXG4gICAgY2xhc3M6ICdvdXRlci1ib3VuZC1tYXJrZXInXG4gIH07XG5cbiAgdmFyIHJlY3QxID0gc3ZnQ3JlYXRlKCdyZWN0Jyk7XG4gIHN2Z0F0dHIocmVjdDEsIHtcbiAgICB4OiAtMTAwMDAsXG4gICAgeTogMTAwMDAsXG4gICAgd2lkdGg6IDEwLFxuICAgIGhlaWdodDogMTBcbiAgfSk7XG4gIHN2Z0F0dHIocmVjdDEsIG1hcmtlclN0eWxlKTtcblxuICBzdmdBcHBlbmQoc3ZnLCByZWN0MSk7XG5cbiAgdmFyIHJlY3QyID0gc3ZnQ3JlYXRlKCdyZWN0Jyk7XG4gIHN2Z0F0dHIocmVjdDIsIHtcbiAgICB4OiAxMDAwMCxcbiAgICB5OiAxMDAwMCxcbiAgICB3aWR0aDogMTAsXG4gICAgaGVpZ2h0OiAxMFxuICB9KTtcbiAgc3ZnQXR0cihyZWN0MiwgbWFya2VyU3R5bGUpO1xuXG4gIHN2Z0FwcGVuZChzdmcsIHJlY3QyKTtcbn07XG4iLCJpbXBvcnQge1xuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZXZlbnQgYXMgZG9tRXZlbnQsXG4gIGNsb3Nlc3QgYXMgZG9tQ2xvc2VzdFxufSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IEhhbW1lciBmcm9tICdoYW1tZXJqcyc7XG5cbmltcG9ydCB7XG4gIHRvUG9pbnRcbn0gZnJvbSAnLi4vLi4vdXRpbC9FdmVudCc7XG5cbnZhciBNSU5fWk9PTSA9IDAuMixcbiAgICBNQVhfWk9PTSA9IDQ7XG5cbnZhciBtb3VzZUV2ZW50cyA9IFtcbiAgJ21vdXNlZG93bicsXG4gICdtb3VzZXVwJyxcbiAgJ21vdXNlb3ZlcicsXG4gICdtb3VzZW91dCcsXG4gICdjbGljaycsXG4gICdkYmxjbGljaydcbl07XG5cbmZ1bmN0aW9uIGxvZygpIHtcblxuICAvLyBjb25zb2xlLmxvZy5hcHBseShjb25zb2xlLCBhcmd1bWVudHMpO1xufVxuXG5mdW5jdGlvbiBnZXQoc2VydmljZSwgaW5qZWN0b3IpIHtcbiAgcmV0dXJuIGluamVjdG9yLmdldChzZXJ2aWNlLCBmYWxzZSk7XG59XG5cbmZ1bmN0aW9uIHN0b3BFdmVudChldmVudCkge1xuXG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgaWYgKHR5cGVvZiBldmVudC5zdG9wUHJvcGFnYXRpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfSBlbHNlIGlmIChldmVudC5zcmNFdmVudCAmJiB0eXBlb2YgZXZlbnQuc3JjRXZlbnQuc3RvcFByb3BhZ2F0aW9uID09PSAnZnVuY3Rpb24nKSB7XG5cbiAgICAvLyBpUGhvbmUgJiBpUGFkXG4gICAgZXZlbnQuc3JjRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBpZiAodHlwZW9mIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICB9XG59XG5cblxuZnVuY3Rpb24gY3JlYXRlVG91Y2hSZWNvZ25pemVyKG5vZGUpIHtcblxuICBmdW5jdGlvbiBzdG9wTW91c2UoZXZlbnQpIHtcblxuICAgIGZvckVhY2gobW91c2VFdmVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGRvbUV2ZW50LmJpbmQobm9kZSwgZSwgc3RvcEV2ZW50LCB0cnVlKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFsbG93TW91c2UoZXZlbnQpIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgZm9yRWFjaChtb3VzZUV2ZW50cywgZnVuY3Rpb24oZSkge1xuICAgICAgICBkb21FdmVudC51bmJpbmQobm9kZSwgZSwgc3RvcEV2ZW50LCB0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0sIDUwMCk7XG4gIH1cblxuICBkb21FdmVudC5iaW5kKG5vZGUsICd0b3VjaHN0YXJ0Jywgc3RvcE1vdXNlLCB0cnVlKTtcbiAgZG9tRXZlbnQuYmluZChub2RlLCAndG91Y2hlbmQnLCBhbGxvd01vdXNlLCB0cnVlKTtcbiAgZG9tRXZlbnQuYmluZChub2RlLCAndG91Y2hjYW5jZWwnLCBhbGxvd01vdXNlLCB0cnVlKTtcblxuICAvLyBBIHRvdWNoIGV2ZW50IHJlY29nbml6ZXIgdGhhdCBoYW5kbGVzXG4gIC8vIHRvdWNoIGV2ZW50cyBvbmx5ICh3ZSBrbm93LCB3ZSBjYW4gYWxyZWFkeSBoYW5kbGVcbiAgLy8gbW91c2UgZXZlbnRzIG91dCBvZiB0aGUgYm94KVxuXG4gIHZhciByZWNvZ25pemVyID0gbmV3IEhhbW1lci5NYW5hZ2VyKG5vZGUsIHtcbiAgICBpbnB1dENsYXNzOiBIYW1tZXIuVG91Y2hJbnB1dCxcbiAgICByZWNvZ25pemVyczogW10sXG4gICAgZG9tRXZlbnRzOiB0cnVlXG4gIH0pO1xuXG5cbiAgdmFyIHRhcCA9IG5ldyBIYW1tZXIuVGFwKCk7XG4gIHZhciBwYW4gPSBuZXcgSGFtbWVyLlBhbih7IHRocmVzaG9sZDogMTAgfSk7XG4gIHZhciBwcmVzcyA9IG5ldyBIYW1tZXIuUHJlc3MoKTtcbiAgdmFyIHBpbmNoID0gbmV3IEhhbW1lci5QaW5jaCgpO1xuXG4gIHZhciBkb3VibGVUYXAgPSBuZXcgSGFtbWVyLlRhcCh7IGV2ZW50OiAnZG91YmxldGFwJywgdGFwczogMiB9KTtcblxuICBwaW5jaC5yZXF1aXJlRmFpbHVyZShwYW4pO1xuICBwaW5jaC5yZXF1aXJlRmFpbHVyZShwcmVzcyk7XG5cbiAgcmVjb2duaXplci5hZGQoWyBwYW4sIHByZXNzLCBwaW5jaCwgZG91YmxlVGFwLCB0YXAgXSk7XG5cbiAgcmVjb2duaXplci5yZXNldCA9IGZ1bmN0aW9uKGZvcmNlKSB7XG4gICAgdmFyIHJlY29nbml6ZXJzID0gdGhpcy5yZWNvZ25pemVycyxcbiAgICAgICAgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbjtcblxuICAgIGlmIChzZXNzaW9uLnN0b3BwZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coJ3JlY29nbml6ZXInLCAnc3RvcCcpO1xuXG4gICAgcmVjb2duaXplci5zdG9wKGZvcmNlKTtcblxuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaSwgcjtcblxuICAgICAgbG9nKCdyZWNvZ25pemVyJywgJ3Jlc2V0Jyk7XG4gICAgICBmb3IgKGkgPSAwOyAociA9IHJlY29nbml6ZXJzW2ldKTsgaSsrKSB7XG4gICAgICAgIHIucmVzZXQoKTtcbiAgICAgICAgci5zdGF0ZSA9IDg7IC8vIEZBSUxFRCBTVEFURVxuICAgICAgfVxuXG4gICAgICBzZXNzaW9uLmN1clJlY29nbml6ZXIgPSBudWxsO1xuICAgIH0sIDApO1xuICB9O1xuXG4gIHJlY29nbml6ZXIub24oJ2hhbW1lci5pbnB1dCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnNyY0V2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJlY29nbml6ZXIucmVzZXQodHJ1ZSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmVjb2duaXplcjtcbn1cblxuLyoqXG4gKiBBIHBsdWdpbiB0aGF0IHByb3ZpZGVzIHRvdWNoIGV2ZW50cyBmb3IgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7SW50ZXJhY3Rpb25FdmVudHN9IGludGVyYWN0aW9uRXZlbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRvdWNoSW50ZXJhY3Rpb25FdmVudHMoXG4gICAgaW5qZWN0b3IsIGNhbnZhcywgZXZlbnRCdXMsXG4gICAgZWxlbWVudFJlZ2lzdHJ5LCBpbnRlcmFjdGlvbkV2ZW50cykge1xuXG4gIC8vIG9wdGlvbmFsIGludGVncmF0aW9uc1xuICB2YXIgZHJhZ2dpbmcgPSBnZXQoJ2RyYWdnaW5nJywgaW5qZWN0b3IpLFxuICAgICAgbW92ZSA9IGdldCgnbW92ZScsIGluamVjdG9yKSxcbiAgICAgIGNvbnRleHRQYWQgPSBnZXQoJ2NvbnRleHRQYWQnLCBpbmplY3RvciksXG4gICAgICBwYWxldHRlID0gZ2V0KCdwYWxldHRlJywgaW5qZWN0b3IpO1xuXG4gIC8vIHRoZSB0b3VjaCByZWNvZ25pemVyXG4gIHZhciByZWNvZ25pemVyO1xuXG4gIGZ1bmN0aW9uIGhhbmRsZXIodHlwZSkge1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICBsb2coJ2VsZW1lbnQnLCB0eXBlLCBldmVudCk7XG5cbiAgICAgIGludGVyYWN0aW9uRXZlbnRzLmZpcmUodHlwZSwgZXZlbnQpO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBnZXRHZngodGFyZ2V0KSB7XG4gICAgdmFyIG5vZGUgPSBkb21DbG9zZXN0KHRhcmdldCwgJ3N2ZywgLmRqcy1lbGVtZW50JywgdHJ1ZSk7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBmdW5jdGlvbiBpbml0RXZlbnRzKHN2Zykge1xuXG4gICAgLy8gdG91Y2ggcmVjb2duaXplclxuICAgIHJlY29nbml6ZXIgPSBjcmVhdGVUb3VjaFJlY29nbml6ZXIoc3ZnKTtcblxuICAgIHJlY29nbml6ZXIub24oJ2RvdWJsZXRhcCcsIGhhbmRsZXIoJ2VsZW1lbnQuZGJsY2xpY2snKSk7XG5cbiAgICByZWNvZ25pemVyLm9uKCd0YXAnLCBoYW5kbGVyKCdlbGVtZW50LmNsaWNrJykpO1xuXG4gICAgZnVuY3Rpb24gc3RhcnRHcmFiQ2FudmFzKGV2ZW50KSB7XG5cbiAgICAgIGxvZygnY2FudmFzJywgJ2dyYWIgc3RhcnQnKTtcblxuICAgICAgdmFyIGx4ID0gMCwgbHkgPSAwO1xuXG4gICAgICBmdW5jdGlvbiB1cGRhdGUoZSkge1xuXG4gICAgICAgIHZhciBkeCA9IGUuZGVsdGFYIC0gbHgsXG4gICAgICAgICAgICBkeSA9IGUuZGVsdGFZIC0gbHk7XG5cbiAgICAgICAgY2FudmFzLnNjcm9sbCh7IGR4OiBkeCwgZHk6IGR5IH0pO1xuXG4gICAgICAgIGx4ID0gZS5kZWx0YVg7XG4gICAgICAgIGx5ID0gZS5kZWx0YVk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGVuZChlKSB7XG4gICAgICAgIHJlY29nbml6ZXIub2ZmKCdwYW5tb3ZlJywgdXBkYXRlKTtcbiAgICAgICAgcmVjb2duaXplci5vZmYoJ3BhbmVuZCcsIGVuZCk7XG4gICAgICAgIHJlY29nbml6ZXIub2ZmKCdwYW5jYW5jZWwnLCBlbmQpO1xuXG4gICAgICAgIGxvZygnY2FudmFzJywgJ2dyYWIgZW5kJyk7XG4gICAgICB9XG5cbiAgICAgIHJlY29nbml6ZXIub24oJ3Bhbm1vdmUnLCB1cGRhdGUpO1xuICAgICAgcmVjb2duaXplci5vbigncGFuZW5kJywgZW5kKTtcbiAgICAgIHJlY29nbml6ZXIub24oJ3BhbmNhbmNlbCcsIGVuZCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RhcnRHcmFiKGV2ZW50KSB7XG5cbiAgICAgIHZhciBnZnggPSBnZXRHZngoZXZlbnQudGFyZ2V0KSxcbiAgICAgICAgICBlbGVtZW50ID0gZ2Z4ICYmIGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcblxuICAgICAgLy8gcmVjb2duaXplclxuICAgICAgaWYgKG1vdmUgJiYgY2FudmFzLmdldFJvb3RFbGVtZW50KCkgIT09IGVsZW1lbnQpIHtcbiAgICAgICAgbG9nKCdlbGVtZW50JywgJ21vdmUgc3RhcnQnLCBlbGVtZW50LCBldmVudCwgdHJ1ZSk7XG4gICAgICAgIHJldHVybiBtb3ZlLnN0YXJ0KGV2ZW50LCBlbGVtZW50LCB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXJ0R3JhYkNhbnZhcyhldmVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RhcnRab29tKGUpIHtcblxuICAgICAgbG9nKCdjYW52YXMnLCAnem9vbSBzdGFydCcpO1xuXG4gICAgICB2YXIgem9vbSA9IGNhbnZhcy56b29tKCksXG4gICAgICAgICAgbWlkID0gZS5jZW50ZXI7XG5cbiAgICAgIGZ1bmN0aW9uIHVwZGF0ZShlKSB7XG5cbiAgICAgICAgdmFyIHJhdGlvID0gMSAtICgxIC0gZS5zY2FsZSkgLyAxLjUwLFxuICAgICAgICAgICAgbmV3Wm9vbSA9IE1hdGgubWF4KE1JTl9aT09NLCBNYXRoLm1pbihNQVhfWk9PTSwgcmF0aW8gKiB6b29tKSk7XG5cbiAgICAgICAgY2FudmFzLnpvb20obmV3Wm9vbSwgbWlkKTtcblxuICAgICAgICBzdG9wRXZlbnQoZSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGVuZChlKSB7XG4gICAgICAgIHJlY29nbml6ZXIub2ZmKCdwaW5jaG1vdmUnLCB1cGRhdGUpO1xuICAgICAgICByZWNvZ25pemVyLm9mZigncGluY2hlbmQnLCBlbmQpO1xuICAgICAgICByZWNvZ25pemVyLm9mZigncGluY2hjYW5jZWwnLCBlbmQpO1xuXG4gICAgICAgIHJlY29nbml6ZXIucmVzZXQodHJ1ZSk7XG5cbiAgICAgICAgbG9nKCdjYW52YXMnLCAnem9vbSBlbmQnKTtcbiAgICAgIH1cblxuICAgICAgcmVjb2duaXplci5vbigncGluY2htb3ZlJywgdXBkYXRlKTtcbiAgICAgIHJlY29nbml6ZXIub24oJ3BpbmNoZW5kJywgZW5kKTtcbiAgICAgIHJlY29nbml6ZXIub24oJ3BpbmNoY2FuY2VsJywgZW5kKTtcbiAgICB9XG5cbiAgICByZWNvZ25pemVyLm9uKCdwYW5zdGFydCcsIHN0YXJ0R3JhYik7XG4gICAgcmVjb2duaXplci5vbigncHJlc3MnLCBzdGFydEdyYWIpO1xuXG4gICAgcmVjb2duaXplci5vbigncGluY2hzdGFydCcsIHN0YXJ0Wm9vbSk7XG4gIH1cblxuICBpZiAoZHJhZ2dpbmcpIHtcblxuICAgIC8vIHNpbXVsYXRlIGhvdmVyIGR1cmluZyBkcmFnZ2luZ1xuICAgIGV2ZW50QnVzLm9uKCdkcmFnLm1vdmUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgICB2YXIgb3JpZ2luYWxFdmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG5cbiAgICAgIGlmICghb3JpZ2luYWxFdmVudCB8fCBvcmlnaW5hbEV2ZW50IGluc3RhbmNlb2YgTW91c2VFdmVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBwb3NpdGlvbiA9IHRvUG9pbnQob3JpZ2luYWxFdmVudCk7XG5cbiAgICAgIC8vIHRoaXMgZ2V0cyByZWFsbHkgZXhwZW5zaXZlIC4uLlxuICAgICAgdmFyIG5vZGUgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpLFxuICAgICAgICAgIGdmeCA9IGdldEdmeChub2RlKSxcbiAgICAgICAgICBlbGVtZW50ID0gZ2Z4ICYmIGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcblxuICAgICAgaWYgKGVsZW1lbnQgIT09IGV2ZW50LmhvdmVyKSB7XG4gICAgICAgIGlmIChldmVudC5ob3Zlcikge1xuICAgICAgICAgIGRyYWdnaW5nLm91dChldmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIGRyYWdnaW5nLmhvdmVyKHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG5cbiAgICAgICAgICBldmVudC5ob3ZlciA9IGVsZW1lbnQ7XG4gICAgICAgICAgZXZlbnQuaG92ZXJHZnggPSBnZng7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChjb250ZXh0UGFkKSB7XG5cbiAgICBldmVudEJ1cy5vbignY29udGV4dFBhZC5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIG5vZGUgPSBldmVudC5wYWQuaHRtbDtcblxuICAgICAgLy8gdG91Y2ggcmVjb2duaXplclxuICAgICAgdmFyIHBhZFJlY29nbml6ZXIgPSBjcmVhdGVUb3VjaFJlY29nbml6ZXIobm9kZSk7XG5cbiAgICAgIHBhZFJlY29nbml6ZXIub24oJ3BhbnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgbG9nKCdjb250ZXh0LXBhZCcsICdwYW5zdGFydCcsIGV2ZW50KTtcbiAgICAgICAgY29udGV4dFBhZC50cmlnZ2VyKCdkcmFnc3RhcnQnLCBldmVudCwgdHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgcGFkUmVjb2duaXplci5vbigncHJlc3MnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICBsb2coJ2NvbnRleHQtcGFkJywgJ3ByZXNzJywgZXZlbnQpO1xuICAgICAgICBjb250ZXh0UGFkLnRyaWdnZXIoJ2RyYWdzdGFydCcsIGV2ZW50LCB0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBwYWRSZWNvZ25pemVyLm9uKCd0YXAnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICBsb2coJ2NvbnRleHQtcGFkJywgJ3RhcCcsIGV2ZW50KTtcbiAgICAgICAgY29udGV4dFBhZC50cmlnZ2VyKCdjbGljaycsIGV2ZW50KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHBhbGV0dGUpIHtcbiAgICBldmVudEJ1cy5vbigncGFsZXR0ZS5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIG5vZGUgPSBldmVudC5jb250YWluZXI7XG5cbiAgICAgIC8vIHRvdWNoIHJlY29nbml6ZXJcbiAgICAgIHZhciBwYWRSZWNvZ25pemVyID0gY3JlYXRlVG91Y2hSZWNvZ25pemVyKG5vZGUpO1xuXG4gICAgICBwYWRSZWNvZ25pemVyLm9uKCdwYW5zdGFydCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIGxvZygncGFsZXR0ZScsICdwYW5zdGFydCcsIGV2ZW50KTtcbiAgICAgICAgcGFsZXR0ZS50cmlnZ2VyKCdkcmFnc3RhcnQnLCBldmVudCwgdHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgcGFkUmVjb2duaXplci5vbigncHJlc3MnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICBsb2coJ3BhbGV0dGUnLCAncHJlc3MnLCBldmVudCk7XG4gICAgICAgIHBhbGV0dGUudHJpZ2dlcignZHJhZ3N0YXJ0JywgZXZlbnQsIHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIHBhZFJlY29nbml6ZXIub24oJ3RhcCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIGxvZygncGFsZXR0ZScsICd0YXAnLCBldmVudCk7XG4gICAgICAgIHBhbGV0dGUudHJpZ2dlcignY2xpY2snLCBldmVudCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuaW5pdCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaW5pdEV2ZW50cyhldmVudC5zdmcpO1xuICB9KTtcbn1cblxuXG5Ub3VjaEludGVyYWN0aW9uRXZlbnRzLiRpbmplY3QgPSBbXG4gICdpbmplY3RvcicsXG4gICdjYW52YXMnLFxuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ2ludGVyYWN0aW9uRXZlbnRzJyxcbiAgJ3RvdWNoRml4J1xuXTtcbiIsImltcG9ydCBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSBmcm9tICcuLi9pbnRlcmFjdGlvbi1ldmVudHMnO1xuXG5pbXBvcnQgVG91Y2hJbnRlcmFjdGlvbkV2ZW50cyBmcm9tICcuL1RvdWNoSW50ZXJhY3Rpb25FdmVudHMnO1xuaW1wb3J0IFRvdWNoRml4IGZyb20gJy4vVG91Y2hGaXgnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbIEludGVyYWN0aW9uRXZlbnRzTW9kdWxlIF0sXG4gIF9faW5pdF9fOiBbICd0b3VjaEludGVyYWN0aW9uRXZlbnRzJyBdLFxuICB0b3VjaEludGVyYWN0aW9uRXZlbnRzOiBbICd0eXBlJywgVG91Y2hJbnRlcmFjdGlvbkV2ZW50cyBdLFxuICB0b3VjaEZpeDogWyAndHlwZScsIFRvdWNoRml4IF1cbn07IiwiaW1wb3J0IHRyYW5zbGF0ZSBmcm9tICcuL3RyYW5zbGF0ZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgdHJhbnNsYXRlOiBbICd2YWx1ZScsIHRyYW5zbGF0ZSBdXG59OyIsIi8qKlxuICogQSBzaW1wbGUgdHJhbnNsYXRpb24gc3R1YiB0byBiZSB1c2VkIGZvciBtdWx0aS1sYW5ndWFnZSBzdXBwb3J0XG4gKiBpbiBkaWFncmFtcy4gQ2FuIGJlIGVhc2lseSByZXBsYWNlZCB3aXRoIGEgbW9yZSBzb3BoaXN0aWNhdGVkXG4gKiBzb2x1dGlvbi5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIHVzZSBpdCBpbnNpZGUgYW55IGRpYWdyYW0gY29tcG9uZW50IGJ5IGluamVjdGluZyBgdHJhbnNsYXRlYC5cbiAqXG4gKiBmdW5jdGlvbiBNeVNlcnZpY2UodHJhbnNsYXRlKSB7XG4gKiAgIGFsZXJ0KHRyYW5zbGF0ZSgnSEVMTE8ge3lvdX0nLCB7IHlvdTogJ1lvdSEnIH0pKTtcbiAqIH1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGVtcGxhdGUgdG8gaW50ZXJwb2xhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVwbGFjZW1lbnRzXSBhIG1hcCB3aXRoIHN1YnN0aXR1dGVzXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgdHJhbnNsYXRlZCBzdHJpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdHJhbnNsYXRlKHRlbXBsYXRlLCByZXBsYWNlbWVudHMpIHtcblxuICByZXBsYWNlbWVudHMgPSByZXBsYWNlbWVudHMgfHwge307XG5cbiAgcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoL3soW159XSspfS9nLCBmdW5jdGlvbihfLCBrZXkpIHtcbiAgICByZXR1cm4gcmVwbGFjZW1lbnRzW2tleV0gfHwgJ3snICsga2V5ICsgJ30nO1xuICB9KTtcbn0iLCJpbXBvcnQge1xuICBnZXRNaWRcbn0gZnJvbSAnLi9MYXlvdXRVdGlsJztcblxuXG4vKipcbiAqIEEgYmFzZSBjb25uZWN0aW9uIGxheW91dGVyIGltcGxlbWVudGF0aW9uXG4gKiB0aGF0IGxheW91dHMgdGhlIGNvbm5lY3Rpb24gYnkgZGlyZWN0bHkgY29ubmVjdGluZ1xuICogbWlkKHNvdXJjZSkgKyBtaWQodGFyZ2V0KS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmFzZUxheW91dGVyKCkge31cblxuXG4vKipcbiAqIFJldHVybiB0aGUgbmV3IGxheW91dGVkIHdheXBvaW50cyBmb3IgdGhlIGdpdmVuIGNvbm5lY3Rpb24uXG4gKlxuICogVGhlIGNvbm5lY3Rpb24gcGFzc2VkIGlzIHN0aWxsIHVuY2hhbmdlZDsgeW91IG1heSBmaWd1cmUgb3V0IGFib3V0XG4gKiB0aGUgbmV3IGNvbm5lY3Rpb24gc3RhcnQgLyBlbmQgdmlhIHRoZSBsYXlvdXQgaGludHMgcHJvdmlkZWQuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuQ29ubmVjdGlvbn0gY29ubmVjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7UG9pbnR9IFtoaW50cy5jb25uZWN0aW9uU3RhcnRdXG4gKiBAcGFyYW0ge1BvaW50fSBbaGludHMuY29ubmVjdGlvbkVuZF1cbiAqIEBwYXJhbSB7UG9pbnR9IFtoaW50cy5zb3VyY2VdXG4gKiBAcGFyYW0ge1BvaW50fSBbaGludHMudGFyZ2V0XVxuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gdGhlIGxheW91dGVkIGNvbm5lY3Rpb24gd2F5cG9pbnRzXG4gKi9cbkJhc2VMYXlvdXRlci5wcm90b3R5cGUubGF5b3V0Q29ubmVjdGlvbiA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIGhpbnRzKSB7XG5cbiAgaGludHMgPSBoaW50cyB8fCB7fTtcblxuICByZXR1cm4gW1xuICAgIGhpbnRzLmNvbm5lY3Rpb25TdGFydCB8fCBnZXRNaWQoaGludHMuc291cmNlIHx8IGNvbm5lY3Rpb24uc291cmNlKSxcbiAgICBoaW50cy5jb25uZWN0aW9uRW5kIHx8IGdldE1pZChoaW50cy50YXJnZXQgfHwgY29ubmVjdGlvbi50YXJnZXQpXG4gIF07XG59O1xuIiwiaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0RWxlbWVudExpbmVJbnRlcnNlY3Rpb25cbn0gZnJvbSAnLi9MYXlvdXRVdGlsJztcblxuXG5mdW5jdGlvbiBkb2NraW5nVG9Qb2ludChkb2NraW5nKSB7XG5cbiAgLy8gdXNlIHRoZSBkb2NraW5ncyBhY3R1YWwgcG9pbnQgYW5kXG4gIC8vIHJldGFpbiB0aGUgb3JpZ2luYWwgZG9ja2luZ1xuICByZXR1cm4gYXNzaWduKHsgb3JpZ2luYWw6IGRvY2tpbmcucG9pbnQub3JpZ2luYWwgfHwgZG9ja2luZy5wb2ludCB9LCBkb2NraW5nLmFjdHVhbCk7XG59XG5cblxuLyoqXG4gKiBBIHtAbGluayBDb25uZWN0aW9uRG9ja2luZ30gdGhhdCBjcm9wcyBjb25uZWN0aW9uIHdheXBvaW50cyBiYXNlZCBvblxuICogdGhlIHBhdGgocykgb2YgdGhlIGNvbm5lY3Rpb24gc291cmNlIGFuZCB0YXJnZXQuXG4gKlxuICogQHBhcmFtIHtkanMuY29yZS5FbGVtZW50UmVnaXN0cnl9IGVsZW1lbnRSZWdpc3RyeVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nKGVsZW1lbnRSZWdpc3RyeSwgZ3JhcGhpY3NGYWN0b3J5KSB7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbiAgdGhpcy5fZ3JhcGhpY3NGYWN0b3J5ID0gZ3JhcGhpY3NGYWN0b3J5O1xufVxuXG5Dcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nLiRpbmplY3QgPSBbICdlbGVtZW50UmVnaXN0cnknLCAnZ3JhcGhpY3NGYWN0b3J5JyBdO1xuXG5cbi8qKlxuICogQGluaGVyaXREb2MgQ29ubmVjdGlvbkRvY2tpbmcjZ2V0Q3JvcHBlZFdheXBvaW50c1xuICovXG5Dcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nLnByb3RvdHlwZS5nZXRDcm9wcGVkV2F5cG9pbnRzID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgc291cmNlLCB0YXJnZXQpIHtcblxuICBzb3VyY2UgPSBzb3VyY2UgfHwgY29ubmVjdGlvbi5zb3VyY2U7XG4gIHRhcmdldCA9IHRhcmdldCB8fCBjb25uZWN0aW9uLnRhcmdldDtcblxuICB2YXIgc291cmNlRG9ja2luZyA9IHRoaXMuZ2V0RG9ja2luZ1BvaW50KGNvbm5lY3Rpb24sIHNvdXJjZSwgdHJ1ZSksXG4gICAgICB0YXJnZXREb2NraW5nID0gdGhpcy5nZXREb2NraW5nUG9pbnQoY29ubmVjdGlvbiwgdGFyZ2V0KTtcblxuICB2YXIgY3JvcHBlZFdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzLnNsaWNlKHNvdXJjZURvY2tpbmcuaWR4ICsgMSwgdGFyZ2V0RG9ja2luZy5pZHgpO1xuXG4gIGNyb3BwZWRXYXlwb2ludHMudW5zaGlmdChkb2NraW5nVG9Qb2ludChzb3VyY2VEb2NraW5nKSk7XG4gIGNyb3BwZWRXYXlwb2ludHMucHVzaChkb2NraW5nVG9Qb2ludCh0YXJnZXREb2NraW5nKSk7XG5cbiAgcmV0dXJuIGNyb3BwZWRXYXlwb2ludHM7XG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgY29ubmVjdGlvbiBkb2NraW5nIHBvaW50IG9uIHRoZSBzcGVjaWZpZWQgc2hhcGVcbiAqXG4gKiBAaW5oZXJpdERvYyBDb25uZWN0aW9uRG9ja2luZyNnZXREb2NraW5nUG9pbnRcbiAqL1xuQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZy5wcm90b3R5cGUuZ2V0RG9ja2luZ1BvaW50ID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgc2hhcGUsIGRvY2tTdGFydCkge1xuXG4gIHZhciB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgIGRvY2tpbmdJZHgsXG4gICAgICBkb2NraW5nUG9pbnQsXG4gICAgICBjcm9wcGVkUG9pbnQ7XG5cbiAgZG9ja2luZ0lkeCA9IGRvY2tTdGFydCA/IDAgOiB3YXlwb2ludHMubGVuZ3RoIC0gMTtcbiAgZG9ja2luZ1BvaW50ID0gd2F5cG9pbnRzW2RvY2tpbmdJZHhdO1xuXG4gIGNyb3BwZWRQb2ludCA9IHRoaXMuX2dldEludGVyc2VjdGlvbihzaGFwZSwgY29ubmVjdGlvbiwgZG9ja1N0YXJ0KTtcblxuICByZXR1cm4ge1xuICAgIHBvaW50OiBkb2NraW5nUG9pbnQsXG4gICAgYWN0dWFsOiBjcm9wcGVkUG9pbnQgfHwgZG9ja2luZ1BvaW50LFxuICAgIGlkeDogZG9ja2luZ0lkeFxuICB9O1xufTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZy5wcm90b3R5cGUuX2dldEludGVyc2VjdGlvbiA9IGZ1bmN0aW9uKHNoYXBlLCBjb25uZWN0aW9uLCB0YWtlRmlyc3QpIHtcblxuICB2YXIgc2hhcGVQYXRoID0gdGhpcy5fZ2V0U2hhcGVQYXRoKHNoYXBlKSxcbiAgICAgIGNvbm5lY3Rpb25QYXRoID0gdGhpcy5fZ2V0Q29ubmVjdGlvblBhdGgoY29ubmVjdGlvbik7XG5cbiAgcmV0dXJuIGdldEVsZW1lbnRMaW5lSW50ZXJzZWN0aW9uKHNoYXBlUGF0aCwgY29ubmVjdGlvblBhdGgsIHRha2VGaXJzdCk7XG59O1xuXG5Dcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nLnByb3RvdHlwZS5fZ2V0Q29ubmVjdGlvblBhdGggPSBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gIHJldHVybiB0aGlzLl9ncmFwaGljc0ZhY3RvcnkuZ2V0Q29ubmVjdGlvblBhdGgoY29ubmVjdGlvbik7XG59O1xuXG5Dcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nLnByb3RvdHlwZS5fZ2V0U2hhcGVQYXRoID0gZnVuY3Rpb24oc2hhcGUpIHtcbiAgcmV0dXJuIHRoaXMuX2dyYXBoaWNzRmFjdG9yeS5nZXRTaGFwZVBhdGgoc2hhcGUpO1xufTtcblxuQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZy5wcm90b3R5cGUuX2dldEdmeCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXRHcmFwaGljcyhlbGVtZW50KTtcbn07XG4iLCJpbXBvcnQge1xuICBpc09iamVjdCxcbiAgc29ydEJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgcG9pbnREaXN0YW5jZSxcbiAgcG9pbnRzT25MaW5lXG59IGZyb20gJy4uL3V0aWwvR2VvbWV0cnknO1xuXG5pbXBvcnQgaW50ZXJzZWN0UGF0aHMgZnJvbSAncGF0aC1pbnRlcnNlY3Rpb24nO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiByb3VuZEJvdW5kcyhib3VuZHMpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBNYXRoLnJvdW5kKGJvdW5kcy54KSxcbiAgICB5OiBNYXRoLnJvdW5kKGJvdW5kcy55KSxcbiAgICB3aWR0aDogTWF0aC5yb3VuZChib3VuZHMud2lkdGgpLFxuICAgIGhlaWdodDogTWF0aC5yb3VuZChib3VuZHMuaGVpZ2h0KVxuICB9O1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiByb3VuZFBvaW50KHBvaW50KSB7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBNYXRoLnJvdW5kKHBvaW50LngpLFxuICAgIHk6IE1hdGgucm91bmQocG9pbnQueSlcbiAgfTtcbn1cblxuXG4vKipcbiAqIENvbnZlcnQgdGhlIGdpdmVuIGJvdW5kcyB0byBhIHsgdG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0IH0gZGVzY3JpcHRvci5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc3xQb2ludH0gYm91bmRzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNUUkJMKGJvdW5kcykge1xuICByZXR1cm4ge1xuICAgIHRvcDogYm91bmRzLnksXG4gICAgcmlnaHQ6IGJvdW5kcy54ICsgKGJvdW5kcy53aWR0aCB8fCAwKSxcbiAgICBib3R0b206IGJvdW5kcy55ICsgKGJvdW5kcy5oZWlnaHQgfHwgMCksXG4gICAgbGVmdDogYm91bmRzLnhcbiAgfTtcbn1cblxuXG4vKipcbiAqIENvbnZlcnQgYSB7IHRvcCwgbGVmdCwgYm90dG9tLCByaWdodCB9IHRvIGFuIG9iamVjdHMgYm91bmRzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0cmJsXG4gKlxuICogQHJldHVybiB7Qm91bmRzfVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNCb3VuZHModHJibCkge1xuICByZXR1cm4ge1xuICAgIHg6IHRyYmwubGVmdCxcbiAgICB5OiB0cmJsLnRvcCxcbiAgICB3aWR0aDogdHJibC5yaWdodCAtIHRyYmwubGVmdCxcbiAgICBoZWlnaHQ6IHRyYmwuYm90dG9tIC0gdHJibC50b3BcbiAgfTtcbn1cblxuXG4vKipcbiAqIEdldCB0aGUgbWlkIG9mIHRoZSBnaXZlbiBib3VuZHMgb3IgcG9pbnQuXG4gKlxuICogQHBhcmFtIHtCb3VuZHN8UG9pbnR9IGJvdW5kc1xuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWlkKGJvdW5kcykge1xuICByZXR1cm4gcm91bmRQb2ludCh7XG4gICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIHx8IDApIC8gMixcbiAgICB5OiBib3VuZHMueSArIChib3VuZHMuaGVpZ2h0IHx8IDApIC8gMlxuICB9KTtcbn1cblxuXG4vLyBvcmllbnRhdGlvbiB1dGlscyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogR2V0IG9yaWVudGF0aW9uIG9mIHRoZSBnaXZlbiByZWN0YW5nbGUgd2l0aCByZXNwZWN0IHRvXG4gKiB0aGUgcmVmZXJlbmNlIHJlY3RhbmdsZS5cbiAqXG4gKiBBIHBhZGRpbmcgKHBvc2l0aXZlIG9yIG5lZ2F0aXZlKSBtYXkgYmUgcGFzc2VkIHRvIGluZmx1ZW5jZVxuICogaG9yaXpvbnRhbCAvIHZlcnRpY2FsIG9yaWVudGF0aW9uIGFuZCBpbnRlcnNlY3Rpb24uXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IHJlY3RcbiAqIEBwYXJhbSB7Qm91bmRzfSByZWZlcmVuY2VcbiAqIEBwYXJhbSB7UG9pbnR8bnVtYmVyfSBwYWRkaW5nXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgb3JpZW50YXRpb247IG9uZSBvZiB0b3AsIHRvcC1sZWZ0LCBsZWZ0LCAuLi4sIGJvdHRvbSwgcmlnaHQgb3IgaW50ZXJzZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3JpZW50YXRpb24ocmVjdCwgcmVmZXJlbmNlLCBwYWRkaW5nKSB7XG5cbiAgcGFkZGluZyA9IHBhZGRpbmcgfHwgMDtcblxuICAvLyBtYWtlIHN1cmUgd2UgY2FuIHVzZSBhbiBvYmplY3QsIHRvb1xuICAvLyBmb3IgaW5kaXZpZHVhbCB7IHgsIHkgfSBwYWRkaW5nXG4gIGlmICghaXNPYmplY3QocGFkZGluZykpIHtcbiAgICBwYWRkaW5nID0geyB4OiBwYWRkaW5nLCB5OiBwYWRkaW5nIH07XG4gIH1cblxuXG4gIHZhciByZWN0T3JpZW50YXRpb24gPSBhc1RSQkwocmVjdCksXG4gICAgICByZWZlcmVuY2VPcmllbnRhdGlvbiA9IGFzVFJCTChyZWZlcmVuY2UpO1xuXG4gIHZhciB0b3AgPSByZWN0T3JpZW50YXRpb24uYm90dG9tICsgcGFkZGluZy55IDw9IHJlZmVyZW5jZU9yaWVudGF0aW9uLnRvcCxcbiAgICAgIHJpZ2h0ID0gcmVjdE9yaWVudGF0aW9uLmxlZnQgLSBwYWRkaW5nLnggPj0gcmVmZXJlbmNlT3JpZW50YXRpb24ucmlnaHQsXG4gICAgICBib3R0b20gPSByZWN0T3JpZW50YXRpb24udG9wIC0gcGFkZGluZy55ID49IHJlZmVyZW5jZU9yaWVudGF0aW9uLmJvdHRvbSxcbiAgICAgIGxlZnQgPSByZWN0T3JpZW50YXRpb24ucmlnaHQgKyBwYWRkaW5nLnggPD0gcmVmZXJlbmNlT3JpZW50YXRpb24ubGVmdDtcblxuICB2YXIgdmVydGljYWwgPSB0b3AgPyAndG9wJyA6IChib3R0b20gPyAnYm90dG9tJyA6IG51bGwpLFxuICAgICAgaG9yaXpvbnRhbCA9IGxlZnQgPyAnbGVmdCcgOiAocmlnaHQgPyAncmlnaHQnIDogbnVsbCk7XG5cbiAgaWYgKGhvcml6b250YWwgJiYgdmVydGljYWwpIHtcbiAgICByZXR1cm4gdmVydGljYWwgKyAnLScgKyBob3Jpem9udGFsO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBob3Jpem9udGFsIHx8IHZlcnRpY2FsIHx8ICdpbnRlcnNlY3QnO1xuICB9XG59XG5cblxuLy8gaW50ZXJzZWN0aW9uIHV0aWxzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBHZXQgaW50ZXJzZWN0aW9uIGJldHdlZW4gYW4gZWxlbWVudCBhbmQgYSBsaW5lIHBhdGguXG4gKlxuICogQHBhcmFtIHtQYXRoRGVmfSBlbGVtZW50UGF0aFxuICogQHBhcmFtIHtQYXRoRGVmfSBsaW5lUGF0aFxuICogQHBhcmFtIHtib29sZWFufSBjcm9wU3RhcnQgY3JvcCBmcm9tIHN0YXJ0IG9yIGVuZFxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RWxlbWVudExpbmVJbnRlcnNlY3Rpb24oZWxlbWVudFBhdGgsIGxpbmVQYXRoLCBjcm9wU3RhcnQpIHtcblxuICB2YXIgaW50ZXJzZWN0aW9ucyA9IGdldEludGVyc2VjdGlvbnMoZWxlbWVudFBhdGgsIGxpbmVQYXRoKTtcblxuICAvLyByZWNvZ25pemUgaW50ZXJzZWN0aW9uc1xuICAvLyBvbmx5IG9uZSAtPiBjaG9vc2VcbiAgLy8gdHdvIGNsb3NlIHRvZ2V0aGVyIC0+IGNob29zZSBmaXJzdFxuICAvLyB0d28gb3IgbW9yZSBkaXN0aW5jdCAtPiBwdWxsIG91dCBhcHByb3ByaWF0ZSBvbmVcbiAgLy8gbm9uZSAtPiBvayAoZmFsbGJhY2sgdG8gcG9pbnQgaXRzZWxmKVxuICBpZiAoaW50ZXJzZWN0aW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gcm91bmRQb2ludChpbnRlcnNlY3Rpb25zWzBdKTtcbiAgfSBlbHNlIGlmIChpbnRlcnNlY3Rpb25zLmxlbmd0aCA9PT0gMiAmJiBwb2ludERpc3RhbmNlKGludGVyc2VjdGlvbnNbMF0sIGludGVyc2VjdGlvbnNbMV0pIDwgMSkge1xuICAgIHJldHVybiByb3VuZFBvaW50KGludGVyc2VjdGlvbnNbMF0pO1xuICB9IGVsc2UgaWYgKGludGVyc2VjdGlvbnMubGVuZ3RoID4gMSkge1xuXG4gICAgLy8gc29ydCBieSBpbnRlcnNlY3Rpb25zIGJhc2VkIG9uIGNvbm5lY3Rpb24gc2VnbWVudCArXG4gICAgLy8gZGlzdGFuY2UgZnJvbSBzdGFydFxuICAgIGludGVyc2VjdGlvbnMgPSBzb3J0QnkoaW50ZXJzZWN0aW9ucywgZnVuY3Rpb24oaSkge1xuICAgICAgdmFyIGRpc3RhbmNlID0gTWF0aC5mbG9vcihpLnQyICogMTAwKSB8fCAxO1xuXG4gICAgICBkaXN0YW5jZSA9IDEwMCAtIGRpc3RhbmNlO1xuXG4gICAgICBkaXN0YW5jZSA9IChkaXN0YW5jZSA8IDEwID8gJzAnIDogJycpICsgZGlzdGFuY2U7XG5cbiAgICAgIC8vIGNyZWF0ZSBhIHNvcnQgc3RyaW5nIHRoYXQgbWFrZXMgc3VyZSB3ZSBzb3J0XG4gICAgICAvLyBsaW5lIHNlZ21lbnQgQVNDICsgbGluZSBzZWdtZW50IHBvc2l0aW9uIERFU0MgKGZvciBjcm9wU3RhcnQpXG4gICAgICAvLyBsaW5lIHNlZ21lbnQgQVNDICsgbGluZSBzZWdtZW50IHBvc2l0aW9uIEFTQyAoZm9yIGNyb3BFbmQpXG4gICAgICByZXR1cm4gaS5zZWdtZW50MiArICcjJyArIGRpc3RhbmNlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJvdW5kUG9pbnQoaW50ZXJzZWN0aW9uc1tjcm9wU3RhcnQgPyAwIDogaW50ZXJzZWN0aW9ucy5sZW5ndGggLSAxXSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW50ZXJzZWN0aW9ucyhhLCBiKSB7XG4gIHJldHVybiBpbnRlcnNlY3RQYXRocyhhLCBiKTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyUmVkdW5kYW50V2F5cG9pbnRzKHdheXBvaW50cykge1xuXG4gIC8vIGFsdGVyIGNvcHkgb2Ygd2F5cG9pbnRzLCBub3Qgb3JpZ2luYWxcbiAgd2F5cG9pbnRzID0gd2F5cG9pbnRzLnNsaWNlKCk7XG5cbiAgdmFyIGlkeCA9IDAsXG4gICAgICBwb2ludCxcbiAgICAgIHByZXZpb3VzUG9pbnQsXG4gICAgICBuZXh0UG9pbnQ7XG5cbiAgd2hpbGUgKHdheXBvaW50c1tpZHhdKSB7XG4gICAgcG9pbnQgPSB3YXlwb2ludHNbaWR4XTtcbiAgICBwcmV2aW91c1BvaW50ID0gd2F5cG9pbnRzW2lkeCAtIDFdO1xuICAgIG5leHRQb2ludCA9IHdheXBvaW50c1tpZHggKyAxXTtcblxuICAgIGlmIChwb2ludERpc3RhbmNlKHBvaW50LCBuZXh0UG9pbnQpID09PSAwIHx8XG4gICAgICAgIHBvaW50c09uTGluZShwcmV2aW91c1BvaW50LCBuZXh0UG9pbnQsIHBvaW50KSkge1xuXG4gICAgICAvLyByZW1vdmUgcG9pbnQsIGlmIG92ZXJsYXBwaW5nIHdpdGgge25leHRQb2ludH1cbiAgICAgIC8vIG9yIG9uIGxpbmUgd2l0aCB7cHJldmlvdXNQb2ludH0gLT4ge3BvaW50fSAtPiB7bmV4dFBvaW50fVxuICAgICAgd2F5cG9pbnRzLnNwbGljZShpZHgsIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZHgrKztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gd2F5cG9pbnRzO1xufVxuIiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaW5kLFxuICBpc0FycmF5LFxuICB3aXRob3V0XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0T3JpZW50YXRpb24sXG4gIGdldE1pZFxufSBmcm9tICcuL0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBwb2ludEluUmVjdCxcbiAgcG9pbnREaXN0YW5jZSxcbiAgcG9pbnRzQWxpZ25lZCxcbiAgcG9pbnRzT25MaW5lXG59IGZyb20gJy4uL3V0aWwvR2VvbWV0cnknO1xuXG52YXIgTUlOX1NFR01FTlRfTEVOR1RIID0gMjAsXG4gICAgUE9JTlRfT1JJRU5UQVRJT05fUEFERElORyA9IDU7XG5cbnZhciByb3VuZCA9IE1hdGgucm91bmQ7XG5cbnZhciBJTlRFUlNFQ1RJT05fVEhSRVNIT0xEID0gMjAsXG4gICAgT1JJRU5UQVRJT05fVEhSRVNIT0xEID0ge1xuICAgICAgJ2g6aCc6IDIwLFxuICAgICAgJ3Y6dic6IDIwLFxuICAgICAgJ2g6dic6IC0xMCxcbiAgICAgICd2OmgnOiAtMTBcbiAgICB9O1xuXG5mdW5jdGlvbiBuZWVkc1R1cm4ob3JpZW50YXRpb24sIHN0YXJ0RGlyZWN0aW9uKSB7XG4gIHJldHVybiAhe1xuICAgIHQ6IC90b3AvLFxuICAgIHI6IC9yaWdodC8sXG4gICAgYjogL2JvdHRvbS8sXG4gICAgbDogL2xlZnQvLFxuICAgIGg6IC8uLyxcbiAgICB2OiAvLi9cbiAgfVtzdGFydERpcmVjdGlvbl0udGVzdChvcmllbnRhdGlvbik7XG59XG5cbmZ1bmN0aW9uIGNhbkxheW91dFN0cmFpZ2h0KGRpcmVjdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24pIHtcbiAgcmV0dXJuIHtcbiAgICB0OiAvdG9wLyxcbiAgICByOiAvcmlnaHQvLFxuICAgIGI6IC9ib3R0b20vLFxuICAgIGw6IC9sZWZ0LyxcbiAgICBoOiAvbGVmdHxyaWdodC8sXG4gICAgdjogL3RvcHxib3R0b20vXG4gIH1bZGlyZWN0aW9uXS50ZXN0KHRhcmdldE9yaWVudGF0aW9uKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2VnbWVudEJlbmRwb2ludHMoYSwgYiwgZGlyZWN0aW9ucykge1xuICB2YXIgb3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihiLCBhLCBQT0lOVF9PUklFTlRBVElPTl9QQURESU5HKTtcblxuICB2YXIgc3RhcnREaXJlY3Rpb24gPSBkaXJlY3Rpb25zLnNwbGl0KCc6JylbMF07XG5cbiAgdmFyIHhtaWQgPSByb3VuZCgoYi54IC0gYS54KSAvIDIgKyBhLngpLFxuICAgICAgeW1pZCA9IHJvdW5kKChiLnkgLSBhLnkpIC8gMiArIGEueSk7XG5cbiAgdmFyIHNlZ21lbnRFbmQsIHNlZ21lbnREaXJlY3Rpb25zO1xuXG4gIHZhciBsYXlvdXRTdHJhaWdodCA9IGNhbkxheW91dFN0cmFpZ2h0KHN0YXJ0RGlyZWN0aW9uLCBvcmllbnRhdGlvbiksXG4gICAgICBsYXlvdXRIb3Jpem9udGFsID0gL2h8cnxsLy50ZXN0KHN0YXJ0RGlyZWN0aW9uKSxcbiAgICAgIGxheW91dFR1cm4gPSBmYWxzZTtcblxuICB2YXIgdHVybk5leHREaXJlY3Rpb25zID0gZmFsc2U7XG5cbiAgaWYgKGxheW91dFN0cmFpZ2h0KSB7XG4gICAgc2VnbWVudEVuZCA9IGxheW91dEhvcml6b250YWwgPyB7IHg6IHhtaWQsIHk6IGEueSB9IDogeyB4OiBhLngsIHk6IHltaWQgfTtcblxuICAgIHNlZ21lbnREaXJlY3Rpb25zID0gbGF5b3V0SG9yaXpvbnRhbCA/ICdoOmgnIDogJ3Y6dic7XG4gIH0gZWxzZSB7XG4gICAgbGF5b3V0VHVybiA9IG5lZWRzVHVybihvcmllbnRhdGlvbiwgc3RhcnREaXJlY3Rpb24pO1xuXG4gICAgc2VnbWVudERpcmVjdGlvbnMgPSBsYXlvdXRIb3Jpem9udGFsID8gJ2g6dicgOiAndjpoJztcblxuICAgIGlmIChsYXlvdXRUdXJuKSB7XG5cbiAgICAgIGlmIChsYXlvdXRIb3Jpem9udGFsKSB7XG4gICAgICAgIHR1cm5OZXh0RGlyZWN0aW9ucyA9IHltaWQgPT09IGEueTtcblxuICAgICAgICBzZWdtZW50RW5kID0ge1xuICAgICAgICAgIHg6IGEueCArIE1JTl9TRUdNRU5UX0xFTkdUSCAqICgvbC8udGVzdChzdGFydERpcmVjdGlvbikgPyAtMSA6IDEpLFxuICAgICAgICAgIHk6IHR1cm5OZXh0RGlyZWN0aW9ucyA/IHltaWQgKyBNSU5fU0VHTUVOVF9MRU5HVEggOiB5bWlkXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0dXJuTmV4dERpcmVjdGlvbnMgPSB4bWlkID09PSBhLng7XG5cbiAgICAgICAgc2VnbWVudEVuZCA9IHtcbiAgICAgICAgICB4OiB0dXJuTmV4dERpcmVjdGlvbnMgPyB4bWlkICsgTUlOX1NFR01FTlRfTEVOR1RIIDogeG1pZCxcbiAgICAgICAgICB5OiBhLnkgKyBNSU5fU0VHTUVOVF9MRU5HVEggKiAoL3QvLnRlc3Qoc3RhcnREaXJlY3Rpb24pID8gLTEgOiAxKVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIHNlZ21lbnRFbmQgPSB7XG4gICAgICAgIHg6IHhtaWQsXG4gICAgICAgIHk6IHltaWRcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3YXlwb2ludHM6IGdldEJlbmRwb2ludHMoYSwgc2VnbWVudEVuZCwgc2VnbWVudERpcmVjdGlvbnMpLmNvbmNhdChzZWdtZW50RW5kKSxcbiAgICBkaXJlY3Rpb25zOiAgc2VnbWVudERpcmVjdGlvbnMsXG4gICAgdHVybk5leHREaXJlY3Rpb25zOiB0dXJuTmV4dERpcmVjdGlvbnNcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RhcnRTZWdtZW50KGEsIGIsIGRpcmVjdGlvbnMpIHtcbiAgcmV0dXJuIGdldFNlZ21lbnRCZW5kcG9pbnRzKGEsIGIsIGRpcmVjdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBnZXRFbmRTZWdtZW50KGEsIGIsIGRpcmVjdGlvbnMpIHtcbiAgdmFyIGludmVydGVkU2VnbWVudCA9IGdldFNlZ21lbnRCZW5kcG9pbnRzKGIsIGEsIGludmVydERpcmVjdGlvbnMoZGlyZWN0aW9ucykpO1xuXG4gIHJldHVybiB7XG4gICAgd2F5cG9pbnRzOiBpbnZlcnRlZFNlZ21lbnQud2F5cG9pbnRzLnNsaWNlKCkucmV2ZXJzZSgpLFxuICAgIGRpcmVjdGlvbnM6IGludmVydERpcmVjdGlvbnMoaW52ZXJ0ZWRTZWdtZW50LmRpcmVjdGlvbnMpLFxuICAgIHR1cm5OZXh0RGlyZWN0aW9uczogaW52ZXJ0ZWRTZWdtZW50LnR1cm5OZXh0RGlyZWN0aW9uc1xuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRNaWRTZWdtZW50KHN0YXJ0U2VnbWVudCwgZW5kU2VnbWVudCkge1xuXG4gIHZhciBzdGFydERpcmVjdGlvbiA9IHN0YXJ0U2VnbWVudC5kaXJlY3Rpb25zLnNwbGl0KCc6JylbMV0sXG4gICAgICBlbmREaXJlY3Rpb24gPSBlbmRTZWdtZW50LmRpcmVjdGlvbnMuc3BsaXQoJzonKVswXTtcblxuICBpZiAoc3RhcnRTZWdtZW50LnR1cm5OZXh0RGlyZWN0aW9ucykge1xuICAgIHN0YXJ0RGlyZWN0aW9uID0gc3RhcnREaXJlY3Rpb24gPT0gJ2gnID8gJ3YnIDogJ2gnO1xuICB9XG5cbiAgaWYgKGVuZFNlZ21lbnQudHVybk5leHREaXJlY3Rpb25zKSB7XG4gICAgZW5kRGlyZWN0aW9uID0gZW5kRGlyZWN0aW9uID09ICdoJyA/ICd2JyA6ICdoJztcbiAgfVxuXG4gIHZhciBkaXJlY3Rpb25zID0gc3RhcnREaXJlY3Rpb24gKyAnOicgKyBlbmREaXJlY3Rpb247XG5cbiAgdmFyIGJlbmRwb2ludHMgPSBnZXRCZW5kcG9pbnRzKFxuICAgIHN0YXJ0U2VnbWVudC53YXlwb2ludHNbc3RhcnRTZWdtZW50LndheXBvaW50cy5sZW5ndGggLSAxXSxcbiAgICBlbmRTZWdtZW50LndheXBvaW50c1swXSxcbiAgICBkaXJlY3Rpb25zXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICB3YXlwb2ludHM6IGJlbmRwb2ludHMsXG4gICAgZGlyZWN0aW9uczogZGlyZWN0aW9uc1xuICB9O1xufVxuXG5mdW5jdGlvbiBpbnZlcnREaXJlY3Rpb25zKGRpcmVjdGlvbnMpIHtcbiAgcmV0dXJuIGRpcmVjdGlvbnMuc3BsaXQoJzonKS5yZXZlcnNlKCkuam9pbignOicpO1xufVxuXG4vKipcbiAqIEhhbmRsZSBzaW1wbGUgbGF5b3V0cyB3aXRoIG1heGltdW0gdHdvIGJlbmRwb2ludHMuXG4gKi9cbmZ1bmN0aW9uIGdldFNpbXBsZUJlbmRwb2ludHMoYSwgYiwgZGlyZWN0aW9ucykge1xuXG4gIHZhciB4bWlkID0gcm91bmQoKGIueCAtIGEueCkgLyAyICsgYS54KSxcbiAgICAgIHltaWQgPSByb3VuZCgoYi55IC0gYS55KSAvIDIgKyBhLnkpO1xuXG4gIC8vIG9uZSBwb2ludCwgcmlnaHQgb3IgbGVmdCBmcm9tIGFcbiAgaWYgKGRpcmVjdGlvbnMgPT09ICdoOnYnKSB7XG4gICAgcmV0dXJuIFsgeyB4OiBiLngsIHk6IGEueSB9IF07XG4gIH1cblxuICAvLyBvbmUgcG9pbnQsIGFib3ZlIG9yIGJlbG93IGFcbiAgaWYgKGRpcmVjdGlvbnMgPT09ICd2OmgnKSB7XG4gICAgcmV0dXJuIFsgeyB4OiBhLngsIHk6IGIueSB9IF07XG4gIH1cblxuICAvLyB2ZXJ0aWNhbCBzZWdtZW50IGJldHdlZW4gYSBhbmQgYlxuICBpZiAoZGlyZWN0aW9ucyA9PT0gJ2g6aCcpIHtcbiAgICByZXR1cm4gW1xuICAgICAgeyB4OiB4bWlkLCB5OiBhLnkgfSxcbiAgICAgIHsgeDogeG1pZCwgeTogYi55IH1cbiAgICBdO1xuICB9XG5cbiAgLy8gaG9yaXpvbnRhbCBzZWdtZW50IGJldHdlZW4gYSBhbmQgYlxuICBpZiAoZGlyZWN0aW9ucyA9PT0gJ3Y6dicpIHtcbiAgICByZXR1cm4gW1xuICAgICAgeyB4OiBhLngsIHk6IHltaWQgfSxcbiAgICAgIHsgeDogYi54LCB5OiB5bWlkIH1cbiAgICBdO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGRpcmVjdGlvbnM6IGNhbiBvbmx5IGhhbmRsZSB2YXJpYW5zIG9mIFtodl06W2h2XScpO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWlkIHBvaW50cyBmb3IgYSBtYW5oYXR0YW4gY29ubmVjdGlvbiBiZXR3ZWVuIHR3byBwb2ludHMuXG4gKlxuICogQGV4YW1wbGUgaDpoIChob3Jpem9udGFsOmhvcml6b250YWwpXG4gKlxuICogW2FdLS0tLVt4XVxuICogICAgICAgICB8XG4gKiAgICAgICAgW3hdLS0tLVtiXVxuICpcbiAqIEBleGFtcGxlIGg6diAoaG9yaXpvbnRhbDp2ZXJ0aWNhbClcbiAqXG4gKiBbYV0tLS0tW3hdXG4gKiAgICAgICAgIHxcbiAqICAgICAgICBbYl1cbiAqXG4gKiBAZXhhbXBsZSBoOnIgKGhvcml6b250YWw6cmlnaHQpXG4gKlxuICogW2FdLS0tLVt4XVxuICogICAgICAgICB8XG4gKiAgICBbYl0tW3hdXG4gKlxuICogQHBhcmFtICB7UG9pbnR9IGFcbiAqIEBwYXJhbSAge1BvaW50fSBiXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGRpcmVjdGlvbnNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxQb2ludD59XG4gKi9cbmZ1bmN0aW9uIGdldEJlbmRwb2ludHMoYSwgYiwgZGlyZWN0aW9ucykge1xuICBkaXJlY3Rpb25zID0gZGlyZWN0aW9ucyB8fCAnaDpoJztcblxuICBpZiAoIWlzVmFsaWREaXJlY3Rpb25zKGRpcmVjdGlvbnMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ3Vua25vd24gZGlyZWN0aW9uczogPCcgKyBkaXJlY3Rpb25zICsgJz46ICcgK1xuICAgICAgJ211c3QgYmUgc3BlY2lmaWVkIGFzIDxzdGFydD46PGVuZD4gJyArXG4gICAgICAnd2l0aCBzdGFydC9lbmQgaW4geyBoLHYsdCxyLGIsbCB9J1xuICAgICk7XG4gIH1cblxuICAvLyBjb21wdXRlIGV4cGxpY2l0IGRpcmVjdGlvbnMsIGludm9sdmluZyB0cmJsIGRvY2tpbmdzXG4gIC8vIHVzaW5nIGEgdGhyZWUgc2VnbWVudGVkIGxheW91dGluZyBhbGdvcml0aG1cbiAgaWYgKGlzRXhwbGljaXREaXJlY3Rpb25zKGRpcmVjdGlvbnMpKSB7XG4gICAgdmFyIHN0YXJ0U2VnbWVudCA9IGdldFN0YXJ0U2VnbWVudChhLCBiLCBkaXJlY3Rpb25zKSxcbiAgICAgICAgZW5kU2VnbWVudCA9IGdldEVuZFNlZ21lbnQoYSwgYiwgZGlyZWN0aW9ucyksXG4gICAgICAgIG1pZFNlZ21lbnQgPSBnZXRNaWRTZWdtZW50KHN0YXJ0U2VnbWVudCwgZW5kU2VnbWVudCk7XG5cbiAgICByZXR1cm4gW10uY29uY2F0KFxuICAgICAgc3RhcnRTZWdtZW50LndheXBvaW50cyxcbiAgICAgIG1pZFNlZ21lbnQud2F5cG9pbnRzLFxuICAgICAgZW5kU2VnbWVudC53YXlwb2ludHNcbiAgICApO1xuICB9XG5cbiAgLy8gaGFuZGxlIHNpbXBsZSBbaHZdOltodl0gY2FzZXMgdGhhdCBjYW4gYmUgZWFzaWx5IGNvbXB1dGVkXG4gIHJldHVybiBnZXRTaW1wbGVCZW5kcG9pbnRzKGEsIGIsIGRpcmVjdGlvbnMpO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGNvbm5lY3Rpb24gYmV0d2VlbiB0aGUgdHdvIHBvaW50cyBhY2NvcmRpbmdcbiAqIHRvIHRoZSBtYW5oYXR0YW4gbGF5b3V0IChvbmx5IGhvcml6b250YWwgYW5kIHZlcnRpY2FsKSBlZGdlcy5cbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBhXG4gKiBAcGFyYW0ge1BvaW50fSBiXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtkaXJlY3Rpb25zPSdoOmgnXSBzcGVjaWZpZXMgbWFuaGF0dGFuIGRpcmVjdGlvbnMgZm9yIGVhY2ggcG9pbnQgYXMge2FkaXJlY3Rpb259OntiZGlyZWN0aW9ufS5cbiAgICAgICAgICAgICAgICAgICBBIGRpcmVjdGlvbmZvciBhIHBvaW50IGlzIGVpdGhlciBgaGAgKGhvcml6b250YWwpIG9yIGB2YCAodmVydGljYWwpXG4gKlxuICogQHJldHVybiB7QXJyYXk8UG9pbnQ+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29ubmVjdFBvaW50cyhhLCBiLCBkaXJlY3Rpb25zKSB7XG5cbiAgdmFyIHBvaW50cyA9IGdldEJlbmRwb2ludHMoYSwgYiwgZGlyZWN0aW9ucyk7XG5cbiAgcG9pbnRzLnVuc2hpZnQoYSk7XG4gIHBvaW50cy5wdXNoKGIpO1xuXG4gIHJldHVybiB3aXRob3V0UmVkdW5kYW50UG9pbnRzKHBvaW50cyk7XG59XG5cblxuLyoqXG4gKiBDb25uZWN0IHR3byByZWN0YW5nbGVzIHVzaW5nIGEgbWFuaGF0dGFuIGxheW91dGVkIGNvbm5lY3Rpb24uXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IHNvdXJjZSBzb3VyY2UgcmVjdGFuZ2xlXG4gKiBAcGFyYW0ge0JvdW5kc30gdGFyZ2V0IHRhcmdldCByZWN0YW5nbGVcbiAqIEBwYXJhbSB7UG9pbnR9IFtzdGFydF0gc291cmNlIGRvY2tpbmdcbiAqIEBwYXJhbSB7UG9pbnR9IFtlbmRdIHRhcmdldCBkb2NraW5nXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7c3RyaW5nfSBbaGludHMucHJlc2VydmVEb2NraW5nPXNvdXJjZV0gcHJlc2VydmUgZG9ja2luZyBvbiBzZWxlY3RlZCBzaWRlXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtoaW50cy5wcmVmZXJyZWRMYXlvdXRzXVxuICogQHBhcmFtIHtQb2ludHxib29sZWFufSBbaGludHMuY29ubmVjdGlvblN0YXJ0XSB3aGV0aGVyIHRoZSBzdGFydCBjaGFuZ2VkXG4gKiBAcGFyYW0ge1BvaW50fGJvb2xlYW59IFtoaW50cy5jb25uZWN0aW9uRW5kXSB3aGV0aGVyIHRoZSBlbmQgY2hhbmdlZFxuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gY29ubmVjdGlvbiBwb2ludHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbm5lY3RSZWN0YW5nbGVzKHNvdXJjZSwgdGFyZ2V0LCBzdGFydCwgZW5kLCBoaW50cykge1xuXG4gIHZhciBwcmVmZXJyZWRMYXlvdXRzID0gaGludHMgJiYgaGludHMucHJlZmVycmVkTGF5b3V0cyB8fCBbXTtcblxuICB2YXIgcHJlZmVycmVkTGF5b3V0ID0gd2l0aG91dChwcmVmZXJyZWRMYXlvdXRzLCAnc3RyYWlnaHQnKVswXSB8fCAnaDpoJztcblxuICB2YXIgdGhyZXNob2xkID0gT1JJRU5UQVRJT05fVEhSRVNIT0xEW3ByZWZlcnJlZExheW91dF0gfHwgMDtcblxuICB2YXIgb3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihzb3VyY2UsIHRhcmdldCwgdGhyZXNob2xkKTtcblxuICB2YXIgZGlyZWN0aW9ucyA9IGdldERpcmVjdGlvbnMob3JpZW50YXRpb24sIHByZWZlcnJlZExheW91dCk7XG5cbiAgc3RhcnQgPSBzdGFydCB8fCBnZXRNaWQoc291cmNlKTtcbiAgZW5kID0gZW5kIHx8IGdldE1pZCh0YXJnZXQpO1xuXG4gIHZhciBkaXJlY3Rpb25TcGxpdCA9IGRpcmVjdGlvbnMuc3BsaXQoJzonKTtcblxuICAvLyBjb21wdXRlIGFjdHVhbCBkb2NraW5nIHBvaW50cyBmb3Igc3RhcnQgLyBlbmRcbiAgLy8gdGhpcyBlbnN1cmVzIHdlIHByb3Blcmx5IGxheW91dCBvbmx5IHBhcnRzIG9mIHRoZVxuICAvLyBjb25uZWN0aW9uIHRoYXQgbGllcyBpbiBiZXR3ZWVuIHRoZSB0d28gcmVjdGFuZ2xlc1xuICB2YXIgc3RhcnREb2NraW5nID0gZ2V0RG9ja2luZ1BvaW50KHN0YXJ0LCBzb3VyY2UsIGRpcmVjdGlvblNwbGl0WzBdLCBpbnZlcnRPcmllbnRhdGlvbihvcmllbnRhdGlvbikpLFxuICAgICAgZW5kRG9ja2luZyA9IGdldERvY2tpbmdQb2ludChlbmQsIHRhcmdldCwgZGlyZWN0aW9uU3BsaXRbMV0sIG9yaWVudGF0aW9uKTtcblxuICByZXR1cm4gY29ubmVjdFBvaW50cyhzdGFydERvY2tpbmcsIGVuZERvY2tpbmcsIGRpcmVjdGlvbnMpO1xufVxuXG5cbi8qKlxuICogUmVwYWlyIHRoZSBjb25uZWN0aW9uIGJldHdlZW4gdHdvIHJlY3RhbmdsZXMsIG9mIHdoaWNoIG9uZSBoYXMgYmVlbiB1cGRhdGVkLlxuICpcbiAqIEBwYXJhbSB7Qm91bmRzfSBzb3VyY2VcbiAqIEBwYXJhbSB7Qm91bmRzfSB0YXJnZXRcbiAqIEBwYXJhbSB7UG9pbnR9IFtzdGFydF1cbiAqIEBwYXJhbSB7UG9pbnR9IFtlbmRdXG4gKiBAcGFyYW0ge0FycmF5PFBvaW50Pn0gW3dheXBvaW50c11cbiAqIEBwYXJhbSB7T2JqZWN0fSBbaGludHNdXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtoaW50cy5wcmVmZXJyZWRMYXlvdXRzXSBsaXN0IG9mIHByZWZlcnJlZCBsYXlvdXRzXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtoaW50cy5jb25uZWN0aW9uU3RhcnRdXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtoaW50cy5jb25uZWN0aW9uRW5kXVxuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gcmVwYWlyZWQgd2F5cG9pbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBhaXJDb25uZWN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBzdGFydCwgZW5kLCB3YXlwb2ludHMsIGhpbnRzKSB7XG5cbiAgaWYgKGlzQXJyYXkoc3RhcnQpKSB7XG4gICAgd2F5cG9pbnRzID0gc3RhcnQ7XG4gICAgaGludHMgPSBlbmQ7XG5cbiAgICBzdGFydCA9IGdldE1pZChzb3VyY2UpO1xuICAgIGVuZCA9IGdldE1pZCh0YXJnZXQpO1xuICB9XG5cbiAgaGludHMgPSBhc3NpZ24oeyBwcmVmZXJyZWRMYXlvdXRzOiBbXSB9LCBoaW50cyk7XG4gIHdheXBvaW50cyA9IHdheXBvaW50cyB8fCBbXTtcblxuICB2YXIgcHJlZmVycmVkTGF5b3V0cyA9IGhpbnRzLnByZWZlcnJlZExheW91dHMsXG4gICAgICBwcmVmZXJTdHJhaWdodCA9IHByZWZlcnJlZExheW91dHMuaW5kZXhPZignc3RyYWlnaHQnKSAhPT0gLTEsXG4gICAgICByZXBhaXJlZFdheXBvaW50cztcblxuICAvLyBqdXN0IGxheW91dCBub24tZXhpc3Rpbmcgb3Igc2ltcGxlIGNvbm5lY3Rpb25zXG4gIC8vIGF0dGVtcHQgdG8gcmVuZGVyIHN0cmFpZ2h0IGxpbmVzLCBpZiByZXF1aXJlZFxuXG4gIC8vIGF0dGVtcHQgdG8gbGF5b3V0IGEgc3RyYWlnaHQgbGluZVxuICByZXBhaXJlZFdheXBvaW50cyA9IHByZWZlclN0cmFpZ2h0ICYmIHRyeUxheW91dFN0cmFpZ2h0KHNvdXJjZSwgdGFyZ2V0LCBzdGFydCwgZW5kLCBoaW50cyk7XG5cbiAgaWYgKHJlcGFpcmVkV2F5cG9pbnRzKSB7XG4gICAgcmV0dXJuIHJlcGFpcmVkV2F5cG9pbnRzO1xuICB9XG5cbiAgLy8gdHJ5IHRvIGxheW91dCBmcm9tIGVuZFxuICByZXBhaXJlZFdheXBvaW50cyA9IGhpbnRzLmNvbm5lY3Rpb25FbmQgJiYgdHJ5UmVwYWlyQ29ubmVjdGlvbkVuZCh0YXJnZXQsIHNvdXJjZSwgZW5kLCB3YXlwb2ludHMpO1xuXG4gIGlmIChyZXBhaXJlZFdheXBvaW50cykge1xuICAgIHJldHVybiByZXBhaXJlZFdheXBvaW50cztcbiAgfVxuXG4gIC8vIHRyeSB0byBsYXlvdXQgZnJvbSBzdGFydFxuICByZXBhaXJlZFdheXBvaW50cyA9IGhpbnRzLmNvbm5lY3Rpb25TdGFydCAmJiB0cnlSZXBhaXJDb25uZWN0aW9uU3RhcnQoc291cmNlLCB0YXJnZXQsIHN0YXJ0LCB3YXlwb2ludHMpO1xuXG4gIGlmIChyZXBhaXJlZFdheXBvaW50cykge1xuICAgIHJldHVybiByZXBhaXJlZFdheXBvaW50cztcbiAgfVxuXG4gIC8vIG9yIHdoZXRoZXIgbm90aGluZyBzZWVtcyB0byBoYXZlIGNoYW5nZWRcbiAgaWYgKCFoaW50cy5jb25uZWN0aW9uU3RhcnQgJiYgIWhpbnRzLmNvbm5lY3Rpb25FbmQgJiYgd2F5cG9pbnRzICYmIHdheXBvaW50cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gd2F5cG9pbnRzO1xuICB9XG5cbiAgLy8gc2ltcGx5IHJlY29ubmVjdCBpZiBub3RoaW5nIGVsc2Ugd29ya2VkXG4gIHJldHVybiBjb25uZWN0UmVjdGFuZ2xlcyhzb3VyY2UsIHRhcmdldCwgc3RhcnQsIGVuZCwgaGludHMpO1xufVxuXG5cbmZ1bmN0aW9uIGluUmFuZ2UoYSwgc3RhcnQsIGVuZCkge1xuICByZXR1cm4gYSA+PSBzdGFydCAmJiBhIDw9IGVuZDtcbn1cblxuZnVuY3Rpb24gaXNJblJhbmdlKGF4aXMsIGEsIGIpIHtcbiAgdmFyIHNpemUgPSB7XG4gICAgeDogJ3dpZHRoJyxcbiAgICB5OiAnaGVpZ2h0J1xuICB9O1xuXG4gIHJldHVybiBpblJhbmdlKGFbYXhpc10sIGJbYXhpc10sIGJbYXhpc10gKyBiW3NpemVbYXhpc11dKTtcbn1cblxuLyoqXG4gKiBMYXlvdXQgYSBzdHJhaWdodCBjb25uZWN0aW9uXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IHNvdXJjZVxuICogQHBhcmFtIHtCb3VuZHN9IHRhcmdldFxuICogQHBhcmFtIHtQb2ludH0gc3RhcnRcbiAqIEBwYXJhbSB7UG9pbnR9IGVuZFxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxQb2ludD58bnVsbH0gd2F5cG9pbnRzIGlmIHN0cmFpZ2h0IGxheW91dCB3b3JrZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyeUxheW91dFN0cmFpZ2h0KHNvdXJjZSwgdGFyZ2V0LCBzdGFydCwgZW5kLCBoaW50cykge1xuICB2YXIgYXhpcyA9IHt9LFxuICAgICAgcHJpbWFyeUF4aXMsXG4gICAgICBvcmllbnRhdGlvbjtcblxuICBvcmllbnRhdGlvbiA9IGdldE9yaWVudGF0aW9uKHNvdXJjZSwgdGFyZ2V0KTtcblxuICAvLyBvbmx5IGxheW91dCBhIHN0cmFpZ2h0IGNvbm5lY3Rpb24gaWYgc2hhcGVzIGFyZVxuICAvLyBob3Jpem9udGFsbHkgb3IgdmVydGljYWxseSBhbGlnbmVkXG4gIGlmICghL14odG9wfGJvdHRvbXxsZWZ0fHJpZ2h0KSQvLnRlc3Qob3JpZW50YXRpb24pKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoL3RvcHxib3R0b20vLnRlc3Qob3JpZW50YXRpb24pKSB7XG4gICAgcHJpbWFyeUF4aXMgPSAneCc7XG4gIH1cblxuICBpZiAoL2xlZnR8cmlnaHQvLnRlc3Qob3JpZW50YXRpb24pKSB7XG4gICAgcHJpbWFyeUF4aXMgPSAneSc7XG4gIH1cblxuICBpZiAoaGludHMucHJlc2VydmVEb2NraW5nID09PSAndGFyZ2V0Jykge1xuXG4gICAgaWYgKCFpc0luUmFuZ2UocHJpbWFyeUF4aXMsIGVuZCwgc291cmNlKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgYXhpc1twcmltYXJ5QXhpc10gPSBlbmRbcHJpbWFyeUF4aXNdO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgeDogYXhpcy54ICE9PSB1bmRlZmluZWQgPyBheGlzLnggOiBzdGFydC54LFxuICAgICAgICB5OiBheGlzLnkgIT09IHVuZGVmaW5lZCA/IGF4aXMueSA6IHN0YXJ0LnksXG4gICAgICAgIG9yaWdpbmFsOiB7XG4gICAgICAgICAgeDogYXhpcy54ICE9PSB1bmRlZmluZWQgPyBheGlzLnggOiBzdGFydC54LFxuICAgICAgICAgIHk6IGF4aXMueSAhPT0gdW5kZWZpbmVkID8gYXhpcy55IDogc3RhcnQueVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB4OiBlbmQueCxcbiAgICAgICAgeTogZW5kLnlcbiAgICAgIH1cbiAgICBdO1xuXG4gIH0gZWxzZSB7XG5cbiAgICBpZiAoIWlzSW5SYW5nZShwcmltYXJ5QXhpcywgc3RhcnQsIHRhcmdldCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGF4aXNbcHJpbWFyeUF4aXNdID0gc3RhcnRbcHJpbWFyeUF4aXNdO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgeDogc3RhcnQueCxcbiAgICAgICAgeTogc3RhcnQueVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgeDogYXhpcy54ICE9PSB1bmRlZmluZWQgPyBheGlzLnggOiBlbmQueCxcbiAgICAgICAgeTogYXhpcy55ICE9PSB1bmRlZmluZWQgPyBheGlzLnkgOiBlbmQueSxcbiAgICAgICAgb3JpZ2luYWw6IHtcbiAgICAgICAgICB4OiBheGlzLnggIT09IHVuZGVmaW5lZCA/IGF4aXMueCA6IGVuZC54LFxuICAgICAgICAgIHk6IGF4aXMueSAhPT0gdW5kZWZpbmVkID8gYXhpcy55IDogZW5kLnlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIF07XG4gIH1cblxufVxuXG4vKipcbiAqIFJlcGFpciBhIGNvbm5lY3Rpb24gZnJvbSBzdGFydC5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc30gbW92ZWRcbiAqIEBwYXJhbSB7Qm91bmRzfSBvdGhlclxuICogQHBhcmFtIHtQb2ludH0gbmV3RG9ja2luZ1xuICogQHBhcmFtIHtBcnJheTxQb2ludD59IHBvaW50cyBvcmlnaW5hbFBvaW50cyBmcm9tIG1vdmVkIHRvIG90aGVyXG4gKlxuICogQHJldHVybiB7QXJyYXk8UG9pbnQ+fG51bGx9IHRoZSByZXBhaXJlZCBwb2ludHMgYmV0d2VlbiB0aGUgdHdvIHJlY3RhbmdsZXNcbiAqL1xuZnVuY3Rpb24gdHJ5UmVwYWlyQ29ubmVjdGlvblN0YXJ0KG1vdmVkLCBvdGhlciwgbmV3RG9ja2luZywgcG9pbnRzKSB7XG4gIHJldHVybiBfdHJ5UmVwYWlyQ29ubmVjdGlvblNpZGUobW92ZWQsIG90aGVyLCBuZXdEb2NraW5nLCBwb2ludHMpO1xufVxuXG4vKipcbiAqIFJlcGFpciBhIGNvbm5lY3Rpb24gZnJvbSBlbmQuXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IG1vdmVkXG4gKiBAcGFyYW0ge0JvdW5kc30gb3RoZXJcbiAqIEBwYXJhbSB7UG9pbnR9IG5ld0RvY2tpbmdcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSBwb2ludHMgb3JpZ2luYWxQb2ludHMgZnJvbSBtb3ZlZCB0byBvdGhlclxuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50PnxudWxsfSB0aGUgcmVwYWlyZWQgcG9pbnRzIGJldHdlZW4gdGhlIHR3byByZWN0YW5nbGVzXG4gKi9cbmZ1bmN0aW9uIHRyeVJlcGFpckNvbm5lY3Rpb25FbmQobW92ZWQsIG90aGVyLCBuZXdEb2NraW5nLCBwb2ludHMpIHtcbiAgdmFyIHdheXBvaW50cyA9IHBvaW50cy5zbGljZSgpLnJldmVyc2UoKTtcblxuICB3YXlwb2ludHMgPSBfdHJ5UmVwYWlyQ29ubmVjdGlvblNpZGUobW92ZWQsIG90aGVyLCBuZXdEb2NraW5nLCB3YXlwb2ludHMpO1xuXG4gIHJldHVybiB3YXlwb2ludHMgPyB3YXlwb2ludHMucmV2ZXJzZSgpIDogbnVsbDtcbn1cblxuLyoqXG4gKiBSZXBhaXIgYSBjb25uZWN0aW9uIGZyb20gb25lIHNpZGUgdGhhdCBtb3ZlZC5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc30gbW92ZWRcbiAqIEBwYXJhbSB7Qm91bmRzfSBvdGhlclxuICogQHBhcmFtIHtQb2ludH0gbmV3RG9ja2luZ1xuICogQHBhcmFtIHtBcnJheTxQb2ludD59IHBvaW50cyBvcmlnaW5hbFBvaW50cyBmcm9tIG1vdmVkIHRvIG90aGVyXG4gKlxuICogQHJldHVybiB7QXJyYXk8UG9pbnQ+fSB0aGUgcmVwYWlyZWQgcG9pbnRzIGJldHdlZW4gdGhlIHR3byByZWN0YW5nbGVzXG4gKi9cbmZ1bmN0aW9uIF90cnlSZXBhaXJDb25uZWN0aW9uU2lkZShtb3ZlZCwgb3RoZXIsIG5ld0RvY2tpbmcsIHBvaW50cykge1xuXG4gIGZ1bmN0aW9uIG5lZWRzUmVsYXlvdXQocG9pbnRzKSB7XG4gICAgaWYgKHBvaW50cy5sZW5ndGggPCAzKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocG9pbnRzLmxlbmd0aCA+IDQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyByZWxheW91dCBpZiB0d28gcG9pbnRzIG92ZXJsYXBcbiAgICAvLyB0aGlzIGlzIG1vc3QgbGlrZWx5IGR1ZSB0b1xuICAgIHJldHVybiAhIWZpbmQocG9pbnRzLCBmdW5jdGlvbihwLCBpZHgpIHtcbiAgICAgIHZhciBxID0gcG9pbnRzW2lkeCAtIDFdO1xuXG4gICAgICByZXR1cm4gcSAmJiBwb2ludERpc3RhbmNlKHAsIHEpIDwgMztcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcGFpckJlbmRwb2ludChjYW5kaWRhdGUsIG9sZFBlZXIsIG5ld1BlZXIpIHtcblxuICAgIHZhciBhbGlnbm1lbnQgPSBwb2ludHNBbGlnbmVkKG9sZFBlZXIsIGNhbmRpZGF0ZSk7XG5cbiAgICBzd2l0Y2ggKGFsaWdubWVudCkge1xuICAgIGNhc2UgJ3YnOlxuXG4gICAgICAvLyByZXBhaXIgaG9yaXpvbnRhbCBhbGlnbm1lbnRcbiAgICAgIHJldHVybiB7IHg6IG5ld1BlZXIueCwgeTogY2FuZGlkYXRlLnkgfTtcbiAgICBjYXNlICdoJzpcblxuICAgICAgLy8gcmVwYWlyIHZlcnRpY2FsIGFsaWdubWVudFxuICAgICAgcmV0dXJuIHsgeDogY2FuZGlkYXRlLngsIHk6IG5ld1BlZXIueSB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IHg6IGNhbmRpZGF0ZS54LCB5OiBjYW5kaWRhdGUuIHkgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZU92ZXJsYXBwaW5nKHBvaW50cywgYSwgYikge1xuICAgIHZhciBpO1xuXG4gICAgZm9yIChpID0gcG9pbnRzLmxlbmd0aCAtIDI7IGkgIT09IDA7IGktLSkge1xuXG4gICAgICAvLyBpbnRlcnNlY3RzICg/KSBicmVhaywgcmVtb3ZlIGFsbCBiZW5kcG9pbnRzIHVwIHRvIHRoaXMgb25lIGFuZCByZWxheW91dFxuICAgICAgaWYgKHBvaW50SW5SZWN0KHBvaW50c1tpXSwgYSwgSU5URVJTRUNUSU9OX1RIUkVTSE9MRCkgfHxcbiAgICAgICAgICBwb2ludEluUmVjdChwb2ludHNbaV0sIGIsIElOVEVSU0VDVElPTl9USFJFU0hPTEQpKSB7XG5cbiAgICAgICAgLy8gcmV0dXJuIHNsaWNlZCBvbGQgY29ubmVjdGlvblxuICAgICAgICByZXR1cm4gcG9pbnRzLnNsaWNlKGkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwb2ludHM7XG4gIH1cblxuICAvLyAoMCkgb25seSByZXBhaXIgd2hhdCBoYXMgbGF5b3V0YWJsZSBiZW5kcG9pbnRzXG5cbiAgLy8gKDEpIGlmIG9ubHkgb25lIGJlbmRwb2ludCBhbmQgb24gc2hhcGUgbW92ZWQgb250byBvdGhlciBzaGFwZXMgYXhpc1xuICAvLyAgICAgKGhvcml6b250YWxseSAvIHZlcnRpY2FsbHkpLCByZWxheW91dFxuXG4gIGlmIChuZWVkc1JlbGF5b3V0KHBvaW50cykpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBvbGREb2NraW5nID0gcG9pbnRzWzBdLFxuICAgICAgbmV3UG9pbnRzID0gcG9pbnRzLnNsaWNlKCksXG4gICAgICBzbGljZWRQb2ludHM7XG5cbiAgLy8gKDIpIHJlcGFpciBvbmx5IGxhc3QgbGluZSBzZWdtZW50IGFuZCBvbmx5IGlmIGl0IHdhcyBsYXlvdXRlZCBiZWZvcmVcblxuICBuZXdQb2ludHNbMF0gPSBuZXdEb2NraW5nO1xuICBuZXdQb2ludHNbMV0gPSByZXBhaXJCZW5kcG9pbnQobmV3UG9pbnRzWzFdLCBvbGREb2NraW5nLCBuZXdEb2NraW5nKTtcblxuXG4gIC8vICgzKSBpZiBzaGFwZSBpbnRlcnNlY3RzIHdpdGggYW55IGJlbmRwb2ludCBhZnRlciByZXBhaXIsXG4gIC8vICAgICByZW1vdmUgYWxsIHNlZ21lbnRzIHVwIHRvIHRoaXMgYmVuZHBvaW50IGFuZCByZXBhaXIgZnJvbSB0aGVyZVxuICBzbGljZWRQb2ludHMgPSByZW1vdmVPdmVybGFwcGluZyhuZXdQb2ludHMsIG1vdmVkLCBvdGhlcik7XG5cbiAgaWYgKHNsaWNlZFBvaW50cyAhPT0gbmV3UG9pbnRzKSB7XG4gICAgbmV3UG9pbnRzID0gX3RyeVJlcGFpckNvbm5lY3Rpb25TaWRlKG1vdmVkLCBvdGhlciwgbmV3RG9ja2luZywgc2xpY2VkUG9pbnRzKTtcbiAgfVxuXG4gIC8vICg0KSBkbyBOT1QgcmVwYWlyIGlmIHJlcGFpcmVkIGJlbmRwb2ludHMgYXJlIGFsaWduZWRcbiAgaWYgKG5ld1BvaW50cyAmJiBwb2ludHNBbGlnbmVkKG5ld1BvaW50cykpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBuZXdQb2ludHM7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYW5oYXR0YW4gZGlyZWN0aW9ucyBjb25uZWN0aW5nIHR3byByZWN0YW5nbGVzXG4gKiB3aXRoIHRoZSBnaXZlbiBvcmllbnRhdGlvbi5cbiAqXG4gKiBXaWxsIGFsd2F5cyByZXR1cm4gdGhlIGRlZmF1bHQgbGF5b3V0LCBpZiBpdCBpcyBzcGVjaWZpY1xuICogcmVnYXJkaW5nIHNpZGVzIGFscmVhZHkgKHRyYmwpLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogZ2V0RGlyZWN0aW9ucygndG9wJyk7IC8vIC0+ICd2OnYnXG4gKiBnZXREaXJlY3Rpb25zKCdpbnRlcnNlY3QnKTsgLy8gLT4gJ3Q6dCdcbiAqXG4gKiBnZXREaXJlY3Rpb25zKCd0b3AtcmlnaHQnLCAndjpoJyk7IC8vIC0+ICd2OmgnXG4gKiBnZXREaXJlY3Rpb25zKCd0b3AtcmlnaHQnLCAnaDpoJyk7IC8vIC0+ICdoOmgnXG4gKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBvcmllbnRhdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IGRlZmF1bHRMYXlvdXRcbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGdldERpcmVjdGlvbnMob3JpZW50YXRpb24sIGRlZmF1bHRMYXlvdXQpIHtcblxuICAvLyBkb24ndCBvdmVycmlkZSBzcGVjaWZpYyB0cmJsIGRpcmVjdGlvbnNcbiAgaWYgKGlzRXhwbGljaXREaXJlY3Rpb25zKGRlZmF1bHRMYXlvdXQpKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRMYXlvdXQ7XG4gIH1cblxuICBzd2l0Y2ggKG9yaWVudGF0aW9uKSB7XG4gIGNhc2UgJ2ludGVyc2VjdCc6XG4gICAgcmV0dXJuICd0OnQnO1xuXG4gIGNhc2UgJ3RvcCc6XG4gIGNhc2UgJ2JvdHRvbSc6XG4gICAgcmV0dXJuICd2OnYnO1xuXG4gIGNhc2UgJ2xlZnQnOlxuICBjYXNlICdyaWdodCc6XG4gICAgcmV0dXJuICdoOmgnO1xuXG4gIC8vICd0b3AtbGVmdCdcbiAgLy8gJ3RvcC1yaWdodCdcbiAgLy8gJ2JvdHRvbS1sZWZ0J1xuICAvLyAnYm90dG9tLXJpZ2h0J1xuICBkZWZhdWx0OlxuICAgIHJldHVybiBkZWZhdWx0TGF5b3V0O1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzVmFsaWREaXJlY3Rpb25zKGRpcmVjdGlvbnMpIHtcbiAgcmV0dXJuIGRpcmVjdGlvbnMgJiYgL15ofHZ8dHxyfGJ8bDpofHZ8dHxyfGJ8bCQvLnRlc3QoZGlyZWN0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGlzRXhwbGljaXREaXJlY3Rpb25zKGRpcmVjdGlvbnMpIHtcbiAgcmV0dXJuIGRpcmVjdGlvbnMgJiYgL3R8cnxifGwvLnRlc3QoZGlyZWN0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGludmVydE9yaWVudGF0aW9uKG9yaWVudGF0aW9uKSB7XG4gIHJldHVybiB7XG4gICAgJ3RvcCc6ICdib3R0b20nLFxuICAgICdib3R0b20nOiAndG9wJyxcbiAgICAnbGVmdCc6ICdyaWdodCcsXG4gICAgJ3JpZ2h0JzogJ2xlZnQnLFxuICAgICd0b3AtbGVmdCc6ICdib3R0b20tcmlnaHQnLFxuICAgICdib3R0b20tcmlnaHQnOiAndG9wLWxlZnQnLFxuICAgICd0b3AtcmlnaHQnOiAnYm90dG9tLWxlZnQnLFxuICAgICdib3R0b20tbGVmdCc6ICd0b3AtcmlnaHQnLFxuICB9W29yaWVudGF0aW9uXTtcbn1cblxuZnVuY3Rpb24gZ2V0RG9ja2luZ1BvaW50KHBvaW50LCByZWN0YW5nbGUsIGRvY2tpbmdEaXJlY3Rpb24sIHRhcmdldE9yaWVudGF0aW9uKSB7XG5cbiAgLy8gZW5zdXJlIHdlIGVuZCB1cCB3aXRoIGEgc3BlY2lmaWMgZG9ja2luZyBkaXJlY3Rpb25cbiAgLy8gYmFzZWQgb24gdGhlIHRhcmdldE9yaWVudGF0aW9uLCBpZiA8aHx2PiBpcyBiZWluZyBwYXNzZWRcblxuICBpZiAoZG9ja2luZ0RpcmVjdGlvbiA9PT0gJ2gnKSB7XG4gICAgZG9ja2luZ0RpcmVjdGlvbiA9IC9sZWZ0Ly50ZXN0KHRhcmdldE9yaWVudGF0aW9uKSA/ICdsJyA6ICdyJztcbiAgfVxuXG4gIGlmIChkb2NraW5nRGlyZWN0aW9uID09PSAndicpIHtcbiAgICBkb2NraW5nRGlyZWN0aW9uID0gL3RvcC8udGVzdCh0YXJnZXRPcmllbnRhdGlvbikgPyAndCcgOiAnYic7XG4gIH1cblxuICBpZiAoZG9ja2luZ0RpcmVjdGlvbiA9PT0gJ3QnKSB7XG4gICAgcmV0dXJuIHsgb3JpZ2luYWw6IHBvaW50LCB4OiBwb2ludC54LCB5OiByZWN0YW5nbGUueSB9O1xuICB9XG5cbiAgaWYgKGRvY2tpbmdEaXJlY3Rpb24gPT09ICdyJykge1xuICAgIHJldHVybiB7IG9yaWdpbmFsOiBwb2ludCwgeDogcmVjdGFuZ2xlLnggKyByZWN0YW5nbGUud2lkdGgsIHk6IHBvaW50LnkgfTtcbiAgfVxuXG4gIGlmIChkb2NraW5nRGlyZWN0aW9uID09PSAnYicpIHtcbiAgICByZXR1cm4geyBvcmlnaW5hbDogcG9pbnQsIHg6IHBvaW50LngsIHk6IHJlY3RhbmdsZS55ICsgcmVjdGFuZ2xlLmhlaWdodCB9O1xuICB9XG5cbiAgaWYgKGRvY2tpbmdEaXJlY3Rpb24gPT09ICdsJykge1xuICAgIHJldHVybiB7IG9yaWdpbmFsOiBwb2ludCwgeDogcmVjdGFuZ2xlLngsIHk6IHBvaW50LnkgfTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcigndW5leHBlY3RlZCBkb2NraW5nRGlyZWN0aW9uOiA8JyArIGRvY2tpbmdEaXJlY3Rpb24gKyAnPicpO1xufVxuXG5cbi8qKlxuICogUmV0dXJuIGxpc3Qgb2Ygd2F5cG9pbnRzIHdpdGggcmVkdW5kYW50IG9uZXMgZmlsdGVyZWQgb3V0LlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogT3JpZ2luYWwgcG9pbnRzOlxuICpcbiAqICAgW3hdIC0tLS0tIFt4XSAtLS0tLS0gW3hdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgIFt4XSAtLS0tLSBbeF0gLSBbeF1cbiAqXG4gKiBGaWx0ZXJlZDpcbiAqXG4gKiAgIFt4XSAtLS0tLS0tLS0tLS0tLS0tIFt4XVxuICogICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICBbeF0gLS0tLS0tLS0tLS0gW3hdXG4gKlxuICogQHBhcmFtICB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxQb2ludD59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRob3V0UmVkdW5kYW50UG9pbnRzKHdheXBvaW50cykge1xuICByZXR1cm4gd2F5cG9pbnRzLnJlZHVjZShmdW5jdGlvbihwb2ludHMsIHAsIGlkeCkge1xuXG4gICAgdmFyIHByZXZpb3VzID0gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgICAgbmV4dCA9IHdheXBvaW50c1tpZHggKyAxXTtcblxuICAgIGlmICghcG9pbnRzT25MaW5lKHByZXZpb3VzLCBuZXh0LCBwLCAwKSkge1xuICAgICAgcG9pbnRzLnB1c2gocCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvaW50cztcbiAgfSwgW10pO1xufVxuIiwiaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnbWluLWRhc2gnO1xuaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IFJlZnMgZnJvbSAnb2JqZWN0LXJlZnMnO1xuXG52YXIgcGFyZW50UmVmcyA9IG5ldyBSZWZzKHsgbmFtZTogJ2NoaWxkcmVuJywgZW51bWVyYWJsZTogdHJ1ZSwgY29sbGVjdGlvbjogdHJ1ZSB9LCB7IG5hbWU6ICdwYXJlbnQnIH0pLFxuICAgIGxhYmVsUmVmcyA9IG5ldyBSZWZzKHsgbmFtZTogJ2xhYmVscycsIGVudW1lcmFibGU6IHRydWUsIGNvbGxlY3Rpb246IHRydWUgfSwgeyBuYW1lOiAnbGFiZWxUYXJnZXQnIH0pLFxuICAgIGF0dGFjaGVyUmVmcyA9IG5ldyBSZWZzKHsgbmFtZTogJ2F0dGFjaGVycycsIGNvbGxlY3Rpb246IHRydWUgfSwgeyBuYW1lOiAnaG9zdCcgfSksXG4gICAgb3V0Z29pbmdSZWZzID0gbmV3IFJlZnMoeyBuYW1lOiAnb3V0Z29pbmcnLCBjb2xsZWN0aW9uOiB0cnVlIH0sIHsgbmFtZTogJ3NvdXJjZScgfSksXG4gICAgaW5jb21pbmdSZWZzID0gbmV3IFJlZnMoeyBuYW1lOiAnaW5jb21pbmcnLCBjb2xsZWN0aW9uOiB0cnVlIH0sIHsgbmFtZTogJ3RhcmdldCcgfSk7XG5cbi8qKlxuICogQG5hbWVzcGFjZSBkanMubW9kZWxcbiAqL1xuXG4vKipcbiAqIEBtZW1iZXJPZiBkanMubW9kZWxcbiAqL1xuXG4vKipcbiAqIFRoZSBiYXNpYyBncmFwaGljYWwgcmVwcmVzZW50YXRpb25cbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAYWJzdHJhY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEJhc2UoKSB7XG5cbiAgLyoqXG4gICAqIFRoZSBvYmplY3QgdGhhdCBiYWNrcyB1cCB0aGUgc2hhcGVcbiAgICpcbiAgICogQG5hbWUgQmFzZSNidXNpbmVzc09iamVjdFxuICAgKiBAdHlwZSBPYmplY3RcbiAgICovXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnYnVzaW5lc3NPYmplY3QnLCB7XG4gICAgd3JpdGFibGU6IHRydWVcbiAgfSk7XG5cblxuICAvKipcbiAgICogU2luZ2xlIGxhYmVsIHN1cHBvcnQsIHdpbGwgbWFwcGVkIHRvIG11bHRpIGxhYmVsIGFycmF5XG4gICAqXG4gICAqIEBuYW1lIEJhc2UjbGFiZWxcbiAgICogQHR5cGUgT2JqZWN0XG4gICAqL1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2xhYmVsJywge1xuICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5sYWJlbHNbMF07XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKG5ld0xhYmVsKSB7XG5cbiAgICAgIHZhciBsYWJlbCA9IHRoaXMubGFiZWwsXG4gICAgICAgICAgbGFiZWxzID0gdGhpcy5sYWJlbHM7XG5cbiAgICAgIGlmICghbmV3TGFiZWwgJiYgbGFiZWwpIHtcbiAgICAgICAgbGFiZWxzLnJlbW92ZShsYWJlbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsYWJlbHMuYWRkKG5ld0xhYmVsLCAwKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBUaGUgcGFyZW50IHNoYXBlXG4gICAqXG4gICAqIEBuYW1lIEJhc2UjcGFyZW50XG4gICAqIEB0eXBlIFNoYXBlXG4gICAqL1xuICBwYXJlbnRSZWZzLmJpbmQodGhpcywgJ3BhcmVudCcpO1xuXG4gIC8qKlxuICAgKiBUaGUgbGlzdCBvZiBsYWJlbHNcbiAgICpcbiAgICogQG5hbWUgQmFzZSNsYWJlbHNcbiAgICogQHR5cGUgTGFiZWxcbiAgICovXG4gIGxhYmVsUmVmcy5iaW5kKHRoaXMsICdsYWJlbHMnKTtcblxuICAvKipcbiAgICogVGhlIGxpc3Qgb2Ygb3V0Z29pbmcgY29ubmVjdGlvbnNcbiAgICpcbiAgICogQG5hbWUgQmFzZSNvdXRnb2luZ1xuICAgKiBAdHlwZSBBcnJheTxDb25uZWN0aW9uPlxuICAgKi9cbiAgb3V0Z29pbmdSZWZzLmJpbmQodGhpcywgJ291dGdvaW5nJyk7XG5cbiAgLyoqXG4gICAqIFRoZSBsaXN0IG9mIGluY29taW5nIGNvbm5lY3Rpb25zXG4gICAqXG4gICAqIEBuYW1lIEJhc2UjaW5jb21pbmdcbiAgICogQHR5cGUgQXJyYXk8Q29ubmVjdGlvbj5cbiAgICovXG4gIGluY29taW5nUmVmcy5iaW5kKHRoaXMsICdpbmNvbWluZycpO1xufVxuXG5cbi8qKlxuICogQSBncmFwaGljYWwgb2JqZWN0XG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBTaGFwZSgpIHtcbiAgQmFzZS5jYWxsKHRoaXMpO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgZnJhbWUgc2hhcGVzXG4gICAqXG4gICAqIEBuYW1lIFNoYXBlI2lzRnJhbWVcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cblxuICAvKipcbiAgICogVGhlIGxpc3Qgb2YgY2hpbGRyZW5cbiAgICpcbiAgICogQG5hbWUgU2hhcGUjY2hpbGRyZW5cbiAgICogQHR5cGUgQXJyYXk8QmFzZT5cbiAgICovXG4gIHBhcmVudFJlZnMuYmluZCh0aGlzLCAnY2hpbGRyZW4nKTtcblxuICAvKipcbiAgICogQG5hbWUgU2hhcGUjaG9zdFxuICAgKiBAdHlwZSBTaGFwZVxuICAgKi9cbiAgYXR0YWNoZXJSZWZzLmJpbmQodGhpcywgJ2hvc3QnKTtcblxuICAvKipcbiAgICogQG5hbWUgU2hhcGUjYXR0YWNoZXJzXG4gICAqIEB0eXBlIFNoYXBlXG4gICAqL1xuICBhdHRhY2hlclJlZnMuYmluZCh0aGlzLCAnYXR0YWNoZXJzJyk7XG59XG5cbmluaGVyaXRzKFNoYXBlLCBCYXNlKTtcblxuXG4vKipcbiAqIEEgcm9vdCBncmFwaGljYWwgb2JqZWN0XG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAZXh0ZW5kcyBTaGFwZVxuICovXG5leHBvcnQgZnVuY3Rpb24gUm9vdCgpIHtcbiAgU2hhcGUuY2FsbCh0aGlzKTtcbn1cblxuaW5oZXJpdHMoUm9vdCwgU2hhcGUpO1xuXG5cbi8qKlxuICogQSBsYWJlbCBmb3IgYW4gZWxlbWVudFxuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQGV4dGVuZHMgU2hhcGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExhYmVsKCkge1xuICBTaGFwZS5jYWxsKHRoaXMpO1xuXG4gIC8qKlxuICAgKiBUaGUgbGFiZWxlZCBlbGVtZW50XG4gICAqXG4gICAqIEBuYW1lIExhYmVsI2xhYmVsVGFyZ2V0XG4gICAqIEB0eXBlIEJhc2VcbiAgICovXG4gIGxhYmVsUmVmcy5iaW5kKHRoaXMsICdsYWJlbFRhcmdldCcpO1xufVxuXG5pbmhlcml0cyhMYWJlbCwgU2hhcGUpO1xuXG5cbi8qKlxuICogQSBjb25uZWN0aW9uIGJldHdlZW4gdHdvIGVsZW1lbnRzXG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDb25uZWN0aW9uKCkge1xuICBCYXNlLmNhbGwodGhpcyk7XG5cbiAgLyoqXG4gICAqIFRoZSBlbGVtZW50IHRoaXMgY29ubmVjdGlvbiBvcmlnaW5hdGVzIGZyb21cbiAgICpcbiAgICogQG5hbWUgQ29ubmVjdGlvbiNzb3VyY2VcbiAgICogQHR5cGUgQmFzZVxuICAgKi9cbiAgb3V0Z29pbmdSZWZzLmJpbmQodGhpcywgJ3NvdXJjZScpO1xuXG4gIC8qKlxuICAgKiBUaGUgZWxlbWVudCB0aGlzIGNvbm5lY3Rpb24gcG9pbnRzIHRvXG4gICAqXG4gICAqIEBuYW1lIENvbm5lY3Rpb24jdGFyZ2V0XG4gICAqIEB0eXBlIEJhc2VcbiAgICovXG4gIGluY29taW5nUmVmcy5iaW5kKHRoaXMsICd0YXJnZXQnKTtcbn1cblxuaW5oZXJpdHMoQ29ubmVjdGlvbiwgQmFzZSk7XG5cblxudmFyIHR5cGVzID0ge1xuICBjb25uZWN0aW9uOiBDb25uZWN0aW9uLFxuICBzaGFwZTogU2hhcGUsXG4gIGxhYmVsOiBMYWJlbCxcbiAgcm9vdDogUm9vdFxufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IG1vZGVsIGVsZW1lbnQgb2YgdGhlIHNwZWNpZmllZCB0eXBlXG4gKlxuICogQG1ldGhvZCBjcmVhdGVcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBzaGFwZTEgPSBNb2RlbC5jcmVhdGUoJ3NoYXBlJywgeyB4OiAxMCwgeTogMTAsIHdpZHRoOiAxMDAsIGhlaWdodDogMTAwIH0pO1xuICogdmFyIHNoYXBlMiA9IE1vZGVsLmNyZWF0ZSgnc2hhcGUnLCB7IHg6IDIxMCwgeTogMjEwLCB3aWR0aDogMTAwLCBoZWlnaHQ6IDEwMCB9KTtcbiAqXG4gKiB2YXIgY29ubmVjdGlvbiA9IE1vZGVsLmNyZWF0ZSgnY29ubmVjdGlvbicsIHsgd2F5cG9pbnRzOiBbIHsgeDogMTEwLCB5OiA1NSB9LCB7eDogMjEwLCB5OiA1NSB9IF0gfSk7XG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSB0eXBlIGxvd2VyLWNhc2VkIG1vZGVsIG5hbWVcbiAqIEBwYXJhbSAge09iamVjdH0gYXR0cnMgYXR0cmlidXRlcyB0byBpbml0aWFsaXplIHRoZSBuZXcgbW9kZWwgaW5zdGFuY2Ugd2l0aFxuICpcbiAqIEByZXR1cm4ge0Jhc2V9IHRoZSBuZXcgbW9kZWwgaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZSh0eXBlLCBhdHRycykge1xuICB2YXIgVHlwZSA9IHR5cGVzW3R5cGVdO1xuICBpZiAoIVR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gdHlwZTogPCcgKyB0eXBlICsgJz4nKTtcbiAgfVxuICByZXR1cm4gYXNzaWduKG5ldyBUeXBlKCksIGF0dHJzKTtcbn0iLCJpbXBvcnQgeyBhc3NpZ24gfSBmcm9tICdtaW4tZGFzaCc7XG5cblxudmFyIERFRkFVTFRfQ09ORklHID0ge1xuICBtb3ZlU3BlZWQ6IDUwLFxuICBtb3ZlU3BlZWRBY2NlbGVyYXRlZDogMjAwXG59O1xuXG5cbi8qKlxuICogQSBmZWF0dXJlIHRoYXQgYWxsb3dzIHVzZXJzIHRvIG1vdmUgdGhlIGNhbnZhcyB1c2luZyB0aGUga2V5Ym9hcmQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZ1xuICogQHBhcmFtIHtudW1iZXJ9IFtjb25maWcubW92ZVNwZWVkPTUwXVxuICogQHBhcmFtIHtudW1iZXJ9IFtjb25maWcubW92ZVNwZWVkQWNjZWxlcmF0ZWQ9MjAwXVxuICogQHBhcmFtIHtLZXlib2FyZH0ga2V5Ym9hcmRcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gS2V5Ym9hcmRNb3ZlKFxuICAgIGNvbmZpZyxcbiAgICBrZXlib2FyZCxcbiAgICBjYW52YXNcbikge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9jb25maWcgPSBhc3NpZ24oe30sIERFRkFVTFRfQ09ORklHLCBjb25maWcgfHwge30pO1xuXG4gIGtleWJvYXJkLmFkZExpc3RlbmVyKGFycm93c0xpc3RlbmVyKTtcblxuXG4gIGZ1bmN0aW9uIGFycm93c0xpc3RlbmVyKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQsXG4gICAgICAgIGNvbmZpZyA9IHNlbGYuX2NvbmZpZztcblxuICAgIGlmICgha2V5Ym9hcmQuaXNDbWQoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGtleWJvYXJkLmlzS2V5KFtcbiAgICAgICdBcnJvd0xlZnQnLCAnTGVmdCcsXG4gICAgICAnQXJyb3dVcCcsICdVcCcsXG4gICAgICAnQXJyb3dEb3duJywgJ0Rvd24nLFxuICAgICAgJ0Fycm93UmlnaHQnLCAnUmlnaHQnXG4gICAgXSwgZXZlbnQpKSB7XG5cbiAgICAgIHZhciBzcGVlZCA9IChcbiAgICAgICAga2V5Ym9hcmQuaXNTaGlmdChldmVudCkgP1xuICAgICAgICAgIGNvbmZpZy5tb3ZlU3BlZWRBY2NlbGVyYXRlZCA6XG4gICAgICAgICAgY29uZmlnLm1vdmVTcGVlZFxuICAgICAgKTtcblxuICAgICAgdmFyIGRpcmVjdGlvbjtcblxuICAgICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0Fycm93TGVmdCc6XG4gICAgICBjYXNlICdMZWZ0JzpcbiAgICAgICAgZGlyZWN0aW9uID0gJ2xlZnQnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgY2FzZSAnVXAnOlxuICAgICAgICBkaXJlY3Rpb24gPSAndXAnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93UmlnaHQnOlxuICAgICAgY2FzZSAnUmlnaHQnOlxuICAgICAgICBkaXJlY3Rpb24gPSAncmlnaHQnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICBjYXNlICdEb3duJzpcbiAgICAgICAgZGlyZWN0aW9uID0gJ2Rvd24nO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgc2VsZi5tb3ZlQ2FudmFzKHtcbiAgICAgICAgc3BlZWQ6IHNwZWVkLFxuICAgICAgICBkaXJlY3Rpb246IGRpcmVjdGlvblxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMubW92ZUNhbnZhcyA9IGZ1bmN0aW9uKG9wdHMpIHtcblxuICAgIHZhciBkeCA9IDAsXG4gICAgICAgIGR5ID0gMCxcbiAgICAgICAgc3BlZWQgPSBvcHRzLnNwZWVkO1xuXG4gICAgdmFyIGFjdHVhbFNwZWVkID0gc3BlZWQgLyBNYXRoLm1pbihNYXRoLnNxcnQoY2FudmFzLnZpZXdib3goKS5zY2FsZSksIDEpO1xuXG4gICAgc3dpdGNoIChvcHRzLmRpcmVjdGlvbikge1xuICAgIGNhc2UgJ2xlZnQnOiAvLyBMZWZ0XG4gICAgICBkeCA9IGFjdHVhbFNwZWVkO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXAnOiAvLyBVcFxuICAgICAgZHkgPSBhY3R1YWxTcGVlZDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3JpZ2h0JzogLy8gUmlnaHRcbiAgICAgIGR4ID0gLWFjdHVhbFNwZWVkO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZG93bic6IC8vIERvd25cbiAgICAgIGR5ID0gLWFjdHVhbFNwZWVkO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgY2FudmFzLnNjcm9sbCh7XG4gICAgICBkeDogZHgsXG4gICAgICBkeTogZHlcbiAgICB9KTtcbiAgfTtcblxufVxuXG5cbktleWJvYXJkTW92ZS4kaW5qZWN0ID0gW1xuICAnY29uZmlnLmtleWJvYXJkTW92ZScsXG4gICdrZXlib2FyZCcsXG4gICdjYW52YXMnXG5dO1xuIiwiaW1wb3J0IEtleWJvYXJkTW9kdWxlIGZyb20gJy4uLy4uL2ZlYXR1cmVzL2tleWJvYXJkJztcblxuaW1wb3J0IEtleWJvYXJkTW92ZSBmcm9tICcuL0tleWJvYXJkTW92ZSc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIEtleWJvYXJkTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdrZXlib2FyZE1vdmUnIF0sXG4gIGtleWJvYXJkTW92ZTogWyAndHlwZScsIEtleWJvYXJkTW92ZSBdXG59OyIsImltcG9ydCB7XG4gIHNldCBhcyBjdXJzb3JTZXQsXG4gIHVuc2V0IGFzIGN1cnNvclVuc2V0XG59IGZyb20gJy4uLy4uL3V0aWwvQ3Vyc29yJztcblxuaW1wb3J0IHtcbiAgaW5zdGFsbCBhcyBpbnN0YWxsQ2xpY2tUcmFwXG59IGZyb20gJy4uLy4uL3V0aWwvQ2xpY2tUcmFwJztcblxuaW1wb3J0IHtcbiAgZGVsdGEgYXMgZGVsdGFQb3Ncbn0gZnJvbSAnLi4vLi4vdXRpbC9Qb3NpdGlvblV0aWwnO1xuXG5pbXBvcnQge1xuICBldmVudCBhcyBkb21FdmVudCxcbiAgY2xvc2VzdCBhcyBkb21DbG9zZXN0XG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICB0b1BvaW50XG59IGZyb20gJy4uLy4uL3V0aWwvRXZlbnQnO1xuXG5cbnZhciBUSFJFU0hPTEQgPSAxNTtcblxuXG4vKipcbiAqIE1vdmUgdGhlIGNhbnZhcyB2aWEgbW91c2UuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW92ZUNhbnZhcyhldmVudEJ1cywgY2FudmFzKSB7XG5cbiAgdmFyIGNvbnRleHQ7XG5cblxuICAvLyBsaXN0ZW4gZm9yIG1vdmUgb24gZWxlbWVudCBtb3VzZSBkb3duO1xuICAvLyBhbGxvdyBvdGhlcnMgdG8gaG9vayBpbnRvIHRoZSBldmVudCBiZWZvcmUgdXMgdGhvdWdoXG4gIC8vIChkcmFnZ2luZyAvIGVsZW1lbnQgbW92aW5nIHdpbGwgZG8gdGhpcylcbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQubW91c2Vkb3duJywgNTAwLCBmdW5jdGlvbihlKSB7XG4gICAgcmV0dXJuIGhhbmRsZVN0YXJ0KGUub3JpZ2luYWxFdmVudCk7XG4gIH0pO1xuXG5cbiAgZnVuY3Rpb24gaGFuZGxlTW92ZShldmVudCkge1xuXG4gICAgdmFyIHN0YXJ0ID0gY29udGV4dC5zdGFydCxcbiAgICAgICAgcG9zaXRpb24gPSB0b1BvaW50KGV2ZW50KSxcbiAgICAgICAgZGVsdGEgPSBkZWx0YVBvcyhwb3NpdGlvbiwgc3RhcnQpO1xuXG4gICAgaWYgKCFjb250ZXh0LmRyYWdnaW5nICYmIGxlbmd0aChkZWx0YSkgPiBUSFJFU0hPTEQpIHtcbiAgICAgIGNvbnRleHQuZHJhZ2dpbmcgPSB0cnVlO1xuXG4gICAgICBpbnN0YWxsQ2xpY2tUcmFwKGV2ZW50QnVzKTtcblxuICAgICAgY3Vyc29yU2V0KCdncmFiJyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQuZHJhZ2dpbmcpIHtcblxuICAgICAgdmFyIGxhc3RQb3NpdGlvbiA9IGNvbnRleHQubGFzdCB8fCBjb250ZXh0LnN0YXJ0O1xuXG4gICAgICBkZWx0YSA9IGRlbHRhUG9zKHBvc2l0aW9uLCBsYXN0UG9zaXRpb24pO1xuXG4gICAgICBjYW52YXMuc2Nyb2xsKHtcbiAgICAgICAgZHg6IGRlbHRhLngsXG4gICAgICAgIGR5OiBkZWx0YS55XG4gICAgICB9KTtcblxuICAgICAgY29udGV4dC5sYXN0ID0gcG9zaXRpb247XG4gICAgfVxuXG4gICAgLy8gcHJldmVudCBzZWxlY3RcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBoYW5kbGVFbmQoZXZlbnQpIHtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdtb3VzZW1vdmUnLCBoYW5kbGVNb3ZlKTtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdtb3VzZXVwJywgaGFuZGxlRW5kKTtcblxuICAgIGNvbnRleHQgPSBudWxsO1xuXG4gICAgY3Vyc29yVW5zZXQoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVN0YXJ0KGV2ZW50KSB7XG5cbiAgICAvLyBldmVudCBpcyBhbHJlYWR5IGhhbmRsZWQgYnkgJy5kanMtZHJhZ2dhYmxlJ1xuICAgIGlmIChkb21DbG9zZXN0KGV2ZW50LnRhcmdldCwgJy5kanMtZHJhZ2dhYmxlJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cblxuICAgIC8vIHJlamVjdCBub24tbGVmdCBsZWZ0IG1vdXNlIGJ1dHRvbiBvciBtb2RpZmllciBrZXlcbiAgICBpZiAoZXZlbnQuYnV0dG9uIHx8IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQuc2hpZnRLZXkgfHwgZXZlbnQuYWx0S2V5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29udGV4dCA9IHtcbiAgICAgIHN0YXJ0OiB0b1BvaW50KGV2ZW50KVxuICAgIH07XG5cbiAgICBkb21FdmVudC5iaW5kKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgaGFuZGxlTW92ZSk7XG4gICAgZG9tRXZlbnQuYmluZChkb2N1bWVudCwgJ21vdXNldXAnLCBoYW5kbGVFbmQpO1xuXG4gICAgLy8gd2UndmUgaGFuZGxlZCB0aGUgZXZlbnRcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5cbk1vdmVDYW52YXMuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcydcbl07XG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy9cblxuZnVuY3Rpb24gbGVuZ3RoKHBvaW50KSB7XG4gIHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3cocG9pbnQueCwgMikgKyBNYXRoLnBvdyhwb2ludC55LCAyKSk7XG59XG4iLCJpbXBvcnQgTW92ZUNhbnZhcyBmcm9tICcuL01vdmVDYW52YXMnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdtb3ZlQ2FudmFzJyBdLFxuICBtb3ZlQ2FudmFzOiBbICd0eXBlJywgTW92ZUNhbnZhcyBdXG59OyIsImltcG9ydCBUb3VjaE1vZHVsZSBmcm9tICcuLi8uLi9mZWF0dXJlcy90b3VjaCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBUb3VjaE1vZHVsZVxuICBdXG59OyIsImltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50LFxuICBjbG9zZXN0IGFzIGRvbUNsb3Nlc3Rcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIGdldFN0ZXBTaXplLFxuICBjYXBcbn0gZnJvbSAnLi9ab29tVXRpbCc7XG5cbmltcG9ydCB7XG4gIGxvZzEwXG59IGZyb20gJy4uLy4uL3V0aWwvTWF0aCc7XG5cbmltcG9ydCB7XG4gIGJpbmRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgc2lnbiA9IE1hdGguc2lnbiB8fCBmdW5jdGlvbihuKSB7XG4gIHJldHVybiBuID49IDAgPyAxIDogLTE7XG59O1xuXG52YXIgUkFOR0UgPSB7IG1pbjogMC4yLCBtYXg6IDQgfSxcbiAgICBOVU1fU1RFUFMgPSAxMDtcblxudmFyIERFTFRBX1RIUkVTSE9MRCA9IDAuMTtcblxudmFyIERFRkFVTFRfU0NBTEUgPSAwLjc1O1xuXG4vKipcbiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIHpvb21pbmcgYW5kIHNjcm9sbGluZyB3aXRoaW4gdGhlXG4gKiB7QGxpbmsgQ2FudmFzfSB2aWEgdGhlIG1vdXNlIHdoZWVsLlxuICpcbiAqIE1vdXNlIHdoZWVsIHpvb21pbmcgLyBzY3JvbGxpbmcgbWF5IGJlIGRpc2FibGVkIHVzaW5nXG4gKiB0aGUge0BsaW5rIHRvZ2dsZShlbmFibGVkKX0gbWV0aG9kLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbY29uZmlnXVxuICogQHBhcmFtIHtib29sZWFufSBbY29uZmlnLmVuYWJsZWQ9dHJ1ZV0gZGVmYXVsdCBlbmFibGVkIHN0YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmZpZy5zY2FsZT0uNzVdIHNjcm9sbCBzZW5zaXZpdHlcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFpvb21TY3JvbGwoY29uZmlnLCBldmVudEJ1cywgY2FudmFzKSB7XG5cbiAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xuXG4gIHRoaXMuX2VuYWJsZWQgPSBmYWxzZTtcblxuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX2NvbnRhaW5lciA9IGNhbnZhcy5fY29udGFpbmVyO1xuXG4gIHRoaXMuX2hhbmRsZVdoZWVsID0gYmluZCh0aGlzLl9oYW5kbGVXaGVlbCwgdGhpcyk7XG5cbiAgdGhpcy5fdG90YWxEZWx0YSA9IDA7XG4gIHRoaXMuX3NjYWxlID0gY29uZmlnLnNjYWxlIHx8IERFRkFVTFRfU0NBTEU7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuaW5pdCcsIGZ1bmN0aW9uKGUpIHtcbiAgICBzZWxmLl9pbml0KGNvbmZpZy5lbmFibGVkICE9PSBmYWxzZSk7XG4gIH0pO1xufVxuXG5ab29tU2Nyb2xsLiRpbmplY3QgPSBbXG4gICdjb25maWcuem9vbVNjcm9sbCcsXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnXG5dO1xuXG5ab29tU2Nyb2xsLnByb3RvdHlwZS5zY3JvbGwgPSBmdW5jdGlvbiBzY3JvbGwoZGVsdGEpIHtcbiAgdGhpcy5fY2FudmFzLnNjcm9sbChkZWx0YSk7XG59O1xuXG5cblpvb21TY3JvbGwucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gcmVzZXQoKSB7XG4gIHRoaXMuX2NhbnZhcy56b29tKCdmaXQtdmlld3BvcnQnKTtcbn07XG5cbi8qKlxuICogWm9vbSBkZXBlbmRpbmcgb24gZGVsdGEuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhXG4gKiBAcGFyYW0ge09iamVjdH0gcG9zaXRpb25cbiAqL1xuWm9vbVNjcm9sbC5wcm90b3R5cGUuem9vbSA9IGZ1bmN0aW9uIHpvb20oZGVsdGEsIHBvc2l0aW9uKSB7XG5cbiAgLy8gem9vbSB3aXRoIGhhbGYgdGhlIHN0ZXAgc2l6ZSBvZiBzdGVwWm9vbVxuICB2YXIgc3RlcFNpemUgPSBnZXRTdGVwU2l6ZShSQU5HRSwgTlVNX1NURVBTICogMik7XG5cbiAgLy8gYWRkIHVudGlsIHRocmVzaG9sZCByZWFjaGVkXG4gIHRoaXMuX3RvdGFsRGVsdGEgKz0gZGVsdGE7XG5cbiAgaWYgKE1hdGguYWJzKHRoaXMuX3RvdGFsRGVsdGEpID4gREVMVEFfVEhSRVNIT0xEKSB7XG4gICAgdGhpcy5fem9vbShkZWx0YSwgcG9zaXRpb24sIHN0ZXBTaXplKTtcblxuICAgIC8vIHJlc2V0XG4gICAgdGhpcy5fdG90YWxEZWx0YSA9IDA7XG4gIH1cbn07XG5cblxuWm9vbVNjcm9sbC5wcm90b3R5cGUuX2hhbmRsZVdoZWVsID0gZnVuY3Rpb24gaGFuZGxlV2hlZWwoZXZlbnQpIHtcblxuICAvLyBldmVudCBpcyBhbHJlYWR5IGhhbmRsZWQgYnkgJy5kanMtc2Nyb2xsYWJsZSdcbiAgaWYgKGRvbUNsb3Nlc3QoZXZlbnQudGFyZ2V0LCAnLmRqcy1zY3JvbGxhYmxlJywgdHJ1ZSkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZWxlbWVudCA9IHRoaXMuX2NvbnRhaW5lcjtcblxuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gIC8vIHBpbmNoIHRvIHpvb20gaXMgbWFwcGVkIHRvIHdoZWVsICsgY3RybEtleSA9IHRydWVcbiAgLy8gaW4gbW9kZXJuIGJyb3dzZXJzICghKVxuXG4gIHZhciBpc1pvb20gPSBldmVudC5jdHJsS2V5O1xuXG4gIHZhciBpc0hvcml6b250YWxTY3JvbGwgPSBldmVudC5zaGlmdEtleTtcblxuICB2YXIgZmFjdG9yID0gLTEgKiB0aGlzLl9zY2FsZSxcbiAgICAgIGRlbHRhO1xuXG4gIGlmIChpc1pvb20pIHtcbiAgICBmYWN0b3IgKj0gZXZlbnQuZGVsdGFNb2RlID09PSAwID8gMC4wMjAgOiAwLjMyO1xuICB9IGVsc2Uge1xuICAgIGZhY3RvciAqPSBldmVudC5kZWx0YU1vZGUgPT09IDAgPyAxLjAgOiAxNi4wO1xuICB9XG5cbiAgaWYgKGlzWm9vbSkge1xuICAgIHZhciBlbGVtZW50UmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB2YXIgb2Zmc2V0ID0ge1xuICAgICAgeDogZXZlbnQuY2xpZW50WCAtIGVsZW1lbnRSZWN0LmxlZnQsXG4gICAgICB5OiBldmVudC5jbGllbnRZIC0gZWxlbWVudFJlY3QudG9wXG4gICAgfTtcblxuICAgIGRlbHRhID0gKFxuICAgICAgTWF0aC5zcXJ0KFxuICAgICAgICBNYXRoLnBvdyhldmVudC5kZWx0YVksIDIpICtcbiAgICAgICAgTWF0aC5wb3coZXZlbnQuZGVsdGFYLCAyKVxuICAgICAgKSAqIHNpZ24oZXZlbnQuZGVsdGFZKSAqIGZhY3RvclxuICAgICk7XG5cbiAgICAvLyB6b29tIGluIHJlbGF0aXZlIHRvIGRpYWdyYW0ge3gseX0gY29vcmRpbmF0ZXNcbiAgICB0aGlzLnpvb20oZGVsdGEsIG9mZnNldCk7XG4gIH0gZWxzZSB7XG5cbiAgICBpZiAoaXNIb3Jpem9udGFsU2Nyb2xsKSB7XG4gICAgICBkZWx0YSA9IHtcbiAgICAgICAgZHg6IGZhY3RvciAqIGV2ZW50LmRlbHRhWSxcbiAgICAgICAgZHk6IDBcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbHRhID0ge1xuICAgICAgICBkeDogZmFjdG9yICogZXZlbnQuZGVsdGFYLFxuICAgICAgICBkeTogZmFjdG9yICogZXZlbnQuZGVsdGFZXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuc2Nyb2xsKGRlbHRhKTtcbiAgfVxufTtcblxuLyoqXG4gKiBab29tIHdpdGggZml4ZWQgc3RlcCBzaXplLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YSAtIFpvb20gZGVsdGEgKDEgZm9yIHpvb21pbmcgaW4sIC0xIGZvciBvdXQpLlxuICogQHBhcmFtIHtPYmplY3R9IHBvc2l0aW9uXG4gKi9cblpvb21TY3JvbGwucHJvdG90eXBlLnN0ZXBab29tID0gZnVuY3Rpb24gc3RlcFpvb20oZGVsdGEsIHBvc2l0aW9uKSB7XG5cbiAgdmFyIHN0ZXBTaXplID0gZ2V0U3RlcFNpemUoUkFOR0UsIE5VTV9TVEVQUyk7XG5cbiAgdGhpcy5fem9vbShkZWx0YSwgcG9zaXRpb24sIHN0ZXBTaXplKTtcbn07XG5cblxuLyoqXG4gKiBab29tIGluL291dCBnaXZlbiBhIHN0ZXAgc2l6ZS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsdGFcbiAqIEBwYXJhbSB7T2JqZWN0fSBwb3NpdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHN0ZXBTaXplXG4gKi9cblpvb21TY3JvbGwucHJvdG90eXBlLl96b29tID0gZnVuY3Rpb24oZGVsdGEsIHBvc2l0aW9uLCBzdGVwU2l6ZSkge1xuICB2YXIgY2FudmFzID0gdGhpcy5fY2FudmFzO1xuXG4gIHZhciBkaXJlY3Rpb24gPSBkZWx0YSA+IDAgPyAxIDogLTE7XG5cbiAgdmFyIGN1cnJlbnRMaW5lYXJab29tTGV2ZWwgPSBsb2cxMChjYW52YXMuem9vbSgpKTtcblxuICAvLyBzbmFwIHRvIGEgcHJveGltYXRlIHpvb20gc3RlcFxuICB2YXIgbmV3TGluZWFyWm9vbUxldmVsID0gTWF0aC5yb3VuZChjdXJyZW50TGluZWFyWm9vbUxldmVsIC8gc3RlcFNpemUpICogc3RlcFNpemU7XG5cbiAgLy8gaW5jcmVhc2Ugb3IgZGVjcmVhc2Ugb25lIHpvb20gc3RlcCBpbiB0aGUgZ2l2ZW4gZGlyZWN0aW9uXG4gIG5ld0xpbmVhclpvb21MZXZlbCArPSBzdGVwU2l6ZSAqIGRpcmVjdGlvbjtcblxuICAvLyBjYWxjdWxhdGUgdGhlIGFic29sdXRlIGxvZ2FyaXRobWljIHpvb20gbGV2ZWwgYmFzZWQgb24gdGhlIGxpbmVhciB6b29tIGxldmVsXG4gIC8vIChlLmcuIDIgZm9yIGFuIGFic29sdXRlIHgyIHpvb20pXG4gIHZhciBuZXdMb2dab29tTGV2ZWwgPSBNYXRoLnBvdygxMCwgbmV3TGluZWFyWm9vbUxldmVsKTtcblxuICBjYW52YXMuem9vbShjYXAoUkFOR0UsIG5ld0xvZ1pvb21MZXZlbCksIHBvc2l0aW9uKTtcbn07XG5cblxuLyoqXG4gKiBUb2dnbGUgdGhlIHpvb20gc2Nyb2xsIGFiaWxpdHkgdmlhIG1vdXNlIHdoZWVsLlxuICpcbiAqIEBwYXJhbSAge2Jvb2xlYW59IFtuZXdFbmFibGVkXSBuZXcgZW5hYmxlZCBzdGF0ZVxuICovXG5ab29tU2Nyb2xsLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiB0b2dnbGUobmV3RW5hYmxlZCkge1xuXG4gIHZhciBlbGVtZW50ID0gdGhpcy5fY29udGFpbmVyO1xuICB2YXIgaGFuZGxlV2hlZWwgPSB0aGlzLl9oYW5kbGVXaGVlbDtcblxuICB2YXIgb2xkRW5hYmxlZCA9IHRoaXMuX2VuYWJsZWQ7XG5cbiAgaWYgKHR5cGVvZiBuZXdFbmFibGVkID09PSAndW5kZWZpbmVkJykge1xuICAgIG5ld0VuYWJsZWQgPSAhb2xkRW5hYmxlZDtcbiAgfVxuXG4gIC8vIG9ubHkgcmVhY3Qgb24gYWN0dWFsIGNoYW5nZXNcbiAgaWYgKG9sZEVuYWJsZWQgIT09IG5ld0VuYWJsZWQpIHtcblxuICAgIC8vIGFkZCBvciByZW1vdmUgd2hlZWwgbGlzdGVuZXIgYmFzZWQgb25cbiAgICAvLyBjaGFuZ2VkIGVuYWJsZWQgc3RhdGVcbiAgICBkb21FdmVudFtuZXdFbmFibGVkID8gJ2JpbmQnIDogJ3VuYmluZCddKGVsZW1lbnQsICd3aGVlbCcsIGhhbmRsZVdoZWVsLCBmYWxzZSk7XG4gIH1cblxuICB0aGlzLl9lbmFibGVkID0gbmV3RW5hYmxlZDtcblxuICByZXR1cm4gbmV3RW5hYmxlZDtcbn07XG5cblxuWm9vbVNjcm9sbC5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbihuZXdFbmFibGVkKSB7XG4gIHRoaXMudG9nZ2xlKG5ld0VuYWJsZWQpO1xufTtcbiIsImltcG9ydCB7XG4gIGxvZzEwXG59IGZyb20gJy4uLy4uL3V0aWwvTWF0aCc7XG5cbi8qKlxuICogR2V0IHN0ZXAgc2l6ZSBmb3IgZ2l2ZW4gcmFuZ2UgYW5kIG51bWJlciBvZiBzdGVwcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcmFuZ2VcbiAqIEBwYXJhbSB7bnVtYmVyfSByYW5nZS5taW5cbiAqIEBwYXJhbSB7bnVtYmVyfSByYW5nZS5tYXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0ZXBTaXplKHJhbmdlLCBzdGVwcykge1xuXG4gIHZhciBtaW5MaW5lYXJSYW5nZSA9IGxvZzEwKHJhbmdlLm1pbiksXG4gICAgICBtYXhMaW5lYXJSYW5nZSA9IGxvZzEwKHJhbmdlLm1heCk7XG5cbiAgdmFyIGFic29sdXRlTGluZWFyUmFuZ2UgPSBNYXRoLmFicyhtaW5MaW5lYXJSYW5nZSkgKyBNYXRoLmFicyhtYXhMaW5lYXJSYW5nZSk7XG5cbiAgcmV0dXJuIGFic29sdXRlTGluZWFyUmFuZ2UgLyBzdGVwcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhcChyYW5nZSwgc2NhbGUpIHtcbiAgcmV0dXJuIE1hdGgubWF4KHJhbmdlLm1pbiwgTWF0aC5taW4ocmFuZ2UubWF4LCBzY2FsZSkpO1xufVxuIiwiaW1wb3J0IFpvb21TY3JvbGwgZnJvbSAnLi9ab29tU2Nyb2xsJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnem9vbVNjcm9sbCcgXSxcbiAgem9vbVNjcm9sbDogWyAndHlwZScsIFpvb21TY3JvbGwgXVxufTsiLCJpbXBvcnQge1xuICBhc1RSQkwsXG4gIGdldE9yaWVudGF0aW9uLFxuICByb3VuZFBvaW50XG59IGZyb20gJy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgY2VudGVyLFxuICBkZWx0YVxufSBmcm9tICcuL1Bvc2l0aW9uVXRpbCc7XG5cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBhYnNvbHV0ZSBwb2ludCByZWxhdGl2ZSB0byB0aGUgbmV3IGVsZW1lbnQncyBwb3NpdGlvblxuICpcbiAqIEBwYXJhbSB7cG9pbnR9IHBvaW50IFthYnNvbHV0ZV1cbiAqIEBwYXJhbSB7Ym91bmRzfSBvbGRCb3VuZHNcbiAqIEBwYXJhbSB7Ym91bmRzfSBuZXdCb3VuZHNcbiAqXG4gKiBAcmV0dXJuIHtwb2ludH0gcG9pbnQgW2Fic29sdXRlXVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmV3QXR0YWNoUG9pbnQocG9pbnQsIG9sZEJvdW5kcywgbmV3Qm91bmRzKSB7XG4gIHZhciBvbGRDZW50ZXIgPSBjZW50ZXIob2xkQm91bmRzKSxcbiAgICAgIG5ld0NlbnRlciA9IGNlbnRlcihuZXdCb3VuZHMpLFxuICAgICAgb2xkRGVsdGEgPSBkZWx0YShwb2ludCwgb2xkQ2VudGVyKTtcblxuICB2YXIgbmV3RGVsdGEgPSB7XG4gICAgeDogb2xkRGVsdGEueCAqIChuZXdCb3VuZHMud2lkdGggLyBvbGRCb3VuZHMud2lkdGgpLFxuICAgIHk6IG9sZERlbHRhLnkgKiAobmV3Qm91bmRzLmhlaWdodCAvIG9sZEJvdW5kcy5oZWlnaHQpXG4gIH07XG5cbiAgcmV0dXJuIHJvdW5kUG9pbnQoe1xuICAgIHg6IG5ld0NlbnRlci54ICsgbmV3RGVsdGEueCxcbiAgICB5OiBuZXdDZW50ZXIueSArIG5ld0RlbHRhLnlcbiAgfSk7XG59XG5cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBzaGFwZSdzIGRlbHRhIHJlbGF0aXZlIHRvIGEgbmV3IHBvc2l0aW9uXG4gKiBvZiBhIGNlcnRhaW4gZWxlbWVudCdzIGJvdW5kc1xuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBwb2ludCBbYWJzb2x1dGVdXG4gKiBAcGFyYW0ge2JvdW5kc30gb2xkQm91bmRzXG4gKiBAcGFyYW0ge2JvdW5kc30gbmV3Qm91bmRzXG4gKlxuICogQHJldHVybiB7ZGVsdGF9IGRlbHRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXROZXdBdHRhY2hTaGFwZURlbHRhKHNoYXBlLCBvbGRCb3VuZHMsIG5ld0JvdW5kcykge1xuICB2YXIgc2hhcGVDZW50ZXIgPSBjZW50ZXIoc2hhcGUpLFxuICAgICAgb2xkQ2VudGVyID0gY2VudGVyKG9sZEJvdW5kcyksXG4gICAgICBuZXdDZW50ZXIgPSBjZW50ZXIobmV3Qm91bmRzKSxcbiAgICAgIHNoYXBlRGVsdGEgPSBkZWx0YShzaGFwZSwgc2hhcGVDZW50ZXIpLFxuICAgICAgb2xkQ2VudGVyRGVsdGEgPSBkZWx0YShzaGFwZUNlbnRlciwgb2xkQ2VudGVyKSxcbiAgICAgIHN0aWNreVBvc2l0aW9uRGVsdGEgPSBnZXRTdGlja3lQb3NpdGlvbkRlbHRhKHNoYXBlQ2VudGVyLCBvbGRCb3VuZHMsIG5ld0JvdW5kcyk7XG5cbiAgaWYgKHN0aWNreVBvc2l0aW9uRGVsdGEpIHtcbiAgICByZXR1cm4gc3RpY2t5UG9zaXRpb25EZWx0YTtcbiAgfVxuXG4gIHZhciBuZXdDZW50ZXJEZWx0YSA9IHtcbiAgICB4OiBvbGRDZW50ZXJEZWx0YS54ICogKG5ld0JvdW5kcy53aWR0aCAvIG9sZEJvdW5kcy53aWR0aCksXG4gICAgeTogb2xkQ2VudGVyRGVsdGEueSAqIChuZXdCb3VuZHMuaGVpZ2h0IC8gb2xkQm91bmRzLmhlaWdodClcbiAgfTtcblxuICB2YXIgbmV3U2hhcGVDZW50ZXIgPSB7XG4gICAgeDogbmV3Q2VudGVyLnggKyBuZXdDZW50ZXJEZWx0YS54LFxuICAgIHk6IG5ld0NlbnRlci55ICsgbmV3Q2VudGVyRGVsdGEueVxuICB9O1xuXG4gIHJldHVybiByb3VuZFBvaW50KHtcbiAgICB4OiBuZXdTaGFwZUNlbnRlci54ICsgc2hhcGVEZWx0YS54IC0gc2hhcGUueCxcbiAgICB5OiBuZXdTaGFwZUNlbnRlci55ICsgc2hhcGVEZWx0YS55IC0gc2hhcGUueVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RpY2t5UG9zaXRpb25EZWx0YShvbGRTaGFwZUNlbnRlciwgb2xkQm91bmRzLCBuZXdCb3VuZHMpIHtcbiAgdmFyIG9sZFRSQkwgPSBhc1RSQkwob2xkQm91bmRzKSxcbiAgICAgIG5ld1RSQkwgPSBhc1RSQkwobmV3Qm91bmRzKTtcblxuICBpZiAoaXNNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIG9sZE9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24ob2xkQm91bmRzLCBvbGRTaGFwZUNlbnRlciksXG4gICAgICBzdGlja3lQb3NpdGlvbkRlbHRhLFxuICAgICAgbmV3U2hhcGVDZW50ZXIsXG4gICAgICBuZXdPcmllbnRhdGlvbjtcblxuICBpZiAob2xkT3JpZW50YXRpb24gPT09ICd0b3AnKSB7XG4gICAgc3RpY2t5UG9zaXRpb25EZWx0YSA9IHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiBuZXdUUkJMLmJvdHRvbSAtIG9sZFRSQkwuYm90dG9tXG4gICAgfTtcbiAgfSBlbHNlIGlmIChvbGRPcmllbnRhdGlvbiA9PT0gJ2JvdHRvbScpIHtcbiAgICBzdGlja3lQb3NpdGlvbkRlbHRhID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IG5ld1RSQkwudG9wIC0gb2xkVFJCTC50b3BcbiAgICB9O1xuICB9IGVsc2UgaWYgKG9sZE9yaWVudGF0aW9uID09PSAncmlnaHQnKSB7XG4gICAgc3RpY2t5UG9zaXRpb25EZWx0YSA9IHtcbiAgICAgIHg6IG5ld1RSQkwubGVmdCAtIG9sZFRSQkwubGVmdCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9IGVsc2UgaWYgKG9sZE9yaWVudGF0aW9uID09PSAnbGVmdCcpIHtcbiAgICBzdGlja3lQb3NpdGlvbkRlbHRhID0ge1xuICAgICAgeDogbmV3VFJCTC5yaWdodCAtIG9sZFRSQkwucmlnaHQsXG4gICAgICB5OiAwXG4gICAgfTtcbiAgfSBlbHNlIHtcblxuICAgIC8vIGZhbGxiYWNrIHRvIHByb3BvcnRpb25hbCBtb3ZlbWVudCBmb3IgY29ybmVyLXBsYWNlZCBhdHRhY2htZW50c1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbmV3U2hhcGVDZW50ZXIgPSB7XG4gICAgeDogb2xkU2hhcGVDZW50ZXIueCArIHN0aWNreVBvc2l0aW9uRGVsdGEueCxcbiAgICB5OiBvbGRTaGFwZUNlbnRlci55ICsgc3RpY2t5UG9zaXRpb25EZWx0YS55XG4gIH07XG5cbiAgbmV3T3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihuZXdCb3VuZHMsIG5ld1NoYXBlQ2VudGVyKTtcblxuICBpZiAobmV3T3JpZW50YXRpb24gIT09IG9sZE9yaWVudGF0aW9uKSB7XG5cbiAgICAvLyBmYWxsYmFjayB0byBwcm9wb3J0aW9uYWwgbW92ZW1lbnQgaWYgb3JpZW50YXRpb24gd291bGQgb3RoZXJ3aXNlIGNoYW5nZVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHN0aWNreVBvc2l0aW9uRGVsdGE7XG59XG5cbmZ1bmN0aW9uIGlzTW92ZWQob2xkVFJCTCwgbmV3VFJCTCkge1xuICByZXR1cm4gaXNIb3Jpem9udGFsbHlNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKSB8fCBpc1ZlcnRpY2FsbHlNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKTtcbn1cblxuZnVuY3Rpb24gaXNIb3Jpem9udGFsbHlNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKSB7XG4gIHJldHVybiBvbGRUUkJMLnJpZ2h0ICE9PSBuZXdUUkJMLnJpZ2h0ICYmIG9sZFRSQkwubGVmdCAhPT0gbmV3VFJCTC5sZWZ0O1xufVxuXG5mdW5jdGlvbiBpc1ZlcnRpY2FsbHlNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKSB7XG4gIHJldHVybiBvbGRUUkJMLnRvcCAhPT0gbmV3VFJCTC50b3AgJiYgb2xkVFJCTC5ib3R0b20gIT09IG5ld1RSQkwuYm90dG9tO1xufVxuIiwidmFyIFRSQVBfUFJJT1JJVFkgPSA1MDAwO1xuXG4vKipcbiAqIEluc3RhbGxzIGEgY2xpY2sgdHJhcCB0aGF0IHByZXZlbnRzIGEgZ2hvc3QgY2xpY2sgZm9sbG93aW5nIGEgZHJhZ2dpbmcgb3BlcmF0aW9uLlxuICpcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBhIGZ1bmN0aW9uIHRvIGltbWVkaWF0ZWx5IHJlbW92ZSB0aGUgaW5zdGFsbGVkIHRyYXAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YWxsKGV2ZW50QnVzLCBldmVudE5hbWUpIHtcblxuICBldmVudE5hbWUgPSBldmVudE5hbWUgfHwgJ2VsZW1lbnQuY2xpY2snO1xuXG4gIGZ1bmN0aW9uIHRyYXAoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZXZlbnRCdXMub25jZShldmVudE5hbWUsIFRSQVBfUFJJT1JJVFksIHRyYXApO1xuXG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBldmVudEJ1cy5vZmYoZXZlbnROYW1lLCB0cmFwKTtcbiAgfTtcbn0iLCIvKipcbiAqIEZhaWxzYWZlIHJlbW92ZSBhbiBlbGVtZW50IGZyb20gYSBjb2xsZWN0aW9uXG4gKlxuICogQHBhcmFtICB7QXJyYXk8T2JqZWN0Pn0gW2NvbGxlY3Rpb25dXG4gKiBAcGFyYW0gIHtPYmplY3R9IFtlbGVtZW50XVxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gdGhlIHByZXZpb3VzIGluZGV4IG9mIHRoZSBlbGVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmUoY29sbGVjdGlvbiwgZWxlbWVudCkge1xuXG4gIGlmICghY29sbGVjdGlvbiB8fCAhZWxlbWVudCkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIHZhciBpZHggPSBjb2xsZWN0aW9uLmluZGV4T2YoZWxlbWVudCk7XG5cbiAgaWYgKGlkeCAhPT0gLTEpIHtcbiAgICBjb2xsZWN0aW9uLnNwbGljZShpZHgsIDEpO1xuICB9XG5cbiAgcmV0dXJuIGlkeDtcbn1cblxuLyoqXG4gKiBGYWlsIHNhdmUgYWRkIGFuIGVsZW1lbnQgdG8gdGhlIGdpdmVuIGNvbm5lY3Rpb24sIGVuc3VyaW5nXG4gKiBpdCBkb2VzIG5vdCB5ZXQgZXhpc3QuXG4gKlxuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBjb2xsZWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gZWxlbWVudFxuICogQHBhcmFtIHtudW1iZXJ9IGlkeFxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkKGNvbGxlY3Rpb24sIGVsZW1lbnQsIGlkeCkge1xuXG4gIGlmICghY29sbGVjdGlvbiB8fCAhZWxlbWVudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgaWR4ICE9PSAnbnVtYmVyJykge1xuICAgIGlkeCA9IC0xO1xuICB9XG5cbiAgdmFyIGN1cnJlbnRJZHggPSBjb2xsZWN0aW9uLmluZGV4T2YoZWxlbWVudCk7XG5cbiAgaWYgKGN1cnJlbnRJZHggIT09IC0xKSB7XG5cbiAgICBpZiAoY3VycmVudElkeCA9PT0gaWR4KSB7XG5cbiAgICAgIC8vIG5vdGhpbmcgdG8gZG8sIHBvc2l0aW9uIGhhcyBub3QgY2hhbmdlZFxuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIGlmIChpZHggIT09IC0xKSB7XG5cbiAgICAgICAgLy8gcmVtb3ZlIGZyb20gY3VycmVudCBwb3NpdGlvblxuICAgICAgICBjb2xsZWN0aW9uLnNwbGljZShjdXJyZW50SWR4LCAxKTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gYWxyZWFkeSBleGlzdHMgaW4gY29sbGVjdGlvblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGlkeCAhPT0gLTEpIHtcblxuICAgIC8vIGluc2VydCBhdCBzcGVjaWZpZWQgcG9zaXRpb25cbiAgICBjb2xsZWN0aW9uLnNwbGljZShpZHgsIDAsIGVsZW1lbnQpO1xuICB9IGVsc2Uge1xuXG4gICAgLy8gcHVzaCB0byBlbmRcbiAgICBjb2xsZWN0aW9uLnB1c2goZWxlbWVudCk7XG4gIH1cbn1cblxuXG4vKipcbiAqIEZhaWwgc2F2ZSBnZXQgdGhlIGluZGV4IG9mIGFuIGVsZW1lbnQgaW4gYSBjb2xsZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gY29sbGVjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHRoZSBpbmRleCBvciAtMSBpZiBjb2xsZWN0aW9uIG9yIGVsZW1lbnQgZG9cbiAqICAgICAgICAgICAgICAgICAgbm90IGV4aXN0IG9yIHRoZSBlbGVtZW50IGlzIG5vdCBjb250YWluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmRleE9mKGNvbGxlY3Rpb24sIGVsZW1lbnQpIHtcblxuICBpZiAoIWNvbGxlY3Rpb24gfHwgIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICByZXR1cm4gY29sbGVjdGlvbi5pbmRleE9mKGVsZW1lbnQpO1xufVxuIiwiaW1wb3J0IHtcbiAgY2xhc3NlcyBhcyBkb21DbGFzc2VzXG59IGZyb20gJ21pbi1kb20nO1xuXG52YXIgQ1VSU09SX0NMU19QQVRURVJOID0gL15kanMtY3Vyc29yLS4qJC87XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHNldChtb2RlKSB7XG4gIHZhciBjbGFzc2VzID0gZG9tQ2xhc3Nlcyhkb2N1bWVudC5ib2R5KTtcblxuICBjbGFzc2VzLnJlbW92ZU1hdGNoaW5nKENVUlNPUl9DTFNfUEFUVEVSTik7XG5cbiAgaWYgKG1vZGUpIHtcbiAgICBjbGFzc2VzLmFkZCgnZGpzLWN1cnNvci0nICsgbW9kZSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVuc2V0KCkge1xuICBzZXQobnVsbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXMobW9kZSkge1xuICB2YXIgY2xhc3NlcyA9IGRvbUNsYXNzZXMoZG9jdW1lbnQuYm9keSk7XG5cbiAgcmV0dXJuIGNsYXNzZXMuaGFzKCdkanMtY3Vyc29yLScgKyBtb2RlKTtcbn1cbiIsImltcG9ydCB7XG4gIGFzc2lnbixcbiAgZmlsdGVyLFxuICBmaW5kLFxuICBpc0FycmF5LFxuICBpc051bWJlcixcbiAgaXNPYmplY3QsXG4gIGlzVW5kZWZpbmVkLFxuICBncm91cEJ5LFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEdldCBwYXJlbnQgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuYmFzZT59IGVsZW1lbnRzXG4gKlxuICogQHJldHVybnMge0FycmF5PGRqcy5tb2RlbC5CYXNlPn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBhcmVudHMoZWxlbWVudHMpIHtcblxuICAvLyBmaW5kIGVsZW1lbnRzIHRoYXQgYXJlIG5vdCBjaGlsZHJlbiBvZiBhbnkgb3RoZXIgZWxlbWVudHNcbiAgcmV0dXJuIGZpbHRlcihlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHJldHVybiAhZmluZChlbGVtZW50cywgZnVuY3Rpb24oZSkge1xuICAgICAgcmV0dXJuIGUgIT09IGVsZW1lbnQgJiYgZ2V0UGFyZW50KGVsZW1lbnQsIGUpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBnZXRQYXJlbnQoZWxlbWVudCwgcGFyZW50KSB7XG4gIGlmICghcGFyZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGVsZW1lbnQgPT09IHBhcmVudCkge1xuICAgIHJldHVybiBwYXJlbnQ7XG4gIH1cblxuICBpZiAoIWVsZW1lbnQucGFyZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIGdldFBhcmVudChlbGVtZW50LnBhcmVudCwgcGFyZW50KTtcbn1cblxuXG4vKipcbiAqIEFkZHMgYW4gZWxlbWVudCB0byBhIGNvbGxlY3Rpb24gYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGVcbiAqIGVsZW1lbnQgd2FzIGFkZGVkLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gZWxlbWVudHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHVuaXF1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkKGVsZW1lbnRzLCBlLCB1bmlxdWUpIHtcbiAgdmFyIGNhbkFkZCA9ICF1bmlxdWUgfHwgZWxlbWVudHMuaW5kZXhPZihlKSA9PT0gLTE7XG5cbiAgaWYgKGNhbkFkZCkge1xuICAgIGVsZW1lbnRzLnB1c2goZSk7XG4gIH1cblxuICByZXR1cm4gY2FuQWRkO1xufVxuXG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGVhY2ggZWxlbWVudCBpbiBhIGNvbGxlY3Rpb24sIGNhbGxpbmcgdGhlIGl0ZXJhdG9yIGZ1bmN0aW9uIGBmbmBcbiAqIHdpdGggKGVsZW1lbnQsIGluZGV4LCByZWN1cnNpb25EZXB0aCkuXG4gKlxuICogUmVjdXJzZSBpbnRvIGFsbCBlbGVtZW50cyB0aGF0IGFyZSByZXR1cm5lZCBieSBgZm5gLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheTxPYmplY3Q+fSBlbGVtZW50c1xuICogQHBhcmFtICB7RnVuY3Rpb259IGZuIGl0ZXJhdG9yIGZ1bmN0aW9uIGNhbGxlZCB3aXRoIChlbGVtZW50LCBpbmRleCwgcmVjdXJzaW9uRGVwdGgpXG4gKiBAcGFyYW0gIHtudW1iZXJ9IFtkZXB0aF0gbWF4aW11bSByZWN1cnNpb24gZGVwdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVhY2hFbGVtZW50KGVsZW1lbnRzLCBmbiwgZGVwdGgpIHtcblxuICBkZXB0aCA9IGRlcHRoIHx8IDA7XG5cbiAgaWYgKCFpc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gWyBlbGVtZW50cyBdO1xuICB9XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24ocywgaSkge1xuICAgIHZhciBmaWx0ZXIgPSBmbihzLCBpLCBkZXB0aCk7XG5cbiAgICBpZiAoaXNBcnJheShmaWx0ZXIpICYmIGZpbHRlci5sZW5ndGgpIHtcbiAgICAgIGVhY2hFbGVtZW50KGZpbHRlciwgZm4sIGRlcHRoICsgMSk7XG4gICAgfVxuICB9KTtcbn1cblxuXG4vKipcbiAqIENvbGxlY3RzIHNlbGYgKyBjaGlsZCBlbGVtZW50cyB1cCB0byBhIGdpdmVuIGRlcHRoIGZyb20gYSBsaXN0IG9mIGVsZW1lbnRzLlxuICpcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfEFycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHMgdGhlIGVsZW1lbnRzIHRvIHNlbGVjdCB0aGUgY2hpbGRyZW4gZnJvbVxuICogQHBhcmFtICB7Ym9vbGVhbn0gdW5pcXVlIHdoZXRoZXIgdG8gcmV0dXJuIGEgdW5pcXVlIHJlc3VsdCBzZXQgKG5vIGR1cGxpY2F0ZXMpXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1heERlcHRoIHRoZSBkZXB0aCB0byBzZWFyY2ggdGhyb3VnaCBvciAtMSBmb3IgaW5maW5pdGVcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGZvdW5kIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWxmQW5kQ2hpbGRyZW4oZWxlbWVudHMsIHVuaXF1ZSwgbWF4RGVwdGgpIHtcbiAgdmFyIHJlc3VsdCA9IFtdLFxuICAgICAgcHJvY2Vzc2VkQ2hpbGRyZW4gPSBbXTtcblxuICBlYWNoRWxlbWVudChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCwgaSwgZGVwdGgpIHtcbiAgICBhZGQocmVzdWx0LCBlbGVtZW50LCB1bmlxdWUpO1xuXG4gICAgdmFyIGNoaWxkcmVuID0gZWxlbWVudC5jaGlsZHJlbjtcblxuICAgIC8vIG1heCB0cmF2ZXJzYWwgZGVwdGggbm90IHJlYWNoZWQgeWV0XG4gICAgaWYgKG1heERlcHRoID09PSAtMSB8fCBkZXB0aCA8IG1heERlcHRoKSB7XG5cbiAgICAgIC8vIGNoaWxkcmVuIGV4aXN0ICYmIGNoaWxkcmVuIG5vdCB5ZXQgcHJvY2Vzc2VkXG4gICAgICBpZiAoY2hpbGRyZW4gJiYgYWRkKHByb2Nlc3NlZENoaWxkcmVuLCBjaGlsZHJlbiwgdW5pcXVlKSkge1xuICAgICAgICByZXR1cm4gY2hpbGRyZW47XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJldHVybiBzZWxmICsgZGlyZWN0IGNoaWxkcmVuIGZvciBhIG51bWJlciBvZiBlbGVtZW50c1xuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHMgdG8gcXVlcnlcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGFsbG93RHVwbGljYXRlcyB0byBhbGxvdyBkdXBsaWNhdGVzIGluIHRoZSByZXN1bHQgc2V0XG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSB0aGUgY29sbGVjdGVkIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWxmQW5kRGlyZWN0Q2hpbGRyZW4oZWxlbWVudHMsIGFsbG93RHVwbGljYXRlcykge1xuICByZXR1cm4gc2VsZkFuZENoaWxkcmVuKGVsZW1lbnRzLCAhYWxsb3dEdXBsaWNhdGVzLCAxKTtcbn1cblxuXG4vKipcbiAqIFJldHVybiBzZWxmICsgQUxMIGNoaWxkcmVuIGZvciBhIG51bWJlciBvZiBlbGVtZW50c1xuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHMgdG8gcXVlcnlcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGFsbG93RHVwbGljYXRlcyB0byBhbGxvdyBkdXBsaWNhdGVzIGluIHRoZSByZXN1bHQgc2V0XG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSB0aGUgY29sbGVjdGVkIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWxmQW5kQWxsQ2hpbGRyZW4oZWxlbWVudHMsIGFsbG93RHVwbGljYXRlcykge1xuICByZXR1cm4gc2VsZkFuZENoaWxkcmVuKGVsZW1lbnRzLCAhYWxsb3dEdXBsaWNhdGVzLCAtMSk7XG59XG5cblxuLyoqXG4gKiBHZXRzIHRoZSB0aGUgY2xvc3VyZSBmb3IgYWxsIHNlbGVjdGVkIGVsZW1lbnRzLFxuICogdGhlaXIgZW5jbG9zZWQgY2hpbGRyZW4gYW5kIGNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICogQHBhcmFtIHtib29sZWFufSBbaXNUb3BMZXZlbD10cnVlXVxuICogQHBhcmFtIHtPYmplY3R9IFtleGlzdGluZ0Nsb3N1cmVdXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBuZXdDbG9zdXJlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbG9zdXJlKGVsZW1lbnRzLCBpc1RvcExldmVsLCBjbG9zdXJlKSB7XG5cbiAgaWYgKGlzVW5kZWZpbmVkKGlzVG9wTGV2ZWwpKSB7XG4gICAgaXNUb3BMZXZlbCA9IHRydWU7XG4gIH1cblxuICBpZiAoaXNPYmplY3QoaXNUb3BMZXZlbCkpIHtcbiAgICBjbG9zdXJlID0gaXNUb3BMZXZlbDtcbiAgICBpc1RvcExldmVsID0gdHJ1ZTtcbiAgfVxuXG5cbiAgY2xvc3VyZSA9IGNsb3N1cmUgfHwge307XG5cbiAgdmFyIGFsbFNoYXBlcyA9IGNvcHlPYmplY3QoY2xvc3VyZS5hbGxTaGFwZXMpLFxuICAgICAgYWxsQ29ubmVjdGlvbnMgPSBjb3B5T2JqZWN0KGNsb3N1cmUuYWxsQ29ubmVjdGlvbnMpLFxuICAgICAgZW5jbG9zZWRFbGVtZW50cyA9IGNvcHlPYmplY3QoY2xvc3VyZS5lbmNsb3NlZEVsZW1lbnRzKSxcbiAgICAgIGVuY2xvc2VkQ29ubmVjdGlvbnMgPSBjb3B5T2JqZWN0KGNsb3N1cmUuZW5jbG9zZWRDb25uZWN0aW9ucyk7XG5cbiAgdmFyIHRvcExldmVsID0gY29weU9iamVjdChcbiAgICBjbG9zdXJlLnRvcExldmVsLFxuICAgIGlzVG9wTGV2ZWwgJiYgZ3JvdXBCeShlbGVtZW50cywgZnVuY3Rpb24oZSkgeyByZXR1cm4gZS5pZDsgfSlcbiAgKTtcblxuXG4gIGZ1bmN0aW9uIGhhbmRsZUNvbm5lY3Rpb24oYykge1xuICAgIGlmICh0b3BMZXZlbFtjLnNvdXJjZS5pZF0gJiYgdG9wTGV2ZWxbYy50YXJnZXQuaWRdKSB7XG4gICAgICB0b3BMZXZlbFtjLmlkXSA9IFsgYyBdO1xuICAgIH1cblxuICAgIC8vIG5vdCBlbmNsb3NlZCBhcyBhIGNoaWxkLCBidXQgbWF5YmUgbG9naWNhbGx5XG4gICAgLy8gKGNvbm5lY3RpbmcgdHdvIG1vdmVkIGVsZW1lbnRzPylcbiAgICBpZiAoYWxsU2hhcGVzW2Muc291cmNlLmlkXSAmJiBhbGxTaGFwZXNbYy50YXJnZXQuaWRdKSB7XG4gICAgICBlbmNsb3NlZENvbm5lY3Rpb25zW2MuaWRdID0gZW5jbG9zZWRFbGVtZW50c1tjLmlkXSA9IGM7XG4gICAgfVxuXG4gICAgYWxsQ29ubmVjdGlvbnNbYy5pZF0gPSBjO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlRWxlbWVudChlbGVtZW50KSB7XG5cbiAgICBlbmNsb3NlZEVsZW1lbnRzW2VsZW1lbnQuaWRdID0gZWxlbWVudDtcblxuICAgIGlmIChlbGVtZW50LndheXBvaW50cykge1xuXG4gICAgICAvLyByZW1lbWJlciBjb25uZWN0aW9uXG4gICAgICBlbmNsb3NlZENvbm5lY3Rpb25zW2VsZW1lbnQuaWRdID0gYWxsQ29ubmVjdGlvbnNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIC8vIHJlbWVtYmVyIHNoYXBlXG4gICAgICBhbGxTaGFwZXNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuXG4gICAgICAvLyByZW1lbWJlciBhbGwgY29ubmVjdGlvbnNcbiAgICAgIGZvckVhY2goZWxlbWVudC5pbmNvbWluZywgaGFuZGxlQ29ubmVjdGlvbik7XG5cbiAgICAgIGZvckVhY2goZWxlbWVudC5vdXRnb2luZywgaGFuZGxlQ29ubmVjdGlvbik7XG5cbiAgICAgIC8vIHJlY3Vyc2UgaW50byBjaGlsZHJlblxuICAgICAgcmV0dXJuIGVsZW1lbnQuY2hpbGRyZW47XG4gICAgfVxuICB9XG5cbiAgZWFjaEVsZW1lbnQoZWxlbWVudHMsIGhhbmRsZUVsZW1lbnQpO1xuXG4gIHJldHVybiB7XG4gICAgYWxsU2hhcGVzOiBhbGxTaGFwZXMsXG4gICAgYWxsQ29ubmVjdGlvbnM6IGFsbENvbm5lY3Rpb25zLFxuICAgIHRvcExldmVsOiB0b3BMZXZlbCxcbiAgICBlbmNsb3NlZENvbm5lY3Rpb25zOiBlbmNsb3NlZENvbm5lY3Rpb25zLFxuICAgIGVuY2xvc2VkRWxlbWVudHM6IGVuY2xvc2VkRWxlbWVudHNcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzdXJyb3VuZGluZyBiYm94IGZvciBhbGwgZWxlbWVudHMgaW5cbiAqIHRoZSBhcnJheSBvciB0aGUgZWxlbWVudCBwcmltaXRpdmUuXG4gKlxuICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuU2hhcGU+fGRqcy5tb2RlbC5TaGFwZX0gZWxlbWVudHNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gc3RvcFJlY3Vyc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QkJveChlbGVtZW50cywgc3RvcFJlY3Vyc2lvbikge1xuXG4gIHN0b3BSZWN1cnNpb24gPSAhIXN0b3BSZWN1cnNpb247XG4gIGlmICghaXNBcnJheShlbGVtZW50cykpIHtcbiAgICBlbGVtZW50cyA9IFtlbGVtZW50c107XG4gIH1cblxuICB2YXIgbWluWCxcbiAgICAgIG1pblksXG4gICAgICBtYXhYLFxuICAgICAgbWF4WTtcblxuICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgICAvLyBJZiBlbGVtZW50IGlzIGEgY29ubmVjdGlvbiB0aGUgYmJveCBtdXN0IGJlIGNvbXB1dGVkIGZpcnN0XG4gICAgdmFyIGJib3ggPSBlbGVtZW50O1xuICAgIGlmIChlbGVtZW50LndheXBvaW50cyAmJiAhc3RvcFJlY3Vyc2lvbikge1xuICAgICAgYmJveCA9IGdldEJCb3goZWxlbWVudC53YXlwb2ludHMsIHRydWUpO1xuICAgIH1cblxuICAgIHZhciB4ID0gYmJveC54LFxuICAgICAgICB5ID0gYmJveC55LFxuICAgICAgICBoZWlnaHQgPSBiYm94LmhlaWdodCB8fCAwLFxuICAgICAgICB3aWR0aCA9IGJib3gud2lkdGggfHwgMDtcblxuICAgIGlmICh4IDwgbWluWCB8fCBtaW5YID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG1pblggPSB4O1xuICAgIH1cbiAgICBpZiAoeSA8IG1pblkgfHwgbWluWSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBtaW5ZID0geTtcbiAgICB9XG5cbiAgICBpZiAoKHggKyB3aWR0aCkgPiBtYXhYIHx8IG1heFggPT09IHVuZGVmaW5lZCkge1xuICAgICAgbWF4WCA9IHggKyB3aWR0aDtcbiAgICB9XG4gICAgaWYgKCh5ICsgaGVpZ2h0KSA+IG1heFkgfHwgbWF4WSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBtYXhZID0geSArIGhlaWdodDtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgeDogbWluWCxcbiAgICB5OiBtaW5ZLFxuICAgIGhlaWdodDogbWF4WSAtIG1pblksXG4gICAgd2lkdGg6IG1heFggLSBtaW5YXG4gIH07XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGFsbCBlbGVtZW50cyB0aGF0IGFyZSBlbmNsb3NlZCBmcm9tIHRoZSBib3VuZGluZyBib3guXG4gKlxuICogICAqIElmIGJib3guKHdpZHRofGhlaWdodCkgaXMgbm90IHNwZWNpZmllZCB0aGUgbWV0aG9kIHJldHVybnNcbiAqICAgICBhbGwgZWxlbWVudHMgd2l0aCBlbGVtZW50LngveSA+IGJib3gueC95XG4gKiAgICogSWYgb25seSBiYm94Lnggb3IgYmJveC55IGlzIHNwZWNpZmllZCwgbWV0aG9kIHJldHVybiBhbGwgZWxlbWVudHMgd2l0aFxuICogICAgIGUueCA+IGJib3gueCBvciBlLnkgPiBiYm94LnlcbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzIExpc3Qgb2YgRWxlbWVudHMgdG8gc2VhcmNoIHRocm91Z2hcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBiYm94IHRoZSBlbmNsb3NpbmcgYmJveC5cbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuU2hhcGU+fSBlbmNsb3NlZCBlbGVtZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RW5jbG9zZWRFbGVtZW50cyhlbGVtZW50cywgYmJveCkge1xuXG4gIHZhciBmaWx0ZXJlZEVsZW1lbnRzID0ge307XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgdmFyIGUgPSBlbGVtZW50O1xuXG4gICAgaWYgKGUud2F5cG9pbnRzKSB7XG4gICAgICBlID0gZ2V0QkJveChlKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzTnVtYmVyKGJib3gueSkgJiYgKGUueCA+IGJib3gueCkpIHtcbiAgICAgIGZpbHRlcmVkRWxlbWVudHNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuICAgIH1cbiAgICBpZiAoIWlzTnVtYmVyKGJib3gueCkgJiYgKGUueSA+IGJib3gueSkpIHtcbiAgICAgIGZpbHRlcmVkRWxlbWVudHNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuICAgIH1cbiAgICBpZiAoZS54ID4gYmJveC54ICYmIGUueSA+IGJib3gueSkge1xuICAgICAgaWYgKGlzTnVtYmVyKGJib3gud2lkdGgpICYmIGlzTnVtYmVyKGJib3guaGVpZ2h0KSAmJlxuICAgICAgICAgIGUud2lkdGggKyBlLnggPCBiYm94LndpZHRoICsgYmJveC54ICYmXG4gICAgICAgICAgZS5oZWlnaHQgKyBlLnkgPCBiYm94LmhlaWdodCArIGJib3gueSkge1xuXG4gICAgICAgIGZpbHRlcmVkRWxlbWVudHNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuICAgICAgfSBlbHNlIGlmICghaXNOdW1iZXIoYmJveC53aWR0aCkgfHwgIWlzTnVtYmVyKGJib3guaGVpZ2h0KSkge1xuICAgICAgICBmaWx0ZXJlZEVsZW1lbnRzW2VsZW1lbnQuaWRdID0gZWxlbWVudDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBmaWx0ZXJlZEVsZW1lbnRzO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUeXBlKGVsZW1lbnQpIHtcblxuICBpZiAoJ3dheXBvaW50cycgaW4gZWxlbWVudCkge1xuICAgIHJldHVybiAnY29ubmVjdGlvbic7XG4gIH1cblxuICBpZiAoJ3gnIGluIGVsZW1lbnQpIHtcbiAgICByZXR1cm4gJ3NoYXBlJztcbiAgfVxuXG4gIHJldHVybiAncm9vdCc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0ZyYW1lRWxlbWVudChlbGVtZW50KSB7XG5cbiAgcmV0dXJuICEhKGVsZW1lbnQgJiYgZWxlbWVudC5pc0ZyYW1lKTtcbn1cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNvcHlPYmplY3Qoc3JjMSwgc3JjMikge1xuICByZXR1cm4gYXNzaWduKHt9LCBzcmMxIHx8IHt9LCBzcmMyIHx8IHt9KTtcbn0iLCJleHBvcnQge1xuICBkZWZhdWx0IGFzIGVzY2FwZUNTU1xufSBmcm9tICdjc3MuZXNjYXBlJztcblxudmFyIEhUTUxfRVNDQVBFX01BUCA9IHtcbiAgJyYnOiAnJmFtcDsnLFxuICAnPCc6ICcmbHQ7JyxcbiAgJz4nOiAnJmd0OycsXG4gICdcIic6ICcmcXVvdDsnLFxuICAnXFwnJzogJyYjMzk7J1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZUhUTUwoc3RyKSB7XG4gIHN0ciA9ICcnICsgc3RyO1xuXG4gIHJldHVybiBzdHIgJiYgc3RyLnJlcGxhY2UoL1smPD5cIiddL2csIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgcmV0dXJuIEhUTUxfRVNDQVBFX01BUFttYXRjaF07XG4gIH0pO1xufVxuIiwiZnVuY3Rpb24gX19zdG9wUHJvcGFnYXRpb24oZXZlbnQpIHtcbiAgaWYgKCFldmVudCB8fCB0eXBlb2YgZXZlbnQuc3RvcFByb3BhZ2F0aW9uICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9yaWdpbmFsKGV2ZW50KSB7XG4gIHJldHVybiBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50LnNyY0V2ZW50O1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBzdG9wUHJvcGFnYXRpb24oZXZlbnQsIGltbWVkaWF0ZSkge1xuICBfX3N0b3BQcm9wYWdhdGlvbihldmVudCwgaW1tZWRpYXRlKTtcbiAgX19zdG9wUHJvcGFnYXRpb24oZ2V0T3JpZ2luYWwoZXZlbnQpLCBpbW1lZGlhdGUpO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiB0b1BvaW50KGV2ZW50KSB7XG5cbiAgaWYgKGV2ZW50LnBvaW50ZXJzICYmIGV2ZW50LnBvaW50ZXJzLmxlbmd0aCkge1xuICAgIGV2ZW50ID0gZXZlbnQucG9pbnRlcnNbMF07XG4gIH1cblxuICBpZiAoZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzLmxlbmd0aCkge1xuICAgIGV2ZW50ID0gZXZlbnQudG91Y2hlc1swXTtcbiAgfVxuXG4gIHJldHVybiBldmVudCA/IHtcbiAgICB4OiBldmVudC5jbGllbnRYLFxuICAgIHk6IGV2ZW50LmNsaWVudFlcbiAgfSA6IG51bGw7XG59IiwiaW1wb3J0IHtcbiAgZXZlcnksXG4gIGlzQXJyYXlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHR3byBwb2ludHNcbiAqXG4gKiBAcGFyYW0gIHtQb2ludH0gIHBcbiAqIEBwYXJhbSAge1BvaW50fSAgcVxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gIGRpc3RhbmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb2ludERpc3RhbmNlKGEsIGIpIHtcbiAgaWYgKCFhIHx8ICFiKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgcmV0dXJuIE1hdGguc3FydChcbiAgICBNYXRoLnBvdyhhLnggLSBiLngsIDIpICtcbiAgICBNYXRoLnBvdyhhLnkgLSBiLnksIDIpXG4gICk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHBvaW50IHIgaXMgb24gdGhlIGxpbmUgYmV0d2VlbiBwIGFuZCBxXG4gKlxuICogQHBhcmFtICB7UG9pbnR9ICBwXG4gKiBAcGFyYW0gIHtQb2ludH0gIHFcbiAqIEBwYXJhbSAge1BvaW50fSAgclxuICogQHBhcmFtICB7bnVtYmVyfSBbYWNjdXJhY3k9NV0gYWNjdXJhY3kgZm9yIHBvaW50cyBvbiBsaW5lIGNoZWNrIChsb3dlciBpcyBiZXR0ZXIpXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvaW50c09uTGluZShwLCBxLCByLCBhY2N1cmFjeSkge1xuXG4gIGlmICh0eXBlb2YgYWNjdXJhY3kgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgYWNjdXJhY3kgPSA1O1xuICB9XG5cbiAgaWYgKCFwIHx8ICFxIHx8ICFyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIHZhbCA9IChxLnggLSBwLngpICogKHIueSAtIHAueSkgLSAocS55IC0gcC55KSAqIChyLnggLSBwLngpLFxuICAgICAgZGlzdCA9IHBvaW50RGlzdGFuY2UocCwgcSk7XG5cbiAgLy8gQHNlZSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS85MDc0OTEvNDEyMTkwXG4gIHJldHVybiBNYXRoLmFicyh2YWwgLyBkaXN0KSA8PSBhY2N1cmFjeTtcbn1cblxuXG52YXIgQUxJR05FRF9USFJFU0hPTEQgPSAyO1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdHdvIHBvaW50cyBhcmUgaG9yaXpvbnRhbGx5IG9yIHZlcnRpY2FsbHkgYWxpZ25lZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PFBvaW50PnxQb2ludH1cbiAqIEBwYXJhbSB7UG9pbnR9XG4gKlxuICogQHJldHVybiB7c3RyaW5nfGJvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb2ludHNBbGlnbmVkKGEsIGIpIHtcbiAgdmFyIHBvaW50cztcblxuICBpZiAoaXNBcnJheShhKSkge1xuICAgIHBvaW50cyA9IGE7XG4gIH0gZWxzZSB7XG4gICAgcG9pbnRzID0gWyBhLCBiIF07XG4gIH1cblxuICBpZiAocG9pbnRzQWxpZ25lZEhvcml6b250YWxseShwb2ludHMpKSB7XG4gICAgcmV0dXJuICdoJztcbiAgfVxuXG4gIGlmIChwb2ludHNBbGlnbmVkVmVydGljYWxseShwb2ludHMpKSB7XG4gICAgcmV0dXJuICd2JztcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBvaW50c0FsaWduZWRIb3Jpem9udGFsbHkoYSwgYikge1xuICB2YXIgcG9pbnRzO1xuXG4gIGlmIChpc0FycmF5KGEpKSB7XG4gICAgcG9pbnRzID0gYTtcbiAgfSBlbHNlIHtcbiAgICBwb2ludHMgPSBbIGEsIGIgXTtcbiAgfVxuXG4gIHZhciBmaXJzdFBvaW50ID0gcG9pbnRzLnNsaWNlKCkuc2hpZnQoKTtcblxuICByZXR1cm4gZXZlcnkocG9pbnRzLCBmdW5jdGlvbihwb2ludCkge1xuICAgIHJldHVybiBNYXRoLmFicyhmaXJzdFBvaW50LnkgLSBwb2ludC55KSA8PSBBTElHTkVEX1RIUkVTSE9MRDtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwb2ludHNBbGlnbmVkVmVydGljYWxseShhLCBiKSB7XG4gIHZhciBwb2ludHM7XG5cbiAgaWYgKGlzQXJyYXkoYSkpIHtcbiAgICBwb2ludHMgPSBhO1xuICB9IGVsc2Uge1xuICAgIHBvaW50cyA9IFsgYSwgYiBdO1xuICB9XG5cbiAgdmFyIGZpcnN0UG9pbnQgPSBwb2ludHMuc2xpY2UoKS5zaGlmdCgpO1xuXG4gIHJldHVybiBldmVyeShwb2ludHMsIGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgcmV0dXJuIE1hdGguYWJzKGZpcnN0UG9pbnQueCAtIHBvaW50LngpIDw9IEFMSUdORURfVEhSRVNIT0xEO1xuICB9KTtcbn1cblxuXG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBwb2ludCBwIGlzIGluc2lkZSB0aGUgcmVjdGFuZ2xlIHJlY3RcbiAqXG4gKiBAcGFyYW0gIHtQb2ludH0gIHBcbiAqIEBwYXJhbSAge1JlY3R9IHJlY3RcbiAqIEBwYXJhbSAge251bWJlcn0gdG9sZXJhbmNlXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvaW50SW5SZWN0KHAsIHJlY3QsIHRvbGVyYW5jZSkge1xuICB0b2xlcmFuY2UgPSB0b2xlcmFuY2UgfHwgMDtcblxuICByZXR1cm4gcC54ID4gcmVjdC54IC0gdG9sZXJhbmNlICYmXG4gICAgICAgICBwLnkgPiByZWN0LnkgLSB0b2xlcmFuY2UgJiZcbiAgICAgICAgIHAueCA8IHJlY3QueCArIHJlY3Qud2lkdGggKyB0b2xlcmFuY2UgJiZcbiAgICAgICAgIHAueSA8IHJlY3QueSArIHJlY3QuaGVpZ2h0ICsgdG9sZXJhbmNlO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBwb2ludCBpbiB0aGUgbWlkZGxlIG9mIHBvaW50cyBwIGFuZCBxXG4gKlxuICogQHBhcmFtICB7UG9pbnR9ICBwXG4gKiBAcGFyYW0gIHtQb2ludH0gIHFcbiAqXG4gKiBAcmV0dXJuIHtQb2ludH0gbWlkZGxlIHBvaW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNaWRQb2ludChwLCBxKSB7XG4gIHJldHVybiB7XG4gICAgeDogTWF0aC5yb3VuZChwLnggKyAoKHEueCAtIHAueCkgLyAyLjApKSxcbiAgICB5OiBNYXRoLnJvdW5kKHAueSArICgocS55IC0gcC55KSAvIDIuMCkpXG4gIH07XG59XG4iLCIvKipcbiAqIFNWR3MgZm9yIGVsZW1lbnRzIGFyZSBnZW5lcmF0ZWQgYnkgdGhlIHtAbGluayBHcmFwaGljc0ZhY3Rvcnl9LlxuICpcbiAqIFRoaXMgdXRpbGl0eSBnaXZlcyBxdWljayBhY2Nlc3MgdG8gdGhlIGltcG9ydGFudCBzZW1hbnRpY1xuICogcGFydHMgb2YgYW4gZWxlbWVudC5cbiAqL1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHZpc3VhbCBwYXJ0IG9mIGEgZGlhZ3JhbSBlbGVtZW50XG4gKlxuICogQHBhcmFtIHtTbmFwPFNWR0VsZW1lbnQ+fSBnZnhcbiAqXG4gKiBAcmV0dXJuIHtTbmFwPFNWR0VsZW1lbnQ+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmlzdWFsKGdmeCkge1xuICByZXR1cm4gZ2Z4LmNoaWxkTm9kZXNbMF07XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY2hpbGRyZW4gZm9yIGEgZ2l2ZW4gZGlhZ3JhbSBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7U25hcDxTVkdFbGVtZW50Pn0gZ2Z4XG4gKiBAcmV0dXJuIHtTbmFwPFNWR0VsZW1lbnQ+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2hpbGRyZW4oZ2Z4KSB7XG4gIHJldHVybiBnZngucGFyZW50Tm9kZS5jaGlsZE5vZGVzWzFdO1xufSIsIi8qKlxuICogVXRpbCB0aGF0IHByb3ZpZGVzIHVuaXF1ZSBJRHMuXG4gKlxuICogQGNsYXNzIGRqcy51dGlsLklkR2VuZXJhdG9yXG4gKiBAY29uc3RydWN0b3JcbiAqIEBtZW1iZXJPZiBkanMudXRpbFxuICpcbiAqIFRoZSBpZHMgY2FuIGJlIGN1c3RvbWl6ZWQgdmlhIGEgZ2l2ZW4gcHJlZml4IGFuZCBjb250YWluIGEgcmFuZG9tIHZhbHVlIHRvIGF2b2lkIGNvbGxpc2lvbnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHByZWZpeCBhIHByZWZpeCB0byBwcmVwZW5kIHRvIGdlbmVyYXRlZCBpZHMgKGZvciBiZXR0ZXIgcmVhZGFiaWxpdHkpXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIElkR2VuZXJhdG9yKHByZWZpeCkge1xuXG4gIHRoaXMuX2NvdW50ZXIgPSAwO1xuICB0aGlzLl9wcmVmaXggPSAocHJlZml4ID8gcHJlZml4ICsgJy0nIDogJycpICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMDAwMDAwMCkgKyAnLSc7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIG5leHQgdW5pcXVlIElELlxuICpcbiAqIEBtZXRob2QgZGpzLnV0aWwuSWRHZW5lcmF0b3IjbmV4dFxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSBpZFxuICovXG5JZEdlbmVyYXRvci5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fcHJlZml4ICsgKCsrdGhpcy5fY291bnRlcik7XG59O1xuIiwiaW1wb3J0IHtcbiAgcG9pbnREaXN0YW5jZVxufSBmcm9tICcuL0dlb21ldHJ5JztcblxuaW1wb3J0IGludGVyc2VjdFBhdGhzIGZyb20gJ3BhdGgtaW50ZXJzZWN0aW9uJztcblxudmFyIHJvdW5kID0gTWF0aC5yb3VuZCxcbiAgICBtYXggPSBNYXRoLm1heDtcblxuXG5mdW5jdGlvbiBjaXJjbGVQYXRoKGNlbnRlciwgcikge1xuICB2YXIgeCA9IGNlbnRlci54LFxuICAgICAgeSA9IGNlbnRlci55O1xuXG4gIHJldHVybiBbXG4gICAgWydNJywgeCwgeV0sXG4gICAgWydtJywgMCwgLXJdLFxuICAgIFsnYScsIHIsIHIsIDAsIDEsIDEsIDAsIDIgKiByXSxcbiAgICBbJ2EnLCByLCByLCAwLCAxLCAxLCAwLCAtMiAqIHJdLFxuICAgIFsneiddXG4gIF07XG59XG5cbmZ1bmN0aW9uIGxpbmVQYXRoKHBvaW50cykge1xuICB2YXIgc2VnbWVudHMgPSBbXTtcblxuICBwb2ludHMuZm9yRWFjaChmdW5jdGlvbihwLCBpZHgpIHtcbiAgICBzZWdtZW50cy5wdXNoKFsgaWR4ID09PSAwID8gJ00nIDogJ0wnLCBwLngsIHAueSBdKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHNlZ21lbnRzO1xufVxuXG5cbnZhciBJTlRFUlNFQ1RJT05fVEhSRVNIT0xEID0gMTA7XG5cbmZ1bmN0aW9uIGdldEJlbmRwb2ludEludGVyc2VjdGlvbih3YXlwb2ludHMsIHJlZmVyZW5jZSkge1xuXG4gIHZhciBpLCB3O1xuXG4gIGZvciAoaSA9IDA7ICh3ID0gd2F5cG9pbnRzW2ldKTsgaSsrKSB7XG5cbiAgICBpZiAocG9pbnREaXN0YW5jZSh3LCByZWZlcmVuY2UpIDw9IElOVEVSU0VDVElPTl9USFJFU0hPTEQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBvaW50OiB3YXlwb2ludHNbaV0sXG4gICAgICAgIGJlbmRwb2ludDogdHJ1ZSxcbiAgICAgICAgaW5kZXg6IGlcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldFBhdGhJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCByZWZlcmVuY2UpIHtcblxuICB2YXIgaW50ZXJzZWN0aW9ucyA9IGludGVyc2VjdFBhdGhzKGNpcmNsZVBhdGgocmVmZXJlbmNlLCBJTlRFUlNFQ1RJT05fVEhSRVNIT0xEKSwgbGluZVBhdGgod2F5cG9pbnRzKSk7XG5cbiAgdmFyIGEgPSBpbnRlcnNlY3Rpb25zWzBdLFxuICAgICAgYiA9IGludGVyc2VjdGlvbnNbaW50ZXJzZWN0aW9ucy5sZW5ndGggLSAxXSxcbiAgICAgIGlkeDtcblxuICBpZiAoIWEpIHtcblxuICAgIC8vIG5vIGludGVyc2VjdGlvblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGEgIT09IGIpIHtcblxuICAgIGlmIChhLnNlZ21lbnQyICE9PSBiLnNlZ21lbnQyKSB7XG5cbiAgICAgIC8vIHdlIHVzZSB0aGUgYmVuZHBvaW50IGluIGJldHdlZW4gYm90aCBzZWdtZW50c1xuICAgICAgLy8gYXMgdGhlIGludGVyc2VjdGlvbiBwb2ludFxuXG4gICAgICBpZHggPSBtYXgoYS5zZWdtZW50MiwgYi5zZWdtZW50MikgLSAxO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBwb2ludDogd2F5cG9pbnRzW2lkeF0sXG4gICAgICAgIGJlbmRwb2ludDogdHJ1ZSxcbiAgICAgICAgaW5kZXg6IGlkeFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcG9pbnQ6IHtcbiAgICAgICAgeDogKHJvdW5kKGEueCArIGIueCkgLyAyKSxcbiAgICAgICAgeTogKHJvdW5kKGEueSArIGIueSkgLyAyKVxuICAgICAgfSxcbiAgICAgIGluZGV4OiBhLnNlZ21lbnQyXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgcG9pbnQ6IHtcbiAgICAgIHg6IHJvdW5kKGEueCksXG4gICAgICB5OiByb3VuZChhLnkpXG4gICAgfSxcbiAgICBpbmRleDogYS5zZWdtZW50MlxuICB9O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGNsb3Nlc3QgcG9pbnQgb24gdGhlIGNvbm5lY3Rpb24gdG93YXJkcyBhIGdpdmVuIHJlZmVyZW5jZSBwb2ludC5cbiAqXG4gKiBAcGFyYW0gIHtBcnJheTxQb2ludD59IHdheXBvaW50c1xuICogQHBhcmFtICB7UG9pbnR9IHJlZmVyZW5jZVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gaW50ZXJzZWN0aW9uIGRhdGEgKHNlZ21lbnQsIHBvaW50KVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXBwcm94SW50ZXJzZWN0aW9uKHdheXBvaW50cywgcmVmZXJlbmNlKSB7XG4gIHJldHVybiBnZXRCZW5kcG9pbnRJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCByZWZlcmVuY2UpIHx8IGdldFBhdGhJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCByZWZlcmVuY2UpO1xufVxuIiwiLyoqXG4gKiBHZXQgdGhlIGxvZ2FyaXRobSBvZiB4IHdpdGggYmFzZSAxMFxuICogQHBhcmFtICB7SW50ZWdlcn0gdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZzEwKHgpIHtcbiAgcmV0dXJuIE1hdGgubG9nKHgpIC8gTWF0aC5sb2coMTApO1xufVxuXG5leHBvcnQgeyBkZWx0YSBhcyBzdWJzdHJhY3QgfSBmcm9tICcuL1Bvc2l0aW9uVXRpbCc7XG4iLCJpbXBvcnQge1xuICBnZXRPcmlnaW5hbCBhcyBnZXRPcmlnaW5hbEV2ZW50XG59IGZyb20gJy4vRXZlbnQnO1xuXG5pbXBvcnQge1xuICBpc01hY1xufSBmcm9tICcuL1BsYXRmb3JtJztcblxuZXhwb3J0IHtcbiAgaXNNYWNcbn0gZnJvbSAnLi9QbGF0Zm9ybSc7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUHJpbWFyeUJ1dHRvbihldmVudCkge1xuXG4gIC8vIGJ1dHRvbiA9PT0gMCAtPiBsZWZ0IMOha2EgcHJpbWFyeSBtb3VzZSBidXR0b25cbiAgcmV0dXJuICEoZ2V0T3JpZ2luYWxFdmVudChldmVudCkgfHwgZXZlbnQpLmJ1dHRvbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1ByaW1hcnlNb2RpZmllcihldmVudCkge1xuICB2YXIgb3JpZ2luYWxFdmVudCA9IGdldE9yaWdpbmFsRXZlbnQoZXZlbnQpIHx8IGV2ZW50O1xuXG4gIGlmICghaXNQcmltYXJ5QnV0dG9uKGV2ZW50KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFVzZSBhbHQgYXMgcHJpbWFyeSBtb2RpZmllciBrZXkgZm9yIG1hYyBPU1xuICBpZiAoaXNNYWMoKSkge1xuICAgIHJldHVybiBvcmlnaW5hbEV2ZW50Lm1ldGFLZXk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9yaWdpbmFsRXZlbnQuY3RybEtleTtcbiAgfVxufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNTZWNvbmRhcnlNb2RpZmllcihldmVudCkge1xuICB2YXIgb3JpZ2luYWxFdmVudCA9IGdldE9yaWdpbmFsRXZlbnQoZXZlbnQpIHx8IGV2ZW50O1xuXG4gIHJldHVybiBpc1ByaW1hcnlCdXR0b24oZXZlbnQpICYmIG9yaWdpbmFsRXZlbnQuc2hpZnRLZXk7XG59IiwiZXhwb3J0IGZ1bmN0aW9uIGlzTWFjKCkge1xuICByZXR1cm4gKC9tYWMvaSkudGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pO1xufSIsImV4cG9ydCBmdW5jdGlvbiBjZW50ZXIoYm91bmRzKSB7XG4gIHJldHVybiB7XG4gICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIC8gMiksXG4gICAgeTogYm91bmRzLnkgKyAoYm91bmRzLmhlaWdodCAvIDIpXG4gIH07XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGRlbHRhKGEsIGIpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBhLnggLSBiLngsXG4gICAgeTogYS55IC0gYi55XG4gIH07XG59IiwiLyoqXG4gKiBSZW1vdmUgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIGEgY29sbGVjdGlvbiB1bnRpbCBpdCBpcyBlbXB0eS5cbiAqXG4gKiBUaGlzIGlzIGEgbnVsbC1zYWZlIG9wZXJhdGlvbiB0aGF0IGVuc3VyZXMgZWxlbWVudHNcbiAqIGFyZSBiZWluZyByZW1vdmVkIGZyb20gdGhlIGdpdmVuIGNvbGxlY3Rpb24gdW50aWwgdGhlXG4gKiBjb2xsZWN0aW9uIGlzIGVtcHR5LlxuICpcbiAqIFRoZSBpbXBsZW1lbnRhdGlvbiBkZWFscyB3aXRoIHRoZSBmYWN0IHRoYXQgYSByZW1vdmUgb3BlcmF0aW9uXG4gKiBtYXkgdG91Y2gsIGkuZS4gcmVtb3ZlIG11bHRpcGxlIGVsZW1lbnRzIGluIHRoZSBjb2xsZWN0aW9uXG4gKiBhdCBhIHRpbWUuXG4gKlxuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBbY29sbGVjdGlvbl1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHJlbW92ZUZuXG4gKlxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn0gdGhlIGNsZWFyZWQgY29sbGVjdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gc2F2ZUNsZWFyKGNvbGxlY3Rpb24sIHJlbW92ZUZuKSB7XG5cbiAgaWYgKHR5cGVvZiByZW1vdmVGbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcigncmVtb3ZlRm4gaXRlcmF0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAoIWNvbGxlY3Rpb24pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZTtcblxuICB3aGlsZSAoKGUgPSBjb2xsZWN0aW9uWzBdKSkge1xuICAgIHJlbW92ZUZuKGUpO1xuICB9XG5cbiAgcmV0dXJuIGNvbGxlY3Rpb247XG59XG4iLCJpbXBvcnQge1xuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wb25lbnRzVG9QYXRoKGVsZW1lbnRzKSB7XG4gIHJldHVybiBlbGVtZW50cy5qb2luKCcsJykucmVwbGFjZSgvLD8oW0Etel0pLD8vZywgJyQxJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b1NWR1BvaW50cyhwb2ludHMpIHtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuXG4gIGZvciAodmFyIGkgPSAwLCBwOyAocCA9IHBvaW50c1tpXSk7IGkrKykge1xuICAgIHJlc3VsdCArPSBwLnggKyAnLCcgKyBwLnkgKyAnICc7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTGluZShwb2ludHMsIGF0dHJzKSB7XG5cbiAgdmFyIGxpbmUgPSBzdmdDcmVhdGUoJ3BvbHlsaW5lJyk7XG4gIHN2Z0F0dHIobGluZSwgeyBwb2ludHM6IHRvU1ZHUG9pbnRzKHBvaW50cykgfSk7XG5cbiAgaWYgKGF0dHJzKSB7XG4gICAgc3ZnQXR0cihsaW5lLCBhdHRycyk7XG4gIH1cblxuICByZXR1cm4gbGluZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUxpbmUoZ2Z4LCBwb2ludHMpIHtcbiAgc3ZnQXR0cihnZngsIHsgcG9pbnRzOiB0b1NWR1BvaW50cyhwb2ludHMpIH0pO1xuXG4gIHJldHVybiBnZng7XG59XG4iLCJpbXBvcnQge1xyXG4gIHRyYW5zZm9ybSBhcyBzdmdUcmFuc2Zvcm0sXHJcbiAgY3JlYXRlVHJhbnNmb3JtXHJcbn0gZnJvbSAndGlueS1zdmcnO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0gezxTVkdFbGVtZW50Pn0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge251bWJlcn0geFxyXG4gKiBAcGFyYW0ge251bWJlcn0geVxyXG4gKiBAcGFyYW0ge251bWJlcn0gYW5nbGVcclxuICogQHBhcmFtIHtudW1iZXJ9IGFtb3VudFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybShnZngsIHgsIHksIGFuZ2xlLCBhbW91bnQpIHtcclxuICB2YXIgdHJhbnNsYXRlID0gY3JlYXRlVHJhbnNmb3JtKCk7XHJcbiAgdHJhbnNsYXRlLnNldFRyYW5zbGF0ZSh4LCB5KTtcclxuXHJcbiAgdmFyIHJvdGF0ZSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xyXG4gIHJvdGF0ZS5zZXRSb3RhdGUoYW5nbGUgfHwgMCwgMCwgMCk7XHJcblxyXG4gIHZhciBzY2FsZSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xyXG4gIHNjYWxlLnNldFNjYWxlKGFtb3VudCB8fCAxLCBhbW91bnQgfHwgMSk7XHJcblxyXG4gIHN2Z1RyYW5zZm9ybShnZngsIFsgdHJhbnNsYXRlLCByb3RhdGUsIHNjYWxlIF0pO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge251bWJlcn0geFxyXG4gKiBAcGFyYW0ge251bWJlcn0geVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zbGF0ZShnZngsIHgsIHkpIHtcclxuICB2YXIgdHJhbnNsYXRlID0gY3JlYXRlVHJhbnNmb3JtKCk7XHJcbiAgdHJhbnNsYXRlLnNldFRyYW5zbGF0ZSh4LCB5KTtcclxuXHJcbiAgc3ZnVHJhbnNmb3JtKGdmeCwgdHJhbnNsYXRlKTtcclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGVsZW1lbnRcclxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlKGdmeCwgYW5nbGUpIHtcclxuICB2YXIgcm90YXRlID0gY3JlYXRlVHJhbnNmb3JtKCk7XHJcbiAgcm90YXRlLnNldFJvdGF0ZShhbmdsZSwgMCwgMCk7XHJcblxyXG4gIHN2Z1RyYW5zZm9ybShnZngsIHJvdGF0ZSk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzY2FsZShnZngsIGFtb3VudCkge1xyXG4gIHZhciBzY2FsZSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xyXG4gIHNjYWxlLnNldFNjYWxlKGFtb3VudCwgYW1vdW50KTtcclxuXHJcbiAgc3ZnVHJhbnNmb3JtKGdmeCwgc2NhbGUpO1xyXG59IiwiaW1wb3J0IHtcbiAgaXNPYmplY3QsXG4gIGFzc2lnbixcbiAgZm9yRWFjaCxcbiAgcmVkdWNlXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICByZW1vdmUgYXMgc3ZnUmVtb3ZlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxudmFyIERFRkFVTFRfQk9YX1BBRERJTkcgPSAwO1xuXG52YXIgREVGQVVMVF9MQUJFTF9TSVpFID0ge1xuICB3aWR0aDogMTUwLFxuICBoZWlnaHQ6IDUwXG59O1xuXG5cbmZ1bmN0aW9uIHBhcnNlQWxpZ24oYWxpZ24pIHtcblxuICB2YXIgcGFydHMgPSBhbGlnbi5zcGxpdCgnLScpO1xuXG4gIHJldHVybiB7XG4gICAgaG9yaXpvbnRhbDogcGFydHNbMF0gfHwgJ2NlbnRlcicsXG4gICAgdmVydGljYWw6IHBhcnRzWzFdIHx8ICd0b3AnXG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhcnNlUGFkZGluZyhwYWRkaW5nKSB7XG5cbiAgaWYgKGlzT2JqZWN0KHBhZGRpbmcpKSB7XG4gICAgcmV0dXJuIGFzc2lnbih7IHRvcDogMCwgbGVmdDogMCwgcmlnaHQ6IDAsIGJvdHRvbTogMCB9LCBwYWRkaW5nKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgdG9wOiBwYWRkaW5nLFxuICAgICAgbGVmdDogcGFkZGluZyxcbiAgICAgIHJpZ2h0OiBwYWRkaW5nLFxuICAgICAgYm90dG9tOiBwYWRkaW5nXG4gICAgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRUZXh0QkJveCh0ZXh0LCBmYWtlVGV4dCkge1xuXG4gIGZha2VUZXh0LnRleHRDb250ZW50ID0gdGV4dDtcblxuICB2YXIgdGV4dEJCb3g7XG5cbiAgdHJ5IHtcbiAgICB2YXIgYmJveCxcbiAgICAgICAgZW1wdHlMaW5lID0gdGV4dCA9PT0gJyc7XG5cbiAgICAvLyBhZGQgZHVtbXkgdGV4dCwgd2hlbiBsaW5lIGlzIGVtcHR5IHRvXG4gICAgLy8gZGV0ZXJtaW5lIGNvcnJlY3QgaGVpZ2h0XG4gICAgZmFrZVRleHQudGV4dENvbnRlbnQgPSBlbXB0eUxpbmUgPyAnZHVtbXknIDogdGV4dDtcblxuICAgIHRleHRCQm94ID0gZmFrZVRleHQuZ2V0QkJveCgpO1xuXG4gICAgLy8gdGFrZSB0ZXh0IHJlbmRlcmluZyByZWxhdGVkIGhvcml6b250YWxcbiAgICAvLyBwYWRkaW5nIGludG8gYWNjb3VudFxuICAgIGJib3ggPSB7XG4gICAgICB3aWR0aDogdGV4dEJCb3gud2lkdGggKyB0ZXh0QkJveC54ICogMixcbiAgICAgIGhlaWdodDogdGV4dEJCb3guaGVpZ2h0XG4gICAgfTtcblxuICAgIGlmIChlbXB0eUxpbmUpIHtcblxuICAgICAgLy8gY29ycmVjdCB3aWR0aFxuICAgICAgYmJveC53aWR0aCA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJib3g7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4geyB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XG4gIH1cbn1cblxuXG4vKipcbiAqIExheW91dCB0aGUgbmV4dCBsaW5lIGFuZCByZXR1cm4gdGhlIGxheW91dGVkIGVsZW1lbnQuXG4gKlxuICogQWx0ZXJzIHRoZSBsaW5lcyBwYXNzZWQuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8c3RyaW5nPn0gbGluZXNcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIGxpbmUgZGVzY3JpcHRvciwgYW4gb2JqZWN0IHsgd2lkdGgsIGhlaWdodCwgdGV4dCB9XG4gKi9cbmZ1bmN0aW9uIGxheW91dE5leHQobGluZXMsIG1heFdpZHRoLCBmYWtlVGV4dCkge1xuXG4gIHZhciBvcmlnaW5hbExpbmUgPSBsaW5lcy5zaGlmdCgpLFxuICAgICAgZml0TGluZSA9IG9yaWdpbmFsTGluZTtcblxuICB2YXIgdGV4dEJCb3g7XG5cbiAgZm9yICg7Oykge1xuICAgIHRleHRCQm94ID0gZ2V0VGV4dEJCb3goZml0TGluZSwgZmFrZVRleHQpO1xuXG4gICAgdGV4dEJCb3gud2lkdGggPSBmaXRMaW5lID8gdGV4dEJCb3gud2lkdGggOiAwO1xuXG4gICAgLy8gdHJ5IHRvIGZpdFxuICAgIGlmIChmaXRMaW5lID09PSAnICcgfHwgZml0TGluZSA9PT0gJycgfHwgdGV4dEJCb3gud2lkdGggPCBNYXRoLnJvdW5kKG1heFdpZHRoKSB8fCBmaXRMaW5lLmxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybiBmaXQobGluZXMsIGZpdExpbmUsIG9yaWdpbmFsTGluZSwgdGV4dEJCb3gpO1xuICAgIH1cblxuICAgIGZpdExpbmUgPSBzaG9ydGVuTGluZShmaXRMaW5lLCB0ZXh0QkJveC53aWR0aCwgbWF4V2lkdGgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpdChsaW5lcywgZml0TGluZSwgb3JpZ2luYWxMaW5lLCB0ZXh0QkJveCkge1xuICBpZiAoZml0TGluZS5sZW5ndGggPCBvcmlnaW5hbExpbmUubGVuZ3RoKSB7XG4gICAgdmFyIHJlbWFpbmRlciA9IG9yaWdpbmFsTGluZS5zbGljZShmaXRMaW5lLmxlbmd0aCkudHJpbSgpO1xuXG4gICAgbGluZXMudW5zaGlmdChyZW1haW5kZXIpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogdGV4dEJCb3gud2lkdGgsXG4gICAgaGVpZ2h0OiB0ZXh0QkJveC5oZWlnaHQsXG4gICAgdGV4dDogZml0TGluZVxuICB9O1xufVxuXG5cbi8qKlxuICogU2hvcnRlbnMgYSBsaW5lIGJhc2VkIG9uIHNwYWNpbmcgYW5kIGh5cGhlbnMuXG4gKiBSZXR1cm5zIHRoZSBzaG9ydGVuZWQgcmVzdWx0IG9uIHN1Y2Nlc3MuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBsaW5lXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1heExlbmd0aCB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIG9mIHRoZSBzdHJpbmdcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIHNob3J0ZW5lZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gc2VtYW50aWNTaG9ydGVuKGxpbmUsIG1heExlbmd0aCkge1xuICB2YXIgcGFydHMgPSBsaW5lLnNwbGl0KC8oXFxzfC0pL2cpLFxuICAgICAgcGFydCxcbiAgICAgIHNob3J0ZW5lZFBhcnRzID0gW10sXG4gICAgICBsZW5ndGggPSAwO1xuXG4gIC8vIHRyeSB0byBzaG9ydGVuIHZpYSBzcGFjZXMgKyBoeXBoZW5zXG4gIGlmIChwYXJ0cy5sZW5ndGggPiAxKSB7XG4gICAgd2hpbGUgKChwYXJ0ID0gcGFydHMuc2hpZnQoKSkpIHtcbiAgICAgIGlmIChwYXJ0Lmxlbmd0aCArIGxlbmd0aCA8IG1heExlbmd0aCkge1xuICAgICAgICBzaG9ydGVuZWRQYXJ0cy5wdXNoKHBhcnQpO1xuICAgICAgICBsZW5ndGggKz0gcGFydC5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIC8vIHJlbW92ZSBwcmV2aW91cyBwYXJ0LCB0b28gaWYgaHlwaGVuIGRvZXMgbm90IGZpdCBhbnltb3JlXG4gICAgICAgIGlmIChwYXJ0ID09PSAnLScpIHtcbiAgICAgICAgICBzaG9ydGVuZWRQYXJ0cy5wb3AoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzaG9ydGVuZWRQYXJ0cy5qb2luKCcnKTtcbn1cblxuXG5mdW5jdGlvbiBzaG9ydGVuTGluZShsaW5lLCB3aWR0aCwgbWF4V2lkdGgpIHtcbiAgdmFyIGxlbmd0aCA9IE1hdGgubWF4KGxpbmUubGVuZ3RoICogKG1heFdpZHRoIC8gd2lkdGgpLCAxKTtcblxuICAvLyB0cnkgdG8gc2hvcnRlbiBzZW1hbnRpY2FsbHkgKGkuZS4gYmFzZWQgb24gc3BhY2VzIGFuZCBoeXBoZW5zKVxuICB2YXIgc2hvcnRlbmVkTGluZSA9IHNlbWFudGljU2hvcnRlbihsaW5lLCBsZW5ndGgpO1xuXG4gIGlmICghc2hvcnRlbmVkTGluZSkge1xuXG4gICAgLy8gZm9yY2Ugc2hvcnRlbiBieSBjdXR0aW5nIHRoZSBsb25nIHdvcmRcbiAgICBzaG9ydGVuZWRMaW5lID0gbGluZS5zbGljZSgwLCBNYXRoLm1heChNYXRoLnJvdW5kKGxlbmd0aCAtIDEpLCAxKSk7XG4gIH1cblxuICByZXR1cm4gc2hvcnRlbmVkTGluZTtcbn1cblxuXG5mdW5jdGlvbiBnZXRIZWxwZXJTdmcoKSB7XG4gIHZhciBoZWxwZXJTdmcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVscGVyLXN2ZycpO1xuXG4gIGlmICghaGVscGVyU3ZnKSB7XG4gICAgaGVscGVyU3ZnID0gc3ZnQ3JlYXRlKCdzdmcnKTtcblxuICAgIHN2Z0F0dHIoaGVscGVyU3ZnLCB7XG4gICAgICBpZDogJ2hlbHBlci1zdmcnLFxuICAgICAgd2lkdGg6IDAsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBzdHlsZTogJ3Zpc2liaWxpdHk6IGhpZGRlbjsgcG9zaXRpb246IGZpeGVkJ1xuICAgIH0pO1xuXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChoZWxwZXJTdmcpO1xuICB9XG5cbiAgcmV0dXJuIGhlbHBlclN2Zztcbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgbGFiZWwgdXRpbGl0eVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWdcbiAqIEBwYXJhbSB7RGltZW5zaW9uc30gY29uZmlnLnNpemVcbiAqIEBwYXJhbSB7bnVtYmVyfSBjb25maWcucGFkZGluZ1xuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZy5zdHlsZVxuICogQHBhcmFtIHtzdHJpbmd9IGNvbmZpZy5hbGlnblxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBUZXh0KGNvbmZpZykge1xuXG4gIHRoaXMuX2NvbmZpZyA9IGFzc2lnbih7fSwge1xuICAgIHNpemU6IERFRkFVTFRfTEFCRUxfU0laRSxcbiAgICBwYWRkaW5nOiBERUZBVUxUX0JPWF9QQURESU5HLFxuICAgIHN0eWxlOiB7fSxcbiAgICBhbGlnbjogJ2NlbnRlci10b3AnXG4gIH0sIGNvbmZpZyB8fCB7fSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbGF5b3V0ZWQgdGV4dCBhcyBhbiBTVkcgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqXG4gKiBAcmV0dXJuIHtTVkdFbGVtZW50fVxuICovXG5UZXh0LnByb3RvdHlwZS5jcmVhdGVUZXh0ID0gZnVuY3Rpb24odGV4dCwgb3B0aW9ucykge1xuICByZXR1cm4gdGhpcy5sYXlvdXRUZXh0KHRleHQsIG9wdGlvbnMpLmVsZW1lbnQ7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBsYWJlbHMgbGF5b3V0ZWQgZGltZW5zaW9ucy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCB0byBsYXlvdXRcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKlxuICogQHJldHVybiB7RGltZW5zaW9uc31cbiAqL1xuVGV4dC5wcm90b3R5cGUuZ2V0RGltZW5zaW9ucyA9IGZ1bmN0aW9uKHRleHQsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHRoaXMubGF5b3V0VGV4dCh0ZXh0LCBvcHRpb25zKS5kaW1lbnNpb25zO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuZCByZXR1cm5zIGEgbGFiZWwgYW5kIGl0cyBib3VuZGluZyBib3guXG4gKlxuICogQG1ldGhvZCBUZXh0I2NyZWF0ZVRleHRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCB0aGUgdGV4dCB0byByZW5kZXIgb24gdGhlIGxhYmVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMuYWxpZ24gaG93IHRvIGFsaWduIGluIHRoZSBib3VuZGluZyBib3guXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbnkgb2YgeyAnY2VudGVyLW1pZGRsZScsICdjZW50ZXItdG9wJyB9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHMgdG8gJ2NlbnRlci10b3AnLlxuICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMuc3R5bGUgc3R5bGUgdG8gYmUgYXBwbGllZCB0byB0aGUgdGV4dFxuICogQHBhcmFtIHtib29sZWFufSBvcHRpb25zLmZpdEJveCBpbmRpY2F0ZXMgaWYgYm94IHdpbGwgYmUgcmVjYWxjdWxhdGVkIHRvXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpdCB0ZXh0XG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB7IGVsZW1lbnQsIGRpbWVuc2lvbnMgfVxuICovXG5UZXh0LnByb3RvdHlwZS5sYXlvdXRUZXh0ID0gZnVuY3Rpb24odGV4dCwgb3B0aW9ucykge1xuICB2YXIgYm94ID0gYXNzaWduKHt9LCB0aGlzLl9jb25maWcuc2l6ZSwgb3B0aW9ucy5ib3gpLFxuICAgICAgc3R5bGUgPSBhc3NpZ24oe30sIHRoaXMuX2NvbmZpZy5zdHlsZSwgb3B0aW9ucy5zdHlsZSksXG4gICAgICBhbGlnbiA9IHBhcnNlQWxpZ24ob3B0aW9ucy5hbGlnbiB8fCB0aGlzLl9jb25maWcuYWxpZ24pLFxuICAgICAgcGFkZGluZyA9IHBhcnNlUGFkZGluZyhvcHRpb25zLnBhZGRpbmcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucGFkZGluZyA6IHRoaXMuX2NvbmZpZy5wYWRkaW5nKSxcbiAgICAgIGZpdEJveCA9IG9wdGlvbnMuZml0Qm94IHx8IGZhbHNlO1xuXG4gIHZhciBsaW5lSGVpZ2h0ID0gZ2V0TGluZUhlaWdodChzdHlsZSk7XG5cbiAgdmFyIGxpbmVzID0gdGV4dC5zcGxpdCgvXFxyP1xcbi9nKSxcbiAgICAgIGxheW91dGVkID0gW107XG5cbiAgdmFyIG1heFdpZHRoID0gYm94LndpZHRoIC0gcGFkZGluZy5sZWZ0IC0gcGFkZGluZy5yaWdodDtcblxuICAvLyBlbnN1cmUgY29ycmVjdCByZW5kZXJpbmcgYnkgYXR0YWNoaW5nIGhlbHBlciB0ZXh0IG5vZGUgdG8gaW52aXNpYmxlIFNWR1xuICB2YXIgaGVscGVyVGV4dCA9IHN2Z0NyZWF0ZSgndGV4dCcpO1xuICBzdmdBdHRyKGhlbHBlclRleHQsIHsgeDogMCwgeTogMCB9KTtcbiAgc3ZnQXR0cihoZWxwZXJUZXh0LCBzdHlsZSk7XG5cbiAgdmFyIGhlbHBlclN2ZyA9IGdldEhlbHBlclN2ZygpO1xuXG4gIHN2Z0FwcGVuZChoZWxwZXJTdmcsIGhlbHBlclRleHQpO1xuXG4gIHdoaWxlIChsaW5lcy5sZW5ndGgpIHtcbiAgICBsYXlvdXRlZC5wdXNoKGxheW91dE5leHQobGluZXMsIG1heFdpZHRoLCBoZWxwZXJUZXh0KSk7XG4gIH1cblxuICBpZiAoYWxpZ24udmVydGljYWwgPT09ICdtaWRkbGUnKSB7XG4gICAgcGFkZGluZy50b3AgPSBwYWRkaW5nLmJvdHRvbSA9IDA7XG4gIH1cblxuICB2YXIgdG90YWxIZWlnaHQgPSByZWR1Y2UobGF5b3V0ZWQsIGZ1bmN0aW9uKHN1bSwgbGluZSwgaWR4KSB7XG4gICAgcmV0dXJuIHN1bSArIChsaW5lSGVpZ2h0IHx8IGxpbmUuaGVpZ2h0KTtcbiAgfSwgMCkgKyBwYWRkaW5nLnRvcCArIHBhZGRpbmcuYm90dG9tO1xuXG4gIHZhciBtYXhMaW5lV2lkdGggPSByZWR1Y2UobGF5b3V0ZWQsIGZ1bmN0aW9uKHN1bSwgbGluZSwgaWR4KSB7XG4gICAgcmV0dXJuIGxpbmUud2lkdGggPiBzdW0gPyBsaW5lLndpZHRoIDogc3VtO1xuICB9LCAwKTtcblxuICAvLyB0aGUgeSBwb3NpdGlvbiBvZiB0aGUgbmV4dCBsaW5lXG4gIHZhciB5ID0gcGFkZGluZy50b3A7XG5cbiAgaWYgKGFsaWduLnZlcnRpY2FsID09PSAnbWlkZGxlJykge1xuICAgIHkgKz0gKGJveC5oZWlnaHQgLSB0b3RhbEhlaWdodCkgLyAyO1xuICB9XG5cbiAgLy8gbWFnaWMgbnVtYmVyIGluaXRpYWwgb2Zmc2V0XG4gIHkgLT0gKGxpbmVIZWlnaHQgfHwgbGF5b3V0ZWRbMF0uaGVpZ2h0KSAvIDQ7XG5cblxuICB2YXIgdGV4dEVsZW1lbnQgPSBzdmdDcmVhdGUoJ3RleHQnKTtcblxuICBzdmdBdHRyKHRleHRFbGVtZW50LCBzdHlsZSk7XG5cbiAgLy8gbGF5b3V0IGVhY2ggbGluZSB0YWtpbmcgaW50byBhY2NvdW50IHRoYXQgcGFyZW50XG4gIC8vIHNoYXBlIG1pZ2h0IHJlc2l6ZSB0byBmaXQgdGV4dCBzaXplXG4gIGZvckVhY2gobGF5b3V0ZWQsIGZ1bmN0aW9uKGxpbmUpIHtcblxuICAgIHZhciB4O1xuXG4gICAgeSArPSAobGluZUhlaWdodCB8fCBsaW5lLmhlaWdodCk7XG5cbiAgICBzd2l0Y2ggKGFsaWduLmhvcml6b250YWwpIHtcbiAgICBjYXNlICdsZWZ0JzpcbiAgICAgIHggPSBwYWRkaW5nLmxlZnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgIHggPSAoKGZpdEJveCA/IG1heExpbmVXaWR0aCA6IG1heFdpZHRoKVxuICAgICAgICAtIHBhZGRpbmcucmlnaHQgLSBsaW5lLndpZHRoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcblxuICAgICAgLy8gYWthIGNlbnRlclxuICAgICAgeCA9IE1hdGgubWF4KCgoKGZpdEJveCA/IG1heExpbmVXaWR0aCA6IG1heFdpZHRoKVxuICAgICAgICAtIGxpbmUud2lkdGgpIC8gMiArIHBhZGRpbmcubGVmdCksIDApO1xuICAgIH1cblxuICAgIHZhciB0c3BhbiA9IHN2Z0NyZWF0ZSgndHNwYW4nKTtcbiAgICBzdmdBdHRyKHRzcGFuLCB7IHg6IHgsIHk6IHkgfSk7XG5cbiAgICB0c3Bhbi50ZXh0Q29udGVudCA9IGxpbmUudGV4dDtcblxuICAgIHN2Z0FwcGVuZCh0ZXh0RWxlbWVudCwgdHNwYW4pO1xuICB9KTtcblxuICBzdmdSZW1vdmUoaGVscGVyVGV4dCk7XG5cbiAgdmFyIGRpbWVuc2lvbnMgPSB7XG4gICAgd2lkdGg6IG1heExpbmVXaWR0aCxcbiAgICBoZWlnaHQ6IHRvdGFsSGVpZ2h0XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBkaW1lbnNpb25zOiBkaW1lbnNpb25zLFxuICAgIGVsZW1lbnQ6IHRleHRFbGVtZW50XG4gIH07XG59O1xuXG5cbmZ1bmN0aW9uIGdldExpbmVIZWlnaHQoc3R5bGUpIHtcbiAgaWYgKCdmb250U2l6ZScgaW4gc3R5bGUgJiYgJ2xpbmVIZWlnaHQnIGluIHN0eWxlKSB7XG4gICAgcmV0dXJuIHN0eWxlLmxpbmVIZWlnaHQgKiBwYXJzZUludChzdHlsZS5mb250U2l6ZSwgMTApO1xuICB9XG59IiwiaW1wb3J0IHsgaXNTdHJpbmcsIGFzc2lnbiB9IGZyb20gJ21pbi1kYXNoJztcbmltcG9ydCB7IE1vZGRsZSB9IGZyb20gJ21vZGRsZSc7XG5pbXBvcnQgeyBSZWFkZXIsIFdyaXRlciB9IGZyb20gJ21vZGRsZS14bWwnO1xuXG4vKipcbiAqIEEgc3ViIGNsYXNzIG9mIHtAbGluayBNb2RkbGV9IHdpdGggc3VwcG9ydCBmb3IgaW1wb3J0IGFuZCBleHBvcnQgb2YgQlBNTiAyLjAgeG1sIGZpbGVzLlxuICpcbiAqIEBjbGFzcyBCcG1uTW9kZGxlXG4gKiBAZXh0ZW5kcyBNb2RkbGVcbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gcGFja2FnZXMgdG8gdXNlIGZvciBpbnN0YW50aWF0aW5nIHRoZSBtb2RlbFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBhZGRpdGlvbmFsIG9wdGlvbnMgdG8gcGFzcyBvdmVyXG4gKi9cbmZ1bmN0aW9uIEJwbW5Nb2RkbGUocGFja2FnZXMsIG9wdGlvbnMpIHtcbiAgTW9kZGxlLmNhbGwodGhpcywgcGFja2FnZXMsIG9wdGlvbnMpO1xufVxuXG5CcG1uTW9kZGxlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoTW9kZGxlLnByb3RvdHlwZSk7XG5cbi8qKlxuICogVGhlIGZyb21YTUwgcmVzdWx0LlxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFBhcnNlUmVzdWx0XG4gKlxuICogQHByb3BlcnR5IHtNb2RkbGVFbGVtZW50fSByb290RWxlbWVudFxuICogQHByb3BlcnR5IHtBcnJheTxPYmplY3Q+fSByZWZlcmVuY2VzXG4gKiBAcHJvcGVydHkge0FycmF5PEVycm9yPn0gd2FybmluZ3NcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBlbGVtZW50c0J5SWQgLSBhIG1hcHBpbmcgY29udGFpbmluZyBlYWNoIElEIC0+IE1vZGRsZUVsZW1lbnRcbiAqL1xuXG4vKipcbiAqIFRoZSBmcm9tWE1MIGVycm9yLlxuICpcbiAqIEB0eXBlZGVmIHtFcnJvcn0gUGFyc2VFcnJvclxuICpcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8RXJyb3I+fSB3YXJuaW5nc1xuICovXG5cbi8qKlxuICogSW5zdGFudGlhdGVzIGEgQlBNTiBtb2RlbCB0cmVlIGZyb20gYSBnaXZlbiB4bWwgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSAgIHhtbFN0clxuICogQHBhcmFtIHtTdHJpbmd9ICAgW3R5cGVOYW1lPSdicG1uOkRlZmluaXRpb25zJ10gbmFtZSBvZiB0aGUgcm9vdCBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gICBbb3B0aW9uc10gIG9wdGlvbnMgdG8gcGFzcyB0byB0aGUgdW5kZXJseWluZyByZWFkZXJcbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxQYXJzZVJlc3VsdCwgUGFyc2VFcnJvcj59XG4gKi9cbkJwbW5Nb2RkbGUucHJvdG90eXBlLmZyb21YTUwgPSBmdW5jdGlvbih4bWxTdHIsIHR5cGVOYW1lLCBvcHRpb25zKSB7XG5cbiAgaWYgKCFpc1N0cmluZyh0eXBlTmFtZSkpIHtcbiAgICBvcHRpb25zID0gdHlwZU5hbWU7XG4gICAgdHlwZU5hbWUgPSAnYnBtbjpEZWZpbml0aW9ucyc7XG4gIH1cblxuICB2YXIgcmVhZGVyID0gbmV3IFJlYWRlcihhc3NpZ24oeyBtb2RlbDogdGhpcywgbGF4OiB0cnVlIH0sIG9wdGlvbnMpKTtcbiAgdmFyIHJvb3RIYW5kbGVyID0gcmVhZGVyLmhhbmRsZXIodHlwZU5hbWUpO1xuXG4gIHJldHVybiByZWFkZXIuZnJvbVhNTCh4bWxTdHIsIHJvb3RIYW5kbGVyKTtcbn07XG5cblxuLyoqXG4gKiBUaGUgdG9YTUwgcmVzdWx0LlxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFNlcmlhbGl6YXRpb25SZXN1bHRcbiAqXG4gKiBAcHJvcGVydHkge1N0cmluZ30geG1sXG4gKi9cblxuLyoqXG4gKiBTZXJpYWxpemVzIGEgQlBNTiAyLjAgb2JqZWN0IHRyZWUgdG8gWE1MLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSAgIGVsZW1lbnQgICAgdGhlIHJvb3QgZWxlbWVudCwgdHlwaWNhbGx5IGFuIGluc3RhbmNlIG9mIGBicG1uOkRlZmluaXRpb25zYFxuICogQHBhcmFtIHtPYmplY3R9ICAgW29wdGlvbnNdICB0byBwYXNzIHRvIHRoZSB1bmRlcmx5aW5nIHdyaXRlclxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPFNlcmlhbGl6YXRpb25SZXN1bHQsIEVycm9yPn1cbiAqL1xuQnBtbk1vZGRsZS5wcm90b3R5cGUudG9YTUwgPSBmdW5jdGlvbihlbGVtZW50LCBvcHRpb25zKSB7XG5cbiAgdmFyIHdyaXRlciA9IG5ldyBXcml0ZXIob3B0aW9ucyk7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzdWx0ID0gd3JpdGVyLnRvWE1MKGVsZW1lbnQpO1xuXG4gICAgICByZXR1cm4gcmVzb2x2ZSh7XG4gICAgICAgIHhtbDogcmVzdWx0XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICB9XG4gIH0pO1xufTtcblxudmFyIG5hbWUgPSBcIkJQTU4yMFwiO1xudmFyIHVyaSA9IFwiaHR0cDovL3d3dy5vbWcub3JnL3NwZWMvQlBNTi8yMDEwMDUyNC9NT0RFTFwiO1xudmFyIHByZWZpeCA9IFwiYnBtblwiO1xudmFyIGFzc29jaWF0aW9ucyA9IFtcbl07XG52YXIgdHlwZXMgPSBbXG5cdHtcblx0XHRuYW1lOiBcIkludGVyZmFjZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm9wZXJhdGlvbnNcIixcblx0XHRcdFx0dHlwZTogXCJPcGVyYXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImltcGxlbWVudGF0aW9uUmVmXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiT3BlcmF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW5NZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvdXRNZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJlcnJvclJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkVycm9yXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25SZWZcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFbmRQb2ludFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQXVkaXRpbmdcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdsb2JhbFRhc2tcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkNhbGxhYmxlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVzb3VyY2VzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVzb3VyY2VSb2xlXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTW9uaXRvcmluZ1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUGVyZm9ybWVyXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSZXNvdXJjZVJvbGVcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUHJvY2Vzc1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRmxvd0VsZW1lbnRzQ29udGFpbmVyXCIsXG5cdFx0XHRcIkNhbGxhYmxlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicHJvY2Vzc1R5cGVcIixcblx0XHRcdFx0dHlwZTogXCJQcm9jZXNzVHlwZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNDbG9zZWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhdWRpdGluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIkF1ZGl0aW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibW9uaXRvcmluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIk1vbml0b3JpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwcm9wZXJ0aWVzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUHJvcGVydHlcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxhbmVTZXRzXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0cmVwbGFjZXM6IFwiRmxvd0VsZW1lbnRzQ29udGFpbmVyI2xhbmVTZXRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiTGFuZVNldFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZsb3dFbGVtZW50c1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdHJlcGxhY2VzOiBcIkZsb3dFbGVtZW50c0NvbnRhaW5lciNmbG93RWxlbWVudHNcIixcblx0XHRcdFx0dHlwZTogXCJGbG93RWxlbWVudFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImFydGlmYWN0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkFydGlmYWN0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJyZXNvdXJjZXNcIixcblx0XHRcdFx0dHlwZTogXCJSZXNvdXJjZVJvbGVcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvcnJlbGF0aW9uU3Vic2NyaXB0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkNvcnJlbGF0aW9uU3Vic2NyaXB0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzdXBwb3J0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIlByb2Nlc3NcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkZWZpbml0aW9uYWxDb2xsYWJvcmF0aW9uUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29sbGFib3JhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzRXhlY3V0YWJsZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJMYW5lU2V0XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibGFuZXNcIixcblx0XHRcdFx0dHlwZTogXCJMYW5lXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTGFuZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpdGlvbkVsZW1lbnRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJCYXNlRWxlbWVudFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpdGlvbkVsZW1lbnRcIixcblx0XHRcdFx0dHlwZTogXCJCYXNlRWxlbWVudFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZsb3dOb2RlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRmxvd05vZGVcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjaGlsZExhbmVTZXRcIixcblx0XHRcdFx0dHlwZTogXCJMYW5lU2V0XCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdsb2JhbE1hbnVhbFRhc2tcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkdsb2JhbFRhc2tcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTWFudWFsVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiVGFza1wiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJVc2VyVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiVGFza1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVuZGVyaW5nc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlJlbmRlcmluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZW5kZXJpbmdcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkh1bWFuUGVyZm9ybWVyXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJQZXJmb3JtZXJcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUG90ZW50aWFsT3duZXJcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkh1bWFuUGVyZm9ybWVyXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdsb2JhbFVzZXJUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJHbG9iYWxUYXNrXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbXBsZW1lbnRhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVuZGVyaW5nc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlJlbmRlcmluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdhdGV3YXlcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRmxvd05vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImdhdGV3YXlEaXJlY3Rpb25cIixcblx0XHRcdFx0dHlwZTogXCJHYXRld2F5RGlyZWN0aW9uXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBcIlVuc3BlY2lmaWVkXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXZlbnRCYXNlZEdhdGV3YXlcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkdhdGV3YXlcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImluc3RhbnRpYXRlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJldmVudEdhdGV3YXlUeXBlXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXZlbnRCYXNlZEdhdGV3YXlUeXBlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0XCJkZWZhdWx0XCI6IFwiRXhjbHVzaXZlXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNvbXBsZXhHYXRld2F5XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJHYXRld2F5XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhY3RpdmF0aW9uQ29uZGl0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXhwcmVzc2lvblwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwieHNpOnR5cGVcIlxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRlZmF1bHRcIixcblx0XHRcdFx0dHlwZTogXCJTZXF1ZW5jZUZsb3dcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXhjbHVzaXZlR2F0ZXdheVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiR2F0ZXdheVwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGVmYXVsdFwiLFxuXHRcdFx0XHR0eXBlOiBcIlNlcXVlbmNlRmxvd1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJbmNsdXNpdmVHYXRld2F5XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJHYXRld2F5XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkZWZhdWx0XCIsXG5cdFx0XHRcdHR5cGU6IFwiU2VxdWVuY2VGbG93XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlBhcmFsbGVsR2F0ZXdheVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiR2F0ZXdheVwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSb290RWxlbWVudFwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZWxhdGlvbnNoaXBcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0eXBlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkaXJlY3Rpb25cIixcblx0XHRcdFx0dHlwZTogXCJSZWxhdGlvbnNoaXBEaXJlY3Rpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNvdXJjZVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkVsZW1lbnRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0YXJnZXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJFbGVtZW50XCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJhc2VFbGVtZW50XCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiLFxuXHRcdFx0XHRpc0lkOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRvY3VtZW50YXRpb25cIixcblx0XHRcdFx0dHlwZTogXCJEb2N1bWVudGF0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25EZWZpbml0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvbkRlZmluaXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25FbGVtZW50c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvbkVsZW1lbnRzXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkV4dGVuc2lvblwiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtdXN0VW5kZXJzdGFuZFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogZmFsc2UsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGVmaW5pdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvbkRlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXh0ZW5zaW9uRGVmaW5pdGlvblwiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25BdHRyaWJ1dGVEZWZpbml0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvbkF0dHJpYnV0ZURlZmluaXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFeHRlbnNpb25BdHRyaWJ1dGVEZWZpbml0aW9uXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInR5cGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzUmVmZXJlbmNlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25EZWZpbml0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXh0ZW5zaW9uRGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFeHRlbnNpb25FbGVtZW50c1wiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ2YWx1ZVJlZlwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkVsZW1lbnRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ2YWx1ZXNcIixcblx0XHRcdFx0dHlwZTogXCJFbGVtZW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25BdHRyaWJ1dGVEZWZpbml0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXh0ZW5zaW9uQXR0cmlidXRlRGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJEb2N1bWVudGF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGV4dFwiLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiLFxuXHRcdFx0XHRpc0JvZHk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGV4dEZvcm1hdFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCJ0ZXh0L3BsYWluXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXZlbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRmxvd05vZGVcIixcblx0XHRcdFwiSW50ZXJhY3Rpb25Ob2RlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwcm9wZXJ0aWVzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUHJvcGVydHlcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJbnRlcm1lZGlhdGVDYXRjaEV2ZW50XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJDYXRjaEV2ZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkludGVybWVkaWF0ZVRocm93RXZlbnRcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlRocm93RXZlbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRW5kRXZlbnRcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlRocm93RXZlbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiU3RhcnRFdmVudFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ2F0Y2hFdmVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNJbnRlcnJ1cHRpbmdcIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IHRydWUsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlRocm93RXZlbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFJbnB1dHNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhSW5wdXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFJbnB1dEFzc29jaWF0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFJbnB1dEFzc29jaWF0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldFwiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0U2V0XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXZlbnREZWZpbml0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXZlbnREZWZpbml0aW9uUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNhdGNoRXZlbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcmFsbGVsTXVsdGlwbGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IGZhbHNlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFPdXRwdXRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRGF0YU91dHB1dFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU91dHB1dEFzc29jaWF0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFPdXRwdXRBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0cHV0U2V0XCIsXG5cdFx0XHRcdHR5cGU6IFwiT3V0cHV0U2V0XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXZlbnREZWZpbml0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXZlbnREZWZpbml0aW9uUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJvdW5kYXJ5RXZlbnRcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkNhdGNoRXZlbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbmNlbEFjdGl2aXR5XCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiB0cnVlLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImF0dGFjaGVkVG9SZWZcIixcblx0XHRcdFx0dHlwZTogXCJBY3Rpdml0eVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFdmVudERlZmluaXRpb25cIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ2FuY2VsRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJFdmVudERlZmluaXRpb25cIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXJyb3JFdmVudERlZmluaXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkV2ZW50RGVmaW5pdGlvblwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXJyb3JSZWZcIixcblx0XHRcdFx0dHlwZTogXCJFcnJvclwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJUZXJtaW5hdGVFdmVudERlZmluaXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkV2ZW50RGVmaW5pdGlvblwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJFdmVudERlZmluaXRpb25cIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImVzY2FsYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJFc2NhbGF0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkVzY2FsYXRpb25cIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3RydWN0dXJlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJlc2NhbGF0aW9uQ29kZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnREZWZpbml0aW9uXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ3YWl0Rm9yQ29tcGxldGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhY3Rpdml0eVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkFjdGl2aXR5XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlRpbWVyRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJFdmVudERlZmluaXRpb25cIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRpbWVEYXRlXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXhwcmVzc2lvblwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwieHNpOnR5cGVcIlxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRpbWVDeWNsZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkV4cHJlc3Npb25cIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInhzaTp0eXBlXCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0aW1lRHVyYXRpb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkxpbmtFdmVudERlZmluaXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkV2ZW50RGVmaW5pdGlvblwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0XCIsXG5cdFx0XHRcdHR5cGU6IFwiTGlua0V2ZW50RGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNvdXJjZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkxpbmtFdmVudERlZmluaXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTWVzc2FnZUV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnREZWZpbml0aW9uXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm9wZXJhdGlvblJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIk9wZXJhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnREZWZpbml0aW9uXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb25kaXRpb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlNpZ25hbEV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnREZWZpbml0aW9uXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzaWduYWxSZWZcIixcblx0XHRcdFx0dHlwZTogXCJTaWduYWxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiU2lnbmFsXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3RydWN0dXJlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSW1wbGljaXRUaHJvd0V2ZW50XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJUaHJvd0V2ZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFTdGF0ZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJdGVtQXdhcmVFbGVtZW50XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXRlbVN1YmplY3RSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJdGVtRGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFTdGF0ZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFTdGF0ZVwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJEYXRhQXNzb2NpYXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzb3VyY2VSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJdGVtQXdhcmVFbGVtZW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbUF3YXJlRWxlbWVudFwiLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0cmFuc2Zvcm1hdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIkZvcm1hbEV4cHJlc3Npb25cIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInByb3BlcnR5XCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhc3NpZ25tZW50XCIsXG5cdFx0XHRcdHR5cGU6IFwiQXNzaWdubWVudFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFJbnB1dFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNDb2xsZWN0aW9uXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0U2V0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldFdpdGhPcHRpb25hbFwiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0U2V0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldFdpdGhXaGlsZUV4ZWN1dGluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0U2V0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRGF0YU91dHB1dFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNDb2xsZWN0aW9uXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvdXRwdXRTZXRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJPdXRwdXRTZXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dHB1dFNldFdpdGhPcHRpb25hbFwiLFxuXHRcdFx0XHR0eXBlOiBcIk91dHB1dFNldFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzVmlydHVhbDogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0cHV0U2V0V2l0aFdoaWxlRXhlY3V0aW5nXCIsXG5cdFx0XHRcdHR5cGU6IFwiT3V0cHV0U2V0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSW5wdXRTZXRcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkYXRhSW5wdXRSZWZzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRGF0YUlucHV0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3B0aW9uYWxJbnB1dFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhSW5wdXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ3aGlsZUV4ZWN1dGluZ0lucHV0UmVmc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFJbnB1dFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dHB1dFNldFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJPdXRwdXRTZXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiT3V0cHV0U2V0XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU91dHB1dFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhT3V0cHV0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW5wdXRTZXRSZWZzXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW5wdXRTZXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcHRpb25hbE91dHB1dFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhT3V0cHV0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwid2hpbGVFeGVjdXRpbmdPdXRwdXRSZWZzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRGF0YU91dHB1dFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJQcm9wZXJ0eVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFJbnB1dEFzc29jaWF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJEYXRhQXNzb2NpYXRpb25cIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRGF0YU91dHB1dEFzc29jaWF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJEYXRhQXNzb2NpYXRpb25cIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSW5wdXRPdXRwdXRTcGVjaWZpY2F0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YUlucHV0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFJbnB1dFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU91dHB1dHNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhT3V0cHV0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldHNcIixcblx0XHRcdFx0dHlwZTogXCJJbnB1dFNldFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0cHV0U2V0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIk91dHB1dFNldFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFPYmplY3RcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkZsb3dFbGVtZW50XCIsXG5cdFx0XHRcIkl0ZW1Bd2FyZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzQ29sbGVjdGlvblwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogZmFsc2UsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIklucHV0T3V0cHV0QmluZGluZ1wiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dERhdGFSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJbnB1dFNldFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dHB1dERhdGFSZWZcIixcblx0XHRcdFx0dHlwZTogXCJPdXRwdXRTZXRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcGVyYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJPcGVyYXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQXNzaWdubWVudFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZyb21cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidG9cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFTdG9yZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIixcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY2FwYWNpdHlcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkludGVnZXJcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpc1VubGltaXRlZFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogdHJ1ZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRGF0YVN0b3JlUmVmZXJlbmNlXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJJdGVtQXdhcmVFbGVtZW50XCIsXG5cdFx0XHRcIkZsb3dFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkYXRhU3RvcmVSZWZcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhU3RvcmVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRGF0YU9iamVjdFJlZmVyZW5jZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiLFxuXHRcdFx0XCJGbG93RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU9iamVjdFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFPYmplY3RcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29udmVyc2F0aW9uTGlua1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNvdXJjZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkludGVyYWN0aW9uTm9kZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRhcmdldFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkludGVyYWN0aW9uTm9kZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb252ZXJzYXRpb25Bc3NvY2lhdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlubmVyQ29udmVyc2F0aW9uTm9kZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkNvbnZlcnNhdGlvbk5vZGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvdXRlckNvbnZlcnNhdGlvbk5vZGVSZWZcIixcblx0XHRcdFx0dHlwZTogXCJDb252ZXJzYXRpb25Ob2RlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNhbGxDb252ZXJzYXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkNvbnZlcnNhdGlvbk5vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbGxlZENvbGxhYm9yYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJDb2xsYWJvcmF0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicGFydGljaXBhbnRBc3NvY2lhdGlvbnNcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudEFzc29jaWF0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29udmVyc2F0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJDb252ZXJzYXRpb25Ob2RlXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlN1YkNvbnZlcnNhdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ29udmVyc2F0aW9uTm9kZVwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29udmVyc2F0aW9uTm9kZXNcIixcblx0XHRcdFx0dHlwZTogXCJDb252ZXJzYXRpb25Ob2RlXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29udmVyc2F0aW9uTm9kZVwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJJbnRlcmFjdGlvbk5vZGVcIixcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpY2lwYW50UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUGFydGljaXBhbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlRmxvd1JlZnNcIixcblx0XHRcdFx0dHlwZTogXCJNZXNzYWdlRmxvd1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvcnJlbGF0aW9uS2V5c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkNvcnJlbGF0aW9uS2V5XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiR2xvYmFsQ29udmVyc2F0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJDb2xsYWJvcmF0aW9uXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlBhcnRuZXJFbnRpdHlcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlJvb3RFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlBhcnRuZXJSb2xlXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicGFydGljaXBhbnRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb3JyZWxhdGlvblByb3BlcnR5XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29ycmVsYXRpb25Qcm9wZXJ0eVJldHJpZXZhbEV4cHJlc3Npb25cIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvblByb3BlcnR5UmV0cmlldmFsRXhwcmVzc2lvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidHlwZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkl0ZW1EZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkVycm9yXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3RydWN0dXJlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJlcnJvckNvZGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb3JyZWxhdGlvbktleVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvcnJlbGF0aW9uUHJvcGVydHlSZWZcIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvblByb3BlcnR5XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkV4cHJlc3Npb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdGlzQWJzdHJhY3Q6IGZhbHNlLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJib2R5XCIsXG5cdFx0XHRcdGlzQm9keTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRm9ybWFsRXhwcmVzc2lvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXhwcmVzc2lvblwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibGFuZ3VhZ2VcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImV2YWx1YXRlc1RvVHlwZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkl0ZW1EZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIk1lc3NhZ2VcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlJvb3RFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpdGVtUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlJvb3RFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpdGVtS2luZFwiLFxuXHRcdFx0XHR0eXBlOiBcIkl0ZW1LaW5kXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzdHJ1Y3R1cmVSZWZcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzQ29sbGVjdGlvblwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogZmFsc2UsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wb3J0XCIsXG5cdFx0XHRcdHR5cGU6IFwiSW1wb3J0XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkZsb3dFbGVtZW50XCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhdWRpdGluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIkF1ZGl0aW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibW9uaXRvcmluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIk1vbml0b3JpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjYXRlZ29yeVZhbHVlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ2F0ZWdvcnlWYWx1ZVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTZXF1ZW5jZUZsb3dcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkZsb3dFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpc0ltbWVkaWF0ZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvbmRpdGlvbkV4cHJlc3Npb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic291cmNlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRmxvd05vZGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0YXJnZXRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJGbG93Tm9kZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJGbG93RWxlbWVudHNDb250YWluZXJcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxhbmVTZXRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiTGFuZVNldFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZmxvd0VsZW1lbnRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRmxvd0VsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDYWxsYWJsZUVsZW1lbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlvU3BlY2lmaWNhdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0T3V0cHV0U3BlY2lmaWNhdGlvblwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwicHJvcGVydHlcIlxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInN1cHBvcnRlZEludGVyZmFjZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkludGVyZmFjZVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlvQmluZGluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0T3V0cHV0QmluZGluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJwcm9wZXJ0eVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkZsb3dOb2RlXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkZsb3dFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbmNvbWluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIlNlcXVlbmNlRmxvd1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dGdvaW5nXCIsXG5cdFx0XHRcdHR5cGU6IFwiU2VxdWVuY2VGbG93XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibGFuZXNcIixcblx0XHRcdFx0dHlwZTogXCJMYW5lXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29ycmVsYXRpb25Qcm9wZXJ0eVJldHJpZXZhbEV4cHJlc3Npb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUGF0aFwiLFxuXHRcdFx0XHR0eXBlOiBcIkZvcm1hbEV4cHJlc3Npb25cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb3JyZWxhdGlvblByb3BlcnR5QmluZGluZ1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFQYXRoXCIsXG5cdFx0XHRcdHR5cGU6IFwiRm9ybWFsRXhwcmVzc2lvblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvcnJlbGF0aW9uUHJvcGVydHlSZWZcIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvblByb3BlcnR5XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlJlc291cmNlXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVzb3VyY2VQYXJhbWV0ZXJzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVzb3VyY2VQYXJhbWV0ZXJcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZXNvdXJjZVBhcmFtZXRlclwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzUmVxdWlyZWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0eXBlXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29ycmVsYXRpb25TdWJzY3JpcHRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb3JyZWxhdGlvbktleVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkNvcnJlbGF0aW9uS2V5XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29ycmVsYXRpb25Qcm9wZXJ0eUJpbmRpbmdcIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvblByb3BlcnR5QmluZGluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIk1lc3NhZ2VGbG93XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic291cmNlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW50ZXJhY3Rpb25Ob2RlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW50ZXJhY3Rpb25Ob2RlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibWVzc2FnZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIk1lc3NhZ2VcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTWVzc2FnZUZsb3dBc3NvY2lhdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlubmVyTWVzc2FnZUZsb3dSZWZcIixcblx0XHRcdFx0dHlwZTogXCJNZXNzYWdlRmxvd1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dGVyTWVzc2FnZUZsb3dSZWZcIixcblx0XHRcdFx0dHlwZTogXCJNZXNzYWdlRmxvd1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJbnRlcmFjdGlvbk5vZGVcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbmNvbWluZ0NvbnZlcnNhdGlvbkxpbmtzXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29udmVyc2F0aW9uTGlua1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzVmlydHVhbDogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0Z29pbmdDb252ZXJzYXRpb25MaW5rc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkNvbnZlcnNhdGlvbkxpbmtcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJQYXJ0aWNpcGFudFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSW50ZXJhY3Rpb25Ob2RlXCIsXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnRlcmZhY2VSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJbnRlcmZhY2VcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudE11bHRpcGxpY2l0eVwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50TXVsdGlwbGljaXR5XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZW5kUG9pbnRSZWZzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRW5kUG9pbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwcm9jZXNzUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUHJvY2Vzc1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJQYXJ0aWNpcGFudEFzc29jaWF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW5uZXJQYXJ0aWNpcGFudFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0ZXJQYXJ0aWNpcGFudFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlBhcnRpY2lwYW50TXVsdGlwbGljaXR5XCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm1pbmltdW1cIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IDAsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJJbnRlZ2VyXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibWF4aW11bVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogMSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkludGVnZXJcIlxuXHRcdFx0fVxuXHRcdF0sXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb2xsYWJvcmF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNDbG9zZWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudHNcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibWVzc2FnZUZsb3dzXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZUZsb3dcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImFydGlmYWN0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkFydGlmYWN0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb252ZXJzYXRpb25zXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29udmVyc2F0aW9uTm9kZVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29udmVyc2F0aW9uQXNzb2NpYXRpb25zXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29udmVyc2F0aW9uQXNzb2NpYXRpb25cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudEFzc29jaWF0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50QXNzb2NpYXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm1lc3NhZ2VGbG93QXNzb2NpYXRpb25zXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZUZsb3dBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29ycmVsYXRpb25LZXlzXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29ycmVsYXRpb25LZXlcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNob3Jlb2dyYXBoeVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkNob3Jlb2dyYXBoeVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvbnZlcnNhdGlvbkxpbmtzXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29udmVyc2F0aW9uTGlua1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNob3Jlb2dyYXBoeUFjdGl2aXR5XCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkZsb3dOb2RlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW5pdGlhdGluZ1BhcnRpY2lwYW50UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUGFydGljaXBhbnRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb3JyZWxhdGlvbktleXNcIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvbktleVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibG9vcFR5cGVcIixcblx0XHRcdFx0dHlwZTogXCJDaG9yZW9ncmFwaHlMb29wVHlwZVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCJOb25lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ2FsbENob3Jlb2dyYXBoeVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ2hvcmVvZ3JhcGh5QWN0aXZpdHlcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbGxlZENob3Jlb2dyYXBoeVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkNob3Jlb2dyYXBoeVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpY2lwYW50QXNzb2NpYXRpb25zXCIsXG5cdFx0XHRcdHR5cGU6IFwiUGFydGljaXBhbnRBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlN1YkNob3Jlb2dyYXBoeVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ2hvcmVvZ3JhcGh5QWN0aXZpdHlcIixcblx0XHRcdFwiRmxvd0VsZW1lbnRzQ29udGFpbmVyXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhcnRpZmFjdHNcIixcblx0XHRcdFx0dHlwZTogXCJBcnRpZmFjdFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNob3Jlb2dyYXBoeVRhc2tcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkNob3Jlb2dyYXBoeUFjdGl2aXR5XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlRmxvd1JlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIk1lc3NhZ2VGbG93XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNob3Jlb2dyYXBoeVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ29sbGFib3JhdGlvblwiLFxuXHRcdFx0XCJGbG93RWxlbWVudHNDb250YWluZXJcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiR2xvYmFsQ2hvcmVvZ3JhcGh5VGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ2hvcmVvZ3JhcGh5XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbml0aWF0aW5nUGFydGljaXBhbnRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJUZXh0QW5ub3RhdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQXJ0aWZhY3RcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRleHRcIixcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0ZXh0Rm9ybWF0XCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBcInRleHQvcGxhaW5cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJHcm91cFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQXJ0aWZhY3RcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhdGVnb3J5VmFsdWVSZWZcIixcblx0XHRcdFx0dHlwZTogXCJDYXRlZ29yeVZhbHVlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkFzc29jaWF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJBcnRpZmFjdFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYXNzb2NpYXRpb25EaXJlY3Rpb25cIixcblx0XHRcdFx0dHlwZTogXCJBc3NvY2lhdGlvbkRpcmVjdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic291cmNlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiQmFzZUVsZW1lbnRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0YXJnZXRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJCYXNlRWxlbWVudFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDYXRlZ29yeVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhdGVnb3J5VmFsdWVcIixcblx0XHRcdFx0dHlwZTogXCJDYXRlZ29yeVZhbHVlXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQXJ0aWZhY3RcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ2F0ZWdvcnlWYWx1ZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhdGVnb3JpemVkRmxvd0VsZW1lbnRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRmxvd0VsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInZhbHVlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQWN0aXZpdHlcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRmxvd05vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzRm9yQ29tcGVuc2F0aW9uXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkZWZhdWx0XCIsXG5cdFx0XHRcdHR5cGU6IFwiU2VxdWVuY2VGbG93XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW9TcGVjaWZpY2F0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW5wdXRPdXRwdXRTcGVjaWZpY2F0aW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJwcm9wZXJ0eVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYm91bmRhcnlFdmVudFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJCb3VuZGFyeUV2ZW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicHJvcGVydGllc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlByb3BlcnR5XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkYXRhSW5wdXRBc3NvY2lhdGlvbnNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhSW5wdXRBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU91dHB1dEFzc29jaWF0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFPdXRwdXRBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3RhcnRRdWFudGl0eVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogMSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkludGVnZXJcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJyZXNvdXJjZXNcIixcblx0XHRcdFx0dHlwZTogXCJSZXNvdXJjZVJvbGVcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvbXBsZXRpb25RdWFudGl0eVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogMSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkludGVnZXJcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJsb29wQ2hhcmFjdGVyaXN0aWNzXCIsXG5cdFx0XHRcdHR5cGU6IFwiTG9vcENoYXJhY3RlcmlzdGljc1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTZXJ2aWNlVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiVGFza1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm9wZXJhdGlvblJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIk9wZXJhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTdWJQcm9jZXNzXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJBY3Rpdml0eVwiLFxuXHRcdFx0XCJGbG93RWxlbWVudHNDb250YWluZXJcIixcblx0XHRcdFwiSW50ZXJhY3Rpb25Ob2RlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0cmlnZ2VyZWRCeUV2ZW50XCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhcnRpZmFjdHNcIixcblx0XHRcdFx0dHlwZTogXCJBcnRpZmFjdFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkxvb3BDaGFyYWN0ZXJpc3RpY3NcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTXVsdGlJbnN0YW5jZUxvb3BDaGFyYWN0ZXJpc3RpY3NcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkxvb3BDaGFyYWN0ZXJpc3RpY3NcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzU2VxdWVudGlhbFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogZmFsc2UsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYmVoYXZpb3JcIixcblx0XHRcdFx0dHlwZTogXCJNdWx0aUluc3RhbmNlQmVoYXZpb3JcIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IFwiQWxsXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJsb29wQ2FyZGluYWxpdHlcIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibG9vcERhdGFJbnB1dFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkl0ZW1Bd2FyZUVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibG9vcERhdGFPdXRwdXRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJdGVtQXdhcmVFbGVtZW50XCIsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlucHV0RGF0YUl0ZW1cIixcblx0XHRcdFx0dHlwZTogXCJEYXRhSW5wdXRcIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInByb3BlcnR5XCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvdXRwdXREYXRhSXRlbVwiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFPdXRwdXRcIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInByb3BlcnR5XCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb21wbGV4QmVoYXZpb3JEZWZpbml0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29tcGxleEJlaGF2aW9yRGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29tcGxldGlvbkNvbmRpdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIkV4cHJlc3Npb25cIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInhzaTp0eXBlXCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvbmVCZWhhdmlvckV2ZW50UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibm9uZUJlaGF2aW9yRXZlbnRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJFdmVudERlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiU3RhbmRhcmRMb29wQ2hhcmFjdGVyaXN0aWNzXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJMb29wQ2hhcmFjdGVyaXN0aWNzXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0ZXN0QmVmb3JlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJsb29wQ29uZGl0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXhwcmVzc2lvblwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwieHNpOnR5cGVcIlxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxvb3BNYXhpbXVtXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW50ZWdlclwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNhbGxBY3Rpdml0eVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQWN0aXZpdHlcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbGxlZEVsZW1lbnRcIixcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJBY3Rpdml0eVwiLFxuXHRcdFx0XCJJbnRlcmFjdGlvbk5vZGVcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiU2VuZFRhc2tcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlRhc2tcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImltcGxlbWVudGF0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcGVyYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJPcGVyYXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZWNlaXZlVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiVGFza1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImluc3RhbnRpYXRlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcGVyYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJPcGVyYXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTY3JpcHRUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJUYXNrXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzY3JpcHRGb3JtYXRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNjcmlwdFwiLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJCdXNpbmVzc1J1bGVUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJUYXNrXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbXBsZW1lbnRhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkFkSG9jU3ViUHJvY2Vzc1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiU3ViUHJvY2Vzc1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29tcGxldGlvbkNvbmRpdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIkV4cHJlc3Npb25cIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInhzaTp0eXBlXCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcmRlcmluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIkFkSG9jT3JkZXJpbmdcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbmNlbFJlbWFpbmluZ0luc3RhbmNlc1wiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogdHJ1ZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiVHJhbnNhY3Rpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlN1YlByb2Nlc3NcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInByb3RvY29sXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXRob2RcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJHbG9iYWxTY3JpcHRUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJHbG9iYWxUYXNrXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzY3JpcHRMYW5ndWFnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic2NyaXB0XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiR2xvYmFsQnVzaW5lc3NSdWxlVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiR2xvYmFsVGFza1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb21wbGV4QmVoYXZpb3JEZWZpbml0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29uZGl0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRm9ybWFsRXhwcmVzc2lvblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImV2ZW50XCIsXG5cdFx0XHRcdHR5cGU6IFwiSW1wbGljaXRUaHJvd0V2ZW50XCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlJlc291cmNlUm9sZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInJlc291cmNlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVzb3VyY2VcIixcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVzb3VyY2VQYXJhbWV0ZXJCaW5kaW5nc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlJlc291cmNlUGFyYW1ldGVyQmluZGluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVzb3VyY2VBc3NpZ25tZW50RXhwcmVzc2lvblwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlc291cmNlQXNzaWdubWVudEV4cHJlc3Npb25cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUmVzb3VyY2VQYXJhbWV0ZXJCaW5kaW5nXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImV4cHJlc3Npb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicGFyYW1ldGVyUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVzb3VyY2VQYXJhbWV0ZXJcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF0sXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZXNvdXJjZUFzc2lnbm1lbnRFeHByZXNzaW9uXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImV4cHJlc3Npb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSW1wb3J0XCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImltcG9ydFR5cGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxvY2F0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lc3BhY2VcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJEZWZpbml0aW9uc1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRhcmdldE5hbWVzcGFjZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXhwcmVzc2lvbkxhbmd1YWdlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBcImh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFBhdGhcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInR5cGVMYW5ndWFnZVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wb3J0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkltcG9ydFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXh0ZW5zaW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicm9vdEVsZW1lbnRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUm9vdEVsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRpYWdyYW1zXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJicG1uZGk6QlBNTkRpYWdyYW1cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHBvcnRlclwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVsYXRpb25zaGlwc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlJlbGF0aW9uc2hpcFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXhwb3J0ZXJWZXJzaW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fVxuXTtcbnZhciBlbnVtZXJhdGlvbnMgPSBbXG5cdHtcblx0XHRuYW1lOiBcIlByb2Nlc3NUeXBlXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIk5vbmVcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJQdWJsaWNcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJQcml2YXRlXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdhdGV3YXlEaXJlY3Rpb25cIixcblx0XHRsaXRlcmFsVmFsdWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiVW5zcGVjaWZpZWRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJDb252ZXJnaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiRGl2ZXJnaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiTWl4ZWRcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXZlbnRCYXNlZEdhdGV3YXlUeXBlXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIlBhcmFsbGVsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiRXhjbHVzaXZlXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlJlbGF0aW9uc2hpcERpcmVjdGlvblwiLFxuXHRcdGxpdGVyYWxWYWx1ZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJOb25lXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiRm9yd2FyZFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIkJhY2t3YXJkXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiQm90aFwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJdGVtS2luZFwiLFxuXHRcdGxpdGVyYWxWYWx1ZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJQaHlzaWNhbFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIkluZm9ybWF0aW9uXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNob3Jlb2dyYXBoeUxvb3BUeXBlXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIk5vbmVcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJTdGFuZGFyZFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIk11bHRpSW5zdGFuY2VTZXF1ZW50aWFsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiTXVsdGlJbnN0YW5jZVBhcmFsbGVsXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkFzc29jaWF0aW9uRGlyZWN0aW9uXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIk5vbmVcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJPbmVcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJCb3RoXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIk11bHRpSW5zdGFuY2VCZWhhdmlvclwiLFxuXHRcdGxpdGVyYWxWYWx1ZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJOb25lXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiT25lXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiQWxsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiQ29tcGxleFwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJBZEhvY09yZGVyaW5nXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIlBhcmFsbGVsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiU2VxdWVudGlhbFwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIHhtbCA9IHtcblx0dGFnQWxpYXM6IFwibG93ZXJDYXNlXCIsXG5cdHR5cGVQcmVmaXg6IFwidFwiXG59O1xudmFyIEJwbW5QYWNrYWdlID0ge1xuXHRuYW1lOiBuYW1lLFxuXHR1cmk6IHVyaSxcblx0cHJlZml4OiBwcmVmaXgsXG5cdGFzc29jaWF0aW9uczogYXNzb2NpYXRpb25zLFxuXHR0eXBlczogdHlwZXMsXG5cdGVudW1lcmF0aW9uczogZW51bWVyYXRpb25zLFxuXHR4bWw6IHhtbFxufTtcblxudmFyIG5hbWUkMSA9IFwiQlBNTkRJXCI7XG52YXIgdXJpJDEgPSBcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0JQTU4vMjAxMDA1MjQvRElcIjtcbnZhciBwcmVmaXgkMSA9IFwiYnBtbmRpXCI7XG52YXIgdHlwZXMkMSA9IFtcblx0e1xuXHRcdG5hbWU6IFwiQlBNTkRpYWdyYW1cIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicGxhbmVcIixcblx0XHRcdFx0dHlwZTogXCJCUE1OUGxhbmVcIixcblx0XHRcdFx0cmVkZWZpbmVzOiBcImRpOkRpYWdyYW0jcm9vdEVsZW1lbnRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJsYWJlbFN0eWxlXCIsXG5cdFx0XHRcdHR5cGU6IFwiQlBNTkxhYmVsU3R5bGVcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcImRpOkRpYWdyYW1cIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQlBNTlBsYW5lXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImJwbW5FbGVtZW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiYnBtbjpCYXNlRWxlbWVudFwiLFxuXHRcdFx0XHRyZWRlZmluZXM6IFwiZGk6RGlhZ3JhbUVsZW1lbnQjbW9kZWxFbGVtZW50XCJcblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiZGk6UGxhbmVcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQlBNTlNoYXBlXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImJwbW5FbGVtZW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiYnBtbjpCYXNlRWxlbWVudFwiLFxuXHRcdFx0XHRyZWRlZmluZXM6IFwiZGk6RGlhZ3JhbUVsZW1lbnQjbW9kZWxFbGVtZW50XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNIb3Jpem9udGFsXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNFeHBhbmRlZFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzTWFya2VyVmlzaWJsZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxhYmVsXCIsXG5cdFx0XHRcdHR5cGU6IFwiQlBNTkxhYmVsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNNZXNzYWdlVmlzaWJsZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpY2lwYW50QmFuZEtpbmRcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudEJhbmRLaW5kXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjaG9yZW9ncmFwaHlBY3Rpdml0eVNoYXBlXCIsXG5cdFx0XHRcdHR5cGU6IFwiQlBNTlNoYXBlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiZGk6TGFiZWxlZFNoYXBlXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJQTU5FZGdlXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxhYmVsXCIsXG5cdFx0XHRcdHR5cGU6IFwiQlBNTkxhYmVsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYnBtbkVsZW1lbnRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJicG1uOkJhc2VFbGVtZW50XCIsXG5cdFx0XHRcdHJlZGVmaW5lczogXCJkaTpEaWFncmFtRWxlbWVudCNtb2RlbEVsZW1lbnRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzb3VyY2VFbGVtZW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiZGk6RGlhZ3JhbUVsZW1lbnRcIixcblx0XHRcdFx0cmVkZWZpbmVzOiBcImRpOkVkZ2Ujc291cmNlXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0RWxlbWVudFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcImRpOkRpYWdyYW1FbGVtZW50XCIsXG5cdFx0XHRcdHJlZGVmaW5lczogXCJkaTpFZGdlI3RhcmdldFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm1lc3NhZ2VWaXNpYmxlS2luZFwiLFxuXHRcdFx0XHR0eXBlOiBcIk1lc3NhZ2VWaXNpYmxlS2luZFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBcImluaXRpYXRpbmdcIlxuXHRcdFx0fVxuXHRcdF0sXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJkaTpMYWJlbGVkRWRnZVwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJCUE1OTGFiZWxcIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibGFiZWxTdHlsZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkJQTU5MYWJlbFN0eWxlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWUsXG5cdFx0XHRcdHJlZGVmaW5lczogXCJkaTpEaWFncmFtRWxlbWVudCNzdHlsZVwiXG5cdFx0XHR9XG5cdFx0XSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcImRpOkxhYmVsXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJQTU5MYWJlbFN0eWxlXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZvbnRcIixcblx0XHRcdFx0dHlwZTogXCJkYzpGb250XCJcblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiZGk6U3R5bGVcIlxuXHRcdF1cblx0fVxuXTtcbnZhciBlbnVtZXJhdGlvbnMkMSA9IFtcblx0e1xuXHRcdG5hbWU6IFwiUGFydGljaXBhbnRCYW5kS2luZFwiLFxuXHRcdGxpdGVyYWxWYWx1ZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0b3BfaW5pdGlhdGluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm1pZGRsZV9pbml0aWF0aW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYm90dG9tX2luaXRpYXRpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0b3Bfbm9uX2luaXRpYXRpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtaWRkbGVfbm9uX2luaXRpYXRpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJib3R0b21fbm9uX2luaXRpYXRpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTWVzc2FnZVZpc2libGVLaW5kXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImluaXRpYXRpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJub25faW5pdGlhdGluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIGFzc29jaWF0aW9ucyQxID0gW1xuXTtcbnZhciBCcG1uRGlQYWNrYWdlID0ge1xuXHRuYW1lOiBuYW1lJDEsXG5cdHVyaTogdXJpJDEsXG5cdHByZWZpeDogcHJlZml4JDEsXG5cdHR5cGVzOiB0eXBlcyQxLFxuXHRlbnVtZXJhdGlvbnM6IGVudW1lcmF0aW9ucyQxLFxuXHRhc3NvY2lhdGlvbnM6IGFzc29jaWF0aW9ucyQxXG59O1xuXG52YXIgbmFtZSQyID0gXCJEQ1wiO1xudmFyIHVyaSQyID0gXCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9ERC8yMDEwMDUyNC9EQ1wiO1xudmFyIHByZWZpeCQyID0gXCJkY1wiO1xudmFyIHR5cGVzJDIgPSBbXG5cdHtcblx0XHRuYW1lOiBcIkJvb2xlYW5cIlxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJbnRlZ2VyXCJcblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUmVhbFwiXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlN0cmluZ1wiXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkZvbnRcIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic2l6ZVwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzQm9sZFwiLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzSXRhbGljXCIsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNVbmRlcmxpbmVcIixcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpc1N0cmlrZVRocm91Z2hcIixcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUG9pbnRcIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwieFwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IFwiMFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwieVwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IFwiMFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJvdW5kc1wiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ4XCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVhbFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCIwXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ5XCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVhbFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCIwXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ3aWR0aFwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImhlaWdodFwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIGFzc29jaWF0aW9ucyQyID0gW1xuXTtcbnZhciBEY1BhY2thZ2UgPSB7XG5cdG5hbWU6IG5hbWUkMixcblx0dXJpOiB1cmkkMixcblx0cHJlZml4OiBwcmVmaXgkMixcblx0dHlwZXM6IHR5cGVzJDIsXG5cdGFzc29jaWF0aW9uczogYXNzb2NpYXRpb25zJDJcbn07XG5cbnZhciBuYW1lJDMgPSBcIkRJXCI7XG52YXIgdXJpJDMgPSBcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0RELzIwMTAwNTI0L0RJXCI7XG52YXIgcHJlZml4JDMgPSBcImRpXCI7XG52YXIgdHlwZXMkMyA9IFtcblx0e1xuXHRcdG5hbWU6IFwiRGlhZ3JhbUVsZW1lbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpZFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzSWQ6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXh0ZW5zaW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXh0ZW5zaW9uXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3duaW5nRGlhZ3JhbVwiLFxuXHRcdFx0XHR0eXBlOiBcIkRpYWdyYW1cIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvd25pbmdFbGVtZW50XCIsXG5cdFx0XHRcdHR5cGU6IFwiRGlhZ3JhbUVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtb2RlbEVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJFbGVtZW50XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3R5bGVcIixcblx0XHRcdFx0dHlwZTogXCJTdHlsZVwiLFxuXHRcdFx0XHRpc1JlYWRPbmx5OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm93bmVkRWxlbWVudFwiLFxuXHRcdFx0XHR0eXBlOiBcIkRpYWdyYW1FbGVtZW50XCIsXG5cdFx0XHRcdGlzUmVhZE9ubHk6IHRydWUsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJOb2RlXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkRpYWdyYW1FbGVtZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkVkZ2VcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRGlhZ3JhbUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNvdXJjZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkRpYWdyYW1FbGVtZW50XCIsXG5cdFx0XHRcdGlzUmVhZE9ubHk6IHRydWUsXG5cdFx0XHRcdGlzVmlydHVhbDogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0XCIsXG5cdFx0XHRcdHR5cGU6IFwiRGlhZ3JhbUVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ3YXlwb2ludFwiLFxuXHRcdFx0XHRpc1VuaXF1ZTogZmFsc2UsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJkYzpQb2ludFwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwieHNpOnR5cGVcIlxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJEaWFncmFtXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc0lkOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInJvb3RFbGVtZW50XCIsXG5cdFx0XHRcdHR5cGU6IFwiRGlhZ3JhbUVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRvY3VtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInJlc29sdXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvd25lZFN0eWxlXCIsXG5cdFx0XHRcdHR5cGU6IFwiU3R5bGVcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlNoYXBlXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIk5vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImJvdW5kc1wiLFxuXHRcdFx0XHR0eXBlOiBcImRjOkJvdW5kc1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJQbGFuZVwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJOb2RlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwbGFuZUVsZW1lbnRcIixcblx0XHRcdFx0dHlwZTogXCJEaWFncmFtRWxlbWVudFwiLFxuXHRcdFx0XHRzdWJzZXR0ZWRQcm9wZXJ0eTogXCJEaWFncmFtRWxlbWVudC1vd25lZEVsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJMYWJlbGVkRWRnZVwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJFZGdlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvd25lZExhYmVsXCIsXG5cdFx0XHRcdHR5cGU6IFwiTGFiZWxcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0c3Vic2V0dGVkUHJvcGVydHk6IFwiRGlhZ3JhbUVsZW1lbnQtb3duZWRFbGVtZW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJMYWJlbGVkU2hhcGVcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiU2hhcGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm93bmVkTGFiZWxcIixcblx0XHRcdFx0dHlwZTogXCJMYWJlbFwiLFxuXHRcdFx0XHRpc1JlYWRPbmx5OiB0cnVlLFxuXHRcdFx0XHRzdWJzZXR0ZWRQcm9wZXJ0eTogXCJEaWFncmFtRWxlbWVudC1vd25lZEVsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkxhYmVsXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIk5vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImJvdW5kc1wiLFxuXHRcdFx0XHR0eXBlOiBcImRjOkJvdW5kc1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTdHlsZVwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlkXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNJZDogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXh0ZW5zaW9uXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInZhbHVlc1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiRWxlbWVudFwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIGFzc29jaWF0aW9ucyQzID0gW1xuXTtcbnZhciB4bWwkMSA9IHtcblx0dGFnQWxpYXM6IFwibG93ZXJDYXNlXCJcbn07XG52YXIgRGlQYWNrYWdlID0ge1xuXHRuYW1lOiBuYW1lJDMsXG5cdHVyaTogdXJpJDMsXG5cdHByZWZpeDogcHJlZml4JDMsXG5cdHR5cGVzOiB0eXBlcyQzLFxuXHRhc3NvY2lhdGlvbnM6IGFzc29jaWF0aW9ucyQzLFxuXHR4bWw6IHhtbCQxXG59O1xuXG52YXIgbmFtZSQ0ID0gXCJicG1uLmlvIGNvbG9ycyBmb3IgQlBNTlwiO1xudmFyIHVyaSQ0ID0gXCJodHRwOi8vYnBtbi5pby9zY2hlbWEvYnBtbi9iaW9jb2xvci8xLjBcIjtcbnZhciBwcmVmaXgkNCA9IFwiYmlvY1wiO1xudmFyIHR5cGVzJDQgPSBbXG5cdHtcblx0XHRuYW1lOiBcIkNvbG9yZWRTaGFwZVwiLFxuXHRcdFwiZXh0ZW5kc1wiOiBbXG5cdFx0XHRcImJwbW5kaTpCUE1OU2hhcGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInN0cm9rZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZmlsbFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNvbG9yZWRFZGdlXCIsXG5cdFx0XCJleHRlbmRzXCI6IFtcblx0XHRcdFwiYnBtbmRpOkJQTU5FZGdlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzdHJva2VcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZpbGxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIGVudW1lcmF0aW9ucyQyID0gW1xuXTtcbnZhciBhc3NvY2lhdGlvbnMkNCA9IFtcbl07XG52YXIgQmlvY1BhY2thZ2UgPSB7XG5cdG5hbWU6IG5hbWUkNCxcblx0dXJpOiB1cmkkNCxcblx0cHJlZml4OiBwcmVmaXgkNCxcblx0dHlwZXM6IHR5cGVzJDQsXG5cdGVudW1lcmF0aW9uczogZW51bWVyYXRpb25zJDIsXG5cdGFzc29jaWF0aW9uczogYXNzb2NpYXRpb25zJDRcbn07XG5cbnZhciBwYWNrYWdlcyA9IHtcbiAgYnBtbjogQnBtblBhY2thZ2UsXG4gIGJwbW5kaTogQnBtbkRpUGFja2FnZSxcbiAgZGM6IERjUGFja2FnZSxcbiAgZGk6IERpUGFja2FnZSxcbiAgYmlvYzogQmlvY1BhY2thZ2Vcbn07XG5cbmZ1bmN0aW9uIHNpbXBsZShhZGRpdGlvbmFsUGFja2FnZXMsIG9wdGlvbnMpIHtcbiAgdmFyIHBrcyA9IGFzc2lnbih7fSwgcGFja2FnZXMsIGFkZGl0aW9uYWxQYWNrYWdlcyk7XG5cbiAgcmV0dXJuIG5ldyBCcG1uTW9kZGxlKHBrcywgb3B0aW9ucyk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHNpbXBsZTtcbiIsIi8qISBodHRwczovL210aHMuYmUvY3NzZXNjYXBlIHYxLjUuMSBieSBAbWF0aGlhcyB8IE1JVCBsaWNlbnNlICovXG47KGZ1bmN0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL3VtZGpzL3VtZC9ibG9iL21hc3Rlci9yZXR1cm5FeHBvcnRzLmpzXG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0Jykge1xuXHRcdC8vIEZvciBOb2RlLmpzLlxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyb290KTtcblx0fSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEZvciBBTUQuIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBtb2R1bGUuXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5LmJpbmQocm9vdCwgcm9vdCkpO1xuXHR9IGVsc2Uge1xuXHRcdC8vIEZvciBicm93c2VyIGdsb2JhbHMgKG5vdCBleHBvc2luZyB0aGUgZnVuY3Rpb24gc2VwYXJhdGVseSkuXG5cdFx0ZmFjdG9yeShyb290KTtcblx0fVxufSh0eXBlb2YgZ2xvYmFsICE9ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogdGhpcywgZnVuY3Rpb24ocm9vdCkge1xuXG5cdGlmIChyb290LkNTUyAmJiByb290LkNTUy5lc2NhcGUpIHtcblx0XHRyZXR1cm4gcm9vdC5DU1MuZXNjYXBlO1xuXHR9XG5cblx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNzZXJpYWxpemUtYW4taWRlbnRpZmllclxuXHR2YXIgY3NzRXNjYXBlID0gZnVuY3Rpb24odmFsdWUpIHtcblx0XHRpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdgQ1NTLmVzY2FwZWAgcmVxdWlyZXMgYW4gYXJndW1lbnQuJyk7XG5cdFx0fVxuXHRcdHZhciBzdHJpbmcgPSBTdHJpbmcodmFsdWUpO1xuXHRcdHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuXHRcdHZhciBpbmRleCA9IC0xO1xuXHRcdHZhciBjb2RlVW5pdDtcblx0XHR2YXIgcmVzdWx0ID0gJyc7XG5cdFx0dmFyIGZpcnN0Q29kZVVuaXQgPSBzdHJpbmcuY2hhckNvZGVBdCgwKTtcblx0XHR3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuXHRcdFx0Y29kZVVuaXQgPSBzdHJpbmcuY2hhckNvZGVBdChpbmRleCk7XG5cdFx0XHQvLyBOb3RlOiB0aGVyZeKAmXMgbm8gbmVlZCB0byBzcGVjaWFsLWNhc2UgYXN0cmFsIHN5bWJvbHMsIHN1cnJvZ2F0ZVxuXHRcdFx0Ly8gcGFpcnMsIG9yIGxvbmUgc3Vycm9nYXRlcy5cblxuXHRcdFx0Ly8gSWYgdGhlIGNoYXJhY3RlciBpcyBOVUxMIChVKzAwMDApLCB0aGVuIHRoZSBSRVBMQUNFTUVOVCBDSEFSQUNURVJcblx0XHRcdC8vIChVK0ZGRkQpLlxuXHRcdFx0aWYgKGNvZGVVbml0ID09IDB4MDAwMCkge1xuXHRcdFx0XHRyZXN1bHQgKz0gJ1xcdUZGRkQnO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKFxuXHRcdFx0XHQvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIGluIHRoZSByYW5nZSBbXFwxLVxcMUZdIChVKzAwMDEgdG8gVSswMDFGKSBvciBpc1xuXHRcdFx0XHQvLyBVKzAwN0YsIFvigKZdXG5cdFx0XHRcdChjb2RlVW5pdCA+PSAweDAwMDEgJiYgY29kZVVuaXQgPD0gMHgwMDFGKSB8fCBjb2RlVW5pdCA9PSAweDAwN0YgfHxcblx0XHRcdFx0Ly8gSWYgdGhlIGNoYXJhY3RlciBpcyB0aGUgZmlyc3QgY2hhcmFjdGVyIGFuZCBpcyBpbiB0aGUgcmFuZ2UgWzAtOV1cblx0XHRcdFx0Ly8gKFUrMDAzMCB0byBVKzAwMzkpLCBb4oCmXVxuXHRcdFx0XHQoaW5kZXggPT0gMCAmJiBjb2RlVW5pdCA+PSAweDAwMzAgJiYgY29kZVVuaXQgPD0gMHgwMDM5KSB8fFxuXHRcdFx0XHQvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIHRoZSBzZWNvbmQgY2hhcmFjdGVyIGFuZCBpcyBpbiB0aGUgcmFuZ2UgWzAtOV1cblx0XHRcdFx0Ly8gKFUrMDAzMCB0byBVKzAwMzkpIGFuZCB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIGEgYC1gIChVKzAwMkQpLCBb4oCmXVxuXHRcdFx0XHQoXG5cdFx0XHRcdFx0aW5kZXggPT0gMSAmJlxuXHRcdFx0XHRcdGNvZGVVbml0ID49IDB4MDAzMCAmJiBjb2RlVW5pdCA8PSAweDAwMzkgJiZcblx0XHRcdFx0XHRmaXJzdENvZGVVbml0ID09IDB4MDAyRFxuXHRcdFx0XHQpXG5cdFx0XHQpIHtcblx0XHRcdFx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNlc2NhcGUtYS1jaGFyYWN0ZXItYXMtY29kZS1wb2ludFxuXHRcdFx0XHRyZXN1bHQgKz0gJ1xcXFwnICsgY29kZVVuaXQudG9TdHJpbmcoMTYpICsgJyAnO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKFxuXHRcdFx0XHQvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYW5kIGlzIGEgYC1gIChVKzAwMkQpLCBhbmRcblx0XHRcdFx0Ly8gdGhlcmUgaXMgbm8gc2Vjb25kIGNoYXJhY3RlciwgW+KApl1cblx0XHRcdFx0aW5kZXggPT0gMCAmJlxuXHRcdFx0XHRsZW5ndGggPT0gMSAmJlxuXHRcdFx0XHRjb2RlVW5pdCA9PSAweDAwMkRcblx0XHRcdCkge1xuXHRcdFx0XHRyZXN1bHQgKz0gJ1xcXFwnICsgc3RyaW5nLmNoYXJBdChpbmRleCk7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIG5vdCBoYW5kbGVkIGJ5IG9uZSBvZiB0aGUgYWJvdmUgcnVsZXMgYW5kIGlzXG5cdFx0XHQvLyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gVSswMDgwLCBpcyBgLWAgKFUrMDAyRCkgb3IgYF9gIChVKzAwNUYpLCBvclxuXHRcdFx0Ly8gaXMgaW4gb25lIG9mIHRoZSByYW5nZXMgWzAtOV0gKFUrMDAzMCB0byBVKzAwMzkpLCBbQS1aXSAoVSswMDQxIHRvXG5cdFx0XHQvLyBVKzAwNUEpLCBvciBbYS16XSAoVSswMDYxIHRvIFUrMDA3QSksIFvigKZdXG5cdFx0XHRpZiAoXG5cdFx0XHRcdGNvZGVVbml0ID49IDB4MDA4MCB8fFxuXHRcdFx0XHRjb2RlVW5pdCA9PSAweDAwMkQgfHxcblx0XHRcdFx0Y29kZVVuaXQgPT0gMHgwMDVGIHx8XG5cdFx0XHRcdGNvZGVVbml0ID49IDB4MDAzMCAmJiBjb2RlVW5pdCA8PSAweDAwMzkgfHxcblx0XHRcdFx0Y29kZVVuaXQgPj0gMHgwMDQxICYmIGNvZGVVbml0IDw9IDB4MDA1QSB8fFxuXHRcdFx0XHRjb2RlVW5pdCA+PSAweDAwNjEgJiYgY29kZVVuaXQgPD0gMHgwMDdBXG5cdFx0XHQpIHtcblx0XHRcdFx0Ly8gdGhlIGNoYXJhY3RlciBpdHNlbGZcblx0XHRcdFx0cmVzdWx0ICs9IHN0cmluZy5jaGFyQXQoaW5kZXgpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3RoZXJ3aXNlLCB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG5cdFx0XHQvLyBodHRwczovL2RyYWZ0cy5jc3N3Zy5vcmcvY3Nzb20vI2VzY2FwZS1hLWNoYXJhY3RlclxuXHRcdFx0cmVzdWx0ICs9ICdcXFxcJyArIHN0cmluZy5jaGFyQXQoaW5kZXgpO1xuXG5cdFx0fVxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH07XG5cblx0aWYgKCFyb290LkNTUykge1xuXHRcdHJvb3QuQ1NTID0ge307XG5cdH1cblxuXHRyb290LkNTUy5lc2NhcGUgPSBjc3NFc2NhcGU7XG5cdHJldHVybiBjc3NFc2NhcGU7XG5cbn0pKTtcbiIsImltcG9ydCBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9pbnRlcmFjdGlvbi1ldmVudHMnO1xuXG5pbXBvcnQgRGlyZWN0RWRpdGluZyBmcm9tICcuL2xpYi9EaXJlY3RFZGl0aW5nJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIEludGVyYWN0aW9uRXZlbnRzTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdkaXJlY3RFZGl0aW5nJyBdLFxuICBkaXJlY3RFZGl0aW5nOiBbICd0eXBlJywgRGlyZWN0RWRpdGluZyBdXG59OyIsImltcG9ydCB7XG4gIGJpbmQsXG4gIGZpbmRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgVGV4dEJveCBmcm9tICcuL1RleHRCb3gnO1xuXG5cbi8qKlxuICogQSBkaXJlY3QgZWRpdGluZyBjb21wb25lbnQgdGhhdCBhbGxvd3MgdXNlcnNcbiAqIHRvIGVkaXQgYW4gZWxlbWVudHMgdGV4dCBkaXJlY3RseSBpbiB0aGUgZGlhZ3JhbVxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzIHRoZSBldmVudCBidXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRGlyZWN0RWRpdGluZyhldmVudEJ1cywgY2FudmFzKSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcblxuICB0aGlzLl9wcm92aWRlcnMgPSBbXTtcbiAgdGhpcy5fdGV4dGJveCA9IG5ldyBUZXh0Qm94KHtcbiAgICBjb250YWluZXI6IGNhbnZhcy5nZXRDb250YWluZXIoKSxcbiAgICBrZXlIYW5kbGVyOiBiaW5kKHRoaXMuX2hhbmRsZUtleSwgdGhpcyksXG4gICAgcmVzaXplSGFuZGxlcjogYmluZCh0aGlzLl9oYW5kbGVSZXNpemUsIHRoaXMpXG4gIH0pO1xufVxuXG5EaXJlY3RFZGl0aW5nLiRpbmplY3QgPSBbICdldmVudEJ1cycsICdjYW52YXMnIF07XG5cblxuLyoqXG4gKiBSZWdpc3RlciBhIGRpcmVjdCBlZGl0aW5nIHByb3ZpZGVyXG5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm92aWRlciB0aGUgcHJvdmlkZXIsIG11c3QgZXhwb3NlIGFuICNhY3RpdmF0ZShlbGVtZW50KSBtZXRob2QgdGhhdCByZXR1cm5zXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgYW4gYWN0aXZhdGlvbiBjb250ZXh0ICh7IGJvdW5kczoge3gsIHksIHdpZHRoLCBoZWlnaHQgfSwgdGV4dCB9KSBpZlxuICogICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdCBlZGl0aW5nIGlzIGF2YWlsYWJsZSBmb3IgdGhlIGdpdmVuIGVsZW1lbnQuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkaXRpb25hbGx5IHRoZSBwcm92aWRlciBtdXN0IGV4cG9zZSBhICN1cGRhdGUoZWxlbWVudCwgdmFsdWUpIG1ldGhvZFxuICogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIHJlY2VpdmUgZGlyZWN0IGVkaXRpbmcgdXBkYXRlcy5cbiAqL1xuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUucmVnaXN0ZXJQcm92aWRlciA9IGZ1bmN0aW9uKHByb3ZpZGVyKSB7XG4gIHRoaXMuX3Byb3ZpZGVycy5wdXNoKHByb3ZpZGVyKTtcbn07XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgZGlyZWN0IGVkaXRpbmcgaXMgY3VycmVudGx5IGFjdGl2ZVxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbkRpcmVjdEVkaXRpbmcucHJvdG90eXBlLmlzQWN0aXZlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAhIXRoaXMuX2FjdGl2ZTtcbn07XG5cblxuLyoqXG4gKiBDYW5jZWwgZGlyZWN0IGVkaXRpbmcsIGlmIGl0IGlzIGN1cnJlbnRseSBhY3RpdmVcbiAqL1xuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUuY2FuY2VsID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5fYWN0aXZlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fZmlyZSgnY2FuY2VsJyk7XG4gIHRoaXMuY2xvc2UoKTtcbn07XG5cblxuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUuX2ZpcmUgPSBmdW5jdGlvbihldmVudCwgY29udGV4dCkge1xuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdkaXJlY3RFZGl0aW5nLicgKyBldmVudCwgY29udGV4dCB8fCB7IGFjdGl2ZTogdGhpcy5fYWN0aXZlIH0pO1xufTtcblxuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fdGV4dGJveC5kZXN0cm95KCk7XG5cbiAgdGhpcy5fZmlyZSgnZGVhY3RpdmF0ZScpO1xuXG4gIHRoaXMuX2FjdGl2ZSA9IG51bGw7XG5cbiAgdGhpcy5yZXNpemFibGUgPSB1bmRlZmluZWQ7XG59O1xuXG5cbkRpcmVjdEVkaXRpbmcucHJvdG90eXBlLmNvbXBsZXRlID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIGFjdGl2ZSA9IHRoaXMuX2FjdGl2ZTtcblxuICBpZiAoIWFjdGl2ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBjb250YWluZXJCb3VuZHMsXG4gICAgICBwcmV2aW91c0JvdW5kcyA9IGFjdGl2ZS5jb250ZXh0LmJvdW5kcyxcbiAgICAgIG5ld0JvdW5kcyA9IHRoaXMuJHRleHRib3guZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICBuZXdUZXh0ID0gdGhpcy5nZXRWYWx1ZSgpLFxuICAgICAgcHJldmlvdXNUZXh0ID0gYWN0aXZlLmNvbnRleHQudGV4dDtcblxuICBpZiAoXG4gICAgbmV3VGV4dCAhPT0gcHJldmlvdXNUZXh0IHx8XG4gICAgbmV3Qm91bmRzLmhlaWdodCAhPT0gcHJldmlvdXNCb3VuZHMuaGVpZ2h0IHx8XG4gICAgbmV3Qm91bmRzLndpZHRoICE9PSBwcmV2aW91c0JvdW5kcy53aWR0aFxuICApIHtcbiAgICBjb250YWluZXJCb3VuZHMgPSB0aGlzLl90ZXh0Ym94LmNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGFjdGl2ZS5wcm92aWRlci51cGRhdGUoYWN0aXZlLmVsZW1lbnQsIG5ld1RleHQsIGFjdGl2ZS5jb250ZXh0LnRleHQsIHtcbiAgICAgIHg6IG5ld0JvdW5kcy5sZWZ0IC0gY29udGFpbmVyQm91bmRzLmxlZnQsXG4gICAgICB5OiBuZXdCb3VuZHMudG9wIC0gY29udGFpbmVyQm91bmRzLnRvcCxcbiAgICAgIHdpZHRoOiBuZXdCb3VuZHMud2lkdGgsXG4gICAgICBoZWlnaHQ6IG5ld0JvdW5kcy5oZWlnaHRcbiAgICB9KTtcbiAgfVxuXG4gIHRoaXMuX2ZpcmUoJ2NvbXBsZXRlJyk7XG5cbiAgdGhpcy5jbG9zZSgpO1xufTtcblxuXG5EaXJlY3RFZGl0aW5nLnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fdGV4dGJveC5nZXRWYWx1ZSgpO1xufTtcblxuXG5EaXJlY3RFZGl0aW5nLnByb3RvdHlwZS5faGFuZGxlS2V5ID0gZnVuY3Rpb24oZSkge1xuXG4gIC8vIHN0b3AgYnViYmxlXG4gIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgdmFyIGtleSA9IGUua2V5Q29kZSB8fCBlLmNoYXJDb2RlO1xuXG4gIC8vIEVTQ1xuICBpZiAoa2V5ID09PSAyNykge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICByZXR1cm4gdGhpcy5jYW5jZWwoKTtcbiAgfVxuXG4gIC8vIEVudGVyXG4gIGlmIChrZXkgPT09IDEzICYmICFlLnNoaWZ0S2V5KSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHJldHVybiB0aGlzLmNvbXBsZXRlKCk7XG4gIH1cbn07XG5cblxuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUuX2hhbmRsZVJlc2l6ZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2ZpcmUoJ3Jlc2l6ZScsIGV2ZW50KTtcbn07XG5cblxuLyoqXG4gKiBBY3RpdmF0ZSBkaXJlY3QgZWRpdGluZyBvbiB0aGUgZ2l2ZW4gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBFbGVtZW50RGVzY3JpcHRvciB0aGUgZGVzY3JpcHRvciBmb3IgYSBzaGFwZSBvciBjb25uZWN0aW9uXG4gKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHRoZSBhY3RpdmF0aW9uIHdhcyBwb3NzaWJsZVxuICovXG5EaXJlY3RFZGl0aW5nLnByb3RvdHlwZS5hY3RpdmF0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgaWYgKHRoaXMuaXNBY3RpdmUoKSkge1xuICAgIHRoaXMuY2FuY2VsKCk7XG4gIH1cblxuICAvLyB0aGUgZGlyZWN0IGVkaXRpbmcgY29udGV4dFxuICB2YXIgY29udGV4dDtcblxuICB2YXIgcHJvdmlkZXIgPSBmaW5kKHRoaXMuX3Byb3ZpZGVycywgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAoY29udGV4dCA9IHAuYWN0aXZhdGUoZWxlbWVudCkpID8gcCA6IG51bGw7XG4gIH0pO1xuXG4gIC8vIGNoZWNrIGlmIGFjdGl2YXRpb24gdG9vayBwbGFjZVxuICBpZiAoY29udGV4dCkge1xuICAgIHRoaXMuJHRleHRib3ggPSB0aGlzLl90ZXh0Ym94LmNyZWF0ZShcbiAgICAgIGNvbnRleHQuYm91bmRzLFxuICAgICAgY29udGV4dC5zdHlsZSxcbiAgICAgIGNvbnRleHQudGV4dCxcbiAgICAgIGNvbnRleHQub3B0aW9uc1xuICAgICk7XG5cbiAgICB0aGlzLl9hY3RpdmUgPSB7XG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgIHByb3ZpZGVyOiBwcm92aWRlclxuICAgIH07XG5cbiAgICBpZiAoY29udGV4dC5vcHRpb25zICYmIGNvbnRleHQub3B0aW9ucy5yZXNpemFibGUpIHtcbiAgICAgIHRoaXMucmVzaXphYmxlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLl9maXJlKCdhY3RpdmF0ZScpO1xuICB9XG5cbiAgcmV0dXJuICEhY29udGV4dDtcbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGJpbmQsXG4gIHBpY2tcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBkb21pZnksXG4gIHF1ZXJ5IGFzIGRvbVF1ZXJ5LFxuICBldmVudCBhcyBkb21FdmVudCxcbiAgcmVtb3ZlIGFzIGRvbVJlbW92ZVxufSBmcm9tICdtaW4tZG9tJztcblxudmFyIG1pbiA9IE1hdGgubWluLFxuICAgIG1heCA9IE1hdGgubWF4O1xuXG5mdW5jdGlvbiBwcmV2ZW50RGVmYXVsdChlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbn1cblxuZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKGUpIHtcbiAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbn1cblxuZnVuY3Rpb24gaXNUZXh0Tm9kZShub2RlKSB7XG4gIHJldHVybiBub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERTtcbn1cblxuZnVuY3Rpb24gdG9BcnJheShub2RlTGlzdCkge1xuICByZXR1cm4gW10uc2xpY2UuY2FsbChub2RlTGlzdCk7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYSBjb250YWluZXIgZm9yIGEgY29udGVudCBlZGl0YWJsZSBkaXYuXG4gKlxuICogU3RydWN0dXJlOlxuICpcbiAqIGNvbnRhaW5lclxuICogICBwYXJlbnRcbiAqICAgICBjb250ZW50XG4gKiAgICAgcmVzaXplLWhhbmRsZVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IG9wdGlvbnMuY29udGFpbmVyIFRoZSBET00gZWxlbWVudCB0byBhcHBlbmQgdGhlIGNvbnRlbnRDb250YWluZXIgdG9cbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdGlvbnMua2V5SGFuZGxlciBIYW5kbGVyIGZvciBrZXkgZXZlbnRzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcHRpb25zLnJlc2l6ZUhhbmRsZXIgSGFuZGxlciBmb3IgcmVzaXplIGV2ZW50c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBUZXh0Qm94KG9wdGlvbnMpIHtcbiAgdGhpcy5jb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lcjtcblxuICB0aGlzLnBhcmVudCA9IGRvbWlmeShcbiAgICAnPGRpdiBjbGFzcz1cImRqcy1kaXJlY3QtZWRpdGluZy1wYXJlbnRcIj4nICtcbiAgICAgICc8ZGl2IGNsYXNzPVwiZGpzLWRpcmVjdC1lZGl0aW5nLWNvbnRlbnRcIiBjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCI+PC9kaXY+JyArXG4gICAgJzwvZGl2PidcbiAgKTtcblxuICB0aGlzLmNvbnRlbnQgPSBkb21RdWVyeSgnW2NvbnRlbnRlZGl0YWJsZV0nLCB0aGlzLnBhcmVudCk7XG5cbiAgdGhpcy5rZXlIYW5kbGVyID0gb3B0aW9ucy5rZXlIYW5kbGVyIHx8IGZ1bmN0aW9uKCkge307XG4gIHRoaXMucmVzaXplSGFuZGxlciA9IG9wdGlvbnMucmVzaXplSGFuZGxlciB8fCBmdW5jdGlvbigpIHt9O1xuXG4gIHRoaXMuYXV0b1Jlc2l6ZSA9IGJpbmQodGhpcy5hdXRvUmVzaXplLCB0aGlzKTtcbiAgdGhpcy5oYW5kbGVQYXN0ZSA9IGJpbmQodGhpcy5oYW5kbGVQYXN0ZSwgdGhpcyk7XG59XG5cblxuLyoqXG4gKiBDcmVhdGUgYSB0ZXh0IGJveCB3aXRoIHRoZSBnaXZlbiBwb3NpdGlvbiwgc2l6ZSwgc3R5bGUgYW5kIHRleHQgY29udGVudFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBib3VuZHNcbiAqIEBwYXJhbSB7TnVtYmVyfSBib3VuZHMueCBhYnNvbHV0ZSB4IHBvc2l0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYm91bmRzLnkgYWJzb2x1dGUgeSBwb3NpdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IFtib3VuZHMud2lkdGhdIGZpeGVkIHdpZHRoIHZhbHVlXG4gKiBAcGFyYW0ge051bWJlcn0gW2JvdW5kcy5oZWlnaHRdIGZpeGVkIGhlaWdodCB2YWx1ZVxuICogQHBhcmFtIHtOdW1iZXJ9IFtib3VuZHMubWF4V2lkdGhdIG1heGltdW0gd2lkdGggdmFsdWVcbiAqIEBwYXJhbSB7TnVtYmVyfSBbYm91bmRzLm1heEhlaWdodF0gbWF4aW11bSBoZWlnaHQgdmFsdWVcbiAqIEBwYXJhbSB7TnVtYmVyfSBbYm91bmRzLm1pbldpZHRoXSBtaW5pbXVtIHdpZHRoIHZhbHVlXG4gKiBAcGFyYW0ge051bWJlcn0gW2JvdW5kcy5taW5IZWlnaHRdIG1pbmltdW0gaGVpZ2h0IHZhbHVlXG4gKiBAcGFyYW0ge09iamVjdH0gW3N0eWxlXVxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlIHRleHQgY29udGVudFxuICpcbiAqIEByZXR1cm4ge0RPTUVsZW1lbnR9IFRoZSBjcmVhdGVkIGNvbnRlbnQgRE9NIGVsZW1lbnRcbiAqL1xuVGV4dEJveC5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24oYm91bmRzLCBzdHlsZSwgdmFsdWUsIG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudCxcbiAgICAgIGNvbnRlbnQgPSB0aGlzLmNvbnRlbnQsXG4gICAgICBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lcjtcblxuICBvcHRpb25zID0gdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICBzdHlsZSA9IHRoaXMuc3R5bGUgPSBzdHlsZSB8fCB7fTtcblxuICB2YXIgcGFyZW50U3R5bGUgPSBwaWNrKHN0eWxlLCBbXG4gICAgJ3dpZHRoJyxcbiAgICAnaGVpZ2h0JyxcbiAgICAnbWF4V2lkdGgnLFxuICAgICdtYXhIZWlnaHQnLFxuICAgICdtaW5XaWR0aCcsXG4gICAgJ21pbkhlaWdodCcsXG4gICAgJ2xlZnQnLFxuICAgICd0b3AnLFxuICAgICdiYWNrZ3JvdW5kQ29sb3InLFxuICAgICdwb3NpdGlvbicsXG4gICAgJ292ZXJmbG93JyxcbiAgICAnYm9yZGVyJyxcbiAgICAnd29yZFdyYXAnLFxuICAgICd0ZXh0QWxpZ24nLFxuICAgICdvdXRsaW5lJyxcbiAgICAndHJhbnNmb3JtJ1xuICBdKTtcblxuICBhc3NpZ24ocGFyZW50LnN0eWxlLCB7XG4gICAgd2lkdGg6IGJvdW5kcy53aWR0aCArICdweCcsXG4gICAgaGVpZ2h0OiBib3VuZHMuaGVpZ2h0ICsgJ3B4JyxcbiAgICBtYXhXaWR0aDogYm91bmRzLm1heFdpZHRoICsgJ3B4JyxcbiAgICBtYXhIZWlnaHQ6IGJvdW5kcy5tYXhIZWlnaHQgKyAncHgnLFxuICAgIG1pbldpZHRoOiBib3VuZHMubWluV2lkdGggKyAncHgnLFxuICAgIG1pbkhlaWdodDogYm91bmRzLm1pbkhlaWdodCArICdweCcsXG4gICAgbGVmdDogYm91bmRzLnggKyAncHgnLFxuICAgIHRvcDogYm91bmRzLnkgKyAncHgnLFxuICAgIGJhY2tncm91bmRDb2xvcjogJyNmZmZmZmYnLFxuICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgIG92ZXJmbG93OiAndmlzaWJsZScsXG4gICAgYm9yZGVyOiAnMXB4IHNvbGlkICNjY2MnLFxuICAgIGJveFNpemluZzogJ2JvcmRlci1ib3gnLFxuICAgIHdvcmRXcmFwOiAnbm9ybWFsJyxcbiAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgIG91dGxpbmU6ICdub25lJ1xuICB9LCBwYXJlbnRTdHlsZSk7XG5cbiAgdmFyIGNvbnRlbnRTdHlsZSA9IHBpY2soc3R5bGUsIFtcbiAgICAnZm9udEZhbWlseScsXG4gICAgJ2ZvbnRTaXplJyxcbiAgICAnZm9udFdlaWdodCcsXG4gICAgJ2xpbmVIZWlnaHQnLFxuICAgICdwYWRkaW5nJyxcbiAgICAncGFkZGluZ1RvcCcsXG4gICAgJ3BhZGRpbmdSaWdodCcsXG4gICAgJ3BhZGRpbmdCb3R0b20nLFxuICAgICdwYWRkaW5nTGVmdCdcbiAgXSk7XG5cbiAgYXNzaWduKGNvbnRlbnQuc3R5bGUsIHtcbiAgICBib3hTaXppbmc6ICdib3JkZXItYm94JyxcbiAgICB3aWR0aDogJzEwMCUnLFxuICAgIG91dGxpbmU6ICdub25lJyxcbiAgICB3b3JkV3JhcDogJ2JyZWFrLXdvcmQnXG4gIH0sIGNvbnRlbnRTdHlsZSk7XG5cbiAgaWYgKG9wdGlvbnMuY2VudGVyVmVydGljYWxseSkge1xuICAgIGFzc2lnbihjb250ZW50LnN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIHRvcDogJzUwJScsXG4gICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGUoMCwgLTUwJSknXG4gICAgfSwgY29udGVudFN0eWxlKTtcbiAgfVxuXG4gIGNvbnRlbnQuaW5uZXJUZXh0ID0gdmFsdWU7XG5cbiAgZG9tRXZlbnQuYmluZChjb250ZW50LCAna2V5ZG93bicsIHRoaXMua2V5SGFuZGxlcik7XG4gIGRvbUV2ZW50LmJpbmQoY29udGVudCwgJ21vdXNlZG93bicsIHN0b3BQcm9wYWdhdGlvbik7XG4gIGRvbUV2ZW50LmJpbmQoY29udGVudCwgJ3Bhc3RlJywgc2VsZi5oYW5kbGVQYXN0ZSk7XG5cbiAgaWYgKG9wdGlvbnMuYXV0b1Jlc2l6ZSkge1xuICAgIGRvbUV2ZW50LmJpbmQoY29udGVudCwgJ2lucHV0JywgdGhpcy5hdXRvUmVzaXplKTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLnJlc2l6YWJsZSkge1xuICAgIHRoaXMucmVzaXphYmxlKHN0eWxlKTtcbiAgfVxuXG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChwYXJlbnQpO1xuXG4gIC8vIHNldCBzZWxlY3Rpb24gdG8gZW5kIG9mIHRleHRcbiAgdGhpcy5zZXRTZWxlY3Rpb24oY29udGVudC5sYXN0Q2hpbGQsIGNvbnRlbnQubGFzdENoaWxkICYmIGNvbnRlbnQubGFzdENoaWxkLmxlbmd0aCk7XG5cbiAgcmV0dXJuIHBhcmVudDtcbn07XG5cbi8qKlxuICogSW50ZXJjZXB0IHBhc3RlIGV2ZW50cyB0byByZW1vdmUgZm9ybWF0dGluZyBmcm9tIHBhc3RlZCB0ZXh0LlxuICovXG5UZXh0Qm94LnByb3RvdHlwZS5oYW5kbGVQYXN0ZSA9IGZ1bmN0aW9uKGUpIHtcbiAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG4gICAgICBzdHlsZSA9IHRoaXMuc3R5bGU7XG5cbiAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gIHZhciB0ZXh0O1xuXG4gIGlmIChlLmNsaXBib2FyZERhdGEpIHtcblxuICAgIC8vIENocm9tZSwgRmlyZWZveCwgU2FmYXJpXG4gICAgdGV4dCA9IGUuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7XG4gIH0gZWxzZSB7XG5cbiAgICAvLyBJbnRlcm5ldCBFeHBsb3JlclxuICAgIHRleHQgPSB3aW5kb3cuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCdUZXh0Jyk7XG4gIH1cblxuICB0aGlzLmluc2VydFRleHQodGV4dCk7XG5cbiAgaWYgKG9wdGlvbnMuYXV0b1Jlc2l6ZSkge1xuICAgIHZhciBoYXNSZXNpemVkID0gdGhpcy5hdXRvUmVzaXplKHN0eWxlKTtcblxuICAgIGlmIChoYXNSZXNpemVkKSB7XG4gICAgICB0aGlzLnJlc2l6ZUhhbmRsZXIoaGFzUmVzaXplZCk7XG4gICAgfVxuICB9XG59O1xuXG5UZXh0Qm94LnByb3RvdHlwZS5pbnNlcnRUZXh0ID0gZnVuY3Rpb24odGV4dCkge1xuXG4gIC8vIGluc2VydFRleHQgY29tbWFuZCBub3Qgc3VwcG9ydGVkIGJ5IEludGVybmV0IEV4cGxvcmVyXG4gIHZhciBzdWNjZXNzID0gZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2luc2VydFRleHQnLCBmYWxzZSwgdGV4dCk7XG5cbiAgaWYgKHN1Y2Nlc3MpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9pbnNlcnRUZXh0SUUodGV4dCk7XG59O1xuXG5UZXh0Qm94LnByb3RvdHlwZS5faW5zZXJ0VGV4dElFID0gZnVuY3Rpb24odGV4dCkge1xuXG4gIC8vIEludGVybmV0IEV4cGxvcmVyXG4gIHZhciByYW5nZSA9IHRoaXMuZ2V0U2VsZWN0aW9uKCksXG4gICAgICBzdGFydENvbnRhaW5lciA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgZW5kQ29udGFpbmVyID0gcmFuZ2UuZW5kQ29udGFpbmVyLFxuICAgICAgc3RhcnRPZmZzZXQgPSByYW5nZS5zdGFydE9mZnNldCxcbiAgICAgIGVuZE9mZnNldCA9IHJhbmdlLmVuZE9mZnNldCxcbiAgICAgIGNvbW1vbkFuY2VzdG9yQ29udGFpbmVyID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXI7XG5cbiAgdmFyIGNoaWxkTm9kZXNBcnJheSA9IHRvQXJyYXkoY29tbW9uQW5jZXN0b3JDb250YWluZXIuY2hpbGROb2Rlcyk7XG5cbiAgdmFyIGNvbnRhaW5lcixcbiAgICAgIG9mZnNldDtcblxuICBpZiAoaXNUZXh0Tm9kZShjb21tb25BbmNlc3RvckNvbnRhaW5lcikpIHtcbiAgICB2YXIgY29udGFpbmVyVGV4dENvbnRlbnQgPSBzdGFydENvbnRhaW5lci50ZXh0Q29udGVudDtcblxuICAgIHN0YXJ0Q29udGFpbmVyLnRleHRDb250ZW50ID1cbiAgICAgIGNvbnRhaW5lclRleHRDb250ZW50LnN1YnN0cmluZygwLCBzdGFydE9mZnNldClcbiAgICAgICsgdGV4dFxuICAgICAgKyBjb250YWluZXJUZXh0Q29udGVudC5zdWJzdHJpbmcoZW5kT2Zmc2V0KTtcblxuICAgIGNvbnRhaW5lciA9IHN0YXJ0Q29udGFpbmVyO1xuICAgIG9mZnNldCA9IHN0YXJ0T2Zmc2V0ICsgdGV4dC5sZW5ndGg7XG5cbiAgfSBlbHNlIGlmIChzdGFydENvbnRhaW5lciA9PT0gdGhpcy5jb250ZW50ICYmIGVuZENvbnRhaW5lciA9PT0gdGhpcy5jb250ZW50KSB7XG4gICAgdmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dCk7XG5cbiAgICB0aGlzLmNvbnRlbnQuaW5zZXJ0QmVmb3JlKHRleHROb2RlLCBjaGlsZE5vZGVzQXJyYXlbc3RhcnRPZmZzZXRdKTtcblxuICAgIGNvbnRhaW5lciA9IHRleHROb2RlO1xuICAgIG9mZnNldCA9IHRleHROb2RlLnRleHRDb250ZW50Lmxlbmd0aDtcbiAgfSBlbHNlIHtcbiAgICB2YXIgc3RhcnRDb250YWluZXJDaGlsZEluZGV4ID0gY2hpbGROb2Rlc0FycmF5LmluZGV4T2Yoc3RhcnRDb250YWluZXIpLFxuICAgICAgICBlbmRDb250YWluZXJDaGlsZEluZGV4ID0gY2hpbGROb2Rlc0FycmF5LmluZGV4T2YoZW5kQ29udGFpbmVyKTtcblxuICAgIGNoaWxkTm9kZXNBcnJheS5mb3JFYWNoKGZ1bmN0aW9uKGNoaWxkTm9kZSwgaW5kZXgpIHtcblxuICAgICAgaWYgKGluZGV4ID09PSBzdGFydENvbnRhaW5lckNoaWxkSW5kZXgpIHtcbiAgICAgICAgY2hpbGROb2RlLnRleHRDb250ZW50ID1cbiAgICAgICAgICBzdGFydENvbnRhaW5lci50ZXh0Q29udGVudC5zdWJzdHJpbmcoMCwgc3RhcnRPZmZzZXQpICtcbiAgICAgICAgICB0ZXh0ICtcbiAgICAgICAgICBlbmRDb250YWluZXIudGV4dENvbnRlbnQuc3Vic3RyaW5nKGVuZE9mZnNldCk7XG4gICAgICB9IGVsc2UgaWYgKGluZGV4ID4gc3RhcnRDb250YWluZXJDaGlsZEluZGV4ICYmIGluZGV4IDw9IGVuZENvbnRhaW5lckNoaWxkSW5kZXgpIHtcbiAgICAgICAgZG9tUmVtb3ZlKGNoaWxkTm9kZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb250YWluZXIgPSBzdGFydENvbnRhaW5lcjtcbiAgICBvZmZzZXQgPSBzdGFydE9mZnNldCArIHRleHQubGVuZ3RoO1xuICB9XG5cbiAgaWYgKGNvbnRhaW5lciAmJiBvZmZzZXQgIT09IHVuZGVmaW5lZCkge1xuXG4gICAgLy8gaXMgbmVjZXNzYXJ5IGluIEludGVybmV0IEV4cGxvcmVyXG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYuc2V0U2VsZWN0aW9uKGNvbnRhaW5lciwgb2Zmc2V0KTtcbiAgICB9KTtcbiAgfVxufTtcblxuLyoqXG4gKiBBdXRvbWF0aWNhbGx5IHJlc2l6ZSBlbGVtZW50IHZlcnRpY2FsbHkgdG8gZml0IGl0cyBjb250ZW50LlxuICovXG5UZXh0Qm94LnByb3RvdHlwZS5hdXRvUmVzaXplID0gZnVuY3Rpb24oKSB7XG4gIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudCxcbiAgICAgIGNvbnRlbnQgPSB0aGlzLmNvbnRlbnQ7XG5cbiAgdmFyIGZvbnRTaXplID0gcGFyc2VJbnQodGhpcy5zdHlsZS5mb250U2l6ZSkgfHwgMTI7XG5cbiAgaWYgKGNvbnRlbnQuc2Nyb2xsSGVpZ2h0ID4gcGFyZW50Lm9mZnNldEhlaWdodCB8fFxuICAgICAgY29udGVudC5zY3JvbGxIZWlnaHQgPCBwYXJlbnQub2Zmc2V0SGVpZ2h0IC0gZm9udFNpemUpIHtcbiAgICB2YXIgYm91bmRzID0gcGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgdmFyIGhlaWdodCA9IGNvbnRlbnQuc2Nyb2xsSGVpZ2h0O1xuICAgIHBhcmVudC5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyAncHgnO1xuXG4gICAgdGhpcy5yZXNpemVIYW5kbGVyKHtcbiAgICAgIHdpZHRoOiBib3VuZHMud2lkdGgsXG4gICAgICBoZWlnaHQ6IGJvdW5kcy5oZWlnaHQsXG4gICAgICBkeDogMCxcbiAgICAgIGR5OiBoZWlnaHQgLSBib3VuZHMuaGVpZ2h0XG4gICAgfSk7XG4gIH1cbn07XG5cbi8qKlxuICogTWFrZSBhbiBlbGVtZW50IHJlc2l6YWJsZSBieSBhZGRpbmcgYSByZXNpemUgaGFuZGxlLlxuICovXG5UZXh0Qm94LnByb3RvdHlwZS5yZXNpemFibGUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudCxcbiAgICAgIHJlc2l6ZUhhbmRsZSA9IHRoaXMucmVzaXplSGFuZGxlO1xuXG4gIHZhciBtaW5XaWR0aCA9IHBhcnNlSW50KHRoaXMuc3R5bGUubWluV2lkdGgpIHx8IDAsXG4gICAgICBtaW5IZWlnaHQgPSBwYXJzZUludCh0aGlzLnN0eWxlLm1pbkhlaWdodCkgfHwgMCxcbiAgICAgIG1heFdpZHRoID0gcGFyc2VJbnQodGhpcy5zdHlsZS5tYXhXaWR0aCkgfHwgSW5maW5pdHksXG4gICAgICBtYXhIZWlnaHQgPSBwYXJzZUludCh0aGlzLnN0eWxlLm1heEhlaWdodCkgfHwgSW5maW5pdHk7XG5cbiAgaWYgKCFyZXNpemVIYW5kbGUpIHtcbiAgICByZXNpemVIYW5kbGUgPSB0aGlzLnJlc2l6ZUhhbmRsZSA9IGRvbWlmeShcbiAgICAgICc8ZGl2IGNsYXNzPVwiZGpzLWRpcmVjdC1lZGl0aW5nLXJlc2l6ZS1oYW5kbGVcIj48L2Rpdj4nXG4gICAgKTtcblxuICAgIHZhciBzdGFydFgsIHN0YXJ0WSwgc3RhcnRXaWR0aCwgc3RhcnRIZWlnaHQ7XG5cbiAgICB2YXIgb25Nb3VzZURvd24gPSBmdW5jdGlvbihlKSB7XG4gICAgICBwcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIHN0b3BQcm9wYWdhdGlvbihlKTtcblxuICAgICAgc3RhcnRYID0gZS5jbGllbnRYO1xuICAgICAgc3RhcnRZID0gZS5jbGllbnRZO1xuXG4gICAgICB2YXIgYm91bmRzID0gcGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgICBzdGFydFdpZHRoID0gYm91bmRzLndpZHRoO1xuICAgICAgc3RhcnRIZWlnaHQgPSBib3VuZHMuaGVpZ2h0O1xuXG4gICAgICBkb21FdmVudC5iaW5kKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgb25Nb3VzZU1vdmUpO1xuICAgICAgZG9tRXZlbnQuYmluZChkb2N1bWVudCwgJ21vdXNldXAnLCBvbk1vdXNlVXApO1xuICAgIH07XG5cbiAgICB2YXIgb25Nb3VzZU1vdmUgPSBmdW5jdGlvbihlKSB7XG4gICAgICBwcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIHN0b3BQcm9wYWdhdGlvbihlKTtcblxuICAgICAgdmFyIG5ld1dpZHRoID0gbWluKG1heChzdGFydFdpZHRoICsgZS5jbGllbnRYIC0gc3RhcnRYLCBtaW5XaWR0aCksIG1heFdpZHRoKTtcbiAgICAgIHZhciBuZXdIZWlnaHQgPSBtaW4obWF4KHN0YXJ0SGVpZ2h0ICsgZS5jbGllbnRZIC0gc3RhcnRZLCBtaW5IZWlnaHQpLCBtYXhIZWlnaHQpO1xuXG4gICAgICBwYXJlbnQuc3R5bGUud2lkdGggPSBuZXdXaWR0aCArICdweCc7XG4gICAgICBwYXJlbnQuc3R5bGUuaGVpZ2h0ID0gbmV3SGVpZ2h0ICsgJ3B4JztcblxuICAgICAgc2VsZi5yZXNpemVIYW5kbGVyKHtcbiAgICAgICAgd2lkdGg6IHN0YXJ0V2lkdGgsXG4gICAgICAgIGhlaWdodDogc3RhcnRIZWlnaHQsXG4gICAgICAgIGR4OiBlLmNsaWVudFggLSBzdGFydFgsXG4gICAgICAgIGR5OiBlLmNsaWVudFkgLSBzdGFydFlcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICB2YXIgb25Nb3VzZVVwID0gZnVuY3Rpb24oZSkge1xuICAgICAgcHJldmVudERlZmF1bHQoZSk7XG4gICAgICBzdG9wUHJvcGFnYXRpb24oZSk7XG5cbiAgICAgIGRvbUV2ZW50LnVuYmluZChkb2N1bWVudCwnbW91c2Vtb3ZlJywgb25Nb3VzZU1vdmUsIGZhbHNlKTtcbiAgICAgIGRvbUV2ZW50LnVuYmluZChkb2N1bWVudCwgJ21vdXNldXAnLCBvbk1vdXNlVXAsIGZhbHNlKTtcbiAgICB9O1xuXG4gICAgZG9tRXZlbnQuYmluZChyZXNpemVIYW5kbGUsICdtb3VzZWRvd24nLCBvbk1vdXNlRG93bik7XG4gIH1cblxuICBhc3NpZ24ocmVzaXplSGFuZGxlLnN0eWxlLCB7XG4gICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgYm90dG9tOiAnMHB4JyxcbiAgICByaWdodDogJzBweCcsXG4gICAgY3Vyc29yOiAnbndzZS1yZXNpemUnLFxuICAgIHdpZHRoOiAnMCcsXG4gICAgaGVpZ2h0OiAnMCcsXG4gICAgYm9yZGVyVG9wOiAocGFyc2VJbnQodGhpcy5zdHlsZS5mb250U2l6ZSkgLyA0IHx8IDMpICsgJ3B4IHNvbGlkIHRyYW5zcGFyZW50JyxcbiAgICBib3JkZXJSaWdodDogKHBhcnNlSW50KHRoaXMuc3R5bGUuZm9udFNpemUpIC8gNCB8fCAzKSArICdweCBzb2xpZCAjY2NjJyxcbiAgICBib3JkZXJCb3R0b206IChwYXJzZUludCh0aGlzLnN0eWxlLmZvbnRTaXplKSAvIDQgfHwgMykgKyAncHggc29saWQgI2NjYycsXG4gICAgYm9yZGVyTGVmdDogKHBhcnNlSW50KHRoaXMuc3R5bGUuZm9udFNpemUpIC8gNCB8fCAzKSArICdweCBzb2xpZCB0cmFuc3BhcmVudCdcbiAgfSk7XG5cbiAgcGFyZW50LmFwcGVuZENoaWxkKHJlc2l6ZUhhbmRsZSk7XG59O1xuXG5cbi8qKlxuICogQ2xlYXIgY29udGVudCBhbmQgc3R5bGUgb2YgdGhlIHRleHRib3gsIHVuYmluZCBsaXN0ZW5lcnMgYW5kXG4gKiByZXNldCBDU1Mgc3R5bGUuXG4gKi9cblRleHRCb3gucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50LFxuICAgICAgY29udGVudCA9IHRoaXMuY29udGVudCxcbiAgICAgIHJlc2l6ZUhhbmRsZSA9IHRoaXMucmVzaXplSGFuZGxlO1xuXG4gIC8vIGNsZWFyIGNvbnRlbnRcbiAgY29udGVudC5pbm5lclRleHQgPSAnJztcblxuICAvLyBjbGVhciBzdHlsZXNcbiAgcGFyZW50LnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTtcbiAgY29udGVudC5yZW1vdmVBdHRyaWJ1dGUoJ3N0eWxlJyk7XG5cbiAgZG9tRXZlbnQudW5iaW5kKGNvbnRlbnQsICdrZXlkb3duJywgdGhpcy5rZXlIYW5kbGVyKTtcbiAgZG9tRXZlbnQudW5iaW5kKGNvbnRlbnQsICdtb3VzZWRvd24nLCBzdG9wUHJvcGFnYXRpb24pO1xuICBkb21FdmVudC51bmJpbmQoY29udGVudCwgJ2lucHV0JywgdGhpcy5hdXRvUmVzaXplKTtcbiAgZG9tRXZlbnQudW5iaW5kKGNvbnRlbnQsICdwYXN0ZScsIHRoaXMuaGFuZGxlUGFzdGUpO1xuXG4gIGlmIChyZXNpemVIYW5kbGUpIHtcbiAgICByZXNpemVIYW5kbGUucmVtb3ZlQXR0cmlidXRlKCdzdHlsZScpO1xuXG4gICAgZG9tUmVtb3ZlKHJlc2l6ZUhhbmRsZSk7XG4gIH1cblxuICBkb21SZW1vdmUocGFyZW50KTtcbn07XG5cblxuVGV4dEJveC5wcm90b3R5cGUuZ2V0VmFsdWUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuY29udGVudC5pbm5lclRleHQudHJpbSgpO1xufTtcblxuXG5UZXh0Qm94LnByb3RvdHlwZS5nZXRTZWxlY3Rpb24gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKSxcbiAgICAgIHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG5cbiAgcmV0dXJuIHJhbmdlO1xufTtcblxuXG5UZXh0Qm94LnByb3RvdHlwZS5zZXRTZWxlY3Rpb24gPSBmdW5jdGlvbihjb250YWluZXIsIG9mZnNldCkge1xuICB2YXIgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuXG4gIGlmIChjb250YWluZXIgPT09IG51bGwpIHtcbiAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGhpcy5jb250ZW50KTtcbiAgfSBlbHNlIHtcbiAgICByYW5nZS5zZXRTdGFydChjb250YWluZXIsIG9mZnNldCk7XG4gICAgcmFuZ2Uuc2V0RW5kKGNvbnRhaW5lciwgb2Zmc2V0KTtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG5cbiAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xufTtcbiIsImltcG9ydCB7XG4gIGZvckVhY2gsXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgcXVlcnlBbGwgYXMgZG9tUXVlcnlBbGxcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7IGlzUHJpbWFyeUJ1dHRvbiB9IGZyb20gJy4uLy4uL3V0aWwvTW91c2UnO1xuXG5pbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVMaW5lLFxuICB1cGRhdGVMaW5lXG59IGZyb20gJy4uLy4uL3V0aWwvUmVuZGVyVXRpbCc7XG5cbmZ1bmN0aW9uIGFsbG93QWxsKGUpIHsgcmV0dXJuIHRydWU7IH1cblxudmFyIExPV19QUklPUklUWSA9IDUwMDtcblxuXG4vKipcbiAqIEEgcGx1Z2luIHRoYXQgcHJvdmlkZXMgaW50ZXJhY3Rpb24gZXZlbnRzIGZvciBkaWFncmFtIGVsZW1lbnRzLlxuICpcbiAqIEl0IGVtaXRzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICpcbiAqICAgKiBlbGVtZW50LmNsaWNrXG4gKiAgICogZWxlbWVudC5jb250ZXh0bWVudVxuICogICAqIGVsZW1lbnQuZGJsY2xpY2tcbiAqICAgKiBlbGVtZW50LmhvdmVyXG4gKiAgICogZWxlbWVudC5tb3VzZWRvd25cbiAqICAgKiBlbGVtZW50Lm1vdXNlbW92ZVxuICogICAqIGVsZW1lbnQubW91c2V1cFxuICogICAqIGVsZW1lbnQub3V0XG4gKlxuICogRWFjaCBldmVudCBpcyBhIHR1cGxlIHsgZWxlbWVudCwgZ2Z4LCBvcmlnaW5hbEV2ZW50IH0uXG4gKlxuICogQ2FuY2VsaW5nIHRoZSBldmVudCB2aWEgRXZlbnQjcHJldmVudERlZmF1bHQoKVxuICogcHJldmVudHMgdGhlIG9yaWdpbmFsIERPTSBvcGVyYXRpb24uXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gSW50ZXJhY3Rpb25FdmVudHMoZXZlbnRCdXMsIGVsZW1lbnRSZWdpc3RyeSwgc3R5bGVzKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8qKlxuICAgKiBGaXJlIGFuIGludGVyYWN0aW9uIGV2ZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBsb2NhbCBldmVudCBuYW1lLCBlLmcuIGVsZW1lbnQuY2xpY2suXG4gICAqIEBwYXJhbSB7RE9NRXZlbnR9IGV2ZW50IG5hdGl2ZSBldmVudFxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBbZWxlbWVudF0gdGhlIGRpYWdyYW0gZWxlbWVudCB0byBlbWl0IHRoZSBldmVudCBvbjtcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzIHRvIHRoZSBldmVudCB0YXJnZXRcbiAgICovXG4gIGZ1bmN0aW9uIGZpcmUodHlwZSwgZXZlbnQsIGVsZW1lbnQpIHtcblxuICAgIGlmIChpc0lnbm9yZWQodHlwZSwgZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRhcmdldCwgZ2Z4LCByZXR1cm5WYWx1ZTtcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgdGFyZ2V0ID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQgfHwgZXZlbnQudGFyZ2V0O1xuXG4gICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgIGdmeCA9IHRhcmdldDtcbiAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZ2Z4ID0gZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGlmICghZ2Z4IHx8ICFlbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuVmFsdWUgPSBldmVudEJ1cy5maXJlKHR5cGUsIHtcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBnZng6IGdmeCxcbiAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2ZW50XG4gICAgfSk7XG5cbiAgICBpZiAocmV0dXJuVmFsdWUgPT09IGZhbHNlKSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVE9ETyhuaWtrdSk6IGRvY3VtZW50IHRoaXNcbiAgdmFyIGhhbmRsZXJzID0ge307XG5cbiAgZnVuY3Rpb24gbW91c2VIYW5kbGVyKGxvY2FsRXZlbnROYW1lKSB7XG4gICAgcmV0dXJuIGhhbmRsZXJzW2xvY2FsRXZlbnROYW1lXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSWdub3JlZChsb2NhbEV2ZW50TmFtZSwgZXZlbnQpIHtcblxuICAgIHZhciBmaWx0ZXIgPSBpZ25vcmVkRmlsdGVyc1tsb2NhbEV2ZW50TmFtZV0gfHwgaXNQcmltYXJ5QnV0dG9uO1xuXG4gICAgLy8gb25seSByZWFjdCBvbiBsZWZ0IG1vdXNlIGJ1dHRvbiBpbnRlcmFjdGlvbnNcbiAgICAvLyBleGNlcHQgZm9yIGludGVyYWN0aW9uIGV2ZW50cyB0aGF0IGFyZSBlbmFibGVkXG4gICAgLy8gZm9yIHNlY3VuZGFyeSBtb3VzZSBidXR0b25cbiAgICByZXR1cm4gIWZpbHRlcihldmVudCk7XG4gIH1cblxuICB2YXIgYmluZGluZ3MgPSB7XG4gICAgY2xpY2s6ICdlbGVtZW50LmNsaWNrJyxcbiAgICBjb250ZXh0bWVudTogJ2VsZW1lbnQuY29udGV4dG1lbnUnLFxuICAgIGRibGNsaWNrOiAnZWxlbWVudC5kYmxjbGljaycsXG4gICAgbW91c2Vkb3duOiAnZWxlbWVudC5tb3VzZWRvd24nLFxuICAgIG1vdXNlbW92ZTogJ2VsZW1lbnQubW91c2Vtb3ZlJyxcbiAgICBtb3VzZW92ZXI6ICdlbGVtZW50LmhvdmVyJyxcbiAgICBtb3VzZW91dDogJ2VsZW1lbnQub3V0JyxcbiAgICBtb3VzZXVwOiAnZWxlbWVudC5tb3VzZXVwJyxcbiAgfTtcblxuICB2YXIgaWdub3JlZEZpbHRlcnMgPSB7XG4gICAgJ2VsZW1lbnQuY29udGV4dG1lbnUnOiBhbGxvd0FsbFxuICB9O1xuXG5cbiAgLy8gbWFudWFsIGV2ZW50IHRyaWdnZXIgLy8vLy8vLy8vL1xuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIGFuIGludGVyYWN0aW9uIGV2ZW50IChiYXNlZCBvbiBhIG5hdGl2ZSBkb20gZXZlbnQpXG4gICAqIG9uIHRoZSB0YXJnZXQgc2hhcGUgb3IgY29ubmVjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50TmFtZSB0aGUgbmFtZSBvZiB0aGUgdHJpZ2dlcmVkIERPTSBldmVudFxuICAgKiBAcGFyYW0ge01vdXNlRXZlbnR9IGV2ZW50XG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IHRhcmdldEVsZW1lbnRcbiAgICovXG4gIGZ1bmN0aW9uIHRyaWdnZXJNb3VzZUV2ZW50KGV2ZW50TmFtZSwgZXZlbnQsIHRhcmdldEVsZW1lbnQpIHtcblxuICAgIC8vIGkuZS4gZWxlbWVudC5tb3VzZWRvd24uLi5cbiAgICB2YXIgbG9jYWxFdmVudE5hbWUgPSBiaW5kaW5nc1tldmVudE5hbWVdO1xuXG4gICAgaWYgKCFsb2NhbEV2ZW50TmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bm1hcHBlZCBET00gZXZlbnQgbmFtZSA8JyArIGV2ZW50TmFtZSArICc+Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpcmUobG9jYWxFdmVudE5hbWUsIGV2ZW50LCB0YXJnZXRFbGVtZW50KTtcbiAgfVxuXG5cbiAgdmFyIEVMRU1FTlRfU0VMRUNUT1IgPSAnc3ZnLCAuZGpzLWVsZW1lbnQnO1xuXG4gIC8vIGV2ZW50IGhhbmRsaW5nIC8vLy8vLy9cblxuICBmdW5jdGlvbiByZWdpc3RlckV2ZW50KG5vZGUsIGV2ZW50LCBsb2NhbEV2ZW50LCBpZ25vcmVkRmlsdGVyKSB7XG5cbiAgICB2YXIgaGFuZGxlciA9IGhhbmRsZXJzW2xvY2FsRXZlbnRdID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIGZpcmUobG9jYWxFdmVudCwgZXZlbnQpO1xuICAgIH07XG5cbiAgICBpZiAoaWdub3JlZEZpbHRlcikge1xuICAgICAgaWdub3JlZEZpbHRlcnNbbG9jYWxFdmVudF0gPSBpZ25vcmVkRmlsdGVyO1xuICAgIH1cblxuICAgIGhhbmRsZXIuJGRlbGVnYXRlID0gZG9tRGVsZWdhdGUuYmluZChub2RlLCBFTEVNRU5UX1NFTEVDVE9SLCBldmVudCwgaGFuZGxlcik7XG4gIH1cblxuICBmdW5jdGlvbiB1bnJlZ2lzdGVyRXZlbnQobm9kZSwgZXZlbnQsIGxvY2FsRXZlbnQpIHtcblxuICAgIHZhciBoYW5kbGVyID0gbW91c2VIYW5kbGVyKGxvY2FsRXZlbnQpO1xuXG4gICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZG9tRGVsZWdhdGUudW5iaW5kKG5vZGUsIGV2ZW50LCBoYW5kbGVyLiRkZWxlZ2F0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiByZWdpc3RlckV2ZW50cyhzdmcpIHtcbiAgICBmb3JFYWNoKGJpbmRpbmdzLCBmdW5jdGlvbih2YWwsIGtleSkge1xuICAgICAgcmVnaXN0ZXJFdmVudChzdmcsIGtleSwgdmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVucmVnaXN0ZXJFdmVudHMoc3ZnKSB7XG4gICAgZm9yRWFjaChiaW5kaW5ncywgZnVuY3Rpb24odmFsLCBrZXkpIHtcbiAgICAgIHVucmVnaXN0ZXJFdmVudChzdmcsIGtleSwgdmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuZGVzdHJveScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdW5yZWdpc3RlckV2ZW50cyhldmVudC5zdmcpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY2FudmFzLmluaXQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHJlZ2lzdGVyRXZlbnRzKGV2ZW50LnN2Zyk7XG4gIH0pO1xuXG5cbiAgLy8gaGl0IGJveCB1cGRhdGluZyAvLy8vLy8vLy8vLy8vLy8vXG5cbiAgZXZlbnRCdXMub24oWyAnc2hhcGUuYWRkZWQnLCAnY29ubmVjdGlvbi5hZGRlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUhpdCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH0pO1xuXG4gIC8vIFVwZGF0ZSBkanMtaGl0IG9uIGNoYW5nZS5cbiAgLy8gQSBsb3cgcHJpb3J0aXR5IGlzIG5lY2Vzc2FyeSwgYmVjYXVzZSBkanMtaGl0IG9mIGxhYmVscyBoYXMgdG8gYmUgdXBkYXRlZFxuICAvLyBhZnRlciB0aGUgbGFiZWwgYm91bmRzIGhhdmUgYmVlbiB1cGRhdGVkIGluIHRoZSByZW5kZXJlci5cbiAgZXZlbnRCdXMub24oW1xuICAgICdzaGFwZS5jaGFuZ2VkJyxcbiAgICAnY29ubmVjdGlvbi5jaGFuZ2VkJ1xuICBdLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdpbnRlcmFjdGlvbkV2ZW50cy5jcmVhdGVIaXQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICBzZWxmLmNyZWF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICBzZWxmLnVwZGF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgfSk7XG5cblxuICAvLyBoaXQgc3R5bGVzIC8vLy8vLy8vLy8vL1xuXG4gIHZhciBTVFJPS0VfSElUX1NUWUxFID0gY3JlYXRlSGl0U3R5bGUoJ2Rqcy1oaXQgZGpzLWhpdC1zdHJva2UnKTtcblxuICB2YXIgQ0xJQ0tfU1RST0tFX0hJVF9TVFlMRSA9IGNyZWF0ZUhpdFN0eWxlKCdkanMtaGl0IGRqcy1oaXQtY2xpY2stc3Ryb2tlJyk7XG5cbiAgdmFyIEFMTF9ISVRfU1RZTEUgPSBjcmVhdGVIaXRTdHlsZSgnZGpzLWhpdCBkanMtaGl0LWFsbCcpO1xuXG4gIHZhciBISVRfVFlQRVMgPSB7XG4gICAgJ2FsbCc6IEFMTF9ISVRfU1RZTEUsXG4gICAgJ2NsaWNrLXN0cm9rZSc6IENMSUNLX1NUUk9LRV9ISVRfU1RZTEUsXG4gICAgJ3N0cm9rZSc6IFNUUk9LRV9ISVRfU1RZTEVcbiAgfTtcblxuICBmdW5jdGlvbiBjcmVhdGVIaXRTdHlsZShjbGFzc05hbWVzLCBhdHRycykge1xuXG4gICAgYXR0cnMgPSBhc3NpZ24oe1xuICAgICAgc3Ryb2tlOiAnd2hpdGUnLFxuICAgICAgc3Ryb2tlV2lkdGg6IDE1XG4gICAgfSwgYXR0cnMgfHwge30pO1xuXG4gICAgcmV0dXJuIHN0eWxlcy5jbHMoY2xhc3NOYW1lcywgWyAnbm8tZmlsbCcsICduby1ib3JkZXInIF0sIGF0dHJzKTtcbiAgfVxuXG5cbiAgLy8gc3R5bGUgaGVscGVycyAvLy8vLy8vLy8vLy8vLy9cblxuICBmdW5jdGlvbiBhcHBseVN0eWxlKGhpdCwgdHlwZSkge1xuXG4gICAgdmFyIGF0dHJzID0gSElUX1RZUEVTW3R5cGVdO1xuXG4gICAgaWYgKCFhdHRycykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGhpdCB0eXBlIDwnICsgdHlwZSArICc+Jyk7XG4gICAgfVxuXG4gICAgc3ZnQXR0cihoaXQsIGF0dHJzKTtcblxuICAgIHJldHVybiBoaXQ7XG4gIH1cblxuICBmdW5jdGlvbiBhcHBlbmRIaXQoZ2Z4LCBoaXQpIHtcbiAgICBzdmdBcHBlbmQoZ2Z4LCBoaXQpO1xuICB9XG5cblxuICAvLyBBUElcblxuICAvKipcbiAgICogUmVtb3ZlIGhpbnRzIG9uIHRoZSBnaXZlbiBncmFwaGljcy5cbiAgICpcbiAgICogQHBhcmFtIHtTVkdFbGVtZW50fSBnZnhcbiAgICovXG4gIHRoaXMucmVtb3ZlSGl0cyA9IGZ1bmN0aW9uKGdmeCkge1xuICAgIHZhciBoaXRzID0gZG9tUXVlcnlBbGwoJy5kanMtaGl0JywgZ2Z4KTtcblxuICAgIGZvckVhY2goaGl0cywgc3ZnUmVtb3ZlKTtcbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGRlZmF1bHQgaGl0IGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGdmeFxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSBjcmVhdGVkIGhpdFxuICAgKi9cbiAgdGhpcy5jcmVhdGVEZWZhdWx0SGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG4gICAgdmFyIHdheXBvaW50cyA9IGVsZW1lbnQud2F5cG9pbnRzLFxuICAgICAgICBpc0ZyYW1lID0gZWxlbWVudC5pc0ZyYW1lLFxuICAgICAgICBib3hUeXBlO1xuXG4gICAgaWYgKHdheXBvaW50cykge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlV2F5cG9pbnRzSGl0KGdmeCwgd2F5cG9pbnRzKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICBib3hUeXBlID0gaXNGcmFtZSA/ICdzdHJva2UnIDogJ2FsbCc7XG5cbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUJveEhpdChnZngsIGJveFR5cGUsIHtcbiAgICAgICAgd2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGhlaWdodDogZWxlbWVudC5oZWlnaHRcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGhpdHMgZm9yIHRoZSBnaXZlbiB3YXlwb2ludHMuXG4gICAqXG4gICAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ2Z4XG4gICAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAgICpcbiAgICogQHJldHVybiB7U1ZHRWxlbWVudH1cbiAgICovXG4gIHRoaXMuY3JlYXRlV2F5cG9pbnRzSGl0ID0gZnVuY3Rpb24oZ2Z4LCB3YXlwb2ludHMpIHtcblxuICAgIHZhciBoaXQgPSBjcmVhdGVMaW5lKHdheXBvaW50cyk7XG5cbiAgICBhcHBseVN0eWxlKGhpdCwgJ3N0cm9rZScpO1xuXG4gICAgYXBwZW5kSGl0KGdmeCwgaGl0KTtcblxuICAgIHJldHVybiBoaXQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBoaXRzIGZvciBhIGJveC5cbiAgICpcbiAgICogQHBhcmFtIHtTVkdFbGVtZW50fSBnZnhcbiAgICogQHBhcmFtIHtTdHJpbmd9IGhpdFR5cGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGF0dHJzXG4gICAqXG4gICAqIEByZXR1cm4ge1NWR0VsZW1lbnR9XG4gICAqL1xuICB0aGlzLmNyZWF0ZUJveEhpdCA9IGZ1bmN0aW9uKGdmeCwgdHlwZSwgYXR0cnMpIHtcblxuICAgIGF0dHJzID0gYXNzaWduKHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwXG4gICAgfSwgYXR0cnMpO1xuXG4gICAgdmFyIGhpdCA9IHN2Z0NyZWF0ZSgncmVjdCcpO1xuXG4gICAgYXBwbHlTdHlsZShoaXQsIHR5cGUpO1xuXG4gICAgc3ZnQXR0cihoaXQsIGF0dHJzKTtcblxuICAgIGFwcGVuZEhpdChnZngsIGhpdCk7XG5cbiAgICByZXR1cm4gaGl0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgZGVmYXVsdCBoaXQgb2YgdGhlIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gICAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IGdmeFxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSB1cGRhdGVkIGhpdFxuICAgKi9cbiAgdGhpcy51cGRhdGVEZWZhdWx0SGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG5cbiAgICB2YXIgaGl0ID0gZG9tUXVlcnkoJy5kanMtaGl0JywgZ2Z4KTtcblxuICAgIGlmICghaGl0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICB1cGRhdGVMaW5lKGhpdCwgZWxlbWVudC53YXlwb2ludHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdmdBdHRyKGhpdCwge1xuICAgICAgICB3aWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhpdDtcbiAgfTtcblxuICB0aGlzLmZpcmUgPSBmaXJlO1xuXG4gIHRoaXMudHJpZ2dlck1vdXNlRXZlbnQgPSB0cmlnZ2VyTW91c2VFdmVudDtcblxuICB0aGlzLm1vdXNlSGFuZGxlciA9IG1vdXNlSGFuZGxlcjtcblxuICB0aGlzLnJlZ2lzdGVyRXZlbnQgPSByZWdpc3RlckV2ZW50O1xuICB0aGlzLnVucmVnaXN0ZXJFdmVudCA9IHVucmVnaXN0ZXJFdmVudDtcbn1cblxuXG5JbnRlcmFjdGlvbkV2ZW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ3N0eWxlcydcbl07XG5cblxuLyoqXG4gKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vdXNlIGhvdmVyZWQgb3ZlciBhbiBlbGVtZW50XG4gKlxuICogQGV2ZW50IGVsZW1lbnQuaG92ZXJcbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSBnZnhcbiAqIEBwcm9wZXJ0eSB7RXZlbnR9IG9yaWdpbmFsRXZlbnRcbiAqL1xuXG4vKipcbiAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgbW91c2UgaGFzIGxlZnQgYW4gZWxlbWVudFxuICpcbiAqIEBldmVudCBlbGVtZW50Lm91dFxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBtb3VzZSBoYXMgY2xpY2tlZCBhbiBlbGVtZW50XG4gKlxuICogQGV2ZW50IGVsZW1lbnQuY2xpY2tcbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSBnZnhcbiAqIEBwcm9wZXJ0eSB7RXZlbnR9IG9yaWdpbmFsRXZlbnRcbiAqL1xuXG4vKipcbiAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgbW91c2UgaGFzIGRvdWJsZSBjbGlja2VkIGFuIGVsZW1lbnRcbiAqXG4gKiBAZXZlbnQgZWxlbWVudC5kYmxjbGlja1xuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBtb3VzZSBoYXMgZ29uZSBkb3duIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogQGV2ZW50IGVsZW1lbnQubW91c2Vkb3duXG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gZ2Z4XG4gKiBAcHJvcGVydHkge0V2ZW50fSBvcmlnaW5hbEV2ZW50XG4gKi9cblxuLyoqXG4gKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vdXNlIGhhcyBnb25lIHVwIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogQGV2ZW50IGVsZW1lbnQubW91c2V1cFxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBjb250ZXh0IG1lbnUgYWN0aW9uIGlzIHRyaWdnZXJlZFxuICogdmlhIG1vdXNlIG9yIHRvdWNoIGNvbnRyb2xzLlxuICpcbiAqIEBldmVudCBlbGVtZW50LmNvbnRleHRtZW51XG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gZ2Z4XG4gKiBAcHJvcGVydHkge0V2ZW50fSBvcmlnaW5hbEV2ZW50XG4gKi8iLCIvKipcbiAqIEEgc2ltcGxlIHRyYW5zbGF0aW9uIHN0dWIgdG8gYmUgdXNlZCBmb3IgbXVsdGktbGFuZ3VhZ2Ugc3VwcG9ydFxuICogaW4gZGlhZ3JhbXMuIENhbiBiZSBlYXNpbHkgcmVwbGFjZWQgd2l0aCBhIG1vcmUgc29waGlzdGljYXRlZFxuICogc29sdXRpb24uXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyB1c2UgaXQgaW5zaWRlIGFueSBkaWFncmFtIGNvbXBvbmVudCBieSBpbmplY3RpbmcgYHRyYW5zbGF0ZWAuXG4gKlxuICogZnVuY3Rpb24gTXlTZXJ2aWNlKHRyYW5zbGF0ZSkge1xuICogICBhbGVydCh0cmFuc2xhdGUoJ0hFTExPIHt5b3V9JywgeyB5b3U6ICdZb3UhJyB9KSk7XG4gKiB9XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRlbXBsYXRlIHRvIGludGVycG9sYXRlXG4gKiBAcGFyYW0ge09iamVjdH0gW3JlcGxhY2VtZW50c10gYSBtYXAgd2l0aCBzdWJzdGl0dXRlc1xuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gdGhlIHRyYW5zbGF0ZWQgc3RyaW5nXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRyYW5zbGF0ZSh0ZW1wbGF0ZSwgcmVwbGFjZW1lbnRzKSB7XG5cbiAgcmVwbGFjZW1lbnRzID0gcmVwbGFjZW1lbnRzIHx8IHt9O1xuXG4gIHJldHVybiB0ZW1wbGF0ZS5yZXBsYWNlKC97KFtefV0rKX0vZywgZnVuY3Rpb24oXywga2V5KSB7XG4gICAgcmV0dXJuIHJlcGxhY2VtZW50c1trZXldIHx8ICd7JyArIGtleSArICd9JztcbiAgfSk7XG59IiwiLyoqXG4gKiBGYWlsc2FmZSByZW1vdmUgYW4gZWxlbWVudCBmcm9tIGEgY29sbGVjdGlvblxuICpcbiAqIEBwYXJhbSAge0FycmF5PE9iamVjdD59IFtjb2xsZWN0aW9uXVxuICogQHBhcmFtICB7T2JqZWN0fSBbZWxlbWVudF1cbiAqXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IHRoZSBwcmV2aW91cyBpbmRleCBvZiB0aGUgZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlKGNvbGxlY3Rpb24sIGVsZW1lbnQpIHtcblxuICBpZiAoIWNvbGxlY3Rpb24gfHwgIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICB2YXIgaWR4ID0gY29sbGVjdGlvbi5pbmRleE9mKGVsZW1lbnQpO1xuXG4gIGlmIChpZHggIT09IC0xKSB7XG4gICAgY29sbGVjdGlvbi5zcGxpY2UoaWR4LCAxKTtcbiAgfVxuXG4gIHJldHVybiBpZHg7XG59XG5cbi8qKlxuICogRmFpbCBzYXZlIGFkZCBhbiBlbGVtZW50IHRvIHRoZSBnaXZlbiBjb25uZWN0aW9uLCBlbnN1cmluZ1xuICogaXQgZG9lcyBub3QgeWV0IGV4aXN0LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gY29sbGVjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSBpZHhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZChjb2xsZWN0aW9uLCBlbGVtZW50LCBpZHgpIHtcblxuICBpZiAoIWNvbGxlY3Rpb24gfHwgIWVsZW1lbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodHlwZW9mIGlkeCAhPT0gJ251bWJlcicpIHtcbiAgICBpZHggPSAtMTtcbiAgfVxuXG4gIHZhciBjdXJyZW50SWR4ID0gY29sbGVjdGlvbi5pbmRleE9mKGVsZW1lbnQpO1xuXG4gIGlmIChjdXJyZW50SWR4ICE9PSAtMSkge1xuXG4gICAgaWYgKGN1cnJlbnRJZHggPT09IGlkeCkge1xuXG4gICAgICAvLyBub3RoaW5nIHRvIGRvLCBwb3NpdGlvbiBoYXMgbm90IGNoYW5nZWRcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuXG4gICAgICBpZiAoaWR4ICE9PSAtMSkge1xuXG4gICAgICAgIC8vIHJlbW92ZSBmcm9tIGN1cnJlbnQgcG9zaXRpb25cbiAgICAgICAgY29sbGVjdGlvbi5zcGxpY2UoY3VycmVudElkeCwgMSk7XG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIC8vIGFscmVhZHkgZXhpc3RzIGluIGNvbGxlY3Rpb25cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChpZHggIT09IC0xKSB7XG5cbiAgICAvLyBpbnNlcnQgYXQgc3BlY2lmaWVkIHBvc2l0aW9uXG4gICAgY29sbGVjdGlvbi5zcGxpY2UoaWR4LCAwLCBlbGVtZW50KTtcbiAgfSBlbHNlIHtcblxuICAgIC8vIHB1c2ggdG8gZW5kXG4gICAgY29sbGVjdGlvbi5wdXNoKGVsZW1lbnQpO1xuICB9XG59XG5cblxuLyoqXG4gKiBGYWlsIHNhdmUgZ2V0IHRoZSBpbmRleCBvZiBhbiBlbGVtZW50IGluIGEgY29sbGVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PE9iamVjdD59IGNvbGxlY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7TnVtYmVyfSB0aGUgaW5kZXggb3IgLTEgaWYgY29sbGVjdGlvbiBvciBlbGVtZW50IGRvXG4gKiAgICAgICAgICAgICAgICAgIG5vdCBleGlzdCBvciB0aGUgZWxlbWVudCBpcyBub3QgY29udGFpbmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5kZXhPZihjb2xsZWN0aW9uLCBlbGVtZW50KSB7XG5cbiAgaWYgKCFjb2xsZWN0aW9uIHx8ICFlbGVtZW50KSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgcmV0dXJuIGNvbGxlY3Rpb24uaW5kZXhPZihlbGVtZW50KTtcbn1cbiIsInZhciBDTEFTU19QQVRURVJOID0gL15jbGFzcyAvO1xuXG5mdW5jdGlvbiBpc0NsYXNzKGZuKSB7XG4gIHJldHVybiBDTEFTU19QQVRURVJOLnRlc3QoZm4udG9TdHJpbmcoKSk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cblxuZnVuY3Rpb24gYW5ub3RhdGUoKSB7XG4gIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgaXNBcnJheShhcmdzWzBdKSkge1xuICAgIGFyZ3MgPSBhcmdzWzBdO1xuICB9XG5cbiAgdmFyIGZuID0gYXJncy5wb3AoKTtcblxuICBmbi4kaW5qZWN0ID0gYXJncztcblxuICByZXR1cm4gZm47XG59XG5cbi8vIEN1cnJlbnQgbGltaXRhdGlvbnM6XG4vLyAtIGNhbid0IHB1dCBpbnRvIFwiZnVuY3Rpb24gYXJnXCIgY29tbWVudHNcbi8vIGZ1bmN0aW9uIC8qIChubyBwYXJlbnRoZXNpcyBsaWtlIHRoaXMpICovICgpe31cbi8vIGZ1bmN0aW9uIGFiYyggLyogeHggKG5vIHBhcmVudGhlc2lzIGxpa2UgdGhpcykgKi8gYSwgYikge31cbi8vXG4vLyBKdXN0IHB1dCB0aGUgY29tbWVudCBiZWZvcmUgZnVuY3Rpb24gb3IgaW5zaWRlOlxuLy8gLyogKCgodGhpcyBpcyBmaW5lKSkpICovIGZ1bmN0aW9uKGEsIGIpIHt9XG4vLyBmdW5jdGlvbiBhYmMoYSkgeyAvKiAoKCh0aGlzIGlzIGZpbmUpKSkgKi99XG4vL1xuLy8gLSBjYW4ndCByZWxpYWJseSBhdXRvLWFubm90YXRlIGNvbnN0cnVjdG9yOyB3ZSdsbCBtYXRjaCB0aGVcbi8vIGZpcnN0IGNvbnN0cnVjdG9yKC4uLikgcGF0dGVybiBmb3VuZCB3aGljaCBtYXkgYmUgdGhlIG9uZVxuLy8gb2YgYSBuZXN0ZWQgY2xhc3MsIHRvby5cblxudmFyIENPTlNUUlVDVE9SX0FSR1MgPSAvY29uc3RydWN0b3JcXHMqW14oXSpcXChcXHMqKFteKV0qKVxcKS9tO1xudmFyIEZOX0FSR1MgPSAvXmZ1bmN0aW9uXFxzKlteKF0qXFwoXFxzKihbXildKilcXCkvbTtcbnZhciBGTl9BUkcgPSAvXFwvXFwqKFteKl0qKVxcKlxcLy9tO1xuXG5mdW5jdGlvbiBwYXJzZShmbikge1xuXG4gIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBhbm5vdGF0ZSBcIicgKyBmbiArICdcIi4gRXhwZWN0ZWQgYSBmdW5jdGlvbiEnKTtcbiAgfVxuXG4gIHZhciBtYXRjaCA9IGZuLnRvU3RyaW5nKCkubWF0Y2goaXNDbGFzcyhmbikgPyBDT05TVFJVQ1RPUl9BUkdTIDogRk5fQVJHUyk7XG5cbiAgLy8gbWF5IHBhcnNlIGNsYXNzIHdpdGhvdXQgY29uc3RydWN0b3JcbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHJldHVybiBtYXRjaFsxXSAmJiBtYXRjaFsxXS5zcGxpdCgnLCcpLm1hcChmdW5jdGlvbiAoYXJnKSB7XG4gICAgbWF0Y2ggPSBhcmcubWF0Y2goRk5fQVJHKTtcbiAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXS50cmltKCkgOiBhcmcudHJpbSgpO1xuICB9KSB8fCBbXTtcbn1cblxuZnVuY3Rpb24gTW9kdWxlKCkge1xuICB2YXIgcHJvdmlkZXJzID0gW107XG5cbiAgdGhpcy5mYWN0b3J5ID0gZnVuY3Rpb24gKG5hbWUsIGZhY3RvcnkpIHtcbiAgICBwcm92aWRlcnMucHVzaChbbmFtZSwgJ2ZhY3RvcnknLCBmYWN0b3J5XSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgdGhpcy52YWx1ZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgIHByb3ZpZGVycy5wdXNoKFtuYW1lLCAndmFsdWUnLCB2YWx1ZV0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHRoaXMudHlwZSA9IGZ1bmN0aW9uIChuYW1lLCB0eXBlKSB7XG4gICAgcHJvdmlkZXJzLnB1c2goW25hbWUsICd0eXBlJywgdHlwZV0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uIChpdGVyYXRvcikge1xuICAgIHByb3ZpZGVycy5mb3JFYWNoKGl0ZXJhdG9yKTtcbiAgfTtcbn1cblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG5mdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7IGlmIChBcnJheS5pc0FycmF5KGFycikpIHsgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9IGVsc2UgeyByZXR1cm4gQXJyYXkuZnJvbShhcnIpOyB9IH1cblxuZnVuY3Rpb24gSW5qZWN0b3IobW9kdWxlcywgcGFyZW50KSB7XG4gIHBhcmVudCA9IHBhcmVudCB8fCB7XG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQobmFtZSwgc3RyaWN0KSB7XG4gICAgICBjdXJyZW50bHlSZXNvbHZpbmcucHVzaChuYW1lKTtcblxuICAgICAgaWYgKHN0cmljdCA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnJvcignTm8gcHJvdmlkZXIgZm9yIFwiJyArIG5hbWUgKyAnXCIhJyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBjdXJyZW50bHlSZXNvbHZpbmcgPSBbXTtcbiAgdmFyIHByb3ZpZGVycyA9IHRoaXMuX3Byb3ZpZGVycyA9IE9iamVjdC5jcmVhdGUocGFyZW50Ll9wcm92aWRlcnMgfHwgbnVsbCk7XG4gIHZhciBpbnN0YW5jZXMgPSB0aGlzLl9pbnN0YW5jZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gIHZhciBzZWxmID0gaW5zdGFuY2VzLmluamVjdG9yID0gdGhpcztcblxuICB2YXIgZXJyb3IgPSBmdW5jdGlvbiBlcnJvcihtc2cpIHtcbiAgICB2YXIgc3RhY2sgPSBjdXJyZW50bHlSZXNvbHZpbmcuam9pbignIC0+ICcpO1xuICAgIGN1cnJlbnRseVJlc29sdmluZy5sZW5ndGggPSAwO1xuICAgIHJldHVybiBuZXcgRXJyb3Ioc3RhY2sgPyBtc2cgKyAnIChSZXNvbHZpbmc6ICcgKyBzdGFjayArICcpJyA6IG1zZyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIG5hbWVkIHNlcnZpY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gW3N0cmljdD10cnVlXSBpZiBmYWxzZSwgcmVzb2x2ZSBtaXNzaW5nIHNlcnZpY2VzIHRvIG51bGxcbiAgICpcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgdmFyIGdldCA9IGZ1bmN0aW9uIGdldChuYW1lLCBzdHJpY3QpIHtcbiAgICBpZiAoIXByb3ZpZGVyc1tuYW1lXSAmJiBuYW1lLmluZGV4T2YoJy4nKSAhPT0gLTEpIHtcbiAgICAgIHZhciBwYXJ0cyA9IG5hbWUuc3BsaXQoJy4nKTtcbiAgICAgIHZhciBwaXZvdCA9IGdldChwYXJ0cy5zaGlmdCgpKTtcblxuICAgICAgd2hpbGUgKHBhcnRzLmxlbmd0aCkge1xuICAgICAgICBwaXZvdCA9IHBpdm90W3BhcnRzLnNoaWZ0KCldO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGl2b3Q7XG4gICAgfVxuXG4gICAgaWYgKGhhc1Byb3AoaW5zdGFuY2VzLCBuYW1lKSkge1xuICAgICAgcmV0dXJuIGluc3RhbmNlc1tuYW1lXTtcbiAgICB9XG5cbiAgICBpZiAoaGFzUHJvcChwcm92aWRlcnMsIG5hbWUpKSB7XG4gICAgICBpZiAoY3VycmVudGx5UmVzb2x2aW5nLmluZGV4T2YobmFtZSkgIT09IC0xKSB7XG4gICAgICAgIGN1cnJlbnRseVJlc29sdmluZy5wdXNoKG5hbWUpO1xuICAgICAgICB0aHJvdyBlcnJvcignQ2Fubm90IHJlc29sdmUgY2lyY3VsYXIgZGVwZW5kZW5jeSEnKTtcbiAgICAgIH1cblxuICAgICAgY3VycmVudGx5UmVzb2x2aW5nLnB1c2gobmFtZSk7XG4gICAgICBpbnN0YW5jZXNbbmFtZV0gPSBwcm92aWRlcnNbbmFtZV1bMF0ocHJvdmlkZXJzW25hbWVdWzFdKTtcbiAgICAgIGN1cnJlbnRseVJlc29sdmluZy5wb3AoKTtcblxuICAgICAgcmV0dXJuIGluc3RhbmNlc1tuYW1lXTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyZW50LmdldChuYW1lLCBzdHJpY3QpO1xuICB9O1xuXG4gIHZhciBmbkRlZiA9IGZ1bmN0aW9uIGZuRGVmKGZuKSB7XG4gICAgdmFyIGxvY2FscyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoaXNBcnJheShmbikpIHtcbiAgICAgICAgZm4gPSBhbm5vdGF0ZShmbi5zbGljZSgpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGludm9rZSBcIicgKyBmbiArICdcIi4gRXhwZWN0ZWQgYSBmdW5jdGlvbiEnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgaW5qZWN0ID0gZm4uJGluamVjdCB8fCBwYXJzZShmbik7XG4gICAgdmFyIGRlcGVuZGVuY2llcyA9IGluamVjdC5tYXAoZnVuY3Rpb24gKGRlcCkge1xuICAgICAgaWYgKGhhc1Byb3AobG9jYWxzLCBkZXApKSB7XG4gICAgICAgIHJldHVybiBsb2NhbHNbZGVwXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBnZXQoZGVwKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBmbjogZm4sXG4gICAgICBkZXBlbmRlbmNpZXM6IGRlcGVuZGVuY2llc1xuICAgIH07XG4gIH07XG5cbiAgdmFyIGluc3RhbnRpYXRlID0gZnVuY3Rpb24gaW5zdGFudGlhdGUoVHlwZSkge1xuICAgIHZhciBfZm5EZWYgPSBmbkRlZihUeXBlKSxcbiAgICAgICAgZGVwZW5kZW5jaWVzID0gX2ZuRGVmLmRlcGVuZGVuY2llcyxcbiAgICAgICAgZm4gPSBfZm5EZWYuZm47XG5cbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseShmbiwgW251bGxdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkoZGVwZW5kZW5jaWVzKSkpKSgpO1xuICB9O1xuXG4gIHZhciBpbnZva2UgPSBmdW5jdGlvbiBpbnZva2UoZnVuYywgY29udGV4dCwgbG9jYWxzKSB7XG4gICAgdmFyIF9mbkRlZjIgPSBmbkRlZihmdW5jLCBsb2NhbHMpLFxuICAgICAgICBkZXBlbmRlbmNpZXMgPSBfZm5EZWYyLmRlcGVuZGVuY2llcyxcbiAgICAgICAgZm4gPSBfZm5EZWYyLmZuO1xuXG4gICAgcmV0dXJuIGZuLmNhbGwuYXBwbHkoZm4sIFtjb250ZXh0XS5jb25jYXQoX3RvQ29uc3VtYWJsZUFycmF5KGRlcGVuZGVuY2llcykpKTtcbiAgfTtcblxuICB2YXIgY3JlYXRlUHJpdmF0ZUluamVjdG9yRmFjdG9yeSA9IGZ1bmN0aW9uIGNyZWF0ZVByaXZhdGVJbmplY3RvckZhY3RvcnkocHJpdmF0ZUNoaWxkSW5qZWN0b3IpIHtcbiAgICByZXR1cm4gYW5ub3RhdGUoZnVuY3Rpb24gKGtleSkge1xuICAgICAgcmV0dXJuIHByaXZhdGVDaGlsZEluamVjdG9yLmdldChrZXkpO1xuICAgIH0pO1xuICB9O1xuXG4gIHZhciBjcmVhdGVDaGlsZCA9IGZ1bmN0aW9uIGNyZWF0ZUNoaWxkKG1vZHVsZXMsIGZvcmNlTmV3SW5zdGFuY2VzKSB7XG4gICAgaWYgKGZvcmNlTmV3SW5zdGFuY2VzICYmIGZvcmNlTmV3SW5zdGFuY2VzLmxlbmd0aCkge1xuICAgICAgdmFyIGZyb21QYXJlbnRNb2R1bGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgdmFyIG1hdGNoZWRTY29wZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgICB2YXIgcHJpdmF0ZUluamVjdG9yc0NhY2hlID0gW107XG4gICAgICB2YXIgcHJpdmF0ZUNoaWxkSW5qZWN0b3JzID0gW107XG4gICAgICB2YXIgcHJpdmF0ZUNoaWxkRmFjdG9yaWVzID0gW107XG5cbiAgICAgIHZhciBwcm92aWRlcjtcbiAgICAgIHZhciBjYWNoZUlkeDtcbiAgICAgIHZhciBwcml2YXRlQ2hpbGRJbmplY3RvcjtcbiAgICAgIHZhciBwcml2YXRlQ2hpbGRJbmplY3RvckZhY3Rvcnk7XG4gICAgICBmb3IgKHZhciBuYW1lIGluIHByb3ZpZGVycykge1xuICAgICAgICBwcm92aWRlciA9IHByb3ZpZGVyc1tuYW1lXTtcblxuICAgICAgICBpZiAoZm9yY2VOZXdJbnN0YW5jZXMuaW5kZXhPZihuYW1lKSAhPT0gLTEpIHtcbiAgICAgICAgICBpZiAocHJvdmlkZXJbMl0gPT09ICdwcml2YXRlJykge1xuICAgICAgICAgICAgY2FjaGVJZHggPSBwcml2YXRlSW5qZWN0b3JzQ2FjaGUuaW5kZXhPZihwcm92aWRlclszXSk7XG4gICAgICAgICAgICBpZiAoY2FjaGVJZHggPT09IC0xKSB7XG4gICAgICAgICAgICAgIHByaXZhdGVDaGlsZEluamVjdG9yID0gcHJvdmlkZXJbM10uY3JlYXRlQ2hpbGQoW10sIGZvcmNlTmV3SW5zdGFuY2VzKTtcbiAgICAgICAgICAgICAgcHJpdmF0ZUNoaWxkSW5qZWN0b3JGYWN0b3J5ID0gY3JlYXRlUHJpdmF0ZUluamVjdG9yRmFjdG9yeShwcml2YXRlQ2hpbGRJbmplY3Rvcik7XG4gICAgICAgICAgICAgIHByaXZhdGVJbmplY3RvcnNDYWNoZS5wdXNoKHByb3ZpZGVyWzNdKTtcbiAgICAgICAgICAgICAgcHJpdmF0ZUNoaWxkSW5qZWN0b3JzLnB1c2gocHJpdmF0ZUNoaWxkSW5qZWN0b3IpO1xuICAgICAgICAgICAgICBwcml2YXRlQ2hpbGRGYWN0b3JpZXMucHVzaChwcml2YXRlQ2hpbGRJbmplY3RvckZhY3RvcnkpO1xuICAgICAgICAgICAgICBmcm9tUGFyZW50TW9kdWxlW25hbWVdID0gW3ByaXZhdGVDaGlsZEluamVjdG9yRmFjdG9yeSwgbmFtZSwgJ3ByaXZhdGUnLCBwcml2YXRlQ2hpbGRJbmplY3Rvcl07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBmcm9tUGFyZW50TW9kdWxlW25hbWVdID0gW3ByaXZhdGVDaGlsZEZhY3Rvcmllc1tjYWNoZUlkeF0sIG5hbWUsICdwcml2YXRlJywgcHJpdmF0ZUNoaWxkSW5qZWN0b3JzW2NhY2hlSWR4XV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZyb21QYXJlbnRNb2R1bGVbbmFtZV0gPSBbcHJvdmlkZXJbMl0sIHByb3ZpZGVyWzFdXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbWF0Y2hlZFNjb3Blc1tuYW1lXSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoKHByb3ZpZGVyWzJdID09PSAnZmFjdG9yeScgfHwgcHJvdmlkZXJbMl0gPT09ICd0eXBlJykgJiYgcHJvdmlkZXJbMV0uJHNjb3BlKSB7XG4gICAgICAgICAgLyoganNoaW50IC1XMDgzICovXG4gICAgICAgICAgZm9yY2VOZXdJbnN0YW5jZXMuZm9yRWFjaChmdW5jdGlvbiAoc2NvcGUpIHtcbiAgICAgICAgICAgIGlmIChwcm92aWRlclsxXS4kc2NvcGUuaW5kZXhPZihzY29wZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgIGZyb21QYXJlbnRNb2R1bGVbbmFtZV0gPSBbcHJvdmlkZXJbMl0sIHByb3ZpZGVyWzFdXTtcbiAgICAgICAgICAgICAgbWF0Y2hlZFNjb3Blc1tzY29wZV0gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvcmNlTmV3SW5zdGFuY2VzLmZvckVhY2goZnVuY3Rpb24gKHNjb3BlKSB7XG4gICAgICAgIGlmICghbWF0Y2hlZFNjb3Blc1tzY29wZV0pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHByb3ZpZGVyIGZvciBcIicgKyBzY29wZSArICdcIi4gQ2Fubm90IHVzZSBwcm92aWRlciBmcm9tIHRoZSBwYXJlbnQhJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBtb2R1bGVzLnVuc2hpZnQoZnJvbVBhcmVudE1vZHVsZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbmplY3Rvcihtb2R1bGVzLCBzZWxmKTtcbiAgfTtcblxuICB2YXIgZmFjdG9yeU1hcCA9IHtcbiAgICBmYWN0b3J5OiBpbnZva2UsXG4gICAgdHlwZTogaW5zdGFudGlhdGUsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKF92YWx1ZSkge1xuICAgICAgcmV0dXJuIF92YWx1ZTtcbiAgICB9XG4gIH07XG5cbiAgbW9kdWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChtb2R1bGUpIHtcblxuICAgIGZ1bmN0aW9uIGFycmF5VW53cmFwKHR5cGUsIHZhbHVlKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ3ZhbHVlJyAmJiBpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IGFubm90YXRlKHZhbHVlLnNsaWNlKCkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gVE9ETyh2b2p0YSk6IGhhbmRsZSB3cm9uZyBpbnB1dHMgKG1vZHVsZXMpXG4gICAgaWYgKG1vZHVsZSBpbnN0YW5jZW9mIE1vZHVsZSkge1xuICAgICAgbW9kdWxlLmZvckVhY2goZnVuY3Rpb24gKHByb3ZpZGVyKSB7XG4gICAgICAgIHZhciBuYW1lID0gcHJvdmlkZXJbMF07XG4gICAgICAgIHZhciB0eXBlID0gcHJvdmlkZXJbMV07XG4gICAgICAgIHZhciB2YWx1ZSA9IHByb3ZpZGVyWzJdO1xuXG4gICAgICAgIHByb3ZpZGVyc1tuYW1lXSA9IFtmYWN0b3J5TWFwW3R5cGVdLCBhcnJheVVud3JhcCh0eXBlLCB2YWx1ZSksIHR5cGVdO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICgodHlwZW9mIG1vZHVsZSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YobW9kdWxlKSkgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAobW9kdWxlLl9fZXhwb3J0c19fKSB7XG4gICAgICAgIHZhciBjbG9uZWRNb2R1bGUgPSBPYmplY3Qua2V5cyhtb2R1bGUpLnJlZHVjZShmdW5jdGlvbiAobSwga2V5KSB7XG4gICAgICAgICAgaWYgKGtleS5zdWJzdHJpbmcoMCwgMikgIT09ICdfXycpIHtcbiAgICAgICAgICAgIG1ba2V5XSA9IG1vZHVsZVtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbTtcbiAgICAgICAgfSwgT2JqZWN0LmNyZWF0ZShudWxsKSk7XG5cbiAgICAgICAgdmFyIHByaXZhdGVJbmplY3RvciA9IG5ldyBJbmplY3RvcigobW9kdWxlLl9fbW9kdWxlc19fIHx8IFtdKS5jb25jYXQoW2Nsb25lZE1vZHVsZV0pLCBzZWxmKTtcbiAgICAgICAgdmFyIGdldEZyb21Qcml2YXRlSW5qZWN0b3IgPSBhbm5vdGF0ZShmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgcmV0dXJuIHByaXZhdGVJbmplY3Rvci5nZXQoa2V5KTtcbiAgICAgICAgfSk7XG4gICAgICAgIG1vZHVsZS5fX2V4cG9ydHNfXy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICBwcm92aWRlcnNba2V5XSA9IFtnZXRGcm9tUHJpdmF0ZUluamVjdG9yLCBrZXksICdwcml2YXRlJywgcHJpdmF0ZUluamVjdG9yXTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBPYmplY3Qua2V5cyhtb2R1bGUpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICBpZiAobW9kdWxlW25hbWVdWzJdID09PSAncHJpdmF0ZScpIHtcbiAgICAgICAgICAgIHByb3ZpZGVyc1tuYW1lXSA9IG1vZHVsZVtuYW1lXTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgdHlwZSA9IG1vZHVsZVtuYW1lXVswXTtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBtb2R1bGVbbmFtZV1bMV07XG5cbiAgICAgICAgICBwcm92aWRlcnNbbmFtZV0gPSBbZmFjdG9yeU1hcFt0eXBlXSwgYXJyYXlVbndyYXAodHlwZSwgdmFsdWUpLCB0eXBlXTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICAvLyBwdWJsaWMgQVBJXG4gIHRoaXMuZ2V0ID0gZ2V0O1xuICB0aGlzLmludm9rZSA9IGludm9rZTtcbiAgdGhpcy5pbnN0YW50aWF0ZSA9IGluc3RhbnRpYXRlO1xuICB0aGlzLmNyZWF0ZUNoaWxkID0gY3JlYXRlQ2hpbGQ7XG59XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaGFzUHJvcChvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG5cbmV4cG9ydCB7IGFubm90YXRlLCBNb2R1bGUsIEluamVjdG9yIH07XG4iLCIvKiEgSGFtbWVyLkpTIC0gdjIuMC43IC0gMjAxNi0wNC0yMlxuICogaHR0cDovL2hhbW1lcmpzLmdpdGh1Yi5pby9cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYgSm9yaWsgVGFuZ2VsZGVyO1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlICovXG4oZnVuY3Rpb24od2luZG93LCBkb2N1bWVudCwgZXhwb3J0TmFtZSwgdW5kZWZpbmVkKSB7XG4gICd1c2Ugc3RyaWN0JztcblxudmFyIFZFTkRPUl9QUkVGSVhFUyA9IFsnJywgJ3dlYmtpdCcsICdNb3onLCAnTVMnLCAnbXMnLCAnbyddO1xudmFyIFRFU1RfRUxFTUVOVCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG52YXIgVFlQRV9GVU5DVElPTiA9ICdmdW5jdGlvbic7XG5cbnZhciByb3VuZCA9IE1hdGgucm91bmQ7XG52YXIgYWJzID0gTWF0aC5hYnM7XG52YXIgbm93ID0gRGF0ZS5ub3c7XG5cbi8qKlxuICogc2V0IGEgdGltZW91dCB3aXRoIGEgZ2l2ZW4gc2NvcGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge051bWJlcn0gdGltZW91dFxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIHNldFRpbWVvdXRDb250ZXh0KGZuLCB0aW1lb3V0LCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIHNldFRpbWVvdXQoYmluZEZuKGZuLCBjb250ZXh0KSwgdGltZW91dCk7XG59XG5cbi8qKlxuICogaWYgdGhlIGFyZ3VtZW50IGlzIGFuIGFycmF5LCB3ZSB3YW50IHRvIGV4ZWN1dGUgdGhlIGZuIG9uIGVhY2ggZW50cnlcbiAqIGlmIGl0IGFpbnQgYW4gYXJyYXkgd2UgZG9uJ3Qgd2FudCB0byBkbyBhIHRoaW5nLlxuICogdGhpcyBpcyB1c2VkIGJ5IGFsbCB0aGUgbWV0aG9kcyB0aGF0IGFjY2VwdCBhIHNpbmdsZSBhbmQgYXJyYXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp8QXJyYXl9IGFyZ1xuICogQHBhcmFtIHtTdHJpbmd9IGZuXG4gKiBAcGFyYW0ge09iamVjdH0gW2NvbnRleHRdXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaW52b2tlQXJyYXlBcmcoYXJnLCBmbiwgY29udGV4dCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGFyZykpIHtcbiAgICAgICAgZWFjaChhcmcsIGNvbnRleHRbZm5dLCBjb250ZXh0KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiB3YWxrIG9iamVjdHMgYW5kIGFycmF5c1xuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0b3JcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKi9cbmZ1bmN0aW9uIGVhY2gob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIHZhciBpO1xuXG4gICAgaWYgKCFvYmopIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChvYmouZm9yRWFjaCkge1xuICAgICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgfSBlbHNlIGlmIChvYmoubGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaSA9IDA7XG4gICAgICAgIHdoaWxlIChpIDwgb2JqLmxlbmd0aCkge1xuICAgICAgICAgICAgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaik7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XG4gICAgICAgICAgICBvYmouaGFzT3duUHJvcGVydHkoaSkgJiYgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogd3JhcCBhIG1ldGhvZCB3aXRoIGEgZGVwcmVjYXRpb24gd2FybmluZyBhbmQgc3RhY2sgdHJhY2VcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IEEgbmV3IGZ1bmN0aW9uIHdyYXBwaW5nIHRoZSBzdXBwbGllZCBtZXRob2QuXG4gKi9cbmZ1bmN0aW9uIGRlcHJlY2F0ZShtZXRob2QsIG5hbWUsIG1lc3NhZ2UpIHtcbiAgICB2YXIgZGVwcmVjYXRpb25NZXNzYWdlID0gJ0RFUFJFQ0FURUQgTUVUSE9EOiAnICsgbmFtZSArICdcXG4nICsgbWVzc2FnZSArICcgQVQgXFxuJztcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBlID0gbmV3IEVycm9yKCdnZXQtc3RhY2stdHJhY2UnKTtcbiAgICAgICAgdmFyIHN0YWNrID0gZSAmJiBlLnN0YWNrID8gZS5zdGFjay5yZXBsYWNlKC9eW15cXChdKz9bXFxuJF0vZ20sICcnKVxuICAgICAgICAgICAgLnJlcGxhY2UoL15cXHMrYXRcXHMrL2dtLCAnJylcbiAgICAgICAgICAgIC5yZXBsYWNlKC9eT2JqZWN0Ljxhbm9ueW1vdXM+XFxzKlxcKC9nbSwgJ3thbm9ueW1vdXN9KClAJykgOiAnVW5rbm93biBTdGFjayBUcmFjZSc7XG5cbiAgICAgICAgdmFyIGxvZyA9IHdpbmRvdy5jb25zb2xlICYmICh3aW5kb3cuY29uc29sZS53YXJuIHx8IHdpbmRvdy5jb25zb2xlLmxvZyk7XG4gICAgICAgIGlmIChsb2cpIHtcbiAgICAgICAgICAgIGxvZy5jYWxsKHdpbmRvdy5jb25zb2xlLCBkZXByZWNhdGlvbk1lc3NhZ2UsIHN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBleHRlbmQgb2JqZWN0LlxuICogbWVhbnMgdGhhdCBwcm9wZXJ0aWVzIGluIGRlc3Qgd2lsbCBiZSBvdmVyd3JpdHRlbiBieSB0aGUgb25lcyBpbiBzcmMuXG4gKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0gey4uLk9iamVjdH0gb2JqZWN0c190b19hc3NpZ25cbiAqIEByZXR1cm5zIHtPYmplY3R9IHRhcmdldFxuICovXG52YXIgYXNzaWduO1xuaWYgKHR5cGVvZiBPYmplY3QuYXNzaWduICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgYXNzaWduID0gZnVuY3Rpb24gYXNzaWduKHRhcmdldCkge1xuICAgICAgICBpZiAodGFyZ2V0ID09PSB1bmRlZmluZWQgfHwgdGFyZ2V0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY29udmVydCB1bmRlZmluZWQgb3IgbnVsbCB0byBvYmplY3QnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvdXRwdXQgPSBPYmplY3QodGFyZ2V0KTtcbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAxOyBpbmRleCA8IGFyZ3VtZW50cy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKHNvdXJjZSAhPT0gdW5kZWZpbmVkICYmIHNvdXJjZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIG5leHRLZXkgaW4gc291cmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuaGFzT3duUHJvcGVydHkobmV4dEtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dFtuZXh0S2V5XSA9IHNvdXJjZVtuZXh0S2V5XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG59IGVsc2Uge1xuICAgIGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG59XG5cbi8qKlxuICogZXh0ZW5kIG9iamVjdC5cbiAqIG1lYW5zIHRoYXQgcHJvcGVydGllcyBpbiBkZXN0IHdpbGwgYmUgb3ZlcndyaXR0ZW4gYnkgdGhlIG9uZXMgaW4gc3JjLlxuICogQHBhcmFtIHtPYmplY3R9IGRlc3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBzcmNcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW21lcmdlPWZhbHNlXVxuICogQHJldHVybnMge09iamVjdH0gZGVzdFxuICovXG52YXIgZXh0ZW5kID0gZGVwcmVjYXRlKGZ1bmN0aW9uIGV4dGVuZChkZXN0LCBzcmMsIG1lcmdlKSB7XG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhzcmMpO1xuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IGtleXMubGVuZ3RoKSB7XG4gICAgICAgIGlmICghbWVyZ2UgfHwgKG1lcmdlICYmIGRlc3Rba2V5c1tpXV0gPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgIGRlc3Rba2V5c1tpXV0gPSBzcmNba2V5c1tpXV07XG4gICAgICAgIH1cbiAgICAgICAgaSsrO1xuICAgIH1cbiAgICByZXR1cm4gZGVzdDtcbn0sICdleHRlbmQnLCAnVXNlIGBhc3NpZ25gLicpO1xuXG4vKipcbiAqIG1lcmdlIHRoZSB2YWx1ZXMgZnJvbSBzcmMgaW4gdGhlIGRlc3QuXG4gKiBtZWFucyB0aGF0IHByb3BlcnRpZXMgdGhhdCBleGlzdCBpbiBkZXN0IHdpbGwgbm90IGJlIG92ZXJ3cml0dGVuIGJ5IHNyY1xuICogQHBhcmFtIHtPYmplY3R9IGRlc3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBzcmNcbiAqIEByZXR1cm5zIHtPYmplY3R9IGRlc3RcbiAqL1xudmFyIG1lcmdlID0gZGVwcmVjYXRlKGZ1bmN0aW9uIG1lcmdlKGRlc3QsIHNyYykge1xuICAgIHJldHVybiBleHRlbmQoZGVzdCwgc3JjLCB0cnVlKTtcbn0sICdtZXJnZScsICdVc2UgYGFzc2lnbmAuJyk7XG5cbi8qKlxuICogc2ltcGxlIGNsYXNzIGluaGVyaXRhbmNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjaGlsZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gYmFzZVxuICogQHBhcmFtIHtPYmplY3R9IFtwcm9wZXJ0aWVzXVxuICovXG5mdW5jdGlvbiBpbmhlcml0KGNoaWxkLCBiYXNlLCBwcm9wZXJ0aWVzKSB7XG4gICAgdmFyIGJhc2VQID0gYmFzZS5wcm90b3R5cGUsXG4gICAgICAgIGNoaWxkUDtcblxuICAgIGNoaWxkUCA9IGNoaWxkLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoYmFzZVApO1xuICAgIGNoaWxkUC5jb25zdHJ1Y3RvciA9IGNoaWxkO1xuICAgIGNoaWxkUC5fc3VwZXIgPSBiYXNlUDtcblxuICAgIGlmIChwcm9wZXJ0aWVzKSB7XG4gICAgICAgIGFzc2lnbihjaGlsZFAsIHByb3BlcnRpZXMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBzaW1wbGUgZnVuY3Rpb24gYmluZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcmV0dXJucyB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIGJpbmRGbihmbiwgY29udGV4dCkge1xuICAgIHJldHVybiBmdW5jdGlvbiBib3VuZEZuKCkge1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuXG4vKipcbiAqIGxldCBhIGJvb2xlYW4gdmFsdWUgYWxzbyBiZSBhIGZ1bmN0aW9uIHRoYXQgbXVzdCByZXR1cm4gYSBib29sZWFuXG4gKiB0aGlzIGZpcnN0IGl0ZW0gaW4gYXJncyB3aWxsIGJlIHVzZWQgYXMgdGhlIGNvbnRleHRcbiAqIEBwYXJhbSB7Qm9vbGVhbnxGdW5jdGlvbn0gdmFsXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJnc11cbiAqIEByZXR1cm5zIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBib29sT3JGbih2YWwsIGFyZ3MpIHtcbiAgICBpZiAodHlwZW9mIHZhbCA9PSBUWVBFX0ZVTkNUSU9OKSB7XG4gICAgICAgIHJldHVybiB2YWwuYXBwbHkoYXJncyA/IGFyZ3NbMF0gfHwgdW5kZWZpbmVkIDogdW5kZWZpbmVkLCBhcmdzKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbDtcbn1cblxuLyoqXG4gKiB1c2UgdGhlIHZhbDIgd2hlbiB2YWwxIGlzIHVuZGVmaW5lZFxuICogQHBhcmFtIHsqfSB2YWwxXG4gKiBAcGFyYW0geyp9IHZhbDJcbiAqIEByZXR1cm5zIHsqfVxuICovXG5mdW5jdGlvbiBpZlVuZGVmaW5lZCh2YWwxLCB2YWwyKSB7XG4gICAgcmV0dXJuICh2YWwxID09PSB1bmRlZmluZWQpID8gdmFsMiA6IHZhbDE7XG59XG5cbi8qKlxuICogYWRkRXZlbnRMaXN0ZW5lciB3aXRoIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSB0YXJnZXRcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuICovXG5mdW5jdGlvbiBhZGRFdmVudExpc3RlbmVycyh0YXJnZXQsIHR5cGVzLCBoYW5kbGVyKSB7XG4gICAgZWFjaChzcGxpdFN0cih0eXBlcyksIGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgaGFuZGxlciwgZmFsc2UpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIHJlbW92ZUV2ZW50TGlzdGVuZXIgd2l0aCBtdWx0aXBsZSBldmVudHMgYXQgb25jZVxuICogQHBhcmFtIHtFdmVudFRhcmdldH0gdGFyZ2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZXNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcnModGFyZ2V0LCB0eXBlcywgaGFuZGxlcikge1xuICAgIGVhY2goc3BsaXRTdHIodHlwZXMpLCBmdW5jdGlvbih0eXBlKSB7XG4gICAgICAgIHRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBmaW5kIGlmIGEgbm9kZSBpcyBpbiB0aGUgZ2l2ZW4gcGFyZW50XG4gKiBAbWV0aG9kIGhhc1BhcmVudFxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbm9kZVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50XG4gKiBAcmV0dXJuIHtCb29sZWFufSBmb3VuZFxuICovXG5mdW5jdGlvbiBoYXNQYXJlbnQobm9kZSwgcGFyZW50KSB7XG4gICAgd2hpbGUgKG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUgPT0gcGFyZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogc21hbGwgaW5kZXhPZiB3cmFwcGVyXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcGFyYW0ge1N0cmluZ30gZmluZFxuICogQHJldHVybnMge0Jvb2xlYW59IGZvdW5kXG4gKi9cbmZ1bmN0aW9uIGluU3RyKHN0ciwgZmluZCkge1xuICAgIHJldHVybiBzdHIuaW5kZXhPZihmaW5kKSA+IC0xO1xufVxuXG4vKipcbiAqIHNwbGl0IHN0cmluZyBvbiB3aGl0ZXNwYWNlXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJucyB7QXJyYXl9IHdvcmRzXG4gKi9cbmZ1bmN0aW9uIHNwbGl0U3RyKHN0cikge1xuICAgIHJldHVybiBzdHIudHJpbSgpLnNwbGl0KC9cXHMrL2cpO1xufVxuXG4vKipcbiAqIGZpbmQgaWYgYSBhcnJheSBjb250YWlucyB0aGUgb2JqZWN0IHVzaW5nIGluZGV4T2Ygb3IgYSBzaW1wbGUgcG9seUZpbGxcbiAqIEBwYXJhbSB7QXJyYXl9IHNyY1xuICogQHBhcmFtIHtTdHJpbmd9IGZpbmRcbiAqIEBwYXJhbSB7U3RyaW5nfSBbZmluZEJ5S2V5XVxuICogQHJldHVybiB7Qm9vbGVhbnxOdW1iZXJ9IGZhbHNlIHdoZW4gbm90IGZvdW5kLCBvciB0aGUgaW5kZXhcbiAqL1xuZnVuY3Rpb24gaW5BcnJheShzcmMsIGZpbmQsIGZpbmRCeUtleSkge1xuICAgIGlmIChzcmMuaW5kZXhPZiAmJiAhZmluZEJ5S2V5KSB7XG4gICAgICAgIHJldHVybiBzcmMuaW5kZXhPZihmaW5kKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgIHdoaWxlIChpIDwgc3JjLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKChmaW5kQnlLZXkgJiYgc3JjW2ldW2ZpbmRCeUtleV0gPT0gZmluZCkgfHwgKCFmaW5kQnlLZXkgJiYgc3JjW2ldID09PSBmaW5kKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG59XG5cbi8qKlxuICogY29udmVydCBhcnJheS1saWtlIG9iamVjdHMgdG8gcmVhbCBhcnJheXNcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdG9BcnJheShvYmopIHtcbiAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwob2JqLCAwKTtcbn1cblxuLyoqXG4gKiB1bmlxdWUgYXJyYXkgd2l0aCBvYmplY3RzIGJhc2VkIG9uIGEga2V5IChsaWtlICdpZCcpIG9yIGp1c3QgYnkgdGhlIGFycmF5J3MgdmFsdWVcbiAqIEBwYXJhbSB7QXJyYXl9IHNyYyBbe2lkOjF9LHtpZDoyfSx7aWQ6MX1dXG4gKiBAcGFyYW0ge1N0cmluZ30gW2tleV1cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW3NvcnQ9RmFsc2VdXG4gKiBAcmV0dXJucyB7QXJyYXl9IFt7aWQ6MX0se2lkOjJ9XVxuICovXG5mdW5jdGlvbiB1bmlxdWVBcnJheShzcmMsIGtleSwgc29ydCkge1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIHZhciBpID0gMDtcblxuICAgIHdoaWxlIChpIDwgc3JjLmxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsID0ga2V5ID8gc3JjW2ldW2tleV0gOiBzcmNbaV07XG4gICAgICAgIGlmIChpbkFycmF5KHZhbHVlcywgdmFsKSA8IDApIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChzcmNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHZhbHVlc1tpXSA9IHZhbDtcbiAgICAgICAgaSsrO1xuICAgIH1cblxuICAgIGlmIChzb3J0KSB7XG4gICAgICAgIGlmICgha2V5KSB7XG4gICAgICAgICAgICByZXN1bHRzID0gcmVzdWx0cy5zb3J0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXN1bHRzID0gcmVzdWx0cy5zb3J0KGZ1bmN0aW9uIHNvcnRVbmlxdWVBcnJheShhLCBiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFba2V5XSA+IGJba2V5XTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbi8qKlxuICogZ2V0IHRoZSBwcmVmaXhlZCBwcm9wZXJ0eVxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gKiBAcmV0dXJucyB7U3RyaW5nfFVuZGVmaW5lZH0gcHJlZml4ZWRcbiAqL1xuZnVuY3Rpb24gcHJlZml4ZWQob2JqLCBwcm9wZXJ0eSkge1xuICAgIHZhciBwcmVmaXgsIHByb3A7XG4gICAgdmFyIGNhbWVsUHJvcCA9IHByb3BlcnR5WzBdLnRvVXBwZXJDYXNlKCkgKyBwcm9wZXJ0eS5zbGljZSgxKTtcblxuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IFZFTkRPUl9QUkVGSVhFUy5sZW5ndGgpIHtcbiAgICAgICAgcHJlZml4ID0gVkVORE9SX1BSRUZJWEVTW2ldO1xuICAgICAgICBwcm9wID0gKHByZWZpeCkgPyBwcmVmaXggKyBjYW1lbFByb3AgOiBwcm9wZXJ0eTtcblxuICAgICAgICBpZiAocHJvcCBpbiBvYmopIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9wO1xuICAgICAgICB9XG4gICAgICAgIGkrKztcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBnZXQgYSB1bmlxdWUgaWRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IHVuaXF1ZUlkXG4gKi9cbnZhciBfdW5pcXVlSWQgPSAxO1xuZnVuY3Rpb24gdW5pcXVlSWQoKSB7XG4gICAgcmV0dXJuIF91bmlxdWVJZCsrO1xufVxuXG4vKipcbiAqIGdldCB0aGUgd2luZG93IG9iamVjdCBvZiBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJucyB7RG9jdW1lbnRWaWV3fFdpbmRvd31cbiAqL1xuZnVuY3Rpb24gZ2V0V2luZG93Rm9yRWxlbWVudChlbGVtZW50KSB7XG4gICAgdmFyIGRvYyA9IGVsZW1lbnQub3duZXJEb2N1bWVudCB8fCBlbGVtZW50O1xuICAgIHJldHVybiAoZG9jLmRlZmF1bHRWaWV3IHx8IGRvYy5wYXJlbnRXaW5kb3cgfHwgd2luZG93KTtcbn1cblxudmFyIE1PQklMRV9SRUdFWCA9IC9tb2JpbGV8dGFibGV0fGlwKGFkfGhvbmV8b2QpfGFuZHJvaWQvaTtcblxudmFyIFNVUFBPUlRfVE9VQ0ggPSAoJ29udG91Y2hzdGFydCcgaW4gd2luZG93KTtcbnZhciBTVVBQT1JUX1BPSU5URVJfRVZFTlRTID0gcHJlZml4ZWQod2luZG93LCAnUG9pbnRlckV2ZW50JykgIT09IHVuZGVmaW5lZDtcbnZhciBTVVBQT1JUX09OTFlfVE9VQ0ggPSBTVVBQT1JUX1RPVUNIICYmIE1PQklMRV9SRUdFWC50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG52YXIgSU5QVVRfVFlQRV9UT1VDSCA9ICd0b3VjaCc7XG52YXIgSU5QVVRfVFlQRV9QRU4gPSAncGVuJztcbnZhciBJTlBVVF9UWVBFX01PVVNFID0gJ21vdXNlJztcbnZhciBJTlBVVF9UWVBFX0tJTkVDVCA9ICdraW5lY3QnO1xuXG52YXIgQ09NUFVURV9JTlRFUlZBTCA9IDI1O1xuXG52YXIgSU5QVVRfU1RBUlQgPSAxO1xudmFyIElOUFVUX01PVkUgPSAyO1xudmFyIElOUFVUX0VORCA9IDQ7XG52YXIgSU5QVVRfQ0FOQ0VMID0gODtcblxudmFyIERJUkVDVElPTl9OT05FID0gMTtcbnZhciBESVJFQ1RJT05fTEVGVCA9IDI7XG52YXIgRElSRUNUSU9OX1JJR0hUID0gNDtcbnZhciBESVJFQ1RJT05fVVAgPSA4O1xudmFyIERJUkVDVElPTl9ET1dOID0gMTY7XG5cbnZhciBESVJFQ1RJT05fSE9SSVpPTlRBTCA9IERJUkVDVElPTl9MRUZUIHwgRElSRUNUSU9OX1JJR0hUO1xudmFyIERJUkVDVElPTl9WRVJUSUNBTCA9IERJUkVDVElPTl9VUCB8IERJUkVDVElPTl9ET1dOO1xudmFyIERJUkVDVElPTl9BTEwgPSBESVJFQ1RJT05fSE9SSVpPTlRBTCB8IERJUkVDVElPTl9WRVJUSUNBTDtcblxudmFyIFBST1BTX1hZID0gWyd4JywgJ3knXTtcbnZhciBQUk9QU19DTElFTlRfWFkgPSBbJ2NsaWVudFgnLCAnY2xpZW50WSddO1xuXG4vKipcbiAqIGNyZWF0ZSBuZXcgaW5wdXQgdHlwZSBtYW5hZ2VyXG4gKiBAcGFyYW0ge01hbmFnZXJ9IG1hbmFnZXJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7SW5wdXR9XG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gSW5wdXQobWFuYWdlciwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5tYW5hZ2VyID0gbWFuYWdlcjtcbiAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgdGhpcy5lbGVtZW50ID0gbWFuYWdlci5lbGVtZW50O1xuICAgIHRoaXMudGFyZ2V0ID0gbWFuYWdlci5vcHRpb25zLmlucHV0VGFyZ2V0O1xuXG4gICAgLy8gc21hbGxlciB3cmFwcGVyIGFyb3VuZCB0aGUgaGFuZGxlciwgZm9yIHRoZSBzY29wZSBhbmQgdGhlIGVuYWJsZWQgc3RhdGUgb2YgdGhlIG1hbmFnZXIsXG4gICAgLy8gc28gd2hlbiBkaXNhYmxlZCB0aGUgaW5wdXQgZXZlbnRzIGFyZSBjb21wbGV0ZWx5IGJ5cGFzc2VkLlxuICAgIHRoaXMuZG9tSGFuZGxlciA9IGZ1bmN0aW9uKGV2KSB7XG4gICAgICAgIGlmIChib29sT3JGbihtYW5hZ2VyLm9wdGlvbnMuZW5hYmxlLCBbbWFuYWdlcl0pKSB7XG4gICAgICAgICAgICBzZWxmLmhhbmRsZXIoZXYpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG59XG5cbklucHV0LnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBzaG91bGQgaGFuZGxlIHRoZSBpbnB1dEV2ZW50IGRhdGEgYW5kIHRyaWdnZXIgdGhlIGNhbGxiYWNrXG4gICAgICogQHZpcnR1YWxcbiAgICAgKi9cbiAgICBoYW5kbGVyOiBmdW5jdGlvbigpIHsgfSxcblxuICAgIC8qKlxuICAgICAqIGJpbmQgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIGluaXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLmV2RWwgJiYgYWRkRXZlbnRMaXN0ZW5lcnModGhpcy5lbGVtZW50LCB0aGlzLmV2RWwsIHRoaXMuZG9tSGFuZGxlcik7XG4gICAgICAgIHRoaXMuZXZUYXJnZXQgJiYgYWRkRXZlbnRMaXN0ZW5lcnModGhpcy50YXJnZXQsIHRoaXMuZXZUYXJnZXQsIHRoaXMuZG9tSGFuZGxlcik7XG4gICAgICAgIHRoaXMuZXZXaW4gJiYgYWRkRXZlbnRMaXN0ZW5lcnMoZ2V0V2luZG93Rm9yRWxlbWVudCh0aGlzLmVsZW1lbnQpLCB0aGlzLmV2V2luLCB0aGlzLmRvbUhhbmRsZXIpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiB1bmJpbmQgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLmV2RWwgJiYgcmVtb3ZlRXZlbnRMaXN0ZW5lcnModGhpcy5lbGVtZW50LCB0aGlzLmV2RWwsIHRoaXMuZG9tSGFuZGxlcik7XG4gICAgICAgIHRoaXMuZXZUYXJnZXQgJiYgcmVtb3ZlRXZlbnRMaXN0ZW5lcnModGhpcy50YXJnZXQsIHRoaXMuZXZUYXJnZXQsIHRoaXMuZG9tSGFuZGxlcik7XG4gICAgICAgIHRoaXMuZXZXaW4gJiYgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoZ2V0V2luZG93Rm9yRWxlbWVudCh0aGlzLmVsZW1lbnQpLCB0aGlzLmV2V2luLCB0aGlzLmRvbUhhbmRsZXIpO1xuICAgIH1cbn07XG5cbi8qKlxuICogY3JlYXRlIG5ldyBpbnB1dCB0eXBlIG1hbmFnZXJcbiAqIGNhbGxlZCBieSB0aGUgTWFuYWdlciBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtIYW1tZXJ9IG1hbmFnZXJcbiAqIEByZXR1cm5zIHtJbnB1dH1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5wdXRJbnN0YW5jZShtYW5hZ2VyKSB7XG4gICAgdmFyIFR5cGU7XG4gICAgdmFyIGlucHV0Q2xhc3MgPSBtYW5hZ2VyLm9wdGlvbnMuaW5wdXRDbGFzcztcblxuICAgIGlmIChpbnB1dENsYXNzKSB7XG4gICAgICAgIFR5cGUgPSBpbnB1dENsYXNzO1xuICAgIH0gZWxzZSBpZiAoU1VQUE9SVF9QT0lOVEVSX0VWRU5UUykge1xuICAgICAgICBUeXBlID0gUG9pbnRlckV2ZW50SW5wdXQ7XG4gICAgfSBlbHNlIGlmIChTVVBQT1JUX09OTFlfVE9VQ0gpIHtcbiAgICAgICAgVHlwZSA9IFRvdWNoSW5wdXQ7XG4gICAgfSBlbHNlIGlmICghU1VQUE9SVF9UT1VDSCkge1xuICAgICAgICBUeXBlID0gTW91c2VJbnB1dDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBUeXBlID0gVG91Y2hNb3VzZUlucHV0O1xuICAgIH1cbiAgICByZXR1cm4gbmV3IChUeXBlKShtYW5hZ2VyLCBpbnB1dEhhbmRsZXIpO1xufVxuXG4vKipcbiAqIGhhbmRsZSBpbnB1dCBldmVudHNcbiAqIEBwYXJhbSB7TWFuYWdlcn0gbWFuYWdlclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50VHlwZVxuICogQHBhcmFtIHtPYmplY3R9IGlucHV0XG4gKi9cbmZ1bmN0aW9uIGlucHV0SGFuZGxlcihtYW5hZ2VyLCBldmVudFR5cGUsIGlucHV0KSB7XG4gICAgdmFyIHBvaW50ZXJzTGVuID0gaW5wdXQucG9pbnRlcnMubGVuZ3RoO1xuICAgIHZhciBjaGFuZ2VkUG9pbnRlcnNMZW4gPSBpbnB1dC5jaGFuZ2VkUG9pbnRlcnMubGVuZ3RoO1xuICAgIHZhciBpc0ZpcnN0ID0gKGV2ZW50VHlwZSAmIElOUFVUX1NUQVJUICYmIChwb2ludGVyc0xlbiAtIGNoYW5nZWRQb2ludGVyc0xlbiA9PT0gMCkpO1xuICAgIHZhciBpc0ZpbmFsID0gKGV2ZW50VHlwZSAmIChJTlBVVF9FTkQgfCBJTlBVVF9DQU5DRUwpICYmIChwb2ludGVyc0xlbiAtIGNoYW5nZWRQb2ludGVyc0xlbiA9PT0gMCkpO1xuXG4gICAgaW5wdXQuaXNGaXJzdCA9ICEhaXNGaXJzdDtcbiAgICBpbnB1dC5pc0ZpbmFsID0gISFpc0ZpbmFsO1xuXG4gICAgaWYgKGlzRmlyc3QpIHtcbiAgICAgICAgbWFuYWdlci5zZXNzaW9uID0ge307XG4gICAgfVxuXG4gICAgLy8gc291cmNlIGV2ZW50IGlzIHRoZSBub3JtYWxpemVkIHZhbHVlIG9mIHRoZSBkb21FdmVudHNcbiAgICAvLyBsaWtlICd0b3VjaHN0YXJ0LCBtb3VzZXVwLCBwb2ludGVyZG93bidcbiAgICBpbnB1dC5ldmVudFR5cGUgPSBldmVudFR5cGU7XG5cbiAgICAvLyBjb21wdXRlIHNjYWxlLCByb3RhdGlvbiBldGNcbiAgICBjb21wdXRlSW5wdXREYXRhKG1hbmFnZXIsIGlucHV0KTtcblxuICAgIC8vIGVtaXQgc2VjcmV0IGV2ZW50XG4gICAgbWFuYWdlci5lbWl0KCdoYW1tZXIuaW5wdXQnLCBpbnB1dCk7XG5cbiAgICBtYW5hZ2VyLnJlY29nbml6ZShpbnB1dCk7XG4gICAgbWFuYWdlci5zZXNzaW9uLnByZXZJbnB1dCA9IGlucHV0O1xufVxuXG4vKipcbiAqIGV4dGVuZCB0aGUgZGF0YSB3aXRoIHNvbWUgdXNhYmxlIHByb3BlcnRpZXMgbGlrZSBzY2FsZSwgcm90YXRlLCB2ZWxvY2l0eSBldGNcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYW5hZ2VyXG4gKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAqL1xuZnVuY3Rpb24gY29tcHV0ZUlucHV0RGF0YShtYW5hZ2VyLCBpbnB1dCkge1xuICAgIHZhciBzZXNzaW9uID0gbWFuYWdlci5zZXNzaW9uO1xuICAgIHZhciBwb2ludGVycyA9IGlucHV0LnBvaW50ZXJzO1xuICAgIHZhciBwb2ludGVyc0xlbmd0aCA9IHBvaW50ZXJzLmxlbmd0aDtcblxuICAgIC8vIHN0b3JlIHRoZSBmaXJzdCBpbnB1dCB0byBjYWxjdWxhdGUgdGhlIGRpc3RhbmNlIGFuZCBkaXJlY3Rpb25cbiAgICBpZiAoIXNlc3Npb24uZmlyc3RJbnB1dCkge1xuICAgICAgICBzZXNzaW9uLmZpcnN0SW5wdXQgPSBzaW1wbGVDbG9uZUlucHV0RGF0YShpbnB1dCk7XG4gICAgfVxuXG4gICAgLy8gdG8gY29tcHV0ZSBzY2FsZSBhbmQgcm90YXRpb24gd2UgbmVlZCB0byBzdG9yZSB0aGUgbXVsdGlwbGUgdG91Y2hlc1xuICAgIGlmIChwb2ludGVyc0xlbmd0aCA+IDEgJiYgIXNlc3Npb24uZmlyc3RNdWx0aXBsZSkge1xuICAgICAgICBzZXNzaW9uLmZpcnN0TXVsdGlwbGUgPSBzaW1wbGVDbG9uZUlucHV0RGF0YShpbnB1dCk7XG4gICAgfSBlbHNlIGlmIChwb2ludGVyc0xlbmd0aCA9PT0gMSkge1xuICAgICAgICBzZXNzaW9uLmZpcnN0TXVsdGlwbGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgZmlyc3RJbnB1dCA9IHNlc3Npb24uZmlyc3RJbnB1dDtcbiAgICB2YXIgZmlyc3RNdWx0aXBsZSA9IHNlc3Npb24uZmlyc3RNdWx0aXBsZTtcbiAgICB2YXIgb2Zmc2V0Q2VudGVyID0gZmlyc3RNdWx0aXBsZSA/IGZpcnN0TXVsdGlwbGUuY2VudGVyIDogZmlyc3RJbnB1dC5jZW50ZXI7XG5cbiAgICB2YXIgY2VudGVyID0gaW5wdXQuY2VudGVyID0gZ2V0Q2VudGVyKHBvaW50ZXJzKTtcbiAgICBpbnB1dC50aW1lU3RhbXAgPSBub3coKTtcbiAgICBpbnB1dC5kZWx0YVRpbWUgPSBpbnB1dC50aW1lU3RhbXAgLSBmaXJzdElucHV0LnRpbWVTdGFtcDtcblxuICAgIGlucHV0LmFuZ2xlID0gZ2V0QW5nbGUob2Zmc2V0Q2VudGVyLCBjZW50ZXIpO1xuICAgIGlucHV0LmRpc3RhbmNlID0gZ2V0RGlzdGFuY2Uob2Zmc2V0Q2VudGVyLCBjZW50ZXIpO1xuXG4gICAgY29tcHV0ZURlbHRhWFkoc2Vzc2lvbiwgaW5wdXQpO1xuICAgIGlucHV0Lm9mZnNldERpcmVjdGlvbiA9IGdldERpcmVjdGlvbihpbnB1dC5kZWx0YVgsIGlucHV0LmRlbHRhWSk7XG5cbiAgICB2YXIgb3ZlcmFsbFZlbG9jaXR5ID0gZ2V0VmVsb2NpdHkoaW5wdXQuZGVsdGFUaW1lLCBpbnB1dC5kZWx0YVgsIGlucHV0LmRlbHRhWSk7XG4gICAgaW5wdXQub3ZlcmFsbFZlbG9jaXR5WCA9IG92ZXJhbGxWZWxvY2l0eS54O1xuICAgIGlucHV0Lm92ZXJhbGxWZWxvY2l0eVkgPSBvdmVyYWxsVmVsb2NpdHkueTtcbiAgICBpbnB1dC5vdmVyYWxsVmVsb2NpdHkgPSAoYWJzKG92ZXJhbGxWZWxvY2l0eS54KSA+IGFicyhvdmVyYWxsVmVsb2NpdHkueSkpID8gb3ZlcmFsbFZlbG9jaXR5LnggOiBvdmVyYWxsVmVsb2NpdHkueTtcblxuICAgIGlucHV0LnNjYWxlID0gZmlyc3RNdWx0aXBsZSA/IGdldFNjYWxlKGZpcnN0TXVsdGlwbGUucG9pbnRlcnMsIHBvaW50ZXJzKSA6IDE7XG4gICAgaW5wdXQucm90YXRpb24gPSBmaXJzdE11bHRpcGxlID8gZ2V0Um90YXRpb24oZmlyc3RNdWx0aXBsZS5wb2ludGVycywgcG9pbnRlcnMpIDogMDtcblxuICAgIGlucHV0Lm1heFBvaW50ZXJzID0gIXNlc3Npb24ucHJldklucHV0ID8gaW5wdXQucG9pbnRlcnMubGVuZ3RoIDogKChpbnB1dC5wb2ludGVycy5sZW5ndGggPlxuICAgICAgICBzZXNzaW9uLnByZXZJbnB1dC5tYXhQb2ludGVycykgPyBpbnB1dC5wb2ludGVycy5sZW5ndGggOiBzZXNzaW9uLnByZXZJbnB1dC5tYXhQb2ludGVycyk7XG5cbiAgICBjb21wdXRlSW50ZXJ2YWxJbnB1dERhdGEoc2Vzc2lvbiwgaW5wdXQpO1xuXG4gICAgLy8gZmluZCB0aGUgY29ycmVjdCB0YXJnZXRcbiAgICB2YXIgdGFyZ2V0ID0gbWFuYWdlci5lbGVtZW50O1xuICAgIGlmIChoYXNQYXJlbnQoaW5wdXQuc3JjRXZlbnQudGFyZ2V0LCB0YXJnZXQpKSB7XG4gICAgICAgIHRhcmdldCA9IGlucHV0LnNyY0V2ZW50LnRhcmdldDtcbiAgICB9XG4gICAgaW5wdXQudGFyZ2V0ID0gdGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBjb21wdXRlRGVsdGFYWShzZXNzaW9uLCBpbnB1dCkge1xuICAgIHZhciBjZW50ZXIgPSBpbnB1dC5jZW50ZXI7XG4gICAgdmFyIG9mZnNldCA9IHNlc3Npb24ub2Zmc2V0RGVsdGEgfHwge307XG4gICAgdmFyIHByZXZEZWx0YSA9IHNlc3Npb24ucHJldkRlbHRhIHx8IHt9O1xuICAgIHZhciBwcmV2SW5wdXQgPSBzZXNzaW9uLnByZXZJbnB1dCB8fCB7fTtcblxuICAgIGlmIChpbnB1dC5ldmVudFR5cGUgPT09IElOUFVUX1NUQVJUIHx8IHByZXZJbnB1dC5ldmVudFR5cGUgPT09IElOUFVUX0VORCkge1xuICAgICAgICBwcmV2RGVsdGEgPSBzZXNzaW9uLnByZXZEZWx0YSA9IHtcbiAgICAgICAgICAgIHg6IHByZXZJbnB1dC5kZWx0YVggfHwgMCxcbiAgICAgICAgICAgIHk6IHByZXZJbnB1dC5kZWx0YVkgfHwgMFxuICAgICAgICB9O1xuXG4gICAgICAgIG9mZnNldCA9IHNlc3Npb24ub2Zmc2V0RGVsdGEgPSB7XG4gICAgICAgICAgICB4OiBjZW50ZXIueCxcbiAgICAgICAgICAgIHk6IGNlbnRlci55XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaW5wdXQuZGVsdGFYID0gcHJldkRlbHRhLnggKyAoY2VudGVyLnggLSBvZmZzZXQueCk7XG4gICAgaW5wdXQuZGVsdGFZID0gcHJldkRlbHRhLnkgKyAoY2VudGVyLnkgLSBvZmZzZXQueSk7XG59XG5cbi8qKlxuICogdmVsb2NpdHkgaXMgY2FsY3VsYXRlZCBldmVyeSB4IG1zXG4gKiBAcGFyYW0ge09iamVjdH0gc2Vzc2lvblxuICogQHBhcmFtIHtPYmplY3R9IGlucHV0XG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVJbnRlcnZhbElucHV0RGF0YShzZXNzaW9uLCBpbnB1dCkge1xuICAgIHZhciBsYXN0ID0gc2Vzc2lvbi5sYXN0SW50ZXJ2YWwgfHwgaW5wdXQsXG4gICAgICAgIGRlbHRhVGltZSA9IGlucHV0LnRpbWVTdGFtcCAtIGxhc3QudGltZVN0YW1wLFxuICAgICAgICB2ZWxvY2l0eSwgdmVsb2NpdHlYLCB2ZWxvY2l0eVksIGRpcmVjdGlvbjtcblxuICAgIGlmIChpbnB1dC5ldmVudFR5cGUgIT0gSU5QVVRfQ0FOQ0VMICYmIChkZWx0YVRpbWUgPiBDT01QVVRFX0lOVEVSVkFMIHx8IGxhc3QudmVsb2NpdHkgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgdmFyIGRlbHRhWCA9IGlucHV0LmRlbHRhWCAtIGxhc3QuZGVsdGFYO1xuICAgICAgICB2YXIgZGVsdGFZID0gaW5wdXQuZGVsdGFZIC0gbGFzdC5kZWx0YVk7XG5cbiAgICAgICAgdmFyIHYgPSBnZXRWZWxvY2l0eShkZWx0YVRpbWUsIGRlbHRhWCwgZGVsdGFZKTtcbiAgICAgICAgdmVsb2NpdHlYID0gdi54O1xuICAgICAgICB2ZWxvY2l0eVkgPSB2Lnk7XG4gICAgICAgIHZlbG9jaXR5ID0gKGFicyh2LngpID4gYWJzKHYueSkpID8gdi54IDogdi55O1xuICAgICAgICBkaXJlY3Rpb24gPSBnZXREaXJlY3Rpb24oZGVsdGFYLCBkZWx0YVkpO1xuXG4gICAgICAgIHNlc3Npb24ubGFzdEludGVydmFsID0gaW5wdXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdXNlIGxhdGVzdCB2ZWxvY2l0eSBpbmZvIGlmIGl0IGRvZXNuJ3Qgb3ZlcnRha2UgYSBtaW5pbXVtIHBlcmlvZFxuICAgICAgICB2ZWxvY2l0eSA9IGxhc3QudmVsb2NpdHk7XG4gICAgICAgIHZlbG9jaXR5WCA9IGxhc3QudmVsb2NpdHlYO1xuICAgICAgICB2ZWxvY2l0eVkgPSBsYXN0LnZlbG9jaXR5WTtcbiAgICAgICAgZGlyZWN0aW9uID0gbGFzdC5kaXJlY3Rpb247XG4gICAgfVxuXG4gICAgaW5wdXQudmVsb2NpdHkgPSB2ZWxvY2l0eTtcbiAgICBpbnB1dC52ZWxvY2l0eVggPSB2ZWxvY2l0eVg7XG4gICAgaW5wdXQudmVsb2NpdHlZID0gdmVsb2NpdHlZO1xuICAgIGlucHV0LmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbn1cblxuLyoqXG4gKiBjcmVhdGUgYSBzaW1wbGUgY2xvbmUgZnJvbSB0aGUgaW5wdXQgdXNlZCBmb3Igc3RvcmFnZSBvZiBmaXJzdElucHV0IGFuZCBmaXJzdE11bHRpcGxlXG4gKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAqIEByZXR1cm5zIHtPYmplY3R9IGNsb25lZElucHV0RGF0YVxuICovXG5mdW5jdGlvbiBzaW1wbGVDbG9uZUlucHV0RGF0YShpbnB1dCkge1xuICAgIC8vIG1ha2UgYSBzaW1wbGUgY29weSBvZiB0aGUgcG9pbnRlcnMgYmVjYXVzZSB3ZSB3aWxsIGdldCBhIHJlZmVyZW5jZSBpZiB3ZSBkb24ndFxuICAgIC8vIHdlIG9ubHkgbmVlZCBjbGllbnRYWSBmb3IgdGhlIGNhbGN1bGF0aW9uc1xuICAgIHZhciBwb2ludGVycyA9IFtdO1xuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IGlucHV0LnBvaW50ZXJzLmxlbmd0aCkge1xuICAgICAgICBwb2ludGVyc1tpXSA9IHtcbiAgICAgICAgICAgIGNsaWVudFg6IHJvdW5kKGlucHV0LnBvaW50ZXJzW2ldLmNsaWVudFgpLFxuICAgICAgICAgICAgY2xpZW50WTogcm91bmQoaW5wdXQucG9pbnRlcnNbaV0uY2xpZW50WSlcbiAgICAgICAgfTtcbiAgICAgICAgaSsrO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHRpbWVTdGFtcDogbm93KCksXG4gICAgICAgIHBvaW50ZXJzOiBwb2ludGVycyxcbiAgICAgICAgY2VudGVyOiBnZXRDZW50ZXIocG9pbnRlcnMpLFxuICAgICAgICBkZWx0YVg6IGlucHV0LmRlbHRhWCxcbiAgICAgICAgZGVsdGFZOiBpbnB1dC5kZWx0YVlcbiAgICB9O1xufVxuXG4vKipcbiAqIGdldCB0aGUgY2VudGVyIG9mIGFsbCB0aGUgcG9pbnRlcnNcbiAqIEBwYXJhbSB7QXJyYXl9IHBvaW50ZXJzXG4gKiBAcmV0dXJuIHtPYmplY3R9IGNlbnRlciBjb250YWlucyBgeGAgYW5kIGB5YCBwcm9wZXJ0aWVzXG4gKi9cbmZ1bmN0aW9uIGdldENlbnRlcihwb2ludGVycykge1xuICAgIHZhciBwb2ludGVyc0xlbmd0aCA9IHBvaW50ZXJzLmxlbmd0aDtcblxuICAgIC8vIG5vIG5lZWQgdG8gbG9vcCB3aGVuIG9ubHkgb25lIHRvdWNoXG4gICAgaWYgKHBvaW50ZXJzTGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiByb3VuZChwb2ludGVyc1swXS5jbGllbnRYKSxcbiAgICAgICAgICAgIHk6IHJvdW5kKHBvaW50ZXJzWzBdLmNsaWVudFkpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHggPSAwLCB5ID0gMCwgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBwb2ludGVyc0xlbmd0aCkge1xuICAgICAgICB4ICs9IHBvaW50ZXJzW2ldLmNsaWVudFg7XG4gICAgICAgIHkgKz0gcG9pbnRlcnNbaV0uY2xpZW50WTtcbiAgICAgICAgaSsrO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHg6IHJvdW5kKHggLyBwb2ludGVyc0xlbmd0aCksXG4gICAgICAgIHk6IHJvdW5kKHkgLyBwb2ludGVyc0xlbmd0aClcbiAgICB9O1xufVxuXG4vKipcbiAqIGNhbGN1bGF0ZSB0aGUgdmVsb2NpdHkgYmV0d2VlbiB0d28gcG9pbnRzLiB1bml0IGlzIGluIHB4IHBlciBtcy5cbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVRpbWVcbiAqIEBwYXJhbSB7TnVtYmVyfSB4XG4gKiBAcGFyYW0ge051bWJlcn0geVxuICogQHJldHVybiB7T2JqZWN0fSB2ZWxvY2l0eSBgeGAgYW5kIGB5YFxuICovXG5mdW5jdGlvbiBnZXRWZWxvY2l0eShkZWx0YVRpbWUsIHgsIHkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiB4IC8gZGVsdGFUaW1lIHx8IDAsXG4gICAgICAgIHk6IHkgLyBkZWx0YVRpbWUgfHwgMFxuICAgIH07XG59XG5cbi8qKlxuICogZ2V0IHRoZSBkaXJlY3Rpb24gYmV0d2VlbiB0d28gcG9pbnRzXG4gKiBAcGFyYW0ge051bWJlcn0geFxuICogQHBhcmFtIHtOdW1iZXJ9IHlcbiAqIEByZXR1cm4ge051bWJlcn0gZGlyZWN0aW9uXG4gKi9cbmZ1bmN0aW9uIGdldERpcmVjdGlvbih4LCB5KSB7XG4gICAgaWYgKHggPT09IHkpIHtcbiAgICAgICAgcmV0dXJuIERJUkVDVElPTl9OT05FO1xuICAgIH1cblxuICAgIGlmIChhYnMoeCkgPj0gYWJzKHkpKSB7XG4gICAgICAgIHJldHVybiB4IDwgMCA/IERJUkVDVElPTl9MRUZUIDogRElSRUNUSU9OX1JJR0hUO1xuICAgIH1cbiAgICByZXR1cm4geSA8IDAgPyBESVJFQ1RJT05fVVAgOiBESVJFQ1RJT05fRE9XTjtcbn1cblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIGFic29sdXRlIGRpc3RhbmNlIGJldHdlZW4gdHdvIHBvaW50c1xuICogQHBhcmFtIHtPYmplY3R9IHAxIHt4LCB5fVxuICogQHBhcmFtIHtPYmplY3R9IHAyIHt4LCB5fVxuICogQHBhcmFtIHtBcnJheX0gW3Byb3BzXSBjb250YWluaW5nIHggYW5kIHkga2V5c1xuICogQHJldHVybiB7TnVtYmVyfSBkaXN0YW5jZVxuICovXG5mdW5jdGlvbiBnZXREaXN0YW5jZShwMSwgcDIsIHByb3BzKSB7XG4gICAgaWYgKCFwcm9wcykge1xuICAgICAgICBwcm9wcyA9IFBST1BTX1hZO1xuICAgIH1cbiAgICB2YXIgeCA9IHAyW3Byb3BzWzBdXSAtIHAxW3Byb3BzWzBdXSxcbiAgICAgICAgeSA9IHAyW3Byb3BzWzFdXSAtIHAxW3Byb3BzWzFdXTtcblxuICAgIHJldHVybiBNYXRoLnNxcnQoKHggKiB4KSArICh5ICogeSkpO1xufVxuXG4vKipcbiAqIGNhbGN1bGF0ZSB0aGUgYW5nbGUgYmV0d2VlbiB0d28gY29vcmRpbmF0ZXNcbiAqIEBwYXJhbSB7T2JqZWN0fSBwMVxuICogQHBhcmFtIHtPYmplY3R9IHAyXG4gKiBAcGFyYW0ge0FycmF5fSBbcHJvcHNdIGNvbnRhaW5pbmcgeCBhbmQgeSBrZXlzXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IGFuZ2xlXG4gKi9cbmZ1bmN0aW9uIGdldEFuZ2xlKHAxLCBwMiwgcHJvcHMpIHtcbiAgICBpZiAoIXByb3BzKSB7XG4gICAgICAgIHByb3BzID0gUFJPUFNfWFk7XG4gICAgfVxuICAgIHZhciB4ID0gcDJbcHJvcHNbMF1dIC0gcDFbcHJvcHNbMF1dLFxuICAgICAgICB5ID0gcDJbcHJvcHNbMV1dIC0gcDFbcHJvcHNbMV1dO1xuICAgIHJldHVybiBNYXRoLmF0YW4yKHksIHgpICogMTgwIC8gTWF0aC5QSTtcbn1cblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIHJvdGF0aW9uIGRlZ3JlZXMgYmV0d2VlbiB0d28gcG9pbnRlcnNldHNcbiAqIEBwYXJhbSB7QXJyYXl9IHN0YXJ0IGFycmF5IG9mIHBvaW50ZXJzXG4gKiBAcGFyYW0ge0FycmF5fSBlbmQgYXJyYXkgb2YgcG9pbnRlcnNcbiAqIEByZXR1cm4ge051bWJlcn0gcm90YXRpb25cbiAqL1xuZnVuY3Rpb24gZ2V0Um90YXRpb24oc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiBnZXRBbmdsZShlbmRbMV0sIGVuZFswXSwgUFJPUFNfQ0xJRU5UX1hZKSArIGdldEFuZ2xlKHN0YXJ0WzFdLCBzdGFydFswXSwgUFJPUFNfQ0xJRU5UX1hZKTtcbn1cblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIHNjYWxlIGZhY3RvciBiZXR3ZWVuIHR3byBwb2ludGVyc2V0c1xuICogbm8gc2NhbGUgaXMgMSwgYW5kIGdvZXMgZG93biB0byAwIHdoZW4gcGluY2hlZCB0b2dldGhlciwgYW5kIGJpZ2dlciB3aGVuIHBpbmNoZWQgb3V0XG4gKiBAcGFyYW0ge0FycmF5fSBzdGFydCBhcnJheSBvZiBwb2ludGVyc1xuICogQHBhcmFtIHtBcnJheX0gZW5kIGFycmF5IG9mIHBvaW50ZXJzXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IHNjYWxlXG4gKi9cbmZ1bmN0aW9uIGdldFNjYWxlKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gZ2V0RGlzdGFuY2UoZW5kWzBdLCBlbmRbMV0sIFBST1BTX0NMSUVOVF9YWSkgLyBnZXREaXN0YW5jZShzdGFydFswXSwgc3RhcnRbMV0sIFBST1BTX0NMSUVOVF9YWSk7XG59XG5cbnZhciBNT1VTRV9JTlBVVF9NQVAgPSB7XG4gICAgbW91c2Vkb3duOiBJTlBVVF9TVEFSVCxcbiAgICBtb3VzZW1vdmU6IElOUFVUX01PVkUsXG4gICAgbW91c2V1cDogSU5QVVRfRU5EXG59O1xuXG52YXIgTU9VU0VfRUxFTUVOVF9FVkVOVFMgPSAnbW91c2Vkb3duJztcbnZhciBNT1VTRV9XSU5ET1dfRVZFTlRTID0gJ21vdXNlbW92ZSBtb3VzZXVwJztcblxuLyoqXG4gKiBNb3VzZSBldmVudHMgaW5wdXRcbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgSW5wdXRcbiAqL1xuZnVuY3Rpb24gTW91c2VJbnB1dCgpIHtcbiAgICB0aGlzLmV2RWwgPSBNT1VTRV9FTEVNRU5UX0VWRU5UUztcbiAgICB0aGlzLmV2V2luID0gTU9VU0VfV0lORE9XX0VWRU5UUztcblxuICAgIHRoaXMucHJlc3NlZCA9IGZhbHNlOyAvLyBtb3VzZWRvd24gc3RhdGVcblxuICAgIElucHV0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbmluaGVyaXQoTW91c2VJbnB1dCwgSW5wdXQsIHtcbiAgICAvKipcbiAgICAgKiBoYW5kbGUgbW91c2UgZXZlbnRzXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAgICovXG4gICAgaGFuZGxlcjogZnVuY3Rpb24gTUVoYW5kbGVyKGV2KSB7XG4gICAgICAgIHZhciBldmVudFR5cGUgPSBNT1VTRV9JTlBVVF9NQVBbZXYudHlwZV07XG5cbiAgICAgICAgLy8gb24gc3RhcnQgd2Ugd2FudCB0byBoYXZlIHRoZSBsZWZ0IG1vdXNlIGJ1dHRvbiBkb3duXG4gICAgICAgIGlmIChldmVudFR5cGUgJiBJTlBVVF9TVEFSVCAmJiBldi5idXR0b24gPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMucHJlc3NlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnRUeXBlICYgSU5QVVRfTU9WRSAmJiBldi53aGljaCAhPT0gMSkge1xuICAgICAgICAgICAgZXZlbnRUeXBlID0gSU5QVVRfRU5EO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbW91c2UgbXVzdCBiZSBkb3duXG4gICAgICAgIGlmICghdGhpcy5wcmVzc2VkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnRUeXBlICYgSU5QVVRfRU5EKSB7XG4gICAgICAgICAgICB0aGlzLnByZXNzZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FsbGJhY2sodGhpcy5tYW5hZ2VyLCBldmVudFR5cGUsIHtcbiAgICAgICAgICAgIHBvaW50ZXJzOiBbZXZdLFxuICAgICAgICAgICAgY2hhbmdlZFBvaW50ZXJzOiBbZXZdLFxuICAgICAgICAgICAgcG9pbnRlclR5cGU6IElOUFVUX1RZUEVfTU9VU0UsXG4gICAgICAgICAgICBzcmNFdmVudDogZXZcbiAgICAgICAgfSk7XG4gICAgfVxufSk7XG5cbnZhciBQT0lOVEVSX0lOUFVUX01BUCA9IHtcbiAgICBwb2ludGVyZG93bjogSU5QVVRfU1RBUlQsXG4gICAgcG9pbnRlcm1vdmU6IElOUFVUX01PVkUsXG4gICAgcG9pbnRlcnVwOiBJTlBVVF9FTkQsXG4gICAgcG9pbnRlcmNhbmNlbDogSU5QVVRfQ0FOQ0VMLFxuICAgIHBvaW50ZXJvdXQ6IElOUFVUX0NBTkNFTFxufTtcblxuLy8gaW4gSUUxMCB0aGUgcG9pbnRlciB0eXBlcyBpcyBkZWZpbmVkIGFzIGFuIGVudW1cbnZhciBJRTEwX1BPSU5URVJfVFlQRV9FTlVNID0ge1xuICAgIDI6IElOUFVUX1RZUEVfVE9VQ0gsXG4gICAgMzogSU5QVVRfVFlQRV9QRU4sXG4gICAgNDogSU5QVVRfVFlQRV9NT1VTRSxcbiAgICA1OiBJTlBVVF9UWVBFX0tJTkVDVCAvLyBzZWUgaHR0cHM6Ly90d2l0dGVyLmNvbS9qYWNvYnJvc3NpL3N0YXR1cy80ODA1OTY0Mzg0ODk4OTA4MTZcbn07XG5cbnZhciBQT0lOVEVSX0VMRU1FTlRfRVZFTlRTID0gJ3BvaW50ZXJkb3duJztcbnZhciBQT0lOVEVSX1dJTkRPV19FVkVOVFMgPSAncG9pbnRlcm1vdmUgcG9pbnRlcnVwIHBvaW50ZXJjYW5jZWwnO1xuXG4vLyBJRTEwIGhhcyBwcmVmaXhlZCBzdXBwb3J0LCBhbmQgY2FzZS1zZW5zaXRpdmVcbmlmICh3aW5kb3cuTVNQb2ludGVyRXZlbnQgJiYgIXdpbmRvdy5Qb2ludGVyRXZlbnQpIHtcbiAgICBQT0lOVEVSX0VMRU1FTlRfRVZFTlRTID0gJ01TUG9pbnRlckRvd24nO1xuICAgIFBPSU5URVJfV0lORE9XX0VWRU5UUyA9ICdNU1BvaW50ZXJNb3ZlIE1TUG9pbnRlclVwIE1TUG9pbnRlckNhbmNlbCc7XG59XG5cbi8qKlxuICogUG9pbnRlciBldmVudHMgaW5wdXRcbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgSW5wdXRcbiAqL1xuZnVuY3Rpb24gUG9pbnRlckV2ZW50SW5wdXQoKSB7XG4gICAgdGhpcy5ldkVsID0gUE9JTlRFUl9FTEVNRU5UX0VWRU5UUztcbiAgICB0aGlzLmV2V2luID0gUE9JTlRFUl9XSU5ET1dfRVZFTlRTO1xuXG4gICAgSW5wdXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIHRoaXMuc3RvcmUgPSAodGhpcy5tYW5hZ2VyLnNlc3Npb24ucG9pbnRlckV2ZW50cyA9IFtdKTtcbn1cblxuaW5oZXJpdChQb2ludGVyRXZlbnRJbnB1dCwgSW5wdXQsIHtcbiAgICAvKipcbiAgICAgKiBoYW5kbGUgbW91c2UgZXZlbnRzXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAgICovXG4gICAgaGFuZGxlcjogZnVuY3Rpb24gUEVoYW5kbGVyKGV2KSB7XG4gICAgICAgIHZhciBzdG9yZSA9IHRoaXMuc3RvcmU7XG4gICAgICAgIHZhciByZW1vdmVQb2ludGVyID0gZmFsc2U7XG5cbiAgICAgICAgdmFyIGV2ZW50VHlwZU5vcm1hbGl6ZWQgPSBldi50eXBlLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgnbXMnLCAnJyk7XG4gICAgICAgIHZhciBldmVudFR5cGUgPSBQT0lOVEVSX0lOUFVUX01BUFtldmVudFR5cGVOb3JtYWxpemVkXTtcbiAgICAgICAgdmFyIHBvaW50ZXJUeXBlID0gSUUxMF9QT0lOVEVSX1RZUEVfRU5VTVtldi5wb2ludGVyVHlwZV0gfHwgZXYucG9pbnRlclR5cGU7XG5cbiAgICAgICAgdmFyIGlzVG91Y2ggPSAocG9pbnRlclR5cGUgPT0gSU5QVVRfVFlQRV9UT1VDSCk7XG5cbiAgICAgICAgLy8gZ2V0IGluZGV4IG9mIHRoZSBldmVudCBpbiB0aGUgc3RvcmVcbiAgICAgICAgdmFyIHN0b3JlSW5kZXggPSBpbkFycmF5KHN0b3JlLCBldi5wb2ludGVySWQsICdwb2ludGVySWQnKTtcblxuICAgICAgICAvLyBzdGFydCBhbmQgbW91c2UgbXVzdCBiZSBkb3duXG4gICAgICAgIGlmIChldmVudFR5cGUgJiBJTlBVVF9TVEFSVCAmJiAoZXYuYnV0dG9uID09PSAwIHx8IGlzVG91Y2gpKSB7XG4gICAgICAgICAgICBpZiAoc3RvcmVJbmRleCA8IDApIHtcbiAgICAgICAgICAgICAgICBzdG9yZS5wdXNoKGV2KTtcbiAgICAgICAgICAgICAgICBzdG9yZUluZGV4ID0gc3RvcmUubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChldmVudFR5cGUgJiAoSU5QVVRfRU5EIHwgSU5QVVRfQ0FOQ0VMKSkge1xuICAgICAgICAgICAgcmVtb3ZlUG9pbnRlciA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpdCBub3QgZm91bmQsIHNvIHRoZSBwb2ludGVyIGhhc24ndCBiZWVuIGRvd24gKHNvIGl0J3MgcHJvYmFibHkgYSBob3ZlcilcbiAgICAgICAgaWYgKHN0b3JlSW5kZXggPCAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyB1cGRhdGUgdGhlIGV2ZW50IGluIHRoZSBzdG9yZVxuICAgICAgICBzdG9yZVtzdG9yZUluZGV4XSA9IGV2O1xuXG4gICAgICAgIHRoaXMuY2FsbGJhY2sodGhpcy5tYW5hZ2VyLCBldmVudFR5cGUsIHtcbiAgICAgICAgICAgIHBvaW50ZXJzOiBzdG9yZSxcbiAgICAgICAgICAgIGNoYW5nZWRQb2ludGVyczogW2V2XSxcbiAgICAgICAgICAgIHBvaW50ZXJUeXBlOiBwb2ludGVyVHlwZSxcbiAgICAgICAgICAgIHNyY0V2ZW50OiBldlxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAocmVtb3ZlUG9pbnRlcikge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGZyb20gdGhlIHN0b3JlXG4gICAgICAgICAgICBzdG9yZS5zcGxpY2Uoc3RvcmVJbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICB9XG59KTtcblxudmFyIFNJTkdMRV9UT1VDSF9JTlBVVF9NQVAgPSB7XG4gICAgdG91Y2hzdGFydDogSU5QVVRfU1RBUlQsXG4gICAgdG91Y2htb3ZlOiBJTlBVVF9NT1ZFLFxuICAgIHRvdWNoZW5kOiBJTlBVVF9FTkQsXG4gICAgdG91Y2hjYW5jZWw6IElOUFVUX0NBTkNFTFxufTtcblxudmFyIFNJTkdMRV9UT1VDSF9UQVJHRVRfRVZFTlRTID0gJ3RvdWNoc3RhcnQnO1xudmFyIFNJTkdMRV9UT1VDSF9XSU5ET1dfRVZFTlRTID0gJ3RvdWNoc3RhcnQgdG91Y2htb3ZlIHRvdWNoZW5kIHRvdWNoY2FuY2VsJztcblxuLyoqXG4gKiBUb3VjaCBldmVudHMgaW5wdXRcbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgSW5wdXRcbiAqL1xuZnVuY3Rpb24gU2luZ2xlVG91Y2hJbnB1dCgpIHtcbiAgICB0aGlzLmV2VGFyZ2V0ID0gU0lOR0xFX1RPVUNIX1RBUkdFVF9FVkVOVFM7XG4gICAgdGhpcy5ldldpbiA9IFNJTkdMRV9UT1VDSF9XSU5ET1dfRVZFTlRTO1xuICAgIHRoaXMuc3RhcnRlZCA9IGZhbHNlO1xuXG4gICAgSW5wdXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuaW5oZXJpdChTaW5nbGVUb3VjaElucHV0LCBJbnB1dCwge1xuICAgIGhhbmRsZXI6IGZ1bmN0aW9uIFRFaGFuZGxlcihldikge1xuICAgICAgICB2YXIgdHlwZSA9IFNJTkdMRV9UT1VDSF9JTlBVVF9NQVBbZXYudHlwZV07XG5cbiAgICAgICAgLy8gc2hvdWxkIHdlIGhhbmRsZSB0aGUgdG91Y2ggZXZlbnRzP1xuICAgICAgICBpZiAodHlwZSA9PT0gSU5QVVRfU1RBUlQpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuc3RhcnRlZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRvdWNoZXMgPSBub3JtYWxpemVTaW5nbGVUb3VjaGVzLmNhbGwodGhpcywgZXYsIHR5cGUpO1xuXG4gICAgICAgIC8vIHdoZW4gZG9uZSwgcmVzZXQgdGhlIHN0YXJ0ZWQgc3RhdGVcbiAgICAgICAgaWYgKHR5cGUgJiAoSU5QVVRfRU5EIHwgSU5QVVRfQ0FOQ0VMKSAmJiB0b3VjaGVzWzBdLmxlbmd0aCAtIHRvdWNoZXNbMV0ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FsbGJhY2sodGhpcy5tYW5hZ2VyLCB0eXBlLCB7XG4gICAgICAgICAgICBwb2ludGVyczogdG91Y2hlc1swXSxcbiAgICAgICAgICAgIGNoYW5nZWRQb2ludGVyczogdG91Y2hlc1sxXSxcbiAgICAgICAgICAgIHBvaW50ZXJUeXBlOiBJTlBVVF9UWVBFX1RPVUNILFxuICAgICAgICAgICAgc3JjRXZlbnQ6IGV2XG4gICAgICAgIH0pO1xuICAgIH1cbn0pO1xuXG4vKipcbiAqIEB0aGlzIHtUb3VjaElucHV0fVxuICogQHBhcmFtIHtPYmplY3R9IGV2XG4gKiBAcGFyYW0ge051bWJlcn0gdHlwZSBmbGFnXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfEFycmF5fSBbYWxsLCBjaGFuZ2VkXVxuICovXG5mdW5jdGlvbiBub3JtYWxpemVTaW5nbGVUb3VjaGVzKGV2LCB0eXBlKSB7XG4gICAgdmFyIGFsbCA9IHRvQXJyYXkoZXYudG91Y2hlcyk7XG4gICAgdmFyIGNoYW5nZWQgPSB0b0FycmF5KGV2LmNoYW5nZWRUb3VjaGVzKTtcblxuICAgIGlmICh0eXBlICYgKElOUFVUX0VORCB8IElOUFVUX0NBTkNFTCkpIHtcbiAgICAgICAgYWxsID0gdW5pcXVlQXJyYXkoYWxsLmNvbmNhdChjaGFuZ2VkKSwgJ2lkZW50aWZpZXInLCB0cnVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW2FsbCwgY2hhbmdlZF07XG59XG5cbnZhciBUT1VDSF9JTlBVVF9NQVAgPSB7XG4gICAgdG91Y2hzdGFydDogSU5QVVRfU1RBUlQsXG4gICAgdG91Y2htb3ZlOiBJTlBVVF9NT1ZFLFxuICAgIHRvdWNoZW5kOiBJTlBVVF9FTkQsXG4gICAgdG91Y2hjYW5jZWw6IElOUFVUX0NBTkNFTFxufTtcblxudmFyIFRPVUNIX1RBUkdFVF9FVkVOVFMgPSAndG91Y2hzdGFydCB0b3VjaG1vdmUgdG91Y2hlbmQgdG91Y2hjYW5jZWwnO1xuXG4vKipcbiAqIE11bHRpLXVzZXIgdG91Y2ggZXZlbnRzIGlucHV0XG4gKiBAY29uc3RydWN0b3JcbiAqIEBleHRlbmRzIElucHV0XG4gKi9cbmZ1bmN0aW9uIFRvdWNoSW5wdXQoKSB7XG4gICAgdGhpcy5ldlRhcmdldCA9IFRPVUNIX1RBUkdFVF9FVkVOVFM7XG4gICAgdGhpcy50YXJnZXRJZHMgPSB7fTtcblxuICAgIElucHV0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbmluaGVyaXQoVG91Y2hJbnB1dCwgSW5wdXQsIHtcbiAgICBoYW5kbGVyOiBmdW5jdGlvbiBNVEVoYW5kbGVyKGV2KSB7XG4gICAgICAgIHZhciB0eXBlID0gVE9VQ0hfSU5QVVRfTUFQW2V2LnR5cGVdO1xuICAgICAgICB2YXIgdG91Y2hlcyA9IGdldFRvdWNoZXMuY2FsbCh0aGlzLCBldiwgdHlwZSk7XG4gICAgICAgIGlmICghdG91Y2hlcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jYWxsYmFjayh0aGlzLm1hbmFnZXIsIHR5cGUsIHtcbiAgICAgICAgICAgIHBvaW50ZXJzOiB0b3VjaGVzWzBdLFxuICAgICAgICAgICAgY2hhbmdlZFBvaW50ZXJzOiB0b3VjaGVzWzFdLFxuICAgICAgICAgICAgcG9pbnRlclR5cGU6IElOUFVUX1RZUEVfVE9VQ0gsXG4gICAgICAgICAgICBzcmNFdmVudDogZXZcbiAgICAgICAgfSk7XG4gICAgfVxufSk7XG5cbi8qKlxuICogQHRoaXMge1RvdWNoSW5wdXR9XG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqIEBwYXJhbSB7TnVtYmVyfSB0eXBlIGZsYWdcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR8QXJyYXl9IFthbGwsIGNoYW5nZWRdXG4gKi9cbmZ1bmN0aW9uIGdldFRvdWNoZXMoZXYsIHR5cGUpIHtcbiAgICB2YXIgYWxsVG91Y2hlcyA9IHRvQXJyYXkoZXYudG91Y2hlcyk7XG4gICAgdmFyIHRhcmdldElkcyA9IHRoaXMudGFyZ2V0SWRzO1xuXG4gICAgLy8gd2hlbiB0aGVyZSBpcyBvbmx5IG9uZSB0b3VjaCwgdGhlIHByb2Nlc3MgY2FuIGJlIHNpbXBsaWZpZWRcbiAgICBpZiAodHlwZSAmIChJTlBVVF9TVEFSVCB8IElOUFVUX01PVkUpICYmIGFsbFRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHRhcmdldElkc1thbGxUb3VjaGVzWzBdLmlkZW50aWZpZXJdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIFthbGxUb3VjaGVzLCBhbGxUb3VjaGVzXTtcbiAgICB9XG5cbiAgICB2YXIgaSxcbiAgICAgICAgdGFyZ2V0VG91Y2hlcyxcbiAgICAgICAgY2hhbmdlZFRvdWNoZXMgPSB0b0FycmF5KGV2LmNoYW5nZWRUb3VjaGVzKSxcbiAgICAgICAgY2hhbmdlZFRhcmdldFRvdWNoZXMgPSBbXSxcbiAgICAgICAgdGFyZ2V0ID0gdGhpcy50YXJnZXQ7XG5cbiAgICAvLyBnZXQgdGFyZ2V0IHRvdWNoZXMgZnJvbSB0b3VjaGVzXG4gICAgdGFyZ2V0VG91Y2hlcyA9IGFsbFRvdWNoZXMuZmlsdGVyKGZ1bmN0aW9uKHRvdWNoKSB7XG4gICAgICAgIHJldHVybiBoYXNQYXJlbnQodG91Y2gudGFyZ2V0LCB0YXJnZXQpO1xuICAgIH0pO1xuXG4gICAgLy8gY29sbGVjdCB0b3VjaGVzXG4gICAgaWYgKHR5cGUgPT09IElOUFVUX1NUQVJUKSB7XG4gICAgICAgIGkgPSAwO1xuICAgICAgICB3aGlsZSAoaSA8IHRhcmdldFRvdWNoZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXJnZXRJZHNbdGFyZ2V0VG91Y2hlc1tpXS5pZGVudGlmaWVyXSA9IHRydWU7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBmaWx0ZXIgY2hhbmdlZCB0b3VjaGVzIHRvIG9ubHkgY29udGFpbiB0b3VjaGVzIHRoYXQgZXhpc3QgaW4gdGhlIGNvbGxlY3RlZCB0YXJnZXQgaWRzXG4gICAgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBjaGFuZ2VkVG91Y2hlcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHRhcmdldElkc1tjaGFuZ2VkVG91Y2hlc1tpXS5pZGVudGlmaWVyXSkge1xuICAgICAgICAgICAgY2hhbmdlZFRhcmdldFRvdWNoZXMucHVzaChjaGFuZ2VkVG91Y2hlc1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjbGVhbnVwIHJlbW92ZWQgdG91Y2hlc1xuICAgICAgICBpZiAodHlwZSAmIChJTlBVVF9FTkQgfCBJTlBVVF9DQU5DRUwpKSB7XG4gICAgICAgICAgICBkZWxldGUgdGFyZ2V0SWRzW2NoYW5nZWRUb3VjaGVzW2ldLmlkZW50aWZpZXJdO1xuICAgICAgICB9XG4gICAgICAgIGkrKztcbiAgICB9XG5cbiAgICBpZiAoIWNoYW5nZWRUYXJnZXRUb3VjaGVzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIFtcbiAgICAgICAgLy8gbWVyZ2UgdGFyZ2V0VG91Y2hlcyB3aXRoIGNoYW5nZWRUYXJnZXRUb3VjaGVzIHNvIGl0IGNvbnRhaW5zIEFMTCB0b3VjaGVzLCBpbmNsdWRpbmcgJ2VuZCcgYW5kICdjYW5jZWwnXG4gICAgICAgIHVuaXF1ZUFycmF5KHRhcmdldFRvdWNoZXMuY29uY2F0KGNoYW5nZWRUYXJnZXRUb3VjaGVzKSwgJ2lkZW50aWZpZXInLCB0cnVlKSxcbiAgICAgICAgY2hhbmdlZFRhcmdldFRvdWNoZXNcbiAgICBdO1xufVxuXG4vKipcbiAqIENvbWJpbmVkIHRvdWNoIGFuZCBtb3VzZSBpbnB1dFxuICpcbiAqIFRvdWNoIGhhcyBhIGhpZ2hlciBwcmlvcml0eSB0aGVuIG1vdXNlLCBhbmQgd2hpbGUgdG91Y2hpbmcgbm8gbW91c2UgZXZlbnRzIGFyZSBhbGxvd2VkLlxuICogVGhpcyBiZWNhdXNlIHRvdWNoIGRldmljZXMgYWxzbyBlbWl0IG1vdXNlIGV2ZW50cyB3aGlsZSBkb2luZyBhIHRvdWNoLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgSW5wdXRcbiAqL1xuXG52YXIgREVEVVBfVElNRU9VVCA9IDI1MDA7XG52YXIgREVEVVBfRElTVEFOQ0UgPSAyNTtcblxuZnVuY3Rpb24gVG91Y2hNb3VzZUlucHV0KCkge1xuICAgIElucHV0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICB2YXIgaGFuZGxlciA9IGJpbmRGbih0aGlzLmhhbmRsZXIsIHRoaXMpO1xuICAgIHRoaXMudG91Y2ggPSBuZXcgVG91Y2hJbnB1dCh0aGlzLm1hbmFnZXIsIGhhbmRsZXIpO1xuICAgIHRoaXMubW91c2UgPSBuZXcgTW91c2VJbnB1dCh0aGlzLm1hbmFnZXIsIGhhbmRsZXIpO1xuXG4gICAgdGhpcy5wcmltYXJ5VG91Y2ggPSBudWxsO1xuICAgIHRoaXMubGFzdFRvdWNoZXMgPSBbXTtcbn1cblxuaW5oZXJpdChUb3VjaE1vdXNlSW5wdXQsIElucHV0LCB7XG4gICAgLyoqXG4gICAgICogaGFuZGxlIG1vdXNlIGFuZCB0b3VjaCBldmVudHNcbiAgICAgKiBAcGFyYW0ge0hhbW1lcn0gbWFuYWdlclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dEV2ZW50XG4gICAgICogQHBhcmFtIHtPYmplY3R9IGlucHV0RGF0YVxuICAgICAqL1xuICAgIGhhbmRsZXI6IGZ1bmN0aW9uIFRNRWhhbmRsZXIobWFuYWdlciwgaW5wdXRFdmVudCwgaW5wdXREYXRhKSB7XG4gICAgICAgIHZhciBpc1RvdWNoID0gKGlucHV0RGF0YS5wb2ludGVyVHlwZSA9PSBJTlBVVF9UWVBFX1RPVUNIKSxcbiAgICAgICAgICAgIGlzTW91c2UgPSAoaW5wdXREYXRhLnBvaW50ZXJUeXBlID09IElOUFVUX1RZUEVfTU9VU0UpO1xuXG4gICAgICAgIGlmIChpc01vdXNlICYmIGlucHV0RGF0YS5zb3VyY2VDYXBhYmlsaXRpZXMgJiYgaW5wdXREYXRhLnNvdXJjZUNhcGFiaWxpdGllcy5maXJlc1RvdWNoRXZlbnRzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyB3aGVuIHdlJ3JlIGluIGEgdG91Y2ggZXZlbnQsIHJlY29yZCB0b3VjaGVzIHRvICBkZS1kdXBlIHN5bnRoZXRpYyBtb3VzZSBldmVudFxuICAgICAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgICAgICAgcmVjb3JkVG91Y2hlcy5jYWxsKHRoaXMsIGlucHV0RXZlbnQsIGlucHV0RGF0YSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNNb3VzZSAmJiBpc1N5bnRoZXRpY0V2ZW50LmNhbGwodGhpcywgaW5wdXREYXRhKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jYWxsYmFjayhtYW5hZ2VyLCBpbnB1dEV2ZW50LCBpbnB1dERhdGEpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiByZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVyc1xuICAgICAqL1xuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMudG91Y2guZGVzdHJveSgpO1xuICAgICAgICB0aGlzLm1vdXNlLmRlc3Ryb3koKTtcbiAgICB9XG59KTtcblxuZnVuY3Rpb24gcmVjb3JkVG91Y2hlcyhldmVudFR5cGUsIGV2ZW50RGF0YSkge1xuICAgIGlmIChldmVudFR5cGUgJiBJTlBVVF9TVEFSVCkge1xuICAgICAgICB0aGlzLnByaW1hcnlUb3VjaCA9IGV2ZW50RGF0YS5jaGFuZ2VkUG9pbnRlcnNbMF0uaWRlbnRpZmllcjtcbiAgICAgICAgc2V0TGFzdFRvdWNoLmNhbGwodGhpcywgZXZlbnREYXRhKTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50VHlwZSAmIChJTlBVVF9FTkQgfCBJTlBVVF9DQU5DRUwpKSB7XG4gICAgICAgIHNldExhc3RUb3VjaC5jYWxsKHRoaXMsIGV2ZW50RGF0YSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBzZXRMYXN0VG91Y2goZXZlbnREYXRhKSB7XG4gICAgdmFyIHRvdWNoID0gZXZlbnREYXRhLmNoYW5nZWRQb2ludGVyc1swXTtcblxuICAgIGlmICh0b3VjaC5pZGVudGlmaWVyID09PSB0aGlzLnByaW1hcnlUb3VjaCkge1xuICAgICAgICB2YXIgbGFzdFRvdWNoID0ge3g6IHRvdWNoLmNsaWVudFgsIHk6IHRvdWNoLmNsaWVudFl9O1xuICAgICAgICB0aGlzLmxhc3RUb3VjaGVzLnB1c2gobGFzdFRvdWNoKTtcbiAgICAgICAgdmFyIGx0cyA9IHRoaXMubGFzdFRvdWNoZXM7XG4gICAgICAgIHZhciByZW1vdmVMYXN0VG91Y2ggPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBpID0gbHRzLmluZGV4T2YobGFzdFRvdWNoKTtcbiAgICAgICAgICAgIGlmIChpID4gLTEpIHtcbiAgICAgICAgICAgICAgICBsdHMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBzZXRUaW1lb3V0KHJlbW92ZUxhc3RUb3VjaCwgREVEVVBfVElNRU9VVCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc1N5bnRoZXRpY0V2ZW50KGV2ZW50RGF0YSkge1xuICAgIHZhciB4ID0gZXZlbnREYXRhLnNyY0V2ZW50LmNsaWVudFgsIHkgPSBldmVudERhdGEuc3JjRXZlbnQuY2xpZW50WTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGFzdFRvdWNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHQgPSB0aGlzLmxhc3RUb3VjaGVzW2ldO1xuICAgICAgICB2YXIgZHggPSBNYXRoLmFicyh4IC0gdC54KSwgZHkgPSBNYXRoLmFicyh5IC0gdC55KTtcbiAgICAgICAgaWYgKGR4IDw9IERFRFVQX0RJU1RBTkNFICYmIGR5IDw9IERFRFVQX0RJU1RBTkNFKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBQUkVGSVhFRF9UT1VDSF9BQ1RJT04gPSBwcmVmaXhlZChURVNUX0VMRU1FTlQuc3R5bGUsICd0b3VjaEFjdGlvbicpO1xudmFyIE5BVElWRV9UT1VDSF9BQ1RJT04gPSBQUkVGSVhFRF9UT1VDSF9BQ1RJT04gIT09IHVuZGVmaW5lZDtcblxuLy8gbWFnaWNhbCB0b3VjaEFjdGlvbiB2YWx1ZVxudmFyIFRPVUNIX0FDVElPTl9DT01QVVRFID0gJ2NvbXB1dGUnO1xudmFyIFRPVUNIX0FDVElPTl9BVVRPID0gJ2F1dG8nO1xudmFyIFRPVUNIX0FDVElPTl9NQU5JUFVMQVRJT04gPSAnbWFuaXB1bGF0aW9uJzsgLy8gbm90IGltcGxlbWVudGVkXG52YXIgVE9VQ0hfQUNUSU9OX05PTkUgPSAnbm9uZSc7XG52YXIgVE9VQ0hfQUNUSU9OX1BBTl9YID0gJ3Bhbi14JztcbnZhciBUT1VDSF9BQ1RJT05fUEFOX1kgPSAncGFuLXknO1xudmFyIFRPVUNIX0FDVElPTl9NQVAgPSBnZXRUb3VjaEFjdGlvblByb3BzKCk7XG5cbi8qKlxuICogVG91Y2ggQWN0aW9uXG4gKiBzZXRzIHRoZSB0b3VjaEFjdGlvbiBwcm9wZXJ0eSBvciB1c2VzIHRoZSBqcyBhbHRlcm5hdGl2ZVxuICogQHBhcmFtIHtNYW5hZ2VyfSBtYW5hZ2VyXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsdWVcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBUb3VjaEFjdGlvbihtYW5hZ2VyLCB2YWx1ZSkge1xuICAgIHRoaXMubWFuYWdlciA9IG1hbmFnZXI7XG4gICAgdGhpcy5zZXQodmFsdWUpO1xufVxuXG5Ub3VjaEFjdGlvbi5wcm90b3R5cGUgPSB7XG4gICAgLyoqXG4gICAgICogc2V0IHRoZSB0b3VjaEFjdGlvbiB2YWx1ZSBvbiB0aGUgZWxlbWVudCBvciBlbmFibGUgdGhlIHBvbHlmaWxsXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXG4gICAgICovXG4gICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAvLyBmaW5kIG91dCB0aGUgdG91Y2gtYWN0aW9uIGJ5IHRoZSBldmVudCBoYW5kbGVyc1xuICAgICAgICBpZiAodmFsdWUgPT0gVE9VQ0hfQUNUSU9OX0NPTVBVVEUpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGhpcy5jb21wdXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoTkFUSVZFX1RPVUNIX0FDVElPTiAmJiB0aGlzLm1hbmFnZXIuZWxlbWVudC5zdHlsZSAmJiBUT1VDSF9BQ1RJT05fTUFQW3ZhbHVlXSkge1xuICAgICAgICAgICAgdGhpcy5tYW5hZ2VyLmVsZW1lbnQuc3R5bGVbUFJFRklYRURfVE9VQ0hfQUNUSU9OXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWN0aW9ucyA9IHZhbHVlLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBqdXN0IHJlLXNldCB0aGUgdG91Y2hBY3Rpb24gdmFsdWVcbiAgICAgKi9cbiAgICB1cGRhdGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnNldCh0aGlzLm1hbmFnZXIub3B0aW9ucy50b3VjaEFjdGlvbik7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGNvbXB1dGUgdGhlIHZhbHVlIGZvciB0aGUgdG91Y2hBY3Rpb24gcHJvcGVydHkgYmFzZWQgb24gdGhlIHJlY29nbml6ZXIncyBzZXR0aW5nc1xuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9IHZhbHVlXG4gICAgICovXG4gICAgY29tcHV0ZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhY3Rpb25zID0gW107XG4gICAgICAgIGVhY2godGhpcy5tYW5hZ2VyLnJlY29nbml6ZXJzLCBmdW5jdGlvbihyZWNvZ25pemVyKSB7XG4gICAgICAgICAgICBpZiAoYm9vbE9yRm4ocmVjb2duaXplci5vcHRpb25zLmVuYWJsZSwgW3JlY29nbml6ZXJdKSkge1xuICAgICAgICAgICAgICAgIGFjdGlvbnMgPSBhY3Rpb25zLmNvbmNhdChyZWNvZ25pemVyLmdldFRvdWNoQWN0aW9uKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNsZWFuVG91Y2hBY3Rpb25zKGFjdGlvbnMuam9pbignICcpKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogdGhpcyBtZXRob2QgaXMgY2FsbGVkIG9uIGVhY2ggaW5wdXQgY3ljbGUgYW5kIHByb3ZpZGVzIHRoZSBwcmV2ZW50aW5nIG9mIHRoZSBicm93c2VyIGJlaGF2aW9yXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGlucHV0XG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHRzOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgc3JjRXZlbnQgPSBpbnB1dC5zcmNFdmVudDtcbiAgICAgICAgdmFyIGRpcmVjdGlvbiA9IGlucHV0Lm9mZnNldERpcmVjdGlvbjtcblxuICAgICAgICAvLyBpZiB0aGUgdG91Y2ggYWN0aW9uIGRpZCBwcmV2ZW50ZWQgb25jZSB0aGlzIHNlc3Npb25cbiAgICAgICAgaWYgKHRoaXMubWFuYWdlci5zZXNzaW9uLnByZXZlbnRlZCkge1xuICAgICAgICAgICAgc3JjRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBhY3Rpb25zID0gdGhpcy5hY3Rpb25zO1xuICAgICAgICB2YXIgaGFzTm9uZSA9IGluU3RyKGFjdGlvbnMsIFRPVUNIX0FDVElPTl9OT05FKSAmJiAhVE9VQ0hfQUNUSU9OX01BUFtUT1VDSF9BQ1RJT05fTk9ORV07XG4gICAgICAgIHZhciBoYXNQYW5ZID0gaW5TdHIoYWN0aW9ucywgVE9VQ0hfQUNUSU9OX1BBTl9ZKSAmJiAhVE9VQ0hfQUNUSU9OX01BUFtUT1VDSF9BQ1RJT05fUEFOX1ldO1xuICAgICAgICB2YXIgaGFzUGFuWCA9IGluU3RyKGFjdGlvbnMsIFRPVUNIX0FDVElPTl9QQU5fWCkgJiYgIVRPVUNIX0FDVElPTl9NQVBbVE9VQ0hfQUNUSU9OX1BBTl9YXTtcblxuICAgICAgICBpZiAoaGFzTm9uZSkge1xuICAgICAgICAgICAgLy9kbyBub3QgcHJldmVudCBkZWZhdWx0cyBpZiB0aGlzIGlzIGEgdGFwIGdlc3R1cmVcblxuICAgICAgICAgICAgdmFyIGlzVGFwUG9pbnRlciA9IGlucHV0LnBvaW50ZXJzLmxlbmd0aCA9PT0gMTtcbiAgICAgICAgICAgIHZhciBpc1RhcE1vdmVtZW50ID0gaW5wdXQuZGlzdGFuY2UgPCAyO1xuICAgICAgICAgICAgdmFyIGlzVGFwVG91Y2hUaW1lID0gaW5wdXQuZGVsdGFUaW1lIDwgMjUwO1xuXG4gICAgICAgICAgICBpZiAoaXNUYXBQb2ludGVyICYmIGlzVGFwTW92ZW1lbnQgJiYgaXNUYXBUb3VjaFRpbWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzUGFuWCAmJiBoYXNQYW5ZKSB7XG4gICAgICAgICAgICAvLyBgcGFuLXggcGFuLXlgIG1lYW5zIGJyb3dzZXIgaGFuZGxlcyBhbGwgc2Nyb2xsaW5nL3Bhbm5pbmcsIGRvIG5vdCBwcmV2ZW50XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzTm9uZSB8fFxuICAgICAgICAgICAgKGhhc1BhblkgJiYgZGlyZWN0aW9uICYgRElSRUNUSU9OX0hPUklaT05UQUwpIHx8XG4gICAgICAgICAgICAoaGFzUGFuWCAmJiBkaXJlY3Rpb24gJiBESVJFQ1RJT05fVkVSVElDQUwpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcmV2ZW50U3JjKHNyY0V2ZW50KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBjYWxsIHByZXZlbnREZWZhdWx0IHRvIHByZXZlbnQgdGhlIGJyb3dzZXIncyBkZWZhdWx0IGJlaGF2aW9yIChzY3JvbGxpbmcgaW4gbW9zdCBjYXNlcylcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc3JjRXZlbnRcbiAgICAgKi9cbiAgICBwcmV2ZW50U3JjOiBmdW5jdGlvbihzcmNFdmVudCkge1xuICAgICAgICB0aGlzLm1hbmFnZXIuc2Vzc2lvbi5wcmV2ZW50ZWQgPSB0cnVlO1xuICAgICAgICBzcmNFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn07XG5cbi8qKlxuICogd2hlbiB0aGUgdG91Y2hBY3Rpb25zIGFyZSBjb2xsZWN0ZWQgdGhleSBhcmUgbm90IGEgdmFsaWQgdmFsdWUsIHNvIHdlIG5lZWQgdG8gY2xlYW4gdGhpbmdzIHVwLiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYWN0aW9uc1xuICogQHJldHVybnMgeyp9XG4gKi9cbmZ1bmN0aW9uIGNsZWFuVG91Y2hBY3Rpb25zKGFjdGlvbnMpIHtcbiAgICAvLyBub25lXG4gICAgaWYgKGluU3RyKGFjdGlvbnMsIFRPVUNIX0FDVElPTl9OT05FKSkge1xuICAgICAgICByZXR1cm4gVE9VQ0hfQUNUSU9OX05PTkU7XG4gICAgfVxuXG4gICAgdmFyIGhhc1BhblggPSBpblN0cihhY3Rpb25zLCBUT1VDSF9BQ1RJT05fUEFOX1gpO1xuICAgIHZhciBoYXNQYW5ZID0gaW5TdHIoYWN0aW9ucywgVE9VQ0hfQUNUSU9OX1BBTl9ZKTtcblxuICAgIC8vIGlmIGJvdGggcGFuLXggYW5kIHBhbi15IGFyZSBzZXQgKGRpZmZlcmVudCByZWNvZ25pemVyc1xuICAgIC8vIGZvciBkaWZmZXJlbnQgZGlyZWN0aW9ucywgZS5nLiBob3Jpem9udGFsIHBhbiBidXQgdmVydGljYWwgc3dpcGU/KVxuICAgIC8vIHdlIG5lZWQgbm9uZSAoYXMgb3RoZXJ3aXNlIHdpdGggcGFuLXggcGFuLXkgY29tYmluZWQgbm9uZSBvZiB0aGVzZVxuICAgIC8vIHJlY29nbml6ZXJzIHdpbGwgd29yaywgc2luY2UgdGhlIGJyb3dzZXIgd291bGQgaGFuZGxlIGFsbCBwYW5uaW5nXG4gICAgaWYgKGhhc1BhblggJiYgaGFzUGFuWSkge1xuICAgICAgICByZXR1cm4gVE9VQ0hfQUNUSU9OX05PTkU7XG4gICAgfVxuXG4gICAgLy8gcGFuLXggT1IgcGFuLXlcbiAgICBpZiAoaGFzUGFuWCB8fCBoYXNQYW5ZKSB7XG4gICAgICAgIHJldHVybiBoYXNQYW5YID8gVE9VQ0hfQUNUSU9OX1BBTl9YIDogVE9VQ0hfQUNUSU9OX1BBTl9ZO1xuICAgIH1cblxuICAgIC8vIG1hbmlwdWxhdGlvblxuICAgIGlmIChpblN0cihhY3Rpb25zLCBUT1VDSF9BQ1RJT05fTUFOSVBVTEFUSU9OKSkge1xuICAgICAgICByZXR1cm4gVE9VQ0hfQUNUSU9OX01BTklQVUxBVElPTjtcbiAgICB9XG5cbiAgICByZXR1cm4gVE9VQ0hfQUNUSU9OX0FVVE87XG59XG5cbmZ1bmN0aW9uIGdldFRvdWNoQWN0aW9uUHJvcHMoKSB7XG4gICAgaWYgKCFOQVRJVkVfVE9VQ0hfQUNUSU9OKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIHRvdWNoTWFwID0ge307XG4gICAgdmFyIGNzc1N1cHBvcnRzID0gd2luZG93LkNTUyAmJiB3aW5kb3cuQ1NTLnN1cHBvcnRzO1xuICAgIFsnYXV0bycsICdtYW5pcHVsYXRpb24nLCAncGFuLXknLCAncGFuLXgnLCAncGFuLXggcGFuLXknLCAnbm9uZSddLmZvckVhY2goZnVuY3Rpb24odmFsKSB7XG5cbiAgICAgICAgLy8gSWYgY3NzLnN1cHBvcnRzIGlzIG5vdCBzdXBwb3J0ZWQgYnV0IHRoZXJlIGlzIG5hdGl2ZSB0b3VjaC1hY3Rpb24gYXNzdW1lIGl0IHN1cHBvcnRzXG4gICAgICAgIC8vIGFsbCB2YWx1ZXMuIFRoaXMgaXMgdGhlIGNhc2UgZm9yIElFIDEwIGFuZCAxMS5cbiAgICAgICAgdG91Y2hNYXBbdmFsXSA9IGNzc1N1cHBvcnRzID8gd2luZG93LkNTUy5zdXBwb3J0cygndG91Y2gtYWN0aW9uJywgdmFsKSA6IHRydWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRvdWNoTWFwO1xufVxuXG4vKipcbiAqIFJlY29nbml6ZXIgZmxvdyBleHBsYWluZWQ7ICpcbiAqIEFsbCByZWNvZ25pemVycyBoYXZlIHRoZSBpbml0aWFsIHN0YXRlIG9mIFBPU1NJQkxFIHdoZW4gYSBpbnB1dCBzZXNzaW9uIHN0YXJ0cy5cbiAqIFRoZSBkZWZpbml0aW9uIG9mIGEgaW5wdXQgc2Vzc2lvbiBpcyBmcm9tIHRoZSBmaXJzdCBpbnB1dCB1bnRpbCB0aGUgbGFzdCBpbnB1dCwgd2l0aCBhbGwgaXQncyBtb3ZlbWVudCBpbiBpdC4gKlxuICogRXhhbXBsZSBzZXNzaW9uIGZvciBtb3VzZS1pbnB1dDogbW91c2Vkb3duIC0+IG1vdXNlbW92ZSAtPiBtb3VzZXVwXG4gKlxuICogT24gZWFjaCByZWNvZ25pemluZyBjeWNsZSAoc2VlIE1hbmFnZXIucmVjb2duaXplKSB0aGUgLnJlY29nbml6ZSgpIG1ldGhvZCBpcyBleGVjdXRlZFxuICogd2hpY2ggZGV0ZXJtaW5lcyB3aXRoIHN0YXRlIGl0IHNob3VsZCBiZS5cbiAqXG4gKiBJZiB0aGUgcmVjb2duaXplciBoYXMgdGhlIHN0YXRlIEZBSUxFRCwgQ0FOQ0VMTEVEIG9yIFJFQ09HTklaRUQgKGVxdWFscyBFTkRFRCksIGl0IGlzIHJlc2V0IHRvXG4gKiBQT1NTSUJMRSB0byBnaXZlIGl0IGFub3RoZXIgY2hhbmdlIG9uIHRoZSBuZXh0IGN5Y2xlLlxuICpcbiAqICAgICAgICAgICAgICAgUG9zc2libGVcbiAqICAgICAgICAgICAgICAgICAgfFxuICogICAgICAgICAgICArLS0tLS0rLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfFxuICogICAgICArLS0tLS0rLS0tLS0rICAgICAgICAgICAgICAgfFxuICogICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICAgICAgfFxuICogICBGYWlsZWQgICAgICBDYW5jZWxsZWQgICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tKy0tLS0tLStcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICBSZWNvZ25pemVkICAgICAgIEJlZ2FuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENoYW5nZWRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbmRlZC9SZWNvZ25pemVkXG4gKi9cbnZhciBTVEFURV9QT1NTSUJMRSA9IDE7XG52YXIgU1RBVEVfQkVHQU4gPSAyO1xudmFyIFNUQVRFX0NIQU5HRUQgPSA0O1xudmFyIFNUQVRFX0VOREVEID0gODtcbnZhciBTVEFURV9SRUNPR05JWkVEID0gU1RBVEVfRU5ERUQ7XG52YXIgU1RBVEVfQ0FOQ0VMTEVEID0gMTY7XG52YXIgU1RBVEVfRkFJTEVEID0gMzI7XG5cbi8qKlxuICogUmVjb2duaXplclxuICogRXZlcnkgcmVjb2duaXplciBuZWVkcyB0byBleHRlbmQgZnJvbSB0aGlzIGNsYXNzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICovXG5mdW5jdGlvbiBSZWNvZ25pemVyKG9wdGlvbnMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBhc3NpZ24oe30sIHRoaXMuZGVmYXVsdHMsIG9wdGlvbnMgfHwge30pO1xuXG4gICAgdGhpcy5pZCA9IHVuaXF1ZUlkKCk7XG5cbiAgICB0aGlzLm1hbmFnZXIgPSBudWxsO1xuXG4gICAgLy8gZGVmYXVsdCBpcyBlbmFibGUgdHJ1ZVxuICAgIHRoaXMub3B0aW9ucy5lbmFibGUgPSBpZlVuZGVmaW5lZCh0aGlzLm9wdGlvbnMuZW5hYmxlLCB0cnVlKTtcblxuICAgIHRoaXMuc3RhdGUgPSBTVEFURV9QT1NTSUJMRTtcblxuICAgIHRoaXMuc2ltdWx0YW5lb3VzID0ge307XG4gICAgdGhpcy5yZXF1aXJlRmFpbCA9IFtdO1xufVxuXG5SZWNvZ25pemVyLnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBAdmlydHVhbFxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG4gICAgZGVmYXVsdHM6IHt9LFxuXG4gICAgLyoqXG4gICAgICogc2V0IG9wdGlvbnNcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm4ge1JlY29nbml6ZXJ9XG4gICAgICovXG4gICAgc2V0OiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgIGFzc2lnbih0aGlzLm9wdGlvbnMsIG9wdGlvbnMpO1xuXG4gICAgICAgIC8vIGFsc28gdXBkYXRlIHRoZSB0b3VjaEFjdGlvbiwgaW4gY2FzZSBzb21ldGhpbmcgY2hhbmdlZCBhYm91dCB0aGUgZGlyZWN0aW9ucy9lbmFibGVkIHN0YXRlXG4gICAgICAgIHRoaXMubWFuYWdlciAmJiB0aGlzLm1hbmFnZXIudG91Y2hBY3Rpb24udXBkYXRlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiByZWNvZ25pemUgc2ltdWx0YW5lb3VzIHdpdGggYW4gb3RoZXIgcmVjb2duaXplci5cbiAgICAgKiBAcGFyYW0ge1JlY29nbml6ZXJ9IG90aGVyUmVjb2duaXplclxuICAgICAqIEByZXR1cm5zIHtSZWNvZ25pemVyfSB0aGlzXG4gICAgICovXG4gICAgcmVjb2duaXplV2l0aDogZnVuY3Rpb24ob3RoZXJSZWNvZ25pemVyKSB7XG4gICAgICAgIGlmIChpbnZva2VBcnJheUFyZyhvdGhlclJlY29nbml6ZXIsICdyZWNvZ25pemVXaXRoJywgdGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHNpbXVsdGFuZW91cyA9IHRoaXMuc2ltdWx0YW5lb3VzO1xuICAgICAgICBvdGhlclJlY29nbml6ZXIgPSBnZXRSZWNvZ25pemVyQnlOYW1lSWZNYW5hZ2VyKG90aGVyUmVjb2duaXplciwgdGhpcyk7XG4gICAgICAgIGlmICghc2ltdWx0YW5lb3VzW290aGVyUmVjb2duaXplci5pZF0pIHtcbiAgICAgICAgICAgIHNpbXVsdGFuZW91c1tvdGhlclJlY29nbml6ZXIuaWRdID0gb3RoZXJSZWNvZ25pemVyO1xuICAgICAgICAgICAgb3RoZXJSZWNvZ25pemVyLnJlY29nbml6ZVdpdGgodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGRyb3AgdGhlIHNpbXVsdGFuZW91cyBsaW5rLiBpdCBkb2VzbnQgcmVtb3ZlIHRoZSBsaW5rIG9uIHRoZSBvdGhlciByZWNvZ25pemVyLlxuICAgICAqIEBwYXJhbSB7UmVjb2duaXplcn0gb3RoZXJSZWNvZ25pemVyXG4gICAgICogQHJldHVybnMge1JlY29nbml6ZXJ9IHRoaXNcbiAgICAgKi9cbiAgICBkcm9wUmVjb2duaXplV2l0aDogZnVuY3Rpb24ob3RoZXJSZWNvZ25pemVyKSB7XG4gICAgICAgIGlmIChpbnZva2VBcnJheUFyZyhvdGhlclJlY29nbml6ZXIsICdkcm9wUmVjb2duaXplV2l0aCcsIHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIG90aGVyUmVjb2duaXplciA9IGdldFJlY29nbml6ZXJCeU5hbWVJZk1hbmFnZXIob3RoZXJSZWNvZ25pemVyLCB0aGlzKTtcbiAgICAgICAgZGVsZXRlIHRoaXMuc2ltdWx0YW5lb3VzW290aGVyUmVjb2duaXplci5pZF07XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiByZWNvZ25pemVyIGNhbiBvbmx5IHJ1biB3aGVuIGFuIG90aGVyIGlzIGZhaWxpbmdcbiAgICAgKiBAcGFyYW0ge1JlY29nbml6ZXJ9IG90aGVyUmVjb2duaXplclxuICAgICAqIEByZXR1cm5zIHtSZWNvZ25pemVyfSB0aGlzXG4gICAgICovXG4gICAgcmVxdWlyZUZhaWx1cmU6IGZ1bmN0aW9uKG90aGVyUmVjb2duaXplcikge1xuICAgICAgICBpZiAoaW52b2tlQXJyYXlBcmcob3RoZXJSZWNvZ25pemVyLCAncmVxdWlyZUZhaWx1cmUnLCB0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWlyZUZhaWwgPSB0aGlzLnJlcXVpcmVGYWlsO1xuICAgICAgICBvdGhlclJlY29nbml6ZXIgPSBnZXRSZWNvZ25pemVyQnlOYW1lSWZNYW5hZ2VyKG90aGVyUmVjb2duaXplciwgdGhpcyk7XG4gICAgICAgIGlmIChpbkFycmF5KHJlcXVpcmVGYWlsLCBvdGhlclJlY29nbml6ZXIpID09PSAtMSkge1xuICAgICAgICAgICAgcmVxdWlyZUZhaWwucHVzaChvdGhlclJlY29nbml6ZXIpO1xuICAgICAgICAgICAgb3RoZXJSZWNvZ25pemVyLnJlcXVpcmVGYWlsdXJlKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBkcm9wIHRoZSByZXF1aXJlRmFpbHVyZSBsaW5rLiBpdCBkb2VzIG5vdCByZW1vdmUgdGhlIGxpbmsgb24gdGhlIG90aGVyIHJlY29nbml6ZXIuXG4gICAgICogQHBhcmFtIHtSZWNvZ25pemVyfSBvdGhlclJlY29nbml6ZXJcbiAgICAgKiBAcmV0dXJucyB7UmVjb2duaXplcn0gdGhpc1xuICAgICAqL1xuICAgIGRyb3BSZXF1aXJlRmFpbHVyZTogZnVuY3Rpb24ob3RoZXJSZWNvZ25pemVyKSB7XG4gICAgICAgIGlmIChpbnZva2VBcnJheUFyZyhvdGhlclJlY29nbml6ZXIsICdkcm9wUmVxdWlyZUZhaWx1cmUnLCB0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBvdGhlclJlY29nbml6ZXIgPSBnZXRSZWNvZ25pemVyQnlOYW1lSWZNYW5hZ2VyKG90aGVyUmVjb2duaXplciwgdGhpcyk7XG4gICAgICAgIHZhciBpbmRleCA9IGluQXJyYXkodGhpcy5yZXF1aXJlRmFpbCwgb3RoZXJSZWNvZ25pemVyKTtcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucmVxdWlyZUZhaWwuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogaGFzIHJlcXVpcmUgZmFpbHVyZXMgYm9vbGVhblxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGhhc1JlcXVpcmVGYWlsdXJlczogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVpcmVGYWlsLmxlbmd0aCA+IDA7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGlmIHRoZSByZWNvZ25pemVyIGNhbiByZWNvZ25pemUgc2ltdWx0YW5lb3VzIHdpdGggYW4gb3RoZXIgcmVjb2duaXplclxuICAgICAqIEBwYXJhbSB7UmVjb2duaXplcn0gb3RoZXJSZWNvZ25pemVyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XG4gICAgICovXG4gICAgY2FuUmVjb2duaXplV2l0aDogZnVuY3Rpb24ob3RoZXJSZWNvZ25pemVyKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuc2ltdWx0YW5lb3VzW290aGVyUmVjb2duaXplci5pZF07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFlvdSBzaG91bGQgdXNlIGB0cnlFbWl0YCBpbnN0ZWFkIG9mIGBlbWl0YCBkaXJlY3RseSB0byBjaGVja1xuICAgICAqIHRoYXQgYWxsIHRoZSBuZWVkZWQgcmVjb2duaXplcnMgaGFzIGZhaWxlZCBiZWZvcmUgZW1pdHRpbmcuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGlucHV0XG4gICAgICovXG4gICAgZW1pdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuXG4gICAgICAgIGZ1bmN0aW9uIGVtaXQoZXZlbnQpIHtcbiAgICAgICAgICAgIHNlbGYubWFuYWdlci5lbWl0KGV2ZW50LCBpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAncGFuc3RhcnQnIGFuZCAncGFubW92ZSdcbiAgICAgICAgaWYgKHN0YXRlIDwgU1RBVEVfRU5ERUQpIHtcbiAgICAgICAgICAgIGVtaXQoc2VsZi5vcHRpb25zLmV2ZW50ICsgc3RhdGVTdHIoc3RhdGUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVtaXQoc2VsZi5vcHRpb25zLmV2ZW50KTsgLy8gc2ltcGxlICdldmVudE5hbWUnIGV2ZW50c1xuXG4gICAgICAgIGlmIChpbnB1dC5hZGRpdGlvbmFsRXZlbnQpIHsgLy8gYWRkaXRpb25hbCBldmVudChwYW5sZWZ0LCBwYW5yaWdodCwgcGluY2hpbiwgcGluY2hvdXQuLi4pXG4gICAgICAgICAgICBlbWl0KGlucHV0LmFkZGl0aW9uYWxFdmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBwYW5lbmQgYW5kIHBhbmNhbmNlbFxuICAgICAgICBpZiAoc3RhdGUgPj0gU1RBVEVfRU5ERUQpIHtcbiAgICAgICAgICAgIGVtaXQoc2VsZi5vcHRpb25zLmV2ZW50ICsgc3RhdGVTdHIoc3RhdGUpKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDaGVjayB0aGF0IGFsbCB0aGUgcmVxdWlyZSBmYWlsdXJlIHJlY29nbml6ZXJzIGhhcyBmYWlsZWQsXG4gICAgICogaWYgdHJ1ZSwgaXQgZW1pdHMgYSBnZXN0dXJlIGV2ZW50LFxuICAgICAqIG90aGVyd2lzZSwgc2V0dXAgdGhlIHN0YXRlIHRvIEZBSUxFRC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAgICAgKi9cbiAgICB0cnlFbWl0OiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5jYW5FbWl0KCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGl0J3MgZmFpbGluZyBhbnl3YXlcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNUQVRFX0ZBSUxFRDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogY2FuIHdlIGVtaXQ/XG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgY2FuRW1pdDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPCB0aGlzLnJlcXVpcmVGYWlsLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCEodGhpcy5yZXF1aXJlRmFpbFtpXS5zdGF0ZSAmIChTVEFURV9GQUlMRUQgfCBTVEFURV9QT1NTSUJMRSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiB1cGRhdGUgdGhlIHJlY29nbml6ZXJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXREYXRhXG4gICAgICovXG4gICAgcmVjb2duaXplOiBmdW5jdGlvbihpbnB1dERhdGEpIHtcbiAgICAgICAgLy8gbWFrZSBhIG5ldyBjb3B5IG9mIHRoZSBpbnB1dERhdGFcbiAgICAgICAgLy8gc28gd2UgY2FuIGNoYW5nZSB0aGUgaW5wdXREYXRhIHdpdGhvdXQgbWVzc2luZyB1cCB0aGUgb3RoZXIgcmVjb2duaXplcnNcbiAgICAgICAgdmFyIGlucHV0RGF0YUNsb25lID0gYXNzaWduKHt9LCBpbnB1dERhdGEpO1xuXG4gICAgICAgIC8vIGlzIGlzIGVuYWJsZWQgYW5kIGFsbG93IHJlY29nbml6aW5nP1xuICAgICAgICBpZiAoIWJvb2xPckZuKHRoaXMub3B0aW9ucy5lbmFibGUsIFt0aGlzLCBpbnB1dERhdGFDbG9uZV0pKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU1RBVEVfRkFJTEVEO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVzZXQgd2hlbiB3ZSd2ZSByZWFjaGVkIHRoZSBlbmRcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgJiAoU1RBVEVfUkVDT0dOSVpFRCB8IFNUQVRFX0NBTkNFTExFRCB8IFNUQVRFX0ZBSUxFRCkpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTVEFURV9QT1NTSUJMRTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RhdGUgPSB0aGlzLnByb2Nlc3MoaW5wdXREYXRhQ2xvbmUpO1xuXG4gICAgICAgIC8vIHRoZSByZWNvZ25pemVyIGhhcyByZWNvZ25pemVkIGEgZ2VzdHVyZVxuICAgICAgICAvLyBzbyB0cmlnZ2VyIGFuIGV2ZW50XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICYgKFNUQVRFX0JFR0FOIHwgU1RBVEVfQ0hBTkdFRCB8IFNUQVRFX0VOREVEIHwgU1RBVEVfQ0FOQ0VMTEVEKSkge1xuICAgICAgICAgICAgdGhpcy50cnlFbWl0KGlucHV0RGF0YUNsb25lKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiByZXR1cm4gdGhlIHN0YXRlIG9mIHRoZSByZWNvZ25pemVyXG4gICAgICogdGhlIGFjdHVhbCByZWNvZ25pemluZyBoYXBwZW5zIGluIHRoaXMgbWV0aG9kXG4gICAgICogQHZpcnR1YWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXREYXRhXG4gICAgICogQHJldHVybnMge0NvbnN0fSBTVEFURVxuICAgICAqL1xuICAgIHByb2Nlc3M6IGZ1bmN0aW9uKGlucHV0RGF0YSkgeyB9LCAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIC8qKlxuICAgICAqIHJldHVybiB0aGUgcHJlZmVycmVkIHRvdWNoLWFjdGlvblxuICAgICAqIEB2aXJ0dWFsXG4gICAgICogQHJldHVybnMge0FycmF5fVxuICAgICAqL1xuICAgIGdldFRvdWNoQWN0aW9uOiBmdW5jdGlvbigpIHsgfSxcblxuICAgIC8qKlxuICAgICAqIGNhbGxlZCB3aGVuIHRoZSBnZXN0dXJlIGlzbid0IGFsbG93ZWQgdG8gcmVjb2duaXplXG4gICAgICogbGlrZSB3aGVuIGFub3RoZXIgaXMgYmVpbmcgcmVjb2duaXplZCBvciBpdCBpcyBkaXNhYmxlZFxuICAgICAqIEB2aXJ0dWFsXG4gICAgICovXG4gICAgcmVzZXQ6IGZ1bmN0aW9uKCkgeyB9XG59O1xuXG4vKipcbiAqIGdldCBhIHVzYWJsZSBzdHJpbmcsIHVzZWQgYXMgZXZlbnQgcG9zdGZpeFxuICogQHBhcmFtIHtDb25zdH0gc3RhdGVcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0YXRlXG4gKi9cbmZ1bmN0aW9uIHN0YXRlU3RyKHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlICYgU1RBVEVfQ0FOQ0VMTEVEKSB7XG4gICAgICAgIHJldHVybiAnY2FuY2VsJztcbiAgICB9IGVsc2UgaWYgKHN0YXRlICYgU1RBVEVfRU5ERUQpIHtcbiAgICAgICAgcmV0dXJuICdlbmQnO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUgJiBTVEFURV9DSEFOR0VEKSB7XG4gICAgICAgIHJldHVybiAnbW92ZSc7XG4gICAgfSBlbHNlIGlmIChzdGF0ZSAmIFNUQVRFX0JFR0FOKSB7XG4gICAgICAgIHJldHVybiAnc3RhcnQnO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG59XG5cbi8qKlxuICogZGlyZWN0aW9uIGNvbnMgdG8gc3RyaW5nXG4gKiBAcGFyYW0ge0NvbnN0fSBkaXJlY3Rpb25cbiAqIEByZXR1cm5zIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGRpcmVjdGlvblN0cihkaXJlY3Rpb24pIHtcbiAgICBpZiAoZGlyZWN0aW9uID09IERJUkVDVElPTl9ET1dOKSB7XG4gICAgICAgIHJldHVybiAnZG93bic7XG4gICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gRElSRUNUSU9OX1VQKSB7XG4gICAgICAgIHJldHVybiAndXAnO1xuICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09IERJUkVDVElPTl9MRUZUKSB7XG4gICAgICAgIHJldHVybiAnbGVmdCc7XG4gICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gRElSRUNUSU9OX1JJR0hUKSB7XG4gICAgICAgIHJldHVybiAncmlnaHQnO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG59XG5cbi8qKlxuICogZ2V0IGEgcmVjb2duaXplciBieSBuYW1lIGlmIGl0IGlzIGJvdW5kIHRvIGEgbWFuYWdlclxuICogQHBhcmFtIHtSZWNvZ25pemVyfFN0cmluZ30gb3RoZXJSZWNvZ25pemVyXG4gKiBAcGFyYW0ge1JlY29nbml6ZXJ9IHJlY29nbml6ZXJcbiAqIEByZXR1cm5zIHtSZWNvZ25pemVyfVxuICovXG5mdW5jdGlvbiBnZXRSZWNvZ25pemVyQnlOYW1lSWZNYW5hZ2VyKG90aGVyUmVjb2duaXplciwgcmVjb2duaXplcikge1xuICAgIHZhciBtYW5hZ2VyID0gcmVjb2duaXplci5tYW5hZ2VyO1xuICAgIGlmIChtYW5hZ2VyKSB7XG4gICAgICAgIHJldHVybiBtYW5hZ2VyLmdldChvdGhlclJlY29nbml6ZXIpO1xuICAgIH1cbiAgICByZXR1cm4gb3RoZXJSZWNvZ25pemVyO1xufVxuXG4vKipcbiAqIFRoaXMgcmVjb2duaXplciBpcyBqdXN0IHVzZWQgYXMgYSBiYXNlIGZvciB0aGUgc2ltcGxlIGF0dHJpYnV0ZSByZWNvZ25pemVycy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBBdHRyUmVjb2duaXplcigpIHtcbiAgICBSZWNvZ25pemVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbmluaGVyaXQoQXR0clJlY29nbml6ZXIsIFJlY29nbml6ZXIsIHtcbiAgICAvKipcbiAgICAgKiBAbmFtZXNwYWNlXG4gICAgICogQG1lbWJlcm9mIEF0dHJSZWNvZ25pemVyXG4gICAgICovXG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAgICAgICAqIEBkZWZhdWx0IDFcbiAgICAgICAgICovXG4gICAgICAgIHBvaW50ZXJzOiAxXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFVzZWQgdG8gY2hlY2sgaWYgaXQgdGhlIHJlY29nbml6ZXIgcmVjZWl2ZXMgdmFsaWQgaW5wdXQsIGxpa2UgaW5wdXQuZGlzdGFuY2UgPiAxMC5cbiAgICAgKiBAbWVtYmVyb2YgQXR0clJlY29nbml6ZXJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gcmVjb2duaXplZFxuICAgICAqL1xuICAgIGF0dHJUZXN0OiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgb3B0aW9uUG9pbnRlcnMgPSB0aGlzLm9wdGlvbnMucG9pbnRlcnM7XG4gICAgICAgIHJldHVybiBvcHRpb25Qb2ludGVycyA9PT0gMCB8fCBpbnB1dC5wb2ludGVycy5sZW5ndGggPT09IG9wdGlvblBvaW50ZXJzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBQcm9jZXNzIHRoZSBpbnB1dCBhbmQgcmV0dXJuIHRoZSBzdGF0ZSBmb3IgdGhlIHJlY29nbml6ZXJcbiAgICAgKiBAbWVtYmVyb2YgQXR0clJlY29nbml6ZXJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAgICAgKiBAcmV0dXJucyB7Kn0gU3RhdGVcbiAgICAgKi9cbiAgICBwcm9jZXNzOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgICAgICB2YXIgZXZlbnRUeXBlID0gaW5wdXQuZXZlbnRUeXBlO1xuXG4gICAgICAgIHZhciBpc1JlY29nbml6ZWQgPSBzdGF0ZSAmIChTVEFURV9CRUdBTiB8IFNUQVRFX0NIQU5HRUQpO1xuICAgICAgICB2YXIgaXNWYWxpZCA9IHRoaXMuYXR0clRlc3QoaW5wdXQpO1xuXG4gICAgICAgIC8vIG9uIGNhbmNlbCBpbnB1dCBhbmQgd2UndmUgcmVjb2duaXplZCBiZWZvcmUsIHJldHVybiBTVEFURV9DQU5DRUxMRURcbiAgICAgICAgaWYgKGlzUmVjb2duaXplZCAmJiAoZXZlbnRUeXBlICYgSU5QVVRfQ0FOQ0VMIHx8ICFpc1ZhbGlkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHN0YXRlIHwgU1RBVEVfQ0FOQ0VMTEVEO1xuICAgICAgICB9IGVsc2UgaWYgKGlzUmVjb2duaXplZCB8fCBpc1ZhbGlkKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnRUeXBlICYgSU5QVVRfRU5EKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlIHwgU1RBVEVfRU5ERUQ7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCEoc3RhdGUgJiBTVEFURV9CRUdBTikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU1RBVEVfQkVHQU47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3RhdGUgfCBTVEFURV9DSEFOR0VEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBTVEFURV9GQUlMRUQ7XG4gICAgfVxufSk7XG5cbi8qKlxuICogUGFuXG4gKiBSZWNvZ25pemVkIHdoZW4gdGhlIHBvaW50ZXIgaXMgZG93biBhbmQgbW92ZWQgaW4gdGhlIGFsbG93ZWQgZGlyZWN0aW9uLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyBBdHRyUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBQYW5SZWNvZ25pemVyKCkge1xuICAgIEF0dHJSZWNvZ25pemVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICB0aGlzLnBYID0gbnVsbDtcbiAgICB0aGlzLnBZID0gbnVsbDtcbn1cblxuaW5oZXJpdChQYW5SZWNvZ25pemVyLCBBdHRyUmVjb2duaXplciwge1xuICAgIC8qKlxuICAgICAqIEBuYW1lc3BhY2VcbiAgICAgKiBAbWVtYmVyb2YgUGFuUmVjb2duaXplclxuICAgICAqL1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgIGV2ZW50OiAncGFuJyxcbiAgICAgICAgdGhyZXNob2xkOiAxMCxcbiAgICAgICAgcG9pbnRlcnM6IDEsXG4gICAgICAgIGRpcmVjdGlvbjogRElSRUNUSU9OX0FMTFxuICAgIH0sXG5cbiAgICBnZXRUb3VjaEFjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSB0aGlzLm9wdGlvbnMuZGlyZWN0aW9uO1xuICAgICAgICB2YXIgYWN0aW9ucyA9IFtdO1xuICAgICAgICBpZiAoZGlyZWN0aW9uICYgRElSRUNUSU9OX0hPUklaT05UQUwpIHtcbiAgICAgICAgICAgIGFjdGlvbnMucHVzaChUT1VDSF9BQ1RJT05fUEFOX1kpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXJlY3Rpb24gJiBESVJFQ1RJT05fVkVSVElDQUwpIHtcbiAgICAgICAgICAgIGFjdGlvbnMucHVzaChUT1VDSF9BQ1RJT05fUEFOX1gpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY3Rpb25zO1xuICAgIH0sXG5cbiAgICBkaXJlY3Rpb25UZXN0OiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGhhc01vdmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIGRpc3RhbmNlID0gaW5wdXQuZGlzdGFuY2U7XG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSBpbnB1dC5kaXJlY3Rpb247XG4gICAgICAgIHZhciB4ID0gaW5wdXQuZGVsdGFYO1xuICAgICAgICB2YXIgeSA9IGlucHV0LmRlbHRhWTtcblxuICAgICAgICAvLyBsb2NrIHRvIGF4aXM/XG4gICAgICAgIGlmICghKGRpcmVjdGlvbiAmIG9wdGlvbnMuZGlyZWN0aW9uKSkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGlyZWN0aW9uICYgRElSRUNUSU9OX0hPUklaT05UQUwpIHtcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAoeCA9PT0gMCkgPyBESVJFQ1RJT05fTk9ORSA6ICh4IDwgMCkgPyBESVJFQ1RJT05fTEVGVCA6IERJUkVDVElPTl9SSUdIVDtcbiAgICAgICAgICAgICAgICBoYXNNb3ZlZCA9IHggIT0gdGhpcy5wWDtcbiAgICAgICAgICAgICAgICBkaXN0YW5jZSA9IE1hdGguYWJzKGlucHV0LmRlbHRhWCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9ICh5ID09PSAwKSA/IERJUkVDVElPTl9OT05FIDogKHkgPCAwKSA/IERJUkVDVElPTl9VUCA6IERJUkVDVElPTl9ET1dOO1xuICAgICAgICAgICAgICAgIGhhc01vdmVkID0geSAhPSB0aGlzLnBZO1xuICAgICAgICAgICAgICAgIGRpc3RhbmNlID0gTWF0aC5hYnMoaW5wdXQuZGVsdGFZKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpbnB1dC5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4gICAgICAgIHJldHVybiBoYXNNb3ZlZCAmJiBkaXN0YW5jZSA+IG9wdGlvbnMudGhyZXNob2xkICYmIGRpcmVjdGlvbiAmIG9wdGlvbnMuZGlyZWN0aW9uO1xuICAgIH0sXG5cbiAgICBhdHRyVGVzdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIEF0dHJSZWNvZ25pemVyLnByb3RvdHlwZS5hdHRyVGVzdC5jYWxsKHRoaXMsIGlucHV0KSAmJlxuICAgICAgICAgICAgKHRoaXMuc3RhdGUgJiBTVEFURV9CRUdBTiB8fCAoISh0aGlzLnN0YXRlICYgU1RBVEVfQkVHQU4pICYmIHRoaXMuZGlyZWN0aW9uVGVzdChpbnB1dCkpKTtcbiAgICB9LFxuXG4gICAgZW1pdDogZnVuY3Rpb24oaW5wdXQpIHtcblxuICAgICAgICB0aGlzLnBYID0gaW5wdXQuZGVsdGFYO1xuICAgICAgICB0aGlzLnBZID0gaW5wdXQuZGVsdGFZO1xuXG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSBkaXJlY3Rpb25TdHIoaW5wdXQuZGlyZWN0aW9uKTtcblxuICAgICAgICBpZiAoZGlyZWN0aW9uKSB7XG4gICAgICAgICAgICBpbnB1dC5hZGRpdGlvbmFsRXZlbnQgPSB0aGlzLm9wdGlvbnMuZXZlbnQgKyBkaXJlY3Rpb247XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3VwZXIuZW1pdC5jYWxsKHRoaXMsIGlucHV0KTtcbiAgICB9XG59KTtcblxuLyoqXG4gKiBQaW5jaFxuICogUmVjb2duaXplZCB3aGVuIHR3byBvciBtb3JlIHBvaW50ZXJzIGFyZSBtb3ZpbmcgdG93YXJkICh6b29tLWluKSBvciBhd2F5IGZyb20gZWFjaCBvdGhlciAoem9vbS1vdXQpLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyBBdHRyUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBQaW5jaFJlY29nbml6ZXIoKSB7XG4gICAgQXR0clJlY29nbml6ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuaW5oZXJpdChQaW5jaFJlY29nbml6ZXIsIEF0dHJSZWNvZ25pemVyLCB7XG4gICAgLyoqXG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqIEBtZW1iZXJvZiBQaW5jaFJlY29nbml6ZXJcbiAgICAgKi9cbiAgICBkZWZhdWx0czoge1xuICAgICAgICBldmVudDogJ3BpbmNoJyxcbiAgICAgICAgdGhyZXNob2xkOiAwLFxuICAgICAgICBwb2ludGVyczogMlxuICAgIH0sXG5cbiAgICBnZXRUb3VjaEFjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBbVE9VQ0hfQUNUSU9OX05PTkVdO1xuICAgIH0sXG5cbiAgICBhdHRyVGVzdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N1cGVyLmF0dHJUZXN0LmNhbGwodGhpcywgaW5wdXQpICYmXG4gICAgICAgICAgICAoTWF0aC5hYnMoaW5wdXQuc2NhbGUgLSAxKSA+IHRoaXMub3B0aW9ucy50aHJlc2hvbGQgfHwgdGhpcy5zdGF0ZSAmIFNUQVRFX0JFR0FOKTtcbiAgICB9LFxuXG4gICAgZW1pdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgaWYgKGlucHV0LnNjYWxlICE9PSAxKSB7XG4gICAgICAgICAgICB2YXIgaW5PdXQgPSBpbnB1dC5zY2FsZSA8IDEgPyAnaW4nIDogJ291dCc7XG4gICAgICAgICAgICBpbnB1dC5hZGRpdGlvbmFsRXZlbnQgPSB0aGlzLm9wdGlvbnMuZXZlbnQgKyBpbk91dDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdXBlci5lbWl0LmNhbGwodGhpcywgaW5wdXQpO1xuICAgIH1cbn0pO1xuXG4vKipcbiAqIFByZXNzXG4gKiBSZWNvZ25pemVkIHdoZW4gdGhlIHBvaW50ZXIgaXMgZG93biBmb3IgeCBtcyB3aXRob3V0IGFueSBtb3ZlbWVudC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBQcmVzc1JlY29nbml6ZXIoKSB7XG4gICAgUmVjb2duaXplci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgdGhpcy5fdGltZXIgPSBudWxsO1xuICAgIHRoaXMuX2lucHV0ID0gbnVsbDtcbn1cblxuaW5oZXJpdChQcmVzc1JlY29nbml6ZXIsIFJlY29nbml6ZXIsIHtcbiAgICAvKipcbiAgICAgKiBAbmFtZXNwYWNlXG4gICAgICogQG1lbWJlcm9mIFByZXNzUmVjb2duaXplclxuICAgICAqL1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgIGV2ZW50OiAncHJlc3MnLFxuICAgICAgICBwb2ludGVyczogMSxcbiAgICAgICAgdGltZTogMjUxLCAvLyBtaW5pbWFsIHRpbWUgb2YgdGhlIHBvaW50ZXIgdG8gYmUgcHJlc3NlZFxuICAgICAgICB0aHJlc2hvbGQ6IDkgLy8gYSBtaW5pbWFsIG1vdmVtZW50IGlzIG9rLCBidXQga2VlcCBpdCBsb3dcbiAgICB9LFxuXG4gICAgZ2V0VG91Y2hBY3Rpb246IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gW1RPVUNIX0FDVElPTl9BVVRPXTtcbiAgICB9LFxuXG4gICAgcHJvY2VzczogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciB2YWxpZFBvaW50ZXJzID0gaW5wdXQucG9pbnRlcnMubGVuZ3RoID09PSBvcHRpb25zLnBvaW50ZXJzO1xuICAgICAgICB2YXIgdmFsaWRNb3ZlbWVudCA9IGlucHV0LmRpc3RhbmNlIDwgb3B0aW9ucy50aHJlc2hvbGQ7XG4gICAgICAgIHZhciB2YWxpZFRpbWUgPSBpbnB1dC5kZWx0YVRpbWUgPiBvcHRpb25zLnRpbWU7XG5cbiAgICAgICAgdGhpcy5faW5wdXQgPSBpbnB1dDtcblxuICAgICAgICAvLyB3ZSBvbmx5IGFsbG93IGxpdHRsZSBtb3ZlbWVudFxuICAgICAgICAvLyBhbmQgd2UndmUgcmVhY2hlZCBhbiBlbmQgZXZlbnQsIHNvIGEgdGFwIGlzIHBvc3NpYmxlXG4gICAgICAgIGlmICghdmFsaWRNb3ZlbWVudCB8fCAhdmFsaWRQb2ludGVycyB8fCAoaW5wdXQuZXZlbnRUeXBlICYgKElOUFVUX0VORCB8IElOUFVUX0NBTkNFTCkgJiYgIXZhbGlkVGltZSkpIHtcbiAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgICAgfSBlbHNlIGlmIChpbnB1dC5ldmVudFR5cGUgJiBJTlBVVF9TVEFSVCkge1xuICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICAgICAgdGhpcy5fdGltZXIgPSBzZXRUaW1lb3V0Q29udGV4dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU1RBVEVfUkVDT0dOSVpFRDtcbiAgICAgICAgICAgICAgICB0aGlzLnRyeUVtaXQoKTtcbiAgICAgICAgICAgIH0sIG9wdGlvbnMudGltZSwgdGhpcyk7XG4gICAgICAgIH0gZWxzZSBpZiAoaW5wdXQuZXZlbnRUeXBlICYgSU5QVVRfRU5EKSB7XG4gICAgICAgICAgICByZXR1cm4gU1RBVEVfUkVDT0dOSVpFRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU1RBVEVfRkFJTEVEO1xuICAgIH0sXG5cbiAgICByZXNldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl90aW1lcik7XG4gICAgfSxcblxuICAgIGVtaXQ6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBTVEFURV9SRUNPR05JWkVEKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5wdXQgJiYgKGlucHV0LmV2ZW50VHlwZSAmIElOUFVUX0VORCkpIHtcbiAgICAgICAgICAgIHRoaXMubWFuYWdlci5lbWl0KHRoaXMub3B0aW9ucy5ldmVudCArICd1cCcsIGlucHV0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2lucHV0LnRpbWVTdGFtcCA9IG5vdygpO1xuICAgICAgICAgICAgdGhpcy5tYW5hZ2VyLmVtaXQodGhpcy5vcHRpb25zLmV2ZW50LCB0aGlzLl9pbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG59KTtcblxuLyoqXG4gKiBSb3RhdGVcbiAqIFJlY29nbml6ZWQgd2hlbiB0d28gb3IgbW9yZSBwb2ludGVyIGFyZSBtb3ZpbmcgaW4gYSBjaXJjdWxhciBtb3Rpb24uXG4gKiBAY29uc3RydWN0b3JcbiAqIEBleHRlbmRzIEF0dHJSZWNvZ25pemVyXG4gKi9cbmZ1bmN0aW9uIFJvdGF0ZVJlY29nbml6ZXIoKSB7XG4gICAgQXR0clJlY29nbml6ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuaW5oZXJpdChSb3RhdGVSZWNvZ25pemVyLCBBdHRyUmVjb2duaXplciwge1xuICAgIC8qKlxuICAgICAqIEBuYW1lc3BhY2VcbiAgICAgKiBAbWVtYmVyb2YgUm90YXRlUmVjb2duaXplclxuICAgICAqL1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgIGV2ZW50OiAncm90YXRlJyxcbiAgICAgICAgdGhyZXNob2xkOiAwLFxuICAgICAgICBwb2ludGVyczogMlxuICAgIH0sXG5cbiAgICBnZXRUb3VjaEFjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBbVE9VQ0hfQUNUSU9OX05PTkVdO1xuICAgIH0sXG5cbiAgICBhdHRyVGVzdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N1cGVyLmF0dHJUZXN0LmNhbGwodGhpcywgaW5wdXQpICYmXG4gICAgICAgICAgICAoTWF0aC5hYnMoaW5wdXQucm90YXRpb24pID4gdGhpcy5vcHRpb25zLnRocmVzaG9sZCB8fCB0aGlzLnN0YXRlICYgU1RBVEVfQkVHQU4pO1xuICAgIH1cbn0pO1xuXG4vKipcbiAqIFN3aXBlXG4gKiBSZWNvZ25pemVkIHdoZW4gdGhlIHBvaW50ZXIgaXMgbW92aW5nIGZhc3QgKHZlbG9jaXR5KSwgd2l0aCBlbm91Z2ggZGlzdGFuY2UgaW4gdGhlIGFsbG93ZWQgZGlyZWN0aW9uLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyBBdHRyUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBTd2lwZVJlY29nbml6ZXIoKSB7XG4gICAgQXR0clJlY29nbml6ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuaW5oZXJpdChTd2lwZVJlY29nbml6ZXIsIEF0dHJSZWNvZ25pemVyLCB7XG4gICAgLyoqXG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqIEBtZW1iZXJvZiBTd2lwZVJlY29nbml6ZXJcbiAgICAgKi9cbiAgICBkZWZhdWx0czoge1xuICAgICAgICBldmVudDogJ3N3aXBlJyxcbiAgICAgICAgdGhyZXNob2xkOiAxMCxcbiAgICAgICAgdmVsb2NpdHk6IDAuMyxcbiAgICAgICAgZGlyZWN0aW9uOiBESVJFQ1RJT05fSE9SSVpPTlRBTCB8IERJUkVDVElPTl9WRVJUSUNBTCxcbiAgICAgICAgcG9pbnRlcnM6IDFcbiAgICB9LFxuXG4gICAgZ2V0VG91Y2hBY3Rpb246IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gUGFuUmVjb2duaXplci5wcm90b3R5cGUuZ2V0VG91Y2hBY3Rpb24uY2FsbCh0aGlzKTtcbiAgICB9LFxuXG4gICAgYXR0clRlc3Q6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSB0aGlzLm9wdGlvbnMuZGlyZWN0aW9uO1xuICAgICAgICB2YXIgdmVsb2NpdHk7XG5cbiAgICAgICAgaWYgKGRpcmVjdGlvbiAmIChESVJFQ1RJT05fSE9SSVpPTlRBTCB8IERJUkVDVElPTl9WRVJUSUNBTCkpIHtcbiAgICAgICAgICAgIHZlbG9jaXR5ID0gaW5wdXQub3ZlcmFsbFZlbG9jaXR5O1xuICAgICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiAmIERJUkVDVElPTl9IT1JJWk9OVEFMKSB7XG4gICAgICAgICAgICB2ZWxvY2l0eSA9IGlucHV0Lm92ZXJhbGxWZWxvY2l0eVg7XG4gICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uICYgRElSRUNUSU9OX1ZFUlRJQ0FMKSB7XG4gICAgICAgICAgICB2ZWxvY2l0eSA9IGlucHV0Lm92ZXJhbGxWZWxvY2l0eVk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5fc3VwZXIuYXR0clRlc3QuY2FsbCh0aGlzLCBpbnB1dCkgJiZcbiAgICAgICAgICAgIGRpcmVjdGlvbiAmIGlucHV0Lm9mZnNldERpcmVjdGlvbiAmJlxuICAgICAgICAgICAgaW5wdXQuZGlzdGFuY2UgPiB0aGlzLm9wdGlvbnMudGhyZXNob2xkICYmXG4gICAgICAgICAgICBpbnB1dC5tYXhQb2ludGVycyA9PSB0aGlzLm9wdGlvbnMucG9pbnRlcnMgJiZcbiAgICAgICAgICAgIGFicyh2ZWxvY2l0eSkgPiB0aGlzLm9wdGlvbnMudmVsb2NpdHkgJiYgaW5wdXQuZXZlbnRUeXBlICYgSU5QVVRfRU5EO1xuICAgIH0sXG5cbiAgICBlbWl0OiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgZGlyZWN0aW9uID0gZGlyZWN0aW9uU3RyKGlucHV0Lm9mZnNldERpcmVjdGlvbik7XG4gICAgICAgIGlmIChkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgIHRoaXMubWFuYWdlci5lbWl0KHRoaXMub3B0aW9ucy5ldmVudCArIGRpcmVjdGlvbiwgaW5wdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tYW5hZ2VyLmVtaXQodGhpcy5vcHRpb25zLmV2ZW50LCBpbnB1dCk7XG4gICAgfVxufSk7XG5cbi8qKlxuICogQSB0YXAgaXMgZWNvZ25pemVkIHdoZW4gdGhlIHBvaW50ZXIgaXMgZG9pbmcgYSBzbWFsbCB0YXAvY2xpY2suIE11bHRpcGxlIHRhcHMgYXJlIHJlY29nbml6ZWQgaWYgdGhleSBvY2N1clxuICogYmV0d2VlbiB0aGUgZ2l2ZW4gaW50ZXJ2YWwgYW5kIHBvc2l0aW9uLiBUaGUgZGVsYXkgb3B0aW9uIGNhbiBiZSB1c2VkIHRvIHJlY29nbml6ZSBtdWx0aS10YXBzIHdpdGhvdXQgZmlyaW5nXG4gKiBhIHNpbmdsZSB0YXAuXG4gKlxuICogVGhlIGV2ZW50RGF0YSBmcm9tIHRoZSBlbWl0dGVkIGV2ZW50IGNvbnRhaW5zIHRoZSBwcm9wZXJ0eSBgdGFwQ291bnRgLCB3aGljaCBjb250YWlucyB0aGUgYW1vdW50IG9mXG4gKiBtdWx0aS10YXBzIGJlaW5nIHJlY29nbml6ZWQuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBleHRlbmRzIFJlY29nbml6ZXJcbiAqL1xuZnVuY3Rpb24gVGFwUmVjb2duaXplcigpIHtcbiAgICBSZWNvZ25pemVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICAvLyBwcmV2aW91cyB0aW1lIGFuZCBjZW50ZXIsXG4gICAgLy8gdXNlZCBmb3IgdGFwIGNvdW50aW5nXG4gICAgdGhpcy5wVGltZSA9IGZhbHNlO1xuICAgIHRoaXMucENlbnRlciA9IGZhbHNlO1xuXG4gICAgdGhpcy5fdGltZXIgPSBudWxsO1xuICAgIHRoaXMuX2lucHV0ID0gbnVsbDtcbiAgICB0aGlzLmNvdW50ID0gMDtcbn1cblxuaW5oZXJpdChUYXBSZWNvZ25pemVyLCBSZWNvZ25pemVyLCB7XG4gICAgLyoqXG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqIEBtZW1iZXJvZiBQaW5jaFJlY29nbml6ZXJcbiAgICAgKi9cbiAgICBkZWZhdWx0czoge1xuICAgICAgICBldmVudDogJ3RhcCcsXG4gICAgICAgIHBvaW50ZXJzOiAxLFxuICAgICAgICB0YXBzOiAxLFxuICAgICAgICBpbnRlcnZhbDogMzAwLCAvLyBtYXggdGltZSBiZXR3ZWVuIHRoZSBtdWx0aS10YXAgdGFwc1xuICAgICAgICB0aW1lOiAyNTAsIC8vIG1heCB0aW1lIG9mIHRoZSBwb2ludGVyIHRvIGJlIGRvd24gKGxpa2UgZmluZ2VyIG9uIHRoZSBzY3JlZW4pXG4gICAgICAgIHRocmVzaG9sZDogOSwgLy8gYSBtaW5pbWFsIG1vdmVtZW50IGlzIG9rLCBidXQga2VlcCBpdCBsb3dcbiAgICAgICAgcG9zVGhyZXNob2xkOiAxMCAvLyBhIG11bHRpLXRhcCBjYW4gYmUgYSBiaXQgb2ZmIHRoZSBpbml0aWFsIHBvc2l0aW9uXG4gICAgfSxcblxuICAgIGdldFRvdWNoQWN0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIFtUT1VDSF9BQ1RJT05fTUFOSVBVTEFUSU9OXTtcbiAgICB9LFxuXG4gICAgcHJvY2VzczogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG5cbiAgICAgICAgdmFyIHZhbGlkUG9pbnRlcnMgPSBpbnB1dC5wb2ludGVycy5sZW5ndGggPT09IG9wdGlvbnMucG9pbnRlcnM7XG4gICAgICAgIHZhciB2YWxpZE1vdmVtZW50ID0gaW5wdXQuZGlzdGFuY2UgPCBvcHRpb25zLnRocmVzaG9sZDtcbiAgICAgICAgdmFyIHZhbGlkVG91Y2hUaW1lID0gaW5wdXQuZGVsdGFUaW1lIDwgb3B0aW9ucy50aW1lO1xuXG4gICAgICAgIHRoaXMucmVzZXQoKTtcblxuICAgICAgICBpZiAoKGlucHV0LmV2ZW50VHlwZSAmIElOUFVUX1NUQVJUKSAmJiAodGhpcy5jb3VudCA9PT0gMCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZhaWxUaW1lb3V0KCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB3ZSBvbmx5IGFsbG93IGxpdHRsZSBtb3ZlbWVudFxuICAgICAgICAvLyBhbmQgd2UndmUgcmVhY2hlZCBhbiBlbmQgZXZlbnQsIHNvIGEgdGFwIGlzIHBvc3NpYmxlXG4gICAgICAgIGlmICh2YWxpZE1vdmVtZW50ICYmIHZhbGlkVG91Y2hUaW1lICYmIHZhbGlkUG9pbnRlcnMpIHtcbiAgICAgICAgICAgIGlmIChpbnB1dC5ldmVudFR5cGUgIT0gSU5QVVRfRU5EKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmFpbFRpbWVvdXQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHZhbGlkSW50ZXJ2YWwgPSB0aGlzLnBUaW1lID8gKGlucHV0LnRpbWVTdGFtcCAtIHRoaXMucFRpbWUgPCBvcHRpb25zLmludGVydmFsKSA6IHRydWU7XG4gICAgICAgICAgICB2YXIgdmFsaWRNdWx0aVRhcCA9ICF0aGlzLnBDZW50ZXIgfHwgZ2V0RGlzdGFuY2UodGhpcy5wQ2VudGVyLCBpbnB1dC5jZW50ZXIpIDwgb3B0aW9ucy5wb3NUaHJlc2hvbGQ7XG5cbiAgICAgICAgICAgIHRoaXMucFRpbWUgPSBpbnB1dC50aW1lU3RhbXA7XG4gICAgICAgICAgICB0aGlzLnBDZW50ZXIgPSBpbnB1dC5jZW50ZXI7XG5cbiAgICAgICAgICAgIGlmICghdmFsaWRNdWx0aVRhcCB8fCAhdmFsaWRJbnRlcnZhbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY291bnQgPSAxO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvdW50ICs9IDE7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX2lucHV0ID0gaW5wdXQ7XG5cbiAgICAgICAgICAgIC8vIGlmIHRhcCBjb3VudCBtYXRjaGVzIHdlIGhhdmUgcmVjb2duaXplZCBpdCxcbiAgICAgICAgICAgIC8vIGVsc2UgaXQgaGFzIGJlZ2FuIHJlY29nbml6aW5nLi4uXG4gICAgICAgICAgICB2YXIgdGFwQ291bnQgPSB0aGlzLmNvdW50ICUgb3B0aW9ucy50YXBzO1xuICAgICAgICAgICAgaWYgKHRhcENvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gbm8gZmFpbGluZyByZXF1aXJlbWVudHMsIGltbWVkaWF0ZWx5IHRyaWdnZXIgdGhlIHRhcCBldmVudFxuICAgICAgICAgICAgICAgIC8vIG9yIHdhaXQgYXMgbG9uZyBhcyB0aGUgbXVsdGl0YXAgaW50ZXJ2YWwgdG8gdHJpZ2dlclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5oYXNSZXF1aXJlRmFpbHVyZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gU1RBVEVfUkVDT0dOSVpFRDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl90aW1lciA9IHNldFRpbWVvdXRDb250ZXh0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNUQVRFX1JFQ09HTklaRUQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyeUVtaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgb3B0aW9ucy5pbnRlcnZhbCwgdGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBTVEFURV9CRUdBTjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFNUQVRFX0ZBSUxFRDtcbiAgICB9LFxuXG4gICAgZmFpbFRpbWVvdXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLl90aW1lciA9IHNldFRpbWVvdXRDb250ZXh0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNUQVRFX0ZBSUxFRDtcbiAgICAgICAgfSwgdGhpcy5vcHRpb25zLmludGVydmFsLCB0aGlzKTtcbiAgICAgICAgcmV0dXJuIFNUQVRFX0ZBSUxFRDtcbiAgICB9LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xuICAgIH0sXG5cbiAgICBlbWl0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT0gU1RBVEVfUkVDT0dOSVpFRCkge1xuICAgICAgICAgICAgdGhpcy5faW5wdXQudGFwQ291bnQgPSB0aGlzLmNvdW50O1xuICAgICAgICAgICAgdGhpcy5tYW5hZ2VyLmVtaXQodGhpcy5vcHRpb25zLmV2ZW50LCB0aGlzLl9pbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG59KTtcblxuLyoqXG4gKiBTaW1wbGUgd2F5IHRvIGNyZWF0ZSBhIG1hbmFnZXIgd2l0aCBhIGRlZmF1bHQgc2V0IG9mIHJlY29nbml6ZXJzLlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIEhhbW1lcihlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgb3B0aW9ucy5yZWNvZ25pemVycyA9IGlmVW5kZWZpbmVkKG9wdGlvbnMucmVjb2duaXplcnMsIEhhbW1lci5kZWZhdWx0cy5wcmVzZXQpO1xuICAgIHJldHVybiBuZXcgTWFuYWdlcihlbGVtZW50LCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBAY29uc3Qge3N0cmluZ31cbiAqL1xuSGFtbWVyLlZFUlNJT04gPSAnMi4wLjcnO1xuXG4vKipcbiAqIGRlZmF1bHQgc2V0dGluZ3NcbiAqIEBuYW1lc3BhY2VcbiAqL1xuSGFtbWVyLmRlZmF1bHRzID0ge1xuICAgIC8qKlxuICAgICAqIHNldCBpZiBET00gZXZlbnRzIGFyZSBiZWluZyB0cmlnZ2VyZWQuXG4gICAgICogQnV0IHRoaXMgaXMgc2xvd2VyIGFuZCB1bnVzZWQgYnkgc2ltcGxlIGltcGxlbWVudGF0aW9ucywgc28gZGlzYWJsZWQgYnkgZGVmYXVsdC5cbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqL1xuICAgIGRvbUV2ZW50czogZmFsc2UsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdmFsdWUgZm9yIHRoZSB0b3VjaEFjdGlvbiBwcm9wZXJ0eS9mYWxsYmFjay5cbiAgICAgKiBXaGVuIHNldCB0byBgY29tcHV0ZWAgaXQgd2lsbCBtYWdpY2FsbHkgc2V0IHRoZSBjb3JyZWN0IHZhbHVlIGJhc2VkIG9uIHRoZSBhZGRlZCByZWNvZ25pemVycy5cbiAgICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgICAqIEBkZWZhdWx0IGNvbXB1dGVcbiAgICAgKi9cbiAgICB0b3VjaEFjdGlvbjogVE9VQ0hfQUNUSU9OX0NPTVBVVEUsXG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICovXG4gICAgZW5hYmxlOiB0cnVlLFxuXG4gICAgLyoqXG4gICAgICogRVhQRVJJTUVOVEFMIEZFQVRVUkUgLS0gY2FuIGJlIHJlbW92ZWQvY2hhbmdlZFxuICAgICAqIENoYW5nZSB0aGUgcGFyZW50IGlucHV0IHRhcmdldCBlbGVtZW50LlxuICAgICAqIElmIE51bGwsIHRoZW4gaXQgaXMgYmVpbmcgc2V0IHRoZSB0byBtYWluIGVsZW1lbnQuXG4gICAgICogQHR5cGUge051bGx8RXZlbnRUYXJnZXR9XG4gICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAqL1xuICAgIGlucHV0VGFyZ2V0OiBudWxsLFxuXG4gICAgLyoqXG4gICAgICogZm9yY2UgYW4gaW5wdXQgY2xhc3NcbiAgICAgKiBAdHlwZSB7TnVsbHxGdW5jdGlvbn1cbiAgICAgKiBAZGVmYXVsdCBudWxsXG4gICAgICovXG4gICAgaW5wdXRDbGFzczogbnVsbCxcblxuICAgIC8qKlxuICAgICAqIERlZmF1bHQgcmVjb2duaXplciBzZXR1cCB3aGVuIGNhbGxpbmcgYEhhbW1lcigpYFxuICAgICAqIFdoZW4gY3JlYXRpbmcgYSBuZXcgTWFuYWdlciB0aGVzZSB3aWxsIGJlIHNraXBwZWQuXG4gICAgICogQHR5cGUge0FycmF5fVxuICAgICAqL1xuICAgIHByZXNldDogW1xuICAgICAgICAvLyBSZWNvZ25pemVyQ2xhc3MsIG9wdGlvbnMsIFtyZWNvZ25pemVXaXRoLCAuLi5dLCBbcmVxdWlyZUZhaWx1cmUsIC4uLl1cbiAgICAgICAgW1JvdGF0ZVJlY29nbml6ZXIsIHtlbmFibGU6IGZhbHNlfV0sXG4gICAgICAgIFtQaW5jaFJlY29nbml6ZXIsIHtlbmFibGU6IGZhbHNlfSwgWydyb3RhdGUnXV0sXG4gICAgICAgIFtTd2lwZVJlY29nbml6ZXIsIHtkaXJlY3Rpb246IERJUkVDVElPTl9IT1JJWk9OVEFMfV0sXG4gICAgICAgIFtQYW5SZWNvZ25pemVyLCB7ZGlyZWN0aW9uOiBESVJFQ1RJT05fSE9SSVpPTlRBTH0sIFsnc3dpcGUnXV0sXG4gICAgICAgIFtUYXBSZWNvZ25pemVyXSxcbiAgICAgICAgW1RhcFJlY29nbml6ZXIsIHtldmVudDogJ2RvdWJsZXRhcCcsIHRhcHM6IDJ9LCBbJ3RhcCddXSxcbiAgICAgICAgW1ByZXNzUmVjb2duaXplcl1cbiAgICBdLFxuXG4gICAgLyoqXG4gICAgICogU29tZSBDU1MgcHJvcGVydGllcyBjYW4gYmUgdXNlZCB0byBpbXByb3ZlIHRoZSB3b3JraW5nIG9mIEhhbW1lci5cbiAgICAgKiBBZGQgdGhlbSB0byB0aGlzIG1ldGhvZCBhbmQgdGhleSB3aWxsIGJlIHNldCB3aGVuIGNyZWF0aW5nIGEgbmV3IE1hbmFnZXIuXG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqL1xuICAgIGNzc1Byb3BzOiB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNhYmxlcyB0ZXh0IHNlbGVjdGlvbiB0byBpbXByb3ZlIHRoZSBkcmFnZ2luZyBnZXN0dXJlLiBNYWlubHkgZm9yIGRlc2t0b3AgYnJvd3NlcnMuXG4gICAgICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICAgICAqIEBkZWZhdWx0ICdub25lJ1xuICAgICAgICAgKi9cbiAgICAgICAgdXNlclNlbGVjdDogJ25vbmUnLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNhYmxlIHRoZSBXaW5kb3dzIFBob25lIGdyaXBwZXJzIHdoZW4gcHJlc3NpbmcgYW4gZWxlbWVudC5cbiAgICAgICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgICAgICogQGRlZmF1bHQgJ25vbmUnXG4gICAgICAgICAqL1xuICAgICAgICB0b3VjaFNlbGVjdDogJ25vbmUnLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNhYmxlcyB0aGUgZGVmYXVsdCBjYWxsb3V0IHNob3duIHdoZW4geW91IHRvdWNoIGFuZCBob2xkIGEgdG91Y2ggdGFyZ2V0LlxuICAgICAgICAgKiBPbiBpT1MsIHdoZW4geW91IHRvdWNoIGFuZCBob2xkIGEgdG91Y2ggdGFyZ2V0IHN1Y2ggYXMgYSBsaW5rLCBTYWZhcmkgZGlzcGxheXNcbiAgICAgICAgICogYSBjYWxsb3V0IGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxpbmsuIFRoaXMgcHJvcGVydHkgYWxsb3dzIHlvdSB0byBkaXNhYmxlIHRoYXQgY2FsbG91dC5cbiAgICAgICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgICAgICogQGRlZmF1bHQgJ25vbmUnXG4gICAgICAgICAqL1xuICAgICAgICB0b3VjaENhbGxvdXQ6ICdub25lJyxcblxuICAgICAgICAvKipcbiAgICAgICAgICogU3BlY2lmaWVzIHdoZXRoZXIgem9vbWluZyBpcyBlbmFibGVkLiBVc2VkIGJ5IElFMTA+XG4gICAgICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICAgICAqIEBkZWZhdWx0ICdub25lJ1xuICAgICAgICAgKi9cbiAgICAgICAgY29udGVudFpvb21pbmc6ICdub25lJyxcblxuICAgICAgICAvKipcbiAgICAgICAgICogU3BlY2lmaWVzIHRoYXQgYW4gZW50aXJlIGVsZW1lbnQgc2hvdWxkIGJlIGRyYWdnYWJsZSBpbnN0ZWFkIG9mIGl0cyBjb250ZW50cy4gTWFpbmx5IGZvciBkZXNrdG9wIGJyb3dzZXJzLlxuICAgICAgICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgICAgICAgKiBAZGVmYXVsdCAnbm9uZSdcbiAgICAgICAgICovXG4gICAgICAgIHVzZXJEcmFnOiAnbm9uZScsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE92ZXJyaWRlcyB0aGUgaGlnaGxpZ2h0IGNvbG9yIHNob3duIHdoZW4gdGhlIHVzZXIgdGFwcyBhIGxpbmsgb3IgYSBKYXZhU2NyaXB0XG4gICAgICAgICAqIGNsaWNrYWJsZSBlbGVtZW50IGluIGlPUy4gVGhpcyBwcm9wZXJ0eSBvYmV5cyB0aGUgYWxwaGEgdmFsdWUsIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgICAgICogQGRlZmF1bHQgJ3JnYmEoMCwwLDAsMCknXG4gICAgICAgICAqL1xuICAgICAgICB0YXBIaWdobGlnaHRDb2xvcjogJ3JnYmEoMCwwLDAsMCknXG4gICAgfVxufTtcblxudmFyIFNUT1AgPSAxO1xudmFyIEZPUkNFRF9TVE9QID0gMjtcblxuLyoqXG4gKiBNYW5hZ2VyXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gTWFuYWdlcihlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gYXNzaWduKHt9LCBIYW1tZXIuZGVmYXVsdHMsIG9wdGlvbnMgfHwge30pO1xuXG4gICAgdGhpcy5vcHRpb25zLmlucHV0VGFyZ2V0ID0gdGhpcy5vcHRpb25zLmlucHV0VGFyZ2V0IHx8IGVsZW1lbnQ7XG5cbiAgICB0aGlzLmhhbmRsZXJzID0ge307XG4gICAgdGhpcy5zZXNzaW9uID0ge307XG4gICAgdGhpcy5yZWNvZ25pemVycyA9IFtdO1xuICAgIHRoaXMub2xkQ3NzUHJvcHMgPSB7fTtcblxuICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgdGhpcy5pbnB1dCA9IGNyZWF0ZUlucHV0SW5zdGFuY2UodGhpcyk7XG4gICAgdGhpcy50b3VjaEFjdGlvbiA9IG5ldyBUb3VjaEFjdGlvbih0aGlzLCB0aGlzLm9wdGlvbnMudG91Y2hBY3Rpb24pO1xuXG4gICAgdG9nZ2xlQ3NzUHJvcHModGhpcywgdHJ1ZSk7XG5cbiAgICBlYWNoKHRoaXMub3B0aW9ucy5yZWNvZ25pemVycywgZnVuY3Rpb24oaXRlbSkge1xuICAgICAgICB2YXIgcmVjb2duaXplciA9IHRoaXMuYWRkKG5ldyAoaXRlbVswXSkoaXRlbVsxXSkpO1xuICAgICAgICBpdGVtWzJdICYmIHJlY29nbml6ZXIucmVjb2duaXplV2l0aChpdGVtWzJdKTtcbiAgICAgICAgaXRlbVszXSAmJiByZWNvZ25pemVyLnJlcXVpcmVGYWlsdXJlKGl0ZW1bM10pO1xuICAgIH0sIHRoaXMpO1xufVxuXG5NYW5hZ2VyLnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBzZXQgb3B0aW9uc1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAgICogQHJldHVybnMge01hbmFnZXJ9XG4gICAgICovXG4gICAgc2V0OiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgIGFzc2lnbih0aGlzLm9wdGlvbnMsIG9wdGlvbnMpO1xuXG4gICAgICAgIC8vIE9wdGlvbnMgdGhhdCBuZWVkIGEgbGl0dGxlIG1vcmUgc2V0dXBcbiAgICAgICAgaWYgKG9wdGlvbnMudG91Y2hBY3Rpb24pIHtcbiAgICAgICAgICAgIHRoaXMudG91Y2hBY3Rpb24udXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuaW5wdXRUYXJnZXQpIHtcbiAgICAgICAgICAgIC8vIENsZWFuIHVwIGV4aXN0aW5nIGV2ZW50IGxpc3RlbmVycyBhbmQgcmVpbml0aWFsaXplXG4gICAgICAgICAgICB0aGlzLmlucHV0LmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQudGFyZ2V0ID0gb3B0aW9ucy5pbnB1dFRhcmdldDtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuaW5pdCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBzdG9wIHJlY29nbml6aW5nIGZvciB0aGlzIHNlc3Npb24uXG4gICAgICogVGhpcyBzZXNzaW9uIHdpbGwgYmUgZGlzY2FyZGVkLCB3aGVuIGEgbmV3IFtpbnB1dF1zdGFydCBldmVudCBpcyBmaXJlZC5cbiAgICAgKiBXaGVuIGZvcmNlZCwgdGhlIHJlY29nbml6ZXIgY3ljbGUgaXMgc3RvcHBlZCBpbW1lZGlhdGVseS5cbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IFtmb3JjZV1cbiAgICAgKi9cbiAgICBzdG9wOiBmdW5jdGlvbihmb3JjZSkge1xuICAgICAgICB0aGlzLnNlc3Npb24uc3RvcHBlZCA9IGZvcmNlID8gRk9SQ0VEX1NUT1AgOiBTVE9QO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBydW4gdGhlIHJlY29nbml6ZXJzIVxuICAgICAqIGNhbGxlZCBieSB0aGUgaW5wdXRIYW5kbGVyIGZ1bmN0aW9uIG9uIGV2ZXJ5IG1vdmVtZW50IG9mIHRoZSBwb2ludGVycyAodG91Y2hlcylcbiAgICAgKiBpdCB3YWxrcyB0aHJvdWdoIGFsbCB0aGUgcmVjb2duaXplcnMgYW5kIHRyaWVzIHRvIGRldGVjdCB0aGUgZ2VzdHVyZSB0aGF0IGlzIGJlaW5nIG1hZGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXREYXRhXG4gICAgICovXG4gICAgcmVjb2duaXplOiBmdW5jdGlvbihpbnB1dERhdGEpIHtcbiAgICAgICAgdmFyIHNlc3Npb24gPSB0aGlzLnNlc3Npb247XG4gICAgICAgIGlmIChzZXNzaW9uLnN0b3BwZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJ1biB0aGUgdG91Y2gtYWN0aW9uIHBvbHlmaWxsXG4gICAgICAgIHRoaXMudG91Y2hBY3Rpb24ucHJldmVudERlZmF1bHRzKGlucHV0RGF0YSk7XG5cbiAgICAgICAgdmFyIHJlY29nbml6ZXI7XG4gICAgICAgIHZhciByZWNvZ25pemVycyA9IHRoaXMucmVjb2duaXplcnM7XG5cbiAgICAgICAgLy8gdGhpcyBob2xkcyB0aGUgcmVjb2duaXplciB0aGF0IGlzIGJlaW5nIHJlY29nbml6ZWQuXG4gICAgICAgIC8vIHNvIHRoZSByZWNvZ25pemVyJ3Mgc3RhdGUgbmVlZHMgdG8gYmUgQkVHQU4sIENIQU5HRUQsIEVOREVEIG9yIFJFQ09HTklaRURcbiAgICAgICAgLy8gaWYgbm8gcmVjb2duaXplciBpcyBkZXRlY3RpbmcgYSB0aGluZywgaXQgaXMgc2V0IHRvIGBudWxsYFxuICAgICAgICB2YXIgY3VyUmVjb2duaXplciA9IHNlc3Npb24uY3VyUmVjb2duaXplcjtcblxuICAgICAgICAvLyByZXNldCB3aGVuIHRoZSBsYXN0IHJlY29nbml6ZXIgaXMgcmVjb2duaXplZFxuICAgICAgICAvLyBvciB3aGVuIHdlJ3JlIGluIGEgbmV3IHNlc3Npb25cbiAgICAgICAgaWYgKCFjdXJSZWNvZ25pemVyIHx8IChjdXJSZWNvZ25pemVyICYmIGN1clJlY29nbml6ZXIuc3RhdGUgJiBTVEFURV9SRUNPR05JWkVEKSkge1xuICAgICAgICAgICAgY3VyUmVjb2duaXplciA9IHNlc3Npb24uY3VyUmVjb2duaXplciA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgIHdoaWxlIChpIDwgcmVjb2duaXplcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZWNvZ25pemVyID0gcmVjb2duaXplcnNbaV07XG5cbiAgICAgICAgICAgIC8vIGZpbmQgb3V0IGlmIHdlIGFyZSBhbGxvd2VkIHRyeSB0byByZWNvZ25pemUgdGhlIGlucHV0IGZvciB0aGlzIG9uZS5cbiAgICAgICAgICAgIC8vIDEuICAgYWxsb3cgaWYgdGhlIHNlc3Npb24gaXMgTk9UIGZvcmNlZCBzdG9wcGVkIChzZWUgdGhlIC5zdG9wKCkgbWV0aG9kKVxuICAgICAgICAgICAgLy8gMi4gICBhbGxvdyBpZiB3ZSBzdGlsbCBoYXZlbid0IHJlY29nbml6ZWQgYSBnZXN0dXJlIGluIHRoaXMgc2Vzc2lvbiwgb3IgdGhlIHRoaXMgcmVjb2duaXplciBpcyB0aGUgb25lXG4gICAgICAgICAgICAvLyAgICAgIHRoYXQgaXMgYmVpbmcgcmVjb2duaXplZC5cbiAgICAgICAgICAgIC8vIDMuICAgYWxsb3cgaWYgdGhlIHJlY29nbml6ZXIgaXMgYWxsb3dlZCB0byBydW4gc2ltdWx0YW5lb3VzIHdpdGggdGhlIGN1cnJlbnQgcmVjb2duaXplZCByZWNvZ25pemVyLlxuICAgICAgICAgICAgLy8gICAgICB0aGlzIGNhbiBiZSBzZXR1cCB3aXRoIHRoZSBgcmVjb2duaXplV2l0aCgpYCBtZXRob2Qgb24gdGhlIHJlY29nbml6ZXIuXG4gICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdG9wcGVkICE9PSBGT1JDRURfU1RPUCAmJiAoIC8vIDFcbiAgICAgICAgICAgICAgICAgICAgIWN1clJlY29nbml6ZXIgfHwgcmVjb2duaXplciA9PSBjdXJSZWNvZ25pemVyIHx8IC8vIDJcbiAgICAgICAgICAgICAgICAgICAgcmVjb2duaXplci5jYW5SZWNvZ25pemVXaXRoKGN1clJlY29nbml6ZXIpKSkgeyAvLyAzXG4gICAgICAgICAgICAgICAgcmVjb2duaXplci5yZWNvZ25pemUoaW5wdXREYXRhKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb2duaXplci5yZXNldCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBpZiB0aGUgcmVjb2duaXplciBoYXMgYmVlbiByZWNvZ25pemluZyB0aGUgaW5wdXQgYXMgYSB2YWxpZCBnZXN0dXJlLCB3ZSB3YW50IHRvIHN0b3JlIHRoaXMgb25lIGFzIHRoZVxuICAgICAgICAgICAgLy8gY3VycmVudCBhY3RpdmUgcmVjb2duaXplci4gYnV0IG9ubHkgaWYgd2UgZG9uJ3QgYWxyZWFkeSBoYXZlIGFuIGFjdGl2ZSByZWNvZ25pemVyXG4gICAgICAgICAgICBpZiAoIWN1clJlY29nbml6ZXIgJiYgcmVjb2duaXplci5zdGF0ZSAmIChTVEFURV9CRUdBTiB8IFNUQVRFX0NIQU5HRUQgfCBTVEFURV9FTkRFRCkpIHtcbiAgICAgICAgICAgICAgICBjdXJSZWNvZ25pemVyID0gc2Vzc2lvbi5jdXJSZWNvZ25pemVyID0gcmVjb2duaXplcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBnZXQgYSByZWNvZ25pemVyIGJ5IGl0cyBldmVudCBuYW1lLlxuICAgICAqIEBwYXJhbSB7UmVjb2duaXplcnxTdHJpbmd9IHJlY29nbml6ZXJcbiAgICAgKiBAcmV0dXJucyB7UmVjb2duaXplcnxOdWxsfVxuICAgICAqL1xuICAgIGdldDogZnVuY3Rpb24ocmVjb2duaXplcikge1xuICAgICAgICBpZiAocmVjb2duaXplciBpbnN0YW5jZW9mIFJlY29nbml6ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiByZWNvZ25pemVyO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlY29nbml6ZXJzID0gdGhpcy5yZWNvZ25pemVycztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWNvZ25pemVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHJlY29nbml6ZXJzW2ldLm9wdGlvbnMuZXZlbnQgPT0gcmVjb2duaXplcikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWNvZ25pemVyc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogYWRkIGEgcmVjb2duaXplciB0byB0aGUgbWFuYWdlclxuICAgICAqIGV4aXN0aW5nIHJlY29nbml6ZXJzIHdpdGggdGhlIHNhbWUgZXZlbnQgbmFtZSB3aWxsIGJlIHJlbW92ZWRcbiAgICAgKiBAcGFyYW0ge1JlY29nbml6ZXJ9IHJlY29nbml6ZXJcbiAgICAgKiBAcmV0dXJucyB7UmVjb2duaXplcnxNYW5hZ2VyfVxuICAgICAqL1xuICAgIGFkZDogZnVuY3Rpb24ocmVjb2duaXplcikge1xuICAgICAgICBpZiAoaW52b2tlQXJyYXlBcmcocmVjb2duaXplciwgJ2FkZCcsIHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlbW92ZSBleGlzdGluZ1xuICAgICAgICB2YXIgZXhpc3RpbmcgPSB0aGlzLmdldChyZWNvZ25pemVyLm9wdGlvbnMuZXZlbnQpO1xuICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlKGV4aXN0aW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVjb2duaXplcnMucHVzaChyZWNvZ25pemVyKTtcbiAgICAgICAgcmVjb2duaXplci5tYW5hZ2VyID0gdGhpcztcblxuICAgICAgICB0aGlzLnRvdWNoQWN0aW9uLnVwZGF0ZSgpO1xuICAgICAgICByZXR1cm4gcmVjb2duaXplcjtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogcmVtb3ZlIGEgcmVjb2duaXplciBieSBuYW1lIG9yIGluc3RhbmNlXG4gICAgICogQHBhcmFtIHtSZWNvZ25pemVyfFN0cmluZ30gcmVjb2duaXplclxuICAgICAqIEByZXR1cm5zIHtNYW5hZ2VyfVxuICAgICAqL1xuICAgIHJlbW92ZTogZnVuY3Rpb24ocmVjb2duaXplcikge1xuICAgICAgICBpZiAoaW52b2tlQXJyYXlBcmcocmVjb2duaXplciwgJ3JlbW92ZScsIHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJlY29nbml6ZXIgPSB0aGlzLmdldChyZWNvZ25pemVyKTtcblxuICAgICAgICAvLyBsZXQncyBtYWtlIHN1cmUgdGhpcyByZWNvZ25pemVyIGV4aXN0c1xuICAgICAgICBpZiAocmVjb2duaXplcikge1xuICAgICAgICAgICAgdmFyIHJlY29nbml6ZXJzID0gdGhpcy5yZWNvZ25pemVycztcbiAgICAgICAgICAgIHZhciBpbmRleCA9IGluQXJyYXkocmVjb2duaXplcnMsIHJlY29nbml6ZXIpO1xuXG4gICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcmVjb2duaXplcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRvdWNoQWN0aW9uLnVwZGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGJpbmQgZXZlbnRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRzXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuICAgICAqIEByZXR1cm5zIHtFdmVudEVtaXR0ZXJ9IHRoaXNcbiAgICAgKi9cbiAgICBvbjogZnVuY3Rpb24oZXZlbnRzLCBoYW5kbGVyKSB7XG4gICAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYW5kbGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBoYW5kbGVycyA9IHRoaXMuaGFuZGxlcnM7XG4gICAgICAgIGVhY2goc3BsaXRTdHIoZXZlbnRzKSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGhhbmRsZXJzW2V2ZW50XSA9IGhhbmRsZXJzW2V2ZW50XSB8fCBbXTtcbiAgICAgICAgICAgIGhhbmRsZXJzW2V2ZW50XS5wdXNoKGhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIHVuYmluZCBldmVudCwgbGVhdmUgZW1pdCBibGFuayB0byByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50c1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtoYW5kbGVyXVxuICAgICAqIEByZXR1cm5zIHtFdmVudEVtaXR0ZXJ9IHRoaXNcbiAgICAgKi9cbiAgICBvZmY6IGZ1bmN0aW9uKGV2ZW50cywgaGFuZGxlcikge1xuICAgICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBoYW5kbGVycyA9IHRoaXMuaGFuZGxlcnM7XG4gICAgICAgIGVhY2goc3BsaXRTdHIoZXZlbnRzKSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBoYW5kbGVyc1tldmVudF07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzW2V2ZW50XSAmJiBoYW5kbGVyc1tldmVudF0uc3BsaWNlKGluQXJyYXkoaGFuZGxlcnNbZXZlbnRdLCBoYW5kbGVyKSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogZW1pdCBldmVudCB0byB0aGUgbGlzdGVuZXJzXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gICAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAgICAgKi9cbiAgICBlbWl0OiBmdW5jdGlvbihldmVudCwgZGF0YSkge1xuICAgICAgICAvLyB3ZSBhbHNvIHdhbnQgdG8gdHJpZ2dlciBkb20gZXZlbnRzXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZG9tRXZlbnRzKSB7XG4gICAgICAgICAgICB0cmlnZ2VyRG9tRXZlbnQoZXZlbnQsIGRhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbm8gaGFuZGxlcnMsIHNvIHNraXAgaXQgYWxsXG4gICAgICAgIHZhciBoYW5kbGVycyA9IHRoaXMuaGFuZGxlcnNbZXZlbnRdICYmIHRoaXMuaGFuZGxlcnNbZXZlbnRdLnNsaWNlKCk7XG4gICAgICAgIGlmICghaGFuZGxlcnMgfHwgIWhhbmRsZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZGF0YS50eXBlID0gZXZlbnQ7XG4gICAgICAgIGRhdGEucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGRhdGEuc3JjRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgIHdoaWxlIChpIDwgaGFuZGxlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBoYW5kbGVyc1tpXShkYXRhKTtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBkZXN0cm95IHRoZSBtYW5hZ2VyIGFuZCB1bmJpbmRzIGFsbCBldmVudHNcbiAgICAgKiBpdCBkb2Vzbid0IHVuYmluZCBkb20gZXZlbnRzLCB0aGF0IGlzIHRoZSB1c2VyIG93biByZXNwb25zaWJpbGl0eVxuICAgICAqL1xuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLmVsZW1lbnQgJiYgdG9nZ2xlQ3NzUHJvcHModGhpcywgZmFsc2UpO1xuXG4gICAgICAgIHRoaXMuaGFuZGxlcnMgPSB7fTtcbiAgICAgICAgdGhpcy5zZXNzaW9uID0ge307XG4gICAgICAgIHRoaXMuaW5wdXQuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBudWxsO1xuICAgIH1cbn07XG5cbi8qKlxuICogYWRkL3JlbW92ZSB0aGUgY3NzIHByb3BlcnRpZXMgYXMgZGVmaW5lZCBpbiBtYW5hZ2VyLm9wdGlvbnMuY3NzUHJvcHNcbiAqIEBwYXJhbSB7TWFuYWdlcn0gbWFuYWdlclxuICogQHBhcmFtIHtCb29sZWFufSBhZGRcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlQ3NzUHJvcHMobWFuYWdlciwgYWRkKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBtYW5hZ2VyLmVsZW1lbnQ7XG4gICAgaWYgKCFlbGVtZW50LnN0eWxlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHByb3A7XG4gICAgZWFjaChtYW5hZ2VyLm9wdGlvbnMuY3NzUHJvcHMsIGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgIHByb3AgPSBwcmVmaXhlZChlbGVtZW50LnN0eWxlLCBuYW1lKTtcbiAgICAgICAgaWYgKGFkZCkge1xuICAgICAgICAgICAgbWFuYWdlci5vbGRDc3NQcm9wc1twcm9wXSA9IGVsZW1lbnQuc3R5bGVbcHJvcF07XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlW3Byb3BdID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlW3Byb3BdID0gbWFuYWdlci5vbGRDc3NQcm9wc1twcm9wXSB8fCAnJztcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIGlmICghYWRkKSB7XG4gICAgICAgIG1hbmFnZXIub2xkQ3NzUHJvcHMgPSB7fTtcbiAgICB9XG59XG5cbi8qKlxuICogdHJpZ2dlciBkb20gZXZlbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAqL1xuZnVuY3Rpb24gdHJpZ2dlckRvbUV2ZW50KGV2ZW50LCBkYXRhKSB7XG4gICAgdmFyIGdlc3R1cmVFdmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudCcpO1xuICAgIGdlc3R1cmVFdmVudC5pbml0RXZlbnQoZXZlbnQsIHRydWUsIHRydWUpO1xuICAgIGdlc3R1cmVFdmVudC5nZXN0dXJlID0gZGF0YTtcbiAgICBkYXRhLnRhcmdldC5kaXNwYXRjaEV2ZW50KGdlc3R1cmVFdmVudCk7XG59XG5cbmFzc2lnbihIYW1tZXIsIHtcbiAgICBJTlBVVF9TVEFSVDogSU5QVVRfU1RBUlQsXG4gICAgSU5QVVRfTU9WRTogSU5QVVRfTU9WRSxcbiAgICBJTlBVVF9FTkQ6IElOUFVUX0VORCxcbiAgICBJTlBVVF9DQU5DRUw6IElOUFVUX0NBTkNFTCxcblxuICAgIFNUQVRFX1BPU1NJQkxFOiBTVEFURV9QT1NTSUJMRSxcbiAgICBTVEFURV9CRUdBTjogU1RBVEVfQkVHQU4sXG4gICAgU1RBVEVfQ0hBTkdFRDogU1RBVEVfQ0hBTkdFRCxcbiAgICBTVEFURV9FTkRFRDogU1RBVEVfRU5ERUQsXG4gICAgU1RBVEVfUkVDT0dOSVpFRDogU1RBVEVfUkVDT0dOSVpFRCxcbiAgICBTVEFURV9DQU5DRUxMRUQ6IFNUQVRFX0NBTkNFTExFRCxcbiAgICBTVEFURV9GQUlMRUQ6IFNUQVRFX0ZBSUxFRCxcblxuICAgIERJUkVDVElPTl9OT05FOiBESVJFQ1RJT05fTk9ORSxcbiAgICBESVJFQ1RJT05fTEVGVDogRElSRUNUSU9OX0xFRlQsXG4gICAgRElSRUNUSU9OX1JJR0hUOiBESVJFQ1RJT05fUklHSFQsXG4gICAgRElSRUNUSU9OX1VQOiBESVJFQ1RJT05fVVAsXG4gICAgRElSRUNUSU9OX0RPV046IERJUkVDVElPTl9ET1dOLFxuICAgIERJUkVDVElPTl9IT1JJWk9OVEFMOiBESVJFQ1RJT05fSE9SSVpPTlRBTCxcbiAgICBESVJFQ1RJT05fVkVSVElDQUw6IERJUkVDVElPTl9WRVJUSUNBTCxcbiAgICBESVJFQ1RJT05fQUxMOiBESVJFQ1RJT05fQUxMLFxuXG4gICAgTWFuYWdlcjogTWFuYWdlcixcbiAgICBJbnB1dDogSW5wdXQsXG4gICAgVG91Y2hBY3Rpb246IFRvdWNoQWN0aW9uLFxuXG4gICAgVG91Y2hJbnB1dDogVG91Y2hJbnB1dCxcbiAgICBNb3VzZUlucHV0OiBNb3VzZUlucHV0LFxuICAgIFBvaW50ZXJFdmVudElucHV0OiBQb2ludGVyRXZlbnRJbnB1dCxcbiAgICBUb3VjaE1vdXNlSW5wdXQ6IFRvdWNoTW91c2VJbnB1dCxcbiAgICBTaW5nbGVUb3VjaElucHV0OiBTaW5nbGVUb3VjaElucHV0LFxuXG4gICAgUmVjb2duaXplcjogUmVjb2duaXplcixcbiAgICBBdHRyUmVjb2duaXplcjogQXR0clJlY29nbml6ZXIsXG4gICAgVGFwOiBUYXBSZWNvZ25pemVyLFxuICAgIFBhbjogUGFuUmVjb2duaXplcixcbiAgICBTd2lwZTogU3dpcGVSZWNvZ25pemVyLFxuICAgIFBpbmNoOiBQaW5jaFJlY29nbml6ZXIsXG4gICAgUm90YXRlOiBSb3RhdGVSZWNvZ25pemVyLFxuICAgIFByZXNzOiBQcmVzc1JlY29nbml6ZXIsXG5cbiAgICBvbjogYWRkRXZlbnRMaXN0ZW5lcnMsXG4gICAgb2ZmOiByZW1vdmVFdmVudExpc3RlbmVycyxcbiAgICBlYWNoOiBlYWNoLFxuICAgIG1lcmdlOiBtZXJnZSxcbiAgICBleHRlbmQ6IGV4dGVuZCxcbiAgICBhc3NpZ246IGFzc2lnbixcbiAgICBpbmhlcml0OiBpbmhlcml0LFxuICAgIGJpbmRGbjogYmluZEZuLFxuICAgIHByZWZpeGVkOiBwcmVmaXhlZFxufSk7XG5cbi8vIHRoaXMgcHJldmVudHMgZXJyb3JzIHdoZW4gSGFtbWVyIGlzIGxvYWRlZCBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EXG4vLyAgc3R5bGUgbG9hZGVyIGJ1dCBieSBzY3JpcHQgdGFnLCBub3QgYnkgdGhlIGxvYWRlci5cbnZhciBmcmVlR2xvYmFsID0gKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IHNlbGYgOiB7fSkpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbmZyZWVHbG9iYWwuSGFtbWVyID0gSGFtbWVyO1xuXG5pZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gSGFtbWVyO1xuICAgIH0pO1xufSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlICE9ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBIYW1tZXI7XG59IGVsc2Uge1xuICAgIHdpbmRvd1tleHBvcnROYW1lXSA9IEhhbW1lcjtcbn1cblxufSkod2luZG93LCBkb2N1bWVudCwgJ0hhbW1lcicpO1xuIiwidmFyIGhhdCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJpdHMsIGJhc2UpIHtcbiAgICBpZiAoIWJhc2UpIGJhc2UgPSAxNjtcbiAgICBpZiAoYml0cyA9PT0gdW5kZWZpbmVkKSBiaXRzID0gMTI4O1xuICAgIGlmIChiaXRzIDw9IDApIHJldHVybiAnMCc7XG4gICAgXG4gICAgdmFyIGRpZ2l0cyA9IE1hdGgubG9nKE1hdGgucG93KDIsIGJpdHMpKSAvIE1hdGgubG9nKGJhc2UpO1xuICAgIGZvciAodmFyIGkgPSAyOyBkaWdpdHMgPT09IEluZmluaXR5OyBpICo9IDIpIHtcbiAgICAgICAgZGlnaXRzID0gTWF0aC5sb2coTWF0aC5wb3coMiwgYml0cyAvIGkpKSAvIE1hdGgubG9nKGJhc2UpICogaTtcbiAgICB9XG4gICAgXG4gICAgdmFyIHJlbSA9IGRpZ2l0cyAtIE1hdGguZmxvb3IoZGlnaXRzKTtcbiAgICBcbiAgICB2YXIgcmVzID0gJyc7XG4gICAgXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBNYXRoLmZsb29yKGRpZ2l0cyk7IGkrKykge1xuICAgICAgICB2YXIgeCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGJhc2UpLnRvU3RyaW5nKGJhc2UpO1xuICAgICAgICByZXMgPSB4ICsgcmVzO1xuICAgIH1cbiAgICBcbiAgICBpZiAocmVtKSB7XG4gICAgICAgIHZhciBiID0gTWF0aC5wb3coYmFzZSwgcmVtKTtcbiAgICAgICAgdmFyIHggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBiKS50b1N0cmluZyhiYXNlKTtcbiAgICAgICAgcmVzID0geCArIHJlcztcbiAgICB9XG4gICAgXG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHJlcywgYmFzZSk7XG4gICAgaWYgKHBhcnNlZCAhPT0gSW5maW5pdHkgJiYgcGFyc2VkID49IE1hdGgucG93KDIsIGJpdHMpKSB7XG4gICAgICAgIHJldHVybiBoYXQoYml0cywgYmFzZSlcbiAgICB9XG4gICAgZWxzZSByZXR1cm4gcmVzO1xufTtcblxuaGF0LnJhY2sgPSBmdW5jdGlvbiAoYml0cywgYmFzZSwgZXhwYW5kQnkpIHtcbiAgICB2YXIgZm4gPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgaXRlcnMgPSAwO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBpZiAoaXRlcnMgKysgPiAxMCkge1xuICAgICAgICAgICAgICAgIGlmIChleHBhbmRCeSkgYml0cyArPSBleHBhbmRCeTtcbiAgICAgICAgICAgICAgICBlbHNlIHRocm93IG5ldyBFcnJvcigndG9vIG1hbnkgSUQgY29sbGlzaW9ucywgdXNlIG1vcmUgYml0cycpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHZhciBpZCA9IGhhdChiaXRzLCBiYXNlKTtcbiAgICAgICAgfSB3aGlsZSAoT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwoaGF0cywgaWQpKTtcbiAgICAgICAgXG4gICAgICAgIGhhdHNbaWRdID0gZGF0YTtcbiAgICAgICAgcmV0dXJuIGlkO1xuICAgIH07XG4gICAgdmFyIGhhdHMgPSBmbi5oYXRzID0ge307XG4gICAgXG4gICAgZm4uZ2V0ID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIHJldHVybiBmbi5oYXRzW2lkXTtcbiAgICB9O1xuICAgIFxuICAgIGZuLnNldCA9IGZ1bmN0aW9uIChpZCwgdmFsdWUpIHtcbiAgICAgICAgZm4uaGF0c1tpZF0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIGZuO1xuICAgIH07XG4gICAgXG4gICAgZm4uYml0cyA9IGJpdHMgfHwgMTI4O1xuICAgIGZuLmJhc2UgPSBiYXNlIHx8IDE2O1xuICAgIHJldHVybiBmbjtcbn07XG4iLCJpbXBvcnQgaGF0IGZyb20gJ2hhdCc7XG5cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgaWQgZ2VuZXJhdG9yIC8gY2FjaGUgaW5zdGFuY2UuXG4gKlxuICogWW91IG1heSBvcHRpb25hbGx5IHByb3ZpZGUgYSBzZWVkIHRoYXQgaXMgdXNlZCBpbnRlcm5hbGx5LlxuICpcbiAqIEBwYXJhbSB7U2VlZH0gc2VlZFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBJZHMoc2VlZCkge1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBJZHMpKSB7XG4gICAgcmV0dXJuIG5ldyBJZHMoc2VlZCk7XG4gIH1cblxuICBzZWVkID0gc2VlZCB8fCBbIDEyOCwgMzYsIDEgXTtcbiAgdGhpcy5fc2VlZCA9IHNlZWQubGVuZ3RoID8gaGF0LnJhY2soc2VlZFswXSwgc2VlZFsxXSwgc2VlZFsyXSkgOiBzZWVkO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIGEgbmV4dCBpZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW2VsZW1lbnRdIGVsZW1lbnQgdG8gYmluZCB0aGUgaWQgdG9cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IGlkXG4gKi9cbklkcy5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHRoaXMuX3NlZWQoZWxlbWVudCB8fCB0cnVlKTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGUgYSBuZXh0IGlkIHdpdGggYSBnaXZlbiBwcmVmaXguXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtlbGVtZW50XSBlbGVtZW50IHRvIGJpbmQgdGhlIGlkIHRvXG4gKlxuICogQHJldHVybiB7U3RyaW5nfSBpZFxuICovXG5JZHMucHJvdG90eXBlLm5leHRQcmVmaXhlZCA9IGZ1bmN0aW9uKHByZWZpeCwgZWxlbWVudCkge1xuICB2YXIgaWQ7XG5cbiAgZG8ge1xuICAgIGlkID0gcHJlZml4ICsgdGhpcy5uZXh0KHRydWUpO1xuICB9IHdoaWxlICh0aGlzLmFzc2lnbmVkKGlkKSk7XG5cbiAgLy8gY2xhaW0ge3ByZWZpeH17cmFuZG9tfVxuICB0aGlzLmNsYWltKGlkLCBlbGVtZW50KTtcblxuICAvLyByZXR1cm5cbiAgcmV0dXJuIGlkO1xufTtcblxuLyoqXG4gKiBNYW51YWxseSBjbGFpbSBhbiBleGlzdGluZyBpZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBbZWxlbWVudF0gZWxlbWVudCB0aGUgaWQgaXMgY2xhaW1lZCBieVxuICovXG5JZHMucHJvdG90eXBlLmNsYWltID0gZnVuY3Rpb24oaWQsIGVsZW1lbnQpIHtcbiAgdGhpcy5fc2VlZC5zZXQoaWQsIGVsZW1lbnQgfHwgdHJ1ZSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gaWQgaGFzIGFscmVhZHkgYmVlbiBhc3NpZ25lZC5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGlkXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5JZHMucHJvdG90eXBlLmFzc2lnbmVkID0gZnVuY3Rpb24oaWQpIHtcbiAgcmV0dXJuIHRoaXMuX3NlZWQuZ2V0KGlkKSB8fCBmYWxzZTtcbn07XG5cbi8qKlxuICogVW5jbGFpbSBhbiBpZC5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGlkIHRoZSBpZCB0byB1bmNsYWltXG4gKi9cbklkcy5wcm90b3R5cGUudW5jbGFpbSA9IGZ1bmN0aW9uKGlkKSB7XG4gIGRlbGV0ZSB0aGlzLl9zZWVkLmhhdHNbaWRdO1xufTtcblxuXG4vKipcbiAqIENsZWFyIGFsbCBjbGFpbWVkIGlkcy5cbiAqL1xuSWRzLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBoYXRzID0gdGhpcy5fc2VlZC5oYXRzLFxuICAgICAgaWQ7XG5cbiAgZm9yIChpZCBpbiBoYXRzKSB7XG4gICAgdGhpcy51bmNsYWltKGlkKTtcbiAgfVxufTsiLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gICAgfVxuICB9XG59XG4iLCIvKiFcbiAqIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjMuNS4xXG4gKiBodHRwczovL2pxdWVyeS5jb20vXG4gKlxuICogSW5jbHVkZXMgU2l6emxlLmpzXG4gKiBodHRwczovL3NpenpsZWpzLmNvbS9cbiAqXG4gKiBDb3B5cmlnaHQgSlMgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqIGh0dHBzOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAyMC0wNS0wNFQyMjo0OVpcbiAqL1xuKCBmdW5jdGlvbiggZ2xvYmFsLCBmYWN0b3J5ICkge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXG5cdGlmICggdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHQvLyBGb3IgQ29tbW9uSlMgYW5kIENvbW1vbkpTLWxpa2UgZW52aXJvbm1lbnRzIHdoZXJlIGEgcHJvcGVyIGB3aW5kb3dgXG5cdFx0Ly8gaXMgcHJlc2VudCwgZXhlY3V0ZSB0aGUgZmFjdG9yeSBhbmQgZ2V0IGpRdWVyeS5cblx0XHQvLyBGb3IgZW52aXJvbm1lbnRzIHRoYXQgZG8gbm90IGhhdmUgYSBgd2luZG93YCB3aXRoIGEgYGRvY3VtZW50YFxuXHRcdC8vIChzdWNoIGFzIE5vZGUuanMpLCBleHBvc2UgYSBmYWN0b3J5IGFzIG1vZHVsZS5leHBvcnRzLlxuXHRcdC8vIFRoaXMgYWNjZW50dWF0ZXMgdGhlIG5lZWQgZm9yIHRoZSBjcmVhdGlvbiBvZiBhIHJlYWwgYHdpbmRvd2AuXG5cdFx0Ly8gZS5nLiB2YXIgalF1ZXJ5ID0gcmVxdWlyZShcImpxdWVyeVwiKSh3aW5kb3cpO1xuXHRcdC8vIFNlZSB0aWNrZXQgIzE0NTQ5IGZvciBtb3JlIGluZm8uXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBnbG9iYWwuZG9jdW1lbnQgP1xuXHRcdFx0ZmFjdG9yeSggZ2xvYmFsLCB0cnVlICkgOlxuXHRcdFx0ZnVuY3Rpb24oIHcgKSB7XG5cdFx0XHRcdGlmICggIXcuZG9jdW1lbnQgKSB7XG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCBcImpRdWVyeSByZXF1aXJlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnRcIiApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBmYWN0b3J5KCB3ICk7XG5cdFx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdGZhY3RvcnkoIGdsb2JhbCApO1xuXHR9XG5cbi8vIFBhc3MgdGhpcyBpZiB3aW5kb3cgaXMgbm90IGRlZmluZWQgeWV0XG59ICkoIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0aGlzLCBmdW5jdGlvbiggd2luZG93LCBub0dsb2JhbCApIHtcblxuLy8gRWRnZSA8PSAxMiAtIDEzKywgRmlyZWZveCA8PTE4IC0gNDUrLCBJRSAxMCAtIDExLCBTYWZhcmkgNS4xIC0gOSssIGlPUyA2IC0gOS4xXG4vLyB0aHJvdyBleGNlcHRpb25zIHdoZW4gbm9uLXN0cmljdCBjb2RlIChlLmcuLCBBU1AuTkVUIDQuNSkgYWNjZXNzZXMgc3RyaWN0IG1vZGVcbi8vIGFyZ3VtZW50cy5jYWxsZWUuY2FsbGVyICh0cmFjLTEzMzM1KS4gQnV0IGFzIG9mIGpRdWVyeSAzLjAgKDIwMTYpLCBzdHJpY3QgbW9kZSBzaG91bGQgYmUgY29tbW9uXG4vLyBlbm91Z2ggdGhhdCBhbGwgc3VjaCBhdHRlbXB0cyBhcmUgZ3VhcmRlZCBpbiBhIHRyeSBibG9jay5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgYXJyID0gW107XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcblxudmFyIHNsaWNlID0gYXJyLnNsaWNlO1xuXG52YXIgZmxhdCA9IGFyci5mbGF0ID8gZnVuY3Rpb24oIGFycmF5ICkge1xuXHRyZXR1cm4gYXJyLmZsYXQuY2FsbCggYXJyYXkgKTtcbn0gOiBmdW5jdGlvbiggYXJyYXkgKSB7XG5cdHJldHVybiBhcnIuY29uY2F0LmFwcGx5KCBbXSwgYXJyYXkgKTtcbn07XG5cblxudmFyIHB1c2ggPSBhcnIucHVzaDtcblxudmFyIGluZGV4T2YgPSBhcnIuaW5kZXhPZjtcblxudmFyIGNsYXNzMnR5cGUgPSB7fTtcblxudmFyIHRvU3RyaW5nID0gY2xhc3MydHlwZS50b1N0cmluZztcblxudmFyIGhhc093biA9IGNsYXNzMnR5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBmblRvU3RyaW5nID0gaGFzT3duLnRvU3RyaW5nO1xuXG52YXIgT2JqZWN0RnVuY3Rpb25TdHJpbmcgPSBmblRvU3RyaW5nLmNhbGwoIE9iamVjdCApO1xuXG52YXIgc3VwcG9ydCA9IHt9O1xuXG52YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIGlzRnVuY3Rpb24oIG9iaiApIHtcblxuICAgICAgLy8gU3VwcG9ydDogQ2hyb21lIDw9NTcsIEZpcmVmb3ggPD01MlxuICAgICAgLy8gSW4gc29tZSBicm93c2VycywgdHlwZW9mIHJldHVybnMgXCJmdW5jdGlvblwiIGZvciBIVE1MIDxvYmplY3Q+IGVsZW1lbnRzXG4gICAgICAvLyAoaS5lLiwgYHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9iamVjdFwiICkgPT09IFwiZnVuY3Rpb25cImApLlxuICAgICAgLy8gV2UgZG9uJ3Qgd2FudCB0byBjbGFzc2lmeSAqYW55KiBET00gbm9kZSBhcyBhIGZ1bmN0aW9uLlxuICAgICAgcmV0dXJuIHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2Ygb2JqLm5vZGVUeXBlICE9PSBcIm51bWJlclwiO1xuICB9O1xuXG5cbnZhciBpc1dpbmRvdyA9IGZ1bmN0aW9uIGlzV2luZG93KCBvYmogKSB7XG5cdFx0cmV0dXJuIG9iaiAhPSBudWxsICYmIG9iaiA9PT0gb2JqLndpbmRvdztcblx0fTtcblxuXG52YXIgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7XG5cblxuXG5cdHZhciBwcmVzZXJ2ZWRTY3JpcHRBdHRyaWJ1dGVzID0ge1xuXHRcdHR5cGU6IHRydWUsXG5cdFx0c3JjOiB0cnVlLFxuXHRcdG5vbmNlOiB0cnVlLFxuXHRcdG5vTW9kdWxlOiB0cnVlXG5cdH07XG5cblx0ZnVuY3Rpb24gRE9NRXZhbCggY29kZSwgbm9kZSwgZG9jICkge1xuXHRcdGRvYyA9IGRvYyB8fCBkb2N1bWVudDtcblxuXHRcdHZhciBpLCB2YWwsXG5cdFx0XHRzY3JpcHQgPSBkb2MuY3JlYXRlRWxlbWVudCggXCJzY3JpcHRcIiApO1xuXG5cdFx0c2NyaXB0LnRleHQgPSBjb2RlO1xuXHRcdGlmICggbm9kZSApIHtcblx0XHRcdGZvciAoIGkgaW4gcHJlc2VydmVkU2NyaXB0QXR0cmlidXRlcyApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDY0KywgRWRnZSAxOCtcblx0XHRcdFx0Ly8gU29tZSBicm93c2VycyBkb24ndCBzdXBwb3J0IHRoZSBcIm5vbmNlXCIgcHJvcGVydHkgb24gc2NyaXB0cy5cblx0XHRcdFx0Ly8gT24gdGhlIG90aGVyIGhhbmQsIGp1c3QgdXNpbmcgYGdldEF0dHJpYnV0ZWAgaXMgbm90IGVub3VnaCBhc1xuXHRcdFx0XHQvLyB0aGUgYG5vbmNlYCBhdHRyaWJ1dGUgaXMgcmVzZXQgdG8gYW4gZW1wdHkgc3RyaW5nIHdoZW5ldmVyIGl0XG5cdFx0XHRcdC8vIGJlY29tZXMgYnJvd3NpbmctY29udGV4dCBjb25uZWN0ZWQuXG5cdFx0XHRcdC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vd2hhdHdnL2h0bWwvaXNzdWVzLzIzNjlcblx0XHRcdFx0Ly8gU2VlIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI25vbmNlLWF0dHJpYnV0ZXNcblx0XHRcdFx0Ly8gVGhlIGBub2RlLmdldEF0dHJpYnV0ZWAgY2hlY2sgd2FzIGFkZGVkIGZvciB0aGUgc2FrZSBvZlxuXHRcdFx0XHQvLyBgalF1ZXJ5Lmdsb2JhbEV2YWxgIHNvIHRoYXQgaXQgY2FuIGZha2UgYSBub25jZS1jb250YWluaW5nIG5vZGVcblx0XHRcdFx0Ly8gdmlhIGFuIG9iamVjdC5cblx0XHRcdFx0dmFsID0gbm9kZVsgaSBdIHx8IG5vZGUuZ2V0QXR0cmlidXRlICYmIG5vZGUuZ2V0QXR0cmlidXRlKCBpICk7XG5cdFx0XHRcdGlmICggdmFsICkge1xuXHRcdFx0XHRcdHNjcmlwdC5zZXRBdHRyaWJ1dGUoIGksIHZhbCApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGRvYy5oZWFkLmFwcGVuZENoaWxkKCBzY3JpcHQgKS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBzY3JpcHQgKTtcblx0fVxuXG5cbmZ1bmN0aW9uIHRvVHlwZSggb2JqICkge1xuXHRpZiAoIG9iaiA9PSBudWxsICkge1xuXHRcdHJldHVybiBvYmogKyBcIlwiO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTIuMyBvbmx5IChmdW5jdGlvbmlzaCBSZWdFeHApXG5cdHJldHVybiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiA/XG5cdFx0Y2xhc3MydHlwZVsgdG9TdHJpbmcuY2FsbCggb2JqICkgXSB8fCBcIm9iamVjdFwiIDpcblx0XHR0eXBlb2Ygb2JqO1xufVxuLyogZ2xvYmFsIFN5bWJvbCAqL1xuLy8gRGVmaW5pbmcgdGhpcyBnbG9iYWwgaW4gLmVzbGludHJjLmpzb24gd291bGQgY3JlYXRlIGEgZGFuZ2VyIG9mIHVzaW5nIHRoZSBnbG9iYWxcbi8vIHVuZ3VhcmRlZCBpbiBhbm90aGVyIHBsYWNlLCBpdCBzZWVtcyBzYWZlciB0byBkZWZpbmUgZ2xvYmFsIG9ubHkgZm9yIHRoaXMgbW9kdWxlXG5cblxuXG52YXJcblx0dmVyc2lvbiA9IFwiMy41LjFcIixcblxuXHQvLyBEZWZpbmUgYSBsb2NhbCBjb3B5IG9mIGpRdWVyeVxuXHRqUXVlcnkgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cblx0XHQvLyBUaGUgalF1ZXJ5IG9iamVjdCBpcyBhY3R1YWxseSBqdXN0IHRoZSBpbml0IGNvbnN0cnVjdG9yICdlbmhhbmNlZCdcblx0XHQvLyBOZWVkIGluaXQgaWYgalF1ZXJ5IGlzIGNhbGxlZCAoanVzdCBhbGxvdyBlcnJvciB0byBiZSB0aHJvd24gaWYgbm90IGluY2x1ZGVkKVxuXHRcdHJldHVybiBuZXcgalF1ZXJ5LmZuLmluaXQoIHNlbGVjdG9yLCBjb250ZXh0ICk7XG5cdH07XG5cbmpRdWVyeS5mbiA9IGpRdWVyeS5wcm90b3R5cGUgPSB7XG5cblx0Ly8gVGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBqUXVlcnkgYmVpbmcgdXNlZFxuXHRqcXVlcnk6IHZlcnNpb24sXG5cblx0Y29uc3RydWN0b3I6IGpRdWVyeSxcblxuXHQvLyBUaGUgZGVmYXVsdCBsZW5ndGggb2YgYSBqUXVlcnkgb2JqZWN0IGlzIDBcblx0bGVuZ3RoOiAwLFxuXG5cdHRvQXJyYXk6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7XG5cdH0sXG5cblx0Ly8gR2V0IHRoZSBOdGggZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBlbGVtZW50IHNldCBPUlxuXHQvLyBHZXQgdGhlIHdob2xlIG1hdGNoZWQgZWxlbWVudCBzZXQgYXMgYSBjbGVhbiBhcnJheVxuXHRnZXQ6IGZ1bmN0aW9uKCBudW0gKSB7XG5cblx0XHQvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyBpbiBhIGNsZWFuIGFycmF5XG5cdFx0aWYgKCBudW0gPT0gbnVsbCApIHtcblx0XHRcdHJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIGp1c3QgdGhlIG9uZSBlbGVtZW50IGZyb20gdGhlIHNldFxuXHRcdHJldHVybiBudW0gPCAwID8gdGhpc1sgbnVtICsgdGhpcy5sZW5ndGggXSA6IHRoaXNbIG51bSBdO1xuXHR9LFxuXG5cdC8vIFRha2UgYW4gYXJyYXkgb2YgZWxlbWVudHMgYW5kIHB1c2ggaXQgb250byB0aGUgc3RhY2tcblx0Ly8gKHJldHVybmluZyB0aGUgbmV3IG1hdGNoZWQgZWxlbWVudCBzZXQpXG5cdHB1c2hTdGFjazogZnVuY3Rpb24oIGVsZW1zICkge1xuXG5cdFx0Ly8gQnVpbGQgYSBuZXcgalF1ZXJ5IG1hdGNoZWQgZWxlbWVudCBzZXRcblx0XHR2YXIgcmV0ID0galF1ZXJ5Lm1lcmdlKCB0aGlzLmNvbnN0cnVjdG9yKCksIGVsZW1zICk7XG5cblx0XHQvLyBBZGQgdGhlIG9sZCBvYmplY3Qgb250byB0aGUgc3RhY2sgKGFzIGEgcmVmZXJlbmNlKVxuXHRcdHJldC5wcmV2T2JqZWN0ID0gdGhpcztcblxuXHRcdC8vIFJldHVybiB0aGUgbmV3bHktZm9ybWVkIGVsZW1lbnQgc2V0XG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHQvLyBFeGVjdXRlIGEgY2FsbGJhY2sgZm9yIGV2ZXJ5IGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgc2V0LlxuXHRlYWNoOiBmdW5jdGlvbiggY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5lYWNoKCB0aGlzLCBjYWxsYmFjayApO1xuXHR9LFxuXG5cdG1hcDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5Lm1hcCggdGhpcywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gY2FsbGJhY2suY2FsbCggZWxlbSwgaSwgZWxlbSApO1xuXHRcdH0gKSApO1xuXHR9LFxuXG5cdHNsaWNlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHNsaWNlLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSApO1xuXHR9LFxuXG5cdGZpcnN0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lcSggMCApO1xuXHR9LFxuXG5cdGxhc3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVxKCAtMSApO1xuXHR9LFxuXG5cdGV2ZW46IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5LmdyZXAoIHRoaXMsIGZ1bmN0aW9uKCBfZWxlbSwgaSApIHtcblx0XHRcdHJldHVybiAoIGkgKyAxICkgJSAyO1xuXHRcdH0gKSApO1xuXHR9LFxuXG5cdG9kZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkuZ3JlcCggdGhpcywgZnVuY3Rpb24oIF9lbGVtLCBpICkge1xuXHRcdFx0cmV0dXJuIGkgJSAyO1xuXHRcdH0gKSApO1xuXHR9LFxuXG5cdGVxOiBmdW5jdGlvbiggaSApIHtcblx0XHR2YXIgbGVuID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRqID0gK2kgKyAoIGkgPCAwID8gbGVuIDogMCApO1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggaiA+PSAwICYmIGogPCBsZW4gPyBbIHRoaXNbIGogXSBdIDogW10gKTtcblx0fSxcblxuXHRlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnByZXZPYmplY3QgfHwgdGhpcy5jb25zdHJ1Y3RvcigpO1xuXHR9LFxuXG5cdC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seS5cblx0Ly8gQmVoYXZlcyBsaWtlIGFuIEFycmF5J3MgbWV0aG9kLCBub3QgbGlrZSBhIGpRdWVyeSBtZXRob2QuXG5cdHB1c2g6IHB1c2gsXG5cdHNvcnQ6IGFyci5zb3J0LFxuXHRzcGxpY2U6IGFyci5zcGxpY2Vcbn07XG5cbmpRdWVyeS5leHRlbmQgPSBqUXVlcnkuZm4uZXh0ZW5kID0gZnVuY3Rpb24oKSB7XG5cdHZhciBvcHRpb25zLCBuYW1lLCBzcmMsIGNvcHksIGNvcHlJc0FycmF5LCBjbG9uZSxcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbIDAgXSB8fCB7fSxcblx0XHRpID0gMSxcblx0XHRsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuXHRcdGRlZXAgPSBmYWxzZTtcblxuXHQvLyBIYW5kbGUgYSBkZWVwIGNvcHkgc2l0dWF0aW9uXG5cdGlmICggdHlwZW9mIHRhcmdldCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0ZGVlcCA9IHRhcmdldDtcblxuXHRcdC8vIFNraXAgdGhlIGJvb2xlYW4gYW5kIHRoZSB0YXJnZXRcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbIGkgXSB8fCB7fTtcblx0XHRpKys7XG5cdH1cblxuXHQvLyBIYW5kbGUgY2FzZSB3aGVuIHRhcmdldCBpcyBhIHN0cmluZyBvciBzb21ldGhpbmcgKHBvc3NpYmxlIGluIGRlZXAgY29weSlcblx0aWYgKCB0eXBlb2YgdGFyZ2V0ICE9PSBcIm9iamVjdFwiICYmICFpc0Z1bmN0aW9uKCB0YXJnZXQgKSApIHtcblx0XHR0YXJnZXQgPSB7fTtcblx0fVxuXG5cdC8vIEV4dGVuZCBqUXVlcnkgaXRzZWxmIGlmIG9ubHkgb25lIGFyZ3VtZW50IGlzIHBhc3NlZFxuXHRpZiAoIGkgPT09IGxlbmd0aCApIHtcblx0XHR0YXJnZXQgPSB0aGlzO1xuXHRcdGktLTtcblx0fVxuXG5cdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXG5cdFx0Ly8gT25seSBkZWFsIHdpdGggbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlc1xuXHRcdGlmICggKCBvcHRpb25zID0gYXJndW1lbnRzWyBpIF0gKSAhPSBudWxsICkge1xuXG5cdFx0XHQvLyBFeHRlbmQgdGhlIGJhc2Ugb2JqZWN0XG5cdFx0XHRmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7XG5cdFx0XHRcdGNvcHkgPSBvcHRpb25zWyBuYW1lIF07XG5cblx0XHRcdFx0Ly8gUHJldmVudCBPYmplY3QucHJvdG90eXBlIHBvbGx1dGlvblxuXHRcdFx0XHQvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXG5cdFx0XHRcdGlmICggbmFtZSA9PT0gXCJfX3Byb3RvX19cIiB8fCB0YXJnZXQgPT09IGNvcHkgKSB7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBSZWN1cnNlIGlmIHdlJ3JlIG1lcmdpbmcgcGxhaW4gb2JqZWN0cyBvciBhcnJheXNcblx0XHRcdFx0aWYgKCBkZWVwICYmIGNvcHkgJiYgKCBqUXVlcnkuaXNQbGFpbk9iamVjdCggY29weSApIHx8XG5cdFx0XHRcdFx0KCBjb3B5SXNBcnJheSA9IEFycmF5LmlzQXJyYXkoIGNvcHkgKSApICkgKSB7XG5cdFx0XHRcdFx0c3JjID0gdGFyZ2V0WyBuYW1lIF07XG5cblx0XHRcdFx0XHQvLyBFbnN1cmUgcHJvcGVyIHR5cGUgZm9yIHRoZSBzb3VyY2UgdmFsdWVcblx0XHRcdFx0XHRpZiAoIGNvcHlJc0FycmF5ICYmICFBcnJheS5pc0FycmF5KCBzcmMgKSApIHtcblx0XHRcdFx0XHRcdGNsb25lID0gW107XG5cdFx0XHRcdFx0fSBlbHNlIGlmICggIWNvcHlJc0FycmF5ICYmICFqUXVlcnkuaXNQbGFpbk9iamVjdCggc3JjICkgKSB7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IHt9O1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IHNyYztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29weUlzQXJyYXkgPSBmYWxzZTtcblxuXHRcdFx0XHRcdC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxuXHRcdFx0XHRcdHRhcmdldFsgbmFtZSBdID0galF1ZXJ5LmV4dGVuZCggZGVlcCwgY2xvbmUsIGNvcHkgKTtcblxuXHRcdFx0XHQvLyBEb24ndCBicmluZyBpbiB1bmRlZmluZWQgdmFsdWVzXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGNvcHkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHR0YXJnZXRbIG5hbWUgXSA9IGNvcHk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIG1vZGlmaWVkIG9iamVjdFxuXHRyZXR1cm4gdGFyZ2V0O1xufTtcblxualF1ZXJ5LmV4dGVuZCgge1xuXG5cdC8vIFVuaXF1ZSBmb3IgZWFjaCBjb3B5IG9mIGpRdWVyeSBvbiB0aGUgcGFnZVxuXHRleHBhbmRvOiBcImpRdWVyeVwiICsgKCB2ZXJzaW9uICsgTWF0aC5yYW5kb20oKSApLnJlcGxhY2UoIC9cXEQvZywgXCJcIiApLFxuXG5cdC8vIEFzc3VtZSBqUXVlcnkgaXMgcmVhZHkgd2l0aG91dCB0aGUgcmVhZHkgbW9kdWxlXG5cdGlzUmVhZHk6IHRydWUsXG5cblx0ZXJyb3I6IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCBtc2cgKTtcblx0fSxcblxuXHRub29wOiBmdW5jdGlvbigpIHt9LFxuXG5cdGlzUGxhaW5PYmplY3Q6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0dmFyIHByb3RvLCBDdG9yO1xuXG5cdFx0Ly8gRGV0ZWN0IG9idmlvdXMgbmVnYXRpdmVzXG5cdFx0Ly8gVXNlIHRvU3RyaW5nIGluc3RlYWQgb2YgalF1ZXJ5LnR5cGUgdG8gY2F0Y2ggaG9zdCBvYmplY3RzXG5cdFx0aWYgKCAhb2JqIHx8IHRvU3RyaW5nLmNhbGwoIG9iaiApICE9PSBcIltvYmplY3QgT2JqZWN0XVwiICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHByb3RvID0gZ2V0UHJvdG8oIG9iaiApO1xuXG5cdFx0Ly8gT2JqZWN0cyB3aXRoIG5vIHByb3RvdHlwZSAoZS5nLiwgYE9iamVjdC5jcmVhdGUoIG51bGwgKWApIGFyZSBwbGFpblxuXHRcdGlmICggIXByb3RvICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gT2JqZWN0cyB3aXRoIHByb3RvdHlwZSBhcmUgcGxhaW4gaWZmIHRoZXkgd2VyZSBjb25zdHJ1Y3RlZCBieSBhIGdsb2JhbCBPYmplY3QgZnVuY3Rpb25cblx0XHRDdG9yID0gaGFzT3duLmNhbGwoIHByb3RvLCBcImNvbnN0cnVjdG9yXCIgKSAmJiBwcm90by5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gdHlwZW9mIEN0b3IgPT09IFwiZnVuY3Rpb25cIiAmJiBmblRvU3RyaW5nLmNhbGwoIEN0b3IgKSA9PT0gT2JqZWN0RnVuY3Rpb25TdHJpbmc7XG5cdH0sXG5cblx0aXNFbXB0eU9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcblx0XHR2YXIgbmFtZTtcblxuXHRcdGZvciAoIG5hbWUgaW4gb2JqICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHQvLyBFdmFsdWF0ZXMgYSBzY3JpcHQgaW4gYSBwcm92aWRlZCBjb250ZXh0OyBmYWxscyBiYWNrIHRvIHRoZSBnbG9iYWwgb25lXG5cdC8vIGlmIG5vdCBzcGVjaWZpZWQuXG5cdGdsb2JhbEV2YWw6IGZ1bmN0aW9uKCBjb2RlLCBvcHRpb25zLCBkb2MgKSB7XG5cdFx0RE9NRXZhbCggY29kZSwgeyBub25jZTogb3B0aW9ucyAmJiBvcHRpb25zLm5vbmNlIH0sIGRvYyApO1xuXHR9LFxuXG5cdGVhY2g6IGZ1bmN0aW9uKCBvYmosIGNhbGxiYWNrICkge1xuXHRcdHZhciBsZW5ndGgsIGkgPSAwO1xuXG5cdFx0aWYgKCBpc0FycmF5TGlrZSggb2JqICkgKSB7XG5cdFx0XHRsZW5ndGggPSBvYmoubGVuZ3RoO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAoIGkgaW4gb2JqICkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrLmNhbGwoIG9ialsgaSBdLCBpLCBvYmpbIGkgXSApID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBvYmo7XG5cdH0sXG5cblx0Ly8gcmVzdWx0cyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxuXHRtYWtlQXJyYXk6IGZ1bmN0aW9uKCBhcnIsIHJlc3VsdHMgKSB7XG5cdFx0dmFyIHJldCA9IHJlc3VsdHMgfHwgW107XG5cblx0XHRpZiAoIGFyciAhPSBudWxsICkge1xuXHRcdFx0aWYgKCBpc0FycmF5TGlrZSggT2JqZWN0KCBhcnIgKSApICkge1xuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIHJldCxcblx0XHRcdFx0XHR0eXBlb2YgYXJyID09PSBcInN0cmluZ1wiID9cblx0XHRcdFx0XHRbIGFyciBdIDogYXJyXG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmNhbGwoIHJldCwgYXJyICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHRpbkFycmF5OiBmdW5jdGlvbiggZWxlbSwgYXJyLCBpICkge1xuXHRcdHJldHVybiBhcnIgPT0gbnVsbCA/IC0xIDogaW5kZXhPZi5jYWxsKCBhcnIsIGVsZW0sIGkgKTtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRtZXJnZTogZnVuY3Rpb24oIGZpcnN0LCBzZWNvbmQgKSB7XG5cdFx0dmFyIGxlbiA9ICtzZWNvbmQubGVuZ3RoLFxuXHRcdFx0aiA9IDAsXG5cdFx0XHRpID0gZmlyc3QubGVuZ3RoO1xuXG5cdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XG5cdFx0XHRmaXJzdFsgaSsrIF0gPSBzZWNvbmRbIGogXTtcblx0XHR9XG5cblx0XHRmaXJzdC5sZW5ndGggPSBpO1xuXG5cdFx0cmV0dXJuIGZpcnN0O1xuXHR9LFxuXG5cdGdyZXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGludmVydCApIHtcblx0XHR2YXIgY2FsbGJhY2tJbnZlcnNlLFxuXHRcdFx0bWF0Y2hlcyA9IFtdLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsZW5ndGggPSBlbGVtcy5sZW5ndGgsXG5cdFx0XHRjYWxsYmFja0V4cGVjdCA9ICFpbnZlcnQ7XG5cblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgb25seSBzYXZpbmcgdGhlIGl0ZW1zXG5cdFx0Ly8gdGhhdCBwYXNzIHRoZSB2YWxpZGF0b3IgZnVuY3Rpb25cblx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdGNhbGxiYWNrSW52ZXJzZSA9ICFjYWxsYmFjayggZWxlbXNbIGkgXSwgaSApO1xuXHRcdFx0aWYgKCBjYWxsYmFja0ludmVyc2UgIT09IGNhbGxiYWNrRXhwZWN0ICkge1xuXHRcdFx0XHRtYXRjaGVzLnB1c2goIGVsZW1zWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gbWF0Y2hlcztcblx0fSxcblxuXHQvLyBhcmcgaXMgZm9yIGludGVybmFsIHVzYWdlIG9ubHlcblx0bWFwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrLCBhcmcgKSB7XG5cdFx0dmFyIGxlbmd0aCwgdmFsdWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdHJldCA9IFtdO1xuXG5cdFx0Ly8gR28gdGhyb3VnaCB0aGUgYXJyYXksIHRyYW5zbGF0aW5nIGVhY2ggb2YgdGhlIGl0ZW1zIHRvIHRoZWlyIG5ldyB2YWx1ZXNcblx0XHRpZiAoIGlzQXJyYXlMaWtlKCBlbGVtcyApICkge1xuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdHZhbHVlID0gY2FsbGJhY2soIGVsZW1zWyBpIF0sIGksIGFyZyApO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXQucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0Ly8gR28gdGhyb3VnaCBldmVyeSBrZXkgb24gdGhlIG9iamVjdCxcblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICggaSBpbiBlbGVtcyApIHtcblx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjayggZWxlbXNbIGkgXSwgaSwgYXJnICk7XG5cblx0XHRcdFx0aWYgKCB2YWx1ZSAhPSBudWxsICkge1xuXHRcdFx0XHRcdHJldC5wdXNoKCB2YWx1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRcdHJldHVybiBmbGF0KCByZXQgKTtcblx0fSxcblxuXHQvLyBBIGdsb2JhbCBHVUlEIGNvdW50ZXIgZm9yIG9iamVjdHNcblx0Z3VpZDogMSxcblxuXHQvLyBqUXVlcnkuc3VwcG9ydCBpcyBub3QgdXNlZCBpbiBDb3JlIGJ1dCBvdGhlciBwcm9qZWN0cyBhdHRhY2ggdGhlaXJcblx0Ly8gcHJvcGVydGllcyB0byBpdCBzbyBpdCBuZWVkcyB0byBleGlzdC5cblx0c3VwcG9ydDogc3VwcG9ydFxufSApO1xuXG5pZiAoIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiApIHtcblx0alF1ZXJ5LmZuWyBTeW1ib2wuaXRlcmF0b3IgXSA9IGFyclsgU3ltYm9sLml0ZXJhdG9yIF07XG59XG5cbi8vIFBvcHVsYXRlIHRoZSBjbGFzczJ0eXBlIG1hcFxualF1ZXJ5LmVhY2goIFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2xcIi5zcGxpdCggXCIgXCIgKSxcbmZ1bmN0aW9uKCBfaSwgbmFtZSApIHtcblx0Y2xhc3MydHlwZVsgXCJbb2JqZWN0IFwiICsgbmFtZSArIFwiXVwiIF0gPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG59ICk7XG5cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKCBvYmogKSB7XG5cblx0Ly8gU3VwcG9ydDogcmVhbCBpT1MgOC4yIG9ubHkgKG5vdCByZXByb2R1Y2libGUgaW4gc2ltdWxhdG9yKVxuXHQvLyBgaW5gIGNoZWNrIHVzZWQgdG8gcHJldmVudCBKSVQgZXJyb3IgKGdoLTIxNDUpXG5cdC8vIGhhc093biBpc24ndCB1c2VkIGhlcmUgZHVlIHRvIGZhbHNlIG5lZ2F0aXZlc1xuXHQvLyByZWdhcmRpbmcgTm9kZWxpc3QgbGVuZ3RoIGluIElFXG5cdHZhciBsZW5ndGggPSAhIW9iaiAmJiBcImxlbmd0aFwiIGluIG9iaiAmJiBvYmoubGVuZ3RoLFxuXHRcdHR5cGUgPSB0b1R5cGUoIG9iaiApO1xuXG5cdGlmICggaXNGdW5jdGlvbiggb2JqICkgfHwgaXNXaW5kb3coIG9iaiApICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0eXBlID09PSBcImFycmF5XCIgfHwgbGVuZ3RoID09PSAwIHx8XG5cdFx0dHlwZW9mIGxlbmd0aCA9PT0gXCJudW1iZXJcIiAmJiBsZW5ndGggPiAwICYmICggbGVuZ3RoIC0gMSApIGluIG9iajtcbn1cbnZhciBTaXp6bGUgPVxuLyohXG4gKiBTaXp6bGUgQ1NTIFNlbGVjdG9yIEVuZ2luZSB2Mi4zLjVcbiAqIGh0dHBzOi8vc2l6emxlanMuY29tL1xuICpcbiAqIENvcHlyaWdodCBKUyBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cHM6Ly9qcy5mb3VuZGF0aW9uL1xuICpcbiAqIERhdGU6IDIwMjAtMDMtMTRcbiAqL1xuKCBmdW5jdGlvbiggd2luZG93ICkge1xudmFyIGksXG5cdHN1cHBvcnQsXG5cdEV4cHIsXG5cdGdldFRleHQsXG5cdGlzWE1MLFxuXHR0b2tlbml6ZSxcblx0Y29tcGlsZSxcblx0c2VsZWN0LFxuXHRvdXRlcm1vc3RDb250ZXh0LFxuXHRzb3J0SW5wdXQsXG5cdGhhc0R1cGxpY2F0ZSxcblxuXHQvLyBMb2NhbCBkb2N1bWVudCB2YXJzXG5cdHNldERvY3VtZW50LFxuXHRkb2N1bWVudCxcblx0ZG9jRWxlbSxcblx0ZG9jdW1lbnRJc0hUTUwsXG5cdHJidWdneVFTQSxcblx0cmJ1Z2d5TWF0Y2hlcyxcblx0bWF0Y2hlcyxcblx0Y29udGFpbnMsXG5cblx0Ly8gSW5zdGFuY2Utc3BlY2lmaWMgZGF0YVxuXHRleHBhbmRvID0gXCJzaXp6bGVcIiArIDEgKiBuZXcgRGF0ZSgpLFxuXHRwcmVmZXJyZWREb2MgPSB3aW5kb3cuZG9jdW1lbnQsXG5cdGRpcnJ1bnMgPSAwLFxuXHRkb25lID0gMCxcblx0Y2xhc3NDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHRva2VuQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRjb21waWxlckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0bm9ubmF0aXZlU2VsZWN0b3JDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHNvcnRPcmRlciA9IGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9LFxuXG5cdC8vIEluc3RhbmNlIG1ldGhvZHNcblx0aGFzT3duID0gKCB7fSApLmhhc093blByb3BlcnR5LFxuXHRhcnIgPSBbXSxcblx0cG9wID0gYXJyLnBvcCxcblx0cHVzaE5hdGl2ZSA9IGFyci5wdXNoLFxuXHRwdXNoID0gYXJyLnB1c2gsXG5cdHNsaWNlID0gYXJyLnNsaWNlLFxuXG5cdC8vIFVzZSBhIHN0cmlwcGVkLWRvd24gaW5kZXhPZiBhcyBpdCdzIGZhc3RlciB0aGFuIG5hdGl2ZVxuXHQvLyBodHRwczovL2pzcGVyZi5jb20vdGhvci1pbmRleG9mLXZzLWZvci81XG5cdGluZGV4T2YgPSBmdW5jdGlvbiggbGlzdCwgZWxlbSApIHtcblx0XHR2YXIgaSA9IDAsXG5cdFx0XHRsZW4gPSBsaXN0Lmxlbmd0aDtcblx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGlmICggbGlzdFsgaSBdID09PSBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIC0xO1xuXHR9LFxuXG5cdGJvb2xlYW5zID0gXCJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58XCIgK1xuXHRcdFwiaXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZFwiLFxuXG5cdC8vIFJlZ3VsYXIgZXhwcmVzc2lvbnNcblxuXHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLXNlbGVjdG9ycy8jd2hpdGVzcGFjZVxuXHR3aGl0ZXNwYWNlID0gXCJbXFxcXHgyMFxcXFx0XFxcXHJcXFxcblxcXFxmXVwiLFxuXG5cdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9jc3Mtc3ludGF4LTMvI2lkZW50LXRva2VuLWRpYWdyYW1cblx0aWRlbnRpZmllciA9IFwiKD86XFxcXFxcXFxbXFxcXGRhLWZBLUZdezEsNn1cIiArIHdoaXRlc3BhY2UgK1xuXHRcdFwiP3xcXFxcXFxcXFteXFxcXHJcXFxcblxcXFxmXXxbXFxcXHctXXxbXlxcMC1cXFxceDdmXSkrXCIsXG5cblx0Ly8gQXR0cmlidXRlIHNlbGVjdG9yczogaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzXG5cdGF0dHJpYnV0ZXMgPSBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFwiICsgaWRlbnRpZmllciArIFwiKSg/OlwiICsgd2hpdGVzcGFjZSArXG5cblx0XHQvLyBPcGVyYXRvciAoY2FwdHVyZSAyKVxuXHRcdFwiKihbKl4kfCF+XT89KVwiICsgd2hpdGVzcGFjZSArXG5cblx0XHQvLyBcIkF0dHJpYnV0ZSB2YWx1ZXMgbXVzdCBiZSBDU1MgaWRlbnRpZmllcnMgW2NhcHR1cmUgNV1cblx0XHQvLyBvciBzdHJpbmdzIFtjYXB0dXJlIDMgb3IgY2FwdHVyZSA0XVwiXG5cdFx0XCIqKD86JygoPzpcXFxcXFxcXC58W15cXFxcXFxcXCddKSopJ3xcXFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcXFxcIl0pKilcXFwifChcIiArIGlkZW50aWZpZXIgKyBcIikpfClcIiArXG5cdFx0d2hpdGVzcGFjZSArIFwiKlxcXFxdXCIsXG5cblx0cHNldWRvcyA9IFwiOihcIiArIGlkZW50aWZpZXIgKyBcIikoPzpcXFxcKChcIiArXG5cblx0XHQvLyBUbyByZWR1Y2UgdGhlIG51bWJlciBvZiBzZWxlY3RvcnMgbmVlZGluZyB0b2tlbml6ZSBpbiB0aGUgcHJlRmlsdGVyLCBwcmVmZXIgYXJndW1lbnRzOlxuXHRcdC8vIDEuIHF1b3RlZCAoY2FwdHVyZSAzOyBjYXB0dXJlIDQgb3IgY2FwdHVyZSA1KVxuXHRcdFwiKCcoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcIil8XCIgK1xuXG5cdFx0Ly8gMi4gc2ltcGxlIChjYXB0dXJlIDYpXG5cdFx0XCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFwoKVtcXFxcXV18XCIgKyBhdHRyaWJ1dGVzICsgXCIpKil8XCIgK1xuXG5cdFx0Ly8gMy4gYW55dGhpbmcgZWxzZSAoY2FwdHVyZSAyKVxuXHRcdFwiLipcIiArXG5cdFx0XCIpXFxcXCl8KVwiLFxuXG5cdC8vIExlYWRpbmcgYW5kIG5vbi1lc2NhcGVkIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGNhcHR1cmluZyBzb21lIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcnMgcHJlY2VkaW5nIHRoZSBsYXR0ZXJcblx0cndoaXRlc3BhY2UgPSBuZXcgUmVnRXhwKCB3aGl0ZXNwYWNlICsgXCIrXCIsIFwiZ1wiICksXG5cdHJ0cmltID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIrfCgoPzpefFteXFxcXFxcXFxdKSg/OlxcXFxcXFxcLikqKVwiICtcblx0XHR3aGl0ZXNwYWNlICsgXCIrJFwiLCBcImdcIiApLFxuXG5cdHJjb21tYSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKixcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxuXHRyY29tYmluYXRvcnMgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiooWz4rfl18XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcIipcIiApLFxuXHRyZGVzY2VuZCA9IG5ldyBSZWdFeHAoIHdoaXRlc3BhY2UgKyBcInw+XCIgKSxcblxuXHRycHNldWRvID0gbmV3IFJlZ0V4cCggcHNldWRvcyApLFxuXHRyaWRlbnRpZmllciA9IG5ldyBSZWdFeHAoIFwiXlwiICsgaWRlbnRpZmllciArIFwiJFwiICksXG5cblx0bWF0Y2hFeHByID0ge1xuXHRcdFwiSURcIjogbmV3IFJlZ0V4cCggXCJeIyhcIiArIGlkZW50aWZpZXIgKyBcIilcIiApLFxuXHRcdFwiQ0xBU1NcIjogbmV3IFJlZ0V4cCggXCJeXFxcXC4oXCIgKyBpZGVudGlmaWVyICsgXCIpXCIgKSxcblx0XHRcIlRBR1wiOiBuZXcgUmVnRXhwKCBcIl4oXCIgKyBpZGVudGlmaWVyICsgXCJ8WypdKVwiICksXG5cdFx0XCJBVFRSXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgYXR0cmlidXRlcyApLFxuXHRcdFwiUFNFVURPXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgcHNldWRvcyApLFxuXHRcdFwiQ0hJTERcIjogbmV3IFJlZ0V4cCggXCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXFxcKFwiICtcblx0XHRcdHdoaXRlc3BhY2UgKyBcIiooZXZlbnxvZGR8KChbKy1dfCkoXFxcXGQqKW58KVwiICsgd2hpdGVzcGFjZSArIFwiKig/OihbKy1dfClcIiArXG5cdFx0XHR3aGl0ZXNwYWNlICsgXCIqKFxcXFxkKyl8KSlcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpXCIsIFwiaVwiICksXG5cdFx0XCJib29sXCI6IG5ldyBSZWdFeHAoIFwiXig/OlwiICsgYm9vbGVhbnMgKyBcIikkXCIsIFwiaVwiICksXG5cblx0XHQvLyBGb3IgdXNlIGluIGxpYnJhcmllcyBpbXBsZW1lbnRpbmcgLmlzKClcblx0XHQvLyBXZSB1c2UgdGhpcyBmb3IgUE9TIG1hdGNoaW5nIGluIGBzZWxlY3RgXG5cdFx0XCJuZWVkc0NvbnRleHRcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFwiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFxcXChcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFx0XCIqKCg/Oi1cXFxcZCk/XFxcXGQqKVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFwpfCkoPz1bXi1dfCQpXCIsIFwiaVwiIClcblx0fSxcblxuXHRyaHRtbCA9IC9IVE1MJC9pLFxuXHRyaW5wdXRzID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxcblx0cmhlYWRlciA9IC9eaFxcZCQvaSxcblxuXHRybmF0aXZlID0gL15bXntdK1xce1xccypcXFtuYXRpdmUgXFx3LyxcblxuXHQvLyBFYXNpbHktcGFyc2VhYmxlL3JldHJpZXZhYmxlIElEIG9yIFRBRyBvciBDTEFTUyBzZWxlY3RvcnNcblx0cnF1aWNrRXhwciA9IC9eKD86IyhbXFx3LV0rKXwoXFx3Kyl8XFwuKFtcXHctXSspKSQvLFxuXG5cdHJzaWJsaW5nID0gL1srfl0vLFxuXG5cdC8vIENTUyBlc2NhcGVzXG5cdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCNlc2NhcGVkLWNoYXJhY3RlcnNcblx0cnVuZXNjYXBlID0gbmV3IFJlZ0V4cCggXCJcXFxcXFxcXFtcXFxcZGEtZkEtRl17MSw2fVwiICsgd2hpdGVzcGFjZSArIFwiP3xcXFxcXFxcXChbXlxcXFxyXFxcXG5cXFxcZl0pXCIsIFwiZ1wiICksXG5cdGZ1bmVzY2FwZSA9IGZ1bmN0aW9uKCBlc2NhcGUsIG5vbkhleCApIHtcblx0XHR2YXIgaGlnaCA9IFwiMHhcIiArIGVzY2FwZS5zbGljZSggMSApIC0gMHgxMDAwMDtcblxuXHRcdHJldHVybiBub25IZXggP1xuXG5cdFx0XHQvLyBTdHJpcCB0aGUgYmFja3NsYXNoIHByZWZpeCBmcm9tIGEgbm9uLWhleCBlc2NhcGUgc2VxdWVuY2Vcblx0XHRcdG5vbkhleCA6XG5cblx0XHRcdC8vIFJlcGxhY2UgYSBoZXhhZGVjaW1hbCBlc2NhcGUgc2VxdWVuY2Ugd2l0aCB0aGUgZW5jb2RlZCBVbmljb2RlIGNvZGUgcG9pbnRcblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9MTErXG5cdFx0XHQvLyBGb3IgdmFsdWVzIG91dHNpZGUgdGhlIEJhc2ljIE11bHRpbGluZ3VhbCBQbGFuZSAoQk1QKSwgbWFudWFsbHkgY29uc3RydWN0IGFcblx0XHRcdC8vIHN1cnJvZ2F0ZSBwYWlyXG5cdFx0XHRoaWdoIDwgMCA/XG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggKyAweDEwMDAwICkgOlxuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoID4+IDEwIHwgMHhEODAwLCBoaWdoICYgMHgzRkYgfCAweERDMDAgKTtcblx0fSxcblxuXHQvLyBDU1Mgc3RyaW5nL2lkZW50aWZpZXIgc2VyaWFsaXphdGlvblxuXHQvLyBodHRwczovL2RyYWZ0cy5jc3N3Zy5vcmcvY3Nzb20vI2NvbW1vbi1zZXJpYWxpemluZy1pZGlvbXNcblx0cmNzc2VzY2FwZSA9IC8oW1xcMC1cXHgxZlxceDdmXXxeLT9cXGQpfF4tJHxbXlxcMC1cXHgxZlxceDdmLVxcdUZGRkZcXHctXS9nLFxuXHRmY3NzZXNjYXBlID0gZnVuY3Rpb24oIGNoLCBhc0NvZGVQb2ludCApIHtcblx0XHRpZiAoIGFzQ29kZVBvaW50ICkge1xuXG5cdFx0XHQvLyBVKzAwMDAgTlVMTCBiZWNvbWVzIFUrRkZGRCBSRVBMQUNFTUVOVCBDSEFSQUNURVJcblx0XHRcdGlmICggY2ggPT09IFwiXFwwXCIgKSB7XG5cdFx0XHRcdHJldHVybiBcIlxcdUZGRkRcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udHJvbCBjaGFyYWN0ZXJzIGFuZCAoZGVwZW5kZW50IHVwb24gcG9zaXRpb24pIG51bWJlcnMgZ2V0IGVzY2FwZWQgYXMgY29kZSBwb2ludHNcblx0XHRcdHJldHVybiBjaC5zbGljZSggMCwgLTEgKSArIFwiXFxcXFwiICtcblx0XHRcdFx0Y2guY2hhckNvZGVBdCggY2gubGVuZ3RoIC0gMSApLnRvU3RyaW5nKCAxNiApICsgXCIgXCI7XG5cdFx0fVxuXG5cdFx0Ly8gT3RoZXIgcG90ZW50aWFsbHktc3BlY2lhbCBBU0NJSSBjaGFyYWN0ZXJzIGdldCBiYWNrc2xhc2gtZXNjYXBlZFxuXHRcdHJldHVybiBcIlxcXFxcIiArIGNoO1xuXHR9LFxuXG5cdC8vIFVzZWQgZm9yIGlmcmFtZXNcblx0Ly8gU2VlIHNldERvY3VtZW50KClcblx0Ly8gUmVtb3ZpbmcgdGhlIGZ1bmN0aW9uIHdyYXBwZXIgY2F1c2VzIGEgXCJQZXJtaXNzaW9uIERlbmllZFwiXG5cdC8vIGVycm9yIGluIElFXG5cdHVubG9hZEhhbmRsZXIgPSBmdW5jdGlvbigpIHtcblx0XHRzZXREb2N1bWVudCgpO1xuXHR9LFxuXG5cdGluRGlzYWJsZWRGaWVsZHNldCA9IGFkZENvbWJpbmF0b3IoXG5cdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gdHJ1ZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiZmllbGRzZXRcIjtcblx0XHR9LFxuXHRcdHsgZGlyOiBcInBhcmVudE5vZGVcIiwgbmV4dDogXCJsZWdlbmRcIiB9XG5cdCk7XG5cbi8vIE9wdGltaXplIGZvciBwdXNoLmFwcGx5KCBfLCBOb2RlTGlzdCApXG50cnkge1xuXHRwdXNoLmFwcGx5KFxuXHRcdCggYXJyID0gc2xpY2UuY2FsbCggcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMgKSApLFxuXHRcdHByZWZlcnJlZERvYy5jaGlsZE5vZGVzXG5cdCk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjBcblx0Ly8gRGV0ZWN0IHNpbGVudGx5IGZhaWxpbmcgcHVzaC5hcHBseVxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG5cdGFyclsgcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMubGVuZ3RoIF0ubm9kZVR5cGU7XG59IGNhdGNoICggZSApIHtcblx0cHVzaCA9IHsgYXBwbHk6IGFyci5sZW5ndGggP1xuXG5cdFx0Ly8gTGV2ZXJhZ2Ugc2xpY2UgaWYgcG9zc2libGVcblx0XHRmdW5jdGlvbiggdGFyZ2V0LCBlbHMgKSB7XG5cdFx0XHRwdXNoTmF0aXZlLmFwcGx5KCB0YXJnZXQsIHNsaWNlLmNhbGwoIGVscyApICk7XG5cdFx0fSA6XG5cblx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZCBkaXJlY3RseVxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcblx0XHRcdHZhciBqID0gdGFyZ2V0Lmxlbmd0aCxcblx0XHRcdFx0aSA9IDA7XG5cblx0XHRcdC8vIENhbid0IHRydXN0IE5vZGVMaXN0Lmxlbmd0aFxuXHRcdFx0d2hpbGUgKCAoIHRhcmdldFsgaisrIF0gPSBlbHNbIGkrKyBdICkgKSB7fVxuXHRcdFx0dGFyZ2V0Lmxlbmd0aCA9IGogLSAxO1xuXHRcdH1cblx0fTtcbn1cblxuZnVuY3Rpb24gU2l6emxlKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcblx0dmFyIG0sIGksIGVsZW0sIG5pZCwgbWF0Y2gsIGdyb3VwcywgbmV3U2VsZWN0b3IsXG5cdFx0bmV3Q29udGV4dCA9IGNvbnRleHQgJiYgY29udGV4dC5vd25lckRvY3VtZW50LFxuXG5cdFx0Ly8gbm9kZVR5cGUgZGVmYXVsdHMgdG8gOSwgc2luY2UgY29udGV4dCBkZWZhdWx0cyB0byBkb2N1bWVudFxuXHRcdG5vZGVUeXBlID0gY29udGV4dCA/IGNvbnRleHQubm9kZVR5cGUgOiA5O1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFJldHVybiBlYXJseSBmcm9tIGNhbGxzIHdpdGggaW52YWxpZCBzZWxlY3RvciBvciBjb250ZXh0XG5cdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiIHx8ICFzZWxlY3RvciB8fFxuXHRcdG5vZGVUeXBlICE9PSAxICYmIG5vZGVUeXBlICE9PSA5ICYmIG5vZGVUeXBlICE9PSAxMSApIHtcblxuXHRcdHJldHVybiByZXN1bHRzO1xuXHR9XG5cblx0Ly8gVHJ5IHRvIHNob3J0Y3V0IGZpbmQgb3BlcmF0aW9ucyAoYXMgb3Bwb3NlZCB0byBmaWx0ZXJzKSBpbiBIVE1MIGRvY3VtZW50c1xuXHRpZiAoICFzZWVkICkge1xuXHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdFx0Y29udGV4dCA9IGNvbnRleHQgfHwgZG9jdW1lbnQ7XG5cblx0XHRpZiAoIGRvY3VtZW50SXNIVE1MICkge1xuXG5cdFx0XHQvLyBJZiB0aGUgc2VsZWN0b3IgaXMgc3VmZmljaWVudGx5IHNpbXBsZSwgdHJ5IHVzaW5nIGEgXCJnZXQqQnkqXCIgRE9NIG1ldGhvZFxuXHRcdFx0Ly8gKGV4Y2VwdGluZyBEb2N1bWVudEZyYWdtZW50IGNvbnRleHQsIHdoZXJlIHRoZSBtZXRob2RzIGRvbid0IGV4aXN0KVxuXHRcdFx0aWYgKCBub2RlVHlwZSAhPT0gMTEgJiYgKCBtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKSApICkge1xuXG5cdFx0XHRcdC8vIElEIHNlbGVjdG9yXG5cdFx0XHRcdGlmICggKCBtID0gbWF0Y2hbIDEgXSApICkge1xuXG5cdFx0XHRcdFx0Ly8gRG9jdW1lbnQgY29udGV4dFxuXHRcdFx0XHRcdGlmICggbm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSApICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFLCBPcGVyYSwgV2Via2l0XG5cdFx0XHRcdFx0XHRcdC8vIFRPRE86IGlkZW50aWZ5IHZlcnNpb25zXG5cdFx0XHRcdFx0XHRcdC8vIGdldEVsZW1lbnRCeUlkIGNhbiBtYXRjaCBlbGVtZW50cyBieSBuYW1lIGluc3RlYWQgb2YgSURcblx0XHRcdFx0XHRcdFx0aWYgKCBlbGVtLmlkID09PSBtICkge1xuXHRcdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIEVsZW1lbnQgY29udGV4dFxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFLCBPcGVyYSwgV2Via2l0XG5cdFx0XHRcdFx0XHQvLyBUT0RPOiBpZGVudGlmeSB2ZXJzaW9uc1xuXHRcdFx0XHRcdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgY2FuIG1hdGNoIGVsZW1lbnRzIGJ5IG5hbWUgaW5zdGVhZCBvZiBJRFxuXHRcdFx0XHRcdFx0aWYgKCBuZXdDb250ZXh0ICYmICggZWxlbSA9IG5ld0NvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSApICYmXG5cdFx0XHRcdFx0XHRcdGNvbnRhaW5zKCBjb250ZXh0LCBlbGVtICkgJiZcblx0XHRcdFx0XHRcdFx0ZWxlbS5pZCA9PT0gbSApIHtcblxuXHRcdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFR5cGUgc2VsZWN0b3Jcblx0XHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbIDIgXSApIHtcblx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCBzZWxlY3RvciApICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cblx0XHRcdFx0Ly8gQ2xhc3Mgc2VsZWN0b3Jcblx0XHRcdFx0fSBlbHNlIGlmICggKCBtID0gbWF0Y2hbIDMgXSApICYmIHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJlxuXHRcdFx0XHRcdGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApIHtcblxuXHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggbSApICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gVGFrZSBhZHZhbnRhZ2Ugb2YgcXVlcnlTZWxlY3RvckFsbFxuXHRcdFx0aWYgKCBzdXBwb3J0LnFzYSAmJlxuXHRcdFx0XHQhbm9ubmF0aXZlU2VsZWN0b3JDYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdICYmXG5cdFx0XHRcdCggIXJidWdneVFTQSB8fCAhcmJ1Z2d5UVNBLnRlc3QoIHNlbGVjdG9yICkgKSAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDggb25seVxuXHRcdFx0XHQvLyBFeGNsdWRlIG9iamVjdCBlbGVtZW50c1xuXHRcdFx0XHQoIG5vZGVUeXBlICE9PSAxIHx8IGNvbnRleHQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPT0gXCJvYmplY3RcIiApICkge1xuXG5cdFx0XHRcdG5ld1NlbGVjdG9yID0gc2VsZWN0b3I7XG5cdFx0XHRcdG5ld0NvbnRleHQgPSBjb250ZXh0O1xuXG5cdFx0XHRcdC8vIHFTQSBjb25zaWRlcnMgZWxlbWVudHMgb3V0c2lkZSBhIHNjb3Bpbmcgcm9vdCB3aGVuIGV2YWx1YXRpbmcgY2hpbGQgb3Jcblx0XHRcdFx0Ly8gZGVzY2VuZGFudCBjb21iaW5hdG9ycywgd2hpY2ggaXMgbm90IHdoYXQgd2Ugd2FudC5cblx0XHRcdFx0Ly8gSW4gc3VjaCBjYXNlcywgd2Ugd29yayBhcm91bmQgdGhlIGJlaGF2aW9yIGJ5IHByZWZpeGluZyBldmVyeSBzZWxlY3RvciBpbiB0aGVcblx0XHRcdFx0Ly8gbGlzdCB3aXRoIGFuIElEIHNlbGVjdG9yIHJlZmVyZW5jaW5nIHRoZSBzY29wZSBjb250ZXh0LlxuXHRcdFx0XHQvLyBUaGUgdGVjaG5pcXVlIGhhcyB0byBiZSB1c2VkIGFzIHdlbGwgd2hlbiBhIGxlYWRpbmcgY29tYmluYXRvciBpcyB1c2VkXG5cdFx0XHRcdC8vIGFzIHN1Y2ggc2VsZWN0b3JzIGFyZSBub3QgcmVjb2duaXplZCBieSBxdWVyeVNlbGVjdG9yQWxsLlxuXHRcdFx0XHQvLyBUaGFua3MgdG8gQW5kcmV3IER1cG9udCBmb3IgdGhpcyB0ZWNobmlxdWUuXG5cdFx0XHRcdGlmICggbm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0XHQoIHJkZXNjZW5kLnRlc3QoIHNlbGVjdG9yICkgfHwgcmNvbWJpbmF0b3JzLnRlc3QoIHNlbGVjdG9yICkgKSApIHtcblxuXHRcdFx0XHRcdC8vIEV4cGFuZCBjb250ZXh0IGZvciBzaWJsaW5nIHNlbGVjdG9yc1xuXHRcdFx0XHRcdG5ld0NvbnRleHQgPSByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fFxuXHRcdFx0XHRcdFx0Y29udGV4dDtcblxuXHRcdFx0XHRcdC8vIFdlIGNhbiB1c2UgOnNjb3BlIGluc3RlYWQgb2YgdGhlIElEIGhhY2sgaWYgdGhlIGJyb3dzZXJcblx0XHRcdFx0XHQvLyBzdXBwb3J0cyBpdCAmIGlmIHdlJ3JlIG5vdCBjaGFuZ2luZyB0aGUgY29udGV4dC5cblx0XHRcdFx0XHRpZiAoIG5ld0NvbnRleHQgIT09IGNvbnRleHQgfHwgIXN1cHBvcnQuc2NvcGUgKSB7XG5cblx0XHRcdFx0XHRcdC8vIENhcHR1cmUgdGhlIGNvbnRleHQgSUQsIHNldHRpbmcgaXQgZmlyc3QgaWYgbmVjZXNzYXJ5XG5cdFx0XHRcdFx0XHRpZiAoICggbmlkID0gY29udGV4dC5nZXRBdHRyaWJ1dGUoIFwiaWRcIiApICkgKSB7XG5cdFx0XHRcdFx0XHRcdG5pZCA9IG5pZC5yZXBsYWNlKCByY3NzZXNjYXBlLCBmY3NzZXNjYXBlICk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRjb250ZXh0LnNldEF0dHJpYnV0ZSggXCJpZFwiLCAoIG5pZCA9IGV4cGFuZG8gKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFByZWZpeCBldmVyeSBzZWxlY3RvciBpbiB0aGUgbGlzdFxuXHRcdFx0XHRcdGdyb3VwcyA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXHRcdFx0XHRcdGkgPSBncm91cHMubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0Z3JvdXBzWyBpIF0gPSAoIG5pZCA/IFwiI1wiICsgbmlkIDogXCI6c2NvcGVcIiApICsgXCIgXCIgK1xuXHRcdFx0XHRcdFx0XHR0b1NlbGVjdG9yKCBncm91cHNbIGkgXSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRuZXdTZWxlY3RvciA9IGdyb3Vwcy5qb2luKCBcIixcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLFxuXHRcdFx0XHRcdFx0bmV3Q29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCBuZXdTZWxlY3RvciApXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0fSBjYXRjaCAoIHFzYUVycm9yICkge1xuXHRcdFx0XHRcdG5vbm5hdGl2ZVNlbGVjdG9yQ2FjaGUoIHNlbGVjdG9yLCB0cnVlICk7XG5cdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0aWYgKCBuaWQgPT09IGV4cGFuZG8gKSB7XG5cdFx0XHRcdFx0XHRjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZSggXCJpZFwiICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQWxsIG90aGVyc1xuXHRyZXR1cm4gc2VsZWN0KCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUga2V5LXZhbHVlIGNhY2hlcyBvZiBsaW1pdGVkIHNpemVcbiAqIEByZXR1cm5zIHtmdW5jdGlvbihzdHJpbmcsIG9iamVjdCl9IFJldHVybnMgdGhlIE9iamVjdCBkYXRhIGFmdGVyIHN0b3JpbmcgaXQgb24gaXRzZWxmIHdpdGhcbiAqXHRwcm9wZXJ0eSBuYW1lIHRoZSAoc3BhY2Utc3VmZml4ZWQpIHN0cmluZyBhbmQgKGlmIHRoZSBjYWNoZSBpcyBsYXJnZXIgdGhhbiBFeHByLmNhY2hlTGVuZ3RoKVxuICpcdGRlbGV0aW5nIHRoZSBvbGRlc3QgZW50cnlcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7XG5cdHZhciBrZXlzID0gW107XG5cblx0ZnVuY3Rpb24gY2FjaGUoIGtleSwgdmFsdWUgKSB7XG5cblx0XHQvLyBVc2UgKGtleSArIFwiIFwiKSB0byBhdm9pZCBjb2xsaXNpb24gd2l0aCBuYXRpdmUgcHJvdG90eXBlIHByb3BlcnRpZXMgKHNlZSBJc3N1ZSAjMTU3KVxuXHRcdGlmICgga2V5cy5wdXNoKCBrZXkgKyBcIiBcIiApID4gRXhwci5jYWNoZUxlbmd0aCApIHtcblxuXHRcdFx0Ly8gT25seSBrZWVwIHRoZSBtb3N0IHJlY2VudCBlbnRyaWVzXG5cdFx0XHRkZWxldGUgY2FjaGVbIGtleXMuc2hpZnQoKSBdO1xuXHRcdH1cblx0XHRyZXR1cm4gKCBjYWNoZVsga2V5ICsgXCIgXCIgXSA9IHZhbHVlICk7XG5cdH1cblx0cmV0dXJuIGNhY2hlO1xufVxuXG4vKipcbiAqIE1hcmsgYSBmdW5jdGlvbiBmb3Igc3BlY2lhbCB1c2UgYnkgU2l6emxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gbWFya1xuICovXG5mdW5jdGlvbiBtYXJrRnVuY3Rpb24oIGZuICkge1xuXHRmblsgZXhwYW5kbyBdID0gdHJ1ZTtcblx0cmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIFN1cHBvcnQgdGVzdGluZyB1c2luZyBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBQYXNzZWQgdGhlIGNyZWF0ZWQgZWxlbWVudCBhbmQgcmV0dXJucyBhIGJvb2xlYW4gcmVzdWx0XG4gKi9cbmZ1bmN0aW9uIGFzc2VydCggZm4gKSB7XG5cdHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZmllbGRzZXRcIiApO1xuXG5cdHRyeSB7XG5cdFx0cmV0dXJuICEhZm4oIGVsICk7XG5cdH0gY2F0Y2ggKCBlICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fSBmaW5hbGx5IHtcblxuXHRcdC8vIFJlbW92ZSBmcm9tIGl0cyBwYXJlbnQgYnkgZGVmYXVsdFxuXHRcdGlmICggZWwucGFyZW50Tm9kZSApIHtcblx0XHRcdGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGVsICk7XG5cdFx0fVxuXG5cdFx0Ly8gcmVsZWFzZSBtZW1vcnkgaW4gSUVcblx0XHRlbCA9IG51bGw7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIHRoZSBzYW1lIGhhbmRsZXIgZm9yIGFsbCBvZiB0aGUgc3BlY2lmaWVkIGF0dHJzXG4gKiBAcGFyYW0ge1N0cmluZ30gYXR0cnMgUGlwZS1zZXBhcmF0ZWQgbGlzdCBvZiBhdHRyaWJ1dGVzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyIFRoZSBtZXRob2QgdGhhdCB3aWxsIGJlIGFwcGxpZWRcbiAqL1xuZnVuY3Rpb24gYWRkSGFuZGxlKCBhdHRycywgaGFuZGxlciApIHtcblx0dmFyIGFyciA9IGF0dHJzLnNwbGl0KCBcInxcIiApLFxuXHRcdGkgPSBhcnIubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdEV4cHIuYXR0ckhhbmRsZVsgYXJyWyBpIF0gXSA9IGhhbmRsZXI7XG5cdH1cbn1cblxuLyoqXG4gKiBDaGVja3MgZG9jdW1lbnQgb3JkZXIgb2YgdHdvIHNpYmxpbmdzXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGFcbiAqIEBwYXJhbSB7RWxlbWVudH0gYlxuICogQHJldHVybnMge051bWJlcn0gUmV0dXJucyBsZXNzIHRoYW4gMCBpZiBhIHByZWNlZGVzIGIsIGdyZWF0ZXIgdGhhbiAwIGlmIGEgZm9sbG93cyBiXG4gKi9cbmZ1bmN0aW9uIHNpYmxpbmdDaGVjayggYSwgYiApIHtcblx0dmFyIGN1ciA9IGIgJiYgYSxcblx0XHRkaWZmID0gY3VyICYmIGEubm9kZVR5cGUgPT09IDEgJiYgYi5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0YS5zb3VyY2VJbmRleCAtIGIuc291cmNlSW5kZXg7XG5cblx0Ly8gVXNlIElFIHNvdXJjZUluZGV4IGlmIGF2YWlsYWJsZSBvbiBib3RoIG5vZGVzXG5cdGlmICggZGlmZiApIHtcblx0XHRyZXR1cm4gZGlmZjtcblx0fVxuXG5cdC8vIENoZWNrIGlmIGIgZm9sbG93cyBhXG5cdGlmICggY3VyICkge1xuXHRcdHdoaWxlICggKCBjdXIgPSBjdXIubmV4dFNpYmxpbmcgKSApIHtcblx0XHRcdGlmICggY3VyID09PSBiICkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGEgPyAxIDogLTE7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBpbnB1dCB0eXBlc1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5wdXRQc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gbmFtZSA9PT0gXCJpbnB1dFwiICYmIGVsZW0udHlwZSA9PT0gdHlwZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIGJ1dHRvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJ1dHRvblBzZXVkbyggdHlwZSApIHtcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdHJldHVybiAoIG5hbWUgPT09IFwiaW5wdXRcIiB8fCBuYW1lID09PSBcImJ1dHRvblwiICkgJiYgZWxlbS50eXBlID09PSB0eXBlO1xuXHR9O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgOmVuYWJsZWQvOmRpc2FibGVkXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRpc2FibGVkIHRydWUgZm9yIDpkaXNhYmxlZDsgZmFsc2UgZm9yIDplbmFibGVkXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZURpc2FibGVkUHNldWRvKCBkaXNhYmxlZCApIHtcblxuXHQvLyBLbm93biA6ZGlzYWJsZWQgZmFsc2UgcG9zaXRpdmVzOiBmaWVsZHNldFtkaXNhYmxlZF0gPiBsZWdlbmQ6bnRoLW9mLXR5cGUobisyKSA6Y2FuLWRpc2FibGVcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gT25seSBjZXJ0YWluIGVsZW1lbnRzIGNhbiBtYXRjaCA6ZW5hYmxlZCBvciA6ZGlzYWJsZWRcblx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zY3JpcHRpbmcuaHRtbCNzZWxlY3Rvci1lbmFibGVkXG5cdFx0Ly8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc2NyaXB0aW5nLmh0bWwjc2VsZWN0b3ItZGlzYWJsZWRcblx0XHRpZiAoIFwiZm9ybVwiIGluIGVsZW0gKSB7XG5cblx0XHRcdC8vIENoZWNrIGZvciBpbmhlcml0ZWQgZGlzYWJsZWRuZXNzIG9uIHJlbGV2YW50IG5vbi1kaXNhYmxlZCBlbGVtZW50czpcblx0XHRcdC8vICogbGlzdGVkIGZvcm0tYXNzb2NpYXRlZCBlbGVtZW50cyBpbiBhIGRpc2FibGVkIGZpZWxkc2V0XG5cdFx0XHQvLyAgIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Zvcm1zLmh0bWwjY2F0ZWdvcnktbGlzdGVkXG5cdFx0XHQvLyAgIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Zvcm1zLmh0bWwjY29uY2VwdC1mZS1kaXNhYmxlZFxuXHRcdFx0Ly8gKiBvcHRpb24gZWxlbWVudHMgaW4gYSBkaXNhYmxlZCBvcHRncm91cFxuXHRcdFx0Ly8gICBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9mb3Jtcy5odG1sI2NvbmNlcHQtb3B0aW9uLWRpc2FibGVkXG5cdFx0XHQvLyBBbGwgc3VjaCBlbGVtZW50cyBoYXZlIGEgXCJmb3JtXCIgcHJvcGVydHkuXG5cdFx0XHRpZiAoIGVsZW0ucGFyZW50Tm9kZSAmJiBlbGVtLmRpc2FibGVkID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHQvLyBPcHRpb24gZWxlbWVudHMgZGVmZXIgdG8gYSBwYXJlbnQgb3B0Z3JvdXAgaWYgcHJlc2VudFxuXHRcdFx0XHRpZiAoIFwibGFiZWxcIiBpbiBlbGVtICkge1xuXHRcdFx0XHRcdGlmICggXCJsYWJlbFwiIGluIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtLnBhcmVudE5vZGUuZGlzYWJsZWQgPT09IGRpc2FibGVkO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgNiAtIDExXG5cdFx0XHRcdC8vIFVzZSB0aGUgaXNEaXNhYmxlZCBzaG9ydGN1dCBwcm9wZXJ0eSB0byBjaGVjayBmb3IgZGlzYWJsZWQgZmllbGRzZXQgYW5jZXN0b3JzXG5cdFx0XHRcdHJldHVybiBlbGVtLmlzRGlzYWJsZWQgPT09IGRpc2FibGVkIHx8XG5cblx0XHRcdFx0XHQvLyBXaGVyZSB0aGVyZSBpcyBubyBpc0Rpc2FibGVkLCBjaGVjayBtYW51YWxseVxuXHRcdFx0XHRcdC8qIGpzaGludCAtVzAxOCAqL1xuXHRcdFx0XHRcdGVsZW0uaXNEaXNhYmxlZCAhPT0gIWRpc2FibGVkICYmXG5cdFx0XHRcdFx0aW5EaXNhYmxlZEZpZWxkc2V0KCBlbGVtICkgPT09IGRpc2FibGVkO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cblx0XHQvLyBUcnkgdG8gd2lubm93IG91dCBlbGVtZW50cyB0aGF0IGNhbid0IGJlIGRpc2FibGVkIGJlZm9yZSB0cnVzdGluZyB0aGUgZGlzYWJsZWQgcHJvcGVydHkuXG5cdFx0Ly8gU29tZSB2aWN0aW1zIGdldCBjYXVnaHQgaW4gb3VyIG5ldCAobGFiZWwsIGxlZ2VuZCwgbWVudSwgdHJhY2spLCBidXQgaXQgc2hvdWxkbid0XG5cdFx0Ly8gZXZlbiBleGlzdCBvbiB0aGVtLCBsZXQgYWxvbmUgaGF2ZSBhIGJvb2xlYW4gdmFsdWUuXG5cdFx0fSBlbHNlIGlmICggXCJsYWJlbFwiIGluIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gUmVtYWluaW5nIGVsZW1lbnRzIGFyZSBuZWl0aGVyIDplbmFibGVkIG5vciA6ZGlzYWJsZWRcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBwb3NpdGlvbmFsc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZm4gKSB7XG5cdHJldHVybiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBhcmd1bWVudCApIHtcblx0XHRhcmd1bWVudCA9ICthcmd1bWVudDtcblx0XHRyZXR1cm4gbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcblx0XHRcdHZhciBqLFxuXHRcdFx0XHRtYXRjaEluZGV4ZXMgPSBmbiggW10sIHNlZWQubGVuZ3RoLCBhcmd1bWVudCApLFxuXHRcdFx0XHRpID0gbWF0Y2hJbmRleGVzLmxlbmd0aDtcblxuXHRcdFx0Ly8gTWF0Y2ggZWxlbWVudHMgZm91bmQgYXQgdGhlIHNwZWNpZmllZCBpbmRleGVzXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCBzZWVkWyAoIGogPSBtYXRjaEluZGV4ZXNbIGkgXSApIF0gKSB7XG5cdFx0XHRcdFx0c2VlZFsgaiBdID0gISggbWF0Y2hlc1sgaiBdID0gc2VlZFsgaiBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9ICk7XG5cdH0gKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgYSBub2RlIGZvciB2YWxpZGl0eSBhcyBhIFNpenpsZSBjb250ZXh0XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0PX0gY29udGV4dFxuICogQHJldHVybnMge0VsZW1lbnR8T2JqZWN0fEJvb2xlYW59IFRoZSBpbnB1dCBub2RlIGlmIGFjY2VwdGFibGUsIG90aGVyd2lzZSBhIGZhbHN5IHZhbHVlXG4gKi9cbmZ1bmN0aW9uIHRlc3RDb250ZXh0KCBjb250ZXh0ICkge1xuXHRyZXR1cm4gY29udGV4dCAmJiB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjb250ZXh0O1xufVxuXG4vLyBFeHBvc2Ugc3VwcG9ydCB2YXJzIGZvciBjb252ZW5pZW5jZVxuc3VwcG9ydCA9IFNpenpsZS5zdXBwb3J0ID0ge307XG5cbi8qKlxuICogRGV0ZWN0cyBYTUwgbm9kZXNcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IGVsZW0gQW4gZWxlbWVudCBvciBhIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZmYgZWxlbSBpcyBhIG5vbi1IVE1MIFhNTCBub2RlXG4gKi9cbmlzWE1MID0gU2l6emxlLmlzWE1MID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciBuYW1lc3BhY2UgPSBlbGVtLm5hbWVzcGFjZVVSSSxcblx0XHRkb2NFbGVtID0gKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApLmRvY3VtZW50RWxlbWVudDtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PThcblx0Ly8gQXNzdW1lIEhUTUwgd2hlbiBkb2N1bWVudEVsZW1lbnQgZG9lc24ndCB5ZXQgZXhpc3QsIHN1Y2ggYXMgaW5zaWRlIGxvYWRpbmcgaWZyYW1lc1xuXHQvLyBodHRwczovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvNDgzM1xuXHRyZXR1cm4gIXJodG1sLnRlc3QoIG5hbWVzcGFjZSB8fCBkb2NFbGVtICYmIGRvY0VsZW0ubm9kZU5hbWUgfHwgXCJIVE1MXCIgKTtcbn07XG5cbi8qKlxuICogU2V0cyBkb2N1bWVudC1yZWxhdGVkIHZhcmlhYmxlcyBvbmNlIGJhc2VkIG9uIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0fSBbZG9jXSBBbiBlbGVtZW50IG9yIGRvY3VtZW50IG9iamVjdCB0byB1c2UgdG8gc2V0IHRoZSBkb2N1bWVudFxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY3VycmVudCBkb2N1bWVudFxuICovXG5zZXREb2N1bWVudCA9IFNpenpsZS5zZXREb2N1bWVudCA9IGZ1bmN0aW9uKCBub2RlICkge1xuXHR2YXIgaGFzQ29tcGFyZSwgc3ViV2luZG93LFxuXHRcdGRvYyA9IG5vZGUgPyBub2RlLm93bmVyRG9jdW1lbnQgfHwgbm9kZSA6IHByZWZlcnJlZERvYztcblxuXHQvLyBSZXR1cm4gZWFybHkgaWYgZG9jIGlzIGludmFsaWQgb3IgYWxyZWFkeSBzZWxlY3RlZFxuXHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRpZiAoIGRvYyA9PSBkb2N1bWVudCB8fCBkb2Mubm9kZVR5cGUgIT09IDkgfHwgIWRvYy5kb2N1bWVudEVsZW1lbnQgKSB7XG5cdFx0cmV0dXJuIGRvY3VtZW50O1xuXHR9XG5cblx0Ly8gVXBkYXRlIGdsb2JhbCB2YXJpYWJsZXNcblx0ZG9jdW1lbnQgPSBkb2M7XG5cdGRvY0VsZW0gPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cdGRvY3VtZW50SXNIVE1MID0gIWlzWE1MKCBkb2N1bWVudCApO1xuXG5cdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSssIEVkZ2UgMTIgLSAxOCtcblx0Ly8gQWNjZXNzaW5nIGlmcmFtZSBkb2N1bWVudHMgYWZ0ZXIgdW5sb2FkIHRocm93cyBcInBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3JzIChqUXVlcnkgIzEzOTM2KVxuXHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRpZiAoIHByZWZlcnJlZERvYyAhPSBkb2N1bWVudCAmJlxuXHRcdCggc3ViV2luZG93ID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcgKSAmJiBzdWJXaW5kb3cudG9wICE9PSBzdWJXaW5kb3cgKSB7XG5cblx0XHQvLyBTdXBwb3J0OiBJRSAxMSwgRWRnZVxuXHRcdGlmICggc3ViV2luZG93LmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRzdWJXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggXCJ1bmxvYWRcIiwgdW5sb2FkSGFuZGxlciwgZmFsc2UgKTtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgLSAxMCBvbmx5XG5cdFx0fSBlbHNlIGlmICggc3ViV2luZG93LmF0dGFjaEV2ZW50ICkge1xuXHRcdFx0c3ViV2luZG93LmF0dGFjaEV2ZW50KCBcIm9udW5sb2FkXCIsIHVubG9hZEhhbmRsZXIgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBJRSA4IC0gMTErLCBFZGdlIDEyIC0gMTgrLCBDaHJvbWUgPD0xNiAtIDI1IG9ubHksIEZpcmVmb3ggPD0zLjYgLSAzMSBvbmx5LFxuXHQvLyBTYWZhcmkgNCAtIDUgb25seSwgT3BlcmEgPD0xMS42IC0gMTIueCBvbmx5XG5cdC8vIElFL0VkZ2UgJiBvbGRlciBicm93c2VycyBkb24ndCBzdXBwb3J0IHRoZSA6c2NvcGUgcHNldWRvLWNsYXNzLlxuXHQvLyBTdXBwb3J0OiBTYWZhcmkgNi4wIG9ubHlcblx0Ly8gU2FmYXJpIDYuMCBzdXBwb3J0cyA6c2NvcGUgYnV0IGl0J3MgYW4gYWxpYXMgb2YgOnJvb3QgdGhlcmUuXG5cdHN1cHBvcnQuc2NvcGUgPSBhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBlbCApLmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKTtcblx0XHRyZXR1cm4gdHlwZW9mIGVsLnF1ZXJ5U2VsZWN0b3JBbGwgIT09IFwidW5kZWZpbmVkXCIgJiZcblx0XHRcdCFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIjpzY29wZSBmaWVsZHNldCBkaXZcIiApLmxlbmd0aDtcblx0fSApO1xuXG5cdC8qIEF0dHJpYnV0ZXNcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIFN1cHBvcnQ6IElFPDhcblx0Ly8gVmVyaWZ5IHRoYXQgZ2V0QXR0cmlidXRlIHJlYWxseSByZXR1cm5zIGF0dHJpYnV0ZXMgYW5kIG5vdCBwcm9wZXJ0aWVzXG5cdC8vIChleGNlcHRpbmcgSUU4IGJvb2xlYW5zKVxuXHRzdXBwb3J0LmF0dHJpYnV0ZXMgPSBhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0XHRlbC5jbGFzc05hbWUgPSBcImlcIjtcblx0XHRyZXR1cm4gIWVsLmdldEF0dHJpYnV0ZSggXCJjbGFzc05hbWVcIiApO1xuXHR9ICk7XG5cblx0LyogZ2V0RWxlbWVudChzKUJ5KlxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCIqXCIpIHJldHVybnMgb25seSBlbGVtZW50c1xuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlUYWdOYW1lID0gYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdFx0ZWwuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQoIFwiXCIgKSApO1xuXHRcdHJldHVybiAhZWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwiKlwiICkubGVuZ3RoO1xuXHR9ICk7XG5cblx0Ly8gU3VwcG9ydDogSUU8OVxuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgPSBybmF0aXZlLnRlc3QoIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKTtcblxuXHQvLyBTdXBwb3J0OiBJRTwxMFxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50QnlJZCByZXR1cm5zIGVsZW1lbnRzIGJ5IG5hbWVcblx0Ly8gVGhlIGJyb2tlbiBnZXRFbGVtZW50QnlJZCBtZXRob2RzIGRvbid0IHBpY2sgdXAgcHJvZ3JhbW1hdGljYWxseS1zZXQgbmFtZXMsXG5cdC8vIHNvIHVzZSBhIHJvdW5kYWJvdXQgZ2V0RWxlbWVudHNCeU5hbWUgdGVzdFxuXHRzdXBwb3J0LmdldEJ5SWQgPSBhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBlbCApLmlkID0gZXhwYW5kbztcblx0XHRyZXR1cm4gIWRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lIHx8ICFkb2N1bWVudC5nZXRFbGVtZW50c0J5TmFtZSggZXhwYW5kbyApLmxlbmd0aDtcblx0fSApO1xuXG5cdC8vIElEIGZpbHRlciBhbmQgZmluZFxuXHRpZiAoIHN1cHBvcnQuZ2V0QnlJZCApIHtcblx0XHRFeHByLmZpbHRlclsgXCJJRFwiIF0gPSBmdW5jdGlvbiggaWQgKSB7XG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCBcImlkXCIgKSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXHRcdEV4cHIuZmluZFsgXCJJRFwiIF0gPSBmdW5jdGlvbiggaWQsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSBcInVuZGVmaW5lZFwiICYmIGRvY3VtZW50SXNIVE1MICkge1xuXHRcdFx0XHR2YXIgZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIGlkICk7XG5cdFx0XHRcdHJldHVybiBlbGVtID8gWyBlbGVtIF0gOiBbXTtcblx0XHRcdH1cblx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdEV4cHIuZmlsdGVyWyBcIklEXCIgXSA9ICBmdW5jdGlvbiggaWQgKSB7XG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIG5vZGUgPSB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGVOb2RlICE9PSBcInVuZGVmaW5lZFwiICYmXG5cdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBcImlkXCIgKTtcblx0XHRcdFx0cmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgNiAtIDcgb25seVxuXHRcdC8vIGdldEVsZW1lbnRCeUlkIGlzIG5vdCByZWxpYWJsZSBhcyBhIGZpbmQgc2hvcnRjdXRcblx0XHRFeHByLmZpbmRbIFwiSURcIiBdID0gZnVuY3Rpb24oIGlkLCBjb250ZXh0ICkge1xuXHRcdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudElzSFRNTCApIHtcblx0XHRcdFx0dmFyIG5vZGUsIGksIGVsZW1zLFxuXHRcdFx0XHRcdGVsZW0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKCBpZCApO1xuXG5cdFx0XHRcdGlmICggZWxlbSApIHtcblxuXHRcdFx0XHRcdC8vIFZlcmlmeSB0aGUgaWQgYXR0cmlidXRlXG5cdFx0XHRcdFx0bm9kZSA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggXCJpZFwiICk7XG5cdFx0XHRcdFx0aWYgKCBub2RlICYmIG5vZGUudmFsdWUgPT09IGlkICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIFsgZWxlbSBdO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIEZhbGwgYmFjayBvbiBnZXRFbGVtZW50c0J5TmFtZVxuXHRcdFx0XHRcdGVsZW1zID0gY29udGV4dC5nZXRFbGVtZW50c0J5TmFtZSggaWQgKTtcblx0XHRcdFx0XHRpID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoICggZWxlbSA9IGVsZW1zWyBpKysgXSApICkge1xuXHRcdFx0XHRcdFx0bm9kZSA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggXCJpZFwiICk7XG5cdFx0XHRcdFx0XHRpZiAoIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gaWQgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBbIGVsZW0gXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gW107XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxuXG5cdC8vIFRhZ1xuXHRFeHByLmZpbmRbIFwiVEFHXCIgXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgP1xuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdC8vIERvY3VtZW50RnJhZ21lbnQgbm9kZXMgZG9uJ3QgaGF2ZSBnRUJUTlxuXHRcdFx0fSBlbHNlIGlmICggc3VwcG9ydC5xc2EgKSB7XG5cdFx0XHRcdHJldHVybiBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIHRhZyApO1xuXHRcdFx0fVxuXHRcdH0gOlxuXG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdHZhciBlbGVtLFxuXHRcdFx0XHR0bXAgPSBbXSxcblx0XHRcdFx0aSA9IDAsXG5cblx0XHRcdFx0Ly8gQnkgaGFwcHkgY29pbmNpZGVuY2UsIGEgKGJyb2tlbikgZ0VCVE4gYXBwZWFycyBvbiBEb2N1bWVudEZyYWdtZW50IG5vZGVzIHRvb1xuXHRcdFx0XHRyZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdC8vIEZpbHRlciBvdXQgcG9zc2libGUgY29tbWVudHNcblx0XHRcdGlmICggdGFnID09PSBcIipcIiApIHtcblx0XHRcdFx0d2hpbGUgKCAoIGVsZW0gPSByZXN1bHRzWyBpKysgXSApICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdHRtcC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHRtcDtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdH07XG5cblx0Ly8gQ2xhc3Ncblx0RXhwci5maW5kWyBcIkNMQVNTXCIgXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJiBmdW5jdGlvbiggY2xhc3NOYW1lLCBjb250ZXh0ICkge1xuXHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudElzSFRNTCApIHtcblx0XHRcdHJldHVybiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoIGNsYXNzTmFtZSApO1xuXHRcdH1cblx0fTtcblxuXHQvKiBRU0EvbWF0Y2hlc1NlbGVjdG9yXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBRU0EgYW5kIG1hdGNoZXNTZWxlY3RvciBzdXBwb3J0XG5cblx0Ly8gbWF0Y2hlc1NlbGVjdG9yKDphY3RpdmUpIHJlcG9ydHMgZmFsc2Ugd2hlbiB0cnVlIChJRTkvT3BlcmEgMTEuNSlcblx0cmJ1Z2d5TWF0Y2hlcyA9IFtdO1xuXG5cdC8vIHFTYSg6Zm9jdXMpIHJlcG9ydHMgZmFsc2Ugd2hlbiB0cnVlIChDaHJvbWUgMjEpXG5cdC8vIFdlIGFsbG93IHRoaXMgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBJRTgvOSB0aGF0IHRocm93cyBhbiBlcnJvclxuXHQvLyB3aGVuZXZlciBgZG9jdW1lbnQuYWN0aXZlRWxlbWVudGAgaXMgYWNjZXNzZWQgb24gYW4gaWZyYW1lXG5cdC8vIFNvLCB3ZSBhbGxvdyA6Zm9jdXMgdG8gcGFzcyB0aHJvdWdoIFFTQSBhbGwgdGhlIHRpbWUgdG8gYXZvaWQgdGhlIElFIGVycm9yXG5cdC8vIFNlZSBodHRwczovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTMzNzhcblx0cmJ1Z2d5UVNBID0gW107XG5cblx0aWYgKCAoIHN1cHBvcnQucXNhID0gcm5hdGl2ZS50ZXN0KCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsICkgKSApIHtcblxuXHRcdC8vIEJ1aWxkIFFTQSByZWdleFxuXHRcdC8vIFJlZ2V4IHN0cmF0ZWd5IGFkb3B0ZWQgZnJvbSBEaWVnbyBQZXJpbmlcblx0XHRhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblxuXHRcdFx0dmFyIGlucHV0O1xuXG5cdFx0XHQvLyBTZWxlY3QgaXMgc2V0IHRvIGVtcHR5IHN0cmluZyBvbiBwdXJwb3NlXG5cdFx0XHQvLyBUaGlzIGlzIHRvIHRlc3QgSUUncyB0cmVhdG1lbnQgb2Ygbm90IGV4cGxpY2l0bHlcblx0XHRcdC8vIHNldHRpbmcgYSBib29sZWFuIGNvbnRlbnQgYXR0cmlidXRlLFxuXHRcdFx0Ly8gc2luY2UgaXRzIHByZXNlbmNlIHNob3VsZCBiZSBlbm91Z2hcblx0XHRcdC8vIGh0dHBzOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC8xMjM1OVxuXHRcdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggZWwgKS5pbm5lckhUTUwgPSBcIjxhIGlkPSdcIiArIGV4cGFuZG8gKyBcIic+PC9hPlwiICtcblx0XHRcdFx0XCI8c2VsZWN0IGlkPSdcIiArIGV4cGFuZG8gKyBcIi1cXHJcXFxcJyBtc2FsbG93Y2FwdHVyZT0nJz5cIiArXG5cdFx0XHRcdFwiPG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD5cIjtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4LCBPcGVyYSAxMS0xMi4xNlxuXHRcdFx0Ly8gTm90aGluZyBzaG91bGQgYmUgc2VsZWN0ZWQgd2hlbiBlbXB0eSBzdHJpbmdzIGZvbGxvdyBePSBvciAkPSBvciAqPVxuXHRcdFx0Ly8gVGhlIHRlc3QgYXR0cmlidXRlIG11c3QgYmUgdW5rbm93biBpbiBPcGVyYSBidXQgXCJzYWZlXCIgZm9yIFdpblJUXG5cdFx0XHQvLyBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2hoNDY1Mzg4LmFzcHgjYXR0cmlidXRlX3NlY3Rpb25cblx0XHRcdGlmICggZWwucXVlcnlTZWxlY3RvckFsbCggXCJbbXNhbGxvd2NhcHR1cmVePScnXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJbKl4kXT1cIiArIHdoaXRlc3BhY2UgKyBcIiooPzonJ3xcXFwiXFxcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcblx0XHRcdC8vIEJvb2xlYW4gYXR0cmlidXRlcyBhbmQgXCJ2YWx1ZVwiIGFyZSBub3QgdHJlYXRlZCBjb3JyZWN0bHlcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiW3NlbGVjdGVkXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKig/OnZhbHVlfFwiICsgYm9vbGVhbnMgKyBcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWU8MjksIEFuZHJvaWQ8NC40LCBTYWZhcmk8Ny4wKywgaU9TPDcuMCssIFBoYW50b21KUzwxLjkuOCtcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiW2lkfj1cIiArIGV4cGFuZG8gKyBcIi1dXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIn49XCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE1IC0gMTgrXG5cdFx0XHQvLyBJRSAxMS9FZGdlIGRvbid0IGZpbmQgZWxlbWVudHMgb24gYSBgW25hbWU9JyddYCBxdWVyeSBpbiBzb21lIGNhc2VzLlxuXHRcdFx0Ly8gQWRkaW5nIGEgdGVtcG9yYXJ5IGF0dHJpYnV0ZSB0byB0aGUgZG9jdW1lbnQgYmVmb3JlIHRoZSBzZWxlY3Rpb24gd29ya3Ncblx0XHRcdC8vIGFyb3VuZCB0aGUgaXNzdWUuXG5cdFx0XHQvLyBJbnRlcmVzdGluZ2x5LCBJRSAxMCAmIG9sZGVyIGRvbid0IHNlZW0gdG8gaGF2ZSB0aGUgaXNzdWUuXG5cdFx0XHRpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApO1xuXHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJcIiApO1xuXHRcdFx0ZWwuYXBwZW5kQ2hpbGQoIGlucHV0ICk7XG5cdFx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIltuYW1lPScnXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKm5hbWVcIiArIHdoaXRlc3BhY2UgKyBcIio9XCIgK1xuXHRcdFx0XHRcdHdoaXRlc3BhY2UgKyBcIiooPzonJ3xcXFwiXFxcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBXZWJraXQvT3BlcmEgLSA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIHNlbGVjdGVkIG9wdGlvbiBlbGVtZW50c1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMS9SRUMtY3NzMy1zZWxlY3RvcnMtMjAxMTA5MjkvI2NoZWNrZWRcblx0XHRcdC8vIElFOCB0aHJvd3MgZXJyb3IgaGVyZSBhbmQgd2lsbCBub3Qgc2VlIGxhdGVyIHRlc3RzXG5cdFx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIjpjaGVja2VkXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIjpjaGVja2VkXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogU2FmYXJpIDgrLCBpT1MgOCtcblx0XHRcdC8vIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzY4NTFcblx0XHRcdC8vIEluLXBhZ2UgYHNlbGVjdG9yI2lkIHNpYmxpbmctY29tYmluYXRvciBzZWxlY3RvcmAgZmFpbHNcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiYSNcIiArIGV4cGFuZG8gKyBcIisqXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIi4jLitbK35dXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA8PTMuNiAtIDUgb25seVxuXHRcdFx0Ly8gT2xkIEZpcmVmb3ggZG9lc24ndCB0aHJvdyBvbiBhIGJhZGx5LWVzY2FwZWQgaWRlbnRpZmllci5cblx0XHRcdGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiXFxcXFxcZlwiICk7XG5cdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJbXFxcXHJcXFxcblxcXFxmXVwiICk7XG5cdFx0fSApO1xuXG5cdFx0YXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdFx0XHRlbC5pbm5lckhUTUwgPSBcIjxhIGhyZWY9JycgZGlzYWJsZWQ9J2Rpc2FibGVkJz48L2E+XCIgK1xuXHRcdFx0XHRcIjxzZWxlY3QgZGlzYWJsZWQ9J2Rpc2FibGVkJz48b3B0aW9uLz48L3NlbGVjdD5cIjtcblxuXHRcdFx0Ly8gU3VwcG9ydDogV2luZG93cyA4IE5hdGl2ZSBBcHBzXG5cdFx0XHQvLyBUaGUgdHlwZSBhbmQgbmFtZSBhdHRyaWJ1dGVzIGFyZSByZXN0cmljdGVkIGR1cmluZyAuaW5uZXJIVE1MIGFzc2lnbm1lbnRcblx0XHRcdHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApO1xuXHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgXCJoaWRkZW5cIiApO1xuXHRcdFx0ZWwuYXBwZW5kQ2hpbGQoIGlucHV0ICkuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJEXCIgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4XG5cdFx0XHQvLyBFbmZvcmNlIGNhc2Utc2Vuc2l0aXZpdHkgb2YgbmFtZSBhdHRyaWJ1dGVcblx0XHRcdGlmICggZWwucXVlcnlTZWxlY3RvckFsbCggXCJbbmFtZT1kXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJuYW1lXCIgKyB3aGl0ZXNwYWNlICsgXCIqWypeJHwhfl0/PVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZGIDMuNSAtIDplbmFibGVkLzpkaXNhYmxlZCBhbmQgaGlkZGVuIGVsZW1lbnRzIChoaWRkZW4gZWxlbWVudHMgYXJlIHN0aWxsIGVuYWJsZWQpXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xuXHRcdFx0aWYgKCBlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIjplbmFibGVkXCIgKS5sZW5ndGggIT09IDIgKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIjplbmFibGVkXCIsIFwiOmRpc2FibGVkXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU5LTExK1xuXHRcdFx0Ly8gSUUncyA6ZGlzYWJsZWQgc2VsZWN0b3IgZG9lcyBub3QgcGljayB1cCB0aGUgY2hpbGRyZW4gb2YgZGlzYWJsZWQgZmllbGRzZXRzXG5cdFx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBlbCApLmRpc2FibGVkID0gdHJ1ZTtcblx0XHRcdGlmICggZWwucXVlcnlTZWxlY3RvckFsbCggXCI6ZGlzYWJsZWRcIiApLmxlbmd0aCAhPT0gMiApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiOmVuYWJsZWRcIiwgXCI6ZGlzYWJsZWRcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBPcGVyYSAxMCAtIDExIG9ubHlcblx0XHRcdC8vIE9wZXJhIDEwLTExIGRvZXMgbm90IHRocm93IG9uIHBvc3QtY29tbWEgaW52YWxpZCBwc2V1ZG9zXG5cdFx0XHRlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIiosOnhcIiApO1xuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiLC4qOlwiICk7XG5cdFx0fSApO1xuXHR9XG5cblx0aWYgKCAoIHN1cHBvcnQubWF0Y2hlc1NlbGVjdG9yID0gcm5hdGl2ZS50ZXN0KCAoIG1hdGNoZXMgPSBkb2NFbGVtLm1hdGNoZXMgfHxcblx0XHRkb2NFbGVtLndlYmtpdE1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ubW96TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5vTWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5tc01hdGNoZXNTZWxlY3RvciApICkgKSApIHtcblxuXHRcdGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXG5cdFx0XHQvLyBDaGVjayB0byBzZWUgaWYgaXQncyBwb3NzaWJsZSB0byBkbyBtYXRjaGVzU2VsZWN0b3Jcblx0XHRcdC8vIG9uIGEgZGlzY29ubmVjdGVkIG5vZGUgKElFIDkpXG5cdFx0XHRzdXBwb3J0LmRpc2Nvbm5lY3RlZE1hdGNoID0gbWF0Y2hlcy5jYWxsKCBlbCwgXCIqXCIgKTtcblxuXHRcdFx0Ly8gVGhpcyBzaG91bGQgZmFpbCB3aXRoIGFuIGV4Y2VwdGlvblxuXHRcdFx0Ly8gR2Vja28gZG9lcyBub3QgZXJyb3IsIHJldHVybnMgZmFsc2UgaW5zdGVhZFxuXHRcdFx0bWF0Y2hlcy5jYWxsKCBlbCwgXCJbcyE9JyddOnhcIiApO1xuXHRcdFx0cmJ1Z2d5TWF0Y2hlcy5wdXNoKCBcIiE9XCIsIHBzZXVkb3MgKTtcblx0XHR9ICk7XG5cdH1cblxuXHRyYnVnZ3lRU0EgPSByYnVnZ3lRU0EubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneVFTQS5qb2luKCBcInxcIiApICk7XG5cdHJidWdneU1hdGNoZXMgPSByYnVnZ3lNYXRjaGVzLmxlbmd0aCAmJiBuZXcgUmVnRXhwKCByYnVnZ3lNYXRjaGVzLmpvaW4oIFwifFwiICkgKTtcblxuXHQvKiBDb250YWluc1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cdGhhc0NvbXBhcmUgPSBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29tcGFyZURvY3VtZW50UG9zaXRpb24gKTtcblxuXHQvLyBFbGVtZW50IGNvbnRhaW5zIGFub3RoZXJcblx0Ly8gUHVycG9zZWZ1bGx5IHNlbGYtZXhjbHVzaXZlXG5cdC8vIEFzIGluLCBhbiBlbGVtZW50IGRvZXMgbm90IGNvbnRhaW4gaXRzZWxmXG5cdGNvbnRhaW5zID0gaGFzQ29tcGFyZSB8fCBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29udGFpbnMgKSA/XG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0XHR2YXIgYWRvd24gPSBhLm5vZGVUeXBlID09PSA5ID8gYS5kb2N1bWVudEVsZW1lbnQgOiBhLFxuXHRcdFx0XHRidXAgPSBiICYmIGIucGFyZW50Tm9kZTtcblx0XHRcdHJldHVybiBhID09PSBidXAgfHwgISEoIGJ1cCAmJiBidXAubm9kZVR5cGUgPT09IDEgJiYgKFxuXHRcdFx0XHRhZG93bi5jb250YWlucyA/XG5cdFx0XHRcdFx0YWRvd24uY29udGFpbnMoIGJ1cCApIDpcblx0XHRcdFx0XHRhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uICYmIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGJ1cCApICYgMTZcblx0XHRcdCkgKTtcblx0XHR9IDpcblx0XHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdGlmICggYiApIHtcblx0XHRcdFx0d2hpbGUgKCAoIGIgPSBiLnBhcmVudE5vZGUgKSApIHtcblx0XHRcdFx0XHRpZiAoIGIgPT09IGEgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9O1xuXG5cdC8qIFNvcnRpbmdcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIERvY3VtZW50IG9yZGVyIHNvcnRpbmdcblx0c29ydE9yZGVyID0gaGFzQ29tcGFyZSA/XG5cdGZ1bmN0aW9uKCBhLCBiICkge1xuXG5cdFx0Ly8gRmxhZyBmb3IgZHVwbGljYXRlIHJlbW92YWxcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0Ly8gU29ydCBvbiBtZXRob2QgZXhpc3RlbmNlIGlmIG9ubHkgb25lIGlucHV0IGhhcyBjb21wYXJlRG9jdW1lbnRQb3NpdGlvblxuXHRcdHZhciBjb21wYXJlID0gIWEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gLSAhYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbjtcblx0XHRpZiAoIGNvbXBhcmUgKSB7XG5cdFx0XHRyZXR1cm4gY29tcGFyZTtcblx0XHR9XG5cblx0XHQvLyBDYWxjdWxhdGUgcG9zaXRpb24gaWYgYm90aCBpbnB1dHMgYmVsb25nIHRvIHRoZSBzYW1lIGRvY3VtZW50XG5cdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRjb21wYXJlID0gKCBhLm93bmVyRG9jdW1lbnQgfHwgYSApID09ICggYi5vd25lckRvY3VtZW50IHx8IGIgKSA/XG5cdFx0XHRhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBiICkgOlxuXG5cdFx0XHQvLyBPdGhlcndpc2Ugd2Uga25vdyB0aGV5IGFyZSBkaXNjb25uZWN0ZWRcblx0XHRcdDE7XG5cblx0XHQvLyBEaXNjb25uZWN0ZWQgbm9kZXNcblx0XHRpZiAoIGNvbXBhcmUgJiAxIHx8XG5cdFx0XHQoICFzdXBwb3J0LnNvcnREZXRhY2hlZCAmJiBiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBhICkgPT09IGNvbXBhcmUgKSApIHtcblxuXHRcdFx0Ly8gQ2hvb3NlIHRoZSBmaXJzdCBlbGVtZW50IHRoYXQgaXMgcmVsYXRlZCB0byBvdXIgcHJlZmVycmVkIGRvY3VtZW50XG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0aWYgKCBhID09IGRvY3VtZW50IHx8IGEub3duZXJEb2N1bWVudCA9PSBwcmVmZXJyZWREb2MgJiZcblx0XHRcdFx0Y29udGFpbnMoIHByZWZlcnJlZERvYywgYSApICkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdFx0XHRpZiAoIGIgPT0gZG9jdW1lbnQgfHwgYi5vd25lckRvY3VtZW50ID09IHByZWZlcnJlZERvYyAmJlxuXHRcdFx0XHRjb250YWlucyggcHJlZmVycmVkRG9jLCBiICkgKSB7XG5cdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBNYWludGFpbiBvcmlnaW5hbCBvcmRlclxuXHRcdFx0cmV0dXJuIHNvcnRJbnB1dCA/XG5cdFx0XHRcdCggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDpcblx0XHRcdFx0MDtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29tcGFyZSAmIDQgPyAtMSA6IDE7XG5cdH0gOlxuXHRmdW5jdGlvbiggYSwgYiApIHtcblxuXHRcdC8vIEV4aXQgZWFybHkgaWYgdGhlIG5vZGVzIGFyZSBpZGVudGljYWxcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0dmFyIGN1cixcblx0XHRcdGkgPSAwLFxuXHRcdFx0YXVwID0gYS5wYXJlbnROb2RlLFxuXHRcdFx0YnVwID0gYi5wYXJlbnROb2RlLFxuXHRcdFx0YXAgPSBbIGEgXSxcblx0XHRcdGJwID0gWyBiIF07XG5cblx0XHQvLyBQYXJlbnRsZXNzIG5vZGVzIGFyZSBlaXRoZXIgZG9jdW1lbnRzIG9yIGRpc2Nvbm5lY3RlZFxuXHRcdGlmICggIWF1cCB8fCAhYnVwICkge1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0LyogZXNsaW50LWRpc2FibGUgZXFlcWVxICovXG5cdFx0XHRyZXR1cm4gYSA9PSBkb2N1bWVudCA/IC0xIDpcblx0XHRcdFx0YiA9PSBkb2N1bWVudCA/IDEgOlxuXHRcdFx0XHQvKiBlc2xpbnQtZW5hYmxlIGVxZXFlcSAqL1xuXHRcdFx0XHRhdXAgPyAtMSA6XG5cdFx0XHRcdGJ1cCA/IDEgOlxuXHRcdFx0XHRzb3J0SW5wdXQgP1xuXHRcdFx0XHQoIGluZGV4T2YoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZiggc29ydElucHV0LCBiICkgKSA6XG5cdFx0XHRcdDA7XG5cblx0XHQvLyBJZiB0aGUgbm9kZXMgYXJlIHNpYmxpbmdzLCB3ZSBjYW4gZG8gYSBxdWljayBjaGVja1xuXHRcdH0gZWxzZSBpZiAoIGF1cCA9PT0gYnVwICkge1xuXHRcdFx0cmV0dXJuIHNpYmxpbmdDaGVjayggYSwgYiApO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyd2lzZSB3ZSBuZWVkIGZ1bGwgbGlzdHMgb2YgdGhlaXIgYW5jZXN0b3JzIGZvciBjb21wYXJpc29uXG5cdFx0Y3VyID0gYTtcblx0XHR3aGlsZSAoICggY3VyID0gY3VyLnBhcmVudE5vZGUgKSApIHtcblx0XHRcdGFwLnVuc2hpZnQoIGN1ciApO1xuXHRcdH1cblx0XHRjdXIgPSBiO1xuXHRcdHdoaWxlICggKCBjdXIgPSBjdXIucGFyZW50Tm9kZSApICkge1xuXHRcdFx0YnAudW5zaGlmdCggY3VyICk7XG5cdFx0fVxuXG5cdFx0Ly8gV2FsayBkb3duIHRoZSB0cmVlIGxvb2tpbmcgZm9yIGEgZGlzY3JlcGFuY3lcblx0XHR3aGlsZSAoIGFwWyBpIF0gPT09IGJwWyBpIF0gKSB7XG5cdFx0XHRpKys7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGkgP1xuXG5cdFx0XHQvLyBEbyBhIHNpYmxpbmcgY2hlY2sgaWYgdGhlIG5vZGVzIGhhdmUgYSBjb21tb24gYW5jZXN0b3Jcblx0XHRcdHNpYmxpbmdDaGVjayggYXBbIGkgXSwgYnBbIGkgXSApIDpcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIG5vZGVzIGluIG91ciBkb2N1bWVudCBzb3J0IGZpcnN0XG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0LyogZXNsaW50LWRpc2FibGUgZXFlcWVxICovXG5cdFx0XHRhcFsgaSBdID09IHByZWZlcnJlZERvYyA/IC0xIDpcblx0XHRcdGJwWyBpIF0gPT0gcHJlZmVycmVkRG9jID8gMSA6XG5cdFx0XHQvKiBlc2xpbnQtZW5hYmxlIGVxZXFlcSAqL1xuXHRcdFx0MDtcblx0fTtcblxuXHRyZXR1cm4gZG9jdW1lbnQ7XG59O1xuXG5TaXp6bGUubWF0Y2hlcyA9IGZ1bmN0aW9uKCBleHByLCBlbGVtZW50cyApIHtcblx0cmV0dXJuIFNpenpsZSggZXhwciwgbnVsbCwgbnVsbCwgZWxlbWVudHMgKTtcbn07XG5cblNpenpsZS5tYXRjaGVzU2VsZWN0b3IgPSBmdW5jdGlvbiggZWxlbSwgZXhwciApIHtcblx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblxuXHRpZiAoIHN1cHBvcnQubWF0Y2hlc1NlbGVjdG9yICYmIGRvY3VtZW50SXNIVE1MICYmXG5cdFx0IW5vbm5hdGl2ZVNlbGVjdG9yQ2FjaGVbIGV4cHIgKyBcIiBcIiBdICYmXG5cdFx0KCAhcmJ1Z2d5TWF0Y2hlcyB8fCAhcmJ1Z2d5TWF0Y2hlcy50ZXN0KCBleHByICkgKSAmJlxuXHRcdCggIXJidWdneVFTQSAgICAgfHwgIXJidWdneVFTQS50ZXN0KCBleHByICkgKSApIHtcblxuXHRcdHRyeSB7XG5cdFx0XHR2YXIgcmV0ID0gbWF0Y2hlcy5jYWxsKCBlbGVtLCBleHByICk7XG5cblx0XHRcdC8vIElFIDkncyBtYXRjaGVzU2VsZWN0b3IgcmV0dXJucyBmYWxzZSBvbiBkaXNjb25uZWN0ZWQgbm9kZXNcblx0XHRcdGlmICggcmV0IHx8IHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggfHxcblxuXHRcdFx0XHQvLyBBcyB3ZWxsLCBkaXNjb25uZWN0ZWQgbm9kZXMgYXJlIHNhaWQgdG8gYmUgaW4gYSBkb2N1bWVudFxuXHRcdFx0XHQvLyBmcmFnbWVudCBpbiBJRSA5XG5cdFx0XHRcdGVsZW0uZG9jdW1lbnQgJiYgZWxlbS5kb2N1bWVudC5ub2RlVHlwZSAhPT0gMTEgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRub25uYXRpdmVTZWxlY3RvckNhY2hlKCBleHByLCB0cnVlICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIFNpenpsZSggZXhwciwgZG9jdW1lbnQsIG51bGwsIFsgZWxlbSBdICkubGVuZ3RoID4gMDtcbn07XG5cblNpenpsZS5jb250YWlucyA9IGZ1bmN0aW9uKCBjb250ZXh0LCBlbGVtICkge1xuXG5cdC8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZFxuXHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRpZiAoICggY29udGV4dC5vd25lckRvY3VtZW50IHx8IGNvbnRleHQgKSAhPSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHR9XG5cdHJldHVybiBjb250YWlucyggY29udGV4dCwgZWxlbSApO1xufTtcblxuU2l6emxlLmF0dHIgPSBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblxuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT0gZG9jdW1lbnQgKSB7XG5cdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblx0fVxuXG5cdHZhciBmbiA9IEV4cHIuYXR0ckhhbmRsZVsgbmFtZS50b0xvd2VyQ2FzZSgpIF0sXG5cblx0XHQvLyBEb24ndCBnZXQgZm9vbGVkIGJ5IE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoalF1ZXJ5ICMxMzgwNylcblx0XHR2YWwgPSBmbiAmJiBoYXNPd24uY2FsbCggRXhwci5hdHRySGFuZGxlLCBuYW1lLnRvTG93ZXJDYXNlKCkgKSA/XG5cdFx0XHRmbiggZWxlbSwgbmFtZSwgIWRvY3VtZW50SXNIVE1MICkgOlxuXHRcdFx0dW5kZWZpbmVkO1xuXG5cdHJldHVybiB2YWwgIT09IHVuZGVmaW5lZCA/XG5cdFx0dmFsIDpcblx0XHRzdXBwb3J0LmF0dHJpYnV0ZXMgfHwgIWRvY3VtZW50SXNIVE1MID9cblx0XHRcdGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lICkgOlxuXHRcdFx0KCB2YWwgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIG5hbWUgKSApICYmIHZhbC5zcGVjaWZpZWQgP1xuXHRcdFx0XHR2YWwudmFsdWUgOlxuXHRcdFx0XHRudWxsO1xufTtcblxuU2l6emxlLmVzY2FwZSA9IGZ1bmN0aW9uKCBzZWwgKSB7XG5cdHJldHVybiAoIHNlbCArIFwiXCIgKS5yZXBsYWNlKCByY3NzZXNjYXBlLCBmY3NzZXNjYXBlICk7XG59O1xuXG5TaXp6bGUuZXJyb3IgPSBmdW5jdGlvbiggbXNnICkge1xuXHR0aHJvdyBuZXcgRXJyb3IoIFwiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogXCIgKyBtc2cgKTtcbn07XG5cbi8qKlxuICogRG9jdW1lbnQgc29ydGluZyBhbmQgcmVtb3ZpbmcgZHVwbGljYXRlc1xuICogQHBhcmFtIHtBcnJheUxpa2V9IHJlc3VsdHNcbiAqL1xuU2l6emxlLnVuaXF1ZVNvcnQgPSBmdW5jdGlvbiggcmVzdWx0cyApIHtcblx0dmFyIGVsZW0sXG5cdFx0ZHVwbGljYXRlcyA9IFtdLFxuXHRcdGogPSAwLFxuXHRcdGkgPSAwO1xuXG5cdC8vIFVubGVzcyB3ZSAqa25vdyogd2UgY2FuIGRldGVjdCBkdXBsaWNhdGVzLCBhc3N1bWUgdGhlaXIgcHJlc2VuY2Vcblx0aGFzRHVwbGljYXRlID0gIXN1cHBvcnQuZGV0ZWN0RHVwbGljYXRlcztcblx0c29ydElucHV0ID0gIXN1cHBvcnQuc29ydFN0YWJsZSAmJiByZXN1bHRzLnNsaWNlKCAwICk7XG5cdHJlc3VsdHMuc29ydCggc29ydE9yZGVyICk7XG5cblx0aWYgKCBoYXNEdXBsaWNhdGUgKSB7XG5cdFx0d2hpbGUgKCAoIGVsZW0gPSByZXN1bHRzWyBpKysgXSApICkge1xuXHRcdFx0aWYgKCBlbGVtID09PSByZXN1bHRzWyBpIF0gKSB7XG5cdFx0XHRcdGogPSBkdXBsaWNhdGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRyZXN1bHRzLnNwbGljZSggZHVwbGljYXRlc1sgaiBdLCAxICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2xlYXIgaW5wdXQgYWZ0ZXIgc29ydGluZyB0byByZWxlYXNlIG9iamVjdHNcblx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvc2l6emxlL3B1bGwvMjI1XG5cdHNvcnRJbnB1dCA9IG51bGw7XG5cblx0cmV0dXJuIHJlc3VsdHM7XG59O1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gZm9yIHJldHJpZXZpbmcgdGhlIHRleHQgdmFsdWUgb2YgYW4gYXJyYXkgb2YgRE9NIG5vZGVzXG4gKiBAcGFyYW0ge0FycmF5fEVsZW1lbnR9IGVsZW1cbiAqL1xuZ2V0VGV4dCA9IFNpenpsZS5nZXRUZXh0ID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciBub2RlLFxuXHRcdHJldCA9IFwiXCIsXG5cdFx0aSA9IDAsXG5cdFx0bm9kZVR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdGlmICggIW5vZGVUeXBlICkge1xuXG5cdFx0Ly8gSWYgbm8gbm9kZVR5cGUsIHRoaXMgaXMgZXhwZWN0ZWQgdG8gYmUgYW4gYXJyYXlcblx0XHR3aGlsZSAoICggbm9kZSA9IGVsZW1bIGkrKyBdICkgKSB7XG5cblx0XHRcdC8vIERvIG5vdCB0cmF2ZXJzZSBjb21tZW50IG5vZGVzXG5cdFx0XHRyZXQgKz0gZ2V0VGV4dCggbm9kZSApO1xuXHRcdH1cblx0fSBlbHNlIGlmICggbm9kZVR5cGUgPT09IDEgfHwgbm9kZVR5cGUgPT09IDkgfHwgbm9kZVR5cGUgPT09IDExICkge1xuXG5cdFx0Ly8gVXNlIHRleHRDb250ZW50IGZvciBlbGVtZW50c1xuXHRcdC8vIGlubmVyVGV4dCB1c2FnZSByZW1vdmVkIGZvciBjb25zaXN0ZW5jeSBvZiBuZXcgbGluZXMgKGpRdWVyeSAjMTExNTMpXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS50ZXh0Q29udGVudCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBlbGVtLnRleHRDb250ZW50O1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIFRyYXZlcnNlIGl0cyBjaGlsZHJlblxuXHRcdFx0Zm9yICggZWxlbSA9IGVsZW0uZmlyc3RDaGlsZDsgZWxlbTsgZWxlbSA9IGVsZW0ubmV4dFNpYmxpbmcgKSB7XG5cdFx0XHRcdHJldCArPSBnZXRUZXh0KCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGVsc2UgaWYgKCBub2RlVHlwZSA9PT0gMyB8fCBub2RlVHlwZSA9PT0gNCApIHtcblx0XHRyZXR1cm4gZWxlbS5ub2RlVmFsdWU7XG5cdH1cblxuXHQvLyBEbyBub3QgaW5jbHVkZSBjb21tZW50IG9yIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZXNcblxuXHRyZXR1cm4gcmV0O1xufTtcblxuRXhwciA9IFNpenpsZS5zZWxlY3RvcnMgPSB7XG5cblx0Ly8gQ2FuIGJlIGFkanVzdGVkIGJ5IHRoZSB1c2VyXG5cdGNhY2hlTGVuZ3RoOiA1MCxcblxuXHRjcmVhdGVQc2V1ZG86IG1hcmtGdW5jdGlvbixcblxuXHRtYXRjaDogbWF0Y2hFeHByLFxuXG5cdGF0dHJIYW5kbGU6IHt9LFxuXG5cdGZpbmQ6IHt9LFxuXG5cdHJlbGF0aXZlOiB7XG5cdFx0XCI+XCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiwgZmlyc3Q6IHRydWUgfSxcblx0XHRcIiBcIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiIH0sXG5cdFx0XCIrXCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiLCBmaXJzdDogdHJ1ZSB9LFxuXHRcdFwiflwiOiB7IGRpcjogXCJwcmV2aW91c1NpYmxpbmdcIiB9XG5cdH0sXG5cblx0cHJlRmlsdGVyOiB7XG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdG1hdGNoWyAxIF0gPSBtYXRjaFsgMSBdLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cblx0XHRcdC8vIE1vdmUgdGhlIGdpdmVuIHZhbHVlIHRvIG1hdGNoWzNdIHdoZXRoZXIgcXVvdGVkIG9yIHVucXVvdGVkXG5cdFx0XHRtYXRjaFsgMyBdID0gKCBtYXRjaFsgMyBdIHx8IG1hdGNoWyA0IF0gfHxcblx0XHRcdFx0bWF0Y2hbIDUgXSB8fCBcIlwiICkucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsgMiBdID09PSBcIn49XCIgKSB7XG5cdFx0XHRcdG1hdGNoWyAzIF0gPSBcIiBcIiArIG1hdGNoWyAzIF0gKyBcIiBcIjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXG5cdFx0XHQvKiBtYXRjaGVzIGZyb20gbWF0Y2hFeHByW1wiQ0hJTERcIl1cblx0XHRcdFx0MSB0eXBlIChvbmx5fG50aHwuLi4pXG5cdFx0XHRcdDIgd2hhdCAoY2hpbGR8b2YtdHlwZSlcblx0XHRcdFx0MyBhcmd1bWVudCAoZXZlbnxvZGR8XFxkKnxcXGQqbihbKy1dXFxkKyk/fC4uLilcblx0XHRcdFx0NCB4bi1jb21wb25lbnQgb2YgeG4reSBhcmd1bWVudCAoWystXT9cXGQqbnwpXG5cdFx0XHRcdDUgc2lnbiBvZiB4bi1jb21wb25lbnRcblx0XHRcdFx0NiB4IG9mIHhuLWNvbXBvbmVudFxuXHRcdFx0XHQ3IHNpZ24gb2YgeS1jb21wb25lbnRcblx0XHRcdFx0OCB5IG9mIHktY29tcG9uZW50XG5cdFx0XHQqL1xuXHRcdFx0bWF0Y2hbIDEgXSA9IG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsgMSBdLnNsaWNlKCAwLCAzICkgPT09IFwibnRoXCIgKSB7XG5cblx0XHRcdFx0Ly8gbnRoLSogcmVxdWlyZXMgYXJndW1lbnRcblx0XHRcdFx0aWYgKCAhbWF0Y2hbIDMgXSApIHtcblx0XHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWyAwIF0gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIG51bWVyaWMgeCBhbmQgeSBwYXJhbWV0ZXJzIGZvciBFeHByLmZpbHRlci5DSElMRFxuXHRcdFx0XHQvLyByZW1lbWJlciB0aGF0IGZhbHNlL3RydWUgY2FzdCByZXNwZWN0aXZlbHkgdG8gMC8xXG5cdFx0XHRcdG1hdGNoWyA0IF0gPSArKCBtYXRjaFsgNCBdID9cblx0XHRcdFx0XHRtYXRjaFsgNSBdICsgKCBtYXRjaFsgNiBdIHx8IDEgKSA6XG5cdFx0XHRcdFx0MiAqICggbWF0Y2hbIDMgXSA9PT0gXCJldmVuXCIgfHwgbWF0Y2hbIDMgXSA9PT0gXCJvZGRcIiApICk7XG5cdFx0XHRcdG1hdGNoWyA1IF0gPSArKCAoIG1hdGNoWyA3IF0gKyBtYXRjaFsgOCBdICkgfHwgbWF0Y2hbIDMgXSA9PT0gXCJvZGRcIiApO1xuXG5cdFx0XHRcdC8vIG90aGVyIHR5cGVzIHByb2hpYml0IGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbIDMgXSApIHtcblx0XHRcdFx0U2l6emxlLmVycm9yKCBtYXRjaFsgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBtYXRjaDtcblx0XHR9LFxuXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0dmFyIGV4Y2Vzcyxcblx0XHRcdFx0dW5xdW90ZWQgPSAhbWF0Y2hbIDYgXSAmJiBtYXRjaFsgMiBdO1xuXG5cdFx0XHRpZiAoIG1hdGNoRXhwclsgXCJDSElMRFwiIF0udGVzdCggbWF0Y2hbIDAgXSApICkge1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWNjZXB0IHF1b3RlZCBhcmd1bWVudHMgYXMtaXNcblx0XHRcdGlmICggbWF0Y2hbIDMgXSApIHtcblx0XHRcdFx0bWF0Y2hbIDIgXSA9IG1hdGNoWyA0IF0gfHwgbWF0Y2hbIDUgXSB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTdHJpcCBleGNlc3MgY2hhcmFjdGVycyBmcm9tIHVucXVvdGVkIGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggdW5xdW90ZWQgJiYgcnBzZXVkby50ZXN0KCB1bnF1b3RlZCApICYmXG5cblx0XHRcdFx0Ly8gR2V0IGV4Y2VzcyBmcm9tIHRva2VuaXplIChyZWN1cnNpdmVseSlcblx0XHRcdFx0KCBleGNlc3MgPSB0b2tlbml6ZSggdW5xdW90ZWQsIHRydWUgKSApICYmXG5cblx0XHRcdFx0Ly8gYWR2YW5jZSB0byB0aGUgbmV4dCBjbG9zaW5nIHBhcmVudGhlc2lzXG5cdFx0XHRcdCggZXhjZXNzID0gdW5xdW90ZWQuaW5kZXhPZiggXCIpXCIsIHVucXVvdGVkLmxlbmd0aCAtIGV4Y2VzcyApIC0gdW5xdW90ZWQubGVuZ3RoICkgKSB7XG5cblx0XHRcdFx0Ly8gZXhjZXNzIGlzIGEgbmVnYXRpdmUgaW5kZXhcblx0XHRcdFx0bWF0Y2hbIDAgXSA9IG1hdGNoWyAwIF0uc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0XHRtYXRjaFsgMiBdID0gdW5xdW90ZWQuc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXR1cm4gb25seSBjYXB0dXJlcyBuZWVkZWQgYnkgdGhlIHBzZXVkbyBmaWx0ZXIgbWV0aG9kICh0eXBlIGFuZCBhcmd1bWVudClcblx0XHRcdHJldHVybiBtYXRjaC5zbGljZSggMCwgMyApO1xuXHRcdH1cblx0fSxcblxuXHRmaWx0ZXI6IHtcblxuXHRcdFwiVEFHXCI6IGZ1bmN0aW9uKCBub2RlTmFtZVNlbGVjdG9yICkge1xuXHRcdFx0dmFyIG5vZGVOYW1lID0gbm9kZU5hbWVTZWxlY3Rvci5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gbm9kZU5hbWVTZWxlY3RvciA9PT0gXCIqXCIgP1xuXHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbm9kZU5hbWU7XG5cdFx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiQ0xBU1NcIjogZnVuY3Rpb24oIGNsYXNzTmFtZSApIHtcblx0XHRcdHZhciBwYXR0ZXJuID0gY2xhc3NDYWNoZVsgY2xhc3NOYW1lICsgXCIgXCIgXTtcblxuXHRcdFx0cmV0dXJuIHBhdHRlcm4gfHxcblx0XHRcdFx0KCBwYXR0ZXJuID0gbmV3IFJlZ0V4cCggXCIoXnxcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFx0XHRcdFwiKVwiICsgY2xhc3NOYW1lICsgXCIoXCIgKyB3aGl0ZXNwYWNlICsgXCJ8JClcIiApICkgJiYgY2xhc3NDYWNoZShcblx0XHRcdFx0XHRcdGNsYXNzTmFtZSwgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBwYXR0ZXJuLnRlc3QoXG5cdFx0XHRcdFx0XHRcdFx0dHlwZW9mIGVsZW0uY2xhc3NOYW1lID09PSBcInN0cmluZ1wiICYmIGVsZW0uY2xhc3NOYW1lIHx8XG5cdFx0XHRcdFx0XHRcdFx0dHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlICE9PSBcInVuZGVmaW5lZFwiICYmXG5cdFx0XHRcdFx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHxcblx0XHRcdFx0XHRcdFx0XHRcIlwiXG5cdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdH0gKTtcblx0XHR9LFxuXG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBuYW1lLCBvcGVyYXRvciwgY2hlY2sgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBTaXp6bGUuYXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0XHRcdGlmICggcmVzdWx0ID09IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIiE9XCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCAhb3BlcmF0b3IgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXN1bHQgKz0gXCJcIjtcblxuXHRcdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cblx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIj1cIiA/IHJlc3VsdCA9PT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIiE9XCIgPyByZXN1bHQgIT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJePVwiID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPT09IDAgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIio9XCIgPyBjaGVjayAmJiByZXN1bHQuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIkPVwiID8gY2hlY2sgJiYgcmVzdWx0LnNsaWNlKCAtY2hlY2subGVuZ3RoICkgPT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ+PVwiID8gKCBcIiBcIiArIHJlc3VsdC5yZXBsYWNlKCByd2hpdGVzcGFjZSwgXCIgXCIgKSArIFwiIFwiICkuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ8PVwiID8gcmVzdWx0ID09PSBjaGVjayB8fCByZXN1bHQuc2xpY2UoIDAsIGNoZWNrLmxlbmd0aCArIDEgKSA9PT0gY2hlY2sgKyBcIi1cIiA6XG5cdFx0XHRcdFx0ZmFsc2U7XG5cdFx0XHRcdC8qIGVzbGludC1lbmFibGUgbWF4LWxlbiAqL1xuXG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRcIkNISUxEXCI6IGZ1bmN0aW9uKCB0eXBlLCB3aGF0LCBfYXJndW1lbnQsIGZpcnN0LCBsYXN0ICkge1xuXHRcdFx0dmFyIHNpbXBsZSA9IHR5cGUuc2xpY2UoIDAsIDMgKSAhPT0gXCJudGhcIixcblx0XHRcdFx0Zm9yd2FyZCA9IHR5cGUuc2xpY2UoIC00ICkgIT09IFwibGFzdFwiLFxuXHRcdFx0XHRvZlR5cGUgPSB3aGF0ID09PSBcIm9mLXR5cGVcIjtcblxuXHRcdFx0cmV0dXJuIGZpcnN0ID09PSAxICYmIGxhc3QgPT09IDAgP1xuXG5cdFx0XHRcdC8vIFNob3J0Y3V0IGZvciA6bnRoLSoobilcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuICEhZWxlbS5wYXJlbnROb2RlO1xuXHRcdFx0XHR9IDpcblxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSwgX2NvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHR2YXIgY2FjaGUsIHVuaXF1ZUNhY2hlLCBvdXRlckNhY2hlLCBub2RlLCBub2RlSW5kZXgsIHN0YXJ0LFxuXHRcdFx0XHRcdFx0ZGlyID0gc2ltcGxlICE9PSBmb3J3YXJkID8gXCJuZXh0U2libGluZ1wiIDogXCJwcmV2aW91c1NpYmxpbmdcIixcblx0XHRcdFx0XHRcdHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZSxcblx0XHRcdFx0XHRcdG5hbWUgPSBvZlR5cGUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLFxuXHRcdFx0XHRcdFx0dXNlQ2FjaGUgPSAheG1sICYmICFvZlR5cGUsXG5cdFx0XHRcdFx0XHRkaWZmID0gZmFsc2U7XG5cblx0XHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblxuXHRcdFx0XHRcdFx0Ly8gOihmaXJzdHxsYXN0fG9ubHkpLShjaGlsZHxvZi10eXBlKVxuXHRcdFx0XHRcdFx0aWYgKCBzaW1wbGUgKSB7XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggZGlyICkge1xuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xuXHRcdFx0XHRcdFx0XHRcdHdoaWxlICggKCBub2RlID0gbm9kZVsgZGlyIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggb2ZUeXBlID9cblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBuYW1lIDpcblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gUmV2ZXJzZSBkaXJlY3Rpb24gZm9yIDpvbmx5LSogKGlmIHdlIGhhdmVuJ3QgeWV0IGRvbmUgc28pXG5cdFx0XHRcdFx0XHRcdFx0c3RhcnQgPSBkaXIgPSB0eXBlID09PSBcIm9ubHlcIiAmJiAhc3RhcnQgJiYgXCJuZXh0U2libGluZ1wiO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRzdGFydCA9IFsgZm9yd2FyZCA/IHBhcmVudC5maXJzdENoaWxkIDogcGFyZW50Lmxhc3RDaGlsZCBdO1xuXG5cdFx0XHRcdFx0XHQvLyBub24teG1sIDpudGgtY2hpbGQoLi4uKSBzdG9yZXMgY2FjaGUgZGF0YSBvbiBgcGFyZW50YFxuXHRcdFx0XHRcdFx0aWYgKCBmb3J3YXJkICYmIHVzZUNhY2hlICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFNlZWsgYGVsZW1gIGZyb20gYSBwcmV2aW91c2x5LWNhY2hlZCBpbmRleFxuXG5cdFx0XHRcdFx0XHRcdC8vIC4uLmluIGEgZ3ppcC1mcmllbmRseSB3YXlcblx0XHRcdFx0XHRcdFx0bm9kZSA9IHBhcmVudDtcblx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IG5vZGVbIGV4cGFuZG8gXSB8fCAoIG5vZGVbIGV4cGFuZG8gXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPDkgb25seVxuXHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcblx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGUgPSBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gfHxcblx0XHRcdFx0XHRcdFx0XHQoIG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdFx0Y2FjaGUgPSB1bmlxdWVDYWNoZVsgdHlwZSBdIHx8IFtdO1xuXHRcdFx0XHRcdFx0XHRub2RlSW5kZXggPSBjYWNoZVsgMCBdID09PSBkaXJydW5zICYmIGNhY2hlWyAxIF07XG5cdFx0XHRcdFx0XHRcdGRpZmYgPSBub2RlSW5kZXggJiYgY2FjaGVbIDIgXTtcblx0XHRcdFx0XHRcdFx0bm9kZSA9IG5vZGVJbmRleCAmJiBwYXJlbnQuY2hpbGROb2Rlc1sgbm9kZUluZGV4IF07XG5cblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBGYWxsYmFjayB0byBzZWVraW5nIGBlbGVtYCBmcm9tIHRoZSBzdGFydFxuXHRcdFx0XHRcdFx0XHRcdCggZGlmZiA9IG5vZGVJbmRleCA9IDAgKSB8fCBzdGFydC5wb3AoKSApICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gV2hlbiBmb3VuZCwgY2FjaGUgaW5kZXhlcyBvbiBgcGFyZW50YCBhbmQgYnJlYWtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgKytkaWZmICYmIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZVsgdHlwZSBdID0gWyBkaXJydW5zLCBub2RlSW5kZXgsIGRpZmYgXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFVzZSBwcmV2aW91c2x5LWNhY2hlZCBlbGVtZW50IGluZGV4IGlmIGF2YWlsYWJsZVxuXHRcdFx0XHRcdFx0XHRpZiAoIHVzZUNhY2hlICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gLi4uaW4gYSBnemlwLWZyaWVuZGx5IHdheVxuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xuXHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHwgKCBub2RlWyBleHBhbmRvIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPDkgb25seVxuXHRcdFx0XHRcdFx0XHRcdC8vIERlZmVuZCBhZ2FpbnN0IGNsb25lZCBhdHRyb3BlcnRpZXMgKGpRdWVyeSBnaC0xNzA5KVxuXHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0XHQoIG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdFx0XHRjYWNoZSA9IHVuaXF1ZUNhY2hlWyB0eXBlIF0gfHwgW107XG5cdFx0XHRcdFx0XHRcdFx0bm9kZUluZGV4ID0gY2FjaGVbIDAgXSA9PT0gZGlycnVucyAmJiBjYWNoZVsgMSBdO1xuXHRcdFx0XHRcdFx0XHRcdGRpZmYgPSBub2RlSW5kZXg7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHQvLyB4bWwgOm50aC1jaGlsZCguLi4pXG5cdFx0XHRcdFx0XHRcdC8vIG9yIDpudGgtbGFzdC1jaGlsZCguLi4pIG9yIDpudGgoLWxhc3QpPy1vZi10eXBlKC4uLilcblx0XHRcdFx0XHRcdFx0aWYgKCBkaWZmID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIFVzZSB0aGUgc2FtZSBsb29wIGFzIGFib3ZlIHRvIHNlZWsgYGVsZW1gIGZyb20gdGhlIHN0YXJ0XG5cdFx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0XHQoIGRpZmYgPSBub2RlSW5kZXggPSAwICkgfHwgc3RhcnQucG9wKCkgKSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCAoIG9mVHlwZSA/XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZVR5cGUgPT09IDEgKSAmJlxuXHRcdFx0XHRcdFx0XHRcdFx0XHQrK2RpZmYgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gQ2FjaGUgdGhlIGluZGV4IG9mIGVhY2ggZW5jb3VudGVyZWQgZWxlbWVudFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIHVzZUNhY2hlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCggbm9kZVsgZXhwYW5kbyBdID0ge30gKTtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KCBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGVbIHR5cGUgXSA9IFsgZGlycnVucywgZGlmZiBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBub2RlID09PSBlbGVtICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIEluY29ycG9yYXRlIHRoZSBvZmZzZXQsIHRoZW4gY2hlY2sgYWdhaW5zdCBjeWNsZSBzaXplXG5cdFx0XHRcdFx0XHRkaWZmIC09IGxhc3Q7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZGlmZiA9PT0gZmlyc3QgfHwgKCBkaWZmICUgZmlyc3QgPT09IDAgJiYgZGlmZiAvIGZpcnN0ID49IDAgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiUFNFVURPXCI6IGZ1bmN0aW9uKCBwc2V1ZG8sIGFyZ3VtZW50ICkge1xuXG5cdFx0XHQvLyBwc2V1ZG8tY2xhc3MgbmFtZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmVcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jcHNldWRvLWNsYXNzZXNcblx0XHRcdC8vIFByaW9yaXRpemUgYnkgY2FzZSBzZW5zaXRpdml0eSBpbiBjYXNlIGN1c3RvbSBwc2V1ZG9zIGFyZSBhZGRlZCB3aXRoIHVwcGVyY2FzZSBsZXR0ZXJzXG5cdFx0XHQvLyBSZW1lbWJlciB0aGF0IHNldEZpbHRlcnMgaW5oZXJpdHMgZnJvbSBwc2V1ZG9zXG5cdFx0XHR2YXIgYXJncyxcblx0XHRcdFx0Zm4gPSBFeHByLnBzZXVkb3NbIHBzZXVkbyBdIHx8IEV4cHIuc2V0RmlsdGVyc1sgcHNldWRvLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBwc2V1ZG86IFwiICsgcHNldWRvICk7XG5cblx0XHRcdC8vIFRoZSB1c2VyIG1heSB1c2UgY3JlYXRlUHNldWRvIHRvIGluZGljYXRlIHRoYXRcblx0XHRcdC8vIGFyZ3VtZW50cyBhcmUgbmVlZGVkIHRvIGNyZWF0ZSB0aGUgZmlsdGVyIGZ1bmN0aW9uXG5cdFx0XHQvLyBqdXN0IGFzIFNpenpsZSBkb2VzXG5cdFx0XHRpZiAoIGZuWyBleHBhbmRvIF0gKSB7XG5cdFx0XHRcdHJldHVybiBmbiggYXJndW1lbnQgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQnV0IG1haW50YWluIHN1cHBvcnQgZm9yIG9sZCBzaWduYXR1cmVzXG5cdFx0XHRpZiAoIGZuLmxlbmd0aCA+IDEgKSB7XG5cdFx0XHRcdGFyZ3MgPSBbIHBzZXVkbywgcHNldWRvLCBcIlwiLCBhcmd1bWVudCBdO1xuXHRcdFx0XHRyZXR1cm4gRXhwci5zZXRGaWx0ZXJzLmhhc093blByb3BlcnR5KCBwc2V1ZG8udG9Mb3dlckNhc2UoKSApID9cblx0XHRcdFx0XHRtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWVkLCBtYXRjaGVzICkge1xuXHRcdFx0XHRcdFx0dmFyIGlkeCxcblx0XHRcdFx0XHRcdFx0bWF0Y2hlZCA9IGZuKCBzZWVkLCBhcmd1bWVudCApLFxuXHRcdFx0XHRcdFx0XHRpID0gbWF0Y2hlZC5sZW5ndGg7XG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdFx0aWR4ID0gaW5kZXhPZiggc2VlZCwgbWF0Y2hlZFsgaSBdICk7XG5cdFx0XHRcdFx0XHRcdHNlZWRbIGlkeCBdID0gISggbWF0Y2hlc1sgaWR4IF0gPSBtYXRjaGVkWyBpIF0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9ICkgOlxuXHRcdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZuKCBlbGVtLCAwLCBhcmdzICk7XG5cdFx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZuO1xuXHRcdH1cblx0fSxcblxuXHRwc2V1ZG9zOiB7XG5cblx0XHQvLyBQb3RlbnRpYWxseSBjb21wbGV4IHBzZXVkb3Ncblx0XHRcIm5vdFwiOiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblxuXHRcdFx0Ly8gVHJpbSB0aGUgc2VsZWN0b3IgcGFzc2VkIHRvIGNvbXBpbGVcblx0XHRcdC8vIHRvIGF2b2lkIHRyZWF0aW5nIGxlYWRpbmcgYW5kIHRyYWlsaW5nXG5cdFx0XHQvLyBzcGFjZXMgYXMgY29tYmluYXRvcnNcblx0XHRcdHZhciBpbnB1dCA9IFtdLFxuXHRcdFx0XHRyZXN1bHRzID0gW10sXG5cdFx0XHRcdG1hdGNoZXIgPSBjb21waWxlKCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICkgKTtcblxuXHRcdFx0cmV0dXJuIG1hdGNoZXJbIGV4cGFuZG8gXSA/XG5cdFx0XHRcdG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMsIF9jb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0dmFyIGVsZW0sXG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQgPSBtYXRjaGVyKCBzZWVkLCBudWxsLCB4bWwsIFtdICksXG5cdFx0XHRcdFx0XHRpID0gc2VlZC5sZW5ndGg7XG5cblx0XHRcdFx0XHQvLyBNYXRjaCBlbGVtZW50cyB1bm1hdGNoZWQgYnkgYG1hdGNoZXJgXG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZWxlbSA9IHVubWF0Y2hlZFsgaSBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdHNlZWRbIGkgXSA9ICEoIG1hdGNoZXNbIGkgXSA9IGVsZW0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gKSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBfY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdGlucHV0WyAwIF0gPSBlbGVtO1xuXHRcdFx0XHRcdG1hdGNoZXIoIGlucHV0LCBudWxsLCB4bWwsIHJlc3VsdHMgKTtcblxuXHRcdFx0XHRcdC8vIERvbid0IGtlZXAgdGhlIGVsZW1lbnQgKGlzc3VlICMyOTkpXG5cdFx0XHRcdFx0aW5wdXRbIDAgXSA9IG51bGw7XG5cdFx0XHRcdFx0cmV0dXJuICFyZXN1bHRzLnBvcCgpO1xuXHRcdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdFwiaGFzXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gU2l6emxlKCBzZWxlY3RvciwgZWxlbSApLmxlbmd0aCA+IDA7XG5cdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdFwiY29udGFpbnNcIjogbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRcdHRleHQgPSB0ZXh0LnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiAoIGVsZW0udGV4dENvbnRlbnQgfHwgZ2V0VGV4dCggZWxlbSApICkuaW5kZXhPZiggdGV4dCApID4gLTE7XG5cdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdC8vIFwiV2hldGhlciBhbiBlbGVtZW50IGlzIHJlcHJlc2VudGVkIGJ5IGEgOmxhbmcoKSBzZWxlY3RvclxuXHRcdC8vIGlzIGJhc2VkIHNvbGVseSBvbiB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlXG5cdFx0Ly8gYmVpbmcgZXF1YWwgdG8gdGhlIGlkZW50aWZpZXIgQyxcblx0XHQvLyBvciBiZWdpbm5pbmcgd2l0aCB0aGUgaWRlbnRpZmllciBDIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IFwiLVwiLlxuXHRcdC8vIFRoZSBtYXRjaGluZyBvZiBDIGFnYWluc3QgdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZSBpcyBwZXJmb3JtZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LlxuXHRcdC8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuXCJcblx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2xhbmctcHNldWRvXG5cdFx0XCJsYW5nXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGxhbmcgKSB7XG5cblx0XHRcdC8vIGxhbmcgdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGlkZW50aWZpZXJcblx0XHRcdGlmICggIXJpZGVudGlmaWVyLnRlc3QoIGxhbmcgfHwgXCJcIiApICkge1xuXHRcdFx0XHRTaXp6bGUuZXJyb3IoIFwidW5zdXBwb3J0ZWQgbGFuZzogXCIgKyBsYW5nICk7XG5cdFx0XHR9XG5cdFx0XHRsYW5nID0gbGFuZy5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciBlbGVtTGFuZztcblx0XHRcdFx0ZG8ge1xuXHRcdFx0XHRcdGlmICggKCBlbGVtTGFuZyA9IGRvY3VtZW50SXNIVE1MID9cblx0XHRcdFx0XHRcdGVsZW0ubGFuZyA6XG5cdFx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZSggXCJ4bWw6bGFuZ1wiICkgfHwgZWxlbS5nZXRBdHRyaWJ1dGUoIFwibGFuZ1wiICkgKSApIHtcblxuXHRcdFx0XHRcdFx0ZWxlbUxhbmcgPSBlbGVtTGFuZy50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVsZW1MYW5nID09PSBsYW5nIHx8IGVsZW1MYW5nLmluZGV4T2YoIGxhbmcgKyBcIi1cIiApID09PSAwO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSB3aGlsZSAoICggZWxlbSA9IGVsZW0ucGFyZW50Tm9kZSApICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fTtcblx0XHR9ICksXG5cblx0XHQvLyBNaXNjZWxsYW5lb3VzXG5cdFx0XCJ0YXJnZXRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbiAmJiB3aW5kb3cubG9jYXRpb24uaGFzaDtcblx0XHRcdHJldHVybiBoYXNoICYmIGhhc2guc2xpY2UoIDEgKSA9PT0gZWxlbS5pZDtcblx0XHR9LFxuXG5cdFx0XCJyb290XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGRvY0VsZW07XG5cdFx0fSxcblxuXHRcdFwiZm9jdXNcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAmJlxuXHRcdFx0XHQoICFkb2N1bWVudC5oYXNGb2N1cyB8fCBkb2N1bWVudC5oYXNGb2N1cygpICkgJiZcblx0XHRcdFx0ISEoIGVsZW0udHlwZSB8fCBlbGVtLmhyZWYgfHwgfmVsZW0udGFiSW5kZXggKTtcblx0XHR9LFxuXG5cdFx0Ly8gQm9vbGVhbiBwcm9wZXJ0aWVzXG5cdFx0XCJlbmFibGVkXCI6IGNyZWF0ZURpc2FibGVkUHNldWRvKCBmYWxzZSApLFxuXHRcdFwiZGlzYWJsZWRcIjogY3JlYXRlRGlzYWJsZWRQc2V1ZG8oIHRydWUgKSxcblxuXHRcdFwiY2hlY2tlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0Ly8gSW4gQ1NTMywgOmNoZWNrZWQgc2hvdWxkIHJldHVybiBib3RoIGNoZWNrZWQgYW5kIHNlbGVjdGVkIGVsZW1lbnRzXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDExL1JFQy1jc3MzLXNlbGVjdG9ycy0yMDExMDkyOS8jY2hlY2tlZFxuXHRcdFx0dmFyIG5vZGVOYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuICggbm9kZU5hbWUgPT09IFwiaW5wdXRcIiAmJiAhIWVsZW0uY2hlY2tlZCApIHx8XG5cdFx0XHRcdCggbm9kZU5hbWUgPT09IFwib3B0aW9uXCIgJiYgISFlbGVtLnNlbGVjdGVkICk7XG5cdFx0fSxcblxuXHRcdFwic2VsZWN0ZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdC8vIEFjY2Vzc2luZyB0aGlzIHByb3BlcnR5IG1ha2VzIHNlbGVjdGVkLWJ5LWRlZmF1bHRcblx0XHRcdC8vIG9wdGlvbnMgaW4gU2FmYXJpIHdvcmsgcHJvcGVybHlcblx0XHRcdGlmICggZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0Ly8gQ29udGVudHNcblx0XHRcImVtcHR5XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2VtcHR5LXBzZXVkb1xuXHRcdFx0Ly8gOmVtcHR5IGlzIG5lZ2F0ZWQgYnkgZWxlbWVudCAoMSkgb3IgY29udGVudCBub2RlcyAodGV4dDogMzsgY2RhdGE6IDQ7IGVudGl0eSByZWY6IDUpLFxuXHRcdFx0Ly8gICBidXQgbm90IGJ5IG90aGVycyAoY29tbWVudDogODsgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbjogNzsgZXRjLilcblx0XHRcdC8vIG5vZGVUeXBlIDwgNiB3b3JrcyBiZWNhdXNlIGF0dHJpYnV0ZXMgKDIpIGRvIG5vdCBhcHBlYXIgYXMgY2hpbGRyZW5cblx0XHRcdGZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkge1xuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPCA2ICkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdFwicGFyZW50XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuICFFeHByLnBzZXVkb3NbIFwiZW1wdHlcIiBdKCBlbGVtICk7XG5cdFx0fSxcblxuXHRcdC8vIEVsZW1lbnQvaW5wdXQgdHlwZXNcblx0XHRcImhlYWRlclwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiByaGVhZGVyLnRlc3QoIGVsZW0ubm9kZU5hbWUgKTtcblx0XHR9LFxuXG5cdFx0XCJpbnB1dFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiByaW5wdXRzLnRlc3QoIGVsZW0ubm9kZU5hbWUgKTtcblx0XHR9LFxuXG5cdFx0XCJidXR0b25cIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBuYW1lID09PSBcImlucHV0XCIgJiYgZWxlbS50eXBlID09PSBcImJ1dHRvblwiIHx8IG5hbWUgPT09IFwiYnV0dG9uXCI7XG5cdFx0fSxcblxuXHRcdFwidGV4dFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBhdHRyO1xuXHRcdFx0cmV0dXJuIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJpbnB1dFwiICYmXG5cdFx0XHRcdGVsZW0udHlwZSA9PT0gXCJ0ZXh0XCIgJiZcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRTw4XG5cdFx0XHRcdC8vIE5ldyBIVE1MNSBhdHRyaWJ1dGUgdmFsdWVzIChlLmcuLCBcInNlYXJjaFwiKSBhcHBlYXIgd2l0aCBlbGVtLnR5cGUgPT09IFwidGV4dFwiXG5cdFx0XHRcdCggKCBhdHRyID0gZWxlbS5nZXRBdHRyaWJ1dGUoIFwidHlwZVwiICkgKSA9PSBudWxsIHx8XG5cdFx0XHRcdFx0YXR0ci50b0xvd2VyQ2FzZSgpID09PSBcInRleHRcIiApO1xuXHRcdH0sXG5cblx0XHQvLyBQb3NpdGlvbi1pbi1jb2xsZWN0aW9uXG5cdFx0XCJmaXJzdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBbIDAgXTtcblx0XHR9ICksXG5cblx0XHRcImxhc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIF9tYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHJldHVybiBbIGxlbmd0aCAtIDEgXTtcblx0XHR9ICksXG5cblx0XHRcImVxXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBfbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xuXHRcdFx0cmV0dXJuIFsgYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudCBdO1xuXHRcdH0gKSxcblxuXHRcdFwiZXZlblwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkgKz0gMiApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSApLFxuXG5cdFx0XCJvZGRcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAxO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0gKSxcblxuXHRcdFwibHRcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID9cblx0XHRcdFx0YXJndW1lbnQgKyBsZW5ndGggOlxuXHRcdFx0XHRhcmd1bWVudCA+IGxlbmd0aCA/XG5cdFx0XHRcdFx0bGVuZ3RoIDpcblx0XHRcdFx0XHRhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgLS1pID49IDA7ICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9ICksXG5cblx0XHRcImd0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCwgYXJndW1lbnQgKSB7XG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XG5cdFx0XHRmb3IgKCA7ICsraSA8IGxlbmd0aDsgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0gKVxuXHR9XG59O1xuXG5FeHByLnBzZXVkb3NbIFwibnRoXCIgXSA9IEV4cHIucHNldWRvc1sgXCJlcVwiIF07XG5cbi8vIEFkZCBidXR0b24vaW5wdXQgdHlwZSBwc2V1ZG9zXG5mb3IgKCBpIGluIHsgcmFkaW86IHRydWUsIGNoZWNrYm94OiB0cnVlLCBmaWxlOiB0cnVlLCBwYXNzd29yZDogdHJ1ZSwgaW1hZ2U6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApO1xufVxuZm9yICggaSBpbiB7IHN1Ym1pdDogdHJ1ZSwgcmVzZXQ6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVCdXR0b25Qc2V1ZG8oIGkgKTtcbn1cblxuLy8gRWFzeSBBUEkgZm9yIGNyZWF0aW5nIG5ldyBzZXRGaWx0ZXJzXG5mdW5jdGlvbiBzZXRGaWx0ZXJzKCkge31cbnNldEZpbHRlcnMucHJvdG90eXBlID0gRXhwci5maWx0ZXJzID0gRXhwci5wc2V1ZG9zO1xuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcblxudG9rZW5pemUgPSBTaXp6bGUudG9rZW5pemUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIHBhcnNlT25seSApIHtcblx0dmFyIG1hdGNoZWQsIG1hdGNoLCB0b2tlbnMsIHR5cGUsXG5cdFx0c29GYXIsIGdyb3VwcywgcHJlRmlsdGVycyxcblx0XHRjYWNoZWQgPSB0b2tlbkNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCBjYWNoZWQgKSB7XG5cdFx0cmV0dXJuIHBhcnNlT25seSA/IDAgOiBjYWNoZWQuc2xpY2UoIDAgKTtcblx0fVxuXG5cdHNvRmFyID0gc2VsZWN0b3I7XG5cdGdyb3VwcyA9IFtdO1xuXHRwcmVGaWx0ZXJzID0gRXhwci5wcmVGaWx0ZXI7XG5cblx0d2hpbGUgKCBzb0ZhciApIHtcblxuXHRcdC8vIENvbW1hIGFuZCBmaXJzdCBydW5cblx0XHRpZiAoICFtYXRjaGVkIHx8ICggbWF0Y2ggPSByY29tbWEuZXhlYyggc29GYXIgKSApICkge1xuXHRcdFx0aWYgKCBtYXRjaCApIHtcblxuXHRcdFx0XHQvLyBEb24ndCBjb25zdW1lIHRyYWlsaW5nIGNvbW1hcyBhcyB2YWxpZFxuXHRcdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaFsgMCBdLmxlbmd0aCApIHx8IHNvRmFyO1xuXHRcdFx0fVxuXHRcdFx0Z3JvdXBzLnB1c2goICggdG9rZW5zID0gW10gKSApO1xuXHRcdH1cblxuXHRcdG1hdGNoZWQgPSBmYWxzZTtcblxuXHRcdC8vIENvbWJpbmF0b3JzXG5cdFx0aWYgKCAoIG1hdGNoID0gcmNvbWJpbmF0b3JzLmV4ZWMoIHNvRmFyICkgKSApIHtcblx0XHRcdG1hdGNoZWQgPSBtYXRjaC5zaGlmdCgpO1xuXHRcdFx0dG9rZW5zLnB1c2goIHtcblx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cblx0XHRcdFx0Ly8gQ2FzdCBkZXNjZW5kYW50IGNvbWJpbmF0b3JzIHRvIHNwYWNlXG5cdFx0XHRcdHR5cGU6IG1hdGNoWyAwIF0ucmVwbGFjZSggcnRyaW0sIFwiIFwiIClcblx0XHRcdH0gKTtcblx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoZWQubGVuZ3RoICk7XG5cdFx0fVxuXG5cdFx0Ly8gRmlsdGVyc1xuXHRcdGZvciAoIHR5cGUgaW4gRXhwci5maWx0ZXIgKSB7XG5cdFx0XHRpZiAoICggbWF0Y2ggPSBtYXRjaEV4cHJbIHR5cGUgXS5leGVjKCBzb0ZhciApICkgJiYgKCAhcHJlRmlsdGVyc1sgdHlwZSBdIHx8XG5cdFx0XHRcdCggbWF0Y2ggPSBwcmVGaWx0ZXJzWyB0eXBlIF0oIG1hdGNoICkgKSApICkge1xuXHRcdFx0XHRtYXRjaGVkID0gbWF0Y2guc2hpZnQoKTtcblx0XHRcdFx0dG9rZW5zLnB1c2goIHtcblx0XHRcdFx0XHR2YWx1ZTogbWF0Y2hlZCxcblx0XHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRcdG1hdGNoZXM6IG1hdGNoXG5cdFx0XHRcdH0gKTtcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoICFtYXRjaGVkICkge1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGludmFsaWQgZXhjZXNzXG5cdC8vIGlmIHdlJ3JlIGp1c3QgcGFyc2luZ1xuXHQvLyBPdGhlcndpc2UsIHRocm93IGFuIGVycm9yIG9yIHJldHVybiB0b2tlbnNcblx0cmV0dXJuIHBhcnNlT25seSA/XG5cdFx0c29GYXIubGVuZ3RoIDpcblx0XHRzb0ZhciA/XG5cdFx0XHRTaXp6bGUuZXJyb3IoIHNlbGVjdG9yICkgOlxuXG5cdFx0XHQvLyBDYWNoZSB0aGUgdG9rZW5zXG5cdFx0XHR0b2tlbkNhY2hlKCBzZWxlY3RvciwgZ3JvdXBzICkuc2xpY2UoIDAgKTtcbn07XG5cbmZ1bmN0aW9uIHRvU2VsZWN0b3IoIHRva2VucyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IHRva2Vucy5sZW5ndGgsXG5cdFx0c2VsZWN0b3IgPSBcIlwiO1xuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRzZWxlY3RvciArPSB0b2tlbnNbIGkgXS52YWx1ZTtcblx0fVxuXHRyZXR1cm4gc2VsZWN0b3I7XG59XG5cbmZ1bmN0aW9uIGFkZENvbWJpbmF0b3IoIG1hdGNoZXIsIGNvbWJpbmF0b3IsIGJhc2UgKSB7XG5cdHZhciBkaXIgPSBjb21iaW5hdG9yLmRpcixcblx0XHRza2lwID0gY29tYmluYXRvci5uZXh0LFxuXHRcdGtleSA9IHNraXAgfHwgZGlyLFxuXHRcdGNoZWNrTm9uRWxlbWVudHMgPSBiYXNlICYmIGtleSA9PT0gXCJwYXJlbnROb2RlXCIsXG5cdFx0ZG9uZU5hbWUgPSBkb25lKys7XG5cblx0cmV0dXJuIGNvbWJpbmF0b3IuZmlyc3QgP1xuXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBjbG9zZXN0IGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHdoaWxlICggKCBlbGVtID0gZWxlbVsgZGlyIF0gKSApIHtcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fSA6XG5cblx0XHQvLyBDaGVjayBhZ2FpbnN0IGFsbCBhbmNlc3Rvci9wcmVjZWRpbmcgZWxlbWVudHNcblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIG9sZENhY2hlLCB1bmlxdWVDYWNoZSwgb3V0ZXJDYWNoZSxcblx0XHRcdFx0bmV3Q2FjaGUgPSBbIGRpcnJ1bnMsIGRvbmVOYW1lIF07XG5cblx0XHRcdC8vIFdlIGNhbid0IHNldCBhcmJpdHJhcnkgZGF0YSBvbiBYTUwgbm9kZXMsIHNvIHRoZXkgZG9uJ3QgYmVuZWZpdCBmcm9tIGNvbWJpbmF0b3IgY2FjaGluZ1xuXHRcdFx0aWYgKCB4bWwgKSB7XG5cdFx0XHRcdHdoaWxlICggKCBlbGVtID0gZWxlbVsgZGlyIF0gKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0d2hpbGUgKCAoIGVsZW0gPSBlbGVtWyBkaXIgXSApICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IGVsZW1bIGV4cGFuZG8gXSB8fCAoIGVsZW1bIGV4cGFuZG8gXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcblx0XHRcdFx0XHRcdC8vIERlZmVuZCBhZ2FpbnN0IGNsb25lZCBhdHRyb3BlcnRpZXMgKGpRdWVyeSBnaC0xNzA5KVxuXHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGUgPSBvdXRlckNhY2hlWyBlbGVtLnVuaXF1ZUlEIF0gfHxcblx0XHRcdFx0XHRcdFx0KCBvdXRlckNhY2hlWyBlbGVtLnVuaXF1ZUlEIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRpZiAoIHNraXAgJiYgc2tpcCA9PT0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICkge1xuXHRcdFx0XHRcdFx0XHRlbGVtID0gZWxlbVsgZGlyIF0gfHwgZWxlbTtcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoICggb2xkQ2FjaGUgPSB1bmlxdWVDYWNoZVsga2V5IF0gKSAmJlxuXHRcdFx0XHRcdFx0XHRvbGRDYWNoZVsgMCBdID09PSBkaXJydW5zICYmIG9sZENhY2hlWyAxIF0gPT09IGRvbmVOYW1lICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEFzc2lnbiB0byBuZXdDYWNoZSBzbyByZXN1bHRzIGJhY2stcHJvcGFnYXRlIHRvIHByZXZpb3VzIGVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdHJldHVybiAoIG5ld0NhY2hlWyAyIF0gPSBvbGRDYWNoZVsgMiBdICk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFJldXNlIG5ld2NhY2hlIHNvIHJlc3VsdHMgYmFjay1wcm9wYWdhdGUgdG8gcHJldmlvdXMgZWxlbWVudHNcblx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGVbIGtleSBdID0gbmV3Q2FjaGU7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQSBtYXRjaCBtZWFucyB3ZSdyZSBkb25lOyBhIGZhaWwgbWVhbnMgd2UgaGF2ZSB0byBrZWVwIGNoZWNraW5nXG5cdFx0XHRcdFx0XHRcdGlmICggKCBuZXdDYWNoZVsgMiBdID0gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG59XG5cbmZ1bmN0aW9uIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApIHtcblx0cmV0dXJuIG1hdGNoZXJzLmxlbmd0aCA+IDEgP1xuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR2YXIgaSA9IG1hdGNoZXJzLmxlbmd0aDtcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRpZiAoICFtYXRjaGVyc1sgaSBdKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gOlxuXHRcdG1hdGNoZXJzWyAwIF07XG59XG5cbmZ1bmN0aW9uIG11bHRpcGxlQ29udGV4dHMoIHNlbGVjdG9yLCBjb250ZXh0cywgcmVzdWx0cyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IGNvbnRleHRzLmxlbmd0aDtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0U2l6emxlKCBzZWxlY3RvciwgY29udGV4dHNbIGkgXSwgcmVzdWx0cyApO1xuXHR9XG5cdHJldHVybiByZXN1bHRzO1xufVxuXG5mdW5jdGlvbiBjb25kZW5zZSggdW5tYXRjaGVkLCBtYXAsIGZpbHRlciwgY29udGV4dCwgeG1sICkge1xuXHR2YXIgZWxlbSxcblx0XHRuZXdVbm1hdGNoZWQgPSBbXSxcblx0XHRpID0gMCxcblx0XHRsZW4gPSB1bm1hdGNoZWQubGVuZ3RoLFxuXHRcdG1hcHBlZCA9IG1hcCAhPSBudWxsO1xuXG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdGlmICggKCBlbGVtID0gdW5tYXRjaGVkWyBpIF0gKSApIHtcblx0XHRcdGlmICggIWZpbHRlciB8fCBmaWx0ZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRuZXdVbm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRpZiAoIG1hcHBlZCApIHtcblx0XHRcdFx0XHRtYXAucHVzaCggaSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG5ld1VubWF0Y2hlZDtcbn1cblxuZnVuY3Rpb24gc2V0TWF0Y2hlciggcHJlRmlsdGVyLCBzZWxlY3RvciwgbWF0Y2hlciwgcG9zdEZpbHRlciwgcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICkge1xuXHRpZiAoIHBvc3RGaWx0ZXIgJiYgIXBvc3RGaWx0ZXJbIGV4cGFuZG8gXSApIHtcblx0XHRwb3N0RmlsdGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbHRlciApO1xuXHR9XG5cdGlmICggcG9zdEZpbmRlciAmJiAhcG9zdEZpbmRlclsgZXhwYW5kbyBdICkge1xuXHRcdHBvc3RGaW5kZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKTtcblx0fVxuXHRyZXR1cm4gbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VlZCwgcmVzdWx0cywgY29udGV4dCwgeG1sICkge1xuXHRcdHZhciB0ZW1wLCBpLCBlbGVtLFxuXHRcdFx0cHJlTWFwID0gW10sXG5cdFx0XHRwb3N0TWFwID0gW10sXG5cdFx0XHRwcmVleGlzdGluZyA9IHJlc3VsdHMubGVuZ3RoLFxuXG5cdFx0XHQvLyBHZXQgaW5pdGlhbCBlbGVtZW50cyBmcm9tIHNlZWQgb3IgY29udGV4dFxuXHRcdFx0ZWxlbXMgPSBzZWVkIHx8IG11bHRpcGxlQ29udGV4dHMoXG5cdFx0XHRcdHNlbGVjdG9yIHx8IFwiKlwiLFxuXHRcdFx0XHRjb250ZXh0Lm5vZGVUeXBlID8gWyBjb250ZXh0IF0gOiBjb250ZXh0LFxuXHRcdFx0XHRbXVxuXHRcdFx0KSxcblxuXHRcdFx0Ly8gUHJlZmlsdGVyIHRvIGdldCBtYXRjaGVyIGlucHV0LCBwcmVzZXJ2aW5nIGEgbWFwIGZvciBzZWVkLXJlc3VsdHMgc3luY2hyb25pemF0aW9uXG5cdFx0XHRtYXRjaGVySW4gPSBwcmVGaWx0ZXIgJiYgKCBzZWVkIHx8ICFzZWxlY3RvciApID9cblx0XHRcdFx0Y29uZGVuc2UoIGVsZW1zLCBwcmVNYXAsIHByZUZpbHRlciwgY29udGV4dCwgeG1sICkgOlxuXHRcdFx0XHRlbGVtcyxcblxuXHRcdFx0bWF0Y2hlck91dCA9IG1hdGNoZXIgP1xuXG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgYSBwb3N0RmluZGVyLCBvciBmaWx0ZXJlZCBzZWVkLCBvciBub24tc2VlZCBwb3N0RmlsdGVyIG9yIHByZWV4aXN0aW5nIHJlc3VsdHMsXG5cdFx0XHRcdHBvc3RGaW5kZXIgfHwgKCBzZWVkID8gcHJlRmlsdGVyIDogcHJlZXhpc3RpbmcgfHwgcG9zdEZpbHRlciApID9cblxuXHRcdFx0XHRcdC8vIC4uLmludGVybWVkaWF0ZSBwcm9jZXNzaW5nIGlzIG5lY2Vzc2FyeVxuXHRcdFx0XHRcdFtdIDpcblxuXHRcdFx0XHRcdC8vIC4uLm90aGVyd2lzZSB1c2UgcmVzdWx0cyBkaXJlY3RseVxuXHRcdFx0XHRcdHJlc3VsdHMgOlxuXHRcdFx0XHRtYXRjaGVySW47XG5cblx0XHQvLyBGaW5kIHByaW1hcnkgbWF0Y2hlc1xuXHRcdGlmICggbWF0Y2hlciApIHtcblx0XHRcdG1hdGNoZXIoIG1hdGNoZXJJbiwgbWF0Y2hlck91dCwgY29udGV4dCwgeG1sICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcG9zdEZpbHRlclxuXHRcdGlmICggcG9zdEZpbHRlciApIHtcblx0XHRcdHRlbXAgPSBjb25kZW5zZSggbWF0Y2hlck91dCwgcG9zdE1hcCApO1xuXHRcdFx0cG9zdEZpbHRlciggdGVtcCwgW10sIGNvbnRleHQsIHhtbCApO1xuXG5cdFx0XHQvLyBVbi1tYXRjaCBmYWlsaW5nIGVsZW1lbnRzIGJ5IG1vdmluZyB0aGVtIGJhY2sgdG8gbWF0Y2hlckluXG5cdFx0XHRpID0gdGVtcC5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAoIGVsZW0gPSB0ZW1wWyBpIF0gKSApIHtcblx0XHRcdFx0XHRtYXRjaGVyT3V0WyBwb3N0TWFwWyBpIF0gXSA9ICEoIG1hdGNoZXJJblsgcG9zdE1hcFsgaSBdIF0gPSBlbGVtICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRpZiAoIHBvc3RGaW5kZXIgfHwgcHJlRmlsdGVyICkge1xuXHRcdFx0XHRpZiAoIHBvc3RGaW5kZXIgKSB7XG5cblx0XHRcdFx0XHQvLyBHZXQgdGhlIGZpbmFsIG1hdGNoZXJPdXQgYnkgY29uZGVuc2luZyB0aGlzIGludGVybWVkaWF0ZSBpbnRvIHBvc3RGaW5kZXIgY29udGV4dHNcblx0XHRcdFx0XHR0ZW1wID0gW107XG5cdFx0XHRcdFx0aSA9IG1hdGNoZXJPdXQubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoIGVsZW0gPSBtYXRjaGVyT3V0WyBpIF0gKSApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBSZXN0b3JlIG1hdGNoZXJJbiBzaW5jZSBlbGVtIGlzIG5vdCB5ZXQgYSBmaW5hbCBtYXRjaFxuXHRcdFx0XHRcdFx0XHR0ZW1wLnB1c2goICggbWF0Y2hlckluWyBpIF0gPSBlbGVtICkgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgKCBtYXRjaGVyT3V0ID0gW10gKSwgdGVtcCwgeG1sICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBNb3ZlIG1hdGNoZWQgZWxlbWVudHMgZnJvbSBzZWVkIHRvIHJlc3VsdHMgdG8ga2VlcCB0aGVtIHN5bmNocm9uaXplZFxuXHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdGlmICggKCBlbGVtID0gbWF0Y2hlck91dFsgaSBdICkgJiZcblx0XHRcdFx0XHRcdCggdGVtcCA9IHBvc3RGaW5kZXIgPyBpbmRleE9mKCBzZWVkLCBlbGVtICkgOiBwcmVNYXBbIGkgXSApID4gLTEgKSB7XG5cblx0XHRcdFx0XHRcdHNlZWRbIHRlbXAgXSA9ICEoIHJlc3VsdHNbIHRlbXAgXSA9IGVsZW0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEFkZCBlbGVtZW50cyB0byByZXN1bHRzLCB0aHJvdWdoIHBvc3RGaW5kZXIgaWYgZGVmaW5lZFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyT3V0ID0gY29uZGVuc2UoXG5cdFx0XHRcdG1hdGNoZXJPdXQgPT09IHJlc3VsdHMgP1xuXHRcdFx0XHRcdG1hdGNoZXJPdXQuc3BsaWNlKCBwcmVleGlzdGluZywgbWF0Y2hlck91dC5sZW5ndGggKSA6XG5cdFx0XHRcdFx0bWF0Y2hlck91dFxuXHRcdFx0KTtcblx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgcmVzdWx0cywgbWF0Y2hlck91dCwgeG1sICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBtYXRjaGVyT3V0ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMgKSB7XG5cdHZhciBjaGVja0NvbnRleHQsIG1hdGNoZXIsIGosXG5cdFx0bGVuID0gdG9rZW5zLmxlbmd0aCxcblx0XHRsZWFkaW5nUmVsYXRpdmUgPSBFeHByLnJlbGF0aXZlWyB0b2tlbnNbIDAgXS50eXBlIF0sXG5cdFx0aW1wbGljaXRSZWxhdGl2ZSA9IGxlYWRpbmdSZWxhdGl2ZSB8fCBFeHByLnJlbGF0aXZlWyBcIiBcIiBdLFxuXHRcdGkgPSBsZWFkaW5nUmVsYXRpdmUgPyAxIDogMCxcblxuXHRcdC8vIFRoZSBmb3VuZGF0aW9uYWwgbWF0Y2hlciBlbnN1cmVzIHRoYXQgZWxlbWVudHMgYXJlIHJlYWNoYWJsZSBmcm9tIHRvcC1sZXZlbCBjb250ZXh0KHMpXG5cdFx0bWF0Y2hDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gY2hlY2tDb250ZXh0O1xuXHRcdH0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSxcblx0XHRtYXRjaEFueUNvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBpbmRleE9mKCBjaGVja0NvbnRleHQsIGVsZW0gKSA+IC0xO1xuXHRcdH0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSxcblx0XHRtYXRjaGVycyA9IFsgZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciByZXQgPSAoICFsZWFkaW5nUmVsYXRpdmUgJiYgKCB4bWwgfHwgY29udGV4dCAhPT0gb3V0ZXJtb3N0Q29udGV4dCApICkgfHwgKFxuXHRcdFx0XHQoIGNoZWNrQ29udGV4dCA9IGNvbnRleHQgKS5ub2RlVHlwZSA/XG5cdFx0XHRcdFx0bWF0Y2hDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdFx0bWF0Y2hBbnlDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSApO1xuXG5cdFx0XHQvLyBBdm9pZCBoYW5naW5nIG9udG8gZWxlbWVudCAoaXNzdWUgIzI5OSlcblx0XHRcdGNoZWNrQ29udGV4dCA9IG51bGw7XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH0gXTtcblxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRpZiAoICggbWF0Y2hlciA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1sgaSBdLnR5cGUgXSApICkge1xuXHRcdFx0bWF0Y2hlcnMgPSBbIGFkZENvbWJpbmF0b3IoIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLCBtYXRjaGVyICkgXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWF0Y2hlciA9IEV4cHIuZmlsdGVyWyB0b2tlbnNbIGkgXS50eXBlIF0uYXBwbHkoIG51bGwsIHRva2Vuc1sgaSBdLm1hdGNoZXMgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIHNwZWNpYWwgdXBvbiBzZWVpbmcgYSBwb3NpdGlvbmFsIG1hdGNoZXJcblx0XHRcdGlmICggbWF0Y2hlclsgZXhwYW5kbyBdICkge1xuXG5cdFx0XHRcdC8vIEZpbmQgdGhlIG5leHQgcmVsYXRpdmUgb3BlcmF0b3IgKGlmIGFueSkgZm9yIHByb3BlciBoYW5kbGluZ1xuXHRcdFx0XHRqID0gKytpO1xuXHRcdFx0XHRmb3IgKCA7IGogPCBsZW47IGorKyApIHtcblx0XHRcdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbIHRva2Vuc1sgaiBdLnR5cGUgXSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gc2V0TWF0Y2hlcihcblx0XHRcdFx0XHRpID4gMSAmJiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSxcblx0XHRcdFx0XHRpID4gMSAmJiB0b1NlbGVjdG9yKFxuXG5cdFx0XHRcdFx0Ly8gSWYgdGhlIHByZWNlZGluZyB0b2tlbiB3YXMgYSBkZXNjZW5kYW50IGNvbWJpbmF0b3IsIGluc2VydCBhbiBpbXBsaWNpdCBhbnktZWxlbWVudCBgKmBcblx0XHRcdFx0XHR0b2tlbnNcblx0XHRcdFx0XHRcdC5zbGljZSggMCwgaSAtIDEgKVxuXHRcdFx0XHRcdFx0LmNvbmNhdCggeyB2YWx1ZTogdG9rZW5zWyBpIC0gMiBdLnR5cGUgPT09IFwiIFwiID8gXCIqXCIgOiBcIlwiIH0gKVxuXHRcdFx0XHRcdCkucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApLFxuXHRcdFx0XHRcdG1hdGNoZXIsXG5cdFx0XHRcdFx0aSA8IGogJiYgbWF0Y2hlckZyb21Ub2tlbnMoIHRva2Vucy5zbGljZSggaSwgaiApICksXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiBtYXRjaGVyRnJvbVRva2VucyggKCB0b2tlbnMgPSB0b2tlbnMuc2xpY2UoIGogKSApICksXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0bWF0Y2hlcnMucHVzaCggbWF0Y2hlciApO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKTtcbn1cblxuZnVuY3Rpb24gbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkge1xuXHR2YXIgYnlTZXQgPSBzZXRNYXRjaGVycy5sZW5ndGggPiAwLFxuXHRcdGJ5RWxlbWVudCA9IGVsZW1lbnRNYXRjaGVycy5sZW5ndGggPiAwLFxuXHRcdHN1cGVyTWF0Y2hlciA9IGZ1bmN0aW9uKCBzZWVkLCBjb250ZXh0LCB4bWwsIHJlc3VsdHMsIG91dGVybW9zdCApIHtcblx0XHRcdHZhciBlbGVtLCBqLCBtYXRjaGVyLFxuXHRcdFx0XHRtYXRjaGVkQ291bnQgPSAwLFxuXHRcdFx0XHRpID0gXCIwXCIsXG5cdFx0XHRcdHVubWF0Y2hlZCA9IHNlZWQgJiYgW10sXG5cdFx0XHRcdHNldE1hdGNoZWQgPSBbXSxcblx0XHRcdFx0Y29udGV4dEJhY2t1cCA9IG91dGVybW9zdENvbnRleHQsXG5cblx0XHRcdFx0Ly8gV2UgbXVzdCBhbHdheXMgaGF2ZSBlaXRoZXIgc2VlZCBlbGVtZW50cyBvciBvdXRlcm1vc3QgY29udGV4dFxuXHRcdFx0XHRlbGVtcyA9IHNlZWQgfHwgYnlFbGVtZW50ICYmIEV4cHIuZmluZFsgXCJUQUdcIiBdKCBcIipcIiwgb3V0ZXJtb3N0ICksXG5cblx0XHRcdFx0Ly8gVXNlIGludGVnZXIgZGlycnVucyBpZmYgdGhpcyBpcyB0aGUgb3V0ZXJtb3N0IG1hdGNoZXJcblx0XHRcdFx0ZGlycnVuc1VuaXF1ZSA9ICggZGlycnVucyArPSBjb250ZXh0QmFja3VwID09IG51bGwgPyAxIDogTWF0aC5yYW5kb20oKSB8fCAwLjEgKSxcblx0XHRcdFx0bGVuID0gZWxlbXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHRcdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dCA9PSBkb2N1bWVudCB8fCBjb250ZXh0IHx8IG91dGVybW9zdDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIGVsZW1lbnRzIHBhc3NpbmcgZWxlbWVudE1hdGNoZXJzIGRpcmVjdGx5IHRvIHJlc3VsdHNcblx0XHRcdC8vIFN1cHBvcnQ6IElFPDksIFNhZmFyaVxuXHRcdFx0Ly8gVG9sZXJhdGUgTm9kZUxpc3QgcHJvcGVydGllcyAoSUU6IFwibGVuZ3RoXCI7IFNhZmFyaTogPG51bWJlcj4pIG1hdGNoaW5nIGVsZW1lbnRzIGJ5IGlkXG5cdFx0XHRmb3IgKCA7IGkgIT09IGxlbiAmJiAoIGVsZW0gPSBlbGVtc1sgaSBdICkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGJ5RWxlbWVudCAmJiBlbGVtICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0XHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRcdFx0XHRpZiAoICFjb250ZXh0ICYmIGVsZW0ub3duZXJEb2N1bWVudCAhPSBkb2N1bWVudCApIHtcblx0XHRcdFx0XHRcdHNldERvY3VtZW50KCBlbGVtICk7XG5cdFx0XHRcdFx0XHR4bWwgPSAhZG9jdW1lbnRJc0hUTUw7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHdoaWxlICggKCBtYXRjaGVyID0gZWxlbWVudE1hdGNoZXJzWyBqKysgXSApICkge1xuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVyKCBlbGVtLCBjb250ZXh0IHx8IGRvY3VtZW50LCB4bWwgKSApIHtcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFRyYWNrIHVubWF0Y2hlZCBlbGVtZW50cyBmb3Igc2V0IGZpbHRlcnNcblx0XHRcdFx0aWYgKCBieVNldCApIHtcblxuXHRcdFx0XHRcdC8vIFRoZXkgd2lsbCBoYXZlIGdvbmUgdGhyb3VnaCBhbGwgcG9zc2libGUgbWF0Y2hlcnNcblx0XHRcdFx0XHRpZiAoICggZWxlbSA9ICFtYXRjaGVyICYmIGVsZW0gKSApIHtcblx0XHRcdFx0XHRcdG1hdGNoZWRDb3VudC0tO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIExlbmd0aGVuIHRoZSBhcnJheSBmb3IgZXZlcnkgZWxlbWVudCwgbWF0Y2hlZCBvciBub3Rcblx0XHRcdFx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBgaWAgaXMgbm93IHRoZSBjb3VudCBvZiBlbGVtZW50cyB2aXNpdGVkIGFib3ZlLCBhbmQgYWRkaW5nIGl0IHRvIGBtYXRjaGVkQ291bnRgXG5cdFx0XHQvLyBtYWtlcyB0aGUgbGF0dGVyIG5vbm5lZ2F0aXZlLlxuXHRcdFx0bWF0Y2hlZENvdW50ICs9IGk7XG5cblx0XHRcdC8vIEFwcGx5IHNldCBmaWx0ZXJzIHRvIHVubWF0Y2hlZCBlbGVtZW50c1xuXHRcdFx0Ly8gTk9URTogVGhpcyBjYW4gYmUgc2tpcHBlZCBpZiB0aGVyZSBhcmUgbm8gdW5tYXRjaGVkIGVsZW1lbnRzIChpLmUuLCBgbWF0Y2hlZENvdW50YFxuXHRcdFx0Ly8gZXF1YWxzIGBpYCksIHVubGVzcyB3ZSBkaWRuJ3QgdmlzaXQgX2FueV8gZWxlbWVudHMgaW4gdGhlIGFib3ZlIGxvb3AgYmVjYXVzZSB3ZSBoYXZlXG5cdFx0XHQvLyBubyBlbGVtZW50IG1hdGNoZXJzIGFuZCBubyBzZWVkLlxuXHRcdFx0Ly8gSW5jcmVtZW50aW5nIGFuIGluaXRpYWxseS1zdHJpbmcgXCIwXCIgYGlgIGFsbG93cyBgaWAgdG8gcmVtYWluIGEgc3RyaW5nIG9ubHkgaW4gdGhhdFxuXHRcdFx0Ly8gY2FzZSwgd2hpY2ggd2lsbCByZXN1bHQgaW4gYSBcIjAwXCIgYG1hdGNoZWRDb3VudGAgdGhhdCBkaWZmZXJzIGZyb20gYGlgIGJ1dCBpcyBhbHNvXG5cdFx0XHQvLyBudW1lcmljYWxseSB6ZXJvLlxuXHRcdFx0aWYgKCBieVNldCAmJiBpICE9PSBtYXRjaGVkQ291bnQgKSB7XG5cdFx0XHRcdGogPSAwO1xuXHRcdFx0XHR3aGlsZSAoICggbWF0Y2hlciA9IHNldE1hdGNoZXJzWyBqKysgXSApICkge1xuXHRcdFx0XHRcdG1hdGNoZXIoIHVubWF0Y2hlZCwgc2V0TWF0Y2hlZCwgY29udGV4dCwgeG1sICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIHNlZWQgKSB7XG5cblx0XHRcdFx0XHQvLyBSZWludGVncmF0ZSBlbGVtZW50IG1hdGNoZXMgdG8gZWxpbWluYXRlIHRoZSBuZWVkIGZvciBzb3J0aW5nXG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVkQ291bnQgPiAwICkge1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggISggdW5tYXRjaGVkWyBpIF0gfHwgc2V0TWF0Y2hlZFsgaSBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c2V0TWF0Y2hlZFsgaSBdID0gcG9wLmNhbGwoIHJlc3VsdHMgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIERpc2NhcmQgaW5kZXggcGxhY2Vob2xkZXIgdmFsdWVzIHRvIGdldCBvbmx5IGFjdHVhbCBtYXRjaGVzXG5cdFx0XHRcdFx0c2V0TWF0Y2hlZCA9IGNvbmRlbnNlKCBzZXRNYXRjaGVkICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBZGQgbWF0Y2hlcyB0byByZXN1bHRzXG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNldE1hdGNoZWQgKTtcblxuXHRcdFx0XHQvLyBTZWVkbGVzcyBzZXQgbWF0Y2hlcyBzdWNjZWVkaW5nIG11bHRpcGxlIHN1Y2Nlc3NmdWwgbWF0Y2hlcnMgc3RpcHVsYXRlIHNvcnRpbmdcblx0XHRcdFx0aWYgKCBvdXRlcm1vc3QgJiYgIXNlZWQgJiYgc2V0TWF0Y2hlZC5sZW5ndGggPiAwICYmXG5cdFx0XHRcdFx0KCBtYXRjaGVkQ291bnQgKyBzZXRNYXRjaGVycy5sZW5ndGggKSA+IDEgKSB7XG5cblx0XHRcdFx0XHRTaXp6bGUudW5pcXVlU29ydCggcmVzdWx0cyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIE92ZXJyaWRlIG1hbmlwdWxhdGlvbiBvZiBnbG9iYWxzIGJ5IG5lc3RlZCBtYXRjaGVyc1xuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dEJhY2t1cDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHVubWF0Y2hlZDtcblx0XHR9O1xuXG5cdHJldHVybiBieVNldCA/XG5cdFx0bWFya0Z1bmN0aW9uKCBzdXBlck1hdGNoZXIgKSA6XG5cdFx0c3VwZXJNYXRjaGVyO1xufVxuXG5jb21waWxlID0gU2l6emxlLmNvbXBpbGUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIG1hdGNoIC8qIEludGVybmFsIFVzZSBPbmx5ICovICkge1xuXHR2YXIgaSxcblx0XHRzZXRNYXRjaGVycyA9IFtdLFxuXHRcdGVsZW1lbnRNYXRjaGVycyA9IFtdLFxuXHRcdGNhY2hlZCA9IGNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXTtcblxuXHRpZiAoICFjYWNoZWQgKSB7XG5cblx0XHQvLyBHZW5lcmF0ZSBhIGZ1bmN0aW9uIG9mIHJlY3Vyc2l2ZSBmdW5jdGlvbnMgdGhhdCBjYW4gYmUgdXNlZCB0byBjaGVjayBlYWNoIGVsZW1lbnRcblx0XHRpZiAoICFtYXRjaCApIHtcblx0XHRcdG1hdGNoID0gdG9rZW5pemUoIHNlbGVjdG9yICk7XG5cdFx0fVxuXHRcdGkgPSBtYXRjaC5sZW5ndGg7XG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRjYWNoZWQgPSBtYXRjaGVyRnJvbVRva2VucyggbWF0Y2hbIGkgXSApO1xuXHRcdFx0aWYgKCBjYWNoZWRbIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0c2V0TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlbGVtZW50TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FjaGUgdGhlIGNvbXBpbGVkIGZ1bmN0aW9uXG5cdFx0Y2FjaGVkID0gY29tcGlsZXJDYWNoZShcblx0XHRcdHNlbGVjdG9yLFxuXHRcdFx0bWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzIClcblx0XHQpO1xuXG5cdFx0Ly8gU2F2ZSBzZWxlY3RvciBhbmQgdG9rZW5pemF0aW9uXG5cdFx0Y2FjaGVkLnNlbGVjdG9yID0gc2VsZWN0b3I7XG5cdH1cblx0cmV0dXJuIGNhY2hlZDtcbn07XG5cbi8qKlxuICogQSBsb3ctbGV2ZWwgc2VsZWN0aW9uIGZ1bmN0aW9uIHRoYXQgd29ya3Mgd2l0aCBTaXp6bGUncyBjb21waWxlZFxuICogIHNlbGVjdG9yIGZ1bmN0aW9uc1xuICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHNlbGVjdG9yIEEgc2VsZWN0b3Igb3IgYSBwcmUtY29tcGlsZWRcbiAqICBzZWxlY3RvciBmdW5jdGlvbiBidWlsdCB3aXRoIFNpenpsZS5jb21waWxlXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGNvbnRleHRcbiAqIEBwYXJhbSB7QXJyYXl9IFtyZXN1bHRzXVxuICogQHBhcmFtIHtBcnJheX0gW3NlZWRdIEEgc2V0IG9mIGVsZW1lbnRzIHRvIG1hdGNoIGFnYWluc3RcbiAqL1xuc2VsZWN0ID0gU2l6emxlLnNlbGVjdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcblx0dmFyIGksIHRva2VucywgdG9rZW4sIHR5cGUsIGZpbmQsXG5cdFx0Y29tcGlsZWQgPSB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiAmJiBzZWxlY3Rvcixcblx0XHRtYXRjaCA9ICFzZWVkICYmIHRva2VuaXplKCAoIHNlbGVjdG9yID0gY29tcGlsZWQuc2VsZWN0b3IgfHwgc2VsZWN0b3IgKSApO1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFRyeSB0byBtaW5pbWl6ZSBvcGVyYXRpb25zIGlmIHRoZXJlIGlzIG9ubHkgb25lIHNlbGVjdG9yIGluIHRoZSBsaXN0IGFuZCBubyBzZWVkXG5cdC8vICh0aGUgbGF0dGVyIG9mIHdoaWNoIGd1YXJhbnRlZXMgdXMgY29udGV4dClcblx0aWYgKCBtYXRjaC5sZW5ndGggPT09IDEgKSB7XG5cblx0XHQvLyBSZWR1Y2UgY29udGV4dCBpZiB0aGUgbGVhZGluZyBjb21wb3VuZCBzZWxlY3RvciBpcyBhbiBJRFxuXHRcdHRva2VucyA9IG1hdGNoWyAwIF0gPSBtYXRjaFsgMCBdLnNsaWNlKCAwICk7XG5cdFx0aWYgKCB0b2tlbnMubGVuZ3RoID4gMiAmJiAoIHRva2VuID0gdG9rZW5zWyAwIF0gKS50eXBlID09PSBcIklEXCIgJiZcblx0XHRcdGNvbnRleHQubm9kZVR5cGUgPT09IDkgJiYgZG9jdW1lbnRJc0hUTUwgJiYgRXhwci5yZWxhdGl2ZVsgdG9rZW5zWyAxIF0udHlwZSBdICkge1xuXG5cdFx0XHRjb250ZXh0ID0gKCBFeHByLmZpbmRbIFwiSURcIiBdKCB0b2tlbi5tYXRjaGVzWyAwIF1cblx0XHRcdFx0LnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICksIGNvbnRleHQgKSB8fCBbXSApWyAwIF07XG5cdFx0XHRpZiAoICFjb250ZXh0ICkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0Ly8gUHJlY29tcGlsZWQgbWF0Y2hlcnMgd2lsbCBzdGlsbCB2ZXJpZnkgYW5jZXN0cnksIHNvIHN0ZXAgdXAgYSBsZXZlbFxuXHRcdFx0fSBlbHNlIGlmICggY29tcGlsZWQgKSB7XG5cdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0LnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cblx0XHRcdHNlbGVjdG9yID0gc2VsZWN0b3Iuc2xpY2UoIHRva2Vucy5zaGlmdCgpLnZhbHVlLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZldGNoIGEgc2VlZCBzZXQgZm9yIHJpZ2h0LXRvLWxlZnQgbWF0Y2hpbmdcblx0XHRpID0gbWF0Y2hFeHByWyBcIm5lZWRzQ29udGV4dFwiIF0udGVzdCggc2VsZWN0b3IgKSA/IDAgOiB0b2tlbnMubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0dG9rZW4gPSB0b2tlbnNbIGkgXTtcblxuXHRcdFx0Ly8gQWJvcnQgaWYgd2UgaGl0IGEgY29tYmluYXRvclxuXHRcdFx0aWYgKCBFeHByLnJlbGF0aXZlWyAoIHR5cGUgPSB0b2tlbi50eXBlICkgXSApIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoICggZmluZCA9IEV4cHIuZmluZFsgdHlwZSBdICkgKSB7XG5cblx0XHRcdFx0Ly8gU2VhcmNoLCBleHBhbmRpbmcgY29udGV4dCBmb3IgbGVhZGluZyBzaWJsaW5nIGNvbWJpbmF0b3JzXG5cdFx0XHRcdGlmICggKCBzZWVkID0gZmluZChcblx0XHRcdFx0XHR0b2tlbi5tYXRjaGVzWyAwIF0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKSxcblx0XHRcdFx0XHRyc2libGluZy50ZXN0KCB0b2tlbnNbIDAgXS50eXBlICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8XG5cdFx0XHRcdFx0XHRjb250ZXh0XG5cdFx0XHRcdCkgKSApIHtcblxuXHRcdFx0XHRcdC8vIElmIHNlZWQgaXMgZW1wdHkgb3Igbm8gdG9rZW5zIHJlbWFpbiwgd2UgY2FuIHJldHVybiBlYXJseVxuXHRcdFx0XHRcdHRva2Vucy5zcGxpY2UoIGksIDEgKTtcblx0XHRcdFx0XHRzZWxlY3RvciA9IHNlZWQubGVuZ3RoICYmIHRvU2VsZWN0b3IoIHRva2VucyApO1xuXHRcdFx0XHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2VlZCApO1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBDb21waWxlIGFuZCBleGVjdXRlIGEgZmlsdGVyaW5nIGZ1bmN0aW9uIGlmIG9uZSBpcyBub3QgcHJvdmlkZWRcblx0Ly8gUHJvdmlkZSBgbWF0Y2hgIHRvIGF2b2lkIHJldG9rZW5pemF0aW9uIGlmIHdlIG1vZGlmaWVkIHRoZSBzZWxlY3RvciBhYm92ZVxuXHQoIGNvbXBpbGVkIHx8IGNvbXBpbGUoIHNlbGVjdG9yLCBtYXRjaCApICkoXG5cdFx0c2VlZCxcblx0XHRjb250ZXh0LFxuXHRcdCFkb2N1bWVudElzSFRNTCxcblx0XHRyZXN1bHRzLFxuXHRcdCFjb250ZXh0IHx8IHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcblx0KTtcblx0cmV0dXJuIHJlc3VsdHM7XG59O1xuXG4vLyBPbmUtdGltZSBhc3NpZ25tZW50c1xuXG4vLyBTb3J0IHN0YWJpbGl0eVxuc3VwcG9ydC5zb3J0U3RhYmxlID0gZXhwYW5kby5zcGxpdCggXCJcIiApLnNvcnQoIHNvcnRPcmRlciApLmpvaW4oIFwiXCIgKSA9PT0gZXhwYW5kbztcblxuLy8gU3VwcG9ydDogQ2hyb21lIDE0LTM1K1xuLy8gQWx3YXlzIGFzc3VtZSBkdXBsaWNhdGVzIGlmIHRoZXkgYXJlbid0IHBhc3NlZCB0byB0aGUgY29tcGFyaXNvbiBmdW5jdGlvblxuc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzID0gISFoYXNEdXBsaWNhdGU7XG5cbi8vIEluaXRpYWxpemUgYWdhaW5zdCB0aGUgZGVmYXVsdCBkb2N1bWVudFxuc2V0RG9jdW1lbnQoKTtcblxuLy8gU3VwcG9ydDogV2Via2l0PDUzNy4zMiAtIFNhZmFyaSA2LjAuMy9DaHJvbWUgMjUgKGZpeGVkIGluIENocm9tZSAyNylcbi8vIERldGFjaGVkIG5vZGVzIGNvbmZvdW5kaW5nbHkgZm9sbG93ICplYWNoIG90aGVyKlxuc3VwcG9ydC5zb3J0RGV0YWNoZWQgPSBhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblxuXHQvLyBTaG91bGQgcmV0dXJuIDEsIGJ1dCByZXR1cm5zIDQgKGZvbGxvd2luZylcblx0cmV0dXJuIGVsLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImZpZWxkc2V0XCIgKSApICYgMTtcbn0gKTtcblxuLy8gU3VwcG9ydDogSUU8OFxuLy8gUHJldmVudCBhdHRyaWJ1dGUvcHJvcGVydHkgXCJpbnRlcnBvbGF0aW9uXCJcbi8vIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1MzY0MjklMjhWUy44NSUyOS5hc3B4XG5pZiAoICFhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0ZWwuaW5uZXJIVE1MID0gXCI8YSBocmVmPScjJz48L2E+XCI7XG5cdHJldHVybiBlbC5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSggXCJocmVmXCIgKSA9PT0gXCIjXCI7XG59ICkgKSB7XG5cdGFkZEhhbmRsZSggXCJ0eXBlfGhyZWZ8aGVpZ2h0fHdpZHRoXCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSwgbmFtZS50b0xvd2VyQ2FzZSgpID09PSBcInR5cGVcIiA/IDEgOiAyICk7XG5cdFx0fVxuXHR9ICk7XG59XG5cbi8vIFN1cHBvcnQ6IElFPDlcbi8vIFVzZSBkZWZhdWx0VmFsdWUgaW4gcGxhY2Ugb2YgZ2V0QXR0cmlidXRlKFwidmFsdWVcIilcbmlmICggIXN1cHBvcnQuYXR0cmlidXRlcyB8fCAhYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdGVsLmlubmVySFRNTCA9IFwiPGlucHV0Lz5cIjtcblx0ZWwuZmlyc3RDaGlsZC5zZXRBdHRyaWJ1dGUoIFwidmFsdWVcIiwgXCJcIiApO1xuXHRyZXR1cm4gZWwuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoIFwidmFsdWVcIiApID09PSBcIlwiO1xufSApICkge1xuXHRhZGRIYW5kbGUoIFwidmFsdWVcIiwgZnVuY3Rpb24oIGVsZW0sIF9uYW1lLCBpc1hNTCApIHtcblx0XHRpZiAoICFpc1hNTCAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiApIHtcblx0XHRcdHJldHVybiBlbGVtLmRlZmF1bHRWYWx1ZTtcblx0XHR9XG5cdH0gKTtcbn1cblxuLy8gU3VwcG9ydDogSUU8OVxuLy8gVXNlIGdldEF0dHJpYnV0ZU5vZGUgdG8gZmV0Y2ggYm9vbGVhbnMgd2hlbiBnZXRBdHRyaWJ1dGUgbGllc1xuaWYgKCAhYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdHJldHVybiBlbC5nZXRBdHRyaWJ1dGUoIFwiZGlzYWJsZWRcIiApID09IG51bGw7XG59ICkgKSB7XG5cdGFkZEhhbmRsZSggYm9vbGVhbnMsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHR2YXIgdmFsO1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0cmV0dXJuIGVsZW1bIG5hbWUgXSA9PT0gdHJ1ZSA/IG5hbWUudG9Mb3dlckNhc2UoKSA6XG5cdFx0XHRcdCggdmFsID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBuYW1lICkgKSAmJiB2YWwuc3BlY2lmaWVkID9cblx0XHRcdFx0XHR2YWwudmFsdWUgOlxuXHRcdFx0XHRcdG51bGw7XG5cdFx0fVxuXHR9ICk7XG59XG5cbnJldHVybiBTaXp6bGU7XG5cbn0gKSggd2luZG93ICk7XG5cblxuXG5qUXVlcnkuZmluZCA9IFNpenpsZTtcbmpRdWVyeS5leHByID0gU2l6emxlLnNlbGVjdG9ycztcblxuLy8gRGVwcmVjYXRlZFxualF1ZXJ5LmV4cHJbIFwiOlwiIF0gPSBqUXVlcnkuZXhwci5wc2V1ZG9zO1xualF1ZXJ5LnVuaXF1ZVNvcnQgPSBqUXVlcnkudW5pcXVlID0gU2l6emxlLnVuaXF1ZVNvcnQ7XG5qUXVlcnkudGV4dCA9IFNpenpsZS5nZXRUZXh0O1xualF1ZXJ5LmlzWE1MRG9jID0gU2l6emxlLmlzWE1MO1xualF1ZXJ5LmNvbnRhaW5zID0gU2l6emxlLmNvbnRhaW5zO1xualF1ZXJ5LmVzY2FwZVNlbGVjdG9yID0gU2l6emxlLmVzY2FwZTtcblxuXG5cblxudmFyIGRpciA9IGZ1bmN0aW9uKCBlbGVtLCBkaXIsIHVudGlsICkge1xuXHR2YXIgbWF0Y2hlZCA9IFtdLFxuXHRcdHRydW5jYXRlID0gdW50aWwgIT09IHVuZGVmaW5lZDtcblxuXHR3aGlsZSAoICggZWxlbSA9IGVsZW1bIGRpciBdICkgJiYgZWxlbS5ub2RlVHlwZSAhPT0gOSApIHtcblx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRpZiAoIHRydW5jYXRlICYmIGpRdWVyeSggZWxlbSApLmlzKCB1bnRpbCApICkge1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdG1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbWF0Y2hlZDtcbn07XG5cblxudmFyIHNpYmxpbmdzID0gZnVuY3Rpb24oIG4sIGVsZW0gKSB7XG5cdHZhciBtYXRjaGVkID0gW107XG5cblx0Zm9yICggOyBuOyBuID0gbi5uZXh0U2libGluZyApIHtcblx0XHRpZiAoIG4ubm9kZVR5cGUgPT09IDEgJiYgbiAhPT0gZWxlbSApIHtcblx0XHRcdG1hdGNoZWQucHVzaCggbiApO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBtYXRjaGVkO1xufTtcblxuXG52YXIgcm5lZWRzQ29udGV4dCA9IGpRdWVyeS5leHByLm1hdGNoLm5lZWRzQ29udGV4dDtcblxuXG5cbmZ1bmN0aW9uIG5vZGVOYW1lKCBlbGVtLCBuYW1lICkge1xuXG4gIHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXG59O1xudmFyIHJzaW5nbGVUYWcgPSAoIC9ePChbYS16XVteXFwvXFwwPjpcXHgyMFxcdFxcclxcblxcZl0qKVtcXHgyMFxcdFxcclxcblxcZl0qXFwvPz4oPzo8XFwvXFwxPnwpJC9pICk7XG5cblxuXG4vLyBJbXBsZW1lbnQgdGhlIGlkZW50aWNhbCBmdW5jdGlvbmFsaXR5IGZvciBmaWx0ZXIgYW5kIG5vdFxuZnVuY3Rpb24gd2lubm93KCBlbGVtZW50cywgcXVhbGlmaWVyLCBub3QgKSB7XG5cdGlmICggaXNGdW5jdGlvbiggcXVhbGlmaWVyICkgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gISFxdWFsaWZpZXIuY2FsbCggZWxlbSwgaSwgZWxlbSApICE9PSBub3Q7XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gU2luZ2xlIGVsZW1lbnRcblx0aWYgKCBxdWFsaWZpZXIubm9kZVR5cGUgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBlbGVtID09PSBxdWFsaWZpZXIgKSAhPT0gbm90O1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIEFycmF5bGlrZSBvZiBlbGVtZW50cyAoalF1ZXJ5LCBhcmd1bWVudHMsIEFycmF5KVxuXHRpZiAoIHR5cGVvZiBxdWFsaWZpZXIgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBpbmRleE9mLmNhbGwoIHF1YWxpZmllciwgZWxlbSApID4gLTEgKSAhPT0gbm90O1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIEZpbHRlcmVkIGRpcmVjdGx5IGZvciBib3RoIHNpbXBsZSBhbmQgY29tcGxleCBzZWxlY3RvcnNcblx0cmV0dXJuIGpRdWVyeS5maWx0ZXIoIHF1YWxpZmllciwgZWxlbWVudHMsIG5vdCApO1xufVxuXG5qUXVlcnkuZmlsdGVyID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1zLCBub3QgKSB7XG5cdHZhciBlbGVtID0gZWxlbXNbIDAgXTtcblxuXHRpZiAoIG5vdCApIHtcblx0XHRleHByID0gXCI6bm90KFwiICsgZXhwciArIFwiKVwiO1xuXHR9XG5cblx0aWYgKCBlbGVtcy5sZW5ndGggPT09IDEgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKCBlbGVtLCBleHByICkgPyBbIGVsZW0gXSA6IFtdO1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeS5maW5kLm1hdGNoZXMoIGV4cHIsIGpRdWVyeS5ncmVwKCBlbGVtcywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGVsZW0ubm9kZVR5cGUgPT09IDE7XG5cdH0gKSApO1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRmaW5kOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGksIHJldCxcblx0XHRcdGxlbiA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0c2VsZiA9IHRoaXM7XG5cblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5KCBzZWxlY3RvciApLmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdFx0aWYgKCBqUXVlcnkuY29udGFpbnMoIHNlbGZbIGkgXSwgdGhpcyApICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9ICkgKTtcblx0XHR9XG5cblx0XHRyZXQgPSB0aGlzLnB1c2hTdGFjayggW10gKTtcblxuXHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRqUXVlcnkuZmluZCggc2VsZWN0b3IsIHNlbGZbIGkgXSwgcmV0ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGxlbiA+IDEgPyBqUXVlcnkudW5pcXVlU29ydCggcmV0ICkgOiByZXQ7XG5cdH0sXG5cdGZpbHRlcjogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggd2lubm93KCB0aGlzLCBzZWxlY3RvciB8fCBbXSwgZmFsc2UgKSApO1xuXHR9LFxuXHRub3Q6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyggdGhpcywgc2VsZWN0b3IgfHwgW10sIHRydWUgKSApO1xuXHR9LFxuXHRpczogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiAhIXdpbm5vdyhcblx0XHRcdHRoaXMsXG5cblx0XHRcdC8vIElmIHRoaXMgaXMgYSBwb3NpdGlvbmFsL3JlbGF0aXZlIHNlbGVjdG9yLCBjaGVjayBtZW1iZXJzaGlwIGluIHRoZSByZXR1cm5lZCBzZXRcblx0XHRcdC8vIHNvICQoXCJwOmZpcnN0XCIpLmlzKFwicDpsYXN0XCIpIHdvbid0IHJldHVybiB0cnVlIGZvciBhIGRvYyB3aXRoIHR3byBcInBcIi5cblx0XHRcdHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiAmJiBybmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9yICkgP1xuXHRcdFx0XHRqUXVlcnkoIHNlbGVjdG9yICkgOlxuXHRcdFx0XHRzZWxlY3RvciB8fCBbXSxcblx0XHRcdGZhbHNlXG5cdFx0KS5sZW5ndGg7XG5cdH1cbn0gKTtcblxuXG4vLyBJbml0aWFsaXplIGEgalF1ZXJ5IG9iamVjdFxuXG5cbi8vIEEgY2VudHJhbCByZWZlcmVuY2UgdG8gdGhlIHJvb3QgalF1ZXJ5KGRvY3VtZW50KVxudmFyIHJvb3RqUXVlcnksXG5cblx0Ly8gQSBzaW1wbGUgd2F5IHRvIGNoZWNrIGZvciBIVE1MIHN0cmluZ3Ncblx0Ly8gUHJpb3JpdGl6ZSAjaWQgb3ZlciA8dGFnPiB0byBhdm9pZCBYU1MgdmlhIGxvY2F0aW9uLmhhc2ggKCM5NTIxKVxuXHQvLyBTdHJpY3QgSFRNTCByZWNvZ25pdGlvbiAoIzExMjkwOiBtdXN0IHN0YXJ0IHdpdGggPClcblx0Ly8gU2hvcnRjdXQgc2ltcGxlICNpZCBjYXNlIGZvciBzcGVlZFxuXHRycXVpY2tFeHByID0gL14oPzpcXHMqKDxbXFx3XFxXXSs+KVtePl0qfCMoW1xcdy1dKykpJC8sXG5cblx0aW5pdCA9IGpRdWVyeS5mbi5pbml0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0LCByb290ICkge1xuXHRcdHZhciBtYXRjaCwgZWxlbTtcblxuXHRcdC8vIEhBTkRMRTogJChcIlwiKSwgJChudWxsKSwgJCh1bmRlZmluZWQpLCAkKGZhbHNlKVxuXHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Ly8gTWV0aG9kIGluaXQoKSBhY2NlcHRzIGFuIGFsdGVybmF0ZSByb290alF1ZXJ5XG5cdFx0Ly8gc28gbWlncmF0ZSBjYW4gc3VwcG9ydCBqUXVlcnkuc3ViIChnaC0yMTAxKVxuXHRcdHJvb3QgPSByb290IHx8IHJvb3RqUXVlcnk7XG5cblx0XHQvLyBIYW5kbGUgSFRNTCBzdHJpbmdzXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRpZiAoIHNlbGVjdG9yWyAwIF0gPT09IFwiPFwiICYmXG5cdFx0XHRcdHNlbGVjdG9yWyBzZWxlY3Rvci5sZW5ndGggLSAxIF0gPT09IFwiPlwiICYmXG5cdFx0XHRcdHNlbGVjdG9yLmxlbmd0aCA+PSAzICkge1xuXG5cdFx0XHRcdC8vIEFzc3VtZSB0aGF0IHN0cmluZ3MgdGhhdCBzdGFydCBhbmQgZW5kIHdpdGggPD4gYXJlIEhUTUwgYW5kIHNraXAgdGhlIHJlZ2V4IGNoZWNrXG5cdFx0XHRcdG1hdGNoID0gWyBudWxsLCBzZWxlY3RvciwgbnVsbCBdO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWF0Y2ggaHRtbCBvciBtYWtlIHN1cmUgbm8gY29udGV4dCBpcyBzcGVjaWZpZWQgZm9yICNpZFxuXHRcdFx0aWYgKCBtYXRjaCAmJiAoIG1hdGNoWyAxIF0gfHwgIWNvbnRleHQgKSApIHtcblxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoaHRtbCkgLT4gJChhcnJheSlcblx0XHRcdFx0aWYgKCBtYXRjaFsgMSBdICkge1xuXHRcdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0IGluc3RhbmNlb2YgalF1ZXJ5ID8gY29udGV4dFsgMCBdIDogY29udGV4dDtcblxuXHRcdFx0XHRcdC8vIE9wdGlvbiB0byBydW4gc2NyaXB0cyBpcyB0cnVlIGZvciBiYWNrLWNvbXBhdFxuXHRcdFx0XHRcdC8vIEludGVudGlvbmFsbHkgbGV0IHRoZSBlcnJvciBiZSB0aHJvd24gaWYgcGFyc2VIVE1MIGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLCBqUXVlcnkucGFyc2VIVE1MKFxuXHRcdFx0XHRcdFx0bWF0Y2hbIDEgXSxcblx0XHRcdFx0XHRcdGNvbnRleHQgJiYgY29udGV4dC5ub2RlVHlwZSA/IGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0IDogZG9jdW1lbnQsXG5cdFx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdFx0KSApO1xuXG5cdFx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwsIHByb3BzKVxuXHRcdFx0XHRcdGlmICggcnNpbmdsZVRhZy50ZXN0KCBtYXRjaFsgMSBdICkgJiYgalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGNvbnRleHQgKSApIHtcblx0XHRcdFx0XHRcdGZvciAoIG1hdGNoIGluIGNvbnRleHQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gUHJvcGVydGllcyBvZiBjb250ZXh0IGFyZSBjYWxsZWQgYXMgbWV0aG9kcyBpZiBwb3NzaWJsZVxuXHRcdFx0XHRcdFx0XHRpZiAoIGlzRnVuY3Rpb24oIHRoaXNbIG1hdGNoIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzWyBtYXRjaCBdKCBjb250ZXh0WyBtYXRjaCBdICk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIG90aGVyd2lzZSBzZXQgYXMgYXR0cmlidXRlc1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuYXR0ciggbWF0Y2gsIGNvbnRleHRbIG1hdGNoIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0XHRcdC8vIEhBTkRMRTogJCgjaWQpXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtYXRjaFsgMiBdICk7XG5cblx0XHRcdFx0XHRpZiAoIGVsZW0gKSB7XG5cblx0XHRcdFx0XHRcdC8vIEluamVjdCB0aGUgZWxlbWVudCBkaXJlY3RseSBpbnRvIHRoZSBqUXVlcnkgb2JqZWN0XG5cdFx0XHRcdFx0XHR0aGlzWyAwIF0gPSBlbGVtO1xuXHRcdFx0XHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBIQU5ETEU6ICQoZXhwciwgJCguLi4pKVxuXHRcdFx0fSBlbHNlIGlmICggIWNvbnRleHQgfHwgY29udGV4dC5qcXVlcnkgKSB7XG5cdFx0XHRcdHJldHVybiAoIGNvbnRleHQgfHwgcm9vdCApLmZpbmQoIHNlbGVjdG9yICk7XG5cblx0XHRcdC8vIEhBTkRMRTogJChleHByLCBjb250ZXh0KVxuXHRcdFx0Ly8gKHdoaWNoIGlzIGp1c3QgZXF1aXZhbGVudCB0bzogJChjb250ZXh0KS5maW5kKGV4cHIpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5jb25zdHJ1Y3RvciggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yICk7XG5cdFx0XHR9XG5cblx0XHQvLyBIQU5ETEU6ICQoRE9NRWxlbWVudClcblx0XHR9IGVsc2UgaWYgKCBzZWxlY3Rvci5ub2RlVHlwZSApIHtcblx0XHRcdHRoaXNbIDAgXSA9IHNlbGVjdG9yO1xuXHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHQvLyBIQU5ETEU6ICQoZnVuY3Rpb24pXG5cdFx0Ly8gU2hvcnRjdXQgZm9yIGRvY3VtZW50IHJlYWR5XG5cdFx0fSBlbHNlIGlmICggaXNGdW5jdGlvbiggc2VsZWN0b3IgKSApIHtcblx0XHRcdHJldHVybiByb290LnJlYWR5ICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRyb290LnJlYWR5KCBzZWxlY3RvciApIDpcblxuXHRcdFx0XHQvLyBFeGVjdXRlIGltbWVkaWF0ZWx5IGlmIHJlYWR5IGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdHNlbGVjdG9yKCBqUXVlcnkgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5Lm1ha2VBcnJheSggc2VsZWN0b3IsIHRoaXMgKTtcblx0fTtcblxuLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvblxuaW5pdC5wcm90b3R5cGUgPSBqUXVlcnkuZm47XG5cbi8vIEluaXRpYWxpemUgY2VudHJhbCByZWZlcmVuY2VcbnJvb3RqUXVlcnkgPSBqUXVlcnkoIGRvY3VtZW50ICk7XG5cblxudmFyIHJwYXJlbnRzcHJldiA9IC9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLFxuXG5cdC8vIE1ldGhvZHMgZ3VhcmFudGVlZCB0byBwcm9kdWNlIGEgdW5pcXVlIHNldCB3aGVuIHN0YXJ0aW5nIGZyb20gYSB1bmlxdWUgc2V0XG5cdGd1YXJhbnRlZWRVbmlxdWUgPSB7XG5cdFx0Y2hpbGRyZW46IHRydWUsXG5cdFx0Y29udGVudHM6IHRydWUsXG5cdFx0bmV4dDogdHJ1ZSxcblx0XHRwcmV2OiB0cnVlXG5cdH07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0aGFzOiBmdW5jdGlvbiggdGFyZ2V0ICkge1xuXHRcdHZhciB0YXJnZXRzID0galF1ZXJ5KCB0YXJnZXQsIHRoaXMgKSxcblx0XHRcdGwgPSB0YXJnZXRzLmxlbmd0aDtcblxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggalF1ZXJ5LmNvbnRhaW5zKCB0aGlzLCB0YXJnZXRzWyBpIF0gKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRjbG9zZXN0OiBmdW5jdGlvbiggc2VsZWN0b3JzLCBjb250ZXh0ICkge1xuXHRcdHZhciBjdXIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aCxcblx0XHRcdG1hdGNoZWQgPSBbXSxcblx0XHRcdHRhcmdldHMgPSB0eXBlb2Ygc2VsZWN0b3JzICE9PSBcInN0cmluZ1wiICYmIGpRdWVyeSggc2VsZWN0b3JzICk7XG5cblx0XHQvLyBQb3NpdGlvbmFsIHNlbGVjdG9ycyBuZXZlciBtYXRjaCwgc2luY2UgdGhlcmUncyBubyBfc2VsZWN0aW9uXyBjb250ZXh0XG5cdFx0aWYgKCAhcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvcnMgKSApIHtcblx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0Zm9yICggY3VyID0gdGhpc1sgaSBdOyBjdXIgJiYgY3VyICE9PSBjb250ZXh0OyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblxuXHRcdFx0XHRcdC8vIEFsd2F5cyBza2lwIGRvY3VtZW50IGZyYWdtZW50c1xuXHRcdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKCB0YXJnZXRzID9cblx0XHRcdFx0XHRcdHRhcmdldHMuaW5kZXgoIGN1ciApID4gLTEgOlxuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGVcblx0XHRcdFx0XHRcdGN1ci5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGN1ciwgc2VsZWN0b3JzICkgKSApIHtcblxuXHRcdFx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZC5sZW5ndGggPiAxID8galF1ZXJ5LnVuaXF1ZVNvcnQoIG1hdGNoZWQgKSA6IG1hdGNoZWQgKTtcblx0fSxcblxuXHQvLyBEZXRlcm1pbmUgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgd2l0aGluIHRoZSBzZXRcblx0aW5kZXg6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gTm8gYXJndW1lbnQsIHJldHVybiBpbmRleCBpbiBwYXJlbnRcblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuICggdGhpc1sgMCBdICYmIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xuXHRcdH1cblxuXHRcdC8vIEluZGV4IGluIHNlbGVjdG9yXG5cdFx0aWYgKCB0eXBlb2YgZWxlbSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGpRdWVyeSggZWxlbSApLCB0aGlzWyAwIF0gKTtcblx0XHR9XG5cblx0XHQvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnRcblx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLFxuXG5cdFx0XHQvLyBJZiBpdCByZWNlaXZlcyBhIGpRdWVyeSBvYmplY3QsIHRoZSBmaXJzdCBlbGVtZW50IGlzIHVzZWRcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbVxuXHRcdCk7XG5cdH0sXG5cblx0YWRkOiBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKFxuXHRcdFx0alF1ZXJ5LnVuaXF1ZVNvcnQoXG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcy5nZXQoKSwgalF1ZXJ5KCBzZWxlY3RvciwgY29udGV4dCApIClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXG5cdGFkZEJhY2s6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5hZGQoIHNlbGVjdG9yID09IG51bGwgP1xuXHRcdFx0dGhpcy5wcmV2T2JqZWN0IDogdGhpcy5wcmV2T2JqZWN0LmZpbHRlciggc2VsZWN0b3IgKVxuXHRcdCk7XG5cdH1cbn0gKTtcblxuZnVuY3Rpb24gc2libGluZyggY3VyLCBkaXIgKSB7XG5cdHdoaWxlICggKCBjdXIgPSBjdXJbIGRpciBdICkgJiYgY3VyLm5vZGVUeXBlICE9PSAxICkge31cblx0cmV0dXJuIGN1cjtcbn1cblxualF1ZXJ5LmVhY2goIHtcblx0cGFyZW50OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlICE9PSAxMSA/IHBhcmVudCA6IG51bGw7XG5cdH0sXG5cdHBhcmVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiICk7XG5cdH0sXG5cdHBhcmVudHNVbnRpbDogZnVuY3Rpb24oIGVsZW0sIF9pLCB1bnRpbCApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcInBhcmVudE5vZGVcIiwgdW50aWwgKTtcblx0fSxcblx0bmV4dDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIHNpYmxpbmcoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xuXHR9LFxuXHRwcmV2OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIgKTtcblx0fSxcblx0cHJldkFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBfaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJuZXh0U2libGluZ1wiLCB1bnRpbCApO1xuXHR9LFxuXHRwcmV2VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBfaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0c2libGluZ3M6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5ncyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7XG5cdH0sXG5cdGNoaWxkcmVuOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZ3MoIGVsZW0uZmlyc3RDaGlsZCApO1xuXHR9LFxuXHRjb250ZW50czogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0aWYgKCBlbGVtLmNvbnRlbnREb2N1bWVudCAhPSBudWxsICYmXG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExK1xuXHRcdFx0Ly8gPG9iamVjdD4gZWxlbWVudHMgd2l0aCBubyBgZGF0YWAgYXR0cmlidXRlIGhhcyBhbiBvYmplY3Rcblx0XHRcdC8vIGBjb250ZW50RG9jdW1lbnRgIHdpdGggYSBgbnVsbGAgcHJvdG90eXBlLlxuXHRcdFx0Z2V0UHJvdG8oIGVsZW0uY29udGVudERvY3VtZW50ICkgKSB7XG5cblx0XHRcdHJldHVybiBlbGVtLmNvbnRlbnREb2N1bWVudDtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTEgb25seSwgaU9TIDcgb25seSwgQW5kcm9pZCBCcm93c2VyIDw9NC4zIG9ubHlcblx0XHQvLyBUcmVhdCB0aGUgdGVtcGxhdGUgZWxlbWVudCBhcyBhIHJlZ3VsYXIgb25lIGluIGJyb3dzZXJzIHRoYXRcblx0XHQvLyBkb24ndCBzdXBwb3J0IGl0LlxuXHRcdGlmICggbm9kZU5hbWUoIGVsZW0sIFwidGVtcGxhdGVcIiApICkge1xuXHRcdFx0ZWxlbSA9IGVsZW0uY29udGVudCB8fCBlbGVtO1xuXHRcdH1cblxuXHRcdHJldHVybiBqUXVlcnkubWVyZ2UoIFtdLCBlbGVtLmNoaWxkTm9kZXMgKTtcblx0fVxufSwgZnVuY3Rpb24oIG5hbWUsIGZuICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCB1bnRpbCwgc2VsZWN0b3IgKSB7XG5cdFx0dmFyIG1hdGNoZWQgPSBqUXVlcnkubWFwKCB0aGlzLCBmbiwgdW50aWwgKTtcblxuXHRcdGlmICggbmFtZS5zbGljZSggLTUgKSAhPT0gXCJVbnRpbFwiICkge1xuXHRcdFx0c2VsZWN0b3IgPSB1bnRpbDtcblx0XHR9XG5cblx0XHRpZiAoIHNlbGVjdG9yICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdG1hdGNoZWQgPSBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgbWF0Y2hlZCApO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy5sZW5ndGggPiAxICkge1xuXG5cdFx0XHQvLyBSZW1vdmUgZHVwbGljYXRlc1xuXHRcdFx0aWYgKCAhZ3VhcmFudGVlZFVuaXF1ZVsgbmFtZSBdICkge1xuXHRcdFx0XHRqUXVlcnkudW5pcXVlU29ydCggbWF0Y2hlZCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXZlcnNlIG9yZGVyIGZvciBwYXJlbnRzKiBhbmQgcHJldi1kZXJpdmF0aXZlc1xuXHRcdFx0aWYgKCBycGFyZW50c3ByZXYudGVzdCggbmFtZSApICkge1xuXHRcdFx0XHRtYXRjaGVkLnJldmVyc2UoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIG1hdGNoZWQgKTtcblx0fTtcbn0gKTtcbnZhciBybm90aHRtbHdoaXRlID0gKCAvW15cXHgyMFxcdFxcclxcblxcZl0rL2cgKTtcblxuXG5cbi8vIENvbnZlcnQgU3RyaW5nLWZvcm1hdHRlZCBvcHRpb25zIGludG8gT2JqZWN0LWZvcm1hdHRlZCBvbmVzXG5mdW5jdGlvbiBjcmVhdGVPcHRpb25zKCBvcHRpb25zICkge1xuXHR2YXIgb2JqZWN0ID0ge307XG5cdGpRdWVyeS5lYWNoKCBvcHRpb25zLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW10sIGZ1bmN0aW9uKCBfLCBmbGFnICkge1xuXHRcdG9iamVjdFsgZmxhZyBdID0gdHJ1ZTtcblx0fSApO1xuXHRyZXR1cm4gb2JqZWN0O1xufVxuXG4vKlxuICogQ3JlYXRlIGEgY2FsbGJhY2sgbGlzdCB1c2luZyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gKlxuICpcdG9wdGlvbnM6IGFuIG9wdGlvbmFsIGxpc3Qgb2Ygc3BhY2Utc2VwYXJhdGVkIG9wdGlvbnMgdGhhdCB3aWxsIGNoYW5nZSBob3dcbiAqXHRcdFx0dGhlIGNhbGxiYWNrIGxpc3QgYmVoYXZlcyBvciBhIG1vcmUgdHJhZGl0aW9uYWwgb3B0aW9uIG9iamVjdFxuICpcbiAqIEJ5IGRlZmF1bHQgYSBjYWxsYmFjayBsaXN0IHdpbGwgYWN0IGxpa2UgYW4gZXZlbnQgY2FsbGJhY2sgbGlzdCBhbmQgY2FuIGJlXG4gKiBcImZpcmVkXCIgbXVsdGlwbGUgdGltZXMuXG4gKlxuICogUG9zc2libGUgb3B0aW9uczpcbiAqXG4gKlx0b25jZTpcdFx0XHR3aWxsIGVuc3VyZSB0aGUgY2FsbGJhY2sgbGlzdCBjYW4gb25seSBiZSBmaXJlZCBvbmNlIChsaWtlIGEgRGVmZXJyZWQpXG4gKlxuICpcdG1lbW9yeTpcdFx0XHR3aWxsIGtlZXAgdHJhY2sgb2YgcHJldmlvdXMgdmFsdWVzIGFuZCB3aWxsIGNhbGwgYW55IGNhbGxiYWNrIGFkZGVkXG4gKlx0XHRcdFx0XHRhZnRlciB0aGUgbGlzdCBoYXMgYmVlbiBmaXJlZCByaWdodCBhd2F5IHdpdGggdGhlIGxhdGVzdCBcIm1lbW9yaXplZFwiXG4gKlx0XHRcdFx0XHR2YWx1ZXMgKGxpa2UgYSBEZWZlcnJlZClcbiAqXG4gKlx0dW5pcXVlOlx0XHRcdHdpbGwgZW5zdXJlIGEgY2FsbGJhY2sgY2FuIG9ubHkgYmUgYWRkZWQgb25jZSAobm8gZHVwbGljYXRlIGluIHRoZSBsaXN0KVxuICpcbiAqXHRzdG9wT25GYWxzZTpcdGludGVycnVwdCBjYWxsaW5ncyB3aGVuIGEgY2FsbGJhY2sgcmV0dXJucyBmYWxzZVxuICpcbiAqL1xualF1ZXJ5LkNhbGxiYWNrcyA9IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXG5cdC8vIENvbnZlcnQgb3B0aW9ucyBmcm9tIFN0cmluZy1mb3JtYXR0ZWQgdG8gT2JqZWN0LWZvcm1hdHRlZCBpZiBuZWVkZWRcblx0Ly8gKHdlIGNoZWNrIGluIGNhY2hlIGZpcnN0KVxuXHRvcHRpb25zID0gdHlwZW9mIG9wdGlvbnMgPT09IFwic3RyaW5nXCIgP1xuXHRcdGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSA6XG5cdFx0alF1ZXJ5LmV4dGVuZCgge30sIG9wdGlvbnMgKTtcblxuXHR2YXIgLy8gRmxhZyB0byBrbm93IGlmIGxpc3QgaXMgY3VycmVudGx5IGZpcmluZ1xuXHRcdGZpcmluZyxcblxuXHRcdC8vIExhc3QgZmlyZSB2YWx1ZSBmb3Igbm9uLWZvcmdldHRhYmxlIGxpc3RzXG5cdFx0bWVtb3J5LFxuXG5cdFx0Ly8gRmxhZyB0byBrbm93IGlmIGxpc3Qgd2FzIGFscmVhZHkgZmlyZWRcblx0XHRmaXJlZCxcblxuXHRcdC8vIEZsYWcgdG8gcHJldmVudCBmaXJpbmdcblx0XHRsb2NrZWQsXG5cblx0XHQvLyBBY3R1YWwgY2FsbGJhY2sgbGlzdFxuXHRcdGxpc3QgPSBbXSxcblxuXHRcdC8vIFF1ZXVlIG9mIGV4ZWN1dGlvbiBkYXRhIGZvciByZXBlYXRhYmxlIGxpc3RzXG5cdFx0cXVldWUgPSBbXSxcblxuXHRcdC8vIEluZGV4IG9mIGN1cnJlbnRseSBmaXJpbmcgY2FsbGJhY2sgKG1vZGlmaWVkIGJ5IGFkZC9yZW1vdmUgYXMgbmVlZGVkKVxuXHRcdGZpcmluZ0luZGV4ID0gLTEsXG5cblx0XHQvLyBGaXJlIGNhbGxiYWNrc1xuXHRcdGZpcmUgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gRW5mb3JjZSBzaW5nbGUtZmlyaW5nXG5cdFx0XHRsb2NrZWQgPSBsb2NrZWQgfHwgb3B0aW9ucy5vbmNlO1xuXG5cdFx0XHQvLyBFeGVjdXRlIGNhbGxiYWNrcyBmb3IgYWxsIHBlbmRpbmcgZXhlY3V0aW9ucyxcblx0XHRcdC8vIHJlc3BlY3RpbmcgZmlyaW5nSW5kZXggb3ZlcnJpZGVzIGFuZCBydW50aW1lIGNoYW5nZXNcblx0XHRcdGZpcmVkID0gZmlyaW5nID0gdHJ1ZTtcblx0XHRcdGZvciAoIDsgcXVldWUubGVuZ3RoOyBmaXJpbmdJbmRleCA9IC0xICkge1xuXHRcdFx0XHRtZW1vcnkgPSBxdWV1ZS5zaGlmdCgpO1xuXHRcdFx0XHR3aGlsZSAoICsrZmlyaW5nSW5kZXggPCBsaXN0Lmxlbmd0aCApIHtcblxuXHRcdFx0XHRcdC8vIFJ1biBjYWxsYmFjayBhbmQgY2hlY2sgZm9yIGVhcmx5IHRlcm1pbmF0aW9uXG5cdFx0XHRcdFx0aWYgKCBsaXN0WyBmaXJpbmdJbmRleCBdLmFwcGx5KCBtZW1vcnlbIDAgXSwgbWVtb3J5WyAxIF0gKSA9PT0gZmFsc2UgJiZcblx0XHRcdFx0XHRcdG9wdGlvbnMuc3RvcE9uRmFsc2UgKSB7XG5cblx0XHRcdFx0XHRcdC8vIEp1bXAgdG8gZW5kIGFuZCBmb3JnZXQgdGhlIGRhdGEgc28gLmFkZCBkb2Vzbid0IHJlLWZpcmVcblx0XHRcdFx0XHRcdGZpcmluZ0luZGV4ID0gbGlzdC5sZW5ndGg7XG5cdFx0XHRcdFx0XHRtZW1vcnkgPSBmYWxzZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gRm9yZ2V0IHRoZSBkYXRhIGlmIHdlJ3JlIGRvbmUgd2l0aCBpdFxuXHRcdFx0aWYgKCAhb3B0aW9ucy5tZW1vcnkgKSB7XG5cdFx0XHRcdG1lbW9yeSA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHRmaXJpbmcgPSBmYWxzZTtcblxuXHRcdFx0Ly8gQ2xlYW4gdXAgaWYgd2UncmUgZG9uZSBmaXJpbmcgZm9yIGdvb2Rcblx0XHRcdGlmICggbG9ja2VkICkge1xuXG5cdFx0XHRcdC8vIEtlZXAgYW4gZW1wdHkgbGlzdCBpZiB3ZSBoYXZlIGRhdGEgZm9yIGZ1dHVyZSBhZGQgY2FsbHNcblx0XHRcdFx0aWYgKCBtZW1vcnkgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IFtdO1xuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSwgdGhpcyBvYmplY3QgaXMgc3BlbnRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRsaXN0ID0gXCJcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvLyBBY3R1YWwgQ2FsbGJhY2tzIG9iamVjdFxuXHRcdHNlbGYgPSB7XG5cblx0XHRcdC8vIEFkZCBhIGNhbGxiYWNrIG9yIGEgY29sbGVjdGlvbiBvZiBjYWxsYmFja3MgdG8gdGhlIGxpc3Rcblx0XHRcdGFkZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblxuXHRcdFx0XHRcdC8vIElmIHdlIGhhdmUgbWVtb3J5IGZyb20gYSBwYXN0IHJ1biwgd2Ugc2hvdWxkIGZpcmUgYWZ0ZXIgYWRkaW5nXG5cdFx0XHRcdFx0aWYgKCBtZW1vcnkgJiYgIWZpcmluZyApIHtcblx0XHRcdFx0XHRcdGZpcmluZ0luZGV4ID0gbGlzdC5sZW5ndGggLSAxO1xuXHRcdFx0XHRcdFx0cXVldWUucHVzaCggbWVtb3J5ICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0KCBmdW5jdGlvbiBhZGQoIGFyZ3MgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJncywgZnVuY3Rpb24oIF8sIGFyZyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCBhcmcgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoICFvcHRpb25zLnVuaXF1ZSB8fCAhc2VsZi5oYXMoIGFyZyApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0bGlzdC5wdXNoKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGFyZyAmJiBhcmcubGVuZ3RoICYmIHRvVHlwZSggYXJnICkgIT09IFwic3RyaW5nXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBJbnNwZWN0IHJlY3Vyc2l2ZWx5XG5cdFx0XHRcdFx0XHRcdFx0YWRkKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdH0gKSggYXJndW1lbnRzICk7XG5cblx0XHRcdFx0XHRpZiAoIG1lbW9yeSAmJiAhZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIFJlbW92ZSBhIGNhbGxiYWNrIGZyb20gdGhlIGxpc3Rcblx0XHRcdHJlbW92ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5lYWNoKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0dmFyIGluZGV4O1xuXHRcdFx0XHRcdHdoaWxlICggKCBpbmRleCA9IGpRdWVyeS5pbkFycmF5KCBhcmcsIGxpc3QsIGluZGV4ICkgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0bGlzdC5zcGxpY2UoIGluZGV4LCAxICk7XG5cblx0XHRcdFx0XHRcdC8vIEhhbmRsZSBmaXJpbmcgaW5kZXhlc1xuXHRcdFx0XHRcdFx0aWYgKCBpbmRleCA8PSBmaXJpbmdJbmRleCApIHtcblx0XHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXgtLTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBDaGVjayBpZiBhIGdpdmVuIGNhbGxiYWNrIGlzIGluIHRoZSBsaXN0LlxuXHRcdFx0Ly8gSWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4sIHJldHVybiB3aGV0aGVyIG9yIG5vdCBsaXN0IGhhcyBjYWxsYmFja3MgYXR0YWNoZWQuXG5cdFx0XHRoYXM6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0cmV0dXJuIGZuID9cblx0XHRcdFx0XHRqUXVlcnkuaW5BcnJheSggZm4sIGxpc3QgKSA+IC0xIDpcblx0XHRcdFx0XHRsaXN0Lmxlbmd0aCA+IDA7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBSZW1vdmUgYWxsIGNhbGxiYWNrcyBmcm9tIHRoZSBsaXN0XG5cdFx0XHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0XHRsaXN0ID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBEaXNhYmxlIC5maXJlIGFuZCAuYWRkXG5cdFx0XHQvLyBBYm9ydCBhbnkgY3VycmVudC9wZW5kaW5nIGV4ZWN1dGlvbnNcblx0XHRcdC8vIENsZWFyIGFsbCBjYWxsYmFja3MgYW5kIHZhbHVlc1xuXHRcdFx0ZGlzYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxvY2tlZCA9IHF1ZXVlID0gW107XG5cdFx0XHRcdGxpc3QgPSBtZW1vcnkgPSBcIlwiO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHRkaXNhYmxlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhbGlzdDtcblx0XHRcdH0sXG5cblx0XHRcdC8vIERpc2FibGUgLmZpcmVcblx0XHRcdC8vIEFsc28gZGlzYWJsZSAuYWRkIHVubGVzcyB3ZSBoYXZlIG1lbW9yeSAoc2luY2UgaXQgd291bGQgaGF2ZSBubyBlZmZlY3QpXG5cdFx0XHQvLyBBYm9ydCBhbnkgcGVuZGluZyBleGVjdXRpb25zXG5cdFx0XHRsb2NrOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0bG9ja2VkID0gcXVldWUgPSBbXTtcblx0XHRcdFx0aWYgKCAhbWVtb3J5ICYmICFmaXJpbmcgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IG1lbW9yeSA9IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0bG9ja2VkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICEhbG9ja2VkO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gQ2FsbCBhbGwgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGNvbnRleHQgYW5kIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZVdpdGg6IGZ1bmN0aW9uKCBjb250ZXh0LCBhcmdzICkge1xuXHRcdFx0XHRpZiAoICFsb2NrZWQgKSB7XG5cdFx0XHRcdFx0YXJncyA9IGFyZ3MgfHwgW107XG5cdFx0XHRcdFx0YXJncyA9IFsgY29udGV4dCwgYXJncy5zbGljZSA/IGFyZ3Muc2xpY2UoKSA6IGFyZ3MgXTtcblx0XHRcdFx0XHRxdWV1ZS5wdXNoKCBhcmdzICk7XG5cdFx0XHRcdFx0aWYgKCAhZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIENhbGwgYWxsIHRoZSBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzXG5cdFx0XHRmaXJlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0c2VsZi5maXJlV2l0aCggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gVG8ga25vdyBpZiB0aGUgY2FsbGJhY2tzIGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZCBhdCBsZWFzdCBvbmNlXG5cdFx0XHRmaXJlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhIWZpcmVkO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0cmV0dXJuIHNlbGY7XG59O1xuXG5cbmZ1bmN0aW9uIElkZW50aXR5KCB2ICkge1xuXHRyZXR1cm4gdjtcbn1cbmZ1bmN0aW9uIFRocm93ZXIoIGV4ICkge1xuXHR0aHJvdyBleDtcbn1cblxuZnVuY3Rpb24gYWRvcHRWYWx1ZSggdmFsdWUsIHJlc29sdmUsIHJlamVjdCwgbm9WYWx1ZSApIHtcblx0dmFyIG1ldGhvZDtcblxuXHR0cnkge1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIHByb21pc2UgYXNwZWN0IGZpcnN0IHRvIHByaXZpbGVnZSBzeW5jaHJvbm91cyBiZWhhdmlvclxuXHRcdGlmICggdmFsdWUgJiYgaXNGdW5jdGlvbiggKCBtZXRob2QgPSB2YWx1ZS5wcm9taXNlICkgKSApIHtcblx0XHRcdG1ldGhvZC5jYWxsKCB2YWx1ZSApLmRvbmUoIHJlc29sdmUgKS5mYWlsKCByZWplY3QgKTtcblxuXHRcdC8vIE90aGVyIHRoZW5hYmxlc1xuXHRcdH0gZWxzZSBpZiAoIHZhbHVlICYmIGlzRnVuY3Rpb24oICggbWV0aG9kID0gdmFsdWUudGhlbiApICkgKSB7XG5cdFx0XHRtZXRob2QuY2FsbCggdmFsdWUsIHJlc29sdmUsIHJlamVjdCApO1xuXG5cdFx0Ly8gT3RoZXIgbm9uLXRoZW5hYmxlc1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIENvbnRyb2wgYHJlc29sdmVgIGFyZ3VtZW50cyBieSBsZXR0aW5nIEFycmF5I3NsaWNlIGNhc3QgYm9vbGVhbiBgbm9WYWx1ZWAgdG8gaW50ZWdlcjpcblx0XHRcdC8vICogZmFsc2U6IFsgdmFsdWUgXS5zbGljZSggMCApID0+IHJlc29sdmUoIHZhbHVlIClcblx0XHRcdC8vICogdHJ1ZTogWyB2YWx1ZSBdLnNsaWNlKCAxICkgPT4gcmVzb2x2ZSgpXG5cdFx0XHRyZXNvbHZlLmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXS5zbGljZSggbm9WYWx1ZSApICk7XG5cdFx0fVxuXG5cdC8vIEZvciBQcm9taXNlcy9BKywgY29udmVydCBleGNlcHRpb25zIGludG8gcmVqZWN0aW9uc1xuXHQvLyBTaW5jZSBqUXVlcnkud2hlbiBkb2Vzbid0IHVud3JhcCB0aGVuYWJsZXMsIHdlIGNhbiBza2lwIHRoZSBleHRyYSBjaGVja3MgYXBwZWFyaW5nIGluXG5cdC8vIERlZmVycmVkI3RoZW4gdG8gY29uZGl0aW9uYWxseSBzdXBwcmVzcyByZWplY3Rpb24uXG5cdH0gY2F0Y2ggKCB2YWx1ZSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIG9ubHlcblx0XHQvLyBTdHJpY3QgbW9kZSBmdW5jdGlvbnMgaW52b2tlZCB3aXRob3V0IC5jYWxsLy5hcHBseSBnZXQgZ2xvYmFsLW9iamVjdCBjb250ZXh0XG5cdFx0cmVqZWN0LmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXSApO1xuXHR9XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHREZWZlcnJlZDogZnVuY3Rpb24oIGZ1bmMgKSB7XG5cdFx0dmFyIHR1cGxlcyA9IFtcblxuXHRcdFx0XHQvLyBhY3Rpb24sIGFkZCBsaXN0ZW5lciwgY2FsbGJhY2tzLFxuXHRcdFx0XHQvLyAuLi4gLnRoZW4gaGFuZGxlcnMsIGFyZ3VtZW50IGluZGV4LCBbZmluYWwgc3RhdGVdXG5cdFx0XHRcdFsgXCJub3RpZnlcIiwgXCJwcm9ncmVzc1wiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm1lbW9yeVwiICksXG5cdFx0XHRcdFx0alF1ZXJ5LkNhbGxiYWNrcyggXCJtZW1vcnlcIiApLCAyIF0sXG5cdFx0XHRcdFsgXCJyZXNvbHZlXCIsIFwiZG9uZVwiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSxcblx0XHRcdFx0XHRqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSwgMCwgXCJyZXNvbHZlZFwiIF0sXG5cdFx0XHRcdFsgXCJyZWplY3RcIiwgXCJmYWlsXCIsIGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLFxuXHRcdFx0XHRcdGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLCAxLCBcInJlamVjdGVkXCIgXVxuXHRcdFx0XSxcblx0XHRcdHN0YXRlID0gXCJwZW5kaW5nXCIsXG5cdFx0XHRwcm9taXNlID0ge1xuXHRcdFx0XHRzdGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRhbHdheXM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGRlZmVycmVkLmRvbmUoIGFyZ3VtZW50cyApLmZhaWwoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRcImNhdGNoXCI6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcHJvbWlzZS50aGVuKCBudWxsLCBmbiApO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIEtlZXAgcGlwZSBmb3IgYmFjay1jb21wYXRcblx0XHRcdFx0cGlwZTogZnVuY3Rpb24oIC8qIGZuRG9uZSwgZm5GYWlsLCBmblByb2dyZXNzICovICkge1xuXHRcdFx0XHRcdHZhciBmbnMgPSBhcmd1bWVudHM7XG5cblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggX2ksIHR1cGxlICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIE1hcCB0dXBsZXMgKHByb2dyZXNzLCBkb25lLCBmYWlsKSB0byBhcmd1bWVudHMgKGRvbmUsIGZhaWwsIHByb2dyZXNzKVxuXHRcdFx0XHRcdFx0XHR2YXIgZm4gPSBpc0Z1bmN0aW9uKCBmbnNbIHR1cGxlWyA0IF0gXSApICYmIGZuc1sgdHVwbGVbIDQgXSBdO1xuXG5cdFx0XHRcdFx0XHRcdC8vIGRlZmVycmVkLnByb2dyZXNzKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLm5vdGlmeSB9KVxuXHRcdFx0XHRcdFx0XHQvLyBkZWZlcnJlZC5kb25lKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLnJlc29sdmUgfSlcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWQuZmFpbChmdW5jdGlvbigpIHsgYmluZCB0byBuZXdEZWZlciBvciBuZXdEZWZlci5yZWplY3QgfSlcblx0XHRcdFx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAxIF0gXSggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkID0gZm4gJiYgZm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdFx0XHRcdGlmICggcmV0dXJuZWQgJiYgaXNGdW5jdGlvbiggcmV0dXJuZWQucHJvbWlzZSApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQucHJvbWlzZSgpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5wcm9ncmVzcyggbmV3RGVmZXIubm90aWZ5IClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmRvbmUoIG5ld0RlZmVyLnJlc29sdmUgKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuZmFpbCggbmV3RGVmZXIucmVqZWN0ICk7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXShcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcyxcblx0XHRcdFx0XHRcdFx0XHRcdFx0Zm4gPyBbIHJldHVybmVkIF0gOiBhcmd1bWVudHNcblx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRmbnMgPSBudWxsO1xuXHRcdFx0XHRcdH0gKS5wcm9taXNlKCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRoZW46IGZ1bmN0aW9uKCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgb25Qcm9ncmVzcyApIHtcblx0XHRcdFx0XHR2YXIgbWF4RGVwdGggPSAwO1xuXHRcdFx0XHRcdGZ1bmN0aW9uIHJlc29sdmUoIGRlcHRoLCBkZWZlcnJlZCwgaGFuZGxlciwgc3BlY2lhbCApIHtcblx0XHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0dmFyIHRoYXQgPSB0aGlzLFxuXHRcdFx0XHRcdFx0XHRcdGFyZ3MgPSBhcmd1bWVudHMsXG5cdFx0XHRcdFx0XHRcdFx0bWlnaHRUaHJvdyA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkLCB0aGVuO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4zLjMuM1xuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTlcblx0XHRcdFx0XHRcdFx0XHRcdC8vIElnbm9yZSBkb3VibGUtcmVzb2x1dGlvbiBhdHRlbXB0c1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBkZXB0aCA8IG1heERlcHRoICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkID0gaGFuZGxlci5hcHBseSggdGhhdCwgYXJncyApO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4xXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC00OFxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCByZXR1cm5lZCA9PT0gZGVmZXJyZWQucHJvbWlzZSgpICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCBcIlRoZW5hYmxlIHNlbGYtcmVzb2x1dGlvblwiICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb25zIDIuMy4zLjEsIDMuNVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTRcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTc1XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXRyaWV2ZSBgdGhlbmAgb25seSBvbmNlXG5cdFx0XHRcdFx0XHRcdFx0XHR0aGVuID0gcmV0dXJuZWQgJiZcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy40XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTY0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgY2hlY2sgb2JqZWN0cyBhbmQgZnVuY3Rpb25zIGZvciB0aGVuYWJpbGl0eVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQoIHR5cGVvZiByZXR1cm5lZCA9PT0gXCJvYmplY3RcIiB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiByZXR1cm5lZCA9PT0gXCJmdW5jdGlvblwiICkgJiZcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQudGhlbjtcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSGFuZGxlIGEgcmV0dXJuZWQgdGhlbmFibGVcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggaXNGdW5jdGlvbiggdGhlbiApICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFNwZWNpYWwgcHJvY2Vzc29ycyAobm90aWZ5KSBqdXN0IHdhaXQgZm9yIHJlc29sdXRpb25cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoZW4uY2FsbChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBJZGVudGl0eSwgc3BlY2lhbCApLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBUaHJvd2VyLCBzcGVjaWFsIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE5vcm1hbCBwcm9jZXNzb3JzIChyZXNvbHZlKSBhbHNvIGhvb2sgaW50byBwcm9ncmVzc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIGRpc3JlZ2FyZCBvbGRlciByZXNvbHV0aW9uIHZhbHVlc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1heERlcHRoKys7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGVuLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5lZCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgSWRlbnRpdHksIHNwZWNpYWwgKSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgVGhyb3dlciwgc3BlY2lhbCApLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBJZGVudGl0eSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBIYW5kbGUgYWxsIG90aGVyIHJldHVybmVkIHZhbHVlc1xuXHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBPbmx5IHN1YnN0aXR1dGUgaGFuZGxlcnMgcGFzcyBvbiBjb250ZXh0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGFuZCBtdWx0aXBsZSB2YWx1ZXMgKG5vbi1zcGVjIGJlaGF2aW9yKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIGhhbmRsZXIgIT09IElkZW50aXR5ICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoYXQgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YXJncyA9IFsgcmV0dXJuZWQgXTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFByb2Nlc3MgdGhlIHZhbHVlKHMpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIERlZmF1bHQgcHJvY2VzcyBpcyByZXNvbHZlXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCggc3BlY2lhbCB8fCBkZWZlcnJlZC5yZXNvbHZlV2l0aCApKCB0aGF0LCBhcmdzICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fSxcblxuXHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgbm9ybWFsIHByb2Nlc3NvcnMgKHJlc29sdmUpIGNhdGNoIGFuZCByZWplY3QgZXhjZXB0aW9uc1xuXHRcdFx0XHRcdFx0XHRcdHByb2Nlc3MgPSBzcGVjaWFsID9cblx0XHRcdFx0XHRcdFx0XHRcdG1pZ2h0VGhyb3cgOlxuXHRcdFx0XHRcdFx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWlnaHRUaHJvdygpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9IGNhdGNoICggZSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LkRlZmVycmVkLmV4Y2VwdGlvbkhvb2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayggZSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cHJvY2Vzcy5zdGFja1RyYWNlICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMy4zLjQuMVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTYxXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gSWdub3JlIHBvc3QtcmVzb2x1dGlvbiBleGNlcHRpb25zXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBkZXB0aCArIDEgPj0gbWF4RGVwdGggKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgc3Vic3RpdHV0ZSBoYW5kbGVycyBwYXNzIG9uIGNvbnRleHRcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGFuZCBtdWx0aXBsZSB2YWx1ZXMgKG5vbi1zcGVjIGJlaGF2aW9yKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBoYW5kbGVyICE9PSBUaHJvd2VyICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGF0ID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRhcmdzID0gWyBlIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIHRoYXQsIGFyZ3MgKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMy4zLjFcblx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTdcblx0XHRcdFx0XHRcdFx0Ly8gUmUtcmVzb2x2ZSBwcm9taXNlcyBpbW1lZGlhdGVseSB0byBkb2RnZSBmYWxzZSByZWplY3Rpb24gZnJvbVxuXHRcdFx0XHRcdFx0XHQvLyBzdWJzZXF1ZW50IGVycm9yc1xuXHRcdFx0XHRcdFx0XHRpZiAoIGRlcHRoICkge1xuXHRcdFx0XHRcdFx0XHRcdHByb2Nlc3MoKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIENhbGwgYW4gb3B0aW9uYWwgaG9vayB0byByZWNvcmQgdGhlIHN0YWNrLCBpbiBjYXNlIG9mIGV4Y2VwdGlvblxuXHRcdFx0XHRcdFx0XHRcdC8vIHNpbmNlIGl0J3Mgb3RoZXJ3aXNlIGxvc3Qgd2hlbiBleGVjdXRpb24gZ29lcyBhc3luY1xuXHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LkRlZmVycmVkLmdldFN0YWNrSG9vayApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHByb2Nlc3Muc3RhY2tUcmFjZSA9IGpRdWVyeS5EZWZlcnJlZC5nZXRTdGFja0hvb2soKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0d2luZG93LnNldFRpbWVvdXQoIHByb2Nlc3MgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XG5cblx0XHRcdFx0XHRcdC8vIHByb2dyZXNzX2hhbmRsZXJzLmFkZCggLi4uIClcblx0XHRcdFx0XHRcdHR1cGxlc1sgMCBdWyAzIF0uYWRkKFxuXHRcdFx0XHRcdFx0XHRyZXNvbHZlKFxuXHRcdFx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIsXG5cdFx0XHRcdFx0XHRcdFx0aXNGdW5jdGlvbiggb25Qcm9ncmVzcyApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uUHJvZ3Jlc3MgOlxuXHRcdFx0XHRcdFx0XHRcdFx0SWRlbnRpdHksXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIubm90aWZ5V2l0aFxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHQvLyBmdWxmaWxsZWRfaGFuZGxlcnMuYWRkKCAuLi4gKVxuXHRcdFx0XHRcdFx0dHVwbGVzWyAxIF1bIDMgXS5hZGQoXG5cdFx0XHRcdFx0XHRcdHJlc29sdmUoXG5cdFx0XHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlcixcblx0XHRcdFx0XHRcdFx0XHRpc0Z1bmN0aW9uKCBvbkZ1bGZpbGxlZCApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uRnVsZmlsbGVkIDpcblx0XHRcdFx0XHRcdFx0XHRcdElkZW50aXR5XG5cdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmFkZCggLi4uIClcblx0XHRcdFx0XHRcdHR1cGxlc1sgMiBdWyAzIF0uYWRkKFxuXHRcdFx0XHRcdFx0XHRyZXNvbHZlKFxuXHRcdFx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIsXG5cdFx0XHRcdFx0XHRcdFx0aXNGdW5jdGlvbiggb25SZWplY3RlZCApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uUmVqZWN0ZWQgOlxuXHRcdFx0XHRcdFx0XHRcdFx0VGhyb3dlclxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH0gKS5wcm9taXNlKCk7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gR2V0IGEgcHJvbWlzZSBmb3IgdGhpcyBkZWZlcnJlZFxuXHRcdFx0XHQvLyBJZiBvYmogaXMgcHJvdmlkZWQsIHRoZSBwcm9taXNlIGFzcGVjdCBpcyBhZGRlZCB0byB0aGUgb2JqZWN0XG5cdFx0XHRcdHByb21pc2U6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9iaiAhPSBudWxsID8galF1ZXJ5LmV4dGVuZCggb2JqLCBwcm9taXNlICkgOiBwcm9taXNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVmZXJyZWQgPSB7fTtcblxuXHRcdC8vIEFkZCBsaXN0LXNwZWNpZmljIG1ldGhvZHNcblx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggaSwgdHVwbGUgKSB7XG5cdFx0XHR2YXIgbGlzdCA9IHR1cGxlWyAyIF0sXG5cdFx0XHRcdHN0YXRlU3RyaW5nID0gdHVwbGVbIDUgXTtcblxuXHRcdFx0Ly8gcHJvbWlzZS5wcm9ncmVzcyA9IGxpc3QuYWRkXG5cdFx0XHQvLyBwcm9taXNlLmRvbmUgPSBsaXN0LmFkZFxuXHRcdFx0Ly8gcHJvbWlzZS5mYWlsID0gbGlzdC5hZGRcblx0XHRcdHByb21pc2VbIHR1cGxlWyAxIF0gXSA9IGxpc3QuYWRkO1xuXG5cdFx0XHQvLyBIYW5kbGUgc3RhdGVcblx0XHRcdGlmICggc3RhdGVTdHJpbmcgKSB7XG5cdFx0XHRcdGxpc3QuYWRkKFxuXHRcdFx0XHRcdGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdFx0XHQvLyBzdGF0ZSA9IFwicmVzb2x2ZWRcIiAoaS5lLiwgZnVsZmlsbGVkKVxuXHRcdFx0XHRcdFx0Ly8gc3RhdGUgPSBcInJlamVjdGVkXCJcblx0XHRcdFx0XHRcdHN0YXRlID0gc3RhdGVTdHJpbmc7XG5cdFx0XHRcdFx0fSxcblxuXHRcdFx0XHRcdC8vIHJlamVjdGVkX2NhbGxiYWNrcy5kaXNhYmxlXG5cdFx0XHRcdFx0Ly8gZnVsZmlsbGVkX2NhbGxiYWNrcy5kaXNhYmxlXG5cdFx0XHRcdFx0dHVwbGVzWyAzIC0gaSBdWyAyIF0uZGlzYWJsZSxcblxuXHRcdFx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmRpc2FibGVcblx0XHRcdFx0XHQvLyBmdWxmaWxsZWRfaGFuZGxlcnMuZGlzYWJsZVxuXHRcdFx0XHRcdHR1cGxlc1sgMyAtIGkgXVsgMyBdLmRpc2FibGUsXG5cblx0XHRcdFx0XHQvLyBwcm9ncmVzc19jYWxsYmFja3MubG9ja1xuXHRcdFx0XHRcdHR1cGxlc1sgMCBdWyAyIF0ubG9jayxcblxuXHRcdFx0XHRcdC8vIHByb2dyZXNzX2hhbmRsZXJzLmxvY2tcblx0XHRcdFx0XHR0dXBsZXNbIDAgXVsgMyBdLmxvY2tcblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gcHJvZ3Jlc3NfaGFuZGxlcnMuZmlyZVxuXHRcdFx0Ly8gZnVsZmlsbGVkX2hhbmRsZXJzLmZpcmVcblx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmZpcmVcblx0XHRcdGxpc3QuYWRkKCB0dXBsZVsgMyBdLmZpcmUgKTtcblxuXHRcdFx0Ly8gZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLm5vdGlmeVdpdGgoLi4uKSB9XG5cdFx0XHQvLyBkZWZlcnJlZC5yZXNvbHZlID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLnJlc29sdmVXaXRoKC4uLikgfVxuXHRcdFx0Ly8gZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLnJlamVjdFdpdGgoLi4uKSB9XG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbIDAgXSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRlZmVycmVkWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXSggdGhpcyA9PT0gZGVmZXJyZWQgPyB1bmRlZmluZWQgOiB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBkZWZlcnJlZC5ub3RpZnlXaXRoID0gbGlzdC5maXJlV2l0aFxuXHRcdFx0Ly8gZGVmZXJyZWQucmVzb2x2ZVdpdGggPSBsaXN0LmZpcmVXaXRoXG5cdFx0XHQvLyBkZWZlcnJlZC5yZWplY3RXaXRoID0gbGlzdC5maXJlV2l0aFxuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdID0gbGlzdC5maXJlV2l0aDtcblx0XHR9ICk7XG5cblx0XHQvLyBNYWtlIHRoZSBkZWZlcnJlZCBhIHByb21pc2Vcblx0XHRwcm9taXNlLnByb21pc2UoIGRlZmVycmVkICk7XG5cblx0XHQvLyBDYWxsIGdpdmVuIGZ1bmMgaWYgYW55XG5cdFx0aWYgKCBmdW5jICkge1xuXHRcdFx0ZnVuYy5jYWxsKCBkZWZlcnJlZCwgZGVmZXJyZWQgKTtcblx0XHR9XG5cblx0XHQvLyBBbGwgZG9uZSFcblx0XHRyZXR1cm4gZGVmZXJyZWQ7XG5cdH0sXG5cblx0Ly8gRGVmZXJyZWQgaGVscGVyXG5cdHdoZW46IGZ1bmN0aW9uKCBzaW5nbGVWYWx1ZSApIHtcblx0XHR2YXJcblxuXHRcdFx0Ly8gY291bnQgb2YgdW5jb21wbGV0ZWQgc3Vib3JkaW5hdGVzXG5cdFx0XHRyZW1haW5pbmcgPSBhcmd1bWVudHMubGVuZ3RoLFxuXG5cdFx0XHQvLyBjb3VudCBvZiB1bnByb2Nlc3NlZCBhcmd1bWVudHNcblx0XHRcdGkgPSByZW1haW5pbmcsXG5cblx0XHRcdC8vIHN1Ym9yZGluYXRlIGZ1bGZpbGxtZW50IGRhdGFcblx0XHRcdHJlc29sdmVDb250ZXh0cyA9IEFycmF5KCBpICksXG5cdFx0XHRyZXNvbHZlVmFsdWVzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICksXG5cblx0XHRcdC8vIHRoZSBtYXN0ZXIgRGVmZXJyZWRcblx0XHRcdG1hc3RlciA9IGpRdWVyeS5EZWZlcnJlZCgpLFxuXG5cdFx0XHQvLyBzdWJvcmRpbmF0ZSBjYWxsYmFjayBmYWN0b3J5XG5cdFx0XHR1cGRhdGVGdW5jID0gZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmVzb2x2ZUNvbnRleHRzWyBpIF0gPSB0aGlzO1xuXHRcdFx0XHRcdHJlc29sdmVWYWx1ZXNbIGkgXSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gc2xpY2UuY2FsbCggYXJndW1lbnRzICkgOiB2YWx1ZTtcblx0XHRcdFx0XHRpZiAoICEoIC0tcmVtYWluaW5nICkgKSB7XG5cdFx0XHRcdFx0XHRtYXN0ZXIucmVzb2x2ZVdpdGgoIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdH07XG5cblx0XHQvLyBTaW5nbGUtIGFuZCBlbXB0eSBhcmd1bWVudHMgYXJlIGFkb3B0ZWQgbGlrZSBQcm9taXNlLnJlc29sdmVcblx0XHRpZiAoIHJlbWFpbmluZyA8PSAxICkge1xuXHRcdFx0YWRvcHRWYWx1ZSggc2luZ2xlVmFsdWUsIG1hc3Rlci5kb25lKCB1cGRhdGVGdW5jKCBpICkgKS5yZXNvbHZlLCBtYXN0ZXIucmVqZWN0LFxuXHRcdFx0XHQhcmVtYWluaW5nICk7XG5cblx0XHRcdC8vIFVzZSAudGhlbigpIHRvIHVud3JhcCBzZWNvbmRhcnkgdGhlbmFibGVzIChjZi4gZ2gtMzAwMClcblx0XHRcdGlmICggbWFzdGVyLnN0YXRlKCkgPT09IFwicGVuZGluZ1wiIHx8XG5cdFx0XHRcdGlzRnVuY3Rpb24oIHJlc29sdmVWYWx1ZXNbIGkgXSAmJiByZXNvbHZlVmFsdWVzWyBpIF0udGhlbiApICkge1xuXG5cdFx0XHRcdHJldHVybiBtYXN0ZXIudGhlbigpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE11bHRpcGxlIGFyZ3VtZW50cyBhcmUgYWdncmVnYXRlZCBsaWtlIFByb21pc2UuYWxsIGFycmF5IGVsZW1lbnRzXG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRhZG9wdFZhbHVlKCByZXNvbHZlVmFsdWVzWyBpIF0sIHVwZGF0ZUZ1bmMoIGkgKSwgbWFzdGVyLnJlamVjdCApO1xuXHRcdH1cblxuXHRcdHJldHVybiBtYXN0ZXIucHJvbWlzZSgpO1xuXHR9XG59ICk7XG5cblxuLy8gVGhlc2UgdXN1YWxseSBpbmRpY2F0ZSBhIHByb2dyYW1tZXIgbWlzdGFrZSBkdXJpbmcgZGV2ZWxvcG1lbnQsXG4vLyB3YXJuIGFib3V0IHRoZW0gQVNBUCByYXRoZXIgdGhhbiBzd2FsbG93aW5nIHRoZW0gYnkgZGVmYXVsdC5cbnZhciByZXJyb3JOYW1lcyA9IC9eKEV2YWx8SW50ZXJuYWx8UmFuZ2V8UmVmZXJlbmNlfFN5bnRheHxUeXBlfFVSSSlFcnJvciQvO1xuXG5qUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayA9IGZ1bmN0aW9uKCBlcnJvciwgc3RhY2sgKSB7XG5cblx0Ly8gU3VwcG9ydDogSUUgOCAtIDkgb25seVxuXHQvLyBDb25zb2xlIGV4aXN0cyB3aGVuIGRldiB0b29scyBhcmUgb3Blbiwgd2hpY2ggY2FuIGhhcHBlbiBhdCBhbnkgdGltZVxuXHRpZiAoIHdpbmRvdy5jb25zb2xlICYmIHdpbmRvdy5jb25zb2xlLndhcm4gJiYgZXJyb3IgJiYgcmVycm9yTmFtZXMudGVzdCggZXJyb3IubmFtZSApICkge1xuXHRcdHdpbmRvdy5jb25zb2xlLndhcm4oIFwialF1ZXJ5LkRlZmVycmVkIGV4Y2VwdGlvbjogXCIgKyBlcnJvci5tZXNzYWdlLCBlcnJvci5zdGFjaywgc3RhY2sgKTtcblx0fVxufTtcblxuXG5cblxualF1ZXJ5LnJlYWR5RXhjZXB0aW9uID0gZnVuY3Rpb24oIGVycm9yICkge1xuXHR3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0dGhyb3cgZXJyb3I7XG5cdH0gKTtcbn07XG5cblxuXG5cbi8vIFRoZSBkZWZlcnJlZCB1c2VkIG9uIERPTSByZWFkeVxudmFyIHJlYWR5TGlzdCA9IGpRdWVyeS5EZWZlcnJlZCgpO1xuXG5qUXVlcnkuZm4ucmVhZHkgPSBmdW5jdGlvbiggZm4gKSB7XG5cblx0cmVhZHlMaXN0XG5cdFx0LnRoZW4oIGZuIClcblxuXHRcdC8vIFdyYXAgalF1ZXJ5LnJlYWR5RXhjZXB0aW9uIGluIGEgZnVuY3Rpb24gc28gdGhhdCB0aGUgbG9va3VwXG5cdFx0Ly8gaGFwcGVucyBhdCB0aGUgdGltZSBvZiBlcnJvciBoYW5kbGluZyBpbnN0ZWFkIG9mIGNhbGxiYWNrXG5cdFx0Ly8gcmVnaXN0cmF0aW9uLlxuXHRcdC5jYXRjaCggZnVuY3Rpb24oIGVycm9yICkge1xuXHRcdFx0alF1ZXJ5LnJlYWR5RXhjZXB0aW9uKCBlcnJvciApO1xuXHRcdH0gKTtcblxuXHRyZXR1cm4gdGhpcztcbn07XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHQvLyBJcyB0aGUgRE9NIHJlYWR5IHRvIGJlIHVzZWQ/IFNldCB0byB0cnVlIG9uY2UgaXQgb2NjdXJzLlxuXHRpc1JlYWR5OiBmYWxzZSxcblxuXHQvLyBBIGNvdW50ZXIgdG8gdHJhY2sgaG93IG1hbnkgaXRlbXMgdG8gd2FpdCBmb3IgYmVmb3JlXG5cdC8vIHRoZSByZWFkeSBldmVudCBmaXJlcy4gU2VlICM2NzgxXG5cdHJlYWR5V2FpdDogMSxcblxuXHQvLyBIYW5kbGUgd2hlbiB0aGUgRE9NIGlzIHJlYWR5XG5cdHJlYWR5OiBmdW5jdGlvbiggd2FpdCApIHtcblxuXHRcdC8vIEFib3J0IGlmIHRoZXJlIGFyZSBwZW5kaW5nIGhvbGRzIG9yIHdlJ3JlIGFscmVhZHkgcmVhZHlcblx0XHRpZiAoIHdhaXQgPT09IHRydWUgPyAtLWpRdWVyeS5yZWFkeVdhaXQgOiBqUXVlcnkuaXNSZWFkeSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBSZW1lbWJlciB0aGF0IHRoZSBET00gaXMgcmVhZHlcblx0XHRqUXVlcnkuaXNSZWFkeSA9IHRydWU7XG5cblx0XHQvLyBJZiBhIG5vcm1hbCBET00gUmVhZHkgZXZlbnQgZmlyZWQsIGRlY3JlbWVudCwgYW5kIHdhaXQgaWYgbmVlZCBiZVxuXHRcdGlmICggd2FpdCAhPT0gdHJ1ZSAmJiAtLWpRdWVyeS5yZWFkeVdhaXQgPiAwICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZXJlIGFyZSBmdW5jdGlvbnMgYm91bmQsIHRvIGV4ZWN1dGVcblx0XHRyZWFkeUxpc3QucmVzb2x2ZVdpdGgoIGRvY3VtZW50LCBbIGpRdWVyeSBdICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LnJlYWR5LnRoZW4gPSByZWFkeUxpc3QudGhlbjtcblxuLy8gVGhlIHJlYWR5IGV2ZW50IGhhbmRsZXIgYW5kIHNlbGYgY2xlYW51cCBtZXRob2RcbmZ1bmN0aW9uIGNvbXBsZXRlZCgpIHtcblx0ZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCApO1xuXHR3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJsb2FkXCIsIGNvbXBsZXRlZCApO1xuXHRqUXVlcnkucmVhZHkoKTtcbn1cblxuLy8gQ2F0Y2ggY2FzZXMgd2hlcmUgJChkb2N1bWVudCkucmVhZHkoKSBpcyBjYWxsZWRcbi8vIGFmdGVyIHRoZSBicm93c2VyIGV2ZW50IGhhcyBhbHJlYWR5IG9jY3VycmVkLlxuLy8gU3VwcG9ydDogSUUgPD05IC0gMTAgb25seVxuLy8gT2xkZXIgSUUgc29tZXRpbWVzIHNpZ25hbHMgXCJpbnRlcmFjdGl2ZVwiIHRvbyBzb29uXG5pZiAoIGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiB8fFxuXHQoIGRvY3VtZW50LnJlYWR5U3RhdGUgIT09IFwibG9hZGluZ1wiICYmICFkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZG9TY3JvbGwgKSApIHtcblxuXHQvLyBIYW5kbGUgaXQgYXN5bmNocm9ub3VzbHkgdG8gYWxsb3cgc2NyaXB0cyB0aGUgb3Bwb3J0dW5pdHkgdG8gZGVsYXkgcmVhZHlcblx0d2luZG93LnNldFRpbWVvdXQoIGpRdWVyeS5yZWFkeSApO1xuXG59IGVsc2Uge1xuXG5cdC8vIFVzZSB0aGUgaGFuZHkgZXZlbnQgY2FsbGJhY2tcblx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCApO1xuXG5cdC8vIEEgZmFsbGJhY2sgdG8gd2luZG93Lm9ubG9hZCwgdGhhdCB3aWxsIGFsd2F5cyB3b3JrXG5cdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCBcImxvYWRcIiwgY29tcGxldGVkICk7XG59XG5cblxuXG5cbi8vIE11bHRpZnVuY3Rpb25hbCBtZXRob2QgdG8gZ2V0IGFuZCBzZXQgdmFsdWVzIG9mIGEgY29sbGVjdGlvblxuLy8gVGhlIHZhbHVlL3MgY2FuIG9wdGlvbmFsbHkgYmUgZXhlY3V0ZWQgaWYgaXQncyBhIGZ1bmN0aW9uXG52YXIgYWNjZXNzID0gZnVuY3Rpb24oIGVsZW1zLCBmbiwga2V5LCB2YWx1ZSwgY2hhaW5hYmxlLCBlbXB0eUdldCwgcmF3ICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bGVuID0gZWxlbXMubGVuZ3RoLFxuXHRcdGJ1bGsgPSBrZXkgPT0gbnVsbDtcblxuXHQvLyBTZXRzIG1hbnkgdmFsdWVzXG5cdGlmICggdG9UeXBlKCBrZXkgKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRjaGFpbmFibGUgPSB0cnVlO1xuXHRcdGZvciAoIGkgaW4ga2V5ICkge1xuXHRcdFx0YWNjZXNzKCBlbGVtcywgZm4sIGksIGtleVsgaSBdLCB0cnVlLCBlbXB0eUdldCwgcmF3ICk7XG5cdFx0fVxuXG5cdC8vIFNldHMgb25lIHZhbHVlXG5cdH0gZWxzZSBpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcblxuXHRcdGlmICggIWlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyYXcgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmICggYnVsayApIHtcblxuXHRcdFx0Ly8gQnVsayBvcGVyYXRpb25zIHJ1biBhZ2FpbnN0IHRoZSBlbnRpcmUgc2V0XG5cdFx0XHRpZiAoIHJhdyApIHtcblx0XHRcdFx0Zm4uY2FsbCggZWxlbXMsIHZhbHVlICk7XG5cdFx0XHRcdGZuID0gbnVsbDtcblxuXHRcdFx0Ly8gLi4uZXhjZXB0IHdoZW4gZXhlY3V0aW5nIGZ1bmN0aW9uIHZhbHVlc1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0YnVsayA9IGZuO1xuXHRcdFx0XHRmbiA9IGZ1bmN0aW9uKCBlbGVtLCBfa2V5LCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gYnVsay5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdmFsdWUgKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIGZuICkge1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdGZuKFxuXHRcdFx0XHRcdGVsZW1zWyBpIF0sIGtleSwgcmF3ID9cblx0XHRcdFx0XHR2YWx1ZSA6XG5cdFx0XHRcdFx0dmFsdWUuY2FsbCggZWxlbXNbIGkgXSwgaSwgZm4oIGVsZW1zWyBpIF0sIGtleSApIClcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRpZiAoIGNoYWluYWJsZSApIHtcblx0XHRyZXR1cm4gZWxlbXM7XG5cdH1cblxuXHQvLyBHZXRzXG5cdGlmICggYnVsayApIHtcblx0XHRyZXR1cm4gZm4uY2FsbCggZWxlbXMgKTtcblx0fVxuXG5cdHJldHVybiBsZW4gPyBmbiggZWxlbXNbIDAgXSwga2V5ICkgOiBlbXB0eUdldDtcbn07XG5cblxuLy8gTWF0Y2hlcyBkYXNoZWQgc3RyaW5nIGZvciBjYW1lbGl6aW5nXG52YXIgcm1zUHJlZml4ID0gL14tbXMtLyxcblx0cmRhc2hBbHBoYSA9IC8tKFthLXpdKS9nO1xuXG4vLyBVc2VkIGJ5IGNhbWVsQ2FzZSBhcyBjYWxsYmFjayB0byByZXBsYWNlKClcbmZ1bmN0aW9uIGZjYW1lbENhc2UoIF9hbGwsIGxldHRlciApIHtcblx0cmV0dXJuIGxldHRlci50b1VwcGVyQ2FzZSgpO1xufVxuXG4vLyBDb252ZXJ0IGRhc2hlZCB0byBjYW1lbENhc2U7IHVzZWQgYnkgdGhlIGNzcyBhbmQgZGF0YSBtb2R1bGVzXG4vLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSwgRWRnZSAxMiAtIDE1XG4vLyBNaWNyb3NvZnQgZm9yZ290IHRvIGh1bXAgdGhlaXIgdmVuZG9yIHByZWZpeCAoIzk1NzIpXG5mdW5jdGlvbiBjYW1lbENhc2UoIHN0cmluZyApIHtcblx0cmV0dXJuIHN0cmluZy5yZXBsYWNlKCBybXNQcmVmaXgsIFwibXMtXCIgKS5yZXBsYWNlKCByZGFzaEFscGhhLCBmY2FtZWxDYXNlICk7XG59XG52YXIgYWNjZXB0RGF0YSA9IGZ1bmN0aW9uKCBvd25lciApIHtcblxuXHQvLyBBY2NlcHRzIG9ubHk6XG5cdC8vICAtIE5vZGVcblx0Ly8gICAgLSBOb2RlLkVMRU1FTlRfTk9ERVxuXHQvLyAgICAtIE5vZGUuRE9DVU1FTlRfTk9ERVxuXHQvLyAgLSBPYmplY3Rcblx0Ly8gICAgLSBBbnlcblx0cmV0dXJuIG93bmVyLm5vZGVUeXBlID09PSAxIHx8IG93bmVyLm5vZGVUeXBlID09PSA5IHx8ICEoICtvd25lci5ub2RlVHlwZSApO1xufTtcblxuXG5cblxuZnVuY3Rpb24gRGF0YSgpIHtcblx0dGhpcy5leHBhbmRvID0galF1ZXJ5LmV4cGFuZG8gKyBEYXRhLnVpZCsrO1xufVxuXG5EYXRhLnVpZCA9IDE7XG5cbkRhdGEucHJvdG90eXBlID0ge1xuXG5cdGNhY2hlOiBmdW5jdGlvbiggb3duZXIgKSB7XG5cblx0XHQvLyBDaGVjayBpZiB0aGUgb3duZXIgb2JqZWN0IGFscmVhZHkgaGFzIGEgY2FjaGVcblx0XHR2YXIgdmFsdWUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cblx0XHQvLyBJZiBub3QsIGNyZWF0ZSBvbmVcblx0XHRpZiAoICF2YWx1ZSApIHtcblx0XHRcdHZhbHVlID0ge307XG5cblx0XHRcdC8vIFdlIGNhbiBhY2NlcHQgZGF0YSBmb3Igbm9uLWVsZW1lbnQgbm9kZXMgaW4gbW9kZXJuIGJyb3dzZXJzLFxuXHRcdFx0Ly8gYnV0IHdlIHNob3VsZCBub3QsIHNlZSAjODMzNS5cblx0XHRcdC8vIEFsd2F5cyByZXR1cm4gYW4gZW1wdHkgb2JqZWN0LlxuXHRcdFx0aWYgKCBhY2NlcHREYXRhKCBvd25lciApICkge1xuXG5cdFx0XHRcdC8vIElmIGl0IGlzIGEgbm9kZSB1bmxpa2VseSB0byBiZSBzdHJpbmdpZnktZWQgb3IgbG9vcGVkIG92ZXJcblx0XHRcdFx0Ly8gdXNlIHBsYWluIGFzc2lnbm1lbnRcblx0XHRcdFx0aWYgKCBvd25lci5ub2RlVHlwZSApIHtcblx0XHRcdFx0XHRvd25lclsgdGhpcy5leHBhbmRvIF0gPSB2YWx1ZTtcblxuXHRcdFx0XHQvLyBPdGhlcndpc2Ugc2VjdXJlIGl0IGluIGEgbm9uLWVudW1lcmFibGUgcHJvcGVydHlcblx0XHRcdFx0Ly8gY29uZmlndXJhYmxlIG11c3QgYmUgdHJ1ZSB0byBhbGxvdyB0aGUgcHJvcGVydHkgdG8gYmVcblx0XHRcdFx0Ly8gZGVsZXRlZCB3aGVuIGRhdGEgaXMgcmVtb3ZlZFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggb3duZXIsIHRoaXMuZXhwYW5kbywge1xuXHRcdFx0XHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0XHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlXG5cdFx0XHRcdFx0fSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9LFxuXHRzZXQ6IGZ1bmN0aW9uKCBvd25lciwgZGF0YSwgdmFsdWUgKSB7XG5cdFx0dmFyIHByb3AsXG5cdFx0XHRjYWNoZSA9IHRoaXMuY2FjaGUoIG93bmVyICk7XG5cblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIGtleSwgdmFsdWUgXSBhcmdzXG5cdFx0Ly8gQWx3YXlzIHVzZSBjYW1lbENhc2Uga2V5IChnaC0yMjU3KVxuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRjYWNoZVsgY2FtZWxDYXNlKCBkYXRhICkgXSA9IHZhbHVlO1xuXG5cdFx0Ly8gSGFuZGxlOiBbIG93bmVyLCB7IHByb3BlcnRpZXMgfSBdIGFyZ3Ncblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBDb3B5IHRoZSBwcm9wZXJ0aWVzIG9uZS1ieS1vbmUgdG8gdGhlIGNhY2hlIG9iamVjdFxuXHRcdFx0Zm9yICggcHJvcCBpbiBkYXRhICkge1xuXHRcdFx0XHRjYWNoZVsgY2FtZWxDYXNlKCBwcm9wICkgXSA9IGRhdGFbIHByb3AgXTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGNhY2hlO1xuXHR9LFxuXHRnZXQ6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xuXHRcdHJldHVybiBrZXkgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHR0aGlzLmNhY2hlKCBvd25lciApIDpcblxuXHRcdFx0Ly8gQWx3YXlzIHVzZSBjYW1lbENhc2Uga2V5IChnaC0yMjU3KVxuXHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdICYmIG93bmVyWyB0aGlzLmV4cGFuZG8gXVsgY2FtZWxDYXNlKCBrZXkgKSBdO1xuXHR9LFxuXHRhY2Nlc3M6IGZ1bmN0aW9uKCBvd25lciwga2V5LCB2YWx1ZSApIHtcblxuXHRcdC8vIEluIGNhc2VzIHdoZXJlIGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gTm8ga2V5IHdhcyBzcGVjaWZpZWRcblx0XHQvLyAgIDIuIEEgc3RyaW5nIGtleSB3YXMgc3BlY2lmaWVkLCBidXQgbm8gdmFsdWUgcHJvdmlkZWRcblx0XHQvL1xuXHRcdC8vIFRha2UgdGhlIFwicmVhZFwiIHBhdGggYW5kIGFsbG93IHRoZSBnZXQgbWV0aG9kIHRvIGRldGVybWluZVxuXHRcdC8vIHdoaWNoIHZhbHVlIHRvIHJldHVybiwgcmVzcGVjdGl2ZWx5IGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gVGhlIGVudGlyZSBjYWNoZSBvYmplY3Rcblx0XHQvLyAgIDIuIFRoZSBkYXRhIHN0b3JlZCBhdCB0aGUga2V5XG5cdFx0Ly9cblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdCggKCBrZXkgJiYgdHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiApICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSApIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0KCBvd25lciwga2V5ICk7XG5cdFx0fVxuXG5cdFx0Ly8gV2hlbiB0aGUga2V5IGlzIG5vdCBhIHN0cmluZywgb3IgYm90aCBhIGtleSBhbmQgdmFsdWVcblx0XHQvLyBhcmUgc3BlY2lmaWVkLCBzZXQgb3IgZXh0ZW5kIChleGlzdGluZyBvYmplY3RzKSB3aXRoIGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gQW4gb2JqZWN0IG9mIHByb3BlcnRpZXNcblx0XHQvLyAgIDIuIEEga2V5IGFuZCB2YWx1ZVxuXHRcdC8vXG5cdFx0dGhpcy5zZXQoIG93bmVyLCBrZXksIHZhbHVlICk7XG5cblx0XHQvLyBTaW5jZSB0aGUgXCJzZXRcIiBwYXRoIGNhbiBoYXZlIHR3byBwb3NzaWJsZSBlbnRyeSBwb2ludHNcblx0XHQvLyByZXR1cm4gdGhlIGV4cGVjdGVkIGRhdGEgYmFzZWQgb24gd2hpY2ggcGF0aCB3YXMgdGFrZW5bKl1cblx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDoga2V5O1xuXHR9LFxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xuXHRcdHZhciBpLFxuXHRcdFx0Y2FjaGUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cblx0XHRpZiAoIGNhY2hlID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCBrZXkgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Ly8gU3VwcG9ydCBhcnJheSBvciBzcGFjZSBzZXBhcmF0ZWQgc3RyaW5nIG9mIGtleXNcblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSgga2V5ICkgKSB7XG5cblx0XHRcdFx0Ly8gSWYga2V5IGlzIGFuIGFycmF5IG9mIGtleXMuLi5cblx0XHRcdFx0Ly8gV2UgYWx3YXlzIHNldCBjYW1lbENhc2Uga2V5cywgc28gcmVtb3ZlIHRoYXQuXG5cdFx0XHRcdGtleSA9IGtleS5tYXAoIGNhbWVsQ2FzZSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0a2V5ID0gY2FtZWxDYXNlKCBrZXkgKTtcblxuXHRcdFx0XHQvLyBJZiBhIGtleSB3aXRoIHRoZSBzcGFjZXMgZXhpc3RzLCB1c2UgaXQuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSwgY3JlYXRlIGFuIGFycmF5IGJ5IG1hdGNoaW5nIG5vbi13aGl0ZXNwYWNlXG5cdFx0XHRcdGtleSA9IGtleSBpbiBjYWNoZSA/XG5cdFx0XHRcdFx0WyBrZXkgXSA6XG5cdFx0XHRcdFx0KCBrZXkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpID0ga2V5Lmxlbmd0aDtcblxuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGRlbGV0ZSBjYWNoZVsga2V5WyBpIF0gXTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBSZW1vdmUgdGhlIGV4cGFuZG8gaWYgdGhlcmUncyBubyBtb3JlIGRhdGFcblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkIHx8IGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBjYWNoZSApICkge1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0zNSAtIDQ1XG5cdFx0XHQvLyBXZWJraXQgJiBCbGluayBwZXJmb3JtYW5jZSBzdWZmZXJzIHdoZW4gZGVsZXRpbmcgcHJvcGVydGllc1xuXHRcdFx0Ly8gZnJvbSBET00gbm9kZXMsIHNvIHNldCB0byB1bmRlZmluZWQgaW5zdGVhZFxuXHRcdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9Mzc4NjA3IChidWcgcmVzdHJpY3RlZClcblx0XHRcdGlmICggb3duZXIubm9kZVR5cGUgKSB7XG5cdFx0XHRcdG93bmVyWyB0aGlzLmV4cGFuZG8gXSA9IHVuZGVmaW5lZDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlbGV0ZSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRoYXNEYXRhOiBmdW5jdGlvbiggb3duZXIgKSB7XG5cdFx0dmFyIGNhY2hlID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xuXHRcdHJldHVybiBjYWNoZSAhPT0gdW5kZWZpbmVkICYmICFqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKTtcblx0fVxufTtcbnZhciBkYXRhUHJpdiA9IG5ldyBEYXRhKCk7XG5cbnZhciBkYXRhVXNlciA9IG5ldyBEYXRhKCk7XG5cblxuXG4vL1x0SW1wbGVtZW50YXRpb24gU3VtbWFyeVxuLy9cbi8vXHQxLiBFbmZvcmNlIEFQSSBzdXJmYWNlIGFuZCBzZW1hbnRpYyBjb21wYXRpYmlsaXR5IHdpdGggMS45LnggYnJhbmNoXG4vL1x0Mi4gSW1wcm92ZSB0aGUgbW9kdWxlJ3MgbWFpbnRhaW5hYmlsaXR5IGJ5IHJlZHVjaW5nIHRoZSBzdG9yYWdlXG4vL1x0XHRwYXRocyB0byBhIHNpbmdsZSBtZWNoYW5pc20uXG4vL1x0My4gVXNlIHRoZSBzYW1lIHNpbmdsZSBtZWNoYW5pc20gdG8gc3VwcG9ydCBcInByaXZhdGVcIiBhbmQgXCJ1c2VyXCIgZGF0YS5cbi8vXHQ0LiBfTmV2ZXJfIGV4cG9zZSBcInByaXZhdGVcIiBkYXRhIHRvIHVzZXIgY29kZSAoVE9ETzogRHJvcCBfZGF0YSwgX3JlbW92ZURhdGEpXG4vL1x0NS4gQXZvaWQgZXhwb3NpbmcgaW1wbGVtZW50YXRpb24gZGV0YWlscyBvbiB1c2VyIG9iamVjdHMgKGVnLiBleHBhbmRvIHByb3BlcnRpZXMpXG4vL1x0Ni4gUHJvdmlkZSBhIGNsZWFyIHBhdGggZm9yIGltcGxlbWVudGF0aW9uIHVwZ3JhZGUgdG8gV2Vha01hcCBpbiAyMDE0XG5cbnZhciByYnJhY2UgPSAvXig/Olxce1tcXHdcXFddKlxcfXxcXFtbXFx3XFxXXSpcXF0pJC8sXG5cdHJtdWx0aURhc2ggPSAvW0EtWl0vZztcblxuZnVuY3Rpb24gZ2V0RGF0YSggZGF0YSApIHtcblx0aWYgKCBkYXRhID09PSBcInRydWVcIiApIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdGlmICggZGF0YSA9PT0gXCJmYWxzZVwiICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGlmICggZGF0YSA9PT0gXCJudWxsXCIgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvLyBPbmx5IGNvbnZlcnQgdG8gYSBudW1iZXIgaWYgaXQgZG9lc24ndCBjaGFuZ2UgdGhlIHN0cmluZ1xuXHRpZiAoIGRhdGEgPT09ICtkYXRhICsgXCJcIiApIHtcblx0XHRyZXR1cm4gK2RhdGE7XG5cdH1cblxuXHRpZiAoIHJicmFjZS50ZXN0KCBkYXRhICkgKSB7XG5cdFx0cmV0dXJuIEpTT04ucGFyc2UoIGRhdGEgKTtcblx0fVxuXG5cdHJldHVybiBkYXRhO1xufVxuXG5mdW5jdGlvbiBkYXRhQXR0ciggZWxlbSwga2V5LCBkYXRhICkge1xuXHR2YXIgbmFtZTtcblxuXHQvLyBJZiBub3RoaW5nIHdhcyBmb3VuZCBpbnRlcm5hbGx5LCB0cnkgdG8gZmV0Y2ggYW55XG5cdC8vIGRhdGEgZnJvbSB0aGUgSFRNTDUgZGF0YS0qIGF0dHJpYnV0ZVxuXHRpZiAoIGRhdGEgPT09IHVuZGVmaW5lZCAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdG5hbWUgPSBcImRhdGEtXCIgKyBrZXkucmVwbGFjZSggcm11bHRpRGFzaCwgXCItJCZcIiApLnRvTG93ZXJDYXNlKCk7XG5cdFx0ZGF0YSA9IGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lICk7XG5cblx0XHRpZiAoIHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0ZGF0YSA9IGdldERhdGEoIGRhdGEgKTtcblx0XHRcdH0gY2F0Y2ggKCBlICkge31cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHdlIHNldCB0aGUgZGF0YSBzbyBpdCBpc24ndCBjaGFuZ2VkIGxhdGVyXG5cdFx0XHRkYXRhVXNlci5zZXQoIGVsZW0sIGtleSwgZGF0YSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZGF0YTtcbn1cblxualF1ZXJ5LmV4dGVuZCgge1xuXHRoYXNEYXRhOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGF0YVVzZXIuaGFzRGF0YSggZWxlbSApIHx8IGRhdGFQcml2Lmhhc0RhdGEoIGVsZW0gKTtcblx0fSxcblxuXHRkYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gZGF0YVVzZXIuYWNjZXNzKCBlbGVtLCBuYW1lLCBkYXRhICk7XG5cdH0sXG5cblx0cmVtb3ZlRGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cdFx0ZGF0YVVzZXIucmVtb3ZlKCBlbGVtLCBuYW1lICk7XG5cdH0sXG5cblx0Ly8gVE9ETzogTm93IHRoYXQgYWxsIGNhbGxzIHRvIF9kYXRhIGFuZCBfcmVtb3ZlRGF0YSBoYXZlIGJlZW4gcmVwbGFjZWRcblx0Ly8gd2l0aCBkaXJlY3QgY2FsbHMgdG8gZGF0YVByaXYgbWV0aG9kcywgdGhlc2UgY2FuIGJlIGRlcHJlY2F0ZWQuXG5cdF9kYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBuYW1lLCBkYXRhICk7XG5cdH0sXG5cblx0X3JlbW92ZURhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgbmFtZSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0ZGF0YTogZnVuY3Rpb24oIGtleSwgdmFsdWUgKSB7XG5cdFx0dmFyIGksIG5hbWUsIGRhdGEsXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdLFxuXHRcdFx0YXR0cnMgPSBlbGVtICYmIGVsZW0uYXR0cmlidXRlcztcblxuXHRcdC8vIEdldHMgYWxsIHZhbHVlc1xuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRpZiAoIHRoaXMubGVuZ3RoICkge1xuXHRcdFx0XHRkYXRhID0gZGF0YVVzZXIuZ2V0KCBlbGVtICk7XG5cblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICFkYXRhUHJpdi5nZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIgKSApIHtcblx0XHRcdFx0XHRpID0gYXR0cnMubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSBvbmx5XG5cdFx0XHRcdFx0XHQvLyBUaGUgYXR0cnMgZWxlbWVudHMgY2FuIGJlIG51bGwgKCMxNDg5NClcblx0XHRcdFx0XHRcdGlmICggYXR0cnNbIGkgXSApIHtcblx0XHRcdFx0XHRcdFx0bmFtZSA9IGF0dHJzWyBpIF0ubmFtZTtcblx0XHRcdFx0XHRcdFx0aWYgKCBuYW1lLmluZGV4T2YoIFwiZGF0YS1cIiApID09PSAwICkge1xuXHRcdFx0XHRcdFx0XHRcdG5hbWUgPSBjYW1lbENhc2UoIG5hbWUuc2xpY2UoIDUgKSApO1xuXHRcdFx0XHRcdFx0XHRcdGRhdGFBdHRyKCBlbGVtLCBuYW1lLCBkYXRhWyBuYW1lIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZGF0YTtcblx0XHR9XG5cblx0XHQvLyBTZXRzIG11bHRpcGxlIHZhbHVlc1xuXHRcdGlmICggdHlwZW9mIGtleSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhVXNlci5zZXQoIHRoaXMsIGtleSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBkYXRhO1xuXG5cdFx0XHQvLyBUaGUgY2FsbGluZyBqUXVlcnkgb2JqZWN0IChlbGVtZW50IG1hdGNoZXMpIGlzIG5vdCBlbXB0eVxuXHRcdFx0Ly8gKGFuZCB0aGVyZWZvcmUgaGFzIGFuIGVsZW1lbnQgYXBwZWFycyBhdCB0aGlzWyAwIF0pIGFuZCB0aGVcblx0XHRcdC8vIGB2YWx1ZWAgcGFyYW1ldGVyIHdhcyBub3QgdW5kZWZpbmVkLiBBbiBlbXB0eSBqUXVlcnkgb2JqZWN0XG5cdFx0XHQvLyB3aWxsIHJlc3VsdCBpbiBgdW5kZWZpbmVkYCBmb3IgZWxlbSA9IHRoaXNbIDAgXSB3aGljaCB3aWxsXG5cdFx0XHQvLyB0aHJvdyBhbiBleGNlcHRpb24gaWYgYW4gYXR0ZW1wdCB0byByZWFkIGEgZGF0YSBjYWNoZSBpcyBtYWRlLlxuXHRcdFx0aWYgKCBlbGVtICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBnZXQgZGF0YSBmcm9tIHRoZSBjYWNoZVxuXHRcdFx0XHQvLyBUaGUga2V5IHdpbGwgYWx3YXlzIGJlIGNhbWVsQ2FzZWQgaW4gRGF0YVxuXHRcdFx0XHRkYXRhID0gZGF0YVVzZXIuZ2V0KCBlbGVtLCBrZXkgKTtcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBdHRlbXB0IHRvIFwiZGlzY292ZXJcIiB0aGUgZGF0YSBpblxuXHRcdFx0XHQvLyBIVE1MNSBjdXN0b20gZGF0YS0qIGF0dHJzXG5cdFx0XHRcdGRhdGEgPSBkYXRhQXR0ciggZWxlbSwga2V5ICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gV2UgdHJpZWQgcmVhbGx5IGhhcmQsIGJ1dCB0aGUgZGF0YSBkb2Vzbid0IGV4aXN0LlxuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgZGF0YS4uLlxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBXZSBhbHdheXMgc3RvcmUgdGhlIGNhbWVsQ2FzZWQga2V5XG5cdFx0XHRcdGRhdGFVc2VyLnNldCggdGhpcywga2V5LCB2YWx1ZSApO1xuXHRcdFx0fSApO1xuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSwgbnVsbCwgdHJ1ZSApO1xuXHR9LFxuXG5cdHJlbW92ZURhdGE6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRkYXRhVXNlci5yZW1vdmUoIHRoaXMsIGtleSApO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5cbmpRdWVyeS5leHRlbmQoIHtcblx0cXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBxdWV1ZTtcblxuXHRcdGlmICggZWxlbSApIHtcblx0XHRcdHR5cGUgPSAoIHR5cGUgfHwgXCJmeFwiICkgKyBcInF1ZXVlXCI7XG5cdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmdldCggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHQvLyBTcGVlZCB1cCBkZXF1ZXVlIGJ5IGdldHRpbmcgb3V0IHF1aWNrbHkgaWYgdGhpcyBpcyBqdXN0IGEgbG9va3VwXG5cdFx0XHRpZiAoIGRhdGEgKSB7XG5cdFx0XHRcdGlmICggIXF1ZXVlIHx8IEFycmF5LmlzQXJyYXkoIGRhdGEgKSApIHtcblx0XHRcdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmFjY2VzcyggZWxlbSwgdHlwZSwgalF1ZXJ5Lm1ha2VBcnJheSggZGF0YSApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cXVldWUucHVzaCggZGF0YSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcXVldWUgfHwgW107XG5cdFx0fVxuXHR9LFxuXG5cdGRlcXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRcdHZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggZWxlbSwgdHlwZSApLFxuXHRcdFx0c3RhcnRMZW5ndGggPSBxdWV1ZS5sZW5ndGgsXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCksXG5cdFx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgdHlwZSApLFxuXHRcdFx0bmV4dCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggZWxlbSwgdHlwZSApO1xuXHRcdFx0fTtcblxuXHRcdC8vIElmIHRoZSBmeCBxdWV1ZSBpcyBkZXF1ZXVlZCwgYWx3YXlzIHJlbW92ZSB0aGUgcHJvZ3Jlc3Mgc2VudGluZWxcblx0XHRpZiAoIGZuID09PSBcImlucHJvZ3Jlc3NcIiApIHtcblx0XHRcdGZuID0gcXVldWUuc2hpZnQoKTtcblx0XHRcdHN0YXJ0TGVuZ3RoLS07XG5cdFx0fVxuXG5cdFx0aWYgKCBmbiApIHtcblxuXHRcdFx0Ly8gQWRkIGEgcHJvZ3Jlc3Mgc2VudGluZWwgdG8gcHJldmVudCB0aGUgZnggcXVldWUgZnJvbSBiZWluZ1xuXHRcdFx0Ly8gYXV0b21hdGljYWxseSBkZXF1ZXVlZFxuXHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgKSB7XG5cdFx0XHRcdHF1ZXVlLnVuc2hpZnQoIFwiaW5wcm9ncmVzc1wiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENsZWFyIHVwIHRoZSBsYXN0IHF1ZXVlIHN0b3AgZnVuY3Rpb25cblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xuXHRcdFx0Zm4uY2FsbCggZWxlbSwgbmV4dCwgaG9va3MgKTtcblx0XHR9XG5cblx0XHRpZiAoICFzdGFydExlbmd0aCAmJiBob29rcyApIHtcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gTm90IHB1YmxpYyAtIGdlbmVyYXRlIGEgcXVldWVIb29rcyBvYmplY3QsIG9yIHJldHVybiB0aGUgY3VycmVudCBvbmVcblx0X3F1ZXVlSG9va3M6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHZhciBrZXkgPSB0eXBlICsgXCJxdWV1ZUhvb2tzXCI7XG5cdFx0cmV0dXJuIGRhdGFQcml2LmdldCggZWxlbSwga2V5ICkgfHwgZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBrZXksIHtcblx0XHRcdGVtcHR5OiBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKS5hZGQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFsgdHlwZSArIFwicXVldWVcIiwga2V5IF0gKTtcblx0XHRcdH0gKVxuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHF1ZXVlOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgc2V0dGVyID0gMjtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRkYXRhID0gdHlwZTtcblx0XHRcdHR5cGUgPSBcImZ4XCI7XG5cdFx0XHRzZXR0ZXItLTtcblx0XHR9XG5cblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPCBzZXR0ZXIgKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LnF1ZXVlKCB0aGlzWyAwIF0sIHR5cGUgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHRoaXMgOlxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCB0aGlzLCB0eXBlLCBkYXRhICk7XG5cblx0XHRcdFx0Ly8gRW5zdXJlIGEgaG9va3MgZm9yIHRoaXMgcXVldWVcblx0XHRcdFx0alF1ZXJ5Ll9xdWV1ZUhvb2tzKCB0aGlzLCB0eXBlICk7XG5cblx0XHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgJiYgcXVldWVbIDAgXSAhPT0gXCJpbnByb2dyZXNzXCIgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHR9LFxuXHRkZXF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0fSApO1xuXHR9LFxuXHRjbGVhclF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSB8fCBcImZ4XCIsIFtdICk7XG5cdH0sXG5cblx0Ly8gR2V0IGEgcHJvbWlzZSByZXNvbHZlZCB3aGVuIHF1ZXVlcyBvZiBhIGNlcnRhaW4gdHlwZVxuXHQvLyBhcmUgZW1wdGllZCAoZnggaXMgdGhlIHR5cGUgYnkgZGVmYXVsdClcblx0cHJvbWlzZTogZnVuY3Rpb24oIHR5cGUsIG9iaiApIHtcblx0XHR2YXIgdG1wLFxuXHRcdFx0Y291bnQgPSAxLFxuXHRcdFx0ZGVmZXIgPSBqUXVlcnkuRGVmZXJyZWQoKSxcblx0XHRcdGVsZW1lbnRzID0gdGhpcyxcblx0XHRcdGkgPSB0aGlzLmxlbmd0aCxcblx0XHRcdHJlc29sdmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhKCAtLWNvdW50ICkgKSB7XG5cdFx0XHRcdFx0ZGVmZXIucmVzb2x2ZVdpdGgoIGVsZW1lbnRzLCBbIGVsZW1lbnRzIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRvYmogPSB0eXBlO1xuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHR0bXAgPSBkYXRhUHJpdi5nZXQoIGVsZW1lbnRzWyBpIF0sIHR5cGUgKyBcInF1ZXVlSG9va3NcIiApO1xuXHRcdFx0aWYgKCB0bXAgJiYgdG1wLmVtcHR5ICkge1xuXHRcdFx0XHRjb3VudCsrO1xuXHRcdFx0XHR0bXAuZW1wdHkuYWRkKCByZXNvbHZlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJlc29sdmUoKTtcblx0XHRyZXR1cm4gZGVmZXIucHJvbWlzZSggb2JqICk7XG5cdH1cbn0gKTtcbnZhciBwbnVtID0gKCAvWystXT8oPzpcXGQqXFwufClcXGQrKD86W2VFXVsrLV0/XFxkK3wpLyApLnNvdXJjZTtcblxudmFyIHJjc3NOdW0gPSBuZXcgUmVnRXhwKCBcIl4oPzooWystXSk9fCkoXCIgKyBwbnVtICsgXCIpKFthLXolXSopJFwiLCBcImlcIiApO1xuXG5cbnZhciBjc3NFeHBhbmQgPSBbIFwiVG9wXCIsIFwiUmlnaHRcIiwgXCJCb3R0b21cIiwgXCJMZWZ0XCIgXTtcblxudmFyIGRvY3VtZW50RWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuXG5cblx0dmFyIGlzQXR0YWNoZWQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApO1xuXHRcdH0sXG5cdFx0Y29tcG9zZWQgPSB7IGNvbXBvc2VkOiB0cnVlIH07XG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExKywgRWRnZSAxMiAtIDE4KywgaU9TIDEwLjAgLSAxMC4yIG9ubHlcblx0Ly8gQ2hlY2sgYXR0YWNobWVudCBhY3Jvc3Mgc2hhZG93IERPTSBib3VuZGFyaWVzIHdoZW4gcG9zc2libGUgKGdoLTM1MDQpXG5cdC8vIFN1cHBvcnQ6IGlPUyAxMC4wLTEwLjIgb25seVxuXHQvLyBFYXJseSBpT1MgMTAgdmVyc2lvbnMgc3VwcG9ydCBgYXR0YWNoU2hhZG93YCBidXQgbm90IGBnZXRSb290Tm9kZWAsXG5cdC8vIGxlYWRpbmcgdG8gZXJyb3JzLiBXZSBuZWVkIHRvIGNoZWNrIGZvciBgZ2V0Um9vdE5vZGVgLlxuXHRpZiAoIGRvY3VtZW50RWxlbWVudC5nZXRSb290Tm9kZSApIHtcblx0XHRpc0F0dGFjaGVkID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKSB8fFxuXHRcdFx0XHRlbGVtLmdldFJvb3ROb2RlKCBjb21wb3NlZCApID09PSBlbGVtLm93bmVyRG9jdW1lbnQ7XG5cdFx0fTtcblx0fVxudmFyIGlzSGlkZGVuV2l0aGluVHJlZSA9IGZ1bmN0aW9uKCBlbGVtLCBlbCApIHtcblxuXHRcdC8vIGlzSGlkZGVuV2l0aGluVHJlZSBtaWdodCBiZSBjYWxsZWQgZnJvbSBqUXVlcnkjZmlsdGVyIGZ1bmN0aW9uO1xuXHRcdC8vIGluIHRoYXQgY2FzZSwgZWxlbWVudCB3aWxsIGJlIHNlY29uZCBhcmd1bWVudFxuXHRcdGVsZW0gPSBlbCB8fCBlbGVtO1xuXG5cdFx0Ly8gSW5saW5lIHN0eWxlIHRydW1wcyBhbGxcblx0XHRyZXR1cm4gZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIm5vbmVcIiB8fFxuXHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmXG5cblx0XHRcdC8vIE90aGVyd2lzZSwgY2hlY2sgY29tcHV0ZWQgc3R5bGVcblx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD00MyAtIDQ1XG5cdFx0XHQvLyBEaXNjb25uZWN0ZWQgZWxlbWVudHMgY2FuIGhhdmUgY29tcHV0ZWQgZGlzcGxheTogbm9uZSwgc28gZmlyc3QgY29uZmlybSB0aGF0IGVsZW0gaXNcblx0XHRcdC8vIGluIHRoZSBkb2N1bWVudC5cblx0XHRcdGlzQXR0YWNoZWQoIGVsZW0gKSAmJlxuXG5cdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApID09PSBcIm5vbmVcIjtcblx0fTtcblxuXG5cbmZ1bmN0aW9uIGFkanVzdENTUyggZWxlbSwgcHJvcCwgdmFsdWVQYXJ0cywgdHdlZW4gKSB7XG5cdHZhciBhZGp1c3RlZCwgc2NhbGUsXG5cdFx0bWF4SXRlcmF0aW9ucyA9IDIwLFxuXHRcdGN1cnJlbnRWYWx1ZSA9IHR3ZWVuID9cblx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gdHdlZW4uY3VyKCk7XG5cdFx0XHR9IDpcblx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4galF1ZXJ5LmNzcyggZWxlbSwgcHJvcCwgXCJcIiApO1xuXHRcdFx0fSxcblx0XHRpbml0aWFsID0gY3VycmVudFZhbHVlKCksXG5cdFx0dW5pdCA9IHZhbHVlUGFydHMgJiYgdmFsdWVQYXJ0c1sgMyBdIHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApLFxuXG5cdFx0Ly8gU3RhcnRpbmcgdmFsdWUgY29tcHV0YXRpb24gaXMgcmVxdWlyZWQgZm9yIHBvdGVudGlhbCB1bml0IG1pc21hdGNoZXNcblx0XHRpbml0aWFsSW5Vbml0ID0gZWxlbS5ub2RlVHlwZSAmJlxuXHRcdFx0KCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gfHwgdW5pdCAhPT0gXCJweFwiICYmICtpbml0aWFsICkgJiZcblx0XHRcdHJjc3NOdW0uZXhlYyggalF1ZXJ5LmNzcyggZWxlbSwgcHJvcCApICk7XG5cblx0aWYgKCBpbml0aWFsSW5Vbml0ICYmIGluaXRpYWxJblVuaXRbIDMgXSAhPT0gdW5pdCApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD01NFxuXHRcdC8vIEhhbHZlIHRoZSBpdGVyYXRpb24gdGFyZ2V0IHZhbHVlIHRvIHByZXZlbnQgaW50ZXJmZXJlbmNlIGZyb20gQ1NTIHVwcGVyIGJvdW5kcyAoZ2gtMjE0NClcblx0XHRpbml0aWFsID0gaW5pdGlhbCAvIDI7XG5cblx0XHQvLyBUcnVzdCB1bml0cyByZXBvcnRlZCBieSBqUXVlcnkuY3NzXG5cdFx0dW5pdCA9IHVuaXQgfHwgaW5pdGlhbEluVW5pdFsgMyBdO1xuXG5cdFx0Ly8gSXRlcmF0aXZlbHkgYXBwcm94aW1hdGUgZnJvbSBhIG5vbnplcm8gc3RhcnRpbmcgcG9pbnRcblx0XHRpbml0aWFsSW5Vbml0ID0gK2luaXRpYWwgfHwgMTtcblxuXHRcdHdoaWxlICggbWF4SXRlcmF0aW9ucy0tICkge1xuXG5cdFx0XHQvLyBFdmFsdWF0ZSBhbmQgdXBkYXRlIG91ciBiZXN0IGd1ZXNzIChkb3VibGluZyBndWVzc2VzIHRoYXQgemVybyBvdXQpLlxuXHRcdFx0Ly8gRmluaXNoIGlmIHRoZSBzY2FsZSBlcXVhbHMgb3IgY3Jvc3NlcyAxIChtYWtpbmcgdGhlIG9sZCpuZXcgcHJvZHVjdCBub24tcG9zaXRpdmUpLlxuXHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBpbml0aWFsSW5Vbml0ICsgdW5pdCApO1xuXHRcdFx0aWYgKCAoIDEgLSBzY2FsZSApICogKCAxIC0gKCBzY2FsZSA9IGN1cnJlbnRWYWx1ZSgpIC8gaW5pdGlhbCB8fCAwLjUgKSApIDw9IDAgKSB7XG5cdFx0XHRcdG1heEl0ZXJhdGlvbnMgPSAwO1xuXHRcdFx0fVxuXHRcdFx0aW5pdGlhbEluVW5pdCA9IGluaXRpYWxJblVuaXQgLyBzY2FsZTtcblxuXHRcdH1cblxuXHRcdGluaXRpYWxJblVuaXQgPSBpbml0aWFsSW5Vbml0ICogMjtcblx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AsIGluaXRpYWxJblVuaXQgKyB1bml0ICk7XG5cblx0XHQvLyBNYWtlIHN1cmUgd2UgdXBkYXRlIHRoZSB0d2VlbiBwcm9wZXJ0aWVzIGxhdGVyIG9uXG5cdFx0dmFsdWVQYXJ0cyA9IHZhbHVlUGFydHMgfHwgW107XG5cdH1cblxuXHRpZiAoIHZhbHVlUGFydHMgKSB7XG5cdFx0aW5pdGlhbEluVW5pdCA9ICtpbml0aWFsSW5Vbml0IHx8ICtpbml0aWFsIHx8IDA7XG5cblx0XHQvLyBBcHBseSByZWxhdGl2ZSBvZmZzZXQgKCs9Ly09KSBpZiBzcGVjaWZpZWRcblx0XHRhZGp1c3RlZCA9IHZhbHVlUGFydHNbIDEgXSA/XG5cdFx0XHRpbml0aWFsSW5Vbml0ICsgKCB2YWx1ZVBhcnRzWyAxIF0gKyAxICkgKiB2YWx1ZVBhcnRzWyAyIF0gOlxuXHRcdFx0K3ZhbHVlUGFydHNbIDIgXTtcblx0XHRpZiAoIHR3ZWVuICkge1xuXHRcdFx0dHdlZW4udW5pdCA9IHVuaXQ7XG5cdFx0XHR0d2Vlbi5zdGFydCA9IGluaXRpYWxJblVuaXQ7XG5cdFx0XHR0d2Vlbi5lbmQgPSBhZGp1c3RlZDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGFkanVzdGVkO1xufVxuXG5cbnZhciBkZWZhdWx0RGlzcGxheU1hcCA9IHt9O1xuXG5mdW5jdGlvbiBnZXREZWZhdWx0RGlzcGxheSggZWxlbSApIHtcblx0dmFyIHRlbXAsXG5cdFx0ZG9jID0gZWxlbS5vd25lckRvY3VtZW50LFxuXHRcdG5vZGVOYW1lID0gZWxlbS5ub2RlTmFtZSxcblx0XHRkaXNwbGF5ID0gZGVmYXVsdERpc3BsYXlNYXBbIG5vZGVOYW1lIF07XG5cblx0aWYgKCBkaXNwbGF5ICkge1xuXHRcdHJldHVybiBkaXNwbGF5O1xuXHR9XG5cblx0dGVtcCA9IGRvYy5ib2R5LmFwcGVuZENoaWxkKCBkb2MuY3JlYXRlRWxlbWVudCggbm9kZU5hbWUgKSApO1xuXHRkaXNwbGF5ID0galF1ZXJ5LmNzcyggdGVtcCwgXCJkaXNwbGF5XCIgKTtcblxuXHR0ZW1wLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHRlbXAgKTtcblxuXHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdGRpc3BsYXkgPSBcImJsb2NrXCI7XG5cdH1cblx0ZGVmYXVsdERpc3BsYXlNYXBbIG5vZGVOYW1lIF0gPSBkaXNwbGF5O1xuXG5cdHJldHVybiBkaXNwbGF5O1xufVxuXG5mdW5jdGlvbiBzaG93SGlkZSggZWxlbWVudHMsIHNob3cgKSB7XG5cdHZhciBkaXNwbGF5LCBlbGVtLFxuXHRcdHZhbHVlcyA9IFtdLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7XG5cblx0Ly8gRGV0ZXJtaW5lIG5ldyBkaXNwbGF5IHZhbHVlIGZvciBlbGVtZW50cyB0aGF0IG5lZWQgdG8gY2hhbmdlXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXHRcdGlmICggIWVsZW0uc3R5bGUgKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHRkaXNwbGF5ID0gZWxlbS5zdHlsZS5kaXNwbGF5O1xuXHRcdGlmICggc2hvdyApIHtcblxuXHRcdFx0Ly8gU2luY2Ugd2UgZm9yY2UgdmlzaWJpbGl0eSB1cG9uIGNhc2NhZGUtaGlkZGVuIGVsZW1lbnRzLCBhbiBpbW1lZGlhdGUgKGFuZCBzbG93KVxuXHRcdFx0Ly8gY2hlY2sgaXMgcmVxdWlyZWQgaW4gdGhpcyBmaXJzdCBsb29wIHVubGVzcyB3ZSBoYXZlIGEgbm9uZW1wdHkgZGlzcGxheSB2YWx1ZSAoZWl0aGVyXG5cdFx0XHQvLyBpbmxpbmUgb3IgYWJvdXQtdG8tYmUtcmVzdG9yZWQpXG5cdFx0XHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBkYXRhUHJpdi5nZXQoIGVsZW0sIFwiZGlzcGxheVwiICkgfHwgbnVsbDtcblx0XHRcdFx0aWYgKCAhdmFsdWVzWyBpbmRleCBdICkge1xuXHRcdFx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmICggZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmIGlzSGlkZGVuV2l0aGluVHJlZSggZWxlbSApICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBnZXREZWZhdWx0RGlzcGxheSggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIGRpc3BsYXkgIT09IFwibm9uZVwiICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBcIm5vbmVcIjtcblxuXHRcdFx0XHQvLyBSZW1lbWJlciB3aGF0IHdlJ3JlIG92ZXJ3cml0aW5nXG5cdFx0XHRcdGRhdGFQcml2LnNldCggZWxlbSwgXCJkaXNwbGF5XCIsIGRpc3BsYXkgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBTZXQgdGhlIGRpc3BsYXkgb2YgdGhlIGVsZW1lbnRzIGluIGEgc2Vjb25kIGxvb3AgdG8gYXZvaWQgY29uc3RhbnQgcmVmbG93XG5cdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0aWYgKCB2YWx1ZXNbIGluZGV4IF0gIT0gbnVsbCApIHtcblx0XHRcdGVsZW1lbnRzWyBpbmRleCBdLnN0eWxlLmRpc3BsYXkgPSB2YWx1ZXNbIGluZGV4IF07XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnRzO1xufVxuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHNob3c6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcywgdHJ1ZSApO1xuXHR9LFxuXHRoaWRlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2hvd0hpZGUoIHRoaXMgKTtcblx0fSxcblx0dG9nZ2xlOiBmdW5jdGlvbiggc3RhdGUgKSB7XG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGUgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0cmV0dXJuIHN0YXRlID8gdGhpcy5zaG93KCkgOiB0aGlzLmhpZGUoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggaXNIaWRkZW5XaXRoaW5UcmVlKCB0aGlzICkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnNob3coKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmhpZGUoKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH1cbn0gKTtcbnZhciByY2hlY2thYmxlVHlwZSA9ICggL14oPzpjaGVja2JveHxyYWRpbykkL2kgKTtcblxudmFyIHJ0YWdOYW1lID0gKCAvPChbYS16XVteXFwvXFwwPlxceDIwXFx0XFxyXFxuXFxmXSopL2kgKTtcblxudmFyIHJzY3JpcHRUeXBlID0gKCAvXiR8Xm1vZHVsZSR8XFwvKD86amF2YXxlY21hKXNjcmlwdC9pICk7XG5cblxuXG4oIGZ1bmN0aW9uKCkge1xuXHR2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG5cdFx0ZGl2ID0gZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApLFxuXHRcdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAgLSA0LjMgb25seVxuXHQvLyBDaGVjayBzdGF0ZSBsb3N0IGlmIHRoZSBuYW1lIGlzIHNldCAoIzExMjE3KVxuXHQvLyBTdXBwb3J0OiBXaW5kb3dzIFdlYiBBcHBzIChXV0EpXG5cdC8vIGBuYW1lYCBhbmQgYHR5cGVgIG11c3QgdXNlIC5zZXRBdHRyaWJ1dGUgZm9yIFdXQSAoIzE0OTAxKVxuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCBcInJhZGlvXCIgKTtcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcImNoZWNrZWRcIiwgXCJjaGVja2VkXCIgKTtcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJ0XCIgKTtcblxuXHRkaXYuYXBwZW5kQ2hpbGQoIGlucHV0ICk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMSBvbmx5XG5cdC8vIE9sZGVyIFdlYktpdCBkb2Vzbid0IGNsb25lIGNoZWNrZWQgc3RhdGUgY29ycmVjdGx5IGluIGZyYWdtZW50c1xuXHRzdXBwb3J0LmNoZWNrQ2xvbmUgPSBkaXYuY2xvbmVOb2RlKCB0cnVlICkuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmNoZWNrZWQ7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIE1ha2Ugc3VyZSB0ZXh0YXJlYSAoYW5kIGNoZWNrYm94KSBkZWZhdWx0VmFsdWUgaXMgcHJvcGVybHkgY2xvbmVkXG5cdGRpdi5pbm5lckhUTUwgPSBcIjx0ZXh0YXJlYT54PC90ZXh0YXJlYT5cIjtcblx0c3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCA9ICEhZGl2LmNsb25lTm9kZSggdHJ1ZSApLmxhc3RDaGlsZC5kZWZhdWx0VmFsdWU7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0Ly8gSUUgPD05IHJlcGxhY2VzIDxvcHRpb24+IHRhZ3Mgd2l0aCB0aGVpciBjb250ZW50cyB3aGVuIGluc2VydGVkIG91dHNpZGUgb2Zcblx0Ly8gdGhlIHNlbGVjdCBlbGVtZW50LlxuXHRkaXYuaW5uZXJIVE1MID0gXCI8b3B0aW9uPjwvb3B0aW9uPlwiO1xuXHRzdXBwb3J0Lm9wdGlvbiA9ICEhZGl2Lmxhc3RDaGlsZDtcbn0gKSgpO1xuXG5cbi8vIFdlIGhhdmUgdG8gY2xvc2UgdGhlc2UgdGFncyB0byBzdXBwb3J0IFhIVE1MICgjMTMyMDApXG52YXIgd3JhcE1hcCA9IHtcblxuXHQvLyBYSFRNTCBwYXJzZXJzIGRvIG5vdCBtYWdpY2FsbHkgaW5zZXJ0IGVsZW1lbnRzIGluIHRoZVxuXHQvLyBzYW1lIHdheSB0aGF0IHRhZyBzb3VwIHBhcnNlcnMgZG8uIFNvIHdlIGNhbm5vdCBzaG9ydGVuXG5cdC8vIHRoaXMgYnkgb21pdHRpbmcgPHRib2R5PiBvciBvdGhlciByZXF1aXJlZCBlbGVtZW50cy5cblx0dGhlYWQ6IFsgMSwgXCI8dGFibGU+XCIsIFwiPC90YWJsZT5cIiBdLFxuXHRjb2w6IFsgMiwgXCI8dGFibGU+PGNvbGdyb3VwPlwiLCBcIjwvY29sZ3JvdXA+PC90YWJsZT5cIiBdLFxuXHR0cjogWyAyLCBcIjx0YWJsZT48dGJvZHk+XCIsIFwiPC90Ym9keT48L3RhYmxlPlwiIF0sXG5cdHRkOiBbIDMsIFwiPHRhYmxlPjx0Ym9keT48dHI+XCIsIFwiPC90cj48L3Rib2R5PjwvdGFibGU+XCIgXSxcblxuXHRfZGVmYXVsdDogWyAwLCBcIlwiLCBcIlwiIF1cbn07XG5cbndyYXBNYXAudGJvZHkgPSB3cmFwTWFwLnRmb290ID0gd3JhcE1hcC5jb2xncm91cCA9IHdyYXBNYXAuY2FwdGlvbiA9IHdyYXBNYXAudGhlYWQ7XG53cmFwTWFwLnRoID0gd3JhcE1hcC50ZDtcblxuLy8gU3VwcG9ydDogSUUgPD05IG9ubHlcbmlmICggIXN1cHBvcnQub3B0aW9uICkge1xuXHR3cmFwTWFwLm9wdGdyb3VwID0gd3JhcE1hcC5vcHRpb24gPSBbIDEsIFwiPHNlbGVjdCBtdWx0aXBsZT0nbXVsdGlwbGUnPlwiLCBcIjwvc2VsZWN0PlwiIF07XG59XG5cblxuZnVuY3Rpb24gZ2V0QWxsKCBjb250ZXh0LCB0YWcgKSB7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHQvLyBVc2UgdHlwZW9mIHRvIGF2b2lkIHplcm8tYXJndW1lbnQgbWV0aG9kIGludm9jYXRpb24gb24gaG9zdCBvYmplY3RzICgjMTUxNTEpXG5cdHZhciByZXQ7XG5cblx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRyZXQgPSBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgfHwgXCIqXCIgKTtcblxuXHR9IGVsc2UgaWYgKCB0eXBlb2YgY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsICE9PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdHJldCA9IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnIHx8IFwiKlwiICk7XG5cblx0fSBlbHNlIHtcblx0XHRyZXQgPSBbXTtcblx0fVxuXG5cdGlmICggdGFnID09PSB1bmRlZmluZWQgfHwgdGFnICYmIG5vZGVOYW1lKCBjb250ZXh0LCB0YWcgKSApIHtcblx0XHRyZXR1cm4galF1ZXJ5Lm1lcmdlKCBbIGNvbnRleHQgXSwgcmV0ICk7XG5cdH1cblxuXHRyZXR1cm4gcmV0O1xufVxuXG5cbi8vIE1hcmsgc2NyaXB0cyBhcyBoYXZpbmcgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZFxuZnVuY3Rpb24gc2V0R2xvYmFsRXZhbCggZWxlbXMsIHJlZkVsZW1lbnRzICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bCA9IGVsZW1zLmxlbmd0aDtcblxuXHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0ZGF0YVByaXYuc2V0KFxuXHRcdFx0ZWxlbXNbIGkgXSxcblx0XHRcdFwiZ2xvYmFsRXZhbFwiLFxuXHRcdFx0IXJlZkVsZW1lbnRzIHx8IGRhdGFQcml2LmdldCggcmVmRWxlbWVudHNbIGkgXSwgXCJnbG9iYWxFdmFsXCIgKVxuXHRcdCk7XG5cdH1cbn1cblxuXG52YXIgcmh0bWwgPSAvPHwmIz9cXHcrOy87XG5cbmZ1bmN0aW9uIGJ1aWxkRnJhZ21lbnQoIGVsZW1zLCBjb250ZXh0LCBzY3JpcHRzLCBzZWxlY3Rpb24sIGlnbm9yZWQgKSB7XG5cdHZhciBlbGVtLCB0bXAsIHRhZywgd3JhcCwgYXR0YWNoZWQsIGosXG5cdFx0ZnJhZ21lbnQgPSBjb250ZXh0LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSxcblx0XHRub2RlcyA9IFtdLFxuXHRcdGkgPSAwLFxuXHRcdGwgPSBlbGVtcy5sZW5ndGg7XG5cblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdGVsZW0gPSBlbGVtc1sgaSBdO1xuXG5cdFx0aWYgKCBlbGVtIHx8IGVsZW0gPT09IDAgKSB7XG5cblx0XHRcdC8vIEFkZCBub2RlcyBkaXJlY3RseVxuXHRcdFx0aWYgKCB0b1R5cGUoIGVsZW0gKSA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIG5vZGVzLCBlbGVtLm5vZGVUeXBlID8gWyBlbGVtIF0gOiBlbGVtICk7XG5cblx0XHRcdC8vIENvbnZlcnQgbm9uLWh0bWwgaW50byBhIHRleHQgbm9kZVxuXHRcdFx0fSBlbHNlIGlmICggIXJodG1sLnRlc3QoIGVsZW0gKSApIHtcblx0XHRcdFx0bm9kZXMucHVzaCggY29udGV4dC5jcmVhdGVUZXh0Tm9kZSggZWxlbSApICk7XG5cblx0XHRcdC8vIENvbnZlcnQgaHRtbCBpbnRvIERPTSBub2Rlc1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dG1wID0gdG1wIHx8IGZyYWdtZW50LmFwcGVuZENoaWxkKCBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApO1xuXG5cdFx0XHRcdC8vIERlc2VyaWFsaXplIGEgc3RhbmRhcmQgcmVwcmVzZW50YXRpb25cblx0XHRcdFx0dGFnID0gKCBydGFnTmFtZS5leGVjKCBlbGVtICkgfHwgWyBcIlwiLCBcIlwiIF0gKVsgMSBdLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdHdyYXAgPSB3cmFwTWFwWyB0YWcgXSB8fCB3cmFwTWFwLl9kZWZhdWx0O1xuXHRcdFx0XHR0bXAuaW5uZXJIVE1MID0gd3JhcFsgMSBdICsgalF1ZXJ5Lmh0bWxQcmVmaWx0ZXIoIGVsZW0gKSArIHdyYXBbIDIgXTtcblxuXHRcdFx0XHQvLyBEZXNjZW5kIHRocm91Z2ggd3JhcHBlcnMgdG8gdGhlIHJpZ2h0IGNvbnRlbnRcblx0XHRcdFx0aiA9IHdyYXBbIDAgXTtcblx0XHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdFx0dG1wID0gdG1wLmxhc3RDaGlsZDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seVxuXHRcdFx0XHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggbm9kZXMsIHRtcC5jaGlsZE5vZGVzICk7XG5cblx0XHRcdFx0Ly8gUmVtZW1iZXIgdGhlIHRvcC1sZXZlbCBjb250YWluZXJcblx0XHRcdFx0dG1wID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcblxuXHRcdFx0XHQvLyBFbnN1cmUgdGhlIGNyZWF0ZWQgbm9kZXMgYXJlIG9ycGhhbmVkICgjMTIzOTIpXG5cdFx0XHRcdHRtcC50ZXh0Q29udGVudCA9IFwiXCI7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmVtb3ZlIHdyYXBwZXIgZnJvbSBmcmFnbWVudFxuXHRmcmFnbWVudC50ZXh0Q29udGVudCA9IFwiXCI7XG5cblx0aSA9IDA7XG5cdHdoaWxlICggKCBlbGVtID0gbm9kZXNbIGkrKyBdICkgKSB7XG5cblx0XHQvLyBTa2lwIGVsZW1lbnRzIGFscmVhZHkgaW4gdGhlIGNvbnRleHQgY29sbGVjdGlvbiAodHJhYy00MDg3KVxuXHRcdGlmICggc2VsZWN0aW9uICYmIGpRdWVyeS5pbkFycmF5KCBlbGVtLCBzZWxlY3Rpb24gKSA+IC0xICkge1xuXHRcdFx0aWYgKCBpZ25vcmVkICkge1xuXHRcdFx0XHRpZ25vcmVkLnB1c2goIGVsZW0gKTtcblx0XHRcdH1cblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblxuXHRcdGF0dGFjaGVkID0gaXNBdHRhY2hlZCggZWxlbSApO1xuXG5cdFx0Ly8gQXBwZW5kIHRvIGZyYWdtZW50XG5cdFx0dG1wID0gZ2V0QWxsKCBmcmFnbWVudC5hcHBlbmRDaGlsZCggZWxlbSApLCBcInNjcmlwdFwiICk7XG5cblx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XG5cdFx0aWYgKCBhdHRhY2hlZCApIHtcblx0XHRcdHNldEdsb2JhbEV2YWwoIHRtcCApO1xuXHRcdH1cblxuXHRcdC8vIENhcHR1cmUgZXhlY3V0YWJsZXNcblx0XHRpZiAoIHNjcmlwdHMgKSB7XG5cdFx0XHRqID0gMDtcblx0XHRcdHdoaWxlICggKCBlbGVtID0gdG1wWyBqKysgXSApICkge1xuXHRcdFx0XHRpZiAoIHJzY3JpcHRUeXBlLnRlc3QoIGVsZW0udHlwZSB8fCBcIlwiICkgKSB7XG5cdFx0XHRcdFx0c2NyaXB0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZnJhZ21lbnQ7XG59XG5cblxudmFyXG5cdHJrZXlFdmVudCA9IC9ea2V5Lyxcblx0cm1vdXNlRXZlbnQgPSAvXig/Om1vdXNlfHBvaW50ZXJ8Y29udGV4dG1lbnV8ZHJhZ3xkcm9wKXxjbGljay8sXG5cdHJ0eXBlbmFtZXNwYWNlID0gL14oW14uXSopKD86XFwuKC4rKXwpLztcblxuZnVuY3Rpb24gcmV0dXJuVHJ1ZSgpIHtcblx0cmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJldHVybkZhbHNlKCkge1xuXHRyZXR1cm4gZmFsc2U7XG59XG5cbi8vIFN1cHBvcnQ6IElFIDw9OSAtIDExK1xuLy8gZm9jdXMoKSBhbmQgYmx1cigpIGFyZSBhc3luY2hyb25vdXMsIGV4Y2VwdCB3aGVuIHRoZXkgYXJlIG5vLW9wLlxuLy8gU28gZXhwZWN0IGZvY3VzIHRvIGJlIHN5bmNocm9ub3VzIHdoZW4gdGhlIGVsZW1lbnQgaXMgYWxyZWFkeSBhY3RpdmUsXG4vLyBhbmQgYmx1ciB0byBiZSBzeW5jaHJvbm91cyB3aGVuIHRoZSBlbGVtZW50IGlzIG5vdCBhbHJlYWR5IGFjdGl2ZS5cbi8vIChmb2N1cyBhbmQgYmx1ciBhcmUgYWx3YXlzIHN5bmNocm9ub3VzIGluIG90aGVyIHN1cHBvcnRlZCBicm93c2Vycyxcbi8vIHRoaXMganVzdCBkZWZpbmVzIHdoZW4gd2UgY2FuIGNvdW50IG9uIGl0KS5cbmZ1bmN0aW9uIGV4cGVjdFN5bmMoIGVsZW0sIHR5cGUgKSB7XG5cdHJldHVybiAoIGVsZW0gPT09IHNhZmVBY3RpdmVFbGVtZW50KCkgKSA9PT0gKCB0eXBlID09PSBcImZvY3VzXCIgKTtcbn1cblxuLy8gU3VwcG9ydDogSUUgPD05IG9ubHlcbi8vIEFjY2Vzc2luZyBkb2N1bWVudC5hY3RpdmVFbGVtZW50IGNhbiB0aHJvdyB1bmV4cGVjdGVkbHlcbi8vIGh0dHBzOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC8xMzM5M1xuZnVuY3Rpb24gc2FmZUFjdGl2ZUVsZW1lbnQoKSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG5cdH0gY2F0Y2ggKCBlcnIgKSB7IH1cbn1cblxuZnVuY3Rpb24gb24oIGVsZW0sIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIG9uZSApIHtcblx0dmFyIG9yaWdGbiwgdHlwZTtcblxuXHQvLyBUeXBlcyBjYW4gYmUgYSBtYXAgb2YgdHlwZXMvaGFuZGxlcnNcblx0aWYgKCB0eXBlb2YgdHlwZXMgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHQvLyAoIHR5cGVzLU9iamVjdCwgc2VsZWN0b3IsIGRhdGEgKVxuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzLU9iamVjdCwgZGF0YSApXG5cdFx0XHRkYXRhID0gZGF0YSB8fCBzZWxlY3Rvcjtcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0b24oIGVsZW0sIHR5cGUsIHNlbGVjdG9yLCBkYXRhLCB0eXBlc1sgdHlwZSBdLCBvbmUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIGVsZW07XG5cdH1cblxuXHRpZiAoIGRhdGEgPT0gbnVsbCAmJiBmbiA9PSBudWxsICkge1xuXG5cdFx0Ly8gKCB0eXBlcywgZm4gKVxuXHRcdGZuID0gc2VsZWN0b3I7XG5cdFx0ZGF0YSA9IHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHR9IGVsc2UgaWYgKCBmbiA9PSBudWxsICkge1xuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzLCBzZWxlY3RvciwgZm4gKVxuXHRcdFx0Zm4gPSBkYXRhO1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyAoIHR5cGVzLCBkYXRhLCBmbiApXG5cdFx0XHRmbiA9IGRhdGE7XG5cdFx0XHRkYXRhID0gc2VsZWN0b3I7XG5cdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblx0aWYgKCBmbiA9PT0gZmFsc2UgKSB7XG5cdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0fSBlbHNlIGlmICggIWZuICkge1xuXHRcdHJldHVybiBlbGVtO1xuXHR9XG5cblx0aWYgKCBvbmUgPT09IDEgKSB7XG5cdFx0b3JpZ0ZuID0gZm47XG5cdFx0Zm4gPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cblx0XHRcdC8vIENhbiB1c2UgYW4gZW1wdHkgc2V0LCBzaW5jZSBldmVudCBjb250YWlucyB0aGUgaW5mb1xuXHRcdFx0alF1ZXJ5KCkub2ZmKCBldmVudCApO1xuXHRcdFx0cmV0dXJuIG9yaWdGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fTtcblxuXHRcdC8vIFVzZSBzYW1lIGd1aWQgc28gY2FsbGVyIGNhbiByZW1vdmUgdXNpbmcgb3JpZ0ZuXG5cdFx0Zm4uZ3VpZCA9IG9yaWdGbi5ndWlkIHx8ICggb3JpZ0ZuLmd1aWQgPSBqUXVlcnkuZ3VpZCsrICk7XG5cdH1cblx0cmV0dXJuIGVsZW0uZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0alF1ZXJ5LmV2ZW50LmFkZCggdGhpcywgdHlwZXMsIGZuLCBkYXRhLCBzZWxlY3RvciApO1xuXHR9ICk7XG59XG5cbi8qXG4gKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBtYW5hZ2luZyBldmVudHMgLS0gbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuXG4gKiBQcm9wcyB0byBEZWFuIEVkd2FyZHMnIGFkZEV2ZW50IGxpYnJhcnkgZm9yIG1hbnkgb2YgdGhlIGlkZWFzLlxuICovXG5qUXVlcnkuZXZlbnQgPSB7XG5cblx0Z2xvYmFsOiB7fSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlcywgaGFuZGxlciwgZGF0YSwgc2VsZWN0b3IgKSB7XG5cblx0XHR2YXIgaGFuZGxlT2JqSW4sIGV2ZW50SGFuZGxlLCB0bXAsXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcblx0XHRcdHNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSxcblx0XHRcdGVsZW1EYXRhID0gZGF0YVByaXYuZ2V0KCBlbGVtICk7XG5cblx0XHQvLyBPbmx5IGF0dGFjaCBldmVudHMgdG8gb2JqZWN0cyB0aGF0IGFjY2VwdCBkYXRhXG5cdFx0aWYgKCAhYWNjZXB0RGF0YSggZWxlbSApICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhbiBvYmplY3Qgb2YgY3VzdG9tIGRhdGEgaW4gbGlldSBvZiB0aGUgaGFuZGxlclxuXHRcdGlmICggaGFuZGxlci5oYW5kbGVyICkge1xuXHRcdFx0aGFuZGxlT2JqSW4gPSBoYW5kbGVyO1xuXHRcdFx0aGFuZGxlciA9IGhhbmRsZU9iakluLmhhbmRsZXI7XG5cdFx0XHRzZWxlY3RvciA9IGhhbmRsZU9iakluLnNlbGVjdG9yO1xuXHRcdH1cblxuXHRcdC8vIEVuc3VyZSB0aGF0IGludmFsaWQgc2VsZWN0b3JzIHRocm93IGV4Y2VwdGlvbnMgYXQgYXR0YWNoIHRpbWVcblx0XHQvLyBFdmFsdWF0ZSBhZ2FpbnN0IGRvY3VtZW50RWxlbWVudCBpbiBjYXNlIGVsZW0gaXMgYSBub24tZWxlbWVudCBub2RlIChlLmcuLCBkb2N1bWVudClcblx0XHRpZiAoIHNlbGVjdG9yICkge1xuXHRcdFx0alF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKCBkb2N1bWVudEVsZW1lbnQsIHNlbGVjdG9yICk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgdGhlIGhhbmRsZXIgaGFzIGEgdW5pcXVlIElELCB1c2VkIHRvIGZpbmQvcmVtb3ZlIGl0IGxhdGVyXG5cdFx0aWYgKCAhaGFuZGxlci5ndWlkICkge1xuXHRcdFx0aGFuZGxlci5ndWlkID0galF1ZXJ5Lmd1aWQrKztcblx0XHR9XG5cblx0XHQvLyBJbml0IHRoZSBlbGVtZW50J3MgZXZlbnQgc3RydWN0dXJlIGFuZCBtYWluIGhhbmRsZXIsIGlmIHRoaXMgaXMgdGhlIGZpcnN0XG5cdFx0aWYgKCAhKCBldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgKSApIHtcblx0XHRcdGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyA9IE9iamVjdC5jcmVhdGUoIG51bGwgKTtcblx0XHR9XG5cdFx0aWYgKCAhKCBldmVudEhhbmRsZSA9IGVsZW1EYXRhLmhhbmRsZSApICkge1xuXHRcdFx0ZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgPSBmdW5jdGlvbiggZSApIHtcblxuXHRcdFx0XHQvLyBEaXNjYXJkIHRoZSBzZWNvbmQgZXZlbnQgb2YgYSBqUXVlcnkuZXZlbnQudHJpZ2dlcigpIGFuZFxuXHRcdFx0XHQvLyB3aGVuIGFuIGV2ZW50IGlzIGNhbGxlZCBhZnRlciBhIHBhZ2UgaGFzIHVubG9hZGVkXG5cdFx0XHRcdHJldHVybiB0eXBlb2YgalF1ZXJ5ICE9PSBcInVuZGVmaW5lZFwiICYmIGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgIT09IGUudHlwZSA/XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmRpc3BhdGNoLmFwcGx5KCBlbGVtLCBhcmd1bWVudHMgKSA6IHVuZGVmaW5lZDtcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gSGFuZGxlIG11bHRpcGxlIGV2ZW50cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZVxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbIHQgXSApIHx8IFtdO1xuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWyAxIF07XG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbIDIgXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBUaGVyZSAqbXVzdCogYmUgYSB0eXBlLCBubyBhdHRhY2hpbmcgbmFtZXNwYWNlLW9ubHkgaGFuZGxlcnNcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiBldmVudCBjaGFuZ2VzIGl0cyB0eXBlLCB1c2UgdGhlIHNwZWNpYWwgZXZlbnQgaGFuZGxlcnMgZm9yIHRoZSBjaGFuZ2VkIHR5cGVcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXG5cdFx0XHQvLyBJZiBzZWxlY3RvciBkZWZpbmVkLCBkZXRlcm1pbmUgc3BlY2lhbCBldmVudCBhcGkgdHlwZSwgb3RoZXJ3aXNlIGdpdmVuIHR5cGVcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblxuXHRcdFx0Ly8gVXBkYXRlIHNwZWNpYWwgYmFzZWQgb24gbmV3bHkgcmVzZXQgdHlwZVxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cblx0XHRcdC8vIGhhbmRsZU9iaiBpcyBwYXNzZWQgdG8gYWxsIGV2ZW50IGhhbmRsZXJzXG5cdFx0XHRoYW5kbGVPYmogPSBqUXVlcnkuZXh0ZW5kKCB7XG5cdFx0XHRcdHR5cGU6IHR5cGUsXG5cdFx0XHRcdG9yaWdUeXBlOiBvcmlnVHlwZSxcblx0XHRcdFx0ZGF0YTogZGF0YSxcblx0XHRcdFx0aGFuZGxlcjogaGFuZGxlcixcblx0XHRcdFx0Z3VpZDogaGFuZGxlci5ndWlkLFxuXHRcdFx0XHRzZWxlY3Rvcjogc2VsZWN0b3IsXG5cdFx0XHRcdG5lZWRzQ29udGV4dDogc2VsZWN0b3IgJiYgalF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9yICksXG5cdFx0XHRcdG5hbWVzcGFjZTogbmFtZXNwYWNlcy5qb2luKCBcIi5cIiApXG5cdFx0XHR9LCBoYW5kbGVPYmpJbiApO1xuXG5cdFx0XHQvLyBJbml0IHRoZSBldmVudCBoYW5kbGVyIHF1ZXVlIGlmIHdlJ3JlIHRoZSBmaXJzdFxuXHRcdFx0aWYgKCAhKCBoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdICkgKSB7XG5cdFx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gPSBbXTtcblx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudCA9IDA7XG5cblx0XHRcdFx0Ly8gT25seSB1c2UgYWRkRXZlbnRMaXN0ZW5lciBpZiB0aGUgc3BlY2lhbCBldmVudHMgaGFuZGxlciByZXR1cm5zIGZhbHNlXG5cdFx0XHRcdGlmICggIXNwZWNpYWwuc2V0dXAgfHxcblx0XHRcdFx0XHRzcGVjaWFsLnNldHVwLmNhbGwoIGVsZW0sIGRhdGEsIG5hbWVzcGFjZXMsIGV2ZW50SGFuZGxlICkgPT09IGZhbHNlICkge1xuXG5cdFx0XHRcdFx0aWYgKCBlbGVtLmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGV2ZW50SGFuZGxlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggc3BlY2lhbC5hZGQgKSB7XG5cdFx0XHRcdHNwZWNpYWwuYWRkLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xuXG5cdFx0XHRcdGlmICggIWhhbmRsZU9iai5oYW5kbGVyLmd1aWQgKSB7XG5cdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCA9IGhhbmRsZXIuZ3VpZDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgdG8gdGhlIGVsZW1lbnQncyBoYW5kbGVyIGxpc3QsIGRlbGVnYXRlcyBpbiBmcm9udFxuXHRcdFx0aWYgKCBzZWxlY3RvciApIHtcblx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50KyssIDAsIGhhbmRsZU9iaiApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aGFuZGxlcnMucHVzaCggaGFuZGxlT2JqICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEtlZXAgdHJhY2sgb2Ygd2hpY2ggZXZlbnRzIGhhdmUgZXZlciBiZWVuIHVzZWQsIGZvciBldmVudCBvcHRpbWl6YXRpb25cblx0XHRcdGpRdWVyeS5ldmVudC5nbG9iYWxbIHR5cGUgXSA9IHRydWU7XG5cdFx0fVxuXG5cdH0sXG5cblx0Ly8gRGV0YWNoIGFuIGV2ZW50IG9yIHNldCBvZiBldmVudHMgZnJvbSBhbiBlbGVtZW50XG5cdHJlbW92ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBzZWxlY3RvciwgbWFwcGVkVHlwZXMgKSB7XG5cblx0XHR2YXIgaiwgb3JpZ0NvdW50LCB0bXAsXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcblx0XHRcdHNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSxcblx0XHRcdGVsZW1EYXRhID0gZGF0YVByaXYuaGFzRGF0YSggZWxlbSApICYmIGRhdGFQcml2LmdldCggZWxlbSApO1xuXG5cdFx0aWYgKCAhZWxlbURhdGEgfHwgISggZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gT25jZSBmb3IgZWFjaCB0eXBlLm5hbWVzcGFjZSBpbiB0eXBlczsgdHlwZSBtYXkgYmUgb21pdHRlZFxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbIHQgXSApIHx8IFtdO1xuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWyAxIF07XG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbIDIgXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBVbmJpbmQgYWxsIGV2ZW50cyAob24gdGhpcyBuYW1lc3BhY2UsIGlmIHByb3ZpZGVkKSBmb3IgdGhlIGVsZW1lbnRcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGZvciAoIHR5cGUgaW4gZXZlbnRzICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIGVsZW0sIHR5cGUgKyB0eXBlc1sgdCBdLCBoYW5kbGVyLCBzZWxlY3RvciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gfHwgW107XG5cdFx0XHR0bXAgPSB0bXBbIDIgXSAmJlxuXHRcdFx0XHRuZXcgUmVnRXhwKCBcIihefFxcXFwuKVwiICsgbmFtZXNwYWNlcy5qb2luKCBcIlxcXFwuKD86LipcXFxcLnwpXCIgKSArIFwiKFxcXFwufCQpXCIgKTtcblxuXHRcdFx0Ly8gUmVtb3ZlIG1hdGNoaW5nIGV2ZW50c1xuXHRcdFx0b3JpZ0NvdW50ID0gaiA9IGhhbmRsZXJzLmxlbmd0aDtcblx0XHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0XHRoYW5kbGVPYmogPSBoYW5kbGVyc1sgaiBdO1xuXG5cdFx0XHRcdGlmICggKCBtYXBwZWRUeXBlcyB8fCBvcmlnVHlwZSA9PT0gaGFuZGxlT2JqLm9yaWdUeXBlICkgJiZcblx0XHRcdFx0XHQoICFoYW5kbGVyIHx8IGhhbmRsZXIuZ3VpZCA9PT0gaGFuZGxlT2JqLmd1aWQgKSAmJlxuXHRcdFx0XHRcdCggIXRtcCB8fCB0bXAudGVzdCggaGFuZGxlT2JqLm5hbWVzcGFjZSApICkgJiZcblx0XHRcdFx0XHQoICFzZWxlY3RvciB8fCBzZWxlY3RvciA9PT0gaGFuZGxlT2JqLnNlbGVjdG9yIHx8XG5cdFx0XHRcdFx0XHRzZWxlY3RvciA9PT0gXCIqKlwiICYmIGhhbmRsZU9iai5zZWxlY3RvciApICkge1xuXHRcdFx0XHRcdGhhbmRsZXJzLnNwbGljZSggaiwgMSApO1xuXG5cdFx0XHRcdFx0aWYgKCBoYW5kbGVPYmouc2VsZWN0b3IgKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVycy5kZWxlZ2F0ZUNvdW50LS07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggc3BlY2lhbC5yZW1vdmUgKSB7XG5cdFx0XHRcdFx0XHRzcGVjaWFsLnJlbW92ZS5jYWxsKCBlbGVtLCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gUmVtb3ZlIGdlbmVyaWMgZXZlbnQgaGFuZGxlciBpZiB3ZSByZW1vdmVkIHNvbWV0aGluZyBhbmQgbm8gbW9yZSBoYW5kbGVycyBleGlzdFxuXHRcdFx0Ly8gKGF2b2lkcyBwb3RlbnRpYWwgZm9yIGVuZGxlc3MgcmVjdXJzaW9uIGR1cmluZyByZW1vdmFsIG9mIHNwZWNpYWwgZXZlbnQgaGFuZGxlcnMpXG5cdFx0XHRpZiAoIG9yaWdDb3VudCAmJiAhaGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0XHRpZiAoICFzcGVjaWFsLnRlYXJkb3duIHx8XG5cdFx0XHRcdFx0c3BlY2lhbC50ZWFyZG93bi5jYWxsKCBlbGVtLCBuYW1lc3BhY2VzLCBlbGVtRGF0YS5oYW5kbGUgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGVsZW1EYXRhLmhhbmRsZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGVsZXRlIGV2ZW50c1sgdHlwZSBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSBkYXRhIGFuZCB0aGUgZXhwYW5kbyBpZiBpdCdzIG5vIGxvbmdlciB1c2VkXG5cdFx0aWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggZXZlbnRzICkgKSB7XG5cdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFwiaGFuZGxlIGV2ZW50c1wiICk7XG5cdFx0fVxuXHR9LFxuXG5cdGRpc3BhdGNoOiBmdW5jdGlvbiggbmF0aXZlRXZlbnQgKSB7XG5cblx0XHR2YXIgaSwgaiwgcmV0LCBtYXRjaGVkLCBoYW5kbGVPYmosIGhhbmRsZXJRdWV1ZSxcblx0XHRcdGFyZ3MgPSBuZXcgQXJyYXkoIGFyZ3VtZW50cy5sZW5ndGggKSxcblxuXHRcdFx0Ly8gTWFrZSBhIHdyaXRhYmxlIGpRdWVyeS5FdmVudCBmcm9tIHRoZSBuYXRpdmUgZXZlbnQgb2JqZWN0XG5cdFx0XHRldmVudCA9IGpRdWVyeS5ldmVudC5maXgoIG5hdGl2ZUV2ZW50ICksXG5cblx0XHRcdGhhbmRsZXJzID0gKFxuXHRcdFx0XHRcdGRhdGFQcml2LmdldCggdGhpcywgXCJldmVudHNcIiApIHx8IE9iamVjdC5jcmVhdGUoIG51bGwgKVxuXHRcdFx0XHQpWyBldmVudC50eXBlIF0gfHwgW10sXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGV2ZW50LnR5cGUgXSB8fCB7fTtcblxuXHRcdC8vIFVzZSB0aGUgZml4LWVkIGpRdWVyeS5FdmVudCByYXRoZXIgdGhhbiB0aGUgKHJlYWQtb25seSkgbmF0aXZlIGV2ZW50XG5cdFx0YXJnc1sgMCBdID0gZXZlbnQ7XG5cblx0XHRmb3IgKCBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKyApIHtcblx0XHRcdGFyZ3NbIGkgXSA9IGFyZ3VtZW50c1sgaSBdO1xuXHRcdH1cblxuXHRcdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gdGhpcztcblxuXHRcdC8vIENhbGwgdGhlIHByZURpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZSwgYW5kIGxldCBpdCBiYWlsIGlmIGRlc2lyZWRcblx0XHRpZiAoIHNwZWNpYWwucHJlRGlzcGF0Y2ggJiYgc3BlY2lhbC5wcmVEaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgaGFuZGxlcnNcblx0XHRoYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7XG5cblx0XHQvLyBSdW4gZGVsZWdhdGVzIGZpcnN0OyB0aGV5IG1heSB3YW50IHRvIHN0b3AgcHJvcGFnYXRpb24gYmVuZWF0aCB1c1xuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKCBtYXRjaGVkID0gaGFuZGxlclF1ZXVlWyBpKysgXSApICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0ZXZlbnQuY3VycmVudFRhcmdldCA9IG1hdGNoZWQuZWxlbTtcblxuXHRcdFx0aiA9IDA7XG5cdFx0XHR3aGlsZSAoICggaGFuZGxlT2JqID0gbWF0Y2hlZC5oYW5kbGVyc1sgaisrIF0gKSAmJlxuXHRcdFx0XHQhZXZlbnQuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblxuXHRcdFx0XHQvLyBJZiB0aGUgZXZlbnQgaXMgbmFtZXNwYWNlZCwgdGhlbiBlYWNoIGhhbmRsZXIgaXMgb25seSBpbnZva2VkIGlmIGl0IGlzXG5cdFx0XHRcdC8vIHNwZWNpYWxseSB1bml2ZXJzYWwgb3IgaXRzIG5hbWVzcGFjZXMgYXJlIGEgc3VwZXJzZXQgb2YgdGhlIGV2ZW50J3MuXG5cdFx0XHRcdGlmICggIWV2ZW50LnJuYW1lc3BhY2UgfHwgaGFuZGxlT2JqLm5hbWVzcGFjZSA9PT0gZmFsc2UgfHxcblx0XHRcdFx0XHRldmVudC5ybmFtZXNwYWNlLnRlc3QoIGhhbmRsZU9iai5uYW1lc3BhY2UgKSApIHtcblxuXHRcdFx0XHRcdGV2ZW50LmhhbmRsZU9iaiA9IGhhbmRsZU9iajtcblx0XHRcdFx0XHRldmVudC5kYXRhID0gaGFuZGxlT2JqLmRhdGE7XG5cblx0XHRcdFx0XHRyZXQgPSAoICggalF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGhhbmRsZU9iai5vcmlnVHlwZSBdIHx8IHt9ICkuaGFuZGxlIHx8XG5cdFx0XHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlciApLmFwcGx5KCBtYXRjaGVkLmVsZW0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggcmV0ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZXZlbnQucmVzdWx0ID0gcmV0ICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWxsIHRoZSBwb3N0RGlzcGF0Y2ggaG9vayBmb3IgdGhlIG1hcHBlZCB0eXBlXG5cdFx0aWYgKCBzcGVjaWFsLnBvc3REaXNwYXRjaCApIHtcblx0XHRcdHNwZWNpYWwucG9zdERpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50LnJlc3VsdDtcblx0fSxcblxuXHRoYW5kbGVyczogZnVuY3Rpb24oIGV2ZW50LCBoYW5kbGVycyApIHtcblx0XHR2YXIgaSwgaGFuZGxlT2JqLCBzZWwsIG1hdGNoZWRIYW5kbGVycywgbWF0Y2hlZFNlbGVjdG9ycyxcblx0XHRcdGhhbmRsZXJRdWV1ZSA9IFtdLFxuXHRcdFx0ZGVsZWdhdGVDb3VudCA9IGhhbmRsZXJzLmRlbGVnYXRlQ291bnQsXG5cdFx0XHRjdXIgPSBldmVudC50YXJnZXQ7XG5cblx0XHQvLyBGaW5kIGRlbGVnYXRlIGhhbmRsZXJzXG5cdFx0aWYgKCBkZWxlZ2F0ZUNvdW50ICYmXG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OVxuXHRcdFx0Ly8gQmxhY2staG9sZSBTVkcgPHVzZT4gaW5zdGFuY2UgdHJlZXMgKHRyYWMtMTMxODApXG5cdFx0XHRjdXIubm9kZVR5cGUgJiZcblxuXHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA8PTQyXG5cdFx0XHQvLyBTdXBwcmVzcyBzcGVjLXZpb2xhdGluZyBjbGlja3MgaW5kaWNhdGluZyBhIG5vbi1wcmltYXJ5IHBvaW50ZXIgYnV0dG9uICh0cmFjLTM4NjEpXG5cdFx0XHQvLyBodHRwczovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudC10eXBlLWNsaWNrXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSBvbmx5XG5cdFx0XHQvLyAuLi5idXQgbm90IGFycm93IGtleSBcImNsaWNrc1wiIG9mIHJhZGlvIGlucHV0cywgd2hpY2ggY2FuIGhhdmUgYGJ1dHRvbmAgLTEgKGdoLTIzNDMpXG5cdFx0XHQhKCBldmVudC50eXBlID09PSBcImNsaWNrXCIgJiYgZXZlbnQuYnV0dG9uID49IDEgKSApIHtcblxuXHRcdFx0Zm9yICggOyBjdXIgIT09IHRoaXM7IGN1ciA9IGN1ci5wYXJlbnROb2RlIHx8IHRoaXMgKSB7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgY2hlY2sgbm9uLWVsZW1lbnRzICgjMTMyMDgpXG5cdFx0XHRcdC8vIERvbid0IHByb2Nlc3MgY2xpY2tzIG9uIGRpc2FibGVkIGVsZW1lbnRzICgjNjkxMSwgIzgxNjUsICMxMTM4MiwgIzExNzY0KVxuXHRcdFx0XHRpZiAoIGN1ci5ub2RlVHlwZSA9PT0gMSAmJiAhKCBldmVudC50eXBlID09PSBcImNsaWNrXCIgJiYgY3VyLmRpc2FibGVkID09PSB0cnVlICkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlZEhhbmRsZXJzID0gW107XG5cdFx0XHRcdFx0bWF0Y2hlZFNlbGVjdG9ycyA9IHt9O1xuXHRcdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgZGVsZWdhdGVDb3VudDsgaSsrICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlT2JqID0gaGFuZGxlcnNbIGkgXTtcblxuXHRcdFx0XHRcdFx0Ly8gRG9uJ3QgY29uZmxpY3Qgd2l0aCBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKCMxMzIwMylcblx0XHRcdFx0XHRcdHNlbCA9IGhhbmRsZU9iai5zZWxlY3RvciArIFwiIFwiO1xuXG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZWRTZWxlY3RvcnNbIHNlbCBdID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRcdG1hdGNoZWRTZWxlY3RvcnNbIHNlbCBdID0gaGFuZGxlT2JqLm5lZWRzQ29udGV4dCA/XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5KCBzZWwsIHRoaXMgKS5pbmRleCggY3VyICkgPiAtMSA6XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmZpbmQoIHNlbCwgdGhpcywgbnVsbCwgWyBjdXIgXSApLmxlbmd0aDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlZFNlbGVjdG9yc1sgc2VsIF0gKSB7XG5cdFx0XHRcdFx0XHRcdG1hdGNoZWRIYW5kbGVycy5wdXNoKCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVkSGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlclF1ZXVlLnB1c2goIHsgZWxlbTogY3VyLCBoYW5kbGVyczogbWF0Y2hlZEhhbmRsZXJzIH0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBBZGQgdGhlIHJlbWFpbmluZyAoZGlyZWN0bHktYm91bmQpIGhhbmRsZXJzXG5cdFx0Y3VyID0gdGhpcztcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgPCBoYW5kbGVycy5sZW5ndGggKSB7XG5cdFx0XHRoYW5kbGVyUXVldWUucHVzaCggeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBoYW5kbGVycy5zbGljZSggZGVsZWdhdGVDb3VudCApIH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gaGFuZGxlclF1ZXVlO1xuXHR9LFxuXG5cdGFkZFByb3A6IGZ1bmN0aW9uKCBuYW1lLCBob29rICkge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggalF1ZXJ5LkV2ZW50LnByb3RvdHlwZSwgbmFtZSwge1xuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblxuXHRcdFx0Z2V0OiBpc0Z1bmN0aW9uKCBob29rICkgP1xuXHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRpZiAoIHRoaXMub3JpZ2luYWxFdmVudCApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGhvb2soIHRoaXMub3JpZ2luYWxFdmVudCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlmICggdGhpcy5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdGhpcy5vcmlnaW5hbEV2ZW50WyBuYW1lIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LFxuXG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCB0aGlzLCBuYW1lLCB7XG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdFx0d3JpdGFibGU6IHRydWUsXG5cdFx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0Zml4OiBmdW5jdGlvbiggb3JpZ2luYWxFdmVudCApIHtcblx0XHRyZXR1cm4gb3JpZ2luYWxFdmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XG5cdFx0XHRvcmlnaW5hbEV2ZW50IDpcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoIG9yaWdpbmFsRXZlbnQgKTtcblx0fSxcblxuXHRzcGVjaWFsOiB7XG5cdFx0bG9hZDoge1xuXG5cdFx0XHQvLyBQcmV2ZW50IHRyaWdnZXJlZCBpbWFnZS5sb2FkIGV2ZW50cyBmcm9tIGJ1YmJsaW5nIHRvIHdpbmRvdy5sb2FkXG5cdFx0XHRub0J1YmJsZTogdHJ1ZVxuXHRcdH0sXG5cdFx0Y2xpY2s6IHtcblxuXHRcdFx0Ly8gVXRpbGl6ZSBuYXRpdmUgZXZlbnQgdG8gZW5zdXJlIGNvcnJlY3Qgc3RhdGUgZm9yIGNoZWNrYWJsZSBpbnB1dHNcblx0XHRcdHNldHVwOiBmdW5jdGlvbiggZGF0YSApIHtcblxuXHRcdFx0XHQvLyBGb3IgbXV0dWFsIGNvbXByZXNzaWJpbGl0eSB3aXRoIF9kZWZhdWx0LCByZXBsYWNlIGB0aGlzYCBhY2Nlc3Mgd2l0aCBhIGxvY2FsIHZhci5cblx0XHRcdFx0Ly8gYHx8IGRhdGFgIGlzIGRlYWQgY29kZSBtZWFudCBvbmx5IHRvIHByZXNlcnZlIHRoZSB2YXJpYWJsZSB0aHJvdWdoIG1pbmlmaWNhdGlvbi5cblx0XHRcdFx0dmFyIGVsID0gdGhpcyB8fCBkYXRhO1xuXG5cdFx0XHRcdC8vIENsYWltIHRoZSBmaXJzdCBoYW5kbGVyXG5cdFx0XHRcdGlmICggcmNoZWNrYWJsZVR5cGUudGVzdCggZWwudHlwZSApICYmXG5cdFx0XHRcdFx0ZWwuY2xpY2sgJiYgbm9kZU5hbWUoIGVsLCBcImlucHV0XCIgKSApIHtcblxuXHRcdFx0XHRcdC8vIGRhdGFQcml2LnNldCggZWwsIFwiY2xpY2tcIiwgLi4uIClcblx0XHRcdFx0XHRsZXZlcmFnZU5hdGl2ZSggZWwsIFwiY2xpY2tcIiwgcmV0dXJuVHJ1ZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmV0dXJuIGZhbHNlIHRvIGFsbG93IG5vcm1hbCBwcm9jZXNzaW5nIGluIHRoZSBjYWxsZXJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSxcblx0XHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCBkYXRhICkge1xuXG5cdFx0XHRcdC8vIEZvciBtdXR1YWwgY29tcHJlc3NpYmlsaXR5IHdpdGggX2RlZmF1bHQsIHJlcGxhY2UgYHRoaXNgIGFjY2VzcyB3aXRoIGEgbG9jYWwgdmFyLlxuXHRcdFx0XHQvLyBgfHwgZGF0YWAgaXMgZGVhZCBjb2RlIG1lYW50IG9ubHkgdG8gcHJlc2VydmUgdGhlIHZhcmlhYmxlIHRocm91Z2ggbWluaWZpY2F0aW9uLlxuXHRcdFx0XHR2YXIgZWwgPSB0aGlzIHx8IGRhdGE7XG5cblx0XHRcdFx0Ly8gRm9yY2Ugc2V0dXAgYmVmb3JlIHRyaWdnZXJpbmcgYSBjbGlja1xuXHRcdFx0XHRpZiAoIHJjaGVja2FibGVUeXBlLnRlc3QoIGVsLnR5cGUgKSAmJlxuXHRcdFx0XHRcdGVsLmNsaWNrICYmIG5vZGVOYW1lKCBlbCwgXCJpbnB1dFwiICkgKSB7XG5cblx0XHRcdFx0XHRsZXZlcmFnZU5hdGl2ZSggZWwsIFwiY2xpY2tcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmV0dXJuIG5vbi1mYWxzZSB0byBhbGxvdyBub3JtYWwgZXZlbnQtcGF0aCBwcm9wYWdhdGlvblxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH0sXG5cblx0XHRcdC8vIEZvciBjcm9zcy1icm93c2VyIGNvbnNpc3RlbmN5LCBzdXBwcmVzcyBuYXRpdmUgLmNsaWNrKCkgb24gbGlua3Ncblx0XHRcdC8vIEFsc28gcHJldmVudCBpdCBpZiB3ZSdyZSBjdXJyZW50bHkgaW5zaWRlIGEgbGV2ZXJhZ2VkIG5hdGl2ZS1ldmVudCBzdGFja1xuXHRcdFx0X2RlZmF1bHQ6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldDtcblx0XHRcdFx0cmV0dXJuIHJjaGVja2FibGVUeXBlLnRlc3QoIHRhcmdldC50eXBlICkgJiZcblx0XHRcdFx0XHR0YXJnZXQuY2xpY2sgJiYgbm9kZU5hbWUoIHRhcmdldCwgXCJpbnB1dFwiICkgJiZcblx0XHRcdFx0XHRkYXRhUHJpdi5nZXQoIHRhcmdldCwgXCJjbGlja1wiICkgfHxcblx0XHRcdFx0XHRub2RlTmFtZSggdGFyZ2V0LCBcImFcIiApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRiZWZvcmV1bmxvYWQ6IHtcblx0XHRcdHBvc3REaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggMjArXG5cdFx0XHRcdC8vIEZpcmVmb3ggZG9lc24ndCBhbGVydCBpZiB0aGUgcmV0dXJuVmFsdWUgZmllbGQgaXMgbm90IHNldC5cblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgIT09IHVuZGVmaW5lZCAmJiBldmVudC5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdGV2ZW50Lm9yaWdpbmFsRXZlbnQucmV0dXJuVmFsdWUgPSBldmVudC5yZXN1bHQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbi8vIEVuc3VyZSB0aGUgcHJlc2VuY2Ugb2YgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBoYW5kbGVzIG1hbnVhbGx5LXRyaWdnZXJlZFxuLy8gc3ludGhldGljIGV2ZW50cyBieSBpbnRlcnJ1cHRpbmcgcHJvZ3Jlc3MgdW50aWwgcmVpbnZva2VkIGluIHJlc3BvbnNlIHRvXG4vLyAqbmF0aXZlKiBldmVudHMgdGhhdCBpdCBmaXJlcyBkaXJlY3RseSwgZW5zdXJpbmcgdGhhdCBzdGF0ZSBjaGFuZ2VzIGhhdmVcbi8vIGFscmVhZHkgb2NjdXJyZWQgYmVmb3JlIG90aGVyIGxpc3RlbmVycyBhcmUgaW52b2tlZC5cbmZ1bmN0aW9uIGxldmVyYWdlTmF0aXZlKCBlbCwgdHlwZSwgZXhwZWN0U3luYyApIHtcblxuXHQvLyBNaXNzaW5nIGV4cGVjdFN5bmMgaW5kaWNhdGVzIGEgdHJpZ2dlciBjYWxsLCB3aGljaCBtdXN0IGZvcmNlIHNldHVwIHRocm91Z2ggalF1ZXJ5LmV2ZW50LmFkZFxuXHRpZiAoICFleHBlY3RTeW5jICkge1xuXHRcdGlmICggZGF0YVByaXYuZ2V0KCBlbCwgdHlwZSApID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuYWRkKCBlbCwgdHlwZSwgcmV0dXJuVHJ1ZSApO1xuXHRcdH1cblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBSZWdpc3RlciB0aGUgY29udHJvbGxlciBhcyBhIHNwZWNpYWwgdW5pdmVyc2FsIGhhbmRsZXIgZm9yIGFsbCBldmVudCBuYW1lc3BhY2VzXG5cdGRhdGFQcml2LnNldCggZWwsIHR5cGUsIGZhbHNlICk7XG5cdGpRdWVyeS5ldmVudC5hZGQoIGVsLCB0eXBlLCB7XG5cdFx0bmFtZXNwYWNlOiBmYWxzZSxcblx0XHRoYW5kbGVyOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHR2YXIgbm90QXN5bmMsIHJlc3VsdCxcblx0XHRcdFx0c2F2ZWQgPSBkYXRhUHJpdi5nZXQoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0aWYgKCAoIGV2ZW50LmlzVHJpZ2dlciAmIDEgKSAmJiB0aGlzWyB0eXBlIF0gKSB7XG5cblx0XHRcdFx0Ly8gSW50ZXJydXB0IHByb2Nlc3Npbmcgb2YgdGhlIG91dGVyIHN5bnRoZXRpYyAudHJpZ2dlcigpZWQgZXZlbnRcblx0XHRcdFx0Ly8gU2F2ZWQgZGF0YSBzaG91bGQgYmUgZmFsc2UgaW4gc3VjaCBjYXNlcywgYnV0IG1pZ2h0IGJlIGEgbGVmdG92ZXIgY2FwdHVyZSBvYmplY3Rcblx0XHRcdFx0Ly8gZnJvbSBhbiBhc3luYyBuYXRpdmUgaGFuZGxlciAoZ2gtNDM1MClcblx0XHRcdFx0aWYgKCAhc2F2ZWQubGVuZ3RoICkge1xuXG5cdFx0XHRcdFx0Ly8gU3RvcmUgYXJndW1lbnRzIGZvciB1c2Ugd2hlbiBoYW5kbGluZyB0aGUgaW5uZXIgbmF0aXZlIGV2ZW50XG5cdFx0XHRcdFx0Ly8gVGhlcmUgd2lsbCBhbHdheXMgYmUgYXQgbGVhc3Qgb25lIGFyZ3VtZW50IChhbiBldmVudCBvYmplY3QpLCBzbyB0aGlzIGFycmF5XG5cdFx0XHRcdFx0Ly8gd2lsbCBub3QgYmUgY29uZnVzZWQgd2l0aCBhIGxlZnRvdmVyIGNhcHR1cmUgb2JqZWN0LlxuXHRcdFx0XHRcdHNhdmVkID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCB0eXBlLCBzYXZlZCApO1xuXG5cdFx0XHRcdFx0Ly8gVHJpZ2dlciB0aGUgbmF0aXZlIGV2ZW50IGFuZCBjYXB0dXJlIGl0cyByZXN1bHRcblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMStcblx0XHRcdFx0XHQvLyBmb2N1cygpIGFuZCBibHVyKCkgYXJlIGFzeW5jaHJvbm91c1xuXHRcdFx0XHRcdG5vdEFzeW5jID0gZXhwZWN0U3luYyggdGhpcywgdHlwZSApO1xuXHRcdFx0XHRcdHRoaXNbIHR5cGUgXSgpO1xuXHRcdFx0XHRcdHJlc3VsdCA9IGRhdGFQcml2LmdldCggdGhpcywgdHlwZSApO1xuXHRcdFx0XHRcdGlmICggc2F2ZWQgIT09IHJlc3VsdCB8fCBub3RBc3luYyApIHtcblx0XHRcdFx0XHRcdGRhdGFQcml2LnNldCggdGhpcywgdHlwZSwgZmFsc2UgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmVzdWx0ID0ge307XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggc2F2ZWQgIT09IHJlc3VsdCApIHtcblxuXHRcdFx0XHRcdFx0Ly8gQ2FuY2VsIHRoZSBvdXRlciBzeW50aGV0aWMgZXZlbnRcblx0XHRcdFx0XHRcdGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHQudmFsdWU7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIElmIHRoaXMgaXMgYW4gaW5uZXIgc3ludGhldGljIGV2ZW50IGZvciBhbiBldmVudCB3aXRoIGEgYnViYmxpbmcgc3Vycm9nYXRlXG5cdFx0XHRcdC8vIChmb2N1cyBvciBibHVyKSwgYXNzdW1lIHRoYXQgdGhlIHN1cnJvZ2F0ZSBhbHJlYWR5IHByb3BhZ2F0ZWQgZnJvbSB0cmlnZ2VyaW5nIHRoZVxuXHRcdFx0XHQvLyBuYXRpdmUgZXZlbnQgYW5kIHByZXZlbnQgdGhhdCBmcm9tIGhhcHBlbmluZyBhZ2FpbiBoZXJlLlxuXHRcdFx0XHQvLyBUaGlzIHRlY2huaWNhbGx5IGdldHMgdGhlIG9yZGVyaW5nIHdyb25nIHcuci50LiB0byBgLnRyaWdnZXIoKWAgKGluIHdoaWNoIHRoZVxuXHRcdFx0XHQvLyBidWJibGluZyBzdXJyb2dhdGUgcHJvcGFnYXRlcyAqYWZ0ZXIqIHRoZSBub24tYnViYmxpbmcgYmFzZSksIGJ1dCB0aGF0IHNlZW1zXG5cdFx0XHRcdC8vIGxlc3MgYmFkIHRoYW4gZHVwbGljYXRpb24uXG5cdFx0XHRcdH0gZWxzZSBpZiAoICggalF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fSApLmRlbGVnYXRlVHlwZSApIHtcblx0XHRcdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgbmF0aXZlIGV2ZW50IHRyaWdnZXJlZCBhYm92ZSwgZXZlcnl0aGluZyBpcyBub3cgaW4gb3JkZXJcblx0XHRcdC8vIEZpcmUgYW4gaW5uZXIgc3ludGhldGljIGV2ZW50IHdpdGggdGhlIG9yaWdpbmFsIGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggc2F2ZWQubGVuZ3RoICkge1xuXG5cdFx0XHRcdC8vIC4uLmFuZCBjYXB0dXJlIHRoZSByZXN1bHRcblx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCB0eXBlLCB7XG5cdFx0XHRcdFx0dmFsdWU6IGpRdWVyeS5ldmVudC50cmlnZ2VyKFxuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMStcblx0XHRcdFx0XHRcdC8vIEV4dGVuZCB3aXRoIHRoZSBwcm90b3R5cGUgdG8gcmVzZXQgdGhlIGFib3ZlIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpXG5cdFx0XHRcdFx0XHRqUXVlcnkuZXh0ZW5kKCBzYXZlZFsgMCBdLCBqUXVlcnkuRXZlbnQucHJvdG90eXBlICksXG5cdFx0XHRcdFx0XHRzYXZlZC5zbGljZSggMSApLFxuXHRcdFx0XHRcdFx0dGhpc1xuXHRcdFx0XHRcdClcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdC8vIEFib3J0IGhhbmRsaW5nIG9mIHRoZSBuYXRpdmUgZXZlbnRcblx0XHRcdFx0ZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59XG5cbmpRdWVyeS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBoYW5kbGUgKSB7XG5cblx0Ly8gVGhpcyBcImlmXCIgaXMgbmVlZGVkIGZvciBwbGFpbiBvYmplY3RzXG5cdGlmICggZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyICkge1xuXHRcdGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgaGFuZGxlICk7XG5cdH1cbn07XG5cbmpRdWVyeS5FdmVudCA9IGZ1bmN0aW9uKCBzcmMsIHByb3BzICkge1xuXG5cdC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCB0aGUgJ25ldycga2V5d29yZFxuXHRpZiAoICEoIHRoaXMgaW5zdGFuY2VvZiBqUXVlcnkuRXZlbnQgKSApIHtcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5FdmVudCggc3JjLCBwcm9wcyApO1xuXHR9XG5cblx0Ly8gRXZlbnQgb2JqZWN0XG5cdGlmICggc3JjICYmIHNyYy50eXBlICkge1xuXHRcdHRoaXMub3JpZ2luYWxFdmVudCA9IHNyYztcblx0XHR0aGlzLnR5cGUgPSBzcmMudHlwZTtcblxuXHRcdC8vIEV2ZW50cyBidWJibGluZyB1cCB0aGUgZG9jdW1lbnQgbWF5IGhhdmUgYmVlbiBtYXJrZWQgYXMgcHJldmVudGVkXG5cdFx0Ly8gYnkgYSBoYW5kbGVyIGxvd2VyIGRvd24gdGhlIHRyZWU7IHJlZmxlY3QgdGhlIGNvcnJlY3QgdmFsdWUuXG5cdFx0dGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSBzcmMuZGVmYXVsdFByZXZlbnRlZCB8fFxuXHRcdFx0XHRzcmMuZGVmYXVsdFByZXZlbnRlZCA9PT0gdW5kZWZpbmVkICYmXG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTIuMyBvbmx5XG5cdFx0XHRcdHNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0cmV0dXJuVHJ1ZSA6XG5cdFx0XHRyZXR1cm5GYWxzZTtcblxuXHRcdC8vIENyZWF0ZSB0YXJnZXQgcHJvcGVydGllc1xuXHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA8PTYgLSA3IG9ubHlcblx0XHQvLyBUYXJnZXQgc2hvdWxkIG5vdCBiZSBhIHRleHQgbm9kZSAoIzUwNCwgIzEzMTQzKVxuXHRcdHRoaXMudGFyZ2V0ID0gKCBzcmMudGFyZ2V0ICYmIHNyYy50YXJnZXQubm9kZVR5cGUgPT09IDMgKSA/XG5cdFx0XHRzcmMudGFyZ2V0LnBhcmVudE5vZGUgOlxuXHRcdFx0c3JjLnRhcmdldDtcblxuXHRcdHRoaXMuY3VycmVudFRhcmdldCA9IHNyYy5jdXJyZW50VGFyZ2V0O1xuXHRcdHRoaXMucmVsYXRlZFRhcmdldCA9IHNyYy5yZWxhdGVkVGFyZ2V0O1xuXG5cdC8vIEV2ZW50IHR5cGVcblx0fSBlbHNlIHtcblx0XHR0aGlzLnR5cGUgPSBzcmM7XG5cdH1cblxuXHQvLyBQdXQgZXhwbGljaXRseSBwcm92aWRlZCBwcm9wZXJ0aWVzIG9udG8gdGhlIGV2ZW50IG9iamVjdFxuXHRpZiAoIHByb3BzICkge1xuXHRcdGpRdWVyeS5leHRlbmQoIHRoaXMsIHByb3BzICk7XG5cdH1cblxuXHQvLyBDcmVhdGUgYSB0aW1lc3RhbXAgaWYgaW5jb21pbmcgZXZlbnQgZG9lc24ndCBoYXZlIG9uZVxuXHR0aGlzLnRpbWVTdGFtcCA9IHNyYyAmJiBzcmMudGltZVN0YW1wIHx8IERhdGUubm93KCk7XG5cblx0Ly8gTWFyayBpdCBhcyBmaXhlZFxuXHR0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTtcbn07XG5cbi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZ1xuLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMDMwMzMxL2VjbWEtc2NyaXB0LWJpbmRpbmcuaHRtbFxualF1ZXJ5LkV2ZW50LnByb3RvdHlwZSA9IHtcblx0Y29uc3RydWN0b3I6IGpRdWVyeS5FdmVudCxcblx0aXNEZWZhdWx0UHJldmVudGVkOiByZXR1cm5GYWxzZSxcblx0aXNQcm9wYWdhdGlvblN0b3BwZWQ6IHJldHVybkZhbHNlLFxuXHRpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cdGlzU2ltdWxhdGVkOiBmYWxzZSxcblxuXHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdH1cblx0fSxcblx0c3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcblxuXHRcdHRoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlO1xuXG5cdFx0aWYgKCBlICYmICF0aGlzLmlzU2ltdWxhdGVkICkge1xuXHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHR9XG5cblx0XHR0aGlzLnN0b3BQcm9wYWdhdGlvbigpO1xuXHR9XG59O1xuXG4vLyBJbmNsdWRlcyBhbGwgY29tbW9uIGV2ZW50IHByb3BzIGluY2x1ZGluZyBLZXlFdmVudCBhbmQgTW91c2VFdmVudCBzcGVjaWZpYyBwcm9wc1xualF1ZXJ5LmVhY2goIHtcblx0YWx0S2V5OiB0cnVlLFxuXHRidWJibGVzOiB0cnVlLFxuXHRjYW5jZWxhYmxlOiB0cnVlLFxuXHRjaGFuZ2VkVG91Y2hlczogdHJ1ZSxcblx0Y3RybEtleTogdHJ1ZSxcblx0ZGV0YWlsOiB0cnVlLFxuXHRldmVudFBoYXNlOiB0cnVlLFxuXHRtZXRhS2V5OiB0cnVlLFxuXHRwYWdlWDogdHJ1ZSxcblx0cGFnZVk6IHRydWUsXG5cdHNoaWZ0S2V5OiB0cnVlLFxuXHR2aWV3OiB0cnVlLFxuXHRcImNoYXJcIjogdHJ1ZSxcblx0Y29kZTogdHJ1ZSxcblx0Y2hhckNvZGU6IHRydWUsXG5cdGtleTogdHJ1ZSxcblx0a2V5Q29kZTogdHJ1ZSxcblx0YnV0dG9uOiB0cnVlLFxuXHRidXR0b25zOiB0cnVlLFxuXHRjbGllbnRYOiB0cnVlLFxuXHRjbGllbnRZOiB0cnVlLFxuXHRvZmZzZXRYOiB0cnVlLFxuXHRvZmZzZXRZOiB0cnVlLFxuXHRwb2ludGVySWQ6IHRydWUsXG5cdHBvaW50ZXJUeXBlOiB0cnVlLFxuXHRzY3JlZW5YOiB0cnVlLFxuXHRzY3JlZW5ZOiB0cnVlLFxuXHR0YXJnZXRUb3VjaGVzOiB0cnVlLFxuXHR0b0VsZW1lbnQ6IHRydWUsXG5cdHRvdWNoZXM6IHRydWUsXG5cblx0d2hpY2g6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHR2YXIgYnV0dG9uID0gZXZlbnQuYnV0dG9uO1xuXG5cdFx0Ly8gQWRkIHdoaWNoIGZvciBrZXkgZXZlbnRzXG5cdFx0aWYgKCBldmVudC53aGljaCA9PSBudWxsICYmIHJrZXlFdmVudC50ZXN0KCBldmVudC50eXBlICkgKSB7XG5cdFx0XHRyZXR1cm4gZXZlbnQuY2hhckNvZGUgIT0gbnVsbCA/IGV2ZW50LmNoYXJDb2RlIDogZXZlbnQua2V5Q29kZTtcblx0XHR9XG5cblx0XHQvLyBBZGQgd2hpY2ggZm9yIGNsaWNrOiAxID09PSBsZWZ0OyAyID09PSBtaWRkbGU7IDMgPT09IHJpZ2h0XG5cdFx0aWYgKCAhZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQgJiYgcm1vdXNlRXZlbnQudGVzdCggZXZlbnQudHlwZSApICkge1xuXHRcdFx0aWYgKCBidXR0b24gJiAxICkge1xuXHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBidXR0b24gJiAyICkge1xuXHRcdFx0XHRyZXR1cm4gMztcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBidXR0b24gJiA0ICkge1xuXHRcdFx0XHRyZXR1cm4gMjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50LndoaWNoO1xuXHR9XG59LCBqUXVlcnkuZXZlbnQuYWRkUHJvcCApO1xuXG5qUXVlcnkuZWFjaCggeyBmb2N1czogXCJmb2N1c2luXCIsIGJsdXI6IFwiZm9jdXNvdXRcIiB9LCBmdW5jdGlvbiggdHlwZSwgZGVsZWdhdGVUeXBlICkge1xuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdID0ge1xuXG5cdFx0Ly8gVXRpbGl6ZSBuYXRpdmUgZXZlbnQgaWYgcG9zc2libGUgc28gYmx1ci9mb2N1cyBzZXF1ZW5jZSBpcyBjb3JyZWN0XG5cdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBDbGFpbSB0aGUgZmlyc3QgaGFuZGxlclxuXHRcdFx0Ly8gZGF0YVByaXYuc2V0KCB0aGlzLCBcImZvY3VzXCIsIC4uLiApXG5cdFx0XHQvLyBkYXRhUHJpdi5zZXQoIHRoaXMsIFwiYmx1clwiLCAuLi4gKVxuXHRcdFx0bGV2ZXJhZ2VOYXRpdmUoIHRoaXMsIHR5cGUsIGV4cGVjdFN5bmMgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIGZhbHNlIHRvIGFsbG93IG5vcm1hbCBwcm9jZXNzaW5nIGluIHRoZSBjYWxsZXJcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBGb3JjZSBzZXR1cCBiZWZvcmUgdHJpZ2dlclxuXHRcdFx0bGV2ZXJhZ2VOYXRpdmUoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIG5vbi1mYWxzZSB0byBhbGxvdyBub3JtYWwgZXZlbnQtcGF0aCBwcm9wYWdhdGlvblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdGRlbGVnYXRlVHlwZTogZGVsZWdhdGVUeXBlXG5cdH07XG59ICk7XG5cbi8vIENyZWF0ZSBtb3VzZWVudGVyL2xlYXZlIGV2ZW50cyB1c2luZyBtb3VzZW92ZXIvb3V0IGFuZCBldmVudC10aW1lIGNoZWNrc1xuLy8gc28gdGhhdCBldmVudCBkZWxlZ2F0aW9uIHdvcmtzIGluIGpRdWVyeS5cbi8vIERvIHRoZSBzYW1lIGZvciBwb2ludGVyZW50ZXIvcG9pbnRlcmxlYXZlIGFuZCBwb2ludGVyb3Zlci9wb2ludGVyb3V0XG4vL1xuLy8gU3VwcG9ydDogU2FmYXJpIDcgb25seVxuLy8gU2FmYXJpIHNlbmRzIG1vdXNlZW50ZXIgdG9vIG9mdGVuOyBzZWU6XG4vLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NzAyNThcbi8vIGZvciB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGJ1ZyAoaXQgZXhpc3RlZCBpbiBvbGRlciBDaHJvbWUgdmVyc2lvbnMgYXMgd2VsbCkuXG5qUXVlcnkuZWFjaCgge1xuXHRtb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLFxuXHRtb3VzZWxlYXZlOiBcIm1vdXNlb3V0XCIsXG5cdHBvaW50ZXJlbnRlcjogXCJwb2ludGVyb3ZlclwiLFxuXHRwb2ludGVybGVhdmU6IFwicG9pbnRlcm91dFwiXG59LCBmdW5jdGlvbiggb3JpZywgZml4ICkge1xuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgb3JpZyBdID0ge1xuXHRcdGRlbGVnYXRlVHlwZTogZml4LFxuXHRcdGJpbmRUeXBlOiBmaXgsXG5cblx0XHRoYW5kbGU6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHZhciByZXQsXG5cdFx0XHRcdHRhcmdldCA9IHRoaXMsXG5cdFx0XHRcdHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0LFxuXHRcdFx0XHRoYW5kbGVPYmogPSBldmVudC5oYW5kbGVPYmo7XG5cblx0XHRcdC8vIEZvciBtb3VzZWVudGVyL2xlYXZlIGNhbGwgdGhlIGhhbmRsZXIgaWYgcmVsYXRlZCBpcyBvdXRzaWRlIHRoZSB0YXJnZXQuXG5cdFx0XHQvLyBOQjogTm8gcmVsYXRlZFRhcmdldCBpZiB0aGUgbW91c2UgbGVmdC9lbnRlcmVkIHRoZSBicm93c2VyIHdpbmRvd1xuXHRcdFx0aWYgKCAhcmVsYXRlZCB8fCAoIHJlbGF0ZWQgIT09IHRhcmdldCAmJiAhalF1ZXJ5LmNvbnRhaW5zKCB0YXJnZXQsIHJlbGF0ZWQgKSApICkge1xuXHRcdFx0XHRldmVudC50eXBlID0gaGFuZGxlT2JqLm9yaWdUeXBlO1xuXHRcdFx0XHRyZXQgPSBoYW5kbGVPYmouaGFuZGxlci5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdGV2ZW50LnR5cGUgPSBmaXg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH1cblx0fTtcbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdG9uOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gb24oIHRoaXMsIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKTtcblx0fSxcblx0b25lOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gb24oIHRoaXMsIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIDEgKTtcblx0fSxcblx0b2ZmOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBmbiApIHtcblx0XHR2YXIgaGFuZGxlT2JqLCB0eXBlO1xuXHRcdGlmICggdHlwZXMgJiYgdHlwZXMucHJldmVudERlZmF1bHQgJiYgdHlwZXMuaGFuZGxlT2JqICkge1xuXG5cdFx0XHQvLyAoIGV2ZW50ICkgIGRpc3BhdGNoZWQgalF1ZXJ5LkV2ZW50XG5cdFx0XHRoYW5kbGVPYmogPSB0eXBlcy5oYW5kbGVPYmo7XG5cdFx0XHRqUXVlcnkoIHR5cGVzLmRlbGVnYXRlVGFyZ2V0ICkub2ZmKFxuXHRcdFx0XHRoYW5kbGVPYmoubmFtZXNwYWNlID9cblx0XHRcdFx0XHRoYW5kbGVPYmoub3JpZ1R5cGUgKyBcIi5cIiArIGhhbmRsZU9iai5uYW1lc3BhY2UgOlxuXHRcdFx0XHRcdGhhbmRsZU9iai5vcmlnVHlwZSxcblx0XHRcdFx0aGFuZGxlT2JqLnNlbGVjdG9yLFxuXHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlclxuXHRcdFx0KTtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdFx0Ly8gKCB0eXBlcy1vYmplY3QgWywgc2VsZWN0b3JdIClcblx0XHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XG5cdFx0XHRcdHRoaXMub2ZmKCB0eXBlLCBzZWxlY3RvciwgdHlwZXNbIHR5cGUgXSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXHRcdGlmICggc2VsZWN0b3IgPT09IGZhbHNlIHx8IHR5cGVvZiBzZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzIFssIGZuXSApXG5cdFx0XHRmbiA9IHNlbGVjdG9yO1xuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICggZm4gPT09IGZhbHNlICkge1xuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCB0eXBlcywgZm4sIHNlbGVjdG9yICk7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cblxudmFyXG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMCAtIDExLCBFZGdlIDEyIC0gMTMgb25seVxuXHQvLyBJbiBJRS9FZGdlIHVzaW5nIHJlZ2V4IGdyb3VwcyBoZXJlIGNhdXNlcyBzZXZlcmUgc2xvd2Rvd25zLlxuXHQvLyBTZWUgaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vSUUvZmVlZGJhY2svZGV0YWlscy8xNzM2NTEyL1xuXHRybm9Jbm5lcmh0bWwgPSAvPHNjcmlwdHw8c3R5bGV8PGxpbmsvaSxcblxuXHQvLyBjaGVja2VkPVwiY2hlY2tlZFwiIG9yIGNoZWNrZWRcblx0cmNoZWNrZWQgPSAvY2hlY2tlZFxccyooPzpbXj1dfD1cXHMqLmNoZWNrZWQuKS9pLFxuXHRyY2xlYW5TY3JpcHQgPSAvXlxccyo8ISg/OlxcW0NEQVRBXFxbfC0tKXwoPzpcXF1cXF18LS0pPlxccyokL2c7XG5cbi8vIFByZWZlciBhIHRib2R5IG92ZXIgaXRzIHBhcmVudCB0YWJsZSBmb3IgY29udGFpbmluZyBuZXcgcm93c1xuZnVuY3Rpb24gbWFuaXB1bGF0aW9uVGFyZ2V0KCBlbGVtLCBjb250ZW50ICkge1xuXHRpZiAoIG5vZGVOYW1lKCBlbGVtLCBcInRhYmxlXCIgKSAmJlxuXHRcdG5vZGVOYW1lKCBjb250ZW50Lm5vZGVUeXBlICE9PSAxMSA/IGNvbnRlbnQgOiBjb250ZW50LmZpcnN0Q2hpbGQsIFwidHJcIiApICkge1xuXG5cdFx0cmV0dXJuIGpRdWVyeSggZWxlbSApLmNoaWxkcmVuKCBcInRib2R5XCIgKVsgMCBdIHx8IGVsZW07XG5cdH1cblxuXHRyZXR1cm4gZWxlbTtcbn1cblxuLy8gUmVwbGFjZS9yZXN0b3JlIHRoZSB0eXBlIGF0dHJpYnV0ZSBvZiBzY3JpcHQgZWxlbWVudHMgZm9yIHNhZmUgRE9NIG1hbmlwdWxhdGlvblxuZnVuY3Rpb24gZGlzYWJsZVNjcmlwdCggZWxlbSApIHtcblx0ZWxlbS50eXBlID0gKCBlbGVtLmdldEF0dHJpYnV0ZSggXCJ0eXBlXCIgKSAhPT0gbnVsbCApICsgXCIvXCIgKyBlbGVtLnR5cGU7XG5cdHJldHVybiBlbGVtO1xufVxuZnVuY3Rpb24gcmVzdG9yZVNjcmlwdCggZWxlbSApIHtcblx0aWYgKCAoIGVsZW0udHlwZSB8fCBcIlwiICkuc2xpY2UoIDAsIDUgKSA9PT0gXCJ0cnVlL1wiICkge1xuXHRcdGVsZW0udHlwZSA9IGVsZW0udHlwZS5zbGljZSggNSApO1xuXHR9IGVsc2Uge1xuXHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBcInR5cGVcIiApO1xuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmZ1bmN0aW9uIGNsb25lQ29weUV2ZW50KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBpLCBsLCB0eXBlLCBwZGF0YU9sZCwgdWRhdGFPbGQsIHVkYXRhQ3VyLCBldmVudHM7XG5cblx0aWYgKCBkZXN0Lm5vZGVUeXBlICE9PSAxICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIDEuIENvcHkgcHJpdmF0ZSBkYXRhOiBldmVudHMsIGhhbmRsZXJzLCBldGMuXG5cdGlmICggZGF0YVByaXYuaGFzRGF0YSggc3JjICkgKSB7XG5cdFx0cGRhdGFPbGQgPSBkYXRhUHJpdi5nZXQoIHNyYyApO1xuXHRcdGV2ZW50cyA9IHBkYXRhT2xkLmV2ZW50cztcblxuXHRcdGlmICggZXZlbnRzICkge1xuXHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBkZXN0LCBcImhhbmRsZSBldmVudHNcIiApO1xuXG5cdFx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcblx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBldmVudHNbIHR5cGUgXS5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggZGVzdCwgdHlwZSwgZXZlbnRzWyB0eXBlIF1bIGkgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gMi4gQ29weSB1c2VyIGRhdGFcblx0aWYgKCBkYXRhVXNlci5oYXNEYXRhKCBzcmMgKSApIHtcblx0XHR1ZGF0YU9sZCA9IGRhdGFVc2VyLmFjY2Vzcyggc3JjICk7XG5cdFx0dWRhdGFDdXIgPSBqUXVlcnkuZXh0ZW5kKCB7fSwgdWRhdGFPbGQgKTtcblxuXHRcdGRhdGFVc2VyLnNldCggZGVzdCwgdWRhdGFDdXIgKTtcblx0fVxufVxuXG4vLyBGaXggSUUgYnVncywgc2VlIHN1cHBvcnQgdGVzdHNcbmZ1bmN0aW9uIGZpeElucHV0KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBub2RlTmFtZSA9IGRlc3Qubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuXHQvLyBGYWlscyB0byBwZXJzaXN0IHRoZSBjaGVja2VkIHN0YXRlIG9mIGEgY2xvbmVkIGNoZWNrYm94IG9yIHJhZGlvIGJ1dHRvbi5cblx0aWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmIHJjaGVja2FibGVUeXBlLnRlc3QoIHNyYy50eXBlICkgKSB7XG5cdFx0ZGVzdC5jaGVja2VkID0gc3JjLmNoZWNrZWQ7XG5cblx0Ly8gRmFpbHMgdG8gcmV0dXJuIHRoZSBzZWxlY3RlZCBvcHRpb24gdG8gdGhlIGRlZmF1bHQgc2VsZWN0ZWQgc3RhdGUgd2hlbiBjbG9uaW5nIG9wdGlvbnNcblx0fSBlbHNlIGlmICggbm9kZU5hbWUgPT09IFwiaW5wdXRcIiB8fCBub2RlTmFtZSA9PT0gXCJ0ZXh0YXJlYVwiICkge1xuXHRcdGRlc3QuZGVmYXVsdFZhbHVlID0gc3JjLmRlZmF1bHRWYWx1ZTtcblx0fVxufVxuXG5mdW5jdGlvbiBkb21NYW5pcCggY29sbGVjdGlvbiwgYXJncywgY2FsbGJhY2ssIGlnbm9yZWQgKSB7XG5cblx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRhcmdzID0gZmxhdCggYXJncyApO1xuXG5cdHZhciBmcmFnbWVudCwgZmlyc3QsIHNjcmlwdHMsIGhhc1NjcmlwdHMsIG5vZGUsIGRvYyxcblx0XHRpID0gMCxcblx0XHRsID0gY29sbGVjdGlvbi5sZW5ndGgsXG5cdFx0aU5vQ2xvbmUgPSBsIC0gMSxcblx0XHR2YWx1ZSA9IGFyZ3NbIDAgXSxcblx0XHR2YWx1ZUlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdC8vIFdlIGNhbid0IGNsb25lTm9kZSBmcmFnbWVudHMgdGhhdCBjb250YWluIGNoZWNrZWQsIGluIFdlYktpdFxuXHRpZiAoIHZhbHVlSXNGdW5jdGlvbiB8fFxuXHRcdFx0KCBsID4gMSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0IXN1cHBvcnQuY2hlY2tDbG9uZSAmJiByY2hlY2tlZC50ZXN0KCB2YWx1ZSApICkgKSB7XG5cdFx0cmV0dXJuIGNvbGxlY3Rpb24uZWFjaCggZnVuY3Rpb24oIGluZGV4ICkge1xuXHRcdFx0dmFyIHNlbGYgPSBjb2xsZWN0aW9uLmVxKCBpbmRleCApO1xuXHRcdFx0aWYgKCB2YWx1ZUlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdGFyZ3NbIDAgXSA9IHZhbHVlLmNhbGwoIHRoaXMsIGluZGV4LCBzZWxmLmh0bWwoKSApO1xuXHRcdFx0fVxuXHRcdFx0ZG9tTWFuaXAoIHNlbGYsIGFyZ3MsIGNhbGxiYWNrLCBpZ25vcmVkICk7XG5cdFx0fSApO1xuXHR9XG5cblx0aWYgKCBsICkge1xuXHRcdGZyYWdtZW50ID0gYnVpbGRGcmFnbWVudCggYXJncywgY29sbGVjdGlvblsgMCBdLm93bmVyRG9jdW1lbnQsIGZhbHNlLCBjb2xsZWN0aW9uLCBpZ25vcmVkICk7XG5cdFx0Zmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkO1xuXG5cdFx0aWYgKCBmcmFnbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSApIHtcblx0XHRcdGZyYWdtZW50ID0gZmlyc3Q7XG5cdFx0fVxuXG5cdFx0Ly8gUmVxdWlyZSBlaXRoZXIgbmV3IGNvbnRlbnQgb3IgYW4gaW50ZXJlc3QgaW4gaWdub3JlZCBlbGVtZW50cyB0byBpbnZva2UgdGhlIGNhbGxiYWNrXG5cdFx0aWYgKCBmaXJzdCB8fCBpZ25vcmVkICkge1xuXHRcdFx0c2NyaXB0cyA9IGpRdWVyeS5tYXAoIGdldEFsbCggZnJhZ21lbnQsIFwic2NyaXB0XCIgKSwgZGlzYWJsZVNjcmlwdCApO1xuXHRcdFx0aGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoO1xuXG5cdFx0XHQvLyBVc2UgdGhlIG9yaWdpbmFsIGZyYWdtZW50IGZvciB0aGUgbGFzdCBpdGVtXG5cdFx0XHQvLyBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXBcblx0XHRcdC8vIGJlaW5nIGVtcHRpZWQgaW5jb3JyZWN0bHkgaW4gY2VydGFpbiBzaXR1YXRpb25zICgjODA3MCkuXG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdG5vZGUgPSBmcmFnbWVudDtcblxuXHRcdFx0XHRpZiAoIGkgIT09IGlOb0Nsb25lICkge1xuXHRcdFx0XHRcdG5vZGUgPSBqUXVlcnkuY2xvbmUoIG5vZGUsIHRydWUsIHRydWUgKTtcblxuXHRcdFx0XHRcdC8vIEtlZXAgcmVmZXJlbmNlcyB0byBjbG9uZWQgc2NyaXB0cyBmb3IgbGF0ZXIgcmVzdG9yYXRpb25cblx0XHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seVxuXHRcdFx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBzY3JpcHRzLCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNhbGxiYWNrLmNhbGwoIGNvbGxlY3Rpb25bIGkgXSwgbm9kZSwgaSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cdFx0XHRcdGRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRcdFx0Ly8gUmVlbmFibGUgc2NyaXB0c1xuXHRcdFx0XHRqUXVlcnkubWFwKCBzY3JpcHRzLCByZXN0b3JlU2NyaXB0ICk7XG5cblx0XHRcdFx0Ly8gRXZhbHVhdGUgZXhlY3V0YWJsZSBzY3JpcHRzIG9uIGZpcnN0IGRvY3VtZW50IGluc2VydGlvblxuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGhhc1NjcmlwdHM7IGkrKyApIHtcblx0XHRcdFx0XHRub2RlID0gc2NyaXB0c1sgaSBdO1xuXHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggbm9kZS50eXBlIHx8IFwiXCIgKSAmJlxuXHRcdFx0XHRcdFx0IWRhdGFQcml2LmFjY2Vzcyggbm9kZSwgXCJnbG9iYWxFdmFsXCIgKSAmJlxuXHRcdFx0XHRcdFx0alF1ZXJ5LmNvbnRhaW5zKCBkb2MsIG5vZGUgKSApIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBub2RlLnNyYyAmJiAoIG5vZGUudHlwZSB8fCBcIlwiICkudG9Mb3dlckNhc2UoKSAgIT09IFwibW9kdWxlXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gT3B0aW9uYWwgQUpBWCBkZXBlbmRlbmN5LCBidXQgd29uJ3QgcnVuIHNjcmlwdHMgaWYgbm90IHByZXNlbnRcblx0XHRcdFx0XHRcdFx0aWYgKCBqUXVlcnkuX2V2YWxVcmwgJiYgIW5vZGUubm9Nb2R1bGUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5Ll9ldmFsVXJsKCBub2RlLnNyYywge1xuXHRcdFx0XHRcdFx0XHRcdFx0bm9uY2U6IG5vZGUubm9uY2UgfHwgbm9kZS5nZXRBdHRyaWJ1dGUoIFwibm9uY2VcIiApXG5cdFx0XHRcdFx0XHRcdFx0fSwgZG9jICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdERPTUV2YWwoIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICksIG5vZGUsIGRvYyApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBjb2xsZWN0aW9uO1xufVxuXG5mdW5jdGlvbiByZW1vdmUoIGVsZW0sIHNlbGVjdG9yLCBrZWVwRGF0YSApIHtcblx0dmFyIG5vZGUsXG5cdFx0bm9kZXMgPSBzZWxlY3RvciA/IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCBlbGVtICkgOiBlbGVtLFxuXHRcdGkgPSAwO1xuXG5cdGZvciAoIDsgKCBub2RlID0gbm9kZXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcblx0XHRpZiAoICFrZWVwRGF0YSAmJiBub2RlLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBub2RlICkgKTtcblx0XHR9XG5cblx0XHRpZiAoIG5vZGUucGFyZW50Tm9kZSApIHtcblx0XHRcdGlmICgga2VlcERhdGEgJiYgaXNBdHRhY2hlZCggbm9kZSApICkge1xuXHRcdFx0XHRzZXRHbG9iYWxFdmFsKCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0fVxuXHRcdFx0bm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBub2RlICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0aHRtbFByZWZpbHRlcjogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0cmV0dXJuIGh0bWw7XG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uKCBlbGVtLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHR2YXIgaSwgbCwgc3JjRWxlbWVudHMsIGRlc3RFbGVtZW50cyxcblx0XHRcdGNsb25lID0gZWxlbS5jbG9uZU5vZGUoIHRydWUgKSxcblx0XHRcdGluUGFnZSA9IGlzQXR0YWNoZWQoIGVsZW0gKTtcblxuXHRcdC8vIEZpeCBJRSBjbG9uaW5nIGlzc3Vlc1xuXHRcdGlmICggIXN1cHBvcnQubm9DbG9uZUNoZWNrZWQgJiYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGVsZW0ubm9kZVR5cGUgPT09IDExICkgJiZcblx0XHRcdFx0IWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXG5cdFx0XHQvLyBXZSBlc2NoZXcgU2l6emxlIGhlcmUgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnM6IGh0dHBzOi8vanNwZXJmLmNvbS9nZXRhbGwtdnMtc2l6emxlLzJcblx0XHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUgKTtcblx0XHRcdHNyY0VsZW1lbnRzID0gZ2V0QWxsKCBlbGVtICk7XG5cblx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRmaXhJbnB1dCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDb3B5IHRoZSBldmVudHMgZnJvbSB0aGUgb3JpZ2luYWwgdG8gdGhlIGNsb25lXG5cdFx0aWYgKCBkYXRhQW5kRXZlbnRzICkge1xuXHRcdFx0aWYgKCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHRcdFx0c3JjRWxlbWVudHMgPSBzcmNFbGVtZW50cyB8fCBnZXRBbGwoIGVsZW0gKTtcblx0XHRcdFx0ZGVzdEVsZW1lbnRzID0gZGVzdEVsZW1lbnRzIHx8IGdldEFsbCggY2xvbmUgKTtcblxuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IHNyY0VsZW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRjbG9uZUNvcHlFdmVudCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIGVsZW0sIGNsb25lICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUHJlc2VydmUgc2NyaXB0IGV2YWx1YXRpb24gaGlzdG9yeVxuXHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUsIFwic2NyaXB0XCIgKTtcblx0XHRpZiAoIGRlc3RFbGVtZW50cy5sZW5ndGggPiAwICkge1xuXHRcdFx0c2V0R2xvYmFsRXZhbCggZGVzdEVsZW1lbnRzLCAhaW5QYWdlICYmIGdldEFsbCggZWxlbSwgXCJzY3JpcHRcIiApICk7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIHRoZSBjbG9uZWQgc2V0XG5cdFx0cmV0dXJuIGNsb25lO1xuXHR9LFxuXG5cdGNsZWFuRGF0YTogZnVuY3Rpb24oIGVsZW1zICkge1xuXHRcdHZhciBkYXRhLCBlbGVtLCB0eXBlLFxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7ICggZWxlbSA9IGVsZW1zWyBpIF0gKSAhPT0gdW5kZWZpbmVkOyBpKysgKSB7XG5cdFx0XHRpZiAoIGFjY2VwdERhdGEoIGVsZW0gKSApIHtcblx0XHRcdFx0aWYgKCAoIGRhdGEgPSBlbGVtWyBkYXRhUHJpdi5leHBhbmRvIF0gKSApIHtcblx0XHRcdFx0XHRpZiAoIGRhdGEuZXZlbnRzICkge1xuXHRcdFx0XHRcdFx0Zm9yICggdHlwZSBpbiBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsWyB0eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIFRoaXMgaXMgYSBzaG9ydGN1dCB0byBhdm9pZCBqUXVlcnkuZXZlbnQucmVtb3ZlJ3Mgb3ZlcmhlYWRcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGRhdGEuaGFuZGxlICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0zNSAtIDQ1K1xuXHRcdFx0XHRcdC8vIEFzc2lnbiB1bmRlZmluZWQgaW5zdGVhZCBvZiB1c2luZyBkZWxldGUsIHNlZSBEYXRhI3JlbW92ZVxuXHRcdFx0XHRcdGVsZW1bIGRhdGFQcml2LmV4cGFuZG8gXSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIGVsZW1bIGRhdGFVc2VyLmV4cGFuZG8gXSApIHtcblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDUrXG5cdFx0XHRcdFx0Ly8gQXNzaWduIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIHVzaW5nIGRlbGV0ZSwgc2VlIERhdGEjcmVtb3ZlXG5cdFx0XHRcdFx0ZWxlbVsgZGF0YVVzZXIuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0ZGV0YWNoOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHJlbW92ZSggdGhpcywgc2VsZWN0b3IsIHRydWUgKTtcblx0fSxcblxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gcmVtb3ZlKCB0aGlzLCBzZWxlY3RvciApO1xuXHR9LFxuXG5cdHRleHQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS50ZXh0KCB0aGlzICkgOlxuXHRcdFx0XHR0aGlzLmVtcHR5KCkuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRleHRDb250ZW50ID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fSxcblxuXHRhcHBlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XG5cdFx0XHRcdHRhcmdldC5hcHBlbmRDaGlsZCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRwcmVwZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0YXJnZXQuZmlyc3RDaGlsZCApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRiZWZvcmU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdGFmdGVyOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0dGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcy5uZXh0U2libGluZyApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGVsZW0sXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKCBlbGVtID0gdGhpc1sgaSBdICkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXG5cdFx0XHRcdC8vIFByZXZlbnQgbWVtb3J5IGxlYWtzXG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggZWxlbSwgZmFsc2UgKSApO1xuXG5cdFx0XHRcdC8vIFJlbW92ZSBhbnkgcmVtYWluaW5nIG5vZGVzXG5cdFx0XHRcdGVsZW0udGV4dENvbnRlbnQgPSBcIlwiO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiggZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0ZGF0YUFuZEV2ZW50cyA9IGRhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGZhbHNlIDogZGF0YUFuZEV2ZW50cztcblx0XHRkZWVwRGF0YUFuZEV2ZW50cyA9IGRlZXBEYXRhQW5kRXZlbnRzID09IG51bGwgPyBkYXRhQW5kRXZlbnRzIDogZGVlcERhdGFBbmRFdmVudHM7XG5cblx0XHRyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5jbG9uZSggdGhpcywgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKTtcblx0XHR9ICk7XG5cdH0sXG5cblx0aHRtbDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBlbGVtID0gdGhpc1sgMCBdIHx8IHt9LFxuXHRcdFx0XHRpID0gMCxcblx0XHRcdFx0bCA9IHRoaXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIHZhbHVlID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uaW5uZXJIVE1MO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZWUgaWYgd2UgY2FuIHRha2UgYSBzaG9ydGN1dCBhbmQganVzdCB1c2UgaW5uZXJIVE1MXG5cdFx0XHRpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAhcm5vSW5uZXJodG1sLnRlc3QoIHZhbHVlICkgJiZcblx0XHRcdFx0IXdyYXBNYXBbICggcnRhZ05hbWUuZXhlYyggdmFsdWUgKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKSBdICkge1xuXG5cdFx0XHRcdHZhbHVlID0galF1ZXJ5Lmh0bWxQcmVmaWx0ZXIoIHZhbHVlICk7XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRlbGVtID0gdGhpc1sgaSBdIHx8IHt9O1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgZWxlbWVudCBub2RlcyBhbmQgcHJldmVudCBtZW1vcnkgbGVha3Ncblx0XHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cdFx0XHRcdFx0XHRcdGVsZW0uaW5uZXJIVE1MID0gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZWxlbSA9IDA7XG5cblx0XHRcdFx0Ly8gSWYgdXNpbmcgaW5uZXJIVE1MIHRocm93cyBhbiBleGNlcHRpb24sIHVzZSB0aGUgZmFsbGJhY2sgbWV0aG9kXG5cdFx0XHRcdH0gY2F0Y2ggKCBlICkge31cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHR0aGlzLmVtcHR5KCkuYXBwZW5kKCB2YWx1ZSApO1xuXHRcdFx0fVxuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoICk7XG5cdH0sXG5cblx0cmVwbGFjZVdpdGg6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBpZ25vcmVkID0gW107XG5cblx0XHQvLyBNYWtlIHRoZSBjaGFuZ2VzLCByZXBsYWNpbmcgZWFjaCBub24taWdub3JlZCBjb250ZXh0IGVsZW1lbnQgd2l0aCB0aGUgbmV3IGNvbnRlbnRcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlO1xuXG5cdFx0XHRpZiAoIGpRdWVyeS5pbkFycmF5KCB0aGlzLCBpZ25vcmVkICkgPCAwICkge1xuXHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIHRoaXMgKSApO1xuXHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblx0XHRcdFx0XHRwYXJlbnQucmVwbGFjZUNoaWxkKCBlbGVtLCB0aGlzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEZvcmNlIGNhbGxiYWNrIGludm9jYXRpb25cblx0XHR9LCBpZ25vcmVkICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIHtcblx0YXBwZW5kVG86IFwiYXBwZW5kXCIsXG5cdHByZXBlbmRUbzogXCJwcmVwZW5kXCIsXG5cdGluc2VydEJlZm9yZTogXCJiZWZvcmVcIixcblx0aW5zZXJ0QWZ0ZXI6IFwiYWZ0ZXJcIixcblx0cmVwbGFjZUFsbDogXCJyZXBsYWNlV2l0aFwiXG59LCBmdW5jdGlvbiggbmFtZSwgb3JpZ2luYWwgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBlbGVtcyxcblx0XHRcdHJldCA9IFtdLFxuXHRcdFx0aW5zZXJ0ID0galF1ZXJ5KCBzZWxlY3RvciApLFxuXHRcdFx0bGFzdCA9IGluc2VydC5sZW5ndGggLSAxLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7IGkgPD0gbGFzdDsgaSsrICkge1xuXHRcdFx0ZWxlbXMgPSBpID09PSBsYXN0ID8gdGhpcyA6IHRoaXMuY2xvbmUoIHRydWUgKTtcblx0XHRcdGpRdWVyeSggaW5zZXJ0WyBpIF0gKVsgb3JpZ2luYWwgXSggZWxlbXMgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdFx0XHQvLyAuZ2V0KCkgYmVjYXVzZSBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdFx0XHRwdXNoLmFwcGx5KCByZXQsIGVsZW1zLmdldCgpICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTtcblx0fTtcbn0gKTtcbnZhciBybnVtbm9ucHggPSBuZXcgUmVnRXhwKCBcIl4oXCIgKyBwbnVtICsgXCIpKD8hcHgpW2EteiVdKyRcIiwgXCJpXCIgKTtcblxudmFyIGdldFN0eWxlcyA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5LCBGaXJlZm94IDw9MzAgKCMxNTA5OCwgIzE0MTUwKVxuXHRcdC8vIElFIHRocm93cyBvbiBlbGVtZW50cyBjcmVhdGVkIGluIHBvcHVwc1xuXHRcdC8vIEZGIG1lYW53aGlsZSB0aHJvd3Mgb24gZnJhbWUgZWxlbWVudHMgdGhyb3VnaCBcImRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGVcIlxuXHRcdHZhciB2aWV3ID0gZWxlbS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3O1xuXG5cdFx0aWYgKCAhdmlldyB8fCAhdmlldy5vcGVuZXIgKSB7XG5cdFx0XHR2aWV3ID0gd2luZG93O1xuXHRcdH1cblxuXHRcdHJldHVybiB2aWV3LmdldENvbXB1dGVkU3R5bGUoIGVsZW0gKTtcblx0fTtcblxudmFyIHN3YXAgPSBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgY2FsbGJhY2sgKSB7XG5cdHZhciByZXQsIG5hbWUsXG5cdFx0b2xkID0ge307XG5cblx0Ly8gUmVtZW1iZXIgdGhlIG9sZCB2YWx1ZXMsIGFuZCBpbnNlcnQgdGhlIG5ldyBvbmVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRvbGRbIG5hbWUgXSA9IGVsZW0uc3R5bGVbIG5hbWUgXTtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvcHRpb25zWyBuYW1lIF07XG5cdH1cblxuXHRyZXQgPSBjYWxsYmFjay5jYWxsKCBlbGVtICk7XG5cblx0Ly8gUmV2ZXJ0IHRoZSBvbGQgdmFsdWVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvbGRbIG5hbWUgXTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59O1xuXG5cbnZhciByYm94U3R5bGUgPSBuZXcgUmVnRXhwKCBjc3NFeHBhbmQuam9pbiggXCJ8XCIgKSwgXCJpXCIgKTtcblxuXG5cbiggZnVuY3Rpb24oKSB7XG5cblx0Ly8gRXhlY3V0aW5nIGJvdGggcGl4ZWxQb3NpdGlvbiAmIGJveFNpemluZ1JlbGlhYmxlIHRlc3RzIHJlcXVpcmUgb25seSBvbmUgbGF5b3V0XG5cdC8vIHNvIHRoZXkncmUgZXhlY3V0ZWQgYXQgdGhlIHNhbWUgdGltZSB0byBzYXZlIHRoZSBzZWNvbmQgY29tcHV0YXRpb24uXG5cdGZ1bmN0aW9uIGNvbXB1dGVTdHlsZVRlc3RzKCkge1xuXG5cdFx0Ly8gVGhpcyBpcyBhIHNpbmdsZXRvbiwgd2UgbmVlZCB0byBleGVjdXRlIGl0IG9ubHkgb25jZVxuXHRcdGlmICggIWRpdiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9IFwicG9zaXRpb246YWJzb2x1dGU7bGVmdDotMTExMTFweDt3aWR0aDo2MHB4O1wiICtcblx0XHRcdFwibWFyZ2luLXRvcDoxcHg7cGFkZGluZzowO2JvcmRlcjowXCI7XG5cdFx0ZGl2LnN0eWxlLmNzc1RleHQgPVxuXHRcdFx0XCJwb3NpdGlvbjpyZWxhdGl2ZTtkaXNwbGF5OmJsb2NrO2JveC1zaXppbmc6Ym9yZGVyLWJveDtvdmVyZmxvdzpzY3JvbGw7XCIgK1xuXHRcdFx0XCJtYXJnaW46YXV0bztib3JkZXI6MXB4O3BhZGRpbmc6MXB4O1wiICtcblx0XHRcdFwid2lkdGg6NjAlO3RvcDoxJVwiO1xuXHRcdGRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZCggY29udGFpbmVyICkuYXBwZW5kQ2hpbGQoIGRpdiApO1xuXG5cdFx0dmFyIGRpdlN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoIGRpdiApO1xuXHRcdHBpeGVsUG9zaXRpb25WYWwgPSBkaXZTdHlsZS50b3AgIT09IFwiMSVcIjtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIC0gNC4zIG9ubHksIEZpcmVmb3ggPD0zIC0gNDRcblx0XHRyZWxpYWJsZU1hcmdpbkxlZnRWYWwgPSByb3VuZFBpeGVsTWVhc3VyZXMoIGRpdlN0eWxlLm1hcmdpbkxlZnQgKSA9PT0gMTI7XG5cblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5LCBTYWZhcmkgPD05LjEgLSAxMC4xLCBpT1MgPD03LjAgLSA5LjNcblx0XHQvLyBTb21lIHN0eWxlcyBjb21lIGJhY2sgd2l0aCBwZXJjZW50YWdlIHZhbHVlcywgZXZlbiB0aG91Z2ggdGhleSBzaG91bGRuJ3Rcblx0XHRkaXYuc3R5bGUucmlnaHQgPSBcIjYwJVwiO1xuXHRcdHBpeGVsQm94U3R5bGVzVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXZTdHlsZS5yaWdodCApID09PSAzNjtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5XG5cdFx0Ly8gRGV0ZWN0IG1pc3JlcG9ydGluZyBvZiBjb250ZW50IGRpbWVuc2lvbnMgZm9yIGJveC1zaXppbmc6Ym9yZGVyLWJveCBlbGVtZW50c1xuXHRcdGJveFNpemluZ1JlbGlhYmxlVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXZTdHlsZS53aWR0aCApID09PSAzNjtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgb25seVxuXHRcdC8vIERldGVjdCBvdmVyZmxvdzpzY3JvbGwgc2NyZXdpbmVzcyAoZ2gtMzY5OSlcblx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD02NFxuXHRcdC8vIERvbid0IGdldCB0cmlja2VkIHdoZW4gem9vbSBhZmZlY3RzIG9mZnNldFdpZHRoIChnaC00MDI5KVxuXHRcdGRpdi5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblx0XHRzY3JvbGxib3hTaXplVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXYub2Zmc2V0V2lkdGggLyAzICkgPT09IDEyO1xuXG5cdFx0ZG9jdW1lbnRFbGVtZW50LnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcblxuXHRcdC8vIE51bGxpZnkgdGhlIGRpdiBzbyBpdCB3b3VsZG4ndCBiZSBzdG9yZWQgaW4gdGhlIG1lbW9yeSBhbmRcblx0XHQvLyBpdCB3aWxsIGFsc28gYmUgYSBzaWduIHRoYXQgY2hlY2tzIGFscmVhZHkgcGVyZm9ybWVkXG5cdFx0ZGl2ID0gbnVsbDtcblx0fVxuXG5cdGZ1bmN0aW9uIHJvdW5kUGl4ZWxNZWFzdXJlcyggbWVhc3VyZSApIHtcblx0XHRyZXR1cm4gTWF0aC5yb3VuZCggcGFyc2VGbG9hdCggbWVhc3VyZSApICk7XG5cdH1cblxuXHR2YXIgcGl4ZWxQb3NpdGlvblZhbCwgYm94U2l6aW5nUmVsaWFibGVWYWwsIHNjcm9sbGJveFNpemVWYWwsIHBpeGVsQm94U3R5bGVzVmFsLFxuXHRcdHJlbGlhYmxlVHJEaW1lbnNpb25zVmFsLCByZWxpYWJsZU1hcmdpbkxlZnRWYWwsXG5cdFx0Y29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApLFxuXHRcdGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHQvLyBGaW5pc2ggZWFybHkgaW4gbGltaXRlZCAobm9uLWJyb3dzZXIpIGVudmlyb25tZW50c1xuXHRpZiAoICFkaXYuc3R5bGUgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHQvLyBTdHlsZSBvZiBjbG9uZWQgZWxlbWVudCBhZmZlY3RzIHNvdXJjZSBlbGVtZW50IGNsb25lZCAoIzg5MDgpXG5cdGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9IFwiY29udGVudC1ib3hcIjtcblx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJcIjtcblx0c3VwcG9ydC5jbGVhckNsb25lU3R5bGUgPSBkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPT09IFwiY29udGVudC1ib3hcIjtcblxuXHRqUXVlcnkuZXh0ZW5kKCBzdXBwb3J0LCB7XG5cdFx0Ym94U2l6aW5nUmVsaWFibGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybiBib3hTaXppbmdSZWxpYWJsZVZhbDtcblx0XHR9LFxuXHRcdHBpeGVsQm94U3R5bGVzOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gcGl4ZWxCb3hTdHlsZXNWYWw7XG5cdFx0fSxcblx0XHRwaXhlbFBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gcGl4ZWxQb3NpdGlvblZhbDtcblx0XHR9LFxuXHRcdHJlbGlhYmxlTWFyZ2luTGVmdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xuXHRcdFx0cmV0dXJuIHJlbGlhYmxlTWFyZ2luTGVmdFZhbDtcblx0XHR9LFxuXHRcdHNjcm9sbGJveFNpemU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybiBzY3JvbGxib3hTaXplVmFsO1xuXHRcdH0sXG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTErLCBFZGdlIDE1IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBtaXNyZXBvcnQgYGdldENvbXB1dGVkU3R5bGVgIG9mIHRhYmxlIHJvd3Mgd2l0aCB3aWR0aC9oZWlnaHRcblx0XHQvLyBzZXQgaW4gQ1NTIHdoaWxlIGBvZmZzZXQqYCBwcm9wZXJ0aWVzIHJlcG9ydCBjb3JyZWN0IHZhbHVlcy5cblx0XHQvLyBCZWhhdmlvciBpbiBJRSA5IGlzIG1vcmUgc3VidGxlIHRoYW4gaW4gbmV3ZXIgdmVyc2lvbnMgJiBpdCBwYXNzZXNcblx0XHQvLyBzb21lIHZlcnNpb25zIG9mIHRoaXMgdGVzdDsgbWFrZSBzdXJlIG5vdCB0byBtYWtlIGl0IHBhc3MgdGhlcmUhXG5cdFx0cmVsaWFibGVUckRpbWVuc2lvbnM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHRhYmxlLCB0ciwgdHJDaGlsZCwgdHJTdHlsZTtcblx0XHRcdGlmICggcmVsaWFibGVUckRpbWVuc2lvbnNWYWwgPT0gbnVsbCApIHtcblx0XHRcdFx0dGFibGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInRhYmxlXCIgKTtcblx0XHRcdFx0dHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInRyXCIgKTtcblx0XHRcdFx0dHJDaGlsZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHRcdFx0XHR0YWJsZS5zdHlsZS5jc3NUZXh0ID0gXCJwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0Oi0xMTExMXB4XCI7XG5cdFx0XHRcdHRyLnN0eWxlLmhlaWdodCA9IFwiMXB4XCI7XG5cdFx0XHRcdHRyQ2hpbGQuc3R5bGUuaGVpZ2h0ID0gXCI5cHhcIjtcblxuXHRcdFx0XHRkb2N1bWVudEVsZW1lbnRcblx0XHRcdFx0XHQuYXBwZW5kQ2hpbGQoIHRhYmxlIClcblx0XHRcdFx0XHQuYXBwZW5kQ2hpbGQoIHRyIClcblx0XHRcdFx0XHQuYXBwZW5kQ2hpbGQoIHRyQ2hpbGQgKTtcblxuXHRcdFx0XHR0clN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoIHRyICk7XG5cdFx0XHRcdHJlbGlhYmxlVHJEaW1lbnNpb25zVmFsID0gcGFyc2VJbnQoIHRyU3R5bGUuaGVpZ2h0ICkgPiAzO1xuXG5cdFx0XHRcdGRvY3VtZW50RWxlbWVudC5yZW1vdmVDaGlsZCggdGFibGUgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZWxpYWJsZVRyRGltZW5zaW9uc1ZhbDtcblx0XHR9XG5cdH0gKTtcbn0gKSgpO1xuXG5cbmZ1bmN0aW9uIGN1ckNTUyggZWxlbSwgbmFtZSwgY29tcHV0ZWQgKSB7XG5cdHZhciB3aWR0aCwgbWluV2lkdGgsIG1heFdpZHRoLCByZXQsXG5cblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDUxK1xuXHRcdC8vIFJldHJpZXZpbmcgc3R5bGUgYmVmb3JlIGNvbXB1dGVkIHNvbWVob3dcblx0XHQvLyBmaXhlcyBhbiBpc3N1ZSB3aXRoIGdldHRpbmcgd3JvbmcgdmFsdWVzXG5cdFx0Ly8gb24gZGV0YWNoZWQgZWxlbWVudHNcblx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0Y29tcHV0ZWQgPSBjb21wdXRlZCB8fCBnZXRTdHlsZXMoIGVsZW0gKTtcblxuXHQvLyBnZXRQcm9wZXJ0eVZhbHVlIGlzIG5lZWRlZCBmb3I6XG5cdC8vICAgLmNzcygnZmlsdGVyJykgKElFIDkgb25seSwgIzEyNTM3KVxuXHQvLyAgIC5jc3MoJy0tY3VzdG9tUHJvcGVydHkpICgjMzE0NClcblx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRyZXQgPSBjb21wdXRlZC5nZXRQcm9wZXJ0eVZhbHVlKCBuYW1lICkgfHwgY29tcHV0ZWRbIG5hbWUgXTtcblxuXHRcdGlmICggcmV0ID09PSBcIlwiICYmICFpc0F0dGFjaGVkKCBlbGVtICkgKSB7XG5cdFx0XHRyZXQgPSBqUXVlcnkuc3R5bGUoIGVsZW0sIG5hbWUgKTtcblx0XHR9XG5cblx0XHQvLyBBIHRyaWJ1dGUgdG8gdGhlIFwiYXdlc29tZSBoYWNrIGJ5IERlYW4gRWR3YXJkc1wiXG5cdFx0Ly8gQW5kcm9pZCBCcm93c2VyIHJldHVybnMgcGVyY2VudGFnZSBmb3Igc29tZSB2YWx1ZXMsXG5cdFx0Ly8gYnV0IHdpZHRoIHNlZW1zIHRvIGJlIHJlbGlhYmx5IHBpeGVscy5cblx0XHQvLyBUaGlzIGlzIGFnYWluc3QgdGhlIENTU09NIGRyYWZ0IHNwZWM6XG5cdFx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNyZXNvbHZlZC12YWx1ZXNcblx0XHRpZiAoICFzdXBwb3J0LnBpeGVsQm94U3R5bGVzKCkgJiYgcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJib3hTdHlsZS50ZXN0KCBuYW1lICkgKSB7XG5cblx0XHRcdC8vIFJlbWVtYmVyIHRoZSBvcmlnaW5hbCB2YWx1ZXNcblx0XHRcdHdpZHRoID0gc3R5bGUud2lkdGg7XG5cdFx0XHRtaW5XaWR0aCA9IHN0eWxlLm1pbldpZHRoO1xuXHRcdFx0bWF4V2lkdGggPSBzdHlsZS5tYXhXaWR0aDtcblxuXHRcdFx0Ly8gUHV0IGluIHRoZSBuZXcgdmFsdWVzIHRvIGdldCBhIGNvbXB1dGVkIHZhbHVlIG91dFxuXHRcdFx0c3R5bGUubWluV2lkdGggPSBzdHlsZS5tYXhXaWR0aCA9IHN0eWxlLndpZHRoID0gcmV0O1xuXHRcdFx0cmV0ID0gY29tcHV0ZWQud2lkdGg7XG5cblx0XHRcdC8vIFJldmVydCB0aGUgY2hhbmdlZCB2YWx1ZXNcblx0XHRcdHN0eWxlLndpZHRoID0gd2lkdGg7XG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IG1pbldpZHRoO1xuXHRcdFx0c3R5bGUubWF4V2lkdGggPSBtYXhXaWR0aDtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcmV0ICE9PSB1bmRlZmluZWQgP1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHRcdC8vIElFIHJldHVybnMgekluZGV4IHZhbHVlIGFzIGFuIGludGVnZXIuXG5cdFx0cmV0ICsgXCJcIiA6XG5cdFx0cmV0O1xufVxuXG5cbmZ1bmN0aW9uIGFkZEdldEhvb2tJZiggY29uZGl0aW9uRm4sIGhvb2tGbiApIHtcblxuXHQvLyBEZWZpbmUgdGhlIGhvb2ssIHdlJ2xsIGNoZWNrIG9uIHRoZSBmaXJzdCBydW4gaWYgaXQncyByZWFsbHkgbmVlZGVkLlxuXHRyZXR1cm4ge1xuXHRcdGdldDogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGNvbmRpdGlvbkZuKCkgKSB7XG5cblx0XHRcdFx0Ly8gSG9vayBub3QgbmVlZGVkIChvciBpdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgaXQgZHVlXG5cdFx0XHRcdC8vIHRvIG1pc3NpbmcgZGVwZW5kZW5jeSksIHJlbW92ZSBpdC5cblx0XHRcdFx0ZGVsZXRlIHRoaXMuZ2V0O1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIEhvb2sgbmVlZGVkOyByZWRlZmluZSBpdCBzbyB0aGF0IHRoZSBzdXBwb3J0IHRlc3QgaXMgbm90IGV4ZWN1dGVkIGFnYWluLlxuXHRcdFx0cmV0dXJuICggdGhpcy5nZXQgPSBob29rRm4gKS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fVxuXHR9O1xufVxuXG5cbnZhciBjc3NQcmVmaXhlcyA9IFsgXCJXZWJraXRcIiwgXCJNb3pcIiwgXCJtc1wiIF0sXG5cdGVtcHR5U3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkuc3R5bGUsXG5cdHZlbmRvclByb3BzID0ge307XG5cbi8vIFJldHVybiBhIHZlbmRvci1wcmVmaXhlZCBwcm9wZXJ0eSBvciB1bmRlZmluZWRcbmZ1bmN0aW9uIHZlbmRvclByb3BOYW1lKCBuYW1lICkge1xuXG5cdC8vIENoZWNrIGZvciB2ZW5kb3IgcHJlZml4ZWQgbmFtZXNcblx0dmFyIGNhcE5hbWUgPSBuYW1lWyAwIF0udG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoIDEgKSxcblx0XHRpID0gY3NzUHJlZml4ZXMubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdG5hbWUgPSBjc3NQcmVmaXhlc1sgaSBdICsgY2FwTmFtZTtcblx0XHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRcdHJldHVybiBuYW1lO1xuXHRcdH1cblx0fVxufVxuXG4vLyBSZXR1cm4gYSBwb3RlbnRpYWxseS1tYXBwZWQgalF1ZXJ5LmNzc1Byb3BzIG9yIHZlbmRvciBwcmVmaXhlZCBwcm9wZXJ0eVxuZnVuY3Rpb24gZmluYWxQcm9wTmFtZSggbmFtZSApIHtcblx0dmFyIGZpbmFsID0galF1ZXJ5LmNzc1Byb3BzWyBuYW1lIF0gfHwgdmVuZG9yUHJvcHNbIG5hbWUgXTtcblxuXHRpZiAoIGZpbmFsICkge1xuXHRcdHJldHVybiBmaW5hbDtcblx0fVxuXHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRyZXR1cm4gbmFtZTtcblx0fVxuXHRyZXR1cm4gdmVuZG9yUHJvcHNbIG5hbWUgXSA9IHZlbmRvclByb3BOYW1lKCBuYW1lICkgfHwgbmFtZTtcbn1cblxuXG52YXJcblxuXHQvLyBTd2FwcGFibGUgaWYgZGlzcGxheSBpcyBub25lIG9yIHN0YXJ0cyB3aXRoIHRhYmxlXG5cdC8vIGV4Y2VwdCBcInRhYmxlXCIsIFwidGFibGUtY2VsbFwiLCBvciBcInRhYmxlLWNhcHRpb25cIlxuXHQvLyBTZWUgaGVyZSBmb3IgZGlzcGxheSB2YWx1ZXM6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvQ1NTL2Rpc3BsYXlcblx0cmRpc3BsYXlzd2FwID0gL14obm9uZXx0YWJsZSg/IS1jW2VhXSkuKykvLFxuXHRyY3VzdG9tUHJvcCA9IC9eLS0vLFxuXHRjc3NTaG93ID0geyBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLCB2aXNpYmlsaXR5OiBcImhpZGRlblwiLCBkaXNwbGF5OiBcImJsb2NrXCIgfSxcblx0Y3NzTm9ybWFsVHJhbnNmb3JtID0ge1xuXHRcdGxldHRlclNwYWNpbmc6IFwiMFwiLFxuXHRcdGZvbnRXZWlnaHQ6IFwiNDAwXCJcblx0fTtcblxuZnVuY3Rpb24gc2V0UG9zaXRpdmVOdW1iZXIoIF9lbGVtLCB2YWx1ZSwgc3VidHJhY3QgKSB7XG5cblx0Ly8gQW55IHJlbGF0aXZlICgrLy0pIHZhbHVlcyBoYXZlIGFscmVhZHkgYmVlblxuXHQvLyBub3JtYWxpemVkIGF0IHRoaXMgcG9pbnRcblx0dmFyIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICk7XG5cdHJldHVybiBtYXRjaGVzID9cblxuXHRcdC8vIEd1YXJkIGFnYWluc3QgdW5kZWZpbmVkIFwic3VidHJhY3RcIiwgZS5nLiwgd2hlbiB1c2VkIGFzIGluIGNzc0hvb2tzXG5cdFx0TWF0aC5tYXgoIDAsIG1hdGNoZXNbIDIgXSAtICggc3VidHJhY3QgfHwgMCApICkgKyAoIG1hdGNoZXNbIDMgXSB8fCBcInB4XCIgKSA6XG5cdFx0dmFsdWU7XG59XG5cbmZ1bmN0aW9uIGJveE1vZGVsQWRqdXN0bWVudCggZWxlbSwgZGltZW5zaW9uLCBib3gsIGlzQm9yZGVyQm94LCBzdHlsZXMsIGNvbXB1dGVkVmFsICkge1xuXHR2YXIgaSA9IGRpbWVuc2lvbiA9PT0gXCJ3aWR0aFwiID8gMSA6IDAsXG5cdFx0ZXh0cmEgPSAwLFxuXHRcdGRlbHRhID0gMDtcblxuXHQvLyBBZGp1c3RtZW50IG1heSBub3QgYmUgbmVjZXNzYXJ5XG5cdGlmICggYm94ID09PSAoIGlzQm9yZGVyQm94ID8gXCJib3JkZXJcIiA6IFwiY29udGVudFwiICkgKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHRmb3IgKCA7IGkgPCA0OyBpICs9IDIgKSB7XG5cblx0XHQvLyBCb3RoIGJveCBtb2RlbHMgZXhjbHVkZSBtYXJnaW5cblx0XHRpZiAoIGJveCA9PT0gXCJtYXJnaW5cIiApIHtcblx0XHRcdGRlbHRhICs9IGpRdWVyeS5jc3MoIGVsZW0sIGJveCArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHR9XG5cblx0XHQvLyBJZiB3ZSBnZXQgaGVyZSB3aXRoIGEgY29udGVudC1ib3gsIHdlJ3JlIHNlZWtpbmcgXCJwYWRkaW5nXCIgb3IgXCJib3JkZXJcIiBvciBcIm1hcmdpblwiXG5cdFx0aWYgKCAhaXNCb3JkZXJCb3ggKSB7XG5cblx0XHRcdC8vIEFkZCBwYWRkaW5nXG5cdFx0XHRkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblxuXHRcdFx0Ly8gRm9yIFwiYm9yZGVyXCIgb3IgXCJtYXJnaW5cIiwgYWRkIGJvcmRlclxuXHRcdFx0aWYgKCBib3ggIT09IFwicGFkZGluZ1wiICkge1xuXHRcdFx0XHRkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXG5cdFx0XHQvLyBCdXQgc3RpbGwga2VlcCB0cmFjayBvZiBpdCBvdGhlcndpc2Vcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGV4dHJhICs9IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm9yZGVyXCIgKyBjc3NFeHBhbmRbIGkgXSArIFwiV2lkdGhcIiwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cblx0XHQvLyBJZiB3ZSBnZXQgaGVyZSB3aXRoIGEgYm9yZGVyLWJveCAoY29udGVudCArIHBhZGRpbmcgKyBib3JkZXIpLCB3ZSdyZSBzZWVraW5nIFwiY29udGVudFwiIG9yXG5cdFx0Ly8gXCJwYWRkaW5nXCIgb3IgXCJtYXJnaW5cIlxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIEZvciBcImNvbnRlbnRcIiwgc3VidHJhY3QgcGFkZGluZ1xuXHRcdFx0aWYgKCBib3ggPT09IFwiY29udGVudFwiICkge1xuXHRcdFx0XHRkZWx0YSAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRm9yIFwiY29udGVudFwiIG9yIFwicGFkZGluZ1wiLCBzdWJ0cmFjdCBib3JkZXJcblx0XHRcdGlmICggYm94ICE9PSBcIm1hcmdpblwiICkge1xuXHRcdFx0XHRkZWx0YSAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIEFjY291bnQgZm9yIHBvc2l0aXZlIGNvbnRlbnQtYm94IHNjcm9sbCBndXR0ZXIgd2hlbiByZXF1ZXN0ZWQgYnkgcHJvdmlkaW5nIGNvbXB1dGVkVmFsXG5cdGlmICggIWlzQm9yZGVyQm94ICYmIGNvbXB1dGVkVmFsID49IDAgKSB7XG5cblx0XHQvLyBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgaXMgYSByb3VuZGVkIHN1bSBvZiBjb250ZW50LCBwYWRkaW5nLCBzY3JvbGwgZ3V0dGVyLCBhbmQgYm9yZGVyXG5cdFx0Ly8gQXNzdW1pbmcgaW50ZWdlciBzY3JvbGwgZ3V0dGVyLCBzdWJ0cmFjdCB0aGUgcmVzdCBhbmQgcm91bmQgZG93blxuXHRcdGRlbHRhICs9IE1hdGgubWF4KCAwLCBNYXRoLmNlaWwoXG5cdFx0XHRlbGVtWyBcIm9mZnNldFwiICsgZGltZW5zaW9uWyAwIF0udG9VcHBlckNhc2UoKSArIGRpbWVuc2lvbi5zbGljZSggMSApIF0gLVxuXHRcdFx0Y29tcHV0ZWRWYWwgLVxuXHRcdFx0ZGVsdGEgLVxuXHRcdFx0ZXh0cmEgLVxuXHRcdFx0MC41XG5cblx0XHQvLyBJZiBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgaXMgdW5rbm93biwgdGhlbiB3ZSBjYW4ndCBkZXRlcm1pbmUgY29udGVudC1ib3ggc2Nyb2xsIGd1dHRlclxuXHRcdC8vIFVzZSBhbiBleHBsaWNpdCB6ZXJvIHRvIGF2b2lkIE5hTiAoZ2gtMzk2NClcblx0XHQpICkgfHwgMDtcblx0fVxuXG5cdHJldHVybiBkZWx0YTtcbn1cblxuZnVuY3Rpb24gZ2V0V2lkdGhPckhlaWdodCggZWxlbSwgZGltZW5zaW9uLCBleHRyYSApIHtcblxuXHQvLyBTdGFydCB3aXRoIGNvbXB1dGVkIHN0eWxlXG5cdHZhciBzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKSxcblxuXHRcdC8vIFRvIGF2b2lkIGZvcmNpbmcgYSByZWZsb3csIG9ubHkgZmV0Y2ggYm94U2l6aW5nIGlmIHdlIG5lZWQgaXQgKGdoLTQzMjIpLlxuXHRcdC8vIEZha2UgY29udGVudC1ib3ggdW50aWwgd2Uga25vdyBpdCdzIG5lZWRlZCB0byBrbm93IHRoZSB0cnVlIHZhbHVlLlxuXHRcdGJveFNpemluZ05lZWRlZCA9ICFzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgfHwgZXh0cmEsXG5cdFx0aXNCb3JkZXJCb3ggPSBib3hTaXppbmdOZWVkZWQgJiZcblx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCIsXG5cdFx0dmFsdWVJc0JvcmRlckJveCA9IGlzQm9yZGVyQm94LFxuXG5cdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBkaW1lbnNpb24sIHN0eWxlcyApLFxuXHRcdG9mZnNldFByb3AgPSBcIm9mZnNldFwiICsgZGltZW5zaW9uWyAwIF0udG9VcHBlckNhc2UoKSArIGRpbWVuc2lvbi5zbGljZSggMSApO1xuXG5cdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD01NFxuXHQvLyBSZXR1cm4gYSBjb25mb3VuZGluZyBub24tcGl4ZWwgdmFsdWUgb3IgZmVpZ24gaWdub3JhbmNlLCBhcyBhcHByb3ByaWF0ZS5cblx0aWYgKCBybnVtbm9ucHgudGVzdCggdmFsICkgKSB7XG5cdFx0aWYgKCAhZXh0cmEgKSB7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblx0XHR2YWwgPSBcImF1dG9cIjtcblx0fVxuXG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExIG9ubHlcblx0Ly8gVXNlIG9mZnNldFdpZHRoL29mZnNldEhlaWdodCBmb3Igd2hlbiBib3ggc2l6aW5nIGlzIHVucmVsaWFibGUuXG5cdC8vIEluIHRob3NlIGNhc2VzLCB0aGUgY29tcHV0ZWQgdmFsdWUgY2FuIGJlIHRydXN0ZWQgdG8gYmUgYm9yZGVyLWJveC5cblx0aWYgKCAoICFzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgJiYgaXNCb3JkZXJCb3ggfHxcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDEwIC0gMTErLCBFZGdlIDE1IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBtaXNyZXBvcnQgYGdldENvbXB1dGVkU3R5bGVgIG9mIHRhYmxlIHJvd3Mgd2l0aCB3aWR0aC9oZWlnaHRcblx0XHQvLyBzZXQgaW4gQ1NTIHdoaWxlIGBvZmZzZXQqYCBwcm9wZXJ0aWVzIHJlcG9ydCBjb3JyZWN0IHZhbHVlcy5cblx0XHQvLyBJbnRlcmVzdGluZ2x5LCBpbiBzb21lIGNhc2VzIElFIDkgZG9lc24ndCBzdWZmZXIgZnJvbSB0aGlzIGlzc3VlLlxuXHRcdCFzdXBwb3J0LnJlbGlhYmxlVHJEaW1lbnNpb25zKCkgJiYgbm9kZU5hbWUoIGVsZW0sIFwidHJcIiApIHx8XG5cblx0XHQvLyBGYWxsIGJhY2sgdG8gb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IHdoZW4gdmFsdWUgaXMgXCJhdXRvXCJcblx0XHQvLyBUaGlzIGhhcHBlbnMgZm9yIGlubGluZSBlbGVtZW50cyB3aXRoIG5vIGV4cGxpY2l0IHNldHRpbmcgKGdoLTM1NzEpXG5cdFx0dmFsID09PSBcImF1dG9cIiB8fFxuXG5cdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMSAtIDQuMyBvbmx5XG5cdFx0Ly8gQWxzbyB1c2Ugb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IGZvciBtaXNyZXBvcnRlZCBpbmxpbmUgZGltZW5zaW9ucyAoZ2gtMzYwMilcblx0XHQhcGFyc2VGbG9hdCggdmFsICkgJiYgalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJpbmxpbmVcIiApICYmXG5cblx0XHQvLyBNYWtlIHN1cmUgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSAmIGNvbm5lY3RlZFxuXHRcdGVsZW0uZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggKSB7XG5cblx0XHRpc0JvcmRlckJveCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCI7XG5cblx0XHQvLyBXaGVyZSBhdmFpbGFibGUsIG9mZnNldFdpZHRoL29mZnNldEhlaWdodCBhcHByb3hpbWF0ZSBib3JkZXIgYm94IGRpbWVuc2lvbnMuXG5cdFx0Ly8gV2hlcmUgbm90IGF2YWlsYWJsZSAoZS5nLiwgU1ZHKSwgYXNzdW1lIHVucmVsaWFibGUgYm94LXNpemluZyBhbmQgaW50ZXJwcmV0IHRoZVxuXHRcdC8vIHJldHJpZXZlZCB2YWx1ZSBhcyBhIGNvbnRlbnQgYm94IGRpbWVuc2lvbi5cblx0XHR2YWx1ZUlzQm9yZGVyQm94ID0gb2Zmc2V0UHJvcCBpbiBlbGVtO1xuXHRcdGlmICggdmFsdWVJc0JvcmRlckJveCApIHtcblx0XHRcdHZhbCA9IGVsZW1bIG9mZnNldFByb3AgXTtcblx0XHR9XG5cdH1cblxuXHQvLyBOb3JtYWxpemUgXCJcIiBhbmQgYXV0b1xuXHR2YWwgPSBwYXJzZUZsb2F0KCB2YWwgKSB8fCAwO1xuXG5cdC8vIEFkanVzdCBmb3IgdGhlIGVsZW1lbnQncyBib3ggbW9kZWxcblx0cmV0dXJuICggdmFsICtcblx0XHRib3hNb2RlbEFkanVzdG1lbnQoXG5cdFx0XHRlbGVtLFxuXHRcdFx0ZGltZW5zaW9uLFxuXHRcdFx0ZXh0cmEgfHwgKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApLFxuXHRcdFx0dmFsdWVJc0JvcmRlckJveCxcblx0XHRcdHN0eWxlcyxcblxuXHRcdFx0Ly8gUHJvdmlkZSB0aGUgY3VycmVudCBjb21wdXRlZCBzaXplIHRvIHJlcXVlc3Qgc2Nyb2xsIGd1dHRlciBjYWxjdWxhdGlvbiAoZ2gtMzU4OSlcblx0XHRcdHZhbFxuXHRcdClcblx0KSArIFwicHhcIjtcbn1cblxualF1ZXJ5LmV4dGVuZCgge1xuXG5cdC8vIEFkZCBpbiBzdHlsZSBwcm9wZXJ0eSBob29rcyBmb3Igb3ZlcnJpZGluZyB0aGUgZGVmYXVsdFxuXHQvLyBiZWhhdmlvciBvZiBnZXR0aW5nIGFuZCBzZXR0aW5nIGEgc3R5bGUgcHJvcGVydHlcblx0Y3NzSG9va3M6IHtcblx0XHRvcGFjaXR5OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblxuXHRcdFx0XHRcdC8vIFdlIHNob3VsZCBhbHdheXMgZ2V0IGEgbnVtYmVyIGJhY2sgZnJvbSBvcGFjaXR5XG5cdFx0XHRcdFx0dmFyIHJldCA9IGN1ckNTUyggZWxlbSwgXCJvcGFjaXR5XCIgKTtcblx0XHRcdFx0XHRyZXR1cm4gcmV0ID09PSBcIlwiID8gXCIxXCIgOiByZXQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0Ly8gRG9uJ3QgYXV0b21hdGljYWxseSBhZGQgXCJweFwiIHRvIHRoZXNlIHBvc3NpYmx5LXVuaXRsZXNzIHByb3BlcnRpZXNcblx0Y3NzTnVtYmVyOiB7XG5cdFx0XCJhbmltYXRpb25JdGVyYXRpb25Db3VudFwiOiB0cnVlLFxuXHRcdFwiY29sdW1uQ291bnRcIjogdHJ1ZSxcblx0XHRcImZpbGxPcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJmbGV4R3Jvd1wiOiB0cnVlLFxuXHRcdFwiZmxleFNocmlua1wiOiB0cnVlLFxuXHRcdFwiZm9udFdlaWdodFwiOiB0cnVlLFxuXHRcdFwiZ3JpZEFyZWFcIjogdHJ1ZSxcblx0XHRcImdyaWRDb2x1bW5cIjogdHJ1ZSxcblx0XHRcImdyaWRDb2x1bW5FbmRcIjogdHJ1ZSxcblx0XHRcImdyaWRDb2x1bW5TdGFydFwiOiB0cnVlLFxuXHRcdFwiZ3JpZFJvd1wiOiB0cnVlLFxuXHRcdFwiZ3JpZFJvd0VuZFwiOiB0cnVlLFxuXHRcdFwiZ3JpZFJvd1N0YXJ0XCI6IHRydWUsXG5cdFx0XCJsaW5lSGVpZ2h0XCI6IHRydWUsXG5cdFx0XCJvcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJvcmRlclwiOiB0cnVlLFxuXHRcdFwib3JwaGFuc1wiOiB0cnVlLFxuXHRcdFwid2lkb3dzXCI6IHRydWUsXG5cdFx0XCJ6SW5kZXhcIjogdHJ1ZSxcblx0XHRcInpvb21cIjogdHJ1ZVxuXHR9LFxuXG5cdC8vIEFkZCBpbiBwcm9wZXJ0aWVzIHdob3NlIG5hbWVzIHlvdSB3aXNoIHRvIGZpeCBiZWZvcmVcblx0Ly8gc2V0dGluZyBvciBnZXR0aW5nIHRoZSB2YWx1ZVxuXHRjc3NQcm9wczoge30sXG5cblx0Ly8gR2V0IGFuZCBzZXQgdGhlIHN0eWxlIHByb3BlcnR5IG9uIGEgRE9NIE5vZGVcblx0c3R5bGU6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSwgZXh0cmEgKSB7XG5cblx0XHQvLyBEb24ndCBzZXQgc3R5bGVzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCB8fCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWVcblx0XHR2YXIgcmV0LCB0eXBlLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0gY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICksXG5cdFx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWUuIFdlIGRvbid0XG5cdFx0Ly8gd2FudCB0byBxdWVyeSB0aGUgdmFsdWUgaWYgaXQgaXMgYSBDU1MgY3VzdG9tIHByb3BlcnR5XG5cdFx0Ly8gc2luY2UgdGhleSBhcmUgdXNlci1kZWZpbmVkLlxuXHRcdGlmICggIWlzQ3VzdG9tUHJvcCApIHtcblx0XHRcdG5hbWUgPSBmaW5hbFByb3BOYW1lKCBvcmlnTmFtZSApO1xuXHRcdH1cblxuXHRcdC8vIEdldHMgaG9vayBmb3IgdGhlIHByZWZpeGVkIHZlcnNpb24sIHRoZW4gdW5wcmVmaXhlZCB2ZXJzaW9uXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBDaGVjayBpZiB3ZSdyZSBzZXR0aW5nIGEgdmFsdWVcblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR0eXBlID0gdHlwZW9mIHZhbHVlO1xuXG5cdFx0XHQvLyBDb252ZXJ0IFwiKz1cIiBvciBcIi09XCIgdG8gcmVsYXRpdmUgbnVtYmVycyAoIzczNDUpXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwic3RyaW5nXCIgJiYgKCByZXQgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICkgKSAmJiByZXRbIDEgXSApIHtcblx0XHRcdFx0dmFsdWUgPSBhZGp1c3RDU1MoIGVsZW0sIG5hbWUsIHJldCApO1xuXG5cdFx0XHRcdC8vIEZpeGVzIGJ1ZyAjOTIzN1xuXHRcdFx0XHR0eXBlID0gXCJudW1iZXJcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgbnVsbCBhbmQgTmFOIHZhbHVlcyBhcmVuJ3Qgc2V0ICgjNzExNilcblx0XHRcdGlmICggdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBudW1iZXIgd2FzIHBhc3NlZCBpbiwgYWRkIHRoZSB1bml0IChleGNlcHQgZm9yIGNlcnRhaW4gQ1NTIHByb3BlcnRpZXMpXG5cdFx0XHQvLyBUaGUgaXNDdXN0b21Qcm9wIGNoZWNrIGNhbiBiZSByZW1vdmVkIGluIGpRdWVyeSA0LjAgd2hlbiB3ZSBvbmx5IGF1dG8tYXBwZW5kXG5cdFx0XHQvLyBcInB4XCIgdG8gYSBmZXcgaGFyZGNvZGVkIHZhbHVlcy5cblx0XHRcdGlmICggdHlwZSA9PT0gXCJudW1iZXJcIiAmJiAhaXNDdXN0b21Qcm9wICkge1xuXHRcdFx0XHR2YWx1ZSArPSByZXQgJiYgcmV0WyAzIF0gfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBvcmlnTmFtZSBdID8gXCJcIiA6IFwicHhcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBiYWNrZ3JvdW5kLSogcHJvcHMgYWZmZWN0IG9yaWdpbmFsIGNsb25lJ3MgdmFsdWVzXG5cdFx0XHRpZiAoICFzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSAmJiB2YWx1ZSA9PT0gXCJcIiAmJiBuYW1lLmluZGV4T2YoIFwiYmFja2dyb3VuZFwiICkgPT09IDAgKSB7XG5cdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSBcImluaGVyaXRcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCwgdXNlIHRoYXQgdmFsdWUsIG90aGVyd2lzZSBqdXN0IHNldCB0aGUgc3BlY2lmaWVkIHZhbHVlXG5cdFx0XHRpZiAoICFob29rcyB8fCAhKCBcInNldFwiIGluIGhvb2tzICkgfHxcblx0XHRcdFx0KCB2YWx1ZSA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIGV4dHJhICkgKSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGlmICggaXNDdXN0b21Qcm9wICkge1xuXHRcdFx0XHRcdHN0eWxlLnNldFByb3BlcnR5KCBuYW1lLCB2YWx1ZSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCBnZXQgdGhlIG5vbi1jb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXG5cdFx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiZcblx0XHRcdFx0KCByZXQgPSBob29rcy5nZXQoIGVsZW0sIGZhbHNlLCBleHRyYSApICkgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdGhlcndpc2UganVzdCBnZXQgdGhlIHZhbHVlIGZyb20gdGhlIHN0eWxlIG9iamVjdFxuXHRcdFx0cmV0dXJuIHN0eWxlWyBuYW1lIF07XG5cdFx0fVxuXHR9LFxuXG5cdGNzczogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGV4dHJhLCBzdHlsZXMgKSB7XG5cdFx0dmFyIHZhbCwgbnVtLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0gY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICk7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWUuIFdlIGRvbid0XG5cdFx0Ly8gd2FudCB0byBtb2RpZnkgdGhlIHZhbHVlIGlmIGl0IGlzIGEgQ1NTIGN1c3RvbSBwcm9wZXJ0eVxuXHRcdC8vIHNpbmNlIHRoZXkgYXJlIHVzZXItZGVmaW5lZC5cblx0XHRpZiAoICFpc0N1c3RvbVByb3AgKSB7XG5cdFx0XHRuYW1lID0gZmluYWxQcm9wTmFtZSggb3JpZ05hbWUgKTtcblx0XHR9XG5cblx0XHQvLyBUcnkgcHJlZml4ZWQgbmFtZSBmb2xsb3dlZCBieSB0aGUgdW5wcmVmaXhlZCBuYW1lXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZVxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbCA9IGhvb2tzLmdldCggZWxlbSwgdHJ1ZSwgZXh0cmEgKTtcblx0XHR9XG5cblx0XHQvLyBPdGhlcndpc2UsIGlmIGEgd2F5IHRvIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZXhpc3RzLCB1c2UgdGhhdFxuXHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR2YWwgPSBjdXJDU1MoIGVsZW0sIG5hbWUsIHN0eWxlcyApO1xuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgXCJub3JtYWxcIiB0byBjb21wdXRlZCB2YWx1ZVxuXHRcdGlmICggdmFsID09PSBcIm5vcm1hbFwiICYmIG5hbWUgaW4gY3NzTm9ybWFsVHJhbnNmb3JtICkge1xuXHRcdFx0dmFsID0gY3NzTm9ybWFsVHJhbnNmb3JtWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBudW1lcmljIGlmIGZvcmNlZCBvciBhIHF1YWxpZmllciB3YXMgcHJvdmlkZWQgYW5kIHZhbCBsb29rcyBudW1lcmljXG5cdFx0aWYgKCBleHRyYSA9PT0gXCJcIiB8fCBleHRyYSApIHtcblx0XHRcdG51bSA9IHBhcnNlRmxvYXQoIHZhbCApO1xuXHRcdFx0cmV0dXJuIGV4dHJhID09PSB0cnVlIHx8IGlzRmluaXRlKCBudW0gKSA/IG51bSB8fCAwIDogdmFsO1xuXHRcdH1cblxuXHRcdHJldHVybiB2YWw7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIFsgXCJoZWlnaHRcIiwgXCJ3aWR0aFwiIF0sIGZ1bmN0aW9uKCBfaSwgZGltZW5zaW9uICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIGRpbWVuc2lvbiBdID0ge1xuXHRcdGdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkLCBleHRyYSApIHtcblx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cblx0XHRcdFx0Ly8gQ2VydGFpbiBlbGVtZW50cyBjYW4gaGF2ZSBkaW1lbnNpb24gaW5mbyBpZiB3ZSBpbnZpc2libHkgc2hvdyB0aGVtXG5cdFx0XHRcdC8vIGJ1dCBpdCBtdXN0IGhhdmUgYSBjdXJyZW50IGRpc3BsYXkgc3R5bGUgdGhhdCB3b3VsZCBiZW5lZml0XG5cdFx0XHRcdHJldHVybiByZGlzcGxheXN3YXAudGVzdCggalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSApICYmXG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgOCtcblx0XHRcdFx0XHQvLyBUYWJsZSBjb2x1bW5zIGluIFNhZmFyaSBoYXZlIG5vbi16ZXJvIG9mZnNldFdpZHRoICYgemVyb1xuXHRcdFx0XHRcdC8vIGdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoIHVubGVzcyBkaXNwbGF5IGlzIGNoYW5nZWQuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdFx0XHRcdFx0Ly8gUnVubmluZyBnZXRCb3VuZGluZ0NsaWVudFJlY3Qgb24gYSBkaXNjb25uZWN0ZWQgbm9kZVxuXHRcdFx0XHRcdC8vIGluIElFIHRocm93cyBhbiBlcnJvci5cblx0XHRcdFx0XHQoICFlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoIHx8ICFlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoICkgP1xuXHRcdFx0XHRcdFx0c3dhcCggZWxlbSwgY3NzU2hvdywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBkaW1lbnNpb24sIGV4dHJhICk7XG5cdFx0XHRcdFx0XHR9ICkgOlxuXHRcdFx0XHRcdFx0Z2V0V2lkdGhPckhlaWdodCggZWxlbSwgZGltZW5zaW9uLCBleHRyYSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSB7XG5cdFx0XHR2YXIgbWF0Y2hlcyxcblx0XHRcdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICksXG5cblx0XHRcdFx0Ly8gT25seSByZWFkIHN0eWxlcy5wb3NpdGlvbiBpZiB0aGUgdGVzdCBoYXMgYSBjaGFuY2UgdG8gZmFpbFxuXHRcdFx0XHQvLyB0byBhdm9pZCBmb3JjaW5nIGEgcmVmbG93LlxuXHRcdFx0XHRzY3JvbGxib3hTaXplQnVnZ3kgPSAhc3VwcG9ydC5zY3JvbGxib3hTaXplKCkgJiZcblx0XHRcdFx0XHRzdHlsZXMucG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIixcblxuXHRcdFx0XHQvLyBUbyBhdm9pZCBmb3JjaW5nIGEgcmVmbG93LCBvbmx5IGZldGNoIGJveFNpemluZyBpZiB3ZSBuZWVkIGl0IChnaC0zOTkxKVxuXHRcdFx0XHRib3hTaXppbmdOZWVkZWQgPSBzY3JvbGxib3hTaXplQnVnZ3kgfHwgZXh0cmEsXG5cdFx0XHRcdGlzQm9yZGVyQm94ID0gYm94U2l6aW5nTmVlZGVkICYmXG5cdFx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIixcblx0XHRcdFx0c3VidHJhY3QgPSBleHRyYSA/XG5cdFx0XHRcdFx0Ym94TW9kZWxBZGp1c3RtZW50KFxuXHRcdFx0XHRcdFx0ZWxlbSxcblx0XHRcdFx0XHRcdGRpbWVuc2lvbixcblx0XHRcdFx0XHRcdGV4dHJhLFxuXHRcdFx0XHRcdFx0aXNCb3JkZXJCb3gsXG5cdFx0XHRcdFx0XHRzdHlsZXNcblx0XHRcdFx0XHQpIDpcblx0XHRcdFx0XHQwO1xuXG5cdFx0XHQvLyBBY2NvdW50IGZvciB1bnJlbGlhYmxlIGJvcmRlci1ib3ggZGltZW5zaW9ucyBieSBjb21wYXJpbmcgb2Zmc2V0KiB0byBjb21wdXRlZCBhbmRcblx0XHRcdC8vIGZha2luZyBhIGNvbnRlbnQtYm94IHRvIGdldCBib3JkZXIgYW5kIHBhZGRpbmcgKGdoLTM2OTkpXG5cdFx0XHRpZiAoIGlzQm9yZGVyQm94ICYmIHNjcm9sbGJveFNpemVCdWdneSApIHtcblx0XHRcdFx0c3VidHJhY3QgLT0gTWF0aC5jZWlsKFxuXHRcdFx0XHRcdGVsZW1bIFwib2Zmc2V0XCIgKyBkaW1lbnNpb25bIDAgXS50b1VwcGVyQ2FzZSgpICsgZGltZW5zaW9uLnNsaWNlKCAxICkgXSAtXG5cdFx0XHRcdFx0cGFyc2VGbG9hdCggc3R5bGVzWyBkaW1lbnNpb24gXSApIC1cblx0XHRcdFx0XHRib3hNb2RlbEFkanVzdG1lbnQoIGVsZW0sIGRpbWVuc2lvbiwgXCJib3JkZXJcIiwgZmFsc2UsIHN0eWxlcyApIC1cblx0XHRcdFx0XHQwLjVcblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udmVydCB0byBwaXhlbHMgaWYgdmFsdWUgYWRqdXN0bWVudCBpcyBuZWVkZWRcblx0XHRcdGlmICggc3VidHJhY3QgJiYgKCBtYXRjaGVzID0gcmNzc051bS5leGVjKCB2YWx1ZSApICkgJiZcblx0XHRcdFx0KCBtYXRjaGVzWyAzIF0gfHwgXCJweFwiICkgIT09IFwicHhcIiApIHtcblxuXHRcdFx0XHRlbGVtLnN0eWxlWyBkaW1lbnNpb24gXSA9IHZhbHVlO1xuXHRcdFx0XHR2YWx1ZSA9IGpRdWVyeS5jc3MoIGVsZW0sIGRpbWVuc2lvbiApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBzdWJ0cmFjdCApO1xuXHRcdH1cblx0fTtcbn0gKTtcblxualF1ZXJ5LmNzc0hvb2tzLm1hcmdpbkxlZnQgPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucmVsaWFibGVNYXJnaW5MZWZ0LFxuXHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdHJldHVybiAoIHBhcnNlRmxvYXQoIGN1ckNTUyggZWxlbSwgXCJtYXJnaW5MZWZ0XCIgKSApIHx8XG5cdFx0XHRcdGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCAtXG5cdFx0XHRcdFx0c3dhcCggZWxlbSwgeyBtYXJnaW5MZWZ0OiAwIH0sIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdDtcblx0XHRcdFx0XHR9IClcblx0XHRcdFx0KSArIFwicHhcIjtcblx0XHR9XG5cdH1cbik7XG5cbi8vIFRoZXNlIGhvb2tzIGFyZSB1c2VkIGJ5IGFuaW1hdGUgdG8gZXhwYW5kIHByb3BlcnRpZXNcbmpRdWVyeS5lYWNoKCB7XG5cdG1hcmdpbjogXCJcIixcblx0cGFkZGluZzogXCJcIixcblx0Ym9yZGVyOiBcIldpZHRoXCJcbn0sIGZ1bmN0aW9uKCBwcmVmaXgsIHN1ZmZpeCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXSA9IHtcblx0XHRleHBhbmQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBpID0gMCxcblx0XHRcdFx0ZXhwYW5kZWQgPSB7fSxcblxuXHRcdFx0XHQvLyBBc3N1bWVzIGEgc2luZ2xlIG51bWJlciBpZiBub3QgYSBzdHJpbmdcblx0XHRcdFx0cGFydHMgPSB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZS5zcGxpdCggXCIgXCIgKSA6IFsgdmFsdWUgXTtcblxuXHRcdFx0Zm9yICggOyBpIDwgNDsgaSsrICkge1xuXHRcdFx0XHRleHBhbmRlZFsgcHJlZml4ICsgY3NzRXhwYW5kWyBpIF0gKyBzdWZmaXggXSA9XG5cdFx0XHRcdFx0cGFydHNbIGkgXSB8fCBwYXJ0c1sgaSAtIDIgXSB8fCBwYXJ0c1sgMCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXhwYW5kZWQ7XG5cdFx0fVxuXHR9O1xuXG5cdGlmICggcHJlZml4ICE9PSBcIm1hcmdpblwiICkge1xuXHRcdGpRdWVyeS5jc3NIb29rc1sgcHJlZml4ICsgc3VmZml4IF0uc2V0ID0gc2V0UG9zaXRpdmVOdW1iZXI7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRjc3M6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgc3R5bGVzLCBsZW4sXG5cdFx0XHRcdG1hcCA9IHt9LFxuXHRcdFx0XHRpID0gMDtcblxuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCBuYW1lICkgKSB7XG5cdFx0XHRcdHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApO1xuXHRcdFx0XHRsZW4gPSBuYW1lLmxlbmd0aDtcblxuXHRcdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRtYXBbIG5hbWVbIGkgXSBdID0galF1ZXJ5LmNzcyggZWxlbSwgbmFtZVsgaSBdLCBmYWxzZSwgc3R5bGVzICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gbWFwO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSwgdmFsdWUgKSA6XG5cdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIG5hbWUgKTtcblx0XHR9LCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fVxufSApO1xuXG5cbmZ1bmN0aW9uIFR3ZWVuKCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApIHtcblx0cmV0dXJuIG5ldyBUd2Vlbi5wcm90b3R5cGUuaW5pdCggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcgKTtcbn1cbmpRdWVyeS5Ud2VlbiA9IFR3ZWVuO1xuXG5Ud2Vlbi5wcm90b3R5cGUgPSB7XG5cdGNvbnN0cnVjdG9yOiBUd2Vlbixcblx0aW5pdDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nLCB1bml0ICkge1xuXHRcdHRoaXMuZWxlbSA9IGVsZW07XG5cdFx0dGhpcy5wcm9wID0gcHJvcDtcblx0XHR0aGlzLmVhc2luZyA9IGVhc2luZyB8fCBqUXVlcnkuZWFzaW5nLl9kZWZhdWx0O1xuXHRcdHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cdFx0dGhpcy5zdGFydCA9IHRoaXMubm93ID0gdGhpcy5jdXIoKTtcblx0XHR0aGlzLmVuZCA9IGVuZDtcblx0XHR0aGlzLnVuaXQgPSB1bml0IHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApO1xuXHR9LFxuXHRjdXI6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBob29rcyA9IFR3ZWVuLnByb3BIb29rc1sgdGhpcy5wcm9wIF07XG5cblx0XHRyZXR1cm4gaG9va3MgJiYgaG9va3MuZ2V0ID9cblx0XHRcdGhvb2tzLmdldCggdGhpcyApIDpcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5nZXQoIHRoaXMgKTtcblx0fSxcblx0cnVuOiBmdW5jdGlvbiggcGVyY2VudCApIHtcblx0XHR2YXIgZWFzZWQsXG5cdFx0XHRob29rcyA9IFR3ZWVuLnByb3BIb29rc1sgdGhpcy5wcm9wIF07XG5cblx0XHRpZiAoIHRoaXMub3B0aW9ucy5kdXJhdGlvbiApIHtcblx0XHRcdHRoaXMucG9zID0gZWFzZWQgPSBqUXVlcnkuZWFzaW5nWyB0aGlzLmVhc2luZyBdKFxuXHRcdFx0XHRwZXJjZW50LCB0aGlzLm9wdGlvbnMuZHVyYXRpb24gKiBwZXJjZW50LCAwLCAxLCB0aGlzLm9wdGlvbnMuZHVyYXRpb25cblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMucG9zID0gZWFzZWQgPSBwZXJjZW50O1xuXHRcdH1cblx0XHR0aGlzLm5vdyA9ICggdGhpcy5lbmQgLSB0aGlzLnN0YXJ0ICkgKiBlYXNlZCArIHRoaXMuc3RhcnQ7XG5cblx0XHRpZiAoIHRoaXMub3B0aW9ucy5zdGVwICkge1xuXHRcdFx0dGhpcy5vcHRpb25zLnN0ZXAuY2FsbCggdGhpcy5lbGVtLCB0aGlzLm5vdywgdGhpcyApO1xuXHRcdH1cblxuXHRcdGlmICggaG9va3MgJiYgaG9va3Muc2V0ICkge1xuXHRcdFx0aG9va3Muc2V0KCB0aGlzICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5zZXQoIHRoaXMgKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cbn07XG5cblR3ZWVuLnByb3RvdHlwZS5pbml0LnByb3RvdHlwZSA9IFR3ZWVuLnByb3RvdHlwZTtcblxuVHdlZW4ucHJvcEhvb2tzID0ge1xuXHRfZGVmYXVsdDoge1xuXHRcdGdldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdFx0dmFyIHJlc3VsdDtcblxuXHRcdFx0Ly8gVXNlIGEgcHJvcGVydHkgb24gdGhlIGVsZW1lbnQgZGlyZWN0bHkgd2hlbiBpdCBpcyBub3QgYSBET00gZWxlbWVudCxcblx0XHRcdC8vIG9yIHdoZW4gdGhlcmUgaXMgbm8gbWF0Y2hpbmcgc3R5bGUgcHJvcGVydHkgdGhhdCBleGlzdHMuXG5cdFx0XHRpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgIT09IDEgfHxcblx0XHRcdFx0dHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdICE9IG51bGwgJiYgdHdlZW4uZWxlbS5zdHlsZVsgdHdlZW4ucHJvcCBdID09IG51bGwgKSB7XG5cdFx0XHRcdHJldHVybiB0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF07XG5cdFx0XHR9XG5cblx0XHRcdC8vIFBhc3NpbmcgYW4gZW1wdHkgc3RyaW5nIGFzIGEgM3JkIHBhcmFtZXRlciB0byAuY3NzIHdpbGwgYXV0b21hdGljYWxseVxuXHRcdFx0Ly8gYXR0ZW1wdCBhIHBhcnNlRmxvYXQgYW5kIGZhbGxiYWNrIHRvIGEgc3RyaW5nIGlmIHRoZSBwYXJzZSBmYWlscy5cblx0XHRcdC8vIFNpbXBsZSB2YWx1ZXMgc3VjaCBhcyBcIjEwcHhcIiBhcmUgcGFyc2VkIHRvIEZsb2F0O1xuXHRcdFx0Ly8gY29tcGxleCB2YWx1ZXMgc3VjaCBhcyBcInJvdGF0ZSgxcmFkKVwiIGFyZSByZXR1cm5lZCBhcy1pcy5cblx0XHRcdHJlc3VsdCA9IGpRdWVyeS5jc3MoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIFwiXCIgKTtcblxuXHRcdFx0Ly8gRW1wdHkgc3RyaW5ncywgbnVsbCwgdW5kZWZpbmVkIGFuZCBcImF1dG9cIiBhcmUgY29udmVydGVkIHRvIDAuXG5cdFx0XHRyZXR1cm4gIXJlc3VsdCB8fCByZXN1bHQgPT09IFwiYXV0b1wiID8gMCA6IHJlc3VsdDtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXG5cdFx0XHQvLyBVc2Ugc3RlcCBob29rIGZvciBiYWNrIGNvbXBhdC5cblx0XHRcdC8vIFVzZSBjc3NIb29rIGlmIGl0cyB0aGVyZS5cblx0XHRcdC8vIFVzZSAuc3R5bGUgaWYgYXZhaWxhYmxlIGFuZCB1c2UgcGxhaW4gcHJvcGVydGllcyB3aGVyZSBhdmFpbGFibGUuXG5cdFx0XHRpZiAoIGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0gKSB7XG5cdFx0XHRcdGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0oIHR3ZWVuICk7XG5cdFx0XHR9IGVsc2UgaWYgKCB0d2Vlbi5lbGVtLm5vZGVUeXBlID09PSAxICYmIChcblx0XHRcdFx0XHRqUXVlcnkuY3NzSG9va3NbIHR3ZWVuLnByb3AgXSB8fFxuXHRcdFx0XHRcdHR3ZWVuLmVsZW0uc3R5bGVbIGZpbmFsUHJvcE5hbWUoIHR3ZWVuLnByb3AgKSBdICE9IG51bGwgKSApIHtcblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCB0d2Vlbi5lbGVtLCB0d2Vlbi5wcm9wLCB0d2Vlbi5ub3cgKyB0d2Vlbi51bml0ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59O1xuXG4vLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuLy8gUGFuaWMgYmFzZWQgYXBwcm9hY2ggdG8gc2V0dGluZyB0aGluZ3Mgb24gZGlzY29ubmVjdGVkIG5vZGVzXG5Ud2Vlbi5wcm9wSG9va3Muc2Nyb2xsVG9wID0gVHdlZW4ucHJvcEhvb2tzLnNjcm9sbExlZnQgPSB7XG5cdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAmJiB0d2Vlbi5lbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0fVxuXHR9XG59O1xuXG5qUXVlcnkuZWFzaW5nID0ge1xuXHRsaW5lYXI6IGZ1bmN0aW9uKCBwICkge1xuXHRcdHJldHVybiBwO1xuXHR9LFxuXHRzd2luZzogZnVuY3Rpb24oIHAgKSB7XG5cdFx0cmV0dXJuIDAuNSAtIE1hdGguY29zKCBwICogTWF0aC5QSSApIC8gMjtcblx0fSxcblx0X2RlZmF1bHQ6IFwic3dpbmdcIlxufTtcblxualF1ZXJ5LmZ4ID0gVHdlZW4ucHJvdG90eXBlLmluaXQ7XG5cbi8vIEJhY2sgY29tcGF0IDwxLjggZXh0ZW5zaW9uIHBvaW50XG5qUXVlcnkuZnguc3RlcCA9IHt9O1xuXG5cblxuXG52YXJcblx0ZnhOb3csIGluUHJvZ3Jlc3MsXG5cdHJmeHR5cGVzID0gL14oPzp0b2dnbGV8c2hvd3xoaWRlKSQvLFxuXHRycnVuID0gL3F1ZXVlSG9va3MkLztcblxuZnVuY3Rpb24gc2NoZWR1bGUoKSB7XG5cdGlmICggaW5Qcm9ncmVzcyApIHtcblx0XHRpZiAoIGRvY3VtZW50LmhpZGRlbiA9PT0gZmFsc2UgJiYgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSApIHtcblx0XHRcdHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoIHNjaGVkdWxlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHdpbmRvdy5zZXRUaW1lb3V0KCBzY2hlZHVsZSwgalF1ZXJ5LmZ4LmludGVydmFsICk7XG5cdFx0fVxuXG5cdFx0alF1ZXJ5LmZ4LnRpY2soKTtcblx0fVxufVxuXG4vLyBBbmltYXRpb25zIGNyZWF0ZWQgc3luY2hyb25vdXNseSB3aWxsIHJ1biBzeW5jaHJvbm91c2x5XG5mdW5jdGlvbiBjcmVhdGVGeE5vdygpIHtcblx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdGZ4Tm93ID0gdW5kZWZpbmVkO1xuXHR9ICk7XG5cdHJldHVybiAoIGZ4Tm93ID0gRGF0ZS5ub3coKSApO1xufVxuXG4vLyBHZW5lcmF0ZSBwYXJhbWV0ZXJzIHRvIGNyZWF0ZSBhIHN0YW5kYXJkIGFuaW1hdGlvblxuZnVuY3Rpb24gZ2VuRngoIHR5cGUsIGluY2x1ZGVXaWR0aCApIHtcblx0dmFyIHdoaWNoLFxuXHRcdGkgPSAwLFxuXHRcdGF0dHJzID0geyBoZWlnaHQ6IHR5cGUgfTtcblxuXHQvLyBJZiB3ZSBpbmNsdWRlIHdpZHRoLCBzdGVwIHZhbHVlIGlzIDEgdG8gZG8gYWxsIGNzc0V4cGFuZCB2YWx1ZXMsXG5cdC8vIG90aGVyd2lzZSBzdGVwIHZhbHVlIGlzIDIgdG8gc2tpcCBvdmVyIExlZnQgYW5kIFJpZ2h0XG5cdGluY2x1ZGVXaWR0aCA9IGluY2x1ZGVXaWR0aCA/IDEgOiAwO1xuXHRmb3IgKCA7IGkgPCA0OyBpICs9IDIgLSBpbmNsdWRlV2lkdGggKSB7XG5cdFx0d2hpY2ggPSBjc3NFeHBhbmRbIGkgXTtcblx0XHRhdHRyc1sgXCJtYXJnaW5cIiArIHdoaWNoIF0gPSBhdHRyc1sgXCJwYWRkaW5nXCIgKyB3aGljaCBdID0gdHlwZTtcblx0fVxuXG5cdGlmICggaW5jbHVkZVdpZHRoICkge1xuXHRcdGF0dHJzLm9wYWNpdHkgPSBhdHRycy53aWR0aCA9IHR5cGU7XG5cdH1cblxuXHRyZXR1cm4gYXR0cnM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVR3ZWVuKCB2YWx1ZSwgcHJvcCwgYW5pbWF0aW9uICkge1xuXHR2YXIgdHdlZW4sXG5cdFx0Y29sbGVjdGlvbiA9ICggQW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gfHwgW10gKS5jb25jYXQoIEFuaW1hdGlvbi50d2VlbmVyc1sgXCIqXCIgXSApLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDtcblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRpZiAoICggdHdlZW4gPSBjb2xsZWN0aW9uWyBpbmRleCBdLmNhbGwoIGFuaW1hdGlvbiwgcHJvcCwgdmFsdWUgKSApICkge1xuXG5cdFx0XHQvLyBXZSdyZSBkb25lIHdpdGggdGhpcyBwcm9wZXJ0eVxuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBkZWZhdWx0UHJlZmlsdGVyKCBlbGVtLCBwcm9wcywgb3B0cyApIHtcblx0dmFyIHByb3AsIHZhbHVlLCB0b2dnbGUsIGhvb2tzLCBvbGRmaXJlLCBwcm9wVHdlZW4sIHJlc3RvcmVEaXNwbGF5LCBkaXNwbGF5LFxuXHRcdGlzQm94ID0gXCJ3aWR0aFwiIGluIHByb3BzIHx8IFwiaGVpZ2h0XCIgaW4gcHJvcHMsXG5cdFx0YW5pbSA9IHRoaXMsXG5cdFx0b3JpZyA9IHt9LFxuXHRcdHN0eWxlID0gZWxlbS5zdHlsZSxcblx0XHRoaWRkZW4gPSBlbGVtLm5vZGVUeXBlICYmIGlzSGlkZGVuV2l0aGluVHJlZSggZWxlbSApLFxuXHRcdGRhdGFTaG93ID0gZGF0YVByaXYuZ2V0KCBlbGVtLCBcImZ4c2hvd1wiICk7XG5cblx0Ly8gUXVldWUtc2tpcHBpbmcgYW5pbWF0aW9ucyBoaWphY2sgdGhlIGZ4IGhvb2tzXG5cdGlmICggIW9wdHMucXVldWUgKSB7XG5cdFx0aG9va3MgPSBqUXVlcnkuX3F1ZXVlSG9va3MoIGVsZW0sIFwiZnhcIiApO1xuXHRcdGlmICggaG9va3MudW5xdWV1ZWQgPT0gbnVsbCApIHtcblx0XHRcdGhvb2tzLnVucXVldWVkID0gMDtcblx0XHRcdG9sZGZpcmUgPSBob29rcy5lbXB0eS5maXJlO1xuXHRcdFx0aG9va3MuZW1wdHkuZmlyZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICFob29rcy51bnF1ZXVlZCApIHtcblx0XHRcdFx0XHRvbGRmaXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHRcdGhvb2tzLnVucXVldWVkKys7XG5cblx0XHRhbmltLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIEVuc3VyZSB0aGUgY29tcGxldGUgaGFuZGxlciBpcyBjYWxsZWQgYmVmb3JlIHRoaXMgY29tcGxldGVzXG5cdFx0XHRhbmltLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGhvb2tzLnVucXVldWVkLS07XG5cdFx0XHRcdGlmICggIWpRdWVyeS5xdWV1ZSggZWxlbSwgXCJmeFwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIERldGVjdCBzaG93L2hpZGUgYW5pbWF0aW9uc1xuXHRmb3IgKCBwcm9wIGluIHByb3BzICkge1xuXHRcdHZhbHVlID0gcHJvcHNbIHByb3AgXTtcblx0XHRpZiAoIHJmeHR5cGVzLnRlc3QoIHZhbHVlICkgKSB7XG5cdFx0XHRkZWxldGUgcHJvcHNbIHByb3AgXTtcblx0XHRcdHRvZ2dsZSA9IHRvZ2dsZSB8fCB2YWx1ZSA9PT0gXCJ0b2dnbGVcIjtcblx0XHRcdGlmICggdmFsdWUgPT09ICggaGlkZGVuID8gXCJoaWRlXCIgOiBcInNob3dcIiApICkge1xuXG5cdFx0XHRcdC8vIFByZXRlbmQgdG8gYmUgaGlkZGVuIGlmIHRoaXMgaXMgYSBcInNob3dcIiBhbmRcblx0XHRcdFx0Ly8gdGhlcmUgaXMgc3RpbGwgZGF0YSBmcm9tIGEgc3RvcHBlZCBzaG93L2hpZGVcblx0XHRcdFx0aWYgKCB2YWx1ZSA9PT0gXCJzaG93XCIgJiYgZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdGhpZGRlbiA9IHRydWU7XG5cblx0XHRcdFx0Ly8gSWdub3JlIGFsbCBvdGhlciBuby1vcCBzaG93L2hpZGUgZGF0YVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRvcmlnWyBwcm9wIF0gPSBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdIHx8IGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCApO1xuXHRcdH1cblx0fVxuXG5cdC8vIEJhaWwgb3V0IGlmIHRoaXMgaXMgYSBuby1vcCBsaWtlIC5oaWRlKCkuaGlkZSgpXG5cdHByb3BUd2VlbiA9ICFqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcHMgKTtcblx0aWYgKCAhcHJvcFR3ZWVuICYmIGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBvcmlnICkgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gUmVzdHJpY3QgXCJvdmVyZmxvd1wiIGFuZCBcImRpc3BsYXlcIiBzdHlsZXMgZHVyaW5nIGJveCBhbmltYXRpb25zXG5cdGlmICggaXNCb3ggJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExLCBFZGdlIDEyIC0gMTVcblx0XHQvLyBSZWNvcmQgYWxsIDMgb3ZlcmZsb3cgYXR0cmlidXRlcyBiZWNhdXNlIElFIGRvZXMgbm90IGluZmVyIHRoZSBzaG9ydGhhbmRcblx0XHQvLyBmcm9tIGlkZW50aWNhbGx5LXZhbHVlZCBvdmVyZmxvd1ggYW5kIG92ZXJmbG93WSBhbmQgRWRnZSBqdXN0IG1pcnJvcnNcblx0XHQvLyB0aGUgb3ZlcmZsb3dYIHZhbHVlIHRoZXJlLlxuXHRcdG9wdHMub3ZlcmZsb3cgPSBbIHN0eWxlLm92ZXJmbG93LCBzdHlsZS5vdmVyZmxvd1gsIHN0eWxlLm92ZXJmbG93WSBdO1xuXG5cdFx0Ly8gSWRlbnRpZnkgYSBkaXNwbGF5IHR5cGUsIHByZWZlcnJpbmcgb2xkIHNob3cvaGlkZSBkYXRhIG92ZXIgdGhlIENTUyBjYXNjYWRlXG5cdFx0cmVzdG9yZURpc3BsYXkgPSBkYXRhU2hvdyAmJiBkYXRhU2hvdy5kaXNwbGF5O1xuXHRcdGlmICggcmVzdG9yZURpc3BsYXkgPT0gbnVsbCApIHtcblx0XHRcdHJlc3RvcmVEaXNwbGF5ID0gZGF0YVByaXYuZ2V0KCBlbGVtLCBcImRpc3BsYXlcIiApO1xuXHRcdH1cblx0XHRkaXNwbGF5ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKTtcblx0XHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdFx0aWYgKCByZXN0b3JlRGlzcGxheSApIHtcblx0XHRcdFx0ZGlzcGxheSA9IHJlc3RvcmVEaXNwbGF5O1xuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBHZXQgbm9uZW1wdHkgdmFsdWUocykgYnkgdGVtcG9yYXJpbHkgZm9yY2luZyB2aXNpYmlsaXR5XG5cdFx0XHRcdHNob3dIaWRlKCBbIGVsZW0gXSwgdHJ1ZSApO1xuXHRcdFx0XHRyZXN0b3JlRGlzcGxheSA9IGVsZW0uc3R5bGUuZGlzcGxheSB8fCByZXN0b3JlRGlzcGxheTtcblx0XHRcdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICk7XG5cdFx0XHRcdHNob3dIaWRlKCBbIGVsZW0gXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEFuaW1hdGUgaW5saW5lIGVsZW1lbnRzIGFzIGlubGluZS1ibG9ja1xuXHRcdGlmICggZGlzcGxheSA9PT0gXCJpbmxpbmVcIiB8fCBkaXNwbGF5ID09PSBcImlubGluZS1ibG9ja1wiICYmIHJlc3RvcmVEaXNwbGF5ICE9IG51bGwgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5jc3MoIGVsZW0sIFwiZmxvYXRcIiApID09PSBcIm5vbmVcIiApIHtcblxuXHRcdFx0XHQvLyBSZXN0b3JlIHRoZSBvcmlnaW5hbCBkaXNwbGF5IHZhbHVlIGF0IHRoZSBlbmQgb2YgcHVyZSBzaG93L2hpZGUgYW5pbWF0aW9uc1xuXHRcdFx0XHRpZiAoICFwcm9wVHdlZW4gKSB7XG5cdFx0XHRcdFx0YW5pbS5kb25lKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdHN0eWxlLmRpc3BsYXkgPSByZXN0b3JlRGlzcGxheTtcblx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0aWYgKCByZXN0b3JlRGlzcGxheSA9PSBudWxsICkge1xuXHRcdFx0XHRcdFx0ZGlzcGxheSA9IHN0eWxlLmRpc3BsYXk7XG5cdFx0XHRcdFx0XHRyZXN0b3JlRGlzcGxheSA9IGRpc3BsYXkgPT09IFwibm9uZVwiID8gXCJcIiA6IGRpc3BsYXk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmICggb3B0cy5vdmVyZmxvdyApIHtcblx0XHRzdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCI7XG5cdFx0YW5pbS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXHRcdFx0c3R5bGUub3ZlcmZsb3cgPSBvcHRzLm92ZXJmbG93WyAwIF07XG5cdFx0XHRzdHlsZS5vdmVyZmxvd1ggPSBvcHRzLm92ZXJmbG93WyAxIF07XG5cdFx0XHRzdHlsZS5vdmVyZmxvd1kgPSBvcHRzLm92ZXJmbG93WyAyIF07XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gSW1wbGVtZW50IHNob3cvaGlkZSBhbmltYXRpb25zXG5cdHByb3BUd2VlbiA9IGZhbHNlO1xuXHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XG5cblx0XHQvLyBHZW5lcmFsIHNob3cvaGlkZSBzZXR1cCBmb3IgdGhpcyBlbGVtZW50IGFuaW1hdGlvblxuXHRcdGlmICggIXByb3BUd2VlbiApIHtcblx0XHRcdGlmICggZGF0YVNob3cgKSB7XG5cdFx0XHRcdGlmICggXCJoaWRkZW5cIiBpbiBkYXRhU2hvdyApIHtcblx0XHRcdFx0XHRoaWRkZW4gPSBkYXRhU2hvdy5oaWRkZW47XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRhdGFTaG93ID0gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBcImZ4c2hvd1wiLCB7IGRpc3BsYXk6IHJlc3RvcmVEaXNwbGF5IH0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3RvcmUgaGlkZGVuL3Zpc2libGUgZm9yIHRvZ2dsZSBzbyBgLnN0b3AoKS50b2dnbGUoKWAgXCJyZXZlcnNlc1wiXG5cdFx0XHRpZiAoIHRvZ2dsZSApIHtcblx0XHRcdFx0ZGF0YVNob3cuaGlkZGVuID0gIWhpZGRlbjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2hvdyBlbGVtZW50cyBiZWZvcmUgYW5pbWF0aW5nIHRoZW1cblx0XHRcdGlmICggaGlkZGVuICkge1xuXHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0sIHRydWUgKTtcblx0XHRcdH1cblxuXHRcdFx0LyogZXNsaW50LWRpc2FibGUgbm8tbG9vcC1mdW5jICovXG5cblx0XHRcdGFuaW0uZG9uZSggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8qIGVzbGludC1lbmFibGUgbm8tbG9vcC1mdW5jICovXG5cblx0XHRcdFx0Ly8gVGhlIGZpbmFsIHN0ZXAgb2YgYSBcImhpZGVcIiBhbmltYXRpb24gaXMgYWN0dWFsbHkgaGlkaW5nIHRoZSBlbGVtZW50XG5cdFx0XHRcdGlmICggIWhpZGRlbiApIHtcblx0XHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFwiZnhzaG93XCIgKTtcblx0XHRcdFx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgb3JpZ1sgcHJvcCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHQvLyBQZXItcHJvcGVydHkgc2V0dXBcblx0XHRwcm9wVHdlZW4gPSBjcmVhdGVUd2VlbiggaGlkZGVuID8gZGF0YVNob3dbIHByb3AgXSA6IDAsIHByb3AsIGFuaW0gKTtcblx0XHRpZiAoICEoIHByb3AgaW4gZGF0YVNob3cgKSApIHtcblx0XHRcdGRhdGFTaG93WyBwcm9wIF0gPSBwcm9wVHdlZW4uc3RhcnQ7XG5cdFx0XHRpZiAoIGhpZGRlbiApIHtcblx0XHRcdFx0cHJvcFR3ZWVuLmVuZCA9IHByb3BUd2Vlbi5zdGFydDtcblx0XHRcdFx0cHJvcFR3ZWVuLnN0YXJ0ID0gMDtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gcHJvcEZpbHRlciggcHJvcHMsIHNwZWNpYWxFYXNpbmcgKSB7XG5cdHZhciBpbmRleCwgbmFtZSwgZWFzaW5nLCB2YWx1ZSwgaG9va3M7XG5cblx0Ly8gY2FtZWxDYXNlLCBzcGVjaWFsRWFzaW5nIGFuZCBleHBhbmQgY3NzSG9vayBwYXNzXG5cdGZvciAoIGluZGV4IGluIHByb3BzICkge1xuXHRcdG5hbWUgPSBjYW1lbENhc2UoIGluZGV4ICk7XG5cdFx0ZWFzaW5nID0gc3BlY2lhbEVhc2luZ1sgbmFtZSBdO1xuXHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF07XG5cdFx0aWYgKCBBcnJheS5pc0FycmF5KCB2YWx1ZSApICkge1xuXHRcdFx0ZWFzaW5nID0gdmFsdWVbIDEgXTtcblx0XHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgMCBdO1xuXHRcdH1cblxuXHRcdGlmICggaW5kZXggIT09IG5hbWUgKSB7XG5cdFx0XHRwcm9wc1sgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRkZWxldGUgcHJvcHNbIGluZGV4IF07XG5cdFx0fVxuXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXTtcblx0XHRpZiAoIGhvb2tzICYmIFwiZXhwYW5kXCIgaW4gaG9va3MgKSB7XG5cdFx0XHR2YWx1ZSA9IGhvb2tzLmV4cGFuZCggdmFsdWUgKTtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgbmFtZSBdO1xuXG5cdFx0XHQvLyBOb3QgcXVpdGUgJC5leHRlbmQsIHRoaXMgd29uJ3Qgb3ZlcndyaXRlIGV4aXN0aW5nIGtleXMuXG5cdFx0XHQvLyBSZXVzaW5nICdpbmRleCcgYmVjYXVzZSB3ZSBoYXZlIHRoZSBjb3JyZWN0IFwibmFtZVwiXG5cdFx0XHRmb3IgKCBpbmRleCBpbiB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhKCBpbmRleCBpbiBwcm9wcyApICkge1xuXHRcdFx0XHRcdHByb3BzWyBpbmRleCBdID0gdmFsdWVbIGluZGV4IF07XG5cdFx0XHRcdFx0c3BlY2lhbEVhc2luZ1sgaW5kZXggXSA9IGVhc2luZztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRzcGVjaWFsRWFzaW5nWyBuYW1lIF0gPSBlYXNpbmc7XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIEFuaW1hdGlvbiggZWxlbSwgcHJvcGVydGllcywgb3B0aW9ucyApIHtcblx0dmFyIHJlc3VsdCxcblx0XHRzdG9wcGVkLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBBbmltYXRpb24ucHJlZmlsdGVycy5sZW5ndGgsXG5cdFx0ZGVmZXJyZWQgPSBqUXVlcnkuRGVmZXJyZWQoKS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBEb24ndCBtYXRjaCBlbGVtIGluIHRoZSA6YW5pbWF0ZWQgc2VsZWN0b3Jcblx0XHRcdGRlbGV0ZSB0aWNrLmVsZW07XG5cdFx0fSApLFxuXHRcdHRpY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggc3RvcHBlZCApIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0dmFyIGN1cnJlbnRUaW1lID0gZnhOb3cgfHwgY3JlYXRlRnhOb3coKSxcblx0XHRcdFx0cmVtYWluaW5nID0gTWF0aC5tYXgoIDAsIGFuaW1hdGlvbi5zdGFydFRpbWUgKyBhbmltYXRpb24uZHVyYXRpb24gLSBjdXJyZW50VGltZSApLFxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zIG9ubHlcblx0XHRcdFx0Ly8gQXJjaGFpYyBjcmFzaCBidWcgd29uJ3QgYWxsb3cgdXMgdG8gdXNlIGAxIC0gKCAwLjUgfHwgMCApYCAoIzEyNDk3KVxuXHRcdFx0XHR0ZW1wID0gcmVtYWluaW5nIC8gYW5pbWF0aW9uLmR1cmF0aW9uIHx8IDAsXG5cdFx0XHRcdHBlcmNlbnQgPSAxIC0gdGVtcCxcblx0XHRcdFx0aW5kZXggPSAwLFxuXHRcdFx0XHRsZW5ndGggPSBhbmltYXRpb24udHdlZW5zLmxlbmd0aDtcblxuXHRcdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVuc1sgaW5kZXggXS5ydW4oIHBlcmNlbnQgKTtcblx0XHRcdH1cblxuXHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIHBlcmNlbnQsIHJlbWFpbmluZyBdICk7XG5cblx0XHRcdC8vIElmIHRoZXJlJ3MgbW9yZSB0byBkbywgeWllbGRcblx0XHRcdGlmICggcGVyY2VudCA8IDEgJiYgbGVuZ3RoICkge1xuXHRcdFx0XHRyZXR1cm4gcmVtYWluaW5nO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGlzIHdhcyBhbiBlbXB0eSBhbmltYXRpb24sIHN5bnRoZXNpemUgYSBmaW5hbCBwcm9ncmVzcyBub3RpZmljYXRpb25cblx0XHRcdGlmICggIWxlbmd0aCApIHtcblx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIDEsIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXNvbHZlIHRoZSBhbmltYXRpb24gYW5kIHJlcG9ydCBpdHMgY29uY2x1c2lvblxuXHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uIF0gKTtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdGFuaW1hdGlvbiA9IGRlZmVycmVkLnByb21pc2UoIHtcblx0XHRcdGVsZW06IGVsZW0sXG5cdFx0XHRwcm9wczogalF1ZXJ5LmV4dGVuZCgge30sIHByb3BlcnRpZXMgKSxcblx0XHRcdG9wdHM6IGpRdWVyeS5leHRlbmQoIHRydWUsIHtcblx0XHRcdFx0c3BlY2lhbEVhc2luZzoge30sXG5cdFx0XHRcdGVhc2luZzogalF1ZXJ5LmVhc2luZy5fZGVmYXVsdFxuXHRcdFx0fSwgb3B0aW9ucyApLFxuXHRcdFx0b3JpZ2luYWxQcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzLFxuXHRcdFx0b3JpZ2luYWxPcHRpb25zOiBvcHRpb25zLFxuXHRcdFx0c3RhcnRUaW1lOiBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLFxuXHRcdFx0ZHVyYXRpb246IG9wdGlvbnMuZHVyYXRpb24sXG5cdFx0XHR0d2VlbnM6IFtdLFxuXHRcdFx0Y3JlYXRlVHdlZW46IGZ1bmN0aW9uKCBwcm9wLCBlbmQgKSB7XG5cdFx0XHRcdHZhciB0d2VlbiA9IGpRdWVyeS5Ud2VlbiggZWxlbSwgYW5pbWF0aW9uLm9wdHMsIHByb3AsIGVuZCxcblx0XHRcdFx0XHRcdGFuaW1hdGlvbi5vcHRzLnNwZWNpYWxFYXNpbmdbIHByb3AgXSB8fCBhbmltYXRpb24ub3B0cy5lYXNpbmcgKTtcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVucy5wdXNoKCB0d2VlbiApO1xuXHRcdFx0XHRyZXR1cm4gdHdlZW47XG5cdFx0XHR9LFxuXHRcdFx0c3RvcDogZnVuY3Rpb24oIGdvdG9FbmQgKSB7XG5cdFx0XHRcdHZhciBpbmRleCA9IDAsXG5cblx0XHRcdFx0XHQvLyBJZiB3ZSBhcmUgZ29pbmcgdG8gdGhlIGVuZCwgd2Ugd2FudCB0byBydW4gYWxsIHRoZSB0d2VlbnNcblx0XHRcdFx0XHQvLyBvdGhlcndpc2Ugd2Ugc2tpcCB0aGlzIHBhcnRcblx0XHRcdFx0XHRsZW5ndGggPSBnb3RvRW5kID8gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGggOiAwO1xuXHRcdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdFx0c3RvcHBlZCA9IHRydWU7XG5cdFx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVuc1sgaW5kZXggXS5ydW4oIDEgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFJlc29sdmUgd2hlbiB3ZSBwbGF5ZWQgdGhlIGxhc3QgZnJhbWU7IG90aGVyd2lzZSwgcmVqZWN0XG5cdFx0XHRcdGlmICggZ290b0VuZCApIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7XG5cdFx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBnb3RvRW5kIF0gKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9XG5cdFx0fSApLFxuXHRcdHByb3BzID0gYW5pbWF0aW9uLnByb3BzO1xuXG5cdHByb3BGaWx0ZXIoIHByb3BzLCBhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nICk7XG5cblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRyZXN1bHQgPSBBbmltYXRpb24ucHJlZmlsdGVyc1sgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIGVsZW0sIHByb3BzLCBhbmltYXRpb24ub3B0cyApO1xuXHRcdGlmICggcmVzdWx0ICkge1xuXHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCByZXN1bHQuc3RvcCApICkge1xuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIGFuaW1hdGlvbi5lbGVtLCBhbmltYXRpb24ub3B0cy5xdWV1ZSApLnN0b3AgPVxuXHRcdFx0XHRcdHJlc3VsdC5zdG9wLmJpbmQoIHJlc3VsdCApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdH1cblxuXHRqUXVlcnkubWFwKCBwcm9wcywgY3JlYXRlVHdlZW4sIGFuaW1hdGlvbiApO1xuXG5cdGlmICggaXNGdW5jdGlvbiggYW5pbWF0aW9uLm9wdHMuc3RhcnQgKSApIHtcblx0XHRhbmltYXRpb24ub3B0cy5zdGFydC5jYWxsKCBlbGVtLCBhbmltYXRpb24gKTtcblx0fVxuXG5cdC8vIEF0dGFjaCBjYWxsYmFja3MgZnJvbSBvcHRpb25zXG5cdGFuaW1hdGlvblxuXHRcdC5wcm9ncmVzcyggYW5pbWF0aW9uLm9wdHMucHJvZ3Jlc3MgKVxuXHRcdC5kb25lKCBhbmltYXRpb24ub3B0cy5kb25lLCBhbmltYXRpb24ub3B0cy5jb21wbGV0ZSApXG5cdFx0LmZhaWwoIGFuaW1hdGlvbi5vcHRzLmZhaWwgKVxuXHRcdC5hbHdheXMoIGFuaW1hdGlvbi5vcHRzLmFsd2F5cyApO1xuXG5cdGpRdWVyeS5meC50aW1lcihcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aWNrLCB7XG5cdFx0XHRlbGVtOiBlbGVtLFxuXHRcdFx0YW5pbTogYW5pbWF0aW9uLFxuXHRcdFx0cXVldWU6IGFuaW1hdGlvbi5vcHRzLnF1ZXVlXG5cdFx0fSApXG5cdCk7XG5cblx0cmV0dXJuIGFuaW1hdGlvbjtcbn1cblxualF1ZXJ5LkFuaW1hdGlvbiA9IGpRdWVyeS5leHRlbmQoIEFuaW1hdGlvbiwge1xuXG5cdHR3ZWVuZXJzOiB7XG5cdFx0XCIqXCI6IFsgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkge1xuXHRcdFx0dmFyIHR3ZWVuID0gdGhpcy5jcmVhdGVUd2VlbiggcHJvcCwgdmFsdWUgKTtcblx0XHRcdGFkanVzdENTUyggdHdlZW4uZWxlbSwgcHJvcCwgcmNzc051bS5leGVjKCB2YWx1ZSApLCB0d2VlbiApO1xuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH0gXVxuXHR9LFxuXG5cdHR3ZWVuZXI6IGZ1bmN0aW9uKCBwcm9wcywgY2FsbGJhY2sgKSB7XG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBwcm9wcyApICkge1xuXHRcdFx0Y2FsbGJhY2sgPSBwcm9wcztcblx0XHRcdHByb3BzID0gWyBcIipcIiBdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcm9wcyA9IHByb3BzLm1hdGNoKCBybm90aHRtbHdoaXRlICk7XG5cdFx0fVxuXG5cdFx0dmFyIHByb3AsXG5cdFx0XHRpbmRleCA9IDAsXG5cdFx0XHRsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cblx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0cHJvcCA9IHByb3BzWyBpbmRleCBdO1xuXHRcdFx0QW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gPSBBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSB8fCBbXTtcblx0XHRcdEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9LFxuXG5cdHByZWZpbHRlcnM6IFsgZGVmYXVsdFByZWZpbHRlciBdLFxuXG5cdHByZWZpbHRlcjogZnVuY3Rpb24oIGNhbGxiYWNrLCBwcmVwZW5kICkge1xuXHRcdGlmICggcHJlcGVuZCApIHtcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnB1c2goIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9XG59ICk7XG5cbmpRdWVyeS5zcGVlZCA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBmbiApIHtcblx0dmFyIG9wdCA9IHNwZWVkICYmIHR5cGVvZiBzcGVlZCA9PT0gXCJvYmplY3RcIiA/IGpRdWVyeS5leHRlbmQoIHt9LCBzcGVlZCApIDoge1xuXHRcdGNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8XG5cdFx0XHRpc0Z1bmN0aW9uKCBzcGVlZCApICYmIHNwZWVkLFxuXHRcdGR1cmF0aW9uOiBzcGVlZCxcblx0XHRlYXNpbmc6IGZuICYmIGVhc2luZyB8fCBlYXNpbmcgJiYgIWlzRnVuY3Rpb24oIGVhc2luZyApICYmIGVhc2luZ1xuXHR9O1xuXG5cdC8vIEdvIHRvIHRoZSBlbmQgc3RhdGUgaWYgZnggYXJlIG9mZlxuXHRpZiAoIGpRdWVyeS5meC5vZmYgKSB7XG5cdFx0b3B0LmR1cmF0aW9uID0gMDtcblxuXHR9IGVsc2Uge1xuXHRcdGlmICggdHlwZW9mIG9wdC5kdXJhdGlvbiAhPT0gXCJudW1iZXJcIiApIHtcblx0XHRcdGlmICggb3B0LmR1cmF0aW9uIGluIGpRdWVyeS5meC5zcGVlZHMgKSB7XG5cdFx0XHRcdG9wdC5kdXJhdGlvbiA9IGpRdWVyeS5meC5zcGVlZHNbIG9wdC5kdXJhdGlvbiBdO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvcHQuZHVyYXRpb24gPSBqUXVlcnkuZnguc3BlZWRzLl9kZWZhdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIE5vcm1hbGl6ZSBvcHQucXVldWUgLSB0cnVlL3VuZGVmaW5lZC9udWxsIC0+IFwiZnhcIlxuXHRpZiAoIG9wdC5xdWV1ZSA9PSBudWxsIHx8IG9wdC5xdWV1ZSA9PT0gdHJ1ZSApIHtcblx0XHRvcHQucXVldWUgPSBcImZ4XCI7XG5cdH1cblxuXHQvLyBRdWV1ZWluZ1xuXHRvcHQub2xkID0gb3B0LmNvbXBsZXRlO1xuXG5cdG9wdC5jb21wbGV0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggaXNGdW5jdGlvbiggb3B0Lm9sZCApICkge1xuXHRcdFx0b3B0Lm9sZC5jYWxsKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBvcHQucXVldWUgKSB7XG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgb3B0LnF1ZXVlICk7XG5cdFx0fVxuXHR9O1xuXG5cdHJldHVybiBvcHQ7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGZhZGVUbzogZnVuY3Rpb24oIHNwZWVkLCB0bywgZWFzaW5nLCBjYWxsYmFjayApIHtcblxuXHRcdC8vIFNob3cgYW55IGhpZGRlbiBlbGVtZW50cyBhZnRlciBzZXR0aW5nIG9wYWNpdHkgdG8gMFxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggaXNIaWRkZW5XaXRoaW5UcmVlICkuY3NzKCBcIm9wYWNpdHlcIiwgMCApLnNob3coKVxuXG5cdFx0XHQvLyBBbmltYXRlIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWRcblx0XHRcdC5lbmQoKS5hbmltYXRlKCB7IG9wYWNpdHk6IHRvIH0sIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XG5cdH0sXG5cdGFuaW1hdGU6IGZ1bmN0aW9uKCBwcm9wLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHR2YXIgZW1wdHkgPSBqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcCApLFxuXHRcdFx0b3B0YWxsID0galF1ZXJ5LnNwZWVkKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApLFxuXHRcdFx0ZG9BbmltYXRpb24gPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBPcGVyYXRlIG9uIGEgY29weSBvZiBwcm9wIHNvIHBlci1wcm9wZXJ0eSBlYXNpbmcgd29uJ3QgYmUgbG9zdFxuXHRcdFx0XHR2YXIgYW5pbSA9IEFuaW1hdGlvbiggdGhpcywgalF1ZXJ5LmV4dGVuZCgge30sIHByb3AgKSwgb3B0YWxsICk7XG5cblx0XHRcdFx0Ly8gRW1wdHkgYW5pbWF0aW9ucywgb3IgZmluaXNoaW5nIHJlc29sdmVzIGltbWVkaWF0ZWx5XG5cdFx0XHRcdGlmICggZW1wdHkgfHwgZGF0YVByaXYuZ2V0KCB0aGlzLCBcImZpbmlzaFwiICkgKSB7XG5cdFx0XHRcdFx0YW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0XHRkb0FuaW1hdGlvbi5maW5pc2ggPSBkb0FuaW1hdGlvbjtcblxuXHRcdHJldHVybiBlbXB0eSB8fCBvcHRhbGwucXVldWUgPT09IGZhbHNlID9cblx0XHRcdHRoaXMuZWFjaCggZG9BbmltYXRpb24gKSA6XG5cdFx0XHR0aGlzLnF1ZXVlKCBvcHRhbGwucXVldWUsIGRvQW5pbWF0aW9uICk7XG5cdH0sXG5cdHN0b3A6IGZ1bmN0aW9uKCB0eXBlLCBjbGVhclF1ZXVlLCBnb3RvRW5kICkge1xuXHRcdHZhciBzdG9wUXVldWUgPSBmdW5jdGlvbiggaG9va3MgKSB7XG5cdFx0XHR2YXIgc3RvcCA9IGhvb2tzLnN0b3A7XG5cdFx0XHRkZWxldGUgaG9va3Muc3RvcDtcblx0XHRcdHN0b3AoIGdvdG9FbmQgKTtcblx0XHR9O1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGdvdG9FbmQgPSBjbGVhclF1ZXVlO1xuXHRcdFx0Y2xlYXJRdWV1ZSA9IHR5cGU7XG5cdFx0XHR0eXBlID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoIGNsZWFyUXVldWUgKSB7XG5cdFx0XHR0aGlzLnF1ZXVlKCB0eXBlIHx8IFwiZnhcIiwgW10gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkZXF1ZXVlID0gdHJ1ZSxcblx0XHRcdFx0aW5kZXggPSB0eXBlICE9IG51bGwgJiYgdHlwZSArIFwicXVldWVIb29rc1wiLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRkYXRhID0gZGF0YVByaXYuZ2V0KCB0aGlzICk7XG5cblx0XHRcdGlmICggaW5kZXggKSB7XG5cdFx0XHRcdGlmICggZGF0YVsgaW5kZXggXSAmJiBkYXRhWyBpbmRleCBdLnN0b3AgKSB7XG5cdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoIGluZGV4IGluIGRhdGEgKSB7XG5cdFx0XHRcdFx0aWYgKCBkYXRhWyBpbmRleCBdICYmIGRhdGFbIGluZGV4IF0uc3RvcCAmJiBycnVuLnRlc3QoIGluZGV4ICkgKSB7XG5cdFx0XHRcdFx0XHRzdG9wUXVldWUoIGRhdGFbIGluZGV4IF0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaW5kZXggPSB0aW1lcnMubGVuZ3RoOyBpbmRleC0tOyApIHtcblx0XHRcdFx0aWYgKCB0aW1lcnNbIGluZGV4IF0uZWxlbSA9PT0gdGhpcyAmJlxuXHRcdFx0XHRcdCggdHlwZSA9PSBudWxsIHx8IHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApICkge1xuXG5cdFx0XHRcdFx0dGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggZ290b0VuZCApO1xuXHRcdFx0XHRcdGRlcXVldWUgPSBmYWxzZTtcblx0XHRcdFx0XHR0aW1lcnMuc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXJ0IHRoZSBuZXh0IGluIHRoZSBxdWV1ZSBpZiB0aGUgbGFzdCBzdGVwIHdhc24ndCBmb3JjZWQuXG5cdFx0XHQvLyBUaW1lcnMgY3VycmVudGx5IHdpbGwgY2FsbCB0aGVpciBjb21wbGV0ZSBjYWxsYmFja3MsIHdoaWNoXG5cdFx0XHQvLyB3aWxsIGRlcXVldWUgYnV0IG9ubHkgaWYgdGhleSB3ZXJlIGdvdG9FbmQuXG5cdFx0XHRpZiAoIGRlcXVldWUgfHwgIWdvdG9FbmQgKSB7XG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXHRmaW5pc2g6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdGlmICggdHlwZSAhPT0gZmFsc2UgKSB7XG5cdFx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGluZGV4LFxuXHRcdFx0XHRkYXRhID0gZGF0YVByaXYuZ2V0KCB0aGlzICksXG5cdFx0XHRcdHF1ZXVlID0gZGF0YVsgdHlwZSArIFwicXVldWVcIiBdLFxuXHRcdFx0XHRob29rcyA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlSG9va3NcIiBdLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRsZW5ndGggPSBxdWV1ZSA/IHF1ZXVlLmxlbmd0aCA6IDA7XG5cblx0XHRcdC8vIEVuYWJsZSBmaW5pc2hpbmcgZmxhZyBvbiBwcml2YXRlIGRhdGFcblx0XHRcdGRhdGEuZmluaXNoID0gdHJ1ZTtcblxuXHRcdFx0Ly8gRW1wdHkgdGhlIHF1ZXVlIGZpcnN0XG5cdFx0XHRqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIFtdICk7XG5cblx0XHRcdGlmICggaG9va3MgJiYgaG9va3Muc3RvcCApIHtcblx0XHRcdFx0aG9va3Muc3RvcC5jYWxsKCB0aGlzLCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIExvb2sgZm9yIGFueSBhY3RpdmUgYW5pbWF0aW9ucywgYW5kIGZpbmlzaCB0aGVtXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xuXHRcdFx0XHRpZiAoIHRpbWVyc1sgaW5kZXggXS5lbGVtID09PSB0aGlzICYmIHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApIHtcblx0XHRcdFx0XHR0aW1lcnNbIGluZGV4IF0uYW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBMb29rIGZvciBhbnkgYW5pbWF0aW9ucyBpbiB0aGUgb2xkIHF1ZXVlIGFuZCBmaW5pc2ggdGhlbVxuXHRcdFx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0aWYgKCBxdWV1ZVsgaW5kZXggXSAmJiBxdWV1ZVsgaW5kZXggXS5maW5pc2ggKSB7XG5cdFx0XHRcdFx0cXVldWVbIGluZGV4IF0uZmluaXNoLmNhbGwoIHRoaXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBUdXJuIG9mZiBmaW5pc2hpbmcgZmxhZ1xuXHRcdFx0ZGVsZXRlIGRhdGEuZmluaXNoO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCggWyBcInRvZ2dsZVwiLCBcInNob3dcIiwgXCJoaWRlXCIgXSwgZnVuY3Rpb24oIF9pLCBuYW1lICkge1xuXHR2YXIgY3NzRm4gPSBqUXVlcnkuZm5bIG5hbWUgXTtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHNwZWVkID09IG51bGwgfHwgdHlwZW9mIHNwZWVkID09PSBcImJvb2xlYW5cIiA/XG5cdFx0XHRjc3NGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICkgOlxuXHRcdFx0dGhpcy5hbmltYXRlKCBnZW5GeCggbmFtZSwgdHJ1ZSApLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSApO1xuXG4vLyBHZW5lcmF0ZSBzaG9ydGN1dHMgZm9yIGN1c3RvbSBhbmltYXRpb25zXG5qUXVlcnkuZWFjaCgge1xuXHRzbGlkZURvd246IGdlbkZ4KCBcInNob3dcIiApLFxuXHRzbGlkZVVwOiBnZW5GeCggXCJoaWRlXCIgKSxcblx0c2xpZGVUb2dnbGU6IGdlbkZ4KCBcInRvZ2dsZVwiICksXG5cdGZhZGVJbjogeyBvcGFjaXR5OiBcInNob3dcIiB9LFxuXHRmYWRlT3V0OiB7IG9wYWNpdHk6IFwiaGlkZVwiIH0sXG5cdGZhZGVUb2dnbGU6IHsgb3BhY2l0eTogXCJ0b2dnbGVcIiB9XG59LCBmdW5jdGlvbiggbmFtZSwgcHJvcHMgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLmFuaW1hdGUoIHByb3BzLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSApO1xuXG5qUXVlcnkudGltZXJzID0gW107XG5qUXVlcnkuZngudGljayA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgdGltZXIsXG5cdFx0aSA9IDAsXG5cdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycztcblxuXHRmeE5vdyA9IERhdGUubm93KCk7XG5cblx0Zm9yICggOyBpIDwgdGltZXJzLmxlbmd0aDsgaSsrICkge1xuXHRcdHRpbWVyID0gdGltZXJzWyBpIF07XG5cblx0XHQvLyBSdW4gdGhlIHRpbWVyIGFuZCBzYWZlbHkgcmVtb3ZlIGl0IHdoZW4gZG9uZSAoYWxsb3dpbmcgZm9yIGV4dGVybmFsIHJlbW92YWwpXG5cdFx0aWYgKCAhdGltZXIoKSAmJiB0aW1lcnNbIGkgXSA9PT0gdGltZXIgKSB7XG5cdFx0XHR0aW1lcnMuc3BsaWNlKCBpLS0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoICF0aW1lcnMubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5meC5zdG9wKCk7XG5cdH1cblx0ZnhOb3cgPSB1bmRlZmluZWQ7XG59O1xuXG5qUXVlcnkuZngudGltZXIgPSBmdW5jdGlvbiggdGltZXIgKSB7XG5cdGpRdWVyeS50aW1lcnMucHVzaCggdGltZXIgKTtcblx0alF1ZXJ5LmZ4LnN0YXJ0KCk7XG59O1xuXG5qUXVlcnkuZnguaW50ZXJ2YWwgPSAxMztcbmpRdWVyeS5meC5zdGFydCA9IGZ1bmN0aW9uKCkge1xuXHRpZiAoIGluUHJvZ3Jlc3MgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aW5Qcm9ncmVzcyA9IHRydWU7XG5cdHNjaGVkdWxlKCk7XG59O1xuXG5qUXVlcnkuZnguc3RvcCA9IGZ1bmN0aW9uKCkge1xuXHRpblByb2dyZXNzID0gbnVsbDtcbn07XG5cbmpRdWVyeS5meC5zcGVlZHMgPSB7XG5cdHNsb3c6IDYwMCxcblx0ZmFzdDogMjAwLFxuXG5cdC8vIERlZmF1bHQgc3BlZWRcblx0X2RlZmF1bHQ6IDQwMFxufTtcblxuXG4vLyBCYXNlZCBvZmYgb2YgdGhlIHBsdWdpbiBieSBDbGludCBIZWxmZXJzLCB3aXRoIHBlcm1pc3Npb24uXG4vLyBodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxMDAzMjQwMTQ3NDcvaHR0cDovL2JsaW5kc2lnbmFscy5jb20vaW5kZXgucGhwLzIwMDkvMDcvanF1ZXJ5LWRlbGF5L1xualF1ZXJ5LmZuLmRlbGF5ID0gZnVuY3Rpb24oIHRpbWUsIHR5cGUgKSB7XG5cdHRpbWUgPSBqUXVlcnkuZnggPyBqUXVlcnkuZnguc3BlZWRzWyB0aW1lIF0gfHwgdGltZSA6IHRpbWU7XG5cdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSwgZnVuY3Rpb24oIG5leHQsIGhvb2tzICkge1xuXHRcdHZhciB0aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoIG5leHQsIHRpbWUgKTtcblx0XHRob29rcy5zdG9wID0gZnVuY3Rpb24oKSB7XG5cdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7XG5cdFx0fTtcblx0fSApO1xufTtcblxuXG4oIGZ1bmN0aW9uKCkge1xuXHR2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKSxcblx0XHRzZWxlY3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInNlbGVjdFwiICksXG5cdFx0b3B0ID0gc2VsZWN0LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9wdGlvblwiICkgKTtcblxuXHRpbnB1dC50eXBlID0gXCJjaGVja2JveFwiO1xuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjMgb25seVxuXHQvLyBEZWZhdWx0IHZhbHVlIGZvciBhIGNoZWNrYm94IHNob3VsZCBiZSBcIm9uXCJcblx0c3VwcG9ydC5jaGVja09uID0gaW5wdXQudmFsdWUgIT09IFwiXCI7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIE11c3QgYWNjZXNzIHNlbGVjdGVkSW5kZXggdG8gbWFrZSBkZWZhdWx0IG9wdGlvbnMgc2VsZWN0XG5cdHN1cHBvcnQub3B0U2VsZWN0ZWQgPSBvcHQuc2VsZWN0ZWQ7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIEFuIGlucHV0IGxvc2VzIGl0cyB2YWx1ZSBhZnRlciBiZWNvbWluZyBhIHJhZGlvXG5cdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cdGlucHV0LnZhbHVlID0gXCJ0XCI7XG5cdGlucHV0LnR5cGUgPSBcInJhZGlvXCI7XG5cdHN1cHBvcnQucmFkaW9WYWx1ZSA9IGlucHV0LnZhbHVlID09PSBcInRcIjtcbn0gKSgpO1xuXG5cbnZhciBib29sSG9vayxcblx0YXR0ckhhbmRsZSA9IGpRdWVyeS5leHByLmF0dHJIYW5kbGU7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0YXR0cjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGpRdWVyeS5hdHRyLCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblxuXHRyZW1vdmVBdHRyOiBmdW5jdGlvbiggbmFtZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCB0aGlzLCBuYW1lICk7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0YXR0cjogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdHZhciByZXQsIGhvb2tzLFxuXHRcdFx0blR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0Ly8gRG9uJ3QgZ2V0L3NldCBhdHRyaWJ1dGVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xuXHRcdGlmICggblR5cGUgPT09IDMgfHwgblR5cGUgPT09IDggfHwgblR5cGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRmFsbGJhY2sgdG8gcHJvcCB3aGVuIGF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcblx0XHRpZiAoIHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSA9PT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucHJvcCggZWxlbSwgbmFtZSwgdmFsdWUgKTtcblx0XHR9XG5cblx0XHQvLyBBdHRyaWJ1dGUgaG9va3MgYXJlIGRldGVybWluZWQgYnkgdGhlIGxvd2VyY2FzZSB2ZXJzaW9uXG5cdFx0Ly8gR3JhYiBuZWNlc3NhcnkgaG9vayBpZiBvbmUgaXMgZGVmaW5lZFxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXHRcdFx0aG9va3MgPSBqUXVlcnkuYXR0ckhvb2tzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHQoIGpRdWVyeS5leHByLm1hdGNoLmJvb2wudGVzdCggbmFtZSApID8gYm9vbEhvb2sgOiB1bmRlZmluZWQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRpZiAoIHZhbHVlID09PSBudWxsICkge1xuXHRcdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJlxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCB2YWx1ZSArIFwiXCIgKTtcblx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHR9XG5cblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKCByZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSApICE9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cblx0XHRyZXQgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHQvLyBOb24tZXhpc3RlbnQgYXR0cmlidXRlcyByZXR1cm4gbnVsbCwgd2Ugbm9ybWFsaXplIHRvIHVuZGVmaW5lZFxuXHRcdHJldHVybiByZXQgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHJldDtcblx0fSxcblxuXHRhdHRySG9va3M6IHtcblx0XHR0eXBlOiB7XG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhc3VwcG9ydC5yYWRpb1ZhbHVlICYmIHZhbHVlID09PSBcInJhZGlvXCIgJiZcblx0XHRcdFx0XHRub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgKSB7XG5cdFx0XHRcdFx0dmFyIHZhbCA9IGVsZW0udmFsdWU7XG5cdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCB2YWx1ZSApO1xuXHRcdFx0XHRcdGlmICggdmFsICkge1xuXHRcdFx0XHRcdFx0ZWxlbS52YWx1ZSA9IHZhbDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHR2YXIgbmFtZSxcblx0XHRcdGkgPSAwLFxuXG5cdFx0XHQvLyBBdHRyaWJ1dGUgbmFtZXMgY2FuIGNvbnRhaW4gbm9uLUhUTUwgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzXG5cdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNhdHRyaWJ1dGVzLTJcblx0XHRcdGF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICk7XG5cblx0XHRpZiAoIGF0dHJOYW1lcyAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0d2hpbGUgKCAoIG5hbWUgPSBhdHRyTmFtZXNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBuYW1lICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59ICk7XG5cbi8vIEhvb2tzIGZvciBib29sZWFuIGF0dHJpYnV0ZXNcbmJvb2xIb29rID0ge1xuXHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgbmFtZSApIHtcblx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblxuXHRcdFx0Ly8gUmVtb3ZlIGJvb2xlYW4gYXR0cmlidXRlcyB3aGVuIHNldCB0byBmYWxzZVxuXHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIGVsZW0sIG5hbWUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cbn07XG5cbmpRdWVyeS5lYWNoKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnNvdXJjZS5tYXRjaCggL1xcdysvZyApLCBmdW5jdGlvbiggX2ksIG5hbWUgKSB7XG5cdHZhciBnZXR0ZXIgPSBhdHRySGFuZGxlWyBuYW1lIF0gfHwgalF1ZXJ5LmZpbmQuYXR0cjtcblxuXHRhdHRySGFuZGxlWyBuYW1lIF0gPSBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0dmFyIHJldCwgaGFuZGxlLFxuXHRcdFx0bG93ZXJjYXNlTmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblxuXHRcdGlmICggIWlzWE1MICkge1xuXG5cdFx0XHQvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wIGJ5IHRlbXBvcmFyaWx5IHJlbW92aW5nIHRoaXMgZnVuY3Rpb24gZnJvbSB0aGUgZ2V0dGVyXG5cdFx0XHRoYW5kbGUgPSBhdHRySGFuZGxlWyBsb3dlcmNhc2VOYW1lIF07XG5cdFx0XHRhdHRySGFuZGxlWyBsb3dlcmNhc2VOYW1lIF0gPSByZXQ7XG5cdFx0XHRyZXQgPSBnZXR0ZXIoIGVsZW0sIG5hbWUsIGlzWE1MICkgIT0gbnVsbCA/XG5cdFx0XHRcdGxvd2VyY2FzZU5hbWUgOlxuXHRcdFx0XHRudWxsO1xuXHRcdFx0YXR0ckhhbmRsZVsgbG93ZXJjYXNlTmFtZSBdID0gaGFuZGxlO1xuXHRcdH1cblx0XHRyZXR1cm4gcmV0O1xuXHR9O1xufSApO1xuXG5cblxuXG52YXIgcmZvY3VzYWJsZSA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksXG5cdHJjbGlja2FibGUgPSAvXig/OmF8YXJlYSkkL2k7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0cHJvcDogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGpRdWVyeS5wcm9wLCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblxuXHRyZW1vdmVQcm9wOiBmdW5jdGlvbiggbmFtZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGRlbGV0ZSB0aGlzWyBqUXVlcnkucHJvcEZpeFsgbmFtZSBdIHx8IG5hbWUgXTtcblx0XHR9ICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmV4dGVuZCgge1xuXHRwcm9wOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0dmFyIHJldCwgaG9va3MsXG5cdFx0XHRuVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0XHQvLyBEb24ndCBnZXQvc2V0IHByb3BlcnRpZXMgb24gdGV4dCwgY29tbWVudCBhbmQgYXR0cmlidXRlIG5vZGVzXG5cdFx0aWYgKCBuVHlwZSA9PT0gMyB8fCBuVHlwZSA9PT0gOCB8fCBuVHlwZSA9PT0gMiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIG5UeXBlICE9PSAxIHx8ICFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHtcblxuXHRcdFx0Ly8gRml4IG5hbWUgYW5kIGF0dGFjaCBob29rc1xuXHRcdFx0bmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTtcblx0XHRcdGhvb2tzID0galF1ZXJ5LnByb3BIb29rc1sgbmFtZSBdO1xuXHRcdH1cblxuXHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGlmICggaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJlxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiAoIGVsZW1bIG5hbWUgXSA9IHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmICggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkgKSAhPT0gbnVsbCApIHtcblx0XHRcdHJldHVybiByZXQ7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGVsZW1bIG5hbWUgXTtcblx0fSxcblxuXHRwcm9wSG9va3M6IHtcblx0XHR0YWJJbmRleDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSBvbmx5XG5cdFx0XHRcdC8vIGVsZW0udGFiSW5kZXggZG9lc24ndCBhbHdheXMgcmV0dXJuIHRoZVxuXHRcdFx0XHQvLyBjb3JyZWN0IHZhbHVlIHdoZW4gaXQgaGFzbid0IGJlZW4gZXhwbGljaXRseSBzZXRcblx0XHRcdFx0Ly8gaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTQxMTE2MjMzMzQ3L2h0dHA6Ly9mbHVpZHByb2plY3Qub3JnL2Jsb2cvMjAwOC8wMS8wOS9nZXR0aW5nLXNldHRpbmctYW5kLXJlbW92aW5nLXRhYmluZGV4LXZhbHVlcy13aXRoLWphdmFzY3JpcHQvXG5cdFx0XHRcdC8vIFVzZSBwcm9wZXIgYXR0cmlidXRlIHJldHJpZXZhbCgjMTIwNzIpXG5cdFx0XHRcdHZhciB0YWJpbmRleCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIFwidGFiaW5kZXhcIiApO1xuXG5cdFx0XHRcdGlmICggdGFiaW5kZXggKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhcnNlSW50KCB0YWJpbmRleCwgMTAgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRyZm9jdXNhYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSB8fFxuXHRcdFx0XHRcdHJjbGlja2FibGUudGVzdCggZWxlbS5ub2RlTmFtZSApICYmXG5cdFx0XHRcdFx0ZWxlbS5ocmVmXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRwcm9wRml4OiB7XG5cdFx0XCJmb3JcIjogXCJodG1sRm9yXCIsXG5cdFx0XCJjbGFzc1wiOiBcImNsYXNzTmFtZVwiXG5cdH1cbn0gKTtcblxuLy8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG4vLyBBY2Nlc3NpbmcgdGhlIHNlbGVjdGVkSW5kZXggcHJvcGVydHlcbi8vIGZvcmNlcyB0aGUgYnJvd3NlciB0byByZXNwZWN0IHNldHRpbmcgc2VsZWN0ZWRcbi8vIG9uIHRoZSBvcHRpb25cbi8vIFRoZSBnZXR0ZXIgZW5zdXJlcyBhIGRlZmF1bHQgb3B0aW9uIGlzIHNlbGVjdGVkXG4vLyB3aGVuIGluIGFuIG9wdGdyb3VwXG4vLyBlc2xpbnQgcnVsZSBcIm5vLXVudXNlZC1leHByZXNzaW9uc1wiIGlzIGRpc2FibGVkIGZvciB0aGlzIGNvZGVcbi8vIHNpbmNlIGl0IGNvbnNpZGVycyBzdWNoIGFjY2Vzc2lvbnMgbm9vcFxuaWYgKCAhc3VwcG9ydC5vcHRTZWxlY3RlZCApIHtcblx0alF1ZXJ5LnByb3BIb29rcy5zZWxlY3RlZCA9IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHQvKiBlc2xpbnQgbm8tdW51c2VkLWV4cHJlc3Npb25zOiBcIm9mZlwiICovXG5cblx0XHRcdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRpZiAoIHBhcmVudCAmJiBwYXJlbnQucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0LyogZXNsaW50IG5vLXVudXNlZC1leHByZXNzaW9uczogXCJvZmZcIiAqL1xuXG5cdFx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdFx0aWYgKCBwYXJlbnQgKSB7XG5cdFx0XHRcdHBhcmVudC5zZWxlY3RlZEluZGV4O1xuXG5cdFx0XHRcdGlmICggcGFyZW50LnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fTtcbn1cblxualF1ZXJ5LmVhY2goIFtcblx0XCJ0YWJJbmRleFwiLFxuXHRcInJlYWRPbmx5XCIsXG5cdFwibWF4TGVuZ3RoXCIsXG5cdFwiY2VsbFNwYWNpbmdcIixcblx0XCJjZWxsUGFkZGluZ1wiLFxuXHRcInJvd1NwYW5cIixcblx0XCJjb2xTcGFuXCIsXG5cdFwidXNlTWFwXCIsXG5cdFwiZnJhbWVCb3JkZXJcIixcblx0XCJjb250ZW50RWRpdGFibGVcIlxuXSwgZnVuY3Rpb24oKSB7XG5cdGpRdWVyeS5wcm9wRml4WyB0aGlzLnRvTG93ZXJDYXNlKCkgXSA9IHRoaXM7XG59ICk7XG5cblxuXG5cblx0Ly8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2UgYWNjb3JkaW5nIHRvIEhUTUwgc3BlY1xuXHQvLyBodHRwczovL2luZnJhLnNwZWMud2hhdHdnLm9yZy8jc3RyaXAtYW5kLWNvbGxhcHNlLWFzY2lpLXdoaXRlc3BhY2Vcblx0ZnVuY3Rpb24gc3RyaXBBbmRDb2xsYXBzZSggdmFsdWUgKSB7XG5cdFx0dmFyIHRva2VucyA9IHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW107XG5cdFx0cmV0dXJuIHRva2Vucy5qb2luKCBcIiBcIiApO1xuXHR9XG5cblxuZnVuY3Rpb24gZ2V0Q2xhc3MoIGVsZW0gKSB7XG5cdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSAmJiBlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHwgXCJcIjtcbn1cblxuZnVuY3Rpb24gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICkge1xuXHRpZiAoIEFycmF5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9XG5cdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiB2YWx1ZS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdO1xuXHR9XG5cdHJldHVybiBbXTtcbn1cblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRhZGRDbGFzczogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBjbGFzc2VzLCBlbGVtLCBjdXIsIGN1clZhbHVlLCBjbGF6eiwgaiwgZmluYWxWYWx1ZSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGogKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmFkZENsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCBnZXRDbGFzcyggdGhpcyApICkgKTtcblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRjbGFzc2VzID0gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICk7XG5cblx0XHRpZiAoIGNsYXNzZXMubGVuZ3RoICkge1xuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xuXHRcdFx0XHRjdXJWYWx1ZSA9IGdldENsYXNzKCBlbGVtICk7XG5cdFx0XHRcdGN1ciA9IGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBcIiBcIiArIHN0cmlwQW5kQ29sbGFwc2UoIGN1clZhbHVlICkgKyBcIiBcIiApO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA8IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1ciArPSBjbGF6eiArIFwiIFwiO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoIGN1ciApO1xuXHRcdFx0XHRcdGlmICggY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLCBmaW5hbFZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0cmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjdXJWYWx1ZSwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRpID0gMDtcblxuXHRcdGlmICggaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBqICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5yZW1vdmVDbGFzcyggdmFsdWUuY2FsbCggdGhpcywgaiwgZ2V0Q2xhc3MoIHRoaXMgKSApICk7XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCAhYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiB0aGlzLmF0dHIoIFwiY2xhc3NcIiwgXCJcIiApO1xuXHRcdH1cblxuXHRcdGNsYXNzZXMgPSBjbGFzc2VzVG9BcnJheSggdmFsdWUgKTtcblxuXHRcdGlmICggY2xhc3Nlcy5sZW5ndGggKSB7XG5cdFx0XHR3aGlsZSAoICggZWxlbSA9IHRoaXNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdGN1clZhbHVlID0gZ2V0Q2xhc3MoIGVsZW0gKTtcblxuXHRcdFx0XHQvLyBUaGlzIGV4cHJlc3Npb24gaXMgaGVyZSBmb3IgYmV0dGVyIGNvbXByZXNzaWJpbGl0eSAoc2VlIGFkZENsYXNzKVxuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggXCIgXCIgKyBzdHJpcEFuZENvbGxhcHNlKCBjdXJWYWx1ZSApICsgXCIgXCIgKTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoICggY2xhenogPSBjbGFzc2VzWyBqKysgXSApICkge1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgKmFsbCogaW5zdGFuY2VzXG5cdFx0XHRcdFx0XHR3aGlsZSAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0XHRjdXIgPSBjdXIucmVwbGFjZSggXCIgXCIgKyBjbGF6eiArIFwiIFwiLCBcIiBcIiApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoIGN1ciApO1xuXHRcdFx0XHRcdGlmICggY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLCBmaW5hbFZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0dG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSwgc3RhdGVWYWwgKSB7XG5cdFx0dmFyIHR5cGUgPSB0eXBlb2YgdmFsdWUsXG5cdFx0XHRpc1ZhbGlkVmFsdWUgPSB0eXBlID09PSBcInN0cmluZ1wiIHx8IEFycmF5LmlzQXJyYXkoIHZhbHVlICk7XG5cblx0XHRpZiAoIHR5cGVvZiBzdGF0ZVZhbCA9PT0gXCJib29sZWFuXCIgJiYgaXNWYWxpZFZhbHVlICkge1xuXHRcdFx0cmV0dXJuIHN0YXRlVmFsID8gdGhpcy5hZGRDbGFzcyggdmFsdWUgKSA6IHRoaXMucmVtb3ZlQ2xhc3MoIHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnRvZ2dsZUNsYXNzKFxuXHRcdFx0XHRcdHZhbHVlLmNhbGwoIHRoaXMsIGksIGdldENsYXNzKCB0aGlzICksIHN0YXRlVmFsICksXG5cdFx0XHRcdFx0c3RhdGVWYWxcblx0XHRcdFx0KTtcblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBjbGFzc05hbWUsIGksIHNlbGYsIGNsYXNzTmFtZXM7XG5cblx0XHRcdGlmICggaXNWYWxpZFZhbHVlICkge1xuXG5cdFx0XHRcdC8vIFRvZ2dsZSBpbmRpdmlkdWFsIGNsYXNzIG5hbWVzXG5cdFx0XHRcdGkgPSAwO1xuXHRcdFx0XHRzZWxmID0galF1ZXJ5KCB0aGlzICk7XG5cdFx0XHRcdGNsYXNzTmFtZXMgPSBjbGFzc2VzVG9BcnJheSggdmFsdWUgKTtcblxuXHRcdFx0XHR3aGlsZSAoICggY2xhc3NOYW1lID0gY2xhc3NOYW1lc1sgaSsrIF0gKSApIHtcblxuXHRcdFx0XHRcdC8vIENoZWNrIGVhY2ggY2xhc3NOYW1lIGdpdmVuLCBzcGFjZSBzZXBhcmF0ZWQgbGlzdFxuXHRcdFx0XHRcdGlmICggc2VsZi5oYXNDbGFzcyggY2xhc3NOYW1lICkgKSB7XG5cdFx0XHRcdFx0XHRzZWxmLnJlbW92ZUNsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c2VsZi5hZGRDbGFzcyggY2xhc3NOYW1lICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdC8vIFRvZ2dsZSB3aG9sZSBjbGFzcyBuYW1lXG5cdFx0XHR9IGVsc2UgaWYgKCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGUgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0XHRjbGFzc05hbWUgPSBnZXRDbGFzcyggdGhpcyApO1xuXHRcdFx0XHRpZiAoIGNsYXNzTmFtZSApIHtcblxuXHRcdFx0XHRcdC8vIFN0b3JlIGNsYXNzTmFtZSBpZiBzZXRcblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiLCBjbGFzc05hbWUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIElmIHRoZSBlbGVtZW50IGhhcyBhIGNsYXNzIG5hbWUgb3IgaWYgd2UncmUgcGFzc2VkIGBmYWxzZWAsXG5cdFx0XHRcdC8vIHRoZW4gcmVtb3ZlIHRoZSB3aG9sZSBjbGFzc25hbWUgKGlmIHRoZXJlIHdhcyBvbmUsIHRoZSBhYm92ZSBzYXZlZCBpdCkuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBicmluZyBiYWNrIHdoYXRldmVyIHdhcyBwcmV2aW91c2x5IHNhdmVkIChpZiBhbnl0aGluZyksXG5cdFx0XHRcdC8vIGZhbGxpbmcgYmFjayB0byB0aGUgZW1wdHkgc3RyaW5nIGlmIG5vdGhpbmcgd2FzIHN0b3JlZC5cblx0XHRcdFx0aWYgKCB0aGlzLnNldEF0dHJpYnV0ZSApIHtcblx0XHRcdFx0XHR0aGlzLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lIHx8IHZhbHVlID09PSBmYWxzZSA/XG5cdFx0XHRcdFx0XHRcIlwiIDpcblx0XHRcdFx0XHRcdGRhdGFQcml2LmdldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIgKSB8fCBcIlwiXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRoYXNDbGFzczogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBjbGFzc05hbWUsIGVsZW0sXG5cdFx0XHRpID0gMDtcblxuXHRcdGNsYXNzTmFtZSA9IFwiIFwiICsgc2VsZWN0b3IgKyBcIiBcIjtcblx0XHR3aGlsZSAoICggZWxlbSA9IHRoaXNbIGkrKyBdICkgKSB7XG5cdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0KCBcIiBcIiArIHN0cmlwQW5kQ29sbGFwc2UoIGdldENsYXNzKCBlbGVtICkgKSArIFwiIFwiICkuaW5kZXhPZiggY2xhc3NOYW1lICkgPiAtMSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0gKTtcblxuXG5cblxudmFyIHJyZXR1cm4gPSAvXFxyL2c7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0dmFsOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGhvb2tzLCByZXQsIHZhbHVlSXNGdW5jdGlvbixcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XG5cblx0XHRpZiAoICFhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgZWxlbS50eXBlIF0gfHxcblx0XHRcdFx0XHRqUXVlcnkudmFsSG9va3NbIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHRcdGlmICggaG9va3MgJiZcblx0XHRcdFx0XHRcImdldFwiIGluIGhvb2tzICYmXG5cdFx0XHRcdFx0KCByZXQgPSBob29rcy5nZXQoIGVsZW0sIFwidmFsdWVcIiApICkgIT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0ID0gZWxlbS52YWx1ZTtcblxuXHRcdFx0XHQvLyBIYW5kbGUgbW9zdCBjb21tb24gc3RyaW5nIGNhc2VzXG5cdFx0XHRcdGlmICggdHlwZW9mIHJldCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcmV0LnJlcGxhY2UoIHJyZXR1cm4sIFwiXCIgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEhhbmRsZSBjYXNlcyB3aGVyZSB2YWx1ZSBpcyBudWxsL3VuZGVmIG9yIG51bWJlclxuXHRcdFx0XHRyZXR1cm4gcmV0ID09IG51bGwgPyBcIlwiIDogcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFsdWVJc0Z1bmN0aW9uID0gaXNGdW5jdGlvbiggdmFsdWUgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0dmFyIHZhbDtcblxuXHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlICE9PSAxICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggdmFsdWVJc0Z1bmN0aW9uICkge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZS5jYWxsKCB0aGlzLCBpLCBqUXVlcnkoIHRoaXMgKS52YWwoKSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dmFsID0gdmFsdWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRyZWF0IG51bGwvdW5kZWZpbmVkIGFzIFwiXCI7IGNvbnZlcnQgbnVtYmVycyB0byBzdHJpbmdcblx0XHRcdGlmICggdmFsID09IG51bGwgKSB7XG5cdFx0XHRcdHZhbCA9IFwiXCI7XG5cblx0XHRcdH0gZWxzZSBpZiAoIHR5cGVvZiB2YWwgPT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRcdHZhbCArPSBcIlwiO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBBcnJheS5pc0FycmF5KCB2YWwgKSApIHtcblx0XHRcdFx0dmFsID0galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKyBcIlwiO1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cblx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyB0aGlzLnR5cGUgXSB8fCBqUXVlcnkudmFsSG9va3NbIHRoaXMubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHQvLyBJZiBzZXQgcmV0dXJucyB1bmRlZmluZWQsIGZhbGwgYmFjayB0byBub3JtYWwgc2V0dGluZ1xuXHRcdFx0aWYgKCAhaG9va3MgfHwgISggXCJzZXRcIiBpbiBob29rcyApIHx8IGhvb2tzLnNldCggdGhpcywgdmFsLCBcInZhbHVlXCIgKSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHR0aGlzLnZhbHVlID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdHZhbEhvb2tzOiB7XG5cdFx0b3B0aW9uOiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHRcdHZhciB2YWwgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInZhbHVlXCIgKTtcblx0XHRcdFx0cmV0dXJuIHZhbCAhPSBudWxsID9cblx0XHRcdFx0XHR2YWwgOlxuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD0xMCAtIDExIG9ubHlcblx0XHRcdFx0XHQvLyBvcHRpb24udGV4dCB0aHJvd3MgZXhjZXB0aW9ucyAoIzE0Njg2LCAjMTQ4NTgpXG5cdFx0XHRcdFx0Ly8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2Vcblx0XHRcdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNzdHJpcC1hbmQtY29sbGFwc2Utd2hpdGVzcGFjZVxuXHRcdFx0XHRcdHN0cmlwQW5kQ29sbGFwc2UoIGpRdWVyeS50ZXh0KCBlbGVtICkgKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdHNlbGVjdDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHZhbHVlLCBvcHRpb24sIGksXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHRpbmRleCA9IGVsZW0uc2VsZWN0ZWRJbmRleCxcblx0XHRcdFx0XHRvbmUgPSBlbGVtLnR5cGUgPT09IFwic2VsZWN0LW9uZVwiLFxuXHRcdFx0XHRcdHZhbHVlcyA9IG9uZSA/IG51bGwgOiBbXSxcblx0XHRcdFx0XHRtYXggPSBvbmUgPyBpbmRleCArIDEgOiBvcHRpb25zLmxlbmd0aDtcblxuXHRcdFx0XHRpZiAoIGluZGV4IDwgMCApIHtcblx0XHRcdFx0XHRpID0gbWF4O1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aSA9IG9uZSA/IGluZGV4IDogMDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIExvb3AgdGhyb3VnaCBhbGwgdGhlIHNlbGVjdGVkIG9wdGlvbnNcblx0XHRcdFx0Zm9yICggOyBpIDwgbWF4OyBpKysgKSB7XG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0XHRcdFx0XHQvLyBJRTgtOSBkb2Vzbid0IHVwZGF0ZSBzZWxlY3RlZCBhZnRlciBmb3JtIHJlc2V0ICgjMjU1MSlcblx0XHRcdFx0XHRpZiAoICggb3B0aW9uLnNlbGVjdGVkIHx8IGkgPT09IGluZGV4ICkgJiZcblxuXHRcdFx0XHRcdFx0XHQvLyBEb24ndCByZXR1cm4gb3B0aW9ucyB0aGF0IGFyZSBkaXNhYmxlZCBvciBpbiBhIGRpc2FibGVkIG9wdGdyb3VwXG5cdFx0XHRcdFx0XHRcdCFvcHRpb24uZGlzYWJsZWQgJiZcblx0XHRcdFx0XHRcdFx0KCAhb3B0aW9uLnBhcmVudE5vZGUuZGlzYWJsZWQgfHxcblx0XHRcdFx0XHRcdFx0XHQhbm9kZU5hbWUoIG9wdGlvbi5wYXJlbnROb2RlLCBcIm9wdGdyb3VwXCIgKSApICkge1xuXG5cdFx0XHRcdFx0XHQvLyBHZXQgdGhlIHNwZWNpZmljIHZhbHVlIGZvciB0aGUgb3B0aW9uXG5cdFx0XHRcdFx0XHR2YWx1ZSA9IGpRdWVyeSggb3B0aW9uICkudmFsKCk7XG5cblx0XHRcdFx0XHRcdC8vIFdlIGRvbid0IG5lZWQgYW4gYXJyYXkgZm9yIG9uZSBzZWxlY3RzXG5cdFx0XHRcdFx0XHRpZiAoIG9uZSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBNdWx0aS1TZWxlY3RzIHJldHVybiBhbiBhcnJheVxuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH0sXG5cblx0XHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgb3B0aW9uU2V0LCBvcHRpb24sXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHR2YWx1ZXMgPSBqUXVlcnkubWFrZUFycmF5KCB2YWx1ZSApLFxuXHRcdFx0XHRcdGkgPSBvcHRpb25zLmxlbmd0aDtcblxuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRvcHRpb24gPSBvcHRpb25zWyBpIF07XG5cblx0XHRcdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuXG5cdFx0XHRcdFx0aWYgKCBvcHRpb24uc2VsZWN0ZWQgPVxuXHRcdFx0XHRcdFx0alF1ZXJ5LmluQXJyYXkoIGpRdWVyeS52YWxIb29rcy5vcHRpb24uZ2V0KCBvcHRpb24gKSwgdmFsdWVzICkgPiAtMVxuXHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0b3B0aW9uU2V0ID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvKiBlc2xpbnQtZW5hYmxlIG5vLWNvbmQtYXNzaWduICovXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBGb3JjZSBicm93c2VycyB0byBiZWhhdmUgY29uc2lzdGVudGx5IHdoZW4gbm9uLW1hdGNoaW5nIHZhbHVlIGlzIHNldFxuXHRcdFx0XHRpZiAoICFvcHRpb25TZXQgKSB7XG5cdFx0XHRcdFx0ZWxlbS5zZWxlY3RlZEluZGV4ID0gLTE7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0gKTtcblxuLy8gUmFkaW9zIGFuZCBjaGVja2JveGVzIGdldHRlci9zZXR0ZXJcbmpRdWVyeS5lYWNoKCBbIFwicmFkaW9cIiwgXCJjaGVja2JveFwiIF0sIGZ1bmN0aW9uKCkge1xuXHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXSA9IHtcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSggdmFsdWUgKSApIHtcblx0XHRcdFx0cmV0dXJuICggZWxlbS5jaGVja2VkID0galF1ZXJ5LmluQXJyYXkoIGpRdWVyeSggZWxlbSApLnZhbCgpLCB2YWx1ZSApID4gLTEgKTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cdGlmICggIXN1cHBvcnQuY2hlY2tPbiApIHtcblx0XHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXS5nZXQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IG51bGwgPyBcIm9uXCIgOiBlbGVtLnZhbHVlO1xuXHRcdH07XG5cdH1cbn0gKTtcblxuXG5cblxuLy8gUmV0dXJuIGpRdWVyeSBmb3IgYXR0cmlidXRlcy1vbmx5IGluY2x1c2lvblxuXG5cbnN1cHBvcnQuZm9jdXNpbiA9IFwib25mb2N1c2luXCIgaW4gd2luZG93O1xuXG5cbnZhciByZm9jdXNNb3JwaCA9IC9eKD86Zm9jdXNpbmZvY3VzfGZvY3Vzb3V0Ymx1cikkLyxcblx0c3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgPSBmdW5jdGlvbiggZSApIHtcblx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHR9O1xuXG5qUXVlcnkuZXh0ZW5kKCBqUXVlcnkuZXZlbnQsIHtcblxuXHR0cmlnZ2VyOiBmdW5jdGlvbiggZXZlbnQsIGRhdGEsIGVsZW0sIG9ubHlIYW5kbGVycyApIHtcblxuXHRcdHZhciBpLCBjdXIsIHRtcCwgYnViYmxlVHlwZSwgb250eXBlLCBoYW5kbGUsIHNwZWNpYWwsIGxhc3RFbGVtZW50LFxuXHRcdFx0ZXZlbnRQYXRoID0gWyBlbGVtIHx8IGRvY3VtZW50IF0sXG5cdFx0XHR0eXBlID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcInR5cGVcIiApID8gZXZlbnQudHlwZSA6IGV2ZW50LFxuXHRcdFx0bmFtZXNwYWNlcyA9IGhhc093bi5jYWxsKCBldmVudCwgXCJuYW1lc3BhY2VcIiApID8gZXZlbnQubmFtZXNwYWNlLnNwbGl0KCBcIi5cIiApIDogW107XG5cblx0XHRjdXIgPSBsYXN0RWxlbWVudCA9IHRtcCA9IGVsZW0gPSBlbGVtIHx8IGRvY3VtZW50O1xuXG5cdFx0Ly8gRG9uJ3QgZG8gZXZlbnRzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBmb2N1cy9ibHVyIG1vcnBocyB0byBmb2N1c2luL291dDsgZW5zdXJlIHdlJ3JlIG5vdCBmaXJpbmcgdGhlbSByaWdodCBub3dcblx0XHRpZiAoIHJmb2N1c01vcnBoLnRlc3QoIHR5cGUgKyBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCB0eXBlLmluZGV4T2YoIFwiLlwiICkgPiAtMSApIHtcblxuXHRcdFx0Ly8gTmFtZXNwYWNlZCB0cmlnZ2VyOyBjcmVhdGUgYSByZWdleHAgdG8gbWF0Y2ggZXZlbnQgdHlwZSBpbiBoYW5kbGUoKVxuXHRcdFx0bmFtZXNwYWNlcyA9IHR5cGUuc3BsaXQoIFwiLlwiICk7XG5cdFx0XHR0eXBlID0gbmFtZXNwYWNlcy5zaGlmdCgpO1xuXHRcdFx0bmFtZXNwYWNlcy5zb3J0KCk7XG5cdFx0fVxuXHRcdG9udHlwZSA9IHR5cGUuaW5kZXhPZiggXCI6XCIgKSA8IDAgJiYgXCJvblwiICsgdHlwZTtcblxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhIGpRdWVyeS5FdmVudCBvYmplY3QsIE9iamVjdCwgb3IganVzdCBhbiBldmVudCB0eXBlIHN0cmluZ1xuXHRcdGV2ZW50ID0gZXZlbnRbIGpRdWVyeS5leHBhbmRvIF0gP1xuXHRcdFx0ZXZlbnQgOlxuXHRcdFx0bmV3IGpRdWVyeS5FdmVudCggdHlwZSwgdHlwZW9mIGV2ZW50ID09PSBcIm9iamVjdFwiICYmIGV2ZW50ICk7XG5cblx0XHQvLyBUcmlnZ2VyIGJpdG1hc2s6ICYgMSBmb3IgbmF0aXZlIGhhbmRsZXJzOyAmIDIgZm9yIGpRdWVyeSAoYWx3YXlzIHRydWUpXG5cdFx0ZXZlbnQuaXNUcmlnZ2VyID0gb25seUhhbmRsZXJzID8gMiA6IDM7XG5cdFx0ZXZlbnQubmFtZXNwYWNlID0gbmFtZXNwYWNlcy5qb2luKCBcIi5cIiApO1xuXHRcdGV2ZW50LnJuYW1lc3BhY2UgPSBldmVudC5uYW1lc3BhY2UgP1xuXHRcdFx0bmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbiggXCJcXFxcLig/Oi4qXFxcXC58KVwiICkgKyBcIihcXFxcLnwkKVwiICkgOlxuXHRcdFx0bnVsbDtcblxuXHRcdC8vIENsZWFuIHVwIHRoZSBldmVudCBpbiBjYXNlIGl0IGlzIGJlaW5nIHJldXNlZFxuXHRcdGV2ZW50LnJlc3VsdCA9IHVuZGVmaW5lZDtcblx0XHRpZiAoICFldmVudC50YXJnZXQgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBlbGVtO1xuXHRcdH1cblxuXHRcdC8vIENsb25lIGFueSBpbmNvbWluZyBkYXRhIGFuZCBwcmVwZW5kIHRoZSBldmVudCwgY3JlYXRpbmcgdGhlIGhhbmRsZXIgYXJnIGxpc3Rcblx0XHRkYXRhID0gZGF0YSA9PSBudWxsID9cblx0XHRcdFsgZXZlbnQgXSA6XG5cdFx0XHRqUXVlcnkubWFrZUFycmF5KCBkYXRhLCBbIGV2ZW50IF0gKTtcblxuXHRcdC8vIEFsbG93IHNwZWNpYWwgZXZlbnRzIHRvIGRyYXcgb3V0c2lkZSB0aGUgbGluZXNcblx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgc3BlY2lhbC50cmlnZ2VyICYmIHNwZWNpYWwudHJpZ2dlci5hcHBseSggZWxlbSwgZGF0YSApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgZXZlbnQgcHJvcGFnYXRpb24gcGF0aCBpbiBhZHZhbmNlLCBwZXIgVzNDIGV2ZW50cyBzcGVjICgjOTk1MSlcblx0XHQvLyBCdWJibGUgdXAgdG8gZG9jdW1lbnQsIHRoZW4gdG8gd2luZG93OyB3YXRjaCBmb3IgYSBnbG9iYWwgb3duZXJEb2N1bWVudCB2YXIgKCM5NzI0KVxuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhc3BlY2lhbC5ub0J1YmJsZSAmJiAhaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0YnViYmxlVHlwZSA9IHNwZWNpYWwuZGVsZWdhdGVUeXBlIHx8IHR5cGU7XG5cdFx0XHRpZiAoICFyZm9jdXNNb3JwaC50ZXN0KCBidWJibGVUeXBlICsgdHlwZSApICkge1xuXHRcdFx0XHRjdXIgPSBjdXIucGFyZW50Tm9kZTtcblx0XHRcdH1cblx0XHRcdGZvciAoIDsgY3VyOyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIGN1ciApO1xuXHRcdFx0XHR0bXAgPSBjdXI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE9ubHkgYWRkIHdpbmRvdyBpZiB3ZSBnb3QgdG8gZG9jdW1lbnQgKGUuZy4sIG5vdCBwbGFpbiBvYmogb3IgZGV0YWNoZWQgRE9NKVxuXHRcdFx0aWYgKCB0bXAgPT09ICggZWxlbS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50ICkgKSB7XG5cdFx0XHRcdGV2ZW50UGF0aC5wdXNoKCB0bXAuZGVmYXVsdFZpZXcgfHwgdG1wLnBhcmVudFdpbmRvdyB8fCB3aW5kb3cgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBGaXJlIGhhbmRsZXJzIG9uIHRoZSBldmVudCBwYXRoXG5cdFx0aSA9IDA7XG5cdFx0d2hpbGUgKCAoIGN1ciA9IGV2ZW50UGF0aFsgaSsrIF0gKSAmJiAhZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblx0XHRcdGxhc3RFbGVtZW50ID0gY3VyO1xuXHRcdFx0ZXZlbnQudHlwZSA9IGkgPiAxID9cblx0XHRcdFx0YnViYmxlVHlwZSA6XG5cdFx0XHRcdHNwZWNpYWwuYmluZFR5cGUgfHwgdHlwZTtcblxuXHRcdFx0Ly8galF1ZXJ5IGhhbmRsZXJcblx0XHRcdGhhbmRsZSA9IChcblx0XHRcdFx0XHRkYXRhUHJpdi5nZXQoIGN1ciwgXCJldmVudHNcIiApIHx8IE9iamVjdC5jcmVhdGUoIG51bGwgKVxuXHRcdFx0XHQpWyBldmVudC50eXBlIF0gJiZcblx0XHRcdFx0ZGF0YVByaXYuZ2V0KCBjdXIsIFwiaGFuZGxlXCIgKTtcblx0XHRcdGlmICggaGFuZGxlICkge1xuXHRcdFx0XHRoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBOYXRpdmUgaGFuZGxlclxuXHRcdFx0aGFuZGxlID0gb250eXBlICYmIGN1clsgb250eXBlIF07XG5cdFx0XHRpZiAoIGhhbmRsZSAmJiBoYW5kbGUuYXBwbHkgJiYgYWNjZXB0RGF0YSggY3VyICkgKSB7XG5cdFx0XHRcdGV2ZW50LnJlc3VsdCA9IGhhbmRsZS5hcHBseSggY3VyLCBkYXRhICk7XG5cdFx0XHRcdGlmICggZXZlbnQucmVzdWx0ID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGV2ZW50LnR5cGUgPSB0eXBlO1xuXG5cdFx0Ly8gSWYgbm9ib2R5IHByZXZlbnRlZCB0aGUgZGVmYXVsdCBhY3Rpb24sIGRvIGl0IG5vd1xuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkgKSB7XG5cblx0XHRcdGlmICggKCAhc3BlY2lhbC5fZGVmYXVsdCB8fFxuXHRcdFx0XHRzcGVjaWFsLl9kZWZhdWx0LmFwcGx5KCBldmVudFBhdGgucG9wKCksIGRhdGEgKSA9PT0gZmFsc2UgKSAmJlxuXHRcdFx0XHRhY2NlcHREYXRhKCBlbGVtICkgKSB7XG5cblx0XHRcdFx0Ly8gQ2FsbCBhIG5hdGl2ZSBET00gbWV0aG9kIG9uIHRoZSB0YXJnZXQgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBldmVudC5cblx0XHRcdFx0Ly8gRG9uJ3QgZG8gZGVmYXVsdCBhY3Rpb25zIG9uIHdpbmRvdywgdGhhdCdzIHdoZXJlIGdsb2JhbCB2YXJpYWJsZXMgYmUgKCM2MTcwKVxuXHRcdFx0XHRpZiAoIG9udHlwZSAmJiBpc0Z1bmN0aW9uKCBlbGVtWyB0eXBlIF0gKSAmJiAhaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0XHRcdC8vIERvbid0IHJlLXRyaWdnZXIgYW4gb25GT08gZXZlbnQgd2hlbiB3ZSBjYWxsIGl0cyBGT08oKSBtZXRob2Rcblx0XHRcdFx0XHR0bXAgPSBlbGVtWyBvbnR5cGUgXTtcblxuXHRcdFx0XHRcdGlmICggdG1wICkge1xuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSBudWxsO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFByZXZlbnQgcmUtdHJpZ2dlcmluZyBvZiB0aGUgc2FtZSBldmVudCwgc2luY2Ugd2UgYWxyZWFkeSBidWJibGVkIGl0IGFib3ZlXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHR5cGU7XG5cblx0XHRcdFx0XHRpZiAoIGV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cdFx0XHRcdFx0XHRsYXN0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCB0eXBlLCBzdG9wUHJvcGFnYXRpb25DYWxsYmFjayApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGVsZW1bIHR5cGUgXSgpO1xuXG5cdFx0XHRcdFx0aWYgKCBldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0XHRcdFx0bGFzdEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgc3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRcdFx0aWYgKCB0bXAgKSB7XG5cdFx0XHRcdFx0XHRlbGVtWyBvbnR5cGUgXSA9IHRtcDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xuXHR9LFxuXG5cdC8vIFBpZ2d5YmFjayBvbiBhIGRvbm9yIGV2ZW50IHRvIHNpbXVsYXRlIGEgZGlmZmVyZW50IG9uZVxuXHQvLyBVc2VkIG9ubHkgZm9yIGBmb2N1cyhpbiB8IG91dClgIGV2ZW50c1xuXHRzaW11bGF0ZTogZnVuY3Rpb24oIHR5cGUsIGVsZW0sIGV2ZW50ICkge1xuXHRcdHZhciBlID0galF1ZXJ5LmV4dGVuZChcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoKSxcblx0XHRcdGV2ZW50LFxuXHRcdFx0e1xuXHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRpc1NpbXVsYXRlZDogdHJ1ZVxuXHRcdFx0fVxuXHRcdCk7XG5cblx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggZSwgbnVsbCwgZWxlbSApO1xuXHR9XG5cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIHRoaXMgKTtcblx0XHR9ICk7XG5cdH0sXG5cdHRyaWdnZXJIYW5kbGVyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgZWxlbSA9IHRoaXNbIDAgXTtcblx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIGVsZW0sIHRydWUgKTtcblx0XHR9XG5cdH1cbn0gKTtcblxuXG4vLyBTdXBwb3J0OiBGaXJlZm94IDw9NDRcbi8vIEZpcmVmb3ggZG9lc24ndCBoYXZlIGZvY3VzKGluIHwgb3V0KSBldmVudHNcbi8vIFJlbGF0ZWQgdGlja2V0IC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njg3Nzg3XG4vL1xuLy8gU3VwcG9ydDogQ2hyb21lIDw9NDggLSA0OSwgU2FmYXJpIDw9OS4wIC0gOS4xXG4vLyBmb2N1cyhpbiB8IG91dCkgZXZlbnRzIGZpcmUgYWZ0ZXIgZm9jdXMgJiBibHVyIGV2ZW50cyxcbi8vIHdoaWNoIGlzIHNwZWMgdmlvbGF0aW9uIC0gaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtZm9jdXNldmVudC1ldmVudC1vcmRlclxuLy8gUmVsYXRlZCB0aWNrZXQgLSBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NDk4NTdcbmlmICggIXN1cHBvcnQuZm9jdXNpbiApIHtcblx0alF1ZXJ5LmVhY2goIHsgZm9jdXM6IFwiZm9jdXNpblwiLCBibHVyOiBcImZvY3Vzb3V0XCIgfSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblxuXHRcdC8vIEF0dGFjaCBhIHNpbmdsZSBjYXB0dXJpbmcgaGFuZGxlciBvbiB0aGUgZG9jdW1lbnQgd2hpbGUgc29tZW9uZSB3YW50cyBmb2N1c2luL2ZvY3Vzb3V0XG5cdFx0dmFyIGhhbmRsZXIgPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuc2ltdWxhdGUoIGZpeCwgZXZlbnQudGFyZ2V0LCBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApICk7XG5cdFx0fTtcblxuXHRcdGpRdWVyeS5ldmVudC5zcGVjaWFsWyBmaXggXSA9IHtcblx0XHRcdHNldHVwOiBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBIYW5kbGU6IHJlZ3VsYXIgbm9kZXMgKHZpYSBgdGhpcy5vd25lckRvY3VtZW50YCksIHdpbmRvd1xuXHRcdFx0XHQvLyAodmlhIGB0aGlzLmRvY3VtZW50YCkgJiBkb2N1bWVudCAodmlhIGB0aGlzYCkuXG5cdFx0XHRcdHZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcy5kb2N1bWVudCB8fCB0aGlzLFxuXHRcdFx0XHRcdGF0dGFjaGVzID0gZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCApO1xuXG5cdFx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRcdGRvYy5hZGRFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCwgKCBhdHRhY2hlcyB8fCAwICkgKyAxICk7XG5cdFx0XHR9LFxuXHRcdFx0dGVhcmRvd246IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMuZG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0XHRhdHRhY2hlcyA9IGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXggKSAtIDE7XG5cblx0XHRcdFx0aWYgKCAhYXR0YWNoZXMgKSB7XG5cdFx0XHRcdFx0ZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTtcblx0XHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGRvYywgZml4ICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4LCBhdHRhY2hlcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fSApO1xufVxudmFyIGxvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uO1xuXG52YXIgbm9uY2UgPSB7IGd1aWQ6IERhdGUubm93KCkgfTtcblxudmFyIHJxdWVyeSA9ICggL1xcPy8gKTtcblxuXG5cbi8vIENyb3NzLWJyb3dzZXIgeG1sIHBhcnNpbmdcbmpRdWVyeS5wYXJzZVhNTCA9IGZ1bmN0aW9uKCBkYXRhICkge1xuXHR2YXIgeG1sO1xuXHRpZiAoICFkYXRhIHx8IHR5cGVvZiBkYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExIG9ubHlcblx0Ly8gSUUgdGhyb3dzIG9uIHBhcnNlRnJvbVN0cmluZyB3aXRoIGludmFsaWQgaW5wdXQuXG5cdHRyeSB7XG5cdFx0eG1sID0gKCBuZXcgd2luZG93LkRPTVBhcnNlcigpICkucGFyc2VGcm9tU3RyaW5nKCBkYXRhLCBcInRleHQveG1sXCIgKTtcblx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0eG1sID0gdW5kZWZpbmVkO1xuXHR9XG5cblx0aWYgKCAheG1sIHx8IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJwYXJzZXJlcnJvclwiICkubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5lcnJvciggXCJJbnZhbGlkIFhNTDogXCIgKyBkYXRhICk7XG5cdH1cblx0cmV0dXJuIHhtbDtcbn07XG5cblxudmFyXG5cdHJicmFja2V0ID0gL1xcW1xcXSQvLFxuXHRyQ1JMRiA9IC9cXHI/XFxuL2csXG5cdHJzdWJtaXR0ZXJUeXBlcyA9IC9eKD86c3VibWl0fGJ1dHRvbnxpbWFnZXxyZXNldHxmaWxlKSQvaSxcblx0cnN1Ym1pdHRhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO1xuXG5mdW5jdGlvbiBidWlsZFBhcmFtcyggcHJlZml4LCBvYmosIHRyYWRpdGlvbmFsLCBhZGQgKSB7XG5cdHZhciBuYW1lO1xuXG5cdGlmICggQXJyYXkuaXNBcnJheSggb2JqICkgKSB7XG5cblx0XHQvLyBTZXJpYWxpemUgYXJyYXkgaXRlbS5cblx0XHRqUXVlcnkuZWFjaCggb2JqLCBmdW5jdGlvbiggaSwgdiApIHtcblx0XHRcdGlmICggdHJhZGl0aW9uYWwgfHwgcmJyYWNrZXQudGVzdCggcHJlZml4ICkgKSB7XG5cblx0XHRcdFx0Ly8gVHJlYXQgZWFjaCBhcnJheSBpdGVtIGFzIGEgc2NhbGFyLlxuXHRcdFx0XHRhZGQoIHByZWZpeCwgdiApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIEl0ZW0gaXMgbm9uLXNjYWxhciAoYXJyYXkgb3Igb2JqZWN0KSwgZW5jb2RlIGl0cyBudW1lcmljIGluZGV4LlxuXHRcdFx0XHRidWlsZFBhcmFtcyhcblx0XHRcdFx0XHRwcmVmaXggKyBcIltcIiArICggdHlwZW9mIHYgPT09IFwib2JqZWN0XCIgJiYgdiAhPSBudWxsID8gaSA6IFwiXCIgKSArIFwiXVwiLFxuXHRcdFx0XHRcdHYsXG5cdFx0XHRcdFx0dHJhZGl0aW9uYWwsXG5cdFx0XHRcdFx0YWRkXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXG5cdH0gZWxzZSBpZiAoICF0cmFkaXRpb25hbCAmJiB0b1R5cGUoIG9iaiApID09PSBcIm9iamVjdFwiICkge1xuXG5cdFx0Ly8gU2VyaWFsaXplIG9iamVjdCBpdGVtLlxuXHRcdGZvciAoIG5hbWUgaW4gb2JqICkge1xuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCArIFwiW1wiICsgbmFtZSArIFwiXVwiLCBvYmpbIG5hbWUgXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xuXHRcdH1cblxuXHR9IGVsc2Uge1xuXG5cdFx0Ly8gU2VyaWFsaXplIHNjYWxhciBpdGVtLlxuXHRcdGFkZCggcHJlZml4LCBvYmogKTtcblx0fVxufVxuXG4vLyBTZXJpYWxpemUgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cyBvciBhIHNldCBvZlxuLy8ga2V5L3ZhbHVlcyBpbnRvIGEgcXVlcnkgc3RyaW5nXG5qUXVlcnkucGFyYW0gPSBmdW5jdGlvbiggYSwgdHJhZGl0aW9uYWwgKSB7XG5cdHZhciBwcmVmaXgsXG5cdFx0cyA9IFtdLFxuXHRcdGFkZCA9IGZ1bmN0aW9uKCBrZXksIHZhbHVlT3JGdW5jdGlvbiApIHtcblxuXHRcdFx0Ly8gSWYgdmFsdWUgaXMgYSBmdW5jdGlvbiwgaW52b2tlIGl0IGFuZCB1c2UgaXRzIHJldHVybiB2YWx1ZVxuXHRcdFx0dmFyIHZhbHVlID0gaXNGdW5jdGlvbiggdmFsdWVPckZ1bmN0aW9uICkgP1xuXHRcdFx0XHR2YWx1ZU9yRnVuY3Rpb24oKSA6XG5cdFx0XHRcdHZhbHVlT3JGdW5jdGlvbjtcblxuXHRcdFx0c1sgcy5sZW5ndGggXSA9IGVuY29kZVVSSUNvbXBvbmVudCgga2V5ICkgKyBcIj1cIiArXG5cdFx0XHRcdGVuY29kZVVSSUNvbXBvbmVudCggdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSApO1xuXHRcdH07XG5cblx0aWYgKCBhID09IG51bGwgKSB7XG5cdFx0cmV0dXJuIFwiXCI7XG5cdH1cblxuXHQvLyBJZiBhbiBhcnJheSB3YXMgcGFzc2VkIGluLCBhc3N1bWUgdGhhdCBpdCBpcyBhbiBhcnJheSBvZiBmb3JtIGVsZW1lbnRzLlxuXHRpZiAoIEFycmF5LmlzQXJyYXkoIGEgKSB8fCAoIGEuanF1ZXJ5ICYmICFqUXVlcnkuaXNQbGFpbk9iamVjdCggYSApICkgKSB7XG5cblx0XHQvLyBTZXJpYWxpemUgdGhlIGZvcm0gZWxlbWVudHNcblx0XHRqUXVlcnkuZWFjaCggYSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRhZGQoIHRoaXMubmFtZSwgdGhpcy52YWx1ZSApO1xuXHRcdH0gKTtcblxuXHR9IGVsc2Uge1xuXG5cdFx0Ly8gSWYgdHJhZGl0aW9uYWwsIGVuY29kZSB0aGUgXCJvbGRcIiB3YXkgKHRoZSB3YXkgMS4zLjIgb3Igb2xkZXJcblx0XHQvLyBkaWQgaXQpLCBvdGhlcndpc2UgZW5jb2RlIHBhcmFtcyByZWN1cnNpdmVseS5cblx0XHRmb3IgKCBwcmVmaXggaW4gYSApIHtcblx0XHRcdGJ1aWxkUGFyYW1zKCBwcmVmaXgsIGFbIHByZWZpeCBdLCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSByZXN1bHRpbmcgc2VyaWFsaXphdGlvblxuXHRyZXR1cm4gcy5qb2luKCBcIiZcIiApO1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRzZXJpYWxpemU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBqUXVlcnkucGFyYW0oIHRoaXMuc2VyaWFsaXplQXJyYXkoKSApO1xuXHR9LFxuXHRzZXJpYWxpemVBcnJheTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFwKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gQ2FuIGFkZCBwcm9wSG9vayBmb3IgXCJlbGVtZW50c1wiIHRvIGZpbHRlciBvciBhZGQgZm9ybSBlbGVtZW50c1xuXHRcdFx0dmFyIGVsZW1lbnRzID0galF1ZXJ5LnByb3AoIHRoaXMsIFwiZWxlbWVudHNcIiApO1xuXHRcdFx0cmV0dXJuIGVsZW1lbnRzID8galF1ZXJ5Lm1ha2VBcnJheSggZWxlbWVudHMgKSA6IHRoaXM7XG5cdFx0fSApXG5cdFx0LmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgdHlwZSA9IHRoaXMudHlwZTtcblxuXHRcdFx0Ly8gVXNlIC5pcyggXCI6ZGlzYWJsZWRcIiApIHNvIHRoYXQgZmllbGRzZXRbZGlzYWJsZWRdIHdvcmtzXG5cdFx0XHRyZXR1cm4gdGhpcy5uYW1lICYmICFqUXVlcnkoIHRoaXMgKS5pcyggXCI6ZGlzYWJsZWRcIiApICYmXG5cdFx0XHRcdHJzdWJtaXR0YWJsZS50ZXN0KCB0aGlzLm5vZGVOYW1lICkgJiYgIXJzdWJtaXR0ZXJUeXBlcy50ZXN0KCB0eXBlICkgJiZcblx0XHRcdFx0KCB0aGlzLmNoZWNrZWQgfHwgIXJjaGVja2FibGVUeXBlLnRlc3QoIHR5cGUgKSApO1xuXHRcdH0gKVxuXHRcdC5tYXAoIGZ1bmN0aW9uKCBfaSwgZWxlbSApIHtcblx0XHRcdHZhciB2YWwgPSBqUXVlcnkoIHRoaXMgKS52YWwoKTtcblxuXHRcdFx0aWYgKCB2YWwgPT0gbnVsbCApIHtcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSggdmFsICkgKSB7XG5cdFx0XHRcdHJldHVybiBqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHsgbmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsLnJlcGxhY2UoIHJDUkxGLCBcIlxcclxcblwiICkgfTtcblx0XHRcdFx0fSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4geyBuYW1lOiBlbGVtLm5hbWUsIHZhbHVlOiB2YWwucmVwbGFjZSggckNSTEYsIFwiXFxyXFxuXCIgKSB9O1xuXHRcdH0gKS5nZXQoKTtcblx0fVxufSApO1xuXG5cbnZhclxuXHRyMjAgPSAvJTIwL2csXG5cdHJoYXNoID0gLyMuKiQvLFxuXHRyYW50aUNhY2hlID0gLyhbPyZdKV89W14mXSovLFxuXHRyaGVhZGVycyA9IC9eKC4qPyk6WyBcXHRdKihbXlxcclxcbl0qKSQvbWcsXG5cblx0Ly8gIzc2NTMsICM4MTI1LCAjODE1MjogbG9jYWwgcHJvdG9jb2wgZGV0ZWN0aW9uXG5cdHJsb2NhbFByb3RvY29sID0gL14oPzphYm91dHxhcHB8YXBwLXN0b3JhZ2V8ListZXh0ZW5zaW9ufGZpbGV8cmVzfHdpZGdldCk6JC8sXG5cdHJub0NvbnRlbnQgPSAvXig/OkdFVHxIRUFEKSQvLFxuXHRycHJvdG9jb2wgPSAvXlxcL1xcLy8sXG5cblx0LyogUHJlZmlsdGVyc1xuXHQgKiAxKSBUaGV5IGFyZSB1c2VmdWwgdG8gaW50cm9kdWNlIGN1c3RvbSBkYXRhVHlwZXMgKHNlZSBhamF4L2pzb25wLmpzIGZvciBhbiBleGFtcGxlKVxuXHQgKiAyKSBUaGVzZSBhcmUgY2FsbGVkOlxuXHQgKiAgICAtIEJFRk9SRSBhc2tpbmcgZm9yIGEgdHJhbnNwb3J0XG5cdCAqICAgIC0gQUZURVIgcGFyYW0gc2VyaWFsaXphdGlvbiAocy5kYXRhIGlzIGEgc3RyaW5nIGlmIHMucHJvY2Vzc0RhdGEgaXMgdHJ1ZSlcblx0ICogMykga2V5IGlzIHRoZSBkYXRhVHlwZVxuXHQgKiA0KSB0aGUgY2F0Y2hhbGwgc3ltYm9sIFwiKlwiIGNhbiBiZSB1c2VkXG5cdCAqIDUpIGV4ZWN1dGlvbiB3aWxsIHN0YXJ0IHdpdGggdHJhbnNwb3J0IGRhdGFUeXBlIGFuZCBUSEVOIGNvbnRpbnVlIGRvd24gdG8gXCIqXCIgaWYgbmVlZGVkXG5cdCAqL1xuXHRwcmVmaWx0ZXJzID0ge30sXG5cblx0LyogVHJhbnNwb3J0cyBiaW5kaW5nc1xuXHQgKiAxKSBrZXkgaXMgdGhlIGRhdGFUeXBlXG5cdCAqIDIpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcblx0ICogMykgc2VsZWN0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gZ28gdG8gXCIqXCIgaWYgbmVlZGVkXG5cdCAqL1xuXHR0cmFuc3BvcnRzID0ge30sXG5cblx0Ly8gQXZvaWQgY29tbWVudC1wcm9sb2cgY2hhciBzZXF1ZW5jZSAoIzEwMDk4KTsgbXVzdCBhcHBlYXNlIGxpbnQgYW5kIGV2YWRlIGNvbXByZXNzaW9uXG5cdGFsbFR5cGVzID0gXCIqL1wiLmNvbmNhdCggXCIqXCIgKSxcblxuXHQvLyBBbmNob3IgdGFnIGZvciBwYXJzaW5nIHRoZSBkb2N1bWVudCBvcmlnaW5cblx0b3JpZ2luQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJhXCIgKTtcblx0b3JpZ2luQW5jaG9yLmhyZWYgPSBsb2NhdGlvbi5ocmVmO1xuXG4vLyBCYXNlIFwiY29uc3RydWN0b3JcIiBmb3IgalF1ZXJ5LmFqYXhQcmVmaWx0ZXIgYW5kIGpRdWVyeS5hamF4VHJhbnNwb3J0XG5mdW5jdGlvbiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSApIHtcblxuXHQvLyBkYXRhVHlwZUV4cHJlc3Npb24gaXMgb3B0aW9uYWwgYW5kIGRlZmF1bHRzIHRvIFwiKlwiXG5cdHJldHVybiBmdW5jdGlvbiggZGF0YVR5cGVFeHByZXNzaW9uLCBmdW5jICkge1xuXG5cdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVFeHByZXNzaW9uICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0ZnVuYyA9IGRhdGFUeXBlRXhwcmVzc2lvbjtcblx0XHRcdGRhdGFUeXBlRXhwcmVzc2lvbiA9IFwiKlwiO1xuXHRcdH1cblxuXHRcdHZhciBkYXRhVHlwZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0ZGF0YVR5cGVzID0gZGF0YVR5cGVFeHByZXNzaW9uLnRvTG93ZXJDYXNlKCkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbXTtcblxuXHRcdGlmICggaXNGdW5jdGlvbiggZnVuYyApICkge1xuXG5cdFx0XHQvLyBGb3IgZWFjaCBkYXRhVHlwZSBpbiB0aGUgZGF0YVR5cGVFeHByZXNzaW9uXG5cdFx0XHR3aGlsZSAoICggZGF0YVR5cGUgPSBkYXRhVHlwZXNbIGkrKyBdICkgKSB7XG5cblx0XHRcdFx0Ly8gUHJlcGVuZCBpZiByZXF1ZXN0ZWRcblx0XHRcdFx0aWYgKCBkYXRhVHlwZVsgMCBdID09PSBcIitcIiApIHtcblx0XHRcdFx0XHRkYXRhVHlwZSA9IGRhdGFUeXBlLnNsaWNlKCAxICkgfHwgXCIqXCI7XG5cdFx0XHRcdFx0KCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gPSBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10gKS51bnNoaWZ0KCBmdW5jICk7XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdCggc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdICkucHVzaCggZnVuYyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xufVxuXG4vLyBCYXNlIGluc3BlY3Rpb24gZnVuY3Rpb24gZm9yIHByZWZpbHRlcnMgYW5kIHRyYW5zcG9ydHNcbmZ1bmN0aW9uIGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBzdHJ1Y3R1cmUsIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKSB7XG5cblx0dmFyIGluc3BlY3RlZCA9IHt9LFxuXHRcdHNlZWtpbmdUcmFuc3BvcnQgPSAoIHN0cnVjdHVyZSA9PT0gdHJhbnNwb3J0cyApO1xuXG5cdGZ1bmN0aW9uIGluc3BlY3QoIGRhdGFUeXBlICkge1xuXHRcdHZhciBzZWxlY3RlZDtcblx0XHRpbnNwZWN0ZWRbIGRhdGFUeXBlIF0gPSB0cnVlO1xuXHRcdGpRdWVyeS5lYWNoKCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10sIGZ1bmN0aW9uKCBfLCBwcmVmaWx0ZXJPckZhY3RvcnkgKSB7XG5cdFx0XHR2YXIgZGF0YVR5cGVPclRyYW5zcG9ydCA9IHByZWZpbHRlck9yRmFjdG9yeSggb3B0aW9ucywgb3JpZ2luYWxPcHRpb25zLCBqcVhIUiApO1xuXHRcdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVPclRyYW5zcG9ydCA9PT0gXCJzdHJpbmdcIiAmJlxuXHRcdFx0XHQhc2Vla2luZ1RyYW5zcG9ydCAmJiAhaW5zcGVjdGVkWyBkYXRhVHlwZU9yVHJhbnNwb3J0IF0gKSB7XG5cblx0XHRcdFx0b3B0aW9ucy5kYXRhVHlwZXMudW5zaGlmdCggZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0XHRpbnNwZWN0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0gZWxzZSBpZiAoIHNlZWtpbmdUcmFuc3BvcnQgKSB7XG5cdFx0XHRcdHJldHVybiAhKCBzZWxlY3RlZCA9IGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdFx0cmV0dXJuIHNlbGVjdGVkO1xuXHR9XG5cblx0cmV0dXJuIGluc3BlY3QoIG9wdGlvbnMuZGF0YVR5cGVzWyAwIF0gKSB8fCAhaW5zcGVjdGVkWyBcIipcIiBdICYmIGluc3BlY3QoIFwiKlwiICk7XG59XG5cbi8vIEEgc3BlY2lhbCBleHRlbmQgZm9yIGFqYXggb3B0aW9uc1xuLy8gdGhhdCB0YWtlcyBcImZsYXRcIiBvcHRpb25zIChub3QgdG8gYmUgZGVlcCBleHRlbmRlZClcbi8vIEZpeGVzICM5ODg3XG5mdW5jdGlvbiBhamF4RXh0ZW5kKCB0YXJnZXQsIHNyYyApIHtcblx0dmFyIGtleSwgZGVlcCxcblx0XHRmbGF0T3B0aW9ucyA9IGpRdWVyeS5hamF4U2V0dGluZ3MuZmxhdE9wdGlvbnMgfHwge307XG5cblx0Zm9yICgga2V5IGluIHNyYyApIHtcblx0XHRpZiAoIHNyY1sga2V5IF0gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdCggZmxhdE9wdGlvbnNbIGtleSBdID8gdGFyZ2V0IDogKCBkZWVwIHx8ICggZGVlcCA9IHt9ICkgKSApWyBrZXkgXSA9IHNyY1sga2V5IF07XG5cdFx0fVxuXHR9XG5cdGlmICggZGVlcCApIHtcblx0XHRqUXVlcnkuZXh0ZW5kKCB0cnVlLCB0YXJnZXQsIGRlZXAgKTtcblx0fVxuXG5cdHJldHVybiB0YXJnZXQ7XG59XG5cbi8qIEhhbmRsZXMgcmVzcG9uc2VzIHRvIGFuIGFqYXggcmVxdWVzdDpcbiAqIC0gZmluZHMgdGhlIHJpZ2h0IGRhdGFUeXBlIChtZWRpYXRlcyBiZXR3ZWVuIGNvbnRlbnQtdHlwZSBhbmQgZXhwZWN0ZWQgZGF0YVR5cGUpXG4gKiAtIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2VcbiAqL1xuZnVuY3Rpb24gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApIHtcblxuXHR2YXIgY3QsIHR5cGUsIGZpbmFsRGF0YVR5cGUsIGZpcnN0RGF0YVR5cGUsXG5cdFx0Y29udGVudHMgPSBzLmNvbnRlbnRzLFxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzO1xuXG5cdC8vIFJlbW92ZSBhdXRvIGRhdGFUeXBlIGFuZCBnZXQgY29udGVudC10eXBlIGluIHRoZSBwcm9jZXNzXG5cdHdoaWxlICggZGF0YVR5cGVzWyAwIF0gPT09IFwiKlwiICkge1xuXHRcdGRhdGFUeXBlcy5zaGlmdCgpO1xuXHRcdGlmICggY3QgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGN0ID0gcy5taW1lVHlwZSB8fCBqcVhIUi5nZXRSZXNwb25zZUhlYWRlciggXCJDb250ZW50LVR5cGVcIiApO1xuXHRcdH1cblx0fVxuXG5cdC8vIENoZWNrIGlmIHdlJ3JlIGRlYWxpbmcgd2l0aCBhIGtub3duIGNvbnRlbnQtdHlwZVxuXHRpZiAoIGN0ICkge1xuXHRcdGZvciAoIHR5cGUgaW4gY29udGVudHMgKSB7XG5cdFx0XHRpZiAoIGNvbnRlbnRzWyB0eXBlIF0gJiYgY29udGVudHNbIHR5cGUgXS50ZXN0KCBjdCApICkge1xuXHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdHlwZSApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBDaGVjayB0byBzZWUgaWYgd2UgaGF2ZSBhIHJlc3BvbnNlIGZvciB0aGUgZXhwZWN0ZWQgZGF0YVR5cGVcblx0aWYgKCBkYXRhVHlwZXNbIDAgXSBpbiByZXNwb25zZXMgKSB7XG5cdFx0ZmluYWxEYXRhVHlwZSA9IGRhdGFUeXBlc1sgMCBdO1xuXHR9IGVsc2Uge1xuXG5cdFx0Ly8gVHJ5IGNvbnZlcnRpYmxlIGRhdGFUeXBlc1xuXHRcdGZvciAoIHR5cGUgaW4gcmVzcG9uc2VzICkge1xuXHRcdFx0aWYgKCAhZGF0YVR5cGVzWyAwIF0gfHwgcy5jb252ZXJ0ZXJzWyB0eXBlICsgXCIgXCIgKyBkYXRhVHlwZXNbIDAgXSBdICkge1xuXHRcdFx0XHRmaW5hbERhdGFUeXBlID0gdHlwZTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoICFmaXJzdERhdGFUeXBlICkge1xuXHRcdFx0XHRmaXJzdERhdGFUeXBlID0gdHlwZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBPciBqdXN0IHVzZSBmaXJzdCBvbmVcblx0XHRmaW5hbERhdGFUeXBlID0gZmluYWxEYXRhVHlwZSB8fCBmaXJzdERhdGFUeXBlO1xuXHR9XG5cblx0Ly8gSWYgd2UgZm91bmQgYSBkYXRhVHlwZVxuXHQvLyBXZSBhZGQgdGhlIGRhdGFUeXBlIHRvIHRoZSBsaXN0IGlmIG5lZWRlZFxuXHQvLyBhbmQgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIHJlc3BvbnNlXG5cdGlmICggZmluYWxEYXRhVHlwZSApIHtcblx0XHRpZiAoIGZpbmFsRGF0YVR5cGUgIT09IGRhdGFUeXBlc1sgMCBdICkge1xuXHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIGZpbmFsRGF0YVR5cGUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIHJlc3BvbnNlc1sgZmluYWxEYXRhVHlwZSBdO1xuXHR9XG59XG5cbi8qIENoYWluIGNvbnZlcnNpb25zIGdpdmVuIHRoZSByZXF1ZXN0IGFuZCB0aGUgb3JpZ2luYWwgcmVzcG9uc2VcbiAqIEFsc28gc2V0cyB0aGUgcmVzcG9uc2VYWFggZmllbGRzIG9uIHRoZSBqcVhIUiBpbnN0YW5jZVxuICovXG5mdW5jdGlvbiBhamF4Q29udmVydCggcywgcmVzcG9uc2UsIGpxWEhSLCBpc1N1Y2Nlc3MgKSB7XG5cdHZhciBjb252MiwgY3VycmVudCwgY29udiwgdG1wLCBwcmV2LFxuXHRcdGNvbnZlcnRlcnMgPSB7fSxcblxuXHRcdC8vIFdvcmsgd2l0aCBhIGNvcHkgb2YgZGF0YVR5cGVzIGluIGNhc2Ugd2UgbmVlZCB0byBtb2RpZnkgaXQgZm9yIGNvbnZlcnNpb25cblx0XHRkYXRhVHlwZXMgPSBzLmRhdGFUeXBlcy5zbGljZSgpO1xuXG5cdC8vIENyZWF0ZSBjb252ZXJ0ZXJzIG1hcCB3aXRoIGxvd2VyY2FzZWQga2V5c1xuXHRpZiAoIGRhdGFUeXBlc1sgMSBdICkge1xuXHRcdGZvciAoIGNvbnYgaW4gcy5jb252ZXJ0ZXJzICkge1xuXHRcdFx0Y29udmVydGVyc1sgY29udi50b0xvd2VyQ2FzZSgpIF0gPSBzLmNvbnZlcnRlcnNbIGNvbnYgXTtcblx0XHR9XG5cdH1cblxuXHRjdXJyZW50ID0gZGF0YVR5cGVzLnNoaWZ0KCk7XG5cblx0Ly8gQ29udmVydCB0byBlYWNoIHNlcXVlbnRpYWwgZGF0YVR5cGVcblx0d2hpbGUgKCBjdXJyZW50ICkge1xuXG5cdFx0aWYgKCBzLnJlc3BvbnNlRmllbGRzWyBjdXJyZW50IF0gKSB7XG5cdFx0XHRqcVhIUlsgcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdIF0gPSByZXNwb25zZTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSB0aGUgZGF0YUZpbHRlciBpZiBwcm92aWRlZFxuXHRcdGlmICggIXByZXYgJiYgaXNTdWNjZXNzICYmIHMuZGF0YUZpbHRlciApIHtcblx0XHRcdHJlc3BvbnNlID0gcy5kYXRhRmlsdGVyKCByZXNwb25zZSwgcy5kYXRhVHlwZSApO1xuXHRcdH1cblxuXHRcdHByZXYgPSBjdXJyZW50O1xuXHRcdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcblxuXHRcdGlmICggY3VycmVudCApIHtcblxuXHRcdFx0Ly8gVGhlcmUncyBvbmx5IHdvcmsgdG8gZG8gaWYgY3VycmVudCBkYXRhVHlwZSBpcyBub24tYXV0b1xuXHRcdFx0aWYgKCBjdXJyZW50ID09PSBcIipcIiApIHtcblxuXHRcdFx0XHRjdXJyZW50ID0gcHJldjtcblxuXHRcdFx0Ly8gQ29udmVydCByZXNwb25zZSBpZiBwcmV2IGRhdGFUeXBlIGlzIG5vbi1hdXRvIGFuZCBkaWZmZXJzIGZyb20gY3VycmVudFxuXHRcdFx0fSBlbHNlIGlmICggcHJldiAhPT0gXCIqXCIgJiYgcHJldiAhPT0gY3VycmVudCApIHtcblxuXHRcdFx0XHQvLyBTZWVrIGEgZGlyZWN0IGNvbnZlcnRlclxuXHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgY3VycmVudCBdIHx8IGNvbnZlcnRlcnNbIFwiKiBcIiArIGN1cnJlbnQgXTtcblxuXHRcdFx0XHQvLyBJZiBub25lIGZvdW5kLCBzZWVrIGEgcGFpclxuXHRcdFx0XHRpZiAoICFjb252ICkge1xuXHRcdFx0XHRcdGZvciAoIGNvbnYyIGluIGNvbnZlcnRlcnMgKSB7XG5cblx0XHRcdFx0XHRcdC8vIElmIGNvbnYyIG91dHB1dHMgY3VycmVudFxuXHRcdFx0XHRcdFx0dG1wID0gY29udjIuc3BsaXQoIFwiIFwiICk7XG5cdFx0XHRcdFx0XHRpZiAoIHRtcFsgMSBdID09PSBjdXJyZW50ICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIElmIHByZXYgY2FuIGJlIGNvbnZlcnRlZCB0byBhY2NlcHRlZCBpbnB1dFxuXHRcdFx0XHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgdG1wWyAwIF0gXSB8fFxuXHRcdFx0XHRcdFx0XHRcdGNvbnZlcnRlcnNbIFwiKiBcIiArIHRtcFsgMCBdIF07XG5cdFx0XHRcdFx0XHRcdGlmICggY29udiApIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIENvbmRlbnNlIGVxdWl2YWxlbmNlIGNvbnZlcnRlcnNcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGNvbnYgPT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgY29udjIgXTtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIE90aGVyd2lzZSwgaW5zZXJ0IHRoZSBpbnRlcm1lZGlhdGUgZGF0YVR5cGVcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBjb252ZXJ0ZXJzWyBjb252MiBdICE9PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y3VycmVudCA9IHRtcFsgMCBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIHRtcFsgMSBdICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXBwbHkgY29udmVydGVyIChpZiBub3QgYW4gZXF1aXZhbGVuY2UpXG5cdFx0XHRcdGlmICggY29udiAhPT0gdHJ1ZSApIHtcblxuXHRcdFx0XHRcdC8vIFVubGVzcyBlcnJvcnMgYXJlIGFsbG93ZWQgdG8gYnViYmxlLCBjYXRjaCBhbmQgcmV0dXJuIHRoZW1cblx0XHRcdFx0XHRpZiAoIGNvbnYgJiYgcy50aHJvd3MgKSB7XG5cdFx0XHRcdFx0XHRyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdHJlc3BvbnNlID0gY29udiggcmVzcG9uc2UgKTtcblx0XHRcdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0XHRcdHN0YXRlOiBcInBhcnNlcmVycm9yXCIsXG5cdFx0XHRcdFx0XHRcdFx0ZXJyb3I6IGNvbnYgPyBlIDogXCJObyBjb252ZXJzaW9uIGZyb20gXCIgKyBwcmV2ICsgXCIgdG8gXCIgKyBjdXJyZW50XG5cdFx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHsgc3RhdGU6IFwic3VjY2Vzc1wiLCBkYXRhOiByZXNwb25zZSB9O1xufVxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cblx0Ly8gQ291bnRlciBmb3IgaG9sZGluZyB0aGUgbnVtYmVyIG9mIGFjdGl2ZSBxdWVyaWVzXG5cdGFjdGl2ZTogMCxcblxuXHQvLyBMYXN0LU1vZGlmaWVkIGhlYWRlciBjYWNoZSBmb3IgbmV4dCByZXF1ZXN0XG5cdGxhc3RNb2RpZmllZDoge30sXG5cdGV0YWc6IHt9LFxuXG5cdGFqYXhTZXR0aW5nczoge1xuXHRcdHVybDogbG9jYXRpb24uaHJlZixcblx0XHR0eXBlOiBcIkdFVFwiLFxuXHRcdGlzTG9jYWw6IHJsb2NhbFByb3RvY29sLnRlc3QoIGxvY2F0aW9uLnByb3RvY29sICksXG5cdFx0Z2xvYmFsOiB0cnVlLFxuXHRcdHByb2Nlc3NEYXRhOiB0cnVlLFxuXHRcdGFzeW5jOiB0cnVlLFxuXHRcdGNvbnRlbnRUeXBlOiBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDsgY2hhcnNldD1VVEYtOFwiLFxuXG5cdFx0Lypcblx0XHR0aW1lb3V0OiAwLFxuXHRcdGRhdGE6IG51bGwsXG5cdFx0ZGF0YVR5cGU6IG51bGwsXG5cdFx0dXNlcm5hbWU6IG51bGwsXG5cdFx0cGFzc3dvcmQ6IG51bGwsXG5cdFx0Y2FjaGU6IG51bGwsXG5cdFx0dGhyb3dzOiBmYWxzZSxcblx0XHR0cmFkaXRpb25hbDogZmFsc2UsXG5cdFx0aGVhZGVyczoge30sXG5cdFx0Ki9cblxuXHRcdGFjY2VwdHM6IHtcblx0XHRcdFwiKlwiOiBhbGxUeXBlcyxcblx0XHRcdHRleHQ6IFwidGV4dC9wbGFpblwiLFxuXHRcdFx0aHRtbDogXCJ0ZXh0L2h0bWxcIixcblx0XHRcdHhtbDogXCJhcHBsaWNhdGlvbi94bWwsIHRleHQveG1sXCIsXG5cdFx0XHRqc29uOiBcImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdFwiXG5cdFx0fSxcblxuXHRcdGNvbnRlbnRzOiB7XG5cdFx0XHR4bWw6IC9cXGJ4bWxcXGIvLFxuXHRcdFx0aHRtbDogL1xcYmh0bWwvLFxuXHRcdFx0anNvbjogL1xcYmpzb25cXGIvXG5cdFx0fSxcblxuXHRcdHJlc3BvbnNlRmllbGRzOiB7XG5cdFx0XHR4bWw6IFwicmVzcG9uc2VYTUxcIixcblx0XHRcdHRleHQ6IFwicmVzcG9uc2VUZXh0XCIsXG5cdFx0XHRqc29uOiBcInJlc3BvbnNlSlNPTlwiXG5cdFx0fSxcblxuXHRcdC8vIERhdGEgY29udmVydGVyc1xuXHRcdC8vIEtleXMgc2VwYXJhdGUgc291cmNlIChvciBjYXRjaGFsbCBcIipcIikgYW5kIGRlc3RpbmF0aW9uIHR5cGVzIHdpdGggYSBzaW5nbGUgc3BhY2Vcblx0XHRjb252ZXJ0ZXJzOiB7XG5cblx0XHRcdC8vIENvbnZlcnQgYW55dGhpbmcgdG8gdGV4dFxuXHRcdFx0XCIqIHRleHRcIjogU3RyaW5nLFxuXG5cdFx0XHQvLyBUZXh0IHRvIGh0bWwgKHRydWUgPSBubyB0cmFuc2Zvcm1hdGlvbilcblx0XHRcdFwidGV4dCBodG1sXCI6IHRydWUsXG5cblx0XHRcdC8vIEV2YWx1YXRlIHRleHQgYXMgYSBqc29uIGV4cHJlc3Npb25cblx0XHRcdFwidGV4dCBqc29uXCI6IEpTT04ucGFyc2UsXG5cblx0XHRcdC8vIFBhcnNlIHRleHQgYXMgeG1sXG5cdFx0XHRcInRleHQgeG1sXCI6IGpRdWVyeS5wYXJzZVhNTFxuXHRcdH0sXG5cblx0XHQvLyBGb3Igb3B0aW9ucyB0aGF0IHNob3VsZG4ndCBiZSBkZWVwIGV4dGVuZGVkOlxuXHRcdC8vIHlvdSBjYW4gYWRkIHlvdXIgb3duIGN1c3RvbSBvcHRpb25zIGhlcmUgaWZcblx0XHQvLyBhbmQgd2hlbiB5b3UgY3JlYXRlIG9uZSB0aGF0IHNob3VsZG4ndCBiZVxuXHRcdC8vIGRlZXAgZXh0ZW5kZWQgKHNlZSBhamF4RXh0ZW5kKVxuXHRcdGZsYXRPcHRpb25zOiB7XG5cdFx0XHR1cmw6IHRydWUsXG5cdFx0XHRjb250ZXh0OiB0cnVlXG5cdFx0fVxuXHR9LFxuXG5cdC8vIENyZWF0ZXMgYSBmdWxsIGZsZWRnZWQgc2V0dGluZ3Mgb2JqZWN0IGludG8gdGFyZ2V0XG5cdC8vIHdpdGggYm90aCBhamF4U2V0dGluZ3MgYW5kIHNldHRpbmdzIGZpZWxkcy5cblx0Ly8gSWYgdGFyZ2V0IGlzIG9taXR0ZWQsIHdyaXRlcyBpbnRvIGFqYXhTZXR0aW5ncy5cblx0YWpheFNldHVwOiBmdW5jdGlvbiggdGFyZ2V0LCBzZXR0aW5ncyApIHtcblx0XHRyZXR1cm4gc2V0dGluZ3MgP1xuXG5cdFx0XHQvLyBCdWlsZGluZyBhIHNldHRpbmdzIG9iamVjdFxuXHRcdFx0YWpheEV4dGVuZCggYWpheEV4dGVuZCggdGFyZ2V0LCBqUXVlcnkuYWpheFNldHRpbmdzICksIHNldHRpbmdzICkgOlxuXG5cdFx0XHQvLyBFeHRlbmRpbmcgYWpheFNldHRpbmdzXG5cdFx0XHRhamF4RXh0ZW5kKCBqUXVlcnkuYWpheFNldHRpbmdzLCB0YXJnZXQgKTtcblx0fSxcblxuXHRhamF4UHJlZmlsdGVyOiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMgKSxcblx0YWpheFRyYW5zcG9ydDogYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzICksXG5cblx0Ly8gTWFpbiBtZXRob2Rcblx0YWpheDogZnVuY3Rpb24oIHVybCwgb3B0aW9ucyApIHtcblxuXHRcdC8vIElmIHVybCBpcyBhbiBvYmplY3QsIHNpbXVsYXRlIHByZS0xLjUgc2lnbmF0dXJlXG5cdFx0aWYgKCB0eXBlb2YgdXJsID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0b3B0aW9ucyA9IHVybDtcblx0XHRcdHVybCA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBGb3JjZSBvcHRpb25zIHRvIGJlIGFuIG9iamVjdFxuXHRcdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cdFx0dmFyIHRyYW5zcG9ydCxcblxuXHRcdFx0Ly8gVVJMIHdpdGhvdXQgYW50aS1jYWNoZSBwYXJhbVxuXHRcdFx0Y2FjaGVVUkwsXG5cblx0XHRcdC8vIFJlc3BvbnNlIGhlYWRlcnNcblx0XHRcdHJlc3BvbnNlSGVhZGVyc1N0cmluZyxcblx0XHRcdHJlc3BvbnNlSGVhZGVycyxcblxuXHRcdFx0Ly8gdGltZW91dCBoYW5kbGVcblx0XHRcdHRpbWVvdXRUaW1lcixcblxuXHRcdFx0Ly8gVXJsIGNsZWFudXAgdmFyXG5cdFx0XHR1cmxBbmNob3IsXG5cblx0XHRcdC8vIFJlcXVlc3Qgc3RhdGUgKGJlY29tZXMgZmFsc2UgdXBvbiBzZW5kIGFuZCB0cnVlIHVwb24gY29tcGxldGlvbilcblx0XHRcdGNvbXBsZXRlZCxcblxuXHRcdFx0Ly8gVG8ga25vdyBpZiBnbG9iYWwgZXZlbnRzIGFyZSB0byBiZSBkaXNwYXRjaGVkXG5cdFx0XHRmaXJlR2xvYmFscyxcblxuXHRcdFx0Ly8gTG9vcCB2YXJpYWJsZVxuXHRcdFx0aSxcblxuXHRcdFx0Ly8gdW5jYWNoZWQgcGFydCBvZiB0aGUgdXJsXG5cdFx0XHR1bmNhY2hlZCxcblxuXHRcdFx0Ly8gQ3JlYXRlIHRoZSBmaW5hbCBvcHRpb25zIG9iamVjdFxuXHRcdFx0cyA9IGpRdWVyeS5hamF4U2V0dXAoIHt9LCBvcHRpb25zICksXG5cblx0XHRcdC8vIENhbGxiYWNrcyBjb250ZXh0XG5cdFx0XHRjYWxsYmFja0NvbnRleHQgPSBzLmNvbnRleHQgfHwgcyxcblxuXHRcdFx0Ly8gQ29udGV4dCBmb3IgZ2xvYmFsIGV2ZW50cyBpcyBjYWxsYmFja0NvbnRleHQgaWYgaXQgaXMgYSBET00gbm9kZSBvciBqUXVlcnkgY29sbGVjdGlvblxuXHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0ID0gcy5jb250ZXh0ICYmXG5cdFx0XHRcdCggY2FsbGJhY2tDb250ZXh0Lm5vZGVUeXBlIHx8IGNhbGxiYWNrQ29udGV4dC5qcXVlcnkgKSA/XG5cdFx0XHRcdFx0alF1ZXJ5KCBjYWxsYmFja0NvbnRleHQgKSA6XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LFxuXG5cdFx0XHQvLyBEZWZlcnJlZHNcblx0XHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCksXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkID0galF1ZXJ5LkNhbGxiYWNrcyggXCJvbmNlIG1lbW9yeVwiICksXG5cblx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRzdGF0dXNDb2RlID0gcy5zdGF0dXNDb2RlIHx8IHt9LFxuXG5cdFx0XHQvLyBIZWFkZXJzICh0aGV5IGFyZSBzZW50IGFsbCBhdCBvbmNlKVxuXHRcdFx0cmVxdWVzdEhlYWRlcnMgPSB7fSxcblx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXMgPSB7fSxcblxuXHRcdFx0Ly8gRGVmYXVsdCBhYm9ydCBtZXNzYWdlXG5cdFx0XHRzdHJBYm9ydCA9IFwiY2FuY2VsZWRcIixcblxuXHRcdFx0Ly8gRmFrZSB4aHJcblx0XHRcdGpxWEhSID0ge1xuXHRcdFx0XHRyZWFkeVN0YXRlOiAwLFxuXG5cdFx0XHRcdC8vIEJ1aWxkcyBoZWFkZXJzIGhhc2h0YWJsZSBpZiBuZWVkZWRcblx0XHRcdFx0Z2V0UmVzcG9uc2VIZWFkZXI6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0XHRcdFx0dmFyIG1hdGNoO1xuXHRcdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRcdFx0aWYgKCAhcmVzcG9uc2VIZWFkZXJzICkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnMgPSB7fTtcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG1hdGNoID0gcmhlYWRlcnMuZXhlYyggcmVzcG9uc2VIZWFkZXJzU3RyaW5nICkgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnNbIG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKSArIFwiIFwiIF0gPVxuXHRcdFx0XHRcdFx0XHRcdFx0KCByZXNwb25zZUhlYWRlcnNbIG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKSArIFwiIFwiIF0gfHwgW10gKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuY29uY2F0KCBtYXRjaFsgMiBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdG1hdGNoID0gcmVzcG9uc2VIZWFkZXJzWyBrZXkudG9Mb3dlckNhc2UoKSArIFwiIFwiIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiBtYXRjaCA9PSBudWxsID8gbnVsbCA6IG1hdGNoLmpvaW4oIFwiLCBcIiApO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIFJhdyBzdHJpbmdcblx0XHRcdFx0Z2V0QWxsUmVzcG9uc2VIZWFkZXJzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29tcGxldGVkID8gcmVzcG9uc2VIZWFkZXJzU3RyaW5nIDogbnVsbDtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBDYWNoZXMgdGhlIGhlYWRlclxuXHRcdFx0XHRzZXRSZXF1ZXN0SGVhZGVyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHRcdFx0aWYgKCBjb21wbGV0ZWQgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRcdG5hbWUgPSByZXF1ZXN0SGVhZGVyc05hbWVzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSA9XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXNbIG5hbWUudG9Mb3dlckNhc2UoKSBdIHx8IG5hbWU7XG5cdFx0XHRcdFx0XHRyZXF1ZXN0SGVhZGVyc1sgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIE92ZXJyaWRlcyByZXNwb25zZSBjb250ZW50LXR5cGUgaGVhZGVyXG5cdFx0XHRcdG92ZXJyaWRlTWltZVR5cGU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdFx0XHRcdGlmICggY29tcGxldGVkID09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRzLm1pbWVUeXBlID0gdHlwZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdFx0c3RhdHVzQ29kZTogZnVuY3Rpb24oIG1hcCApIHtcblx0XHRcdFx0XHR2YXIgY29kZTtcblx0XHRcdFx0XHRpZiAoIG1hcCApIHtcblx0XHRcdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEV4ZWN1dGUgdGhlIGFwcHJvcHJpYXRlIGNhbGxiYWNrc1xuXHRcdFx0XHRcdFx0XHRqcVhIUi5hbHdheXMoIG1hcFsganFYSFIuc3RhdHVzIF0gKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gTGF6eS1hZGQgdGhlIG5ldyBjYWxsYmFja3MgaW4gYSB3YXkgdGhhdCBwcmVzZXJ2ZXMgb2xkIG9uZXNcblx0XHRcdFx0XHRcdFx0Zm9yICggY29kZSBpbiBtYXAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c3RhdHVzQ29kZVsgY29kZSBdID0gWyBzdGF0dXNDb2RlWyBjb2RlIF0sIG1hcFsgY29kZSBdIF07XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gQ2FuY2VsIHRoZSByZXF1ZXN0XG5cdFx0XHRcdGFib3J0OiBmdW5jdGlvbiggc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHR2YXIgZmluYWxUZXh0ID0gc3RhdHVzVGV4dCB8fCBzdHJBYm9ydDtcblx0XHRcdFx0XHRpZiAoIHRyYW5zcG9ydCApIHtcblx0XHRcdFx0XHRcdHRyYW5zcG9ydC5hYm9ydCggZmluYWxUZXh0ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRvbmUoIDAsIGZpbmFsVGV4dCApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0Ly8gQXR0YWNoIGRlZmVycmVkc1xuXHRcdGRlZmVycmVkLnByb21pc2UoIGpxWEhSICk7XG5cblx0XHQvLyBBZGQgcHJvdG9jb2wgaWYgbm90IHByb3ZpZGVkIChwcmVmaWx0ZXJzIG1pZ2h0IGV4cGVjdCBpdClcblx0XHQvLyBIYW5kbGUgZmFsc3kgdXJsIGluIHRoZSBzZXR0aW5ncyBvYmplY3QgKCMxMDA5MzogY29uc2lzdGVuY3kgd2l0aCBvbGQgc2lnbmF0dXJlKVxuXHRcdC8vIFdlIGFsc28gdXNlIHRoZSB1cmwgcGFyYW1ldGVyIGlmIGF2YWlsYWJsZVxuXHRcdHMudXJsID0gKCAoIHVybCB8fCBzLnVybCB8fCBsb2NhdGlvbi5ocmVmICkgKyBcIlwiIClcblx0XHRcdC5yZXBsYWNlKCBycHJvdG9jb2wsIGxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICk7XG5cblx0XHQvLyBBbGlhcyBtZXRob2Qgb3B0aW9uIHRvIHR5cGUgYXMgcGVyIHRpY2tldCAjMTIwMDRcblx0XHRzLnR5cGUgPSBvcHRpb25zLm1ldGhvZCB8fCBvcHRpb25zLnR5cGUgfHwgcy5tZXRob2QgfHwgcy50eXBlO1xuXG5cdFx0Ly8gRXh0cmFjdCBkYXRhVHlwZXMgbGlzdFxuXHRcdHMuZGF0YVR5cGVzID0gKCBzLmRhdGFUeXBlIHx8IFwiKlwiICkudG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXG5cdFx0Ly8gQSBjcm9zcy1kb21haW4gcmVxdWVzdCBpcyBpbiBvcmRlciB3aGVuIHRoZSBvcmlnaW4gZG9lc24ndCBtYXRjaCB0aGUgY3VycmVudCBvcmlnaW4uXG5cdFx0aWYgKCBzLmNyb3NzRG9tYWluID09IG51bGwgKSB7XG5cdFx0XHR1cmxBbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImFcIiApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTggLSAxMSwgRWRnZSAxMiAtIDE1XG5cdFx0XHQvLyBJRSB0aHJvd3MgZXhjZXB0aW9uIG9uIGFjY2Vzc2luZyB0aGUgaHJlZiBwcm9wZXJ0eSBpZiB1cmwgaXMgbWFsZm9ybWVkLFxuXHRcdFx0Ly8gZS5nLiBodHRwOi8vZXhhbXBsZS5jb206ODB4L1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0dXJsQW5jaG9yLmhyZWYgPSBzLnVybDtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTggLSAxMSBvbmx5XG5cdFx0XHRcdC8vIEFuY2hvcidzIGhvc3QgcHJvcGVydHkgaXNuJ3QgY29ycmVjdGx5IHNldCB3aGVuIHMudXJsIGlzIHJlbGF0aXZlXG5cdFx0XHRcdHVybEFuY2hvci5ocmVmID0gdXJsQW5jaG9yLmhyZWY7XG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSBvcmlnaW5BbmNob3IucHJvdG9jb2wgKyBcIi8vXCIgKyBvcmlnaW5BbmNob3IuaG9zdCAhPT1cblx0XHRcdFx0XHR1cmxBbmNob3IucHJvdG9jb2wgKyBcIi8vXCIgKyB1cmxBbmNob3IuaG9zdDtcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXG5cdFx0XHRcdC8vIElmIHRoZXJlIGlzIGFuIGVycm9yIHBhcnNpbmcgdGhlIFVSTCwgYXNzdW1lIGl0IGlzIGNyb3NzRG9tYWluLFxuXHRcdFx0XHQvLyBpdCBjYW4gYmUgcmVqZWN0ZWQgYnkgdGhlIHRyYW5zcG9ydCBpZiBpdCBpcyBpbnZhbGlkXG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgZGF0YSBpZiBub3QgYWxyZWFkeSBhIHN0cmluZ1xuXHRcdGlmICggcy5kYXRhICYmIHMucHJvY2Vzc0RhdGEgJiYgdHlwZW9mIHMuZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHMuZGF0YSA9IGpRdWVyeS5wYXJhbSggcy5kYXRhLCBzLnRyYWRpdGlvbmFsICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcHJlZmlsdGVyc1xuXHRcdGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBwcmVmaWx0ZXJzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xuXG5cdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYSBwcmVmaWx0ZXIsIHN0b3AgdGhlcmVcblx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdHJldHVybiBqcVhIUjtcblx0XHR9XG5cblx0XHQvLyBXZSBjYW4gZmlyZSBnbG9iYWwgZXZlbnRzIGFzIG9mIG5vdyBpZiBhc2tlZCB0b1xuXHRcdC8vIERvbid0IGZpcmUgZXZlbnRzIGlmIGpRdWVyeS5ldmVudCBpcyB1bmRlZmluZWQgaW4gYW4gQU1ELXVzYWdlIHNjZW5hcmlvICgjMTUxMTgpXG5cdFx0ZmlyZUdsb2JhbHMgPSBqUXVlcnkuZXZlbnQgJiYgcy5nbG9iYWw7XG5cblx0XHQvLyBXYXRjaCBmb3IgYSBuZXcgc2V0IG9mIHJlcXVlc3RzXG5cdFx0aWYgKCBmaXJlR2xvYmFscyAmJiBqUXVlcnkuYWN0aXZlKysgPT09IDAgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggXCJhamF4U3RhcnRcIiApO1xuXHRcdH1cblxuXHRcdC8vIFVwcGVyY2FzZSB0aGUgdHlwZVxuXHRcdHMudHlwZSA9IHMudHlwZS50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0Ly8gRGV0ZXJtaW5lIGlmIHJlcXVlc3QgaGFzIGNvbnRlbnRcblx0XHRzLmhhc0NvbnRlbnQgPSAhcm5vQ29udGVudC50ZXN0KCBzLnR5cGUgKTtcblxuXHRcdC8vIFNhdmUgdGhlIFVSTCBpbiBjYXNlIHdlJ3JlIHRveWluZyB3aXRoIHRoZSBJZi1Nb2RpZmllZC1TaW5jZVxuXHRcdC8vIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciBsYXRlciBvblxuXHRcdC8vIFJlbW92ZSBoYXNoIHRvIHNpbXBsaWZ5IHVybCBtYW5pcHVsYXRpb25cblx0XHRjYWNoZVVSTCA9IHMudXJsLnJlcGxhY2UoIHJoYXNoLCBcIlwiICk7XG5cblx0XHQvLyBNb3JlIG9wdGlvbnMgaGFuZGxpbmcgZm9yIHJlcXVlc3RzIHdpdGggbm8gY29udGVudFxuXHRcdGlmICggIXMuaGFzQ29udGVudCApIHtcblxuXHRcdFx0Ly8gUmVtZW1iZXIgdGhlIGhhc2ggc28gd2UgY2FuIHB1dCBpdCBiYWNrXG5cdFx0XHR1bmNhY2hlZCA9IHMudXJsLnNsaWNlKCBjYWNoZVVSTC5sZW5ndGggKTtcblxuXHRcdFx0Ly8gSWYgZGF0YSBpcyBhdmFpbGFibGUgYW5kIHNob3VsZCBiZSBwcm9jZXNzZWQsIGFwcGVuZCBkYXRhIHRvIHVybFxuXHRcdFx0aWYgKCBzLmRhdGEgJiYgKCBzLnByb2Nlc3NEYXRhIHx8IHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgKSApIHtcblx0XHRcdFx0Y2FjaGVVUkwgKz0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuZGF0YTtcblxuXHRcdFx0XHQvLyAjOTY4MjogcmVtb3ZlIGRhdGEgc28gdGhhdCBpdCdzIG5vdCB1c2VkIGluIGFuIGV2ZW50dWFsIHJldHJ5XG5cdFx0XHRcdGRlbGV0ZSBzLmRhdGE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBvciB1cGRhdGUgYW50aS1jYWNoZSBwYXJhbSBpZiBuZWVkZWRcblx0XHRcdGlmICggcy5jYWNoZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdGNhY2hlVVJMID0gY2FjaGVVUkwucmVwbGFjZSggcmFudGlDYWNoZSwgXCIkMVwiICk7XG5cdFx0XHRcdHVuY2FjaGVkID0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIFwiXz1cIiArICggbm9uY2UuZ3VpZCsrICkgK1xuXHRcdFx0XHRcdHVuY2FjaGVkO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBQdXQgaGFzaCBhbmQgYW50aS1jYWNoZSBvbiB0aGUgVVJMIHRoYXQgd2lsbCBiZSByZXF1ZXN0ZWQgKGdoLTE3MzIpXG5cdFx0XHRzLnVybCA9IGNhY2hlVVJMICsgdW5jYWNoZWQ7XG5cblx0XHQvLyBDaGFuZ2UgJyUyMCcgdG8gJysnIGlmIHRoaXMgaXMgZW5jb2RlZCBmb3JtIGJvZHkgY29udGVudCAoZ2gtMjY1OClcblx0XHR9IGVsc2UgaWYgKCBzLmRhdGEgJiYgcy5wcm9jZXNzRGF0YSAmJlxuXHRcdFx0KCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKS5pbmRleE9mKCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiICkgPT09IDAgKSB7XG5cdFx0XHRzLmRhdGEgPSBzLmRhdGEucmVwbGFjZSggcjIwLCBcIitcIiApO1xuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuXG5cdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKSB7XG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTW9kaWZpZWQtU2luY2VcIiwgalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApIHtcblx0XHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJJZi1Ob25lLU1hdGNoXCIsIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBjb3JyZWN0IGhlYWRlciwgaWYgZGF0YSBpcyBiZWluZyBzZW50XG5cdFx0aWYgKCBzLmRhdGEgJiYgcy5oYXNDb250ZW50ICYmIHMuY29udGVudFR5cGUgIT09IGZhbHNlIHx8IG9wdGlvbnMuY29udGVudFR5cGUgKSB7XG5cdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIkNvbnRlbnQtVHlwZVwiLCBzLmNvbnRlbnRUeXBlICk7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBBY2NlcHRzIGhlYWRlciBmb3IgdGhlIHNlcnZlciwgZGVwZW5kaW5nIG9uIHRoZSBkYXRhVHlwZVxuXHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoXG5cdFx0XHRcIkFjY2VwdFwiLFxuXHRcdFx0cy5kYXRhVHlwZXNbIDAgXSAmJiBzLmFjY2VwdHNbIHMuZGF0YVR5cGVzWyAwIF0gXSA/XG5cdFx0XHRcdHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbIDAgXSBdICtcblx0XHRcdFx0XHQoIHMuZGF0YVR5cGVzWyAwIF0gIT09IFwiKlwiID8gXCIsIFwiICsgYWxsVHlwZXMgKyBcIjsgcT0wLjAxXCIgOiBcIlwiICkgOlxuXHRcdFx0XHRzLmFjY2VwdHNbIFwiKlwiIF1cblx0XHQpO1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIGhlYWRlcnMgb3B0aW9uXG5cdFx0Zm9yICggaSBpbiBzLmhlYWRlcnMgKSB7XG5cdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBpLCBzLmhlYWRlcnNbIGkgXSApO1xuXHRcdH1cblxuXHRcdC8vIEFsbG93IGN1c3RvbSBoZWFkZXJzL21pbWV0eXBlcyBhbmQgZWFybHkgYWJvcnRcblx0XHRpZiAoIHMuYmVmb3JlU2VuZCAmJlxuXHRcdFx0KCBzLmJlZm9yZVNlbmQuY2FsbCggY2FsbGJhY2tDb250ZXh0LCBqcVhIUiwgcyApID09PSBmYWxzZSB8fCBjb21wbGV0ZWQgKSApIHtcblxuXHRcdFx0Ly8gQWJvcnQgaWYgbm90IGRvbmUgYWxyZWFkeSBhbmQgcmV0dXJuXG5cdFx0XHRyZXR1cm4ganFYSFIuYWJvcnQoKTtcblx0XHR9XG5cblx0XHQvLyBBYm9ydGluZyBpcyBubyBsb25nZXIgYSBjYW5jZWxsYXRpb25cblx0XHRzdHJBYm9ydCA9IFwiYWJvcnRcIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tzIG9uIGRlZmVycmVkc1xuXHRcdGNvbXBsZXRlRGVmZXJyZWQuYWRkKCBzLmNvbXBsZXRlICk7XG5cdFx0anFYSFIuZG9uZSggcy5zdWNjZXNzICk7XG5cdFx0anFYSFIuZmFpbCggcy5lcnJvciApO1xuXG5cdFx0Ly8gR2V0IHRyYW5zcG9ydFxuXHRcdHRyYW5zcG9ydCA9IGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xuXG5cdFx0Ly8gSWYgbm8gdHJhbnNwb3J0LCB3ZSBhdXRvLWFib3J0XG5cdFx0aWYgKCAhdHJhbnNwb3J0ICkge1xuXHRcdFx0ZG9uZSggLTEsIFwiTm8gVHJhbnNwb3J0XCIgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IDE7XG5cblx0XHRcdC8vIFNlbmQgZ2xvYmFsIGV2ZW50XG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggXCJhamF4U2VuZFwiLCBbIGpxWEhSLCBzIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYWpheFNlbmQsIHN0b3AgdGhlcmVcblx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRyZXR1cm4ganFYSFI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRpbWVvdXRcblx0XHRcdGlmICggcy5hc3luYyAmJiBzLnRpbWVvdXQgPiAwICkge1xuXHRcdFx0XHR0aW1lb3V0VGltZXIgPSB3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0anFYSFIuYWJvcnQoIFwidGltZW91dFwiICk7XG5cdFx0XHRcdH0sIHMudGltZW91dCApO1xuXHRcdFx0fVxuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb21wbGV0ZWQgPSBmYWxzZTtcblx0XHRcdFx0dHJhbnNwb3J0LnNlbmQoIHJlcXVlc3RIZWFkZXJzLCBkb25lICk7XG5cdFx0XHR9IGNhdGNoICggZSApIHtcblxuXHRcdFx0XHQvLyBSZXRocm93IHBvc3QtY29tcGxldGlvbiBleGNlcHRpb25zXG5cdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRcdHRocm93IGU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBQcm9wYWdhdGUgb3RoZXJzIGFzIHJlc3VsdHNcblx0XHRcdFx0ZG9uZSggLTEsIGUgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWxsYmFjayBmb3Igd2hlbiBldmVyeXRoaW5nIGlzIGRvbmVcblx0XHRmdW5jdGlvbiBkb25lKCBzdGF0dXMsIG5hdGl2ZVN0YXR1c1RleHQsIHJlc3BvbnNlcywgaGVhZGVycyApIHtcblx0XHRcdHZhciBpc1N1Y2Nlc3MsIHN1Y2Nlc3MsIGVycm9yLCByZXNwb25zZSwgbW9kaWZpZWQsXG5cdFx0XHRcdHN0YXR1c1RleHQgPSBuYXRpdmVTdGF0dXNUZXh0O1xuXG5cdFx0XHQvLyBJZ25vcmUgcmVwZWF0IGludm9jYXRpb25zXG5cdFx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRjb21wbGV0ZWQgPSB0cnVlO1xuXG5cdFx0XHQvLyBDbGVhciB0aW1lb3V0IGlmIGl0IGV4aXN0c1xuXHRcdFx0aWYgKCB0aW1lb3V0VGltZXIgKSB7XG5cdFx0XHRcdHdpbmRvdy5jbGVhclRpbWVvdXQoIHRpbWVvdXRUaW1lciApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBEZXJlZmVyZW5jZSB0cmFuc3BvcnQgZm9yIGVhcmx5IGdhcmJhZ2UgY29sbGVjdGlvblxuXHRcdFx0Ly8gKG5vIG1hdHRlciBob3cgbG9uZyB0aGUganFYSFIgb2JqZWN0IHdpbGwgYmUgdXNlZClcblx0XHRcdHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcblxuXHRcdFx0Ly8gQ2FjaGUgcmVzcG9uc2UgaGVhZGVyc1xuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nID0gaGVhZGVycyB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTZXQgcmVhZHlTdGF0ZVxuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IHN0YXR1cyA+IDAgPyA0IDogMDtcblxuXHRcdFx0Ly8gRGV0ZXJtaW5lIGlmIHN1Y2Nlc3NmdWxcblx0XHRcdGlzU3VjY2VzcyA9IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwIHx8IHN0YXR1cyA9PT0gMzA0O1xuXG5cdFx0XHQvLyBHZXQgcmVzcG9uc2UgZGF0YVxuXHRcdFx0aWYgKCByZXNwb25zZXMgKSB7XG5cdFx0XHRcdHJlc3BvbnNlID0gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBVc2UgYSBub29wIGNvbnZlcnRlciBmb3IgbWlzc2luZyBzY3JpcHRcblx0XHRcdGlmICggIWlzU3VjY2VzcyAmJiBqUXVlcnkuaW5BcnJheSggXCJzY3JpcHRcIiwgcy5kYXRhVHlwZXMgKSA+IC0xICkge1xuXHRcdFx0XHRzLmNvbnZlcnRlcnNbIFwidGV4dCBzY3JpcHRcIiBdID0gZnVuY3Rpb24oKSB7fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udmVydCBubyBtYXR0ZXIgd2hhdCAodGhhdCB3YXkgcmVzcG9uc2VYWFggZmllbGRzIGFyZSBhbHdheXMgc2V0KVxuXHRcdFx0cmVzcG9uc2UgPSBhamF4Q29udmVydCggcywgcmVzcG9uc2UsIGpxWEhSLCBpc1N1Y2Nlc3MgKTtcblxuXHRcdFx0Ly8gSWYgc3VjY2Vzc2Z1bCwgaGFuZGxlIHR5cGUgY2hhaW5pbmdcblx0XHRcdGlmICggaXNTdWNjZXNzICkge1xuXG5cdFx0XHRcdC8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuXG5cdFx0XHRcdGlmICggcy5pZk1vZGlmaWVkICkge1xuXHRcdFx0XHRcdG1vZGlmaWVkID0ganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoIFwiTGFzdC1Nb2RpZmllZFwiICk7XG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlciggXCJldGFnXCIgKTtcblx0XHRcdFx0XHRpZiAoIG1vZGlmaWVkICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBpZiBubyBjb250ZW50XG5cdFx0XHRcdGlmICggc3RhdHVzID09PSAyMDQgfHwgcy50eXBlID09PSBcIkhFQURcIiApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJub2NvbnRlbnRcIjtcblxuXHRcdFx0XHQvLyBpZiBub3QgbW9kaWZpZWRcblx0XHRcdFx0fSBlbHNlIGlmICggc3RhdHVzID09PSAzMDQgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm90bW9kaWZpZWRcIjtcblxuXHRcdFx0XHQvLyBJZiB3ZSBoYXZlIGRhdGEsIGxldCdzIGNvbnZlcnQgaXRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gcmVzcG9uc2Uuc3RhdGU7XG5cdFx0XHRcdFx0c3VjY2VzcyA9IHJlc3BvbnNlLmRhdGE7XG5cdFx0XHRcdFx0ZXJyb3IgPSByZXNwb25zZS5lcnJvcjtcblx0XHRcdFx0XHRpc1N1Y2Nlc3MgPSAhZXJyb3I7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gRXh0cmFjdCBlcnJvciBmcm9tIHN0YXR1c1RleHQgYW5kIG5vcm1hbGl6ZSBmb3Igbm9uLWFib3J0c1xuXHRcdFx0XHRlcnJvciA9IHN0YXR1c1RleHQ7XG5cdFx0XHRcdGlmICggc3RhdHVzIHx8ICFzdGF0dXNUZXh0ICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcImVycm9yXCI7XG5cdFx0XHRcdFx0aWYgKCBzdGF0dXMgPCAwICkge1xuXHRcdFx0XHRcdFx0c3RhdHVzID0gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IGRhdGEgZm9yIHRoZSBmYWtlIHhociBvYmplY3Rcblx0XHRcdGpxWEhSLnN0YXR1cyA9IHN0YXR1cztcblx0XHRcdGpxWEhSLnN0YXR1c1RleHQgPSAoIG5hdGl2ZVN0YXR1c1RleHQgfHwgc3RhdHVzVGV4dCApICsgXCJcIjtcblxuXHRcdFx0Ly8gU3VjY2Vzcy9FcnJvclxuXHRcdFx0aWYgKCBpc1N1Y2Nlc3MgKSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsgc3VjY2Vzcywgc3RhdHVzVGV4dCwganFYSFIgXSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVmZXJyZWQucmVqZWN0V2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIGpxWEhSLCBzdGF0dXNUZXh0LCBlcnJvciBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRqcVhIUi5zdGF0dXNDb2RlKCBzdGF0dXNDb2RlICk7XG5cdFx0XHRzdGF0dXNDb2RlID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggaXNTdWNjZXNzID8gXCJhamF4U3VjY2Vzc1wiIDogXCJhamF4RXJyb3JcIixcblx0XHRcdFx0XHRbIGpxWEhSLCBzLCBpc1N1Y2Nlc3MgPyBzdWNjZXNzIDogZXJyb3IgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb21wbGV0ZVxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZC5maXJlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIGpxWEhSLCBzdGF0dXNUZXh0IF0gKTtcblxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIFwiYWpheENvbXBsZXRlXCIsIFsganFYSFIsIHMgXSApO1xuXG5cdFx0XHRcdC8vIEhhbmRsZSB0aGUgZ2xvYmFsIEFKQVggY291bnRlclxuXHRcdFx0XHRpZiAoICEoIC0talF1ZXJ5LmFjdGl2ZSApICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCBcImFqYXhTdG9wXCIgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBqcVhIUjtcblx0fSxcblxuXHRnZXRKU09OOiBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCBkYXRhLCBjYWxsYmFjaywgXCJqc29uXCIgKTtcblx0fSxcblxuXHRnZXRTY3JpcHQ6IGZ1bmN0aW9uKCB1cmwsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIHVuZGVmaW5lZCwgY2FsbGJhY2ssIFwic2NyaXB0XCIgKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCggWyBcImdldFwiLCBcInBvc3RcIiBdLCBmdW5jdGlvbiggX2ksIG1ldGhvZCApIHtcblx0alF1ZXJ5WyBtZXRob2QgXSA9IGZ1bmN0aW9uKCB1cmwsIGRhdGEsIGNhbGxiYWNrLCB0eXBlICkge1xuXG5cdFx0Ly8gU2hpZnQgYXJndW1lbnRzIGlmIGRhdGEgYXJndW1lbnQgd2FzIG9taXR0ZWRcblx0XHRpZiAoIGlzRnVuY3Rpb24oIGRhdGEgKSApIHtcblx0XHRcdHR5cGUgPSB0eXBlIHx8IGNhbGxiYWNrO1xuXHRcdFx0Y2FsbGJhY2sgPSBkYXRhO1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBUaGUgdXJsIGNhbiBiZSBhbiBvcHRpb25zIG9iamVjdCAod2hpY2ggdGhlbiBtdXN0IGhhdmUgLnVybClcblx0XHRyZXR1cm4galF1ZXJ5LmFqYXgoIGpRdWVyeS5leHRlbmQoIHtcblx0XHRcdHVybDogdXJsLFxuXHRcdFx0dHlwZTogbWV0aG9kLFxuXHRcdFx0ZGF0YVR5cGU6IHR5cGUsXG5cdFx0XHRkYXRhOiBkYXRhLFxuXHRcdFx0c3VjY2VzczogY2FsbGJhY2tcblx0XHR9LCBqUXVlcnkuaXNQbGFpbk9iamVjdCggdXJsICkgJiYgdXJsICkgKTtcblx0fTtcbn0gKTtcblxualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIGZ1bmN0aW9uKCBzICkge1xuXHR2YXIgaTtcblx0Zm9yICggaSBpbiBzLmhlYWRlcnMgKSB7XG5cdFx0aWYgKCBpLnRvTG93ZXJDYXNlKCkgPT09IFwiY29udGVudC10eXBlXCIgKSB7XG5cdFx0XHRzLmNvbnRlbnRUeXBlID0gcy5oZWFkZXJzWyBpIF0gfHwgXCJcIjtcblx0XHR9XG5cdH1cbn0gKTtcblxuXG5qUXVlcnkuX2V2YWxVcmwgPSBmdW5jdGlvbiggdXJsLCBvcHRpb25zLCBkb2MgKSB7XG5cdHJldHVybiBqUXVlcnkuYWpheCgge1xuXHRcdHVybDogdXJsLFxuXG5cdFx0Ly8gTWFrZSB0aGlzIGV4cGxpY2l0LCBzaW5jZSB1c2VyIGNhbiBvdmVycmlkZSB0aGlzIHRocm91Z2ggYWpheFNldHVwICgjMTEyNjQpXG5cdFx0dHlwZTogXCJHRVRcIixcblx0XHRkYXRhVHlwZTogXCJzY3JpcHRcIixcblx0XHRjYWNoZTogdHJ1ZSxcblx0XHRhc3luYzogZmFsc2UsXG5cdFx0Z2xvYmFsOiBmYWxzZSxcblxuXHRcdC8vIE9ubHkgZXZhbHVhdGUgdGhlIHJlc3BvbnNlIGlmIGl0IGlzIHN1Y2Nlc3NmdWwgKGdoLTQxMjYpXG5cdFx0Ly8gZGF0YUZpbHRlciBpcyBub3QgaW52b2tlZCBmb3IgZmFpbHVyZSByZXNwb25zZXMsIHNvIHVzaW5nIGl0IGluc3RlYWRcblx0XHQvLyBvZiB0aGUgZGVmYXVsdCBjb252ZXJ0ZXIgaXMga2x1ZGd5IGJ1dCBpdCB3b3Jrcy5cblx0XHRjb252ZXJ0ZXJzOiB7XG5cdFx0XHRcInRleHQgc2NyaXB0XCI6IGZ1bmN0aW9uKCkge31cblx0XHR9LFxuXHRcdGRhdGFGaWx0ZXI6IGZ1bmN0aW9uKCByZXNwb25zZSApIHtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCByZXNwb25zZSwgb3B0aW9ucywgZG9jICk7XG5cdFx0fVxuXHR9ICk7XG59O1xuXG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0d3JhcEFsbDogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0dmFyIHdyYXA7XG5cblx0XHRpZiAoIHRoaXNbIDAgXSApIHtcblx0XHRcdGlmICggaXNGdW5jdGlvbiggaHRtbCApICkge1xuXHRcdFx0XHRodG1sID0gaHRtbC5jYWxsKCB0aGlzWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVGhlIGVsZW1lbnRzIHRvIHdyYXAgdGhlIHRhcmdldCBhcm91bmRcblx0XHRcdHdyYXAgPSBqUXVlcnkoIGh0bWwsIHRoaXNbIDAgXS5vd25lckRvY3VtZW50ICkuZXEoIDAgKS5jbG9uZSggdHJ1ZSApO1xuXG5cdFx0XHRpZiAoIHRoaXNbIDAgXS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR3cmFwLmluc2VydEJlZm9yZSggdGhpc1sgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHdyYXAubWFwKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGVsZW0gPSB0aGlzO1xuXG5cdFx0XHRcdHdoaWxlICggZWxlbS5maXJzdEVsZW1lbnRDaGlsZCApIHtcblx0XHRcdFx0XHRlbGVtID0gZWxlbS5maXJzdEVsZW1lbnRDaGlsZDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBlbGVtO1xuXHRcdFx0fSApLmFwcGVuZCggdGhpcyApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHdyYXBJbm5lcjogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcElubmVyKCBodG1sLmNhbGwoIHRoaXMsIGkgKSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHNlbGYgPSBqUXVlcnkoIHRoaXMgKSxcblx0XHRcdFx0Y29udGVudHMgPSBzZWxmLmNvbnRlbnRzKCk7XG5cblx0XHRcdGlmICggY29udGVudHMubGVuZ3RoICkge1xuXHRcdFx0XHRjb250ZW50cy53cmFwQWxsKCBodG1sICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNlbGYuYXBwZW5kKCBodG1sICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdHdyYXA6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciBodG1sSXNGdW5jdGlvbiA9IGlzRnVuY3Rpb24oIGh0bWwgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaHRtbElzRnVuY3Rpb24gPyBodG1sLmNhbGwoIHRoaXMsIGkgKSA6IGh0bWwgKTtcblx0XHR9ICk7XG5cdH0sXG5cblx0dW53cmFwOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dGhpcy5wYXJlbnQoIHNlbGVjdG9yICkubm90KCBcImJvZHlcIiApLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5KCB0aGlzICkucmVwbGFjZVdpdGgoIHRoaXMuY2hpbGROb2RlcyApO1xuXHRcdH0gKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxufSApO1xuXG5cbmpRdWVyeS5leHByLnBzZXVkb3MuaGlkZGVuID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiAhalF1ZXJ5LmV4cHIucHNldWRvcy52aXNpYmxlKCBlbGVtICk7XG59O1xualF1ZXJ5LmV4cHIucHNldWRvcy52aXNpYmxlID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiAhISggZWxlbS5vZmZzZXRXaWR0aCB8fCBlbGVtLm9mZnNldEhlaWdodCB8fCBlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoICk7XG59O1xuXG5cblxuXG5qUXVlcnkuYWpheFNldHRpbmdzLnhociA9IGZ1bmN0aW9uKCkge1xuXHR0cnkge1xuXHRcdHJldHVybiBuZXcgd2luZG93LlhNTEh0dHBSZXF1ZXN0KCk7XG5cdH0gY2F0Y2ggKCBlICkge31cbn07XG5cbnZhciB4aHJTdWNjZXNzU3RhdHVzID0ge1xuXG5cdFx0Ly8gRmlsZSBwcm90b2NvbCBhbHdheXMgeWllbGRzIHN0YXR1cyBjb2RlIDAsIGFzc3VtZSAyMDBcblx0XHQwOiAyMDAsXG5cblx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdC8vICMxNDUwOiBzb21ldGltZXMgSUUgcmV0dXJucyAxMjIzIHdoZW4gaXQgc2hvdWxkIGJlIDIwNFxuXHRcdDEyMjM6IDIwNFxuXHR9LFxuXHR4aHJTdXBwb3J0ZWQgPSBqUXVlcnkuYWpheFNldHRpbmdzLnhocigpO1xuXG5zdXBwb3J0LmNvcnMgPSAhIXhoclN1cHBvcnRlZCAmJiAoIFwid2l0aENyZWRlbnRpYWxzXCIgaW4geGhyU3VwcG9ydGVkICk7XG5zdXBwb3J0LmFqYXggPSB4aHJTdXBwb3J0ZWQgPSAhIXhoclN1cHBvcnRlZDtcblxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoIGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXHR2YXIgY2FsbGJhY2ssIGVycm9yQ2FsbGJhY2s7XG5cblx0Ly8gQ3Jvc3MgZG9tYWluIG9ubHkgYWxsb3dlZCBpZiBzdXBwb3J0ZWQgdGhyb3VnaCBYTUxIdHRwUmVxdWVzdFxuXHRpZiAoIHN1cHBvcnQuY29ycyB8fCB4aHJTdXBwb3J0ZWQgJiYgIW9wdGlvbnMuY3Jvc3NEb21haW4gKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBoZWFkZXJzLCBjb21wbGV0ZSApIHtcblx0XHRcdFx0dmFyIGksXG5cdFx0XHRcdFx0eGhyID0gb3B0aW9ucy54aHIoKTtcblxuXHRcdFx0XHR4aHIub3Blbihcblx0XHRcdFx0XHRvcHRpb25zLnR5cGUsXG5cdFx0XHRcdFx0b3B0aW9ucy51cmwsXG5cdFx0XHRcdFx0b3B0aW9ucy5hc3luYyxcblx0XHRcdFx0XHRvcHRpb25zLnVzZXJuYW1lLFxuXHRcdFx0XHRcdG9wdGlvbnMucGFzc3dvcmRcblx0XHRcdFx0KTtcblxuXHRcdFx0XHQvLyBBcHBseSBjdXN0b20gZmllbGRzIGlmIHByb3ZpZGVkXG5cdFx0XHRcdGlmICggb3B0aW9ucy54aHJGaWVsZHMgKSB7XG5cdFx0XHRcdFx0Zm9yICggaSBpbiBvcHRpb25zLnhockZpZWxkcyApIHtcblx0XHRcdFx0XHRcdHhoclsgaSBdID0gb3B0aW9ucy54aHJGaWVsZHNbIGkgXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBPdmVycmlkZSBtaW1lIHR5cGUgaWYgbmVlZGVkXG5cdFx0XHRcdGlmICggb3B0aW9ucy5taW1lVHlwZSAmJiB4aHIub3ZlcnJpZGVNaW1lVHlwZSApIHtcblx0XHRcdFx0XHR4aHIub3ZlcnJpZGVNaW1lVHlwZSggb3B0aW9ucy5taW1lVHlwZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gWC1SZXF1ZXN0ZWQtV2l0aCBoZWFkZXJcblx0XHRcdFx0Ly8gRm9yIGNyb3NzLWRvbWFpbiByZXF1ZXN0cywgc2VlaW5nIGFzIGNvbmRpdGlvbnMgZm9yIGEgcHJlZmxpZ2h0IGFyZVxuXHRcdFx0XHQvLyBha2luIHRvIGEgamlnc2F3IHB1enpsZSwgd2Ugc2ltcGx5IG5ldmVyIHNldCBpdCB0byBiZSBzdXJlLlxuXHRcdFx0XHQvLyAoaXQgY2FuIGFsd2F5cyBiZSBzZXQgb24gYSBwZXItcmVxdWVzdCBiYXNpcyBvciBldmVuIHVzaW5nIGFqYXhTZXR1cClcblx0XHRcdFx0Ly8gRm9yIHNhbWUtZG9tYWluIHJlcXVlc3RzLCB3b24ndCBjaGFuZ2UgaGVhZGVyIGlmIGFscmVhZHkgcHJvdmlkZWQuXG5cdFx0XHRcdGlmICggIW9wdGlvbnMuY3Jvc3NEb21haW4gJiYgIWhlYWRlcnNbIFwiWC1SZXF1ZXN0ZWQtV2l0aFwiIF0gKSB7XG5cdFx0XHRcdFx0aGVhZGVyc1sgXCJYLVJlcXVlc3RlZC1XaXRoXCIgXSA9IFwiWE1MSHR0cFJlcXVlc3RcIjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFNldCBoZWFkZXJzXG5cdFx0XHRcdGZvciAoIGkgaW4gaGVhZGVycyApIHtcblx0XHRcdFx0XHR4aHIuc2V0UmVxdWVzdEhlYWRlciggaSwgaGVhZGVyc1sgaSBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBDYWxsYmFja1xuXHRcdFx0XHRjYWxsYmFjayA9IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdGNhbGxiYWNrID0gZXJyb3JDYWxsYmFjayA9IHhoci5vbmxvYWQgPVxuXHRcdFx0XHRcdFx0XHRcdHhoci5vbmVycm9yID0geGhyLm9uYWJvcnQgPSB4aHIub250aW1lb3V0ID1cblx0XHRcdFx0XHRcdFx0XHRcdHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuXG5cdFx0XHRcdFx0XHRcdGlmICggdHlwZSA9PT0gXCJhYm9ydFwiICkge1xuXHRcdFx0XHRcdFx0XHRcdHhoci5hYm9ydCgpO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCB0eXBlID09PSBcImVycm9yXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdFx0XHRcdFx0XHRcdC8vIE9uIGEgbWFudWFsIG5hdGl2ZSBhYm9ydCwgSUU5IHRocm93c1xuXHRcdFx0XHRcdFx0XHRcdC8vIGVycm9ycyBvbiBhbnkgcHJvcGVydHkgYWNjZXNzIHRoYXQgaXMgbm90IHJlYWR5U3RhdGVcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHR5cGVvZiB4aHIuc3RhdHVzICE9PSBcIm51bWJlclwiICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIDAsIFwiZXJyb3JcIiApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjb21wbGV0ZShcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBGaWxlOiBwcm90b2NvbCBhbHdheXMgeWllbGRzIHN0YXR1cyAwOyBzZWUgIzg2MDUsICMxNDIwN1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dFxuXHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHJTdWNjZXNzU3RhdHVzWyB4aHIuc3RhdHVzIF0gfHwgeGhyLnN0YXR1cyxcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXNUZXh0LFxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSUU5IGhhcyBubyBYSFIyIGJ1dCB0aHJvd3Mgb24gYmluYXJ5ICh0cmFjLTExNDI2KVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gRm9yIFhIUjIgbm9uLXRleHQsIGxldCB0aGUgY2FsbGVyIGhhbmRsZSBpdCAoZ2gtMjQ5OClcblx0XHRcdFx0XHRcdFx0XHRcdCggeGhyLnJlc3BvbnNlVHlwZSB8fCBcInRleHRcIiApICE9PSBcInRleHRcIiAgfHxcblx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiB4aHIucmVzcG9uc2VUZXh0ICE9PSBcInN0cmluZ1wiID9cblx0XHRcdFx0XHRcdFx0XHRcdFx0eyBiaW5hcnk6IHhoci5yZXNwb25zZSB9IDpcblx0XHRcdFx0XHRcdFx0XHRcdFx0eyB0ZXh0OiB4aHIucmVzcG9uc2VUZXh0IH0sXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKClcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fTtcblxuXHRcdFx0XHQvLyBMaXN0ZW4gdG8gZXZlbnRzXG5cdFx0XHRcdHhoci5vbmxvYWQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHRlcnJvckNhbGxiYWNrID0geGhyLm9uZXJyb3IgPSB4aHIub250aW1lb3V0ID0gY2FsbGJhY2soIFwiZXJyb3JcIiApO1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDkgb25seVxuXHRcdFx0XHQvLyBVc2Ugb25yZWFkeXN0YXRlY2hhbmdlIHRvIHJlcGxhY2Ugb25hYm9ydFxuXHRcdFx0XHQvLyB0byBoYW5kbGUgdW5jYXVnaHQgYWJvcnRzXG5cdFx0XHRcdGlmICggeGhyLm9uYWJvcnQgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHR4aHIub25hYm9ydCA9IGVycm9yQ2FsbGJhY2s7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0eGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdFx0XHQvLyBDaGVjayByZWFkeVN0YXRlIGJlZm9yZSB0aW1lb3V0IGFzIGl0IGNoYW5nZXNcblx0XHRcdFx0XHRcdGlmICggeGhyLnJlYWR5U3RhdGUgPT09IDQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQWxsb3cgb25lcnJvciB0byBiZSBjYWxsZWQgZmlyc3QsXG5cdFx0XHRcdFx0XHRcdC8vIGJ1dCB0aGF0IHdpbGwgbm90IGhhbmRsZSBhIG5hdGl2ZSBhYm9ydFxuXHRcdFx0XHRcdFx0XHQvLyBBbHNvLCBzYXZlIGVycm9yQ2FsbGJhY2sgdG8gYSB2YXJpYWJsZVxuXHRcdFx0XHRcdFx0XHQvLyBhcyB4aHIub25lcnJvciBjYW5ub3QgYmUgYWNjZXNzZWRcblx0XHRcdFx0XHRcdFx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRlcnJvckNhbGxiYWNrKCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIENyZWF0ZSB0aGUgYWJvcnQgY2FsbGJhY2tcblx0XHRcdFx0Y2FsbGJhY2sgPSBjYWxsYmFjayggXCJhYm9ydFwiICk7XG5cblx0XHRcdFx0dHJ5IHtcblxuXHRcdFx0XHRcdC8vIERvIHNlbmQgdGhlIHJlcXVlc3QgKHRoaXMgbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbilcblx0XHRcdFx0XHR4aHIuc2VuZCggb3B0aW9ucy5oYXNDb250ZW50ICYmIG9wdGlvbnMuZGF0YSB8fCBudWxsICk7XG5cdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXG5cdFx0XHRcdFx0Ly8gIzE0NjgzOiBPbmx5IHJldGhyb3cgaWYgdGhpcyBoYXNuJ3QgYmVlbiBub3RpZmllZCBhcyBhbiBlcnJvciB5ZXRcblx0XHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdFx0dGhyb3cgZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cblx0XHRcdGFib3J0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufSApO1xuXG5cblxuXG4vLyBQcmV2ZW50IGF1dG8tZXhlY3V0aW9uIG9mIHNjcmlwdHMgd2hlbiBubyBleHBsaWNpdCBkYXRhVHlwZSB3YXMgcHJvdmlkZWQgKFNlZSBnaC0yNDMyKVxualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIGZ1bmN0aW9uKCBzICkge1xuXHRpZiAoIHMuY3Jvc3NEb21haW4gKSB7XG5cdFx0cy5jb250ZW50cy5zY3JpcHQgPSBmYWxzZTtcblx0fVxufSApO1xuXG4vLyBJbnN0YWxsIHNjcmlwdCBkYXRhVHlwZVxualF1ZXJ5LmFqYXhTZXR1cCgge1xuXHRhY2NlcHRzOiB7XG5cdFx0c2NyaXB0OiBcInRleHQvamF2YXNjcmlwdCwgYXBwbGljYXRpb24vamF2YXNjcmlwdCwgXCIgK1xuXHRcdFx0XCJhcHBsaWNhdGlvbi9lY21hc2NyaXB0LCBhcHBsaWNhdGlvbi94LWVjbWFzY3JpcHRcIlxuXHR9LFxuXHRjb250ZW50czoge1xuXHRcdHNjcmlwdDogL1xcYig/OmphdmF8ZWNtYSlzY3JpcHRcXGIvXG5cdH0sXG5cdGNvbnZlcnRlcnM6IHtcblx0XHRcInRleHQgc2NyaXB0XCI6IGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIHRleHQgKTtcblx0XHRcdHJldHVybiB0ZXh0O1xuXHRcdH1cblx0fVxufSApO1xuXG4vLyBIYW5kbGUgY2FjaGUncyBzcGVjaWFsIGNhc2UgYW5kIGNyb3NzRG9tYWluXG5qUXVlcnkuYWpheFByZWZpbHRlciggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XG5cdGlmICggcy5jYWNoZSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdHMuY2FjaGUgPSBmYWxzZTtcblx0fVxuXHRpZiAoIHMuY3Jvc3NEb21haW4gKSB7XG5cdFx0cy50eXBlID0gXCJHRVRcIjtcblx0fVxufSApO1xuXG4vLyBCaW5kIHNjcmlwdCB0YWcgaGFjayB0cmFuc3BvcnRcbmpRdWVyeS5hamF4VHJhbnNwb3J0KCBcInNjcmlwdFwiLCBmdW5jdGlvbiggcyApIHtcblxuXHQvLyBUaGlzIHRyYW5zcG9ydCBvbmx5IGRlYWxzIHdpdGggY3Jvc3MgZG9tYWluIG9yIGZvcmNlZC1ieS1hdHRycyByZXF1ZXN0c1xuXHRpZiAoIHMuY3Jvc3NEb21haW4gfHwgcy5zY3JpcHRBdHRycyApIHtcblx0XHR2YXIgc2NyaXB0LCBjYWxsYmFjaztcblx0XHRyZXR1cm4ge1xuXHRcdFx0c2VuZDogZnVuY3Rpb24oIF8sIGNvbXBsZXRlICkge1xuXHRcdFx0XHRzY3JpcHQgPSBqUXVlcnkoIFwiPHNjcmlwdD5cIiApXG5cdFx0XHRcdFx0LmF0dHIoIHMuc2NyaXB0QXR0cnMgfHwge30gKVxuXHRcdFx0XHRcdC5wcm9wKCB7IGNoYXJzZXQ6IHMuc2NyaXB0Q2hhcnNldCwgc3JjOiBzLnVybCB9IClcblx0XHRcdFx0XHQub24oIFwibG9hZCBlcnJvclwiLCBjYWxsYmFjayA9IGZ1bmN0aW9uKCBldnQgKSB7XG5cdFx0XHRcdFx0XHRzY3JpcHQucmVtb3ZlKCk7XG5cdFx0XHRcdFx0XHRjYWxsYmFjayA9IG51bGw7XG5cdFx0XHRcdFx0XHRpZiAoIGV2dCApIHtcblx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIGV2dC50eXBlID09PSBcImVycm9yXCIgPyA0MDQgOiAyMDAsIGV2dC50eXBlICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdC8vIFVzZSBuYXRpdmUgRE9NIG1hbmlwdWxhdGlvbiB0byBhdm9pZCBvdXIgZG9tTWFuaXAgQUpBWCB0cmlja2VyeVxuXHRcdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKCBzY3JpcHRbIDAgXSApO1xuXHRcdFx0fSxcblx0XHRcdGFib3J0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufSApO1xuXG5cblxuXG52YXIgb2xkQ2FsbGJhY2tzID0gW10sXG5cdHJqc29ucCA9IC8oPSlcXD8oPz0mfCQpfFxcP1xcPy87XG5cbi8vIERlZmF1bHQganNvbnAgc2V0dGluZ3NcbmpRdWVyeS5hamF4U2V0dXAoIHtcblx0anNvbnA6IFwiY2FsbGJhY2tcIixcblx0anNvbnBDYWxsYmFjazogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGNhbGxiYWNrID0gb2xkQ2FsbGJhY2tzLnBvcCgpIHx8ICggalF1ZXJ5LmV4cGFuZG8gKyBcIl9cIiArICggbm9uY2UuZ3VpZCsrICkgKTtcblx0XHR0aGlzWyBjYWxsYmFjayBdID0gdHJ1ZTtcblx0XHRyZXR1cm4gY2FsbGJhY2s7XG5cdH1cbn0gKTtcblxuLy8gRGV0ZWN0LCBub3JtYWxpemUgb3B0aW9ucyBhbmQgaW5zdGFsbCBjYWxsYmFja3MgZm9yIGpzb25wIHJlcXVlc3RzXG5qUXVlcnkuYWpheFByZWZpbHRlciggXCJqc29uIGpzb25wXCIsIGZ1bmN0aW9uKCBzLCBvcmlnaW5hbFNldHRpbmdzLCBqcVhIUiApIHtcblxuXHR2YXIgY2FsbGJhY2tOYW1lLCBvdmVyd3JpdHRlbiwgcmVzcG9uc2VDb250YWluZXIsXG5cdFx0anNvblByb3AgPSBzLmpzb25wICE9PSBmYWxzZSAmJiAoIHJqc29ucC50ZXN0KCBzLnVybCApID9cblx0XHRcdFwidXJsXCIgOlxuXHRcdFx0dHlwZW9mIHMuZGF0YSA9PT0gXCJzdHJpbmdcIiAmJlxuXHRcdFx0XHQoIHMuY29udGVudFR5cGUgfHwgXCJcIiApXG5cdFx0XHRcdFx0LmluZGV4T2YoIFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXCIgKSA9PT0gMCAmJlxuXHRcdFx0XHRyanNvbnAudGVzdCggcy5kYXRhICkgJiYgXCJkYXRhXCJcblx0XHQpO1xuXG5cdC8vIEhhbmRsZSBpZmYgdGhlIGV4cGVjdGVkIGRhdGEgdHlwZSBpcyBcImpzb25wXCIgb3Igd2UgaGF2ZSBhIHBhcmFtZXRlciB0byBzZXRcblx0aWYgKCBqc29uUHJvcCB8fCBzLmRhdGFUeXBlc1sgMCBdID09PSBcImpzb25wXCIgKSB7XG5cblx0XHQvLyBHZXQgY2FsbGJhY2sgbmFtZSwgcmVtZW1iZXJpbmcgcHJlZXhpc3RpbmcgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGl0XG5cdFx0Y2FsbGJhY2tOYW1lID0gcy5qc29ucENhbGxiYWNrID0gaXNGdW5jdGlvbiggcy5qc29ucENhbGxiYWNrICkgP1xuXHRcdFx0cy5qc29ucENhbGxiYWNrKCkgOlxuXHRcdFx0cy5qc29ucENhbGxiYWNrO1xuXG5cdFx0Ly8gSW5zZXJ0IGNhbGxiYWNrIGludG8gdXJsIG9yIGZvcm0gZGF0YVxuXHRcdGlmICgganNvblByb3AgKSB7XG5cdFx0XHRzWyBqc29uUHJvcCBdID0gc1sganNvblByb3AgXS5yZXBsYWNlKCByanNvbnAsIFwiJDFcIiArIGNhbGxiYWNrTmFtZSApO1xuXHRcdH0gZWxzZSBpZiAoIHMuanNvbnAgIT09IGZhbHNlICkge1xuXHRcdFx0cy51cmwgKz0gKCBycXVlcnkudGVzdCggcy51cmwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuanNvbnAgKyBcIj1cIiArIGNhbGxiYWNrTmFtZTtcblx0XHR9XG5cblx0XHQvLyBVc2UgZGF0YSBjb252ZXJ0ZXIgdG8gcmV0cmlldmUganNvbiBhZnRlciBzY3JpcHQgZXhlY3V0aW9uXG5cdFx0cy5jb252ZXJ0ZXJzWyBcInNjcmlwdCBqc29uXCIgXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCAhcmVzcG9uc2VDb250YWluZXIgKSB7XG5cdFx0XHRcdGpRdWVyeS5lcnJvciggY2FsbGJhY2tOYW1lICsgXCIgd2FzIG5vdCBjYWxsZWRcIiApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3BvbnNlQ29udGFpbmVyWyAwIF07XG5cdFx0fTtcblxuXHRcdC8vIEZvcmNlIGpzb24gZGF0YVR5cGVcblx0XHRzLmRhdGFUeXBlc1sgMCBdID0gXCJqc29uXCI7XG5cblx0XHQvLyBJbnN0YWxsIGNhbGxiYWNrXG5cdFx0b3ZlcndyaXR0ZW4gPSB3aW5kb3dbIGNhbGxiYWNrTmFtZSBdO1xuXHRcdHdpbmRvd1sgY2FsbGJhY2tOYW1lIF0gPSBmdW5jdGlvbigpIHtcblx0XHRcdHJlc3BvbnNlQ29udGFpbmVyID0gYXJndW1lbnRzO1xuXHRcdH07XG5cblx0XHQvLyBDbGVhbi11cCBmdW5jdGlvbiAoZmlyZXMgYWZ0ZXIgY29udmVydGVycylcblx0XHRqcVhIUi5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBJZiBwcmV2aW91cyB2YWx1ZSBkaWRuJ3QgZXhpc3QgLSByZW1vdmUgaXRcblx0XHRcdGlmICggb3ZlcndyaXR0ZW4gPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0alF1ZXJ5KCB3aW5kb3cgKS5yZW1vdmVQcm9wKCBjYWxsYmFja05hbWUgKTtcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIHJlc3RvcmUgcHJlZXhpc3RpbmcgdmFsdWVcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHdpbmRvd1sgY2FsbGJhY2tOYW1lIF0gPSBvdmVyd3JpdHRlbjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2F2ZSBiYWNrIGFzIGZyZWVcblx0XHRcdGlmICggc1sgY2FsbGJhY2tOYW1lIF0gKSB7XG5cblx0XHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgcmUtdXNpbmcgdGhlIG9wdGlvbnMgZG9lc24ndCBzY3JldyB0aGluZ3MgYXJvdW5kXG5cdFx0XHRcdHMuanNvbnBDYWxsYmFjayA9IG9yaWdpbmFsU2V0dGluZ3MuanNvbnBDYWxsYmFjaztcblxuXHRcdFx0XHQvLyBTYXZlIHRoZSBjYWxsYmFjayBuYW1lIGZvciBmdXR1cmUgdXNlXG5cdFx0XHRcdG9sZENhbGxiYWNrcy5wdXNoKCBjYWxsYmFja05hbWUgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FsbCBpZiBpdCB3YXMgYSBmdW5jdGlvbiBhbmQgd2UgaGF2ZSBhIHJlc3BvbnNlXG5cdFx0XHRpZiAoIHJlc3BvbnNlQ29udGFpbmVyICYmIGlzRnVuY3Rpb24oIG92ZXJ3cml0dGVuICkgKSB7XG5cdFx0XHRcdG92ZXJ3cml0dGVuKCByZXNwb25zZUNvbnRhaW5lclsgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHJlc3BvbnNlQ29udGFpbmVyID0gb3ZlcndyaXR0ZW4gPSB1bmRlZmluZWQ7XG5cdFx0fSApO1xuXG5cdFx0Ly8gRGVsZWdhdGUgdG8gc2NyaXB0XG5cdFx0cmV0dXJuIFwic2NyaXB0XCI7XG5cdH1cbn0gKTtcblxuXG5cblxuLy8gU3VwcG9ydDogU2FmYXJpIDggb25seVxuLy8gSW4gU2FmYXJpIDggZG9jdW1lbnRzIGNyZWF0ZWQgdmlhIGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudFxuLy8gY29sbGFwc2Ugc2libGluZyBmb3JtczogdGhlIHNlY29uZCBvbmUgYmVjb21lcyBhIGNoaWxkIG9mIHRoZSBmaXJzdCBvbmUuXG4vLyBCZWNhdXNlIG9mIHRoYXQsIHRoaXMgc2VjdXJpdHkgbWVhc3VyZSBoYXMgdG8gYmUgZGlzYWJsZWQgaW4gU2FmYXJpIDguXG4vLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM3MzM3XG5zdXBwb3J0LmNyZWF0ZUhUTUxEb2N1bWVudCA9ICggZnVuY3Rpb24oKSB7XG5cdHZhciBib2R5ID0gZG9jdW1lbnQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCBcIlwiICkuYm9keTtcblx0Ym9keS5pbm5lckhUTUwgPSBcIjxmb3JtPjwvZm9ybT48Zm9ybT48L2Zvcm0+XCI7XG5cdHJldHVybiBib2R5LmNoaWxkTm9kZXMubGVuZ3RoID09PSAyO1xufSApKCk7XG5cblxuLy8gQXJndW1lbnQgXCJkYXRhXCIgc2hvdWxkIGJlIHN0cmluZyBvZiBodG1sXG4vLyBjb250ZXh0IChvcHRpb25hbCk6IElmIHNwZWNpZmllZCwgdGhlIGZyYWdtZW50IHdpbGwgYmUgY3JlYXRlZCBpbiB0aGlzIGNvbnRleHQsXG4vLyBkZWZhdWx0cyB0byBkb2N1bWVudFxuLy8ga2VlcFNjcmlwdHMgKG9wdGlvbmFsKTogSWYgdHJ1ZSwgd2lsbCBpbmNsdWRlIHNjcmlwdHMgcGFzc2VkIGluIHRoZSBodG1sIHN0cmluZ1xualF1ZXJ5LnBhcnNlSFRNTCA9IGZ1bmN0aW9uKCBkYXRhLCBjb250ZXh0LCBrZWVwU2NyaXB0cyApIHtcblx0aWYgKCB0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gW107XG5cdH1cblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0a2VlcFNjcmlwdHMgPSBjb250ZXh0O1xuXHRcdGNvbnRleHQgPSBmYWxzZTtcblx0fVxuXG5cdHZhciBiYXNlLCBwYXJzZWQsIHNjcmlwdHM7XG5cblx0aWYgKCAhY29udGV4dCApIHtcblxuXHRcdC8vIFN0b3Agc2NyaXB0cyBvciBpbmxpbmUgZXZlbnQgaGFuZGxlcnMgZnJvbSBiZWluZyBleGVjdXRlZCBpbW1lZGlhdGVseVxuXHRcdC8vIGJ5IHVzaW5nIGRvY3VtZW50LmltcGxlbWVudGF0aW9uXG5cdFx0aWYgKCBzdXBwb3J0LmNyZWF0ZUhUTUxEb2N1bWVudCApIHtcblx0XHRcdGNvbnRleHQgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoIFwiXCIgKTtcblxuXHRcdFx0Ly8gU2V0IHRoZSBiYXNlIGhyZWYgZm9yIHRoZSBjcmVhdGVkIGRvY3VtZW50XG5cdFx0XHQvLyBzbyBhbnkgcGFyc2VkIGVsZW1lbnRzIHdpdGggVVJMc1xuXHRcdFx0Ly8gYXJlIGJhc2VkIG9uIHRoZSBkb2N1bWVudCdzIFVSTCAoZ2gtMjk2NSlcblx0XHRcdGJhc2UgPSBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoIFwiYmFzZVwiICk7XG5cdFx0XHRiYXNlLmhyZWYgPSBkb2N1bWVudC5sb2NhdGlvbi5ocmVmO1xuXHRcdFx0Y29udGV4dC5oZWFkLmFwcGVuZENoaWxkKCBiYXNlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnRleHQgPSBkb2N1bWVudDtcblx0XHR9XG5cdH1cblxuXHRwYXJzZWQgPSByc2luZ2xlVGFnLmV4ZWMoIGRhdGEgKTtcblx0c2NyaXB0cyA9ICFrZWVwU2NyaXB0cyAmJiBbXTtcblxuXHQvLyBTaW5nbGUgdGFnXG5cdGlmICggcGFyc2VkICkge1xuXHRcdHJldHVybiBbIGNvbnRleHQuY3JlYXRlRWxlbWVudCggcGFyc2VkWyAxIF0gKSBdO1xuXHR9XG5cblx0cGFyc2VkID0gYnVpbGRGcmFnbWVudCggWyBkYXRhIF0sIGNvbnRleHQsIHNjcmlwdHMgKTtcblxuXHRpZiAoIHNjcmlwdHMgJiYgc2NyaXB0cy5sZW5ndGggKSB7XG5cdFx0alF1ZXJ5KCBzY3JpcHRzICkucmVtb3ZlKCk7XG5cdH1cblxuXHRyZXR1cm4galF1ZXJ5Lm1lcmdlKCBbXSwgcGFyc2VkLmNoaWxkTm9kZXMgKTtcbn07XG5cblxuLyoqXG4gKiBMb2FkIGEgdXJsIGludG8gYSBwYWdlXG4gKi9cbmpRdWVyeS5mbi5sb2FkID0gZnVuY3Rpb24oIHVybCwgcGFyYW1zLCBjYWxsYmFjayApIHtcblx0dmFyIHNlbGVjdG9yLCB0eXBlLCByZXNwb25zZSxcblx0XHRzZWxmID0gdGhpcyxcblx0XHRvZmYgPSB1cmwuaW5kZXhPZiggXCIgXCIgKTtcblxuXHRpZiAoIG9mZiA+IC0xICkge1xuXHRcdHNlbGVjdG9yID0gc3RyaXBBbmRDb2xsYXBzZSggdXJsLnNsaWNlKCBvZmYgKSApO1xuXHRcdHVybCA9IHVybC5zbGljZSggMCwgb2ZmICk7XG5cdH1cblxuXHQvLyBJZiBpdCdzIGEgZnVuY3Rpb25cblx0aWYgKCBpc0Z1bmN0aW9uKCBwYXJhbXMgKSApIHtcblxuXHRcdC8vIFdlIGFzc3VtZSB0aGF0IGl0J3MgdGhlIGNhbGxiYWNrXG5cdFx0Y2FsbGJhY2sgPSBwYXJhbXM7XG5cdFx0cGFyYW1zID0gdW5kZWZpbmVkO1xuXG5cdC8vIE90aGVyd2lzZSwgYnVpbGQgYSBwYXJhbSBzdHJpbmdcblx0fSBlbHNlIGlmICggcGFyYW1zICYmIHR5cGVvZiBwYXJhbXMgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0dHlwZSA9IFwiUE9TVFwiO1xuXHR9XG5cblx0Ly8gSWYgd2UgaGF2ZSBlbGVtZW50cyB0byBtb2RpZnksIG1ha2UgdGhlIHJlcXVlc3Rcblx0aWYgKCBzZWxmLmxlbmd0aCA+IDAgKSB7XG5cdFx0alF1ZXJ5LmFqYXgoIHtcblx0XHRcdHVybDogdXJsLFxuXG5cdFx0XHQvLyBJZiBcInR5cGVcIiB2YXJpYWJsZSBpcyB1bmRlZmluZWQsIHRoZW4gXCJHRVRcIiBtZXRob2Qgd2lsbCBiZSB1c2VkLlxuXHRcdFx0Ly8gTWFrZSB2YWx1ZSBvZiB0aGlzIGZpZWxkIGV4cGxpY2l0IHNpbmNlXG5cdFx0XHQvLyB1c2VyIGNhbiBvdmVycmlkZSBpdCB0aHJvdWdoIGFqYXhTZXR1cCBtZXRob2Rcblx0XHRcdHR5cGU6IHR5cGUgfHwgXCJHRVRcIixcblx0XHRcdGRhdGFUeXBlOiBcImh0bWxcIixcblx0XHRcdGRhdGE6IHBhcmFtc1xuXHRcdH0gKS5kb25lKCBmdW5jdGlvbiggcmVzcG9uc2VUZXh0ICkge1xuXG5cdFx0XHQvLyBTYXZlIHJlc3BvbnNlIGZvciB1c2UgaW4gY29tcGxldGUgY2FsbGJhY2tcblx0XHRcdHJlc3BvbnNlID0gYXJndW1lbnRzO1xuXG5cdFx0XHRzZWxmLmh0bWwoIHNlbGVjdG9yID9cblxuXHRcdFx0XHQvLyBJZiBhIHNlbGVjdG9yIHdhcyBzcGVjaWZpZWQsIGxvY2F0ZSB0aGUgcmlnaHQgZWxlbWVudHMgaW4gYSBkdW1teSBkaXZcblx0XHRcdFx0Ly8gRXhjbHVkZSBzY3JpcHRzIHRvIGF2b2lkIElFICdQZXJtaXNzaW9uIERlbmllZCcgZXJyb3JzXG5cdFx0XHRcdGpRdWVyeSggXCI8ZGl2PlwiICkuYXBwZW5kKCBqUXVlcnkucGFyc2VIVE1MKCByZXNwb25zZVRleHQgKSApLmZpbmQoIHNlbGVjdG9yICkgOlxuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSB1c2UgdGhlIGZ1bGwgcmVzdWx0XG5cdFx0XHRcdHJlc3BvbnNlVGV4dCApO1xuXG5cdFx0Ly8gSWYgdGhlIHJlcXVlc3Qgc3VjY2VlZHMsIHRoaXMgZnVuY3Rpb24gZ2V0cyBcImRhdGFcIiwgXCJzdGF0dXNcIiwgXCJqcVhIUlwiXG5cdFx0Ly8gYnV0IHRoZXkgYXJlIGlnbm9yZWQgYmVjYXVzZSByZXNwb25zZSB3YXMgc2V0IGFib3ZlLlxuXHRcdC8vIElmIGl0IGZhaWxzLCB0aGlzIGZ1bmN0aW9uIGdldHMgXCJqcVhIUlwiLCBcInN0YXR1c1wiLCBcImVycm9yXCJcblx0XHR9ICkuYWx3YXlzKCBjYWxsYmFjayAmJiBmdW5jdGlvbigganFYSFIsIHN0YXR1cyApIHtcblx0XHRcdHNlbGYuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGNhbGxiYWNrLmFwcGx5KCB0aGlzLCByZXNwb25zZSB8fCBbIGpxWEhSLnJlc3BvbnNlVGV4dCwgc3RhdHVzLCBqcVhIUiBdICk7XG5cdFx0XHR9ICk7XG5cdFx0fSApO1xuXHR9XG5cblx0cmV0dXJuIHRoaXM7XG59O1xuXG5cblxuXG5qUXVlcnkuZXhwci5wc2V1ZG9zLmFuaW1hdGVkID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiBqUXVlcnkuZ3JlcCggalF1ZXJ5LnRpbWVycywgZnVuY3Rpb24oIGZuICkge1xuXHRcdHJldHVybiBlbGVtID09PSBmbi5lbGVtO1xuXHR9ICkubGVuZ3RoO1xufTtcblxuXG5cblxualF1ZXJ5Lm9mZnNldCA9IHtcblx0c2V0T2Zmc2V0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgaSApIHtcblx0XHR2YXIgY3VyUG9zaXRpb24sIGN1ckxlZnQsIGN1ckNTU1RvcCwgY3VyVG9wLCBjdXJPZmZzZXQsIGN1ckNTU0xlZnQsIGNhbGN1bGF0ZVBvc2l0aW9uLFxuXHRcdFx0cG9zaXRpb24gPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSxcblx0XHRcdGN1ckVsZW0gPSBqUXVlcnkoIGVsZW0gKSxcblx0XHRcdHByb3BzID0ge307XG5cblx0XHQvLyBTZXQgcG9zaXRpb24gZmlyc3QsIGluLWNhc2UgdG9wL2xlZnQgYXJlIHNldCBldmVuIG9uIHN0YXRpYyBlbGVtXG5cdFx0aWYgKCBwb3NpdGlvbiA9PT0gXCJzdGF0aWNcIiApIHtcblx0XHRcdGVsZW0uc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG5cdFx0fVxuXG5cdFx0Y3VyT2Zmc2V0ID0gY3VyRWxlbS5vZmZzZXQoKTtcblx0XHRjdXJDU1NUb3AgPSBqUXVlcnkuY3NzKCBlbGVtLCBcInRvcFwiICk7XG5cdFx0Y3VyQ1NTTGVmdCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwibGVmdFwiICk7XG5cdFx0Y2FsY3VsYXRlUG9zaXRpb24gPSAoIHBvc2l0aW9uID09PSBcImFic29sdXRlXCIgfHwgcG9zaXRpb24gPT09IFwiZml4ZWRcIiApICYmXG5cdFx0XHQoIGN1ckNTU1RvcCArIGN1ckNTU0xlZnQgKS5pbmRleE9mKCBcImF1dG9cIiApID4gLTE7XG5cblx0XHQvLyBOZWVkIHRvIGJlIGFibGUgdG8gY2FsY3VsYXRlIHBvc2l0aW9uIGlmIGVpdGhlclxuXHRcdC8vIHRvcCBvciBsZWZ0IGlzIGF1dG8gYW5kIHBvc2l0aW9uIGlzIGVpdGhlciBhYnNvbHV0ZSBvciBmaXhlZFxuXHRcdGlmICggY2FsY3VsYXRlUG9zaXRpb24gKSB7XG5cdFx0XHRjdXJQb3NpdGlvbiA9IGN1ckVsZW0ucG9zaXRpb24oKTtcblx0XHRcdGN1clRvcCA9IGN1clBvc2l0aW9uLnRvcDtcblx0XHRcdGN1ckxlZnQgPSBjdXJQb3NpdGlvbi5sZWZ0O1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1clRvcCA9IHBhcnNlRmxvYXQoIGN1ckNTU1RvcCApIHx8IDA7XG5cdFx0XHRjdXJMZWZ0ID0gcGFyc2VGbG9hdCggY3VyQ1NTTGVmdCApIHx8IDA7XG5cdFx0fVxuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBvcHRpb25zICkgKSB7XG5cblx0XHRcdC8vIFVzZSBqUXVlcnkuZXh0ZW5kIGhlcmUgdG8gYWxsb3cgbW9kaWZpY2F0aW9uIG9mIGNvb3JkaW5hdGVzIGFyZ3VtZW50IChnaC0xODQ4KVxuXHRcdFx0b3B0aW9ucyA9IG9wdGlvbnMuY2FsbCggZWxlbSwgaSwgalF1ZXJ5LmV4dGVuZCgge30sIGN1ck9mZnNldCApICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBvcHRpb25zLnRvcCAhPSBudWxsICkge1xuXHRcdFx0cHJvcHMudG9wID0gKCBvcHRpb25zLnRvcCAtIGN1ck9mZnNldC50b3AgKSArIGN1clRvcDtcblx0XHR9XG5cdFx0aWYgKCBvcHRpb25zLmxlZnQgIT0gbnVsbCApIHtcblx0XHRcdHByb3BzLmxlZnQgPSAoIG9wdGlvbnMubGVmdCAtIGN1ck9mZnNldC5sZWZ0ICkgKyBjdXJMZWZ0O1xuXHRcdH1cblxuXHRcdGlmICggXCJ1c2luZ1wiIGluIG9wdGlvbnMgKSB7XG5cdFx0XHRvcHRpb25zLnVzaW5nLmNhbGwoIGVsZW0sIHByb3BzICk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKCB0eXBlb2YgcHJvcHMudG9wID09PSBcIm51bWJlclwiICkge1xuXHRcdFx0XHRwcm9wcy50b3AgKz0gXCJweFwiO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCB0eXBlb2YgcHJvcHMubGVmdCA9PT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0cHJvcHMubGVmdCArPSBcInB4XCI7XG5cdFx0XHR9XG5cdFx0XHRjdXJFbGVtLmNzcyggcHJvcHMgKTtcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblxuXHQvLyBvZmZzZXQoKSByZWxhdGVzIGFuIGVsZW1lbnQncyBib3JkZXIgYm94IHRvIHRoZSBkb2N1bWVudCBvcmlnaW5cblx0b2Zmc2V0OiBmdW5jdGlvbiggb3B0aW9ucyApIHtcblxuXHRcdC8vIFByZXNlcnZlIGNoYWluaW5nIGZvciBzZXR0ZXJcblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gb3B0aW9ucyA9PT0gdW5kZWZpbmVkID9cblx0XHRcdFx0dGhpcyA6XG5cdFx0XHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5Lm9mZnNldC5zZXRPZmZzZXQoIHRoaXMsIG9wdGlvbnMsIGkgKTtcblx0XHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHZhciByZWN0LCB3aW4sXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdO1xuXG5cdFx0aWYgKCAhZWxlbSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBSZXR1cm4gemVyb3MgZm9yIGRpc2Nvbm5lY3RlZCBhbmQgaGlkZGVuIChkaXNwbGF5OiBub25lKSBlbGVtZW50cyAoZ2gtMjMxMClcblx0XHQvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHlcblx0XHQvLyBSdW5uaW5nIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBvbiBhXG5cdFx0Ly8gZGlzY29ubmVjdGVkIG5vZGUgaW4gSUUgdGhyb3dzIGFuIGVycm9yXG5cdFx0aWYgKCAhZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiB7IHRvcDogMCwgbGVmdDogMCB9O1xuXHRcdH1cblxuXHRcdC8vIEdldCBkb2N1bWVudC1yZWxhdGl2ZSBwb3NpdGlvbiBieSBhZGRpbmcgdmlld3BvcnQgc2Nyb2xsIHRvIHZpZXdwb3J0LXJlbGF0aXZlIGdCQ1Jcblx0XHRyZWN0ID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHR3aW4gPSBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXc7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogcmVjdC50b3AgKyB3aW4ucGFnZVlPZmZzZXQsXG5cdFx0XHRsZWZ0OiByZWN0LmxlZnQgKyB3aW4ucGFnZVhPZmZzZXRcblx0XHR9O1xuXHR9LFxuXG5cdC8vIHBvc2l0aW9uKCkgcmVsYXRlcyBhbiBlbGVtZW50J3MgbWFyZ2luIGJveCB0byBpdHMgb2Zmc2V0IHBhcmVudCdzIHBhZGRpbmcgYm94XG5cdC8vIFRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGJlaGF2aW9yIG9mIENTUyBhYnNvbHV0ZSBwb3NpdGlvbmluZ1xuXHRwb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCAhdGhpc1sgMCBdICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBvZmZzZXRQYXJlbnQsIG9mZnNldCwgZG9jLFxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXSxcblx0XHRcdHBhcmVudE9mZnNldCA9IHsgdG9wOiAwLCBsZWZ0OiAwIH07XG5cblx0XHQvLyBwb3NpdGlvbjpmaXhlZCBlbGVtZW50cyBhcmUgb2Zmc2V0IGZyb20gdGhlIHZpZXdwb3J0LCB3aGljaCBpdHNlbGYgYWx3YXlzIGhhcyB6ZXJvIG9mZnNldFxuXHRcdGlmICggalF1ZXJ5LmNzcyggZWxlbSwgXCJwb3NpdGlvblwiICkgPT09IFwiZml4ZWRcIiApIHtcblxuXHRcdFx0Ly8gQXNzdW1lIHBvc2l0aW9uOmZpeGVkIGltcGxpZXMgYXZhaWxhYmlsaXR5IG9mIGdldEJvdW5kaW5nQ2xpZW50UmVjdFxuXHRcdFx0b2Zmc2V0ID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRvZmZzZXQgPSB0aGlzLm9mZnNldCgpO1xuXG5cdFx0XHQvLyBBY2NvdW50IGZvciB0aGUgKnJlYWwqIG9mZnNldCBwYXJlbnQsIHdoaWNoIGNhbiBiZSB0aGUgZG9jdW1lbnQgb3IgaXRzIHJvb3QgZWxlbWVudFxuXHRcdFx0Ly8gd2hlbiBhIHN0YXRpY2FsbHkgcG9zaXRpb25lZCBlbGVtZW50IGlzIGlkZW50aWZpZWRcblx0XHRcdGRvYyA9IGVsZW0ub3duZXJEb2N1bWVudDtcblx0XHRcdG9mZnNldFBhcmVudCA9IGVsZW0ub2Zmc2V0UGFyZW50IHx8IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG5cdFx0XHR3aGlsZSAoIG9mZnNldFBhcmVudCAmJlxuXHRcdFx0XHQoIG9mZnNldFBhcmVudCA9PT0gZG9jLmJvZHkgfHwgb2Zmc2V0UGFyZW50ID09PSBkb2MuZG9jdW1lbnRFbGVtZW50ICkgJiZcblx0XHRcdFx0alF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcInBvc2l0aW9uXCIgKSA9PT0gXCJzdGF0aWNcIiApIHtcblxuXHRcdFx0XHRvZmZzZXRQYXJlbnQgPSBvZmZzZXRQYXJlbnQucGFyZW50Tm9kZTtcblx0XHRcdH1cblx0XHRcdGlmICggb2Zmc2V0UGFyZW50ICYmIG9mZnNldFBhcmVudCAhPT0gZWxlbSAmJiBvZmZzZXRQYXJlbnQubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHRcdFx0Ly8gSW5jb3Jwb3JhdGUgYm9yZGVycyBpbnRvIGl0cyBvZmZzZXQsIHNpbmNlIHRoZXkgYXJlIG91dHNpZGUgaXRzIGNvbnRlbnQgb3JpZ2luXG5cdFx0XHRcdHBhcmVudE9mZnNldCA9IGpRdWVyeSggb2Zmc2V0UGFyZW50ICkub2Zmc2V0KCk7XG5cdFx0XHRcdHBhcmVudE9mZnNldC50b3AgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcImJvcmRlclRvcFdpZHRoXCIsIHRydWUgKTtcblx0XHRcdFx0cGFyZW50T2Zmc2V0LmxlZnQgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcImJvcmRlckxlZnRXaWR0aFwiLCB0cnVlICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU3VidHJhY3QgcGFyZW50IG9mZnNldHMgYW5kIGVsZW1lbnQgbWFyZ2luc1xuXHRcdHJldHVybiB7XG5cdFx0XHR0b3A6IG9mZnNldC50b3AgLSBwYXJlbnRPZmZzZXQudG9wIC0galF1ZXJ5LmNzcyggZWxlbSwgXCJtYXJnaW5Ub3BcIiwgdHJ1ZSApLFxuXHRcdFx0bGVmdDogb2Zmc2V0LmxlZnQgLSBwYXJlbnRPZmZzZXQubGVmdCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luTGVmdFwiLCB0cnVlIClcblx0XHR9O1xuXHR9LFxuXG5cdC8vIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGRvY3VtZW50RWxlbWVudCBpbiB0aGUgZm9sbG93aW5nIGNhc2VzOlxuXHQvLyAxKSBGb3IgdGhlIGVsZW1lbnQgaW5zaWRlIHRoZSBpZnJhbWUgd2l0aG91dCBvZmZzZXRQYXJlbnQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuXG5cdC8vICAgIGRvY3VtZW50RWxlbWVudCBvZiB0aGUgcGFyZW50IHdpbmRvd1xuXHQvLyAyKSBGb3IgdGhlIGhpZGRlbiBvciBkZXRhY2hlZCBlbGVtZW50XG5cdC8vIDMpIEZvciBib2R5IG9yIGh0bWwgZWxlbWVudCwgaS5lLiBpbiBjYXNlIG9mIHRoZSBodG1sIG5vZGUgLSBpdCB3aWxsIHJldHVybiBpdHNlbGZcblx0Ly9cblx0Ly8gYnV0IHRob3NlIGV4Y2VwdGlvbnMgd2VyZSBuZXZlciBwcmVzZW50ZWQgYXMgYSByZWFsIGxpZmUgdXNlLWNhc2VzXG5cdC8vIGFuZCBtaWdodCBiZSBjb25zaWRlcmVkIGFzIG1vcmUgcHJlZmVyYWJsZSByZXN1bHRzLlxuXHQvL1xuXHQvLyBUaGlzIGxvZ2ljLCBob3dldmVyLCBpcyBub3QgZ3VhcmFudGVlZCBhbmQgY2FuIGNoYW5nZSBhdCBhbnkgcG9pbnQgaW4gdGhlIGZ1dHVyZVxuXHRvZmZzZXRQYXJlbnQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgb2Zmc2V0UGFyZW50ID0gdGhpcy5vZmZzZXRQYXJlbnQ7XG5cblx0XHRcdHdoaWxlICggb2Zmc2V0UGFyZW50ICYmIGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudCwgXCJwb3NpdGlvblwiICkgPT09IFwic3RhdGljXCIgKSB7XG5cdFx0XHRcdG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudC5vZmZzZXRQYXJlbnQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZG9jdW1lbnRFbGVtZW50O1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG4vLyBDcmVhdGUgc2Nyb2xsTGVmdCBhbmQgc2Nyb2xsVG9wIG1ldGhvZHNcbmpRdWVyeS5lYWNoKCB7IHNjcm9sbExlZnQ6IFwicGFnZVhPZmZzZXRcIiwgc2Nyb2xsVG9wOiBcInBhZ2VZT2Zmc2V0XCIgfSwgZnVuY3Rpb24oIG1ldGhvZCwgcHJvcCApIHtcblx0dmFyIHRvcCA9IFwicGFnZVlPZmZzZXRcIiA9PT0gcHJvcDtcblxuXHRqUXVlcnkuZm5bIG1ldGhvZCBdID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbWV0aG9kLCB2YWwgKSB7XG5cblx0XHRcdC8vIENvYWxlc2NlIGRvY3VtZW50cyBhbmQgd2luZG93c1xuXHRcdFx0dmFyIHdpbjtcblx0XHRcdGlmICggaXNXaW5kb3coIGVsZW0gKSApIHtcblx0XHRcdFx0d2luID0gZWxlbTtcblx0XHRcdH0gZWxzZSBpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdHdpbiA9IGVsZW0uZGVmYXVsdFZpZXc7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiB3aW4gPyB3aW5bIHByb3AgXSA6IGVsZW1bIG1ldGhvZCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHdpbiApIHtcblx0XHRcdFx0d2luLnNjcm9sbFRvKFxuXHRcdFx0XHRcdCF0b3AgPyB2YWwgOiB3aW4ucGFnZVhPZmZzZXQsXG5cdFx0XHRcdFx0dG9wID8gdmFsIDogd2luLnBhZ2VZT2Zmc2V0XG5cdFx0XHRcdCk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1bIG1ldGhvZCBdID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0sIG1ldGhvZCwgdmFsLCBhcmd1bWVudHMubGVuZ3RoICk7XG5cdH07XG59ICk7XG5cbi8vIFN1cHBvcnQ6IFNhZmFyaSA8PTcgLSA5LjEsIENocm9tZSA8PTM3IC0gNDlcbi8vIEFkZCB0aGUgdG9wL2xlZnQgY3NzSG9va3MgdXNpbmcgalF1ZXJ5LmZuLnBvc2l0aW9uXG4vLyBXZWJraXQgYnVnOiBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjkwODRcbi8vIEJsaW5rIGJ1ZzogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NTg5MzQ3XG4vLyBnZXRDb21wdXRlZFN0eWxlIHJldHVybnMgcGVyY2VudCB3aGVuIHNwZWNpZmllZCBmb3IgdG9wL2xlZnQvYm90dG9tL3JpZ2h0O1xuLy8gcmF0aGVyIHRoYW4gbWFrZSB0aGUgY3NzIG1vZHVsZSBkZXBlbmQgb24gdGhlIG9mZnNldCBtb2R1bGUsIGp1c3QgY2hlY2sgZm9yIGl0IGhlcmVcbmpRdWVyeS5lYWNoKCBbIFwidG9wXCIsIFwibGVmdFwiIF0sIGZ1bmN0aW9uKCBfaSwgcHJvcCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcm9wIF0gPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucGl4ZWxQb3NpdGlvbixcblx0XHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0XHRjb21wdXRlZCA9IGN1ckNTUyggZWxlbSwgcHJvcCApO1xuXG5cdFx0XHRcdC8vIElmIGN1ckNTUyByZXR1cm5zIHBlcmNlbnRhZ2UsIGZhbGxiYWNrIHRvIG9mZnNldFxuXHRcdFx0XHRyZXR1cm4gcm51bW5vbnB4LnRlc3QoIGNvbXB1dGVkICkgP1xuXHRcdFx0XHRcdGpRdWVyeSggZWxlbSApLnBvc2l0aW9uKClbIHByb3AgXSArIFwicHhcIiA6XG5cdFx0XHRcdFx0Y29tcHV0ZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHQpO1xufSApO1xuXG5cbi8vIENyZWF0ZSBpbm5lckhlaWdodCwgaW5uZXJXaWR0aCwgaGVpZ2h0LCB3aWR0aCwgb3V0ZXJIZWlnaHQgYW5kIG91dGVyV2lkdGggbWV0aG9kc1xualF1ZXJ5LmVhY2goIHsgSGVpZ2h0OiBcImhlaWdodFwiLCBXaWR0aDogXCJ3aWR0aFwiIH0sIGZ1bmN0aW9uKCBuYW1lLCB0eXBlICkge1xuXHRqUXVlcnkuZWFjaCggeyBwYWRkaW5nOiBcImlubmVyXCIgKyBuYW1lLCBjb250ZW50OiB0eXBlLCBcIlwiOiBcIm91dGVyXCIgKyBuYW1lIH0sXG5cdFx0ZnVuY3Rpb24oIGRlZmF1bHRFeHRyYSwgZnVuY05hbWUgKSB7XG5cblx0XHQvLyBNYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGhcblx0XHRqUXVlcnkuZm5bIGZ1bmNOYW1lIF0gPSBmdW5jdGlvbiggbWFyZ2luLCB2YWx1ZSApIHtcblx0XHRcdHZhciBjaGFpbmFibGUgPSBhcmd1bWVudHMubGVuZ3RoICYmICggZGVmYXVsdEV4dHJhIHx8IHR5cGVvZiBtYXJnaW4gIT09IFwiYm9vbGVhblwiICksXG5cdFx0XHRcdGV4dHJhID0gZGVmYXVsdEV4dHJhIHx8ICggbWFyZ2luID09PSB0cnVlIHx8IHZhbHVlID09PSB0cnVlID8gXCJtYXJnaW5cIiA6IFwiYm9yZGVyXCIgKTtcblxuXHRcdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIHR5cGUsIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgZG9jO1xuXG5cdFx0XHRcdGlmICggaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0XHRcdC8vICQoIHdpbmRvdyApLm91dGVyV2lkdGgvSGVpZ2h0IHJldHVybiB3L2ggaW5jbHVkaW5nIHNjcm9sbGJhcnMgKGdoLTE3MjkpXG5cdFx0XHRcdFx0cmV0dXJuIGZ1bmNOYW1lLmluZGV4T2YoIFwib3V0ZXJcIiApID09PSAwID9cblx0XHRcdFx0XHRcdGVsZW1bIFwiaW5uZXJcIiArIG5hbWUgXSA6XG5cdFx0XHRcdFx0XHRlbGVtLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFsgXCJjbGllbnRcIiArIG5hbWUgXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEdldCBkb2N1bWVudCB3aWR0aCBvciBoZWlnaHRcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdGRvYyA9IGVsZW0uZG9jdW1lbnRFbGVtZW50O1xuXG5cdFx0XHRcdFx0Ly8gRWl0aGVyIHNjcm9sbFtXaWR0aC9IZWlnaHRdIG9yIG9mZnNldFtXaWR0aC9IZWlnaHRdIG9yIGNsaWVudFtXaWR0aC9IZWlnaHRdLFxuXHRcdFx0XHRcdC8vIHdoaWNoZXZlciBpcyBncmVhdGVzdFxuXHRcdFx0XHRcdHJldHVybiBNYXRoLm1heChcblx0XHRcdFx0XHRcdGVsZW0uYm9keVsgXCJzY3JvbGxcIiArIG5hbWUgXSwgZG9jWyBcInNjcm9sbFwiICsgbmFtZSBdLFxuXHRcdFx0XHRcdFx0ZWxlbS5ib2R5WyBcIm9mZnNldFwiICsgbmFtZSBdLCBkb2NbIFwib2Zmc2V0XCIgKyBuYW1lIF0sXG5cdFx0XHRcdFx0XHRkb2NbIFwiY2xpZW50XCIgKyBuYW1lIF1cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgP1xuXG5cdFx0XHRcdFx0Ly8gR2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudCwgcmVxdWVzdGluZyBidXQgbm90IGZvcmNpbmcgcGFyc2VGbG9hdFxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIHR5cGUsIGV4dHJhICkgOlxuXG5cdFx0XHRcdFx0Ly8gU2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudFxuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgdHlwZSwgdmFsdWUsIGV4dHJhICk7XG5cdFx0XHR9LCB0eXBlLCBjaGFpbmFibGUgPyBtYXJnaW4gOiB1bmRlZmluZWQsIGNoYWluYWJsZSApO1xuXHRcdH07XG5cdH0gKTtcbn0gKTtcblxuXG5qUXVlcnkuZWFjaCggW1xuXHRcImFqYXhTdGFydFwiLFxuXHRcImFqYXhTdG9wXCIsXG5cdFwiYWpheENvbXBsZXRlXCIsXG5cdFwiYWpheEVycm9yXCIsXG5cdFwiYWpheFN1Y2Nlc3NcIixcblx0XCJhamF4U2VuZFwiXG5dLCBmdW5jdGlvbiggX2ksIHR5cGUgKSB7XG5cdGpRdWVyeS5mblsgdHlwZSBdID0gZnVuY3Rpb24oIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlLCBmbiApO1xuXHR9O1xufSApO1xuXG5cblxuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cblx0YmluZDogZnVuY3Rpb24oIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIG51bGwsIGRhdGEsIGZuICk7XG5cdH0sXG5cdHVuYmluZDogZnVuY3Rpb24oIHR5cGVzLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYoIHR5cGVzLCBudWxsLCBmbiApO1xuXHR9LFxuXG5cdGRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApO1xuXHR9LFxuXHR1bmRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBmbiApIHtcblxuXHRcdC8vICggbmFtZXNwYWNlICkgb3IgKCBzZWxlY3RvciwgdHlwZXMgWywgZm5dIClcblx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/XG5cdFx0XHR0aGlzLm9mZiggc2VsZWN0b3IsIFwiKipcIiApIDpcblx0XHRcdHRoaXMub2ZmKCB0eXBlcywgc2VsZWN0b3IgfHwgXCIqKlwiLCBmbiApO1xuXHR9LFxuXG5cdGhvdmVyOiBmdW5jdGlvbiggZm5PdmVyLCBmbk91dCApIHtcblx0XHRyZXR1cm4gdGhpcy5tb3VzZWVudGVyKCBmbk92ZXIgKS5tb3VzZWxlYXZlKCBmbk91dCB8fCBmbk92ZXIgKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCggKCBcImJsdXIgZm9jdXMgZm9jdXNpbiBmb2N1c291dCByZXNpemUgc2Nyb2xsIGNsaWNrIGRibGNsaWNrIFwiICtcblx0XCJtb3VzZWRvd24gbW91c2V1cCBtb3VzZW1vdmUgbW91c2VvdmVyIG1vdXNlb3V0IG1vdXNlZW50ZXIgbW91c2VsZWF2ZSBcIiArXG5cdFwiY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBjb250ZXh0bWVudVwiICkuc3BsaXQoIFwiIFwiICksXG5cdGZ1bmN0aW9uKCBfaSwgbmFtZSApIHtcblxuXHRcdC8vIEhhbmRsZSBldmVudCBiaW5kaW5nXG5cdFx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggZGF0YSwgZm4gKSB7XG5cdFx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDAgP1xuXHRcdFx0XHR0aGlzLm9uKCBuYW1lLCBudWxsLCBkYXRhLCBmbiApIDpcblx0XHRcdFx0dGhpcy50cmlnZ2VyKCBuYW1lICk7XG5cdFx0fTtcblx0fSApO1xuXG5cblxuXG4vLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHlcbi8vIE1ha2Ugc3VyZSB3ZSB0cmltIEJPTSBhbmQgTkJTUFxudmFyIHJ0cmltID0gL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nO1xuXG4vLyBCaW5kIGEgZnVuY3Rpb24gdG8gYSBjb250ZXh0LCBvcHRpb25hbGx5IHBhcnRpYWxseSBhcHBseWluZyBhbnlcbi8vIGFyZ3VtZW50cy5cbi8vIGpRdWVyeS5wcm94eSBpcyBkZXByZWNhdGVkIHRvIHByb21vdGUgc3RhbmRhcmRzIChzcGVjaWZpY2FsbHkgRnVuY3Rpb24jYmluZClcbi8vIEhvd2V2ZXIsIGl0IGlzIG5vdCBzbGF0ZWQgZm9yIHJlbW92YWwgYW55IHRpbWUgc29vblxualF1ZXJ5LnByb3h5ID0gZnVuY3Rpb24oIGZuLCBjb250ZXh0ICkge1xuXHR2YXIgdG1wLCBhcmdzLCBwcm94eTtcblxuXHRpZiAoIHR5cGVvZiBjb250ZXh0ID09PSBcInN0cmluZ1wiICkge1xuXHRcdHRtcCA9IGZuWyBjb250ZXh0IF07XG5cdFx0Y29udGV4dCA9IGZuO1xuXHRcdGZuID0gdG1wO1xuXHR9XG5cblx0Ly8gUXVpY2sgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRhcmdldCBpcyBjYWxsYWJsZSwgaW4gdGhlIHNwZWNcblx0Ly8gdGhpcyB0aHJvd3MgYSBUeXBlRXJyb3IsIGJ1dCB3ZSB3aWxsIGp1c3QgcmV0dXJuIHVuZGVmaW5lZC5cblx0aWYgKCAhaXNGdW5jdGlvbiggZm4gKSApIHtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cblx0Ly8gU2ltdWxhdGVkIGJpbmRcblx0YXJncyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMiApO1xuXHRwcm94eSA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBmbi5hcHBseSggY29udGV4dCB8fCB0aGlzLCBhcmdzLmNvbmNhdCggc2xpY2UuY2FsbCggYXJndW1lbnRzICkgKSApO1xuXHR9O1xuXG5cdC8vIFNldCB0aGUgZ3VpZCBvZiB1bmlxdWUgaGFuZGxlciB0byB0aGUgc2FtZSBvZiBvcmlnaW5hbCBoYW5kbGVyLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZFxuXHRwcm94eS5ndWlkID0gZm4uZ3VpZCA9IGZuLmd1aWQgfHwgalF1ZXJ5Lmd1aWQrKztcblxuXHRyZXR1cm4gcHJveHk7XG59O1xuXG5qUXVlcnkuaG9sZFJlYWR5ID0gZnVuY3Rpb24oIGhvbGQgKSB7XG5cdGlmICggaG9sZCApIHtcblx0XHRqUXVlcnkucmVhZHlXYWl0Kys7XG5cdH0gZWxzZSB7XG5cdFx0alF1ZXJ5LnJlYWR5KCB0cnVlICk7XG5cdH1cbn07XG5qUXVlcnkuaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5qUXVlcnkucGFyc2VKU09OID0gSlNPTi5wYXJzZTtcbmpRdWVyeS5ub2RlTmFtZSA9IG5vZGVOYW1lO1xualF1ZXJ5LmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xualF1ZXJ5LmlzV2luZG93ID0gaXNXaW5kb3c7XG5qUXVlcnkuY2FtZWxDYXNlID0gY2FtZWxDYXNlO1xualF1ZXJ5LnR5cGUgPSB0b1R5cGU7XG5cbmpRdWVyeS5ub3cgPSBEYXRlLm5vdztcblxualF1ZXJ5LmlzTnVtZXJpYyA9IGZ1bmN0aW9uKCBvYmogKSB7XG5cblx0Ly8gQXMgb2YgalF1ZXJ5IDMuMCwgaXNOdW1lcmljIGlzIGxpbWl0ZWQgdG9cblx0Ly8gc3RyaW5ncyBhbmQgbnVtYmVycyAocHJpbWl0aXZlcyBvciBvYmplY3RzKVxuXHQvLyB0aGF0IGNhbiBiZSBjb2VyY2VkIHRvIGZpbml0ZSBudW1iZXJzIChnaC0yNjYyKVxuXHR2YXIgdHlwZSA9IGpRdWVyeS50eXBlKCBvYmogKTtcblx0cmV0dXJuICggdHlwZSA9PT0gXCJudW1iZXJcIiB8fCB0eXBlID09PSBcInN0cmluZ1wiICkgJiZcblxuXHRcdC8vIHBhcnNlRmxvYXQgTmFOcyBudW1lcmljLWNhc3QgZmFsc2UgcG9zaXRpdmVzIChcIlwiKVxuXHRcdC8vIC4uLmJ1dCBtaXNpbnRlcnByZXRzIGxlYWRpbmctbnVtYmVyIHN0cmluZ3MsIHBhcnRpY3VsYXJseSBoZXggbGl0ZXJhbHMgKFwiMHguLi5cIilcblx0XHQvLyBzdWJ0cmFjdGlvbiBmb3JjZXMgaW5maW5pdGllcyB0byBOYU5cblx0XHQhaXNOYU4oIG9iaiAtIHBhcnNlRmxvYXQoIG9iaiApICk7XG59O1xuXG5qUXVlcnkudHJpbSA9IGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRyZXR1cm4gdGV4dCA9PSBudWxsID9cblx0XHRcIlwiIDpcblx0XHQoIHRleHQgKyBcIlwiICkucmVwbGFjZSggcnRyaW0sIFwiXCIgKTtcbn07XG5cblxuXG4vLyBSZWdpc3RlciBhcyBhIG5hbWVkIEFNRCBtb2R1bGUsIHNpbmNlIGpRdWVyeSBjYW4gYmUgY29uY2F0ZW5hdGVkIHdpdGggb3RoZXJcbi8vIGZpbGVzIHRoYXQgbWF5IHVzZSBkZWZpbmUsIGJ1dCBub3QgdmlhIGEgcHJvcGVyIGNvbmNhdGVuYXRpb24gc2NyaXB0IHRoYXRcbi8vIHVuZGVyc3RhbmRzIGFub255bW91cyBBTUQgbW9kdWxlcy4gQSBuYW1lZCBBTUQgaXMgc2FmZXN0IGFuZCBtb3N0IHJvYnVzdFxuLy8gd2F5IHRvIHJlZ2lzdGVyLiBMb3dlcmNhc2UganF1ZXJ5IGlzIHVzZWQgYmVjYXVzZSBBTUQgbW9kdWxlIG5hbWVzIGFyZVxuLy8gZGVyaXZlZCBmcm9tIGZpbGUgbmFtZXMsIGFuZCBqUXVlcnkgaXMgbm9ybWFsbHkgZGVsaXZlcmVkIGluIGEgbG93ZXJjYXNlXG4vLyBmaWxlIG5hbWUuIERvIHRoaXMgYWZ0ZXIgY3JlYXRpbmcgdGhlIGdsb2JhbCBzbyB0aGF0IGlmIGFuIEFNRCBtb2R1bGUgd2FudHNcbi8vIHRvIGNhbGwgbm9Db25mbGljdCB0byBoaWRlIHRoaXMgdmVyc2lvbiBvZiBqUXVlcnksIGl0IHdpbGwgd29yay5cblxuLy8gTm90ZSB0aGF0IGZvciBtYXhpbXVtIHBvcnRhYmlsaXR5LCBsaWJyYXJpZXMgdGhhdCBhcmUgbm90IGpRdWVyeSBzaG91bGRcbi8vIGRlY2xhcmUgdGhlbXNlbHZlcyBhcyBhbm9ueW1vdXMgbW9kdWxlcywgYW5kIGF2b2lkIHNldHRpbmcgYSBnbG9iYWwgaWYgYW5cbi8vIEFNRCBsb2FkZXIgaXMgcHJlc2VudC4galF1ZXJ5IGlzIGEgc3BlY2lhbCBjYXNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlXG4vLyBodHRwczovL2dpdGh1Yi5jb20vanJidXJrZS9yZXF1aXJlanMvd2lraS9VcGRhdGluZy1leGlzdGluZy1saWJyYXJpZXMjd2lraS1hbm9uXG5cbmlmICggdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQgKSB7XG5cdGRlZmluZSggXCJqcXVlcnlcIiwgW10sIGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBqUXVlcnk7XG5cdH0gKTtcbn1cblxuXG5cblxudmFyXG5cblx0Ly8gTWFwIG92ZXIgalF1ZXJ5IGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF9qUXVlcnkgPSB3aW5kb3cualF1ZXJ5LFxuXG5cdC8vIE1hcCBvdmVyIHRoZSAkIGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF8kID0gd2luZG93LiQ7XG5cbmpRdWVyeS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oIGRlZXAgKSB7XG5cdGlmICggd2luZG93LiQgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cuJCA9IF8kO1xuXHR9XG5cblx0aWYgKCBkZWVwICYmIHdpbmRvdy5qUXVlcnkgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cualF1ZXJ5ID0gX2pRdWVyeTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnk7XG59O1xuXG4vLyBFeHBvc2UgalF1ZXJ5IGFuZCAkIGlkZW50aWZpZXJzLCBldmVuIGluIEFNRFxuLy8gKCM3MTAyI2NvbW1lbnQ6MTAsIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvNTU3KVxuLy8gYW5kIENvbW1vbkpTIGZvciBicm93c2VyIGVtdWxhdG9ycyAoIzEzNTY2KVxuaWYgKCB0eXBlb2Ygbm9HbG9iYWwgPT09IFwidW5kZWZpbmVkXCIgKSB7XG5cdHdpbmRvdy5qUXVlcnkgPSB3aW5kb3cuJCA9IGpRdWVyeTtcbn1cblxuXG5cblxucmV0dXJuIGpRdWVyeTtcbn0gKTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgRGF0YVZpZXcgPSBnZXROYXRpdmUocm9vdCwgJ0RhdGFWaWV3Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gRGF0YVZpZXc7XG4iLCJ2YXIgaGFzaENsZWFyID0gcmVxdWlyZSgnLi9faGFzaENsZWFyJyksXG4gICAgaGFzaERlbGV0ZSA9IHJlcXVpcmUoJy4vX2hhc2hEZWxldGUnKSxcbiAgICBoYXNoR2V0ID0gcmVxdWlyZSgnLi9faGFzaEdldCcpLFxuICAgIGhhc2hIYXMgPSByZXF1aXJlKCcuL19oYXNoSGFzJyksXG4gICAgaGFzaFNldCA9IHJlcXVpcmUoJy4vX2hhc2hTZXQnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgaGFzaCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gKi9cbmZ1bmN0aW9uIEhhc2goZW50cmllcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICB0aGlzLmNsZWFyKCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgfVxufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgSGFzaGAuXG5IYXNoLnByb3RvdHlwZS5jbGVhciA9IGhhc2hDbGVhcjtcbkhhc2gucHJvdG90eXBlWydkZWxldGUnXSA9IGhhc2hEZWxldGU7XG5IYXNoLnByb3RvdHlwZS5nZXQgPSBoYXNoR2V0O1xuSGFzaC5wcm90b3R5cGUuaGFzID0gaGFzaEhhcztcbkhhc2gucHJvdG90eXBlLnNldCA9IGhhc2hTZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gSGFzaDtcbiIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9fYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL19iYXNlTG9kYXNoJyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTU7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxhenkgd3JhcHBlciBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgbGF6eSBldmFsdWF0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gKi9cbmZ1bmN0aW9uIExhenlXcmFwcGVyKHZhbHVlKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IFtdO1xuICB0aGlzLl9fZGlyX18gPSAxO1xuICB0aGlzLl9fZmlsdGVyZWRfXyA9IGZhbHNlO1xuICB0aGlzLl9faXRlcmF0ZWVzX18gPSBbXTtcbiAgdGhpcy5fX3Rha2VDb3VudF9fID0gTUFYX0FSUkFZX0xFTkdUSDtcbiAgdGhpcy5fX3ZpZXdzX18gPSBbXTtcbn1cblxuLy8gRW5zdXJlIGBMYXp5V3JhcHBlcmAgaXMgYW4gaW5zdGFuY2Ugb2YgYGJhc2VMb2Rhc2hgLlxuTGF6eVdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG5MYXp5V3JhcHBlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBMYXp5V3JhcHBlcjtcblxubW9kdWxlLmV4cG9ydHMgPSBMYXp5V3JhcHBlcjtcbiIsInZhciBsaXN0Q2FjaGVDbGVhciA9IHJlcXVpcmUoJy4vX2xpc3RDYWNoZUNsZWFyJyksXG4gICAgbGlzdENhY2hlRGVsZXRlID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlRGVsZXRlJyksXG4gICAgbGlzdENhY2hlR2V0ID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlR2V0JyksXG4gICAgbGlzdENhY2hlSGFzID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlSGFzJyksXG4gICAgbGlzdENhY2hlU2V0ID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlU2V0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBsaXN0IGNhY2hlIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gTGlzdENhY2hlKGVudHJpZXMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7XG5cbiAgdGhpcy5jbGVhcigpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdO1xuICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7XG4gIH1cbn1cblxuLy8gQWRkIG1ldGhvZHMgdG8gYExpc3RDYWNoZWAuXG5MaXN0Q2FjaGUucHJvdG90eXBlLmNsZWFyID0gbGlzdENhY2hlQ2xlYXI7XG5MaXN0Q2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IGxpc3RDYWNoZURlbGV0ZTtcbkxpc3RDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbGlzdENhY2hlR2V0O1xuTGlzdENhY2hlLnByb3RvdHlwZS5oYXMgPSBsaXN0Q2FjaGVIYXM7XG5MaXN0Q2FjaGUucHJvdG90eXBlLnNldCA9IGxpc3RDYWNoZVNldDtcblxubW9kdWxlLmV4cG9ydHMgPSBMaXN0Q2FjaGU7XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX2Jhc2VDcmVhdGUnKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi9fYmFzZUxvZGFzaCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGNvbnN0cnVjdG9yIGZvciBjcmVhdGluZyBgbG9kYXNoYCB3cmFwcGVyIG9iamVjdHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtjaGFpbkFsbF0gRW5hYmxlIGV4cGxpY2l0IG1ldGhvZCBjaGFpbiBzZXF1ZW5jZXMuXG4gKi9cbmZ1bmN0aW9uIExvZGFzaFdyYXBwZXIodmFsdWUsIGNoYWluQWxsKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IFtdO1xuICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG4gIHRoaXMuX19pbmRleF9fID0gMDtcbiAgdGhpcy5fX3ZhbHVlc19fID0gdW5kZWZpbmVkO1xufVxuXG5Mb2Rhc2hXcmFwcGVyLnByb3RvdHlwZSA9IGJhc2VDcmVhdGUoYmFzZUxvZGFzaC5wcm90b3R5cGUpO1xuTG9kYXNoV3JhcHBlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBMb2Rhc2hXcmFwcGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExvZGFzaFdyYXBwZXI7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyksXG4gICAgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xudmFyIE1hcCA9IGdldE5hdGl2ZShyb290LCAnTWFwJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gTWFwO1xuIiwidmFyIG1hcENhY2hlQ2xlYXIgPSByZXF1aXJlKCcuL19tYXBDYWNoZUNsZWFyJyksXG4gICAgbWFwQ2FjaGVEZWxldGUgPSByZXF1aXJlKCcuL19tYXBDYWNoZURlbGV0ZScpLFxuICAgIG1hcENhY2hlR2V0ID0gcmVxdWlyZSgnLi9fbWFwQ2FjaGVHZXQnKSxcbiAgICBtYXBDYWNoZUhhcyA9IHJlcXVpcmUoJy4vX21hcENhY2hlSGFzJyksXG4gICAgbWFwQ2FjaGVTZXQgPSByZXF1aXJlKCcuL19tYXBDYWNoZVNldCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXAgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gTWFwQ2FjaGUoZW50cmllcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICB0aGlzLmNsZWFyKCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgfVxufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgTWFwQ2FjaGVgLlxuTWFwQ2FjaGUucHJvdG90eXBlLmNsZWFyID0gbWFwQ2FjaGVDbGVhcjtcbk1hcENhY2hlLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBtYXBDYWNoZURlbGV0ZTtcbk1hcENhY2hlLnByb3RvdHlwZS5nZXQgPSBtYXBDYWNoZUdldDtcbk1hcENhY2hlLnByb3RvdHlwZS5oYXMgPSBtYXBDYWNoZUhhcztcbk1hcENhY2hlLnByb3RvdHlwZS5zZXQgPSBtYXBDYWNoZVNldDtcblxubW9kdWxlLmV4cG9ydHMgPSBNYXBDYWNoZTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgUHJvbWlzZSA9IGdldE5hdGl2ZShyb290LCAnUHJvbWlzZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyksXG4gICAgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xudmFyIFNldCA9IGdldE5hdGl2ZShyb290LCAnU2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gU2V0O1xuIiwidmFyIE1hcENhY2hlID0gcmVxdWlyZSgnLi9fTWFwQ2FjaGUnKSxcbiAgICBzZXRDYWNoZUFkZCA9IHJlcXVpcmUoJy4vX3NldENhY2hlQWRkJyksXG4gICAgc2V0Q2FjaGVIYXMgPSByZXF1aXJlKCcuL19zZXRDYWNoZUhhcycpO1xuXG4vKipcbiAqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGNhY2hlIG9iamVjdCB0byBzdG9yZSB1bmlxdWUgdmFsdWVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY2FjaGUuXG4gKi9cbmZ1bmN0aW9uIFNldENhY2hlKHZhbHVlcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHZhbHVlcyA9PSBudWxsID8gMCA6IHZhbHVlcy5sZW5ndGg7XG5cbiAgdGhpcy5fX2RhdGFfXyA9IG5ldyBNYXBDYWNoZTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB0aGlzLmFkZCh2YWx1ZXNbaW5kZXhdKTtcbiAgfVxufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgU2V0Q2FjaGVgLlxuU2V0Q2FjaGUucHJvdG90eXBlLmFkZCA9IFNldENhY2hlLnByb3RvdHlwZS5wdXNoID0gc2V0Q2FjaGVBZGQ7XG5TZXRDYWNoZS5wcm90b3R5cGUuaGFzID0gc2V0Q2FjaGVIYXM7XG5cbm1vZHVsZS5leHBvcnRzID0gU2V0Q2FjaGU7XG4iLCJ2YXIgTGlzdENhY2hlID0gcmVxdWlyZSgnLi9fTGlzdENhY2hlJyksXG4gICAgc3RhY2tDbGVhciA9IHJlcXVpcmUoJy4vX3N0YWNrQ2xlYXInKSxcbiAgICBzdGFja0RlbGV0ZSA9IHJlcXVpcmUoJy4vX3N0YWNrRGVsZXRlJyksXG4gICAgc3RhY2tHZXQgPSByZXF1aXJlKCcuL19zdGFja0dldCcpLFxuICAgIHN0YWNrSGFzID0gcmVxdWlyZSgnLi9fc3RhY2tIYXMnKSxcbiAgICBzdGFja1NldCA9IHJlcXVpcmUoJy4vX3N0YWNrU2V0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHN0YWNrIGNhY2hlIG9iamVjdCB0byBzdG9yZSBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gKi9cbmZ1bmN0aW9uIFN0YWNrKGVudHJpZXMpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZShlbnRyaWVzKTtcbiAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgU3RhY2tgLlxuU3RhY2sucHJvdG90eXBlLmNsZWFyID0gc3RhY2tDbGVhcjtcblN0YWNrLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBzdGFja0RlbGV0ZTtcblN0YWNrLnByb3RvdHlwZS5nZXQgPSBzdGFja0dldDtcblN0YWNrLnByb3RvdHlwZS5oYXMgPSBzdGFja0hhcztcblN0YWNrLnByb3RvdHlwZS5zZXQgPSBzdGFja1NldDtcblxubW9kdWxlLmV4cG9ydHMgPSBTdGFjaztcbiIsInZhciByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBTeW1ib2wgPSByb290LlN5bWJvbDtcblxubW9kdWxlLmV4cG9ydHMgPSBTeW1ib2w7XG4iLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgVWludDhBcnJheSA9IHJvb3QuVWludDhBcnJheTtcblxubW9kdWxlLmV4cG9ydHMgPSBVaW50OEFycmF5O1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKHJvb3QsICdXZWFrTWFwJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gV2Vha01hcDtcbiIsIi8qKlxuICogQSBmYXN0ZXIgYWx0ZXJuYXRpdmUgdG8gYEZ1bmN0aW9uI2FwcGx5YCwgdGhpcyBmdW5jdGlvbiBpbnZva2VzIGBmdW5jYFxuICogd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYXJndW1lbnRzIG9mIGBhcmdzYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIGBmdW5jYCB3aXRoLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc3VsdCBvZiBgZnVuY2AuXG4gKi9cbmZ1bmN0aW9uIGFwcGx5KGZ1bmMsIHRoaXNBcmcsIGFyZ3MpIHtcbiAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgIGNhc2UgMDogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnKTtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYXJnc1swXSk7XG4gICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgfVxuICByZXR1cm4gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcHBseTtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQWdncmVnYXRvcmAgZm9yIGFycmF5cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gKiBAcGFyYW0ge09iamVjdH0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgYWdncmVnYXRlZCBvYmplY3QuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlBZ2dyZWdhdG9yKGFycmF5LCBzZXR0ZXIsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgIHNldHRlcihhY2N1bXVsYXRvciwgdmFsdWUsIGl0ZXJhdGVlKHZhbHVlKSwgYXJyYXkpO1xuICB9XG4gIHJldHVybiBhY2N1bXVsYXRvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUFnZ3JlZ2F0b3I7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5mb3JFYWNoYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlFYWNoKGFycmF5LCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSA9PT0gZmFsc2UpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlFYWNoO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZmlsdGVyYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RmlsdGVyKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc0luZGV4ID0gMCxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5RmlsdGVyO1xuIiwidmFyIGJhc2VJbmRleE9mID0gcmVxdWlyZSgnLi9fYmFzZUluZGV4T2YnKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uaW5jbHVkZXNgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICogc3BlY2lmeWluZyBhbiBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0gdGFyZ2V0IFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB0YXJnZXRgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5SW5jbHVkZXMoYXJyYXksIHZhbHVlKSB7XG4gIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgcmV0dXJuICEhbGVuZ3RoICYmIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgMCkgPiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUluY2x1ZGVzO1xuIiwiLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGFycmF5SW5jbHVkZXNgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYSBjb21wYXJhdG9yLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJhdG9yIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHRhcmdldGAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlJbmNsdWRlc1dpdGgoYXJyYXksIHZhbHVlLCBjb21wYXJhdG9yKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoY29tcGFyYXRvcih2YWx1ZSwgYXJyYXlbaW5kZXhdKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUluY2x1ZGVzV2l0aDtcbiIsInZhciBiYXNlVGltZXMgPSByZXF1aXJlKCcuL19iYXNlVGltZXMnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNCdWZmZXIgPSByZXF1aXJlKCcuL2lzQnVmZmVyJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vX2lzSW5kZXgnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGluaGVyaXRlZCBTcGVjaWZ5IHJldHVybmluZyBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBhcnJheUxpa2VLZXlzKHZhbHVlLCBpbmhlcml0ZWQpIHtcbiAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSksXG4gICAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyh2YWx1ZSksXG4gICAgICBpc0J1ZmYgPSAhaXNBcnIgJiYgIWlzQXJnICYmIGlzQnVmZmVyKHZhbHVlKSxcbiAgICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkodmFsdWUpLFxuICAgICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLFxuICAgICAgcmVzdWx0ID0gc2tpcEluZGV4ZXMgPyBiYXNlVGltZXModmFsdWUubGVuZ3RoLCBTdHJpbmcpIDogW10sXG4gICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgIGlmICgoaW5oZXJpdGVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIGtleSkpICYmXG4gICAgICAgICEoc2tpcEluZGV4ZXMgJiYgKFxuICAgICAgICAgICAvLyBTYWZhcmkgOSBoYXMgZW51bWVyYWJsZSBgYXJndW1lbnRzLmxlbmd0aGAgaW4gc3RyaWN0IG1vZGUuXG4gICAgICAgICAgIGtleSA9PSAnbGVuZ3RoJyB8fFxuICAgICAgICAgICAvLyBOb2RlLmpzIDAuMTAgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gYnVmZmVycy5cbiAgICAgICAgICAgKGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykpIHx8XG4gICAgICAgICAgIC8vIFBoYW50b21KUyAyIGhhcyBlbnVtZXJhYmxlIG5vbi1pbmRleCBwcm9wZXJ0aWVzIG9uIHR5cGVkIGFycmF5cy5cbiAgICAgICAgICAgKGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykpIHx8XG4gICAgICAgICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy5cbiAgICAgICAgICAgaXNJbmRleChrZXksIGxlbmd0aClcbiAgICAgICAgKSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlMaWtlS2V5cztcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLm1hcGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlXG4gKiBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlNYXA7XG4iLCIvKipcbiAqIEFwcGVuZHMgdGhlIGVsZW1lbnRzIG9mIGB2YWx1ZXNgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBhcHBlbmQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlQdXNoKGFycmF5LCB2YWx1ZXMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgb2Zmc2V0ID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgYXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gdmFsdWVzW2luZGV4XTtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlQdXNoO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlXG4gKiBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5U29tZShhcnJheSwgcHJlZGljYXRlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVNvbWU7XG4iLCJ2YXIgYmFzZUFzc2lnblZhbHVlID0gcmVxdWlyZSgnLi9fYmFzZUFzc2lnblZhbHVlJyksXG4gICAgZXEgPSByZXF1aXJlKCcuL2VxJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQXNzaWducyBgdmFsdWVgIHRvIGBrZXlgIG9mIGBvYmplY3RgIGlmIHRoZSBleGlzdGluZyB2YWx1ZSBpcyBub3QgZXF1aXZhbGVudFxuICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICovXG5mdW5jdGlvbiBhc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV07XG4gIGlmICghKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpICYmIGVxKG9ialZhbHVlLCB2YWx1ZSkpIHx8XG4gICAgICAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSkge1xuICAgIGJhc2VBc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzaWduVmFsdWU7XG4iLCJ2YXIgZXEgPSByZXF1aXJlKCcuL2VxJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGBrZXlgIGlzIGZvdW5kIGluIGBhcnJheWAgb2Yga2V5LXZhbHVlIHBhaXJzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0ga2V5IFRoZSBrZXkgdG8gc2VhcmNoIGZvci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gKi9cbmZ1bmN0aW9uIGFzc29jSW5kZXhPZihhcnJheSwga2V5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChlcShhcnJheVtsZW5ndGhdWzBdLCBrZXkpKSB7XG4gICAgICByZXR1cm4gbGVuZ3RoO1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzb2NJbmRleE9mO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi9fYmFzZUVhY2gnKTtcblxuLyoqXG4gKiBBZ2dyZWdhdGVzIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCBvbiBgYWNjdW11bGF0b3JgIHdpdGgga2V5cyB0cmFuc2Zvcm1lZFxuICogYnkgYGl0ZXJhdGVlYCBhbmQgdmFsdWVzIHNldCBieSBgc2V0dGVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gKiBAcGFyYW0ge09iamVjdH0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgYWdncmVnYXRlZCBvYmplY3QuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUFnZ3JlZ2F0b3IoY29sbGVjdGlvbiwgc2V0dGVyLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgIHNldHRlcihhY2N1bXVsYXRvciwgdmFsdWUsIGl0ZXJhdGVlKHZhbHVlKSwgY29sbGVjdGlvbik7XG4gIH0pO1xuICByZXR1cm4gYWNjdW11bGF0b3I7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUFnZ3JlZ2F0b3I7XG4iLCJ2YXIgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19kZWZpbmVQcm9wZXJ0eScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBhc3NpZ25WYWx1ZWAgYW5kIGBhc3NpZ25NZXJnZVZhbHVlYCB3aXRob3V0XG4gKiB2YWx1ZSBjaGVja3MuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAqL1xuZnVuY3Rpb24gYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICBpZiAoa2V5ID09ICdfX3Byb3RvX18nICYmIGRlZmluZVByb3BlcnR5KSB7XG4gICAgZGVmaW5lUHJvcGVydHkob2JqZWN0LCBrZXksIHtcbiAgICAgICdjb25maWd1cmFibGUnOiB0cnVlLFxuICAgICAgJ2VudW1lcmFibGUnOiB0cnVlLFxuICAgICAgJ3ZhbHVlJzogdmFsdWUsXG4gICAgICAnd3JpdGFibGUnOiB0cnVlXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VBc3NpZ25WYWx1ZTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jcmVhdGVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXNzaWduaW5nXG4gKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvIFRoZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAqL1xudmFyIGJhc2VDcmVhdGUgPSAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIG9iamVjdCgpIHt9XG4gIHJldHVybiBmdW5jdGlvbihwcm90bykge1xuICAgIGlmICghaXNPYmplY3QocHJvdG8pKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGlmIChvYmplY3RDcmVhdGUpIHtcbiAgICAgIHJldHVybiBvYmplY3RDcmVhdGUocHJvdG8pO1xuICAgIH1cbiAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG87XG4gICAgdmFyIHJlc3VsdCA9IG5ldyBvYmplY3Q7XG4gICAgb2JqZWN0LnByb3RvdHlwZSA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ3JlYXRlO1xuIiwidmFyIFNldENhY2hlID0gcmVxdWlyZSgnLi9fU2V0Q2FjaGUnKSxcbiAgICBhcnJheUluY2x1ZGVzID0gcmVxdWlyZSgnLi9fYXJyYXlJbmNsdWRlcycpLFxuICAgIGFycmF5SW5jbHVkZXNXaXRoID0gcmVxdWlyZSgnLi9fYXJyYXlJbmNsdWRlc1dpdGgnKSxcbiAgICBhcnJheU1hcCA9IHJlcXVpcmUoJy4vX2FycmF5TWFwJyksXG4gICAgYmFzZVVuYXJ5ID0gcmVxdWlyZSgnLi9fYmFzZVVuYXJ5JyksXG4gICAgY2FjaGVIYXMgPSByZXF1aXJlKCcuL19jYWNoZUhhcycpO1xuXG4vKiogVXNlZCBhcyB0aGUgc2l6ZSB0byBlbmFibGUgbGFyZ2UgYXJyYXkgb3B0aW1pemF0aW9ucy4gKi9cbnZhciBMQVJHRV9BUlJBWV9TSVpFID0gMjAwO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5kaWZmZXJlbmNlYCB3aXRob3V0IHN1cHBvcnRcbiAqIGZvciBleGNsdWRpbmcgbXVsdGlwbGUgYXJyYXlzIG9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gYmFzZURpZmZlcmVuY2UoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXMsXG4gICAgICBpc0NvbW1vbiA9IHRydWUsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBbXSxcbiAgICAgIHZhbHVlc0xlbmd0aCA9IHZhbHVlcy5sZW5ndGg7XG5cbiAgaWYgKCFsZW5ndGgpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGlmIChpdGVyYXRlZSkge1xuICAgIHZhbHVlcyA9IGFycmF5TWFwKHZhbHVlcywgYmFzZVVuYXJ5KGl0ZXJhdGVlKSk7XG4gIH1cbiAgaWYgKGNvbXBhcmF0b3IpIHtcbiAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXNXaXRoO1xuICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gIH1cbiAgZWxzZSBpZiAodmFsdWVzLmxlbmd0aCA+PSBMQVJHRV9BUlJBWV9TSVpFKSB7XG4gICAgaW5jbHVkZXMgPSBjYWNoZUhhcztcbiAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgIHZhbHVlcyA9IG5ldyBTZXRDYWNoZSh2YWx1ZXMpO1xuICB9XG4gIG91dGVyOlxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA9PSBudWxsID8gdmFsdWUgOiBpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICB2YWx1ZSA9IChjb21wYXJhdG9yIHx8IHZhbHVlICE9PSAwKSA/IHZhbHVlIDogMDtcbiAgICBpZiAoaXNDb21tb24gJiYgY29tcHV0ZWQgPT09IGNvbXB1dGVkKSB7XG4gICAgICB2YXIgdmFsdWVzSW5kZXggPSB2YWx1ZXNMZW5ndGg7XG4gICAgICB3aGlsZSAodmFsdWVzSW5kZXgtLSkge1xuICAgICAgICBpZiAodmFsdWVzW3ZhbHVlc0luZGV4XSA9PT0gY29tcHV0ZWQpIHtcbiAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgIH1cbiAgICBlbHNlIGlmICghaW5jbHVkZXModmFsdWVzLCBjb21wdXRlZCwgY29tcGFyYXRvcikpIHtcbiAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRGlmZmVyZW5jZTtcbiIsInZhciBiYXNlRm9yT3duID0gcmVxdWlyZSgnLi9fYmFzZUZvck93bicpLFxuICAgIGNyZWF0ZUJhc2VFYWNoID0gcmVxdWlyZSgnLi9fY3JlYXRlQmFzZUVhY2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAqL1xudmFyIGJhc2VFYWNoID0gY3JlYXRlQmFzZUVhY2goYmFzZUZvck93bik7XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUVhY2g7XG4iLCJ2YXIgYmFzZUVhY2ggPSByZXF1aXJlKCcuL19iYXNlRWFjaCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbHRlcmAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlRmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSkge1xuICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZpbHRlcjtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmluZEluZGV4YCBhbmQgYF8uZmluZExhc3RJbmRleGAgd2l0aG91dFxuICogc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlRmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCwgZnJvbVJpZ2h0KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBpbmRleCA9IGZyb21JbmRleCArIChmcm9tUmlnaHQgPyAxIDogLTEpO1xuXG4gIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpKSB7XG4gICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGaW5kSW5kZXg7XG4iLCJ2YXIgYXJyYXlQdXNoID0gcmVxdWlyZSgnLi9fYXJyYXlQdXNoJyksXG4gICAgaXNGbGF0dGVuYWJsZSA9IHJlcXVpcmUoJy4vX2lzRmxhdHRlbmFibGUnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mbGF0dGVuYCB3aXRoIHN1cHBvcnQgZm9yIHJlc3RyaWN0aW5nIGZsYXR0ZW5pbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICogQHBhcmFtIHtudW1iZXJ9IGRlcHRoIFRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBkZXB0aC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3ByZWRpY2F0ZT1pc0ZsYXR0ZW5hYmxlXSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNTdHJpY3RdIFJlc3RyaWN0IHRvIHZhbHVlcyB0aGF0IHBhc3MgYHByZWRpY2F0ZWAgY2hlY2tzLlxuICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdD1bXV0gVGhlIGluaXRpYWwgcmVzdWx0IHZhbHVlLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlRmxhdHRlbihhcnJheSwgZGVwdGgsIHByZWRpY2F0ZSwgaXNTdHJpY3QsIHJlc3VsdCkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICBwcmVkaWNhdGUgfHwgKHByZWRpY2F0ZSA9IGlzRmxhdHRlbmFibGUpO1xuICByZXN1bHQgfHwgKHJlc3VsdCA9IFtdKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAoZGVwdGggPiAwICYmIHByZWRpY2F0ZSh2YWx1ZSkpIHtcbiAgICAgIGlmIChkZXB0aCA+IDEpIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgZmxhdHRlbiBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgYmFzZUZsYXR0ZW4odmFsdWUsIGRlcHRoIC0gMSwgcHJlZGljYXRlLCBpc1N0cmljdCwgcmVzdWx0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFycmF5UHVzaChyZXN1bHQsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFpc1N0cmljdCkge1xuICAgICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZsYXR0ZW47XG4iLCJ2YXIgY3JlYXRlQmFzZUZvciA9IHJlcXVpcmUoJy4vX2NyZWF0ZUJhc2VGb3InKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgYmFzZUZvck93bmAgd2hpY2ggaXRlcmF0ZXMgb3ZlciBgb2JqZWN0YFxuICogcHJvcGVydGllcyByZXR1cm5lZCBieSBga2V5c0Z1bmNgIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggcHJvcGVydHkuXG4gKiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vX2Jhc2VGb3InKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBvYmplY3QgJiYgYmFzZUZvcihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9yT3duO1xuIiwidmFyIGNhc3RQYXRoID0gcmVxdWlyZSgnLi9fY2FzdFBhdGgnKSxcbiAgICB0b0tleSA9IHJlcXVpcmUoJy4vX3RvS2V5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZ2V0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZmF1bHQgdmFsdWVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlR2V0KG9iamVjdCwgcGF0aCkge1xuICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcblxuICB2YXIgaW5kZXggPSAwLFxuICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgb2JqZWN0ID0gb2JqZWN0W3RvS2V5KHBhdGhbaW5kZXgrK10pXTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldDtcbiIsInZhciBhcnJheVB1c2ggPSByZXF1aXJlKCcuL19hcnJheVB1c2gnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldEFsbEtleXNgIGFuZCBgZ2V0QWxsS2V5c0luYCB3aGljaCB1c2VzXG4gKiBga2V5c0Z1bmNgIGFuZCBgc3ltYm9sc0Z1bmNgIHRvIGdldCB0aGUgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmRcbiAqIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzeW1ib2xzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAqL1xuZnVuY3Rpb24gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzRnVuYywgc3ltYm9sc0Z1bmMpIHtcbiAgdmFyIHJlc3VsdCA9IGtleXNGdW5jKG9iamVjdCk7XG4gIHJldHVybiBpc0FycmF5KG9iamVjdCkgPyByZXN1bHQgOiBhcnJheVB1c2gocmVzdWx0LCBzeW1ib2xzRnVuYyhvYmplY3QpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlR2V0QWxsS2V5cztcbiIsInZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19TeW1ib2wnKSxcbiAgICBnZXRSYXdUYWcgPSByZXF1aXJlKCcuL19nZXRSYXdUYWcnKSxcbiAgICBvYmplY3RUb1N0cmluZyA9IHJlcXVpcmUoJy4vX29iamVjdFRvU3RyaW5nJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBudWxsVGFnID0gJ1tvYmplY3QgTnVsbF0nLFxuICAgIHVuZGVmaW5lZFRhZyA9ICdbb2JqZWN0IFVuZGVmaW5lZF0nO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBzeW1Ub1N0cmluZ1RhZyA9IFN5bWJvbCA/IFN5bWJvbC50b1N0cmluZ1RhZyA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgZ2V0VGFnYCB3aXRob3V0IGZhbGxiYWNrcyBmb3IgYnVnZ3kgZW52aXJvbm1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXRUYWcodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZFRhZyA6IG51bGxUYWc7XG4gIH1cbiAgcmV0dXJuIChzeW1Ub1N0cmluZ1RhZyAmJiBzeW1Ub1N0cmluZ1RhZyBpbiBPYmplY3QodmFsdWUpKVxuICAgID8gZ2V0UmF3VGFnKHZhbHVlKVxuICAgIDogb2JqZWN0VG9TdHJpbmcodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VHZXRUYWc7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmhhc0luYCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IGtleSBUaGUga2V5IHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSGFzSW4ob2JqZWN0LCBrZXkpIHtcbiAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGtleSBpbiBPYmplY3Qob2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSGFzSW47XG4iLCJ2YXIgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vX2Jhc2VGaW5kSW5kZXgnKSxcbiAgICBiYXNlSXNOYU4gPSByZXF1aXJlKCcuL19iYXNlSXNOYU4nKSxcbiAgICBzdHJpY3RJbmRleE9mID0gcmVxdWlyZSgnLi9fc3RyaWN0SW5kZXhPZicpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmluZGV4T2ZgIHdpdGhvdXQgYGZyb21JbmRleGAgYm91bmRzIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICByZXR1cm4gdmFsdWUgPT09IHZhbHVlXG4gICAgPyBzdHJpY3RJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KVxuICAgIDogYmFzZUZpbmRJbmRleChhcnJheSwgYmFzZUlzTmFOLCBmcm9tSW5kZXgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJbmRleE9mO1xuIiwidmFyIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0FyZ3VtZW50c2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LFxuICovXG5mdW5jdGlvbiBiYXNlSXNBcmd1bWVudHModmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJnc1RhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNBcmd1bWVudHM7XG4iLCJ2YXIgYmFzZUlzRXF1YWxEZWVwID0gcmVxdWlyZSgnLi9fYmFzZUlzRXF1YWxEZWVwJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aGljaCBzdXBwb3J0cyBwYXJ0aWFsIGNvbXBhcmlzb25zXG4gKiBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAqICAxIC0gVW5vcmRlcmVkIGNvbXBhcmlzb25cbiAqICAyIC0gUGFydGlhbCBjb21wYXJpc29uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBzdGFjaykge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzT2JqZWN0TGlrZShvdGhlcikpKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7XG4gIH1cbiAgcmV0dXJuIGJhc2VJc0VxdWFsRGVlcCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGJhc2VJc0VxdWFsLCBzdGFjayk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzRXF1YWw7XG4iLCJ2YXIgU3RhY2sgPSByZXF1aXJlKCcuL19TdGFjaycpLFxuICAgIGVxdWFsQXJyYXlzID0gcmVxdWlyZSgnLi9fZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9fZXF1YWxCeVRhZycpLFxuICAgIGVxdWFsT2JqZWN0cyA9IHJlcXVpcmUoJy4vX2VxdWFsT2JqZWN0cycpLFxuICAgIGdldFRhZyA9IHJlcXVpcmUoJy4vX2dldFRhZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0J1ZmZlciA9IHJlcXVpcmUoJy4vaXNCdWZmZXInKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi9cbnZhciBDT01QQVJFX1BBUlRJQUxfRkxBRyA9IDE7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAqIHJlZmVyZW5jZXMgdG8gYmUgY29tcGFyZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgIG90aElzQXJyID0gaXNBcnJheShvdGhlciksXG4gICAgICBvYmpUYWcgPSBvYmpJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG9iamVjdCksXG4gICAgICBvdGhUYWcgPSBvdGhJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG90aGVyKTtcblxuICBvYmpUYWcgPSBvYmpUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG9ialRhZztcbiAgb3RoVGFnID0gb3RoVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvdGhUYWc7XG5cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyxcbiAgICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZyxcbiAgICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7XG5cbiAgaWYgKGlzU2FtZVRhZyAmJiBpc0J1ZmZlcihvYmplY3QpKSB7XG4gICAgaWYgKCFpc0J1ZmZlcihvdGhlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgb2JqSXNBcnIgPSB0cnVlO1xuICAgIG9iaklzT2JqID0gZmFsc2U7XG4gIH1cbiAgaWYgKGlzU2FtZVRhZyAmJiAhb2JqSXNPYmopIHtcbiAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgIHJldHVybiAob2JqSXNBcnIgfHwgaXNUeXBlZEFycmF5KG9iamVjdCkpXG4gICAgICA/IGVxdWFsQXJyYXlzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spXG4gICAgICA6IGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgfVxuICBpZiAoIShiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcpKSB7XG4gICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSxcbiAgICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7XG5cbiAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkge1xuICAgICAgdmFyIG9ialVud3JhcHBlZCA9IG9iaklzV3JhcHBlZCA/IG9iamVjdC52YWx1ZSgpIDogb2JqZWN0LFxuICAgICAgICAgIG90aFVud3JhcHBlZCA9IG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlcjtcblxuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqVW53cmFwcGVkLCBvdGhVbndyYXBwZWQsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFpc1NhbWVUYWcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgcmV0dXJuIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgU3RhY2sgPSByZXF1aXJlKCcuL19TdGFjaycpLFxuICAgIGJhc2VJc0VxdWFsID0gcmVxdWlyZSgnLi9fYmFzZUlzRXF1YWwnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWF0Y2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ0eSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyB0byBtYXRjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzTWF0Y2gob2JqZWN0LCBzb3VyY2UsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gIWxlbmd0aDtcbiAgfVxuICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07XG4gICAgaWYgKChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSlcbiAgICAgICAgICA/IGRhdGFbMV0gIT09IG9iamVjdFtkYXRhWzBdXVxuICAgICAgICAgIDogIShkYXRhWzBdIGluIG9iamVjdClcbiAgICAgICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07XG4gICAgdmFyIGtleSA9IGRhdGFbMF0sXG4gICAgICAgIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgIHNyY1ZhbHVlID0gZGF0YVsxXTtcblxuICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSkge1xuICAgICAgaWYgKG9ialZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBzdGFjayA9IG5ldyBTdGFjaztcbiAgICAgIGlmIChjdXN0b21pemVyKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSwgc3RhY2spO1xuICAgICAgfVxuICAgICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcsIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICAgICAgOiByZXN1bHRcbiAgICAgICAgICApKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzTWF0Y2g7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmFOYCB3aXRob3V0IHN1cHBvcnQgZm9yIG51bWJlciBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBOYU5gLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc05hTih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT09IHZhbHVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc05hTjtcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNNYXNrZWQgPSByZXF1aXJlKCcuL19pc01hc2tlZCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpLFxuICAgIHRvU291cmNlID0gcmVxdWlyZSgnLi9fdG9Tb3VyY2UnKTtcblxuLyoqXG4gKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgXG4gKiBbc3ludGF4IGNoYXJhY3RlcnNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXBhdHRlcm5zKS5cbiAqL1xudmFyIHJlUmVnRXhwQ2hhciA9IC9bXFxcXF4kLiorPygpW1xcXXt9fF0vZztcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGhvc3QgY29uc3RydWN0b3JzIChTYWZhcmkpLiAqL1xudmFyIHJlSXNIb3N0Q3RvciA9IC9eXFxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXFxdJC87XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBmdW5jUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGUsXG4gICAgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byByZXNvbHZlIHRoZSBkZWNvbXBpbGVkIHNvdXJjZSBvZiBmdW5jdGlvbnMuICovXG52YXIgZnVuY1RvU3RyaW5nID0gZnVuY1Byb3RvLnRvU3RyaW5nO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaWYgYSBtZXRob2QgaXMgbmF0aXZlLiAqL1xudmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICtcbiAgZnVuY1RvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UocmVSZWdFeHBDaGFyLCAnXFxcXCQmJylcbiAgLnJlcGxhY2UoL2hhc093blByb3BlcnR5fChmdW5jdGlvbikuKj8oPz1cXFxcXFwoKXwgZm9yIC4rPyg/PVxcXFxcXF0pL2csICckMS4qPycpICsgJyQnXG4pO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmF0aXZlYCB3aXRob3V0IGJhZCBzaGltIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbixcbiAqICBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc05hdGl2ZSh2YWx1ZSkge1xuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSB8fCBpc01hc2tlZCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHBhdHRlcm4gPSBpc0Z1bmN0aW9uKHZhbHVlKSA/IHJlSXNOYXRpdmUgOiByZUlzSG9zdEN0b3I7XG4gIHJldHVybiBwYXR0ZXJuLnRlc3QodG9Tb3VyY2UodmFsdWUpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNOYXRpdmU7XG4iLCJ2YXIgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG52YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbnR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xudHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZGF0YVZpZXdUYWddID0gdHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID0gdHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPVxudHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9IHR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPVxudHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1R5cGVkQXJyYXlgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzVHlwZWRBcnJheSh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJlxuICAgIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tiYXNlR2V0VGFnKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzVHlwZWRBcnJheTtcbiIsInZhciBiYXNlTWF0Y2hlcyA9IHJlcXVpcmUoJy4vX2Jhc2VNYXRjaGVzJyksXG4gICAgYmFzZU1hdGNoZXNQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2Jhc2VNYXRjaGVzUHJvcGVydHknKSxcbiAgICBpZGVudGl0eSA9IHJlcXVpcmUoJy4vaWRlbnRpdHknKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgcHJvcGVydHkgPSByZXF1aXJlKCcuL3Byb3BlcnR5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXRlcmF0ZWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IFt2YWx1ZT1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhbiBpdGVyYXRlZS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgaXRlcmF0ZWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJdGVyYXRlZSh2YWx1ZSkge1xuICAvLyBEb24ndCBzdG9yZSB0aGUgYHR5cGVvZmAgcmVzdWx0IGluIGEgdmFyaWFibGUgdG8gYXZvaWQgYSBKSVQgYnVnIGluIFNhZmFyaSA5LlxuICAvLyBTZWUgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE1NjAzNCBmb3IgbW9yZSBkZXRhaWxzLlxuICBpZiAodHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gaWRlbnRpdHk7XG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBpc0FycmF5KHZhbHVlKVxuICAgICAgPyBiYXNlTWF0Y2hlc1Byb3BlcnR5KHZhbHVlWzBdLCB2YWx1ZVsxXSlcbiAgICAgIDogYmFzZU1hdGNoZXModmFsdWUpO1xuICB9XG4gIHJldHVybiBwcm9wZXJ0eSh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUl0ZXJhdGVlO1xuIiwidmFyIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKSxcbiAgICBuYXRpdmVLZXlzID0gcmVxdWlyZSgnLi9fbmF0aXZlS2V5cycpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmtleXNgIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqL1xuZnVuY3Rpb24gYmFzZUtleXMob2JqZWN0KSB7XG4gIGlmICghaXNQcm90b3R5cGUob2JqZWN0KSkge1xuICAgIHJldHVybiBuYXRpdmVLZXlzKG9iamVjdCk7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkgJiYga2V5ICE9ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUtleXM7XG4iLCIvKipcbiAqIFRoZSBmdW5jdGlvbiB3aG9zZSBwcm90b3R5cGUgY2hhaW4gc2VxdWVuY2Ugd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gIC8vIE5vIG9wZXJhdGlvbiBwZXJmb3JtZWQuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUxvZGFzaDtcbiIsInZhciBiYXNlRWFjaCA9IHJlcXVpcmUoJy4vX2Jhc2VFYWNoJyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWFwYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGJhc2VNYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IEFycmF5KGNvbGxlY3Rpb24ubGVuZ3RoKSA6IFtdO1xuXG4gIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSBpdGVyYXRlZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hcDtcbiIsInZhciBiYXNlSXNNYXRjaCA9IHJlcXVpcmUoJy4vX2Jhc2VJc01hdGNoJyksXG4gICAgZ2V0TWF0Y2hEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWF0Y2hEYXRhJyksXG4gICAgbWF0Y2hlc1N0cmljdENvbXBhcmFibGUgPSByZXF1aXJlKCcuL19tYXRjaGVzU3RyaWN0Q29tcGFyYWJsZScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNgIHdoaWNoIGRvZXNuJ3QgY2xvbmUgYHNvdXJjZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlTWF0Y2hlcyhzb3VyY2UpIHtcbiAgdmFyIG1hdGNoRGF0YSA9IGdldE1hdGNoRGF0YShzb3VyY2UpO1xuICBpZiAobWF0Y2hEYXRhLmxlbmd0aCA9PSAxICYmIG1hdGNoRGF0YVswXVsyXSkge1xuICAgIHJldHVybiBtYXRjaGVzU3RyaWN0Q29tcGFyYWJsZShtYXRjaERhdGFbMF1bMF0sIG1hdGNoRGF0YVswXVsxXSk7XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT09IHNvdXJjZSB8fCBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgbWF0Y2hEYXRhKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlcztcbiIsInZhciBiYXNlSXNFcXVhbCA9IHJlcXVpcmUoJy4vX2Jhc2VJc0VxdWFsJyksXG4gICAgZ2V0ID0gcmVxdWlyZSgnLi9nZXQnKSxcbiAgICBoYXNJbiA9IHJlcXVpcmUoJy4vaGFzSW4nKSxcbiAgICBpc0tleSA9IHJlcXVpcmUoJy4vX2lzS2V5JyksXG4gICAgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9faXNTdHJpY3RDb21wYXJhYmxlJyksXG4gICAgbWF0Y2hlc1N0cmljdENvbXBhcmFibGUgPSByZXF1aXJlKCcuL19tYXRjaGVzU3RyaWN0Q29tcGFyYWJsZScpLFxuICAgIHRvS2V5ID0gcmVxdWlyZSgnLi9fdG9LZXknKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lc24ndCBjbG9uZSBgc3JjVmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIHNyY1ZhbHVlKSB7XG4gIGlmIChpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpKSB7XG4gICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKHRvS2V5KHBhdGgpLCBzcmNWYWx1ZSk7XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHZhciBvYmpWYWx1ZSA9IGdldChvYmplY3QsIHBhdGgpO1xuICAgIHJldHVybiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiBvYmpWYWx1ZSA9PT0gc3JjVmFsdWUpXG4gICAgICA/IGhhc0luKG9iamVjdCwgcGF0aClcbiAgICAgIDogYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNYXRjaGVzUHJvcGVydHk7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eTtcbiIsInZhciBiYXNlR2V0ID0gcmVxdWlyZSgnLi9fYmFzZUdldCcpO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVByb3BlcnR5YCB3aGljaCBzdXBwb3J0cyBkZWVwIHBhdGhzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eURlZXAocGF0aCkge1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgcmV0dXJuIGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlUHJvcGVydHlEZWVwO1xuIiwidmFyIGlkZW50aXR5ID0gcmVxdWlyZSgnLi9pZGVudGl0eScpLFxuICAgIG92ZXJSZXN0ID0gcmVxdWlyZSgnLi9fb3ZlclJlc3QnKSxcbiAgICBzZXRUb1N0cmluZyA9IHJlcXVpcmUoJy4vX3NldFRvU3RyaW5nJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmVzdGAgd2hpY2ggZG9lc24ndCB2YWxpZGF0ZSBvciBjb2VyY2UgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD1mdW5jLmxlbmd0aC0xXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJlc3QgcGFyYW1ldGVyLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VSZXN0KGZ1bmMsIHN0YXJ0KSB7XG4gIHJldHVybiBzZXRUb1N0cmluZyhvdmVyUmVzdChmdW5jLCBzdGFydCwgaWRlbnRpdHkpLCBmdW5jICsgJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VSZXN0O1xuIiwidmFyIGlkZW50aXR5ID0gcmVxdWlyZSgnLi9pZGVudGl0eScpLFxuICAgIG1ldGFNYXAgPSByZXF1aXJlKCcuL19tZXRhTWFwJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYHNldERhdGFgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaG90IGxvb3Agc2hvcnRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBiYXNlU2V0RGF0YSA9ICFtZXRhTWFwID8gaWRlbnRpdHkgOiBmdW5jdGlvbihmdW5jLCBkYXRhKSB7XG4gIG1ldGFNYXAuc2V0KGZ1bmMsIGRhdGEpO1xuICByZXR1cm4gZnVuYztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVNldERhdGE7XG4iLCJ2YXIgY29uc3RhbnQgPSByZXF1aXJlKCcuL2NvbnN0YW50JyksXG4gICAgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19kZWZpbmVQcm9wZXJ0eScpLFxuICAgIGlkZW50aXR5ID0gcmVxdWlyZSgnLi9pZGVudGl0eScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXRUb1N0cmluZ2Agd2l0aG91dCBzdXBwb3J0IGZvciBob3QgbG9vcCBzaG9ydGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3RyaW5nIFRoZSBgdG9TdHJpbmdgIHJlc3VsdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBiYXNlU2V0VG9TdHJpbmcgPSAhZGVmaW5lUHJvcGVydHkgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIHN0cmluZykge1xuICByZXR1cm4gZGVmaW5lUHJvcGVydHkoZnVuYywgJ3RvU3RyaW5nJywge1xuICAgICdjb25maWd1cmFibGUnOiB0cnVlLFxuICAgICdlbnVtZXJhYmxlJzogZmFsc2UsXG4gICAgJ3ZhbHVlJzogY29uc3RhbnQoc3RyaW5nKSxcbiAgICAnd3JpdGFibGUnOiB0cnVlXG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2V0VG9TdHJpbmc7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRpbWVzYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHNcbiAqIG9yIG1heCBhcnJheSBsZW5ndGggY2hlY2tzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGludm9rZSBgaXRlcmF0ZWVgLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAqL1xuZnVuY3Rpb24gYmFzZVRpbWVzKG4sIGl0ZXJhdGVlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobik7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBuKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGluZGV4KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUaW1lcztcbiIsInZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19TeW1ib2wnKSxcbiAgICBhcnJheU1hcCA9IHJlcXVpcmUoJy4vX2FycmF5TWFwJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzU3ltYm9sID0gcmVxdWlyZSgnLi9pc1N5bWJvbCcpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBJTkZJTklUWSA9IDEgLyAwO1xuXG4vKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbnZhciBzeW1ib2xQcm90byA9IFN5bWJvbCA/IFN5bWJvbC5wcm90b3R5cGUgOiB1bmRlZmluZWQsXG4gICAgc3ltYm9sVG9TdHJpbmcgPSBzeW1ib2xQcm90byA/IHN5bWJvbFByb3RvLnRvU3RyaW5nIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRvU3RyaW5nYCB3aGljaCBkb2Vzbid0IGNvbnZlcnQgbnVsbGlzaFxuICogdmFsdWVzIHRvIGVtcHR5IHN0cmluZ3MuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkge1xuICAvLyBFeGl0IGVhcmx5IGZvciBzdHJpbmdzIHRvIGF2b2lkIGEgcGVyZm9ybWFuY2UgaGl0IGluIHNvbWUgZW52aXJvbm1lbnRzLlxuICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbnZlcnQgdmFsdWVzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgcmV0dXJuIGFycmF5TWFwKHZhbHVlLCBiYXNlVG9TdHJpbmcpICsgJyc7XG4gIH1cbiAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgIHJldHVybiBzeW1ib2xUb1N0cmluZyA/IHN5bWJvbFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7XG4gIH1cbiAgdmFyIHJlc3VsdCA9ICh2YWx1ZSArICcnKTtcbiAgcmV0dXJuIChyZXN1bHQgPT0gJzAnICYmICgxIC8gdmFsdWUpID09IC1JTkZJTklUWSkgPyAnLTAnIDogcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUb1N0cmluZztcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udW5hcnlgIHdpdGhvdXQgc3VwcG9ydCBmb3Igc3RvcmluZyBtZXRhZGF0YS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2FwIGFyZ3VtZW50cyBmb3IuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VVbmFyeShmdW5jKSB7XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiBmdW5jKHZhbHVlKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlVW5hcnk7XG4iLCJ2YXIgU2V0Q2FjaGUgPSByZXF1aXJlKCcuL19TZXRDYWNoZScpLFxuICAgIGFycmF5SW5jbHVkZXMgPSByZXF1aXJlKCcuL19hcnJheUluY2x1ZGVzJyksXG4gICAgYXJyYXlJbmNsdWRlc1dpdGggPSByZXF1aXJlKCcuL19hcnJheUluY2x1ZGVzV2l0aCcpLFxuICAgIGNhY2hlSGFzID0gcmVxdWlyZSgnLi9fY2FjaGVIYXMnKSxcbiAgICBjcmVhdGVTZXQgPSByZXF1aXJlKCcuL19jcmVhdGVTZXQnKSxcbiAgICBzZXRUb0FycmF5ID0gcmVxdWlyZSgnLi9fc2V0VG9BcnJheScpO1xuXG4vKiogVXNlZCBhcyB0aGUgc2l6ZSB0byBlbmFibGUgbGFyZ2UgYXJyYXkgb3B0aW1pemF0aW9ucy4gKi9cbnZhciBMQVJHRV9BUlJBWV9TSVpFID0gMjAwO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuaXFCeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlVW5pcShhcnJheSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXMsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBpc0NvbW1vbiA9IHRydWUsXG4gICAgICByZXN1bHQgPSBbXSxcbiAgICAgIHNlZW4gPSByZXN1bHQ7XG5cbiAgaWYgKGNvbXBhcmF0b3IpIHtcbiAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgIGluY2x1ZGVzID0gYXJyYXlJbmNsdWRlc1dpdGg7XG4gIH1cbiAgZWxzZSBpZiAobGVuZ3RoID49IExBUkdFX0FSUkFZX1NJWkUpIHtcbiAgICB2YXIgc2V0ID0gaXRlcmF0ZWUgPyBudWxsIDogY3JlYXRlU2V0KGFycmF5KTtcbiAgICBpZiAoc2V0KSB7XG4gICAgICByZXR1cm4gc2V0VG9BcnJheShzZXQpO1xuICAgIH1cbiAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgIGluY2x1ZGVzID0gY2FjaGVIYXM7XG4gICAgc2VlbiA9IG5ldyBTZXRDYWNoZTtcbiAgfVxuICBlbHNlIHtcbiAgICBzZWVuID0gaXRlcmF0ZWUgPyBbXSA6IHJlc3VsdDtcbiAgfVxuICBvdXRlcjpcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSkgOiB2YWx1ZTtcblxuICAgIHZhbHVlID0gKGNvbXBhcmF0b3IgfHwgdmFsdWUgIT09IDApID8gdmFsdWUgOiAwO1xuICAgIGlmIChpc0NvbW1vbiAmJiBjb21wdXRlZCA9PT0gY29tcHV0ZWQpIHtcbiAgICAgIHZhciBzZWVuSW5kZXggPSBzZWVuLmxlbmd0aDtcbiAgICAgIHdoaWxlIChzZWVuSW5kZXgtLSkge1xuICAgICAgICBpZiAoc2VlbltzZWVuSW5kZXhdID09PSBjb21wdXRlZCkge1xuICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXRlcmF0ZWUpIHtcbiAgICAgICAgc2Vlbi5wdXNoKGNvbXB1dGVkKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoIWluY2x1ZGVzKHNlZW4sIGNvbXB1dGVkLCBjb21wYXJhdG9yKSkge1xuICAgICAgaWYgKHNlZW4gIT09IHJlc3VsdCkge1xuICAgICAgICBzZWVuLnB1c2goY29tcHV0ZWQpO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VVbmlxO1xuIiwidmFyIGFycmF5TWFwID0gcmVxdWlyZSgnLi9fYXJyYXlNYXAnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy52YWx1ZXNgIGFuZCBgXy52YWx1ZXNJbmAgd2hpY2ggY3JlYXRlcyBhblxuICogYXJyYXkgb2YgYG9iamVjdGAgcHJvcGVydHkgdmFsdWVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByb3BlcnR5IG5hbWVzXG4gKiBvZiBgcHJvcHNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZ2V0IHZhbHVlcyBmb3IuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VWYWx1ZXMob2JqZWN0LCBwcm9wcykge1xuICByZXR1cm4gYXJyYXlNYXAocHJvcHMsIGZ1bmN0aW9uKGtleSkge1xuICAgIHJldHVybiBvYmplY3Rba2V5XTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVZhbHVlcztcbiIsInZhciBiYXNlRGlmZmVyZW5jZSA9IHJlcXVpcmUoJy4vX2Jhc2VEaWZmZXJlbmNlJyksXG4gICAgYmFzZUZsYXR0ZW4gPSByZXF1aXJlKCcuL19iYXNlRmxhdHRlbicpLFxuICAgIGJhc2VVbmlxID0gcmVxdWlyZSgnLi9fYmFzZVVuaXEnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8ueG9yYCwgd2l0aG91dCBzdXBwb3J0IGZvclxuICogaXRlcmF0ZWUgc2hvcnRoYW5kcywgdGhhdCBhY2NlcHRzIGFuIGFycmF5IG9mIGFycmF5cyB0byBpbnNwZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheXMgVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBiYXNlWG9yKGFycmF5cywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5cy5sZW5ndGg7XG4gIGlmIChsZW5ndGggPCAyKSB7XG4gICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VVbmlxKGFycmF5c1swXSkgOiBbXTtcbiAgfVxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgYXJyYXkgPSBhcnJheXNbaW5kZXhdLFxuICAgICAgICBvdGhJbmRleCA9IC0xO1xuXG4gICAgd2hpbGUgKCsrb3RoSW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChvdGhJbmRleCAhPSBpbmRleCkge1xuICAgICAgICByZXN1bHRbaW5kZXhdID0gYmFzZURpZmZlcmVuY2UocmVzdWx0W2luZGV4XSB8fCBhcnJheSwgYXJyYXlzW290aEluZGV4XSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4ocmVzdWx0LCAxKSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VYb3I7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBhIGBjYWNoZWAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IGNhY2hlIFRoZSBjYWNoZSB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBjYWNoZUhhcyhjYWNoZSwga2V5KSB7XG4gIHJldHVybiBjYWNoZS5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjYWNoZUhhcztcbiIsInZhciBpZGVudGl0eSA9IHJlcXVpcmUoJy4vaWRlbnRpdHknKTtcblxuLyoqXG4gKiBDYXN0cyBgdmFsdWVgIHRvIGBpZGVudGl0eWAgaWYgaXQncyBub3QgYSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBjYXN0IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjYXN0RnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnZnVuY3Rpb24nID8gdmFsdWUgOiBpZGVudGl0eTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjYXN0RnVuY3Rpb247XG4iLCJ2YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzS2V5ID0gcmVxdWlyZSgnLi9faXNLZXknKSxcbiAgICBzdHJpbmdUb1BhdGggPSByZXF1aXJlKCcuL19zdHJpbmdUb1BhdGgnKSxcbiAgICB0b1N0cmluZyA9IHJlcXVpcmUoJy4vdG9TdHJpbmcnKTtcblxuLyoqXG4gKiBDYXN0cyBgdmFsdWVgIHRvIGEgcGF0aCBhcnJheSBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjYXN0IHByb3BlcnR5IHBhdGggYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGNhc3RQYXRoKHZhbHVlLCBvYmplY3QpIHtcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHJldHVybiBpc0tleSh2YWx1ZSwgb2JqZWN0KSA/IFt2YWx1ZV0gOiBzdHJpbmdUb1BhdGgodG9TdHJpbmcodmFsdWUpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjYXN0UGF0aDtcbiIsIi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cyxcbiAqIHBsYWNlaG9sZGVycywgYW5kIHByb3ZpZGVkIGFyZ3VtZW50cyBpbnRvIGEgc2luZ2xlIGFycmF5IG9mIGFyZ3VtZW50cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHBhcmFtcyB7Ym9vbGVhbn0gW2lzQ3VycmllZF0gU3BlY2lmeSBjb21wb3NpbmcgZm9yIGEgY3VycmllZCBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbXBvc2VkIGFyZ3VtZW50cy5cbiAqL1xuZnVuY3Rpb24gY29tcG9zZUFyZ3MoYXJncywgcGFydGlhbHMsIGhvbGRlcnMsIGlzQ3VycmllZCkge1xuICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gYXJncy5sZW5ndGgsXG4gICAgICBob2xkZXJzTGVuZ3RoID0gaG9sZGVycy5sZW5ndGgsXG4gICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByYW5nZUxlbmd0aCA9IG5hdGl2ZU1heChhcmdzTGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgcmFuZ2VMZW5ndGgpLFxuICAgICAgaXNVbmN1cnJpZWQgPSAhaXNDdXJyaWVkO1xuXG4gIHdoaWxlICgrK2xlZnRJbmRleCA8IGxlZnRMZW5ndGgpIHtcbiAgICByZXN1bHRbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gIH1cbiAgd2hpbGUgKCsrYXJnc0luZGV4IDwgaG9sZGVyc0xlbmd0aCkge1xuICAgIGlmIChpc1VuY3VycmllZCB8fCBhcmdzSW5kZXggPCBhcmdzTGVuZ3RoKSB7XG4gICAgICByZXN1bHRbaG9sZGVyc1thcmdzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKHJhbmdlTGVuZ3RoLS0pIHtcbiAgICByZXN1bHRbbGVmdEluZGV4KytdID0gYXJnc1thcmdzSW5kZXgrK107XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb21wb3NlQXJncztcbiIsIi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gKiBpcyB0YWlsb3JlZCBmb3IgYF8ucGFydGlhbFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBob2xkZXJzIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW1zIHtib29sZWFufSBbaXNDdXJyaWVkXSBTcGVjaWZ5IGNvbXBvc2luZyBmb3IgYSBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpIHtcbiAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgYXJnc0xlbmd0aCA9IGFyZ3MubGVuZ3RoLFxuICAgICAgaG9sZGVyc0luZGV4ID0gLTEsXG4gICAgICBob2xkZXJzTGVuZ3RoID0gaG9sZGVycy5sZW5ndGgsXG4gICAgICByaWdodEluZGV4ID0gLTEsXG4gICAgICByaWdodExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgIHJhbmdlTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3NMZW5ndGggLSBob2xkZXJzTGVuZ3RoLCAwKSxcbiAgICAgIHJlc3VsdCA9IEFycmF5KHJhbmdlTGVuZ3RoICsgcmlnaHRMZW5ndGgpLFxuICAgICAgaXNVbmN1cnJpZWQgPSAhaXNDdXJyaWVkO1xuXG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IHJhbmdlTGVuZ3RoKSB7XG4gICAgcmVzdWx0W2FyZ3NJbmRleF0gPSBhcmdzW2FyZ3NJbmRleF07XG4gIH1cbiAgdmFyIG9mZnNldCA9IGFyZ3NJbmRleDtcbiAgd2hpbGUgKCsrcmlnaHRJbmRleCA8IHJpZ2h0TGVuZ3RoKSB7XG4gICAgcmVzdWx0W29mZnNldCArIHJpZ2h0SW5kZXhdID0gcGFydGlhbHNbcmlnaHRJbmRleF07XG4gIH1cbiAgd2hpbGUgKCsraG9sZGVyc0luZGV4IDwgaG9sZGVyc0xlbmd0aCkge1xuICAgIGlmIChpc1VuY3VycmllZCB8fCBhcmdzSW5kZXggPCBhcmdzTGVuZ3RoKSB7XG4gICAgICByZXN1bHRbb2Zmc2V0ICsgaG9sZGVyc1tob2xkZXJzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzUmlnaHQ7XG4iLCIvKipcbiAqIENvcGllcyB0aGUgdmFsdWVzIG9mIGBzb3VyY2VgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcblxuICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5QXJyYXk7XG4iLCJ2YXIgYXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19hc3NpZ25WYWx1ZScpLFxuICAgIGJhc2VBc3NpZ25WYWx1ZSA9IHJlcXVpcmUoJy4vX2Jhc2VBc3NpZ25WYWx1ZScpO1xuXG4vKipcbiAqIENvcGllcyBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgaWRlbnRpZmllcnMgdG8gY29weS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyB0by5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvcGllZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBjb3B5T2JqZWN0KHNvdXJjZSwgcHJvcHMsIG9iamVjdCwgY3VzdG9taXplcikge1xuICB2YXIgaXNOZXcgPSAhb2JqZWN0O1xuICBvYmplY3QgfHwgKG9iamVjdCA9IHt9KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG5cbiAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICA/IGN1c3RvbWl6ZXIob2JqZWN0W2tleV0sIHNvdXJjZVtrZXldLCBrZXksIG9iamVjdCwgc291cmNlKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbmV3VmFsdWUgPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gICAgaWYgKGlzTmV3KSB7XG4gICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5T2JqZWN0O1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvdmVycmVhY2hpbmcgY29yZS1qcyBzaGltcy4gKi9cbnZhciBjb3JlSnNEYXRhID0gcm9vdFsnX19jb3JlLWpzX3NoYXJlZF9fJ107XG5cbm1vZHVsZS5leHBvcnRzID0gY29yZUpzRGF0YTtcbiIsIi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIGBwbGFjZWhvbGRlcmAgb2NjdXJyZW5jZXMgaW4gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB0byBzZWFyY2ggZm9yLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcGxhY2Vob2xkZXIgY291bnQuXG4gKi9cbmZ1bmN0aW9uIGNvdW50SG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IDA7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKGFycmF5W2xlbmd0aF0gPT09IHBsYWNlaG9sZGVyKSB7XG4gICAgICArK3Jlc3VsdDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3VudEhvbGRlcnM7XG4iLCJ2YXIgYXJyYXlBZ2dyZWdhdG9yID0gcmVxdWlyZSgnLi9fYXJyYXlBZ2dyZWdhdG9yJyksXG4gICAgYmFzZUFnZ3JlZ2F0b3IgPSByZXF1aXJlKCcuL19iYXNlQWdncmVnYXRvcicpLFxuICAgIGJhc2VJdGVyYXRlZSA9IHJlcXVpcmUoJy4vX2Jhc2VJdGVyYXRlZScpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5ncm91cEJ5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYWNjdW11bGF0b3IgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2luaXRpYWxpemVyXSBUaGUgYWNjdW11bGF0b3Igb2JqZWN0IGluaXRpYWxpemVyLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWdncmVnYXRvciBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQWdncmVnYXRvcihzZXR0ZXIsIGluaXRpYWxpemVyKSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5QWdncmVnYXRvciA6IGJhc2VBZ2dyZWdhdG9yLFxuICAgICAgICBhY2N1bXVsYXRvciA9IGluaXRpYWxpemVyID8gaW5pdGlhbGl6ZXIoKSA6IHt9O1xuXG4gICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgc2V0dGVyLCBiYXNlSXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCBhY2N1bXVsYXRvcik7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQWdncmVnYXRvcjtcbiIsInZhciBiYXNlUmVzdCA9IHJlcXVpcmUoJy4vX2Jhc2VSZXN0JyksXG4gICAgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuL19pc0l0ZXJhdGVlQ2FsbCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmFzc2lnbmAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFzc2lnbmVyIFRoZSBmdW5jdGlvbiB0byBhc3NpZ24gdmFsdWVzLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYXNzaWduZXIgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUFzc2lnbmVyKGFzc2lnbmVyKSB7XG4gIHJldHVybiBiYXNlUmVzdChmdW5jdGlvbihvYmplY3QsIHNvdXJjZXMpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gc291cmNlcy5sZW5ndGgsXG4gICAgICAgIGN1c3RvbWl6ZXIgPSBsZW5ndGggPiAxID8gc291cmNlc1tsZW5ndGggLSAxXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZ3VhcmQgPSBsZW5ndGggPiAyID8gc291cmNlc1syXSA6IHVuZGVmaW5lZDtcblxuICAgIGN1c3RvbWl6ZXIgPSAoYXNzaWduZXIubGVuZ3RoID4gMyAmJiB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nKVxuICAgICAgPyAobGVuZ3RoLS0sIGN1c3RvbWl6ZXIpXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzb3VyY2VzWzBdLCBzb3VyY2VzWzFdLCBndWFyZCkpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSBsZW5ndGggPCAzID8gdW5kZWZpbmVkIDogY3VzdG9taXplcjtcbiAgICAgIGxlbmd0aCA9IDE7XG4gICAgfVxuICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICB2YXIgc291cmNlID0gc291cmNlc1tpbmRleF07XG4gICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgIGFzc2lnbmVyKG9iamVjdCwgc291cmNlLCBpbmRleCwgY3VzdG9taXplcik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmplY3Q7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUFzc2lnbmVyO1xuIiwidmFyIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgYmFzZUVhY2hgIG9yIGBiYXNlRWFjaFJpZ2h0YCBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VFYWNoKGVhY2hGdW5jLCBmcm9tUmlnaHQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gICAgfVxuICAgIGlmICghaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG4gICAgfVxuICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMSxcbiAgICAgICAgaXRlcmFibGUgPSBPYmplY3QoY29sbGVjdGlvbik7XG5cbiAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2luZGV4XSwgaW5kZXgsIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VFYWNoO1xuIiwiLyoqXG4gKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgbWV0aG9kcyBsaWtlIGBfLmZvckluYCBhbmQgYF8uZm9yT3duYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRm9yKGZyb21SaWdodCkge1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgaXRlcmFibGUgPSBPYmplY3Qob2JqZWN0KSxcbiAgICAgICAgcHJvcHMgPSBrZXlzRnVuYyhvYmplY3QpLFxuICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIHZhciBrZXkgPSBwcm9wc1tmcm9tUmlnaHQgPyBsZW5ndGggOiArK2luZGV4XTtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmplY3Q7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQmFzZUZvcjtcbiIsInZhciBjcmVhdGVDdG9yID0gcmVxdWlyZSgnLi9fY3JlYXRlQ3RvcicpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xudmFyIFdSQVBfQklORF9GTEFHID0gMTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gaW52b2tlIGl0IHdpdGggdGhlIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmQoZnVuYywgYml0bWFzaywgdGhpc0FyZykge1xuICB2YXIgaXNCaW5kID0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHLFxuICAgICAgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSByb290ICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgIHJldHVybiBmbi5hcHBseShpc0JpbmQgPyB0aGlzQXJnIDogdGhpcywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kO1xuIiwidmFyIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL19iYXNlQ3JlYXRlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdG9yKEN0b3IpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIC8vIFVzZSBhIGBzd2l0Y2hgIHN0YXRlbWVudCB0byB3b3JrIHdpdGggY2xhc3MgY29uc3RydWN0b3JzLiBTZWVcbiAgICAvLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWZ1bmN0aW9uLW9iamVjdHMtY2FsbC10aGlzYXJndW1lbnQtYXJndW1lbnRzbGlzdFxuICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IEN0b3I7XG4gICAgICBjYXNlIDE6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdKTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgY2FzZSAzOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICBjYXNlIDQ6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgICAgIGNhc2UgNTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0pO1xuICAgICAgY2FzZSA2OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSk7XG4gICAgICBjYXNlIDc6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdLCBhcmdzWzZdKTtcbiAgICB9XG4gICAgdmFyIHRoaXNCaW5kaW5nID0gYmFzZUNyZWF0ZShDdG9yLnByb3RvdHlwZSksXG4gICAgICAgIHJlc3VsdCA9IEN0b3IuYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuXG4gICAgLy8gTWltaWMgdGhlIGNvbnN0cnVjdG9yJ3MgYHJldHVybmAgYmVoYXZpb3IuXG4gICAgLy8gU2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDEzLjIuMiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJldHVybiBpc09iamVjdChyZXN1bHQpID8gcmVzdWx0IDogdGhpc0JpbmRpbmc7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQ3RvcjtcbiIsInZhciBhcHBseSA9IHJlcXVpcmUoJy4vX2FwcGx5JyksXG4gICAgY3JlYXRlQ3RvciA9IHJlcXVpcmUoJy4vX2NyZWF0ZUN0b3InKSxcbiAgICBjcmVhdGVIeWJyaWQgPSByZXF1aXJlKCcuL19jcmVhdGVIeWJyaWQnKSxcbiAgICBjcmVhdGVSZWN1cnJ5ID0gcmVxdWlyZSgnLi9fY3JlYXRlUmVjdXJyeScpLFxuICAgIGdldEhvbGRlciA9IHJlcXVpcmUoJy4vX2dldEhvbGRlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi9fcmVwbGFjZUhvbGRlcnMnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBlbmFibGUgY3VycnlpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtudW1iZXJ9IGFyaXR5IFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdXJyeShmdW5jLCBiaXRtYXNrLCBhcml0eSkge1xuICB2YXIgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICBwbGFjZWhvbGRlciA9IGdldEhvbGRlcih3cmFwcGVyKTtcblxuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgfVxuICAgIHZhciBob2xkZXJzID0gKGxlbmd0aCA8IDMgJiYgYXJnc1swXSAhPT0gcGxhY2Vob2xkZXIgJiYgYXJnc1tsZW5ndGggLSAxXSAhPT0gcGxhY2Vob2xkZXIpXG4gICAgICA/IFtdXG4gICAgICA6IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcblxuICAgIGxlbmd0aCAtPSBob2xkZXJzLmxlbmd0aDtcbiAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgIHJldHVybiBjcmVhdGVSZWN1cnJ5KFxuICAgICAgICBmdW5jLCBiaXRtYXNrLCBjcmVhdGVIeWJyaWQsIHdyYXBwZXIucGxhY2Vob2xkZXIsIHVuZGVmaW5lZCxcbiAgICAgICAgYXJncywgaG9sZGVycywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyaXR5IC0gbGVuZ3RoKTtcbiAgICB9XG4gICAgdmFyIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gYXBwbHkoZm4sIHRoaXMsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUN1cnJ5O1xuIiwidmFyIGJhc2VJdGVyYXRlZSA9IHJlcXVpcmUoJy4vX2Jhc2VJdGVyYXRlZScpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuL2tleXMnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYF8uZmluZGAgb3IgYF8uZmluZExhc3RgIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmaW5kSW5kZXhGdW5jIFRoZSBmdW5jdGlvbiB0byBmaW5kIHRoZSBjb2xsZWN0aW9uIGluZGV4LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRmluZChmaW5kSW5kZXhGdW5jKSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICAgIHZhciBpdGVyYWJsZSA9IE9iamVjdChjb2xsZWN0aW9uKTtcbiAgICBpZiAoIWlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7XG4gICAgICB2YXIgaXRlcmF0ZWUgPSBiYXNlSXRlcmF0ZWUocHJlZGljYXRlLCAzKTtcbiAgICAgIGNvbGxlY3Rpb24gPSBrZXlzKGNvbGxlY3Rpb24pO1xuICAgICAgcHJlZGljYXRlID0gZnVuY3Rpb24oa2V5KSB7IHJldHVybiBpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKTsgfTtcbiAgICB9XG4gICAgdmFyIGluZGV4ID0gZmluZEluZGV4RnVuYyhjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21JbmRleCk7XG4gICAgcmV0dXJuIGluZGV4ID4gLTEgPyBpdGVyYWJsZVtpdGVyYXRlZSA/IGNvbGxlY3Rpb25baW5kZXhdIDogaW5kZXhdIDogdW5kZWZpbmVkO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUZpbmQ7XG4iLCJ2YXIgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL19jb21wb3NlQXJncycpLFxuICAgIGNvbXBvc2VBcmdzUmlnaHQgPSByZXF1aXJlKCcuL19jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgY291bnRIb2xkZXJzID0gcmVxdWlyZSgnLi9fY291bnRIb2xkZXJzJyksXG4gICAgY3JlYXRlQ3RvciA9IHJlcXVpcmUoJy4vX2NyZWF0ZUN0b3InKSxcbiAgICBjcmVhdGVSZWN1cnJ5ID0gcmVxdWlyZSgnLi9fY3JlYXRlUmVjdXJyeScpLFxuICAgIGdldEhvbGRlciA9IHJlcXVpcmUoJy4vX2dldEhvbGRlcicpLFxuICAgIHJlb3JkZXIgPSByZXF1aXJlKCcuL19yZW9yZGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL19yZXBsYWNlSG9sZGVycycpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xudmFyIFdSQVBfQklORF9GTEFHID0gMSxcbiAgICBXUkFQX0JJTkRfS0VZX0ZMQUcgPSAyLFxuICAgIFdSQVBfQ1VSUllfRkxBRyA9IDgsXG4gICAgV1JBUF9DVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgV1JBUF9BUllfRkxBRyA9IDEyOCxcbiAgICBXUkFQX0ZMSVBfRkxBRyA9IDUxMjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gaW52b2tlIGl0IHdpdGggb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mIGB0aGlzQXJnYCwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gd3JhcC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAqICB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWRcbiAqICB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcnldIFRoZSBhcml0eSBjYXAgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUh5YnJpZChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgdmFyIGlzQXJ5ID0gYml0bWFzayAmIFdSQVBfQVJZX0ZMQUcsXG4gICAgICBpc0JpbmQgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcsXG4gICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0tFWV9GTEFHLFxuICAgICAgaXNDdXJyaWVkID0gYml0bWFzayAmIChXUkFQX0NVUlJZX0ZMQUcgfCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcpLFxuICAgICAgaXNGbGlwID0gYml0bWFzayAmIFdSQVBfRkxJUF9GTEFHLFxuICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuXG4gICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgIGFyZ3NbaW5kZXhdID0gYXJndW1lbnRzW2luZGV4XTtcbiAgICB9XG4gICAgaWYgKGlzQ3VycmllZCkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0gZ2V0SG9sZGVyKHdyYXBwZXIpLFxuICAgICAgICAgIGhvbGRlcnNDb3VudCA9IGNvdW50SG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG4gICAgfVxuICAgIGlmIChwYXJ0aWFscykge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpO1xuICAgIH1cbiAgICBpZiAocGFydGlhbHNSaWdodCkge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBpc0N1cnJpZWQpO1xuICAgIH1cbiAgICBsZW5ndGggLT0gaG9sZGVyc0NvdW50O1xuICAgIGlmIChpc0N1cnJpZWQgJiYgbGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgIHZhciBuZXdIb2xkZXJzID0gcmVwbGFjZUhvbGRlcnMoYXJncywgcGxhY2Vob2xkZXIpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVJlY3VycnkoXG4gICAgICAgIGZ1bmMsIGJpdG1hc2ssIGNyZWF0ZUh5YnJpZCwgd3JhcHBlci5wbGFjZWhvbGRlciwgdGhpc0FyZyxcbiAgICAgICAgYXJncywgbmV3SG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5IC0gbGVuZ3RoXG4gICAgICApO1xuICAgIH1cbiAgICB2YXIgdGhpc0JpbmRpbmcgPSBpc0JpbmQgPyB0aGlzQXJnIDogdGhpcyxcbiAgICAgICAgZm4gPSBpc0JpbmRLZXkgPyB0aGlzQmluZGluZ1tmdW5jXSA6IGZ1bmM7XG5cbiAgICBsZW5ndGggPSBhcmdzLmxlbmd0aDtcbiAgICBpZiAoYXJnUG9zKSB7XG4gICAgICBhcmdzID0gcmVvcmRlcihhcmdzLCBhcmdQb3MpO1xuICAgIH0gZWxzZSBpZiAoaXNGbGlwICYmIGxlbmd0aCA+IDEpIHtcbiAgICAgIGFyZ3MucmV2ZXJzZSgpO1xuICAgIH1cbiAgICBpZiAoaXNBcnkgJiYgYXJ5IDwgbGVuZ3RoKSB7XG4gICAgICBhcmdzLmxlbmd0aCA9IGFyeTtcbiAgICB9XG4gICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgZm4gPSBDdG9yIHx8IGNyZWF0ZUN0b3IoZm4pO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUh5YnJpZDtcbiIsInZhciBhcHBseSA9IHJlcXVpcmUoJy4vX2FwcGx5JyksXG4gICAgY3JlYXRlQ3RvciA9IHJlcXVpcmUoJy4vX2NyZWF0ZUN0b3InKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbnZhciBXUkFQX0JJTkRfRkxBRyA9IDE7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGludm9rZSBpdCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZ1xuICogb2YgYHRoaXNBcmdgIGFuZCBgcGFydGlhbHNgIHByZXBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gKiAgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBhcnRpYWwoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGlzQmluZCA9IGJpdG1hc2sgJiBXUkFQX0JJTkRfRkxBRyxcbiAgICAgIEN0b3IgPSBjcmVhdGVDdG9yKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgIGFyZ3MgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCksXG4gICAgICAgIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcblxuICAgIHdoaWxlICgrK2xlZnRJbmRleCA8IGxlZnRMZW5ndGgpIHtcbiAgICAgIGFyZ3NbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gICAgfVxuICAgIHdoaWxlIChhcmdzTGVuZ3RoLS0pIHtcbiAgICAgIGFyZ3NbbGVmdEluZGV4KytdID0gYXJndW1lbnRzWysrYXJnc0luZGV4XTtcbiAgICB9XG4gICAgcmV0dXJuIGFwcGx5KGZuLCBpc0JpbmQgPyB0aGlzQXJnIDogdGhpcywgYXJncyk7XG4gIH1cbiAgcmV0dXJuIHdyYXBwZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUGFydGlhbDtcbiIsInZhciBpc0xhemlhYmxlID0gcmVxdWlyZSgnLi9faXNMYXppYWJsZScpLFxuICAgIHNldERhdGEgPSByZXF1aXJlKCcuL19zZXREYXRhJyksXG4gICAgc2V0V3JhcFRvU3RyaW5nID0gcmVxdWlyZSgnLi9fc2V0V3JhcFRvU3RyaW5nJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xudmFyIFdSQVBfQklORF9GTEFHID0gMSxcbiAgICBXUkFQX0JJTkRfS0VZX0ZMQUcgPSAyLFxuICAgIFdSQVBfQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgV1JBUF9DVVJSWV9GTEFHID0gOCxcbiAgICBXUkFQX1BBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHID0gNjQ7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGNvbnRpbnVlIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHdyYXBGdW5jIFRoZSBmdW5jdGlvbiB0byBjcmVhdGUgdGhlIGBmdW5jYCB3cmFwcGVyLlxuICogQHBhcmFtIHsqfSBwbGFjZWhvbGRlciBUaGUgcGxhY2Vob2xkZXIgdmFsdWUuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAqICB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJnUG9zXSBUaGUgYXJndW1lbnQgcG9zaXRpb25zIG9mIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUmVjdXJyeShmdW5jLCBiaXRtYXNrLCB3cmFwRnVuYywgcGxhY2Vob2xkZXIsIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgdmFyIGlzQ3VycnkgPSBiaXRtYXNrICYgV1JBUF9DVVJSWV9GTEFHLFxuICAgICAgbmV3SG9sZGVycyA9IGlzQ3VycnkgPyBob2xkZXJzIDogdW5kZWZpbmVkLFxuICAgICAgbmV3SG9sZGVyc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGhvbGRlcnMsXG4gICAgICBuZXdQYXJ0aWFscyA9IGlzQ3VycnkgPyBwYXJ0aWFscyA6IHVuZGVmaW5lZCxcbiAgICAgIG5ld1BhcnRpYWxzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogcGFydGlhbHM7XG5cbiAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFdSQVBfUEFSVElBTF9GTEFHIDogV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICBiaXRtYXNrICY9IH4oaXNDdXJyeSA/IFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHIDogV1JBUF9QQVJUSUFMX0ZMQUcpO1xuXG4gIGlmICghKGJpdG1hc2sgJiBXUkFQX0NVUlJZX0JPVU5EX0ZMQUcpKSB7XG4gICAgYml0bWFzayAmPSB+KFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHKTtcbiAgfVxuICB2YXIgbmV3RGF0YSA9IFtcbiAgICBmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3SG9sZGVycywgbmV3UGFydGlhbHNSaWdodCxcbiAgICBuZXdIb2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eVxuICBdO1xuXG4gIHZhciByZXN1bHQgPSB3cmFwRnVuYy5hcHBseSh1bmRlZmluZWQsIG5ld0RhdGEpO1xuICBpZiAoaXNMYXppYWJsZShmdW5jKSkge1xuICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgfVxuICByZXN1bHQucGxhY2Vob2xkZXIgPSBwbGFjZWhvbGRlcjtcbiAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhyZXN1bHQsIGZ1bmMsIGJpdG1hc2spO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVJlY3Vycnk7XG4iLCJ2YXIgU2V0ID0gcmVxdWlyZSgnLi9fU2V0JyksXG4gICAgbm9vcCA9IHJlcXVpcmUoJy4vbm9vcCcpLFxuICAgIHNldFRvQXJyYXkgPSByZXF1aXJlKCcuL19zZXRUb0FycmF5Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIElORklOSVRZID0gMSAvIDA7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHNldCBvYmplY3Qgb2YgYHZhbHVlc2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFkZCB0byB0aGUgc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IHNldC5cbiAqL1xudmFyIGNyZWF0ZVNldCA9ICEoU2V0ICYmICgxIC8gc2V0VG9BcnJheShuZXcgU2V0KFssLTBdKSlbMV0pID09IElORklOSVRZKSA/IG5vb3AgOiBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgcmV0dXJuIG5ldyBTZXQodmFsdWVzKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlU2V0O1xuIiwidmFyIGJhc2VTZXREYXRhID0gcmVxdWlyZSgnLi9fYmFzZVNldERhdGEnKSxcbiAgICBjcmVhdGVCaW5kID0gcmVxdWlyZSgnLi9fY3JlYXRlQmluZCcpLFxuICAgIGNyZWF0ZUN1cnJ5ID0gcmVxdWlyZSgnLi9fY3JlYXRlQ3VycnknKSxcbiAgICBjcmVhdGVIeWJyaWQgPSByZXF1aXJlKCcuL19jcmVhdGVIeWJyaWQnKSxcbiAgICBjcmVhdGVQYXJ0aWFsID0gcmVxdWlyZSgnLi9fY3JlYXRlUGFydGlhbCcpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL19nZXREYXRhJyksXG4gICAgbWVyZ2VEYXRhID0gcmVxdWlyZSgnLi9fbWVyZ2VEYXRhJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vX3NldERhdGEnKSxcbiAgICBzZXRXcmFwVG9TdHJpbmcgPSByZXF1aXJlKCcuL19zZXRXcmFwVG9TdHJpbmcnKSxcbiAgICB0b0ludGVnZXIgPSByZXF1aXJlKCcuL3RvSW50ZWdlcicpO1xuXG4vKiogRXJyb3IgbWVzc2FnZSBjb25zdGFudHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbnZhciBXUkFQX0JJTkRfRkxBRyA9IDEsXG4gICAgV1JBUF9CSU5EX0tFWV9GTEFHID0gMixcbiAgICBXUkFQX0NVUlJZX0ZMQUcgPSA4LFxuICAgIFdSQVBfQ1VSUllfUklHSFRfRkxBRyA9IDE2LFxuICAgIFdSQVBfUEFSVElBTF9GTEFHID0gMzIsXG4gICAgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcgPSA2NDtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGVpdGhlciBjdXJyaWVzIG9yIGludm9rZXMgYGZ1bmNgIHdpdGggb3B0aW9uYWxcbiAqIGB0aGlzYCBiaW5kaW5nIGFuZCBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byB3cmFwLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gKiAgICAxIC0gYF8uYmluZGBcbiAqICAgIDIgLSBgXy5iaW5kS2V5YFxuICogICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gKiAgICA4IC0gYF8uY3VycnlgXG4gKiAgIDE2IC0gYF8uY3VycnlSaWdodGBcbiAqICAgMzIgLSBgXy5wYXJ0aWFsYFxuICogICA2NCAtIGBfLnBhcnRpYWxSaWdodGBcbiAqICAxMjggLSBgXy5yZWFyZ2BcbiAqICAyNTYgLSBgXy5hcnlgXG4gKiAgNTEyIC0gYF8uZmxpcGBcbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVXcmFwKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgdmFyIGlzQmluZEtleSA9IGJpdG1hc2sgJiBXUkFQX0JJTkRfS0VZX0ZMQUc7XG4gIGlmICghaXNCaW5kS2V5ICYmIHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gIH1cbiAgdmFyIGxlbmd0aCA9IHBhcnRpYWxzID8gcGFydGlhbHMubGVuZ3RoIDogMDtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBiaXRtYXNrICY9IH4oV1JBUF9QQVJUSUFMX0ZMQUcgfCBXUkFQX1BBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICB9XG4gIGFyeSA9IGFyeSA9PT0gdW5kZWZpbmVkID8gYXJ5IDogbmF0aXZlTWF4KHRvSW50ZWdlcihhcnkpLCAwKTtcbiAgYXJpdHkgPSBhcml0eSA9PT0gdW5kZWZpbmVkID8gYXJpdHkgOiB0b0ludGVnZXIoYXJpdHkpO1xuICBsZW5ndGggLT0gaG9sZGVycyA/IGhvbGRlcnMubGVuZ3RoIDogMDtcblxuICBpZiAoYml0bWFzayAmIFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHKSB7XG4gICAgdmFyIHBhcnRpYWxzUmlnaHQgPSBwYXJ0aWFscyxcbiAgICAgICAgaG9sZGVyc1JpZ2h0ID0gaG9sZGVycztcblxuICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgfVxuICB2YXIgZGF0YSA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGdldERhdGEoZnVuYyk7XG5cbiAgdmFyIG5ld0RhdGEgPSBbXG4gICAgZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCxcbiAgICBhcmdQb3MsIGFyeSwgYXJpdHlcbiAgXTtcblxuICBpZiAoZGF0YSkge1xuICAgIG1lcmdlRGF0YShuZXdEYXRhLCBkYXRhKTtcbiAgfVxuICBmdW5jID0gbmV3RGF0YVswXTtcbiAgYml0bWFzayA9IG5ld0RhdGFbMV07XG4gIHRoaXNBcmcgPSBuZXdEYXRhWzJdO1xuICBwYXJ0aWFscyA9IG5ld0RhdGFbM107XG4gIGhvbGRlcnMgPSBuZXdEYXRhWzRdO1xuICBhcml0eSA9IG5ld0RhdGFbOV0gPSBuZXdEYXRhWzldID09PSB1bmRlZmluZWRcbiAgICA/IChpc0JpbmRLZXkgPyAwIDogZnVuYy5sZW5ndGgpXG4gICAgOiBuYXRpdmVNYXgobmV3RGF0YVs5XSAtIGxlbmd0aCwgMCk7XG5cbiAgaWYgKCFhcml0eSAmJiBiaXRtYXNrICYgKFdSQVBfQ1VSUllfRkxBRyB8IFdSQVBfQ1VSUllfUklHSFRfRkxBRykpIHtcbiAgICBiaXRtYXNrICY9IH4oV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKTtcbiAgfVxuICBpZiAoIWJpdG1hc2sgfHwgYml0bWFzayA9PSBXUkFQX0JJTkRfRkxBRykge1xuICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcpO1xuICB9IGVsc2UgaWYgKGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9GTEFHIHx8IGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9SSUdIVF9GTEFHKSB7XG4gICAgcmVzdWx0ID0gY3JlYXRlQ3VycnkoZnVuYywgYml0bWFzaywgYXJpdHkpO1xuICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFdSQVBfUEFSVElBTF9GTEFHIHx8IGJpdG1hc2sgPT0gKFdSQVBfQklORF9GTEFHIHwgV1JBUF9QQVJUSUFMX0ZMQUcpKSAmJiAhaG9sZGVycy5sZW5ndGgpIHtcbiAgICByZXN1bHQgPSBjcmVhdGVQYXJ0aWFsKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWQuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfVxuICB2YXIgc2V0dGVyID0gZGF0YSA/IGJhc2VTZXREYXRhIDogc2V0RGF0YTtcbiAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKSwgZnVuYywgYml0bWFzayk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlV3JhcDtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBmdW5jID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2RlZmluZVByb3BlcnR5Jyk7XG4gICAgZnVuYyh7fSwgJycsIHt9KTtcbiAgICByZXR1cm4gZnVuYztcbiAgfSBjYXRjaCAoZSkge31cbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydHk7XG4iLCJ2YXIgU2V0Q2FjaGUgPSByZXF1aXJlKCcuL19TZXRDYWNoZScpLFxuICAgIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vX2FycmF5U29tZScpLFxuICAgIGNhY2hlSGFzID0gcmVxdWlyZSgnLi9fY2FjaGVIYXMnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgYXJyYXlzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYGFycmF5YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcsXG4gICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBvdGhMZW5ndGggPSBvdGhlci5sZW5ndGg7XG5cbiAgaWYgKGFyckxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIShpc1BhcnRpYWwgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBDaGVjayB0aGF0IGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLlxuICB2YXIgYXJyU3RhY2tlZCA9IHN0YWNrLmdldChhcnJheSk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKGFyclN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBhcnJTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gYXJyYXk7XG4gIH1cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgc2VlbiA9IChiaXRtYXNrICYgQ09NUEFSRV9VTk9SREVSRURfRkxBRykgPyBuZXcgU2V0Q2FjaGUgOiB1bmRlZmluZWQ7XG5cbiAgc3RhY2suc2V0KGFycmF5LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgYXJyYXkpO1xuXG4gIC8vIElnbm9yZSBub24taW5kZXggcHJvcGVydGllcy5cbiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHtcbiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdO1xuXG4gICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgIHZhciBjb21wYXJlZCA9IGlzUGFydGlhbFxuICAgICAgICA/IGN1c3RvbWl6ZXIob3RoVmFsdWUsIGFyclZhbHVlLCBpbmRleCwgb3RoZXIsIGFycmF5LCBzdGFjaylcbiAgICAgICAgOiBjdXN0b21pemVyKGFyclZhbHVlLCBvdGhWYWx1ZSwgaW5kZXgsIGFycmF5LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICBpZiAoY29tcGFyZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGNvbXBhcmVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoc2Vlbikge1xuICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uKG90aFZhbHVlLCBvdGhJbmRleCkge1xuICAgICAgICAgICAgaWYgKCFjYWNoZUhhcyhzZWVuLCBvdGhJbmRleCkgJiZcbiAgICAgICAgICAgICAgICAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHNlZW4ucHVzaChvdGhJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShcbiAgICAgICAgICBhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHxcbiAgICAgICAgICAgIGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICApKSB7XG4gICAgICByZXN1bHQgPSBmYWxzZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBzdGFja1snZGVsZXRlJ10oYXJyYXkpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQXJyYXlzO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpLFxuICAgIFVpbnQ4QXJyYXkgPSByZXF1aXJlKCcuL19VaW50OEFycmF5JyksXG4gICAgZXEgPSByZXF1aXJlKCcuL2VxJyksXG4gICAgZXF1YWxBcnJheXMgPSByZXF1aXJlKCcuL19lcXVhbEFycmF5cycpLFxuICAgIG1hcFRvQXJyYXkgPSByZXF1aXJlKCcuL19tYXBUb0FycmF5JyksXG4gICAgc2V0VG9BcnJheSA9IHJlcXVpcmUoJy4vX3NldFRvQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7XG5cbi8qKiBVc2VkIHRvIGNvbnZlcnQgc3ltYm9scyB0byBwcmltaXRpdmVzIGFuZCBzdHJpbmdzLiAqL1xudmFyIHN5bWJvbFByb3RvID0gU3ltYm9sID8gU3ltYm9sLnByb3RvdHlwZSA6IHVuZGVmaW5lZCxcbiAgICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgZGF0YVZpZXdUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgKG9iamVjdC5ieXRlT2Zmc2V0ICE9IG90aGVyLmJ5dGVPZmZzZXQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IG9iamVjdC5idWZmZXI7XG4gICAgICBvdGhlciA9IG90aGVyLmJ1ZmZlcjtcblxuICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgIWVxdWFsRnVuYyhuZXcgVWludDhBcnJheShvYmplY3QpLCBuZXcgVWludDhBcnJheShvdGhlcikpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgY2FzZSBib29sVGFnOlxuICAgIGNhc2UgZGF0ZVRhZzpcbiAgICBjYXNlIG51bWJlclRhZzpcbiAgICAgIC8vIENvZXJjZSBib29sZWFucyB0byBgMWAgb3IgYDBgIGFuZCBkYXRlcyB0byBtaWxsaXNlY29uZHMuXG4gICAgICAvLyBJbnZhbGlkIGRhdGVzIGFyZSBjb2VyY2VkIHRvIGBOYU5gLlxuICAgICAgcmV0dXJuIGVxKCtvYmplY3QsICtvdGhlcik7XG5cbiAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgcmV0dXJuIG9iamVjdC5uYW1lID09IG90aGVyLm5hbWUgJiYgb2JqZWN0Lm1lc3NhZ2UgPT0gb3RoZXIubWVzc2FnZTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgLy8gQ29lcmNlIHJlZ2V4ZXMgdG8gc3RyaW5ncyBhbmQgdHJlYXQgc3RyaW5ncywgcHJpbWl0aXZlcyBhbmQgb2JqZWN0cyxcbiAgICAgIC8vIGFzIGVxdWFsLiBTZWUgaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXJlZ2V4cC5wcm90b3R5cGUudG9zdHJpbmdcbiAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcblxuICAgIGNhc2UgbWFwVGFnOlxuICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5O1xuXG4gICAgY2FzZSBzZXRUYWc6XG4gICAgICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHO1xuICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpO1xuXG4gICAgICBpZiAob2JqZWN0LnNpemUgIT0gb3RoZXIuc2l6ZSAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICByZXR1cm4gc3RhY2tlZCA9PSBvdGhlcjtcbiAgICAgIH1cbiAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRztcblxuICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gICAgICB2YXIgcmVzdWx0ID0gZXF1YWxBcnJheXMoY29udmVydChvYmplY3QpLCBjb252ZXJ0KG90aGVyKSwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgIGlmIChzeW1ib2xWYWx1ZU9mKSB7XG4gICAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mLmNhbGwob2JqZWN0KSA9PSBzeW1ib2xWYWx1ZU9mLmNhbGwob3RoZXIpO1xuICAgICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEJ5VGFnO1xuIiwidmFyIGdldEFsbEtleXMgPSByZXF1aXJlKCcuL19nZXRBbGxLZXlzJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqL1xudmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIG9iamVjdHMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHtcbiAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgIG9ialByb3BzID0gZ2V0QWxsS2V5cyhvYmplY3QpLFxuICAgICAgb2JqTGVuZ3RoID0gb2JqUHJvcHMubGVuZ3RoLFxuICAgICAgb3RoUHJvcHMgPSBnZXRBbGxLZXlzKG90aGVyKSxcbiAgICAgIG90aExlbmd0aCA9IG90aFByb3BzLmxlbmd0aDtcblxuICBpZiAob2JqTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzUGFydGlhbCA/IGtleSBpbiBvdGhlciA6IGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsIGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIHZhciBvYmpTdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKG9ialN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBvYmpTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gb2JqZWN0O1xuICB9XG4gIHZhciByZXN1bHQgPSB0cnVlO1xuICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgb2JqZWN0KTtcblxuICB2YXIgc2tpcEN0b3IgPSBpc1BhcnRpYWw7XG4gIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07XG5cbiAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsXG4gICAgICAgID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spXG4gICAgICAgIDogY3VzdG9taXplcihvYmpWYWx1ZSwgb3RoVmFsdWUsIGtleSwgb2JqZWN0LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoIShjb21wYXJlZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyAob2JqVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSlcbiAgICAgICAgICA6IGNvbXBhcmVkXG4gICAgICAgICkpIHtcbiAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTtcbiAgfVxuICBpZiAocmVzdWx0ICYmICFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIHN0YWNrWydkZWxldGUnXShvYmplY3QpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsT2JqZWN0cztcbiIsIi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZUdsb2JhbDtcbiIsInZhciBiYXNlR2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRBbGxLZXlzJyksXG4gICAgZ2V0U3ltYm9scyA9IHJlcXVpcmUoJy4vX2dldFN5bWJvbHMnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAqL1xuZnVuY3Rpb24gZ2V0QWxsS2V5cyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5cywgZ2V0U3ltYm9scyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0QWxsS2V5cztcbiIsInZhciBtZXRhTWFwID0gcmVxdWlyZSgnLi9fbWV0YU1hcCcpLFxuICAgIG5vb3AgPSByZXF1aXJlKCcuL25vb3AnKTtcblxuLyoqXG4gKiBHZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKi9cbnZhciBnZXREYXRhID0gIW1ldGFNYXAgPyBub29wIDogZnVuY3Rpb24oZnVuYykge1xuICByZXR1cm4gbWV0YU1hcC5nZXQoZnVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldERhdGE7XG4iLCJ2YXIgcmVhbE5hbWVzID0gcmVxdWlyZSgnLi9fcmVhbE5hbWVzJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogR2V0cyB0aGUgbmFtZSBvZiBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZS5cbiAqL1xuZnVuY3Rpb24gZ2V0RnVuY05hbWUoZnVuYykge1xuICB2YXIgcmVzdWx0ID0gKGZ1bmMubmFtZSArICcnKSxcbiAgICAgIGFycmF5ID0gcmVhbE5hbWVzW3Jlc3VsdF0sXG4gICAgICBsZW5ndGggPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlYWxOYW1lcywgcmVzdWx0KSA/IGFycmF5Lmxlbmd0aCA6IDA7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgdmFyIGRhdGEgPSBhcnJheVtsZW5ndGhdLFxuICAgICAgICBvdGhlckZ1bmMgPSBkYXRhLmZ1bmM7XG4gICAgaWYgKG90aGVyRnVuYyA9PSBudWxsIHx8IG90aGVyRnVuYyA9PSBmdW5jKSB7XG4gICAgICByZXR1cm4gZGF0YS5uYW1lO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldEZ1bmNOYW1lO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSBhcmd1bWVudCBwbGFjZWhvbGRlciB2YWx1ZSBmb3IgYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBpbnNwZWN0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHBsYWNlaG9sZGVyIHZhbHVlLlxuICovXG5mdW5jdGlvbiBnZXRIb2xkZXIoZnVuYykge1xuICB2YXIgb2JqZWN0ID0gZnVuYztcbiAgcmV0dXJuIG9iamVjdC5wbGFjZWhvbGRlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRIb2xkZXI7XG4iLCJ2YXIgaXNLZXlhYmxlID0gcmVxdWlyZSgnLi9faXNLZXlhYmxlJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgZGF0YSBmb3IgYG1hcGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWFwIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHtcbiAgdmFyIGRhdGEgPSBtYXAuX19kYXRhX187XG4gIHJldHVybiBpc0tleWFibGUoa2V5KVxuICAgID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddXG4gICAgOiBkYXRhLm1hcDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRNYXBEYXRhO1xuIiwidmFyIGlzU3RyaWN0Q29tcGFyYWJsZSA9IHJlcXVpcmUoJy4vX2lzU3RyaWN0Q29tcGFyYWJsZScpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuL2tleXMnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBwcm9wZXJ0eSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBtYXRjaCBkYXRhIG9mIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBnZXRNYXRjaERhdGEob2JqZWN0KSB7XG4gIHZhciByZXN1bHQgPSBrZXlzKG9iamVjdCksXG4gICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIHZhciBrZXkgPSByZXN1bHRbbGVuZ3RoXSxcbiAgICAgICAgdmFsdWUgPSBvYmplY3Rba2V5XTtcblxuICAgIHJlc3VsdFtsZW5ndGhdID0gW2tleSwgdmFsdWUsIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSldO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWF0Y2hEYXRhO1xuIiwidmFyIGJhc2VJc05hdGl2ZSA9IHJlcXVpcmUoJy4vX2Jhc2VJc05hdGl2ZScpLFxuICAgIGdldFZhbHVlID0gcmVxdWlyZSgnLi9fZ2V0VmFsdWUnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqL1xuZnVuY3Rpb24gZ2V0TmF0aXZlKG9iamVjdCwga2V5KSB7XG4gIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTtcbiAgcmV0dXJuIGJhc2VJc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXROYXRpdmU7XG4iLCJ2YXIgb3ZlckFyZyA9IHJlcXVpcmUoJy4vX292ZXJBcmcnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgZ2V0UHJvdG90eXBlID0gb3ZlckFyZyhPYmplY3QuZ2V0UHJvdG90eXBlT2YsIE9iamVjdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UHJvdG90eXBlO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSByYXcgYHRvU3RyaW5nVGFnYC5cbiAqL1xuZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7XG4gIHZhciBpc093biA9IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHN5bVRvU3RyaW5nVGFnKSxcbiAgICAgIHRhZyA9IHZhbHVlW3N5bVRvU3RyaW5nVGFnXTtcblxuICB0cnkge1xuICAgIHZhbHVlW3N5bVRvU3RyaW5nVGFnXSA9IHVuZGVmaW5lZDtcbiAgICB2YXIgdW5tYXNrZWQgPSB0cnVlO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIHZhciByZXN1bHQgPSBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgaWYgKHVubWFza2VkKSB7XG4gICAgaWYgKGlzT3duKSB7XG4gICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ10gPSB0YWc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ107XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UmF3VGFnO1xuIiwidmFyIGFycmF5RmlsdGVyID0gcmVxdWlyZSgnLi9fYXJyYXlGaWx0ZXInKSxcbiAgICBzdHViQXJyYXkgPSByZXF1aXJlKCcuL3N0dWJBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlR2V0U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBzeW1ib2xzLlxuICovXG52YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgcmV0dXJuIGFycmF5RmlsdGVyKG5hdGl2ZUdldFN5bWJvbHMob2JqZWN0KSwgZnVuY3Rpb24oc3ltYm9sKSB7XG4gICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U3ltYm9scztcbiIsInZhciBEYXRhVmlldyA9IHJlcXVpcmUoJy4vX0RhdGFWaWV3JyksXG4gICAgTWFwID0gcmVxdWlyZSgnLi9fTWFwJyksXG4gICAgUHJvbWlzZSA9IHJlcXVpcmUoJy4vX1Byb21pc2UnKSxcbiAgICBTZXQgPSByZXF1aXJlKCcuL19TZXQnKSxcbiAgICBXZWFrTWFwID0gcmVxdWlyZSgnLi9fV2Vha01hcCcpLFxuICAgIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgdG9Tb3VyY2UgPSByZXF1aXJlKCcuL190b1NvdXJjZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcHJvbWlzZVRhZyA9ICdbb2JqZWN0IFByb21pc2VdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nO1xuXG52YXIgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgbWFwcywgc2V0cywgYW5kIHdlYWttYXBzLiAqL1xudmFyIGRhdGFWaWV3Q3RvclN0cmluZyA9IHRvU291cmNlKERhdGFWaWV3KSxcbiAgICBtYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoTWFwKSxcbiAgICBwcm9taXNlQ3RvclN0cmluZyA9IHRvU291cmNlKFByb21pc2UpLFxuICAgIHNldEN0b3JTdHJpbmcgPSB0b1NvdXJjZShTZXQpLFxuICAgIHdlYWtNYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoV2Vha01hcCk7XG5cbi8qKlxuICogR2V0cyB0aGUgYHRvU3RyaW5nVGFnYCBvZiBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuXG4gKi9cbnZhciBnZXRUYWcgPSBiYXNlR2V0VGFnO1xuXG4vLyBGYWxsYmFjayBmb3IgZGF0YSB2aWV3cywgbWFwcywgc2V0cywgYW5kIHdlYWsgbWFwcyBpbiBJRSAxMSBhbmQgcHJvbWlzZXMgaW4gTm9kZS5qcyA8IDYuXG5pZiAoKERhdGFWaWV3ICYmIGdldFRhZyhuZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDEpKSkgIT0gZGF0YVZpZXdUYWcpIHx8XG4gICAgKE1hcCAmJiBnZXRUYWcobmV3IE1hcCkgIT0gbWFwVGFnKSB8fFxuICAgIChQcm9taXNlICYmIGdldFRhZyhQcm9taXNlLnJlc29sdmUoKSkgIT0gcHJvbWlzZVRhZykgfHxcbiAgICAoU2V0ICYmIGdldFRhZyhuZXcgU2V0KSAhPSBzZXRUYWcpIHx8XG4gICAgKFdlYWtNYXAgJiYgZ2V0VGFnKG5ldyBXZWFrTWFwKSAhPSB3ZWFrTWFwVGFnKSkge1xuICBnZXRUYWcgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciByZXN1bHQgPSBiYXNlR2V0VGFnKHZhbHVlKSxcbiAgICAgICAgQ3RvciA9IHJlc3VsdCA9PSBvYmplY3RUYWcgPyB2YWx1ZS5jb25zdHJ1Y3RvciA6IHVuZGVmaW5lZCxcbiAgICAgICAgY3RvclN0cmluZyA9IEN0b3IgPyB0b1NvdXJjZShDdG9yKSA6ICcnO1xuXG4gICAgaWYgKGN0b3JTdHJpbmcpIHtcbiAgICAgIHN3aXRjaCAoY3RvclN0cmluZykge1xuICAgICAgICBjYXNlIGRhdGFWaWV3Q3RvclN0cmluZzogcmV0dXJuIGRhdGFWaWV3VGFnO1xuICAgICAgICBjYXNlIG1hcEN0b3JTdHJpbmc6IHJldHVybiBtYXBUYWc7XG4gICAgICAgIGNhc2UgcHJvbWlzZUN0b3JTdHJpbmc6IHJldHVybiBwcm9taXNlVGFnO1xuICAgICAgICBjYXNlIHNldEN0b3JTdHJpbmc6IHJldHVybiBzZXRUYWc7XG4gICAgICAgIGNhc2Ugd2Vha01hcEN0b3JTdHJpbmc6IHJldHVybiB3ZWFrTWFwVGFnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFRhZztcbiIsIi8qKlxuICogR2V0cyB0aGUgdmFsdWUgYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGdldFZhbHVlKG9iamVjdCwga2V5KSB7XG4gIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFZhbHVlO1xuIiwiLyoqIFVzZWQgdG8gbWF0Y2ggd3JhcCBkZXRhaWwgY29tbWVudHMuICovXG52YXIgcmVXcmFwRGV0YWlscyA9IC9cXHtcXG5cXC9cXCogXFxbd3JhcHBlZCB3aXRoICguKylcXF0gXFwqLyxcbiAgICByZVNwbGl0RGV0YWlscyA9IC8sPyAmIC87XG5cbi8qKlxuICogRXh0cmFjdHMgd3JhcHBlciBkZXRhaWxzIGZyb20gdGhlIGBzb3VyY2VgIGJvZHkgY29tbWVudC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSBUaGUgc291cmNlIHRvIGluc3BlY3QuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHdyYXBwZXIgZGV0YWlscy5cbiAqL1xuZnVuY3Rpb24gZ2V0V3JhcERldGFpbHMoc291cmNlKSB7XG4gIHZhciBtYXRjaCA9IHNvdXJjZS5tYXRjaChyZVdyYXBEZXRhaWxzKTtcbiAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0uc3BsaXQocmVTcGxpdERldGFpbHMpIDogW107XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0V3JhcERldGFpbHM7XG4iLCJ2YXIgY2FzdFBhdGggPSByZXF1aXJlKCcuL19jYXN0UGF0aCcpLFxuICAgIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9faXNJbmRleCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi9pc0xlbmd0aCcpLFxuICAgIHRvS2V5ID0gcmVxdWlyZSgnLi9fdG9LZXknKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHBhdGhgIGV4aXN0cyBvbiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYXNGdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjayBwcm9wZXJ0aWVzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaGFzUGF0aChvYmplY3QsIHBhdGgsIGhhc0Z1bmMpIHtcbiAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IGZhbHNlO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHRvS2V5KHBhdGhbaW5kZXhdKTtcbiAgICBpZiAoIShyZXN1bHQgPSBvYmplY3QgIT0gbnVsbCAmJiBoYXNGdW5jKG9iamVjdCwga2V5KSkpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBvYmplY3QgPSBvYmplY3Rba2V5XTtcbiAgfVxuICBpZiAocmVzdWx0IHx8ICsraW5kZXggIT0gbGVuZ3RoKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBsZW5ndGggPSBvYmplY3QgPT0gbnVsbCA/IDAgOiBvYmplY3QubGVuZ3RoO1xuICByZXR1cm4gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzUGF0aDtcbiIsInZhciBuYXRpdmVDcmVhdGUgPSByZXF1aXJlKCcuL19uYXRpdmVDcmVhdGUnKTtcblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBoYXNoLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBjbGVhclxuICogQG1lbWJlck9mIEhhc2hcbiAqL1xuZnVuY3Rpb24gaGFzaENsZWFyKCkge1xuICB0aGlzLl9fZGF0YV9fID0gbmF0aXZlQ3JlYXRlID8gbmF0aXZlQ3JlYXRlKG51bGwpIDoge307XG4gIHRoaXMuc2l6ZSA9IDA7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzaENsZWFyO1xuIiwiLyoqXG4gKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgaGFzaC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgZGVsZXRlXG4gKiBAbWVtYmVyT2YgSGFzaFxuICogQHBhcmFtIHtPYmplY3R9IGhhc2ggVGhlIGhhc2ggdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGhhc2hEZWxldGUoa2V5KSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLmhhcyhrZXkpICYmIGRlbGV0ZSB0aGlzLl9fZGF0YV9fW2tleV07XG4gIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoRGVsZXRlO1xuIiwidmFyIG5hdGl2ZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX25hdGl2ZUNyZWF0ZScpO1xuXG4vKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovXG52YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogR2V0cyB0aGUgaGFzaCB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIEhhc2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICovXG5mdW5jdGlvbiBoYXNoR2V0KGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gIGlmIChuYXRpdmVDcmVhdGUpIHtcbiAgICB2YXIgcmVzdWx0ID0gZGF0YVtrZXldO1xuICAgIHJldHVybiByZXN1bHQgPT09IEhBU0hfVU5ERUZJTkVEID8gdW5kZWZpbmVkIDogcmVzdWx0O1xuICB9XG4gIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGRhdGEsIGtleSkgPyBkYXRhW2tleV0gOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzaEdldDtcbiIsInZhciBuYXRpdmVDcmVhdGUgPSByZXF1aXJlKCcuL19uYXRpdmVDcmVhdGUnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBoYXNoIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGhhc1xuICogQG1lbWJlck9mIEhhc2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBoYXNoSGFzKGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gIHJldHVybiBuYXRpdmVDcmVhdGUgPyAoZGF0YVtrZXldICE9PSB1bmRlZmluZWQpIDogaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hIYXM7XG4iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi9cbnZhciBIQVNIX1VOREVGSU5FRCA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJztcblxuLyoqXG4gKiBTZXRzIHRoZSBoYXNoIGBrZXlgIHRvIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIHNldFxuICogQG1lbWJlck9mIEhhc2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaGFzaCBpbnN0YW5jZS5cbiAqL1xuZnVuY3Rpb24gaGFzaFNldChrZXksIHZhbHVlKSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgdGhpcy5zaXplICs9IHRoaXMuaGFzKGtleSkgPyAwIDogMTtcbiAgZGF0YVtrZXldID0gKG5hdGl2ZUNyZWF0ZSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkKSA/IEhBU0hfVU5ERUZJTkVEIDogdmFsdWU7XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hTZXQ7XG4iLCIvKiogVXNlZCB0byBtYXRjaCB3cmFwIGRldGFpbCBjb21tZW50cy4gKi9cbnZhciByZVdyYXBDb21tZW50ID0gL1xceyg/OlxcblxcL1xcKiBcXFt3cmFwcGVkIHdpdGggLitcXF0gXFwqXFwvKT9cXG4/LztcblxuLyoqXG4gKiBJbnNlcnRzIHdyYXBwZXIgYGRldGFpbHNgIGluIGEgY29tbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBgc291cmNlYCBib2R5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIFRoZSBzb3VyY2UgdG8gbW9kaWZ5LlxuICogQHJldHVybnMge0FycmF5fSBkZXRhaWxzIFRoZSBkZXRhaWxzIHRvIGluc2VydC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIG1vZGlmaWVkIHNvdXJjZS5cbiAqL1xuZnVuY3Rpb24gaW5zZXJ0V3JhcERldGFpbHMoc291cmNlLCBkZXRhaWxzKSB7XG4gIHZhciBsZW5ndGggPSBkZXRhaWxzLmxlbmd0aDtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICByZXR1cm4gc291cmNlO1xuICB9XG4gIHZhciBsYXN0SW5kZXggPSBsZW5ndGggLSAxO1xuICBkZXRhaWxzW2xhc3RJbmRleF0gPSAobGVuZ3RoID4gMSA/ICcmICcgOiAnJykgKyBkZXRhaWxzW2xhc3RJbmRleF07XG4gIGRldGFpbHMgPSBkZXRhaWxzLmpvaW4obGVuZ3RoID4gMiA/ICcsICcgOiAnICcpO1xuICByZXR1cm4gc291cmNlLnJlcGxhY2UocmVXcmFwQ29tbWVudCwgJ3tcXG4vKiBbd3JhcHBlZCB3aXRoICcgKyBkZXRhaWxzICsgJ10gKi9cXG4nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbnNlcnRXcmFwRGV0YWlscztcbiIsInZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19TeW1ib2wnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5Jyk7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHNwcmVhZGFibGVTeW1ib2wgPSBTeW1ib2wgPyBTeW1ib2wuaXNDb25jYXRTcHJlYWRhYmxlIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgZmxhdHRlbmFibGUgYGFyZ3VtZW50c2Agb2JqZWN0IG9yIGFycmF5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZsYXR0ZW5hYmxlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzRmxhdHRlbmFibGUodmFsdWUpIHtcbiAgcmV0dXJuIGlzQXJyYXkodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSB8fFxuICAgICEhKHNwcmVhZGFibGVTeW1ib2wgJiYgdmFsdWUgJiYgdmFsdWVbc3ByZWFkYWJsZVN5bWJvbF0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRmxhdHRlbmFibGU7XG4iLCIvKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXFxkKikkLztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcblxuICByZXR1cm4gISFsZW5ndGggJiZcbiAgICAodHlwZSA9PSAnbnVtYmVyJyB8fFxuICAgICAgKHR5cGUgIT0gJ3N5bWJvbCcgJiYgcmVJc1VpbnQudGVzdCh2YWx1ZSkpKSAmJlxuICAgICAgICAodmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcbiIsInZhciBlcSA9IHJlcXVpcmUoJy4vZXEnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9faXNJbmRleCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsXG4gKiAgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgaW5kZXgsIG9iamVjdCkge1xuICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7XG4gIGlmICh0eXBlID09ICdudW1iZXInXG4gICAgICAgID8gKGlzQXJyYXlMaWtlKG9iamVjdCkgJiYgaXNJbmRleChpbmRleCwgb2JqZWN0Lmxlbmd0aCkpXG4gICAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KVxuICAgICAgKSB7XG4gICAgcmV0dXJuIGVxKG9iamVjdFtpbmRleF0sIHZhbHVlKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJdGVyYXRlZUNhbGw7XG4iLCJ2YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzU3ltYm9sID0gcmVxdWlyZSgnLi9pc1N5bWJvbCcpO1xuXG4vKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG52YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICByZUlzUGxhaW5Qcm9wID0gL15cXHcqJC87XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5IGtleXMgb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNLZXkodmFsdWUsIG9iamVjdCkge1xuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGlmICh0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicgfHxcbiAgICAgIHZhbHVlID09IG51bGwgfHwgaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkgfHwgIXJlSXNEZWVwUHJvcC50ZXN0KHZhbHVlKSB8fFxuICAgIChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiBPYmplY3Qob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNLZXk7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciB1c2UgYXMgdW5pcXVlIG9iamVjdCBrZXkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNLZXlhYmxlKHZhbHVlKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gKHR5cGUgPT0gJ3N0cmluZycgfHwgdHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdzeW1ib2wnIHx8IHR5cGUgPT0gJ2Jvb2xlYW4nKVxuICAgID8gKHZhbHVlICE9PSAnX19wcm90b19fJylcbiAgICA6ICh2YWx1ZSA9PT0gbnVsbCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNLZXlhYmxlO1xuIiwidmFyIExhenlXcmFwcGVyID0gcmVxdWlyZSgnLi9fTGF6eVdyYXBwZXInKSxcbiAgICBnZXREYXRhID0gcmVxdWlyZSgnLi9fZ2V0RGF0YScpLFxuICAgIGdldEZ1bmNOYW1lID0gcmVxdWlyZSgnLi9fZ2V0RnVuY05hbWUnKSxcbiAgICBsb2Rhc2ggPSByZXF1aXJlKCcuL3dyYXBwZXJMb2Rhc2gnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBhIGxhenkgY291bnRlcnBhcnQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNMYXppYWJsZShmdW5jKSB7XG4gIHZhciBmdW5jTmFtZSA9IGdldEZ1bmNOYW1lKGZ1bmMpLFxuICAgICAgb3RoZXIgPSBsb2Rhc2hbZnVuY05hbWVdO1xuXG4gIGlmICh0eXBlb2Ygb3RoZXIgIT0gJ2Z1bmN0aW9uJyB8fCAhKGZ1bmNOYW1lIGluIExhenlXcmFwcGVyLnByb3RvdHlwZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGZ1bmMgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdmFyIGRhdGEgPSBnZXREYXRhKG90aGVyKTtcbiAgcmV0dXJuICEhZGF0YSAmJiBmdW5jID09PSBkYXRhWzBdO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTGF6aWFibGU7XG4iLCJ2YXIgY29yZUpzRGF0YSA9IHJlcXVpcmUoJy4vX2NvcmVKc0RhdGEnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IG1ldGhvZHMgbWFzcXVlcmFkaW5nIGFzIG5hdGl2ZS4gKi9cbnZhciBtYXNrU3JjS2V5ID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgdWlkID0gL1teLl0rJC8uZXhlYyhjb3JlSnNEYXRhICYmIGNvcmVKc0RhdGEua2V5cyAmJiBjb3JlSnNEYXRhLmtleXMuSUVfUFJPVE8gfHwgJycpO1xuICByZXR1cm4gdWlkID8gKCdTeW1ib2woc3JjKV8xLicgKyB1aWQpIDogJyc7XG59KCkpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgZnVuY2AgaGFzIGl0cyBzb3VyY2UgbWFza2VkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2VkLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzTWFza2VkKGZ1bmMpIHtcbiAgcmV0dXJuICEhbWFza1NyY0tleSAmJiAobWFza1NyY0tleSBpbiBmdW5jKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc01hc2tlZDtcbiIsIi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgcHJvdG90eXBlIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3RvdHlwZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkge1xuICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLFxuICAgICAgcHJvdG8gPSAodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG87XG5cbiAgcmV0dXJuIHZhbHVlID09PSBwcm90bztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1Byb3RvdHlwZTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSBmb3Igc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpLmUuIGA9PT1gLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlmIHN1aXRhYmxlIGZvciBzdHJpY3RcbiAqICBlcXVhbGl0eSBjb21wYXJpc29ucywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc1N0cmljdENvbXBhcmFibGUodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSAmJiAhaXNPYmplY3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU3RyaWN0Q29tcGFyYWJsZTtcbiIsIi8qKlxuICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7XG4gIHRoaXMuX19kYXRhX18gPSBbXTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVDbGVhcjtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBkZWxldGVcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7XG5cbiAgaWYgKGluZGV4IDwgMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxO1xuICBpZiAoaW5kZXggPT0gbGFzdEluZGV4KSB7XG4gICAgZGF0YS5wb3AoKTtcbiAgfSBlbHNlIHtcbiAgICBzcGxpY2UuY2FsbChkYXRhLCBpbmRleCwgMSk7XG4gIH1cbiAgLS10aGlzLnNpemU7XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZURlbGV0ZTtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBsaXN0IGNhY2hlIHZhbHVlIGZvciBga2V5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgZ2V0XG4gKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlR2V0KGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIHJldHVybiBpbmRleCA8IDAgPyB1bmRlZmluZWQgOiBkYXRhW2luZGV4XVsxXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVHZXQ7XG4iLCJ2YXIgYXNzb2NJbmRleE9mID0gcmVxdWlyZSgnLi9fYXNzb2NJbmRleE9mJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVIYXMoa2V5KSB7XG4gIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZUhhcztcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBsaXN0IGNhY2hlIGBrZXlgIHRvIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIHNldFxuICogQG1lbWJlck9mIExpc3RDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVTZXQoa2V5LCB2YWx1ZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIGlmIChpbmRleCA8IDApIHtcbiAgICArK3RoaXMuc2l6ZTtcbiAgICBkYXRhLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgfSBlbHNlIHtcbiAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlO1xuICB9XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZVNldDtcbiIsInZhciBIYXNoID0gcmVxdWlyZSgnLi9fSGFzaCcpLFxuICAgIExpc3RDYWNoZSA9IHJlcXVpcmUoJy4vX0xpc3RDYWNoZScpLFxuICAgIE1hcCA9IHJlcXVpcmUoJy4vX01hcCcpO1xuXG4vKipcbiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkge1xuICB0aGlzLnNpemUgPSAwO1xuICB0aGlzLl9fZGF0YV9fID0ge1xuICAgICdoYXNoJzogbmV3IEhhc2gsXG4gICAgJ21hcCc6IG5ldyAoTWFwIHx8IExpc3RDYWNoZSksXG4gICAgJ3N0cmluZyc6IG5ldyBIYXNoXG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVDbGVhcjtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciByZXN1bHQgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSlbJ2RlbGV0ZSddKGtleSk7XG4gIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZURlbGV0ZTtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG1hcCB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVHZXQoa2V5KSB7XG4gIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuZ2V0KGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVHZXQ7XG4iLCJ2YXIgZ2V0TWFwRGF0YSA9IHJlcXVpcmUoJy4vX2dldE1hcERhdGEnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBtYXAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgaGFzXG4gKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUhhcyhrZXkpIHtcbiAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZUhhcztcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFNldHMgdGhlIG1hcCBga2V5YCB0byBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBzZXRcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBtYXAgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIG1hcENhY2hlU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSksXG4gICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVTZXQ7XG4iLCIvKipcbiAqIENvbnZlcnRzIGBtYXBgIHRvIGl0cyBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjb252ZXJ0LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuXG4gKi9cbmZ1bmN0aW9uIG1hcFRvQXJyYXkobWFwKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpO1xuXG4gIG1hcC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSBba2V5LCB2YWx1ZV07XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcFRvQXJyYXk7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgbWF0Y2hlc1Byb3BlcnR5YCBmb3Igc291cmNlIHZhbHVlcyBzdWl0YWJsZVxuICogZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKGtleSwgc3JjVmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IHNyY1ZhbHVlICYmXG4gICAgICAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIE9iamVjdChvYmplY3QpKSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWF0Y2hlc1N0cmljdENvbXBhcmFibGU7XG4iLCJ2YXIgbWVtb2l6ZSA9IHJlcXVpcmUoJy4vbWVtb2l6ZScpO1xuXG4vKiogVXNlZCBhcyB0aGUgbWF4aW11bSBtZW1vaXplIGNhY2hlIHNpemUuICovXG52YXIgTUFYX01FTU9JWkVfU0laRSA9IDUwMDtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWVtb2l6ZWAgd2hpY2ggY2xlYXJzIHRoZSBtZW1vaXplZCBmdW5jdGlvbidzXG4gKiBjYWNoZSB3aGVuIGl0IGV4Y2VlZHMgYE1BWF9NRU1PSVpFX1NJWkVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBoYXZlIGl0cyBvdXRwdXQgbWVtb2l6ZWQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtZW1vaXplZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gbWVtb2l6ZUNhcHBlZChmdW5jKSB7XG4gIHZhciByZXN1bHQgPSBtZW1vaXplKGZ1bmMsIGZ1bmN0aW9uKGtleSkge1xuICAgIGlmIChjYWNoZS5zaXplID09PSBNQVhfTUVNT0laRV9TSVpFKSB7XG4gICAgICBjYWNoZS5jbGVhcigpO1xuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9KTtcblxuICB2YXIgY2FjaGUgPSByZXN1bHQuY2FjaGU7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWVtb2l6ZUNhcHBlZDtcbiIsInZhciBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vX2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vX2NvbXBvc2VBcmdzUmlnaHQnKSxcbiAgICByZXBsYWNlSG9sZGVycyA9IHJlcXVpcmUoJy4vX3JlcGxhY2VIb2xkZXJzJyk7XG5cbi8qKiBVc2VkIGFzIHRoZSBpbnRlcm5hbCBhcmd1bWVudCBwbGFjZWhvbGRlci4gKi9cbnZhciBQTEFDRUhPTERFUiA9ICdfX2xvZGFzaF9wbGFjZWhvbGRlcl9fJztcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgV1JBUF9CSU5EX0ZMQUcgPSAxLFxuICAgIFdSQVBfQklORF9LRVlfRkxBRyA9IDIsXG4gICAgV1JBUF9DVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBXUkFQX0NVUlJZX0ZMQUcgPSA4LFxuICAgIFdSQVBfQVJZX0ZMQUcgPSAxMjgsXG4gICAgV1JBUF9SRUFSR19GTEFHID0gMjU2O1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKlxuICogTWVyZ2VzIHRoZSBmdW5jdGlvbiBtZXRhZGF0YSBvZiBgc291cmNlYCBpbnRvIGBkYXRhYC5cbiAqXG4gKiBNZXJnaW5nIG1ldGFkYXRhIHJlZHVjZXMgdGhlIG51bWJlciBvZiB3cmFwcGVycyB1c2VkIHRvIGludm9rZSBhIGZ1bmN0aW9uLlxuICogVGhpcyBpcyBwb3NzaWJsZSBiZWNhdXNlIG1ldGhvZHMgbGlrZSBgXy5iaW5kYCwgYF8uY3VycnlgLCBhbmQgYF8ucGFydGlhbGBcbiAqIG1heSBiZSBhcHBsaWVkIHJlZ2FyZGxlc3Mgb2YgZXhlY3V0aW9uIG9yZGVyLiBNZXRob2RzIGxpa2UgYF8uYXJ5YCBhbmRcbiAqIGBfLnJlYXJnYCBtb2RpZnkgZnVuY3Rpb24gYXJndW1lbnRzLCBtYWtpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlXG4gKiBleGVjdXRlZCBpbXBvcnRhbnQsIHByZXZlbnRpbmcgdGhlIG1lcmdpbmcgb2YgbWV0YWRhdGEuIEhvd2V2ZXIsIHdlIG1ha2VcbiAqIGFuIGV4Y2VwdGlvbiBmb3IgYSBzYWZlIGNvbWJpbmVkIGNhc2Ugd2hlcmUgY3VycmllZCBmdW5jdGlvbnMgaGF2ZSBgXy5hcnlgXG4gKiBhbmQgb3IgYF8ucmVhcmdgIGFwcGxpZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgVGhlIGRlc3RpbmF0aW9uIG1ldGFkYXRhLlxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBzb3VyY2UgbWV0YWRhdGEuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGRhdGFgLlxuICovXG5mdW5jdGlvbiBtZXJnZURhdGEoZGF0YSwgc291cmNlKSB7XG4gIHZhciBiaXRtYXNrID0gZGF0YVsxXSxcbiAgICAgIHNyY0JpdG1hc2sgPSBzb3VyY2VbMV0sXG4gICAgICBuZXdCaXRtYXNrID0gYml0bWFzayB8IHNyY0JpdG1hc2ssXG4gICAgICBpc0NvbW1vbiA9IG5ld0JpdG1hc2sgPCAoV1JBUF9CSU5EX0ZMQUcgfCBXUkFQX0JJTkRfS0VZX0ZMQUcgfCBXUkFQX0FSWV9GTEFHKTtcblxuICB2YXIgaXNDb21ibyA9XG4gICAgKChzcmNCaXRtYXNrID09IFdSQVBfQVJZX0ZMQUcpICYmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRykpIHx8XG4gICAgKChzcmNCaXRtYXNrID09IFdSQVBfQVJZX0ZMQUcpICYmIChiaXRtYXNrID09IFdSQVBfUkVBUkdfRkxBRykgJiYgKGRhdGFbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkpIHx8XG4gICAgKChzcmNCaXRtYXNrID09IChXUkFQX0FSWV9GTEFHIHwgV1JBUF9SRUFSR19GTEFHKSkgJiYgKHNvdXJjZVs3XS5sZW5ndGggPD0gc291cmNlWzhdKSAmJiAoYml0bWFzayA9PSBXUkFQX0NVUlJZX0ZMQUcpKTtcblxuICAvLyBFeGl0IGVhcmx5IGlmIG1ldGFkYXRhIGNhbid0IGJlIG1lcmdlZC5cbiAgaWYgKCEoaXNDb21tb24gfHwgaXNDb21ibykpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGB0aGlzQXJnYCBpZiBhdmFpbGFibGUuXG4gIGlmIChzcmNCaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcpIHtcbiAgICBkYXRhWzJdID0gc291cmNlWzJdO1xuICAgIC8vIFNldCB3aGVuIGN1cnJ5aW5nIGEgYm91bmQgZnVuY3Rpb24uXG4gICAgbmV3Qml0bWFzayB8PSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcgPyAwIDogV1JBUF9DVVJSWV9CT1VORF9GTEFHO1xuICB9XG4gIC8vIENvbXBvc2UgcGFydGlhbCBhcmd1bWVudHMuXG4gIHZhciB2YWx1ZSA9IHNvdXJjZVszXTtcbiAgaWYgKHZhbHVlKSB7XG4gICAgdmFyIHBhcnRpYWxzID0gZGF0YVszXTtcbiAgICBkYXRhWzNdID0gcGFydGlhbHMgPyBjb21wb3NlQXJncyhwYXJ0aWFscywgdmFsdWUsIHNvdXJjZVs0XSkgOiB2YWx1ZTtcbiAgICBkYXRhWzRdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzNdLCBQTEFDRUhPTERFUikgOiBzb3VyY2VbNF07XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIHJpZ2h0IGFyZ3VtZW50cy5cbiAgdmFsdWUgPSBzb3VyY2VbNV07XG4gIGlmICh2YWx1ZSkge1xuICAgIHBhcnRpYWxzID0gZGF0YVs1XTtcbiAgICBkYXRhWzVdID0gcGFydGlhbHMgPyBjb21wb3NlQXJnc1JpZ2h0KHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzZdKSA6IHZhbHVlO1xuICAgIGRhdGFbNl0gPSBwYXJ0aWFscyA/IHJlcGxhY2VIb2xkZXJzKGRhdGFbNV0sIFBMQUNFSE9MREVSKSA6IHNvdXJjZVs2XTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcmdQb3NgIGlmIGF2YWlsYWJsZS5cbiAgdmFsdWUgPSBzb3VyY2VbN107XG4gIGlmICh2YWx1ZSkge1xuICAgIGRhdGFbN10gPSB2YWx1ZTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcnlgIGlmIGl0J3Mgc21hbGxlci5cbiAgaWYgKHNyY0JpdG1hc2sgJiBXUkFQX0FSWV9GTEFHKSB7XG4gICAgZGF0YVs4XSA9IGRhdGFbOF0gPT0gbnVsbCA/IHNvdXJjZVs4XSA6IG5hdGl2ZU1pbihkYXRhWzhdLCBzb3VyY2VbOF0pO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYGFyaXR5YCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkLlxuICBpZiAoZGF0YVs5XSA9PSBudWxsKSB7XG4gICAgZGF0YVs5XSA9IHNvdXJjZVs5XTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBmdW5jYCBhbmQgbWVyZ2UgYml0bWFza3MuXG4gIGRhdGFbMF0gPSBzb3VyY2VbMF07XG4gIGRhdGFbMV0gPSBuZXdCaXRtYXNrO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1lcmdlRGF0YTtcbiIsInZhciBXZWFrTWFwID0gcmVxdWlyZSgnLi9fV2Vha01hcCcpO1xuXG4vKiogVXNlZCB0byBzdG9yZSBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbnZhciBtZXRhTWFwID0gV2Vha01hcCAmJiBuZXcgV2Vha01hcDtcblxubW9kdWxlLmV4cG9ydHMgPSBtZXRhTWFwO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgbmF0aXZlQ3JlYXRlID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2NyZWF0ZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5hdGl2ZUNyZWF0ZTtcbiIsInZhciBvdmVyQXJnID0gcmVxdWlyZSgnLi9fb3ZlckFyZycpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IG92ZXJBcmcoT2JqZWN0LmtleXMsIE9iamVjdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmF0aXZlS2V5cztcbiIsInZhciBmcmVlR2xvYmFsID0gcmVxdWlyZSgnLi9fZnJlZUdsb2JhbCcpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xudmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG52YXIgZnJlZU1vZHVsZSA9IGZyZWVFeHBvcnRzICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXG4vKiogRGV0ZWN0IHRoZSBwb3B1bGFyIENvbW1vbkpTIGV4dGVuc2lvbiBgbW9kdWxlLmV4cG9ydHNgLiAqL1xudmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHM7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgcHJvY2Vzc2AgZnJvbSBOb2RlLmpzLiAqL1xudmFyIGZyZWVQcm9jZXNzID0gbW9kdWxlRXhwb3J0cyAmJiBmcmVlR2xvYmFsLnByb2Nlc3M7XG5cbi8qKiBVc2VkIHRvIGFjY2VzcyBmYXN0ZXIgTm9kZS5qcyBoZWxwZXJzLiAqL1xudmFyIG5vZGVVdGlsID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIC8vIFVzZSBgdXRpbC50eXBlc2AgZm9yIE5vZGUuanMgMTArLlxuICAgIHZhciB0eXBlcyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5yZXF1aXJlICYmIGZyZWVNb2R1bGUucmVxdWlyZSgndXRpbCcpLnR5cGVzO1xuXG4gICAgaWYgKHR5cGVzKSB7XG4gICAgICByZXR1cm4gdHlwZXM7XG4gICAgfVxuXG4gICAgLy8gTGVnYWN5IGBwcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKWAgZm9yIE5vZGUuanMgPCAxMC5cbiAgICByZXR1cm4gZnJlZVByb2Nlc3MgJiYgZnJlZVByb2Nlc3MuYmluZGluZyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nKCd1dGlsJyk7XG4gIH0gY2F0Y2ggKGUpIHt9XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5vZGVVdGlsO1xuIiwiLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlXG4gKiBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG5hdGl2ZU9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyB1c2luZyBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gb2JqZWN0VG9TdHJpbmc7XG4iLCIvKipcbiAqIENyZWF0ZXMgYSB1bmFyeSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50IHRyYW5zZm9ybWVkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNmb3JtIFRoZSBhcmd1bWVudCB0cmFuc2Zvcm0uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gb3ZlckFyZyhmdW5jLCB0cmFuc2Zvcm0pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiBmdW5jKHRyYW5zZm9ybShhcmcpKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBvdmVyQXJnO1xuIiwidmFyIGFwcGx5ID0gcmVxdWlyZSgnLi9fYXBwbHknKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVJlc3RgIHdoaWNoIHRyYW5zZm9ybXMgdGhlIHJlc3QgYXJyYXkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIHJlc3QgYXJyYXkgdHJhbnNmb3JtLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIG92ZXJSZXN0KGZ1bmMsIHN0YXJ0LCB0cmFuc2Zvcm0pIHtcbiAgc3RhcnQgPSBuYXRpdmVNYXgoc3RhcnQgPT09IHVuZGVmaW5lZCA/IChmdW5jLmxlbmd0aCAtIDEpIDogc3RhcnQsIDApO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIHN0YXJ0LCAwKSxcbiAgICAgICAgYXJyYXkgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGFycmF5W2luZGV4XSA9IGFyZ3Nbc3RhcnQgKyBpbmRleF07XG4gICAgfVxuICAgIGluZGV4ID0gLTE7XG4gICAgdmFyIG90aGVyQXJncyA9IEFycmF5KHN0YXJ0ICsgMSk7XG4gICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkge1xuICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgIH1cbiAgICBvdGhlckFyZ3Nbc3RhcnRdID0gdHJhbnNmb3JtKGFycmF5KTtcbiAgICByZXR1cm4gYXBwbHkoZnVuYywgdGhpcywgb3RoZXJBcmdzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBvdmVyUmVzdDtcbiIsIi8qKiBVc2VkIHRvIGxvb2t1cCB1bm1pbmlmaWVkIGZ1bmN0aW9uIG5hbWVzLiAqL1xudmFyIHJlYWxOYW1lcyA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlYWxOYW1lcztcbiIsInZhciBjb3B5QXJyYXkgPSByZXF1aXJlKCcuL19jb3B5QXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9faXNJbmRleCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKlxuICogUmVvcmRlciBgYXJyYXlgIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGluZGV4ZXMgd2hlcmUgdGhlIGVsZW1lbnQgYXRcbiAqIHRoZSBmaXJzdCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgZmlyc3QgZWxlbWVudCwgdGhlIGVsZW1lbnQgYXRcbiAqIHRoZSBzZWNvbmQgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIHNlY29uZCBlbGVtZW50LCBhbmQgc28gb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byByZW9yZGVyLlxuICogQHBhcmFtIHtBcnJheX0gaW5kZXhlcyBUaGUgYXJyYW5nZWQgYXJyYXkgaW5kZXhlcy5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiByZW9yZGVyKGFycmF5LCBpbmRleGVzKSB7XG4gIHZhciBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBsZW5ndGggPSBuYXRpdmVNaW4oaW5kZXhlcy5sZW5ndGgsIGFyckxlbmd0aCksXG4gICAgICBvbGRBcnJheSA9IGNvcHlBcnJheShhcnJheSk7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgdmFyIGluZGV4ID0gaW5kZXhlc1tsZW5ndGhdO1xuICAgIGFycmF5W2xlbmd0aF0gPSBpc0luZGV4KGluZGV4LCBhcnJMZW5ndGgpID8gb2xkQXJyYXlbaW5kZXhdIDogdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZW9yZGVyO1xuIiwiLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xudmFyIFBMQUNFSE9MREVSID0gJ19fbG9kYXNoX3BsYWNlaG9sZGVyX18nO1xuXG4vKipcbiAqIFJlcGxhY2VzIGFsbCBgcGxhY2Vob2xkZXJgIGVsZW1lbnRzIGluIGBhcnJheWAgd2l0aCBhbiBpbnRlcm5hbCBwbGFjZWhvbGRlclxuICogYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgdGhlaXIgaW5kZXhlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7Kn0gcGxhY2Vob2xkZXIgVGhlIHBsYWNlaG9sZGVyIHRvIHJlcGxhY2UuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBwbGFjZWhvbGRlciBpbmRleGVzLlxuICovXG5mdW5jdGlvbiByZXBsYWNlSG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXNJbmRleCA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAodmFsdWUgPT09IHBsYWNlaG9sZGVyIHx8IHZhbHVlID09PSBQTEFDRUhPTERFUikge1xuICAgICAgYXJyYXlbaW5kZXhdID0gUExBQ0VIT0xERVI7XG4gICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXBsYWNlSG9sZGVycztcbiIsInZhciBmcmVlR2xvYmFsID0gcmVxdWlyZSgnLi9fZnJlZUdsb2JhbCcpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqL1xudmFyIGZyZWVTZWxmID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZiAmJiBzZWxmLk9iamVjdCA9PT0gT2JqZWN0ICYmIHNlbGY7XG5cbi8qKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LiAqL1xudmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8IGZyZWVTZWxmIHx8IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gcm9vdDtcbiIsIi8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi9cbnZhciBIQVNIX1VOREVGSU5FRCA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJztcblxuLyoqXG4gKiBBZGRzIGB2YWx1ZWAgdG8gdGhlIGFycmF5IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBhZGRcbiAqIEBtZW1iZXJPZiBTZXRDYWNoZVxuICogQGFsaWFzIHB1c2hcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNhY2hlLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIHNldENhY2hlQWRkKHZhbHVlKSB7XG4gIHRoaXMuX19kYXRhX18uc2V0KHZhbHVlLCBIQVNIX1VOREVGSU5FRCk7XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldENhY2hlQWRkO1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBpbiB0aGUgYXJyYXkgY2FjaGUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGhhc1xuICogQG1lbWJlck9mIFNldENhY2hlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBzZXRDYWNoZUhhcyh2YWx1ZSkge1xuICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXModmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldENhY2hlSGFzO1xuIiwidmFyIGJhc2VTZXREYXRhID0gcmVxdWlyZSgnLi9fYmFzZVNldERhdGEnKSxcbiAgICBzaG9ydE91dCA9IHJlcXVpcmUoJy4vX3Nob3J0T3V0Jyk7XG5cbi8qKlxuICogU2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICpcbiAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICogcGVyaW9kIG9mIHRpbWUsIGl0IHdpbGwgdHJpcCBpdHMgYnJlYWtlciBhbmQgdHJhbnNpdGlvbiB0byBhbiBpZGVudGl0eVxuICogZnVuY3Rpb24gdG8gYXZvaWQgZ2FyYmFnZSBjb2xsZWN0aW9uIHBhdXNlcyBpbiBWOC4gU2VlXG4gKiBbVjggaXNzdWUgMjA3MF0oaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjA3MClcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBzZXREYXRhID0gc2hvcnRPdXQoYmFzZVNldERhdGEpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNldERhdGE7XG4iLCIvKipcbiAqIENvbnZlcnRzIGBzZXRgIHRvIGFuIGFycmF5IG9mIGl0cyB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZXQgVGhlIHNldCB0byBjb252ZXJ0LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB2YWx1ZXMuXG4gKi9cbmZ1bmN0aW9uIHNldFRvQXJyYXkoc2V0KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkoc2V0LnNpemUpO1xuXG4gIHNldC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmVzdWx0WysraW5kZXhdID0gdmFsdWU7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldFRvQXJyYXk7XG4iLCJ2YXIgYmFzZVNldFRvU3RyaW5nID0gcmVxdWlyZSgnLi9fYmFzZVNldFRvU3RyaW5nJyksXG4gICAgc2hvcnRPdXQgPSByZXF1aXJlKCcuL19zaG9ydE91dCcpO1xuXG4vKipcbiAqIFNldHMgdGhlIGB0b1N0cmluZ2AgbWV0aG9kIG9mIGBmdW5jYCB0byByZXR1cm4gYHN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHN0cmluZyBUaGUgYHRvU3RyaW5nYCByZXN1bHQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICovXG52YXIgc2V0VG9TdHJpbmcgPSBzaG9ydE91dChiYXNlU2V0VG9TdHJpbmcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNldFRvU3RyaW5nO1xuIiwidmFyIGdldFdyYXBEZXRhaWxzID0gcmVxdWlyZSgnLi9fZ2V0V3JhcERldGFpbHMnKSxcbiAgICBpbnNlcnRXcmFwRGV0YWlscyA9IHJlcXVpcmUoJy4vX2luc2VydFdyYXBEZXRhaWxzJyksXG4gICAgc2V0VG9TdHJpbmcgPSByZXF1aXJlKCcuL19zZXRUb1N0cmluZycpLFxuICAgIHVwZGF0ZVdyYXBEZXRhaWxzID0gcmVxdWlyZSgnLi9fdXBkYXRlV3JhcERldGFpbHMnKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBgdG9TdHJpbmdgIG1ldGhvZCBvZiBgd3JhcHBlcmAgdG8gbWltaWMgdGhlIHNvdXJjZSBvZiBgcmVmZXJlbmNlYFxuICogd2l0aCB3cmFwcGVyIGRldGFpbHMgaW4gYSBjb21tZW50IGF0IHRoZSB0b3Agb2YgdGhlIHNvdXJjZSBib2R5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB3cmFwcGVyIFRoZSBmdW5jdGlvbiB0byBtb2RpZnkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWZlcmVuY2UgVGhlIHJlZmVyZW5jZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYHdyYXBwZXJgLlxuICovXG5mdW5jdGlvbiBzZXRXcmFwVG9TdHJpbmcod3JhcHBlciwgcmVmZXJlbmNlLCBiaXRtYXNrKSB7XG4gIHZhciBzb3VyY2UgPSAocmVmZXJlbmNlICsgJycpO1xuICByZXR1cm4gc2V0VG9TdHJpbmcod3JhcHBlciwgaW5zZXJ0V3JhcERldGFpbHMoc291cmNlLCB1cGRhdGVXcmFwRGV0YWlscyhnZXRXcmFwRGV0YWlscyhzb3VyY2UpLCBiaXRtYXNrKSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldFdyYXBUb1N0cmluZztcbiIsIi8qKiBVc2VkIHRvIGRldGVjdCBob3QgZnVuY3Rpb25zIGJ5IG51bWJlciBvZiBjYWxscyB3aXRoaW4gYSBzcGFuIG9mIG1pbGxpc2Vjb25kcy4gKi9cbnZhciBIT1RfQ09VTlQgPSA4MDAsXG4gICAgSE9UX1NQQU4gPSAxNjtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU5vdyA9IERhdGUubm93O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0J2xsIHNob3J0IG91dCBhbmQgaW52b2tlIGBpZGVudGl0eWAgaW5zdGVhZFxuICogb2YgYGZ1bmNgIHdoZW4gaXQncyBjYWxsZWQgYEhPVF9DT1VOVGAgb3IgbW9yZSB0aW1lcyBpbiBgSE9UX1NQQU5gXG4gKiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc2hvcnRhYmxlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBzaG9ydE91dChmdW5jKSB7XG4gIHZhciBjb3VudCA9IDAsXG4gICAgICBsYXN0Q2FsbGVkID0gMDtcblxuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHN0YW1wID0gbmF0aXZlTm93KCksXG4gICAgICAgIHJlbWFpbmluZyA9IEhPVF9TUEFOIC0gKHN0YW1wIC0gbGFzdENhbGxlZCk7XG5cbiAgICBsYXN0Q2FsbGVkID0gc3RhbXA7XG4gICAgaWYgKHJlbWFpbmluZyA+IDApIHtcbiAgICAgIGlmICgrK2NvdW50ID49IEhPVF9DT1VOVCkge1xuICAgICAgICByZXR1cm4gYXJndW1lbnRzWzBdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb3VudCA9IDA7XG4gICAgfVxuICAgIHJldHVybiBmdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaG9ydE91dDtcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKTtcblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBzdGFjay5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBTdGFja1xuICovXG5mdW5jdGlvbiBzdGFja0NsZWFyKCkge1xuICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0NsZWFyO1xuIiwiLyoqXG4gKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgc3RhY2suXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gc3RhY2tEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIHJlc3VsdCA9IGRhdGFbJ2RlbGV0ZSddKGtleSk7XG5cbiAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrRGVsZXRlO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gc3RhY2tHZXQoa2V5KSB7XG4gIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrR2V0O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYSBzdGFjayB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBTdGFja1xuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrSGFzKGtleSkge1xuICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0hhcztcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKSxcbiAgICBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBNYXBDYWNoZSA9IHJlcXVpcmUoJy4vX01hcENhY2hlJyk7XG5cbi8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqL1xudmFyIExBUkdFX0FSUkFZX1NJWkUgPSAyMDA7XG5cbi8qKlxuICogU2V0cyB0aGUgc3RhY2sgYGtleWAgdG8gYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgc2V0XG4gKiBAbWVtYmVyT2YgU3RhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgc3RhY2sgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkge1xuICAgIHZhciBwYWlycyA9IGRhdGEuX19kYXRhX187XG4gICAgaWYgKCFNYXAgfHwgKHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSkge1xuICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgdGhpcy5zaXplID0gKytkYXRhLnNpemU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGUocGFpcnMpO1xuICB9XG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgPSBkYXRhLnNpemU7XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrU2V0O1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uaW5kZXhPZmAgd2hpY2ggcGVyZm9ybXMgc3RyaWN0IGVxdWFsaXR5XG4gKiBjb21wYXJpc29ucyBvZiB2YWx1ZXMsIGkuZS4gYD09PWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gc3RyaWN0SW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICB2YXIgaW5kZXggPSBmcm9tSW5kZXggLSAxLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGFycmF5W2luZGV4XSA9PT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0cmljdEluZGV4T2Y7XG4iLCJ2YXIgbWVtb2l6ZUNhcHBlZCA9IHJlcXVpcmUoJy4vX21lbW9pemVDYXBwZWQnKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxcXF18XFxcXC4pKj8pXFwyKVxcXXwoPz0oPzpcXC58XFxbXFxdKSg/OlxcLnxcXFtcXF18JCkpL2c7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlRXNjYXBlQ2hhciA9IC9cXFxcKFxcXFwpPy9nO1xuXG4vKipcbiAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIGEgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gKi9cbnZhciBzdHJpbmdUb1BhdGggPSBtZW1vaXplQ2FwcGVkKGZ1bmN0aW9uKHN0cmluZykge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIGlmIChzdHJpbmcuY2hhckNvZGVBdCgwKSA9PT0gNDYgLyogLiAqLykge1xuICAgIHJlc3VsdC5wdXNoKCcnKTtcbiAgfVxuICBzdHJpbmcucmVwbGFjZShyZVByb3BOYW1lLCBmdW5jdGlvbihtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG4gICAgcmVzdWx0LnB1c2gocXVvdGUgPyBzdWJTdHJpbmcucmVwbGFjZShyZUVzY2FwZUNoYXIsICckMScpIDogKG51bWJlciB8fCBtYXRjaCkpO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHN0cmluZ1RvUGF0aDtcbiIsInZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJy4vaXNTeW1ib2wnKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG52YXIgSU5GSU5JVFkgPSAxIC8gMDtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIGtleSBpZiBpdCdzIG5vdCBhIHN0cmluZyBvciBzeW1ib2wuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gKiBAcmV0dXJucyB7c3RyaW5nfHN5bWJvbH0gUmV0dXJucyB0aGUga2V5LlxuICovXG5mdW5jdGlvbiB0b0tleSh2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IGlzU3ltYm9sKHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICB2YXIgcmVzdWx0ID0gKHZhbHVlICsgJycpO1xuICByZXR1cm4gKHJlc3VsdCA9PSAnMCcgJiYgKDEgLyB2YWx1ZSkgPT0gLUlORklOSVRZKSA/ICctMCcgOiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdG9LZXk7XG4iLCIvKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1Byb3RvID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byByZXNvbHZlIHRoZSBkZWNvbXBpbGVkIHNvdXJjZSBvZiBmdW5jdGlvbnMuICovXG52YXIgZnVuY1RvU3RyaW5nID0gZnVuY1Byb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENvbnZlcnRzIGBmdW5jYCB0byBpdHMgc291cmNlIGNvZGUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzb3VyY2UgY29kZS5cbiAqL1xuZnVuY3Rpb24gdG9Tb3VyY2UoZnVuYykge1xuICBpZiAoZnVuYyAhPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBmdW5jVG9TdHJpbmcuY2FsbChmdW5jKTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gKGZ1bmMgKyAnJyk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfVxuICByZXR1cm4gJyc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdG9Tb3VyY2U7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi9fYXJyYXlFYWNoJyksXG4gICAgYXJyYXlJbmNsdWRlcyA9IHJlcXVpcmUoJy4vX2FycmF5SW5jbHVkZXMnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgV1JBUF9CSU5EX0ZMQUcgPSAxLFxuICAgIFdSQVBfQklORF9LRVlfRkxBRyA9IDIsXG4gICAgV1JBUF9DVVJSWV9GTEFHID0gOCxcbiAgICBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcgPSAxNixcbiAgICBXUkFQX1BBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHID0gNjQsXG4gICAgV1JBUF9BUllfRkxBRyA9IDEyOCxcbiAgICBXUkFQX1JFQVJHX0ZMQUcgPSAyNTYsXG4gICAgV1JBUF9GTElQX0ZMQUcgPSA1MTI7XG5cbi8qKiBVc2VkIHRvIGFzc29jaWF0ZSB3cmFwIG1ldGhvZHMgd2l0aCB0aGVpciBiaXQgZmxhZ3MuICovXG52YXIgd3JhcEZsYWdzID0gW1xuICBbJ2FyeScsIFdSQVBfQVJZX0ZMQUddLFxuICBbJ2JpbmQnLCBXUkFQX0JJTkRfRkxBR10sXG4gIFsnYmluZEtleScsIFdSQVBfQklORF9LRVlfRkxBR10sXG4gIFsnY3VycnknLCBXUkFQX0NVUlJZX0ZMQUddLFxuICBbJ2N1cnJ5UmlnaHQnLCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUddLFxuICBbJ2ZsaXAnLCBXUkFQX0ZMSVBfRkxBR10sXG4gIFsncGFydGlhbCcsIFdSQVBfUEFSVElBTF9GTEFHXSxcbiAgWydwYXJ0aWFsUmlnaHQnLCBXUkFQX1BBUlRJQUxfUklHSFRfRkxBR10sXG4gIFsncmVhcmcnLCBXUkFQX1JFQVJHX0ZMQUddXG5dO1xuXG4vKipcbiAqIFVwZGF0ZXMgd3JhcHBlciBgZGV0YWlsc2AgYmFzZWQgb24gYGJpdG1hc2tgIGZsYWdzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJucyB7QXJyYXl9IGRldGFpbHMgVGhlIGRldGFpbHMgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGV0YWlsc2AuXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZVdyYXBEZXRhaWxzKGRldGFpbHMsIGJpdG1hc2spIHtcbiAgYXJyYXlFYWNoKHdyYXBGbGFncywgZnVuY3Rpb24ocGFpcikge1xuICAgIHZhciB2YWx1ZSA9ICdfLicgKyBwYWlyWzBdO1xuICAgIGlmICgoYml0bWFzayAmIHBhaXJbMV0pICYmICFhcnJheUluY2x1ZGVzKGRldGFpbHMsIHZhbHVlKSkge1xuICAgICAgZGV0YWlscy5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gZGV0YWlscy5zb3J0KCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdXBkYXRlV3JhcERldGFpbHM7XG4iLCJ2YXIgTGF6eVdyYXBwZXIgPSByZXF1aXJlKCcuL19MYXp5V3JhcHBlcicpLFxuICAgIExvZGFzaFdyYXBwZXIgPSByZXF1aXJlKCcuL19Mb2Rhc2hXcmFwcGVyJyksXG4gICAgY29weUFycmF5ID0gcmVxdWlyZSgnLi9fY29weUFycmF5Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIGB3cmFwcGVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHdyYXBwZXIgVGhlIHdyYXBwZXIgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgd3JhcHBlci5cbiAqL1xuZnVuY3Rpb24gd3JhcHBlckNsb25lKHdyYXBwZXIpIHtcbiAgaWYgKHdyYXBwZXIgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikge1xuICAgIHJldHVybiB3cmFwcGVyLmNsb25lKCk7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fKTtcbiAgcmVzdWx0Ll9fYWN0aW9uc19fID0gY29weUFycmF5KHdyYXBwZXIuX19hY3Rpb25zX18pO1xuICByZXN1bHQuX19pbmRleF9fICA9IHdyYXBwZXIuX19pbmRleF9fO1xuICByZXN1bHQuX192YWx1ZXNfXyA9IHdyYXBwZXIuX192YWx1ZXNfXztcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB3cmFwcGVyQ2xvbmU7XG4iLCJ2YXIgYXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19hc3NpZ25WYWx1ZScpLFxuICAgIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAgY3JlYXRlQXNzaWduZXIgPSByZXF1aXJlKCcuL19jcmVhdGVBc3NpZ25lcicpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQXNzaWducyBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBzb3VyY2Ugb2JqZWN0cyB0byB0aGVcbiAqIGRlc3RpbmF0aW9uIG9iamVjdC4gU291cmNlIG9iamVjdHMgYXJlIGFwcGxpZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0LlxuICogU3Vic2VxdWVudCBzb3VyY2VzIG92ZXJ3cml0ZSBwcm9wZXJ0eSBhc3NpZ25tZW50cyBvZiBwcmV2aW91cyBzb3VyY2VzLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgIGFuZCBpcyBsb29zZWx5IGJhc2VkIG9uXG4gKiBbYE9iamVjdC5hc3NpZ25gXShodHRwczovL21kbi5pby9PYmplY3QvYXNzaWduKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMTAuMFxuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICogQHNlZSBfLmFzc2lnbkluXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqIH1cbiAqXG4gKiBmdW5jdGlvbiBCYXIoKSB7XG4gKiAgIHRoaXMuYyA9IDM7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5iID0gMjtcbiAqIEJhci5wcm90b3R5cGUuZCA9IDQ7XG4gKlxuICogXy5hc3NpZ24oeyAnYSc6IDAgfSwgbmV3IEZvbywgbmV3IEJhcik7XG4gKiAvLyA9PiB7ICdhJzogMSwgJ2MnOiAzIH1cbiAqL1xudmFyIGFzc2lnbiA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlKSB7XG4gIGlmIChpc1Byb3RvdHlwZShzb3VyY2UpIHx8IGlzQXJyYXlMaWtlKHNvdXJjZSkpIHtcbiAgICBjb3B5T2JqZWN0KHNvdXJjZSwga2V5cyhzb3VyY2UpLCBvYmplY3QpO1xuICAgIHJldHVybjtcbiAgfVxuICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICBhc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgc291cmNlW2tleV0pO1xuICAgIH1cbiAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzaWduO1xuIiwidmFyIGJhc2VSZXN0ID0gcmVxdWlyZSgnLi9fYmFzZVJlc3QnKSxcbiAgICBjcmVhdGVXcmFwID0gcmVxdWlyZSgnLi9fY3JlYXRlV3JhcCcpLFxuICAgIGdldEhvbGRlciA9IHJlcXVpcmUoJy4vX2dldEhvbGRlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi9fcmVwbGFjZUhvbGRlcnMnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgV1JBUF9CSU5EX0ZMQUcgPSAxLFxuICAgIFdSQVBfUEFSVElBTF9GTEFHID0gMzI7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gKiBhbmQgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAqXG4gKiBUaGUgYF8uYmluZC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljIGJ1aWxkcyxcbiAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAqXG4gKiAqKk5vdGU6KiogVW5saWtlIG5hdGl2ZSBgRnVuY3Rpb24jYmluZGAsIHRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiXG4gKiBwcm9wZXJ0eSBvZiBib3VuZCBmdW5jdGlvbnMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJvdW5kIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBncmVldChncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAqICAgcmV0dXJuIGdyZWV0aW5nICsgJyAnICsgdGhpcy51c2VyICsgcHVuY3R1YXRpb247XG4gKiB9XG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gKiBib3VuZCgnIScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICpcbiAqIC8vIEJvdW5kIHdpdGggcGxhY2Vob2xkZXJzLlxuICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsIF8sICchJyk7XG4gKiBib3VuZCgnaGknKTtcbiAqIC8vID0+ICdoaSBmcmVkISdcbiAqL1xudmFyIGJpbmQgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICB2YXIgYml0bWFzayA9IFdSQVBfQklORF9GTEFHO1xuICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKGJpbmQpKTtcbiAgICBiaXRtYXNrIHw9IFdSQVBfUEFSVElBTF9GTEFHO1xuICB9XG4gIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzKTtcbn0pO1xuXG4vLyBBc3NpZ24gZGVmYXVsdCBwbGFjZWhvbGRlcnMuXG5iaW5kLnBsYWNlaG9sZGVyID0ge307XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZDtcbiIsIi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBgdmFsdWVgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMi40LjBcbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byByZXR1cm4gZnJvbSB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29uc3RhbnQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3RzID0gXy50aW1lcygyLCBfLmNvbnN0YW50KHsgJ2EnOiAxIH0pKTtcbiAqXG4gKiBjb25zb2xlLmxvZyhvYmplY3RzKTtcbiAqIC8vID0+IFt7ICdhJzogMSB9LCB7ICdhJzogMSB9XVxuICpcbiAqIGNvbnNvbGUubG9nKG9iamVjdHNbMF0gPT09IG9iamVjdHNbMV0pO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBjb25zdGFudCh2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbnN0YW50O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpLFxuICAgIG5vdyA9IHJlcXVpcmUoJy4vbm93JyksXG4gICAgdG9OdW1iZXIgPSByZXF1aXJlKCcuL3RvTnVtYmVyJyk7XG5cbi8qKiBFcnJvciBtZXNzYWdlIGNvbnN0YW50cy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heCxcbiAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVib3VuY2VkIGZ1bmN0aW9uIHRoYXQgZGVsYXlzIGludm9raW5nIGBmdW5jYCB1bnRpbCBhZnRlciBgd2FpdGBcbiAqIG1pbGxpc2Vjb25kcyBoYXZlIGVsYXBzZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHdhc1xuICogaW52b2tlZC4gVGhlIGRlYm91bmNlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGAgbWV0aG9kIHRvIGNhbmNlbFxuICogZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG8gaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uXG4gKiBQcm92aWRlIGBvcHRpb25zYCB0byBpbmRpY2F0ZSB3aGV0aGVyIGBmdW5jYCBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGVcbiAqIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YCB0aW1lb3V0LiBUaGUgYGZ1bmNgIGlzIGludm9rZWRcbiAqIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnRcbiAqIGNhbGxzIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgXG4gKiBpbnZvY2F0aW9uLlxuICpcbiAqICoqTm90ZToqKiBJZiBgbGVhZGluZ2AgYW5kIGB0cmFpbGluZ2Agb3B0aW9ucyBhcmUgYHRydWVgLCBgZnVuY2AgaXNcbiAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uXG4gKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gKlxuICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gKlxuICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLmRlYm91bmNlYCBhbmQgYF8udGhyb3R0bGVgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVib3VuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gW3dhaXQ9MF0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz1mYWxzZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4V2FpdF1cbiAqICBUaGUgbWF4aW11bSB0aW1lIGBmdW5jYCBpcyBhbGxvd2VkIHRvIGJlIGRlbGF5ZWQgYmVmb3JlIGl0J3MgaW52b2tlZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZGVib3VuY2VkIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBBdm9pZCBjb3N0bHkgY2FsY3VsYXRpb25zIHdoaWxlIHRoZSB3aW5kb3cgc2l6ZSBpcyBpbiBmbHV4LlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3Jlc2l6ZScsIF8uZGVib3VuY2UoY2FsY3VsYXRlTGF5b3V0LCAxNTApKTtcbiAqXG4gKiAvLyBJbnZva2UgYHNlbmRNYWlsYCB3aGVuIGNsaWNrZWQsIGRlYm91bmNpbmcgc3Vic2VxdWVudCBjYWxscy5cbiAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCBfLmRlYm91bmNlKHNlbmRNYWlsLCAzMDAsIHtcbiAqICAgJ2xlYWRpbmcnOiB0cnVlLFxuICogICAndHJhaWxpbmcnOiBmYWxzZVxuICogfSkpO1xuICpcbiAqIC8vIEVuc3VyZSBgYmF0Y2hMb2dgIGlzIGludm9rZWQgb25jZSBhZnRlciAxIHNlY29uZCBvZiBkZWJvdW5jZWQgY2FsbHMuXG4gKiB2YXIgZGVib3VuY2VkID0gXy5kZWJvdW5jZShiYXRjaExvZywgMjUwLCB7ICdtYXhXYWl0JzogMTAwMCB9KTtcbiAqIHZhciBzb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2UoJy9zdHJlYW0nKTtcbiAqIGpRdWVyeShzb3VyY2UpLm9uKCdtZXNzYWdlJywgZGVib3VuY2VkKTtcbiAqXG4gKiAvLyBDYW5jZWwgdGhlIHRyYWlsaW5nIGRlYm91bmNlZCBpbnZvY2F0aW9uLlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3BvcHN0YXRlJywgZGVib3VuY2VkLmNhbmNlbCk7XG4gKi9cbmZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIHdhaXQsIG9wdGlvbnMpIHtcbiAgdmFyIGxhc3RBcmdzLFxuICAgICAgbGFzdFRoaXMsXG4gICAgICBtYXhXYWl0LFxuICAgICAgcmVzdWx0LFxuICAgICAgdGltZXJJZCxcbiAgICAgIGxhc3RDYWxsVGltZSxcbiAgICAgIGxhc3RJbnZva2VUaW1lID0gMCxcbiAgICAgIGxlYWRpbmcgPSBmYWxzZSxcbiAgICAgIG1heGluZyA9IGZhbHNlLFxuICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHdhaXQgPSB0b051bWJlcih3YWl0KSB8fCAwO1xuICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICBsZWFkaW5nID0gISFvcHRpb25zLmxlYWRpbmc7XG4gICAgbWF4aW5nID0gJ21heFdhaXQnIGluIG9wdGlvbnM7XG4gICAgbWF4V2FpdCA9IG1heGluZyA/IG5hdGl2ZU1heCh0b051bWJlcihvcHRpb25zLm1heFdhaXQpIHx8IDAsIHdhaXQpIDogbWF4V2FpdDtcbiAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlRnVuYyh0aW1lKSB7XG4gICAgdmFyIGFyZ3MgPSBsYXN0QXJncyxcbiAgICAgICAgdGhpc0FyZyA9IGxhc3RUaGlzO1xuXG4gICAgbGFzdEFyZ3MgPSBsYXN0VGhpcyA9IHVuZGVmaW5lZDtcbiAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gbGVhZGluZ0VkZ2UodGltZSkge1xuICAgIC8vIFJlc2V0IGFueSBgbWF4V2FpdGAgdGltZXIuXG4gICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgIC8vIFN0YXJ0IHRoZSB0aW1lciBmb3IgdGhlIHRyYWlsaW5nIGVkZ2UuXG4gICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAvLyBJbnZva2UgdGhlIGxlYWRpbmcgZWRnZS5cbiAgICByZXR1cm4gbGVhZGluZyA/IGludm9rZUZ1bmModGltZSkgOiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiByZW1haW5pbmdXYWl0KHRpbWUpIHtcbiAgICB2YXIgdGltZVNpbmNlTGFzdENhbGwgPSB0aW1lIC0gbGFzdENhbGxUaW1lLFxuICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lLFxuICAgICAgICB0aW1lV2FpdGluZyA9IHdhaXQgLSB0aW1lU2luY2VMYXN0Q2FsbDtcblxuICAgIHJldHVybiBtYXhpbmdcbiAgICAgID8gbmF0aXZlTWluKHRpbWVXYWl0aW5nLCBtYXhXYWl0IC0gdGltZVNpbmNlTGFzdEludm9rZSlcbiAgICAgIDogdGltZVdhaXRpbmc7XG4gIH1cblxuICBmdW5jdGlvbiBzaG91bGRJbnZva2UodGltZSkge1xuICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWU7XG5cbiAgICAvLyBFaXRoZXIgdGhpcyBpcyB0aGUgZmlyc3QgY2FsbCwgYWN0aXZpdHkgaGFzIHN0b3BwZWQgYW5kIHdlJ3JlIGF0IHRoZVxuICAgIC8vIHRyYWlsaW5nIGVkZ2UsIHRoZSBzeXN0ZW0gdGltZSBoYXMgZ29uZSBiYWNrd2FyZHMgYW5kIHdlJ3JlIHRyZWF0aW5nXG4gICAgLy8gaXQgYXMgdGhlIHRyYWlsaW5nIGVkZ2UsIG9yIHdlJ3ZlIGhpdCB0aGUgYG1heFdhaXRgIGxpbWl0LlxuICAgIHJldHVybiAobGFzdENhbGxUaW1lID09PSB1bmRlZmluZWQgfHwgKHRpbWVTaW5jZUxhc3RDYWxsID49IHdhaXQpIHx8XG4gICAgICAodGltZVNpbmNlTGFzdENhbGwgPCAwKSB8fCAobWF4aW5nICYmIHRpbWVTaW5jZUxhc3RJbnZva2UgPj0gbWF4V2FpdCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGltZXJFeHBpcmVkKCkge1xuICAgIHZhciB0aW1lID0gbm93KCk7XG4gICAgaWYgKHNob3VsZEludm9rZSh0aW1lKSkge1xuICAgICAgcmV0dXJuIHRyYWlsaW5nRWRnZSh0aW1lKTtcbiAgICB9XG4gICAgLy8gUmVzdGFydCB0aGUgdGltZXIuXG4gICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCByZW1haW5pbmdXYWl0KHRpbWUpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWlsaW5nRWRnZSh0aW1lKSB7XG4gICAgdGltZXJJZCA9IHVuZGVmaW5lZDtcblxuICAgIC8vIE9ubHkgaW52b2tlIGlmIHdlIGhhdmUgYGxhc3RBcmdzYCB3aGljaCBtZWFucyBgZnVuY2AgaGFzIGJlZW5cbiAgICAvLyBkZWJvdW5jZWQgYXQgbGVhc3Qgb25jZS5cbiAgICBpZiAodHJhaWxpbmcgJiYgbGFzdEFyZ3MpIHtcbiAgICAgIHJldHVybiBpbnZva2VGdW5jKHRpbWUpO1xuICAgIH1cbiAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBjYW5jZWwoKSB7XG4gICAgaWYgKHRpbWVySWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgIH1cbiAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgbGFzdEFyZ3MgPSBsYXN0Q2FsbFRpbWUgPSBsYXN0VGhpcyA9IHRpbWVySWQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICByZXR1cm4gdGltZXJJZCA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogdHJhaWxpbmdFZGdlKG5vdygpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICB2YXIgdGltZSA9IG5vdygpLFxuICAgICAgICBpc0ludm9raW5nID0gc2hvdWxkSW52b2tlKHRpbWUpO1xuXG4gICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgbGFzdFRoaXMgPSB0aGlzO1xuICAgIGxhc3RDYWxsVGltZSA9IHRpbWU7XG5cbiAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbGVhZGluZ0VkZ2UobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXhpbmcpIHtcbiAgICAgICAgLy8gSGFuZGxlIGludm9jYXRpb25zIGluIGEgdGlnaHQgbG9vcC5cbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICByZXR1cm4gaW52b2tlRnVuYyhsYXN0Q2FsbFRpbWUpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGltZXJJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGRlYm91bmNlZC5jYW5jZWwgPSBjYW5jZWw7XG4gIGRlYm91bmNlZC5mbHVzaCA9IGZsdXNoO1xuICByZXR1cm4gZGVib3VuY2VkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRlYm91bmNlO1xuIiwiLyoqXG4gKiBQZXJmb3JtcyBhXG4gKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogY29tcGFyaXNvbiBiZXR3ZWVuIHR3byB2YWx1ZXMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlIGVxdWl2YWxlbnQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07XG4gKiB2YXIgb3RoZXIgPSB7ICdhJzogMSB9O1xuICpcbiAqIF8uZXEob2JqZWN0LCBvYmplY3QpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEob2JqZWN0LCBvdGhlcik7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoJ2EnLCAnYScpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEoJ2EnLCBPYmplY3QoJ2EnKSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoTmFOLCBOYU4pO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHtcbiAgcmV0dXJuIHZhbHVlID09PSBvdGhlciB8fCAodmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXE7XG4iLCJ2YXIgYXJyYXlGaWx0ZXIgPSByZXF1aXJlKCcuL19hcnJheUZpbHRlcicpLFxuICAgIGJhc2VGaWx0ZXIgPSByZXF1aXJlKCcuL19iYXNlRmlsdGVyJyksXG4gICAgYmFzZUl0ZXJhdGVlID0gcmVxdWlyZSgnLi9fYmFzZUl0ZXJhdGVlJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpO1xuXG4vKipcbiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgYWxsIGVsZW1lbnRzXG4gKiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRocmVlXG4gKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAqXG4gKiAqKk5vdGU6KiogVW5saWtlIGBfLnJlbW92ZWAsIHRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICogQHNlZSBfLnJlamVjdFxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgdXNlcnMgPSBbXG4gKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAqIF07XG4gKlxuICogXy5maWx0ZXIodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICpcbiAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gKiBfLmZpbHRlcih1c2VycywgeyAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0pO1xuICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICpcbiAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAqIF8uZmlsdGVyKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICpcbiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maWx0ZXIodXNlcnMsICdhY3RpdmUnKTtcbiAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J11cbiAqXG4gKiAvLyBDb21iaW5pbmcgc2V2ZXJhbCBwcmVkaWNhdGVzIHVzaW5nIGBfLm92ZXJFdmVyeWAgb3IgYF8ub3ZlclNvbWVgLlxuICogXy5maWx0ZXIodXNlcnMsIF8ub3ZlclNvbWUoW3sgJ2FnZSc6IDM2IH0sIFsnYWdlJywgNDBdXSkpO1xuICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ2Jhcm5leSddXG4gKi9cbmZ1bmN0aW9uIGZpbHRlcihjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBiYXNlSXRlcmF0ZWUocHJlZGljYXRlLCAzKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZmlsdGVyO1xuIiwidmFyIGNyZWF0ZUZpbmQgPSByZXF1aXJlKCcuL19jcmVhdGVGaW5kJyksXG4gICAgZmluZEluZGV4ID0gcmVxdWlyZSgnLi9maW5kSW5kZXgnKTtcblxuLyoqXG4gKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nIHRoZSBmaXJzdCBlbGVtZW50XG4gKiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRocmVlXG4gKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAqIF07XG4gKlxuICogXy5maW5kKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZSA8IDQwOyB9KTtcbiAqIC8vID0+IG9iamVjdCBmb3IgJ2Jhcm5leSdcbiAqXG4gKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kKHVzZXJzLCB7ICdhZ2UnOiAxLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAqIC8vID0+IG9iamVjdCBmb3IgJ3BlYmJsZXMnXG4gKlxuICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gKiAvLyA9PiBvYmplY3QgZm9yICdmcmVkJ1xuICpcbiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kKHVzZXJzLCAnYWN0aXZlJyk7XG4gKiAvLyA9PiBvYmplY3QgZm9yICdiYXJuZXknXG4gKi9cbnZhciBmaW5kID0gY3JlYXRlRmluZChmaW5kSW5kZXgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmQ7XG4iLCJ2YXIgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vX2Jhc2VGaW5kSW5kZXgnKSxcbiAgICBiYXNlSXRlcmF0ZWUgPSByZXF1aXJlKCcuL19iYXNlSXRlcmF0ZWUnKSxcbiAgICB0b0ludGVnZXIgPSByZXF1aXJlKCcuL3RvSW50ZWdlcicpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kYCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3RcbiAqIGVsZW1lbnQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMS4xLjBcbiAqIEBjYXRlZ29yeSBBcnJheVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZm91bmQgZWxlbWVudCwgZWxzZSBgLTFgLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgdXNlcnMgPSBbXG4gKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICogXTtcbiAqXG4gKiBfLmZpbmRJbmRleCh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby51c2VyID09ICdiYXJuZXknOyB9KTtcbiAqIC8vID0+IDBcbiAqXG4gKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kSW5kZXgodXNlcnMsIHsgJ3VzZXInOiAnZnJlZCcsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAqIC8vID0+IDFcbiAqXG4gKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gKiBfLmZpbmRJbmRleCh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICogLy8gPT4gMFxuICpcbiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kSW5kZXgodXNlcnMsICdhY3RpdmUnKTtcbiAqIC8vID0+IDJcbiAqL1xuZnVuY3Rpb24gZmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIHZhciBpbmRleCA9IGZyb21JbmRleCA9PSBudWxsID8gMCA6IHRvSW50ZWdlcihmcm9tSW5kZXgpO1xuICBpZiAoaW5kZXggPCAwKSB7XG4gICAgaW5kZXggPSBuYXRpdmVNYXgobGVuZ3RoICsgaW5kZXgsIDApO1xuICB9XG4gIHJldHVybiBiYXNlRmluZEluZGV4KGFycmF5LCBiYXNlSXRlcmF0ZWUocHJlZGljYXRlLCAzKSwgaW5kZXgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmRJbmRleDtcbiIsInZhciBiYXNlRmxhdHRlbiA9IHJlcXVpcmUoJy4vX2Jhc2VGbGF0dGVuJyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIElORklOSVRZID0gMSAvIDA7XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgZmxhdHRlbnMgYGFycmF5YC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDMuMC4wXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmZsYXR0ZW5EZWVwKFsxLCBbMiwgWzMsIFs0XV0sIDVdXSk7XG4gKiAvLyA9PiBbMSwgMiwgMywgNCwgNV1cbiAqL1xuZnVuY3Rpb24gZmxhdHRlbkRlZXAoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICByZXR1cm4gbGVuZ3RoID8gYmFzZUZsYXR0ZW4oYXJyYXksIElORklOSVRZKSA6IFtdO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZsYXR0ZW5EZWVwO1xuIiwidmFyIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vX2FycmF5RWFjaCcpLFxuICAgIGJhc2VFYWNoID0gcmVxdWlyZSgnLi9fYmFzZUVhY2gnKSxcbiAgICBjYXN0RnVuY3Rpb24gPSByZXF1aXJlKCcuL19jYXN0RnVuY3Rpb24nKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5Jyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgYW5kIGludm9rZXMgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAqXG4gKiAqKk5vdGU6KiogQXMgd2l0aCBvdGhlciBcIkNvbGxlY3Rpb25zXCIgbWV0aG9kcywgb2JqZWN0cyB3aXRoIGEgXCJsZW5ndGhcIlxuICogcHJvcGVydHkgYXJlIGl0ZXJhdGVkIGxpa2UgYXJyYXlzLiBUbyBhdm9pZCB0aGlzIGJlaGF2aW9yIHVzZSBgXy5mb3JJbmBcbiAqIG9yIGBfLmZvck93bmAgZm9yIG9iamVjdCBpdGVyYXRpb24uXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGFsaWFzIGVhY2hcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICogQHNlZSBfLmZvckVhY2hSaWdodFxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmZvckVhY2goWzEsIDJdLCBmdW5jdGlvbih2YWx1ZSkge1xuICogICBjb25zb2xlLmxvZyh2YWx1ZSk7XG4gKiB9KTtcbiAqIC8vID0+IExvZ3MgYDFgIHRoZW4gYDJgLlxuICpcbiAqIF8uZm9yRWFjaCh7ICdhJzogMSwgJ2InOiAyIH0sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAqICAgY29uc29sZS5sb2coa2V5KTtcbiAqIH0pO1xuICogLy8gPT4gTG9ncyAnYScgdGhlbiAnYicgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZCkuXG4gKi9cbmZ1bmN0aW9uIGZvckVhY2goY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlFYWNoIDogYmFzZUVhY2g7XG4gIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGNhc3RGdW5jdGlvbihpdGVyYXRlZSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZvckVhY2g7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vX2Jhc2VHZXQnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYG9iamVjdGAuIElmIHRoZSByZXNvbHZlZCB2YWx1ZSBpc1xuICogYHVuZGVmaW5lZGAsIHRoZSBgZGVmYXVsdFZhbHVlYCBpcyByZXR1cm5lZCBpbiBpdHMgcGxhY2UuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAzLjcuMFxuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGZvciBgdW5kZWZpbmVkYCByZXNvbHZlZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH1dIH07XG4gKlxuICogXy5nZXQob2JqZWN0LCAnYVswXS5iLmMnKTtcbiAqIC8vID0+IDNcbiAqXG4gKiBfLmdldChvYmplY3QsIFsnYScsICcwJywgJ2InLCAnYyddKTtcbiAqIC8vID0+IDNcbiAqXG4gKiBfLmdldChvYmplY3QsICdhLmIuYycsICdkZWZhdWx0Jyk7XG4gKiAvLyA9PiAnZGVmYXVsdCdcbiAqL1xuZnVuY3Rpb24gZ2V0KG9iamVjdCwgcGF0aCwgZGVmYXVsdFZhbHVlKSB7XG4gIHZhciByZXN1bHQgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcbiAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdFZhbHVlIDogcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldDtcbiIsInZhciBiYXNlSGFzSW4gPSByZXF1aXJlKCcuL19iYXNlSGFzSW4nKSxcbiAgICBoYXNQYXRoID0gcmVxdWlyZSgnLi9faGFzUGF0aCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgcGF0aGAgaXMgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG9mIGBvYmplY3RgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IF8uY3JlYXRlKHsgJ2EnOiBfLmNyZWF0ZSh7ICdiJzogMiB9KSB9KTtcbiAqXG4gKiBfLmhhc0luKG9iamVjdCwgJ2EnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmhhc0luKG9iamVjdCwgJ2EuYicpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaGFzSW4ob2JqZWN0LCBbJ2EnLCAnYiddKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmhhc0luKG9iamVjdCwgJ2InKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGhhc0luKG9iamVjdCwgcGF0aCkge1xuICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgaGFzUGF0aChvYmplY3QsIHBhdGgsIGJhc2VIYXNJbik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzSW47XG4iLCIvKipcbiAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IGl0IHJlY2VpdmVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBzaW5jZSAwLjEuMFxuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICpcbiAqIGNvbnNvbGUubG9nKF8uaWRlbnRpdHkob2JqZWN0KSA9PT0gb2JqZWN0KTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaWRlbnRpdHkodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlkZW50aXR5O1xuIiwidmFyIGJhc2VJc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vX2Jhc2VJc0FyZ3VtZW50cycpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8ucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGFuIGBhcmd1bWVudHNgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsXG4gKiAgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0FyZ3VtZW50cyA9IGJhc2VJc0FyZ3VtZW50cyhmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKSA/IGJhc2VJc0FyZ3VtZW50cyA6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjYWxsZWUnKSAmJlxuICAgICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJndW1lbnRzO1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KCdhYmMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheTtcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFycmF5LWxpa2UgaWYgaXQnc1xuICogbm90IGEgZnVuY3Rpb24gYW5kIGhhcyBhIGB2YWx1ZS5sZW5ndGhgIHRoYXQncyBhbiBpbnRlZ2VyIGdyZWF0ZXIgdGhhbiBvclxuICogZXF1YWwgdG8gYDBgIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYE51bWJlci5NQVhfU0FGRV9JTlRFR0VSYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoJ2FiYycpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgIWlzRnVuY3Rpb24odmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJyYXlMaWtlO1xuIiwidmFyIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKlxuICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pc0FycmF5TGlrZWAgZXhjZXB0IHRoYXQgaXQgYWxzbyBjaGVja3MgaWYgYHZhbHVlYFxuICogaXMgYW4gb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LWxpa2Ugb2JqZWN0LFxuICogIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5TGlrZU9iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2VPYmplY3QoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZU9iamVjdCgnYWJjJyk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNBcnJheUxpa2VPYmplY3QoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlT2JqZWN0KHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5TGlrZU9iamVjdDtcbiIsInZhciByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpLFxuICAgIHN0dWJGYWxzZSA9IHJlcXVpcmUoJy4vc3R1YkZhbHNlJyk7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG52YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbnZhciBmcmVlTW9kdWxlID0gZnJlZUV4cG9ydHMgJiYgdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbi8qKiBEZXRlY3QgdGhlIHBvcHVsYXIgQ29tbW9uSlMgZXh0ZW5zaW9uIGBtb2R1bGUuZXhwb3J0c2AuICovXG52YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0cztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgQnVmZmVyID0gbW9kdWxlRXhwb3J0cyA/IHJvb3QuQnVmZmVyIDogdW5kZWZpbmVkO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlSXNCdWZmZXIgPSBCdWZmZXIgPyBCdWZmZXIuaXNCdWZmZXIgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBidWZmZXIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjMuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBidWZmZXIsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0J1ZmZlcihuZXcgQnVmZmVyKDIpKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQnVmZmVyKG5ldyBVaW50OEFycmF5KDIpKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0J1ZmZlciA9IG5hdGl2ZUlzQnVmZmVyIHx8IHN0dWJGYWxzZTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0J1ZmZlcjtcbiIsInZhciBiYXNlS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VLZXlzJyksXG4gICAgZ2V0VGFnID0gcmVxdWlyZSgnLi9fZ2V0VGFnJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpLFxuICAgIGlzQnVmZmVyID0gcmVxdWlyZSgnLi9pc0J1ZmZlcicpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XSc7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gZW1wdHkgb2JqZWN0LCBjb2xsZWN0aW9uLCBtYXAsIG9yIHNldC5cbiAqXG4gKiBPYmplY3RzIGFyZSBjb25zaWRlcmVkIGVtcHR5IGlmIHRoZXkgaGF2ZSBubyBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWRcbiAqIHByb3BlcnRpZXMuXG4gKlxuICogQXJyYXktbGlrZSB2YWx1ZXMgc3VjaCBhcyBgYXJndW1lbnRzYCBvYmplY3RzLCBhcnJheXMsIGJ1ZmZlcnMsIHN0cmluZ3MsIG9yXG4gKiBqUXVlcnktbGlrZSBjb2xsZWN0aW9ucyBhcmUgY29uc2lkZXJlZCBlbXB0eSBpZiB0aGV5IGhhdmUgYSBgbGVuZ3RoYCBvZiBgMGAuXG4gKiBTaW1pbGFybHksIG1hcHMgYW5kIHNldHMgYXJlIGNvbnNpZGVyZWQgZW1wdHkgaWYgdGhleSBoYXZlIGEgYHNpemVgIG9mIGAwYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBlbXB0eSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzRW1wdHkobnVsbCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KHRydWUpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eSgxKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0VtcHR5KHsgJ2EnOiAxIH0pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNFbXB0eSh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkgJiZcbiAgICAgIChpc0FycmF5KHZhbHVlKSB8fCB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgdHlwZW9mIHZhbHVlLnNwbGljZSA9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgIGlzQnVmZmVyKHZhbHVlKSB8fCBpc1R5cGVkQXJyYXkodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSkpIHtcbiAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgfVxuICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKTtcbiAgaWYgKHRhZyA9PSBtYXBUYWcgfHwgdGFnID09IHNldFRhZykge1xuICAgIHJldHVybiAhdmFsdWUuc2l6ZTtcbiAgfVxuICBpZiAoaXNQcm90b3R5cGUodmFsdWUpKSB7XG4gICAgcmV0dXJuICFiYXNlS2V5cyh2YWx1ZSkubGVuZ3RoO1xuICB9XG4gIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBrZXkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRW1wdHk7XG4iLCJ2YXIgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFzeW5jVGFnID0gJ1tvYmplY3QgQXN5bmNGdW5jdGlvbl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXScsXG4gICAgcHJveHlUYWcgPSAnW29iamVjdCBQcm94eV0nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNGdW5jdGlvbihfKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3JcbiAgLy8gaW4gU2FmYXJpIDkgd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXlzIGFuZCBvdGhlciBjb25zdHJ1Y3RvcnMuXG4gIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgcmV0dXJuIHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWcgfHwgdGFnID09IGFzeW5jVGFnIHx8IHRhZyA9PSBwcm94eVRhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0Z1bmN0aW9uO1xuIiwiLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBhcnJheS1saWtlIGxlbmd0aC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgbG9vc2VseSBiYXNlZCBvblxuICogW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRvbGVuZ3RoKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzTGVuZ3RoKDMpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNMZW5ndGgoTnVtYmVyLk1JTl9WQUxVRSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNMZW5ndGgoSW5maW5pdHkpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzTGVuZ3RoKCczJyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmXG4gICAgdmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8PSBNQVhfU0FGRV9JTlRFR0VSO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTGVuZ3RoO1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGVcbiAqIFtsYW5ndWFnZSB0eXBlXShodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcylcbiAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoXy5ub29wKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLiBBIHZhbHVlIGlzIG9iamVjdC1saWtlIGlmIGl0J3Mgbm90IGBudWxsYFxuICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdExpa2U7XG4iLCJ2YXIgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTeW1ib2xgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzeW1ib2wsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fFxuICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHN5bWJvbFRhZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTeW1ib2w7XG4iLCJ2YXIgYmFzZUlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4vX2Jhc2VJc1R5cGVkQXJyYXknKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzVHlwZWRBcnJheTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAzLjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzVHlwZWRBcnJheSA9IG5vZGVJc1R5cGVkQXJyYXkgPyBiYXNlVW5hcnkobm9kZUlzVHlwZWRBcnJheSkgOiBiYXNlSXNUeXBlZEFycmF5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVHlwZWRBcnJheTtcbiIsInZhciBiYXNlQXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19iYXNlQXNzaWduVmFsdWUnKSxcbiAgICBjcmVhdGVBZ2dyZWdhdG9yID0gcmVxdWlyZSgnLi9fY3JlYXRlQWdncmVnYXRvcicpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIGtleXMgZ2VuZXJhdGVkIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZ1xuICogZWFjaCBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBjb3JyZXNwb25kaW5nIHZhbHVlIG9mXG4gKiBlYWNoIGtleSBpcyB0aGUgbGFzdCBlbGVtZW50IHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZSBrZXkuIFRoZVxuICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBhcnJheSA9IFtcbiAqICAgeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sXG4gKiAgIHsgJ2Rpcic6ICdyaWdodCcsICdjb2RlJzogMTAwIH1cbiAqIF07XG4gKlxuICogXy5rZXlCeShhcnJheSwgZnVuY3Rpb24obykge1xuICogICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShvLmNvZGUpO1xuICogfSk7XG4gKiAvLyA9PiB7ICdhJzogeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sICdkJzogeyAnZGlyJzogJ3JpZ2h0JywgJ2NvZGUnOiAxMDAgfSB9XG4gKlxuICogXy5rZXlCeShhcnJheSwgJ2RpcicpO1xuICogLy8gPT4geyAnbGVmdCc6IHsgJ2Rpcic6ICdsZWZ0JywgJ2NvZGUnOiA5NyB9LCAncmlnaHQnOiB7ICdkaXInOiAncmlnaHQnLCAnY29kZSc6IDEwMCB9IH1cbiAqL1xudmFyIGtleUJ5ID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCB2YWx1ZSk7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlCeTtcbiIsInZhciBhcnJheUxpa2VLZXlzID0gcmVxdWlyZSgnLi9fYXJyYXlMaWtlS2V5cycpLFxuICAgIGJhc2VLZXlzID0gcmVxdWlyZSgnLi9fYmFzZUtleXMnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5rZXlzKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXMobmV3IEZvbyk7XG4gKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy5rZXlzKCdoaScpO1xuICogLy8gPT4gWycwJywgJzEnXVxuICovXG5mdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5cztcbiIsInZhciBhcnJheU1hcCA9IHJlcXVpcmUoJy4vX2FycmF5TWFwJyksXG4gICAgYmFzZUl0ZXJhdGVlID0gcmVxdWlyZSgnLi9fYmFzZUl0ZXJhdGVlJyksXG4gICAgYmFzZU1hcCA9IHJlcXVpcmUoJy4vX2Jhc2VNYXAnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB2YWx1ZXMgYnkgcnVubmluZyBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gIHRocnVcbiAqIGBpdGVyYXRlZWAuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICpcbiAqIE1hbnkgbG9kYXNoIG1ldGhvZHMgYXJlIGd1YXJkZWQgdG8gd29yayBhcyBpdGVyYXRlZXMgZm9yIG1ldGhvZHMgbGlrZVxuICogYF8uZXZlcnlgLCBgXy5maWx0ZXJgLCBgXy5tYXBgLCBgXy5tYXBWYWx1ZXNgLCBgXy5yZWplY3RgLCBhbmQgYF8uc29tZWAuXG4gKlxuICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6XG4gKiBgYXJ5YCwgYGNodW5rYCwgYGN1cnJ5YCwgYGN1cnJ5UmlnaHRgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLFxuICogYGZpbGxgLCBgaW52ZXJ0YCwgYHBhcnNlSW50YCwgYHJhbmRvbWAsIGByYW5nZWAsIGByYW5nZVJpZ2h0YCwgYHJlcGVhdGAsXG4gKiBgc2FtcGxlU2l6ZWAsIGBzbGljZWAsIGBzb21lYCwgYHNvcnRCeWAsIGBzcGxpdGAsIGB0YWtlYCwgYHRha2VSaWdodGAsXG4gKiBgdGVtcGxhdGVgLCBgdHJpbWAsIGB0cmltRW5kYCwgYHRyaW1TdGFydGAsIGFuZCBgd29yZHNgXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICogICByZXR1cm4gbiAqIG47XG4gKiB9XG4gKlxuICogXy5tYXAoWzQsIDhdLCBzcXVhcmUpO1xuICogLy8gPT4gWzE2LCA2NF1cbiAqXG4gKiBfLm1hcCh7ICdhJzogNCwgJ2InOiA4IH0sIHNxdWFyZSk7XG4gKiAvLyA9PiBbMTYsIDY0XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAqIF8ubWFwKHVzZXJzLCAndXNlcicpO1xuICogLy8gPT4gWydiYXJuZXknLCAnZnJlZCddXG4gKi9cbmZ1bmN0aW9uIG1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheU1hcCA6IGJhc2VNYXA7XG4gIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGJhc2VJdGVyYXRlZShpdGVyYXRlZSwgMykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcDtcbiIsInZhciBNYXBDYWNoZSA9IHJlcXVpcmUoJy4vX01hcENhY2hlJyk7XG5cbi8qKiBFcnJvciBtZXNzYWdlIGNvbnN0YW50cy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgbWVtb2l6ZXMgdGhlIHJlc3VsdCBvZiBgZnVuY2AuIElmIGByZXNvbHZlcmAgaXNcbiAqIHByb3ZpZGVkLCBpdCBkZXRlcm1pbmVzIHRoZSBjYWNoZSBrZXkgZm9yIHN0b3JpbmcgdGhlIHJlc3VsdCBiYXNlZCBvbiB0aGVcbiAqIGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24uIEJ5IGRlZmF1bHQsIHRoZSBmaXJzdCBhcmd1bWVudFxuICogcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uIGlzIHVzZWQgYXMgdGhlIG1hcCBjYWNoZSBrZXkuIFRoZSBgZnVuY2BcbiAqIGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIG1lbW9pemVkIGZ1bmN0aW9uLlxuICpcbiAqICoqTm90ZToqKiBUaGUgY2FjaGUgaXMgZXhwb3NlZCBhcyB0aGUgYGNhY2hlYCBwcm9wZXJ0eSBvbiB0aGUgbWVtb2l6ZWRcbiAqIGZ1bmN0aW9uLiBJdHMgY3JlYXRpb24gbWF5IGJlIGN1c3RvbWl6ZWQgYnkgcmVwbGFjaW5nIHRoZSBgXy5tZW1vaXplLkNhY2hlYFxuICogY29uc3RydWN0b3Igd2l0aCBvbmUgd2hvc2UgaW5zdGFuY2VzIGltcGxlbWVudCB0aGVcbiAqIFtgTWFwYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcHJvcGVydGllcy1vZi10aGUtbWFwLXByb3RvdHlwZS1vYmplY3QpXG4gKiBtZXRob2QgaW50ZXJmYWNlIG9mIGBjbGVhcmAsIGBkZWxldGVgLCBgZ2V0YCwgYGhhc2AsIGFuZCBgc2V0YC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtyZXNvbHZlcl0gVGhlIGZ1bmN0aW9uIHRvIHJlc29sdmUgdGhlIGNhY2hlIGtleS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG1lbW9pemVkIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiB9O1xuICogdmFyIG90aGVyID0geyAnYyc6IDMsICdkJzogNCB9O1xuICpcbiAqIHZhciB2YWx1ZXMgPSBfLm1lbW9pemUoXy52YWx1ZXMpO1xuICogdmFsdWVzKG9iamVjdCk7XG4gKiAvLyA9PiBbMSwgMl1cbiAqXG4gKiB2YWx1ZXMob3RoZXIpO1xuICogLy8gPT4gWzMsIDRdXG4gKlxuICogb2JqZWN0LmEgPSAyO1xuICogdmFsdWVzKG9iamVjdCk7XG4gKiAvLyA9PiBbMSwgMl1cbiAqXG4gKiAvLyBNb2RpZnkgdGhlIHJlc3VsdCBjYWNoZS5cbiAqIHZhbHVlcy5jYWNoZS5zZXQob2JqZWN0LCBbJ2EnLCAnYiddKTtcbiAqIHZhbHVlcyhvYmplY3QpO1xuICogLy8gPT4gWydhJywgJ2InXVxuICpcbiAqIC8vIFJlcGxhY2UgYF8ubWVtb2l6ZS5DYWNoZWAuXG4gKiBfLm1lbW9pemUuQ2FjaGUgPSBXZWFrTWFwO1xuICovXG5mdW5jdGlvbiBtZW1vaXplKGZ1bmMsIHJlc29sdmVyKSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nIHx8IChyZXNvbHZlciAhPSBudWxsICYmIHR5cGVvZiByZXNvbHZlciAhPSAnZnVuY3Rpb24nKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB2YXIgbWVtb2l6ZWQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAga2V5ID0gcmVzb2x2ZXIgPyByZXNvbHZlci5hcHBseSh0aGlzLCBhcmdzKSA6IGFyZ3NbMF0sXG4gICAgICAgIGNhY2hlID0gbWVtb2l6ZWQuY2FjaGU7XG5cbiAgICBpZiAoY2FjaGUuaGFzKGtleSkpIHtcbiAgICAgIHJldHVybiBjYWNoZS5nZXQoa2V5KTtcbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgbWVtb2l6ZWQuY2FjaGUgPSBjYWNoZS5zZXQoa2V5LCByZXN1bHQpIHx8IGNhY2hlO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIG1lbW9pemVkLmNhY2hlID0gbmV3IChtZW1vaXplLkNhY2hlIHx8IE1hcENhY2hlKTtcbiAgcmV0dXJuIG1lbW9pemVkO1xufVxuXG4vLyBFeHBvc2UgYE1hcENhY2hlYC5cbm1lbW9pemUuQ2FjaGUgPSBNYXBDYWNoZTtcblxubW9kdWxlLmV4cG9ydHMgPSBtZW1vaXplO1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIGB1bmRlZmluZWRgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMi4zLjBcbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udGltZXMoMiwgXy5ub29wKTtcbiAqIC8vID0+IFt1bmRlZmluZWQsIHVuZGVmaW5lZF1cbiAqL1xuZnVuY3Rpb24gbm9vcCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub29wO1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgdGltZXN0YW1wIG9mIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoYXQgaGF2ZSBlbGFwc2VkIHNpbmNlXG4gKiB0aGUgVW5peCBlcG9jaCAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDIuNC4wXG4gKiBAY2F0ZWdvcnkgRGF0ZVxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgdGltZXN0YW1wLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmRlZmVyKGZ1bmN0aW9uKHN0YW1wKSB7XG4gKiAgIGNvbnNvbGUubG9nKF8ubm93KCkgLSBzdGFtcCk7XG4gKiB9LCBfLm5vdygpKTtcbiAqIC8vID0+IExvZ3MgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgaXQgdG9vayBmb3IgdGhlIGRlZmVycmVkIGludm9jYXRpb24uXG4gKi9cbnZhciBub3cgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHJvb3QuRGF0ZS5ub3coKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbm93O1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2Jhc2VQcm9wZXJ0eScpLFxuICAgIGJhc2VQcm9wZXJ0eURlZXAgPSByZXF1aXJlKCcuL19iYXNlUHJvcGVydHlEZWVwJyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuL19pc0tleScpLFxuICAgIHRvS2V5ID0gcmVxdWlyZSgnLi9fdG9LZXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAyLjQuMFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdHMgPSBbXG4gKiAgIHsgJ2EnOiB7ICdiJzogMiB9IH0sXG4gKiAgIHsgJ2EnOiB7ICdiJzogMSB9IH1cbiAqIF07XG4gKlxuICogXy5tYXAob2JqZWN0cywgXy5wcm9wZXJ0eSgnYS5iJykpO1xuICogLy8gPT4gWzIsIDFdXG4gKlxuICogXy5tYXAoXy5zb3J0Qnkob2JqZWN0cywgXy5wcm9wZXJ0eShbJ2EnLCAnYiddKSksICdhLmInKTtcbiAqIC8vID0+IFsxLCAyXVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eSh0b0tleShwYXRoKSkgOiBiYXNlUHJvcGVydHlEZWVwKHBhdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHByb3BlcnR5O1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGVtcHR5IGFycmF5LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4xMy4wXG4gKiBAY2F0ZWdvcnkgVXRpbFxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZW1wdHkgYXJyYXkuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBhcnJheXMgPSBfLnRpbWVzKDIsIF8uc3R1YkFycmF5KTtcbiAqXG4gKiBjb25zb2xlLmxvZyhhcnJheXMpO1xuICogLy8gPT4gW1tdLCBbXV1cbiAqXG4gKiBjb25zb2xlLmxvZyhhcnJheXNbMF0gPT09IGFycmF5c1sxXSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBzdHViQXJyYXkoKSB7XG4gIHJldHVybiBbXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdHViQXJyYXk7XG4iLCIvKipcbiAqIFRoaXMgbWV0aG9kIHJldHVybnMgYGZhbHNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMTMuMFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udGltZXMoMiwgXy5zdHViRmFsc2UpO1xuICogLy8gPT4gW2ZhbHNlLCBmYWxzZV1cbiAqL1xuZnVuY3Rpb24gc3R1YkZhbHNlKCkge1xuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3R1YkZhbHNlO1xuIiwidmFyIHRvTnVtYmVyID0gcmVxdWlyZSgnLi90b051bWJlcicpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBJTkZJTklUWSA9IDEgLyAwLFxuICAgIE1BWF9JTlRFR0VSID0gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDg7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjEyLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b0Zpbml0ZSgzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b0Zpbml0ZShOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9GaW5pdGUoSW5maW5pdHkpO1xuICogLy8gPT4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDhcbiAqXG4gKiBfLnRvRmluaXRlKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b0Zpbml0ZSh2YWx1ZSkge1xuICBpZiAoIXZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiAwO1xuICB9XG4gIHZhbHVlID0gdG9OdW1iZXIodmFsdWUpO1xuICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHtcbiAgICB2YXIgc2lnbiA9ICh2YWx1ZSA8IDAgPyAtMSA6IDEpO1xuICAgIHJldHVybiBzaWduICogTUFYX0lOVEVHRVI7XG4gIH1cbiAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/IHZhbHVlIDogMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b0Zpbml0ZTtcbiIsInZhciB0b0Zpbml0ZSA9IHJlcXVpcmUoJy4vdG9GaW5pdGUnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIGludGVnZXIuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAqIFtgVG9JbnRlZ2VyYF0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRvaW50ZWdlcikuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW50ZWdlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b0ludGVnZXIoMy4yKTtcbiAqIC8vID0+IDNcbiAqXG4gKiBfLnRvSW50ZWdlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDBcbiAqXG4gKiBfLnRvSW50ZWdlcihJbmZpbml0eSk7XG4gKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICpcbiAqIF8udG9JbnRlZ2VyKCczLjInKTtcbiAqIC8vID0+IDNcbiAqL1xuZnVuY3Rpb24gdG9JbnRlZ2VyKHZhbHVlKSB7XG4gIHZhciByZXN1bHQgPSB0b0Zpbml0ZSh2YWx1ZSksXG4gICAgICByZW1haW5kZXIgPSByZXN1bHQgJSAxO1xuXG4gIHJldHVybiByZXN1bHQgPT09IHJlc3VsdCA/IChyZW1haW5kZXIgPyByZXN1bHQgLSByZW1haW5kZXIgOiByZXN1bHQpIDogMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b0ludGVnZXI7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgaXNTeW1ib2wgPSByZXF1aXJlKCcuL2lzU3ltYm9sJyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE5BTiA9IDAgLyAwO1xuXG4vKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLiAqL1xudmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG5cbi8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG52YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b051bWJlcigzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICogLy8gPT4gSW5maW5pdHlcbiAqXG4gKiBfLnRvTnVtYmVyKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gTkFOO1xuICB9XG4gIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICB2YXIgb3RoZXIgPSB0eXBlb2YgdmFsdWUudmFsdWVPZiA9PSAnZnVuY3Rpb24nID8gdmFsdWUudmFsdWVPZigpIDogdmFsdWU7XG4gICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gIH1cbiAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHJlVHJpbSwgJycpO1xuICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOClcbiAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b051bWJlcjtcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuL19iYXNlVG9TdHJpbmcnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgZm9yIGBudWxsYFxuICogYW5kIGB1bmRlZmluZWRgIHZhbHVlcy4gVGhlIHNpZ24gb2YgYC0wYCBpcyBwcmVzZXJ2ZWQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRvU3RyaW5nKG51bGwpO1xuICogLy8gPT4gJydcbiAqXG4gKiBfLnRvU3RyaW5nKC0wKTtcbiAqIC8vID0+ICctMCdcbiAqXG4gKiBfLnRvU3RyaW5nKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiAnMSwyLDMnXG4gKi9cbmZ1bmN0aW9uIHRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiBiYXNlVG9TdHJpbmcodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvU3RyaW5nO1xuIiwidmFyIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vX2FycmF5RWFjaCcpLFxuICAgIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL19iYXNlQ3JlYXRlJyksXG4gICAgYmFzZUZvck93biA9IHJlcXVpcmUoJy4vX2Jhc2VGb3JPd24nKSxcbiAgICBiYXNlSXRlcmF0ZWUgPSByZXF1aXJlKCcuL19iYXNlSXRlcmF0ZWUnKSxcbiAgICBnZXRQcm90b3R5cGUgPSByZXF1aXJlKCcuL19nZXRQcm90b3R5cGUnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNCdWZmZXIgPSByZXF1aXJlKCcuL2lzQnVmZmVyJyksXG4gICAgaXNGdW5jdGlvbiA9IHJlcXVpcmUoJy4vaXNGdW5jdGlvbicpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpLFxuICAgIGlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4vaXNUeXBlZEFycmF5Jyk7XG5cbi8qKlxuICogQW4gYWx0ZXJuYXRpdmUgdG8gYF8ucmVkdWNlYDsgdGhpcyBtZXRob2QgdHJhbnNmb3JtcyBgb2JqZWN0YCB0byBhIG5ld1xuICogYGFjY3VtdWxhdG9yYCBvYmplY3Qgd2hpY2ggaXMgdGhlIHJlc3VsdCBvZiBydW5uaW5nIGVhY2ggb2YgaXRzIG93blxuICogZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyB0aHJ1IGBpdGVyYXRlZWAsIHdpdGggZWFjaCBpbnZvY2F0aW9uXG4gKiBwb3RlbnRpYWxseSBtdXRhdGluZyB0aGUgYGFjY3VtdWxhdG9yYCBvYmplY3QuIElmIGBhY2N1bXVsYXRvcmAgaXMgbm90XG4gKiBwcm92aWRlZCwgYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUgYFtbUHJvdG90eXBlXV1gIHdpbGwgYmUgdXNlZC4gVGhlXG4gKiBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggZm91ciBhcmd1bWVudHM6IChhY2N1bXVsYXRvciwgdmFsdWUsIGtleSwgb2JqZWN0KS5cbiAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGN1c3RvbSBhY2N1bXVsYXRvciB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50cmFuc2Zvcm0oWzIsIDMsIDRdLCBmdW5jdGlvbihyZXN1bHQsIG4pIHtcbiAqICAgcmVzdWx0LnB1c2gobiAqPSBuKTtcbiAqICAgcmV0dXJuIG4gJSAyID09IDA7XG4gKiB9LCBbXSk7XG4gKiAvLyA9PiBbNCwgOV1cbiAqXG4gKiBfLnRyYW5zZm9ybSh7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDEgfSwgZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gKiAgIChyZXN1bHRbdmFsdWVdIHx8IChyZXN1bHRbdmFsdWVdID0gW10pKS5wdXNoKGtleSk7XG4gKiB9LCB7fSk7XG4gKiAvLyA9PiB7ICcxJzogWydhJywgJ2MnXSwgJzInOiBbJ2InXSB9XG4gKi9cbmZ1bmN0aW9uIHRyYW5zZm9ybShvYmplY3QsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iamVjdCksXG4gICAgICBpc0Fyckxpa2UgPSBpc0FyciB8fCBpc0J1ZmZlcihvYmplY3QpIHx8IGlzVHlwZWRBcnJheShvYmplY3QpO1xuXG4gIGl0ZXJhdGVlID0gYmFzZUl0ZXJhdGVlKGl0ZXJhdGVlLCA0KTtcbiAgaWYgKGFjY3VtdWxhdG9yID09IG51bGwpIHtcbiAgICB2YXIgQ3RvciA9IG9iamVjdCAmJiBvYmplY3QuY29uc3RydWN0b3I7XG4gICAgaWYgKGlzQXJyTGlrZSkge1xuICAgICAgYWNjdW11bGF0b3IgPSBpc0FyciA/IG5ldyBDdG9yIDogW107XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gaXNGdW5jdGlvbihDdG9yKSA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlKG9iamVjdCkpIDoge307XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgYWNjdW11bGF0b3IgPSB7fTtcbiAgICB9XG4gIH1cbiAgKGlzQXJyTGlrZSA/IGFycmF5RWFjaCA6IGJhc2VGb3JPd24pKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgICByZXR1cm4gaXRlcmF0ZWUoYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgb2JqZWN0KTtcbiAgfSk7XG4gIHJldHVybiBhY2N1bXVsYXRvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0cmFuc2Zvcm07XG4iLCJ2YXIgYmFzZVZhbHVlcyA9IHJlcXVpcmUoJy4vX2Jhc2VWYWx1ZXMnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IHZhbHVlcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy52YWx1ZXMobmV3IEZvbyk7XG4gKiAvLyA9PiBbMSwgMl0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLnZhbHVlcygnaGknKTtcbiAqIC8vID0+IFsnaCcsICdpJ11cbiAqL1xuZnVuY3Rpb24gdmFsdWVzKG9iamVjdCkge1xuICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBbXSA6IGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZhbHVlcztcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vX0xhenlXcmFwcGVyJyksXG4gICAgTG9kYXNoV3JhcHBlciA9IHJlcXVpcmUoJy4vX0xvZGFzaFdyYXBwZXInKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi9fYmFzZUxvZGFzaCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpLFxuICAgIHdyYXBwZXJDbG9uZSA9IHJlcXVpcmUoJy4vX3dyYXBwZXJDbG9uZScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgbG9kYXNoYCBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgaW1wbGljaXQgbWV0aG9kXG4gKiBjaGFpbiBzZXF1ZW5jZXMuIE1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIGFuZCByZXR1cm4gYXJyYXlzLCBjb2xsZWN0aW9ucyxcbiAqIGFuZCBmdW5jdGlvbnMgY2FuIGJlIGNoYWluZWQgdG9nZXRoZXIuIE1ldGhvZHMgdGhhdCByZXRyaWV2ZSBhIHNpbmdsZSB2YWx1ZVxuICogb3IgbWF5IHJldHVybiBhIHByaW1pdGl2ZSB2YWx1ZSB3aWxsIGF1dG9tYXRpY2FsbHkgZW5kIHRoZSBjaGFpbiBzZXF1ZW5jZVxuICogYW5kIHJldHVybiB0aGUgdW53cmFwcGVkIHZhbHVlLiBPdGhlcndpc2UsIHRoZSB2YWx1ZSBtdXN0IGJlIHVud3JhcHBlZFxuICogd2l0aCBgXyN2YWx1ZWAuXG4gKlxuICogRXhwbGljaXQgY2hhaW4gc2VxdWVuY2VzLCB3aGljaCBtdXN0IGJlIHVud3JhcHBlZCB3aXRoIGBfI3ZhbHVlYCwgbWF5IGJlXG4gKiBlbmFibGVkIHVzaW5nIGBfLmNoYWluYC5cbiAqXG4gKiBUaGUgZXhlY3V0aW9uIG9mIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBpdCdzIGRlZmVycmVkIHVudGlsXG4gKiBgXyN2YWx1ZWAgaXMgaW1wbGljaXRseSBvciBleHBsaWNpdGx5IGNhbGxlZC5cbiAqXG4gKiBMYXp5IGV2YWx1YXRpb24gYWxsb3dzIHNldmVyYWwgbWV0aG9kcyB0byBzdXBwb3J0IHNob3J0Y3V0IGZ1c2lvbi5cbiAqIFNob3J0Y3V0IGZ1c2lvbiBpcyBhbiBvcHRpbWl6YXRpb24gdG8gbWVyZ2UgaXRlcmF0ZWUgY2FsbHM7IHRoaXMgYXZvaWRzXG4gKiB0aGUgY3JlYXRpb24gb2YgaW50ZXJtZWRpYXRlIGFycmF5cyBhbmQgY2FuIGdyZWF0bHkgcmVkdWNlIHRoZSBudW1iZXIgb2ZcbiAqIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuIFNlY3Rpb25zIG9mIGEgY2hhaW4gc2VxdWVuY2UgcXVhbGlmeSBmb3Igc2hvcnRjdXRcbiAqIGZ1c2lvbiBpZiB0aGUgc2VjdGlvbiBpcyBhcHBsaWVkIHRvIGFuIGFycmF5IGFuZCBpdGVyYXRlZXMgYWNjZXB0IG9ubHlcbiAqIG9uZSBhcmd1bWVudC4gVGhlIGhldXJpc3RpYyBmb3Igd2hldGhlciBhIHNlY3Rpb24gcXVhbGlmaWVzIGZvciBzaG9ydGN1dFxuICogZnVzaW9uIGlzIHN1YmplY3QgdG8gY2hhbmdlLlxuICpcbiAqIENoYWluaW5nIGlzIHN1cHBvcnRlZCBpbiBjdXN0b20gYnVpbGRzIGFzIGxvbmcgYXMgdGhlIGBfI3ZhbHVlYCBtZXRob2QgaXNcbiAqIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgaW5jbHVkZWQgaW4gdGhlIGJ1aWxkLlxuICpcbiAqIEluIGFkZGl0aW9uIHRvIGxvZGFzaCBtZXRob2RzLCB3cmFwcGVycyBoYXZlIGBBcnJheWAgYW5kIGBTdHJpbmdgIG1ldGhvZHMuXG4gKlxuICogVGhlIHdyYXBwZXIgYEFycmF5YCBtZXRob2RzIGFyZTpcbiAqIGBjb25jYXRgLCBgam9pbmAsIGBwb3BgLCBgcHVzaGAsIGBzaGlmdGAsIGBzb3J0YCwgYHNwbGljZWAsIGFuZCBgdW5zaGlmdGBcbiAqXG4gKiBUaGUgd3JhcHBlciBgU3RyaW5nYCBtZXRob2RzIGFyZTpcbiAqIGByZXBsYWNlYCBhbmQgYHNwbGl0YFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBzdXBwb3J0IHNob3J0Y3V0IGZ1c2lvbiBhcmU6XG4gKiBgYXRgLCBgY29tcGFjdGAsIGBkcm9wYCwgYGRyb3BSaWdodGAsIGBkcm9wV2hpbGVgLCBgZmlsdGVyYCwgYGZpbmRgLFxuICogYGZpbmRMYXN0YCwgYGhlYWRgLCBgaW5pdGlhbGAsIGBsYXN0YCwgYG1hcGAsIGByZWplY3RgLCBgcmV2ZXJzZWAsIGBzbGljZWAsXG4gKiBgdGFpbGAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBhbmQgYHRvQXJyYXlgXG4gKlxuICogVGhlIGNoYWluYWJsZSB3cmFwcGVyIG1ldGhvZHMgYXJlOlxuICogYGFmdGVyYCwgYGFyeWAsIGBhc3NpZ25gLCBgYXNzaWduSW5gLCBgYXNzaWduSW5XaXRoYCwgYGFzc2lnbldpdGhgLCBgYXRgLFxuICogYGJlZm9yZWAsIGBiaW5kYCwgYGJpbmRBbGxgLCBgYmluZEtleWAsIGBjYXN0QXJyYXlgLCBgY2hhaW5gLCBgY2h1bmtgLFxuICogYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25mb3Jtc2AsIGBjb25zdGFudGAsIGBjb3VudEJ5YCwgYGNyZWF0ZWAsXG4gKiBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCwgYGRlZmVyYCwgYGRlbGF5YCxcbiAqIGBkaWZmZXJlbmNlYCwgYGRpZmZlcmVuY2VCeWAsIGBkaWZmZXJlbmNlV2l0aGAsIGBkcm9wYCwgYGRyb3BSaWdodGAsXG4gKiBgZHJvcFJpZ2h0V2hpbGVgLCBgZHJvcFdoaWxlYCwgYGV4dGVuZGAsIGBleHRlbmRXaXRoYCwgYGZpbGxgLCBgZmlsdGVyYCxcbiAqIGBmbGF0TWFwYCwgYGZsYXRNYXBEZWVwYCwgYGZsYXRNYXBEZXB0aGAsIGBmbGF0dGVuYCwgYGZsYXR0ZW5EZWVwYCxcbiAqIGBmbGF0dGVuRGVwdGhgLCBgZmxpcGAsIGBmbG93YCwgYGZsb3dSaWdodGAsIGBmcm9tUGFpcnNgLCBgZnVuY3Rpb25zYCxcbiAqIGBmdW5jdGlvbnNJbmAsIGBncm91cEJ5YCwgYGluaXRpYWxgLCBgaW50ZXJzZWN0aW9uYCwgYGludGVyc2VjdGlvbkJ5YCxcbiAqIGBpbnRlcnNlY3Rpb25XaXRoYCwgYGludmVydGAsIGBpbnZlcnRCeWAsIGBpbnZva2VNYXBgLCBgaXRlcmF0ZWVgLCBga2V5QnlgLFxuICogYGtleXNgLCBga2V5c0luYCwgYG1hcGAsIGBtYXBLZXlzYCwgYG1hcFZhbHVlc2AsIGBtYXRjaGVzYCwgYG1hdGNoZXNQcm9wZXJ0eWAsXG4gKiBgbWVtb2l6ZWAsIGBtZXJnZWAsIGBtZXJnZVdpdGhgLCBgbWV0aG9kYCwgYG1ldGhvZE9mYCwgYG1peGluYCwgYG5lZ2F0ZWAsXG4gKiBgbnRoQXJnYCwgYG9taXRgLCBgb21pdEJ5YCwgYG9uY2VgLCBgb3JkZXJCeWAsIGBvdmVyYCwgYG92ZXJBcmdzYCxcbiAqIGBvdmVyRXZlcnlgLCBgb3ZlclNvbWVgLCBgcGFydGlhbGAsIGBwYXJ0aWFsUmlnaHRgLCBgcGFydGl0aW9uYCwgYHBpY2tgLFxuICogYHBpY2tCeWAsIGBwbGFudGAsIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLCBgcHVsbEFsbGAsIGBwdWxsQWxsQnlgLFxuICogYHB1bGxBbGxXaXRoYCwgYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJhbmdlUmlnaHRgLCBgcmVhcmdgLCBgcmVqZWN0YCxcbiAqIGByZW1vdmVgLCBgcmVzdGAsIGByZXZlcnNlYCwgYHNhbXBsZVNpemVgLCBgc2V0YCwgYHNldFdpdGhgLCBgc2h1ZmZsZWAsXG4gKiBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc3BsaWNlYCwgYHNwcmVhZGAsIGB0YWlsYCwgYHRha2VgLCBgdGFrZVJpZ2h0YCxcbiAqIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdG9BcnJheWAsXG4gKiBgdG9QYWlyc2AsIGB0b1BhaXJzSW5gLCBgdG9QYXRoYCwgYHRvUGxhaW5PYmplY3RgLCBgdHJhbnNmb3JtYCwgYHVuYXJ5YCxcbiAqIGB1bmlvbmAsIGB1bmlvbkJ5YCwgYHVuaW9uV2l0aGAsIGB1bmlxYCwgYHVuaXFCeWAsIGB1bmlxV2l0aGAsIGB1bnNldGAsXG4gKiBgdW5zaGlmdGAsIGB1bnppcGAsIGB1bnppcFdpdGhgLCBgdXBkYXRlYCwgYHVwZGF0ZVdpdGhgLCBgdmFsdWVzYCxcbiAqIGB2YWx1ZXNJbmAsIGB3aXRob3V0YCwgYHdyYXBgLCBgeG9yYCwgYHhvckJ5YCwgYHhvcldpdGhgLCBgemlwYCxcbiAqIGB6aXBPYmplY3RgLCBgemlwT2JqZWN0RGVlcGAsIGFuZCBgemlwV2l0aGBcbiAqXG4gKiBUaGUgd3JhcHBlciBtZXRob2RzIHRoYXQgYXJlICoqbm90KiogY2hhaW5hYmxlIGJ5IGRlZmF1bHQgYXJlOlxuICogYGFkZGAsIGBhdHRlbXB0YCwgYGNhbWVsQ2FzZWAsIGBjYXBpdGFsaXplYCwgYGNlaWxgLCBgY2xhbXBgLCBgY2xvbmVgLFxuICogYGNsb25lRGVlcGAsIGBjbG9uZURlZXBXaXRoYCwgYGNsb25lV2l0aGAsIGBjb25mb3Jtc1RvYCwgYGRlYnVycmAsXG4gKiBgZGVmYXVsdFRvYCwgYGRpdmlkZWAsIGBlYWNoYCwgYGVhY2hSaWdodGAsIGBlbmRzV2l0aGAsIGBlcWAsIGBlc2NhcGVgLFxuICogYGVzY2FwZVJlZ0V4cGAsIGBldmVyeWAsIGBmaW5kYCwgYGZpbmRJbmRleGAsIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCxcbiAqIGBmaW5kTGFzdEluZGV4YCwgYGZpbmRMYXN0S2V5YCwgYGZpcnN0YCwgYGZsb29yYCwgYGZvckVhY2hgLCBgZm9yRWFjaFJpZ2h0YCxcbiAqIGBmb3JJbmAsIGBmb3JJblJpZ2h0YCwgYGZvck93bmAsIGBmb3JPd25SaWdodGAsIGBnZXRgLCBgZ3RgLCBgZ3RlYCwgYGhhc2AsXG4gKiBgaGFzSW5gLCBgaGVhZGAsIGBpZGVudGl0eWAsIGBpbmNsdWRlc2AsIGBpbmRleE9mYCwgYGluUmFuZ2VgLCBgaW52b2tlYCxcbiAqIGBpc0FyZ3VtZW50c2AsIGBpc0FycmF5YCwgYGlzQXJyYXlCdWZmZXJgLCBgaXNBcnJheUxpa2VgLCBgaXNBcnJheUxpa2VPYmplY3RgLFxuICogYGlzQm9vbGVhbmAsIGBpc0J1ZmZlcmAsIGBpc0RhdGVgLCBgaXNFbGVtZW50YCwgYGlzRW1wdHlgLCBgaXNFcXVhbGAsXG4gKiBgaXNFcXVhbFdpdGhgLCBgaXNFcnJvcmAsIGBpc0Zpbml0ZWAsIGBpc0Z1bmN0aW9uYCwgYGlzSW50ZWdlcmAsIGBpc0xlbmd0aGAsXG4gKiBgaXNNYXBgLCBgaXNNYXRjaGAsIGBpc01hdGNoV2l0aGAsIGBpc05hTmAsIGBpc05hdGl2ZWAsIGBpc05pbGAsIGBpc051bGxgLFxuICogYGlzTnVtYmVyYCwgYGlzT2JqZWN0YCwgYGlzT2JqZWN0TGlrZWAsIGBpc1BsYWluT2JqZWN0YCwgYGlzUmVnRXhwYCxcbiAqIGBpc1NhZmVJbnRlZ2VyYCwgYGlzU2V0YCwgYGlzU3RyaW5nYCwgYGlzVW5kZWZpbmVkYCwgYGlzVHlwZWRBcnJheWAsXG4gKiBgaXNXZWFrTWFwYCwgYGlzV2Vha1NldGAsIGBqb2luYCwgYGtlYmFiQ2FzZWAsIGBsYXN0YCwgYGxhc3RJbmRleE9mYCxcbiAqIGBsb3dlckNhc2VgLCBgbG93ZXJGaXJzdGAsIGBsdGAsIGBsdGVgLCBgbWF4YCwgYG1heEJ5YCwgYG1lYW5gLCBgbWVhbkJ5YCxcbiAqIGBtaW5gLCBgbWluQnlgLCBgbXVsdGlwbHlgLCBgbm9Db25mbGljdGAsIGBub29wYCwgYG5vd2AsIGBudGhgLCBgcGFkYCxcbiAqIGBwYWRFbmRgLCBgcGFkU3RhcnRgLCBgcGFyc2VJbnRgLCBgcG9wYCwgYHJhbmRvbWAsIGByZWR1Y2VgLCBgcmVkdWNlUmlnaHRgLFxuICogYHJlcGVhdGAsIGByZXN1bHRgLCBgcm91bmRgLCBgcnVuSW5Db250ZXh0YCwgYHNhbXBsZWAsIGBzaGlmdGAsIGBzaXplYCxcbiAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRJbmRleEJ5YCwgYHNvcnRlZExhc3RJbmRleGAsXG4gKiBgc29ydGVkTGFzdEluZGV4QnlgLCBgc3RhcnRDYXNlYCwgYHN0YXJ0c1dpdGhgLCBgc3R1YkFycmF5YCwgYHN0dWJGYWxzZWAsXG4gKiBgc3R1Yk9iamVjdGAsIGBzdHViU3RyaW5nYCwgYHN0dWJUcnVlYCwgYHN1YnRyYWN0YCwgYHN1bWAsIGBzdW1CeWAsXG4gKiBgdGVtcGxhdGVgLCBgdGltZXNgLCBgdG9GaW5pdGVgLCBgdG9JbnRlZ2VyYCwgYHRvSlNPTmAsIGB0b0xlbmd0aGAsXG4gKiBgdG9Mb3dlcmAsIGB0b051bWJlcmAsIGB0b1NhZmVJbnRlZ2VyYCwgYHRvU3RyaW5nYCwgYHRvVXBwZXJgLCBgdHJpbWAsXG4gKiBgdHJpbUVuZGAsIGB0cmltU3RhcnRgLCBgdHJ1bmNhdGVgLCBgdW5lc2NhcGVgLCBgdW5pcXVlSWRgLCBgdXBwZXJDYXNlYCxcbiAqIGB1cHBlckZpcnN0YCwgYHZhbHVlYCwgYW5kIGB3b3Jkc2BcbiAqXG4gKiBAbmFtZSBfXG4gKiBAY29uc3RydWN0b3JcbiAqIEBjYXRlZ29yeSBTZXFcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAgaW4gYSBgbG9kYXNoYCBpbnN0YW5jZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICogICByZXR1cm4gbiAqIG47XG4gKiB9XG4gKlxuICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gKlxuICogLy8gUmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWUuXG4gKiB3cmFwcGVkLnJlZHVjZShfLmFkZCk7XG4gKiAvLyA9PiA2XG4gKlxuICogLy8gUmV0dXJucyBhIHdyYXBwZWQgdmFsdWUuXG4gKiB2YXIgc3F1YXJlcyA9IHdyYXBwZWQubWFwKHNxdWFyZSk7XG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoc3F1YXJlcy52YWx1ZSgpKTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbG9kYXNoKHZhbHVlKSB7XG4gIGlmIChpc09iamVjdExpa2UodmFsdWUpICYmICFpc0FycmF5KHZhbHVlKSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpKSB7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTG9kYXNoV3JhcHBlcikge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ19fd3JhcHBlZF9fJykpIHtcbiAgICAgIHJldHVybiB3cmFwcGVyQ2xvbmUodmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIodmFsdWUpO1xufVxuXG4vLyBFbnN1cmUgd3JhcHBlcnMgYXJlIGluc3RhbmNlcyBvZiBgYmFzZUxvZGFzaGAuXG5sb2Rhc2gucHJvdG90eXBlID0gYmFzZUxvZGFzaC5wcm90b3R5cGU7XG5sb2Rhc2gucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gbG9kYXNoO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGxvZGFzaDtcbiIsInZhciBhcnJheUZpbHRlciA9IHJlcXVpcmUoJy4vX2FycmF5RmlsdGVyJyksXG4gICAgYmFzZVJlc3QgPSByZXF1aXJlKCcuL19iYXNlUmVzdCcpLFxuICAgIGJhc2VYb3IgPSByZXF1aXJlKCcuL19iYXNlWG9yJyksXG4gICAgaXNBcnJheUxpa2VPYmplY3QgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzIHRoYXQgaXMgdGhlXG4gKiBbc3ltbWV0cmljIGRpZmZlcmVuY2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N5bW1ldHJpY19kaWZmZXJlbmNlKVxuICogb2YgdGhlIGdpdmVuIGFycmF5cy4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXJcbiAqIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDIuNC4wXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAqIEBzZWUgXy5kaWZmZXJlbmNlLCBfLndpdGhvdXRcbiAqIEBleGFtcGxlXG4gKlxuICogXy54b3IoWzIsIDFdLCBbMiwgM10pO1xuICogLy8gPT4gWzEsIDNdXG4gKi9cbnZhciB4b3IgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgcmV0dXJuIGJhc2VYb3IoYXJyYXlGaWx0ZXIoYXJyYXlzLCBpc0FycmF5TGlrZU9iamVjdCkpO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0geG9yO1xuIiwiLyoqXG4gKiBGbGF0dGVuIGFycmF5LCBvbmUgbGV2ZWwgZGVlcC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PD8+fSBhcnJcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTw/Pn1cbiAqL1xuZnVuY3Rpb24gZmxhdHRlbihhcnIpIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBwbHkoW10sIGFycik7XG59XG5cbnZhciBuYXRpdmVUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgbmF0aXZlSGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gaXNVbmRlZmluZWQob2JqKSB7XG4gIHJldHVybiBvYmogPT09IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGlzRGVmaW5lZChvYmopIHtcbiAgcmV0dXJuIG9iaiAhPT0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gaXNOaWwob2JqKSB7XG4gIHJldHVybiBvYmogPT0gbnVsbDtcbn1cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7XG4gIHJldHVybiBuYXRpdmVUb1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59XG5mdW5jdGlvbiBpc09iamVjdChvYmopIHtcbiAgcmV0dXJuIG5hdGl2ZVRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgT2JqZWN0XSc7XG59XG5mdW5jdGlvbiBpc051bWJlcihvYmopIHtcbiAgcmV0dXJuIG5hdGl2ZVRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXSc7XG59XG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iaikge1xuICB2YXIgdGFnID0gbmF0aXZlVG9TdHJpbmcuY2FsbChvYmopO1xuICByZXR1cm4gdGFnID09PSAnW29iamVjdCBGdW5jdGlvbl0nIHx8IHRhZyA9PT0gJ1tvYmplY3QgQXN5bmNGdW5jdGlvbl0nIHx8IHRhZyA9PT0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJyB8fCB0YWcgPT09ICdbb2JqZWN0IEFzeW5jR2VuZXJhdG9yRnVuY3Rpb25dJyB8fCB0YWcgPT09ICdbb2JqZWN0IFByb3h5XSc7XG59XG5mdW5jdGlvbiBpc1N0cmluZyhvYmopIHtcbiAgcmV0dXJuIG5hdGl2ZVRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG59XG4vKipcbiAqIEVuc3VyZSBjb2xsZWN0aW9uIGlzIGFuIGFycmF5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqL1xuXG5mdW5jdGlvbiBlbnN1cmVBcnJheShvYmopIHtcbiAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignbXVzdCBzdXBwbHkgYXJyYXknKTtcbn1cbi8qKlxuICogUmV0dXJuIHRydWUsIGlmIHRhcmdldCBvd25zIGEgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4ga2V5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmZ1bmN0aW9uIGhhcyh0YXJnZXQsIGtleSkge1xuICByZXR1cm4gbmF0aXZlSGFzT3duUHJvcGVydHkuY2FsbCh0YXJnZXQsIGtleSk7XG59XG5cbi8qKlxuICogRmluZCBlbGVtZW50IGluIGNvbGxlY3Rpb24uXG4gKlxuICogQHBhcmFtICB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uXG4gKiBAcGFyYW0gIHtGdW5jdGlvbnxPYmplY3R9IG1hdGNoZXJcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cblxuZnVuY3Rpb24gZmluZChjb2xsZWN0aW9uLCBtYXRjaGVyKSB7XG4gIG1hdGNoZXIgPSB0b01hdGNoZXIobWF0Y2hlcik7XG4gIHZhciBtYXRjaDtcbiAgZm9yRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICBpZiAobWF0Y2hlcih2YWwsIGtleSkpIHtcbiAgICAgIG1hdGNoID0gdmFsO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBtYXRjaDtcbn1cbi8qKlxuICogRmluZCBlbGVtZW50IGluZGV4IGluIGNvbGxlY3Rpb24uXG4gKlxuICogQHBhcmFtICB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gbWF0Y2hlclxuICpcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuXG5mdW5jdGlvbiBmaW5kSW5kZXgoY29sbGVjdGlvbiwgbWF0Y2hlcikge1xuICBtYXRjaGVyID0gdG9NYXRjaGVyKG1hdGNoZXIpO1xuICB2YXIgaWR4ID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IC0xIDogdW5kZWZpbmVkO1xuICBmb3JFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWwsIGtleSkge1xuICAgIGlmIChtYXRjaGVyKHZhbCwga2V5KSkge1xuICAgICAgaWR4ID0ga2V5O1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBpZHg7XG59XG4vKipcbiAqIEZpbmQgZWxlbWVudCBpbiBjb2xsZWN0aW9uLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fE9iamVjdH0gY29sbGVjdGlvblxuICogQHBhcmFtICB7RnVuY3Rpb259IG1hdGNoZXJcbiAqXG4gKiBAcmV0dXJuIHtBcnJheX0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gZmlsdGVyKGNvbGxlY3Rpb24sIG1hdGNoZXIpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3JFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWwsIGtleSkge1xuICAgIGlmIChtYXRjaGVyKHZhbCwga2V5KSkge1xuICAgICAgcmVzdWx0LnB1c2godmFsKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuLyoqXG4gKiBJdGVyYXRlIG92ZXIgY29sbGVjdGlvbjsgcmV0dXJuaW5nIHNvbWV0aGluZ1xuICogKG5vbi11bmRlZmluZWQpIHdpbGwgc3RvcCBpdGVyYXRpb24uXG4gKlxuICogQHBhcmFtICB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gaXRlcmF0b3JcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHJldHVybiByZXN1bHQgdGhhdCBzdG9wcGVkIHRoZSBpdGVyYXRpb25cbiAqL1xuXG5mdW5jdGlvbiBmb3JFYWNoKGNvbGxlY3Rpb24sIGl0ZXJhdG9yKSB7XG4gIHZhciB2YWwsIHJlc3VsdDtcblxuICBpZiAoaXNVbmRlZmluZWQoY29sbGVjdGlvbikpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgY29udmVydEtleSA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyB0b051bSA6IGlkZW50aXR5O1xuXG4gIGZvciAodmFyIGtleSBpbiBjb2xsZWN0aW9uKSB7XG4gICAgaWYgKGhhcyhjb2xsZWN0aW9uLCBrZXkpKSB7XG4gICAgICB2YWwgPSBjb2xsZWN0aW9uW2tleV07XG4gICAgICByZXN1bHQgPSBpdGVyYXRvcih2YWwsIGNvbnZlcnRLZXkoa2V5KSk7XG5cbiAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4vKipcbiAqIFJldHVybiBjb2xsZWN0aW9uIHdpdGhvdXQgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0gIHtBcnJheX0gYXJyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gbWF0Y2hlclxuICpcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5cbmZ1bmN0aW9uIHdpdGhvdXQoYXJyLCBtYXRjaGVyKSB7XG4gIGlmIChpc1VuZGVmaW5lZChhcnIpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgZW5zdXJlQXJyYXkoYXJyKTtcbiAgbWF0Y2hlciA9IHRvTWF0Y2hlcihtYXRjaGVyKTtcbiAgcmV0dXJuIGFyci5maWx0ZXIoZnVuY3Rpb24gKGVsLCBpZHgpIHtcbiAgICByZXR1cm4gIW1hdGNoZXIoZWwsIGlkeCk7XG4gIH0pO1xufVxuLyoqXG4gKiBSZWR1Y2UgY29sbGVjdGlvbiwgcmV0dXJuaW5nIGEgc2luZ2xlIHJlc3VsdC5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R8QXJyYXl9IGNvbGxlY3Rpb25cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBpdGVyYXRvclxuICogQHBhcmFtICB7QW55fSByZXN1bHRcbiAqXG4gKiBAcmV0dXJuIHtBbnl9IHJlc3VsdCByZXR1cm5lZCBmcm9tIGxhc3QgaXRlcmF0b3JcbiAqL1xuXG5mdW5jdGlvbiByZWR1Y2UoY29sbGVjdGlvbiwgaXRlcmF0b3IsIHJlc3VsdCkge1xuICBmb3JFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWx1ZSwgaWR4KSB7XG4gICAgcmVzdWx0ID0gaXRlcmF0b3IocmVzdWx0LCB2YWx1ZSwgaWR4KTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG4vKipcbiAqIFJldHVybiB0cnVlIGlmIGV2ZXJ5IGVsZW1lbnQgaW4gdGhlIGNvbGxlY3Rpb25cbiAqIG1hdGNoZXMgdGhlIGNyaXRlcmlhLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheX0gY29sbGVjdGlvblxuICogQHBhcmFtICB7RnVuY3Rpb259IG1hdGNoZXJcbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmZ1bmN0aW9uIGV2ZXJ5KGNvbGxlY3Rpb24sIG1hdGNoZXIpIHtcbiAgcmV0dXJuICEhcmVkdWNlKGNvbGxlY3Rpb24sIGZ1bmN0aW9uIChtYXRjaGVzLCB2YWwsIGtleSkge1xuICAgIHJldHVybiBtYXRjaGVzICYmIG1hdGNoZXIodmFsLCBrZXkpO1xuICB9LCB0cnVlKTtcbn1cbi8qKlxuICogUmV0dXJuIHRydWUgaWYgc29tZSBlbGVtZW50cyBpbiB0aGUgY29sbGVjdGlvblxuICogbWF0Y2ggdGhlIGNyaXRlcmlhLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheX0gY29sbGVjdGlvblxuICogQHBhcmFtICB7RnVuY3Rpb259IG1hdGNoZXJcbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmZ1bmN0aW9uIHNvbWUoY29sbGVjdGlvbiwgbWF0Y2hlcikge1xuICByZXR1cm4gISFmaW5kKGNvbGxlY3Rpb24sIG1hdGNoZXIpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm0gYSBjb2xsZWN0aW9uIGludG8gYW5vdGhlciBjb2xsZWN0aW9uXG4gKiBieSBwaXBpbmcgZWFjaCBtZW1iZXIgdGhyb3VnaCB0aGUgZ2l2ZW4gZm4uXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fEFycmF5fSAgIGNvbGxlY3Rpb25cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmblxuICpcbiAqIEByZXR1cm4ge0FycmF5fSB0cmFuc2Zvcm1lZCBjb2xsZWN0aW9uXG4gKi9cblxuZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGZuKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICByZXN1bHQucHVzaChmbih2YWwsIGtleSkpO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogR2V0IHRoZSBjb2xsZWN0aW9ucyBrZXlzLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheX0gY29sbGVjdGlvblxuICpcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5cbmZ1bmN0aW9uIGtleXMoY29sbGVjdGlvbikge1xuICByZXR1cm4gY29sbGVjdGlvbiAmJiBPYmplY3Qua2V5cyhjb2xsZWN0aW9uKSB8fCBbXTtcbn1cbi8qKlxuICogU2hvcnRoYW5kIGZvciBga2V5cyhvKS5sZW5ndGhgLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheX0gY29sbGVjdGlvblxuICpcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqL1xuXG5mdW5jdGlvbiBzaXplKGNvbGxlY3Rpb24pIHtcbiAgcmV0dXJuIGtleXMoY29sbGVjdGlvbikubGVuZ3RoO1xufVxuLyoqXG4gKiBHZXQgdGhlIHZhbHVlcyBpbiB0aGUgY29sbGVjdGlvbi5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R8QXJyYXl9IGNvbGxlY3Rpb25cbiAqXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuXG5mdW5jdGlvbiB2YWx1ZXMoY29sbGVjdGlvbikge1xuICByZXR1cm4gbWFwKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWwpIHtcbiAgICByZXR1cm4gdmFsO1xuICB9KTtcbn1cbi8qKlxuICogR3JvdXAgY29sbGVjdGlvbiBtZW1iZXJzIGJ5IGF0dHJpYnV0ZS5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R8QXJyYXl9IGNvbGxlY3Rpb25cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBleHRyYWN0b3JcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IG1hcCB3aXRoIHsgYXR0clZhbHVlID0+IFsgYSwgYiwgYyBdIH1cbiAqL1xuXG5mdW5jdGlvbiBncm91cEJ5KGNvbGxlY3Rpb24sIGV4dHJhY3Rvcikge1xuICB2YXIgZ3JvdXBlZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDoge307XG4gIGV4dHJhY3RvciA9IHRvRXh0cmFjdG9yKGV4dHJhY3Rvcik7XG4gIGZvckVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhciBkaXNjcmltaW5hdG9yID0gZXh0cmFjdG9yKHZhbCkgfHwgJ18nO1xuICAgIHZhciBncm91cCA9IGdyb3VwZWRbZGlzY3JpbWluYXRvcl07XG5cbiAgICBpZiAoIWdyb3VwKSB7XG4gICAgICBncm91cCA9IGdyb3VwZWRbZGlzY3JpbWluYXRvcl0gPSBbXTtcbiAgICB9XG5cbiAgICBncm91cC5wdXNoKHZhbCk7XG4gIH0pO1xuICByZXR1cm4gZ3JvdXBlZDtcbn1cbmZ1bmN0aW9uIHVuaXF1ZUJ5KGV4dHJhY3Rvcikge1xuICBleHRyYWN0b3IgPSB0b0V4dHJhY3RvcihleHRyYWN0b3IpO1xuICB2YXIgZ3JvdXBlZCA9IHt9O1xuXG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBjb2xsZWN0aW9ucyA9IG5ldyBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgY29sbGVjdGlvbnNbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgZm9yRWFjaChjb2xsZWN0aW9ucywgZnVuY3Rpb24gKGMpIHtcbiAgICByZXR1cm4gZ3JvdXBCeShjLCBleHRyYWN0b3IsIGdyb3VwZWQpO1xuICB9KTtcbiAgdmFyIHJlc3VsdCA9IG1hcChncm91cGVkLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICByZXR1cm4gdmFsWzBdO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbnZhciB1bmlvbkJ5ID0gdW5pcXVlQnk7XG4vKipcbiAqIFNvcnQgY29sbGVjdGlvbiBieSBjcml0ZXJpYS5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R8QXJyYXl9IGNvbGxlY3Rpb25cbiAqIEBwYXJhbSAge1N0cmluZ3xGdW5jdGlvbn0gZXh0cmFjdG9yXG4gKlxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cblxuZnVuY3Rpb24gc29ydEJ5KGNvbGxlY3Rpb24sIGV4dHJhY3Rvcikge1xuICBleHRyYWN0b3IgPSB0b0V4dHJhY3RvcihleHRyYWN0b3IpO1xuICB2YXIgc29ydGVkID0gW107XG4gIGZvckVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICB2YXIgZGlzYyA9IGV4dHJhY3Rvcih2YWx1ZSwga2V5KTtcbiAgICB2YXIgZW50cnkgPSB7XG4gICAgICBkOiBkaXNjLFxuICAgICAgdjogdmFsdWVcbiAgICB9O1xuXG4gICAgZm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgc29ydGVkLmxlbmd0aDsgaWR4KyspIHtcbiAgICAgIHZhciBkID0gc29ydGVkW2lkeF0uZDtcblxuICAgICAgaWYgKGRpc2MgPCBkKSB7XG4gICAgICAgIHNvcnRlZC5zcGxpY2UoaWR4LCAwLCBlbnRyeSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IC8vIG5vdCBpbnNlcnRlZCwgYXBwZW5kICghKVxuXG5cbiAgICBzb3J0ZWQucHVzaChlbnRyeSk7XG4gIH0pO1xuICByZXR1cm4gbWFwKHNvcnRlZCwgZnVuY3Rpb24gKGUpIHtcbiAgICByZXR1cm4gZS52O1xuICB9KTtcbn1cbi8qKlxuICogQ3JlYXRlIGFuIG9iamVjdCBwYXR0ZXJuIG1hdGNoZXIuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBjb25zdCBtYXRjaGVyID0gbWF0Y2hQYXR0ZXJuKHsgaWQ6IDEgfSk7XG4gKlxuICogdmFyIGVsZW1lbnQgPSBmaW5kKGVsZW1lbnRzLCBtYXRjaGVyKTtcbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IHBhdHRlcm5cbiAqXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gbWF0Y2hlckZuXG4gKi9cblxuZnVuY3Rpb24gbWF0Y2hQYXR0ZXJuKHBhdHRlcm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChlbCkge1xuICAgIHJldHVybiBldmVyeShwYXR0ZXJuLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICAgIHJldHVybiBlbFtrZXldID09PSB2YWw7XG4gICAgfSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHRvRXh0cmFjdG9yKGV4dHJhY3Rvcikge1xuICByZXR1cm4gaXNGdW5jdGlvbihleHRyYWN0b3IpID8gZXh0cmFjdG9yIDogZnVuY3Rpb24gKGUpIHtcbiAgICByZXR1cm4gZVtleHRyYWN0b3JdO1xuICB9O1xufVxuXG5mdW5jdGlvbiB0b01hdGNoZXIobWF0Y2hlcikge1xuICByZXR1cm4gaXNGdW5jdGlvbihtYXRjaGVyKSA/IG1hdGNoZXIgOiBmdW5jdGlvbiAoZSkge1xuICAgIHJldHVybiBlID09PSBtYXRjaGVyO1xuICB9O1xufVxuXG5mdW5jdGlvbiBpZGVudGl0eShhcmcpIHtcbiAgcmV0dXJuIGFyZztcbn1cblxuZnVuY3Rpb24gdG9OdW0oYXJnKSB7XG4gIHJldHVybiBOdW1iZXIoYXJnKTtcbn1cblxuLyoqXG4gKiBEZWJvdW5jZSBmbiwgY2FsbGluZyBpdCBvbmx5IG9uY2UgaWZcbiAqIHRoZSBnaXZlbiB0aW1lIGVsYXBzZWQgYmV0d2VlbiBjYWxscy5cbiAqXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm5cbiAqIEBwYXJhbSAge051bWJlcn0gdGltZW91dFxuICpcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBkZWJvdW5jZWQgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gZGVib3VuY2UoZm4sIHRpbWVvdXQpIHtcbiAgdmFyIHRpbWVyO1xuICB2YXIgbGFzdEFyZ3M7XG4gIHZhciBsYXN0VGhpcztcbiAgdmFyIGxhc3ROb3c7XG5cbiAgZnVuY3Rpb24gZmlyZSgpIHtcbiAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcbiAgICB2YXIgc2NoZWR1bGVkRGlmZiA9IGxhc3ROb3cgKyB0aW1lb3V0IC0gbm93O1xuXG4gICAgaWYgKHNjaGVkdWxlZERpZmYgPiAwKSB7XG4gICAgICByZXR1cm4gc2NoZWR1bGUoc2NoZWR1bGVkRGlmZik7XG4gICAgfVxuXG4gICAgZm4uYXBwbHkobGFzdFRoaXMsIGxhc3RBcmdzKTtcbiAgICB0aW1lciA9IGxhc3ROb3cgPSBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NoZWR1bGUodGltZW91dCkge1xuICAgIHRpbWVyID0gc2V0VGltZW91dChmaXJlLCB0aW1lb3V0KTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgbGFzdE5vdyA9IERhdGUubm93KCk7XG5cbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgfVxuXG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGxhc3RUaGlzID0gdGhpczsgLy8gZW5zdXJlIGFuIGV4ZWN1dGlvbiBpcyBzY2hlZHVsZWRcblxuICAgIGlmICghdGltZXIpIHtcbiAgICAgIHNjaGVkdWxlKHRpbWVvdXQpO1xuICAgIH1cbiAgfTtcbn1cbi8qKlxuICogVGhyb3R0bGUgZm4sIGNhbGxpbmcgYXQgbW9zdCBvbmNlXG4gKiBpbiB0aGUgZ2l2ZW4gaW50ZXJ2YWwuXG4gKlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGludGVydmFsXG4gKlxuICogQHJldHVybiB7RnVuY3Rpb259IHRocm90dGxlZCBmdW5jdGlvblxuICovXG5cbmZ1bmN0aW9uIHRocm90dGxlKGZuLCBpbnRlcnZhbCkge1xuICB2YXIgdGhyb3R0bGluZyA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aHJvdHRsaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm4uYXBwbHkodm9pZCAwLCBhcmd1bWVudHMpO1xuICAgIHRocm90dGxpbmcgPSB0cnVlO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3R0bGluZyA9IGZhbHNlO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbn1cbi8qKlxuICogQmluZCBmdW5jdGlvbiBhZ2FpbnN0IHRhcmdldCA8dGhpcz4uXG4gKlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgdGFyZ2V0XG4gKlxuICogQHJldHVybiB7RnVuY3Rpb259IGJvdW5kIGZ1bmN0aW9uXG4gKi9cblxuZnVuY3Rpb24gYmluZChmbiwgdGFyZ2V0KSB7XG4gIHJldHVybiBmbi5iaW5kKHRhcmdldCk7XG59XG5cbmZ1bmN0aW9uIF9leHRlbmRzKCkge1xuICBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkge1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0YXJnZXQ7XG4gIH07XG5cbiAgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbi8qKlxuICogQ29udmVuaWVuY2Ugd3JhcHBlciBmb3IgYE9iamVjdC5hc3NpZ25gLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7Li4uT2JqZWN0fSBvdGhlcnNcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSB0YXJnZXRcbiAqL1xuXG5mdW5jdGlvbiBhc3NpZ24odGFyZ2V0KSB7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBvdGhlcnMgPSBuZXcgQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgIG90aGVyc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gIH1cblxuICByZXR1cm4gX2V4dGVuZHMuYXBwbHkodm9pZCAwLCBbdGFyZ2V0XS5jb25jYXQob3RoZXJzKSk7XG59XG4vKipcbiAqIFBpY2sgZ2l2ZW4gcHJvcGVydGllcyBmcm9tIHRoZSB0YXJnZXQgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BlcnRpZXNcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRhcmdldFxuICovXG5cbmZ1bmN0aW9uIHBpY2sodGFyZ2V0LCBwcm9wZXJ0aWVzKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcbiAgdmFyIG9iaiA9IE9iamVjdCh0YXJnZXQpO1xuICBmb3JFYWNoKHByb3BlcnRpZXMsIGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgaWYgKHByb3AgaW4gb2JqKSB7XG4gICAgICByZXN1bHRbcHJvcF0gPSB0YXJnZXRbcHJvcF07XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogUGljayBhbGwgdGFyZ2V0IHByb3BlcnRpZXMsIGV4Y2x1ZGluZyB0aGUgZ2l2ZW4gb25lcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wZXJ0aWVzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB0YXJnZXRcbiAqL1xuXG5mdW5jdGlvbiBvbWl0KHRhcmdldCwgcHJvcGVydGllcykge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIHZhciBvYmogPSBPYmplY3QodGFyZ2V0KTtcbiAgZm9yRWFjaChvYmosIGZ1bmN0aW9uIChwcm9wLCBrZXkpIHtcbiAgICBpZiAocHJvcGVydGllcy5pbmRleE9mKGtleSkgPT09IC0xKSB7XG4gICAgICByZXN1bHRba2V5XSA9IHByb3A7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogUmVjdXJzaXZlbHkgbWVyZ2UgYC4uLnNvdXJjZXNgIGludG8gZ2l2ZW4gdGFyZ2V0LlxuICpcbiAqIERvZXMgc3VwcG9ydCBtZXJnaW5nIG9iamVjdHM7IGRvZXMgbm90IHN1cHBvcnQgbWVyZ2luZyBhcnJheXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRhcmdldFxuICogQHBhcmFtIHsuLi5PYmplY3R9IHNvdXJjZXNcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSB0YXJnZXRcbiAqL1xuXG5mdW5jdGlvbiBtZXJnZSh0YXJnZXQpIHtcbiAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBzb3VyY2VzID0gbmV3IEFycmF5KF9sZW4yID4gMSA/IF9sZW4yIC0gMSA6IDApLCBfa2V5MiA9IDE7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcbiAgICBzb3VyY2VzW19rZXkyIC0gMV0gPSBhcmd1bWVudHNbX2tleTJdO1xuICB9XG5cbiAgaWYgKCFzb3VyY2VzLmxlbmd0aCkge1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cblxuICBmb3JFYWNoKHNvdXJjZXMsIGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICAvLyBza2lwIG5vbi1vYmogc291cmNlcywgaS5lLiBudWxsXG4gICAgaWYgKCFzb3VyY2UgfHwgIWlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmb3JFYWNoKHNvdXJjZSwgZnVuY3Rpb24gKHNvdXJjZVZhbCwga2V5KSB7XG4gICAgICBpZiAoa2V5ID09PSAnX19wcm90b19fJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciB0YXJnZXRWYWwgPSB0YXJnZXRba2V5XTtcblxuICAgICAgaWYgKGlzT2JqZWN0KHNvdXJjZVZhbCkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdCh0YXJnZXRWYWwpKSB7XG4gICAgICAgICAgLy8gb3ZlcnJpZGUgdGFyZ2V0W2tleV0gd2l0aCBvYmplY3RcbiAgICAgICAgICB0YXJnZXRWYWwgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRhcmdldFtrZXldID0gbWVyZ2UodGFyZ2V0VmFsLCBzb3VyY2VWYWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2VWYWw7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5leHBvcnQgeyBmbGF0dGVuLCBmaW5kLCBmaW5kSW5kZXgsIGZpbHRlciwgZm9yRWFjaCwgd2l0aG91dCwgcmVkdWNlLCBldmVyeSwgc29tZSwgbWFwLCBrZXlzLCBzaXplLCB2YWx1ZXMsIGdyb3VwQnksIHVuaXF1ZUJ5LCB1bmlvbkJ5LCBzb3J0QnksIG1hdGNoUGF0dGVybiwgZGVib3VuY2UsIHRocm90dGxlLCBiaW5kLCBpc1VuZGVmaW5lZCwgaXNEZWZpbmVkLCBpc05pbCwgaXNBcnJheSwgaXNPYmplY3QsIGlzTnVtYmVyLCBpc0Z1bmN0aW9uLCBpc1N0cmluZywgZW5zdXJlQXJyYXksIGhhcywgYXNzaWduLCBwaWNrLCBvbWl0LCBtZXJnZSB9O1xuIiwiLyoqXG4gKiBTZXQgYXR0cmlidXRlIGBuYW1lYCB0byBgdmFsYCwgb3IgZ2V0IGF0dHIgYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0ge1N0cmluZ30gW3ZhbF1cbiAqIEBhcGkgcHVibGljXG4gKi9cbmZ1bmN0aW9uIGF0dHIoZWwsIG5hbWUsIHZhbCkge1xuICAvLyBnZXRcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMikge1xuICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUobmFtZSk7XG4gIH1cblxuICAvLyByZW1vdmVcbiAgaWYgKHZhbCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBlbC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gIH1cblxuICAvLyBzZXRcbiAgZWwuc2V0QXR0cmlidXRlKG5hbWUsIHZhbCk7XG5cbiAgcmV0dXJuIGVsO1xufVxuXG52YXIgaW5kZXhPZiA9IFtdLmluZGV4T2Y7XG5cbnZhciBpbmRleG9mID0gZnVuY3Rpb24oYXJyLCBvYmope1xuICBpZiAoaW5kZXhPZikgcmV0dXJuIGFyci5pbmRleE9mKG9iaik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGFycltpXSA9PT0gb2JqKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59O1xuXG4vKipcbiAqIFRha2VuIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvbmVudC9jbGFzc2VzXG4gKlxuICogV2l0aG91dCB0aGUgY29tcG9uZW50IGJpdHMuXG4gKi9cblxuLyoqXG4gKiBXaGl0ZXNwYWNlIHJlZ2V4cC5cbiAqL1xuXG52YXIgcmUgPSAvXFxzKy87XG5cbi8qKlxuICogdG9TdHJpbmcgcmVmZXJlbmNlLlxuICovXG5cbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogV3JhcCBgZWxgIGluIGEgYENsYXNzTGlzdGAuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBjbGFzc2VzKGVsKSB7XG4gIHJldHVybiBuZXcgQ2xhc3NMaXN0KGVsKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IENsYXNzTGlzdCBmb3IgYGVsYC5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBDbGFzc0xpc3QoZWwpIHtcbiAgaWYgKCFlbCB8fCAhZWwubm9kZVR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgRE9NIGVsZW1lbnQgcmVmZXJlbmNlIGlzIHJlcXVpcmVkJyk7XG4gIH1cbiAgdGhpcy5lbCA9IGVsO1xuICB0aGlzLmxpc3QgPSBlbC5jbGFzc0xpc3Q7XG59XG5cbi8qKlxuICogQWRkIGNsYXNzIGBuYW1lYCBpZiBub3QgYWxyZWFkeSBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtDbGFzc0xpc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkNsYXNzTGlzdC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgLy8gY2xhc3NMaXN0XG4gIGlmICh0aGlzLmxpc3QpIHtcbiAgICB0aGlzLmxpc3QuYWRkKG5hbWUpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZmFsbGJhY2tcbiAgdmFyIGFyciA9IHRoaXMuYXJyYXkoKTtcbiAgdmFyIGkgPSBpbmRleG9mKGFyciwgbmFtZSk7XG4gIGlmICghfmkpIGFyci5wdXNoKG5hbWUpO1xuICB0aGlzLmVsLmNsYXNzTmFtZSA9IGFyci5qb2luKCcgJyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgY2xhc3MgYG5hbWVgIHdoZW4gcHJlc2VudCwgb3JcbiAqIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gcmVtb3ZlXG4gKiBhbnkgd2hpY2ggbWF0Y2guXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBuYW1lXG4gKiBAcmV0dXJuIHtDbGFzc0xpc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkNsYXNzTGlzdC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKCdbb2JqZWN0IFJlZ0V4cF0nID09IHRvU3RyaW5nLmNhbGwobmFtZSkpIHtcbiAgICByZXR1cm4gdGhpcy5yZW1vdmVNYXRjaGluZyhuYW1lKTtcbiAgfVxuXG4gIC8vIGNsYXNzTGlzdFxuICBpZiAodGhpcy5saXN0KSB7XG4gICAgdGhpcy5saXN0LnJlbW92ZShuYW1lKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGZhbGxiYWNrXG4gIHZhciBhcnIgPSB0aGlzLmFycmF5KCk7XG4gIHZhciBpID0gaW5kZXhvZihhcnIsIG5hbWUpO1xuICBpZiAofmkpIGFyci5zcGxpY2UoaSwgMSk7XG4gIHRoaXMuZWwuY2xhc3NOYW1lID0gYXJyLmpvaW4oJyAnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBhbGwgY2xhc3NlcyBtYXRjaGluZyBgcmVgLlxuICpcbiAqIEBwYXJhbSB7UmVnRXhwfSByZVxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuQ2xhc3NMaXN0LnByb3RvdHlwZS5yZW1vdmVNYXRjaGluZyA9IGZ1bmN0aW9uIChyZSkge1xuICB2YXIgYXJyID0gdGhpcy5hcnJheSgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChyZS50ZXN0KGFycltpXSkpIHtcbiAgICAgIHRoaXMucmVtb3ZlKGFycltpXSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBUb2dnbGUgY2xhc3MgYG5hbWVgLCBjYW4gZm9yY2Ugc3RhdGUgdmlhIGBmb3JjZWAuXG4gKlxuICogRm9yIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBjbGFzc0xpc3QsIGJ1dCBkbyBub3Qgc3VwcG9ydCBgZm9yY2VgIHlldCxcbiAqIHRoZSBtaXN0YWtlIHdpbGwgYmUgZGV0ZWN0ZWQgYW5kIGNvcnJlY3RlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtCb29sZWFufSBmb3JjZVxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5DbGFzc0xpc3QucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uIChuYW1lLCBmb3JjZSkge1xuICAvLyBjbGFzc0xpc3RcbiAgaWYgKHRoaXMubGlzdCkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGZvcmNlKSB7XG4gICAgICBpZiAoZm9yY2UgIT09IHRoaXMubGlzdC50b2dnbGUobmFtZSwgZm9yY2UpKSB7XG4gICAgICAgIHRoaXMubGlzdC50b2dnbGUobmFtZSk7IC8vIHRvZ2dsZSBhZ2FpbiB0byBjb3JyZWN0XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGlzdC50b2dnbGUobmFtZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZmFsbGJhY2tcbiAgaWYgKCd1bmRlZmluZWQnICE9PSB0eXBlb2YgZm9yY2UpIHtcbiAgICBpZiAoIWZvcmNlKSB7XG4gICAgICB0aGlzLnJlbW92ZShuYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGQobmFtZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0aGlzLmhhcyhuYW1lKSkge1xuICAgICAgdGhpcy5yZW1vdmUobmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWRkKG5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYW4gYXJyYXkgb2YgY2xhc3Nlcy5cbiAqXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuQ2xhc3NMaXN0LnByb3RvdHlwZS5hcnJheSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpIHx8ICcnO1xuICB2YXIgc3RyID0gY2xhc3NOYW1lLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbiAgdmFyIGFyciA9IHN0ci5zcGxpdChyZSk7XG4gIGlmICgnJyA9PT0gYXJyWzBdKSBhcnIuc2hpZnQoKTtcbiAgcmV0dXJuIGFycjtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgY2xhc3MgYG5hbWVgIGlzIHByZXNlbnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm4ge0NsYXNzTGlzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuQ2xhc3NMaXN0LnByb3RvdHlwZS5oYXMgPSBDbGFzc0xpc3QucHJvdG90eXBlLmNvbnRhaW5zID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIHRoaXMubGlzdCA/IHRoaXMubGlzdC5jb250YWlucyhuYW1lKSA6ICEhfmluZGV4b2YodGhpcy5hcnJheSgpLCBuYW1lKTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFsbCBjaGlsZHJlbiBmcm9tIHRoZSBnaXZlbiBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBjbGVhcihlbCkge1xuXG4gIHZhciBjO1xuXG4gIHdoaWxlIChlbC5jaGlsZE5vZGVzLmxlbmd0aCkge1xuICAgIGMgPSBlbC5jaGlsZE5vZGVzWzBdO1xuICAgIGVsLnJlbW92ZUNoaWxkKGMpO1xuICB9XG5cbiAgcmV0dXJuIGVsO1xufVxuXG52YXIgcHJvdG8gPSB0eXBlb2YgRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcgPyBFbGVtZW50LnByb3RvdHlwZSA6IHt9O1xudmFyIHZlbmRvciA9IHByb3RvLm1hdGNoZXNcbiAgfHwgcHJvdG8ubWF0Y2hlc1NlbGVjdG9yXG4gIHx8IHByb3RvLndlYmtpdE1hdGNoZXNTZWxlY3RvclxuICB8fCBwcm90by5tb3pNYXRjaGVzU2VsZWN0b3JcbiAgfHwgcHJvdG8ubXNNYXRjaGVzU2VsZWN0b3JcbiAgfHwgcHJvdG8ub01hdGNoZXNTZWxlY3RvcjtcblxudmFyIG1hdGNoZXNTZWxlY3RvciA9IG1hdGNoO1xuXG4vKipcbiAqIE1hdGNoIGBlbGAgdG8gYHNlbGVjdG9yYC5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIG1hdGNoKGVsLCBzZWxlY3Rvcikge1xuICBpZiAoIWVsIHx8IGVsLm5vZGVUeXBlICE9PSAxKSByZXR1cm4gZmFsc2U7XG4gIGlmICh2ZW5kb3IpIHJldHVybiB2ZW5kb3IuY2FsbChlbCwgc2VsZWN0b3IpO1xuICB2YXIgbm9kZXMgPSBlbC5wYXJlbnROb2RlLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKG5vZGVzW2ldID09IGVsKSByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2xvc2VzdFxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxlY3RvclxuICogQHBhcmFtIHtCb29sZWFufSBjaGVja1lvdXJTZWxmIChvcHRpb25hbClcbiAqL1xuZnVuY3Rpb24gY2xvc2VzdCAoZWxlbWVudCwgc2VsZWN0b3IsIGNoZWNrWW91clNlbGYpIHtcbiAgdmFyIGN1cnJlbnRFbGVtID0gY2hlY2tZb3VyU2VsZiA/IGVsZW1lbnQgOiBlbGVtZW50LnBhcmVudE5vZGU7XG5cbiAgd2hpbGUgKGN1cnJlbnRFbGVtICYmIGN1cnJlbnRFbGVtLm5vZGVUeXBlICE9PSBkb2N1bWVudC5ET0NVTUVOVF9OT0RFICYmIGN1cnJlbnRFbGVtLm5vZGVUeXBlICE9PSBkb2N1bWVudC5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFKSB7XG5cbiAgICBpZiAobWF0Y2hlc1NlbGVjdG9yKGN1cnJlbnRFbGVtLCBzZWxlY3RvcikpIHtcbiAgICAgIHJldHVybiBjdXJyZW50RWxlbTtcbiAgICB9XG5cbiAgICBjdXJyZW50RWxlbSA9IGN1cnJlbnRFbGVtLnBhcmVudE5vZGU7XG4gIH1cblxuICByZXR1cm4gbWF0Y2hlc1NlbGVjdG9yKGN1cnJlbnRFbGVtLCBzZWxlY3RvcikgPyBjdXJyZW50RWxlbSA6IG51bGw7XG59XG5cbnZhciBiaW5kID0gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIgPyAnYWRkRXZlbnRMaXN0ZW5lcicgOiAnYXR0YWNoRXZlbnQnLFxuICAgIHVuYmluZCA9IHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyID8gJ3JlbW92ZUV2ZW50TGlzdGVuZXInIDogJ2RldGFjaEV2ZW50JyxcbiAgICBwcmVmaXggPSBiaW5kICE9PSAnYWRkRXZlbnRMaXN0ZW5lcicgPyAnb24nIDogJyc7XG5cbi8qKlxuICogQmluZCBgZWxgIGV2ZW50IGB0eXBlYCB0byBgZm5gLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtCb29sZWFufSBjYXB0dXJlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxudmFyIGJpbmRfMSA9IGZ1bmN0aW9uKGVsLCB0eXBlLCBmbiwgY2FwdHVyZSl7XG4gIGVsW2JpbmRdKHByZWZpeCArIHR5cGUsIGZuLCBjYXB0dXJlIHx8IGZhbHNlKTtcbiAgcmV0dXJuIGZuO1xufTtcblxuLyoqXG4gKiBVbmJpbmQgYGVsYCBldmVudCBgdHlwZWAncyBjYWxsYmFjayBgZm5gLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtCb29sZWFufSBjYXB0dXJlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxudmFyIHVuYmluZF8xID0gZnVuY3Rpb24oZWwsIHR5cGUsIGZuLCBjYXB0dXJlKXtcbiAgZWxbdW5iaW5kXShwcmVmaXggKyB0eXBlLCBmbiwgY2FwdHVyZSB8fCBmYWxzZSk7XG4gIHJldHVybiBmbjtcbn07XG5cbnZhciBjb21wb25lbnRFdmVudCA9IHtcblx0YmluZDogYmluZF8xLFxuXHR1bmJpbmQ6IHVuYmluZF8xXG59O1xuXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxuLyoqXG4gKiBEZWxlZ2F0ZSBldmVudCBgdHlwZWAgdG8gYHNlbGVjdG9yYFxuICogYW5kIGludm9rZSBgZm4oZSlgLiBBIGNhbGxiYWNrIGZ1bmN0aW9uXG4gKiBpcyByZXR1cm5lZCB3aGljaCBtYXkgYmUgcGFzc2VkIHRvIGAudW5iaW5kKClgLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxlY3RvclxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGNhcHR1cmVcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG4vLyBTb21lIGV2ZW50cyBkb24ndCBidWJibGUsIHNvIHdlIHdhbnQgdG8gYmluZCB0byB0aGUgY2FwdHVyZSBwaGFzZSBpbnN0ZWFkXG4vLyB3aGVuIGRlbGVnYXRpbmcuXG52YXIgZm9yY2VDYXB0dXJlRXZlbnRzID0gWydmb2N1cycsICdibHVyJ107XG5cbmZ1bmN0aW9uIGJpbmQkMShlbCwgc2VsZWN0b3IsIHR5cGUsIGZuLCBjYXB0dXJlKSB7XG4gIGlmIChmb3JjZUNhcHR1cmVFdmVudHMuaW5kZXhPZih0eXBlKSAhPT0gLTEpIHtcbiAgICBjYXB0dXJlID0gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBjb21wb25lbnRFdmVudC5iaW5kKGVsLCB0eXBlLCBmdW5jdGlvbiAoZSkge1xuICAgIHZhciB0YXJnZXQgPSBlLnRhcmdldCB8fCBlLnNyY0VsZW1lbnQ7XG4gICAgZS5kZWxlZ2F0ZVRhcmdldCA9IGNsb3Nlc3QodGFyZ2V0LCBzZWxlY3RvciwgdHJ1ZSwgZWwpO1xuICAgIGlmIChlLmRlbGVnYXRlVGFyZ2V0KSB7XG4gICAgICBmbi5jYWxsKGVsLCBlKTtcbiAgICB9XG4gIH0sIGNhcHR1cmUpO1xufVxuXG4vKipcbiAqIFVuYmluZCBldmVudCBgdHlwZWAncyBjYWxsYmFjayBgZm5gLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtCb29sZWFufSBjYXB0dXJlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiB1bmJpbmQkMShlbCwgdHlwZSwgZm4sIGNhcHR1cmUpIHtcbiAgaWYgKGZvcmNlQ2FwdHVyZUV2ZW50cy5pbmRleE9mKHR5cGUpICE9PSAtMSkge1xuICAgIGNhcHR1cmUgPSB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGNvbXBvbmVudEV2ZW50LnVuYmluZChlbCwgdHlwZSwgZm4sIGNhcHR1cmUpO1xufVxuXG52YXIgZGVsZWdhdGUgPSB7XG4gIGJpbmQ6IGJpbmQkMSxcbiAgdW5iaW5kOiB1bmJpbmQkMVxufTtcblxuLyoqXG4gKiBFeHBvc2UgYHBhcnNlYC5cbiAqL1xuXG52YXIgZG9taWZ5ID0gcGFyc2U7XG5cbi8qKlxuICogVGVzdHMgZm9yIGJyb3dzZXIgc3VwcG9ydC5cbiAqL1xuXG52YXIgaW5uZXJIVE1MQnVnID0gZmFsc2U7XG52YXIgYnVnVGVzdERpdjtcbmlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gIGJ1Z1Rlc3REaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgLy8gU2V0dXBcbiAgYnVnVGVzdERpdi5pbm5lckhUTUwgPSAnICA8bGluay8+PHRhYmxlPjwvdGFibGU+PGEgaHJlZj1cIi9hXCI+YTwvYT48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIvPic7XG4gIC8vIE1ha2Ugc3VyZSB0aGF0IGxpbmsgZWxlbWVudHMgZ2V0IHNlcmlhbGl6ZWQgY29ycmVjdGx5IGJ5IGlubmVySFRNTFxuICAvLyBUaGlzIHJlcXVpcmVzIGEgd3JhcHBlciBlbGVtZW50IGluIElFXG4gIGlubmVySFRNTEJ1ZyA9ICFidWdUZXN0RGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdsaW5rJykubGVuZ3RoO1xuICBidWdUZXN0RGl2ID0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFdyYXAgbWFwIGZyb20ganF1ZXJ5LlxuICovXG5cbnZhciBtYXAgPSB7XG4gIGxlZ2VuZDogWzEsICc8ZmllbGRzZXQ+JywgJzwvZmllbGRzZXQ+J10sXG4gIHRyOiBbMiwgJzx0YWJsZT48dGJvZHk+JywgJzwvdGJvZHk+PC90YWJsZT4nXSxcbiAgY29sOiBbMiwgJzx0YWJsZT48dGJvZHk+PC90Ym9keT48Y29sZ3JvdXA+JywgJzwvY29sZ3JvdXA+PC90YWJsZT4nXSxcbiAgLy8gZm9yIHNjcmlwdC9saW5rL3N0eWxlIHRhZ3MgdG8gd29yayBpbiBJRTYtOCwgeW91IGhhdmUgdG8gd3JhcFxuICAvLyBpbiBhIGRpdiB3aXRoIGEgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyIGluIGZyb250LCBoYSFcbiAgX2RlZmF1bHQ6IGlubmVySFRNTEJ1ZyA/IFsxLCAnWDxkaXY+JywgJzwvZGl2PiddIDogWzAsICcnLCAnJ11cbn07XG5cbm1hcC50ZCA9XG5tYXAudGggPSBbMywgJzx0YWJsZT48dGJvZHk+PHRyPicsICc8L3RyPjwvdGJvZHk+PC90YWJsZT4nXTtcblxubWFwLm9wdGlvbiA9XG5tYXAub3B0Z3JvdXAgPSBbMSwgJzxzZWxlY3QgbXVsdGlwbGU9XCJtdWx0aXBsZVwiPicsICc8L3NlbGVjdD4nXTtcblxubWFwLnRoZWFkID1cbm1hcC50Ym9keSA9XG5tYXAuY29sZ3JvdXAgPVxubWFwLmNhcHRpb24gPVxubWFwLnRmb290ID0gWzEsICc8dGFibGU+JywgJzwvdGFibGU+J107XG5cbm1hcC5wb2x5bGluZSA9XG5tYXAuZWxsaXBzZSA9XG5tYXAucG9seWdvbiA9XG5tYXAuY2lyY2xlID1cbm1hcC50ZXh0ID1cbm1hcC5saW5lID1cbm1hcC5wYXRoID1cbm1hcC5yZWN0ID1cbm1hcC5nID0gWzEsICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2ZXJzaW9uPVwiMS4xXCI+JywnPC9zdmc+J107XG5cbi8qKlxuICogUGFyc2UgYGh0bWxgIGFuZCByZXR1cm4gYSBET00gTm9kZSBpbnN0YW5jZSwgd2hpY2ggY291bGQgYmUgYSBUZXh0Tm9kZSxcbiAqIEhUTUwgRE9NIE5vZGUgb2Ygc29tZSBraW5kICg8ZGl2PiBmb3IgZXhhbXBsZSksIG9yIGEgRG9jdW1lbnRGcmFnbWVudFxuICogaW5zdGFuY2UsIGRlcGVuZGluZyBvbiB0aGUgY29udGVudHMgb2YgdGhlIGBodG1sYCBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGh0bWwgLSBIVE1MIHN0cmluZyB0byBcImRvbWlmeVwiXG4gKiBAcGFyYW0ge0RvY3VtZW50fSBkb2MgLSBUaGUgYGRvY3VtZW50YCBpbnN0YW5jZSB0byBjcmVhdGUgdGhlIE5vZGUgZm9yXG4gKiBAcmV0dXJuIHtET01Ob2RlfSB0aGUgVGV4dE5vZGUsIERPTSBOb2RlLCBvciBEb2N1bWVudEZyYWdtZW50IGluc3RhbmNlXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJzZShodG1sLCBkb2MpIHtcbiAgaWYgKCdzdHJpbmcnICE9IHR5cGVvZiBodG1sKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdHJpbmcgZXhwZWN0ZWQnKTtcblxuICAvLyBkZWZhdWx0IHRvIHRoZSBnbG9iYWwgYGRvY3VtZW50YCBvYmplY3RcbiAgaWYgKCFkb2MpIGRvYyA9IGRvY3VtZW50O1xuXG4gIC8vIHRhZyBuYW1lXG4gIHZhciBtID0gLzwoW1xcdzpdKykvLmV4ZWMoaHRtbCk7XG4gIGlmICghbSkgcmV0dXJuIGRvYy5jcmVhdGVUZXh0Tm9kZShodG1sKTtcblxuICBodG1sID0gaHRtbC5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJyk7IC8vIFJlbW92ZSBsZWFkaW5nL3RyYWlsaW5nIHdoaXRlc3BhY2VcblxuICB2YXIgdGFnID0gbVsxXTtcblxuICAvLyBib2R5IHN1cHBvcnRcbiAgaWYgKHRhZyA9PSAnYm9keScpIHtcbiAgICB2YXIgZWwgPSBkb2MuY3JlYXRlRWxlbWVudCgnaHRtbCcpO1xuICAgIGVsLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIGVsLnJlbW92ZUNoaWxkKGVsLmxhc3RDaGlsZCk7XG4gIH1cblxuICAvLyB3cmFwIG1hcFxuICB2YXIgd3JhcCA9IG1hcFt0YWddIHx8IG1hcC5fZGVmYXVsdDtcbiAgdmFyIGRlcHRoID0gd3JhcFswXTtcbiAgdmFyIHByZWZpeCA9IHdyYXBbMV07XG4gIHZhciBzdWZmaXggPSB3cmFwWzJdO1xuICB2YXIgZWwgPSBkb2MuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIGVsLmlubmVySFRNTCA9IHByZWZpeCArIGh0bWwgKyBzdWZmaXg7XG4gIHdoaWxlIChkZXB0aC0tKSBlbCA9IGVsLmxhc3RDaGlsZDtcblxuICAvLyBvbmUgZWxlbWVudFxuICBpZiAoZWwuZmlyc3RDaGlsZCA9PSBlbC5sYXN0Q2hpbGQpIHtcbiAgICByZXR1cm4gZWwucmVtb3ZlQ2hpbGQoZWwuZmlyc3RDaGlsZCk7XG4gIH1cblxuICAvLyBzZXZlcmFsIGVsZW1lbnRzXG4gIHZhciBmcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gIHdoaWxlIChlbC5maXJzdENoaWxkKSB7XG4gICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoZWwucmVtb3ZlQ2hpbGQoZWwuZmlyc3RDaGlsZCkpO1xuICB9XG5cbiAgcmV0dXJuIGZyYWdtZW50O1xufVxuXG5mdW5jdGlvbiBxdWVyeShzZWxlY3RvciwgZWwpIHtcbiAgZWwgPSBlbCB8fCBkb2N1bWVudDtcblxuICByZXR1cm4gZWwucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG59XG5cbmZ1bmN0aW9uIGFsbChzZWxlY3RvciwgZWwpIHtcbiAgZWwgPSBlbCB8fCBkb2N1bWVudDtcblxuICByZXR1cm4gZWwucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShlbCkge1xuICBlbC5wYXJlbnROb2RlICYmIGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWwpO1xufVxuXG5leHBvcnQgeyBhdHRyLCBjbGFzc2VzLCBjbGVhciwgY2xvc2VzdCwgZGVsZWdhdGUsIGRvbWlmeSwgY29tcG9uZW50RXZlbnQgYXMgZXZlbnQsIG1hdGNoZXNTZWxlY3RvciBhcyBtYXRjaGVzLCBxdWVyeSwgYWxsIGFzIHF1ZXJ5QWxsLCByZW1vdmUgfTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG4vLyAgICAgIFxuLy8gQW4gZXZlbnQgaGFuZGxlciBjYW4gdGFrZSBhbiBvcHRpb25hbCBldmVudCBhcmd1bWVudFxuLy8gYW5kIHNob3VsZCBub3QgcmV0dXJuIGEgdmFsdWVcbi8vIEFuIGFycmF5IG9mIGFsbCBjdXJyZW50bHkgcmVnaXN0ZXJlZCBldmVudCBoYW5kbGVycyBmb3IgYSB0eXBlXG4vLyBBIG1hcCBvZiBldmVudCB0eXBlcyBhbmQgdGhlaXIgY29ycmVzcG9uZGluZyBldmVudCBoYW5kbGVycy5cblxuLyoqIE1pdHQ6IFRpbnkgKH4yMDBiKSBmdW5jdGlvbmFsIGV2ZW50IGVtaXR0ZXIgLyBwdWJzdWIuXG4gKiAgQG5hbWUgbWl0dFxuICogIEByZXR1cm5zIHtNaXR0fVxuICovXG5mdW5jdGlvbiBtaXR0KGFsbCkge1xuICBhbGwgPSBhbGwgfHwgT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgcmV0dXJuIHtcbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhbiBldmVudCBoYW5kbGVyIGZvciB0aGUgZ2l2ZW4gdHlwZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gdHlwZVx0VHlwZSBvZiBldmVudCB0byBsaXN0ZW4gZm9yLCBvciBgXCIqXCJgIGZvciBhbGwgZXZlbnRzXG4gICAgICogQHBhcmFtICB7RnVuY3Rpb259IGhhbmRsZXIgRnVuY3Rpb24gdG8gY2FsbCBpbiByZXNwb25zZSB0byBnaXZlbiBldmVudFxuICAgICAqIEBtZW1iZXJPZiBtaXR0XG4gICAgICovXG4gICAgb246IGZ1bmN0aW9uIG9uKHR5cGUsIGhhbmRsZXIpIHtcbiAgICAgIChhbGxbdHlwZV0gfHwgKGFsbFt0eXBlXSA9IFtdKSkucHVzaChoYW5kbGVyKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGFuIGV2ZW50IGhhbmRsZXIgZm9yIHRoZSBnaXZlbiB0eXBlLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSB0eXBlXHRUeXBlIG9mIGV2ZW50IHRvIHVucmVnaXN0ZXIgYGhhbmRsZXJgIGZyb20sIG9yIGBcIipcImBcbiAgICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gaGFuZGxlciBIYW5kbGVyIGZ1bmN0aW9uIHRvIHJlbW92ZVxuICAgICAqIEBtZW1iZXJPZiBtaXR0XG4gICAgICovXG4gICAgb2ZmOiBmdW5jdGlvbiBvZmYodHlwZSwgaGFuZGxlcikge1xuICAgICAgaWYgKGFsbFt0eXBlXSkge1xuICAgICAgICBhbGxbdHlwZV0uc3BsaWNlKGFsbFt0eXBlXS5pbmRleE9mKGhhbmRsZXIpID4+PiAwLCAxKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogSW52b2tlIGFsbCBoYW5kbGVycyBmb3IgdGhlIGdpdmVuIHR5cGUuXG4gICAgICogSWYgcHJlc2VudCwgYFwiKlwiYCBoYW5kbGVycyBhcmUgaW52b2tlZCBhZnRlciB0eXBlLW1hdGNoZWQgaGFuZGxlcnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAgVGhlIGV2ZW50IHR5cGUgdG8gaW52b2tlXG4gICAgICogQHBhcmFtIHtBbnl9IFtldnRdICBBbnkgdmFsdWUgKG9iamVjdCBpcyByZWNvbW1lbmRlZCBhbmQgcG93ZXJmdWwpLCBwYXNzZWQgdG8gZWFjaCBoYW5kbGVyXG4gICAgICogQG1lbWJlck9mIG1pdHRcbiAgICAgKi9cbiAgICBlbWl0OiBmdW5jdGlvbiBlbWl0KHR5cGUsIGV2dCkge1xuICAgICAgKGFsbFt0eXBlXSB8fCBbXSkuc2xpY2UoKS5tYXAoZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICAgICAgaGFuZGxlcihldnQpO1xuICAgICAgfSk7XG4gICAgICAoYWxsWycqJ10gfHwgW10pLnNsaWNlKCkubWFwKGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgICAgIGhhbmRsZXIodHlwZSwgZXZ0KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbn1cblxudmFyIF9kZWZhdWx0ID0gbWl0dDtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiWFN3aWJtRnRaWE1pT2x0ZExDSnRZWEJ3YVc1bmN5STZJaUo5IiwiaW1wb3J0IHsgZm9yRWFjaCwgYXNzaWduLCBmaW5kLCBmaWx0ZXIsIGlzU3RyaW5nLCBtYXAgfSBmcm9tICdtaW4tZGFzaCc7XG5pbXBvcnQgeyBQYXJzZXIgfSBmcm9tICdzYXhlbic7XG5pbXBvcnQgeyBjb2VyY2VUeXBlLCBwYXJzZU5hbWVOUywgaXNTaW1wbGVUeXBlLCBNb2RkbGUgfSBmcm9tICdtb2RkbGUnO1xuXG5mdW5jdGlvbiBoYXNMb3dlckNhc2VBbGlhcyhwa2cpIHtcbiAgcmV0dXJuIHBrZy54bWwgJiYgcGtnLnhtbC50YWdBbGlhcyA9PT0gJ2xvd2VyQ2FzZSc7XG59XG5cbnZhciBERUZBVUxUX05TX01BUCA9IHtcbiAgJ3hzaSc6ICdodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZScsXG4gICd4bWwnOiAnaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJ1xufTtcblxudmFyIFhTSV9UWVBFID0gJ3hzaTp0eXBlJztcblxuZnVuY3Rpb24gc2VyaWFsaXplRm9ybWF0KGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQueG1sICYmIGVsZW1lbnQueG1sLnNlcmlhbGl6ZTtcbn1cblxuZnVuY3Rpb24gc2VyaWFsaXplQXNUeXBlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHNlcmlhbGl6ZUZvcm1hdChlbGVtZW50KSA9PT0gWFNJX1RZUEU7XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZUFzUHJvcGVydHkoZWxlbWVudCkge1xuICByZXR1cm4gc2VyaWFsaXplRm9ybWF0KGVsZW1lbnQpID09PSAncHJvcGVydHknO1xufVxuXG5mdW5jdGlvbiBjYXBpdGFsaXplKHN0cikge1xuICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xufVxuXG5mdW5jdGlvbiBhbGlhc1RvTmFtZShhbGlhc05zLCBwa2cpIHtcblxuICBpZiAoIWhhc0xvd2VyQ2FzZUFsaWFzKHBrZykpIHtcbiAgICByZXR1cm4gYWxpYXNOcy5uYW1lO1xuICB9XG5cbiAgcmV0dXJuIGFsaWFzTnMucHJlZml4ICsgJzonICsgY2FwaXRhbGl6ZShhbGlhc05zLmxvY2FsTmFtZSk7XG59XG5cbmZ1bmN0aW9uIHByZWZpeGVkVG9OYW1lKG5hbWVOcywgcGtnKSB7XG5cbiAgdmFyIG5hbWUgPSBuYW1lTnMubmFtZSxcbiAgICAgIGxvY2FsTmFtZSA9IG5hbWVOcy5sb2NhbE5hbWU7XG5cbiAgdmFyIHR5cGVQcmVmaXggPSBwa2cueG1sICYmIHBrZy54bWwudHlwZVByZWZpeDtcblxuICBpZiAodHlwZVByZWZpeCAmJiBsb2NhbE5hbWUuaW5kZXhPZih0eXBlUHJlZml4KSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lTnMucHJlZml4ICsgJzonICsgbG9jYWxOYW1lLnNsaWNlKHR5cGVQcmVmaXgubGVuZ3RoKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBub3JtYWxpemVYc2lUeXBlTmFtZShuYW1lLCBtb2RlbCkge1xuXG4gIHZhciBuYW1lTnMgPSBwYXJzZU5hbWVOUyhuYW1lKTtcbiAgdmFyIHBrZyA9IG1vZGVsLmdldFBhY2thZ2UobmFtZU5zLnByZWZpeCk7XG5cbiAgcmV0dXJuIHByZWZpeGVkVG9OYW1lKG5hbWVOcywgcGtnKTtcbn1cblxuZnVuY3Rpb24gZXJyb3IobWVzc2FnZSkge1xuICByZXR1cm4gbmV3IEVycm9yKG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgbW9kZGxlIGRlc2NyaXB0b3IgZm9yIGEgZ2l2ZW4gaW5zdGFuY2Ugb3IgdHlwZS5cbiAqXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50fEZ1bmN0aW9ufSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB0aGUgbW9kZGxlIGRlc2NyaXB0b3JcbiAqL1xuZnVuY3Rpb24gZ2V0TW9kZGxlRGVzY3JpcHRvcihlbGVtZW50KSB7XG4gIHJldHVybiBlbGVtZW50LiRkZXNjcmlwdG9yO1xufVxuXG5cbi8qKlxuICogQSBwYXJzZSBjb250ZXh0LlxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0ge0VsZW1lbnRIYW5kbGVyfSBvcHRpb25zLnJvb3RIYW5kbGVyIHRoZSByb290IGhhbmRsZXIgZm9yIHBhcnNpbmcgYSBkb2N1bWVudFxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5sYXg9ZmFsc2VdIHdoZXRoZXIgb3Igbm90IHRvIGlnbm9yZSBpbnZhbGlkIGVsZW1lbnRzXG4gKi9cbmZ1bmN0aW9uIENvbnRleHQob3B0aW9ucykge1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkge0VsZW1lbnRIYW5kbGVyfSByb290SGFuZGxlclxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IHtCb29sZWFufSBsYXhcbiAgICovXG5cbiAgYXNzaWduKHRoaXMsIG9wdGlvbnMpO1xuXG4gIHRoaXMuZWxlbWVudHNCeUlkID0ge307XG4gIHRoaXMucmVmZXJlbmNlcyA9IFtdO1xuICB0aGlzLndhcm5pbmdzID0gW107XG5cbiAgLyoqXG4gICAqIEFkZCBhbiB1bnJlc29sdmVkIHJlZmVyZW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHJlZmVyZW5jZVxuICAgKi9cbiAgdGhpcy5hZGRSZWZlcmVuY2UgPSBmdW5jdGlvbihyZWZlcmVuY2UpIHtcbiAgICB0aGlzLnJlZmVyZW5jZXMucHVzaChyZWZlcmVuY2UpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBZGQgYSBwcm9jZXNzZWQgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBlbGVtZW50XG4gICAqL1xuICB0aGlzLmFkZEVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHRocm93IGVycm9yKCdleHBlY3RlZCBlbGVtZW50Jyk7XG4gICAgfVxuXG4gICAgdmFyIGVsZW1lbnRzQnlJZCA9IHRoaXMuZWxlbWVudHNCeUlkO1xuXG4gICAgdmFyIGRlc2NyaXB0b3IgPSBnZXRNb2RkbGVEZXNjcmlwdG9yKGVsZW1lbnQpO1xuXG4gICAgdmFyIGlkUHJvcGVydHkgPSBkZXNjcmlwdG9yLmlkUHJvcGVydHksXG4gICAgICAgIGlkO1xuXG4gICAgaWYgKGlkUHJvcGVydHkpIHtcbiAgICAgIGlkID0gZWxlbWVudC5nZXQoaWRQcm9wZXJ0eS5uYW1lKTtcblxuICAgICAgaWYgKGlkKSB7XG4gICAgICAgIC8vIGZvciBRTmFtZSB2YWxpZGF0aW9uIGFzIHBlciBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLyNOVC1OYW1lQ2hhclxuICAgICAgICBpZiAoIS9eKFthLXpdW1xcdy0uXSo6KT9bYS16X11bXFx3LS5dKiQvaS50ZXN0KGlkKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignaWxsZWdhbCBJRCA8JyArIGlkICsgJz4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbGVtZW50c0J5SWRbaWRdKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3IoJ2R1cGxpY2F0ZSBJRCA8JyArIGlkICsgJz4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsZW1lbnRzQnlJZFtpZF0gPSBlbGVtZW50O1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQWRkIGFuIGltcG9ydCB3YXJuaW5nLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gd2FybmluZ1xuICAgKiBAcGFyYW0ge1N0cmluZ30gd2FybmluZy5tZXNzYWdlXG4gICAqIEBwYXJhbSB7RXJyb3J9IFt3YXJuaW5nLmVycm9yXVxuICAgKi9cbiAgdGhpcy5hZGRXYXJuaW5nID0gZnVuY3Rpb24od2FybmluZykge1xuICAgIHRoaXMud2FybmluZ3MucHVzaCh3YXJuaW5nKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gQmFzZUhhbmRsZXIoKSB7fVxuXG5CYXNlSGFuZGxlci5wcm90b3R5cGUuaGFuZGxlRW5kID0gZnVuY3Rpb24oKSB7fTtcbkJhc2VIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVUZXh0ID0gZnVuY3Rpb24oKSB7fTtcbkJhc2VIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVOb2RlID0gZnVuY3Rpb24oKSB7fTtcblxuXG4vKipcbiAqIEEgc2ltcGxlIHBhc3MgdGhyb3VnaCBoYW5kbGVyIHRoYXQgZG9lcyBub3RoaW5nIGV4Y2VwdCBmb3JcbiAqIGlnbm9yaW5nIGFsbCBpbnB1dCBpdCByZWNlaXZlcy5cbiAqXG4gKiBUaGlzIGlzIHVzZWQgdG8gaWdub3JlIHVua25vd24gZWxlbWVudHMgYW5kXG4gKiBhdHRyaWJ1dGVzLlxuICovXG5mdW5jdGlvbiBOb29wSGFuZGxlcigpIHsgfVxuXG5Ob29wSGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VIYW5kbGVyLnByb3RvdHlwZSk7XG5cbk5vb3BIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVOb2RlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gQm9keUhhbmRsZXIoKSB7fVxuXG5Cb2R5SGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VIYW5kbGVyLnByb3RvdHlwZSk7XG5cbkJvZHlIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVUZXh0ID0gZnVuY3Rpb24odGV4dCkge1xuICB0aGlzLmJvZHkgPSAodGhpcy5ib2R5IHx8ICcnKSArIHRleHQ7XG59O1xuXG5mdW5jdGlvbiBSZWZlcmVuY2VIYW5kbGVyKHByb3BlcnR5LCBjb250ZXh0KSB7XG4gIHRoaXMucHJvcGVydHkgPSBwcm9wZXJ0eTtcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbn1cblxuUmVmZXJlbmNlSGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJvZHlIYW5kbGVyLnByb3RvdHlwZSk7XG5cblJlZmVyZW5jZUhhbmRsZXIucHJvdG90eXBlLmhhbmRsZU5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgaWYgKHRoaXMuZWxlbWVudCkge1xuICAgIHRocm93IGVycm9yKCdleHBlY3RlZCBubyBzdWIgbm9kZXMnKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNyZWF0ZVJlZmVyZW5jZShub2RlKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuUmVmZXJlbmNlSGFuZGxlci5wcm90b3R5cGUuaGFuZGxlRW5kID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuZWxlbWVudC5pZCA9IHRoaXMuYm9keTtcbn07XG5cblJlZmVyZW5jZUhhbmRsZXIucHJvdG90eXBlLmNyZWF0ZVJlZmVyZW5jZSA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgcmV0dXJuIHtcbiAgICBwcm9wZXJ0eTogdGhpcy5wcm9wZXJ0eS5ucy5uYW1lLFxuICAgIGlkOiAnJ1xuICB9O1xufTtcblxuZnVuY3Rpb24gVmFsdWVIYW5kbGVyKHByb3BlcnR5RGVzYywgZWxlbWVudCkge1xuICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICB0aGlzLnByb3BlcnR5RGVzYyA9IHByb3BlcnR5RGVzYztcbn1cblxuVmFsdWVIYW5kbGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQm9keUhhbmRsZXIucHJvdG90eXBlKTtcblxuVmFsdWVIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVFbmQgPSBmdW5jdGlvbigpIHtcblxuICB2YXIgdmFsdWUgPSB0aGlzLmJvZHkgfHwgJycsXG4gICAgICBlbGVtZW50ID0gdGhpcy5lbGVtZW50LFxuICAgICAgcHJvcGVydHlEZXNjID0gdGhpcy5wcm9wZXJ0eURlc2M7XG5cbiAgdmFsdWUgPSBjb2VyY2VUeXBlKHByb3BlcnR5RGVzYy50eXBlLCB2YWx1ZSk7XG5cbiAgaWYgKHByb3BlcnR5RGVzYy5pc01hbnkpIHtcbiAgICBlbGVtZW50LmdldChwcm9wZXJ0eURlc2MubmFtZSkucHVzaCh2YWx1ZSk7XG4gIH0gZWxzZSB7XG4gICAgZWxlbWVudC5zZXQocHJvcGVydHlEZXNjLm5hbWUsIHZhbHVlKTtcbiAgfVxufTtcblxuXG5mdW5jdGlvbiBCYXNlRWxlbWVudEhhbmRsZXIoKSB7fVxuXG5CYXNlRWxlbWVudEhhbmRsZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShCb2R5SGFuZGxlci5wcm90b3R5cGUpO1xuXG5CYXNlRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmhhbmRsZU5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gIHZhciBwYXJzZXIgPSB0aGlzLFxuICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblxuICBpZiAoIWVsZW1lbnQpIHtcbiAgICBlbGVtZW50ID0gdGhpcy5lbGVtZW50ID0gdGhpcy5jcmVhdGVFbGVtZW50KG5vZGUpO1xuXG4gICAgdGhpcy5jb250ZXh0LmFkZEVsZW1lbnQoZWxlbWVudCk7XG4gIH0gZWxzZSB7XG4gICAgcGFyc2VyID0gdGhpcy5oYW5kbGVDaGlsZChub2RlKTtcbiAgfVxuXG4gIHJldHVybiBwYXJzZXI7XG59O1xuXG4vKipcbiAqIEBjbGFzcyBSZWFkZXIuRWxlbWVudEhhbmRsZXJcbiAqXG4gKi9cbmZ1bmN0aW9uIEVsZW1lbnRIYW5kbGVyKG1vZGVsLCB0eXBlTmFtZSwgY29udGV4dCkge1xuICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gIHRoaXMudHlwZSA9IG1vZGVsLmdldFR5cGUodHlwZU5hbWUpO1xuICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xufVxuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VFbGVtZW50SGFuZGxlci5wcm90b3R5cGUpO1xuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUuYWRkUmVmZXJlbmNlID0gZnVuY3Rpb24ocmVmZXJlbmNlKSB7XG4gIHRoaXMuY29udGV4dC5hZGRSZWZlcmVuY2UocmVmZXJlbmNlKTtcbn07XG5cbkVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVUZXh0ID0gZnVuY3Rpb24odGV4dCkge1xuXG4gIHZhciBlbGVtZW50ID0gdGhpcy5lbGVtZW50LFxuICAgICAgZGVzY3JpcHRvciA9IGdldE1vZGRsZURlc2NyaXB0b3IoZWxlbWVudCksXG4gICAgICBib2R5UHJvcGVydHkgPSBkZXNjcmlwdG9yLmJvZHlQcm9wZXJ0eTtcblxuICBpZiAoIWJvZHlQcm9wZXJ0eSkge1xuICAgIHRocm93IGVycm9yKCd1bmV4cGVjdGVkIGJvZHkgdGV4dCA8JyArIHRleHQgKyAnPicpO1xuICB9XG5cbiAgQm9keUhhbmRsZXIucHJvdG90eXBlLmhhbmRsZVRleHQuY2FsbCh0aGlzLCB0ZXh0KTtcbn07XG5cbkVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVFbmQgPSBmdW5jdGlvbigpIHtcblxuICB2YXIgdmFsdWUgPSB0aGlzLmJvZHksXG4gICAgICBlbGVtZW50ID0gdGhpcy5lbGVtZW50LFxuICAgICAgZGVzY3JpcHRvciA9IGdldE1vZGRsZURlc2NyaXB0b3IoZWxlbWVudCksXG4gICAgICBib2R5UHJvcGVydHkgPSBkZXNjcmlwdG9yLmJvZHlQcm9wZXJ0eTtcblxuICBpZiAoYm9keVByb3BlcnR5ICYmIHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YWx1ZSA9IGNvZXJjZVR5cGUoYm9keVByb3BlcnR5LnR5cGUsIHZhbHVlKTtcbiAgICBlbGVtZW50LnNldChib2R5UHJvcGVydHkubmFtZSwgdmFsdWUpO1xuICB9XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgbW9kZWwgZnJvbSB0aGUgZ2l2ZW4gbm9kZS5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBub2RlIHRoZSB4bWwgbm9kZVxuICovXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUuY3JlYXRlRWxlbWVudCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgdmFyIGF0dHJpYnV0ZXMgPSBub2RlLmF0dHJpYnV0ZXMsXG4gICAgICBUeXBlID0gdGhpcy50eXBlLFxuICAgICAgZGVzY3JpcHRvciA9IGdldE1vZGRsZURlc2NyaXB0b3IoVHlwZSksXG4gICAgICBjb250ZXh0ID0gdGhpcy5jb250ZXh0LFxuICAgICAgaW5zdGFuY2UgPSBuZXcgVHlwZSh7fSksXG4gICAgICBtb2RlbCA9IHRoaXMubW9kZWwsXG4gICAgICBwcm9wTmFtZU5zO1xuXG4gIGZvckVhY2goYXR0cmlidXRlcywgZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcblxuICAgIHZhciBwcm9wID0gZGVzY3JpcHRvci5wcm9wZXJ0aWVzQnlOYW1lW25hbWVdLFxuICAgICAgICB2YWx1ZXM7XG5cbiAgICBpZiAocHJvcCAmJiBwcm9wLmlzUmVmZXJlbmNlKSB7XG5cbiAgICAgIGlmICghcHJvcC5pc01hbnkpIHtcbiAgICAgICAgY29udGV4dC5hZGRSZWZlcmVuY2Uoe1xuICAgICAgICAgIGVsZW1lbnQ6IGluc3RhbmNlLFxuICAgICAgICAgIHByb3BlcnR5OiBwcm9wLm5zLm5hbWUsXG4gICAgICAgICAgaWQ6IHZhbHVlXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSURSRUZTOiBwYXJzZSByZWZlcmVuY2VzIGFzIHdoaXRlc3BhY2Utc2VwYXJhdGVkIGxpc3RcbiAgICAgICAgdmFsdWVzID0gdmFsdWUuc3BsaXQoJyAnKTtcblxuICAgICAgICBmb3JFYWNoKHZhbHVlcywgZnVuY3Rpb24odikge1xuICAgICAgICAgIGNvbnRleHQuYWRkUmVmZXJlbmNlKHtcbiAgICAgICAgICAgIGVsZW1lbnQ6IGluc3RhbmNlLFxuICAgICAgICAgICAgcHJvcGVydHk6IHByb3AubnMubmFtZSxcbiAgICAgICAgICAgIGlkOiB2XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgIHZhbHVlID0gY29lcmNlVHlwZShwcm9wLnR5cGUsIHZhbHVlKTtcbiAgICAgIH0gZWxzZVxuICAgICAgaWYgKG5hbWUgIT09ICd4bWxucycpIHtcbiAgICAgICAgcHJvcE5hbWVOcyA9IHBhcnNlTmFtZU5TKG5hbWUsIGRlc2NyaXB0b3IubnMucHJlZml4KTtcblxuICAgICAgICAvLyBjaGVjayB3aGV0aGVyIGF0dHJpYnV0ZSBpcyBkZWZpbmVkIGluIGEgd2VsbC1rbm93biBuYW1lc3BhY2VcbiAgICAgICAgLy8gaWYgdGhhdCBpcyB0aGUgY2FzZSB3ZSBlbWl0IGEgd2FybmluZyB0byBpbmRpY2F0ZSBwb3RlbnRpYWwgbWlzdXNlXG4gICAgICAgIGlmIChtb2RlbC5nZXRQYWNrYWdlKHByb3BOYW1lTnMucHJlZml4KSkge1xuXG4gICAgICAgICAgY29udGV4dC5hZGRXYXJuaW5nKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6ICd1bmtub3duIGF0dHJpYnV0ZSA8JyArIG5hbWUgKyAnPicsXG4gICAgICAgICAgICBlbGVtZW50OiBpbnN0YW5jZSxcbiAgICAgICAgICAgIHByb3BlcnR5OiBuYW1lLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaW5zdGFuY2Uuc2V0KG5hbWUsIHZhbHVlKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBpbnN0YW5jZTtcbn07XG5cbkVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5nZXRQcm9wZXJ0eUZvck5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgdmFyIG5hbWUgPSBub2RlLm5hbWU7XG4gIHZhciBuYW1lTnMgPSBwYXJzZU5hbWVOUyhuYW1lKTtcblxuICB2YXIgdHlwZSA9IHRoaXMudHlwZSxcbiAgICAgIG1vZGVsID0gdGhpcy5tb2RlbCxcbiAgICAgIGRlc2NyaXB0b3IgPSBnZXRNb2RkbGVEZXNjcmlwdG9yKHR5cGUpO1xuXG4gIHZhciBwcm9wZXJ0eU5hbWUgPSBuYW1lTnMubmFtZSxcbiAgICAgIHByb3BlcnR5ID0gZGVzY3JpcHRvci5wcm9wZXJ0aWVzQnlOYW1lW3Byb3BlcnR5TmFtZV0sXG4gICAgICBlbGVtZW50VHlwZU5hbWUsXG4gICAgICBlbGVtZW50VHlwZTtcblxuICAvLyBzZWFyY2ggZm9yIHByb3BlcnRpZXMgYnkgbmFtZSBmaXJzdFxuXG4gIGlmIChwcm9wZXJ0eSAmJiAhcHJvcGVydHkuaXNBdHRyKSB7XG5cbiAgICBpZiAoc2VyaWFsaXplQXNUeXBlKHByb3BlcnR5KSkge1xuICAgICAgZWxlbWVudFR5cGVOYW1lID0gbm9kZS5hdHRyaWJ1dGVzW1hTSV9UWVBFXTtcblxuICAgICAgLy8geHNpIHR5cGUgaXMgb3B0aW9uYWwsIGlmIGl0IGRvZXMgbm90IGV4aXN0cyB0aGVcbiAgICAgIC8vIGRlZmF1bHQgdHlwZSBpcyBhc3N1bWVkXG4gICAgICBpZiAoZWxlbWVudFR5cGVOYW1lKSB7XG5cbiAgICAgICAgLy8gdGFrZSBwb3NzaWJsZSB0eXBlIHByZWZpeGVzIGZyb20gWE1MXG4gICAgICAgIC8vIGludG8gYWNjb3VudCwgaS5lLjogeHNpOnR5cGU9XCJ0e0FjdHVhbFR5cGV9XCJcbiAgICAgICAgZWxlbWVudFR5cGVOYW1lID0gbm9ybWFsaXplWHNpVHlwZU5hbWUoZWxlbWVudFR5cGVOYW1lLCBtb2RlbCk7XG5cbiAgICAgICAgZWxlbWVudFR5cGUgPSBtb2RlbC5nZXRUeXBlKGVsZW1lbnRUeXBlTmFtZSk7XG5cbiAgICAgICAgcmV0dXJuIGFzc2lnbih7fSwgcHJvcGVydHksIHtcbiAgICAgICAgICBlZmZlY3RpdmVUeXBlOiBnZXRNb2RkbGVEZXNjcmlwdG9yKGVsZW1lbnRUeXBlKS5uYW1lXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNlYXJjaCBmb3IgcHJvcGVydGllcyBieSBuYW1lIGZpcnN0XG4gICAgcmV0dXJuIHByb3BlcnR5O1xuICB9XG5cbiAgdmFyIHBrZyA9IG1vZGVsLmdldFBhY2thZ2UobmFtZU5zLnByZWZpeCk7XG5cbiAgaWYgKHBrZykge1xuICAgIGVsZW1lbnRUeXBlTmFtZSA9IGFsaWFzVG9OYW1lKG5hbWVOcywgcGtnKTtcbiAgICBlbGVtZW50VHlwZSA9IG1vZGVsLmdldFR5cGUoZWxlbWVudFR5cGVOYW1lKTtcblxuICAgIC8vIHNlYXJjaCBmb3IgY29sbGVjdGlvbiBtZW1iZXJzIGxhdGVyXG4gICAgcHJvcGVydHkgPSBmaW5kKGRlc2NyaXB0b3IucHJvcGVydGllcywgZnVuY3Rpb24ocCkge1xuICAgICAgcmV0dXJuICFwLmlzVmlydHVhbCAmJiAhcC5pc1JlZmVyZW5jZSAmJiAhcC5pc0F0dHJpYnV0ZSAmJiBlbGVtZW50VHlwZS5oYXNUeXBlKHAudHlwZSk7XG4gICAgfSk7XG5cbiAgICBpZiAocHJvcGVydHkpIHtcbiAgICAgIHJldHVybiBhc3NpZ24oe30sIHByb3BlcnR5LCB7XG4gICAgICAgIGVmZmVjdGl2ZVR5cGU6IGdldE1vZGRsZURlc2NyaXB0b3IoZWxlbWVudFR5cGUpLm5hbWVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBwYXJzZSB1bmtub3duIGVsZW1lbnQgKG1heWJlIGV4dGVuc2lvbilcbiAgICBwcm9wZXJ0eSA9IGZpbmQoZGVzY3JpcHRvci5wcm9wZXJ0aWVzLCBmdW5jdGlvbihwKSB7XG4gICAgICByZXR1cm4gIXAuaXNSZWZlcmVuY2UgJiYgIXAuaXNBdHRyaWJ1dGUgJiYgcC50eXBlID09PSAnRWxlbWVudCc7XG4gICAgfSk7XG5cbiAgICBpZiAocHJvcGVydHkpIHtcbiAgICAgIHJldHVybiBwcm9wZXJ0eTtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBlcnJvcigndW5yZWNvZ25pemVkIGVsZW1lbnQgPCcgKyBuYW1lTnMubmFtZSArICc+Jyk7XG59O1xuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuICdFbGVtZW50RGVzY3JpcHRvclsnICsgZ2V0TW9kZGxlRGVzY3JpcHRvcih0aGlzLnR5cGUpLm5hbWUgKyAnXSc7XG59O1xuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUudmFsdWVIYW5kbGVyID0gZnVuY3Rpb24ocHJvcGVydHlEZXNjLCBlbGVtZW50KSB7XG4gIHJldHVybiBuZXcgVmFsdWVIYW5kbGVyKHByb3BlcnR5RGVzYywgZWxlbWVudCk7XG59O1xuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUucmVmZXJlbmNlSGFuZGxlciA9IGZ1bmN0aW9uKHByb3BlcnR5RGVzYykge1xuICByZXR1cm4gbmV3IFJlZmVyZW5jZUhhbmRsZXIocHJvcGVydHlEZXNjLCB0aGlzLmNvbnRleHQpO1xufTtcblxuRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmhhbmRsZXIgPSBmdW5jdGlvbih0eXBlKSB7XG4gIGlmICh0eXBlID09PSAnRWxlbWVudCcpIHtcbiAgICByZXR1cm4gbmV3IEdlbmVyaWNFbGVtZW50SGFuZGxlcih0aGlzLm1vZGVsLCB0eXBlLCB0aGlzLmNvbnRleHQpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgRWxlbWVudEhhbmRsZXIodGhpcy5tb2RlbCwgdHlwZSwgdGhpcy5jb250ZXh0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBIYW5kbGUgdGhlIGNoaWxkIGVsZW1lbnQgcGFyc2luZ1xuICpcbiAqIEBwYXJhbSAge0VsZW1lbnR9IG5vZGUgdGhlIHhtbCBub2RlXG4gKi9cbkVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVDaGlsZCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgdmFyIHByb3BlcnR5RGVzYywgdHlwZSwgZWxlbWVudCwgY2hpbGRIYW5kbGVyO1xuXG4gIHByb3BlcnR5RGVzYyA9IHRoaXMuZ2V0UHJvcGVydHlGb3JOb2RlKG5vZGUpO1xuICBlbGVtZW50ID0gdGhpcy5lbGVtZW50O1xuXG4gIHR5cGUgPSBwcm9wZXJ0eURlc2MuZWZmZWN0aXZlVHlwZSB8fCBwcm9wZXJ0eURlc2MudHlwZTtcblxuICBpZiAoaXNTaW1wbGVUeXBlKHR5cGUpKSB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWVIYW5kbGVyKHByb3BlcnR5RGVzYywgZWxlbWVudCk7XG4gIH1cblxuICBpZiAocHJvcGVydHlEZXNjLmlzUmVmZXJlbmNlKSB7XG4gICAgY2hpbGRIYW5kbGVyID0gdGhpcy5yZWZlcmVuY2VIYW5kbGVyKHByb3BlcnR5RGVzYykuaGFuZGxlTm9kZShub2RlKTtcbiAgfSBlbHNlIHtcbiAgICBjaGlsZEhhbmRsZXIgPSB0aGlzLmhhbmRsZXIodHlwZSkuaGFuZGxlTm9kZShub2RlKTtcbiAgfVxuXG4gIHZhciBuZXdFbGVtZW50ID0gY2hpbGRIYW5kbGVyLmVsZW1lbnQ7XG5cbiAgLy8gY2hpbGQgaGFuZGxlcyBtYXkgZGVjaWRlIHRvIHNraXAgZWxlbWVudHNcbiAgLy8gYnkgbm90IHJldHVybmluZyBhbnl0aGluZ1xuICBpZiAobmV3RWxlbWVudCAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICBpZiAocHJvcGVydHlEZXNjLmlzTWFueSkge1xuICAgICAgZWxlbWVudC5nZXQocHJvcGVydHlEZXNjLm5hbWUpLnB1c2gobmV3RWxlbWVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQuc2V0KHByb3BlcnR5RGVzYy5uYW1lLCBuZXdFbGVtZW50KTtcbiAgICB9XG5cbiAgICBpZiAocHJvcGVydHlEZXNjLmlzUmVmZXJlbmNlKSB7XG4gICAgICBhc3NpZ24obmV3RWxlbWVudCwge1xuICAgICAgICBlbGVtZW50OiBlbGVtZW50XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5jb250ZXh0LmFkZFJlZmVyZW5jZShuZXdFbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZXN0YWJsaXNoIGNoaWxkIC0+IHBhcmVudCByZWxhdGlvbnNoaXBcbiAgICAgIG5ld0VsZW1lbnQuJHBhcmVudCA9IGVsZW1lbnQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNoaWxkSGFuZGxlcjtcbn07XG5cbi8qKlxuICogQW4gZWxlbWVudCBoYW5kbGVyIHRoYXQgcGVyZm9ybXMgc3BlY2lhbCB2YWxpZGF0aW9uXG4gKiB0byBlbnN1cmUgdGhlIG5vZGUgaXQgZ2V0cyBpbml0aWFsaXplZCB3aXRoIG1hdGNoZXNcbiAqIHRoZSBoYW5kbGVycyB0eXBlIChuYW1lc3BhY2Ugd2lzZSkuXG4gKlxuICogQHBhcmFtIHtNb2RkbGV9IG1vZGVsXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZU5hbWVcbiAqIEBwYXJhbSB7Q29udGV4dH0gY29udGV4dFxuICovXG5mdW5jdGlvbiBSb290RWxlbWVudEhhbmRsZXIobW9kZWwsIHR5cGVOYW1lLCBjb250ZXh0KSB7XG4gIEVsZW1lbnRIYW5kbGVyLmNhbGwodGhpcywgbW9kZWwsIHR5cGVOYW1lLCBjb250ZXh0KTtcbn1cblxuUm9vdEVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRWxlbWVudEhhbmRsZXIucHJvdG90eXBlKTtcblxuUm9vdEVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5jcmVhdGVFbGVtZW50ID0gZnVuY3Rpb24obm9kZSkge1xuXG4gIHZhciBuYW1lID0gbm9kZS5uYW1lLFxuICAgICAgbmFtZU5zID0gcGFyc2VOYW1lTlMobmFtZSksXG4gICAgICBtb2RlbCA9IHRoaXMubW9kZWwsXG4gICAgICB0eXBlID0gdGhpcy50eXBlLFxuICAgICAgcGtnID0gbW9kZWwuZ2V0UGFja2FnZShuYW1lTnMucHJlZml4KSxcbiAgICAgIHR5cGVOYW1lID0gcGtnICYmIGFsaWFzVG9OYW1lKG5hbWVOcywgcGtnKSB8fCBuYW1lO1xuXG4gIC8vIHZlcmlmeSB0aGUgY29ycmVjdCBuYW1lc3BhY2UgaWYgd2UgcGFyc2VcbiAgLy8gdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIGhhbmRsZXIgdHJlZVxuICAvL1xuICAvLyB0aGlzIGVuc3VyZXMgd2UgZG9uJ3QgbWlzdGFrZW5seSBpbXBvcnQgd3JvbmcgbmFtZXNwYWNlIGVsZW1lbnRzXG4gIGlmICghdHlwZS5oYXNUeXBlKHR5cGVOYW1lKSkge1xuICAgIHRocm93IGVycm9yKCd1bmV4cGVjdGVkIGVsZW1lbnQgPCcgKyBub2RlLm9yaWdpbmFsTmFtZSArICc+Jyk7XG4gIH1cblxuICByZXR1cm4gRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmNyZWF0ZUVsZW1lbnQuY2FsbCh0aGlzLCBub2RlKTtcbn07XG5cblxuZnVuY3Rpb24gR2VuZXJpY0VsZW1lbnRIYW5kbGVyKG1vZGVsLCB0eXBlTmFtZSwgY29udGV4dCkge1xuICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG59XG5cbkdlbmVyaWNFbGVtZW50SGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VFbGVtZW50SGFuZGxlci5wcm90b3R5cGUpO1xuXG5HZW5lcmljRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgdmFyIG5hbWUgPSBub2RlLm5hbWUsXG4gICAgICBucyA9IHBhcnNlTmFtZU5TKG5hbWUpLFxuICAgICAgcHJlZml4ID0gbnMucHJlZml4LFxuICAgICAgdXJpID0gbm9kZS5uc1twcmVmaXggKyAnJHVyaSddLFxuICAgICAgYXR0cmlidXRlcyA9IG5vZGUuYXR0cmlidXRlcztcblxuICByZXR1cm4gdGhpcy5tb2RlbC5jcmVhdGVBbnkobmFtZSwgdXJpLCBhdHRyaWJ1dGVzKTtcbn07XG5cbkdlbmVyaWNFbGVtZW50SGFuZGxlci5wcm90b3R5cGUuaGFuZGxlQ2hpbGQgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgdmFyIGhhbmRsZXIgPSBuZXcgR2VuZXJpY0VsZW1lbnRIYW5kbGVyKHRoaXMubW9kZWwsICdFbGVtZW50JywgdGhpcy5jb250ZXh0KS5oYW5kbGVOb2RlKG5vZGUpLFxuICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblxuICB2YXIgbmV3RWxlbWVudCA9IGhhbmRsZXIuZWxlbWVudCxcbiAgICAgIGNoaWxkcmVuO1xuXG4gIGlmIChuZXdFbGVtZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICBjaGlsZHJlbiA9IGVsZW1lbnQuJGNoaWxkcmVuID0gZWxlbWVudC4kY2hpbGRyZW4gfHwgW107XG4gICAgY2hpbGRyZW4ucHVzaChuZXdFbGVtZW50KTtcblxuICAgIC8vIGVzdGFibGlzaCBjaGlsZCAtPiBwYXJlbnQgcmVsYXRpb25zaGlwXG4gICAgbmV3RWxlbWVudC4kcGFyZW50ID0gZWxlbWVudDtcbiAgfVxuXG4gIHJldHVybiBoYW5kbGVyO1xufTtcblxuR2VuZXJpY0VsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVFbmQgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuYm9keSkge1xuICAgIHRoaXMuZWxlbWVudC4kYm9keSA9IHRoaXMuYm9keTtcbiAgfVxufTtcblxuLyoqXG4gKiBBIHJlYWRlciBmb3IgYSBtZXRhLW1vZGVsXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7TW9kZWx9IG9wdGlvbnMubW9kZWwgdXNlZCB0byByZWFkIHhtbCBmaWxlc1xuICogQHBhcmFtIHtCb29sZWFufSBvcHRpb25zLmxheCB3aGV0aGVyIHRvIG1ha2UgcGFyc2UgZXJyb3JzIHdhcm5pbmdzXG4gKi9cbmZ1bmN0aW9uIFJlYWRlcihvcHRpb25zKSB7XG5cbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBNb2RkbGUpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbW9kZWw6IG9wdGlvbnNcbiAgICB9O1xuICB9XG5cbiAgYXNzaWduKHRoaXMsIHsgbGF4OiBmYWxzZSB9LCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBUaGUgZnJvbVhNTCByZXN1bHQuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gUGFyc2VSZXN1bHRcbiAqXG4gKiBAcHJvcGVydHkge01vZGRsZUVsZW1lbnR9IHJvb3RFbGVtZW50XG4gKiBAcHJvcGVydHkge0FycmF5PE9iamVjdD59IHJlZmVyZW5jZXNcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8RXJyb3I+fSB3YXJuaW5nc1xuICogQHByb3BlcnR5IHtPYmplY3R9IGVsZW1lbnRzQnlJZCAtIGEgbWFwcGluZyBjb250YWluaW5nIGVhY2ggSUQgLT4gTW9kZGxlRWxlbWVudFxuICovXG5cbi8qKlxuICogVGhlIGZyb21YTUwgcmVzdWx0LlxuICpcbiAqIEB0eXBlZGVmIHtFcnJvcn0gUGFyc2VFcnJvclxuICpcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8RXJyb3I+fSB3YXJuaW5nc1xuICovXG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIFhNTCBpbnRvIGEgbW9kZGxlIGRvY3VtZW50IHRyZWUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHhtbFxuICogQHBhcmFtIHtFbGVtZW50SGFuZGxlcnxPYmplY3R9IG9wdGlvbnMgb3Igcm9vdEhhbmRsZXJcbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxQYXJzZVJlc3VsdCwgUGFyc2VFcnJvcj59XG4gKi9cblJlYWRlci5wcm90b3R5cGUuZnJvbVhNTCA9IGZ1bmN0aW9uKHhtbCwgb3B0aW9ucywgZG9uZSkge1xuXG4gIHZhciByb290SGFuZGxlciA9IG9wdGlvbnMucm9vdEhhbmRsZXI7XG5cbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBFbGVtZW50SGFuZGxlcikge1xuICAgIC8vIHJvb3QgaGFuZGxlciBwYXNzZWQgdmlhICh4bWwsIHsgcm9vdEhhbmRsZXI6IEVsZW1lbnRIYW5kbGVyIH0sIC4uLilcbiAgICByb290SGFuZGxlciA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIHJvb3RIYW5kbGVyIHBhc3NlZCB2aWEgKHhtbCwgJ3NvbWVTdHJpbmcnLCAuLi4pXG4gICAgICByb290SGFuZGxlciA9IHRoaXMuaGFuZGxlcihvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiByb290SGFuZGxlciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIHJvb3RIYW5kbGVyIHBhc3NlZCB2aWEgKHhtbCwgeyByb290SGFuZGxlcjogJ3NvbWVTdHJpbmcnIH0sIC4uLilcbiAgICAgIHJvb3RIYW5kbGVyID0gdGhpcy5oYW5kbGVyKHJvb3RIYW5kbGVyKTtcbiAgICB9XG4gIH1cblxuICB2YXIgbW9kZWwgPSB0aGlzLm1vZGVsLFxuICAgICAgbGF4ID0gdGhpcy5sYXg7XG5cbiAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dChhc3NpZ24oe30sIG9wdGlvbnMsIHsgcm9vdEhhbmRsZXI6IHJvb3RIYW5kbGVyIH0pKSxcbiAgICAgIHBhcnNlciA9IG5ldyBQYXJzZXIoeyBwcm94eTogdHJ1ZSB9KSxcbiAgICAgIHN0YWNrID0gY3JlYXRlU3RhY2soKTtcblxuICByb290SGFuZGxlci5jb250ZXh0ID0gY29udGV4dDtcblxuICAvLyBwdXNoIHJvb3QgaGFuZGxlclxuICBzdGFjay5wdXNoKHJvb3RIYW5kbGVyKTtcblxuXG4gIC8qKlxuICAgKiBIYW5kbGUgZXJyb3IuXG4gICAqXG4gICAqIEBwYXJhbSAge0Vycm9yfSBlcnJcbiAgICogQHBhcmFtICB7RnVuY3Rpb259IGdldENvbnRleHRcbiAgICogQHBhcmFtICB7Ym9vbGVhbn0gbGF4XG4gICAqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgaGFuZGxlZFxuICAgKi9cbiAgZnVuY3Rpb24gaGFuZGxlRXJyb3IoZXJyLCBnZXRDb250ZXh0LCBsYXgpIHtcblxuICAgIHZhciBjdHggPSBnZXRDb250ZXh0KCk7XG5cbiAgICB2YXIgbGluZSA9IGN0eC5saW5lLFxuICAgICAgICBjb2x1bW4gPSBjdHguY29sdW1uLFxuICAgICAgICBkYXRhID0gY3R4LmRhdGE7XG5cbiAgICAvLyB3ZSByZWNlaXZlIHRoZSBmdWxsIGNvbnRleHQgZGF0YSBoZXJlLFxuICAgIC8vIGZvciBlbGVtZW50cyB0cmltIGRvd24gdGhlIGluZm9ybWF0aW9uXG4gICAgLy8gdG8gdGhlIHRhZyBuYW1lLCBvbmx5XG4gICAgaWYgKGRhdGEuY2hhckF0KDApID09PSAnPCcgJiYgZGF0YS5pbmRleE9mKCcgJykgIT09IC0xKSB7XG4gICAgICBkYXRhID0gZGF0YS5zbGljZSgwLCBkYXRhLmluZGV4T2YoJyAnKSkgKyAnPic7XG4gICAgfVxuXG4gICAgdmFyIG1lc3NhZ2UgPVxuICAgICAgJ3VucGFyc2FibGUgY29udGVudCAnICsgKGRhdGEgPyBkYXRhICsgJyAnIDogJycpICsgJ2RldGVjdGVkXFxuXFx0JyArXG4gICAgICAgICdsaW5lOiAnICsgbGluZSArICdcXG5cXHQnICtcbiAgICAgICAgJ2NvbHVtbjogJyArIGNvbHVtbiArICdcXG5cXHQnICtcbiAgICAgICAgJ25lc3RlZCBlcnJvcjogJyArIGVyci5tZXNzYWdlO1xuXG4gICAgaWYgKGxheCkge1xuICAgICAgY29udGV4dC5hZGRXYXJuaW5nKHtcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgZXJyb3I6IGVyclxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlcnJvcihtZXNzYWdlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVXYXJuaW5nKGVyciwgZ2V0Q29udGV4dCkge1xuICAgIC8vIGp1c3QgbGlrZSBoYW5kbGluZyBlcnJvcnMgaW4gPGxheD10cnVlPiBtb2RlXG4gICAgcmV0dXJuIGhhbmRsZUVycm9yKGVyciwgZ2V0Q29udGV4dCwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBjb2xsZWN0ZWQgcmVmZXJlbmNlcyBvbiBwYXJzZSBlbmQuXG4gICAqL1xuICBmdW5jdGlvbiByZXNvbHZlUmVmZXJlbmNlcygpIHtcblxuICAgIHZhciBlbGVtZW50c0J5SWQgPSBjb250ZXh0LmVsZW1lbnRzQnlJZDtcbiAgICB2YXIgcmVmZXJlbmNlcyA9IGNvbnRleHQucmVmZXJlbmNlcztcblxuICAgIHZhciBpLCByO1xuXG4gICAgZm9yIChpID0gMDsgKHIgPSByZWZlcmVuY2VzW2ldKTsgaSsrKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IHIuZWxlbWVudDtcbiAgICAgIHZhciByZWZlcmVuY2UgPSBlbGVtZW50c0J5SWRbci5pZF07XG4gICAgICB2YXIgcHJvcGVydHkgPSBnZXRNb2RkbGVEZXNjcmlwdG9yKGVsZW1lbnQpLnByb3BlcnRpZXNCeU5hbWVbci5wcm9wZXJ0eV07XG5cbiAgICAgIGlmICghcmVmZXJlbmNlKSB7XG4gICAgICAgIGNvbnRleHQuYWRkV2FybmluZyh7XG4gICAgICAgICAgbWVzc2FnZTogJ3VucmVzb2x2ZWQgcmVmZXJlbmNlIDwnICsgci5pZCArICc+JyxcbiAgICAgICAgICBlbGVtZW50OiByLmVsZW1lbnQsXG4gICAgICAgICAgcHJvcGVydHk6IHIucHJvcGVydHksXG4gICAgICAgICAgdmFsdWU6IHIuaWRcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wZXJ0eS5pc01hbnkpIHtcbiAgICAgICAgdmFyIGNvbGxlY3Rpb24gPSBlbGVtZW50LmdldChwcm9wZXJ0eS5uYW1lKSxcbiAgICAgICAgICAgIGlkeCA9IGNvbGxlY3Rpb24uaW5kZXhPZihyKTtcblxuICAgICAgICAvLyB3ZSByZXBsYWNlIGFuIGV4aXN0aW5nIHBsYWNlIGhvbGRlciAoaWR4ICE9IC0xKSBvclxuICAgICAgICAvLyBhcHBlbmQgdG8gdGhlIGNvbGxlY3Rpb24gaW5zdGVhZFxuICAgICAgICBpZiAoaWR4ID09PSAtMSkge1xuICAgICAgICAgIGlkeCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFyZWZlcmVuY2UpIHtcbiAgICAgICAgICAvLyByZW1vdmUgdW5yZXNvbHZhYmxlIHJlZmVyZW5jZVxuICAgICAgICAgIGNvbGxlY3Rpb24uc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gYWRkIG9yIHVwZGF0ZSByZWZlcmVuY2UgaW4gY29sbGVjdGlvblxuICAgICAgICAgIGNvbGxlY3Rpb25baWR4XSA9IHJlZmVyZW5jZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5zZXQocHJvcGVydHkubmFtZSwgcmVmZXJlbmNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVDbG9zZSgpIHtcbiAgICBzdGFjay5wb3AoKS5oYW5kbGVFbmQoKTtcbiAgfVxuXG4gIHZhciBQUkVBTUJMRV9TVEFSVF9QQVRURVJOID0gL148XFw/eG1sIC9pO1xuXG4gIHZhciBFTkNPRElOR19QQVRURVJOID0gLyBlbmNvZGluZz1cIihbXlwiXSspXCIvaTtcblxuICB2YXIgVVRGXzhfUEFUVEVSTiA9IC9edXRmLTgkL2k7XG5cbiAgZnVuY3Rpb24gaGFuZGxlUXVlc3Rpb24ocXVlc3Rpb24pIHtcblxuICAgIGlmICghUFJFQU1CTEVfU1RBUlRfUEFUVEVSTi50ZXN0KHF1ZXN0aW9uKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBtYXRjaCA9IEVOQ09ESU5HX1BBVFRFUk4uZXhlYyhxdWVzdGlvbik7XG4gICAgdmFyIGVuY29kaW5nID0gbWF0Y2ggJiYgbWF0Y2hbMV07XG5cbiAgICBpZiAoIWVuY29kaW5nIHx8IFVURl84X1BBVFRFUk4udGVzdChlbmNvZGluZykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb250ZXh0LmFkZFdhcm5pbmcoe1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgJ3Vuc3VwcG9ydGVkIGRvY3VtZW50IGVuY29kaW5nIDwnICsgZW5jb2RpbmcgKyAnPiwgJyArXG4gICAgICAgICdmYWxsaW5nIGJhY2sgdG8gVVRGLTgnXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVPcGVuKG5vZGUsIGdldENvbnRleHQpIHtcbiAgICB2YXIgaGFuZGxlciA9IHN0YWNrLnBlZWsoKTtcblxuICAgIHRyeSB7XG4gICAgICBzdGFjay5wdXNoKGhhbmRsZXIuaGFuZGxlTm9kZShub2RlKSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG5cbiAgICAgIGlmIChoYW5kbGVFcnJvcihlcnIsIGdldENvbnRleHQsIGxheCkpIHtcbiAgICAgICAgc3RhY2sucHVzaChuZXcgTm9vcEhhbmRsZXIoKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlQ0RhdGEodGV4dCwgZ2V0Q29udGV4dCkge1xuXG4gICAgdHJ5IHtcbiAgICAgIHN0YWNrLnBlZWsoKS5oYW5kbGVUZXh0KHRleHQpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaGFuZGxlV2FybmluZyhlcnIsIGdldENvbnRleHQpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVRleHQodGV4dCwgZ2V0Q29udGV4dCkge1xuICAgIC8vIHN0cmlwIHdoaXRlc3BhY2Ugb25seSBub2RlcywgaS5lLiBiZWZvcmVcbiAgICAvLyA8IUNEQVRBWyAuLi4gXT4gc2VjdGlvbnMgYW5kIGluIGJldHdlZW4gdGFnc1xuICAgIHRleHQgPSB0ZXh0LnRyaW0oKTtcblxuICAgIGlmICghdGV4dCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGhhbmRsZUNEYXRhKHRleHQsIGdldENvbnRleHQpO1xuICB9XG5cbiAgdmFyIHVyaU1hcCA9IG1vZGVsLmdldFBhY2thZ2VzKCkucmVkdWNlKGZ1bmN0aW9uKHVyaU1hcCwgcCkge1xuICAgIHVyaU1hcFtwLnVyaV0gPSBwLnByZWZpeDtcblxuICAgIHJldHVybiB1cmlNYXA7XG4gIH0sIHtcbiAgICAnaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJzogJ3htbCcgLy8gYWRkIGRlZmF1bHQgeG1sIG5zXG4gIH0pO1xuICBwYXJzZXJcbiAgICAubnModXJpTWFwKVxuICAgIC5vbignb3BlblRhZycsIGZ1bmN0aW9uKG9iaiwgZGVjb2RlU3RyLCBzZWxmQ2xvc2luZywgZ2V0Q29udGV4dCkge1xuXG4gICAgICAvLyBncmFjZWZ1bGx5IGhhbmRsZSB1bnBhcnNhYmxlIGF0dHJpYnV0ZXMgKGF0dHJzPWZhbHNlKVxuICAgICAgdmFyIGF0dHJzID0gb2JqLmF0dHJzIHx8IHt9O1xuXG4gICAgICB2YXIgZGVjb2RlZEF0dHJzID0gT2JqZWN0LmtleXMoYXR0cnMpLnJlZHVjZShmdW5jdGlvbihkLCBrZXkpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gZGVjb2RlU3RyKGF0dHJzW2tleV0pO1xuXG4gICAgICAgIGRba2V5XSA9IHZhbHVlO1xuXG4gICAgICAgIHJldHVybiBkO1xuICAgICAgfSwge30pO1xuXG4gICAgICB2YXIgbm9kZSA9IHtcbiAgICAgICAgbmFtZTogb2JqLm5hbWUsXG4gICAgICAgIG9yaWdpbmFsTmFtZTogb2JqLm9yaWdpbmFsTmFtZSxcbiAgICAgICAgYXR0cmlidXRlczogZGVjb2RlZEF0dHJzLFxuICAgICAgICBuczogb2JqLm5zXG4gICAgICB9O1xuXG4gICAgICBoYW5kbGVPcGVuKG5vZGUsIGdldENvbnRleHQpO1xuICAgIH0pXG4gICAgLm9uKCdxdWVzdGlvbicsIGhhbmRsZVF1ZXN0aW9uKVxuICAgIC5vbignY2xvc2VUYWcnLCBoYW5kbGVDbG9zZSlcbiAgICAub24oJ2NkYXRhJywgaGFuZGxlQ0RhdGEpXG4gICAgLm9uKCd0ZXh0JywgZnVuY3Rpb24odGV4dCwgZGVjb2RlRW50aXRpZXMsIGdldENvbnRleHQpIHtcbiAgICAgIGhhbmRsZVRleHQoZGVjb2RlRW50aXRpZXModGV4dCksIGdldENvbnRleHQpO1xuICAgIH0pXG4gICAgLm9uKCdlcnJvcicsIGhhbmRsZUVycm9yKVxuICAgIC5vbignd2FybicsIGhhbmRsZVdhcm5pbmcpO1xuXG4gIC8vIGFzeW5jIFhNTCBwYXJzaW5nIHRvIG1ha2Ugc3VyZSB0aGUgZXhlY3V0aW9uIGVudmlyb25tZW50XG4gIC8vIChub2RlIG9yIGJyb3dlcikgaXMga2VwdCByZXNwb25zaXZlIGFuZCB0aGF0IGNlcnRhaW4gb3B0aW1pemF0aW9uXG4gIC8vIHN0cmF0ZWdpZXMgY2FuIGtpY2sgaW4uXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcblxuICAgIHZhciBlcnI7XG5cbiAgICB0cnkge1xuICAgICAgcGFyc2VyLnBhcnNlKHhtbCk7XG5cbiAgICAgIHJlc29sdmVSZWZlcmVuY2VzKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZXJyID0gZTtcbiAgICB9XG5cbiAgICB2YXIgcm9vdEVsZW1lbnQgPSByb290SGFuZGxlci5lbGVtZW50O1xuXG4gICAgaWYgKCFlcnIgJiYgIXJvb3RFbGVtZW50KSB7XG4gICAgICBlcnIgPSBlcnJvcignZmFpbGVkIHRvIHBhcnNlIGRvY3VtZW50IGFzIDwnICsgcm9vdEhhbmRsZXIudHlwZS4kZGVzY3JpcHRvci5uYW1lICsgJz4nKTtcbiAgICB9XG5cbiAgICB2YXIgd2FybmluZ3MgPSBjb250ZXh0Lndhcm5pbmdzO1xuICAgIHZhciByZWZlcmVuY2VzID0gY29udGV4dC5yZWZlcmVuY2VzO1xuICAgIHZhciBlbGVtZW50c0J5SWQgPSBjb250ZXh0LmVsZW1lbnRzQnlJZDtcblxuICAgIGlmIChlcnIpIHtcbiAgICAgIGVyci53YXJuaW5ncyA9IHdhcm5pbmdzO1xuXG4gICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByZXNvbHZlKHtcbiAgICAgICAgcm9vdEVsZW1lbnQ6IHJvb3RFbGVtZW50LFxuICAgICAgICBlbGVtZW50c0J5SWQ6IGVsZW1lbnRzQnlJZCxcbiAgICAgICAgcmVmZXJlbmNlczogcmVmZXJlbmNlcyxcbiAgICAgICAgd2FybmluZ3M6IHdhcm5pbmdzXG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xufTtcblxuUmVhZGVyLnByb3RvdHlwZS5oYW5kbGVyID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gbmV3IFJvb3RFbGVtZW50SGFuZGxlcih0aGlzLm1vZGVsLCBuYW1lKTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBjcmVhdGVTdGFjaygpIHtcbiAgdmFyIHN0YWNrID0gW107XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0YWNrLCAncGVlaycsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpc1t0aGlzLmxlbmd0aCAtIDFdO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHN0YWNrO1xufVxuXG52YXIgWE1MX1BSRUFNQkxFID0gJzw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCI/Plxcbic7XG5cbnZhciBFU0NBUEVfQVRUUl9DSEFSUyA9IC88fD58J3xcInwmfFxcblxccnxcXG4vZztcbnZhciBFU0NBUEVfQ0hBUlMgPSAvPHw+fCYvZztcblxuXG5mdW5jdGlvbiBOYW1lc3BhY2VzKHBhcmVudCkge1xuXG4gIHZhciBwcmVmaXhNYXAgPSB7fTtcbiAgdmFyIHVyaU1hcCA9IHt9O1xuICB2YXIgdXNlZCA9IHt9O1xuXG4gIHZhciB3ZWxsa25vd24gPSBbXTtcbiAgdmFyIGN1c3RvbSA9IFtdO1xuXG4gIC8vIEFQSVxuXG4gIHRoaXMuYnlVcmkgPSBmdW5jdGlvbih1cmkpIHtcbiAgICByZXR1cm4gdXJpTWFwW3VyaV0gfHwgKFxuICAgICAgcGFyZW50ICYmIHBhcmVudC5ieVVyaSh1cmkpXG4gICAgKTtcbiAgfTtcblxuICB0aGlzLmFkZCA9IGZ1bmN0aW9uKG5zLCBpc1dlbGxrbm93bikge1xuXG4gICAgdXJpTWFwW25zLnVyaV0gPSBucztcblxuICAgIGlmIChpc1dlbGxrbm93bikge1xuICAgICAgd2VsbGtub3duLnB1c2gobnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXN0b20ucHVzaChucyk7XG4gICAgfVxuXG4gICAgdGhpcy5tYXBQcmVmaXgobnMucHJlZml4LCBucy51cmkpO1xuICB9O1xuXG4gIHRoaXMudXJpQnlQcmVmaXggPSBmdW5jdGlvbihwcmVmaXgpIHtcbiAgICByZXR1cm4gcHJlZml4TWFwW3ByZWZpeCB8fCAneG1sbnMnXTtcbiAgfTtcblxuICB0aGlzLm1hcFByZWZpeCA9IGZ1bmN0aW9uKHByZWZpeCwgdXJpKSB7XG4gICAgcHJlZml4TWFwW3ByZWZpeCB8fCAneG1sbnMnXSA9IHVyaTtcbiAgfTtcblxuICB0aGlzLmdldE5TS2V5ID0gZnVuY3Rpb24obnMpIHtcbiAgICByZXR1cm4gKG5zLnByZWZpeCAhPT0gdW5kZWZpbmVkKSA/IChucy51cmkgKyAnfCcgKyBucy5wcmVmaXgpIDogbnMudXJpO1xuICB9O1xuXG4gIHRoaXMubG9nVXNlZCA9IGZ1bmN0aW9uKG5zKSB7XG5cbiAgICB2YXIgdXJpID0gbnMudXJpO1xuICAgIHZhciBuc0tleSA9IHRoaXMuZ2V0TlNLZXkobnMpO1xuXG4gICAgdXNlZFtuc0tleV0gPSB0aGlzLmJ5VXJpKHVyaSk7XG5cbiAgICAvLyBJbmZvcm0gcGFyZW50IHJlY3Vyc2l2ZWx5IGFib3V0IHRoZSB1c2FnZSBvZiB0aGlzIE5TXG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgcGFyZW50LmxvZ1VzZWQobnMpO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLmdldFVzZWQgPSBmdW5jdGlvbihucykge1xuXG4gICAgZnVuY3Rpb24gaXNVc2VkKG5zKSB7XG4gICAgICB2YXIgbnNLZXkgPSBzZWxmLmdldE5TS2V5KG5zKTtcblxuICAgICAgcmV0dXJuIHVzZWRbbnNLZXldO1xuICAgIH1cblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBhbGxOcyA9IFtdLmNvbmNhdCh3ZWxsa25vd24sIGN1c3RvbSk7XG5cbiAgICByZXR1cm4gYWxsTnMuZmlsdGVyKGlzVXNlZCk7XG4gIH07XG5cbn1cblxuZnVuY3Rpb24gbG93ZXIoc3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG59XG5cbmZ1bmN0aW9uIG5hbWVUb0FsaWFzKG5hbWUsIHBrZykge1xuICBpZiAoaGFzTG93ZXJDYXNlQWxpYXMocGtnKSkge1xuICAgIHJldHVybiBsb3dlcihuYW1lKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3I7XG4gIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG5zTmFtZShucykge1xuICBpZiAoaXNTdHJpbmcobnMpKSB7XG4gICAgcmV0dXJuIG5zO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAobnMucHJlZml4ID8gbnMucHJlZml4ICsgJzonIDogJycpICsgbnMubG9jYWxOYW1lO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldE5zQXR0cnMobmFtZXNwYWNlcykge1xuXG4gIHJldHVybiBtYXAobmFtZXNwYWNlcy5nZXRVc2VkKCksIGZ1bmN0aW9uKG5zKSB7XG4gICAgdmFyIG5hbWUgPSAneG1sbnMnICsgKG5zLnByZWZpeCA/ICc6JyArIG5zLnByZWZpeCA6ICcnKTtcbiAgICByZXR1cm4geyBuYW1lOiBuYW1lLCB2YWx1ZTogbnMudXJpIH07XG4gIH0pO1xuXG59XG5cbmZ1bmN0aW9uIGdldEVsZW1lbnROcyhucywgZGVzY3JpcHRvcikge1xuICBpZiAoZGVzY3JpcHRvci5pc0dlbmVyaWMpIHtcbiAgICByZXR1cm4gYXNzaWduKHsgbG9jYWxOYW1lOiBkZXNjcmlwdG9yLm5zLmxvY2FsTmFtZSB9LCBucyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGFzc2lnbih7IGxvY2FsTmFtZTogbmFtZVRvQWxpYXMoZGVzY3JpcHRvci5ucy5sb2NhbE5hbWUsIGRlc2NyaXB0b3IuJHBrZykgfSwgbnMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFByb3BlcnR5TnMobnMsIGRlc2NyaXB0b3IpIHtcbiAgcmV0dXJuIGFzc2lnbih7IGxvY2FsTmFtZTogZGVzY3JpcHRvci5ucy5sb2NhbE5hbWUgfSwgbnMpO1xufVxuXG5mdW5jdGlvbiBnZXRTZXJpYWxpemFibGVQcm9wZXJ0aWVzKGVsZW1lbnQpIHtcbiAgdmFyIGRlc2NyaXB0b3IgPSBlbGVtZW50LiRkZXNjcmlwdG9yO1xuXG4gIHJldHVybiBmaWx0ZXIoZGVzY3JpcHRvci5wcm9wZXJ0aWVzLCBmdW5jdGlvbihwKSB7XG4gICAgdmFyIG5hbWUgPSBwLm5hbWU7XG5cbiAgICBpZiAocC5pc1ZpcnR1YWwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBkbyBub3Qgc2VyaWFsaXplIGRlZmF1bHRzXG4gICAgaWYgKCFlbGVtZW50Lmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIHZhbHVlID0gZWxlbWVudFtuYW1lXTtcblxuICAgIC8vIGRvIG5vdCBzZXJpYWxpemUgZGVmYXVsdCBlcXVhbHNcbiAgICBpZiAodmFsdWUgPT09IHAuZGVmYXVsdCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIGRvIG5vdCBzZXJpYWxpemUgbnVsbCBwcm9wZXJ0aWVzXG4gICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHAuaXNNYW55ID8gdmFsdWUubGVuZ3RoIDogdHJ1ZTtcbiAgfSk7XG59XG5cbnZhciBFU0NBUEVfQVRUUl9NQVAgPSB7XG4gICdcXG4nOiAnIzEwJyxcbiAgJ1xcblxccic6ICcjMTAnLFxuICAnXCInOiAnIzM0JyxcbiAgJ1xcJyc6ICcjMzknLFxuICAnPCc6ICcjNjAnLFxuICAnPic6ICcjNjInLFxuICAnJic6ICcjMzgnXG59O1xuXG52YXIgRVNDQVBFX01BUCA9IHtcbiAgJzwnOiAnbHQnLFxuICAnPic6ICdndCcsXG4gICcmJzogJ2FtcCdcbn07XG5cbmZ1bmN0aW9uIGVzY2FwZShzdHIsIGNoYXJQYXR0ZXJuLCByZXBsYWNlTWFwKSB7XG5cbiAgLy8gZW5zdXJlIHdlIGFyZSBoYW5kbGluZyBzdHJpbmdzIGhlcmVcbiAgc3RyID0gaXNTdHJpbmcoc3RyKSA/IHN0ciA6ICcnICsgc3RyO1xuXG4gIHJldHVybiBzdHIucmVwbGFjZShjaGFyUGF0dGVybiwgZnVuY3Rpb24ocykge1xuICAgIHJldHVybiAnJicgKyByZXBsYWNlTWFwW3NdICsgJzsnO1xuICB9KTtcbn1cblxuLyoqXG4gKiBFc2NhcGUgYSBzdHJpbmcgYXR0cmlidXRlIHRvIG5vdCBjb250YWluIGFueSBiYWQgdmFsdWVzIChsaW5lIGJyZWFrcywgJ1wiJywgLi4uKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgdGhlIHN0cmluZyB0byBlc2NhcGVcbiAqIEByZXR1cm4ge1N0cmluZ30gdGhlIGVzY2FwZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGVzY2FwZUF0dHIoc3RyKSB7XG4gIHJldHVybiBlc2NhcGUoc3RyLCBFU0NBUEVfQVRUUl9DSEFSUywgRVNDQVBFX0FUVFJfTUFQKTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlQm9keShzdHIpIHtcbiAgcmV0dXJuIGVzY2FwZShzdHIsIEVTQ0FQRV9DSEFSUywgRVNDQVBFX01BUCk7XG59XG5cbmZ1bmN0aW9uIGZpbHRlckF0dHJpYnV0ZXMocHJvcHMpIHtcbiAgcmV0dXJuIGZpbHRlcihwcm9wcywgZnVuY3Rpb24ocCkgeyByZXR1cm4gcC5pc0F0dHI7IH0pO1xufVxuXG5mdW5jdGlvbiBmaWx0ZXJDb250YWluZWQocHJvcHMpIHtcbiAgcmV0dXJuIGZpbHRlcihwcm9wcywgZnVuY3Rpb24ocCkgeyByZXR1cm4gIXAuaXNBdHRyOyB9KTtcbn1cblxuXG5mdW5jdGlvbiBSZWZlcmVuY2VTZXJpYWxpemVyKHRhZ05hbWUpIHtcbiAgdGhpcy50YWdOYW1lID0gdGFnTmFtZTtcbn1cblxuUmVmZXJlbmNlU2VyaWFsaXplci5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gIHJldHVybiB0aGlzO1xufTtcblxuUmVmZXJlbmNlU2VyaWFsaXplci5wcm90b3R5cGUuc2VyaWFsaXplVG8gPSBmdW5jdGlvbih3cml0ZXIpIHtcbiAgd3JpdGVyXG4gICAgLmFwcGVuZEluZGVudCgpXG4gICAgLmFwcGVuZCgnPCcgKyB0aGlzLnRhZ05hbWUgKyAnPicgKyB0aGlzLmVsZW1lbnQuaWQgKyAnPC8nICsgdGhpcy50YWdOYW1lICsgJz4nKVxuICAgIC5hcHBlbmROZXdMaW5lKCk7XG59O1xuXG5mdW5jdGlvbiBCb2R5U2VyaWFsaXplcigpIHt9XG5cbkJvZHlTZXJpYWxpemVyLnByb3RvdHlwZS5zZXJpYWxpemVWYWx1ZSA9XG5Cb2R5U2VyaWFsaXplci5wcm90b3R5cGUuc2VyaWFsaXplVG8gPSBmdW5jdGlvbih3cml0ZXIpIHtcbiAgd3JpdGVyLmFwcGVuZChcbiAgICB0aGlzLmVzY2FwZVxuICAgICAgPyBlc2NhcGVCb2R5KHRoaXMudmFsdWUpXG4gICAgICA6IHRoaXMudmFsdWVcbiAgKTtcbn07XG5cbkJvZHlTZXJpYWxpemVyLnByb3RvdHlwZS5idWlsZCA9IGZ1bmN0aW9uKHByb3AsIHZhbHVlKSB7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcblxuICBpZiAocHJvcC50eXBlID09PSAnU3RyaW5nJyAmJiB2YWx1ZS5zZWFyY2goRVNDQVBFX0NIQVJTKSAhPT0gLTEpIHtcbiAgICB0aGlzLmVzY2FwZSA9IHRydWU7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIFZhbHVlU2VyaWFsaXplcih0YWdOYW1lKSB7XG4gIHRoaXMudGFnTmFtZSA9IHRhZ05hbWU7XG59XG5cbmluaGVyaXRzKFZhbHVlU2VyaWFsaXplciwgQm9keVNlcmlhbGl6ZXIpO1xuXG5WYWx1ZVNlcmlhbGl6ZXIucHJvdG90eXBlLnNlcmlhbGl6ZVRvID0gZnVuY3Rpb24od3JpdGVyKSB7XG5cbiAgd3JpdGVyXG4gICAgLmFwcGVuZEluZGVudCgpXG4gICAgLmFwcGVuZCgnPCcgKyB0aGlzLnRhZ05hbWUgKyAnPicpO1xuXG4gIHRoaXMuc2VyaWFsaXplVmFsdWUod3JpdGVyKTtcblxuICB3cml0ZXJcbiAgICAuYXBwZW5kKCc8LycgKyB0aGlzLnRhZ05hbWUgKyAnPicpXG4gICAgLmFwcGVuZE5ld0xpbmUoKTtcbn07XG5cbmZ1bmN0aW9uIEVsZW1lbnRTZXJpYWxpemVyKHBhcmVudCwgcHJvcGVydHlEZXNjcmlwdG9yKSB7XG4gIHRoaXMuYm9keSA9IFtdO1xuICB0aGlzLmF0dHJzID0gW107XG5cbiAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMucHJvcGVydHlEZXNjcmlwdG9yID0gcHJvcGVydHlEZXNjcmlwdG9yO1xufVxuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgdmFyIGVsZW1lbnREZXNjcmlwdG9yID0gZWxlbWVudC4kZGVzY3JpcHRvcixcbiAgICAgIHByb3BlcnR5RGVzY3JpcHRvciA9IHRoaXMucHJvcGVydHlEZXNjcmlwdG9yO1xuXG4gIHZhciBvdGhlckF0dHJzLFxuICAgICAgcHJvcGVydGllcztcblxuICB2YXIgaXNHZW5lcmljID0gZWxlbWVudERlc2NyaXB0b3IuaXNHZW5lcmljO1xuXG4gIGlmIChpc0dlbmVyaWMpIHtcbiAgICBvdGhlckF0dHJzID0gdGhpcy5wYXJzZUdlbmVyaWMoZWxlbWVudCk7XG4gIH0gZWxzZSB7XG4gICAgb3RoZXJBdHRycyA9IHRoaXMucGFyc2VOc0F0dHJpYnV0ZXMoZWxlbWVudCk7XG4gIH1cblxuICBpZiAocHJvcGVydHlEZXNjcmlwdG9yKSB7XG4gICAgdGhpcy5ucyA9IHRoaXMubnNQcm9wZXJ0eVRhZ05hbWUocHJvcGVydHlEZXNjcmlwdG9yKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLm5zID0gdGhpcy5uc1RhZ05hbWUoZWxlbWVudERlc2NyaXB0b3IpO1xuICB9XG5cbiAgLy8gY29tcHV0ZSB0YWcgbmFtZVxuICB0aGlzLnRhZ05hbWUgPSB0aGlzLmFkZFRhZ05hbWUodGhpcy5ucyk7XG5cbiAgaWYgKCFpc0dlbmVyaWMpIHtcbiAgICBwcm9wZXJ0aWVzID0gZ2V0U2VyaWFsaXphYmxlUHJvcGVydGllcyhlbGVtZW50KTtcblxuICAgIHRoaXMucGFyc2VBdHRyaWJ1dGVzKGZpbHRlckF0dHJpYnV0ZXMocHJvcGVydGllcykpO1xuICAgIHRoaXMucGFyc2VDb250YWlubWVudHMoZmlsdGVyQ29udGFpbmVkKHByb3BlcnRpZXMpKTtcbiAgfVxuXG4gIHRoaXMucGFyc2VHZW5lcmljQXR0cmlidXRlcyhlbGVtZW50LCBvdGhlckF0dHJzKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkVsZW1lbnRTZXJpYWxpemVyLnByb3RvdHlwZS5uc1RhZ05hbWUgPSBmdW5jdGlvbihkZXNjcmlwdG9yKSB7XG4gIHZhciBlZmZlY3RpdmVOcyA9IHRoaXMubG9nTmFtZXNwYWNlVXNlZChkZXNjcmlwdG9yLm5zKTtcbiAgcmV0dXJuIGdldEVsZW1lbnROcyhlZmZlY3RpdmVOcywgZGVzY3JpcHRvcik7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUubnNQcm9wZXJ0eVRhZ05hbWUgPSBmdW5jdGlvbihkZXNjcmlwdG9yKSB7XG4gIHZhciBlZmZlY3RpdmVOcyA9IHRoaXMubG9nTmFtZXNwYWNlVXNlZChkZXNjcmlwdG9yLm5zKTtcbiAgcmV0dXJuIGdldFByb3BlcnR5TnMoZWZmZWN0aXZlTnMsIGRlc2NyaXB0b3IpO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLmlzTG9jYWxOcyA9IGZ1bmN0aW9uKG5zKSB7XG4gIHJldHVybiBucy51cmkgPT09IHRoaXMubnMudXJpO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGFjdHVhbCBucyBhdHRyaWJ1dGUgbmFtZSBmb3IgdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnRcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW2VsZW1lbnQuaW5oZXJpdGVkPWZhbHNlXVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gbnNOYW1lXG4gKi9cbkVsZW1lbnRTZXJpYWxpemVyLnByb3RvdHlwZS5uc0F0dHJpYnV0ZU5hbWUgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgdmFyIG5zO1xuXG4gIGlmIChpc1N0cmluZyhlbGVtZW50KSkge1xuICAgIG5zID0gcGFyc2VOYW1lTlMoZWxlbWVudCk7XG4gIH0gZWxzZSB7XG4gICAgbnMgPSBlbGVtZW50Lm5zO1xuICB9XG5cbiAgLy8gcmV0dXJuIGp1c3QgbG9jYWwgbmFtZSBmb3IgaW5oZXJpdGVkIGF0dHJpYnV0ZXNcbiAgaWYgKGVsZW1lbnQuaW5oZXJpdGVkKSB7XG4gICAgcmV0dXJuIHsgbG9jYWxOYW1lOiBucy5sb2NhbE5hbWUgfTtcbiAgfVxuXG4gIC8vIHBhcnNlICsgbG9nIGVmZmVjdGl2ZSBuc1xuICB2YXIgZWZmZWN0aXZlTnMgPSB0aGlzLmxvZ05hbWVzcGFjZVVzZWQobnMpO1xuXG4gIC8vIExPRyBBQ1RVQUwgbmFtZXNwYWNlIHVzZVxuICB0aGlzLmdldE5hbWVzcGFjZXMoKS5sb2dVc2VkKGVmZmVjdGl2ZU5zKTtcblxuICAvLyBzdHJpcCBwcmVmaXggaWYgc2FtZSBuYW1lc3BhY2UgbGlrZSBwYXJlbnRcbiAgaWYgKHRoaXMuaXNMb2NhbE5zKGVmZmVjdGl2ZU5zKSkge1xuICAgIHJldHVybiB7IGxvY2FsTmFtZTogbnMubG9jYWxOYW1lIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGFzc2lnbih7IGxvY2FsTmFtZTogbnMubG9jYWxOYW1lIH0sIGVmZmVjdGl2ZU5zKTtcbiAgfVxufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLnBhcnNlR2VuZXJpYyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICBib2R5ID0gdGhpcy5ib2R5O1xuXG4gIHZhciBhdHRyaWJ1dGVzID0gW107XG5cbiAgZm9yRWFjaChlbGVtZW50LCBmdW5jdGlvbih2YWwsIGtleSkge1xuXG4gICAgdmFyIG5vbk5zQXR0cjtcblxuICAgIGlmIChrZXkgPT09ICckYm9keScpIHtcbiAgICAgIGJvZHkucHVzaChuZXcgQm9keVNlcmlhbGl6ZXIoKS5idWlsZCh7IHR5cGU6ICdTdHJpbmcnIH0sIHZhbCkpO1xuICAgIH0gZWxzZVxuICAgIGlmIChrZXkgPT09ICckY2hpbGRyZW4nKSB7XG4gICAgICBmb3JFYWNoKHZhbCwgZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgICAgYm9keS5wdXNoKG5ldyBFbGVtZW50U2VyaWFsaXplcihzZWxmKS5idWlsZChjaGlsZCkpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlXG4gICAgaWYgKGtleS5pbmRleE9mKCckJykgIT09IDApIHtcbiAgICAgIG5vbk5zQXR0ciA9IHNlbGYucGFyc2VOc0F0dHJpYnV0ZShlbGVtZW50LCBrZXksIHZhbCk7XG5cbiAgICAgIGlmIChub25Oc0F0dHIpIHtcbiAgICAgICAgYXR0cmlidXRlcy5wdXNoKHsgbmFtZToga2V5LCB2YWx1ZTogdmFsIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGF0dHJpYnV0ZXM7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VOc0F0dHJpYnV0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5hbWUsIHZhbHVlKSB7XG4gIHZhciBtb2RlbCA9IGVsZW1lbnQuJG1vZGVsO1xuXG4gIHZhciBuYW1lTnMgPSBwYXJzZU5hbWVOUyhuYW1lKTtcblxuICB2YXIgbnM7XG5cbiAgLy8gcGFyc2UgeG1sbnM6Zm9vPVwiaHR0cDovL2Zvby5iYXJcIlxuICBpZiAobmFtZU5zLnByZWZpeCA9PT0gJ3htbG5zJykge1xuICAgIG5zID0geyBwcmVmaXg6IG5hbWVOcy5sb2NhbE5hbWUsIHVyaTogdmFsdWUgfTtcbiAgfVxuXG4gIC8vIHBhcnNlIHhtbG5zPVwiaHR0cDovL2Zvby5iYXJcIlxuICBpZiAoIW5hbWVOcy5wcmVmaXggJiYgbmFtZU5zLmxvY2FsTmFtZSA9PT0gJ3htbG5zJykge1xuICAgIG5zID0geyB1cmk6IHZhbHVlIH07XG4gIH1cblxuICBpZiAoIW5zKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IG5hbWUsXG4gICAgICB2YWx1ZTogdmFsdWVcbiAgICB9O1xuICB9XG5cbiAgaWYgKG1vZGVsICYmIG1vZGVsLmdldFBhY2thZ2UodmFsdWUpKSB7XG4gICAgLy8gcmVnaXN0ZXIgd2VsbCBrbm93biBuYW1lc3BhY2VcbiAgICB0aGlzLmxvZ05hbWVzcGFjZShucywgdHJ1ZSwgdHJ1ZSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbG9nIGN1c3RvbSBuYW1lc3BhY2UgZGlyZWN0bHkgYXMgdXNlZFxuICAgIHZhciBhY3R1YWxOcyA9IHRoaXMubG9nTmFtZXNwYWNlVXNlZChucywgdHJ1ZSk7XG5cbiAgICB0aGlzLmdldE5hbWVzcGFjZXMoKS5sb2dVc2VkKGFjdHVhbE5zKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIFBhcnNlIG5hbWVzcGFjZXMgYW5kIHJldHVybiBhIGxpc3Qgb2YgbGVmdCBvdmVyIGdlbmVyaWMgYXR0cmlidXRlc1xuICpcbiAqIEBwYXJhbSAge09iamVjdH0gZWxlbWVudFxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn1cbiAqL1xuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLnBhcnNlTnNBdHRyaWJ1dGVzID0gZnVuY3Rpb24oZWxlbWVudCwgYXR0cnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBnZW5lcmljQXR0cnMgPSBlbGVtZW50LiRhdHRycztcblxuICB2YXIgYXR0cmlidXRlcyA9IFtdO1xuXG4gIC8vIHBhcnNlIG5hbWVzcGFjZSBhdHRyaWJ1dGVzIGZpcnN0XG4gIC8vIGFuZCBsb2cgdGhlbS4gcHVzaCBub24gbmFtZXNwYWNlIGF0dHJpYnV0ZXMgdG8gYSBsaXN0XG4gIC8vIGFuZCBwcm9jZXNzIHRoZW0gbGF0ZXJcbiAgZm9yRWFjaChnZW5lcmljQXR0cnMsIGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG5cbiAgICB2YXIgbm9uTnNBdHRyID0gc2VsZi5wYXJzZU5zQXR0cmlidXRlKGVsZW1lbnQsIG5hbWUsIHZhbHVlKTtcblxuICAgIGlmIChub25Oc0F0dHIpIHtcbiAgICAgIGF0dHJpYnV0ZXMucHVzaChub25Oc0F0dHIpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGF0dHJpYnV0ZXM7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VHZW5lcmljQXR0cmlidXRlcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGF0dHJpYnV0ZXMpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZm9yRWFjaChhdHRyaWJ1dGVzLCBmdW5jdGlvbihhdHRyKSB7XG5cbiAgICAvLyBkbyBub3Qgc2VyaWFsaXplIHhzaTp0eXBlIGF0dHJpYnV0ZVxuICAgIC8vIGl0IGlzIHNldCBtYW51YWxseSBiYXNlZCBvbiB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIHR5cGVcbiAgICBpZiAoYXR0ci5uYW1lID09PSBYU0lfVFlQRSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBzZWxmLmFkZEF0dHJpYnV0ZShzZWxmLm5zQXR0cmlidXRlTmFtZShhdHRyLm5hbWUpLCBhdHRyLnZhbHVlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdtaXNzaW5nIG5hbWVzcGFjZSBpbmZvcm1hdGlvbiBmb3IgJyxcbiAgICAgICAgYXR0ci5uYW1lLCAnPScsIGF0dHIudmFsdWUsICdvbicsIGVsZW1lbnQsXG4gICAgICAgIGUpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VDb250YWlubWVudHMgPSBmdW5jdGlvbihwcm9wZXJ0aWVzKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgYm9keSA9IHRoaXMuYm9keSxcbiAgICAgIGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQ7XG5cbiAgZm9yRWFjaChwcm9wZXJ0aWVzLCBmdW5jdGlvbihwKSB7XG4gICAgdmFyIHZhbHVlID0gZWxlbWVudC5nZXQocC5uYW1lKSxcbiAgICAgICAgaXNSZWZlcmVuY2UgPSBwLmlzUmVmZXJlbmNlLFxuICAgICAgICBpc01hbnkgPSBwLmlzTWFueTtcblxuICAgIGlmICghaXNNYW55KSB7XG4gICAgICB2YWx1ZSA9IFsgdmFsdWUgXTtcbiAgICB9XG5cbiAgICBpZiAocC5pc0JvZHkpIHtcbiAgICAgIGJvZHkucHVzaChuZXcgQm9keVNlcmlhbGl6ZXIoKS5idWlsZChwLCB2YWx1ZVswXSkpO1xuICAgIH0gZWxzZVxuICAgIGlmIChpc1NpbXBsZVR5cGUocC50eXBlKSkge1xuICAgICAgZm9yRWFjaCh2YWx1ZSwgZnVuY3Rpb24odikge1xuICAgICAgICBib2R5LnB1c2gobmV3IFZhbHVlU2VyaWFsaXplcihzZWxmLmFkZFRhZ05hbWUoc2VsZi5uc1Byb3BlcnR5VGFnTmFtZShwKSkpLmJ1aWxkKHAsIHYpKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZVxuICAgIGlmIChpc1JlZmVyZW5jZSkge1xuICAgICAgZm9yRWFjaCh2YWx1ZSwgZnVuY3Rpb24odikge1xuICAgICAgICBib2R5LnB1c2gobmV3IFJlZmVyZW5jZVNlcmlhbGl6ZXIoc2VsZi5hZGRUYWdOYW1lKHNlbGYubnNQcm9wZXJ0eVRhZ05hbWUocCkpKS5idWlsZCh2KSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gYWxsb3cgc2VyaWFsaXphdGlvbiB2aWEgdHlwZVxuICAgICAgLy8gcmF0aGVyIHRoYW4gZWxlbWVudCBuYW1lXG4gICAgICB2YXIgYXNUeXBlID0gc2VyaWFsaXplQXNUeXBlKHApLFxuICAgICAgICAgIGFzUHJvcGVydHkgPSBzZXJpYWxpemVBc1Byb3BlcnR5KHApO1xuXG4gICAgICBmb3JFYWNoKHZhbHVlLCBmdW5jdGlvbih2KSB7XG4gICAgICAgIHZhciBzZXJpYWxpemVyO1xuXG4gICAgICAgIGlmIChhc1R5cGUpIHtcbiAgICAgICAgICBzZXJpYWxpemVyID0gbmV3IFR5cGVTZXJpYWxpemVyKHNlbGYsIHApO1xuICAgICAgICB9IGVsc2VcbiAgICAgICAgaWYgKGFzUHJvcGVydHkpIHtcbiAgICAgICAgICBzZXJpYWxpemVyID0gbmV3IEVsZW1lbnRTZXJpYWxpemVyKHNlbGYsIHApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNlcmlhbGl6ZXIgPSBuZXcgRWxlbWVudFNlcmlhbGl6ZXIoc2VsZik7XG4gICAgICAgIH1cblxuICAgICAgICBib2R5LnB1c2goc2VyaWFsaXplci5idWlsZCh2KSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLmdldE5hbWVzcGFjZXMgPSBmdW5jdGlvbihsb2NhbCkge1xuXG4gIHZhciBuYW1lc3BhY2VzID0gdGhpcy5uYW1lc3BhY2VzLFxuICAgICAgcGFyZW50ID0gdGhpcy5wYXJlbnQsXG4gICAgICBwYXJlbnROYW1lc3BhY2VzO1xuXG4gIGlmICghbmFtZXNwYWNlcykge1xuICAgIHBhcmVudE5hbWVzcGFjZXMgPSBwYXJlbnQgJiYgcGFyZW50LmdldE5hbWVzcGFjZXMoKTtcblxuICAgIGlmIChsb2NhbCB8fCAhcGFyZW50TmFtZXNwYWNlcykge1xuICAgICAgdGhpcy5uYW1lc3BhY2VzID0gbmFtZXNwYWNlcyA9IG5ldyBOYW1lc3BhY2VzKHBhcmVudE5hbWVzcGFjZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lc3BhY2VzID0gcGFyZW50TmFtZXNwYWNlcztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZXNwYWNlcztcbn07XG5cbkVsZW1lbnRTZXJpYWxpemVyLnByb3RvdHlwZS5sb2dOYW1lc3BhY2UgPSBmdW5jdGlvbihucywgd2VsbGtub3duLCBsb2NhbCkge1xuICB2YXIgbmFtZXNwYWNlcyA9IHRoaXMuZ2V0TmFtZXNwYWNlcyhsb2NhbCk7XG5cbiAgdmFyIG5zVXJpID0gbnMudXJpLFxuICAgICAgbnNQcmVmaXggPSBucy5wcmVmaXg7XG5cbiAgdmFyIGV4aXN0aW5nID0gbmFtZXNwYWNlcy5ieVVyaShuc1VyaSk7XG5cbiAgaWYgKG5zUHJlZml4ICE9PSAneG1sJyAmJiAoIWV4aXN0aW5nIHx8IGxvY2FsKSkge1xuICAgIG5hbWVzcGFjZXMuYWRkKG5zLCB3ZWxsa25vd24pO1xuICB9XG5cbiAgbmFtZXNwYWNlcy5tYXBQcmVmaXgobnNQcmVmaXgsIG5zVXJpKTtcblxuICByZXR1cm4gbnM7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUubG9nTmFtZXNwYWNlVXNlZCA9IGZ1bmN0aW9uKG5zLCBsb2NhbCkge1xuICB2YXIgZWxlbWVudCA9IHRoaXMuZWxlbWVudCxcbiAgICAgIG1vZGVsID0gZWxlbWVudC4kbW9kZWwsXG4gICAgICBuYW1lc3BhY2VzID0gdGhpcy5nZXROYW1lc3BhY2VzKGxvY2FsKTtcblxuICAvLyBucyBtYXkgYmVcbiAgLy9cbiAgLy8gICAqIHByZWZpeCBvbmx5XG4gIC8vICAgKiBwcmVmaXg6dXJpXG4gIC8vICAgKiBsb2NhbE5hbWUgb25seVxuXG4gIHZhciBwcmVmaXggPSBucy5wcmVmaXgsXG4gICAgICB1cmkgPSBucy51cmksXG4gICAgICBuZXdQcmVmaXgsIGlkeCxcbiAgICAgIHdlbGxrbm93blVyaTtcblxuICAvLyBoYW5kbGUgYW5vbnltb3VzIG5hbWVzcGFjZXMgKGVsZW1lbnRGb3JtPXVucXVhbGlmaWVkKSwgY2YuICMyM1xuICBpZiAoIXByZWZpeCAmJiAhdXJpKSB7XG4gICAgcmV0dXJuIHsgbG9jYWxOYW1lOiBucy5sb2NhbE5hbWUgfTtcbiAgfVxuXG4gIHdlbGxrbm93blVyaSA9IERFRkFVTFRfTlNfTUFQW3ByZWZpeF0gfHwgbW9kZWwgJiYgKG1vZGVsLmdldFBhY2thZ2UocHJlZml4KSB8fCB7fSkudXJpO1xuXG4gIHVyaSA9IHVyaSB8fCB3ZWxsa25vd25VcmkgfHwgbmFtZXNwYWNlcy51cmlCeVByZWZpeChwcmVmaXgpO1xuXG4gIGlmICghdXJpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdubyBuYW1lc3BhY2UgdXJpIGdpdmVuIGZvciBwcmVmaXggPCcgKyBwcmVmaXggKyAnPicpO1xuICB9XG5cbiAgbnMgPSBuYW1lc3BhY2VzLmJ5VXJpKHVyaSk7XG5cbiAgaWYgKCFucykge1xuICAgIG5ld1ByZWZpeCA9IHByZWZpeDtcbiAgICBpZHggPSAxO1xuXG4gICAgLy8gZmluZCBhIHByZWZpeCB0aGF0IGlzIG5vdCBtYXBwZWQgeWV0XG4gICAgd2hpbGUgKG5hbWVzcGFjZXMudXJpQnlQcmVmaXgobmV3UHJlZml4KSkge1xuICAgICAgbmV3UHJlZml4ID0gcHJlZml4ICsgJ18nICsgaWR4Kys7XG4gICAgfVxuXG4gICAgbnMgPSB0aGlzLmxvZ05hbWVzcGFjZSh7IHByZWZpeDogbmV3UHJlZml4LCB1cmk6IHVyaSB9LCB3ZWxsa25vd25VcmkgPT09IHVyaSk7XG4gIH1cblxuICBpZiAocHJlZml4KSB7XG4gICAgbmFtZXNwYWNlcy5tYXBQcmVmaXgocHJlZml4LCB1cmkpO1xuICB9XG5cbiAgcmV0dXJuIG5zO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLnBhcnNlQXR0cmlidXRlcyA9IGZ1bmN0aW9uKHByb3BlcnRpZXMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblxuICBmb3JFYWNoKHByb3BlcnRpZXMsIGZ1bmN0aW9uKHApIHtcblxuICAgIHZhciB2YWx1ZSA9IGVsZW1lbnQuZ2V0KHAubmFtZSk7XG5cbiAgICBpZiAocC5pc1JlZmVyZW5jZSkge1xuXG4gICAgICBpZiAoIXAuaXNNYW55KSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWUuaWQ7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgICAgICBmb3JFYWNoKHZhbHVlLCBmdW5jdGlvbih2KSB7XG4gICAgICAgICAgdmFsdWVzLnB1c2godi5pZCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBJRFJFRlMgaXMgYSB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBsaXN0IG9mIHJlZmVyZW5jZXMuXG4gICAgICAgIHZhbHVlID0gdmFsdWVzLmpvaW4oJyAnKTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHNlbGYuYWRkQXR0cmlidXRlKHNlbGYubnNBdHRyaWJ1dGVOYW1lKHApLCB2YWx1ZSk7XG4gIH0pO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLmFkZFRhZ05hbWUgPSBmdW5jdGlvbihuc1RhZ05hbWUpIHtcbiAgdmFyIGFjdHVhbE5zID0gdGhpcy5sb2dOYW1lc3BhY2VVc2VkKG5zVGFnTmFtZSk7XG5cbiAgdGhpcy5nZXROYW1lc3BhY2VzKCkubG9nVXNlZChhY3R1YWxOcyk7XG5cbiAgcmV0dXJuIG5zTmFtZShuc1RhZ05hbWUpO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLmFkZEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHZhciBhdHRycyA9IHRoaXMuYXR0cnM7XG5cbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhbHVlID0gZXNjYXBlQXR0cih2YWx1ZSk7XG4gIH1cblxuICBhdHRycy5wdXNoKHsgbmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlIH0pO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLnNlcmlhbGl6ZUF0dHJpYnV0ZXMgPSBmdW5jdGlvbih3cml0ZXIpIHtcbiAgdmFyIGF0dHJzID0gdGhpcy5hdHRycyxcbiAgICAgIG5hbWVzcGFjZXMgPSB0aGlzLm5hbWVzcGFjZXM7XG5cbiAgaWYgKG5hbWVzcGFjZXMpIHtcbiAgICBhdHRycyA9IGdldE5zQXR0cnMobmFtZXNwYWNlcykuY29uY2F0KGF0dHJzKTtcbiAgfVxuXG4gIGZvckVhY2goYXR0cnMsIGZ1bmN0aW9uKGEpIHtcbiAgICB3cml0ZXJcbiAgICAgIC5hcHBlbmQoJyAnKVxuICAgICAgLmFwcGVuZChuc05hbWUoYS5uYW1lKSkuYXBwZW5kKCc9XCInKS5hcHBlbmQoYS52YWx1ZSkuYXBwZW5kKCdcIicpO1xuICB9KTtcbn07XG5cbkVsZW1lbnRTZXJpYWxpemVyLnByb3RvdHlwZS5zZXJpYWxpemVUbyA9IGZ1bmN0aW9uKHdyaXRlcikge1xuICB2YXIgZmlyc3RCb2R5ID0gdGhpcy5ib2R5WzBdLFxuICAgICAgaW5kZW50ID0gZmlyc3RCb2R5ICYmIGZpcnN0Qm9keS5jb25zdHJ1Y3RvciAhPT0gQm9keVNlcmlhbGl6ZXI7XG5cbiAgd3JpdGVyXG4gICAgLmFwcGVuZEluZGVudCgpXG4gICAgLmFwcGVuZCgnPCcgKyB0aGlzLnRhZ05hbWUpO1xuXG4gIHRoaXMuc2VyaWFsaXplQXR0cmlidXRlcyh3cml0ZXIpO1xuXG4gIHdyaXRlci5hcHBlbmQoZmlyc3RCb2R5ID8gJz4nIDogJyAvPicpO1xuXG4gIGlmIChmaXJzdEJvZHkpIHtcblxuICAgIGlmIChpbmRlbnQpIHtcbiAgICAgIHdyaXRlclxuICAgICAgICAuYXBwZW5kTmV3TGluZSgpXG4gICAgICAgIC5pbmRlbnQoKTtcbiAgICB9XG5cbiAgICBmb3JFYWNoKHRoaXMuYm9keSwgZnVuY3Rpb24oYikge1xuICAgICAgYi5zZXJpYWxpemVUbyh3cml0ZXIpO1xuICAgIH0pO1xuXG4gICAgaWYgKGluZGVudCkge1xuICAgICAgd3JpdGVyXG4gICAgICAgIC51bmluZGVudCgpXG4gICAgICAgIC5hcHBlbmRJbmRlbnQoKTtcbiAgICB9XG5cbiAgICB3cml0ZXIuYXBwZW5kKCc8LycgKyB0aGlzLnRhZ05hbWUgKyAnPicpO1xuICB9XG5cbiAgd3JpdGVyLmFwcGVuZE5ld0xpbmUoKTtcbn07XG5cbi8qKlxuICogQSBzZXJpYWxpemVyIGZvciB0eXBlcyB0aGF0IGhhbmRsZXMgc2VyaWFsaXphdGlvbiBvZiBkYXRhIHR5cGVzXG4gKi9cbmZ1bmN0aW9uIFR5cGVTZXJpYWxpemVyKHBhcmVudCwgcHJvcGVydHlEZXNjcmlwdG9yKSB7XG4gIEVsZW1lbnRTZXJpYWxpemVyLmNhbGwodGhpcywgcGFyZW50LCBwcm9wZXJ0eURlc2NyaXB0b3IpO1xufVxuXG5pbmhlcml0cyhUeXBlU2VyaWFsaXplciwgRWxlbWVudFNlcmlhbGl6ZXIpO1xuXG5UeXBlU2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VOc0F0dHJpYnV0ZXMgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgLy8gZXh0cmFjdGVkIGF0dHJpYnV0ZXNcbiAgdmFyIGF0dHJpYnV0ZXMgPSBFbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VOc0F0dHJpYnV0ZXMuY2FsbCh0aGlzLCBlbGVtZW50KTtcblxuICB2YXIgZGVzY3JpcHRvciA9IGVsZW1lbnQuJGRlc2NyaXB0b3I7XG5cbiAgLy8gb25seSBzZXJpYWxpemUgeHNpOnR5cGUgaWYgbmVjZXNzYXJ5XG4gIGlmIChkZXNjcmlwdG9yLm5hbWUgPT09IHRoaXMucHJvcGVydHlEZXNjcmlwdG9yLnR5cGUpIHtcbiAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgfVxuXG4gIHZhciB0eXBlTnMgPSB0aGlzLnR5cGVOcyA9IHRoaXMubnNUYWdOYW1lKGRlc2NyaXB0b3IpO1xuICB0aGlzLmdldE5hbWVzcGFjZXMoKS5sb2dVc2VkKHRoaXMudHlwZU5zKTtcblxuICAvLyBhZGQgeHNpOnR5cGUgYXR0cmlidXRlIHRvIHJlcHJlc2VudCB0aGUgZWxlbWVudHNcbiAgLy8gYWN0dWFsIHR5cGVcblxuICB2YXIgcGtnID0gZWxlbWVudC4kbW9kZWwuZ2V0UGFja2FnZSh0eXBlTnMudXJpKSxcbiAgICAgIHR5cGVQcmVmaXggPSAocGtnLnhtbCAmJiBwa2cueG1sLnR5cGVQcmVmaXgpIHx8ICcnO1xuXG4gIHRoaXMuYWRkQXR0cmlidXRlKFxuICAgIHRoaXMubnNBdHRyaWJ1dGVOYW1lKFhTSV9UWVBFKSxcbiAgICAodHlwZU5zLnByZWZpeCA/IHR5cGVOcy5wcmVmaXggKyAnOicgOiAnJykgKyB0eXBlUHJlZml4ICsgZGVzY3JpcHRvci5ucy5sb2NhbE5hbWVcbiAgKTtcblxuICByZXR1cm4gYXR0cmlidXRlcztcbn07XG5cblR5cGVTZXJpYWxpemVyLnByb3RvdHlwZS5pc0xvY2FsTnMgPSBmdW5jdGlvbihucykge1xuICByZXR1cm4gbnMudXJpID09PSAodGhpcy50eXBlTnMgfHwgdGhpcy5ucykudXJpO1xufTtcblxuZnVuY3Rpb24gU2F2aW5nV3JpdGVyKCkge1xuICB0aGlzLnZhbHVlID0gJyc7XG5cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKHN0cikge1xuICAgIHRoaXMudmFsdWUgKz0gc3RyO1xuICB9O1xufVxuXG5mdW5jdGlvbiBGb3JtYXRpbmdXcml0ZXIob3V0LCBmb3JtYXQpIHtcblxuICB2YXIgaW5kZW50ID0gWycnXTtcblxuICB0aGlzLmFwcGVuZCA9IGZ1bmN0aW9uKHN0cikge1xuICAgIG91dC53cml0ZShzdHIpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgdGhpcy5hcHBlbmROZXdMaW5lID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKGZvcm1hdCkge1xuICAgICAgb3V0LndyaXRlKCdcXG4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICB0aGlzLmFwcGVuZEluZGVudCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmIChmb3JtYXQpIHtcbiAgICAgIG91dC53cml0ZShpbmRlbnQuam9pbignICAnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgdGhpcy5pbmRlbnQgPSBmdW5jdGlvbigpIHtcbiAgICBpbmRlbnQucHVzaCgnJyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgdGhpcy51bmluZGVudCA9IGZ1bmN0aW9uKCkge1xuICAgIGluZGVudC5wb3AoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbn1cblxuLyoqXG4gKiBBIHdyaXRlciBmb3IgbWV0YS1tb2RlbCBiYWNrZWQgZG9jdW1lbnQgdHJlZXNcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBvdXRwdXQgb3B0aW9ucyB0byBwYXNzIGludG8gdGhlIHdyaXRlclxuICovXG5mdW5jdGlvbiBXcml0ZXIob3B0aW9ucykge1xuXG4gIG9wdGlvbnMgPSBhc3NpZ24oeyBmb3JtYXQ6IGZhbHNlLCBwcmVhbWJsZTogdHJ1ZSB9LCBvcHRpb25zIHx8IHt9KTtcblxuICBmdW5jdGlvbiB0b1hNTCh0cmVlLCB3cml0ZXIpIHtcbiAgICB2YXIgaW50ZXJuYWxXcml0ZXIgPSB3cml0ZXIgfHwgbmV3IFNhdmluZ1dyaXRlcigpO1xuICAgIHZhciBmb3JtYXRpbmdXcml0ZXIgPSBuZXcgRm9ybWF0aW5nV3JpdGVyKGludGVybmFsV3JpdGVyLCBvcHRpb25zLmZvcm1hdCk7XG5cbiAgICBpZiAob3B0aW9ucy5wcmVhbWJsZSkge1xuICAgICAgZm9ybWF0aW5nV3JpdGVyLmFwcGVuZChYTUxfUFJFQU1CTEUpO1xuICAgIH1cblxuICAgIG5ldyBFbGVtZW50U2VyaWFsaXplcigpLmJ1aWxkKHRyZWUpLnNlcmlhbGl6ZVRvKGZvcm1hdGluZ1dyaXRlcik7XG5cbiAgICBpZiAoIXdyaXRlcikge1xuICAgICAgcmV0dXJuIGludGVybmFsV3JpdGVyLnZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdG9YTUw6IHRvWE1MXG4gIH07XG59XG5cbmV4cG9ydCB7IFJlYWRlciwgV3JpdGVyIH07XG4iLCJpbXBvcnQgeyBmb3JFYWNoLCBiaW5kLCBwaWNrLCBhc3NpZ24sIGlzU3RyaW5nLCBpc09iamVjdCB9IGZyb20gJ21pbi1kYXNoJztcblxuLyoqXG4gKiBNb2RkbGUgYmFzZSBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBCYXNlKCkgeyB9XG5cbkJhc2UucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuIHRoaXMuJG1vZGVsLnByb3BlcnRpZXMuZ2V0KHRoaXMsIG5hbWUpO1xufTtcblxuQmFzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgdGhpcy4kbW9kZWwucHJvcGVydGllcy5zZXQodGhpcywgbmFtZSwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBBIG1vZGVsIGVsZW1lbnQgZmFjdG9yeS5cbiAqXG4gKiBAcGFyYW0ge01vZGRsZX0gbW9kZWxcbiAqIEBwYXJhbSB7UHJvcGVydGllc30gcHJvcGVydGllc1xuICovXG5mdW5jdGlvbiBGYWN0b3J5KG1vZGVsLCBwcm9wZXJ0aWVzKSB7XG4gIHRoaXMubW9kZWwgPSBtb2RlbDtcbiAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbn1cblxuXG5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVUeXBlID0gZnVuY3Rpb24oZGVzY3JpcHRvcikge1xuXG4gIHZhciBtb2RlbCA9IHRoaXMubW9kZWw7XG5cbiAgdmFyIHByb3BzID0gdGhpcy5wcm9wZXJ0aWVzLFxuICAgICAgcHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShCYXNlLnByb3RvdHlwZSk7XG5cbiAgLy8gaW5pdGlhbGl6ZSBkZWZhdWx0IHZhbHVlc1xuICBmb3JFYWNoKGRlc2NyaXB0b3IucHJvcGVydGllcywgZnVuY3Rpb24ocCkge1xuICAgIGlmICghcC5pc01hbnkgJiYgcC5kZWZhdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHByb3RvdHlwZVtwLm5hbWVdID0gcC5kZWZhdWx0O1xuICAgIH1cbiAgfSk7XG5cbiAgcHJvcHMuZGVmaW5lTW9kZWwocHJvdG90eXBlLCBtb2RlbCk7XG4gIHByb3BzLmRlZmluZURlc2NyaXB0b3IocHJvdG90eXBlLCBkZXNjcmlwdG9yKTtcblxuICB2YXIgbmFtZSA9IGRlc2NyaXB0b3IubnMubmFtZTtcblxuICAvKipcbiAgICogVGhlIG5ldyB0eXBlIGNvbnN0cnVjdG9yXG4gICAqL1xuICBmdW5jdGlvbiBNb2RkbGVFbGVtZW50KGF0dHJzKSB7XG4gICAgcHJvcHMuZGVmaW5lKHRoaXMsICckdHlwZScsIHsgdmFsdWU6IG5hbWUsIGVudW1lcmFibGU6IHRydWUgfSk7XG4gICAgcHJvcHMuZGVmaW5lKHRoaXMsICckYXR0cnMnLCB7IHZhbHVlOiB7fSB9KTtcbiAgICBwcm9wcy5kZWZpbmUodGhpcywgJyRwYXJlbnQnLCB7IHdyaXRhYmxlOiB0cnVlIH0pO1xuXG4gICAgZm9yRWFjaChhdHRycywgYmluZChmdW5jdGlvbih2YWwsIGtleSkge1xuICAgICAgdGhpcy5zZXQoa2V5LCB2YWwpO1xuICAgIH0sIHRoaXMpKTtcbiAgfVxuXG4gIE1vZGRsZUVsZW1lbnQucHJvdG90eXBlID0gcHJvdG90eXBlO1xuXG4gIE1vZGRsZUVsZW1lbnQuaGFzVHlwZSA9IHByb3RvdHlwZS4kaW5zdGFuY2VPZiA9IHRoaXMubW9kZWwuaGFzVHlwZTtcblxuICAvLyBzdGF0aWMgbGlua3NcbiAgcHJvcHMuZGVmaW5lTW9kZWwoTW9kZGxlRWxlbWVudCwgbW9kZWwpO1xuICBwcm9wcy5kZWZpbmVEZXNjcmlwdG9yKE1vZGRsZUVsZW1lbnQsIGRlc2NyaXB0b3IpO1xuXG4gIHJldHVybiBNb2RkbGVFbGVtZW50O1xufTtcblxuLyoqXG4gKiBCdWlsdC1pbiBtb2RkbGUgdHlwZXNcbiAqL1xudmFyIEJVSUxUSU5TID0ge1xuICBTdHJpbmc6IHRydWUsXG4gIEJvb2xlYW46IHRydWUsXG4gIEludGVnZXI6IHRydWUsXG4gIFJlYWw6IHRydWUsXG4gIEVsZW1lbnQ6IHRydWVcbn07XG5cbi8qKlxuICogQ29udmVydGVycyBmb3IgYnVpbHQgaW4gdHlwZXMgZnJvbSBzdHJpbmcgcmVwcmVzZW50YXRpb25zXG4gKi9cbnZhciBUWVBFX0NPTlZFUlRFUlMgPSB7XG4gIFN0cmluZzogZnVuY3Rpb24ocykgeyByZXR1cm4gczsgfSxcbiAgQm9vbGVhbjogZnVuY3Rpb24ocykgeyByZXR1cm4gcyA9PT0gJ3RydWUnOyB9LFxuICBJbnRlZ2VyOiBmdW5jdGlvbihzKSB7IHJldHVybiBwYXJzZUludChzLCAxMCk7IH0sXG4gIFJlYWw6IGZ1bmN0aW9uKHMpIHsgcmV0dXJuIHBhcnNlRmxvYXQocywgMTApOyB9XG59O1xuXG4vKipcbiAqIENvbnZlcnQgYSB0eXBlIHRvIGl0cyByZWFsIHJlcHJlc2VudGF0aW9uXG4gKi9cbmZ1bmN0aW9uIGNvZXJjZVR5cGUodHlwZSwgdmFsdWUpIHtcblxuICB2YXIgY29udmVydGVyID0gVFlQRV9DT05WRVJURVJTW3R5cGVdO1xuXG4gIGlmIChjb252ZXJ0ZXIpIHtcbiAgICByZXR1cm4gY29udmVydGVyKHZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gd2hldGhlciB0aGUgZ2l2ZW4gdHlwZSBpcyBidWlsdC1pblxuICovXG5mdW5jdGlvbiBpc0J1aWx0SW4odHlwZSkge1xuICByZXR1cm4gISFCVUlMVElOU1t0eXBlXTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gd2hldGhlciB0aGUgZ2l2ZW4gdHlwZSBpcyBzaW1wbGVcbiAqL1xuZnVuY3Rpb24gaXNTaW1wbGUodHlwZSkge1xuICByZXR1cm4gISFUWVBFX0NPTlZFUlRFUlNbdHlwZV07XG59XG5cbi8qKlxuICogUGFyc2VzIGEgbmFtZXNwYWNlZCBhdHRyaWJ1dGUgbmFtZSBvZiB0aGUgZm9ybSAobnM6KWxvY2FsTmFtZSB0byBhbiBvYmplY3QsXG4gKiBnaXZlbiBhIGRlZmF1bHQgcHJlZml4IHRvIGFzc3VtZSBpbiBjYXNlIG5vIGV4cGxpY2l0IG5hbWVzcGFjZSBpcyBnaXZlbi5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtTdHJpbmd9IFtkZWZhdWx0UHJlZml4XSB0aGUgZGVmYXVsdCBwcmVmaXggdG8gdGFrZSwgaWYgbm9uZSBpcyBwcmVzZW50LlxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIHBhcnNlZCBuYW1lXG4gKi9cbmZ1bmN0aW9uIHBhcnNlTmFtZShuYW1lLCBkZWZhdWx0UHJlZml4KSB7XG4gIHZhciBwYXJ0cyA9IG5hbWUuc3BsaXQoLzovKSxcbiAgICAgIGxvY2FsTmFtZSwgcHJlZml4O1xuXG4gIC8vIG5vIHByZWZpeCAoaS5lLiBvbmx5IGxvY2FsIG5hbWUpXG4gIGlmIChwYXJ0cy5sZW5ndGggPT09IDEpIHtcbiAgICBsb2NhbE5hbWUgPSBuYW1lO1xuICAgIHByZWZpeCA9IGRlZmF1bHRQcmVmaXg7XG4gIH0gZWxzZVxuICAvLyBwcmVmaXggKyBsb2NhbCBuYW1lXG4gIGlmIChwYXJ0cy5sZW5ndGggPT09IDIpIHtcbiAgICBsb2NhbE5hbWUgPSBwYXJ0c1sxXTtcbiAgICBwcmVmaXggPSBwYXJ0c1swXTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIDxwcmVmaXg6bG9jYWxOYW1lPiBvciA8bG9jYWxOYW1lPiwgZ290ICcgKyBuYW1lKTtcbiAgfVxuXG4gIG5hbWUgPSAocHJlZml4ID8gcHJlZml4ICsgJzonIDogJycpICsgbG9jYWxOYW1lO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogbmFtZSxcbiAgICBwcmVmaXg6IHByZWZpeCxcbiAgICBsb2NhbE5hbWU6IGxvY2FsTmFtZVxuICB9O1xufVxuXG4vKipcbiAqIEEgdXRpbGl0eSB0byBidWlsZCBlbGVtZW50IGRlc2NyaXB0b3JzLlxuICovXG5mdW5jdGlvbiBEZXNjcmlwdG9yQnVpbGRlcihuYW1lTnMpIHtcbiAgdGhpcy5ucyA9IG5hbWVOcztcbiAgdGhpcy5uYW1lID0gbmFtZU5zLm5hbWU7XG4gIHRoaXMuYWxsVHlwZXMgPSBbXTtcbiAgdGhpcy5hbGxUeXBlc0J5TmFtZSA9IHt9O1xuICB0aGlzLnByb3BlcnRpZXMgPSBbXTtcbiAgdGhpcy5wcm9wZXJ0aWVzQnlOYW1lID0ge307XG59XG5cblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLmJ1aWxkID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBwaWNrKHRoaXMsIFtcbiAgICAnbnMnLFxuICAgICduYW1lJyxcbiAgICAnYWxsVHlwZXMnLFxuICAgICdhbGxUeXBlc0J5TmFtZScsXG4gICAgJ3Byb3BlcnRpZXMnLFxuICAgICdwcm9wZXJ0aWVzQnlOYW1lJyxcbiAgICAnYm9keVByb3BlcnR5JyxcbiAgICAnaWRQcm9wZXJ0eSdcbiAgXSk7XG59O1xuXG4vKipcbiAqIEFkZCBwcm9wZXJ0eSBhdCBnaXZlbiBpbmRleC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcFxuICogQHBhcmFtIHtOdW1iZXJ9IFtpZHhdXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFt2YWxpZGF0ZT10cnVlXVxuICovXG5EZXNjcmlwdG9yQnVpbGRlci5wcm90b3R5cGUuYWRkUHJvcGVydHkgPSBmdW5jdGlvbihwLCBpZHgsIHZhbGlkYXRlKSB7XG5cbiAgaWYgKHR5cGVvZiBpZHggPT09ICdib29sZWFuJykge1xuICAgIHZhbGlkYXRlID0gaWR4O1xuICAgIGlkeCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHRoaXMuYWRkTmFtZWRQcm9wZXJ0eShwLCB2YWxpZGF0ZSAhPT0gZmFsc2UpO1xuXG4gIHZhciBwcm9wZXJ0aWVzID0gdGhpcy5wcm9wZXJ0aWVzO1xuXG4gIGlmIChpZHggIT09IHVuZGVmaW5lZCkge1xuICAgIHByb3BlcnRpZXMuc3BsaWNlKGlkeCwgMCwgcCk7XG4gIH0gZWxzZSB7XG4gICAgcHJvcGVydGllcy5wdXNoKHApO1xuICB9XG59O1xuXG5cbkRlc2NyaXB0b3JCdWlsZGVyLnByb3RvdHlwZS5yZXBsYWNlUHJvcGVydHkgPSBmdW5jdGlvbihvbGRQcm9wZXJ0eSwgbmV3UHJvcGVydHksIHJlcGxhY2UpIHtcbiAgdmFyIG9sZE5hbWVOcyA9IG9sZFByb3BlcnR5Lm5zO1xuXG4gIHZhciBwcm9wcyA9IHRoaXMucHJvcGVydGllcyxcbiAgICAgIHByb3BlcnRpZXNCeU5hbWUgPSB0aGlzLnByb3BlcnRpZXNCeU5hbWUsXG4gICAgICByZW5hbWUgPSBvbGRQcm9wZXJ0eS5uYW1lICE9PSBuZXdQcm9wZXJ0eS5uYW1lO1xuXG4gIGlmIChvbGRQcm9wZXJ0eS5pc0lkKSB7XG4gICAgaWYgKCFuZXdQcm9wZXJ0eS5pc0lkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdwcm9wZXJ0eSA8JyArIG5ld1Byb3BlcnR5Lm5zLm5hbWUgKyAnPiBtdXN0IGJlIGlkIHByb3BlcnR5ICcgK1xuICAgICAgICAndG8gcmVmaW5lIDwnICsgb2xkUHJvcGVydHkubnMubmFtZSArICc+Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXRJZFByb3BlcnR5KG5ld1Byb3BlcnR5LCBmYWxzZSk7XG4gIH1cblxuICBpZiAob2xkUHJvcGVydHkuaXNCb2R5KSB7XG5cbiAgICBpZiAoIW5ld1Byb3BlcnR5LmlzQm9keSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAncHJvcGVydHkgPCcgKyBuZXdQcm9wZXJ0eS5ucy5uYW1lICsgJz4gbXVzdCBiZSBib2R5IHByb3BlcnR5ICcgK1xuICAgICAgICAndG8gcmVmaW5lIDwnICsgb2xkUHJvcGVydHkubnMubmFtZSArICc+Jyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogQ2hlY2sgY29tcGF0aWJpbGl0eVxuICAgIHRoaXMuc2V0Qm9keVByb3BlcnR5KG5ld1Byb3BlcnR5LCBmYWxzZSk7XG4gIH1cblxuICAvLyB2YWxpZGF0ZSBleGlzdGVuY2UgYW5kIGdldCBsb2NhdGlvbiBvZiBvbGQgcHJvcGVydHlcbiAgdmFyIGlkeCA9IHByb3BzLmluZGV4T2Yob2xkUHJvcGVydHkpO1xuICBpZiAoaWR4ID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvcGVydHkgPCcgKyBvbGROYW1lTnMubmFtZSArICc+IG5vdCBmb3VuZCBpbiBwcm9wZXJ0eSBsaXN0Jyk7XG4gIH1cblxuICAvLyByZW1vdmUgb2xkIHByb3BlcnR5XG4gIHByb3BzLnNwbGljZShpZHgsIDEpO1xuXG4gIC8vIHJlcGxhY2luZyB0aGUgbmFtZWQgcHJvcGVydHkgaXMgaW50ZW50aW9uYWxcbiAgLy9cbiAgLy8gICogdmFsaWRhdGUgb25seSBpZiB0aGlzIGlzIGEgXCJyZW5hbWVcIiBvcGVyYXRpb25cbiAgLy8gICogYWRkIGF0IHNwZWNpZmljIGluZGV4IHVubGVzcyB3ZSBcInJlcGxhY2VcIlxuICAvL1xuICB0aGlzLmFkZFByb3BlcnR5KG5ld1Byb3BlcnR5LCByZXBsYWNlID8gdW5kZWZpbmVkIDogaWR4LCByZW5hbWUpO1xuXG4gIC8vIG1ha2UgbmV3IHByb3BlcnR5IGF2YWlsYWJsZSB1bmRlciBvbGQgbmFtZVxuICBwcm9wZXJ0aWVzQnlOYW1lW29sZE5hbWVOcy5uYW1lXSA9IHByb3BlcnRpZXNCeU5hbWVbb2xkTmFtZU5zLmxvY2FsTmFtZV0gPSBuZXdQcm9wZXJ0eTtcbn07XG5cblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLnJlZGVmaW5lUHJvcGVydHkgPSBmdW5jdGlvbihwLCB0YXJnZXRQcm9wZXJ0eU5hbWUsIHJlcGxhY2UpIHtcblxuICB2YXIgbnNQcmVmaXggPSBwLm5zLnByZWZpeDtcbiAgdmFyIHBhcnRzID0gdGFyZ2V0UHJvcGVydHlOYW1lLnNwbGl0KCcjJyk7XG5cbiAgdmFyIG5hbWUgPSBwYXJzZU5hbWUocGFydHNbMF0sIG5zUHJlZml4KTtcbiAgdmFyIGF0dHJOYW1lID0gcGFyc2VOYW1lKHBhcnRzWzFdLCBuYW1lLnByZWZpeCkubmFtZTtcblxuICB2YXIgcmVkZWZpbmVkUHJvcGVydHkgPSB0aGlzLnByb3BlcnRpZXNCeU5hbWVbYXR0ck5hbWVdO1xuICBpZiAoIXJlZGVmaW5lZFByb3BlcnR5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdyZWZpbmVkIHByb3BlcnR5IDwnICsgYXR0ck5hbWUgKyAnPiBub3QgZm91bmQnKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnJlcGxhY2VQcm9wZXJ0eShyZWRlZmluZWRQcm9wZXJ0eSwgcCwgcmVwbGFjZSk7XG4gIH1cblxuICBkZWxldGUgcC5yZWRlZmluZXM7XG59O1xuXG5EZXNjcmlwdG9yQnVpbGRlci5wcm90b3R5cGUuYWRkTmFtZWRQcm9wZXJ0eSA9IGZ1bmN0aW9uKHAsIHZhbGlkYXRlKSB7XG4gIHZhciBucyA9IHAubnMsXG4gICAgICBwcm9wc0J5TmFtZSA9IHRoaXMucHJvcGVydGllc0J5TmFtZTtcblxuICBpZiAodmFsaWRhdGUpIHtcbiAgICB0aGlzLmFzc2VydE5vdERlZmluZWQocCwgbnMubmFtZSk7XG4gICAgdGhpcy5hc3NlcnROb3REZWZpbmVkKHAsIG5zLmxvY2FsTmFtZSk7XG4gIH1cblxuICBwcm9wc0J5TmFtZVtucy5uYW1lXSA9IHByb3BzQnlOYW1lW25zLmxvY2FsTmFtZV0gPSBwO1xufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLnJlbW92ZU5hbWVkUHJvcGVydHkgPSBmdW5jdGlvbihwKSB7XG4gIHZhciBucyA9IHAubnMsXG4gICAgICBwcm9wc0J5TmFtZSA9IHRoaXMucHJvcGVydGllc0J5TmFtZTtcblxuICBkZWxldGUgcHJvcHNCeU5hbWVbbnMubmFtZV07XG4gIGRlbGV0ZSBwcm9wc0J5TmFtZVtucy5sb2NhbE5hbWVdO1xufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLnNldEJvZHlQcm9wZXJ0eSA9IGZ1bmN0aW9uKHAsIHZhbGlkYXRlKSB7XG5cbiAgaWYgKHZhbGlkYXRlICYmIHRoaXMuYm9keVByb3BlcnR5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ2JvZHkgcHJvcGVydHkgZGVmaW5lZCBtdWx0aXBsZSB0aW1lcyAnICtcbiAgICAgICcoPCcgKyB0aGlzLmJvZHlQcm9wZXJ0eS5ucy5uYW1lICsgJz4sIDwnICsgcC5ucy5uYW1lICsgJz4pJyk7XG4gIH1cblxuICB0aGlzLmJvZHlQcm9wZXJ0eSA9IHA7XG59O1xuXG5EZXNjcmlwdG9yQnVpbGRlci5wcm90b3R5cGUuc2V0SWRQcm9wZXJ0eSA9IGZ1bmN0aW9uKHAsIHZhbGlkYXRlKSB7XG5cbiAgaWYgKHZhbGlkYXRlICYmIHRoaXMuaWRQcm9wZXJ0eSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdpZCBwcm9wZXJ0eSBkZWZpbmVkIG11bHRpcGxlIHRpbWVzICcgK1xuICAgICAgJyg8JyArIHRoaXMuaWRQcm9wZXJ0eS5ucy5uYW1lICsgJz4sIDwnICsgcC5ucy5uYW1lICsgJz4pJyk7XG4gIH1cblxuICB0aGlzLmlkUHJvcGVydHkgPSBwO1xufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLmFzc2VydE5vdERlZmluZWQgPSBmdW5jdGlvbihwLCBuYW1lKSB7XG4gIHZhciBwcm9wZXJ0eU5hbWUgPSBwLm5hbWUsXG4gICAgICBkZWZpbmVkUHJvcGVydHkgPSB0aGlzLnByb3BlcnRpZXNCeU5hbWVbcHJvcGVydHlOYW1lXTtcblxuICBpZiAoZGVmaW5lZFByb3BlcnR5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ3Byb3BlcnR5IDwnICsgcHJvcGVydHlOYW1lICsgJz4gYWxyZWFkeSBkZWZpbmVkOyAnICtcbiAgICAgICdvdmVycmlkZSBvZiA8JyArIGRlZmluZWRQcm9wZXJ0eS5kZWZpbmVkQnkubnMubmFtZSArICcjJyArIGRlZmluZWRQcm9wZXJ0eS5ucy5uYW1lICsgJz4gYnkgJyArXG4gICAgICAnPCcgKyBwLmRlZmluZWRCeS5ucy5uYW1lICsgJyMnICsgcC5ucy5uYW1lICsgJz4gbm90IGFsbG93ZWQgd2l0aG91dCByZWRlZmluZXMnKTtcbiAgfVxufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLmhhc1Byb3BlcnR5ID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzQnlOYW1lW25hbWVdO1xufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLmFkZFRyYWl0ID0gZnVuY3Rpb24odCwgaW5oZXJpdGVkKSB7XG5cbiAgdmFyIHR5cGVzQnlOYW1lID0gdGhpcy5hbGxUeXBlc0J5TmFtZSxcbiAgICAgIHR5cGVzID0gdGhpcy5hbGxUeXBlcztcblxuICB2YXIgdHlwZU5hbWUgPSB0Lm5hbWU7XG5cbiAgaWYgKHR5cGVOYW1lIGluIHR5cGVzQnlOYW1lKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZm9yRWFjaCh0LnByb3BlcnRpZXMsIGJpbmQoZnVuY3Rpb24ocCkge1xuXG4gICAgLy8gY2xvbmUgcHJvcGVydHkgdG8gYWxsb3cgZXh0ZW5zaW9uc1xuICAgIHAgPSBhc3NpZ24oe30sIHAsIHtcbiAgICAgIG5hbWU6IHAubnMubG9jYWxOYW1lLFxuICAgICAgaW5oZXJpdGVkOiBpbmhlcml0ZWRcbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwLCAnZGVmaW5lZEJ5Jywge1xuICAgICAgdmFsdWU6IHRcbiAgICB9KTtcblxuICAgIHZhciByZXBsYWNlcyA9IHAucmVwbGFjZXMsXG4gICAgICAgIHJlZGVmaW5lcyA9IHAucmVkZWZpbmVzO1xuXG4gICAgLy8gYWRkIHJlcGxhY2UvcmVkZWZpbmUgc3VwcG9ydFxuICAgIGlmIChyZXBsYWNlcyB8fCByZWRlZmluZXMpIHtcbiAgICAgIHRoaXMucmVkZWZpbmVQcm9wZXJ0eShwLCByZXBsYWNlcyB8fCByZWRlZmluZXMsIHJlcGxhY2VzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHAuaXNCb2R5KSB7XG4gICAgICAgIHRoaXMuc2V0Qm9keVByb3BlcnR5KHApO1xuICAgICAgfVxuICAgICAgaWYgKHAuaXNJZCkge1xuICAgICAgICB0aGlzLnNldElkUHJvcGVydHkocCk7XG4gICAgICB9XG4gICAgICB0aGlzLmFkZFByb3BlcnR5KHApO1xuICAgIH1cbiAgfSwgdGhpcykpO1xuXG4gIHR5cGVzLnB1c2godCk7XG4gIHR5cGVzQnlOYW1lW3R5cGVOYW1lXSA9IHQ7XG59O1xuXG4vKipcbiAqIEEgcmVnaXN0cnkgb2YgTW9kZGxlIHBhY2thZ2VzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8UGFja2FnZT59IHBhY2thZ2VzXG4gKiBAcGFyYW0ge1Byb3BlcnRpZXN9IHByb3BlcnRpZXNcbiAqL1xuZnVuY3Rpb24gUmVnaXN0cnkocGFja2FnZXMsIHByb3BlcnRpZXMpIHtcbiAgdGhpcy5wYWNrYWdlTWFwID0ge307XG4gIHRoaXMudHlwZU1hcCA9IHt9O1xuXG4gIHRoaXMucGFja2FnZXMgPSBbXTtcblxuICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuXG4gIGZvckVhY2gocGFja2FnZXMsIGJpbmQodGhpcy5yZWdpc3RlclBhY2thZ2UsIHRoaXMpKTtcbn1cblxuXG5SZWdpc3RyeS5wcm90b3R5cGUuZ2V0UGFja2FnZSA9IGZ1bmN0aW9uKHVyaU9yUHJlZml4KSB7XG4gIHJldHVybiB0aGlzLnBhY2thZ2VNYXBbdXJpT3JQcmVmaXhdO1xufTtcblxuUmVnaXN0cnkucHJvdG90eXBlLmdldFBhY2thZ2VzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnBhY2thZ2VzO1xufTtcblxuXG5SZWdpc3RyeS5wcm90b3R5cGUucmVnaXN0ZXJQYWNrYWdlID0gZnVuY3Rpb24ocGtnKSB7XG5cbiAgLy8gY29weSBwYWNrYWdlXG4gIHBrZyA9IGFzc2lnbih7fSwgcGtnKTtcblxuICB2YXIgcGtnTWFwID0gdGhpcy5wYWNrYWdlTWFwO1xuXG4gIGVuc3VyZUF2YWlsYWJsZShwa2dNYXAsIHBrZywgJ3ByZWZpeCcpO1xuICBlbnN1cmVBdmFpbGFibGUocGtnTWFwLCBwa2csICd1cmknKTtcblxuICAvLyByZWdpc3RlciB0eXBlc1xuICBmb3JFYWNoKHBrZy50eXBlcywgYmluZChmdW5jdGlvbihkZXNjcmlwdG9yKSB7XG4gICAgdGhpcy5yZWdpc3RlclR5cGUoZGVzY3JpcHRvciwgcGtnKTtcbiAgfSwgdGhpcykpO1xuXG4gIHBrZ01hcFtwa2cudXJpXSA9IHBrZ01hcFtwa2cucHJlZml4XSA9IHBrZztcbiAgdGhpcy5wYWNrYWdlcy5wdXNoKHBrZyk7XG59O1xuXG5cbi8qKlxuICogUmVnaXN0ZXIgYSB0eXBlIGZyb20gYSBzcGVjaWZpYyBwYWNrYWdlIHdpdGggdXNcbiAqL1xuUmVnaXN0cnkucHJvdG90eXBlLnJlZ2lzdGVyVHlwZSA9IGZ1bmN0aW9uKHR5cGUsIHBrZykge1xuXG4gIHR5cGUgPSBhc3NpZ24oe30sIHR5cGUsIHtcbiAgICBzdXBlckNsYXNzOiAodHlwZS5zdXBlckNsYXNzIHx8IFtdKS5zbGljZSgpLFxuICAgIGV4dGVuZHM6ICh0eXBlLmV4dGVuZHMgfHwgW10pLnNsaWNlKCksXG4gICAgcHJvcGVydGllczogKHR5cGUucHJvcGVydGllcyB8fCBbXSkuc2xpY2UoKSxcbiAgICBtZXRhOiBhc3NpZ24oKHR5cGUubWV0YSB8fCB7fSkpXG4gIH0pO1xuXG4gIHZhciBucyA9IHBhcnNlTmFtZSh0eXBlLm5hbWUsIHBrZy5wcmVmaXgpLFxuICAgICAgbmFtZSA9IG5zLm5hbWUsXG4gICAgICBwcm9wZXJ0aWVzQnlOYW1lID0ge307XG5cbiAgLy8gcGFyc2UgcHJvcGVydGllc1xuICBmb3JFYWNoKHR5cGUucHJvcGVydGllcywgYmluZChmdW5jdGlvbihwKSB7XG5cbiAgICAvLyBuYW1lc3BhY2UgcHJvcGVydHkgbmFtZXNcbiAgICB2YXIgcHJvcGVydHlOcyA9IHBhcnNlTmFtZShwLm5hbWUsIG5zLnByZWZpeCksXG4gICAgICAgIHByb3BlcnR5TmFtZSA9IHByb3BlcnR5TnMubmFtZTtcblxuICAgIC8vIG5hbWVzcGFjZSBwcm9wZXJ0eSB0eXBlc1xuICAgIGlmICghaXNCdWlsdEluKHAudHlwZSkpIHtcbiAgICAgIHAudHlwZSA9IHBhcnNlTmFtZShwLnR5cGUsIHByb3BlcnR5TnMucHJlZml4KS5uYW1lO1xuICAgIH1cblxuICAgIGFzc2lnbihwLCB7XG4gICAgICBuczogcHJvcGVydHlOcyxcbiAgICAgIG5hbWU6IHByb3BlcnR5TmFtZVxuICAgIH0pO1xuXG4gICAgcHJvcGVydGllc0J5TmFtZVtwcm9wZXJ0eU5hbWVdID0gcDtcbiAgfSwgdGhpcykpO1xuXG4gIC8vIHVwZGF0ZSBucyArIG5hbWVcbiAgYXNzaWduKHR5cGUsIHtcbiAgICBuczogbnMsXG4gICAgbmFtZTogbmFtZSxcbiAgICBwcm9wZXJ0aWVzQnlOYW1lOiBwcm9wZXJ0aWVzQnlOYW1lXG4gIH0pO1xuXG4gIGZvckVhY2godHlwZS5leHRlbmRzLCBiaW5kKGZ1bmN0aW9uKGV4dGVuZHNOYW1lKSB7XG4gICAgdmFyIGV4dGVuZGVkID0gdGhpcy50eXBlTWFwW2V4dGVuZHNOYW1lXTtcblxuICAgIGV4dGVuZGVkLnRyYWl0cyA9IGV4dGVuZGVkLnRyYWl0cyB8fCBbXTtcbiAgICBleHRlbmRlZC50cmFpdHMucHVzaChuYW1lKTtcbiAgfSwgdGhpcykpO1xuXG4gIC8vIGxpbmsgdG8gcGFja2FnZVxuICB0aGlzLmRlZmluZVBhY2thZ2UodHlwZSwgcGtnKTtcblxuICAvLyByZWdpc3RlclxuICB0aGlzLnR5cGVNYXBbbmFtZV0gPSB0eXBlO1xufTtcblxuXG4vKipcbiAqIFRyYXZlcnNlIHRoZSB0eXBlIGhpZXJhcmNoeSBmcm9tIGJvdHRvbSB0byB0b3AsXG4gKiBjYWxsaW5nIGl0ZXJhdG9yIHdpdGggKHR5cGUsIGluaGVyaXRlZCkgZm9yIGFsbCBlbGVtZW50cyBpblxuICogdGhlIGluaGVyaXRhbmNlIGNoYWluLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBuc05hbWVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdG9yXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFt0cmFpdD1mYWxzZV1cbiAqL1xuUmVnaXN0cnkucHJvdG90eXBlLm1hcFR5cGVzID0gZnVuY3Rpb24obnNOYW1lLCBpdGVyYXRvciwgdHJhaXQpIHtcblxuICB2YXIgdHlwZSA9IGlzQnVpbHRJbihuc05hbWUubmFtZSkgPyB7IG5hbWU6IG5zTmFtZS5uYW1lIH0gOiB0aGlzLnR5cGVNYXBbbnNOYW1lLm5hbWVdO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvKipcbiAgICogVHJhdmVyc2UgdGhlIHNlbGVjdGVkIHRyYWl0LlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2xzXG4gICAqL1xuICBmdW5jdGlvbiB0cmF2ZXJzZVRyYWl0KGNscykge1xuICAgIHJldHVybiB0cmF2ZXJzZVN1cGVyKGNscywgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhdmVyc2UgdGhlIHNlbGVjdGVkIHN1cGVyIHR5cGUgb3IgdHJhaXRcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGNsc1xuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFt0cmFpdD1mYWxzZV1cbiAgICovXG4gIGZ1bmN0aW9uIHRyYXZlcnNlU3VwZXIoY2xzLCB0cmFpdCkge1xuICAgIHZhciBwYXJlbnROcyA9IHBhcnNlTmFtZShjbHMsIGlzQnVpbHRJbihjbHMpID8gJycgOiBuc05hbWUucHJlZml4KTtcbiAgICBzZWxmLm1hcFR5cGVzKHBhcmVudE5zLCBpdGVyYXRvciwgdHJhaXQpO1xuICB9XG5cbiAgaWYgKCF0eXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIHR5cGUgPCcgKyBuc05hbWUubmFtZSArICc+Jyk7XG4gIH1cblxuICBmb3JFYWNoKHR5cGUuc3VwZXJDbGFzcywgdHJhaXQgPyB0cmF2ZXJzZVRyYWl0IDogdHJhdmVyc2VTdXBlcik7XG5cbiAgLy8gY2FsbCBpdGVyYXRvciB3aXRoICh0eXBlLCBpbmhlcml0ZWQ9IXRyYWl0KVxuICBpdGVyYXRvcih0eXBlLCAhdHJhaXQpO1xuXG4gIGZvckVhY2godHlwZS50cmFpdHMsIHRyYXZlcnNlVHJhaXQpO1xufTtcblxuXG4vKipcbiAqIFJldHVybnMgdGhlIGVmZmVjdGl2ZSBkZXNjcmlwdG9yIGZvciBhIHR5cGUuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSB0eXBlIHRoZSBuYW1lc3BhY2VkIG5hbWUgKG5zOmxvY2FsTmFtZSkgb2YgdGhlIHR5cGVcbiAqXG4gKiBAcmV0dXJuIHtEZXNjcmlwdG9yfSB0aGUgcmVzdWx0aW5nIGVmZmVjdGl2ZSBkZXNjcmlwdG9yXG4gKi9cblJlZ2lzdHJ5LnByb3RvdHlwZS5nZXRFZmZlY3RpdmVEZXNjcmlwdG9yID0gZnVuY3Rpb24obmFtZSkge1xuXG4gIHZhciBuc05hbWUgPSBwYXJzZU5hbWUobmFtZSk7XG5cbiAgdmFyIGJ1aWxkZXIgPSBuZXcgRGVzY3JpcHRvckJ1aWxkZXIobnNOYW1lKTtcblxuICB0aGlzLm1hcFR5cGVzKG5zTmFtZSwgZnVuY3Rpb24odHlwZSwgaW5oZXJpdGVkKSB7XG4gICAgYnVpbGRlci5hZGRUcmFpdCh0eXBlLCBpbmhlcml0ZWQpO1xuICB9KTtcblxuICB2YXIgZGVzY3JpcHRvciA9IGJ1aWxkZXIuYnVpbGQoKTtcblxuICAvLyBkZWZpbmUgcGFja2FnZSBsaW5rXG4gIHRoaXMuZGVmaW5lUGFja2FnZShkZXNjcmlwdG9yLCBkZXNjcmlwdG9yLmFsbFR5cGVzW2Rlc2NyaXB0b3IuYWxsVHlwZXMubGVuZ3RoIC0gMV0uJHBrZyk7XG5cbiAgcmV0dXJuIGRlc2NyaXB0b3I7XG59O1xuXG5cblJlZ2lzdHJ5LnByb3RvdHlwZS5kZWZpbmVQYWNrYWdlID0gZnVuY3Rpb24odGFyZ2V0LCBwa2cpIHtcbiAgdGhpcy5wcm9wZXJ0aWVzLmRlZmluZSh0YXJnZXQsICckcGtnJywgeyB2YWx1ZTogcGtnIH0pO1xufTtcblxuXG5cbi8vLy8vLy8vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZW5zdXJlQXZhaWxhYmxlKHBhY2thZ2VNYXAsIHBrZywgaWRlbnRpZmllcktleSkge1xuXG4gIHZhciB2YWx1ZSA9IHBrZ1tpZGVudGlmaWVyS2V5XTtcblxuICBpZiAodmFsdWUgaW4gcGFja2FnZU1hcCkge1xuICAgIHRocm93IG5ldyBFcnJvcigncGFja2FnZSB3aXRoICcgKyBpZGVudGlmaWVyS2V5ICsgJyA8JyArIHZhbHVlICsgJz4gYWxyZWFkeSBkZWZpbmVkJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIHV0aWxpdHkgdGhhdCBnZXRzIGFuZCBzZXRzIHByb3BlcnRpZXMgb2YgbW9kZWwgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtNb2RlbH0gbW9kZWxcbiAqL1xuZnVuY3Rpb24gUHJvcGVydGllcyhtb2RlbCkge1xuICB0aGlzLm1vZGVsID0gbW9kZWw7XG59XG5cblxuLyoqXG4gKiBTZXRzIGEgbmFtZWQgcHJvcGVydHkgb24gdGhlIHRhcmdldCBlbGVtZW50LlxuICogSWYgdGhlIHZhbHVlIGlzIHVuZGVmaW5lZCwgdGhlIHByb3BlcnR5IGdldHMgZGVsZXRlZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlXG4gKi9cblByb3BlcnRpZXMucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKHRhcmdldCwgbmFtZSwgdmFsdWUpIHtcblxuICB2YXIgcHJvcGVydHkgPSB0aGlzLm1vZGVsLmdldFByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIG5hbWUpO1xuXG4gIHZhciBwcm9wZXJ0eU5hbWUgPSBwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5uYW1lO1xuXG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAvLyB1bnNldCB0aGUgcHJvcGVydHksIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgdW5kZWZpbmVkO1xuICAgIC8vIGRlbGV0ZSBmcm9tICRhdHRycyAoZm9yIGV4dGVuc2lvbnMpIG9yIHRoZSB0YXJnZXQgaXRzZWxmXG4gICAgaWYgKHByb3BlcnR5KSB7XG4gICAgICBkZWxldGUgdGFyZ2V0W3Byb3BlcnR5TmFtZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSB0YXJnZXQuJGF0dHJzW25hbWVdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBzZXQgdGhlIHByb3BlcnR5LCBkZWZpbmluZyB3ZWxsIGRlZmluZWQgcHJvcGVydGllcyBvbiB0aGUgZmx5XG4gICAgLy8gb3Igc2ltcGx5IHVwZGF0aW5nIHRoZW0gaW4gdGFyZ2V0LiRhdHRycyAoZm9yIGV4dGVuc2lvbnMpXG4gICAgaWYgKHByb3BlcnR5KSB7XG4gICAgICBpZiAocHJvcGVydHlOYW1lIGluIHRhcmdldCkge1xuICAgICAgICB0YXJnZXRbcHJvcGVydHlOYW1lXSA9IHZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXQuJGF0dHJzW25hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG5hbWVkIHByb3BlcnR5IG9mIHRoZSBnaXZlbiBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSAge1N0cmluZ30gbmFtZVxuICpcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuUHJvcGVydGllcy5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24odGFyZ2V0LCBuYW1lKSB7XG5cbiAgdmFyIHByb3BlcnR5ID0gdGhpcy5tb2RlbC5nZXRQcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBuYW1lKTtcblxuICBpZiAoIXByb3BlcnR5KSB7XG4gICAgcmV0dXJuIHRhcmdldC4kYXR0cnNbbmFtZV07XG4gIH1cblxuICB2YXIgcHJvcGVydHlOYW1lID0gcHJvcGVydHkubmFtZTtcblxuICAvLyBjaGVjayBpZiBhY2Nlc3MgdG8gY29sbGVjdGlvbiBwcm9wZXJ0eSBhbmQgbGF6aWx5IGluaXRpYWxpemUgaXRcbiAgaWYgKCF0YXJnZXRbcHJvcGVydHlOYW1lXSAmJiBwcm9wZXJ0eS5pc01hbnkpIHtcbiAgICBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCBbXSk7XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0W3Byb3BlcnR5TmFtZV07XG59O1xuXG5cbi8qKlxuICogRGVmaW5lIGEgcHJvcGVydHkgb24gdGhlIHRhcmdldCBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSAge1N0cmluZ30gbmFtZVxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gKi9cblByb3BlcnRpZXMucHJvdG90eXBlLmRlZmluZSA9IGZ1bmN0aW9uKHRhcmdldCwgbmFtZSwgb3B0aW9ucykge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBuYW1lLCBvcHRpb25zKTtcbn07XG5cblxuLyoqXG4gKiBEZWZpbmUgdGhlIGRlc2NyaXB0b3IgZm9yIGFuIGVsZW1lbnRcbiAqL1xuUHJvcGVydGllcy5wcm90b3R5cGUuZGVmaW5lRGVzY3JpcHRvciA9IGZ1bmN0aW9uKHRhcmdldCwgZGVzY3JpcHRvcikge1xuICB0aGlzLmRlZmluZSh0YXJnZXQsICckZGVzY3JpcHRvcicsIHsgdmFsdWU6IGRlc2NyaXB0b3IgfSk7XG59O1xuXG4vKipcbiAqIERlZmluZSB0aGUgbW9kZWwgZm9yIGFuIGVsZW1lbnRcbiAqL1xuUHJvcGVydGllcy5wcm90b3R5cGUuZGVmaW5lTW9kZWwgPSBmdW5jdGlvbih0YXJnZXQsIG1vZGVsKSB7XG4gIHRoaXMuZGVmaW5lKHRhcmdldCwgJyRtb2RlbCcsIHsgdmFsdWU6IG1vZGVsIH0pO1xufTtcblxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICd1bmRlZmluZWQnO1xufVxuXG5mdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eS5uYW1lLCB7XG4gICAgZW51bWVyYWJsZTogIXByb3BlcnR5LmlzUmVmZXJlbmNlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIHZhbHVlOiB2YWx1ZSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59XG5cbi8vLy8gTW9kZGxlIGltcGxlbWVudGF0aW9uIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBAY2xhc3MgTW9kZGxlXG4gKlxuICogQSBtb2RlbCB0aGF0IGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBlbGVtZW50cyBvZiBhIHNwZWNpZmljIHR5cGUuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgTW9kZGxlID0gcmVxdWlyZSgnbW9kZGxlJyk7XG4gKlxuICogdmFyIHBrZyA9IHtcbiAqICAgbmFtZTogJ215cGFja2FnZScsXG4gKiAgIHByZWZpeDogJ215JyxcbiAqICAgdHlwZXM6IFtcbiAqICAgICB7IG5hbWU6ICdSb290JyB9XG4gKiAgIF1cbiAqIH07XG4gKlxuICogdmFyIG1vZGRsZSA9IG5ldyBNb2RkbGUoW3BrZ10pO1xuICpcbiAqIEBwYXJhbSB7QXJyYXk8UGFja2FnZT59IHBhY2thZ2VzIHRoZSBwYWNrYWdlcyB0byBjb250YWluXG4gKi9cbmZ1bmN0aW9uIE1vZGRsZShwYWNrYWdlcykge1xuXG4gIHRoaXMucHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKHRoaXMpO1xuXG4gIHRoaXMuZmFjdG9yeSA9IG5ldyBGYWN0b3J5KHRoaXMsIHRoaXMucHJvcGVydGllcyk7XG4gIHRoaXMucmVnaXN0cnkgPSBuZXcgUmVnaXN0cnkocGFja2FnZXMsIHRoaXMucHJvcGVydGllcyk7XG5cbiAgdGhpcy50eXBlQ2FjaGUgPSB7fTtcbn1cblxuXG4vKipcbiAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgc3BlY2lmaWVkIHR5cGUuXG4gKlxuICogQG1ldGhvZCBNb2RkbGUjY3JlYXRlXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgZm9vID0gbW9kZGxlLmNyZWF0ZSgnbXk6Rm9vJyk7XG4gKiB2YXIgYmFyID0gbW9kZGxlLmNyZWF0ZSgnbXk6QmFyJywgeyBpZDogJ0JBUl8xJyB9KTtcbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd8T2JqZWN0fSBkZXNjcmlwdG9yIHRoZSB0eXBlIGRlc2NyaXB0b3Igb3IgbmFtZSBrbm93IHRvIHRoZSBtb2RlbFxuICogQHBhcmFtICB7T2JqZWN0fSBhdHRycyAgIGEgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgdG8gaW5pdGlhbGl6ZSB0aGUgbW9kZWwgaW5zdGFuY2Ugd2l0aFxuICogQHJldHVybiB7T2JqZWN0fSAgICAgICAgIG1vZGVsIGluc3RhbmNlXG4gKi9cbk1vZGRsZS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24oZGVzY3JpcHRvciwgYXR0cnMpIHtcbiAgdmFyIFR5cGUgPSB0aGlzLmdldFR5cGUoZGVzY3JpcHRvcik7XG5cbiAgaWYgKCFUeXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIHR5cGUgPCcgKyBkZXNjcmlwdG9yICsgJz4nKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgVHlwZShhdHRycyk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgdHlwZSByZXByZXNlbnRpbmcgYSBnaXZlbiBkZXNjcmlwdG9yXG4gKlxuICogQG1ldGhvZCBNb2RkbGUjZ2V0VHlwZVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIEZvbyA9IG1vZGRsZS5nZXRUeXBlKCdteTpGb28nKTtcbiAqIHZhciBmb28gPSBuZXcgRm9vKHsgJ2lkJyA6ICdGT09fMScgfSk7XG4gKlxuICogQHBhcmFtICB7U3RyaW5nfE9iamVjdH0gZGVzY3JpcHRvciB0aGUgdHlwZSBkZXNjcmlwdG9yIG9yIG5hbWUga25vdyB0byB0aGUgbW9kZWxcbiAqIEByZXR1cm4ge09iamVjdH0gICAgICAgICB0aGUgdHlwZSByZXByZXNlbnRpbmcgdGhlIGRlc2NyaXB0b3JcbiAqL1xuTW9kZGxlLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24oZGVzY3JpcHRvcikge1xuXG4gIHZhciBjYWNoZSA9IHRoaXMudHlwZUNhY2hlO1xuXG4gIHZhciBuYW1lID0gaXNTdHJpbmcoZGVzY3JpcHRvcikgPyBkZXNjcmlwdG9yIDogZGVzY3JpcHRvci5ucy5uYW1lO1xuXG4gIHZhciB0eXBlID0gY2FjaGVbbmFtZV07XG5cbiAgaWYgKCF0eXBlKSB7XG4gICAgZGVzY3JpcHRvciA9IHRoaXMucmVnaXN0cnkuZ2V0RWZmZWN0aXZlRGVzY3JpcHRvcihuYW1lKTtcbiAgICB0eXBlID0gY2FjaGVbbmFtZV0gPSB0aGlzLmZhY3RvcnkuY3JlYXRlVHlwZShkZXNjcmlwdG9yKTtcbiAgfVxuXG4gIHJldHVybiB0eXBlO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZXMgYW4gYW55LWVsZW1lbnQgdHlwZSB0byBiZSB1c2VkIHdpdGhpbiBtb2RlbCBpbnN0YW5jZXMuXG4gKlxuICogVGhpcyBjYW4gYmUgdXNlZCB0byBjcmVhdGUgY3VzdG9tIGVsZW1lbnRzIHRoYXQgbGllIG91dHNpZGUgdGhlIG1ldGEtbW9kZWwuXG4gKiBUaGUgY3JlYXRlZCBlbGVtZW50IGNvbnRhaW5zIGFsbCB0aGUgbWV0YS1kYXRhIHJlcXVpcmVkIHRvIHNlcmlhbGl6ZSBpdFxuICogYXMgcGFydCBvZiBtZXRhLW1vZGVsIGVsZW1lbnRzLlxuICpcbiAqIEBtZXRob2QgTW9kZGxlI2NyZWF0ZUFueVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIGZvbyA9IG1vZGRsZS5jcmVhdGVBbnkoJ3ZlbmRvcjpGb28nLCAnaHR0cDovL3ZlbmRvcicsIHtcbiAqICAgdmFsdWU6ICdiYXInXG4gKiB9KTtcbiAqXG4gKiB2YXIgY29udGFpbmVyID0gbW9kZGxlLmNyZWF0ZSgnbXk6Q29udGFpbmVyJywgJ2h0dHA6Ly9teScsIHtcbiAqICAgYW55OiBbIGZvbyBdXG4gKiB9KTtcbiAqXG4gKiAvLyBnbyBhaGVhZCBhbmQgc2VyaWFsaXplIHRoZSBzdHVmZlxuICpcbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG5hbWUgIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50XG4gKiBAcGFyYW0gIHtTdHJpbmd9IG5zVXJpIHRoZSBuYW1lc3BhY2UgdXJpIG9mIHRoZSBlbGVtZW50XG4gKiBAcGFyYW0gIHtPYmplY3R9IFtwcm9wZXJ0aWVzXSBhIG1hcCBvZiBwcm9wZXJ0aWVzIHRvIGluaXRpYWxpemUgdGhlIGluc3RhbmNlIHdpdGhcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIGFueSB0eXBlIGluc3RhbmNlXG4gKi9cbk1vZGRsZS5wcm90b3R5cGUuY3JlYXRlQW55ID0gZnVuY3Rpb24obmFtZSwgbnNVcmksIHByb3BlcnRpZXMpIHtcblxuICB2YXIgbmFtZU5zID0gcGFyc2VOYW1lKG5hbWUpO1xuXG4gIHZhciBlbGVtZW50ID0ge1xuICAgICR0eXBlOiBuYW1lLFxuICAgICRpbnN0YW5jZU9mOiBmdW5jdGlvbih0eXBlKSB7XG4gICAgICByZXR1cm4gdHlwZSA9PT0gdGhpcy4kdHlwZTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIGRlc2NyaXB0b3IgPSB7XG4gICAgbmFtZTogbmFtZSxcbiAgICBpc0dlbmVyaWM6IHRydWUsXG4gICAgbnM6IHtcbiAgICAgIHByZWZpeDogbmFtZU5zLnByZWZpeCxcbiAgICAgIGxvY2FsTmFtZTogbmFtZU5zLmxvY2FsTmFtZSxcbiAgICAgIHVyaTogbnNVcmlcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5wcm9wZXJ0aWVzLmRlZmluZURlc2NyaXB0b3IoZWxlbWVudCwgZGVzY3JpcHRvcik7XG4gIHRoaXMucHJvcGVydGllcy5kZWZpbmVNb2RlbChlbGVtZW50LCB0aGlzKTtcbiAgdGhpcy5wcm9wZXJ0aWVzLmRlZmluZShlbGVtZW50LCAnJHBhcmVudCcsIHsgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlIH0pO1xuXG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24oYSwga2V5KSB7XG4gICAgaWYgKGlzT2JqZWN0KGEpICYmIGEudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZWxlbWVudFthLm5hbWVdID0gYS52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudFtrZXldID0gYTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgcmVnaXN0ZXJlZCBwYWNrYWdlIGJ5IHVyaSBvciBwcmVmaXhcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSBwYWNrYWdlXG4gKi9cbk1vZGRsZS5wcm90b3R5cGUuZ2V0UGFja2FnZSA9IGZ1bmN0aW9uKHVyaU9yUHJlZml4KSB7XG4gIHJldHVybiB0aGlzLnJlZ2lzdHJ5LmdldFBhY2thZ2UodXJpT3JQcmVmaXgpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgc25hcHNob3Qgb2YgYWxsIGtub3duIHBhY2thZ2VzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB0aGUgcGFja2FnZVxuICovXG5Nb2RkbGUucHJvdG90eXBlLmdldFBhY2thZ2VzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnJlZ2lzdHJ5LmdldFBhY2thZ2VzKCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGRlc2NyaXB0b3IgZm9yIGFuIGVsZW1lbnRcbiAqL1xuTW9kZGxlLnByb3RvdHlwZS5nZXRFbGVtZW50RGVzY3JpcHRvciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQuJGRlc2NyaXB0b3I7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gZGVzY3JpcHRvciBvciBpbnN0YW5jZVxuICogcmVwcmVzZW50cyB0aGUgZ2l2ZW4gdHlwZS5cbiAqXG4gKiBNYXkgYmUgYXBwbGllZCB0byB0aGlzLCBpZiBlbGVtZW50IGlzIG9taXR0ZWQuXG4gKi9cbk1vZGRsZS5wcm90b3R5cGUuaGFzVHlwZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHR5cGUpIHtcbiAgaWYgKHR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgIHR5cGUgPSBlbGVtZW50O1xuICAgIGVsZW1lbnQgPSB0aGlzO1xuICB9XG5cbiAgdmFyIGRlc2NyaXB0b3IgPSBlbGVtZW50LiRtb2RlbC5nZXRFbGVtZW50RGVzY3JpcHRvcihlbGVtZW50KTtcblxuICByZXR1cm4gKHR5cGUgaW4gZGVzY3JpcHRvci5hbGxUeXBlc0J5TmFtZSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGRlc2NyaXB0b3Igb2YgYW4gZWxlbWVudHMgbmFtZWQgcHJvcGVydHlcbiAqL1xuTW9kZGxlLnByb3RvdHlwZS5nZXRQcm9wZXJ0eURlc2NyaXB0b3IgPSBmdW5jdGlvbihlbGVtZW50LCBwcm9wZXJ0eSkge1xuICByZXR1cm4gdGhpcy5nZXRFbGVtZW50RGVzY3JpcHRvcihlbGVtZW50KS5wcm9wZXJ0aWVzQnlOYW1lW3Byb3BlcnR5XTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIG1hcHBlZCB0eXBlJ3MgZGVzY3JpcHRvclxuICovXG5Nb2RkbGUucHJvdG90eXBlLmdldFR5cGVEZXNjcmlwdG9yID0gZnVuY3Rpb24odHlwZSkge1xuICByZXR1cm4gdGhpcy5yZWdpc3RyeS50eXBlTWFwW3R5cGVdO1xufTtcblxuZXhwb3J0IHsgTW9kZGxlLCBjb2VyY2VUeXBlLCBpc0J1aWx0SW4gYXMgaXNCdWlsdEluVHlwZSwgaXNTaW1wbGUgYXMgaXNTaW1wbGVUeXBlLCBwYXJzZU5hbWUgYXMgcGFyc2VOYW1lTlMgfTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvcmVmcycpO1xuXG5tb2R1bGUuZXhwb3J0cy5Db2xsZWN0aW9uID0gcmVxdWlyZSgnLi9saWIvY29sbGVjdGlvbicpOyIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBBbiBlbXB0eSBjb2xsZWN0aW9uIHN0dWIuIFVzZSB7QGxpbmsgUmVmc0NvbGxlY3Rpb24uZXh0ZW5kfSB0byBleHRlbmQgYVxuICogY29sbGVjdGlvbiB3aXRoIHJlZiBzZW1hbnRpY3MuXG4gKlxuICogQGNsYXNzIFJlZnNDb2xsZWN0aW9uXG4gKi9cblxuLyoqXG4gKiBFeHRlbmRzIGEgY29sbGVjdGlvbiB3aXRoIHtAbGluayBSZWZzfSBhd2FyZSBtZXRob2RzXG4gKlxuICogQG1lbWJlcm9mIFJlZnNDb2xsZWN0aW9uXG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtICB7QXJyYXk8T2JqZWN0Pn0gY29sbGVjdGlvblxuICogQHBhcmFtICB7UmVmc30gcmVmcyBpbnN0YW5jZVxuICogQHBhcmFtICB7T2JqZWN0fSBwcm9wZXJ0eSByZXByZXNlbnRlZCBieSB0aGUgY29sbGVjdGlvblxuICogQHBhcmFtICB7T2JqZWN0fSB0YXJnZXQgb2JqZWN0IHRoZSBjb2xsZWN0aW9uIGlzIGF0dGFjaGVkIHRvXG4gKlxuICogQHJldHVybiB7UmVmc0NvbGxlY3Rpb248T2JqZWN0Pn0gdGhlIGV4dGVuZGVkIGFycmF5XG4gKi9cbmZ1bmN0aW9uIGV4dGVuZChjb2xsZWN0aW9uLCByZWZzLCBwcm9wZXJ0eSwgdGFyZ2V0KSB7XG5cbiAgdmFyIGludmVyc2VQcm9wZXJ0eSA9IHByb3BlcnR5LmludmVyc2U7XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGdpdmVuIGVsZW1lbnQgZnJvbSB0aGUgYXJyYXkgYW5kIHJldHVybnMgaXQuXG4gICAqXG4gICAqIEBtZXRob2QgUmVmc0NvbGxlY3Rpb24jcmVtb3ZlXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50IHRoZSBlbGVtZW50IHRvIHJlbW92ZVxuICAgKi9cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbGxlY3Rpb24sICdyZW1vdmUnLCB7XG4gICAgdmFsdWU6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgIHZhciBpZHggPSB0aGlzLmluZGV4T2YoZWxlbWVudCk7XG4gICAgICBpZiAoaWR4ICE9PSAtMSkge1xuICAgICAgICB0aGlzLnNwbGljZShpZHgsIDEpO1xuXG4gICAgICAgIC8vIHVuc2V0IGludmVyc2VcbiAgICAgICAgcmVmcy51bnNldChlbGVtZW50LCBpbnZlcnNlUHJvcGVydHksIHRhcmdldCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY29sbGVjdGlvbiBjb250YWlucyB0aGUgZ2l2ZW4gZWxlbWVudFxuICAgKlxuICAgKiBAbWV0aG9kIFJlZnNDb2xsZWN0aW9uI2NvbnRhaW5zXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50IHRoZSBlbGVtZW50IHRvIGNoZWNrIGZvclxuICAgKi9cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbGxlY3Rpb24sICdjb250YWlucycsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIHRoaXMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTE7XG4gICAgfVxuICB9KTtcblxuICAvKipcbiAgICogQWRkcyBhbiBlbGVtZW50IHRvIHRoZSBhcnJheSwgdW5sZXNzIGl0IGV4aXN0cyBhbHJlYWR5IChzZXQgc2VtYW50aWNzKS5cbiAgICpcbiAgICogQG1ldGhvZCBSZWZzQ29sbGVjdGlvbiNhZGRcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnQgdGhlIGVsZW1lbnQgdG8gYWRkXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25hbCBpbmRleCB0byBhZGQgZWxlbWVudCB0b1xuICAgKiAgICAgICAgICAgICAgICAgKHBvc3NpYmx5IG1vdmluZyBvdGhlciBlbGVtZW50cyBhcm91bmQpXG4gICAqL1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29sbGVjdGlvbiwgJ2FkZCcsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24oZWxlbWVudCwgaWR4KSB7XG5cbiAgICAgIHZhciBjdXJyZW50SWR4ID0gdGhpcy5pbmRleE9mKGVsZW1lbnQpO1xuXG4gICAgICBpZiAodHlwZW9mIGlkeCA9PT0gJ3VuZGVmaW5lZCcpIHtcblxuICAgICAgICBpZiAoY3VycmVudElkeCAhPT0gLTEpIHtcbiAgICAgICAgICAvLyBlbGVtZW50IGFscmVhZHkgaW4gY29sbGVjdGlvbiAoISlcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgdG8gZW5kIG9mIGFycmF5LCBhcyBubyBpZHggaXMgc3BlY2lmaWVkXG4gICAgICAgIGlkeCA9IHRoaXMubGVuZ3RoO1xuICAgICAgfVxuXG4gICAgICAvLyBoYW5kbGUgYWxyZWFkeSBpbiBjb2xsZWN0aW9uXG4gICAgICBpZiAoY3VycmVudElkeCAhPT0gLTEpIHtcblxuICAgICAgICAvLyByZW1vdmUgZWxlbWVudCBmcm9tIGN1cnJlbnRJZHhcbiAgICAgICAgdGhpcy5zcGxpY2UoY3VycmVudElkeCwgMSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGFkZCBlbGVtZW50IGF0IGlkeFxuICAgICAgdGhpcy5zcGxpY2UoaWR4LCAwLCBlbGVtZW50KTtcblxuICAgICAgaWYgKGN1cnJlbnRJZHggPT09IC0xKSB7XG4gICAgICAgIC8vIHNldCBpbnZlcnNlLCB1bmxlc3MgZWxlbWVudCB3YXNcbiAgICAgICAgLy8gaW4gY29sbGVjdGlvbiBhbHJlYWR5XG4gICAgICAgIHJlZnMuc2V0KGVsZW1lbnQsIGludmVyc2VQcm9wZXJ0eSwgdGFyZ2V0KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIGEgc2ltcGxlIG1hcmtlciwgaWRlbnRpZnlpbmcgdGhpcyBlbGVtZW50XG4gIC8vIGFzIGJlaW5nIGEgcmVmcyBjb2xsZWN0aW9uXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb2xsZWN0aW9uLCAnX19yZWZzX2NvbGxlY3Rpb24nLCB7XG4gICAgdmFsdWU6IHRydWVcbiAgfSk7XG5cbiAgcmV0dXJuIGNvbGxlY3Rpb247XG59XG5cblxuZnVuY3Rpb24gaXNFeHRlbmRlZChjb2xsZWN0aW9uKSB7XG4gIHJldHVybiBjb2xsZWN0aW9uLl9fcmVmc19jb2xsZWN0aW9uID09PSB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgPSBleHRlbmQ7XG5cbm1vZHVsZS5leHBvcnRzLmlzRXh0ZW5kZWQgPSBpc0V4dGVuZGVkOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbGxlY3Rpb24gPSByZXF1aXJlKCcuL2NvbGxlY3Rpb24nKTtcblxuZnVuY3Rpb24gaGFzT3duUHJvcGVydHkoZSwgcHJvcGVydHkpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChlLCBwcm9wZXJ0eS5uYW1lIHx8IHByb3BlcnR5KTtcbn1cblxuZnVuY3Rpb24gZGVmaW5lQ29sbGVjdGlvblByb3BlcnR5KHJlZiwgcHJvcGVydHksIHRhcmdldCkge1xuXG4gIHZhciBjb2xsZWN0aW9uID0gQ29sbGVjdGlvbi5leHRlbmQodGFyZ2V0W3Byb3BlcnR5Lm5hbWVdIHx8IFtdLCByZWYsIHByb3BlcnR5LCB0YXJnZXQpO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5Lm5hbWUsIHtcbiAgICBlbnVtZXJhYmxlOiBwcm9wZXJ0eS5lbnVtZXJhYmxlLFxuICAgIHZhbHVlOiBjb2xsZWN0aW9uXG4gIH0pO1xuXG4gIGlmIChjb2xsZWN0aW9uLmxlbmd0aCkge1xuXG4gICAgY29sbGVjdGlvbi5mb3JFYWNoKGZ1bmN0aW9uKG8pIHtcbiAgICAgIHJlZi5zZXQobywgcHJvcGVydHkuaW52ZXJzZSwgdGFyZ2V0KTtcbiAgICB9KTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KHJlZiwgcHJvcGVydHksIHRhcmdldCkge1xuXG4gIHZhciBpbnZlcnNlUHJvcGVydHkgPSBwcm9wZXJ0eS5pbnZlcnNlO1xuXG4gIHZhciBfdmFsdWUgPSB0YXJnZXRbcHJvcGVydHkubmFtZV07XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHkubmFtZSwge1xuICAgIGNvbmZpZ3VyYWJsZTogcHJvcGVydHkuY29uZmlndXJhYmxlLFxuICAgIGVudW1lcmFibGU6IHByb3BlcnR5LmVudW1lcmFibGUsXG5cbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIF92YWx1ZTtcbiAgICB9LFxuXG4gICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuXG4gICAgICAvLyByZXR1cm4gaWYgd2UgYWxyZWFkeSBwZXJmb3JtZWQgYWxsIGNoYW5nZXNcbiAgICAgIGlmICh2YWx1ZSA9PT0gX3ZhbHVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIG9sZCA9IF92YWx1ZTtcblxuICAgICAgLy8gdGVtcG9yYXJ5IHNldCBudWxsXG4gICAgICBfdmFsdWUgPSBudWxsO1xuXG4gICAgICBpZiAob2xkKSB7XG4gICAgICAgIHJlZi51bnNldChvbGQsIGludmVyc2VQcm9wZXJ0eSwgdGFyZ2V0KTtcbiAgICAgIH1cblxuICAgICAgLy8gc2V0IG5ldyB2YWx1ZVxuICAgICAgX3ZhbHVlID0gdmFsdWU7XG5cbiAgICAgIC8vIHNldCBpbnZlcnNlIHZhbHVlXG4gICAgICByZWYuc2V0KF92YWx1ZSwgaW52ZXJzZVByb3BlcnR5LCB0YXJnZXQpO1xuICAgIH1cbiAgfSk7XG5cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHJlZmVyZW5jZXMgb2JqZWN0IGRlZmluaW5nIHR3byBpbnZlcnNseSByZWxhdGVkXG4gKiBhdHRyaWJ1dGUgZGVzY3JpcHRvcnMgYSBhbmQgYi5cbiAqXG4gKiA8cD5cbiAqICAgV2hlbiBib3VuZCB0byBhbiBvYmplY3QgdXNpbmcge0BsaW5rIFJlZnMjYmluZH0gdGhlIHJlZmVyZW5jZXNcbiAqICAgZ2V0IGFjdGl2YXRlZCBhbmQgZW5zdXJlIHRoYXQgYWRkIGFuZCByZW1vdmUgb3BlcmF0aW9ucyBhcmUgYXBwbGllZFxuICogICByZXZlcnNlbHksIHRvby5cbiAqIDwvcD5cbiAqXG4gKiA8cD5cbiAqICAgRm9yIGF0dHJpYnV0ZXMgcmVwcmVzZW50ZWQgYXMgY29sbGVjdGlvbnMge0BsaW5rIFJlZnN9IHByb3ZpZGVzIHRoZVxuICogICB7QGxpbmsgUmVmc0NvbGxlY3Rpb24jYWRkfSwge0BsaW5rIFJlZnNDb2xsZWN0aW9uI3JlbW92ZX0gYW5kIHtAbGluayBSZWZzQ29sbGVjdGlvbiNjb250YWluc30gZXh0ZW5zaW9uc1xuICogICB0aGF0IG11c3QgYmUgdXNlZCB0byBwcm9wZXJseSBob29rIGludG8gdGhlIGludmVyc2UgY2hhbmdlIG1lY2hhbmlzbS5cbiAqIDwvcD5cbiAqXG4gKiBAY2xhc3MgUmVmc1xuICpcbiAqIEBjbGFzc2Rlc2MgQSBiaS1kaXJlY3Rpb25hbCByZWZlcmVuY2UgYmV0d2VlbiB0d28gYXR0cmlidXRlcy5cbiAqXG4gKiBAcGFyYW0ge1JlZnMuQXR0cmlidXRlRGVzY3JpcHRvcn0gYSBwcm9wZXJ0eSBkZXNjcmlwdG9yXG4gKiBAcGFyYW0ge1JlZnMuQXR0cmlidXRlRGVzY3JpcHRvcn0gYiBwcm9wZXJ0eSBkZXNjcmlwdG9yXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgcmVmcyA9IFJlZnMoeyBuYW1lOiAnd2hlZWxzJywgY29sbGVjdGlvbjogdHJ1ZSwgZW51bWVyYWJsZTogdHJ1ZSB9LCB7IG5hbWU6ICdjYXInIH0pO1xuICpcbiAqIHZhciBjYXIgPSB7IG5hbWU6ICd0b3lvdGEnIH07XG4gKiB2YXIgd2hlZWxzID0gW3sgcG9zOiAnZnJvbnQtbGVmdCcgfSwgeyBwb3M6ICdmcm9udC1yaWdodCcgfV07XG4gKlxuICogcmVmcy5iaW5kKGNhciwgJ3doZWVscycpO1xuICpcbiAqIGNhci53aGVlbHMgLy8gW11cbiAqIGNhci53aGVlbHMuYWRkKHdoZWVsc1swXSk7XG4gKiBjYXIud2hlZWxzLmFkZCh3aGVlbHNbMV0pO1xuICpcbiAqIGNhci53aGVlbHMgLy8gW3sgcG9zOiAnZnJvbnQtbGVmdCcgfSwgeyBwb3M6ICdmcm9udC1yaWdodCcgfV1cbiAqXG4gKiB3aGVlbHNbMF0uY2FyIC8vIHsgbmFtZTogJ3RveW90YScgfTtcbiAqIGNhci53aGVlbHMucmVtb3ZlKHdoZWVsc1swXSk7XG4gKlxuICogd2hlZWxzWzBdLmNhciAvLyB1bmRlZmluZWRcbiAqL1xuZnVuY3Rpb24gUmVmcyhhLCBiKSB7XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlZnMpKSB7XG4gICAgcmV0dXJuIG5ldyBSZWZzKGEsIGIpO1xuICB9XG5cbiAgLy8gbGlua1xuICBhLmludmVyc2UgPSBiO1xuICBiLmludmVyc2UgPSBhO1xuXG4gIHRoaXMucHJvcHMgPSB7fTtcbiAgdGhpcy5wcm9wc1thLm5hbWVdID0gYTtcbiAgdGhpcy5wcm9wc1tiLm5hbWVdID0gYjtcbn1cblxuLyoqXG4gKiBCaW5kcyBvbmUgc2lkZSBvZiBhIGJpLWRpcmVjdGlvbmFsIHJlZmVyZW5jZSB0byBhXG4gKiB0YXJnZXQgb2JqZWN0LlxuICpcbiAqIEBtZW1iZXJPZiBSZWZzXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSAge1N0cmluZ30gcHJvcGVydHlcbiAqL1xuUmVmcy5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uKHRhcmdldCwgcHJvcGVydHkpIHtcbiAgaWYgKHR5cGVvZiBwcm9wZXJ0eSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIXRoaXMucHJvcHNbcHJvcGVydHldKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByb3BlcnR5IDwnICsgcHJvcGVydHkgKyAnPiBpbiByZWYnKTtcbiAgICB9XG4gICAgcHJvcGVydHkgPSB0aGlzLnByb3BzW3Byb3BlcnR5XTtcbiAgfVxuXG4gIGlmIChwcm9wZXJ0eS5jb2xsZWN0aW9uKSB7XG4gICAgZGVmaW5lQ29sbGVjdGlvblByb3BlcnR5KHRoaXMsIHByb3BlcnR5LCB0YXJnZXQpO1xuICB9IGVsc2Uge1xuICAgIGRlZmluZVByb3BlcnR5KHRoaXMsIHByb3BlcnR5LCB0YXJnZXQpO1xuICB9XG59O1xuXG5SZWZzLnByb3RvdHlwZS5lbnN1cmVSZWZzQ29sbGVjdGlvbiA9IGZ1bmN0aW9uKHRhcmdldCwgcHJvcGVydHkpIHtcblxuICB2YXIgY29sbGVjdGlvbiA9IHRhcmdldFtwcm9wZXJ0eS5uYW1lXTtcblxuICBpZiAoIUNvbGxlY3Rpb24uaXNFeHRlbmRlZChjb2xsZWN0aW9uKSkge1xuICAgIGRlZmluZUNvbGxlY3Rpb25Qcm9wZXJ0eSh0aGlzLCBwcm9wZXJ0eSwgdGFyZ2V0KTtcbiAgfVxuXG4gIHJldHVybiBjb2xsZWN0aW9uO1xufTtcblxuUmVmcy5wcm90b3R5cGUuZW5zdXJlQm91bmQgPSBmdW5jdGlvbih0YXJnZXQsIHByb3BlcnR5KSB7XG4gIGlmICghaGFzT3duUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSkpIHtcbiAgICB0aGlzLmJpbmQodGFyZ2V0LCBwcm9wZXJ0eSk7XG4gIH1cbn07XG5cblJlZnMucHJvdG90eXBlLnVuc2V0ID0gZnVuY3Rpb24odGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpIHtcblxuICBpZiAodGFyZ2V0KSB7XG4gICAgdGhpcy5lbnN1cmVCb3VuZCh0YXJnZXQsIHByb3BlcnR5KTtcblxuICAgIGlmIChwcm9wZXJ0eS5jb2xsZWN0aW9uKSB7XG4gICAgICB0aGlzLmVuc3VyZVJlZnNDb2xsZWN0aW9uKHRhcmdldCwgcHJvcGVydHkpLnJlbW92ZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhcmdldFtwcm9wZXJ0eS5uYW1lXSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbn07XG5cblJlZnMucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKHRhcmdldCwgcHJvcGVydHksIHZhbHVlKSB7XG5cbiAgaWYgKHRhcmdldCkge1xuICAgIHRoaXMuZW5zdXJlQm91bmQodGFyZ2V0LCBwcm9wZXJ0eSk7XG5cbiAgICBpZiAocHJvcGVydHkuY29sbGVjdGlvbikge1xuICAgICAgdGhpcy5lbnN1cmVSZWZzQ29sbGVjdGlvbih0YXJnZXQsIHByb3BlcnR5KS5hZGQodmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXRbcHJvcGVydHkubmFtZV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVmcztcblxuXG4vKipcbiAqIEFuIGF0dHJpYnV0ZSBkZXNjcmlwdG9yIHRvIGJlIHVzZWQgc3BlY2lmeSBhbiBhdHRyaWJ1dGUgaW4gYSB7QGxpbmsgUmVmc30gaW5zdGFuY2VcbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBSZWZzLkF0dHJpYnV0ZURlc2NyaXB0b3JcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBuYW1lXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtjb2xsZWN0aW9uPWZhbHNlXVxuICogQHByb3BlcnR5IHtib29sZWFufSBbZW51bWVyYWJsZT1mYWxzZV1cbiAqLyIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBUaGlzIGZpbGUgY29udGFpbnMgc291cmNlIGNvZGUgYWRhcHRlZCBmcm9tIFNuYXAuc3ZnIChsaWNlbnNlZCBBcGFjaGUtMi4wKS5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hZG9iZS13ZWJwbGF0Zm9ybS9TbmFwLnN2Zy9ibG9iL21hc3Rlci9zcmMvcGF0aC5qc1xuICovXG5cbi8qIGVzbGludCBuby1mYWxsdGhyb3VnaDogXCJvZmZcIiAqL1xuXG52YXIgcDJzID0gLyw/KFthLXpdKSw/L2dpLFxuICAgIHRvRmxvYXQgPSBwYXJzZUZsb2F0LFxuICAgIG1hdGggPSBNYXRoLFxuICAgIFBJID0gbWF0aC5QSSxcbiAgICBtbWluID0gbWF0aC5taW4sXG4gICAgbW1heCA9IG1hdGgubWF4LFxuICAgIHBvdyA9IG1hdGgucG93LFxuICAgIGFicyA9IG1hdGguYWJzLFxuICAgIHBhdGhDb21tYW5kID0gLyhbYS16XSlbXFxzLF0qKCgtP1xcZCpcXC4/XFxkKig/OmVbLStdP1xcZCspP1tcXHNdKiw/W1xcc10qKSspL2lnLFxuICAgIHBhdGhWYWx1ZXMgPSAvKC0/XFxkKlxcLj9cXGQqKD86ZVstK10/XFxcXGQrKT8pW1xcc10qLD9bXFxzXSovaWc7XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbihvKSB7IHJldHVybiBvIGluc3RhbmNlb2YgQXJyYXk7IH07XG5cbmZ1bmN0aW9uIGhhc1Byb3BlcnR5KG9iaiwgcHJvcGVydHkpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3BlcnR5KTtcbn1cblxuZnVuY3Rpb24gY2xvbmUob2JqKSB7XG5cbiAgaWYgKHR5cGVvZiBvYmogPT0gJ2Z1bmN0aW9uJyB8fCBPYmplY3Qob2JqKSAhPT0gb2JqKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHZhciByZXMgPSBuZXcgb2JqLmNvbnN0cnVjdG9yO1xuXG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoaGFzUHJvcGVydHkob2JqLCBrZXkpKSB7XG4gICAgICByZXNba2V5XSA9IGNsb25lKG9ialtrZXldKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiByZXB1c2goYXJyYXksIGl0ZW0pIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gYXJyYXkubGVuZ3RoOyBpIDwgaWk7IGkrKykgaWYgKGFycmF5W2ldID09PSBpdGVtKSB7XG4gICAgcmV0dXJuIGFycmF5LnB1c2goYXJyYXkuc3BsaWNlKGksIDEpWzBdKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjYWNoZXIoZikge1xuXG4gIGZ1bmN0aW9uIG5ld2YoKSB7XG5cbiAgICB2YXIgYXJnID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSxcbiAgICAgICAgYXJncyA9IGFyZy5qb2luKCdcXHUyNDAwJyksXG4gICAgICAgIGNhY2hlID0gbmV3Zi5jYWNoZSA9IG5ld2YuY2FjaGUgfHwge30sXG4gICAgICAgIGNvdW50ID0gbmV3Zi5jb3VudCA9IG5ld2YuY291bnQgfHwgW107XG5cbiAgICBpZiAoaGFzUHJvcGVydHkoY2FjaGUsIGFyZ3MpKSB7XG4gICAgICByZXB1c2goY291bnQsIGFyZ3MpO1xuICAgICAgcmV0dXJuIGNhY2hlW2FyZ3NdO1xuICAgIH1cblxuICAgIGNvdW50Lmxlbmd0aCA+PSAxZTMgJiYgZGVsZXRlIGNhY2hlW2NvdW50LnNoaWZ0KCldO1xuICAgIGNvdW50LnB1c2goYXJncyk7XG4gICAgY2FjaGVbYXJnc10gPSBmLmFwcGx5KDAsIGFyZyk7XG5cbiAgICByZXR1cm4gY2FjaGVbYXJnc107XG4gIH1cbiAgcmV0dXJuIG5ld2Y7XG59XG5cbmZ1bmN0aW9uIHBhcnNlUGF0aFN0cmluZyhwYXRoU3RyaW5nKSB7XG5cbiAgaWYgKCFwYXRoU3RyaW5nKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgcHRoID0gcGF0aHMocGF0aFN0cmluZyk7XG5cbiAgaWYgKHB0aC5hcnIpIHtcbiAgICByZXR1cm4gY2xvbmUocHRoLmFycik7XG4gIH1cblxuICB2YXIgcGFyYW1Db3VudHMgPSB7IGE6IDcsIGM6IDYsIGg6IDEsIGw6IDIsIG06IDIsIHE6IDQsIHM6IDQsIHQ6IDIsIHY6IDEsIHo6IDAgfSxcbiAgICAgIGRhdGEgPSBbXTtcblxuICBpZiAoaXNBcnJheShwYXRoU3RyaW5nKSAmJiBpc0FycmF5KHBhdGhTdHJpbmdbMF0pKSB7IC8vIHJvdWdoIGFzc3VtcHRpb25cbiAgICBkYXRhID0gY2xvbmUocGF0aFN0cmluZyk7XG4gIH1cblxuICBpZiAoIWRhdGEubGVuZ3RoKSB7XG5cbiAgICBTdHJpbmcocGF0aFN0cmluZykucmVwbGFjZShwYXRoQ29tbWFuZCwgZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAgdmFyIHBhcmFtcyA9IFtdLFxuICAgICAgICAgIG5hbWUgPSBiLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgIGMucmVwbGFjZShwYXRoVmFsdWVzLCBmdW5jdGlvbihhLCBiKSB7XG4gICAgICAgIGIgJiYgcGFyYW1zLnB1c2goK2IpO1xuICAgICAgfSk7XG5cbiAgICAgIGlmIChuYW1lID09ICdtJyAmJiBwYXJhbXMubGVuZ3RoID4gMikge1xuICAgICAgICBkYXRhLnB1c2goW2JdLmNvbmNhdChwYXJhbXMuc3BsaWNlKDAsIDIpKSk7XG4gICAgICAgIG5hbWUgPSAnbCc7XG4gICAgICAgIGIgPSBiID09ICdtJyA/ICdsJyA6ICdMJztcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKHBhcmFtcy5sZW5ndGggPj0gcGFyYW1Db3VudHNbbmFtZV0pIHtcbiAgICAgICAgZGF0YS5wdXNoKFtiXS5jb25jYXQocGFyYW1zLnNwbGljZSgwLCBwYXJhbUNvdW50c1tuYW1lXSkpKTtcbiAgICAgICAgaWYgKCFwYXJhbUNvdW50c1tuYW1lXSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBkYXRhLnRvU3RyaW5nID0gcGF0aHMudG9TdHJpbmc7XG4gIHB0aC5hcnIgPSBjbG9uZShkYXRhKTtcblxuICByZXR1cm4gZGF0YTtcbn1cblxuZnVuY3Rpb24gcGF0aHMocHMpIHtcbiAgdmFyIHAgPSBwYXRocy5wcyA9IHBhdGhzLnBzIHx8IHt9O1xuXG4gIGlmIChwW3BzXSkge1xuICAgIHBbcHNdLnNsZWVwID0gMTAwO1xuICB9IGVsc2Uge1xuICAgIHBbcHNdID0ge1xuICAgICAgc2xlZXA6IDEwMFxuICAgIH07XG4gIH1cblxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIGtleSBpbiBwKSB7XG4gICAgICBpZiAoaGFzUHJvcGVydHkocCwga2V5KSAmJiBrZXkgIT0gcHMpIHtcbiAgICAgICAgcFtrZXldLnNsZWVwLS07XG4gICAgICAgICFwW2tleV0uc2xlZXAgJiYgZGVsZXRlIHBba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBwW3BzXTtcbn1cblxuZnVuY3Rpb24gcmVjdEJCb3goeCwgeSwgd2lkdGgsIGhlaWdodCkge1xuXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgeSA9IHgueTtcbiAgICB3aWR0aCA9IHgud2lkdGg7XG4gICAgaGVpZ2h0ID0geC5oZWlnaHQ7XG4gICAgeCA9IHgueDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgeDogeCxcbiAgICB5OiB5LFxuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICB4MjogeCArIHdpZHRoLFxuICAgIHkyOiB5ICsgaGVpZ2h0XG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhdGhUb1N0cmluZygpIHtcbiAgcmV0dXJuIHRoaXMuam9pbignLCcpLnJlcGxhY2UocDJzLCAnJDEnKTtcbn1cblxuZnVuY3Rpb24gcGF0aENsb25lKHBhdGhBcnJheSkge1xuICB2YXIgcmVzID0gY2xvbmUocGF0aEFycmF5KTtcbiAgcmVzLnRvU3RyaW5nID0gcGF0aFRvU3RyaW5nO1xuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiBmaW5kRG90c0F0U2VnbWVudChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdCkge1xuICB2YXIgdDEgPSAxIC0gdCxcbiAgICAgIHQxMyA9IHBvdyh0MSwgMyksXG4gICAgICB0MTIgPSBwb3codDEsIDIpLFxuICAgICAgdDIgPSB0ICogdCxcbiAgICAgIHQzID0gdDIgKiB0LFxuICAgICAgeCA9IHQxMyAqIHAxeCArIHQxMiAqIDMgKiB0ICogYzF4ICsgdDEgKiAzICogdCAqIHQgKiBjMnggKyB0MyAqIHAyeCxcbiAgICAgIHkgPSB0MTMgKiBwMXkgKyB0MTIgKiAzICogdCAqIGMxeSArIHQxICogMyAqIHQgKiB0ICogYzJ5ICsgdDMgKiBwMnk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBmaXhFcnJvcih4KSxcbiAgICB5OiBmaXhFcnJvcih5KVxuICB9O1xufVxuXG5mdW5jdGlvbiBiZXppZXJCQm94KHBvaW50cykge1xuXG4gIHZhciBiYm94ID0gY3VydmVCQm94LmFwcGx5KG51bGwsIHBvaW50cyk7XG5cbiAgcmV0dXJuIHJlY3RCQm94KFxuICAgIGJib3gueDAsXG4gICAgYmJveC55MCxcbiAgICBiYm94LngxIC0gYmJveC54MCxcbiAgICBiYm94LnkxIC0gYmJveC55MFxuICApO1xufVxuXG5mdW5jdGlvbiBpc1BvaW50SW5zaWRlQkJveChiYm94LCB4LCB5KSB7XG4gIHJldHVybiB4ID49IGJib3gueCAmJlxuICAgIHggPD0gYmJveC54ICsgYmJveC53aWR0aCAmJlxuICAgIHkgPj0gYmJveC55ICYmXG4gICAgeSA8PSBiYm94LnkgKyBiYm94LmhlaWdodDtcbn1cblxuZnVuY3Rpb24gaXNCQm94SW50ZXJzZWN0KGJib3gxLCBiYm94Mikge1xuICBiYm94MSA9IHJlY3RCQm94KGJib3gxKTtcbiAgYmJveDIgPSByZWN0QkJveChiYm94Mik7XG4gIHJldHVybiBpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueCwgYmJveDEueSlcbiAgICB8fCBpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueDIsIGJib3gxLnkpXG4gICAgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDIsIGJib3gxLngsIGJib3gxLnkyKVxuICAgIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gyLCBiYm94MS54MiwgYmJveDEueTIpXG4gICAgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDEsIGJib3gyLngsIGJib3gyLnkpXG4gICAgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDEsIGJib3gyLngyLCBiYm94Mi55KVxuICAgIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gxLCBiYm94Mi54LCBiYm94Mi55MilcbiAgICB8fCBpc1BvaW50SW5zaWRlQkJveChiYm94MSwgYmJveDIueDIsIGJib3gyLnkyKVxuICAgIHx8IChiYm94MS54IDwgYmJveDIueDIgJiYgYmJveDEueCA+IGJib3gyLnhcbiAgICAgICAgfHwgYmJveDIueCA8IGJib3gxLngyICYmIGJib3gyLnggPiBiYm94MS54KVxuICAgICYmIChiYm94MS55IDwgYmJveDIueTIgJiYgYmJveDEueSA+IGJib3gyLnlcbiAgICAgICAgfHwgYmJveDIueSA8IGJib3gxLnkyICYmIGJib3gyLnkgPiBiYm94MS55KTtcbn1cblxuZnVuY3Rpb24gYmFzZTModCwgcDEsIHAyLCBwMywgcDQpIHtcbiAgdmFyIHQxID0gLTMgKiBwMSArIDkgKiBwMiAtIDkgKiBwMyArIDMgKiBwNCxcbiAgICAgIHQyID0gdCAqIHQxICsgNiAqIHAxIC0gMTIgKiBwMiArIDYgKiBwMztcbiAgcmV0dXJuIHQgKiB0MiAtIDMgKiBwMSArIDMgKiBwMjtcbn1cblxuZnVuY3Rpb24gYmV6bGVuKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgeikge1xuXG4gIGlmICh6ID09IG51bGwpIHtcbiAgICB6ID0gMTtcbiAgfVxuXG4gIHogPSB6ID4gMSA/IDEgOiB6IDwgMCA/IDAgOiB6O1xuXG4gIHZhciB6MiA9IHogLyAyLFxuICAgICAgbiA9IDEyLFxuICAgICAgVHZhbHVlcyA9IFstLjEyNTIsLjEyNTIsLS4zNjc4LC4zNjc4LC0uNTg3MywuNTg3MywtLjc2OTksLjc2OTksLS45MDQxLC45MDQxLC0uOTgxNiwuOTgxNl0sXG4gICAgICBDdmFsdWVzID0gWzAuMjQ5MSwwLjI0OTEsMC4yMzM1LDAuMjMzNSwwLjIwMzIsMC4yMDMyLDAuMTYwMSwwLjE2MDEsMC4xMDY5LDAuMTA2OSwwLjA0NzIsMC4wNDcyXSxcbiAgICAgIHN1bSA9IDA7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICB2YXIgY3QgPSB6MiAqIFR2YWx1ZXNbaV0gKyB6MixcbiAgICAgICAgeGJhc2UgPSBiYXNlMyhjdCwgeDEsIHgyLCB4MywgeDQpLFxuICAgICAgICB5YmFzZSA9IGJhc2UzKGN0LCB5MSwgeTIsIHkzLCB5NCksXG4gICAgICAgIGNvbWIgPSB4YmFzZSAqIHhiYXNlICsgeWJhc2UgKiB5YmFzZTtcblxuICAgIHN1bSArPSBDdmFsdWVzW2ldICogbWF0aC5zcXJ0KGNvbWIpO1xuICB9XG5cbiAgcmV0dXJuIHoyICogc3VtO1xufVxuXG5cbmZ1bmN0aW9uIGludGVyc2VjdExpbmVzKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCkge1xuXG4gIGlmIChcbiAgICBtbWF4KHgxLCB4MikgPCBtbWluKHgzLCB4NCkgfHxcbiAgICAgIG1taW4oeDEsIHgyKSA+IG1tYXgoeDMsIHg0KSB8fFxuICAgICAgbW1heCh5MSwgeTIpIDwgbW1pbih5MywgeTQpIHx8XG4gICAgICBtbWluKHkxLCB5MikgPiBtbWF4KHkzLCB5NClcbiAgKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG54ID0gKHgxICogeTIgLSB5MSAqIHgyKSAqICh4MyAtIHg0KSAtICh4MSAtIHgyKSAqICh4MyAqIHk0IC0geTMgKiB4NCksXG4gICAgICBueSA9ICh4MSAqIHkyIC0geTEgKiB4MikgKiAoeTMgLSB5NCkgLSAoeTEgLSB5MikgKiAoeDMgKiB5NCAtIHkzICogeDQpLFxuICAgICAgZGVub21pbmF0b3IgPSAoeDEgLSB4MikgKiAoeTMgLSB5NCkgLSAoeTEgLSB5MikgKiAoeDMgLSB4NCk7XG5cbiAgaWYgKCFkZW5vbWluYXRvcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBweCA9IGZpeEVycm9yKG54IC8gZGVub21pbmF0b3IpLFxuICAgICAgcHkgPSBmaXhFcnJvcihueSAvIGRlbm9taW5hdG9yKSxcbiAgICAgIHB4MiA9ICtweC50b0ZpeGVkKDIpLFxuICAgICAgcHkyID0gK3B5LnRvRml4ZWQoMik7XG5cbiAgaWYgKFxuICAgIHB4MiA8ICttbWluKHgxLCB4MikudG9GaXhlZCgyKSB8fFxuICAgICAgcHgyID4gK21tYXgoeDEsIHgyKS50b0ZpeGVkKDIpIHx8XG4gICAgICBweDIgPCArbW1pbih4MywgeDQpLnRvRml4ZWQoMikgfHxcbiAgICAgIHB4MiA+ICttbWF4KHgzLCB4NCkudG9GaXhlZCgyKSB8fFxuICAgICAgcHkyIDwgK21taW4oeTEsIHkyKS50b0ZpeGVkKDIpIHx8XG4gICAgICBweTIgPiArbW1heCh5MSwgeTIpLnRvRml4ZWQoMikgfHxcbiAgICAgIHB5MiA8ICttbWluKHkzLCB5NCkudG9GaXhlZCgyKSB8fFxuICAgICAgcHkyID4gK21tYXgoeTMsIHk0KS50b0ZpeGVkKDIpXG4gICkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiB7IHg6IHB4LCB5OiBweSB9O1xufVxuXG5mdW5jdGlvbiBmaXhFcnJvcihudW1iZXIpIHtcbiAgcmV0dXJuIE1hdGgucm91bmQobnVtYmVyICogMTAwMDAwMDAwMDAwKSAvIDEwMDAwMDAwMDAwMDtcbn1cblxuZnVuY3Rpb24gZmluZEJlemllckludGVyc2VjdGlvbnMoYmV6MSwgYmV6MiwganVzdENvdW50KSB7XG4gIHZhciBiYm94MSA9IGJlemllckJCb3goYmV6MSksXG4gICAgICBiYm94MiA9IGJlemllckJCb3goYmV6Mik7XG5cbiAgaWYgKCFpc0JCb3hJbnRlcnNlY3QoYmJveDEsIGJib3gyKSkge1xuICAgIHJldHVybiBqdXN0Q291bnQgPyAwIDogW107XG4gIH1cblxuICAvLyBBcyBhbiBvcHRpbWl6YXRpb24sIGxpbmVzIHdpbGwgaGF2ZSBvbmx5IDEgc2VnbWVudFxuXG4gIHZhciBsMSA9IGJlemxlbi5hcHBseSgwLCBiZXoxKSxcbiAgICAgIGwyID0gYmV6bGVuLmFwcGx5KDAsIGJlejIpLFxuICAgICAgbjEgPSBpc0xpbmUoYmV6MSkgPyAxIDogfn4obDEgLyA1KSB8fCAxLFxuICAgICAgbjIgPSBpc0xpbmUoYmV6MikgPyAxIDogfn4obDIgLyA1KSB8fCAxLFxuICAgICAgZG90czEgPSBbXSxcbiAgICAgIGRvdHMyID0gW10sXG4gICAgICB4eSA9IHt9LFxuICAgICAgcmVzID0ganVzdENvdW50ID8gMCA6IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjEgKyAxOyBpKyspIHtcbiAgICB2YXIgcCA9IGZpbmREb3RzQXRTZWdtZW50LmFwcGx5KDAsIGJlejEuY29uY2F0KGkgLyBuMSkpO1xuICAgIGRvdHMxLnB1c2goeyB4OiBwLngsIHk6IHAueSwgdDogaSAvIG4xIH0pO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IG4yICsgMTsgaSsrKSB7XG4gICAgcCA9IGZpbmREb3RzQXRTZWdtZW50LmFwcGx5KDAsIGJlejIuY29uY2F0KGkgLyBuMikpO1xuICAgIGRvdHMyLnB1c2goeyB4OiBwLngsIHk6IHAueSwgdDogaSAvIG4yIH0pO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IG4xOyBpKyspIHtcblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbjI7IGorKykge1xuICAgICAgdmFyIGRpID0gZG90czFbaV0sXG4gICAgICAgICAgZGkxID0gZG90czFbaSArIDFdLFxuICAgICAgICAgIGRqID0gZG90czJbal0sXG4gICAgICAgICAgZGoxID0gZG90czJbaiArIDFdLFxuICAgICAgICAgIGNpID0gYWJzKGRpMS54IC0gZGkueCkgPCAuMDEgPyAneScgOiAneCcsXG4gICAgICAgICAgY2ogPSBhYnMoZGoxLnggLSBkai54KSA8IC4wMSA/ICd5JyA6ICd4JyxcbiAgICAgICAgICBpcyA9IGludGVyc2VjdExpbmVzKGRpLngsIGRpLnksIGRpMS54LCBkaTEueSwgZGoueCwgZGoueSwgZGoxLngsIGRqMS55KSxcbiAgICAgICAgICBrZXk7XG5cbiAgICAgIGlmIChpcykge1xuICAgICAgICBrZXkgPSBpcy54LnRvRml4ZWQoOSkgKyAnIycgKyBpcy55LnRvRml4ZWQoOSk7XG5cbiAgICAgICAgaWYgKHh5W2tleV0pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHh5W2tleV0gPSB0cnVlO1xuXG4gICAgICAgIHZhciB0MSA9IGRpLnQgKyBhYnMoKGlzW2NpXSAtIGRpW2NpXSkgLyAoZGkxW2NpXSAtIGRpW2NpXSkpICogKGRpMS50IC0gZGkudCksXG4gICAgICAgICAgICB0MiA9IGRqLnQgKyBhYnMoKGlzW2NqXSAtIGRqW2NqXSkgLyAoZGoxW2NqXSAtIGRqW2NqXSkpICogKGRqMS50IC0gZGoudCk7XG5cbiAgICAgICAgaWYgKHQxID49IDAgJiYgdDEgPD0gMSAmJiB0MiA+PSAwICYmIHQyIDw9IDEpIHtcblxuICAgICAgICAgIGlmIChqdXN0Q291bnQpIHtcbiAgICAgICAgICAgIHJlcysrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXMucHVzaCh7XG4gICAgICAgICAgICAgIHg6IGlzLngsXG4gICAgICAgICAgICAgIHk6IGlzLnksXG4gICAgICAgICAgICAgIHQxOiB0MSxcbiAgICAgICAgICAgICAgdDI6IHQyXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufVxuXG5cbi8qKlxuICogRmluZCBvciBjb3VudHMgdGhlIGludGVyc2VjdGlvbnMgYmV0d2VlbiB0d28gU1ZHIHBhdGhzLlxuICpcbiAqIFJldHVybnMgYSBudW1iZXIgaW4gY291bnRpbmcgbW9kZSBhbmQgYSBsaXN0IG9mIGludGVyc2VjdGlvbnMgb3RoZXJ3aXNlLlxuICpcbiAqIEEgc2luZ2xlIGludGVyc2VjdGlvbiBlbnRyeSBjb250YWlucyB0aGUgaW50ZXJzZWN0aW9uIGNvb3JkaW5hdGVzICh4LCB5KVxuICogYXMgd2VsbCBhcyBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyB0aGUgaW50ZXJzZWN0aW5nIHNlZ21lbnRzXG4gKiBvbiBlYWNoIHBhdGggKHNlZ21lbnQxLCBzZWdtZW50MikgYW5kIHRoZSByZWxhdGl2ZSBsb2NhdGlvbiBvZiB0aGVcbiAqIGludGVyc2VjdGlvbiBvbiB0aGVzZSBzZWdtZW50cyAodDEsIHQyKS5cbiAqXG4gKiBUaGUgcGF0aCBtYXkgYmUgYW4gU1ZHIHBhdGggc3RyaW5nIG9yIGEgbGlzdCBvZiBwYXRoIGNvbXBvbmVudHNcbiAqIHN1Y2ggYXMgYFsgWyAnTScsIDAsIDEwIF0sIFsgJ0wnLCAyMCwgMCBdIF1gLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIGludGVyc2VjdGlvbnMgPSBmaW5kUGF0aEludGVyc2VjdGlvbnMoXG4gKiAgICdNMCwwTDEwMCwxMDAnLFxuICogICBbIFsgJ00nLCAwLCAxMDAgXSwgWyAnTCcsIDEwMCwgMCBdIF1cbiAqICk7XG4gKlxuICogLy8gaW50ZXJzZWN0aW9ucyA9IFtcbiAqIC8vICAgeyB4OiA1MCwgeTogNTAsIHNlZ21lbnQxOiAxLCBzZWdtZW50MjogMSwgdDE6IDAuNSwgdDI6IDAuNSB9XG4gKiAvLyBdXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXk8UGF0aERlZj59IHBhdGgxXG4gKiBAcGFyYW0ge1N0cmluZ3xBcnJheTxQYXRoRGVmPn0gcGF0aDJcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW2p1c3RDb3VudD1mYWxzZV1cbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxJbnRlcnNlY3Rpb24+fE51bWJlcn1cbiAqL1xuZnVuY3Rpb24gZmluZFBhdGhJbnRlcnNlY3Rpb25zKHBhdGgxLCBwYXRoMiwganVzdENvdW50KSB7XG4gIHBhdGgxID0gcGF0aFRvQ3VydmUocGF0aDEpO1xuICBwYXRoMiA9IHBhdGhUb0N1cnZlKHBhdGgyKTtcblxuICB2YXIgeDEsIHkxLCB4MiwgeTIsIHgxbSwgeTFtLCB4Mm0sIHkybSwgYmV6MSwgYmV6MixcbiAgICAgIHJlcyA9IGp1c3RDb3VudCA/IDAgOiBbXTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBwYXRoMS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgdmFyIHBpID0gcGF0aDFbaV07XG5cbiAgICBpZiAocGlbMF0gPT0gJ00nKSB7XG4gICAgICB4MSA9IHgxbSA9IHBpWzFdO1xuICAgICAgeTEgPSB5MW0gPSBwaVsyXTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICBpZiAocGlbMF0gPT0gJ0MnKSB7XG4gICAgICAgIGJlejEgPSBbeDEsIHkxXS5jb25jYXQocGkuc2xpY2UoMSkpO1xuICAgICAgICB4MSA9IGJlejFbNl07XG4gICAgICAgIHkxID0gYmV6MVs3XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJlejEgPSBbeDEsIHkxLCB4MSwgeTEsIHgxbSwgeTFtLCB4MW0sIHkxbV07XG4gICAgICAgIHgxID0geDFtO1xuICAgICAgICB5MSA9IHkxbTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gcGF0aDIubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICB2YXIgcGogPSBwYXRoMltqXTtcblxuICAgICAgICBpZiAocGpbMF0gPT0gJ00nKSB7XG4gICAgICAgICAgeDIgPSB4Mm0gPSBwalsxXTtcbiAgICAgICAgICB5MiA9IHkybSA9IHBqWzJdO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgaWYgKHBqWzBdID09ICdDJykge1xuICAgICAgICAgICAgYmV6MiA9IFt4MiwgeTJdLmNvbmNhdChwai5zbGljZSgxKSk7XG4gICAgICAgICAgICB4MiA9IGJlejJbNl07XG4gICAgICAgICAgICB5MiA9IGJlejJbN107XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJlejIgPSBbeDIsIHkyLCB4MiwgeTIsIHgybSwgeTJtLCB4Mm0sIHkybV07XG4gICAgICAgICAgICB4MiA9IHgybTtcbiAgICAgICAgICAgIHkyID0geTJtO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBpbnRyID0gZmluZEJlemllckludGVyc2VjdGlvbnMoYmV6MSwgYmV6MiwganVzdENvdW50KTtcblxuICAgICAgICAgIGlmIChqdXN0Q291bnQpIHtcbiAgICAgICAgICAgIHJlcyArPSBpbnRyO1xuICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGsgPSAwLCBrayA9IGludHIubGVuZ3RoOyBrIDwga2s7IGsrKykge1xuICAgICAgICAgICAgICBpbnRyW2tdLnNlZ21lbnQxID0gaTtcbiAgICAgICAgICAgICAgaW50cltrXS5zZWdtZW50MiA9IGo7XG4gICAgICAgICAgICAgIGludHJba10uYmV6MSA9IGJlejE7XG4gICAgICAgICAgICAgIGludHJba10uYmV6MiA9IGJlejI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoaW50cik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn1cblxuXG5mdW5jdGlvbiBwYXRoVG9BYnNvbHV0ZShwYXRoQXJyYXkpIHtcbiAgdmFyIHB0aCA9IHBhdGhzKHBhdGhBcnJheSk7XG5cbiAgaWYgKHB0aC5hYnMpIHtcbiAgICByZXR1cm4gcGF0aENsb25lKHB0aC5hYnMpO1xuICB9XG5cbiAgaWYgKCFpc0FycmF5KHBhdGhBcnJheSkgfHwgIWlzQXJyYXkocGF0aEFycmF5ICYmIHBhdGhBcnJheVswXSkpIHsgLy8gcm91Z2ggYXNzdW1wdGlvblxuICAgIHBhdGhBcnJheSA9IHBhcnNlUGF0aFN0cmluZyhwYXRoQXJyYXkpO1xuICB9XG5cbiAgaWYgKCFwYXRoQXJyYXkgfHwgIXBhdGhBcnJheS5sZW5ndGgpIHtcbiAgICByZXR1cm4gW1snTScsIDAsIDBdXTtcbiAgfVxuXG4gIHZhciByZXMgPSBbXSxcbiAgICAgIHggPSAwLFxuICAgICAgeSA9IDAsXG4gICAgICBteCA9IDAsXG4gICAgICBteSA9IDAsXG4gICAgICBzdGFydCA9IDAsXG4gICAgICBwYTA7XG5cbiAgaWYgKHBhdGhBcnJheVswXVswXSA9PSAnTScpIHtcbiAgICB4ID0gK3BhdGhBcnJheVswXVsxXTtcbiAgICB5ID0gK3BhdGhBcnJheVswXVsyXTtcbiAgICBteCA9IHg7XG4gICAgbXkgPSB5O1xuICAgIHN0YXJ0Kys7XG4gICAgcmVzWzBdID0gWydNJywgeCwgeV07XG4gIH1cblxuICBmb3IgKHZhciByLCBwYSwgaSA9IHN0YXJ0LCBpaSA9IHBhdGhBcnJheS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgcmVzLnB1c2gociA9IFtdKTtcbiAgICBwYSA9IHBhdGhBcnJheVtpXTtcbiAgICBwYTAgPSBwYVswXTtcblxuICAgIGlmIChwYTAgIT0gcGEwLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgIHJbMF0gPSBwYTAudG9VcHBlckNhc2UoKTtcblxuICAgICAgc3dpdGNoIChyWzBdKSB7XG4gICAgICBjYXNlICdBJzpcbiAgICAgICAgclsxXSA9IHBhWzFdO1xuICAgICAgICByWzJdID0gcGFbMl07XG4gICAgICAgIHJbM10gPSBwYVszXTtcbiAgICAgICAgcls0XSA9IHBhWzRdO1xuICAgICAgICByWzVdID0gcGFbNV07XG4gICAgICAgIHJbNl0gPSArcGFbNl0gKyB4O1xuICAgICAgICByWzddID0gK3BhWzddICsgeTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdWJzpcbiAgICAgICAgclsxXSA9ICtwYVsxXSArIHk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnSCc6XG4gICAgICAgIHJbMV0gPSArcGFbMV0gKyB4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ00nOlxuICAgICAgICBteCA9ICtwYVsxXSArIHg7XG4gICAgICAgIG15ID0gK3BhWzJdICsgeTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGZvciAodmFyIGogPSAxLCBqaiA9IHBhLmxlbmd0aDsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICByW2pdID0gK3BhW2pdICsgKChqICUgMikgPyB4IDogeSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgayA9IDAsIGtrID0gcGEubGVuZ3RoOyBrIDwga2s7IGsrKykge1xuICAgICAgICByW2tdID0gcGFba107XG4gICAgICB9XG4gICAgfVxuICAgIHBhMCA9IHBhMC50b1VwcGVyQ2FzZSgpO1xuXG4gICAgc3dpdGNoIChyWzBdKSB7XG4gICAgY2FzZSAnWic6XG4gICAgICB4ID0gK214O1xuICAgICAgeSA9ICtteTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0gnOlxuICAgICAgeCA9IHJbMV07XG4gICAgICBicmVhaztcbiAgICBjYXNlICdWJzpcbiAgICAgIHkgPSByWzFdO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnTSc6XG4gICAgICBteCA9IHJbci5sZW5ndGggLSAyXTtcbiAgICAgIG15ID0gcltyLmxlbmd0aCAtIDFdO1xuICAgIGRlZmF1bHQ6XG4gICAgICB4ID0gcltyLmxlbmd0aCAtIDJdO1xuICAgICAgeSA9IHJbci5sZW5ndGggLSAxXTtcbiAgICB9XG4gIH1cblxuICByZXMudG9TdHJpbmcgPSBwYXRoVG9TdHJpbmc7XG4gIHB0aC5hYnMgPSBwYXRoQ2xvbmUocmVzKTtcblxuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiBpc0xpbmUoYmV6KSB7XG4gIHJldHVybiAoXG4gICAgYmV6WzBdID09PSBiZXpbMl0gJiZcbiAgICBiZXpbMV0gPT09IGJlelszXSAmJlxuICAgIGJlels0XSA9PT0gYmV6WzZdICYmXG4gICAgYmV6WzVdID09PSBiZXpbN11cbiAgKTtcbn1cblxuZnVuY3Rpb24gbGluZVRvQ3VydmUoeDEsIHkxLCB4MiwgeTIpIHtcbiAgcmV0dXJuIFtcbiAgICB4MSwgeTEsIHgyLFxuICAgIHkyLCB4MiwgeTJcbiAgXTtcbn1cblxuZnVuY3Rpb24gcXViaWNUb0N1cnZlKHgxLCB5MSwgYXgsIGF5LCB4MiwgeTIpIHtcbiAgdmFyIF8xMyA9IDEgLyAzLFxuICAgICAgXzIzID0gMiAvIDM7XG5cbiAgcmV0dXJuIFtcbiAgICBfMTMgKiB4MSArIF8yMyAqIGF4LFxuICAgIF8xMyAqIHkxICsgXzIzICogYXksXG4gICAgXzEzICogeDIgKyBfMjMgKiBheCxcbiAgICBfMTMgKiB5MiArIF8yMyAqIGF5LFxuICAgIHgyLFxuICAgIHkyXG4gIF07XG59XG5cbmZ1bmN0aW9uIGFyY1RvQ3VydmUoeDEsIHkxLCByeCwgcnksIGFuZ2xlLCBsYXJnZV9hcmNfZmxhZywgc3dlZXBfZmxhZywgeDIsIHkyLCByZWN1cnNpdmUpIHtcblxuICAvLyBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvZiB3aGVyZSB0aGlzIG1hdGggY2FtZSBmcm9tIHZpc2l0OlxuICAvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9pbXBsbm90ZS5odG1sI0FyY0ltcGxlbWVudGF0aW9uTm90ZXNcbiAgdmFyIF8xMjAgPSBQSSAqIDEyMCAvIDE4MCxcbiAgICAgIHJhZCA9IFBJIC8gMTgwICogKCthbmdsZSB8fCAwKSxcbiAgICAgIHJlcyA9IFtdLFxuICAgICAgeHksXG4gICAgICByb3RhdGUgPSBjYWNoZXIoZnVuY3Rpb24oeCwgeSwgcmFkKSB7XG4gICAgICAgIHZhciBYID0geCAqIG1hdGguY29zKHJhZCkgLSB5ICogbWF0aC5zaW4ocmFkKSxcbiAgICAgICAgICAgIFkgPSB4ICogbWF0aC5zaW4ocmFkKSArIHkgKiBtYXRoLmNvcyhyYWQpO1xuXG4gICAgICAgIHJldHVybiB7IHg6IFgsIHk6IFkgfTtcbiAgICAgIH0pO1xuXG4gIGlmICghcmVjdXJzaXZlKSB7XG4gICAgeHkgPSByb3RhdGUoeDEsIHkxLCAtcmFkKTtcbiAgICB4MSA9IHh5Lng7XG4gICAgeTEgPSB4eS55O1xuICAgIHh5ID0gcm90YXRlKHgyLCB5MiwgLXJhZCk7XG4gICAgeDIgPSB4eS54O1xuICAgIHkyID0geHkueTtcblxuICAgIHZhciB4ID0gKHgxIC0geDIpIC8gMixcbiAgICAgICAgeSA9ICh5MSAtIHkyKSAvIDI7XG5cbiAgICB2YXIgaCA9ICh4ICogeCkgLyAocnggKiByeCkgKyAoeSAqIHkpIC8gKHJ5ICogcnkpO1xuXG4gICAgaWYgKGggPiAxKSB7XG4gICAgICBoID0gbWF0aC5zcXJ0KGgpO1xuICAgICAgcnggPSBoICogcng7XG4gICAgICByeSA9IGggKiByeTtcbiAgICB9XG5cbiAgICB2YXIgcngyID0gcnggKiByeCxcbiAgICAgICAgcnkyID0gcnkgKiByeSxcbiAgICAgICAgayA9IChsYXJnZV9hcmNfZmxhZyA9PSBzd2VlcF9mbGFnID8gLTEgOiAxKSAqXG4gICAgICAgICAgICBtYXRoLnNxcnQoYWJzKChyeDIgKiByeTIgLSByeDIgKiB5ICogeSAtIHJ5MiAqIHggKiB4KSAvIChyeDIgKiB5ICogeSArIHJ5MiAqIHggKiB4KSkpLFxuICAgICAgICBjeCA9IGsgKiByeCAqIHkgLyByeSArICh4MSArIHgyKSAvIDIsXG4gICAgICAgIGN5ID0gayAqIC1yeSAqIHggLyByeCArICh5MSArIHkyKSAvIDIsXG4gICAgICAgIGYxID0gbWF0aC5hc2luKCgoeTEgLSBjeSkgLyByeSkudG9GaXhlZCg5KSksXG4gICAgICAgIGYyID0gbWF0aC5hc2luKCgoeTIgLSBjeSkgLyByeSkudG9GaXhlZCg5KSk7XG5cbiAgICBmMSA9IHgxIDwgY3ggPyBQSSAtIGYxIDogZjE7XG4gICAgZjIgPSB4MiA8IGN4ID8gUEkgLSBmMiA6IGYyO1xuICAgIGYxIDwgMCAmJiAoZjEgPSBQSSAqIDIgKyBmMSk7XG4gICAgZjIgPCAwICYmIChmMiA9IFBJICogMiArIGYyKTtcblxuICAgIGlmIChzd2VlcF9mbGFnICYmIGYxID4gZjIpIHtcbiAgICAgIGYxID0gZjEgLSBQSSAqIDI7XG4gICAgfVxuICAgIGlmICghc3dlZXBfZmxhZyAmJiBmMiA+IGYxKSB7XG4gICAgICBmMiA9IGYyIC0gUEkgKiAyO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmMSA9IHJlY3Vyc2l2ZVswXTtcbiAgICBmMiA9IHJlY3Vyc2l2ZVsxXTtcbiAgICBjeCA9IHJlY3Vyc2l2ZVsyXTtcbiAgICBjeSA9IHJlY3Vyc2l2ZVszXTtcbiAgfVxuXG4gIHZhciBkZiA9IGYyIC0gZjE7XG5cbiAgaWYgKGFicyhkZikgPiBfMTIwKSB7XG4gICAgdmFyIGYyb2xkID0gZjIsXG4gICAgICAgIHgyb2xkID0geDIsXG4gICAgICAgIHkyb2xkID0geTI7XG5cbiAgICBmMiA9IGYxICsgXzEyMCAqIChzd2VlcF9mbGFnICYmIGYyID4gZjEgPyAxIDogLTEpO1xuICAgIHgyID0gY3ggKyByeCAqIG1hdGguY29zKGYyKTtcbiAgICB5MiA9IGN5ICsgcnkgKiBtYXRoLnNpbihmMik7XG4gICAgcmVzID0gYXJjVG9DdXJ2ZSh4MiwgeTIsIHJ4LCByeSwgYW5nbGUsIDAsIHN3ZWVwX2ZsYWcsIHgyb2xkLCB5Mm9sZCwgW2YyLCBmMm9sZCwgY3gsIGN5XSk7XG4gIH1cblxuICBkZiA9IGYyIC0gZjE7XG5cbiAgdmFyIGMxID0gbWF0aC5jb3MoZjEpLFxuICAgICAgczEgPSBtYXRoLnNpbihmMSksXG4gICAgICBjMiA9IG1hdGguY29zKGYyKSxcbiAgICAgIHMyID0gbWF0aC5zaW4oZjIpLFxuICAgICAgdCA9IG1hdGgudGFuKGRmIC8gNCksXG4gICAgICBoeCA9IDQgLyAzICogcnggKiB0LFxuICAgICAgaHkgPSA0IC8gMyAqIHJ5ICogdCxcbiAgICAgIG0xID0gW3gxLCB5MV0sXG4gICAgICBtMiA9IFt4MSArIGh4ICogczEsIHkxIC0gaHkgKiBjMV0sXG4gICAgICBtMyA9IFt4MiArIGh4ICogczIsIHkyIC0gaHkgKiBjMl0sXG4gICAgICBtNCA9IFt4MiwgeTJdO1xuXG4gIG0yWzBdID0gMiAqIG0xWzBdIC0gbTJbMF07XG4gIG0yWzFdID0gMiAqIG0xWzFdIC0gbTJbMV07XG5cbiAgaWYgKHJlY3Vyc2l2ZSkge1xuICAgIHJldHVybiBbbTIsIG0zLCBtNF0uY29uY2F0KHJlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVzID0gW20yLCBtMywgbTRdLmNvbmNhdChyZXMpLmpvaW4oKS5zcGxpdCgnLCcpO1xuICAgIHZhciBuZXdyZXMgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHJlcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICBuZXdyZXNbaV0gPSBpICUgMiA/IHJvdGF0ZShyZXNbaSAtIDFdLCByZXNbaV0sIHJhZCkueSA6IHJvdGF0ZShyZXNbaV0sIHJlc1tpICsgMV0sIHJhZCkueDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3cmVzO1xuICB9XG59XG5cbi8vIFJldHVybnMgYm91bmRpbmcgYm94IG9mIGN1YmljIGJlemllciBjdXJ2ZS5cbi8vIFNvdXJjZTogaHR0cDovL2Jsb2cuaGFja2Vycy1jYWZlLm5ldC8yMDA5LzA2L2hvdy10by1jYWxjdWxhdGUtYmV6aWVyLWN1cnZlcy1ib3VuZGluZy5odG1sXG4vLyBPcmlnaW5hbCB2ZXJzaW9uOiBOSVNISU8gSGlyb2thenVcbi8vIE1vZGlmaWNhdGlvbnM6IGh0dHBzOi8vZ2l0aHViLmNvbS90aW1vMjIzNDVcbmZ1bmN0aW9uIGN1cnZlQkJveCh4MCwgeTAsIHgxLCB5MSwgeDIsIHkyLCB4MywgeTMpIHtcbiAgdmFyIHR2YWx1ZXMgPSBbXSxcbiAgICAgIGJvdW5kcyA9IFtbXSwgW11dLFxuICAgICAgYSwgYiwgYywgdCwgdDEsIHQyLCBiMmFjLCBzcXJ0YjJhYztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDI7ICsraSkge1xuXG4gICAgaWYgKGkgPT0gMCkge1xuICAgICAgYiA9IDYgKiB4MCAtIDEyICogeDEgKyA2ICogeDI7XG4gICAgICBhID0gLTMgKiB4MCArIDkgKiB4MSAtIDkgKiB4MiArIDMgKiB4MztcbiAgICAgIGMgPSAzICogeDEgLSAzICogeDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGIgPSA2ICogeTAgLSAxMiAqIHkxICsgNiAqIHkyO1xuICAgICAgYSA9IC0zICogeTAgKyA5ICogeTEgLSA5ICogeTIgKyAzICogeTM7XG4gICAgICBjID0gMyAqIHkxIC0gMyAqIHkwO1xuICAgIH1cblxuICAgIGlmIChhYnMoYSkgPCAxZS0xMikge1xuXG4gICAgICBpZiAoYWJzKGIpIDwgMWUtMTIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHQgPSAtYyAvIGI7XG5cbiAgICAgIGlmICgwIDwgdCAmJiB0IDwgMSkge1xuICAgICAgICB0dmFsdWVzLnB1c2godCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGIyYWMgPSBiICogYiAtIDQgKiBjICogYTtcbiAgICBzcXJ0YjJhYyA9IG1hdGguc3FydChiMmFjKTtcblxuICAgIGlmIChiMmFjIDwgMCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdDEgPSAoLWIgKyBzcXJ0YjJhYykgLyAoMiAqIGEpO1xuXG4gICAgaWYgKDAgPCB0MSAmJiB0MSA8IDEpIHtcbiAgICAgIHR2YWx1ZXMucHVzaCh0MSk7XG4gICAgfVxuXG4gICAgdDIgPSAoLWIgLSBzcXJ0YjJhYykgLyAoMiAqIGEpO1xuXG4gICAgaWYgKDAgPCB0MiAmJiB0MiA8IDEpIHtcbiAgICAgIHR2YWx1ZXMucHVzaCh0Mik7XG4gICAgfVxuICB9XG5cbiAgdmFyIGogPSB0dmFsdWVzLmxlbmd0aCxcbiAgICAgIGpsZW4gPSBqLFxuICAgICAgbXQ7XG5cbiAgd2hpbGUgKGotLSkge1xuICAgIHQgPSB0dmFsdWVzW2pdO1xuICAgIG10ID0gMSAtIHQ7XG4gICAgYm91bmRzWzBdW2pdID0gKG10ICogbXQgKiBtdCAqIHgwKSArICgzICogbXQgKiBtdCAqIHQgKiB4MSkgKyAoMyAqIG10ICogdCAqIHQgKiB4MikgKyAodCAqIHQgKiB0ICogeDMpO1xuICAgIGJvdW5kc1sxXVtqXSA9IChtdCAqIG10ICogbXQgKiB5MCkgKyAoMyAqIG10ICogbXQgKiB0ICogeTEpICsgKDMgKiBtdCAqIHQgKiB0ICogeTIpICsgKHQgKiB0ICogdCAqIHkzKTtcbiAgfVxuXG4gIGJvdW5kc1swXVtqbGVuXSA9IHgwO1xuICBib3VuZHNbMV1bamxlbl0gPSB5MDtcbiAgYm91bmRzWzBdW2psZW4gKyAxXSA9IHgzO1xuICBib3VuZHNbMV1bamxlbiArIDFdID0geTM7XG4gIGJvdW5kc1swXS5sZW5ndGggPSBib3VuZHNbMV0ubGVuZ3RoID0gamxlbiArIDI7XG5cbiAgcmV0dXJuIHtcbiAgICB4MDogbW1pbi5hcHBseSgwLCBib3VuZHNbMF0pLFxuICAgIHkwOiBtbWluLmFwcGx5KDAsIGJvdW5kc1sxXSksXG4gICAgeDE6IG1tYXguYXBwbHkoMCwgYm91bmRzWzBdKSxcbiAgICB5MTogbW1heC5hcHBseSgwLCBib3VuZHNbMV0pXG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhdGhUb0N1cnZlKHBhdGgpIHtcblxuICB2YXIgcHRoID0gcGF0aHMocGF0aCk7XG5cbiAgLy8gcmV0dXJuIGNhY2hlZCBjdXJ2ZSwgaWYgZXhpc3RpbmdcbiAgaWYgKHB0aC5jdXJ2ZSkge1xuICAgIHJldHVybiBwYXRoQ2xvbmUocHRoLmN1cnZlKTtcbiAgfVxuXG4gIHZhciBjdXJ2ZWRQYXRoID0gcGF0aFRvQWJzb2x1dGUocGF0aCksXG4gICAgICBhdHRycyA9IHsgeDogMCwgeTogMCwgYng6IDAsIGJ5OiAwLCBYOiAwLCBZOiAwLCBxeDogbnVsbCwgcXk6IG51bGwgfSxcbiAgICAgIHByb2Nlc3NQYXRoID0gZnVuY3Rpb24ocGF0aCwgZCwgcGF0aENvbW1hbmQpIHtcbiAgICAgICAgdmFyIG54LCBueTtcblxuICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICByZXR1cm4gWydDJywgZC54LCBkLnksIGQueCwgZC55LCBkLngsIGQueV07XG4gICAgICAgIH1cblxuICAgICAgICAhKHBhdGhbMF0gaW4geyBUOiAxLCBROiAxIH0pICYmIChkLnF4ID0gZC5xeSA9IG51bGwpO1xuXG4gICAgICAgIHN3aXRjaCAocGF0aFswXSkge1xuICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICBkLlggPSBwYXRoWzFdO1xuICAgICAgICAgIGQuWSA9IHBhdGhbMl07XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0EnOlxuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQoYXJjVG9DdXJ2ZS5hcHBseSgwLCBbZC54LCBkLnldLmNvbmNhdChwYXRoLnNsaWNlKDEpKSkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdTJzpcbiAgICAgICAgICBpZiAocGF0aENvbW1hbmQgPT0gJ0MnIHx8IHBhdGhDb21tYW5kID09ICdTJykge1xuICAgICAgICAgICAgLy8gSW4gJ1MnIGNhc2Ugd2UgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCwgaWYgdGhlIHByZXZpb3VzIGNvbW1hbmQgaXMgQy9TLlxuICAgICAgICAgICAgbnggPSBkLnggKiAyIC0gZC5ieDtcbiAgICAgICAgICAgIC8vIEFuZCByZWZsZWN0IHRoZSBwcmV2aW91c1xuICAgICAgICAgICAgbnkgPSBkLnkgKiAyIC0gZC5ieTtcbiAgICAgICAgICAgIC8vIGNvbW1hbmQncyBjb250cm9sIHBvaW50IHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHBvaW50LlxuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIG9yIHNvbWUgZWxzZSBvciBub3RoaW5nXG4gICAgICAgICAgICBueCA9IGQueDtcbiAgICAgICAgICAgIG55ID0gZC55O1xuICAgICAgICAgIH1cbiAgICAgICAgICBwYXRoID0gWydDJywgbngsIG55XS5jb25jYXQocGF0aC5zbGljZSgxKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1QnOlxuICAgICAgICAgIGlmIChwYXRoQ29tbWFuZCA9PSAnUScgfHwgcGF0aENvbW1hbmQgPT0gJ1QnKSB7XG4gICAgICAgICAgICAvLyBJbiAnVCcgY2FzZSB3ZSBoYXZlIHRvIHRha2UgaW50byBhY2NvdW50LCBpZiB0aGUgcHJldmlvdXMgY29tbWFuZCBpcyBRL1QuXG4gICAgICAgICAgICBkLnF4ID0gZC54ICogMiAtIGQucXg7XG4gICAgICAgICAgICAvLyBBbmQgbWFrZSBhIHJlZmxlY3Rpb24gc2ltaWxhclxuICAgICAgICAgICAgZC5xeSA9IGQueSAqIDIgLSBkLnF5O1xuICAgICAgICAgICAgLy8gdG8gY2FzZSAnUycuXG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gb3Igc29tZXRoaW5nIGVsc2Ugb3Igbm90aGluZ1xuICAgICAgICAgICAgZC5xeCA9IGQueDtcbiAgICAgICAgICAgIGQucXkgPSBkLnk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQocXViaWNUb0N1cnZlKGQueCwgZC55LCBkLnF4LCBkLnF5LCBwYXRoWzFdLCBwYXRoWzJdKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1EnOlxuICAgICAgICAgIGQucXggPSBwYXRoWzFdO1xuICAgICAgICAgIGQucXkgPSBwYXRoWzJdO1xuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQocXViaWNUb0N1cnZlKGQueCwgZC55LCBwYXRoWzFdLCBwYXRoWzJdLCBwYXRoWzNdLCBwYXRoWzRdKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0wnOlxuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQobGluZVRvQ3VydmUoZC54LCBkLnksIHBhdGhbMV0sIHBhdGhbMl0pKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnSCc6XG4gICAgICAgICAgcGF0aCA9IFsnQyddLmNvbmNhdChsaW5lVG9DdXJ2ZShkLngsIGQueSwgcGF0aFsxXSwgZC55KSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1YnOlxuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQobGluZVRvQ3VydmUoZC54LCBkLnksIGQueCwgcGF0aFsxXSkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdaJzpcbiAgICAgICAgICBwYXRoID0gWydDJ10uY29uY2F0KGxpbmVUb0N1cnZlKGQueCwgZC55LCBkLlgsIGQuWSkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgICB9LFxuXG4gICAgICBmaXhBcmMgPSBmdW5jdGlvbihwcCwgaSkge1xuXG4gICAgICAgIGlmIChwcFtpXS5sZW5ndGggPiA3KSB7XG4gICAgICAgICAgcHBbaV0uc2hpZnQoKTtcbiAgICAgICAgICB2YXIgcGkgPSBwcFtpXTtcblxuICAgICAgICAgIHdoaWxlIChwaS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHBhdGhDb21tYW5kc1tpXSA9ICdBJzsgLy8gaWYgY3JlYXRlZCBtdWx0aXBsZSBDOnMsIHRoZWlyIG9yaWdpbmFsIHNlZyBpcyBzYXZlZFxuICAgICAgICAgICAgcHAuc3BsaWNlKGkrKywgMCwgWydDJ10uY29uY2F0KHBpLnNwbGljZSgwLCA2KSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHBwLnNwbGljZShpLCAxKTtcbiAgICAgICAgICBpaSA9IGN1cnZlZFBhdGgubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgICBwYXRoQ29tbWFuZHMgPSBbXSwgLy8gcGF0aCBjb21tYW5kcyBvZiBvcmlnaW5hbCBwYXRoIHBcbiAgICAgIHBmaXJzdCA9ICcnLCAvLyB0ZW1wb3JhcnkgaG9sZGVyIGZvciBvcmlnaW5hbCBwYXRoIGNvbW1hbmRcbiAgICAgIHBhdGhDb21tYW5kID0gJyc7IC8vIGhvbGRlciBmb3IgcHJldmlvdXMgcGF0aCBjb21tYW5kIG9mIG9yaWdpbmFsIHBhdGhcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBjdXJ2ZWRQYXRoLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBjdXJ2ZWRQYXRoW2ldICYmIChwZmlyc3QgPSBjdXJ2ZWRQYXRoW2ldWzBdKTsgLy8gc2F2ZSBjdXJyZW50IHBhdGggY29tbWFuZFxuXG4gICAgaWYgKHBmaXJzdCAhPSAnQycpIC8vIEMgaXMgbm90IHNhdmVkIHlldCwgYmVjYXVzZSBpdCBtYXkgYmUgcmVzdWx0IG9mIGNvbnZlcnNpb25cbiAgICB7XG4gICAgICBwYXRoQ29tbWFuZHNbaV0gPSBwZmlyc3Q7IC8vIFNhdmUgY3VycmVudCBwYXRoIGNvbW1hbmRcbiAgICAgIGkgJiYgKHBhdGhDb21tYW5kID0gcGF0aENvbW1hbmRzW2kgLSAxXSk7IC8vIEdldCBwcmV2aW91cyBwYXRoIGNvbW1hbmQgcGF0aENvbW1hbmRcbiAgICB9XG4gICAgY3VydmVkUGF0aFtpXSA9IHByb2Nlc3NQYXRoKGN1cnZlZFBhdGhbaV0sIGF0dHJzLCBwYXRoQ29tbWFuZCk7IC8vIFByZXZpb3VzIHBhdGggY29tbWFuZCBpcyBpbnB1dHRlZCB0byBwcm9jZXNzUGF0aFxuXG4gICAgaWYgKHBhdGhDb21tYW5kc1tpXSAhPSAnQScgJiYgcGZpcnN0ID09ICdDJykgcGF0aENvbW1hbmRzW2ldID0gJ0MnOyAvLyBBIGlzIHRoZSBvbmx5IGNvbW1hbmRcbiAgICAvLyB3aGljaCBtYXkgcHJvZHVjZSBtdWx0aXBsZSBDOnNcbiAgICAvLyBzbyB3ZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IEMgaXMgYWxzbyBDIGluIG9yaWdpbmFsIHBhdGhcblxuICAgIGZpeEFyYyhjdXJ2ZWRQYXRoLCBpKTsgLy8gZml4QXJjIGFkZHMgYWxzbyB0aGUgcmlnaHQgYW1vdW50IG9mIEE6cyB0byBwYXRoQ29tbWFuZHNcblxuICAgIHZhciBzZWcgPSBjdXJ2ZWRQYXRoW2ldLFxuICAgICAgICBzZWdsZW4gPSBzZWcubGVuZ3RoO1xuXG4gICAgYXR0cnMueCA9IHNlZ1tzZWdsZW4gLSAyXTtcbiAgICBhdHRycy55ID0gc2VnW3NlZ2xlbiAtIDFdO1xuICAgIGF0dHJzLmJ4ID0gdG9GbG9hdChzZWdbc2VnbGVuIC0gNF0pIHx8IGF0dHJzLng7XG4gICAgYXR0cnMuYnkgPSB0b0Zsb2F0KHNlZ1tzZWdsZW4gLSAzXSkgfHwgYXR0cnMueTtcbiAgfVxuXG4gIC8vIGNhY2hlIGN1cnZlXG4gIHB0aC5jdXJ2ZSA9IHBhdGhDbG9uZShjdXJ2ZWRQYXRoKTtcblxuICByZXR1cm4gY3VydmVkUGF0aDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmaW5kUGF0aEludGVyc2VjdGlvbnM7XG4iLCJ2YXIgZnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcblxudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxudmFyIEVOVElUWV9QQVRURVJOID0gLyYjKFxcZCspO3wmI3goWzAtOWEtZl0rKTt8JihcXHcrKTsvaWc7XG5cbnZhciBFTlRJVFlfTUFQUElORyA9IHtcbiAgJ2FtcCc6ICcmJyxcbiAgJ2Fwb3MnOiAnXFwnJyxcbiAgJ2d0JzogJz4nLFxuICAnbHQnOiAnPCcsXG4gICdxdW90JzogJ1wiJ1xufTtcblxuLy8gbWFwIFVQUEVSQ0FTRSB2YXJpYW50cyBvZiBzdXBwb3J0ZWQgc3BlY2lhbCBjaGFyc1xuT2JqZWN0LmtleXMoRU5USVRZX01BUFBJTkcpLmZvckVhY2goZnVuY3Rpb24oaykge1xuICBFTlRJVFlfTUFQUElOR1trLnRvVXBwZXJDYXNlKCldID0gRU5USVRZX01BUFBJTkdba107XG59KTtcblxuXG5mdW5jdGlvbiByZXBsYWNlRW50aXRpZXMoXywgZCwgeCwgeikge1xuXG4gIC8vIHJlc2VydmVkIG5hbWVzLCBpLmUuICZuYnNwO1xuICBpZiAoeikge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKEVOVElUWV9NQVBQSU5HLCB6KSkge1xuICAgICAgcmV0dXJuIEVOVElUWV9NQVBQSU5HW3pdO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIC8vIGZhbGwgYmFjayB0byBvcmlnaW5hbCB2YWx1ZVxuICAgICAgcmV0dXJuICcmJyArIHogKyAnOyc7XG4gICAgfVxuICB9XG5cbiAgLy8gZGVjaW1hbCBlbmNvZGVkIGNoYXJcbiAgaWYgKGQpIHtcbiAgICByZXR1cm4gZnJvbUNoYXJDb2RlKGQpO1xuICB9XG5cbiAgLy8gaGV4IGVuY29kZWQgY2hhclxuICByZXR1cm4gZnJvbUNoYXJDb2RlKHBhcnNlSW50KHgsIDE2KSk7XG59XG5cblxuLyoqXG4gKiBBIGJhc2ljIGVudGl0eSBkZWNvZGVyIHRoYXQgY2FuIGRlY29kZSBhIG1pbmltYWxcbiAqIHN1Yi1zZXQgb2YgcmVzZXJ2ZWQgbmFtZXMgKCZhbXA7KSBhcyB3ZWxsIGFzXG4gKiBoZXggKCYjeGFhZjspIGFuZCBkZWNpbWFsICgmIzEyMzE7KSBlbmNvZGVkIGNoYXJhY3RlcnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICpcbiAqIEByZXR1cm4ge3N0cmluZ30gZGVjb2RlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gZGVjb2RlRW50aXRpZXMocykge1xuICBpZiAocy5sZW5ndGggPiAzICYmIHMuaW5kZXhPZignJicpICE9PSAtMSkge1xuICAgIHJldHVybiBzLnJlcGxhY2UoRU5USVRZX1BBVFRFUk4sIHJlcGxhY2VFbnRpdGllcyk7XG4gIH1cblxuICByZXR1cm4gcztcbn1cblxudmFyIFhTSV9VUkkgPSAnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UnO1xudmFyIFhTSV9QUkVGSVggPSAneHNpJztcbnZhciBYU0lfVFlQRSA9ICd4c2k6dHlwZSc7XG5cbnZhciBOT05fV0hJVEVTUEFDRV9PVVRTSURFX1JPT1RfTk9ERSA9ICdub24td2hpdGVzcGFjZSBvdXRzaWRlIG9mIHJvb3Qgbm9kZSc7XG5cbmZ1bmN0aW9uIGVycm9yKG1zZykge1xuICByZXR1cm4gbmV3IEVycm9yKG1zZyk7XG59XG5cbmZ1bmN0aW9uIG1pc3NpbmdOYW1lc3BhY2VGb3JQcmVmaXgocHJlZml4KSB7XG4gIHJldHVybiAnbWlzc2luZyBuYW1lc3BhY2UgZm9yIHByZWZpeCA8JyArIHByZWZpeCArICc+Jztcbn1cblxuZnVuY3Rpb24gZ2V0dGVyKGdldEZuKSB7XG4gIHJldHVybiB7XG4gICAgJ2dldCc6IGdldEZuLFxuICAgICdlbnVtZXJhYmxlJzogdHJ1ZVxuICB9O1xufVxuXG5mdW5jdGlvbiBjbG9uZU5zTWF0cml4KG5zTWF0cml4KSB7XG4gIHZhciBjbG9uZSA9IHt9LCBrZXk7XG4gIGZvciAoa2V5IGluIG5zTWF0cml4KSB7XG4gICAgY2xvbmVba2V5XSA9IG5zTWF0cml4W2tleV07XG4gIH1cbiAgcmV0dXJuIGNsb25lO1xufVxuXG5mdW5jdGlvbiB1cmlQcmVmaXgocHJlZml4KSB7XG4gIHJldHVybiBwcmVmaXggKyAnJHVyaSc7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkTnNNYXRyaXgobnNVcmlUb1ByZWZpeCkge1xuICB2YXIgbnNNYXRyaXggPSB7fSxcbiAgICAgIHVyaSxcbiAgICAgIHByZWZpeDtcblxuICBmb3IgKHVyaSBpbiBuc1VyaVRvUHJlZml4KSB7XG4gICAgcHJlZml4ID0gbnNVcmlUb1ByZWZpeFt1cmldO1xuICAgIG5zTWF0cml4W3ByZWZpeF0gPSBwcmVmaXg7XG4gICAgbnNNYXRyaXhbdXJpUHJlZml4KHByZWZpeCldID0gdXJpO1xuICB9XG5cbiAgcmV0dXJuIG5zTWF0cml4O1xufVxuXG5mdW5jdGlvbiBub29wR2V0Q29udGV4dCgpIHtcbiAgcmV0dXJuIHsgJ2xpbmUnOiAwLCAnY29sdW1uJzogMCB9O1xufVxuXG5mdW5jdGlvbiB0aHJvd0Z1bmMoZXJyKSB7XG4gIHRocm93IGVycjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHBhcnNlciB3aXRoIHRoZSBnaXZlbiBvcHRpb25zLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSAgeyFPYmplY3Q8c3RyaW5nLCA/Pj19IG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gUGFyc2VyKG9wdGlvbnMpIHtcblxuICBpZiAoIXRoaXMpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlcihvcHRpb25zKTtcbiAgfVxuXG4gIHZhciBwcm94eSA9IG9wdGlvbnMgJiYgb3B0aW9uc1sncHJveHknXTtcblxuICB2YXIgb25UZXh0LFxuICAgICAgb25PcGVuVGFnLFxuICAgICAgb25DbG9zZVRhZyxcbiAgICAgIG9uQ0RBVEEsXG4gICAgICBvbkVycm9yID0gdGhyb3dGdW5jLFxuICAgICAgb25XYXJuaW5nLFxuICAgICAgb25Db21tZW50LFxuICAgICAgb25RdWVzdGlvbixcbiAgICAgIG9uQXR0ZW50aW9uO1xuXG4gIHZhciBnZXRDb250ZXh0ID0gbm9vcEdldENvbnRleHQ7XG5cbiAgLyoqXG4gICAqIERvIHdlIG5lZWQgdG8gcGFyc2UgdGhlIGN1cnJlbnQgZWxlbWVudHMgYXR0cmlidXRlcyBmb3IgbmFtZXNwYWNlcz9cbiAgICpcbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqL1xuICB2YXIgbWF5YmVOUyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBEbyB3ZSBwcm9jZXNzIG5hbWVzcGFjZXMgYXQgYWxsP1xuICAgKlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIHZhciBpc05hbWVzcGFjZSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBUaGUgY2F1Z2h0IGVycm9yIHJldHVybmVkIG9uIHBhcnNlIGVuZFxuICAgKlxuICAgKiBAdHlwZSB7RXJyb3J9XG4gICAqL1xuICB2YXIgcmV0dXJuRXJyb3IgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBTaG91bGQgd2Ugc3RvcCBwYXJzaW5nP1xuICAgKlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIHZhciBwYXJzZVN0b3AgPSBmYWxzZTtcblxuICAvKipcbiAgICogQSBtYXAgb2YgeyB1cmk6IHByZWZpeCB9IHVzZWQgYnkgdGhlIHBhcnNlci5cbiAgICpcbiAgICogVGhpcyBtYXAgd2lsbCBlbnN1cmUgd2UgY2FuIG5vcm1hbGl6ZSBwcmVmaXhlcyBkdXJpbmcgcHJvY2Vzc2luZztcbiAgICogZm9yIGVhY2ggdXJpLCBvbmx5IG9uZSBwcmVmaXggd2lsbCBiZSBleHBvc2VkIHRvIHRoZSBoYW5kbGVycy5cbiAgICpcbiAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBzdHJpbmc+fX1cbiAgICovXG4gIHZhciBuc1VyaVRvUHJlZml4O1xuXG4gIC8qKlxuICAgKiBIYW5kbGUgcGFyc2UgZXJyb3IuXG4gICAqXG4gICAqIEBwYXJhbSAge3N0cmluZ3xFcnJvcn0gZXJyXG4gICAqL1xuICBmdW5jdGlvbiBoYW5kbGVFcnJvcihlcnIpIHtcbiAgICBpZiAoIShlcnIgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgIGVyciA9IGVycm9yKGVycik7XG4gICAgfVxuXG4gICAgcmV0dXJuRXJyb3IgPSBlcnI7XG5cbiAgICBvbkVycm9yKGVyciwgZ2V0Q29udGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHBhcnNlIGVycm9yLlxuICAgKlxuICAgKiBAcGFyYW0gIHtzdHJpbmd8RXJyb3J9IGVyclxuICAgKi9cbiAgZnVuY3Rpb24gaGFuZGxlV2FybmluZyhlcnIpIHtcblxuICAgIGlmICghb25XYXJuaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCEoZXJyIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICBlcnIgPSBlcnJvcihlcnIpO1xuICAgIH1cblxuICAgIG9uV2FybmluZyhlcnIsIGdldENvbnRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIHBhcnNlIGxpc3RlbmVyLlxuICAgKlxuICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAgbmFtZVxuICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gY2JcbiAgICpcbiAgICogQHJldHVybiB7UGFyc2VyfVxuICAgKi9cbiAgdGhpc1snb24nXSA9IGZ1bmN0aW9uKG5hbWUsIGNiKSB7XG5cbiAgICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBlcnJvcigncmVxdWlyZWQgYXJncyA8bmFtZSwgY2I+Jyk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgY2FzZSAnb3BlblRhZyc6IG9uT3BlblRhZyA9IGNiOyBicmVhaztcbiAgICBjYXNlICd0ZXh0Jzogb25UZXh0ID0gY2I7IGJyZWFrO1xuICAgIGNhc2UgJ2Nsb3NlVGFnJzogb25DbG9zZVRhZyA9IGNiOyBicmVhaztcbiAgICBjYXNlICdlcnJvcic6IG9uRXJyb3IgPSBjYjsgYnJlYWs7XG4gICAgY2FzZSAnd2Fybic6IG9uV2FybmluZyA9IGNiOyBicmVhaztcbiAgICBjYXNlICdjZGF0YSc6IG9uQ0RBVEEgPSBjYjsgYnJlYWs7XG4gICAgY2FzZSAnYXR0ZW50aW9uJzogb25BdHRlbnRpb24gPSBjYjsgYnJlYWs7IC8vIDwhWFhYWFggenp6ej1cImVlZWVcIj5cbiAgICBjYXNlICdxdWVzdGlvbic6IG9uUXVlc3Rpb24gPSBjYjsgYnJlYWs7IC8vIDw/IC4uLi4gID8+XG4gICAgY2FzZSAnY29tbWVudCc6IG9uQ29tbWVudCA9IGNiOyBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgZXJyb3IoJ3Vuc3VwcG9ydGVkIGV2ZW50OiAnICsgbmFtZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgbmFtZXNwYWNlIHRvIHByZWZpeCBtYXBwaW5nLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBwYXJzZXIubnMoe1xuICAgKiAgICdodHRwOi8vZm9vJzogJ2ZvbycsXG4gICAqICAgJ2h0dHA6Ly9iYXInOiAnYmFyJ1xuICAgKiB9KTtcbiAgICpcbiAgICogQHBhcmFtICB7IU9iamVjdDxzdHJpbmcsIHN0cmluZz59IG5zTWFwXG4gICAqXG4gICAqIEByZXR1cm4ge1BhcnNlcn1cbiAgICovXG4gIHRoaXNbJ25zJ10gPSBmdW5jdGlvbihuc01hcCkge1xuXG4gICAgaWYgKHR5cGVvZiBuc01hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG5zTWFwID0ge307XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBuc01hcCAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IGVycm9yKCdyZXF1aXJlZCBhcmdzIDxuc01hcD17fT4nKTtcbiAgICB9XG5cbiAgICB2YXIgX25zVXJpVG9QcmVmaXggPSB7fSwgaztcblxuICAgIGZvciAoayBpbiBuc01hcCkge1xuICAgICAgX25zVXJpVG9QcmVmaXhba10gPSBuc01hcFtrXTtcbiAgICB9XG5cbiAgICAvLyBGT1JDRSBkZWZhdWx0IG1hcHBpbmcgZm9yIHNjaGVtYSBpbnN0YW5jZVxuICAgIF9uc1VyaVRvUHJlZml4W1hTSV9VUkldID0gWFNJX1BSRUZJWDtcblxuICAgIGlzTmFtZXNwYWNlID0gdHJ1ZTtcbiAgICBuc1VyaVRvUHJlZml4ID0gX25zVXJpVG9QcmVmaXg7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogUGFyc2UgeG1sIHN0cmluZy5cbiAgICpcbiAgICogQHBhcmFtICB7c3RyaW5nfSB4bWxcbiAgICpcbiAgICogQHJldHVybiB7RXJyb3J9IHJldHVybkVycm9yLCBpZiBub3QgdGhyb3duXG4gICAqL1xuICB0aGlzWydwYXJzZSddID0gZnVuY3Rpb24oeG1sKSB7XG4gICAgaWYgKHR5cGVvZiB4bWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBlcnJvcigncmVxdWlyZWQgYXJncyA8eG1sPXN0cmluZz4nKTtcbiAgICB9XG5cbiAgICByZXR1cm5FcnJvciA9IG51bGw7XG5cbiAgICBwYXJzZSh4bWwpO1xuXG4gICAgZ2V0Q29udGV4dCA9IG5vb3BHZXRDb250ZXh0O1xuICAgIHBhcnNlU3RvcCA9IGZhbHNlO1xuXG4gICAgcmV0dXJuIHJldHVybkVycm9yO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTdG9wIHBhcnNpbmcuXG4gICAqL1xuICB0aGlzWydzdG9wJ10gPSBmdW5jdGlvbigpIHtcbiAgICBwYXJzZVN0b3AgPSB0cnVlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBQYXJzZSBzdHJpbmcsIGludm9raW5nIGNvbmZpZ3VyZWQgbGlzdGVuZXJzIG9uIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSAge3N0cmluZ30geG1sXG4gICAqL1xuICBmdW5jdGlvbiBwYXJzZSh4bWwpIHtcbiAgICB2YXIgbnNNYXRyaXhTdGFjayA9IGlzTmFtZXNwYWNlID8gW10gOiBudWxsLFxuICAgICAgICBuc01hdHJpeCA9IGlzTmFtZXNwYWNlID8gYnVpbGROc01hdHJpeChuc1VyaVRvUHJlZml4KSA6IG51bGwsXG4gICAgICAgIF9uc01hdHJpeCxcbiAgICAgICAgbm9kZVN0YWNrID0gW10sXG4gICAgICAgIGFub255bW91c05zQ291bnQgPSAwLFxuICAgICAgICB0YWdTdGFydCA9IGZhbHNlLFxuICAgICAgICB0YWdFbmQgPSBmYWxzZSxcbiAgICAgICAgaSA9IDAsIGogPSAwLFxuICAgICAgICB4LCB5LCBxLCB3LCB2LFxuICAgICAgICB4bWxucyxcbiAgICAgICAgZWxlbWVudE5hbWUsXG4gICAgICAgIF9lbGVtZW50TmFtZSxcbiAgICAgICAgZWxlbWVudFByb3h5XG4gICAgICAgIDtcblxuICAgIHZhciBhdHRyc1N0cmluZyA9ICcnLFxuICAgICAgICBhdHRyc1N0YXJ0ID0gMCxcbiAgICAgICAgY2FjaGVkQXR0cnMgLy8gZmFsc2UgPSBwYXJzZWQgd2l0aCBlcnJvcnMsIG51bGwgPSBuZWVkcyBwYXJzaW5nXG4gICAgICAgIDtcblxuICAgIC8qKlxuICAgICAqIFBhcnNlIGF0dHJpYnV0ZXMgb24gZGVtYW5kIGFuZCByZXR1cm5zIHRoZSBwYXJzZWQgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIFJldHVybiBzZW1hbnRpY3M6ICgxKSBgZmFsc2VgIG9uIGF0dHJpYnV0ZSBwYXJzZSBlcnJvcixcbiAgICAgKiAoMikgb2JqZWN0IGhhc2ggb24gZXh0cmFjdGVkIGF0dHJzLlxuICAgICAqXG4gICAgICogQHJldHVybiB7Ym9vbGVhbnxPYmplY3R9XG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0QXR0cnMoKSB7XG4gICAgICBpZiAoY2FjaGVkQXR0cnMgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGNhY2hlZEF0dHJzO1xuICAgICAgfVxuXG4gICAgICB2YXIgbnNVcmksXG4gICAgICAgICAgbnNVcmlQcmVmaXgsXG4gICAgICAgICAgbnNOYW1lLFxuICAgICAgICAgIGRlZmF1bHRBbGlhcyA9IGlzTmFtZXNwYWNlICYmIG5zTWF0cml4Wyd4bWxucyddLFxuICAgICAgICAgIGF0dHJMaXN0ID0gaXNOYW1lc3BhY2UgJiYgbWF5YmVOUyA/IFtdIDogbnVsbCxcbiAgICAgICAgICBpID0gYXR0cnNTdGFydCxcbiAgICAgICAgICBzID0gYXR0cnNTdHJpbmcsXG4gICAgICAgICAgbCA9IHMubGVuZ3RoLFxuICAgICAgICAgIGhhc05ld01hdHJpeCxcbiAgICAgICAgICBuZXdhbGlhcyxcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBhbGlhcyxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIGF0dHJzID0ge30sXG4gICAgICAgICAgc2VlbkF0dHJzID0ge30sXG4gICAgICAgICAgc2tpcEF0dHIsXG4gICAgICAgICAgdyxcbiAgICAgICAgICBqO1xuXG4gICAgICBwYXJzZUF0dHI6XG4gICAgICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgICAgICBza2lwQXR0ciA9IGZhbHNlO1xuICAgICAgICB3ID0gcy5jaGFyQ29kZUF0KGkpO1xuXG4gICAgICAgIGlmICh3ID09PSAzMiB8fCAodyA8IDE0ICYmIHcgPiA4KSkgeyAvLyBXSElURVNQQUNFPXsgXFxmXFxuXFxyXFx0XFx2fVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gd2FpdCBmb3Igbm9uIHdoaXRlc3BhY2UgY2hhcmFjdGVyXG4gICAgICAgIGlmICh3IDwgNjUgfHwgdyA+IDEyMiB8fCAodyA+IDkwICYmIHcgPCA5NykpIHtcbiAgICAgICAgICBpZiAodyAhPT0gOTUgJiYgdyAhPT0gNTgpIHsgLy8gY2hhciA5NVwiX1wiIDU4XCI6XCJcbiAgICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2lsbGVnYWwgZmlyc3QgY2hhciBhdHRyaWJ1dGUgbmFtZScpO1xuICAgICAgICAgICAgc2tpcEF0dHIgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHBhcnNlIGF0dHJpYnV0ZSBuYW1lXG4gICAgICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbDsgaisrKSB7XG4gICAgICAgICAgdyA9IHMuY2hhckNvZGVBdChqKTtcblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHcgPiA5NiAmJiB3IDwgMTIzIHx8XG4gICAgICAgICAgICB3ID4gNjQgJiYgdyA8IDkxIHx8XG4gICAgICAgICAgICB3ID4gNDcgJiYgdyA8IDU5IHx8XG4gICAgICAgICAgICB3ID09PSA0NiB8fCAvLyAnLidcbiAgICAgICAgICAgIHcgPT09IDQ1IHx8IC8vICctJ1xuICAgICAgICAgICAgdyA9PT0gOTUgLy8gJ18nXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHdoaXRlc3BhY2VcbiAgICAgICAgICBpZiAodyA9PT0gMzIgfHwgKHcgPCAxNCAmJiB3ID4gOCkpIHsgLy8gV0hJVEVTUEFDRVxuICAgICAgICAgICAgaGFuZGxlV2FybmluZygnbWlzc2luZyBhdHRyaWJ1dGUgdmFsdWUnKTtcbiAgICAgICAgICAgIGkgPSBqO1xuXG4gICAgICAgICAgICBjb250aW51ZSBwYXJzZUF0dHI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gZXhwZWN0ZWQgXCI9XCJcbiAgICAgICAgICBpZiAodyA9PT0gNjEpIHsgLy8gXCI9XCIgPT0gNjFcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2lsbGVnYWwgYXR0cmlidXRlIG5hbWUgY2hhcicpO1xuICAgICAgICAgIHNraXBBdHRyID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5hbWUgPSBzLnN1YnN0cmluZyhpLCBqKTtcblxuICAgICAgICBpZiAobmFtZSA9PT0gJ3htbG5zOnhtbG5zJykge1xuICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2lsbGVnYWwgZGVjbGFyYXRpb24gb2YgeG1sbnMnKTtcbiAgICAgICAgICBza2lwQXR0ciA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB3ID0gcy5jaGFyQ29kZUF0KGogKyAxKTtcblxuICAgICAgICBpZiAodyA9PT0gMzQpIHsgLy8gJ1wiJ1xuICAgICAgICAgIGogPSBzLmluZGV4T2YoJ1wiJywgaSA9IGogKyAyKTtcblxuICAgICAgICAgIGlmIChqID09PSAtMSkge1xuICAgICAgICAgICAgaiA9IHMuaW5kZXhPZignXFwnJywgaSk7XG5cbiAgICAgICAgICAgIGlmIChqICE9PSAtMSkge1xuICAgICAgICAgICAgICBoYW5kbGVXYXJuaW5nKCdhdHRyaWJ1dGUgdmFsdWUgcXVvdGUgbWlzc21hdGNoJyk7XG4gICAgICAgICAgICAgIHNraXBBdHRyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgfSBlbHNlIGlmICh3ID09PSAzOSkgeyAvLyBcIidcIlxuICAgICAgICAgIGogPSBzLmluZGV4T2YoJ1xcJycsIGkgPSBqICsgMik7XG5cbiAgICAgICAgICBpZiAoaiA9PT0gLTEpIHtcbiAgICAgICAgICAgIGogPSBzLmluZGV4T2YoJ1wiJywgaSk7XG5cbiAgICAgICAgICAgIGlmIChqICE9PSAtMSkge1xuICAgICAgICAgICAgICBoYW5kbGVXYXJuaW5nKCdhdHRyaWJ1dGUgdmFsdWUgcXVvdGUgbWlzc21hdGNoJyk7XG4gICAgICAgICAgICAgIHNraXBBdHRyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoYW5kbGVXYXJuaW5nKCdtaXNzaW5nIGF0dHJpYnV0ZSB2YWx1ZSBxdW90ZXMnKTtcbiAgICAgICAgICBza2lwQXR0ciA9IHRydWU7XG5cbiAgICAgICAgICAvLyBza2lwIHRvIG5leHQgc3BhY2VcbiAgICAgICAgICBmb3IgKGogPSBqICsgMTsgaiA8IGw7IGorKykge1xuICAgICAgICAgICAgdyA9IHMuY2hhckNvZGVBdChqICsgMSk7XG5cbiAgICAgICAgICAgIGlmICh3ID09PSAzMiB8fCAodyA8IDE0ICYmIHcgPiA4KSkgeyAvLyBXSElURVNQQUNFXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGogPT09IC0xKSB7XG4gICAgICAgICAgaGFuZGxlV2FybmluZygnbWlzc2luZyBjbG9zaW5nIHF1b3RlcycpO1xuXG4gICAgICAgICAgaiA9IGw7XG4gICAgICAgICAgc2tpcEF0dHIgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFza2lwQXR0cikge1xuICAgICAgICAgIHZhbHVlID0gcy5zdWJzdHJpbmcoaSwgaik7XG4gICAgICAgIH1cblxuICAgICAgICBpID0gajtcblxuICAgICAgICAvLyBlbnN1cmUgU1BBQ0UgZm9sbG93cyBhdHRyaWJ1dGVcbiAgICAgICAgLy8gc2tpcCBpbGxlZ2FsIGNvbnRlbnQgb3RoZXJ3aXNlXG4gICAgICAgIC8vIGV4YW1wbGUgYT1cImJcImNcbiAgICAgICAgZm9yICg7IGogKyAxIDwgbDsgaisrKSB7XG4gICAgICAgICAgdyA9IHMuY2hhckNvZGVBdChqICsgMSk7XG5cbiAgICAgICAgICBpZiAodyA9PT0gMzIgfHwgKHcgPCAxNCAmJiB3ID4gOCkpIHsgLy8gV0hJVEVTUEFDRVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gRklSU1QgSUxMRUdBTCBDSEFSXG4gICAgICAgICAgaWYgKGkgPT09IGopIHtcbiAgICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2lsbGVnYWwgY2hhcmFjdGVyIGFmdGVyIGF0dHJpYnV0ZSBlbmQnKTtcbiAgICAgICAgICAgIHNraXBBdHRyID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZHZhbmNlIGN1cnNvciB0byBuZXh0IGF0dHJpYnV0ZVxuICAgICAgICBpID0gaiArIDE7XG5cbiAgICAgICAgaWYgKHNraXBBdHRyKSB7XG4gICAgICAgICAgY29udGludWUgcGFyc2VBdHRyO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2hlY2sgYXR0cmlidXRlIHJlLWRlY2xhcmF0aW9uXG4gICAgICAgIGlmIChuYW1lIGluIHNlZW5BdHRycykge1xuICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2F0dHJpYnV0ZSA8JyArIG5hbWUgKyAnPiBhbHJlYWR5IGRlZmluZWQnKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlZW5BdHRyc1tuYW1lXSA9IHRydWU7XG5cbiAgICAgICAgaWYgKCFpc05hbWVzcGFjZSkge1xuICAgICAgICAgIGF0dHJzW25hbWVdID0gdmFsdWU7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0cnkgdG8gZXh0cmFjdCBuYW1lc3BhY2UgaW5mb3JtYXRpb25cbiAgICAgICAgaWYgKG1heWJlTlMpIHtcbiAgICAgICAgICBuZXdhbGlhcyA9IChcbiAgICAgICAgICAgIG5hbWUgPT09ICd4bWxucydcbiAgICAgICAgICAgICAgPyAneG1sbnMnXG4gICAgICAgICAgICAgIDogKG5hbWUuY2hhckNvZGVBdCgwKSA9PT0gMTIwICYmIG5hbWUuc3Vic3RyKDAsIDYpID09PSAneG1sbnM6JylcbiAgICAgICAgICAgICAgICA/IG5hbWUuc3Vic3RyKDYpXG4gICAgICAgICAgICAgICAgOiBudWxsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIGhhbmRsZSB4bWxucyg6YWxpYXMpIGFzc2lnbm1lbnRcbiAgICAgICAgICBpZiAobmV3YWxpYXMgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5zVXJpID0gZGVjb2RlRW50aXRpZXModmFsdWUpO1xuICAgICAgICAgICAgbnNVcmlQcmVmaXggPSB1cmlQcmVmaXgobmV3YWxpYXMpO1xuXG4gICAgICAgICAgICBhbGlhcyA9IG5zVXJpVG9QcmVmaXhbbnNVcmldO1xuXG4gICAgICAgICAgICBpZiAoIWFsaWFzKSB7XG5cbiAgICAgICAgICAgICAgLy8gbm8gcHJlZml4IGRlZmluZWQgb3IgcHJlZml4IGNvbGxpc2lvblxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgKG5ld2FsaWFzID09PSAneG1sbnMnKSB8fFxuICAgICAgICAgICAgICAgIChuc1VyaVByZWZpeCBpbiBuc01hdHJpeCAmJiBuc01hdHJpeFtuc1VyaVByZWZpeF0gIT09IG5zVXJpKVxuICAgICAgICAgICAgICApIHtcblxuICAgICAgICAgICAgICAgIC8vIGFsb2NhdGUgZnJlZSBucyBwcmVmaXhcbiAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICBhbGlhcyA9ICducycgKyAoYW5vbnltb3VzTnNDb3VudCsrKTtcbiAgICAgICAgICAgICAgICB9IHdoaWxlICh0eXBlb2YgbnNNYXRyaXhbYWxpYXNdICE9PSAndW5kZWZpbmVkJyk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYWxpYXMgPSBuZXdhbGlhcztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIG5zVXJpVG9QcmVmaXhbbnNVcmldID0gYWxpYXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChuc01hdHJpeFtuZXdhbGlhc10gIT09IGFsaWFzKSB7XG4gICAgICAgICAgICAgIGlmICghaGFzTmV3TWF0cml4KSB7XG4gICAgICAgICAgICAgICAgbnNNYXRyaXggPSBjbG9uZU5zTWF0cml4KG5zTWF0cml4KTtcbiAgICAgICAgICAgICAgICBoYXNOZXdNYXRyaXggPSB0cnVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgbnNNYXRyaXhbbmV3YWxpYXNdID0gYWxpYXM7XG4gICAgICAgICAgICAgIGlmIChuZXdhbGlhcyA9PT0gJ3htbG5zJykge1xuICAgICAgICAgICAgICAgIG5zTWF0cml4W3VyaVByZWZpeChhbGlhcyldID0gbnNVcmk7XG4gICAgICAgICAgICAgICAgZGVmYXVsdEFsaWFzID0gYWxpYXM7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBuc01hdHJpeFtuc1VyaVByZWZpeF0gPSBuc1VyaTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZXhwb3NlIHhtbG5zKDphc2QpPVwiLi4uXCIgaW4gYXR0cmlidXRlc1xuICAgICAgICAgICAgYXR0cnNbbmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGNvbGxlY3QgYXR0cmlidXRlcyB1bnRpbCBhbGwgbmFtZXNwYWNlXG4gICAgICAgICAgLy8gZGVjbGFyYXRpb25zIGFyZSBwcm9jZXNzZWRcbiAgICAgICAgICBhdHRyTGlzdC5wdXNoKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICBjb250aW51ZTtcblxuICAgICAgICB9IC8qKiBlbmQgaWYgKG1heWJlTnMpICovXG5cbiAgICAgICAgLy8gaGFuZGxlIGF0dHJpYnV0ZXMgb24gZWxlbWVudCB3aXRob3V0XG4gICAgICAgIC8vIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnNcbiAgICAgICAgdyA9IG5hbWUuaW5kZXhPZignOicpO1xuICAgICAgICBpZiAodyA9PT0gLTEpIHtcbiAgICAgICAgICBhdHRyc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbm9ybWFsaXplIG5zIGF0dHJpYnV0ZSBuYW1lXG4gICAgICAgIGlmICghKG5zTmFtZSA9IG5zTWF0cml4W25hbWUuc3Vic3RyaW5nKDAsIHcpXSkpIHtcbiAgICAgICAgICBoYW5kbGVXYXJuaW5nKG1pc3NpbmdOYW1lc3BhY2VGb3JQcmVmaXgobmFtZS5zdWJzdHJpbmcoMCwgdykpKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5hbWUgPSBkZWZhdWx0QWxpYXMgPT09IG5zTmFtZVxuICAgICAgICAgID8gbmFtZS5zdWJzdHIodyArIDEpXG4gICAgICAgICAgOiBuc05hbWUgKyBuYW1lLnN1YnN0cih3KTtcblxuICAgICAgICAvLyBlbmQ6IG5vcm1hbGl6ZSBucyBhdHRyaWJ1dGUgbmFtZVxuXG4gICAgICAgIC8vIG5vcm1hbGl6ZSB4c2k6dHlwZSBucyBhdHRyaWJ1dGUgdmFsdWVcbiAgICAgICAgaWYgKG5hbWUgPT09IFhTSV9UWVBFKSB7XG4gICAgICAgICAgdyA9IHZhbHVlLmluZGV4T2YoJzonKTtcblxuICAgICAgICAgIGlmICh3ICE9PSAtMSkge1xuICAgICAgICAgICAgbnNOYW1lID0gdmFsdWUuc3Vic3RyaW5nKDAsIHcpO1xuXG4gICAgICAgICAgICAvLyBoYW5kbGUgZGVmYXVsdCBwcmVmaXhlcywgaS5lLiB4czpTdHJpbmcgZ3JhY2VmdWxseVxuICAgICAgICAgICAgbnNOYW1lID0gbnNNYXRyaXhbbnNOYW1lXSB8fCBuc05hbWU7XG4gICAgICAgICAgICB2YWx1ZSA9IG5zTmFtZSArIHZhbHVlLnN1YnN0cmluZyh3KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgPSBkZWZhdWx0QWxpYXMgKyAnOicgKyB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBlbmQ6IG5vcm1hbGl6ZSB4c2k6dHlwZSBucyBhdHRyaWJ1dGUgdmFsdWVcblxuICAgICAgICBhdHRyc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgfVxuXG5cbiAgICAgIC8vIGhhbmRsZSBkZWZlcnJlZCwgcG9zc2libHkgbmFtZXNwYWNlZCBhdHRyaWJ1dGVzXG4gICAgICBpZiAobWF5YmVOUykge1xuXG4gICAgICAgIC8vIG5vcm1hbGl6ZSBjYXB0dXJlZCBhdHRyaWJ1dGVzXG4gICAgICAgIGZvciAoaSA9IDAsIGwgPSBhdHRyTGlzdC5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblxuICAgICAgICAgIG5hbWUgPSBhdHRyTGlzdFtpKytdO1xuICAgICAgICAgIHZhbHVlID0gYXR0ckxpc3RbaV07XG5cbiAgICAgICAgICB3ID0gbmFtZS5pbmRleE9mKCc6Jyk7XG5cbiAgICAgICAgICBpZiAodyAhPT0gLTEpIHtcblxuICAgICAgICAgICAgLy8gbm9ybWFsaXplIG5zIGF0dHJpYnV0ZSBuYW1lXG4gICAgICAgICAgICBpZiAoIShuc05hbWUgPSBuc01hdHJpeFtuYW1lLnN1YnN0cmluZygwLCB3KV0pKSB7XG4gICAgICAgICAgICAgIGhhbmRsZVdhcm5pbmcobWlzc2luZ05hbWVzcGFjZUZvclByZWZpeChuYW1lLnN1YnN0cmluZygwLCB3KSkpO1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmFtZSA9IGRlZmF1bHRBbGlhcyA9PT0gbnNOYW1lXG4gICAgICAgICAgICAgID8gbmFtZS5zdWJzdHIodyArIDEpXG4gICAgICAgICAgICAgIDogbnNOYW1lICsgbmFtZS5zdWJzdHIodyk7XG5cbiAgICAgICAgICAgIC8vIGVuZDogbm9ybWFsaXplIG5zIGF0dHJpYnV0ZSBuYW1lXG5cbiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSB4c2k6dHlwZSBucyBhdHRyaWJ1dGUgdmFsdWVcbiAgICAgICAgICAgIGlmIChuYW1lID09PSBYU0lfVFlQRSkge1xuICAgICAgICAgICAgICB3ID0gdmFsdWUuaW5kZXhPZignOicpO1xuXG4gICAgICAgICAgICAgIGlmICh3ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIG5zTmFtZSA9IHZhbHVlLnN1YnN0cmluZygwLCB3KTtcblxuICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBkZWZhdWx0IHByZWZpeGVzLCBpLmUuIHhzOlN0cmluZyBncmFjZWZ1bGx5XG4gICAgICAgICAgICAgICAgbnNOYW1lID0gbnNNYXRyaXhbbnNOYW1lXSB8fCBuc05hbWU7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBuc05hbWUgKyB2YWx1ZS5zdWJzdHJpbmcodyk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBkZWZhdWx0QWxpYXMgKyAnOicgKyB2YWx1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBlbmQ6IG5vcm1hbGl6ZSB4c2k6dHlwZSBucyBhdHRyaWJ1dGUgdmFsdWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhdHRyc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZW5kOiBub3JtYWxpemUgY2FwdHVyZWQgYXR0cmlidXRlc1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2FjaGVkQXR0cnMgPSBhdHRycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0IHRoZSBwYXJzZSBjb250ZXh0IHsgbGluZSwgY29sdW1uLCBwYXJ0IH1cbiAgICAgKiBmcm9tIHRoZSBjdXJyZW50IHBhcnNlciBwb3NpdGlvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gcGFyc2UgY29udGV4dFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFBhcnNlQ29udGV4dCgpIHtcbiAgICAgIHZhciBzcGxpdHNSZSA9IC8oXFxyXFxufFxccnxcXG4pL2c7XG5cbiAgICAgIHZhciBsaW5lID0gMDtcbiAgICAgIHZhciBjb2x1bW4gPSAwO1xuICAgICAgdmFyIHN0YXJ0T2ZMaW5lID0gMDtcbiAgICAgIHZhciBlbmRPZkxpbmUgPSBqO1xuICAgICAgdmFyIG1hdGNoO1xuICAgICAgdmFyIGRhdGE7XG5cbiAgICAgIHdoaWxlIChpID49IHN0YXJ0T2ZMaW5lKSB7XG5cbiAgICAgICAgbWF0Y2ggPSBzcGxpdHNSZS5leGVjKHhtbCk7XG5cbiAgICAgICAgaWYgKCFtYXRjaCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZW5kIG9mIGxpbmUgPSAoYnJlYWsgaWR4ICsgYnJlYWsgY2hhcnMpXG4gICAgICAgIGVuZE9mTGluZSA9IG1hdGNoWzBdLmxlbmd0aCArIG1hdGNoLmluZGV4O1xuXG4gICAgICAgIGlmIChlbmRPZkxpbmUgPiBpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZHZhbmNlIHRvIG5leHQgbGluZVxuICAgICAgICBsaW5lICs9IDE7XG5cbiAgICAgICAgc3RhcnRPZkxpbmUgPSBlbmRPZkxpbmU7XG4gICAgICB9XG5cbiAgICAgIC8vIEVPRiBlcnJvcnNcbiAgICAgIGlmIChpID09IC0xKSB7XG4gICAgICAgIGNvbHVtbiA9IGVuZE9mTGluZTtcbiAgICAgICAgZGF0YSA9IHhtbC5zdWJzdHJpbmcoaik7XG4gICAgICB9IGVsc2VcblxuICAgICAgLy8gc3RhcnQgZXJyb3JzXG4gICAgICBpZiAoaiA9PT0gMCkge1xuICAgICAgICBkYXRhID0geG1sLnN1YnN0cmluZyhqLCBpKTtcbiAgICAgIH1cblxuICAgICAgLy8gb3RoZXIgZXJyb3JzXG4gICAgICBlbHNlIHtcbiAgICAgICAgY29sdW1uID0gaSAtIHN0YXJ0T2ZMaW5lO1xuICAgICAgICBkYXRhID0gKGogPT0gLTEgPyB4bWwuc3Vic3RyaW5nKGkpIDogeG1sLnN1YnN0cmluZyhpLCBqICsgMSkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAnZGF0YSc6IGRhdGEsXG4gICAgICAgICdsaW5lJzogbGluZSxcbiAgICAgICAgJ2NvbHVtbic6IGNvbHVtblxuICAgICAgfTtcbiAgICB9XG5cbiAgICBnZXRDb250ZXh0ID0gZ2V0UGFyc2VDb250ZXh0O1xuXG5cbiAgICBpZiAocHJveHkpIHtcbiAgICAgIGVsZW1lbnRQcm94eSA9IE9iamVjdC5jcmVhdGUoe30sIHtcbiAgICAgICAgJ25hbWUnOiBnZXR0ZXIoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIGVsZW1lbnROYW1lO1xuICAgICAgICB9KSxcbiAgICAgICAgJ29yaWdpbmFsTmFtZSc6IGdldHRlcihmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gX2VsZW1lbnROYW1lO1xuICAgICAgICB9KSxcbiAgICAgICAgJ2F0dHJzJzogZ2V0dGVyKGdldEF0dHJzKSxcbiAgICAgICAgJ25zJzogZ2V0dGVyKGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBuc01hdHJpeDtcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGFjdHVhbCBwYXJzZSBsb2dpY1xuICAgIHdoaWxlIChqICE9PSAtMSkge1xuXG4gICAgICBpZiAoeG1sLmNoYXJDb2RlQXQoaikgPT09IDYwKSB7IC8vIFwiPFwiXG4gICAgICAgIGkgPSBqO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaSA9IHhtbC5pbmRleE9mKCc8Jywgaik7XG4gICAgICB9XG5cbiAgICAgIC8vIHBhcnNlIGVuZFxuICAgICAgaWYgKGkgPT09IC0xKSB7XG4gICAgICAgIGlmIChub2RlU3RhY2subGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZUVycm9yKCd1bmV4cGVjdGVkIGVuZCBvZiBmaWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaiA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBoYW5kbGVFcnJvcignbWlzc2luZyBzdGFydCB0YWcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChqIDwgeG1sLmxlbmd0aCkge1xuICAgICAgICAgIGlmICh4bWwuc3Vic3RyaW5nKGopLnRyaW0oKSkge1xuICAgICAgICAgICAgaGFuZGxlV2FybmluZyhOT05fV0hJVEVTUEFDRV9PVVRTSURFX1JPT1RfTk9ERSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBwYXJzZSB0ZXh0XG4gICAgICBpZiAoaiAhPT0gaSkge1xuXG4gICAgICAgIGlmIChub2RlU3RhY2subGVuZ3RoKSB7XG4gICAgICAgICAgaWYgKG9uVGV4dCkge1xuICAgICAgICAgICAgb25UZXh0KHhtbC5zdWJzdHJpbmcoaiwgaSksIGRlY29kZUVudGl0aWVzLCBnZXRDb250ZXh0KTtcblxuICAgICAgICAgICAgaWYgKHBhcnNlU3RvcCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh4bWwuc3Vic3RyaW5nKGosIGkpLnRyaW0oKSkge1xuICAgICAgICAgICAgaGFuZGxlV2FybmluZyhOT05fV0hJVEVTUEFDRV9PVVRTSURFX1JPT1RfTk9ERSk7XG5cbiAgICAgICAgICAgIGlmIChwYXJzZVN0b3ApIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB3ID0geG1sLmNoYXJDb2RlQXQoaSsxKTtcblxuICAgICAgLy8gcGFyc2UgY29tbWVudHMgKyBDREFUQVxuICAgICAgaWYgKHcgPT09IDMzKSB7IC8vIFwiIVwiXG4gICAgICAgIHEgPSB4bWwuY2hhckNvZGVBdChpKzIpO1xuXG4gICAgICAgIC8vIENEQVRBIHNlY3Rpb25cbiAgICAgICAgaWYgKHEgPT09IDkxICYmIHhtbC5zdWJzdHIoaSArIDMsIDYpID09PSAnQ0RBVEFbJykgeyAvLyA5MSA9PSBcIltcIlxuICAgICAgICAgIGogPSB4bWwuaW5kZXhPZignXV0+JywgaSk7XG4gICAgICAgICAgaWYgKGogPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ3VuY2xvc2VkIGNkYXRhJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG9uQ0RBVEEpIHtcbiAgICAgICAgICAgIG9uQ0RBVEEoeG1sLnN1YnN0cmluZyhpICsgOSwgaiksIGdldENvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHBhcnNlU3RvcCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaiArPSAzO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY29tbWVudFxuICAgICAgICBpZiAocSA9PT0gNDUgJiYgeG1sLmNoYXJDb2RlQXQoaSArIDMpID09PSA0NSkgeyAvLyA0NSA9PSBcIi1cIlxuICAgICAgICAgIGogPSB4bWwuaW5kZXhPZignLS0+JywgaSk7XG4gICAgICAgICAgaWYgKGogPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ3VuY2xvc2VkIGNvbW1lbnQnKTtcbiAgICAgICAgICB9XG5cblxuICAgICAgICAgIGlmIChvbkNvbW1lbnQpIHtcbiAgICAgICAgICAgIG9uQ29tbWVudCh4bWwuc3Vic3RyaW5nKGkgKyA0LCBqKSwgZGVjb2RlRW50aXRpZXMsIGdldENvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHBhcnNlU3RvcCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaiArPSAzO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHBhcnNlIHF1ZXN0aW9uIDw/IC4uLiA/PlxuICAgICAgaWYgKHcgPT09IDYzKSB7IC8vIFwiP1wiXG4gICAgICAgIGogPSB4bWwuaW5kZXhPZignPz4nLCBpKTtcbiAgICAgICAgaWYgKGogPT09IC0xKSB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZUVycm9yKCd1bmNsb3NlZCBxdWVzdGlvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9uUXVlc3Rpb24pIHtcbiAgICAgICAgICBvblF1ZXN0aW9uKHhtbC5zdWJzdHJpbmcoaSwgaiArIDIpLCBnZXRDb250ZXh0KTtcbiAgICAgICAgICBpZiAocGFyc2VTdG9wKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaiArPSAyO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gZmluZCBtYXRjaGluZyBjbG9zaW5nIHRhZyBmb3IgYXR0ZW50aW9uIG9yIHN0YW5kYXJkIHRhZ3NcbiAgICAgIC8vIGZvciB0aGF0IHdlIG11c3Qgc2tpcCB0aHJvdWdoIGF0dHJpYnV0ZSB2YWx1ZXNcbiAgICAgIC8vIChlbmNsb3NlZCBpbiBzaW5nbGUgb3IgZG91YmxlIHF1b3RlcylcbiAgICAgIGZvciAoeCA9IGkgKyAxOyA7IHgrKykge1xuICAgICAgICB2ID0geG1sLmNoYXJDb2RlQXQoeCk7XG4gICAgICAgIGlmIChpc05hTih2KSkge1xuICAgICAgICAgIGogPSAtMTtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ3VuY2xvc2VkIHRhZycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gWzEwXSBBdHRWYWx1ZSA6Oj0gJ1wiJyAoW148JlwiXSB8IFJlZmVyZW5jZSkqICdcIicgfCBcIidcIiAoW148JiddIHwgUmVmZXJlbmNlKSogXCInXCJcbiAgICAgICAgLy8gc2tpcHMgdGhlIHF1b3RlZCBzdHJpbmdcbiAgICAgICAgLy8gKGRvdWJsZSBxdW90ZXMpIGRvZXMgbm90IGFwcGVhciBpbiBhIGxpdGVyYWwgZW5jbG9zZWQgYnkgKGRvdWJsZSBxdW90ZXMpXG4gICAgICAgIC8vIChzaW5nbGUgcXVvdGUpIGRvZXMgbm90IGFwcGVhciBpbiBhIGxpdGVyYWwgZW5jbG9zZWQgYnkgKHNpbmdsZSBxdW90ZSlcbiAgICAgICAgaWYgKHYgPT09IDM0KSB7IC8vICAnXCInXG4gICAgICAgICAgcSA9IHhtbC5pbmRleE9mKCdcIicsIHggKyAxKTtcbiAgICAgICAgICB4ID0gcSAhPT0gLTEgPyBxIDogeDtcbiAgICAgICAgfSBlbHNlIGlmICh2ID09PSAzOSkgeyAvLyBcIidcIlxuICAgICAgICAgIHEgPSB4bWwuaW5kZXhPZihcIidcIiwgeCArIDEpO1xuICAgICAgICAgIHggPSBxICE9PSAtMSA/IHEgOiB4O1xuICAgICAgICB9IGVsc2UgaWYgKHYgPT09IDYyKSB7IC8vICc+J1xuICAgICAgICAgIGogPSB4O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cblxuICAgICAgLy8gcGFyc2UgYXR0ZW50aW9uIDwhIC4uLj5cbiAgICAgIC8vIHByZXZpb3VzbHkgY29tbWVudCBhbmQgQ0RBVEEgaGF2ZSBhbHJlYWR5IGJlZW4gcGFyc2VkXG4gICAgICBpZiAodyA9PT0gMzMpIHsgLy8gXCIhXCJcblxuICAgICAgICBpZiAob25BdHRlbnRpb24pIHtcbiAgICAgICAgICBvbkF0dGVudGlvbih4bWwuc3Vic3RyaW5nKGksIGogKyAxKSwgZGVjb2RlRW50aXRpZXMsIGdldENvbnRleHQpO1xuICAgICAgICAgIGlmIChwYXJzZVN0b3ApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBqICs9IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBkb24ndCBwcm9jZXNzIGF0dHJpYnV0ZXM7XG4gICAgICAvLyB0aGVyZSBhcmUgbm9uZVxuICAgICAgY2FjaGVkQXR0cnMgPSB7fTtcblxuICAgICAgLy8gaWYgKHhtbC5jaGFyQ29kZUF0KGkrMSkgPT09IDQ3KSB7IC8vIDwvLi4uXG4gICAgICBpZiAodyA9PT0gNDcpIHsgLy8gPC8uLi5cbiAgICAgICAgdGFnU3RhcnQgPSBmYWxzZTtcbiAgICAgICAgdGFnRW5kID0gdHJ1ZTtcblxuICAgICAgICBpZiAoIW5vZGVTdGFjay5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ21pc3Npbmcgb3BlbiB0YWcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZlcmlmeSBvcGVuIDwtPiBjbG9zZSB0YWcgbWF0Y2hcbiAgICAgICAgeCA9IGVsZW1lbnROYW1lID0gbm9kZVN0YWNrLnBvcCgpO1xuICAgICAgICBxID0gaSArIDIgKyB4Lmxlbmd0aDtcblxuICAgICAgICBpZiAoeG1sLnN1YnN0cmluZyhpICsgMiwgcSkgIT09IHgpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ2Nsb3NpbmcgdGFnIG1pc21hdGNoJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB2ZXJpZnkgY2hhcnMgaW4gY2xvc2UgdGFnXG4gICAgICAgIGZvciAoOyBxIDwgajsgcSsrKSB7XG4gICAgICAgICAgdyA9IHhtbC5jaGFyQ29kZUF0KHEpO1xuXG4gICAgICAgICAgaWYgKHcgPT09IDMyIHx8ICh3ID4gOCAmJiB3IDwgMTQpKSB7IC8vIFxcZlxcblxcclxcdFxcdiBzcGFjZVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGhhbmRsZUVycm9yKCdjbG9zZSB0YWcnKTtcbiAgICAgICAgfVxuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoeG1sLmNoYXJDb2RlQXQoaiAtIDEpID09PSA0NykgeyAvLyAuLi4vPlxuICAgICAgICAgIHggPSBlbGVtZW50TmFtZSA9IHhtbC5zdWJzdHJpbmcoaSArIDEsIGogLSAxKTtcblxuICAgICAgICAgIHRhZ1N0YXJ0ID0gdHJ1ZTtcbiAgICAgICAgICB0YWdFbmQgPSB0cnVlO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgeCA9IGVsZW1lbnROYW1lID0geG1sLnN1YnN0cmluZyhpICsgMSwgaik7XG5cbiAgICAgICAgICB0YWdTdGFydCA9IHRydWU7XG4gICAgICAgICAgdGFnRW5kID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISh3ID4gOTYgJiYgdyA8IDEyMyB8fCB3ID4gNjQgJiYgdyA8IDkxIHx8IHcgPT09IDk1IHx8IHcgPT09IDU4KSkgeyAvLyBjaGFyIDk1XCJfXCIgNThcIjpcIlxuICAgICAgICAgIHJldHVybiBoYW5kbGVFcnJvcignaWxsZWdhbCBmaXJzdCBjaGFyIG5vZGVOYW1lJyk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHEgPSAxLCB5ID0geC5sZW5ndGg7IHEgPCB5OyBxKyspIHtcbiAgICAgICAgICB3ID0geC5jaGFyQ29kZUF0KHEpO1xuXG4gICAgICAgICAgaWYgKHcgPiA5NiAmJiB3IDwgMTIzIHx8IHcgPiA2NCAmJiB3IDwgOTEgfHwgdyA+IDQ3ICYmIHcgPCA1OSB8fCB3ID09PSA0NSB8fCB3ID09PSA5NSB8fCB3ID09IDQ2KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodyA9PT0gMzIgfHwgKHcgPCAxNCAmJiB3ID4gOCkpIHsgLy8gXFxmXFxuXFxyXFx0XFx2IHNwYWNlXG4gICAgICAgICAgICBlbGVtZW50TmFtZSA9IHguc3Vic3RyaW5nKDAsIHEpO1xuXG4gICAgICAgICAgICAvLyBtYXliZSB0aGVyZSBhcmUgYXR0cmlidXRlc1xuICAgICAgICAgICAgY2FjaGVkQXR0cnMgPSBudWxsO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGhhbmRsZUVycm9yKCdpbnZhbGlkIG5vZGVOYW1lJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRhZ0VuZCkge1xuICAgICAgICAgIG5vZGVTdGFjay5wdXNoKGVsZW1lbnROYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaXNOYW1lc3BhY2UpIHtcblxuICAgICAgICBfbnNNYXRyaXggPSBuc01hdHJpeDtcblxuICAgICAgICBpZiAodGFnU3RhcnQpIHtcblxuICAgICAgICAgIC8vIHJlbWVtYmVyIG9sZCBuYW1lc3BhY2VcbiAgICAgICAgICAvLyB1bmxlc3Mgd2UncmUgc2VsZi1jbG9zaW5nXG4gICAgICAgICAgaWYgKCF0YWdFbmQpIHtcbiAgICAgICAgICAgIG5zTWF0cml4U3RhY2sucHVzaChfbnNNYXRyaXgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjYWNoZWRBdHRycyA9PT0gbnVsbCkge1xuXG4gICAgICAgICAgICAvLyBxdWljayBjaGVjaywgd2hldGhlciB0aGVyZSBtYXkgYmUgbmFtZXNwYWNlXG4gICAgICAgICAgICAvLyBkZWNsYXJhdGlvbnMgb24gdGhlIG5vZGU7IGlmIHRoYXQgaXMgdGhlIGNhc2VcbiAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gZWFnZXJseSBwYXJzZSB0aGUgbm9kZSBhdHRyaWJ1dGVzXG4gICAgICAgICAgICBpZiAoKG1heWJlTlMgPSB4LmluZGV4T2YoJ3htbG5zJywgcSkgIT09IC0xKSkge1xuICAgICAgICAgICAgICBhdHRyc1N0YXJ0ID0gcTtcbiAgICAgICAgICAgICAgYXR0cnNTdHJpbmcgPSB4O1xuXG4gICAgICAgICAgICAgIGdldEF0dHJzKCk7XG5cbiAgICAgICAgICAgICAgbWF5YmVOUyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIF9lbGVtZW50TmFtZSA9IGVsZW1lbnROYW1lO1xuXG4gICAgICAgIHcgPSBlbGVtZW50TmFtZS5pbmRleE9mKCc6Jyk7XG4gICAgICAgIGlmICh3ICE9PSAtMSkge1xuICAgICAgICAgIHhtbG5zID0gbnNNYXRyaXhbZWxlbWVudE5hbWUuc3Vic3RyaW5nKDAsIHcpXTtcblxuICAgICAgICAgIC8vIHByZWZpeCBnaXZlbjsgbmFtZXNwYWNlIG11c3QgZXhpc3RcbiAgICAgICAgICBpZiAoIXhtbG5zKSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ21pc3NpbmcgbmFtZXNwYWNlIG9uIDwnICsgX2VsZW1lbnROYW1lICsgJz4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlbGVtZW50TmFtZSA9IGVsZW1lbnROYW1lLnN1YnN0cih3ICsgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgeG1sbnMgPSBuc01hdHJpeFsneG1sbnMnXTtcblxuICAgICAgICAgIC8vIGlmIG5vIGRlZmF1bHQgbmFtZXNwYWNlIGlzIGRlZmluZWQsXG4gICAgICAgICAgLy8gd2UnbGwgaW1wb3J0IHRoZSBlbGVtZW50IGFzIGFub255bW91cy5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIGl0IGlzIHVwIHRvIHVzZXJzIHRvIGNvcnJlY3QgdGhhdCB0byB0aGUgZG9jdW1lbnQgZGVmaW5lZFxuICAgICAgICAgIC8vIHRhcmdldE5hbWVzcGFjZSwgb3Igd2hhdGV2ZXIgdGhlaXIgdW5kZXJzYW5kaW5nIG9mIHRoZVxuICAgICAgICAgIC8vIFhNTCBzcGVjIG1hbmRhdGVzLlxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWRqdXN0IG5hbWVzcGFjZSBwcmVmaXhzIGFzIGNvbmZpZ3VyZWRcbiAgICAgICAgaWYgKHhtbG5zKSB7XG4gICAgICAgICAgZWxlbWVudE5hbWUgPSB4bWxucyArICc6JyArIGVsZW1lbnROYW1lO1xuICAgICAgICB9XG5cbiAgICAgIH1cblxuICAgICAgaWYgKHRhZ1N0YXJ0KSB7XG4gICAgICAgIGF0dHJzU3RhcnQgPSBxO1xuICAgICAgICBhdHRyc1N0cmluZyA9IHg7XG5cbiAgICAgICAgaWYgKG9uT3BlblRhZykge1xuICAgICAgICAgIGlmIChwcm94eSkge1xuICAgICAgICAgICAgb25PcGVuVGFnKGVsZW1lbnRQcm94eSwgZGVjb2RlRW50aXRpZXMsIHRhZ0VuZCwgZ2V0Q29udGV4dCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9uT3BlblRhZyhlbGVtZW50TmFtZSwgZ2V0QXR0cnMsIGRlY29kZUVudGl0aWVzLCB0YWdFbmQsIGdldENvbnRleHQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwYXJzZVN0b3ApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgfVxuXG4gICAgICBpZiAodGFnRW5kKSB7XG5cbiAgICAgICAgaWYgKG9uQ2xvc2VUYWcpIHtcbiAgICAgICAgICBvbkNsb3NlVGFnKHByb3h5ID8gZWxlbWVudFByb3h5IDogZWxlbWVudE5hbWUsIGRlY29kZUVudGl0aWVzLCB0YWdTdGFydCwgZ2V0Q29udGV4dCk7XG5cbiAgICAgICAgICBpZiAocGFyc2VTdG9wKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVzdG9yZSBvbGQgbmFtZXNwYWNlXG4gICAgICAgIGlmIChpc05hbWVzcGFjZSkge1xuICAgICAgICAgIGlmICghdGFnU3RhcnQpIHtcbiAgICAgICAgICAgIG5zTWF0cml4ID0gbnNNYXRyaXhTdGFjay5wb3AoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbnNNYXRyaXggPSBfbnNNYXRyaXg7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGogKz0gMTtcbiAgICB9XG4gIH0gLyoqIGVuZCBwYXJzZSAqL1xuXG59XG5cbmV4cG9ydCB7IFBhcnNlciwgZGVjb2RlRW50aXRpZXMgYXMgZGVjb2RlIH07XG4iLCJpbXBvcnQge1xuICBkb21pZnksXG4gIGNsYXNzZXMgYXMgZG9tQ2xhc3NlcyxcbiAgbWF0Y2hlcyBhcyBkb21NYXRjaGVzLFxuICBkZWxlZ2F0ZSBhcyBkb21EZWxlZ2F0ZSxcbiAgcXVlcnkgYXMgZG9tUXVlcnksXG4gIHF1ZXJ5QWxsIGFzIGRvbVF1ZXJ5QWxsLFxuICBldmVudCBhcyBkb21FdmVudCxcbiAgYXR0ciBhcyBkb21BdHRyXG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICBmaWx0ZXIsXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCBjcmVhdGVFbWl0dGVyIGZyb20gJ21pdHQnO1xuXG52YXIgREVGQVVMVF9PUFRJT05TID0ge1xuICBzY3JvbGxTeW1ib2xMZWZ0OiAn4oC5JyxcbiAgc2Nyb2xsU3ltYm9sUmlnaHQ6ICfigLonXG59O1xuXG5cbi8qKlxuICogVGhpcyBjb21wb25lbnQgYWRkcyB0aGUgZnVuY3Rpb25hbGl0eSB0byBzY3JvbGwgb3ZlciBhIGxpc3Qgb2YgdGFicy5cbiAqXG4gKiBJdCBhZGRzIHNjcm9sbCBidXR0b25zIG9uIHRoZSBsZWZ0IGFuZCByaWdodCBzaWRlIG9mIHRoZSB0YWJzIGNvbnRhaW5lclxuICogaWYgbm90IGFsbCB0YWJzIGFyZSB2aXNpYmxlLiBJdCBhbHNvIGFkZHMgYSBtb3VzZSB3aGVlbCBsaXN0ZW5lciBvbiB0aGVcbiAqIGNvbnRhaW5lci5cbiAqXG4gKiBJZiBlaXRoZXIgYSBidXR0b24gaXMgY2xpY2tlZCBvciB0aGUgbW91c2Ugd2hlZWwgaXMgdXNlZCBvdmVyIHRoZSB0YWJzLFxuICogYSAnc2Nyb2xsJyBldmVudCBpcyBiZWluZyBmaXJlZC4gVGhpcyBldmVudCBjb250YWlucyB0aGUgbm9kZSBlbGVtZW50c1xuICogb2YgdGhlIG5ldyBhbmQgb2xkIGFjdGl2ZSB0YWIsIGFuZCB0aGUgZGlyZWN0aW9uIGluIHdoaWNoIHRoZSB0YWIgaGFzXG4gKiBjaGFuZ2VkIHJlbGF0aXZlIHRvIHRoZSBvbGQgYWN0aXZlIHRhYi5cbiAqXG4gKiBAZXhhbXBsZTpcbiAqICgxKSBwcm92aWRlIGEgdGFicy1jb250YWluZXI6XG4gKlxuICogdmFyICRlbCA9IChcbiAqICAgPGRpdj5cbiAqICAgICA8IS0tIGJ1dHRvbiBhZGRlZCBieSBzY3JvbGxUYWJzIC0tPlxuICogICAgIDxzcGFuIGNsYXNzPVwic2Nyb2xsLXRhYnMtYnV0dG9uIHNjcm9sbC10YWJzLWxlZnRcIj48L3NwYW4+XG4gKiAgICAgPHVsIGNsYXNzPVwibXktdGFicy1jb250YWluZXJcIj5cbiAqICAgICAgIDxsaSBjbGFzcz1cIm15LXRhYiBpLWFtLWFjdGl2ZVwiPjwvbGk+XG4gKiAgICAgICA8bGkgY2xhc3M9XCJteS10YWJcIj48L2xpPlxuICogICAgICAgPGxpIGNsYXNzPVwibXktdGFiIGlnbm9yZS1tZVwiPjwvbGk+XG4gKiAgICAgPC91bD5cbiAqICAgICA8IS0tIGJ1dHRvbiBhZGRlZCBieSBzY3JvbGxUYWJzIC0tPlxuICogICAgIDxzcGFuIGNsYXNzPVwic2Nyb2xsLXRhYnMtYnV0dG9uIHNjcm9sbC10YWJzLXJpZ2h0XCI+PC9zcGFuPlxuICogICA8L2Rpdj5cbiAqICk7XG4gKlxuICpcbiAqICgyKSBpbml0aWFsaXplIHNjcm9sbFRhYnM6XG4gKlxuICogIHZhciBzY3JvbGxlciA9IHNjcm9sbFRhYnModGFiQmFyTm9kZSwge1xuICogICAgc2VsZWN0b3JzOiB7XG4gKiAgICAgIHRhYnNDb250YWluZXI6ICcubXktdGFicy1jb250YWluZXInLFxuICogICAgICB0YWI6ICcubXktdGFiJyxcbiAqICAgICAgaWdub3JlOiAnLmlnbm9yZS1tZScsXG4gKiAgICAgIGFjdGl2ZTogJy5pLWFtLWFjdGl2ZSdcbiAqICAgIH1cbiAqICB9KTtcbiAqXG4gKlxuICogKDMpIGxpc3RlbiB0byB0aGUgc2Nyb2xsIGV2ZW50OlxuICpcbiAqIHNjcm9sbGVyLm9uKCdzY3JvbGwnLCBmdW5jdGlvbihuZXdBY3RpdmVOb2RlLCBvbGRBY3RpdmVOb2RlLCBkaXJlY3Rpb24pIHtcbiAqICAgLy8gZGlyZWN0aW9uIGlzIGFueSBvZiAoLTE6IGxlZnQsIDE6IHJpZ2h0KVxuICogICAvLyBhY3RpdmF0ZSB0aGUgbmV3IGFjdGl2ZSB0YWJcbiAqIH0pO1xuICpcbiAqXG4gKiAoNCkgdXBkYXRlIHRoZSBzY3JvbGxlciBpZiB0YWJzIGNoYW5nZSBhbmQgb3IgdGhlIHRhYiBjb250YWluZXIgcmVzaXplczpcbiAqXG4gKiBzY3JvbGxlci51cGRhdGUoKTtcbiAqXG4gKlxuICogQHBhcmFtICB7RE9NRWxlbWVudH0gZWxcbiAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zLnNlbGVjdG9yc1xuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNlbGVjdG9ycy50YWJzQ29udGFpbmVyIHRoZSBjb250YWluZXIgYWxsIHRhYnMgYXJlIGNvbnRhaW5lZCBpblxuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNlbGVjdG9ycy50YWIgYSBzaW5nbGUgdGFiIGluc2lkZSB0aGUgdGFiIGNvbnRhaW5lclxuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNlbGVjdG9ycy5pZ25vcmUgdGFicyB0aGF0IHNob3VsZCBiZSBpZ25vcmVkIGR1cmluZyBzY3JvbGwgbGVmdC9yaWdodFxuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNlbGVjdG9ycy5hY3RpdmUgc2VsZWN0b3IgZm9yIHRoZSBjdXJyZW50IGFjdGl2ZSB0YWJcbiAqIEBwYXJhbSAge1N0cmluZ30gW29wdGlvbnMuc2Nyb2xsU3ltYm9sTGVmdF1cbiAqIEBwYXJhbSAge1N0cmluZ30gW29wdGlvbnMuc2Nyb2xsU3ltYm9sUmlnaHRdXG4gKi9cbmZ1bmN0aW9uIFNjcm9sbFRhYnMoJGVsLCBvcHRpb25zKSB7XG5cbiAgLy8gd2UgYXJlIGFuIGV2ZW50IGVtaXR0ZXJcbiAgYXNzaWduKHRoaXMsIGNyZWF0ZUVtaXR0ZXIoKSk7XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyA9IGFzc2lnbih7fSwgREVGQVVMVF9PUFRJT05TLCBvcHRpb25zKTtcbiAgdGhpcy5jb250YWluZXIgPSAkZWw7XG5cbiAgdGhpcy5fY3JlYXRlU2Nyb2xsQnV0dG9ucygkZWwsIG9wdGlvbnMpO1xuXG4gIHRoaXMuX2JpbmRFdmVudHMoJGVsKTtcbn1cblxuXG4vKipcbiAqIENyZWF0ZSBhIGNsaWNrYWJsZSBzY3JvbGwgYnV0dG9uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfSBvcHRpb25zLmNsYXNzTmFtZVxuICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMubGFiZWxcbiAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmRpcmVjdGlvblxuICpcbiAqIEByZXR1cm4ge0RPTUVsZW1lbnR9IFRoZSBjcmVhdGVkIHNjcm9sbCBidXR0b24gbm9kZVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5fY3JlYXRlQnV0dG9uID0gZnVuY3Rpb24ocGFyZW50Tm9kZSwgb3B0aW9ucykge1xuXG4gIHZhciBjbGFzc05hbWUgPSBvcHRpb25zLmNsYXNzTmFtZSxcbiAgICAgIGRpcmVjdGlvbiA9IG9wdGlvbnMuZGlyZWN0aW9uO1xuXG5cbiAgdmFyIGJ1dHRvbiA9IGRvbVF1ZXJ5KCcuJyArIGNsYXNzTmFtZSwgcGFyZW50Tm9kZSk7XG5cbiAgaWYgKCFidXR0b24pIHtcbiAgICBidXR0b24gPSBkb21pZnkoJzxzcGFuIGNsYXNzPVwic2Nyb2xsLXRhYnMtYnV0dG9uICcgKyBjbGFzc05hbWUgKyAnXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMubGFiZWwgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvc3Bhbj4nKTtcblxuICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGJ1dHRvbiwgcGFyZW50Tm9kZS5jaGlsZE5vZGVzWzBdKTtcbiAgfVxuXG4gIGRvbUF0dHIoYnV0dG9uLCAnZGF0YS1kaXJlY3Rpb24nLCBkaXJlY3Rpb24pO1xuXG4gIHJldHVybiBidXR0b247XG59O1xuXG4vKipcbiAqIENyZWF0ZSBib3RoIHNjcm9sbCBidXR0b25zXG4gKlxuICogQHBhcmFtICB7RE9NRWxlbWVudH0gcGFyZW50Tm9kZVxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG9wdGlvbnMuc2Nyb2xsU3ltYm9sTGVmdFxuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNjcm9sbFN5bWJvbFJpZ2h0XG4gKi9cblNjcm9sbFRhYnMucHJvdG90eXBlLl9jcmVhdGVTY3JvbGxCdXR0b25zID0gZnVuY3Rpb24ocGFyZW50Tm9kZSwgb3B0aW9ucykge1xuXG4gIC8vIENyZWF0ZSBhIGJ1dHRvbiB0aGF0IHNjcm9sbHMgdG8gdGhlIHRhYiBsZWZ0IHRvIHRoZSBjdXJyZW50bHkgYWN0aXZlIHRhYlxuICB0aGlzLl9jcmVhdGVCdXR0b24ocGFyZW50Tm9kZSwge1xuICAgIGNsYXNzTmFtZTogJ3Njcm9sbC10YWJzLWxlZnQnLFxuICAgIGxhYmVsOiBvcHRpb25zLnNjcm9sbFN5bWJvbExlZnQsXG4gICAgZGlyZWN0aW9uOiAtMVxuICB9KTtcblxuICAvLyBDcmVhdGUgYSBidXR0b24gdGhhdCBzY3JvbGxzIHRvIHRoZSB0YWIgcmlnaHQgdG8gdGhlIGN1cnJlbnRseSBhY3RpdmUgdGFiXG4gIHRoaXMuX2NyZWF0ZUJ1dHRvbihwYXJlbnROb2RlLCB7XG4gICAgY2xhc3NOYW1lOiAnc2Nyb2xsLXRhYnMtcmlnaHQnLFxuICAgIGxhYmVsOiBvcHRpb25zLnNjcm9sbFN5bWJvbFJpZ2h0LFxuICAgIGRpcmVjdGlvbjogMVxuICB9KTtcbn07XG5cbi8qKlxuICogR2V0IHRoZSBjdXJyZW50IGFjdGl2ZSB0YWJcbiAqXG4gKiBAcmV0dXJuIHtET01FbGVtZW50fVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5nZXRBY3RpdmVUYWJOb2RlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBkb21RdWVyeSh0aGlzLm9wdGlvbnMuc2VsZWN0b3JzLmFjdGl2ZSwgdGhpcy5jb250YWluZXIpO1xufTtcblxuXG4vKipcbiAqIEdldCB0aGUgY29udGFpbmVyIGFsbCB0YWJzIGFyZSBjb250YWluZWQgaW5cbiAqXG4gKiBAcmV0dXJuIHtET01FbGVtZW50fVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5nZXRUYWJzQ29udGFpbmVyTm9kZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gZG9tUXVlcnkodGhpcy5vcHRpb25zLnNlbGVjdG9ycy50YWJzQ29udGFpbmVyLCB0aGlzLmNvbnRhaW5lcik7XG59O1xuXG5cbi8qKlxuICogR2V0IGFsbCB0YWJzICh2aXNpYmxlIGFuZCBpbnZpc2libGUgb25lcylcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxET01FbGVtZW50Pn1cbiAqL1xuU2Nyb2xsVGFicy5wcm90b3R5cGUuZ2V0QWxsVGFiTm9kZXMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGRvbVF1ZXJ5QWxsKHRoaXMub3B0aW9ucy5zZWxlY3RvcnMudGFiLCB0aGlzLmNvbnRhaW5lcik7XG59O1xuXG5cbi8qKlxuICogR2V0cyBhbGwgdGFicyB0aGF0IGRvbid0IGhhdmUgdGhlIGlnbm9yZSBjbGFzcyBzZXRcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxET01FbGVtZW50Pn1cbiAqL1xuU2Nyb2xsVGFicy5wcm90b3R5cGUuZ2V0VmlzaWJsZVRhYnMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGFsbFRhYnMgPSB0aGlzLmdldEFsbFRhYk5vZGVzKCk7XG5cbiAgdmFyIGlnbm9yZSA9IHRoaXMub3B0aW9ucy5zZWxlY3RvcnMuaWdub3JlO1xuXG4gIHJldHVybiBmaWx0ZXIoYWxsVGFicywgZnVuY3Rpb24odGFiTm9kZSkge1xuICAgIHJldHVybiAhZG9tTWF0Y2hlcyh0YWJOb2RlLCBpZ25vcmUpO1xuICB9KTtcbn07XG5cblxuLyoqXG4gKiBHZXQgYSB0YWIgcmVsYXRpdmUgdG8gYSByZWZlcmVuY2UgdGFiLlxuICpcbiAqIEBwYXJhbSAge0RPTUVsZW1lbnR9IHJlZmVyZW5jZVRhYk5vZGVcbiAqIEBwYXJhbSAge051bWJlcn0gbiBnZXRzIHRoZSBudGggdGFiIG5leHQgb3IgcHJldmlvdXMgdG8gdGhlIHJlZmVyZW5jZSB0YWJcbiAqXG4gKiBAcmV0dXJuIHtET01FbGVtZW50fVxuICpcbiAqIEBleGFtcGxlOlxuICogVmlzaWJsZSB0YWJzOiBbIEEgfCBCIHwgQyB8IEQgfCBFIF1cbiAqIEFzc3VtZSB0YWIgJ0MnIGlzIHRoZSByZWZlcmVuY2UgdGFiOlxuICogSWYgZGlyZWN0aW9uID09PSAtMSwgaXQgcmV0dXJucyB0YWIgJ0InLFxuICogaWYgZGlyZWN0aW9uID09PSAgMiwgaXQgcmV0dXJucyB0YWIgJ0UnXG4gKi9cblNjcm9sbFRhYnMucHJvdG90eXBlLmdldEFkamFjZW50VGFiID0gZnVuY3Rpb24ocmVmZXJlbmNlVGFiTm9kZSwgbikge1xuICB2YXIgdmlzaWJsZVRhYnMgPSB0aGlzLmdldFZpc2libGVUYWJzKCk7XG5cbiAgdmFyIGluZGV4ID0gdmlzaWJsZVRhYnMuaW5kZXhPZihyZWZlcmVuY2VUYWJOb2RlKTtcblxuICByZXR1cm4gdmlzaWJsZVRhYnNbaW5kZXggKyBuXTtcbn07XG5cblNjcm9sbFRhYnMucHJvdG90eXBlLl9iaW5kRXZlbnRzID0gZnVuY3Rpb24obm9kZSkge1xuICB0aGlzLl9iaW5kV2hlZWxFdmVudChub2RlKTtcbiAgdGhpcy5fYmluZFRhYkNsaWNrRXZlbnRzKG5vZGUpO1xuICB0aGlzLl9iaW5kU2Nyb2xsQnV0dG9uRXZlbnRzKG5vZGUpO1xufTtcblxuLyoqXG4gKiAgQmluZCBhIGNsaWNrIGxpc3RlbmVyIHRvIGEgRE9NIG5vZGUuXG4gKiAgTWFrZSBzdXJlIGEgdGFiIGxpbmsgaXMgZW50aXJlbHkgdmlzaWJsZSBhZnRlciBvbkNsaWNrLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5fYmluZFRhYkNsaWNrRXZlbnRzID0gZnVuY3Rpb24obm9kZSkge1xuICB2YXIgc2VsZWN0b3IgPSB0aGlzLm9wdGlvbnMuc2VsZWN0b3JzLnRhYjtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZG9tRGVsZWdhdGUuYmluZChub2RlLCBzZWxlY3RvciwgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljayhldmVudCkge1xuICAgIHNlbGYuc2Nyb2xsVG9UYWJOb2RlKGV2ZW50LmRlbGVnYXRlVGFyZ2V0KTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuICogQmluZCB0aGUgd2hlZWwgZXZlbnQgbGlzdGVuZXIgdG8gYSBET00gbm9kZVxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5fYmluZFdoZWVsRXZlbnQgPSBmdW5jdGlvbihub2RlKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBkb21FdmVudC5iaW5kKG5vZGUsICd3aGVlbCcsIGZ1bmN0aW9uKGUpIHtcblxuICAgIC8vIHNjcm9sbCBkaXJlY3Rpb24gKC0xOiBsZWZ0LCAxOiByaWdodClcbiAgICB2YXIgZGlyZWN0aW9uID0gTWF0aC5zaWduKGUuZGVsdGFZKTtcblxuICAgIHZhciBvbGRBY3RpdmVUYWIgPSBzZWxmLmdldEFjdGl2ZVRhYk5vZGUoKTtcblxuICAgIHZhciBuZXdBY3RpdmVUYWIgPSBzZWxmLmdldEFkamFjZW50VGFiKG9sZEFjdGl2ZVRhYiwgZGlyZWN0aW9uKTtcblxuICAgIGlmIChuZXdBY3RpdmVUYWIpIHtcbiAgICAgIHNlbGYuc2Nyb2xsVG9UYWJOb2RlKG5ld0FjdGl2ZVRhYik7XG4gICAgICBzZWxmLmVtaXQoJ3Njcm9sbCcsIG5ld0FjdGl2ZVRhYiwgb2xkQWN0aXZlVGFiLCBkaXJlY3Rpb24pO1xuICAgIH1cblxuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEJpbmQgc2Nyb2xsIGJ1dHRvbiBldmVudHMgdG8gYSBET00gbm9kZVxuICpcbiAqIEBwYXJhbSAge0RPTUVsZW1lbnR9IG5vZGVcbiAqL1xuU2Nyb2xsVGFicy5wcm90b3R5cGUuX2JpbmRTY3JvbGxCdXR0b25FdmVudHMgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQobm9kZSwgJy5zY3JvbGwtdGFicy1idXR0b24nLCAnY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIHRhcmdldCA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0O1xuXG4gICAgLy8gZGF0YS1kaXJlY3Rpb24gaXMgZWl0aGVyIC0xIG9yIDFcbiAgICB2YXIgZGlyZWN0aW9uID0gcGFyc2VJbnQoZG9tQXR0cih0YXJnZXQsICdkYXRhLWRpcmVjdGlvbicpLCAxMCk7XG5cbiAgICB2YXIgb2xkQWN0aXZlVGFiTm9kZSA9IHNlbGYuZ2V0QWN0aXZlVGFiTm9kZSgpO1xuXG4gICAgdmFyIG5ld0FjdGl2ZVRhYk5vZGUgPSBzZWxmLmdldEFkamFjZW50VGFiKG9sZEFjdGl2ZVRhYk5vZGUsIGRpcmVjdGlvbik7XG5cbiAgICBpZiAobmV3QWN0aXZlVGFiTm9kZSkge1xuICAgICAgc2VsZi5zY3JvbGxUb1RhYk5vZGUobmV3QWN0aXZlVGFiTm9kZSk7XG4gICAgICBzZWxmLmVtaXQoJ3Njcm9sbCcsIG5ld0FjdGl2ZVRhYk5vZGUsIG9sZEFjdGl2ZVRhYk5vZGUsIGRpcmVjdGlvbik7XG4gICAgfVxuXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuKiBTY3JvbGwgdG8gYSB0YWIgaWYgaXQgaXMgbm90IGVudGlyZWx5IHZpc2libGVcbipcbiogQHBhcmFtICB7RE9NRWxlbWVudH0gdGFiTm9kZSB0YWIgbm9kZSB0byBzY3JvbGwgdG9cbiovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5zY3JvbGxUb1RhYk5vZGUgPSBmdW5jdGlvbih0YWJOb2RlKSB7XG4gIGlmICghdGFiTm9kZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciB0YWJzQ29udGFpbmVyTm9kZSA9IHRhYk5vZGUucGFyZW50Tm9kZTtcblxuICB2YXIgdGFiV2lkdGggPSB0YWJOb2RlLm9mZnNldFdpZHRoLFxuICAgICAgdGFiT2Zmc2V0TGVmdCA9IHRhYk5vZGUub2Zmc2V0TGVmdCxcbiAgICAgIHRhYk9mZnNldFJpZ2h0ID0gdGFiT2Zmc2V0TGVmdCArIHRhYldpZHRoLFxuICAgICAgY29udGFpbmVyV2lkdGggPSB0YWJzQ29udGFpbmVyTm9kZS5vZmZzZXRXaWR0aCxcbiAgICAgIGNvbnRhaW5lclNjcm9sbExlZnQgPSB0YWJzQ29udGFpbmVyTm9kZS5zY3JvbGxMZWZ0O1xuXG4gIGlmIChjb250YWluZXJTY3JvbGxMZWZ0ID4gdGFiT2Zmc2V0TGVmdCkge1xuICAgIC8vIHNjcm9sbCB0byB0aGUgbGVmdCwgaWYgdGhlIHRhYiBpcyBvdmVyZmxvd2luZyBvbiB0aGUgbGVmdCBzaWRlXG4gICAgdGFic0NvbnRhaW5lck5vZGUuc2Nyb2xsTGVmdCA9IDA7XG4gIH0gZWxzZSBpZiAodGFiT2Zmc2V0UmlnaHQgPiBjb250YWluZXJXaWR0aCkge1xuICAgIC8vIHNjcm9sbCB0byB0aGUgcmlnaHQsIGlmIHRoZSB0YWIgaXMgb3ZlcmZsb3dpbmcgb24gdGhlIHJpZ2h0IHNpZGVcbiAgICB0YWJzQ29udGFpbmVyTm9kZS5zY3JvbGxMZWZ0ID0gdGFiT2Zmc2V0UmlnaHQgLSBjb250YWluZXJXaWR0aDtcbiAgfVxufTtcblxuXG4vKipcbiAqIFJlYWN0IG9uIHRhYiBjaGFuZ2VzIGZyb20gb3V0c2lkZSAocmVzaXplL3Nob3cvaGlkZS9hZGQvcmVtb3ZlKSxcbiAqIHVwZGF0ZSBzY3JvbGwgYnV0dG9uIHZpc2liaWxpdHkuXG4gKi9cblNjcm9sbFRhYnMucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciB0YWJzQ29udGFpbmVyTm9kZSA9IHRoaXMuZ2V0VGFic0NvbnRhaW5lck5vZGUoKTtcblxuICAvLyBjaGVjayBpZiB0YWJzIGZpdCBpbiBjb250YWluZXJcbiAgdmFyIG92ZXJmbG93ID0gdGFic0NvbnRhaW5lck5vZGUuc2Nyb2xsV2lkdGggPiB0YWJzQ29udGFpbmVyTm9kZS5vZmZzZXRXaWR0aDtcblxuICAvLyBUT0RPKG5pa2t1KTogZGlzdGluZ3Vpc2ggb3ZlcmZsb3cgbGVmdCAvIG92ZXJmbG93IHJpZ2h0P1xuICB2YXIgb3ZlcmZsb3dDbGFzcyA9ICdzY3JvbGwtdGFicy1vdmVyZmxvdyc7XG5cbiAgZG9tQ2xhc3Nlcyh0aGlzLmNvbnRhaW5lcikudG9nZ2xlKG92ZXJmbG93Q2xhc3MsIG92ZXJmbG93KTtcblxuICBpZiAob3ZlcmZsb3cpIHtcbiAgICAvLyBtYWtlIHN1cmUgdGhlIGN1cnJlbnQgYWN0aXZlIHRhYiBpcyBhbHdheXMgdmlzaWJsZVxuICAgIHRoaXMuc2Nyb2xsVG9UYWJOb2RlKHRoaXMuZ2V0QWN0aXZlVGFiTm9kZSgpKTtcbiAgfVxufTtcblxuXG4vLyBleHBvcnRzIC8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBDcmVhdGUgYSBzY3JvbGxUYWJzIGluc3RhbmNlIG9uIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gJGVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICpcbiAqIEByZXR1cm4ge1Njcm9sbFRhYnN9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNyZWF0ZSgkZWwsIG9wdGlvbnMpIHtcblxuICB2YXIgc2Nyb2xsVGFicyA9IGdldCgkZWwpO1xuXG4gIGlmICghc2Nyb2xsVGFicykge1xuICAgIHNjcm9sbFRhYnMgPSBuZXcgU2Nyb2xsVGFicygkZWwsIG9wdGlvbnMpO1xuXG4gICAgJGVsLl9fc2Nyb2xsVGFicyA9IHNjcm9sbFRhYnM7XG4gIH1cblxuICByZXR1cm4gc2Nyb2xsVGFicztcbn1cblxuXG4vKipcbiAqIFJldHVybiB0aGUgc2Nyb2xsVGFicyBpbnN0YW5jZSB0aGF0IGhhcyBiZWVuIHByZXZpb3VzbHlcbiAqIGluaXRpYWxpemVkIG9uIHRoZSBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gJGVsXG4gKiBAcmV0dXJuIHtTY3JvbGxUYWJzfVxuICovXG5mdW5jdGlvbiBnZXQoJGVsKSB7XG4gIHJldHVybiAkZWwuX19zY3JvbGxUYWJzO1xufVxuXG5jcmVhdGUuZ2V0ID0gZ2V0OyIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHNlbGVjdGlvbiB1cGRhdGUgZm9yIHRoZSBnaXZlblxuICogY3VycmVudCBhbmQgbmV3IGlucHV0IHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3VycmVudFNlbGVjdGlvbiBhcyB7c3RhcnQsIGVuZH1cbiAqIEBwYXJhbSB7U3RyaW5nfSBjdXJyZW50VmFsdWVcbiAqIEBwYXJhbSB7U3RyaW5nfSBuZXdWYWx1ZVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gbmV3U2VsZWN0aW9uIGFzIHtzdGFydCwgZW5kfVxuICovXG5mdW5jdGlvbiBjYWxjdWxhdGVVcGRhdGUoY3VycmVudFNlbGVjdGlvbiwgY3VycmVudFZhbHVlLCBuZXdWYWx1ZSkge1xuXG4gIHZhciBjdXJyZW50Q3Vyc29yID0gY3VycmVudFNlbGVjdGlvbi5zdGFydCxcbiAgICAgIG5ld0N1cnNvciA9IGN1cnJlbnRDdXJzb3IsXG4gICAgICBkaWZmID0gbmV3VmFsdWUubGVuZ3RoIC0gY3VycmVudFZhbHVlLmxlbmd0aCxcbiAgICAgIGlkeDtcblxuICB2YXIgbGVuZ3RoRGVsdGEgPSBuZXdWYWx1ZS5sZW5ndGggLSBjdXJyZW50VmFsdWUubGVuZ3RoO1xuXG4gIHZhciBjdXJyZW50VGFpbCA9IGN1cnJlbnRWYWx1ZS5zdWJzdHJpbmcoY3VycmVudEN1cnNvcik7XG5cbiAgLy8gY2hlY2sgaWYgd2UgY2FuIHJlbW92ZSBjb21tb24gZW5kaW5nIGZyb20gdGhlIGVxdWF0aW9uXG4gIC8vIHRvIGJlIGFibGUgdG8gcHJvcGVybHkgZGV0ZWN0IGEgc2VsZWN0aW9uIGNoYW5nZSBmb3JcbiAgLy8gdGhlIGZvbGxvd2luZyBzY2VuYXJpb3M6XG4gIC8vXG4gIC8vICAqIChBQUFUVFR8VEYpID0+IChBQUFUfFRGKVxuICAvLyAgKiAoQUFBVHxURikgPT4gIChBQUFUVFR8VEYpXG4gIC8vXG4gIGlmIChuZXdWYWx1ZS5sYXN0SW5kZXhPZihjdXJyZW50VGFpbCkgPT09IG5ld1ZhbHVlLmxlbmd0aCAtIGN1cnJlbnRUYWlsLmxlbmd0aCkge1xuICAgIGN1cnJlbnRWYWx1ZSA9IGN1cnJlbnRWYWx1ZS5zdWJzdHJpbmcoMCwgY3VycmVudFZhbHVlLmxlbmd0aCAtIGN1cnJlbnRUYWlsLmxlbmd0aCk7XG4gICAgbmV3VmFsdWUgPSBuZXdWYWx1ZS5zdWJzdHJpbmcoMCwgbmV3VmFsdWUubGVuZ3RoIC0gY3VycmVudFRhaWwubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIGRpZmZcbiAgdmFyIGRpZmYgPSBjcmVhdGVEaWZmKGN1cnJlbnRWYWx1ZSwgbmV3VmFsdWUpO1xuXG4gIGlmIChkaWZmKSB7XG4gICAgaWYgKGRpZmYudHlwZSA9PT0gJ3JlbW92ZScpIHtcbiAgICAgIG5ld0N1cnNvciA9IGRpZmYubmV3U3RhcnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0N1cnNvciA9IGRpZmYubmV3RW5kO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByYW5nZShuZXdDdXJzb3IpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNhbGN1bGF0ZVVwZGF0ZTtcblxuXG5mdW5jdGlvbiBjcmVhdGVEaWZmKGN1cnJlbnRWYWx1ZSwgbmV3VmFsdWUpIHtcblxuICB2YXIgaW5zZXJ0O1xuXG4gIHZhciBsX3N0ciwgbF9jaGFyLCBsX2lkeCA9IDAsXG4gICAgICBzX3N0ciwgc19jaGFyLCBzX2lkeCA9IDA7XG5cbiAgaWYgKG5ld1ZhbHVlLmxlbmd0aCA+IGN1cnJlbnRWYWx1ZS5sZW5ndGgpIHtcbiAgICBsX3N0ciA9IG5ld1ZhbHVlO1xuICAgIHNfc3RyID0gY3VycmVudFZhbHVlO1xuICB9IGVsc2Uge1xuICAgIGxfc3RyID0gY3VycmVudFZhbHVlO1xuICAgIHNfc3RyID0gbmV3VmFsdWU7XG4gIH1cblxuICAvLyBhc3N1bWUgdGhlcmUgd2lsbCBiZSBvbmx5IG9uZSBpbnNlcnQgLyByZW1vdmUgYW5kXG4gIC8vIGRldGVjdCB0aGF0IF9maXJzdF8gZWRpdCBvcGVyYXRpb24gb25seVxuICB3aGlsZSAobF9pZHggPCBsX3N0ci5sZW5ndGgpIHtcblxuICAgIGxfY2hhciA9IGxfc3RyLmNoYXJBdChsX2lkeCk7XG4gICAgc19jaGFyID0gc19zdHIuY2hhckF0KHNfaWR4KTtcblxuICAgIC8vIGNoYXJzIG5vIG5vdCBlcXVhbFxuICAgIGlmIChsX2NoYXIgIT09IHNfY2hhcikge1xuXG4gICAgICBpZiAoIWluc2VydCkge1xuICAgICAgICBpbnNlcnQgPSB7XG4gICAgICAgICAgbF9zdGFydDogbF9pZHgsXG4gICAgICAgICAgc19zdGFydDogc19pZHhcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgbF9pZHgrKztcbiAgICB9XG5cbiAgICAvLyBjaGFycyBlcXVhbCAoYWdhaW4/KVxuICAgIGVsc2Uge1xuXG4gICAgICBpZiAoaW5zZXJ0ICYmICFpbnNlcnQuY29tcGxldGUpIHtcbiAgICAgICAgaW5zZXJ0LmxfZW5kID0gbF9pZHg7XG4gICAgICAgIGluc2VydC5zX2VuZCA9IHNfaWR4O1xuICAgICAgICBpbnNlcnQuY29tcGxldGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBzX2lkeCsrO1xuICAgICAgbF9pZHgrKztcbiAgICB9XG4gIH1cblxuICBpZiAoaW5zZXJ0ICYmICFpbnNlcnQuY29tcGxldGUpIHtcbiAgICBpbnNlcnQuY29tcGxldGUgPSB0cnVlO1xuICAgIGluc2VydC5zX2VuZCA9IHNfc3RyLmxlbmd0aDtcbiAgICBpbnNlcnQubF9lbmQgPSBsX3N0ci5sZW5ndGg7XG4gIH1cblxuICAvLyBubyBkaWZmXG4gIGlmICghaW5zZXJ0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKG5ld1ZhbHVlLmxlbmd0aCA+IGN1cnJlbnRWYWx1ZS5sZW5ndGgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmV3U3RhcnQ6IGluc2VydC5sX3N0YXJ0LFxuICAgICAgbmV3RW5kOiBpbnNlcnQubF9lbmQsXG4gICAgICB0eXBlOiAnYWRkJ1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5ld1N0YXJ0OiBpbnNlcnQuc19zdGFydCxcbiAgICAgIG5ld0VuZDogaW5zZXJ0LnNfZW5kLFxuICAgICAgdHlwZTogbmV3VmFsdWUubGVuZ3RoIDwgY3VycmVudFZhbHVlLmxlbmd0aCA/ICdyZW1vdmUnIDogJ3JlcGxhY2UnXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIFV0aWxpdHkgbWV0aG9kIGZvciBjcmVhdGluZyBhIG5ldyBzZWxlY3Rpb24gcmFuZ2Uge3N0YXJ0LCBlbmR9IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gc3RhcnRcbiAqIEBwYXJhbSB7TnVtYmVyfSBbZW5kXVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gc2VsZWN0aW9uIHJhbmdlIGFzIHtzdGFydCwgZW5kfVxuICovXG5mdW5jdGlvbiByYW5nZShzdGFydCwgZW5kKSB7XG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IHN0YXJ0LFxuICAgIGVuZDogZW5kID09PSB1bmRlZmluZWQgPyBzdGFydCA6IGVuZFxuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cy5yYW5nZSA9IHJhbmdlO1xuXG5cbmZ1bmN0aW9uIHNwbGl0U3RyKHN0ciwgcG9zaXRpb24pIHtcbiAgcmV0dXJuIHtcbiAgICBiZWZvcmU6IHN0ci5zdWJzdHJpbmcoMCwgcG9zaXRpb24pLFxuICAgIGFmdGVyOiBzdHIuc3Vic3RyaW5nKHBvc2l0aW9uKVxuICB9O1xufSIsImZ1bmN0aW9uIGVuc3VyZUltcG9ydGVkKGVsZW1lbnQsIHRhcmdldCkge1xuXG4gIGlmIChlbGVtZW50Lm93bmVyRG9jdW1lbnQgIT09IHRhcmdldC5vd25lckRvY3VtZW50KSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIG1heSBmYWlsIG9uIHdlYmtpdFxuICAgICAgcmV0dXJuIHRhcmdldC5vd25lckRvY3VtZW50LmltcG9ydE5vZGUoZWxlbWVudCwgdHJ1ZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gaWdub3JlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG5cbi8qKlxuICogYXBwZW5kVG8gdXRpbGl0eVxuICovXG5cbi8qKlxuICogQXBwZW5kIGEgbm9kZSB0byBhIHRhcmdldCBlbGVtZW50IGFuZCByZXR1cm4gdGhlIGFwcGVuZGVkIG5vZGUuXG4gKlxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gdGFyZ2V0XG4gKlxuICogQHJldHVybiB7U1ZHRWxlbWVudH0gdGhlIGFwcGVuZGVkIG5vZGVcbiAqL1xuZnVuY3Rpb24gYXBwZW5kVG8oZWxlbWVudCwgdGFyZ2V0KSB7XG4gIHJldHVybiB0YXJnZXQuYXBwZW5kQ2hpbGQoZW5zdXJlSW1wb3J0ZWQoZWxlbWVudCwgdGFyZ2V0KSk7XG59XG5cbi8qKlxuICogYXBwZW5kIHV0aWxpdHlcbiAqL1xuXG4vKipcbiAqIEFwcGVuZCBhIG5vZGUgdG8gYW4gZWxlbWVudFxuICpcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IG5vZGVcbiAqXG4gKiBAcmV0dXJuIHtTVkdFbGVtZW50fSB0aGUgZWxlbWVudFxuICovXG5mdW5jdGlvbiBhcHBlbmQodGFyZ2V0LCBub2RlKSB7XG4gIGFwcGVuZFRvKG5vZGUsIHRhcmdldCk7XG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbi8qKlxuICogYXR0cmlidXRlIGFjY2Vzc29yIHV0aWxpdHlcbiAqL1xuXG52YXIgTEVOR1RIX0FUVFIgPSAyO1xuXG52YXIgQ1NTX1BST1BFUlRJRVMgPSB7XG4gICdhbGlnbm1lbnQtYmFzZWxpbmUnOiAxLFxuICAnYmFzZWxpbmUtc2hpZnQnOiAxLFxuICAnY2xpcCc6IDEsXG4gICdjbGlwLXBhdGgnOiAxLFxuICAnY2xpcC1ydWxlJzogMSxcbiAgJ2NvbG9yJzogMSxcbiAgJ2NvbG9yLWludGVycG9sYXRpb24nOiAxLFxuICAnY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzJzogMSxcbiAgJ2NvbG9yLXByb2ZpbGUnOiAxLFxuICAnY29sb3ItcmVuZGVyaW5nJzogMSxcbiAgJ2N1cnNvcic6IDEsXG4gICdkaXJlY3Rpb24nOiAxLFxuICAnZGlzcGxheSc6IDEsXG4gICdkb21pbmFudC1iYXNlbGluZSc6IDEsXG4gICdlbmFibGUtYmFja2dyb3VuZCc6IDEsXG4gICdmaWxsJzogMSxcbiAgJ2ZpbGwtb3BhY2l0eSc6IDEsXG4gICdmaWxsLXJ1bGUnOiAxLFxuICAnZmlsdGVyJzogMSxcbiAgJ2Zsb29kLWNvbG9yJzogMSxcbiAgJ2Zsb29kLW9wYWNpdHknOiAxLFxuICAnZm9udCc6IDEsXG4gICdmb250LWZhbWlseSc6IDEsXG4gICdmb250LXNpemUnOiBMRU5HVEhfQVRUUixcbiAgJ2ZvbnQtc2l6ZS1hZGp1c3QnOiAxLFxuICAnZm9udC1zdHJldGNoJzogMSxcbiAgJ2ZvbnQtc3R5bGUnOiAxLFxuICAnZm9udC12YXJpYW50JzogMSxcbiAgJ2ZvbnQtd2VpZ2h0JzogMSxcbiAgJ2dseXBoLW9yaWVudGF0aW9uLWhvcml6b250YWwnOiAxLFxuICAnZ2x5cGgtb3JpZW50YXRpb24tdmVydGljYWwnOiAxLFxuICAnaW1hZ2UtcmVuZGVyaW5nJzogMSxcbiAgJ2tlcm5pbmcnOiAxLFxuICAnbGV0dGVyLXNwYWNpbmcnOiAxLFxuICAnbGlnaHRpbmctY29sb3InOiAxLFxuICAnbWFya2VyJzogMSxcbiAgJ21hcmtlci1lbmQnOiAxLFxuICAnbWFya2VyLW1pZCc6IDEsXG4gICdtYXJrZXItc3RhcnQnOiAxLFxuICAnbWFzayc6IDEsXG4gICdvcGFjaXR5JzogMSxcbiAgJ292ZXJmbG93JzogMSxcbiAgJ3BvaW50ZXItZXZlbnRzJzogMSxcbiAgJ3NoYXBlLXJlbmRlcmluZyc6IDEsXG4gICdzdG9wLWNvbG9yJzogMSxcbiAgJ3N0b3Atb3BhY2l0eSc6IDEsXG4gICdzdHJva2UnOiAxLFxuICAnc3Ryb2tlLWRhc2hhcnJheSc6IDEsXG4gICdzdHJva2UtZGFzaG9mZnNldCc6IDEsXG4gICdzdHJva2UtbGluZWNhcCc6IDEsXG4gICdzdHJva2UtbGluZWpvaW4nOiAxLFxuICAnc3Ryb2tlLW1pdGVybGltaXQnOiAxLFxuICAnc3Ryb2tlLW9wYWNpdHknOiAxLFxuICAnc3Ryb2tlLXdpZHRoJzogTEVOR1RIX0FUVFIsXG4gICd0ZXh0LWFuY2hvcic6IDEsXG4gICd0ZXh0LWRlY29yYXRpb24nOiAxLFxuICAndGV4dC1yZW5kZXJpbmcnOiAxLFxuICAndW5pY29kZS1iaWRpJzogMSxcbiAgJ3Zpc2liaWxpdHknOiAxLFxuICAnd29yZC1zcGFjaW5nJzogMSxcbiAgJ3dyaXRpbmctbW9kZSc6IDFcbn07XG5cblxuZnVuY3Rpb24gZ2V0QXR0cmlidXRlKG5vZGUsIG5hbWUpIHtcbiAgaWYgKENTU19QUk9QRVJUSUVTW25hbWVdKSB7XG4gICAgcmV0dXJuIG5vZGUuc3R5bGVbbmFtZV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5vZGUuZ2V0QXR0cmlidXRlTlMobnVsbCwgbmFtZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0QXR0cmlidXRlKG5vZGUsIG5hbWUsIHZhbHVlKSB7XG4gIHZhciBoeXBoZW5hdGVkID0gbmFtZS5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCAnJDEtJDInKS50b0xvd2VyQ2FzZSgpO1xuXG4gIHZhciB0eXBlID0gQ1NTX1BST1BFUlRJRVNbaHlwaGVuYXRlZF07XG5cbiAgaWYgKHR5cGUpIHtcbiAgICAvLyBhcHBlbmQgcGl4ZWwgdW5pdCwgdW5sZXNzIHByZXNlbnRcbiAgICBpZiAodHlwZSA9PT0gTEVOR1RIX0FUVFIgJiYgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgdmFsdWUgPSBTdHJpbmcodmFsdWUpICsgJ3B4JztcbiAgICB9XG5cbiAgICBub2RlLnN0eWxlW2h5cGhlbmF0ZWRdID0gdmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgbm9kZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCBuYW1lLCB2YWx1ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0QXR0cmlidXRlcyhub2RlLCBhdHRycykge1xuXG4gIHZhciBuYW1lcyA9IE9iamVjdC5rZXlzKGF0dHJzKSwgaSwgbmFtZTtcblxuICBmb3IgKGkgPSAwLCBuYW1lOyAobmFtZSA9IG5hbWVzW2ldKTsgaSsrKSB7XG4gICAgc2V0QXR0cmlidXRlKG5vZGUsIG5hbWUsIGF0dHJzW25hbWVdKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldHMgb3Igc2V0cyByYXcgYXR0cmlidXRlcyBvbiBhIG5vZGUuXG4gKlxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gbm9kZVxuICogQHBhcmFtICB7T2JqZWN0fSBbYXR0cnNdXG4gKiBAcGFyYW0gIHtTdHJpbmd9IFtuYW1lXVxuICogQHBhcmFtICB7U3RyaW5nfSBbdmFsdWVdXG4gKlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBhdHRyKG5vZGUsIG5hbWUsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgc2V0QXR0cmlidXRlKG5vZGUsIG5hbWUsIHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGdldEF0dHJpYnV0ZShub2RlLCBuYW1lKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc2V0QXR0cmlidXRlcyhub2RlLCBuYW1lKTtcbiAgfVxuXG4gIHJldHVybiBub2RlO1xufVxuXG4vKipcclxuICogQ2xlYXIgdXRpbGl0eVxyXG4gKi9cclxuZnVuY3Rpb24gaW5kZXgoYXJyLCBvYmopIHtcclxuICBpZiAoYXJyLmluZGV4T2YpIHtcclxuICAgIHJldHVybiBhcnIuaW5kZXhPZihvYmopO1xyXG4gIH1cclxuXHJcblxyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XHJcbiAgICBpZiAoYXJyW2ldID09PSBvYmopIHtcclxuICAgICAgcmV0dXJuIGk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gLTE7XHJcbn1cclxuXHJcbnZhciByZSA9IC9cXHMrLztcclxuXHJcbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XHJcblxyXG5mdW5jdGlvbiBkZWZpbmVkKG8pIHtcclxuICByZXR1cm4gdHlwZW9mIG8gIT09ICd1bmRlZmluZWQnO1xyXG59XHJcblxyXG4vKipcclxuICogV3JhcCBgZWxgIGluIGEgYENsYXNzTGlzdGAuXHJcbiAqXHJcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcclxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbmZ1bmN0aW9uIGNsYXNzZXMoZWwpIHtcclxuICByZXR1cm4gbmV3IENsYXNzTGlzdChlbCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIENsYXNzTGlzdChlbCkge1xyXG4gIGlmICghZWwgfHwgIWVsLm5vZGVUeXBlKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgRE9NIGVsZW1lbnQgcmVmZXJlbmNlIGlzIHJlcXVpcmVkJyk7XHJcbiAgfVxyXG4gIHRoaXMuZWwgPSBlbDtcclxuICB0aGlzLmxpc3QgPSBlbC5jbGFzc0xpc3Q7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBZGQgY2xhc3MgYG5hbWVgIGlmIG5vdCBhbHJlYWR5IHByZXNlbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXHJcbiAqIEByZXR1cm4ge0NsYXNzTGlzdH1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKG5hbWUpIHtcclxuXHJcbiAgLy8gY2xhc3NMaXN0XHJcbiAgaWYgKHRoaXMubGlzdCkge1xyXG4gICAgdGhpcy5saXN0LmFkZChuYW1lKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gZmFsbGJhY2tcclxuICB2YXIgYXJyID0gdGhpcy5hcnJheSgpO1xyXG4gIHZhciBpID0gaW5kZXgoYXJyLCBuYW1lKTtcclxuICBpZiAoIX5pKSB7XHJcbiAgICBhcnIucHVzaChuYW1lKTtcclxuICB9XHJcblxyXG4gIGlmIChkZWZpbmVkKHRoaXMuZWwuY2xhc3NOYW1lLmJhc2VWYWwpKSB7XHJcbiAgICB0aGlzLmVsLmNsYXNzTmFtZS5iYXNlVmFsID0gYXJyLmpvaW4oJyAnKTtcclxuICB9IGVsc2Uge1xyXG4gICAgdGhpcy5lbC5jbGFzc05hbWUgPSBhcnIuam9pbignICcpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogUmVtb3ZlIGNsYXNzIGBuYW1lYCB3aGVuIHByZXNlbnQsIG9yXHJcbiAqIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gcmVtb3ZlXHJcbiAqIGFueSB3aGljaCBtYXRjaC5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBuYW1lXHJcbiAqIEByZXR1cm4ge0NsYXNzTGlzdH1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKG5hbWUpIHtcclxuICBpZiAoJ1tvYmplY3QgUmVnRXhwXScgPT09IHRvU3RyaW5nLmNhbGwobmFtZSkpIHtcclxuICAgIHJldHVybiB0aGlzLnJlbW92ZU1hdGNoaW5nKG5hbWUpO1xyXG4gIH1cclxuXHJcbiAgLy8gY2xhc3NMaXN0XHJcbiAgaWYgKHRoaXMubGlzdCkge1xyXG4gICAgdGhpcy5saXN0LnJlbW92ZShuYW1lKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gZmFsbGJhY2tcclxuICB2YXIgYXJyID0gdGhpcy5hcnJheSgpO1xyXG4gIHZhciBpID0gaW5kZXgoYXJyLCBuYW1lKTtcclxuICBpZiAofmkpIHtcclxuICAgIGFyci5zcGxpY2UoaSwgMSk7XHJcbiAgfVxyXG4gIHRoaXMuZWwuY2xhc3NOYW1lLmJhc2VWYWwgPSBhcnIuam9pbignICcpO1xyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJlbW92ZSBhbGwgY2xhc3NlcyBtYXRjaGluZyBgcmVgLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlZ0V4cH0gcmVcclxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxyXG4gKiBAYXBpIHByaXZhdGVcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLnJlbW92ZU1hdGNoaW5nID0gZnVuY3Rpb24ocmUpIHtcclxuICB2YXIgYXJyID0gdGhpcy5hcnJheSgpO1xyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XHJcbiAgICBpZiAocmUudGVzdChhcnJbaV0pKSB7XHJcbiAgICAgIHRoaXMucmVtb3ZlKGFycltpXSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRvZ2dsZSBjbGFzcyBgbmFtZWAsIGNhbiBmb3JjZSBzdGF0ZSB2aWEgYGZvcmNlYC5cclxuICpcclxuICogRm9yIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBjbGFzc0xpc3QsIGJ1dCBkbyBub3Qgc3VwcG9ydCBgZm9yY2VgIHlldCxcclxuICogdGhlIG1pc3Rha2Ugd2lsbCBiZSBkZXRlY3RlZCBhbmQgY29ycmVjdGVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlXHJcbiAqIEByZXR1cm4ge0NsYXNzTGlzdH1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uKG5hbWUsIGZvcmNlKSB7XHJcbiAgLy8gY2xhc3NMaXN0XHJcbiAgaWYgKHRoaXMubGlzdCkge1xyXG4gICAgaWYgKGRlZmluZWQoZm9yY2UpKSB7XHJcbiAgICAgIGlmIChmb3JjZSAhPT0gdGhpcy5saXN0LnRvZ2dsZShuYW1lLCBmb3JjZSkpIHtcclxuICAgICAgICB0aGlzLmxpc3QudG9nZ2xlKG5hbWUpOyAvLyB0b2dnbGUgYWdhaW4gdG8gY29ycmVjdFxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmxpc3QudG9nZ2xlKG5hbWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvLyBmYWxsYmFja1xyXG4gIGlmIChkZWZpbmVkKGZvcmNlKSkge1xyXG4gICAgaWYgKCFmb3JjZSkge1xyXG4gICAgICB0aGlzLnJlbW92ZShuYW1lKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuYWRkKG5hbWUpO1xyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICBpZiAodGhpcy5oYXMobmFtZSkpIHtcclxuICAgICAgdGhpcy5yZW1vdmUobmFtZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmFkZChuYW1lKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybiBhbiBhcnJheSBvZiBjbGFzc2VzLlxyXG4gKlxyXG4gKiBAcmV0dXJuIHtBcnJheX1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLmFycmF5ID0gZnVuY3Rpb24oKSB7XHJcbiAgdmFyIGNsYXNzTmFtZSA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpIHx8ICcnO1xyXG4gIHZhciBzdHIgPSBjbGFzc05hbWUucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xyXG4gIHZhciBhcnIgPSBzdHIuc3BsaXQocmUpO1xyXG4gIGlmICgnJyA9PT0gYXJyWzBdKSB7XHJcbiAgICBhcnIuc2hpZnQoKTtcclxuICB9XHJcbiAgcmV0dXJuIGFycjtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiBjbGFzcyBgbmFtZWAgaXMgcHJlc2VudC5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcclxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkNsYXNzTGlzdC5wcm90b3R5cGUuaGFzID1cclxuQ2xhc3NMaXN0LnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uKG5hbWUpIHtcclxuICByZXR1cm4gKFxyXG4gICAgdGhpcy5saXN0ID9cclxuICAgICAgdGhpcy5saXN0LmNvbnRhaW5zKG5hbWUpIDpcclxuICAgICAgISEgfmluZGV4KHRoaXMuYXJyYXkoKSwgbmFtZSlcclxuICApO1xyXG59O1xuXG5mdW5jdGlvbiByZW1vdmUoZWxlbWVudCkge1xuICB2YXIgcGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudDtcbn1cblxuLyoqXG4gKiBDbGVhciB1dGlsaXR5XG4gKi9cblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBjaGlsZHJlbiBmcm9tIHRoZSBnaXZlbiBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7RE9NRWxlbWVudH0gZWxlbWVudFxuICogQHJldHVybiB7RE9NRWxlbWVudH0gdGhlIGVsZW1lbnQgKGZvciBjaGFpbmluZylcbiAqL1xuZnVuY3Rpb24gY2xlYXIoZWxlbWVudCkge1xuICB2YXIgY2hpbGQ7XG5cbiAgd2hpbGUgKChjaGlsZCA9IGVsZW1lbnQuZmlyc3RDaGlsZCkpIHtcbiAgICByZW1vdmUoY2hpbGQpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGNsb25lKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQuY2xvbmVOb2RlKHRydWUpO1xufVxuXG52YXIgbnMgPSB7XG4gIHN2ZzogJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJ1xufTtcblxuLyoqXG4gKiBET00gcGFyc2luZyB1dGlsaXR5XG4gKi9cblxudmFyIFNWR19TVEFSVCA9ICc8c3ZnIHhtbG5zPVwiJyArIG5zLnN2ZyArICdcIic7XG5cbmZ1bmN0aW9uIHBhcnNlKHN2Zykge1xuXG4gIHZhciB1bndyYXAgPSBmYWxzZTtcblxuICAvLyBlbnN1cmUgd2UgaW1wb3J0IGEgdmFsaWQgc3ZnIGRvY3VtZW50XG4gIGlmIChzdmcuc3Vic3RyaW5nKDAsIDQpID09PSAnPHN2ZycpIHtcbiAgICBpZiAoc3ZnLmluZGV4T2YobnMuc3ZnKSA9PT0gLTEpIHtcbiAgICAgIHN2ZyA9IFNWR19TVEFSVCArIHN2Zy5zdWJzdHJpbmcoNCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIG5hbWVzcGFjZSBzdmdcbiAgICBzdmcgPSBTVkdfU1RBUlQgKyAnPicgKyBzdmcgKyAnPC9zdmc+JztcbiAgICB1bndyYXAgPSB0cnVlO1xuICB9XG5cbiAgdmFyIHBhcnNlZCA9IHBhcnNlRG9jdW1lbnQoc3ZnKTtcblxuICBpZiAoIXVud3JhcCkge1xuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICB2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG5cbiAgdmFyIHBhcmVudCA9IHBhcnNlZC5maXJzdENoaWxkO1xuXG4gIHdoaWxlIChwYXJlbnQuZmlyc3RDaGlsZCkge1xuICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKHBhcmVudC5maXJzdENoaWxkKTtcbiAgfVxuXG4gIHJldHVybiBmcmFnbWVudDtcbn1cblxuZnVuY3Rpb24gcGFyc2VEb2N1bWVudChzdmcpIHtcblxuICB2YXIgcGFyc2VyO1xuXG4gIC8vIHBhcnNlXG4gIHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgcGFyc2VyLmFzeW5jID0gZmFsc2U7XG5cbiAgcmV0dXJuIHBhcnNlci5wYXJzZUZyb21TdHJpbmcoc3ZnLCAndGV4dC94bWwnKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgdXRpbGl0eSBmb3IgU1ZHIGVsZW1lbnRzXG4gKi9cblxuXG4vKipcbiAqIENyZWF0ZSBhIHNwZWNpZmljIHR5cGUgZnJvbSBuYW1lIG9yIFNWRyBtYXJrdXAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgdGhlIG5hbWUgb3IgbWFya3VwIG9mIHRoZSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gW2F0dHJzXSBhdHRyaWJ1dGVzIHRvIHNldCBvbiB0aGUgZWxlbWVudFxuICpcbiAqIEByZXR1cm5zIHtTVkdFbGVtZW50fVxuICovXG5mdW5jdGlvbiBjcmVhdGUobmFtZSwgYXR0cnMpIHtcbiAgdmFyIGVsZW1lbnQ7XG5cbiAgaWYgKG5hbWUuY2hhckF0KDApID09PSAnPCcpIHtcbiAgICBlbGVtZW50ID0gcGFyc2UobmFtZSkuZmlyc3RDaGlsZDtcbiAgICBlbGVtZW50ID0gZG9jdW1lbnQuaW1wb3J0Tm9kZShlbGVtZW50LCB0cnVlKTtcbiAgfSBlbHNlIHtcbiAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKG5zLnN2ZywgbmFtZSk7XG4gIH1cblxuICBpZiAoYXR0cnMpIHtcbiAgICBhdHRyKGVsZW1lbnQsIGF0dHJzKTtcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIEV2ZW50cyBoYW5kbGluZyB1dGlsaXR5XG4gKi9cblxuZnVuY3Rpb24gb24obm9kZSwgZXZlbnQsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKSB7XG4gIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpO1xufVxuXG5mdW5jdGlvbiBvZmYobm9kZSwgZXZlbnQsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKSB7XG4gIG5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpO1xufVxuXG4vKipcbiAqIEdlb21ldHJ5IGhlbHBlcnNcbiAqL1xuXG4vLyBmYWtlIG5vZGUgdXNlZCB0byBpbnN0YW50aWF0ZSBzdmcgZ2VvbWV0cnkgZWxlbWVudHNcbnZhciBub2RlID0gY3JlYXRlKCdzdmcnKTtcblxuZnVuY3Rpb24gZXh0ZW5kKG9iamVjdCwgcHJvcHMpIHtcbiAgdmFyIGksIGssIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wcyk7XG5cbiAgZm9yIChpID0gMDsgKGsgPSBrZXlzW2ldKTsgaSsrKSB7XG4gICAgb2JqZWN0W2tdID0gcHJvcHNba107XG4gIH1cblxuICByZXR1cm4gb2JqZWN0O1xufVxuXG5cbmZ1bmN0aW9uIGNyZWF0ZVBvaW50KHgsIHkpIHtcbiAgdmFyIHBvaW50ID0gbm9kZS5jcmVhdGVTVkdQb2ludCgpO1xuXG4gIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICBjYXNlIDA6XG4gICAgcmV0dXJuIHBvaW50O1xuICBjYXNlIDI6XG4gICAgeCA9IHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5XG4gICAgfTtcbiAgICBicmVhaztcbiAgfVxuXG4gIHJldHVybiBleHRlbmQocG9pbnQsIHgpO1xufVxuXG4vKipcbiAqIENyZWF0ZSBtYXRyaXggdmlhIGFyZ3MuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBjcmVhdGVNYXRyaXgoeyBhOiAxLCBiOiAxIH0pO1xuICogY3JlYXRlTWF0cml4KCk7XG4gKiBjcmVhdGVNYXRyaXgoMSwgMiwgMCwgMCwgMzAsIDIwKTtcbiAqXG4gKiBAcmV0dXJuIHtTVkdNYXRyaXh9XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZU1hdHJpeChhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIHZhciBtYXRyaXggPSBub2RlLmNyZWF0ZVNWR01hdHJpeCgpO1xuXG4gIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICBjYXNlIDA6XG4gICAgcmV0dXJuIG1hdHJpeDtcbiAgY2FzZSAxOlxuICAgIHJldHVybiBleHRlbmQobWF0cml4LCBhKTtcbiAgY2FzZSA2OlxuICAgIHJldHVybiBleHRlbmQobWF0cml4LCB7XG4gICAgICBhOiBhLFxuICAgICAgYjogYixcbiAgICAgIGM6IGMsXG4gICAgICBkOiBkLFxuICAgICAgZTogZSxcbiAgICAgIGY6IGZcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVUcmFuc2Zvcm0obWF0cml4KSB7XG4gIGlmIChtYXRyaXgpIHtcbiAgICByZXR1cm4gbm9kZS5jcmVhdGVTVkdUcmFuc2Zvcm1Gcm9tTWF0cml4KG1hdHJpeCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5vZGUuY3JlYXRlU1ZHVHJhbnNmb3JtKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBTZXJpYWxpemF0aW9uIHV0aWxcbiAqL1xuXG52YXIgVEVYVF9FTlRJVElFUyA9IC8oWyY8Pl17MX0pL2c7XG52YXIgQVRUUl9FTlRJVElFUyA9IC8oW1xcblxcclwiXXsxfSkvZztcblxudmFyIEVOVElUWV9SRVBMQUNFTUVOVCA9IHtcbiAgJyYnOiAnJmFtcDsnLFxuICAnPCc6ICcmbHQ7JyxcbiAgJz4nOiAnJmd0OycsXG4gICdcIic6ICdcXCcnXG59O1xuXG5mdW5jdGlvbiBlc2NhcGUoc3RyLCBwYXR0ZXJuKSB7XG5cbiAgZnVuY3Rpb24gcmVwbGFjZUZuKG1hdGNoLCBlbnRpdHkpIHtcbiAgICByZXR1cm4gRU5USVRZX1JFUExBQ0VNRU5UW2VudGl0eV0gfHwgZW50aXR5O1xuICB9XG5cbiAgcmV0dXJuIHN0ci5yZXBsYWNlKHBhdHRlcm4sIHJlcGxhY2VGbik7XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZShub2RlLCBvdXRwdXQpIHtcblxuICB2YXIgaSwgbGVuLCBhdHRyTWFwLCBhdHRyTm9kZSwgY2hpbGROb2RlcztcblxuICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgLy8gVEVYVFxuICBjYXNlIDM6XG4gICAgLy8gcmVwbGFjZSBzcGVjaWFsIFhNTCBjaGFyYWN0ZXJzXG4gICAgb3V0cHV0LnB1c2goZXNjYXBlKG5vZGUudGV4dENvbnRlbnQsIFRFWFRfRU5USVRJRVMpKTtcbiAgICBicmVhaztcblxuICAvLyBFTEVNRU5UXG4gIGNhc2UgMTpcbiAgICBvdXRwdXQucHVzaCgnPCcsIG5vZGUudGFnTmFtZSk7XG5cbiAgICBpZiAobm9kZS5oYXNBdHRyaWJ1dGVzKCkpIHtcbiAgICAgIGF0dHJNYXAgPSBub2RlLmF0dHJpYnV0ZXM7XG4gICAgICBmb3IgKGkgPSAwLCBsZW4gPSBhdHRyTWFwLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIGF0dHJOb2RlID0gYXR0ck1hcC5pdGVtKGkpO1xuICAgICAgICBvdXRwdXQucHVzaCgnICcsIGF0dHJOb2RlLm5hbWUsICc9XCInLCBlc2NhcGUoYXR0ck5vZGUudmFsdWUsIEFUVFJfRU5USVRJRVMpLCAnXCInKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobm9kZS5oYXNDaGlsZE5vZGVzKCkpIHtcbiAgICAgIG91dHB1dC5wdXNoKCc+Jyk7XG4gICAgICBjaGlsZE5vZGVzID0gbm9kZS5jaGlsZE5vZGVzO1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gY2hpbGROb2Rlcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICBzZXJpYWxpemUoY2hpbGROb2Rlcy5pdGVtKGkpLCBvdXRwdXQpO1xuICAgICAgfVxuICAgICAgb3V0cHV0LnB1c2goJzwvJywgbm9kZS50YWdOYW1lLCAnPicpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnLz4nKTtcbiAgICB9XG4gICAgYnJlYWs7XG5cbiAgLy8gQ09NTUVOVFxuICBjYXNlIDg6XG4gICAgb3V0cHV0LnB1c2goJzwhLS0nLCBlc2NhcGUobm9kZS5ub2RlVmFsdWUsIFRFWFRfRU5USVRJRVMpLCAnLS0+Jyk7XG4gICAgYnJlYWs7XG5cbiAgLy8gQ0RBVEFcbiAgY2FzZSA0OlxuICAgIG91dHB1dC5wdXNoKCc8IVtDREFUQVsnLCBub2RlLm5vZGVWYWx1ZSwgJ11dPicpO1xuICAgIGJyZWFrO1xuXG4gIGRlZmF1bHQ6XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmFibGUgdG8gaGFuZGxlIG5vZGUgJyArIG5vZGUubm9kZVR5cGUpO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBpbm5lckhUTUwgbGlrZSBmdW5jdGlvbmFsaXR5IGZvciBTVkcgZWxlbWVudHMuXG4gKiBiYXNlZCBvbiBpbm5lclNWRyAoaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9pbm5lcnN2ZylcbiAqL1xuXG5cbmZ1bmN0aW9uIHNldChlbGVtZW50LCBzdmcpIHtcblxuICB2YXIgcGFyc2VkID0gcGFyc2Uoc3ZnKTtcblxuICAvLyBjbGVhciBlbGVtZW50IGNvbnRlbnRzXG4gIGNsZWFyKGVsZW1lbnQpO1xuXG4gIGlmICghc3ZnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCFpc0ZyYWdtZW50KHBhcnNlZCkpIHtcbiAgICAvLyBleHRyYWN0IDxzdmc+IGZyb20gcGFyc2VkIGRvY3VtZW50XG4gICAgcGFyc2VkID0gcGFyc2VkLmRvY3VtZW50RWxlbWVudDtcbiAgfVxuXG4gIHZhciBub2RlcyA9IHNsaWNlKHBhcnNlZC5jaGlsZE5vZGVzKTtcblxuICAvLyBpbXBvcnQgKyBhcHBlbmQgZWFjaCBub2RlXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICBhcHBlbmRUbyhub2Rlc1tpXSwgZWxlbWVudCk7XG4gIH1cblxufVxuXG5mdW5jdGlvbiBnZXQoZWxlbWVudCkge1xuICB2YXIgY2hpbGQgPSBlbGVtZW50LmZpcnN0Q2hpbGQsXG4gICAgICBvdXRwdXQgPSBbXTtcblxuICB3aGlsZSAoY2hpbGQpIHtcbiAgICBzZXJpYWxpemUoY2hpbGQsIG91dHB1dCk7XG4gICAgY2hpbGQgPSBjaGlsZC5uZXh0U2libGluZztcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQuam9pbignJyk7XG59XG5cbmZ1bmN0aW9uIGlzRnJhZ21lbnQobm9kZSkge1xuICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gJyNkb2N1bWVudC1mcmFnbWVudCc7XG59XG5cbmZ1bmN0aW9uIGlubmVyU1ZHKGVsZW1lbnQsIHN2Zykge1xuXG4gIGlmIChzdmcgIT09IHVuZGVmaW5lZCkge1xuXG4gICAgdHJ5IHtcbiAgICAgIHNldChlbGVtZW50LCBzdmcpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXJyb3IgcGFyc2luZyBTVkc6ICcgKyBlLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBlbGVtZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBnZXQoZWxlbWVudCk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBzbGljZShhcnIpIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFycik7XG59XG5cbi8qKlxuICogU2VsZWN0aW9uIHV0aWxpdGllc1xuICovXG5cbmZ1bmN0aW9uIHNlbGVjdChub2RlLCBzZWxlY3Rvcikge1xuICByZXR1cm4gbm9kZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0QWxsKG5vZGUsIHNlbGVjdG9yKSB7XG4gIHZhciBub2RlcyA9IG5vZGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG5cbiAgcmV0dXJuIFtdLm1hcC5jYWxsKG5vZGVzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH0pO1xufVxuXG4vKipcbiAqIHByZXBlbmRUbyB1dGlsaXR5XG4gKi9cblxuLyoqXG4gKiBQcmVwZW5kIGEgbm9kZSB0byBhIHRhcmdldCBlbGVtZW50IGFuZCByZXR1cm4gdGhlIHByZXBlbmRlZCBub2RlLlxuICpcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IG5vZGVcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IHRhcmdldFxuICpcbiAqIEByZXR1cm4ge1NWR0VsZW1lbnR9IHRoZSBwcmVwZW5kZWQgbm9kZVxuICovXG5mdW5jdGlvbiBwcmVwZW5kVG8obm9kZSwgdGFyZ2V0KSB7XG4gIHJldHVybiB0YXJnZXQuaW5zZXJ0QmVmb3JlKGVuc3VyZUltcG9ydGVkKG5vZGUsIHRhcmdldCksIHRhcmdldC5maXJzdENoaWxkIHx8IG51bGwpO1xufVxuXG4vKipcbiAqIHByZXBlbmQgdXRpbGl0eVxuICovXG5cbi8qKlxuICogUHJlcGVuZCBhIG5vZGUgdG8gYSB0YXJnZXQgZWxlbWVudFxuICpcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IHRhcmdldFxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gbm9kZVxuICpcbiAqIEByZXR1cm4ge1NWR0VsZW1lbnR9IHRoZSB0YXJnZXQgZWxlbWVudFxuICovXG5mdW5jdGlvbiBwcmVwZW5kKHRhcmdldCwgbm9kZSkge1xuICBwcmVwZW5kVG8obm9kZSwgdGFyZ2V0KTtcbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuLyoqXG4gKiBSZXBsYWNlIHV0aWxpdHlcbiAqL1xuXG5mdW5jdGlvbiByZXBsYWNlKGVsZW1lbnQsIHJlcGxhY2VtZW50KSB7XG4gIGVsZW1lbnQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoZW5zdXJlSW1wb3J0ZWQocmVwbGFjZW1lbnQsIGVsZW1lbnQpLCBlbGVtZW50KTtcbiAgcmV0dXJuIHJlcGxhY2VtZW50O1xufVxuXG4vKipcbiAqIHRyYW5zZm9ybSBhY2Nlc3NvciB1dGlsaXR5XG4gKi9cblxuZnVuY3Rpb24gd3JhcE1hdHJpeCh0cmFuc2Zvcm1MaXN0LCB0cmFuc2Zvcm0pIHtcbiAgaWYgKHRyYW5zZm9ybSBpbnN0YW5jZW9mIFNWR01hdHJpeCkge1xuICAgIHJldHVybiB0cmFuc2Zvcm1MaXN0LmNyZWF0ZVNWR1RyYW5zZm9ybUZyb21NYXRyaXgodHJhbnNmb3JtKTtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm07XG59XG5cblxuZnVuY3Rpb24gc2V0VHJhbnNmb3Jtcyh0cmFuc2Zvcm1MaXN0LCB0cmFuc2Zvcm1zKSB7XG4gIHZhciBpLCB0O1xuXG4gIHRyYW5zZm9ybUxpc3QuY2xlYXIoKTtcblxuICBmb3IgKGkgPSAwOyAodCA9IHRyYW5zZm9ybXNbaV0pOyBpKyspIHtcbiAgICB0cmFuc2Zvcm1MaXN0LmFwcGVuZEl0ZW0od3JhcE1hdHJpeCh0cmFuc2Zvcm1MaXN0LCB0KSk7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgb3Igc2V0IHRoZSB0cmFuc2Zvcm1zIG9uIHRoZSBnaXZlbiBub2RlLlxuICpcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gbm9kZVxuICogQHBhcmFtICB7U1ZHVHJhbnNmb3JtfFNWR01hdHJpeHxBcnJheTxTVkdUcmFuc2Zvcm18U1ZHTWF0cml4Pn0gW3RyYW5zZm9ybXNdXG4gKlxuICogQHJldHVybiB7U1ZHVHJhbnNmb3JtfSB0aGUgY29uc29saWRhdGVkIHRyYW5zZm9ybVxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm0obm9kZSwgdHJhbnNmb3Jtcykge1xuICB2YXIgdHJhbnNmb3JtTGlzdCA9IG5vZGUudHJhbnNmb3JtLmJhc2VWYWw7XG5cbiAgaWYgKHRyYW5zZm9ybXMpIHtcblxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0cmFuc2Zvcm1zKSkge1xuICAgICAgdHJhbnNmb3JtcyA9IFsgdHJhbnNmb3JtcyBdO1xuICAgIH1cblxuICAgIHNldFRyYW5zZm9ybXModHJhbnNmb3JtTGlzdCwgdHJhbnNmb3Jtcyk7XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtTGlzdC5jb25zb2xpZGF0ZSgpO1xufVxuXG5leHBvcnQgeyBhcHBlbmQsIGFwcGVuZFRvLCBhdHRyLCBjbGFzc2VzLCBjbGVhciwgY2xvbmUsIGNyZWF0ZSwgaW5uZXJTVkcsIHByZXBlbmQsIHByZXBlbmRUbywgcmVtb3ZlLCByZXBsYWNlLCB0cmFuc2Zvcm0sIG9uLCBvZmYsIGNyZWF0ZVBvaW50LCBjcmVhdGVNYXRyaXgsIGNyZWF0ZVRyYW5zZm9ybSwgc2VsZWN0LCBzZWxlY3RBbGwgfTtcbiIsIm1vZHVsZS5leHBvcnRzPXtcclxuICBcIm5hbWVcIjogXCJBY3Rpdml0aVwiLFxyXG4gIFwidXJpXCI6IFwiaHR0cDovL2FjdGl2aXRpLm9yZy9icG1uXCIsXHJcbiAgXCJwcmVmaXhcIjogXCJhY3Rpdml0aVwiLFxyXG4gIFwieG1sXCI6IHtcclxuICAgIFwidGFnQWxpYXNcIjogXCJsb3dlckNhc2VcIlxyXG4gIH0sXHJcbiAgXCJhc3NvY2lhdGlvbnNcIjogW10sXHJcbiAgXCJ0eXBlc1wiOiBbXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkRlZmluaXRpb25zXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpEZWZpbml0aW9uc1wiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZGlhZ3JhbVJlbGF0aW9uSWRcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiSW5PdXRCaW5kaW5nXCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbXHJcbiAgICAgICAgXCJFbGVtZW50XCJcclxuICAgICAgXSxcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwic291cmNlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInNvdXJjZUV4cHJlc3Npb25cIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidGFyZ2V0XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImJ1c2luZXNzS2V5XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImxvY2FsXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQm9vbGVhblwiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IGZhbHNlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YXJpYWJsZXNcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiSW5cIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFtcclxuICAgICAgICBcIkluT3V0QmluZGluZ1wiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJicG1uOkNhbGxBY3Rpdml0eVwiXHJcbiAgICAgICAgXVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJPdXRcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFtcclxuICAgICAgICBcIkluT3V0QmluZGluZ1wiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJicG1uOkNhbGxBY3Rpdml0eVwiXHJcbiAgICAgICAgXVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJBc3luY0NhcGFibGVcIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOkFjdGl2aXR5XCIsXHJcbiAgICAgICAgXCJicG1uOkdhdGV3YXlcIixcclxuICAgICAgICBcImJwbW46RXZlbnRcIlxyXG4gICAgICBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImFzeW5jXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQm9vbGVhblwiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IGZhbHNlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJhc3luY0JlZm9yZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkJvb2xlYW5cIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBmYWxzZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiYXN5bmNBZnRlclwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkJvb2xlYW5cIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBmYWxzZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZXhjbHVzaXZlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQm9vbGVhblwiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkpvYlByaW9yaXplZFwiLFxyXG4gICAgICBcImlzQWJzdHJhY3RcIjogdHJ1ZSxcclxuICAgICAgXCJleHRlbmRzXCI6IFtcclxuICAgICAgICBcImJwbW46UHJvY2Vzc1wiLFxyXG4gICAgICAgIFwiYWN0aXZpdGk6QXN5bmNDYXBhYmxlXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJqb2JQcmlvcml0eVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJTaWduYWxFdmVudERlZmluaXRpb25cIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiYXN5bmNcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJCb29sZWFuXCIsXHJcbiAgICAgICAgICBcImRlZmF1bHRcIjogZmFsc2VcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkVycm9yRXZlbnREZWZpbml0aW9uXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpFcnJvckV2ZW50RGVmaW5pdGlvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZXJyb3JDb2RlVmFyaWFibGVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZXJyb3JNZXNzYWdlVmFyaWFibGVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiRXJyb3JcIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOkVycm9yXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJhY3Rpdml0aTplcnJvck1lc3NhZ2VcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiUG90ZW50aWFsU3RhcnRlclwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogW1xyXG4gICAgICAgIFwiRWxlbWVudFwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicmVzb3VyY2VBc3NpZ25tZW50RXhwcmVzc2lvblwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiYnBtbjpSZXNvdXJjZUFzc2lnbm1lbnRFeHByZXNzaW9uXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkZvcm1TdXBwb3J0ZWRcIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOlN0YXJ0RXZlbnRcIixcclxuICAgICAgICBcImJwbW46VXNlclRhc2tcIlxyXG4gICAgICBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImZvcm1IYW5kbGVyQ2xhc3NcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZm9ybUtleVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJUZW1wbGF0ZVN1cHBvcnRlZFwiLFxyXG4gICAgICBcImlzQWJzdHJhY3RcIjogdHJ1ZSxcclxuICAgICAgXCJleHRlbmRzXCI6IFtcclxuICAgICAgICBcImJwbW46UHJvY2Vzc1wiLFxyXG4gICAgICAgIFwiYnBtbjpGbG93RWxlbWVudFwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibW9kZWxlclRlbXBsYXRlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkluaXRpYXRvclwiLFxyXG4gICAgICBcImlzQWJzdHJhY3RcIjogdHJ1ZSxcclxuICAgICAgXCJleHRlbmRzXCI6IFsgXCJicG1uOlN0YXJ0RXZlbnRcIiBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImluaXRpYXRvclwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJTY3JpcHRUYXNrXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpTY3JpcHRUYXNrXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJyZXN1bHRWYXJpYWJsZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJyZXNvdXJjZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJQcm9jZXNzXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpQcm9jZXNzXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYW5kaWRhdGVTdGFydGVyQ29uZmlndXJhdGlvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYW5kaWRhdGVTdGFydGVyVXNlcnNcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidmVyc2lvblRhZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJoaXN0b3J5VGltZVRvTGl2ZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpc1N0YXJ0YWJsZUluVGFza2xpc3RcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJCb29sZWFuXCIsXHJcbiAgICAgICAgICBcImRlZmF1bHRcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicHJvY2Vzcy1pcy1leGVjdXRhYmxlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQm9vbGVhblwiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkVzY2FsYXRpb25FdmVudERlZmluaXRpb25cIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOkVzY2FsYXRpb25FdmVudERlZmluaXRpb25cIlxyXG4gICAgICBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImVzY2FsYXRpb25Db2RlVmFyaWFibGVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiRm9ybWFsRXhwcmVzc2lvblwiLFxyXG4gICAgICBcImlzQWJzdHJhY3RcIjogdHJ1ZSxcclxuICAgICAgXCJleHRlbmRzXCI6IFtcclxuICAgICAgICBcImJwbW46Rm9ybWFsRXhwcmVzc2lvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicmVzb3VyY2VcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiQXNzaWduYWJsZVwiLFxyXG4gICAgICBcImV4dGVuZHNcIjogWyBcImJwbW46VXNlclRhc2tcIiBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImFzc2lnbmVlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNhbmRpZGF0ZVVzZXJzXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNhbmRpZGF0ZUdyb3Vwc1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkdWVEYXRlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImZvbGxvd1VwRGF0ZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJwcmlvcml0eVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJDYWxsQWN0aXZpdHlcIixcclxuICAgICAgXCJleHRlbmRzXCI6IFsgXCJicG1uOkNhbGxBY3Rpdml0eVwiIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiY2FsbGVkRWxlbWVudEJpbmRpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBcImxhdGVzdFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYWxsZWRFbGVtZW50VmVyc2lvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYWxsZWRFbGVtZW50VmVyc2lvblRhZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYWxsZWRFbGVtZW50VGVuYW50SWRcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiY2FzZVJlZlwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYXNlQmluZGluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IFwibGF0ZXN0XCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNhc2VWZXJzaW9uXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNhc2VUZW5hbnRJZFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YXJpYWJsZU1hcHBpbmdDbGFzc1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YXJpYWJsZU1hcHBpbmdEZWxlZ2F0ZUV4cHJlc3Npb25cIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiU2VydmljZVRhc2tMaWtlXCIsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOlNlcnZpY2VUYXNrXCIsXHJcbiAgICAgICAgXCJicG1uOkJ1c2luZXNzUnVsZVRhc2tcIixcclxuICAgICAgICBcImJwbW46U2VuZFRhc2tcIixcclxuICAgICAgICBcImJwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZXhwcmVzc2lvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjbGFzc1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWxlZ2F0ZUV4cHJlc3Npb25cIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicmVzdWx0VmFyaWFibGVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiRG1uQ2FwYWJsZVwiLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpCdXNpbmVzc1J1bGVUYXNrXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWNpc2lvblJlZlwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWNpc2lvblJlZkJpbmRpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBcImxhdGVzdFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWNpc2lvblJlZlZlcnNpb25cIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibWFwRGVjaXNpb25SZXN1bHRcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBcInJlc3VsdExpc3RcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZGVjaXNpb25SZWZUZW5hbnRJZFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJFeHRlcm5hbENhcGFibGVcIixcclxuICAgICAgXCJleHRlbmRzXCI6IFtcclxuICAgICAgICBcImFjdGl2aXRpOlNlcnZpY2VUYXNrTGlrZVwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidHlwZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ0b3BpY1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJUYXNrUHJpb3JpemVkXCIsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOlByb2Nlc3NcIixcclxuICAgICAgICBcImFjdGl2aXRpOkV4dGVybmFsQ2FwYWJsZVwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidGFza1ByaW9yaXR5XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIlByb3BlcnRpZXNcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFtcclxuICAgICAgICBcIkVsZW1lbnRcIlxyXG4gICAgICBdLFxyXG4gICAgICBcIm1ldGFcIjoge1xyXG4gICAgICAgIFwiYWxsb3dlZEluXCI6IFsgXCIqXCIgXVxyXG4gICAgICB9LFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlc1wiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiUHJvcGVydHlcIixcclxuICAgICAgICAgIFwiaXNNYW55XCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIlByb3BlcnR5XCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbXHJcbiAgICAgICAgXCJFbGVtZW50XCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpZFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJuYW1lXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkNvbm5lY3RvclwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogW1xyXG4gICAgICAgIFwiRWxlbWVudFwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJhY3Rpdml0aTpTZXJ2aWNlVGFza0xpa2VcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpbnB1dE91dHB1dFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiSW5wdXRPdXRwdXRcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiY29ubmVjdG9ySWRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJJbnB1dE91dHB1dFwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogW1xyXG4gICAgICAgIFwiRWxlbWVudFwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJicG1uOkZsb3dOb2RlXCIsXHJcbiAgICAgICAgICBcImFjdGl2aXRpOkNvbm5lY3RvclwiXHJcbiAgICAgICAgXVxyXG4gICAgICB9LFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImlucHV0T3V0cHV0XCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJJbnB1dE91dHB1dFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjb25uZWN0b3JJZFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImlucHV0UGFyYW1ldGVyc1wiLFxyXG4gICAgICAgICAgXCJpc01hbnlcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIklucHV0UGFyYW1ldGVyXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcIm91dHB1dFBhcmFtZXRlcnNcIixcclxuICAgICAgICAgIFwiaXNNYW55XCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJPdXRwdXRQYXJhbWV0ZXJcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiSW5wdXRPdXRwdXRQYXJhbWV0ZXJcIixcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJuYW1lXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImRlZmluaXRpb25cIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIklucHV0T3V0cHV0UGFyYW1ldGVyRGVmaW5pdGlvblwiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJJbnB1dE91dHB1dFBhcmFtZXRlckRlZmluaXRpb25cIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkxpc3RcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJJbnB1dE91dHB1dFBhcmFtZXRlckRlZmluaXRpb25cIiBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcIml0ZW1zXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiSW5wdXRPdXRwdXRQYXJhbWV0ZXJEZWZpbml0aW9uXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIk1hcFwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIklucHV0T3V0cHV0UGFyYW1ldGVyRGVmaW5pdGlvblwiIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZW50cmllc1wiLFxyXG4gICAgICAgICAgXCJpc01hbnlcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkVudHJ5XCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkVudHJ5XCIsXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwia2V5XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImRlZmluaXRpb25cIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIklucHV0T3V0cHV0UGFyYW1ldGVyRGVmaW5pdGlvblwiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJWYWx1ZVwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogW1xyXG4gICAgICAgIFwiSW5wdXRPdXRwdXRQYXJhbWV0ZXJEZWZpbml0aW9uXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpZFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJuYW1lXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIlNjcmlwdFwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIklucHV0T3V0cHV0UGFyYW1ldGVyRGVmaW5pdGlvblwiIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwic2NyaXB0Rm9ybWF0XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInJlc291cmNlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkZpZWxkXCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbIFwiRWxlbWVudFwiIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJhY3Rpdml0aTpTZXJ2aWNlVGFza0xpa2VcIixcclxuICAgICAgICAgIFwiYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXJcIixcclxuICAgICAgICAgIFwiYWN0aXZpdGk6VGFza0xpc3RlbmVyXCJcclxuICAgICAgICBdXHJcbiAgICAgIH0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibmFtZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJleHByZXNzaW9uXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwic3RyaW5nVmFsdWVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwic3RyaW5nXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiSW5wdXRQYXJhbWV0ZXJcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJJbnB1dE91dHB1dFBhcmFtZXRlclwiIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIk91dHB1dFBhcmFtZXRlclwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIklucHV0T3V0cHV0UGFyYW1ldGVyXCIgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiQ29sbGVjdGFibGVcIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbIFwiYnBtbjpNdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljc1wiIF0sXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbIFwiYWN0aXZpdGk6QXN5bmNDYXBhYmxlXCIgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjb2xsZWN0aW9uXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImVsZW1lbnRWYXJpYWJsZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZVwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIkVsZW1lbnRcIiBdLFxyXG4gICAgICBcIm1ldGFcIjoge1xyXG4gICAgICAgIFwiYWxsb3dlZEluXCI6IFtcclxuICAgICAgICAgIFwiYWN0aXZpdGk6QXN5bmNDYXBhYmxlXCIsXHJcbiAgICAgICAgICBcImJwbW46TXVsdGlJbnN0YW5jZUxvb3BDaGFyYWN0ZXJpc3RpY3NcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJib2R5XCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkV4ZWN1dGlvbkxpc3RlbmVyXCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbIFwiRWxlbWVudFwiIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJicG1uOlRhc2tcIixcclxuICAgICAgICAgIFwiYnBtbjpTZXJ2aWNlVGFza1wiLFxyXG4gICAgICAgICAgXCJicG1uOlVzZXJUYXNrXCIsXHJcbiAgICAgICAgICBcImJwbW46QnVzaW5lc3NSdWxlVGFza1wiLFxyXG4gICAgICAgICAgXCJicG1uOlNjcmlwdFRhc2tcIixcclxuICAgICAgICAgIFwiYnBtbjpSZWNlaXZlVGFza1wiLFxyXG4gICAgICAgICAgXCJicG1uOk1hbnVhbFRhc2tcIixcclxuICAgICAgICAgIFwiYnBtbjpFeGNsdXNpdmVHYXRld2F5XCIsXHJcbiAgICAgICAgICBcImJwbW46U2VxdWVuY2VGbG93XCIsXHJcbiAgICAgICAgICBcImJwbW46UGFyYWxsZWxHYXRld2F5XCIsXHJcbiAgICAgICAgICBcImJwbW46SW5jbHVzaXZlR2F0ZXdheVwiLFxyXG4gICAgICAgICAgXCJicG1uOkV2ZW50QmFzZWRHYXRld2F5XCIsXHJcbiAgICAgICAgICBcImJwbW46U3RhcnRFdmVudFwiLFxyXG4gICAgICAgICAgXCJicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnRcIixcclxuICAgICAgICAgIFwiYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50XCIsXHJcbiAgICAgICAgICBcImJwbW46RW5kRXZlbnRcIixcclxuICAgICAgICAgIFwiYnBtbjpCb3VuZGFyeUV2ZW50XCIsXHJcbiAgICAgICAgICBcImJwbW46Q2FsbEFjdGl2aXR5XCIsXHJcbiAgICAgICAgICBcImJwbW46U3ViUHJvY2Vzc1wiLFxyXG4gICAgICAgICAgXCJicG1uOlByb2Nlc3NcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJleHByZXNzaW9uXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNsYXNzXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImRlbGVnYXRlRXhwcmVzc2lvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJldmVudFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJzY3JpcHRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlNjcmlwdFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJmaWVsZHNcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkZpZWxkXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJUYXNrTGlzdGVuZXJcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJFbGVtZW50XCIgXSxcclxuICAgICAgXCJtZXRhXCI6IHtcclxuICAgICAgICBcImFsbG93ZWRJblwiOiBbXHJcbiAgICAgICAgICBcImJwbW46VXNlclRhc2tcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJleHByZXNzaW9uXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNsYXNzXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImRlbGVnYXRlRXhwcmVzc2lvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJldmVudFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJzY3JpcHRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlNjcmlwdFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJmaWVsZHNcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkZpZWxkXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpZFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJldmVudERlZmluaXRpb25zXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJicG1uOlRpbWVyRXZlbnREZWZpbml0aW9uXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJGb3JtUHJvcGVydHlcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJFbGVtZW50XCIgXSxcclxuICAgICAgXCJtZXRhXCI6IHtcclxuICAgICAgICBcImFsbG93ZWRJblwiOiBbXHJcbiAgICAgICAgICBcImJwbW46U3RhcnRFdmVudFwiLFxyXG4gICAgICAgICAgXCJicG1uOlVzZXJUYXNrXCJcclxuICAgICAgICBdXHJcbiAgICAgIH0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiaWRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibmFtZVwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ0eXBlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInJlcXVpcmVkXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInJlYWRhYmxlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcIndyaXRhYmxlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhcmlhYmxlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImV4cHJlc3Npb25cIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZGF0ZVBhdHRlcm5cIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZGVmYXVsdFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YWx1ZXNcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJGb3JtRGF0YVwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIkVsZW1lbnRcIiBdLFxyXG4gICAgICBcIm1ldGFcIjoge1xyXG4gICAgICAgIFwiYWxsb3dlZEluXCI6IFtcclxuICAgICAgICAgIFwiYnBtbjpTdGFydEV2ZW50XCIsXHJcbiAgICAgICAgICBcImJwbW46VXNlclRhc2tcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJmaWVsZHNcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkZvcm1GaWVsZFwiLFxyXG4gICAgICAgICAgXCJpc01hbnlcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiYnVzaW5lc3NLZXlcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiRm9ybUZpZWxkXCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbIFwiRWxlbWVudFwiIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiaWRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibGFiZWxcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidHlwZVwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkYXRlUGF0dGVyblwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWZhdWx0VmFsdWVcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicHJvcGVydGllc1wiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiUHJvcGVydGllc1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YWxpZGF0aW9uXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJWYWxpZGF0aW9uXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlc1wiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVmFsdWVcIixcclxuICAgICAgICAgIFwiaXNNYW55XCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIlZhbGlkYXRpb25cIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJFbGVtZW50XCIgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjb25zdHJhaW50c1wiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQ29uc3RyYWludFwiLFxyXG4gICAgICAgICAgXCJpc01hbnlcIjogdHJ1ZVxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiQ29uc3RyYWludFwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIkVsZW1lbnRcIiBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcIm5hbWVcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiY29uZmlnXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidmFyaWFibGVOYW1lXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhcmlhYmxlRXZlbnRcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfVxyXG4gIF0sXHJcbiAgXCJlbXVtZXJhdGlvbnNcIjogWyBdXHJcbn1cclxuIiwiZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ3VzdG9tQ29udGV4dFBhZCB7XHJcbiAgY29uc3RydWN0b3IoY29uZmlnLCBjb250ZXh0UGFkLCBjcmVhdGUsIGVsZW1lbnRGYWN0b3J5LCBpbmplY3RvciwgdHJhbnNsYXRlKSB7XHJcbiAgICB0aGlzLmNyZWF0ZSA9IGNyZWF0ZTtcclxuICAgIHRoaXMuZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcclxuICAgIHRoaXMudHJhbnNsYXRlID0gdHJhbnNsYXRlO1xyXG4gICAgLy/oh6rliqjmkYbmlL7kvY3nva5cclxuICAgIGlmIChjb25maWcuYXV0b1BsYWNlICE9PSBmYWxzZSkge1xyXG4gICAgICB0aGlzLmF1dG9QbGFjZSA9IGluamVjdG9yLmdldCgnYXV0b1BsYWNlJywgZmFsc2UpO1xyXG4gICAgfVxyXG4gICAgLy/ms6jlhozlt6XlhbdcclxuICAgIGNvbnRleHRQYWQucmVnaXN0ZXJQcm92aWRlcih0aGlzKTtcclxuICB9XHJcbiAgZ2V0Q29udGV4dFBhZEVudHJpZXMoZWxlbWVudCkge1xyXG4gICAgY29uc3Qge1xyXG4gICAgICBhdXRvUGxhY2UsXHJcbiAgICAgIGNyZWF0ZSxcclxuICAgICAgZWxlbWVudEZhY3RvcnksXHJcbiAgICAgIHRyYW5zbGF0ZVxyXG4gICAgfSA9IHRoaXM7XHJcblxyXG4gICAgZnVuY3Rpb24gYXBwZW5kVXNlclRhc2soZXZlbnQsIGVsZW1lbnQpIHtcclxuICAgICAgaWYgKGF1dG9QbGFjZSkge1xyXG4gICAgICAgIGNvbnN0IHNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoeyB0eXBlOiAnYnBtbjpVc2VyVGFzaycgfSk7XHJcbiAgICAgICAgYXV0b1BsYWNlLmFwcGVuZChlbGVtZW50LCBzaGFwZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgYXBwZW5kVXNlclRhc2tTdGFydChldmVudCwgZWxlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBhcHBlbmRVc2VyVGFza1N0YXJ0KGV2ZW50KSB7XHJcbiAgICAgICAgICBjb25zdCBzaGFwZSA9IGVsZW1lbnRGYWN0b3J5LmNyZWF0ZVNoYXBlKHsgdHlwZTogJ2JwbW46VXNlclRhc2snIH0pO1xyXG4gICAgICAgICAgY3JlYXRlLnN0YXJ0KGV2ZW50LCBzaGFwZSwgZWxlbWVudCk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBhcHBlbmRDYWxsQWN0aXZpdHlTdGFydChldmVudCkge1xyXG4gICAgICBjb25zdCBzaGFwZSA9IGVsZW1lbnRGYWN0b3J5LmNyZWF0ZVNoYXBlKHsgdHlwZTogJ2JwbW46Q2FsbEFjdGl2aXR5JyB9KTtcclxuICAgICAgY3JlYXRlLnN0YXJ0KGV2ZW50LCBzaGFwZSwgZWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gYXBwZW5kQ2FsbEFjdGl2aXR5KGV2ZW50LCBlbGVtZW50KSB7XHJcbiAgICAgICAgaWYgKGF1dG9QbGFjZSkge1xyXG4gICAgICAgICAgICBjb25zdCBzaGFwZSA9IGVsZW1lbnRGYWN0b3J5LmNyZWF0ZVNoYXBlKHsgdHlwZTogJ2JwbW46Q2FsbEFjdGl2aXR5JyB9KTtcclxuICAgICAgICAgICAgYXV0b1BsYWNlLmFwcGVuZChlbGVtZW50LCBzaGFwZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYXBwZW5kQ2FsbEFjdGl2aXR5U3RhcnQoZXZlbnQsIGVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICdhcHBlbmQudXNlci10YXNrJzoge1xyXG4gICAgICAgIGdyb3VwOiAnbW9kZWwnLFxyXG4gICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi11c2VyLXRhc2snLFxyXG4gICAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FwcGVuZCBTZXJ2aWNlVGFzaycpLFxyXG4gICAgICAgIGFjdGlvbjoge1xyXG4gICAgICAgICAgY2xpY2s6IGFwcGVuZFVzZXJUYXNrLFxyXG4gICAgICAgICAgZHJhZ3N0YXJ0OiBhcHBlbmRVc2VyVGFza1N0YXJ0XHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICAnYXBwZW5kLmNhbGwtYWN0aXZpdHknOntcclxuICAgICAgICAgIGdyb3VwOiAnbW9kZWwnLFxyXG4gICAgICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWNhbGwtYWN0aXZpdHknLFxyXG4gICAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQXBwZW5kIENhbGxBY3Rpdml0eScpLFxyXG4gICAgICAgICAgYWN0aW9uOiB7XHJcbiAgICAgICAgICAgICAgY2xpY2s6IGFwcGVuZENhbGxBY3Rpdml0eSxcclxuICAgICAgICAgICAgICBkcmFnc3RhcnQ6IGFwcGVuZENhbGxBY3Rpdml0eVN0YXJ0XHJcbiAgICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgfVxyXG59XHJcbkN1c3RvbUNvbnRleHRQYWQuJGluamVjdCA9IFtcclxuICAnY29uZmlnJyxcclxuICAnY29udGV4dFBhZCcsXHJcbiAgJ2NyZWF0ZScsXHJcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcclxuICAnaW5qZWN0b3InLFxyXG4gICd0cmFuc2xhdGUnXHJcbl07IiwiZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ3VzdG9tUGFsZXR0ZSB7XHJcbiAgY29uc3RydWN0b3IoY3JlYXRlLCBlbGVtZW50RmFjdG9yeSwgcGFsZXR0ZSwgdHJhbnNsYXRlKSB7XHJcbiAgICB0aGlzLmNyZWF0ZSA9IGNyZWF0ZTtcclxuICAgIHRoaXMuZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcclxuICAgIHRoaXMudHJhbnNsYXRlID0gdHJhbnNsYXRlO1xyXG4gICAgcGFsZXR0ZS5yZWdpc3RlclByb3ZpZGVyKHRoaXMpO1xyXG4gIH1cclxuXHJcbiAgZ2V0UGFsZXR0ZUVudHJpZXMoZWxlbWVudCkge1xyXG4gICAgY29uc3Qge1xyXG4gICAgICBjcmVhdGUsXHJcbiAgICAgIGVsZW1lbnRGYWN0b3J5LFxyXG4gICAgICB0cmFuc2xhdGVcclxuICAgIH0gPSB0aGlzO1xyXG5cclxuICAgIGZ1bmN0aW9uIGNyZWF0ZVNlcnZpY2VUYXNrKGV2ZW50KSB7XHJcbiAgICAgIGNvbnN0IHNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoeyB0eXBlOiAnYnBtbjpVc2VyVGFzaycgfSk7XHJcbiAgICAgIGNyZWF0ZS5zdGFydChldmVudCwgc2hhcGUpO1xyXG4gICAgfVxyXG4gICAgICBmdW5jdGlvbiBjcmVhdGVDYWxsQWN0aXZpdHkoZXZlbnQpIHtcclxuICAgICAgICAgIGNvbnN0IHNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoeyB0eXBlOiAnYnBtbjpDYWxsQWN0aXZpdHknIH0pO1xyXG4gICAgICAgICAgY3JlYXRlLnN0YXJ0KGV2ZW50LCBzaGFwZSk7XHJcbiAgICAgIH1cclxuXHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgJ2NyZWF0ZS51c2VyLXRhc2snOiB7XHJcbiAgICAgICAgZ3JvdXA6ICdhY3Rpdml0eScsXHJcbiAgICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXVzZXItdGFzaycsXHJcbiAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQ3JlYXRlIFVzZXJUYXNrJyksXHJcbiAgICAgICAgYWN0aW9uOiB7XHJcbiAgICAgICAgICBkcmFnc3RhcnQ6IGNyZWF0ZVNlcnZpY2VUYXNrLFxyXG4gICAgICAgICAgY2xpY2s6IGNyZWF0ZVNlcnZpY2VUYXNrXHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICAgICdjcmVhdGUuY2FsbC1hY3Rpdml0eSc6IHtcclxuICAgICAgICAgICAgZ3JvdXA6ICdhY3Rpdml0eScsXHJcbiAgICAgICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jYWxsLWFjdGl2aXR5JyxcclxuICAgICAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQ3JlYXRlIENhbGxBY3Rpdml0eScpLFxyXG4gICAgICAgICAgICBhY3Rpb246IHtcclxuICAgICAgICAgICAgICAgIGRyYWdzdGFydDogY3JlYXRlQ2FsbEFjdGl2aXR5LFxyXG4gICAgICAgICAgICAgICAgY2xpY2s6IGNyZWF0ZUNhbGxBY3Rpdml0eVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuQ3VzdG9tUGFsZXR0ZS4kaW5qZWN0ID0gW1xyXG4gICdjcmVhdGUnLFxyXG4gICdlbGVtZW50RmFjdG9yeScsXHJcbiAgJ3BhbGV0dGUnLFxyXG4gICd0cmFuc2xhdGUnXHJcbl07IiwiaW1wb3J0IEN1c3RvbUNvbnRleHRQYWQgZnJvbSAnLi9DdXN0b21Db250ZXh0UGFkJztcclxuaW1wb3J0IEN1c3RvbVBhbGV0dGUgZnJvbSAnLi9DdXN0b21QYWxldHRlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBfX2luaXRfXzogWyAnY3VzdG9tQ29udGV4dFBhZCcsICdjdXN0b21QYWxldHRlJyBdLFxyXG4gIGN1c3RvbUNvbnRleHRQYWQ6IFsgJ3R5cGUnLCBDdXN0b21Db250ZXh0UGFkIF0sXHJcbiAgY3VzdG9tUGFsZXR0ZTogWyAndHlwZScsIEN1c3RvbVBhbGV0dGUgXVxyXG59OyIsImltcG9ydCB0cmFuc2xhdGlvbnMgZnJvbSAnLi90cmFuc2xhdGlvbnNHZXJtYW4nO1xyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjdXN0b21UcmFuc2xhdGUodGVtcGxhdGUsIHJlcGxhY2VtZW50cykge1xyXG4gIHJlcGxhY2VtZW50cyA9IHJlcGxhY2VtZW50cyB8fCB7fTtcclxuICB0ZW1wbGF0ZSA9IHRyYW5zbGF0aW9uc1t0ZW1wbGF0ZV0gfHwgdGVtcGxhdGU7XHJcbiAgcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoL3soW159XSspfS9nLCBmdW5jdGlvbihfLCBrZXkpIHtcclxuXHQgdmFyIHN0ciA9IHJlcGxhY2VtZW50c1trZXldO1xyXG5cdCAgaWYodHJhbnNsYXRpb25zW3JlcGxhY2VtZW50c1trZXldXSAhPSBudWxsICYmIHRyYW5zbGF0aW9ucyBbcmVwbGFjZW1lbnRzW2tleV1dICE9ICd1bmRlZmluZWQnKXtcclxuXHRcdCAgc3RyID0gdHJhbnNsYXRpb25zW3JlcGxhY2VtZW50c1trZXldXTtcclxuXHQgIH1cclxuICAgIHJldHVybiAgc3RyIHx8ICd7JyArIGtleSArICd9JztcclxuICB9KTtcclxufSIsImV4cG9ydCBkZWZhdWx0IHtcclxuICAgIC8vIExhYmVsc1xyXG4gICAgJ0FjdGl2YXRlIHRoZSBnbG9iYWwgY29ubmVjdCB0b29sJyA6ICfmv4DmtLvlhajlsYDov57mjqXlt6XlhbcnLFxyXG4gICAgJ0FwcGVuZCB7dHlwZX0nOiAn6L+95YqgIHt0eXBlfScsXHJcbiAgICAnQXBwZW5kIEVuZEV2ZW50JzogJ+i/veWKoCDnu5PmnZ/kuovku7YgJyxcclxuICAgICdBcHBlbmQgVGFzayc6J+i/veWKoCDku7vliqEnLFxyXG4gICAgJ0FwcGVuZCBHYXRld2F5Jzon6L+95YqgIOe9keWFsycsXHJcbiAgICAnQXBwZW5kIEludGVybWVkaWF0ZS9Cb3VuZGFyeSBFdmVudCc6J+i/veWKoCDkuK3pl7Qv6L6555WMIOS6i+S7ticsXHJcbiAgICAnQWRkIExhbmUgYWJvdmUnOiAn5Zyo5LiK6Z2i5re75Yqg6YGTJyxcclxuICAgICdEaXZpZGUgaW50byB0d28gTGFuZXMnOiAn5YiG5Ymy5oiQ5Lik5Liq6YGTJyxcclxuICAgICdEaXZpZGUgaW50byB0aHJlZSBMYW5lcyc6ICfliIblibLmiJDkuInkuKrpgZMnLFxyXG4gICAgJ0FkZCBMYW5lIGJlbG93JzogJ+WcqOS4i+mdoua3u+WKoOmBkycsXHJcbiAgICAnQXBwZW5kIGNvbXBlbnNhdGlvbiBhY3Rpdml0eSc6ICfov73liqDooaXlgb/mtLvliqgnLFxyXG4gICAgJ0NoYW5nZSB0eXBlJzogJ+S/ruaUueexu+WeiycsXHJcbiAgICAnQ29ubmVjdCB1c2luZyBBc3NvY2lhdGlvbic6ICfkvb/nlKjlhbPogZTov57mjqUnLFxyXG4gICAgJ0Nvbm5lY3QgdXNpbmcgU2VxdWVuY2UvTWVzc2FnZUZsb3cgb3IgQXNzb2NpYXRpb24nOiAn5L2/55So6aG65bqPL+a2iOaBr+a1geaIluiAheWFs+iBlOi/nuaOpScsXHJcbiAgICAnQ29ubmVjdCB1c2luZyBEYXRhSW5wdXRBc3NvY2lhdGlvbic6ICfkvb/nlKjmlbDmja7ovpPlhaXlhbPogZTov57mjqUnLFxyXG4gICAgJ1JlbW92ZSc6ICfnp7vpmaQnLFxyXG4gICAgJ0FjdGl2YXRlIHRoZSBoYW5kIHRvb2wnOiAn5r+A5rS75oqT5omL5bel5YW3JyxcclxuICAgICdBY3RpdmF0ZSB0aGUgbGFzc28gdG9vbCc6ICfmv4DmtLvlpZfntKLlt6XlhbcnLFxyXG4gICAgJ0FjdGl2YXRlIHRoZSBjcmVhdGUvcmVtb3ZlIHNwYWNlIHRvb2wnOiAn5r+A5rS75Yib5bu6L+WIoOmZpOepuumXtOW3peWFtycsXHJcbiAgICAnQ3JlYXRlIGV4cGFuZGVkIFN1YlByb2Nlc3MnOiAn5Yib5bu65omp5bGV5a2Q6L+H56iLJyxcclxuICAgICdDcmVhdGUgSW50ZXJtZWRpYXRlVGhyb3dFdmVudC9Cb3VuZGFyeUV2ZW50JyA6ICfliJvlu7rkuK3pl7Tmipvlh7rkuovku7Yv6L6555WM5LqL5Lu2JyxcclxuICAgICdDcmVhdGUgUG9vbC9QYXJ0aWNpcGFudCc6ICfliJvlu7rmsaAv5Y+C5LiO6ICFJyxcclxuICAgICdQYXJhbGxlbCBNdWx0aSBJbnN0YW5jZSc6ICflubbooYzlpJrph43kuovku7YnLFxyXG4gICAgJ1NlcXVlbnRpYWwgTXVsdGkgSW5zdGFuY2UnOiAn5pe25bqP5aSa6YeN5LqL5Lu2JyxcclxuICAgICdEYXRhT2JqZWN0UmVmZXJlbmNlJzon5pWw5o2u5a+56LGh5Y+C6ICDJyxcclxuICAgICdEYXRhU3RvcmVSZWZlcmVuY2UnOifmlbDmja7lrZjlgqjlj4LogIMnLFxyXG4gICAgJ0xvb3AnOiAn5b6q546vJyxcclxuICAgICdBZC1ob2MnOiAn5Y2z5bitJyxcclxuICAgICdDcmVhdGUge3R5cGV9JzogJ+WIm+W7uiB7dHlwZX0nLFxyXG4gICAgJ0NyZWF0ZSBUYXNrJzon5Yib5bu65Lu75YqhJyxcclxuICAgICdDcmVhdGUgU3RhcnRFdmVudCc6J+WIm+W7uuW8gOWni+S6i+S7ticsXHJcbiAgICAnQ3JlYXRlIEVuZEV2ZW50Jzon5Yib5bu657uT5p2f5LqL5Lu2JyxcclxuICAgICdDcmVhdGUgR3JvdXAnOifliJvlu7rnu4QnLFxyXG4gICAgJ1Rhc2snOiAn5Lu75YqhJyxcclxuICAgICdTZW5kIFRhc2snOiAn5Y+R6YCB5Lu75YqhJyxcclxuICAgICdSZWNlaXZlIFRhc2snOiAn5o6l5pS25Lu75YqhJyxcclxuICAgICdVc2VyIFRhc2snOiAn55So5oi35Lu75YqhJyxcclxuICAgICdNYW51YWwgVGFzayc6ICfmiYvlt6Xku7vliqEnLFxyXG4gICAgJ0J1c2luZXNzIFJ1bGUgVGFzayc6ICfkuJrliqHop4TliJnku7vliqEnLFxyXG4gICAgJ1NlcnZpY2UgVGFzayc6ICfmnI3liqHku7vliqEnLFxyXG4gICAgJ1NjcmlwdCBUYXNrJzogJ+iEmuacrOS7u+WKoScsXHJcbiAgICAnQ2FsbCBBY3Rpdml0eSc6ICfosIPnlKjmtLvliqgnLFxyXG4gICAgJ1N1YiBQcm9jZXNzIChjb2xsYXBzZWQpJzogJ+WtkOa1geeoi++8iOaKmOWPoOeahO+8iScsXHJcbiAgICAnU3ViIFByb2Nlc3MgKGV4cGFuZGVkKSc6ICflrZDmtYHnqIvvvIjlsZXlvIDnmoTvvIknLFxyXG4gICAgJ1N0YXJ0IEV2ZW50JzogJ+W8gOWni+S6i+S7ticsXHJcbiAgICAnU3RhcnRFdmVudCc6ICflvIDlp4vkuovku7YnLFxyXG4gICAgJ0ludGVybWVkaWF0ZSBUaHJvdyBFdmVudCc6ICfkuK3pl7Tkuovku7YnLFxyXG4gICAgJ0VuZCBFdmVudCc6ICfnu5PmnZ/kuovku7YnLFxyXG4gICAgJ0VuZEV2ZW50JzogJ+e7k+adn+S6i+S7ticsXHJcbiAgICAnQ3JlYXRlIEdhdGV3YXknOiAn5Yib5bu6572R5YWzJyxcclxuICAgICdHYXRlV2F5Jzon572R5YWzJyxcclxuICAgICdDcmVhdGUgSW50ZXJtZWRpYXRlL0JvdW5kYXJ5IEV2ZW50JzogJ+WIm+W7uuS4remXtC/ovrnnlYzkuovku7YnLFxyXG4gICAgJ01lc3NhZ2UgU3RhcnQgRXZlbnQnOiAn5raI5oGv5byA5aeL5LqL5Lu2JyxcclxuICAgICdUaW1lciBTdGFydCBFdmVudCc6ICflrprml7blvIDlp4vkuovku7YnLFxyXG4gICAgJ0NvbmRpdGlvbmFsIFN0YXJ0IEV2ZW50JzogJ+adoeS7tuW8gOWni+S6i+S7ticsXHJcbiAgICAnU2lnbmFsIFN0YXJ0IEV2ZW50JzogJ+S/oeWPt+W8gOWni+S6i+S7ticsXHJcbiAgICAnRXJyb3IgU3RhcnQgRXZlbnQnOiAn6ZSZ6K+v5byA5aeL5LqL5Lu2JyxcclxuICAgICdFc2NhbGF0aW9uIFN0YXJ0IEV2ZW50JzogJ+WNh+e6p+W8gOWni+S6i+S7ticsXHJcbiAgICAnQ29tcGVuc2F0aW9uIFN0YXJ0IEV2ZW50JzogJ+ihpeWBv+W8gOWni+S6i+S7ticsXHJcbiAgICAnTWVzc2FnZSBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5raI5oGv5byA5aeL5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdUaW1lciBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5a6a5pe25byA5aeL5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdDb25kaXRpb25hbCBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5p2h5Lu25byA5aeL5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdTaWduYWwgU3RhcnQgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJzogJ+S/oeWPt+W8gOWni+S6i+S7tu+8iOmdnuS4reaWre+8iScsXHJcbiAgICAnRXNjYWxhdGlvbiBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5Y2H57qn5byA5aeL5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdNZXNzYWdlIEludGVybWVkaWF0ZSBDYXRjaCBFdmVudCc6ICfmtojmga/kuK3pl7TmjZXojrfkuovku7YnLFxyXG4gICAgJ01lc3NhZ2UgSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JzogJ+a2iOaBr+S4remXtOaKm+WHuuS6i+S7ticsXHJcbiAgICAnVGltZXIgSW50ZXJtZWRpYXRlIENhdGNoIEV2ZW50JzogJ+WumuaXtuS4remXtOaNleiOt+S6i+S7ticsXHJcbiAgICAnRXNjYWxhdGlvbiBJbnRlcm1lZGlhdGUgVGhyb3cgRXZlbnQnOiAn5Y2H57qn5Lit6Ze05oqb5Ye65LqL5Lu2JyxcclxuICAgICdDb25kaXRpb25hbCBJbnRlcm1lZGlhdGUgQ2F0Y2ggRXZlbnQnOiAn5p2h5Lu25Lit6Ze05o2V6I635LqL5Lu2JyxcclxuICAgICdMaW5rIEludGVybWVkaWF0ZSBDYXRjaCBFdmVudCc6ICfpk77mjqXkuK3pl7TmjZXojrfkuovku7YnLFxyXG4gICAgJ0xpbmsgSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JzogJ+mTvuaOpeS4remXtOaKm+WHuuS6i+S7ticsXHJcbiAgICAnQ29tcGVuc2F0aW9uIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCc6ICfooaXlgb/kuK3pl7Tmipvlh7rkuovku7YnLFxyXG4gICAgJ1NpZ25hbCBJbnRlcm1lZGlhdGUgQ2F0Y2ggRXZlbnQnOiAn5L+h5Y+35Lit6Ze05o2V6I635LqL5Lu2JyxcclxuICAgICdTaWduYWwgSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JzogJ+S/oeWPt+S4remXtOaKm+WHuuS6i+S7ticsXHJcbiAgICAnTWVzc2FnZSBFbmQgRXZlbnQnOiAn5raI5oGv57uT5p2f5LqL5Lu2JyxcclxuICAgICdFc2NhbGF0aW9uIEVuZCBFdmVudCc6ICflrprml7bnu5PmnZ/kuovku7YnLFxyXG4gICAgJ0Vycm9yIEVuZCBFdmVudCc6ICfplJnor6/nu5PmnZ/kuovku7YnLFxyXG4gICAgJ0NhbmNlbCBFbmQgRXZlbnQnOiAn5Y+W5raI57uT5p2f5LqL5Lu2JyxcclxuICAgICdDb21wZW5zYXRpb24gRW5kIEV2ZW50JzogJ+ihpeWBv+e7k+adn+S6i+S7ticsXHJcbiAgICAnU2lnbmFsIEVuZCBFdmVudCc6ICfkv6Hlj7fnu5PmnZ/kuovku7YnLFxyXG4gICAgJ1Rlcm1pbmF0ZSBFbmQgRXZlbnQnOiAn57uI5q2i57uT5p2f5LqL5Lu2JyxcclxuICAgICdNZXNzYWdlIEJvdW5kYXJ5IEV2ZW50JzogJ+a2iOaBr+i+ueeVjOS6i+S7ticsXHJcbiAgICAnTWVzc2FnZSBCb3VuZGFyeSBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5raI5oGv6L6555WM5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdUaW1lciBCb3VuZGFyeSBFdmVudCc6ICflrprml7bovrnnlYzkuovku7YnLFxyXG4gICAgJ1RpbWVyIEJvdW5kYXJ5IEV2ZW50IChub24taW50ZXJydXB0aW5nKSc6ICflrprml7bovrnnlYzkuovku7bvvIjpnZ7kuK3mlq3vvIknLFxyXG4gICAgJ0VzY2FsYXRpb24gQm91bmRhcnkgRXZlbnQnOiAn5Y2H57qn6L6555WM5LqL5Lu2JyxcclxuICAgICdFc2NhbGF0aW9uIEJvdW5kYXJ5IEV2ZW50IChub24taW50ZXJydXB0aW5nKSc6ICfljYfnuqfovrnnlYzkuovku7bvvIjpnZ7kuK3mlq3vvIknLFxyXG4gICAgJ0NvbmRpdGlvbmFsIEJvdW5kYXJ5IEV2ZW50JzogJ+adoeS7tui+ueeVjOS6i+S7ticsXHJcbiAgICAnQ29uZGl0aW9uYWwgQm91bmRhcnkgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJzogJ+adoeS7tui+ueeVjOS6i+S7tu+8iOmdnuS4reaWre+8iScsXHJcbiAgICAnRXJyb3IgQm91bmRhcnkgRXZlbnQnOiAn6ZSZ6K+v6L6555WM5LqL5Lu2JyxcclxuICAgICdDYW5jZWwgQm91bmRhcnkgRXZlbnQnOiAn5Y+W5raI6L6555WM5LqL5Lu2JyxcclxuICAgICdTaWduYWwgQm91bmRhcnkgRXZlbnQnOiAn5L+h5Y+36L6555WM5LqL5Lu2JyxcclxuICAgICdTaWduYWwgQm91bmRhcnkgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJzogJ+S/oeWPt+i+ueeVjOS6i+S7tu+8iOmdnuS4reaWre+8iScsXHJcbiAgICAnQ29tcGVuc2F0aW9uIEJvdW5kYXJ5IEV2ZW50JzogJ+ihpeWBv+i+ueeVjOS6i+S7ticsXHJcbiAgICAnRXhjbHVzaXZlIEdhdGV3YXknOiAn5LqS5pal572R5YWzJyxcclxuICAgICdQYXJhbGxlbCBHYXRld2F5JzogJ+W5tuihjOe9keWFsycsXHJcbiAgICAnSW5jbHVzaXZlIEdhdGV3YXknOiAn55u45a65572R5YWzJyxcclxuICAgICdDb21wbGV4IEdhdGV3YXknOiAn5aSN5p2C572R5YWzJyxcclxuICAgICdFdmVudCBiYXNlZCBHYXRld2F5JzogJ+S6i+S7tue9keWFsycsXHJcbiAgICAnVHJhbnNhY3Rpb24nOiAn6L2s6L+QJyxcclxuICAgICdTdWIgUHJvY2Vzcyc6ICflrZDmtYHnqIsnLFxyXG4gICAgJ0V2ZW50IFN1YiBQcm9jZXNzJzogJ+S6i+S7tuWtkOa1geeoiycsXHJcbiAgICAnQ29sbGFwc2VkIFBvb2wnOiAn5oqY5Y+g5rGgJyxcclxuICAgICdFeHBhbmRlZCBQb29sJzogJ+WxleW8gOaxoCcsXHJcbiAgICAvLyBFcnJvcnNcclxuICAgICdubyBwYXJlbnQgZm9yIHtlbGVtZW50fSBpbiB7cGFyZW50fSc6ICflnKh7cGFyZW50femHjO+8jHtlbGVtZW50feayoeacieeItuexuycsXHJcbiAgICAnbm8gc2hhcGUgdHlwZSBzcGVjaWZpZWQnOiAn5rKh5pyJ5oyH5a6a55qE5b2i54q257G75Z6LJyxcclxuICAgICdmbG93IGVsZW1lbnRzIG11c3QgYmUgY2hpbGRyZW4gb2YgcG9vbHMvcGFydGljaXBhbnRzJzogJ+a1geWFg+e0oOW/hemhu+aYr+axoC/lj4LkuI7ogIXnmoTlrZDnsbsnLFxyXG4gICAgJ291dCBvZiBib3VuZHMgcmVsZWFzZSc6ICdvdXQgb2YgYm91bmRzIHJlbGVhc2UnLFxyXG4gICAgJ21vcmUgdGhhbiB7Y291bnR9IGNoaWxkIGxhbmVzJzogJ+WtkOmBk+Wkp+S6jntjb3VudH0gJyxcclxuICAgICdlbGVtZW50IHJlcXVpcmVkJzogJ+WFg+e0oOS4jeiDveS4uuepuicsXHJcbiAgICAnZGlhZ3JhbSBub3QgcGFydCBvZiBicG1uOkRlZmluaXRpb25zJzogJ+a1geeoi+WbvuS4jeespuWQiGJwbW7op4TojIMnLFxyXG4gICAgJ25vIGRpYWdyYW0gdG8gZGlzcGxheSc6ICfmsqHmnInlj6/lsZXnpLrnmoTmtYHnqIvlm74nLFxyXG4gICAgJ25vIHByb2Nlc3Mgb3IgY29sbGFib3JhdGlvbiB0byBkaXNwbGF5JzogJ+ayoeacieWPr+WxleekuueahOa1geeoiy/ljY/kvZwnLFxyXG4gICAgJ2VsZW1lbnQge2VsZW1lbnR9IHJlZmVyZW5jZWQgYnkge3JlZmVyZW5jZWR9I3twcm9wZXJ0eX0gbm90IHlldCBkcmF3bic6ICfnlLF7cmVmZXJlbmNlZH0je3Byb3BlcnR5feW8leeUqOeahHtlbGVtZW50feWFg+e0oOS7jeacque7mOWIticsXHJcbiAgICAnYWxyZWFkeSByZW5kZXJlZCB7ZWxlbWVudH0nOiAne2VsZW1lbnR9IOW3suiiq+a4suafkycsXHJcbiAgICAnZmFpbGVkIHRvIGltcG9ydCB7ZWxlbWVudH0nOiAn5a+85YWle2VsZW1lbnR95aSx6LSlJyxcclxuICAgIC8v5bGe5oCn6Z2i5p2/55qE5Y+C5pWwXHJcbiAgICAnSWQnOifnvJblj7cnLFxyXG4gICAgJ05hbWUnOiflkI3np7AnLFxyXG4gICAgJ0dlbmVyYWwnOifluLjop4QnLFxyXG4gICAgJ0RldGFpbHMnOifor6bmg4UnLFxyXG4gICAgJ01lc3NhZ2UgTmFtZSc6J+a2iOaBr+WQjeensCcsXHJcbiAgICAnTWVzc2FnZSc6J+a2iOaBrycsXHJcbiAgICAnSW5pdGlhdG9yJzon5Yib5bu66ICFJyxcclxuICAgICdBc3luY2hyb25vdXMgQ29udGludWF0aW9ucyc6J+aMgee7reW8guatpScsXHJcbiAgICAnQXN5bmNocm9ub3VzIEJlZm9yZSc6J+W8guatpeWJjScsXHJcbiAgICAnQXN5bmNocm9ub3VzIEFmdGVyJzon5byC5q2l5ZCOJyxcclxuICAgICdKb2IgQ29uZmlndXJhdGlvbic6J+W3peS9nOmFjee9ricsXHJcbiAgICAnRXhjbHVzaXZlJzon5o6S6ZmkJyxcclxuICAgICdKb2IgUHJpb3JpdHknOiflt6XkvZzkvJjlhYjnuqcnLFxyXG4gICAgJ1JldHJ5IFRpbWUgQ3ljbGUnOifph43or5Xml7bpl7TlkajmnJ8nLFxyXG4gICAgJ0RvY3VtZW50YXRpb24nOifmlofmoaMnLFxyXG4gICAgJ0VsZW1lbnQgRG9jdW1lbnRhdGlvbic6J+WFg+e0oOaWh+ahoycsXHJcbiAgICAnSGlzdG9yeSBDb25maWd1cmF0aW9uJzon5Y6G5Y+y6YWN572uJyxcclxuICAgICdIaXN0b3J5IFRpbWUgVG8gTGl2ZSc6J+WOhuWPsueahOeUn+WtmOaXtumXtCcsXHJcbiAgICAnRm9ybXMnOifooajljZUnLFxyXG4gICAgJ0Zvcm0gS2V5Jzon6KGo5Y2Va2V5JyxcclxuICAgICdGb3JtIEZpZWxkcyc6J+ihqOWNleWtl+autScsXHJcbiAgICAnQnVzaW5lc3MgS2V5Jzon5Lia5Yqha2V5JyxcclxuICAgICdGb3JtIEZpZWxkJzon6KGo5Y2V5a2X5q61JyxcclxuICAgICdJRCc6J+e8luWPtycsXHJcbiAgICAnVHlwZSc6J+exu+WeiycsXHJcbiAgICAnTGFiZWwnOiflkI3np7AnLFxyXG4gICAgJ0RlZmF1bHQgVmFsdWUnOifpu5jorqTlgLwnLFxyXG4gICAgJ1ZhbGlkYXRpb24nOifmoKHpqownLFxyXG4gICAgJ0FkZCBDb25zdHJhaW50Jzon5re75Yqg57qm5p2fJyxcclxuICAgICdDb25maWcnOifphY3nva4nLFxyXG4gICAgJ1Byb3BlcnRpZXMnOiflsZ7mgKcnLFxyXG4gICAgJ0FkZCBQcm9wZXJ0eSc6J+a3u+WKoOWxnuaApycsXHJcbiAgICAnVmFsdWUnOiflgLwnLFxyXG4gICAgJ0FkZCc6J+a3u+WKoCcsXHJcbiAgICAnVmFsdWVzJzon5YC8JyxcclxuICAgICdBZGQgVmFsdWUnOifmt7vliqDlgLwnLFxyXG4gICAgJ0xpc3RlbmVycyc6J+ebkeWQrOWZqCcsXHJcbiAgICAnRXhlY3V0aW9uIExpc3RlbmVyJzon5omn6KGM55uR5ZCsJyxcclxuICAgICdFdmVudCBUeXBlJzon5LqL5Lu257G75Z6LJyxcclxuICAgICdMaXN0ZW5lciBUeXBlJzon55uR5ZCs5Zmo57G75Z6LJyxcclxuICAgICdKYXZhIENsYXNzJzonSmF2YeexuycsXHJcbiAgICAnRXhwcmVzc2lvbic6J+ihqOi+vuW8jycsXHJcbiAgICAnTXVzdCBwcm92aWRlIGEgdmFsdWUnOiflv4Xpobvmj5DkvpvkuIDkuKrlgLwnLFxyXG4gICAgJ0RlbGVnYXRlIEV4cHJlc3Npb24nOifku6PnkIbooajovr7lvI8nLFxyXG4gICAgJ1NjcmlwdCc6J+iEmuacrCcsXHJcbiAgICAnU2NyaXB0IEZvcm1hdCc6J+iEmuacrOagvOW8jycsXHJcbiAgICAnU2NyaXB0IFR5cGUnOifohJrmnKznsbvlnosnLFxyXG4gICAgJ0lubGluZSBTY3JpcHQnOiflhoXogZTohJrmnKwnLFxyXG4gICAgJ0V4dGVybmFsIFNjcmlwdCc6J+WklumDqOiEmuacrCcsXHJcbiAgICAnUmVzb3VyY2UnOifotYTmupAnLFxyXG4gICAgJ0ZpZWxkIEluamVjdGlvbic6J+Wtl+auteazqOWFpScsXHJcbiAgICAnRXh0ZW5zaW9ucyc6J+aJqeWxlScsXHJcbiAgICAnSW5wdXQvT3V0cHV0Jzon6L6T5YWlL+i+k+WHuicsXHJcbiAgICAnSW5wdXQgUGFyYW1ldGVycyc6J+i+k+WFpeWPguaVsCcsXHJcbiAgICAnT3V0cHV0IFBhcmFtZXRlcnMnOifovpPlh7rlj4LmlbAnLFxyXG4gICAgJ1BhcmFtZXRlcnMnOiflj4LmlbAnLFxyXG4gICAgJ091dHB1dCBQYXJhbWV0ZXInOifovpPlh7rlj4LmlbAnLFxyXG4gICAgJ1RpbWVyIERlZmluaXRpb24gVHlwZSc6J+WumuaXtuWZqOWumuS5ieexu+WeiycsXHJcbiAgICAnVGltZXIgRGVmaW5pdGlvbic6J+WumuaXtuWZqOWumuS5iScsXHJcbiAgICAnRGF0ZSc6J+aXpeacnycsXHJcbiAgICAnRHVyYXRpb24nOifmjIHnu60nLFxyXG4gICAgJ0N5Y2xlJzon5b6q546vJyxcclxuICAgICdTaWduYWwnOifkv6Hlj7cnLFxyXG4gICAgJ1NpZ25hbCBOYW1lJzon5L+h5Y+35ZCN56ewJyxcclxuICAgICdFc2NhbGF0aW9uJzon5Y2H57qnJyxcclxuICAgICdFcnJvcic6J+mUmeivrycsXHJcbiAgICAnTGluayBOYW1lJzon6ZO+5o6l5ZCN56ewJyxcclxuICAgICdDb25kaXRpb24nOifmnaHku7blkI3np7AnLFxyXG4gICAgJ1ZhcmlhYmxlIE5hbWUnOiflj5jph4/lkI3np7AnLFxyXG4gICAgJ1ZhcmlhYmxlIEV2ZW50Jzon5Y+Y6YeP5LqL5Lu2JyxcclxuICAgICdTcGVjaWZ5IG1vcmUgdGhhbiBvbmUgdmFyaWFibGUgY2hhbmdlIGV2ZW50IGFzIGEgY29tbWEgc2VwYXJhdGVkIGxpc3QuJzon5aSa5Liq5Y+Y6YeP5LqL5Lu25Lul6YCX5Y+36ZqU5byAJyxcclxuICAgICdXYWl0IGZvciBDb21wbGV0aW9uJzon562J5b6F5a6M5oiQJyxcclxuICAgICdBY3Rpdml0eSBSZWYnOifmtLvliqjlj4LogIMnLFxyXG4gICAgJ1ZlcnNpb24gVGFnJzon54mI5pys5qCH562+JyxcclxuICAgICdFeGVjdXRhYmxlJzon5Y+v5omn6KGM5paH5Lu2JyxcclxuICAgICdFeHRlcm5hbCBUYXNrIENvbmZpZ3VyYXRpb24nOifmianlsZXku7vliqHphY3nva4nLFxyXG4gICAgJ1Rhc2sgUHJpb3JpdHknOifku7vliqHkvJjlhYjnuqcnLFxyXG4gICAgJ0V4dGVybmFsJzon5aSW6YOoJyxcclxuICAgICdDb25uZWN0b3InOifov57mjqXlmagnLFxyXG4gICAgJ011c3QgY29uZmlndXJlIENvbm5lY3Rvcic6J+W/hemhu+mFjee9rui/nuaOpeWZqCcsXHJcbiAgICAnQ29ubmVjdG9yIElkJzon6L+e5o6l5Zmo57yW5Y+3JyxcclxuICAgICdJbXBsZW1lbnRhdGlvbic6J+WunueOsOaWueW8jycsXHJcbiAgICAnRmllbGQgSW5qZWN0aW9ucyc6J+Wtl+auteazqOWFpScsXHJcbiAgICAnRmllbGRzJzon5a2X5q61JyxcclxuICAgICdSZXN1bHQgVmFyaWFibGUnOifnu5Pmnpzlj5jph48nLFxyXG4gICAgJ1RvcGljJzon5Li76aKYJyxcclxuICAgICdDb25maWd1cmUgQ29ubmVjdG9yJzon6YWN572u6L+e5o6l5ZmoJyxcclxuICAgICdJbnB1dCBQYXJhbWV0ZXInOifovpPlhaXlj4LmlbAnLFxyXG4gICAgJ0Fzc2lnbmVlJzon5Luj55CG5Lq6JyxcclxuICAgICdDYW5kaWRhdGUgVXNlcnMnOiflgJnpgInnlKjmiLcnLFxyXG4gICAgJ0NhbmRpZGF0ZSBHcm91cHMnOiflgJnpgInnu4QnLFxyXG4gICAgJ0R1ZSBEYXRlJzon5Yiw5pyf5pe26Ze0JyxcclxuICAgICdGb2xsb3cgVXAgRGF0ZSc6J+i3n+i4quaXpeacnycsXHJcbiAgICAnUHJpb3JpdHknOifkvJjlhYjnuqcnLFxyXG4gICAgJ1RoZSBmb2xsb3cgdXAgZGF0ZSBhcyBhbiBFTCBleHByZXNzaW9uIChlLmcuICR7c29tZURhdGV9IG9yIGFuIElTTyBkYXRlIChlLmcuIDIwMTUtMDYtMjZUMDk6NTQ6MDApJzon6Lef6Liq5pel5pyf5b+F6aG756ym5ZCIRUzooajovr7lvI/vvIzlpoLvvJogJHtzb21lRGF0ZX0gLOaIluiAheS4gOS4qklTT+agh+WHhuaXpeacn++8jOWmgu+8mjIwMTUtMDYtMjZUMDk6NTQ6MDAnLFxyXG4gICAgJ1RoZSBkdWUgZGF0ZSBhcyBhbiBFTCBleHByZXNzaW9uIChlLmcuICR7c29tZURhdGV9IG9yIGFuIElTTyBkYXRlIChlLmcuIDIwMTUtMDYtMjZUMDk6NTQ6MDApJzon6Lef6Liq5pel5pyf5b+F6aG756ym5ZCIRUzooajovr7lvI/vvIzlpoLvvJogJHtzb21lRGF0ZX0gLOaIluiAheS4gOS4qklTT+agh+WHhuaXpeacn++8jOWmgu+8mjIwMTUtMDYtMjZUMDk6NTQ6MDAnLFxyXG4gICAgJ1ZhcmlhYmxlcyc6J+WPmOmHjycsXHJcbiAgICAnQ2FuZGlkYXRlIFN0YXJ0ZXIgQ29uZmlndXJhdGlvbic6J+WAmemAieW8gOWni+mFjee9ricsXHJcbiAgICAnVGFzayBMaXN0ZW5lcic6J+S7u+WKoeebkeWQrOWZqCcsXHJcbiAgICAnQ2FuZGlkYXRlIFN0YXJ0ZXIgR3JvdXBzJzon5YCZ6YCJ5byA5aeL57uEJyxcclxuICAgICdDYW5kaWRhdGUgU3RhcnRlciBVc2Vycyc6J+WAmemAieW8gOWni+eUqOaItycsXHJcbiAgICAnVGFza2xpc3QgQ29uZmlndXJhdGlvbic6J+S7u+WKoeWIl+ihqOmFjee9ricsXHJcbiAgICAnU3RhcnRhYmxlJzon5ZCv5YqoJyxcclxuICAgICdTcGVjaWZ5IG1vcmUgdGhhbiBvbmUgZ3JvdXAgYXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdC4nOifmjIflrprlpJrkuKrnu4Qs55So6YCX5Y+35YiG6ZqUJyxcclxuICAgICdTcGVjaWZ5IG1vcmUgdGhhbiBvbmUgdXNlciBhcyBhIGNvbW1hIHNlcGFyYXRlZCBsaXN0Lic6J+aMh+WumuWkmuS4queUqOaItyznlKjpgJflj7fliIbpmpQnLFxyXG4gICAgJ1RoaXMgbWFwcyB0byB0aGUgcHJvY2VzcyBkZWZpbml0aW9uIGtleS4nOifov5nkvJrmmKDlsITkuLrmtYHnqIvlrprkuYnnmoTplK4nLFxyXG4gICAgJ0NhbGxBY3Rpdml0eSBUeXBlJzon6LCD55So5rS75Yqo57G75Z6LJyxcclxuICAgICdDb25kaXRpb24gVHlwZSc6J+adoeS7tuexu+WeiycsXHJcbiAgICAnQ3JlYXRlIFVzZXJUYXNrJzon5Yib5bu655So5oi35Lu75YqhJyxcclxuICAgICdDcmVhdGUgQ2FsbEFjdGl2aXR5Jzon5Yib5bu66LCD55So5rS75YqoJyxcclxuICAgICdDYWxsZWQgRWxlbWVudCc6J+iwg+eUqOWFg+e0oCcsXHJcbiAgICAnQ3JlYXRlIERhdGFPYmplY3RSZWZlcmVuY2UnOifliJvlu7rmlbDmja7lr7nosaHlvJXnlKgnLFxyXG4gICAgJ0NyZWF0ZSBEYXRhU3RvcmVSZWZlcmVuY2UnOifliJvlu7rmlbDmja7lrZjlgqjlvJXnlKgnLFxyXG4gICAgJ011bHRpIEluc3RhbmNlJzon5aSa5a6e5L6LJyxcclxuICAgICdMb29wIENhcmRpbmFsaXR5Jzon5a6e5L6L5pWw6YePJyxcclxuICAgICdDb2xsZWN0aW9uJzon5Lu75Yqh5Y+C5LiO5Lq65YiX6KGoJyxcclxuICAgICdFbGVtZW50IFZhcmlhYmxlJzon5YWD57Sg5Y+Y6YePJyxcclxuICAgICdDb21wbGV0aW9uIENvbmRpdGlvbic6J+WujOaIkOadoeS7tidcclxufTtcclxuIiwibW9kdWxlLmV4cG9ydHMgPSBcIjw/eG1sIHZlcnNpb249XFxcIjEuMFxcXCIgZW5jb2Rpbmc9XFxcIlVURi04XFxcIj8+XFxyXFxuPGJwbW4yOmRlZmluaXRpb25zIHhtbG5zOnhzaT1cXFwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2VcXFwiIHhtbG5zOmJwbW4yPVxcXCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9CUE1OLzIwMTAwNTI0L01PREVMXFxcIiB4bWxuczpicG1uZGk9XFxcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0JQTU4vMjAxMDA1MjQvRElcXFwiIHhtbG5zOmRjPVxcXCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9ERC8yMDEwMDUyNC9EQ1xcXCIgeG1sbnM6ZGk9XFxcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0RELzIwMTAwNTI0L0RJXFxcIiB4c2k6c2NoZW1hTG9jYXRpb249XFxcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0JQTU4vMjAxMDA1MjQvTU9ERUwgQlBNTjIwLnhzZFxcXCIgaWQ9XFxcInNhbXBsZS1kaWFncmFtXFxcIiB0YXJnZXROYW1lc3BhY2U9XFxcImh0dHA6Ly9hY3Rpdml0aS5vcmcvYnBtblxcXCI+XFxyXFxuICA8YnBtbjI6cHJvY2VzcyBpZD1cXFwiUHJvY2Vzc18xXFxcIiBpc0V4ZWN1dGFibGU9XFxcInRydWVcXFwiPlxcclxcbiAgICA8YnBtbjI6c3RhcnRFdmVudCBpZD1cXFwiU3RhcnRFdmVudF8xXFxcIi8+XFxyXFxuICA8L2JwbW4yOnByb2Nlc3M+XFxyXFxuICA8YnBtbmRpOkJQTU5EaWFncmFtIGlkPVxcXCJCUE1ORGlhZ3JhbV8xXFxcIj5cXHJcXG4gICAgPGJwbW5kaTpCUE1OUGxhbmUgaWQ9XFxcIkJQTU5QbGFuZV8xXFxcIiBicG1uRWxlbWVudD1cXFwiUHJvY2Vzc18xXFxcIj5cXHJcXG4gICAgICA8YnBtbmRpOkJQTU5TaGFwZSBpZD1cXFwiX0JQTU5TaGFwZV9TdGFydEV2ZW50XzJcXFwiIGJwbW5FbGVtZW50PVxcXCJTdGFydEV2ZW50XzFcXFwiPlxcclxcbiAgICAgICAgPGRjOkJvdW5kcyBoZWlnaHQ9XFxcIjM2LjBcXFwiIHdpZHRoPVxcXCIzNi4wXFxcIiB4PVxcXCI0MTIuMFxcXCIgeT1cXFwiMjQwLjBcXFwiLz5cXHJcXG4gICAgICA8L2JwbW5kaTpCUE1OU2hhcGU+XFxyXFxuICAgIDwvYnBtbmRpOkJQTU5QbGFuZT5cXHJcXG4gIDwvYnBtbmRpOkJQTU5EaWFncmFtPlxcclxcbjwvYnBtbjI6ZGVmaW5pdGlvbnM+XCI7XG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgREVGQVVMVF9QUklPUklUWSA9IDEwMDA7XHJcblxyXG5cclxuLyoqXHJcbiAqIEEgY29tcG9uZW50IHRoYXQgZGVjaWRlcyB1cG9uIHRoZSB2aXNpYmlsaXR5IC8gZWRpdGFibGVcclxuICogc3RhdGUgb2YgcHJvcGVydGllcyBpbiB0aGUgcHJvcGVydGllcyBwYW5lbC5cclxuICpcclxuICogSW1wbGVtZW50b3JzIG11c3Qgc3ViY2xhc3MgdGhpcyBjb21wb25lbnQgYW5kIG92ZXJyaWRlXHJcbiAqIHtAbGluayBQcm9wZXJ0aWVzQWN0aXZhdG9yI2lzRW50cnlWaXNpYmxlfSBhbmRcclxuICoge0BsaW5rIFByb3BlcnRpZXNBY3RpdmF0b3IjaXNQcm9wZXJ0eUVkaXRhYmxlfSB0byBwcm92aWRlXHJcbiAqIGN1c3RvbSBiZWhhdmlvci5cclxuICpcclxuICogQGNsYXNzXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKlxyXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xyXG4gKiBAcGFyYW0ge051bWJlcn0gW3ByaW9yaXR5XSBhdCB3aGljaCBwcmlvcml0eSB0byBob29rIGludG8gdGhlIGFjdGl2YXRpb25cclxuICovXHJcbmZ1bmN0aW9uIFByb3BlcnRpZXNBY3RpdmF0b3IoZXZlbnRCdXMsIHByaW9yaXR5KSB7XHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICBwcmlvcml0eSA9IHByaW9yaXR5IHx8IERFRkFVTFRfUFJJT1JJVFk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdwcm9wZXJ0aWVzUGFuZWwuaXNFbnRyeVZpc2libGUnLCBwcmlvcml0eSwgZnVuY3Rpb24oZSkge1xyXG4gICAgcmV0dXJuIHNlbGYuaXNFbnRyeVZpc2libGUoZS5lbnRyeSwgZS5lbGVtZW50KTtcclxuICB9KTtcclxuXHJcbiAgZXZlbnRCdXMub24oJ3Byb3BlcnRpZXNQYW5lbC5pc1Byb3BlcnR5RWRpdGFibGUnLCBwcmlvcml0eSwgZnVuY3Rpb24oZSkge1xyXG4gICAgcmV0dXJuIHNlbGYuaXNQcm9wZXJ0eUVkaXRhYmxlKGUuZW50cnksIGUucHJvcGVydHlOYW1lLCBlLmVsZW1lbnQpO1xyXG4gIH0pO1xyXG59XHJcblxyXG5Qcm9wZXJ0aWVzQWN0aXZhdG9yLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gUHJvcGVydGllc0FjdGl2YXRvcjtcclxuXHJcblxyXG4vKipcclxuICogU2hvdWxkIHRoZSBnaXZlbiBlbnRyeSBiZSB2aXNpYmxlIGZvciB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuXHJcbiAqXHJcbiAqIEBtZXRob2QgIFByb3BlcnRpZXNBY3RpdmF0b3IjaXNFbnRyeVZpc2libGVcclxuICpcclxuICogQHBhcmFtIHtFbnRyeURlc2NyaXB0b3J9IGVudHJ5XHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICovXHJcblByb3BlcnRpZXNBY3RpdmF0b3IucHJvdG90eXBlLmlzRW50cnlWaXNpYmxlID0gZnVuY3Rpb24oZW50cnksIGVsZW1lbnQpIHtcclxuICByZXR1cm4gdHJ1ZTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBTaG91bGQgdGhlIGdpdmVuIHByb3BlcnR5IGJlIGVkaXRhYmxlIGZvciB0aGUgc3BlY2lmaWVkIGVsZW1lbnRcclxuICpcclxuICogQG1ldGhvZCAgUHJvcGVydGllc0FjdGl2YXRvciNpc1Byb3BlcnR5RWRpdGFibGVcclxuICpcclxuICogQHBhcmFtIHtFbnRyeURlc2NyaXB0b3J9IGVudHJ5XHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eU5hbWVcclxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gKi9cclxuUHJvcGVydGllc0FjdGl2YXRvci5wcm90b3R5cGUuaXNQcm9wZXJ0eUVkaXRhYmxlID0gZnVuY3Rpb24oZW50cnksIHByb3BlcnR5TmFtZSwgZWxlbWVudCkge1xyXG4gIHJldHVybiB0cnVlO1xyXG59OyIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBkb21RdWVyeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeSxcclxuICAgIGRvbUNsZWFyID0gcmVxdWlyZSgnbWluLWRvbScpLmNsZWFyLFxyXG4gICAgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyksXHJcbiAgICBkb21pZnkgPSByZXF1aXJlKCdtaW4tZG9tJykuZG9taWZ5LFxyXG4gICAgSWRzID0gcmVxdWlyZSgnaWRzJykuZGVmYXVsdDtcclxuXHJcbnZhciBTUEFDRV9SRUdFWCA9IC9cXHMvO1xyXG5cclxuLy8gZm9yIFFOYW1lIHZhbGlkYXRpb24gYXMgcGVyIGh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwvI05ULU5hbWVDaGFyXHJcbnZhciBRTkFNRV9SRUdFWCA9IC9eKFthLXpdW1xcdy0uXSo6KT9bYS16X11bXFx3LS5dKiQvaTtcclxuXHJcbi8vIGZvciBJRCB2YWxpZGF0aW9uIGFzIHBlciBCUE1OIFNjaGVtYSAoUU5hbWUgLSBOYW1lc3BhY2UpXHJcbnZhciBJRF9SRUdFWCA9IC9eW2Etel9dW1xcdy0uXSokL2k7XHJcblxyXG52YXIgUExBQ0VIT0xERVJfUkVHRVggPSAvXFwkXFx7KFtefV0qKVxcfS9nO1xyXG5cclxudmFyIEhUTUxfRVNDQVBFX01BUCA9IHtcclxuICAnJic6ICcmYW1wOycsXHJcbiAgJzwnOiAnJmx0OycsXHJcbiAgJz4nOiAnJmd0OycsXHJcbiAgJ1wiJzogJyZxdW90OycsXHJcbiAgJ1xcJyc6ICcmIzM5OydcclxufTtcclxuXHJcbmZ1bmN0aW9uIHNlbGVjdGVkT3B0aW9uKHNlbGVjdEJveCkge1xyXG4gIGlmIChzZWxlY3RCb3guc2VsZWN0ZWRJbmRleCA+PSAwKSB7XHJcbiAgICByZXR1cm4gc2VsZWN0Qm94Lm9wdGlvbnNbc2VsZWN0Qm94LnNlbGVjdGVkSW5kZXhdLnZhbHVlO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuc2VsZWN0ZWRPcHRpb24gPSBzZWxlY3RlZE9wdGlvbjtcclxuXHJcblxyXG5mdW5jdGlvbiBzZWxlY3RlZFR5cGUoZWxlbWVudFN5bnRheCwgaW5wdXROb2RlKSB7XHJcbiAgdmFyIHR5cGVTZWxlY3QgPSBkb21RdWVyeShlbGVtZW50U3ludGF4LCBpbnB1dE5vZGUpO1xyXG4gIHJldHVybiBzZWxlY3RlZE9wdGlvbih0eXBlU2VsZWN0KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuc2VsZWN0ZWRUeXBlID0gc2VsZWN0ZWRUeXBlO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBSZXRyaWV2ZSB0aGUgcm9vdCBlbGVtZW50IHRoZSBkb2N1bWVudCB0aGlzXHJcbiAqIGJ1c2luZXNzIG9iamVjdCBpcyBjb250YWluZWQgaW4uXHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRSb290KGJ1c2luZXNzT2JqZWN0KSB7XHJcbiAgdmFyIHBhcmVudCA9IGJ1c2luZXNzT2JqZWN0O1xyXG4gIHdoaWxlIChwYXJlbnQuJHBhcmVudCkge1xyXG4gICAgcGFyZW50ID0gcGFyZW50LiRwYXJlbnQ7XHJcbiAgfVxyXG4gIHJldHVybiBwYXJlbnQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmdldFJvb3QgPSBnZXRSb290O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBmaWx0ZXJzIGFsbCBlbGVtZW50cyBpbiB0aGUgbGlzdCB3aGljaCBoYXZlIGEgZ2l2ZW4gdHlwZS5cclxuICogcmVtb3ZlcyBhIG5ldyBsaXN0XHJcbiAqL1xyXG5mdW5jdGlvbiBmaWx0ZXJFbGVtZW50c0J5VHlwZShvYmplY3RMaXN0LCB0eXBlKSB7XHJcbiAgdmFyIGxpc3QgPSBvYmplY3RMaXN0IHx8IFtdO1xyXG4gIHZhciByZXN1bHQgPSBbXTtcclxuICBmb3JFYWNoKGxpc3QsIGZ1bmN0aW9uKG9iaikge1xyXG4gICAgaWYgKGlzKG9iaiwgdHlwZSkpIHtcclxuICAgICAgcmVzdWx0LnB1c2gob2JqKTtcclxuICAgIH1cclxuICB9KTtcclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5maWx0ZXJFbGVtZW50c0J5VHlwZSA9IGZpbHRlckVsZW1lbnRzQnlUeXBlO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGZpbmRSb290RWxlbWVudHNCeVR5cGUoYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRUeXBlKSB7XHJcbiAgdmFyIHJvb3QgPSBnZXRSb290KGJ1c2luZXNzT2JqZWN0KTtcclxuXHJcbiAgcmV0dXJuIGZpbHRlckVsZW1lbnRzQnlUeXBlKHJvb3Qucm9vdEVsZW1lbnRzLCByZWZlcmVuY2VkVHlwZSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmZpbmRSb290RWxlbWVudHNCeVR5cGUgPSBmaW5kUm9vdEVsZW1lbnRzQnlUeXBlO1xyXG5cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZUFsbENoaWxkcmVuKGRvbUVsZW1lbnQpIHtcclxuICB3aGlsZSAoZG9tRWxlbWVudC5maXJzdENoaWxkKSB7XHJcbiAgICBkb21FbGVtZW50LnJlbW92ZUNoaWxkKGRvbUVsZW1lbnQuZmlyc3RDaGlsZCk7XHJcbiAgfVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5yZW1vdmVBbGxDaGlsZHJlbiA9IHJlbW92ZUFsbENoaWxkcmVuO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBhZGRzIGFuIGVtcHR5IG9wdGlvbiB0byB0aGUgbGlzdFxyXG4gKi9cclxuZnVuY3Rpb24gYWRkRW1wdHlQYXJhbWV0ZXIobGlzdCkge1xyXG4gIHJldHVybiBsaXN0LnB1c2goeyAnbGFiZWwnOiAnJywgJ3ZhbHVlJzogJycsICduYW1lJzogJycgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmFkZEVtcHR5UGFyYW1ldGVyID0gYWRkRW1wdHlQYXJhbWV0ZXI7XHJcblxyXG5cclxuLyoqXHJcbiAqIHJldHVybnMgYSBsaXN0IHdpdGggYWxsIHJvb3QgZWxlbWVudHMgZm9yIHRoZSBnaXZlbiBwYXJhbWV0ZXIgJ3JlZmVyZW5jZWRUeXBlJ1xyXG4gKi9cclxuZnVuY3Rpb24gcmVmcmVzaE9wdGlvbnNNb2RlbChidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpIHtcclxuICB2YXIgbW9kZWwgPSBbXTtcclxuICB2YXIgcmVmZXJhYmxlT2JqZWN0cyA9IGZpbmRSb290RWxlbWVudHNCeVR5cGUoYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRUeXBlKTtcclxuICBmb3JFYWNoKHJlZmVyYWJsZU9iamVjdHMsIGZ1bmN0aW9uKG9iaikge1xyXG4gICAgbW9kZWwucHVzaCh7XHJcbiAgICAgIGxhYmVsOiAob2JqLm5hbWUgfHwgJycpICsgJyAoaWQ9JytvYmouaWQrJyknLFxyXG4gICAgICB2YWx1ZTogb2JqLmlkLFxyXG4gICAgICBuYW1lOiBvYmoubmFtZVxyXG4gICAgfSk7XHJcbiAgfSk7XHJcbiAgcmV0dXJuIG1vZGVsO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5yZWZyZXNoT3B0aW9uc01vZGVsID0gcmVmcmVzaE9wdGlvbnNNb2RlbDtcclxuXHJcblxyXG4vKipcclxuICogZmlsbHMgdGhlIGRyb3AgZG93biB3aXRoIG9wdGlvbnNcclxuICovXHJcbmZ1bmN0aW9uIHVwZGF0ZU9wdGlvbnNEcm9wRG93bihkb21TZWxlY3RvciwgYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRUeXBlLCBlbnRyeU5vZGUpIHtcclxuICB2YXIgb3B0aW9ucyA9IHJlZnJlc2hPcHRpb25zTW9kZWwoYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRUeXBlKTtcclxuICBhZGRFbXB0eVBhcmFtZXRlcihvcHRpb25zKTtcclxuICB2YXIgc2VsZWN0Qm94ID0gZG9tUXVlcnkoZG9tU2VsZWN0b3IsIGVudHJ5Tm9kZSk7XHJcbiAgZG9tQ2xlYXIoc2VsZWN0Qm94KTtcclxuXHJcbiAgZm9yRWFjaChvcHRpb25zLCBmdW5jdGlvbihvcHRpb24pIHtcclxuICAgIHZhciBvcHRpb25FbnRyeSA9IGRvbWlmeSgnPG9wdGlvbiB2YWx1ZT1cIicgKyBlc2NhcGVIVE1MKG9wdGlvbi52YWx1ZSkgKyAnXCI+JyArIGVzY2FwZUhUTUwob3B0aW9uLmxhYmVsKSArICc8L29wdGlvbj4nKTtcclxuICAgIHNlbGVjdEJveC5hcHBlbmRDaGlsZChvcHRpb25FbnRyeSk7XHJcbiAgfSk7XHJcbiAgcmV0dXJuIG9wdGlvbnM7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLnVwZGF0ZU9wdGlvbnNEcm9wRG93biA9IHVwZGF0ZU9wdGlvbnNEcm9wRG93bjtcclxuXHJcblxyXG4vKipcclxuICogY2hlY2tzIHdoZXRoZXIgdGhlIGlkIHZhbHVlIGlzIHZhbGlkXHJcbiAqXHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gYm9cclxuICogQHBhcmFtIHtTdHJpbmd9IGlkVmFsdWVcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNsYXRlXHJcbiAqXHJcbiAqIEByZXR1cm4ge1N0cmluZ30gZXJyb3IgbWVzc2FnZVxyXG4gKi9cclxuZnVuY3Rpb24gaXNJZFZhbGlkKGJvLCBpZFZhbHVlLCB0cmFuc2xhdGUpIHtcclxuICB2YXIgYXNzaWduZWQgPSBiby4kbW9kZWwuaWRzLmFzc2lnbmVkKGlkVmFsdWUpO1xyXG5cclxuICB2YXIgaWRFeGlzdHMgPSBhc3NpZ25lZCAmJiBhc3NpZ25lZCAhPT0gYm87XHJcblxyXG4gIGlmICghaWRWYWx1ZSB8fCBpZEV4aXN0cykge1xyXG4gICAgcmV0dXJuIHRyYW5zbGF0ZSgnRWxlbWVudCBtdXN0IGhhdmUgYW4gdW5pcXVlIGlkLicpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHZhbGlkYXRlSWQoaWRWYWx1ZSwgdHJhbnNsYXRlKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuaXNJZFZhbGlkID0gaXNJZFZhbGlkO1xyXG5cclxuXHJcbmZ1bmN0aW9uIHZhbGlkYXRlSWQoaWRWYWx1ZSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlkVmFsdWUgPSBzdHJpcFBsYWNlaG9sZGVycyhpZFZhbHVlKTtcclxuXHJcbiAgaWYgKGNvbnRhaW5zU3BhY2UoaWRWYWx1ZSkpIHtcclxuICAgIHJldHVybiB0cmFuc2xhdGUoJ0lkIG11c3Qgbm90IGNvbnRhaW4gc3BhY2VzLicpO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFJRF9SRUdFWC50ZXN0KGlkVmFsdWUpKSB7XHJcblxyXG4gICAgaWYgKFFOQU1FX1JFR0VYLnRlc3QoaWRWYWx1ZSkpIHtcclxuICAgICAgcmV0dXJuIHRyYW5zbGF0ZSgnSWQgbXVzdCBub3QgY29udGFpbiBwcmVmaXguJyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRyYW5zbGF0ZSgnSWQgbXVzdCBiZSBhIHZhbGlkIFFOYW1lLicpO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMudmFsaWRhdGVJZCA9IHZhbGlkYXRlSWQ7XHJcblxyXG5cclxuZnVuY3Rpb24gY29udGFpbnNTcGFjZSh2YWx1ZSkge1xyXG4gIHJldHVybiBTUEFDRV9SRUdFWC50ZXN0KHZhbHVlKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuY29udGFpbnNTcGFjZSA9IGNvbnRhaW5zU3BhY2U7XHJcblxyXG5cclxuZnVuY3Rpb24gc3RyaXBQbGFjZWhvbGRlcnMoaWRWYWx1ZSkge1xyXG5cclxuICAvLyByZXBsYWNlIGV4cHJlc3Npb24gZS5nLiAke1ZFUlNJT05fVEFHfVxyXG4gIC8vIHVzZSBvbmx5IHRoZSBjb250ZW50IGJldHdlZW4gJHt9XHJcbiAgLy8gZm9yIHRoZSBSRUdFWCBjaGVja1xyXG4gIHJldHVybiBpZFZhbHVlLnJlcGxhY2UoUExBQ0VIT0xERVJfUkVHRVgsICckMScpO1xyXG59XHJcblxyXG4vKipcclxuICogZ2VuZXJhdGUgYSBzZW1hbnRpYyBpZCB3aXRoIGdpdmVuIHByZWZpeFxyXG4gKi9cclxuZnVuY3Rpb24gbmV4dElkKHByZWZpeCkge1xyXG4gIHZhciBpZHMgPSBuZXcgSWRzKFszMiwzMiwxXSk7XHJcblxyXG4gIHJldHVybiBpZHMubmV4dFByZWZpeGVkKHByZWZpeCk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLm5leHRJZCA9IG5leHRJZDtcclxuXHJcblxyXG5mdW5jdGlvbiB0cmlnZ2VyQ2xpY2tFdmVudChlbGVtZW50KSB7XHJcbiAgdmFyIGV2dDtcclxuICB2YXIgZXZlbnRUeXBlID0gJ2NsaWNrJztcclxuXHJcbiAgaWYgKGRvY3VtZW50LmNyZWF0ZUV2ZW50KSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAvLyBDaHJvbWUsIFNhZmFyaSwgRmlyZWZveFxyXG4gICAgICBldnQgPSBuZXcgTW91c2VFdmVudCgoZXZlbnRUeXBlKSwgeyB2aWV3OiB3aW5kb3csIGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibGU6IHRydWUgfSk7XHJcbiAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgIC8vIElFIDExLCBQaGFudG9tSlMgKHdhdCEpXHJcbiAgICAgIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50Jyk7XHJcblxyXG4gICAgICBldnQuaW5pdEV2ZW50KChldmVudFR5cGUpLCB0cnVlLCB0cnVlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBlbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZ0KTtcclxuICB9IGVsc2Uge1xyXG4gICAgLy8gV2VsY29tZSBJRVxyXG4gICAgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnRPYmplY3QoKTtcclxuXHJcbiAgICByZXR1cm4gZWxlbWVudC5maXJlRXZlbnQoJ29uJyArIGV2ZW50VHlwZSwgZXZ0KTtcclxuICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLnRyaWdnZXJDbGlja0V2ZW50ID0gdHJpZ2dlckNsaWNrRXZlbnQ7XHJcblxyXG5cclxuZnVuY3Rpb24gZXNjYXBlSFRNTChzdHIpIHtcclxuICBzdHIgPSAnJyArIHN0cjtcclxuXHJcbiAgcmV0dXJuIHN0ciAmJiBzdHIucmVwbGFjZSgvWyY8PlwiJ10vZywgZnVuY3Rpb24obWF0Y2gpIHtcclxuICAgIHJldHVybiBIVE1MX0VTQ0FQRV9NQVBbbWF0Y2hdO1xyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5lc2NhcGVIVE1MID0gZXNjYXBlSFRNTDsiLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uL1V0aWxzJykuZXNjYXBlSFRNTDtcclxuXHJcbnZhciBlbnRyeUZpZWxkRGVzY3JpcHRpb24gPSByZXF1aXJlKCcuL0VudHJ5RmllbGREZXNjcmlwdGlvbicpO1xyXG5cclxuXHJcbnZhciBjaGVja2JveCA9IGZ1bmN0aW9uKG9wdGlvbnMsIGRlZmF1bHRQYXJhbWV0ZXJzKSB7XHJcbiAgdmFyIHJlc291cmNlID0gZGVmYXVsdFBhcmFtZXRlcnMsXHJcbiAgICAgIGlkID0gcmVzb3VyY2UuaWQsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCB8fCBpZCxcclxuICAgICAgY2FuQmVEaXNhYmxlZCA9ICEhb3B0aW9ucy5kaXNhYmxlZCAmJiB0eXBlb2Ygb3B0aW9ucy5kaXNhYmxlZCA9PT0gJ2Z1bmN0aW9uJyxcclxuICAgICAgY2FuQmVIaWRkZW4gPSAhIW9wdGlvbnMuaGlkZGVuICYmIHR5cGVvZiBvcHRpb25zLmhpZGRlbiA9PT0gJ2Z1bmN0aW9uJyxcclxuICAgICAgZGVzY3JpcHRpb24gPSBvcHRpb25zLmRlc2NyaXB0aW9uO1xyXG5cclxuICByZXNvdXJjZS5odG1sID1cclxuICAgICc8aW5wdXQgaWQ9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChpZCkgKyAnXCIgJyArXHJcbiAgICAgICAgICd0eXBlPVwiY2hlY2tib3hcIiAnICtcclxuICAgICAgICAgJ25hbWU9XCInICsgZXNjYXBlSFRNTChvcHRpb25zLm1vZGVsUHJvcGVydHkpICsgJ1wiICcgK1xyXG4gICAgICAgICAoY2FuQmVEaXNhYmxlZCA/ICdkYXRhLWRpc2FibGU9XCJpc0Rpc2FibGVkXCInIDogJycpICtcclxuICAgICAgICAgKGNhbkJlSGlkZGVuID8gJ2RhdGEtc2hvdz1cImlzSGlkZGVuXCInIDogJycpICtcclxuICAgICAgICAgJyAvPicgK1xyXG4gICAgJzxsYWJlbCBmb3I9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChpZCkgKyAnXCIgJyArXHJcbiAgICAgICAgIChjYW5CZURpc2FibGVkID8gJ2RhdGEtZGlzYWJsZT1cImlzRGlzYWJsZWRcIicgOiAnJykgK1xyXG4gICAgICAgICAoY2FuQmVIaWRkZW4gPyAnZGF0YS1zaG93PVwiaXNIaWRkZW5cIicgOiAnJykgK1xyXG4gICAgICAgICAnPicgKyBlc2NhcGVIVE1MKGxhYmVsKSArICc8L2xhYmVsPic7XHJcblxyXG4gIC8vIGFkZCBkZXNjcmlwdGlvbiBiZWxvdyBjaGVja2JveCBlbnRyeSBmaWVsZFxyXG4gIGlmIChkZXNjcmlwdGlvbikge1xyXG4gICAgcmVzb3VyY2UuaHRtbCArPSBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgcmVzb3VyY2UuZ2V0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksXHJcbiAgICAgICAgcmVzID0ge307XHJcblxyXG4gICAgcmVzW29wdGlvbnMubW9kZWxQcm9wZXJ0eV0gPSBiby5nZXQob3B0aW9ucy5tb2RlbFByb3BlcnR5KTtcclxuXHJcbiAgICByZXR1cm4gcmVzO1xyXG4gIH07XHJcblxyXG4gIHJlc291cmNlLnNldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgdmFyIHJlcyA9IHt9O1xyXG5cclxuICAgIHJlc1tvcHRpb25zLm1vZGVsUHJvcGVydHldID0gISF2YWx1ZXNbb3B0aW9ucy5tb2RlbFByb3BlcnR5XTtcclxuXHJcbiAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcmVzKTtcclxuICB9O1xyXG5cclxuICBpZiAodHlwZW9mIG9wdGlvbnMuc2V0ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICByZXNvdXJjZS5zZXQgPSBvcHRpb25zLnNldDtcclxuICB9XHJcblxyXG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5nZXQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgIHJlc291cmNlLmdldCA9IG9wdGlvbnMuZ2V0O1xyXG4gIH1cclxuXHJcbiAgaWYgKGNhbkJlRGlzYWJsZWQpIHtcclxuICAgIHJlc291cmNlLmlzRGlzYWJsZWQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgcmV0dXJuIG9wdGlvbnMuZGlzYWJsZWQuYXBwbHkocmVzb3VyY2UsIGFyZ3VtZW50cyk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgaWYgKGNhbkJlSGlkZGVuKSB7XHJcbiAgICByZXNvdXJjZS5pc0hpZGRlbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICByZXR1cm4gIW9wdGlvbnMuaGlkZGVuLmFwcGx5KHJlc291cmNlLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJlc291cmNlLmNzc0NsYXNzZXMgPSBbJ2JwcC1jaGVja2JveCddO1xyXG5cclxuICByZXR1cm4gcmVzb3VyY2U7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNoZWNrYm94O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpLFxyXG4gICAgZmluZCA9IHJlcXVpcmUoJ2xvZGFzaC9maW5kJyk7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnk7XHJcblxyXG52YXIgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uL1V0aWxzJykuZXNjYXBlSFRNTDtcclxuXHJcbnZhciBzZWxlY3RFbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuL1NlbGVjdEVudHJ5RmFjdG9yeScpLFxyXG4gICAgZW50cnlGaWVsZERlc2NyaXB0aW9uID0gcmVxdWlyZSgnLi9FbnRyeUZpZWxkRGVzY3JpcHRpb24nKTtcclxuXHJcblxyXG4vKipcclxuICogVGhlIGNvbWJvIGJveCBpcyBhIHNwZWNpYWwgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlbGVjdCBlbnRyeSBhbmQgYWRkcyB0aGUgb3B0aW9uICdjdXN0b20nIHRvIHRoZVxyXG4gKiBzZWxlY3QgYm94LiBJZiAnY3VzdG9tJyBpcyBzZWxlY3RlZCwgYW4gYWRkaXRpb25hbCB0ZXh0IGlucHV0IGZpZWxkIGlzIHNob3duIHdoaWNoIGFsbG93cyB0byBkZWZpbmVcclxuICogYSBjdXN0b20gdmFsdWUuXHJcbiAqXHJcbiAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMuaWRcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmxhYmVsXHJcbiAqIEBwYXJhbSAge0FycmF5PE9iamVjdD59IG9wdGlvbnMuc2VsZWN0T3B0aW9ucyBsaXN0IG9mIG5hbWUvdmFsdWUgcGFpcnNcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLm1vZGVsUHJvcGVydHlcclxuICogQHBhcmFtICB7ZnVuY3Rpb259IG9wdGlvbnMuZ2V0XHJcbiAqIEBwYXJhbSAge2Z1bmN0aW9ufSBvcHRpb25zLnNldFxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IFtvcHRpb25zLmN1c3RvbVZhbHVlXSBjdXN0b20gc2VsZWN0IG9wdGlvbiB2YWx1ZSAoZGVmYXVsdDogJ2N1c3RvbScpXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gW29wdGlvbnMuY3VzdG9tTmFtZV0gY3VzdG9tIHNlbGVjdCBvcHRpb24gbmFtZSB2aXNpYmxlIGluIHRoZSBzZWxlY3QgYm94IChkZWZhdWx0OiAnY3VzdG9tJylcclxuICpcclxuICogQHJldHVybiB7T2JqZWN0fVxyXG4gKi9cclxudmFyIGNvbWJvQm94ID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG5cclxuICB2YXIgc2VsZWN0T3B0aW9ucyA9IG9wdGlvbnMuc2VsZWN0T3B0aW9ucyxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eSxcclxuICAgICAgY3VzdG9tVmFsdWUgPSBvcHRpb25zLmN1c3RvbVZhbHVlIHx8ICdjdXN0b20nLFxyXG4gICAgICBjdXN0b21OYW1lID0gb3B0aW9ucy5jdXN0b21OYW1lIHx8ICdjdXN0b20gJyArIG1vZGVsUHJvcGVydHksXHJcbiAgICAgIGRlc2NyaXB0aW9uID0gb3B0aW9ucy5kZXNjcmlwdGlvbjtcclxuXHJcbiAgLy8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBub3QgYSBidWlsdCBpbiB2YWx1ZVxyXG4gIHZhciBpc0N1c3RvbVZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgdmFsdWVbbW9kZWxQcm9wZXJ0eV0gPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgaXNDdXN0b20gPSAhZmluZChzZWxlY3RPcHRpb25zLCBmdW5jdGlvbihvcHRpb24pIHtcclxuICAgICAgcmV0dXJuIHZhbHVlW21vZGVsUHJvcGVydHldID09PSBvcHRpb24udmFsdWU7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gaXNDdXN0b207XHJcbiAgfTtcclxuXHJcbiAgdmFyIGNvbWJvT3B0aW9ucyA9IGFzc2lnbih7fSwgb3B0aW9ucyk7XHJcblxyXG4gIC8vIHRydWUgaWYgdGhlIHNlbGVjdGVkIHZhbHVlIGluIHRoZSBzZWxlY3QgYm94IGlzIGN1c3RvbVZhbHVlXHJcbiAgY29tYm9PcHRpb25zLnNob3dDdXN0b21JbnB1dCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciBzZWxlY3RCb3ggPSBkb21RdWVyeSgnW2RhdGEtZW50cnk9XCInKyBvcHRpb25zLmlkICsnXCJdIHNlbGVjdCcsIG5vZGUucGFyZW50Tm9kZSk7XHJcblxyXG4gICAgaWYgKHNlbGVjdEJveCkge1xyXG4gICAgICByZXR1cm4gc2VsZWN0Qm94LnZhbHVlID09PSBjdXN0b21WYWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfTtcclxuXHJcbiAgY29tYm9PcHRpb25zLmdldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciB2YWx1ZSA9IG9wdGlvbnMuZ2V0KGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgIHZhciBtb2RpZmllZFZhbHVlcyA9IHt9O1xyXG5cclxuICAgIGlmICghaXNDdXN0b21WYWx1ZSh2YWx1ZSkpIHtcclxuICAgICAgbW9kaWZpZWRWYWx1ZXNbbW9kZWxQcm9wZXJ0eV0gPSB2YWx1ZVttb2RlbFByb3BlcnR5XSB8fCAnJztcclxuXHJcbiAgICAgIHJldHVybiBtb2RpZmllZFZhbHVlcztcclxuICAgIH1cclxuXHJcbiAgICBtb2RpZmllZFZhbHVlc1ttb2RlbFByb3BlcnR5XSA9IGN1c3RvbVZhbHVlO1xyXG4gICAgbW9kaWZpZWRWYWx1ZXNbJ2N1c3RvbS0nK21vZGVsUHJvcGVydHldID0gdmFsdWVbbW9kZWxQcm9wZXJ0eV07XHJcblxyXG4gICAgcmV0dXJuIG1vZGlmaWVkVmFsdWVzO1xyXG4gIH07XHJcblxyXG4gIGNvbWJvT3B0aW9ucy5zZXQgPSBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgIHZhciBtb2RpZmllZFZhbHVlcyA9IHt9O1xyXG5cclxuICAgIC8vIGlmIHRoZSBjdXN0b20gc2VsZWN0IG9wdGlvbiBoYXMgYmVlbiBzZWxlY3RlZFxyXG4gICAgLy8gdGFrZSB0aGUgdmFsdWUgZnJvbSB0aGUgdGV4dCBpbnB1dCBmaWVsZFxyXG4gICAgaWYgKHZhbHVlc1ttb2RlbFByb3BlcnR5XSA9PT0gY3VzdG9tVmFsdWUpIHtcclxuICAgICAgbW9kaWZpZWRWYWx1ZXNbbW9kZWxQcm9wZXJ0eV0gPSB2YWx1ZXNbJ2N1c3RvbS0nICsgbW9kZWxQcm9wZXJ0eV0gfHwgJyc7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChvcHRpb25zLmVtcHR5UGFyYW1ldGVyICYmIHZhbHVlc1ttb2RlbFByb3BlcnR5XSA9PT0gJycpIHtcclxuICAgICAgbW9kaWZpZWRWYWx1ZXNbbW9kZWxQcm9wZXJ0eV0gPSB1bmRlZmluZWQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBtb2RpZmllZFZhbHVlc1ttb2RlbFByb3BlcnR5XSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XTtcclxuICAgIH1cclxuICAgIHJldHVybiBvcHRpb25zLnNldChlbGVtZW50LCBtb2RpZmllZFZhbHVlcywgbm9kZSk7XHJcbiAgfTtcclxuXHJcbiAgY29tYm9PcHRpb25zLnNlbGVjdE9wdGlvbnMucHVzaCh7IG5hbWU6IGN1c3RvbU5hbWUsIHZhbHVlOiBjdXN0b21WYWx1ZSB9KTtcclxuXHJcbiAgdmFyIGNvbWJvQm94RW50cnkgPSBhc3NpZ24oe30sIHNlbGVjdEVudHJ5RmFjdG9yeShjb21ib09wdGlvbnMsIGNvbWJvT3B0aW9ucykpO1xyXG5cclxuICBjb21ib0JveEVudHJ5Lmh0bWwgKz0gJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlciBicHAtY29tYm8taW5wdXRcIiAnICtcclxuICAgICdkYXRhLXNob3c9XCJzaG93Q3VzdG9tSW5wdXRcIicgK1xyXG4gICAgJz4nICtcclxuICAgICc8aW5wdXQgaWQ9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChvcHRpb25zLmlkKSArICctaW5wdXRcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJjdXN0b20tJyArXHJcbiAgICAgIGVzY2FwZUhUTUwobW9kZWxQcm9wZXJ0eSkgKyAnXCIgJyArXHJcbiAgICAnIC8+JyArXHJcbiAgJzwvZGl2Pic7XHJcblxyXG4gIC8vIGFkZCBkZXNjcmlwdGlvbiBiZWxvdyBjb21ibyBib3ggZW50cnkgZmllbGRcclxuICBpZiAoZGVzY3JpcHRpb24pIHtcclxuICAgIGNvbWJvQm94RW50cnkuaHRtbCArPSBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGNvbWJvQm94RW50cnk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNvbWJvQm94O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuLy8gaW5wdXQgZW50aXRpZXNcclxudmFyIHRleHRJbnB1dEZpZWxkID0gcmVxdWlyZSgnLi9UZXh0SW5wdXRFbnRyeUZhY3RvcnknKSxcclxuICAgIGNoZWNrYm94RmllbGQgPSByZXF1aXJlKCcuL0NoZWNrYm94RW50cnlGYWN0b3J5JyksXHJcbiAgICBzZWxlY3RCb3hGaWVsZCA9IHJlcXVpcmUoJy4vU2VsZWN0RW50cnlGYWN0b3J5JyksXHJcbiAgICBjb21ib0JveEZpZWxkID0gcmVxdWlyZSgnLi9Db21ib0VudHJ5RmFjdG9yeScpLFxyXG4gICAgdGV4dEJveEZpZWxkID0gcmVxdWlyZSgnLi9UZXh0Qm94RW50cnlGYWN0b3J5JyksXHJcbiAgICB2YWxpZGF0aW9uQXdhcmVUZXh0SW5wdXRGaWVsZCA9IHJlcXVpcmUoJy4vVmFsaWRhdGlvbkF3YXJlVGV4dElucHV0JyksXHJcbiAgICB0YWJsZUZpZWxkID0gcmVxdWlyZSgnLi9UYWJsZUVudHJ5RmFjdG9yeScpLFxyXG4gICAgbGFiZWxFbnRyeSA9IHJlcXVpcmUoJy4vTGFiZWxGYWN0b3J5JyksXHJcbiAgICBsaW5rID0gcmVxdWlyZSgnLi9MaW5rRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBlbnN1cmVOb3ROdWxsKHByb3ApIHtcclxuICBpZiAoIXByb3ApIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihwcm9wICsgJyBtdXN0IGJlIHNldC4nKTtcclxuICB9XHJcblxyXG4gIHJldHVybiBwcm9wO1xyXG59XHJcblxyXG4vKipcclxuICogc2V0cyB0aGUgZGVmYXVsdCBwYXJhbWV0ZXJzIHdoaWNoIGFyZSBuZWVkZWQgdG8gY3JlYXRlIGFuIGVudHJ5XHJcbiAqXHJcbiAqIEBwYXJhbSBvcHRpb25zXHJcbiAqIEByZXR1cm5zIHt7aWQ6ICosIGRlc2NyaXB0aW9uOiAoKnxzdHJpbmcpLCBnZXQ6ICgqfEZ1bmN0aW9uKSwgc2V0OiAoKnxGdW5jdGlvbiksXHJcbiAqICAgICAgICAgICAgdmFsaWRhdGU6ICgqfEZ1bmN0aW9uKSwgaHRtbDogc3RyaW5nfX1cclxuICovXHJcbnZhciBzZXREZWZhdWx0UGFyYW1ldGVycyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuXHJcbiAgLy8gZGVmYXVsdCBtZXRob2QgdG8gZmV0Y2ggdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGlucHV0IGZpZWxkXHJcbiAgdmFyIGRlZmF1bHRHZXQgPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICByZXMgPSB7fSxcclxuICAgICAgICBwcm9wID0gZW5zdXJlTm90TnVsbChvcHRpb25zLm1vZGVsUHJvcGVydHkpO1xyXG4gICAgcmVzW3Byb3BdID0gYm8uZ2V0KHByb3ApO1xyXG5cclxuICAgIHJldHVybiByZXM7XHJcbiAgfTtcclxuXHJcbiAgLy8gZGVmYXVsdCBtZXRob2QgdG8gc2V0IGEgbmV3IHZhbHVlIHRvIHRoZSBpbnB1dCBmaWVsZFxyXG4gIHZhciBkZWZhdWx0U2V0ID0gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICB2YXIgcmVzID0ge30sXHJcbiAgICAgICAgcHJvcCA9IGVuc3VyZU5vdE51bGwob3B0aW9ucy5tb2RlbFByb3BlcnR5KTtcclxuICAgIGlmICh2YWx1ZXNbcHJvcF0gIT09ICcnKSB7XHJcbiAgICAgIHJlc1twcm9wXSA9IHZhbHVlc1twcm9wXTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJlc1twcm9wXSA9IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcmVzKTtcclxuICB9O1xyXG5cclxuICAvLyBkZWZhdWx0IHZhbGlkYXRpb24gbWV0aG9kXHJcbiAgdmFyIGRlZmF1bHRWYWxpZGF0ZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHt9O1xyXG4gIH07XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBpZCA6IG9wdGlvbnMuaWQsXHJcbiAgICBkZXNjcmlwdGlvbiA6IChvcHRpb25zLmRlc2NyaXB0aW9uIHx8ICcnKSxcclxuICAgIGdldCA6IChvcHRpb25zLmdldCB8fCBkZWZhdWx0R2V0KSxcclxuICAgIHNldCA6IChvcHRpb25zLnNldCB8fCBkZWZhdWx0U2V0KSxcclxuICAgIHZhbGlkYXRlIDogKG9wdGlvbnMudmFsaWRhdGUgfHwgZGVmYXVsdFZhbGlkYXRlKSxcclxuICAgIGh0bWw6ICcnXHJcbiAgfTtcclxufTtcclxuXHJcbmZ1bmN0aW9uIEVudHJ5RmFjdG9yeSgpIHtcclxuXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYW4gdGV4dCBpbnB1dCBlbnRyeSBvYmplY3QgZm9yIGEgcHJvcGVydHkgcGFuZWwuXHJcbiAqIG9wdGlvbnMgYXJlOlxyXG4gKiAtIGlkOiBpZCBvZiB0aGUgZW50cnkgLSBTdHJpbmdcclxuICpcclxuICogLSBkZXNjcmlwdGlvbjogZGVzY3JpcHRpb24gb2YgdGhlIHByb3BlcnR5IC0gU3RyaW5nXHJcbiAqXHJcbiAqIC0gbGFiZWw6IGxhYmVsIGZvciB0aGUgaW5wdXQgZmllbGQgLSBTdHJpbmdcclxuICpcclxuICogLSBzZXQ6IHNldHRlciBtZXRob2QgLSBGdW5jdGlvblxyXG4gKlxyXG4gKiAtIGdldDogZ2V0dGVyIG1ldGhvZCAtIEZ1bmN0aW9uXHJcbiAqXHJcbiAqIC0gdmFsaWRhdGU6IHZhbGlkYXRpb24gbWVodG9kIC0gRnVuY3Rpb25cclxuICpcclxuICogLSBtb2RlbFByb3BlcnR5OiBuYW1lIG9mIHRoZSBtb2RlbCBwcm9wZXJ0eSAtIFN0cmluZ1xyXG4gKlxyXG4gKiAtIGJ1dHRvbkFjdGlvbjogT2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczogLSBPYmplY3RcclxuICogLS0tLSBuYW1lOiBuYW1lIG9mIHRoZSBbZGF0YS1hY3Rpb25dIGNhbGxiYWNrIC0gU3RyaW5nXHJcbiAqIC0tLS0gbWV0aG9kOiBjYWxsYmFjayBmdW5jdGlvbiBmb3IgW2RhdGEtYWN0aW9uXSAtIEZ1bmN0aW9uXHJcbiAqXHJcbiAqIC0gYnV0dG9uU2hvdzogT2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczogLSBPYmplY3RcclxuICogLS0tLSBuYW1lOiBuYW1lIG9mIHRoZSBbZGF0YS1zaG93XSBjYWxsYmFjayAtIFN0cmluZ1xyXG4gKiAtLS0tIG1ldGhvZDogY2FsbGJhY2sgZnVuY3Rpb24gZm9yIFtkYXRhLXNob3ddIC0gRnVuY3Rpb25cclxuICpcclxuICogQHBhcmFtIG9wdGlvbnNcclxuICogQHJldHVybnMgdGhlIHByb3BlcnR5UGFuZWwgZW50cnkgcmVzb3VyY2Ugb2JqZWN0XHJcbiAqL1xyXG5FbnRyeUZhY3RvcnkudGV4dEZpZWxkID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG4gIHJldHVybiB0ZXh0SW5wdXRGaWVsZChvcHRpb25zLCBzZXREZWZhdWx0UGFyYW1ldGVycyhvcHRpb25zKSk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkudmFsaWRhdGlvbkF3YXJlVGV4dEZpZWxkID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG4gIHJldHVybiB2YWxpZGF0aW9uQXdhcmVUZXh0SW5wdXRGaWVsZChvcHRpb25zLCBzZXREZWZhdWx0UGFyYW1ldGVycyhvcHRpb25zKSk7XHJcbn07XHJcblxyXG4vKipcclxuICogR2VuZXJhdGVzIGEgY2hlY2tib3ggaW5wdXQgZW50cnkgb2JqZWN0IGZvciBhIHByb3BlcnR5IHBhbmVsLlxyXG4gKiBvcHRpb25zIGFyZTpcclxuICogLSBpZDogaWQgb2YgdGhlIGVudHJ5IC0gU3RyaW5nXHJcbiAqXHJcbiAqIC0gZGVzY3JpcHRpb246IGRlc2NyaXB0aW9uIG9mIHRoZSBwcm9wZXJ0eSAtIFN0cmluZ1xyXG4gKlxyXG4gKiAtIGxhYmVsOiBsYWJlbCBmb3IgdGhlIGlucHV0IGZpZWxkIC0gU3RyaW5nXHJcbiAqXHJcbiAqIC0gc2V0OiBzZXR0ZXIgbWV0aG9kIC0gRnVuY3Rpb25cclxuICpcclxuICogLSBnZXQ6IGdldHRlciBtZXRob2QgLSBGdW5jdGlvblxyXG4gKlxyXG4gKiAtIHZhbGlkYXRlOiB2YWxpZGF0aW9uIG1ldGhvZCAtIEZ1bmN0aW9uXHJcbiAqXHJcbiAqIC0gbW9kZWxQcm9wZXJ0eTogbmFtZSBvZiB0aGUgbW9kZWwgcHJvcGVydHkgLSBTdHJpbmdcclxuICpcclxuICogQHBhcmFtIG9wdGlvbnNcclxuICogQHJldHVybnMgdGhlIHByb3BlcnR5UGFuZWwgZW50cnkgcmVzb3VyY2Ugb2JqZWN0XHJcbiAqL1xyXG5FbnRyeUZhY3RvcnkuY2hlY2tib3ggPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIGNoZWNrYm94RmllbGQob3B0aW9ucywgc2V0RGVmYXVsdFBhcmFtZXRlcnMob3B0aW9ucykpO1xyXG59O1xyXG5cclxuRW50cnlGYWN0b3J5LnRleHRCb3ggPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIHRleHRCb3hGaWVsZChvcHRpb25zLCBzZXREZWZhdWx0UGFyYW1ldGVycyhvcHRpb25zKSk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3Rvcnkuc2VsZWN0Qm94ID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG4gIHJldHVybiBzZWxlY3RCb3hGaWVsZChvcHRpb25zLCBzZXREZWZhdWx0UGFyYW1ldGVycyhvcHRpb25zKSk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkuY29tYm9Cb3ggPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIGNvbWJvQm94RmllbGQob3B0aW9ucyk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkudGFibGUgPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIHRhYmxlRmllbGQob3B0aW9ucyk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkubGFiZWwgPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIGxhYmVsRW50cnkob3B0aW9ucyk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkubGluayA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuICByZXR1cm4gbGluayhvcHRpb25zKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gRW50cnlGYWN0b3J5O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uL1V0aWxzJykuZXNjYXBlSFRNTDtcclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYSBsaW5raWZpZWQgYW5kIEhUTUwgZXNjYXBlZCBlbnRyeSBmaWVsZCBkZXNjcmlwdGlvbi5cclxuICpcclxuICogQXMgYSBzcGVjaWFsIGZlYXR1cmUsIHRoaXMgZGVzY3JpcHRpb24gbWF5IGNvbnRhaW4gYm90aCBtYXJrZG93blxyXG4gKiBhbmQgcGxhaW4gPGEgaHJlZj4gbGlua3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBkZXNjcmlwdGlvblxyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pIHtcclxuXHJcbiAgLy8gd2UgdG9rZW5pemUgdGhlIGRlc2NyaXB0aW9uIHRvIGV4dHJhY3QgdGV4dCwgSFRNTCBhbmQgbWFya2Rvd24gbGlua3NcclxuICAvLyB0ZXh0IGFuZCBsaW5rcyBhcmUgaGFuZGxlZCBzZXBlcmF0ZWx5XHJcblxyXG4gIHZhciBlc2NhcGVkID0gW107XHJcblxyXG4gIC8vIG1hdGNoIG1hcmtkb3duIFt7VEVYVH1dKHtVUkx9KSBhbmQgSFRNTCBsaW5rcyA8YSBocmVmPVwie1VSTH1cIj57VEVYVH08L2E+XHJcbiAgdmFyIHBhdHRlcm4gPSAvKD86XFxbKFteXFxdXSspXFxdXFwoKGh0dHBzPzpcXC9cXC9bXlwiPD5cXF1dKylcXCkpfCg/OjxhIGhyZWY9XCIoaHR0cHM/OlxcL1xcL1teXCI8Pl0rKVwiPihbXjxdKik8XFwvYT4pL2dpO1xyXG5cclxuICB2YXIgaW5kZXggPSAwO1xyXG4gIHZhciBtYXRjaDtcclxuICB2YXIgbGluaywgdGV4dDtcclxuXHJcbiAgd2hpbGUgKChtYXRjaCA9IHBhdHRlcm4uZXhlYyhkZXNjcmlwdGlvbikpKSB7XHJcblxyXG4gICAgLy8gZXNjYXBlICsgaW5zZXJ0IHRleHQgYmVmb3JlIG1hdGNoXHJcbiAgICBpZiAobWF0Y2guaW5kZXggPiBpbmRleCkge1xyXG4gICAgICBlc2NhcGVkLnB1c2goZXNjYXBlSFRNTChkZXNjcmlwdGlvbi5zdWJzdHJpbmcoaW5kZXgsIG1hdGNoLmluZGV4KSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGxpbmsgPSBtYXRjaFsyXSB8fCBtYXRjaFszXTtcclxuICAgIHRleHQgPSBtYXRjaFsxXSB8fCBtYXRjaFs0XTtcclxuXHJcbiAgICAvLyBpbnNlcnQgc2FmZSBsaW5rXHJcbiAgICBlc2NhcGVkLnB1c2goJzxhIGhyZWY9XCInICsgbGluayArICdcIiB0YXJnZXQ9XCJfYmxhbmtcIj4nICsgZXNjYXBlSFRNTCh0ZXh0KSArICc8L2E+Jyk7XHJcblxyXG4gICAgaW5kZXggPSBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aDtcclxuICB9XHJcblxyXG4gIC8vIGVzY2FwZSBhbmQgaW5zZXJ0IHRleHQgYWZ0ZXIgbGFzdCBtYXRjaFxyXG4gIGlmIChpbmRleCA8IGRlc2NyaXB0aW9uLmxlbmd0aCkge1xyXG4gICAgZXNjYXBlZC5wdXNoKGVzY2FwZUhUTUwoZGVzY3JpcHRpb24uc3Vic3RyaW5nKGluZGV4KSkpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLWRlc2NyaXB0aW9uXCI+JyArIGVzY2FwZWQuam9pbignJykgKyAnPC9kaXY+JztcclxufTsiLCIndXNlIHN0cmljdCc7XHJcblxyXG4vKipcclxuICogVGhlIGxhYmVsIGZhY3RvcnkgcHJvdmlkZXMgYSBsYWJlbCBlbnRyeS4gRm9yIHRoZSBsYWJlbCB0ZXh0XHJcbiAqIGl0IGV4cGVjdHMgZWl0aGVyIGEgc3RyaW5nIHByb3ZpZGVkIGJ5IHRoZSBvcHRpb25zLmxhYmVsVGV4dFxyXG4gKiBwYXJhbWV0ZXIgb3IgaXQgY291bGQgYmUgZ2VuZXJhdGVkIHByb2dyYW1tYXRpY2FsbHkgdXNpbmcgYVxyXG4gKiBmdW5jdGlvbiBwYXNzZWQgYXMgdGhlIG9wdGlvbnMuZ2V0IHBhcmFtZXRlci5cclxuICpcclxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5pZFxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IFtvcHRpb25zLmxhYmVsVGV4dF1cclxuICogQHBhcmFtICB7RnVuY3Rpb259IFtvcHRpb25zLmdldF1cclxuICogQHBhcmFtICB7RnVuY3Rpb259IFtvcHRpb25zLnNob3dMYWJlbF1cclxuICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuZGl2aWRlcl0gYWRkcyBhIGRpdmlkZXIgYXQgdGhlIHRvcCBvZiB0aGUgbGFiZWwgaWYgdHJ1ZTsgZGVmYXVsdDogZmFsc2VcclxuICovXHJcbnZhciBsYWJlbCA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuICByZXR1cm4ge1xyXG4gICAgaWQ6IG9wdGlvbnMuaWQsXHJcbiAgICBodG1sOiAnPGxhYmVsIGRhdGEtdmFsdWU9XCJsYWJlbFwiICcgK1xyXG4gICAgICAgICAgICAnZGF0YS1zaG93PVwic2hvd0xhYmVsXCIgJyArXHJcbiAgICAgICAgICAgICdjbGFzcz1cImVudHJ5LWxhYmVsJyArIChvcHRpb25zLmRpdmlkZXIgPyAnIGRpdmlkZXInIDogJycpICsgJ1wiPicgK1xyXG4gICAgICAgICAgJzwvbGFiZWw+JyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMuZ2V0ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuZ2V0KGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB7IGxhYmVsOiBvcHRpb25zLmxhYmVsVGV4dCB9O1xyXG4gICAgfSxcclxuICAgIHNob3dMYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMuc2hvd0xhYmVsID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuc2hvd0xhYmVsKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gIH07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGxhYmVsO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uL1V0aWxzJykuZXNjYXBlSFRNTDtcclxuXHJcbnZhciBlbnRyeUZpZWxkRGVzY3JpcHRpb24gPSByZXF1aXJlKCcuL0VudHJ5RmllbGREZXNjcmlwdGlvbicpO1xyXG5cclxudmFyIGJpbmQgPSByZXF1aXJlKCdsb2Rhc2gvYmluZCcpO1xyXG5cclxuLyoqXHJcbiAqIEFuIGVudHJ5IHRoYXQgcmVuZGVycyBhIGNsaWNrYWJsZSBsaW5rLlxyXG4gKlxyXG4gKiBBIHBhc3NlZCB7QGxpbmsgb3B0aW9ucyNoYW5kbGVDbGlja30gaGFuZGxlciBpcyByZXNwb25zaWJsZVxyXG4gKiB0byBwcm9jZXNzIHRoZSBjbGljay5cclxuICpcclxuICogVGhlIGxpbmsgbWF5IGJlIGNvbmRpdGlvbmFsbHkgc2hvd24gb3IgaGlkZGVuLiBUaGlzIGNhbiBiZVxyXG4gKiBjb250cm9sbGVkIHZpYSB0aGUge0BsaW5rIG9wdGlvbnMuc2hvd0xpbmt9LlxyXG4gKlxyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xyXG4gKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucy5pZFxyXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMubGFiZWxdXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdGlvbnMuaGFuZGxlQ2xpY2tcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuc2hvd0xpbmtdIHJldHVybmluZyBmYWxzZSB0byBoaWRlIGxpbmtcclxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmRlc2NyaXB0aW9uXVxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKlxyXG4gKiB2YXIgbGlua0VudHJ5ID0gbGluayh7XHJcbiAqICAgaWQ6ICdmb28nLFxyXG4gKiAgIGRlc2NyaXB0aW9uOiAnU29tZSBEZXNjcmlwdGlvbicsXHJcbiAqICAgaGFuZGxlQ2xpY2s6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50KSB7IC4uLiB9LFxyXG4gKiAgIHNob3dMaW5rOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7IC4uLiB9XHJcbiAqIH0pO1xyXG4gKlxyXG4gKiBAcmV0dXJuIHtFbnRyeX0gdGhlIG5ld2x5IGNyZWF0ZWQgZW50cnlcclxuICovXHJcbmZ1bmN0aW9uIGxpbmsob3B0aW9ucykge1xyXG5cclxuICB2YXIgaWQgPSBvcHRpb25zLmlkLFxyXG4gICAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgaWQsXHJcbiAgICAgIHNob3dMaW5rID0gb3B0aW9ucy5zaG93TGluayxcclxuICAgICAgaGFuZGxlQ2xpY2sgPSBvcHRpb25zLmhhbmRsZUNsaWNrLFxyXG4gICAgICBkZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb247XHJcblxyXG4gIGlmIChzaG93TGluayAmJiB0eXBlb2Ygc2hvd0xpbmsgIT09ICdmdW5jdGlvbicpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcignb3B0aW9ucy5zaG93TGluayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcclxuICB9XHJcblxyXG4gIGlmICh0eXBlb2YgaGFuZGxlQ2xpY2sgIT09ICdmdW5jdGlvbicpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcignb3B0aW9ucy5oYW5kbGVDbGljayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcclxuICB9XHJcblxyXG4gIHZhciByZXNvdXJjZSA9IHtcclxuICAgIGlkOiBpZFxyXG4gIH07XHJcblxyXG4gIHJlc291cmNlLmh0bWwgPVxyXG4gICAgJzxhIGRhdGEtYWN0aW9uPVwiaGFuZGxlQ2xpY2tcIiAnICtcclxuICAgIChzaG93TGluayA/ICdkYXRhLXNob3c9XCJzaG93TGlua1wiICcgOiAnJykgK1xyXG4gICAgJ2NsYXNzPVwiYnBwLWVudHJ5LWxpbmsnICsgKG9wdGlvbnMuY3NzQ2xhc3NlcyA/ICcgJyArIGVzY2FwZUhUTUwob3B0aW9ucy5jc3NDbGFzc2VzKSA6ICcnKSArXHJcbiAgICAnXCI+JyArIGVzY2FwZUhUTUwobGFiZWwpICsgJzwvYT4nO1xyXG5cclxuICAvLyBhZGQgZGVzY3JpcHRpb24gYmVsb3cgbGluayBlbnRyeSBmaWVsZFxyXG4gIGlmIChkZXNjcmlwdGlvbikge1xyXG4gICAgcmVzb3VyY2UuaHRtbCArPSBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgcmVzb3VyY2UuaGFuZGxlQ2xpY2sgPSBiaW5kKGhhbmRsZUNsaWNrLCByZXNvdXJjZSk7XHJcblxyXG4gIGlmICh0eXBlb2Ygc2hvd0xpbmsgPT09ICdmdW5jdGlvbicpIHtcclxuICAgIHJlc291cmNlLnNob3dMaW5rID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgIHJldHVybiBzaG93TGluay5hcHBseShyZXNvdXJjZSwgYXJndW1lbnRzKTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcmVzb3VyY2U7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbGluaztcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVzY2FwZUhUTUwgPSByZXF1aXJlKCcuLi9VdGlscycpLmVzY2FwZUhUTUw7XHJcblxyXG52YXIgZG9taWZ5ID0gcmVxdWlyZSgnbWluLWRvbScpLmRvbWlmeTtcclxuXHJcbnZhciBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKTtcclxuXHJcbnZhciBlbnRyeUZpZWxkRGVzY3JpcHRpb24gPSByZXF1aXJlKCcuL0VudHJ5RmllbGREZXNjcmlwdGlvbicpO1xyXG5cclxuXHJcbnZhciBpc0xpc3QgPSBmdW5jdGlvbihsaXN0KSB7XHJcbiAgcmV0dXJuICEoIWxpc3QgfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGxpc3QpICE9PSAnW29iamVjdCBBcnJheV0nKTtcclxufTtcclxuXHJcbnZhciBhZGRFbXB0eVBhcmFtZXRlciA9IGZ1bmN0aW9uKGxpc3QpIHtcclxuICByZXR1cm4gbGlzdC5jb25jYXQoWyB7IG5hbWU6ICcnLCB2YWx1ZTogJycgfSBdKTtcclxufTtcclxuXHJcbnZhciBjcmVhdGVPcHRpb24gPSBmdW5jdGlvbihvcHRpb24pIHtcclxuICByZXR1cm4gJzxvcHRpb24gdmFsdWU9XCInICsgb3B0aW9uLnZhbHVlICsgJ1wiPicgKyBvcHRpb24ubmFtZSArICc8L29wdGlvbj4nO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMuaWRcclxuICogQHBhcmFtICB7c3RyaW5nfSBbb3B0aW9ucy5sYWJlbF1cclxuICogQHBhcmFtICB7QXJyYXk8T2JqZWN0Pn0gb3B0aW9ucy5zZWxlY3RPcHRpb25zXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5tb2RlbFByb3BlcnR5XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IG9wdGlvbnMuZW1wdHlQYXJhbWV0ZXJcclxuICogQHBhcmFtICB7ZnVuY3Rpb259IG9wdGlvbnMuZGlzYWJsZWRcclxuICogQHBhcmFtICB7ZnVuY3Rpb259IG9wdGlvbnMuaGlkZGVuXHJcbiAqIEBwYXJhbSAge09iamVjdH0gZGVmYXVsdFBhcmFtZXRlcnNcclxuICpcclxuICogQHJldHVybiB7T2JqZWN0fVxyXG4gKi9cclxudmFyIHNlbGVjdGJveCA9IGZ1bmN0aW9uKG9wdGlvbnMsIGRlZmF1bHRQYXJhbWV0ZXJzKSB7XHJcbiAgdmFyIHJlc291cmNlID0gZGVmYXVsdFBhcmFtZXRlcnMsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCB8fCByZXNvdXJjZS5pZCxcclxuICAgICAgc2VsZWN0T3B0aW9ucyA9IG9wdGlvbnMuc2VsZWN0T3B0aW9ucyB8fCBbIHsgbmFtZTogJycsIHZhbHVlOiAnJyB9IF0sXHJcbiAgICAgIG1vZGVsUHJvcGVydHkgPSBvcHRpb25zLm1vZGVsUHJvcGVydHksXHJcbiAgICAgIGVtcHR5UGFyYW1ldGVyID0gb3B0aW9ucy5lbXB0eVBhcmFtZXRlcixcclxuICAgICAgY2FuQmVEaXNhYmxlZCA9ICEhb3B0aW9ucy5kaXNhYmxlZCAmJiB0eXBlb2Ygb3B0aW9ucy5kaXNhYmxlZCA9PT0gJ2Z1bmN0aW9uJyxcclxuICAgICAgY2FuQmVIaWRkZW4gPSAhIW9wdGlvbnMuaGlkZGVuICYmIHR5cGVvZiBvcHRpb25zLmhpZGRlbiA9PT0gJ2Z1bmN0aW9uJyxcclxuICAgICAgZGVzY3JpcHRpb24gPSBvcHRpb25zLmRlc2NyaXB0aW9uO1xyXG5cclxuXHJcbiAgaWYgKGVtcHR5UGFyYW1ldGVyKSB7XHJcbiAgICBzZWxlY3RPcHRpb25zID0gYWRkRW1wdHlQYXJhbWV0ZXIoc2VsZWN0T3B0aW9ucyk7XHJcbiAgfVxyXG5cclxuXHJcbiAgcmVzb3VyY2UuaHRtbCA9XHJcbiAgICAnPGxhYmVsIGZvcj1cImFjdGl2aXRpLScgKyBlc2NhcGVIVE1MKHJlc291cmNlLmlkKSArICdcIicgK1xyXG4gICAgKGNhbkJlRGlzYWJsZWQgPyAnZGF0YS1kaXNhYmxlPVwiaXNEaXNhYmxlZFwiICcgOiAnJykgK1xyXG4gICAgKGNhbkJlSGlkZGVuID8gJ2RhdGEtc2hvdz1cImlzSGlkZGVuXCIgJyA6ICcnKSArXHJcbiAgICAnPicgKyBlc2NhcGVIVE1MKGxhYmVsKSArICc8L2xhYmVsPicgK1xyXG4gICAgJzxzZWxlY3QgaWQ9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChyZXNvdXJjZS5pZCkgKyAnLXNlbGVjdFwiIG5hbWU9XCInICtcclxuICAgIGVzY2FwZUhUTUwobW9kZWxQcm9wZXJ0eSkgKyAnXCInICtcclxuICAgIChjYW5CZURpc2FibGVkID8gJ2RhdGEtZGlzYWJsZT1cImlzRGlzYWJsZWRcIiAnIDogJycpICtcclxuICAgIChjYW5CZUhpZGRlbiA/ICdkYXRhLXNob3c9XCJpc0hpZGRlblwiICcgOiAnJykgK1xyXG4gICAgJyBkYXRhLXZhbHVlPic7XHJcblxyXG4gIGlmIChpc0xpc3Qoc2VsZWN0T3B0aW9ucykpIHtcclxuICAgIGZvckVhY2goc2VsZWN0T3B0aW9ucywgZnVuY3Rpb24ob3B0aW9uKSB7XHJcbiAgICAgIHJlc291cmNlLmh0bWwgKz0gJzxvcHRpb24gdmFsdWU9XCInICsgZXNjYXBlSFRNTChvcHRpb24udmFsdWUpICsgJ1wiPicgK1xyXG4gICAgICAob3B0aW9uLm5hbWUgPyBlc2NhcGVIVE1MKG9wdGlvbi5uYW1lKSA6ICcnKSArICc8L29wdGlvbj4nO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXNvdXJjZS5odG1sICs9ICc8L3NlbGVjdD4nO1xyXG5cclxuICAvLyBhZGQgZGVzY3JpcHRpb24gYmVsb3cgc2VsZWN0IGJveCBlbnRyeSBmaWVsZFxyXG4gIGlmIChkZXNjcmlwdGlvbiAmJiB0eXBlb2Ygb3B0aW9ucy5zaG93Q3VzdG9tSW5wdXQgIT09ICdmdW5jdGlvbicpIHtcclxuICAgIHJlc291cmNlLmh0bWwgKz0gZW50cnlGaWVsZERlc2NyaXB0aW9uKGRlc2NyaXB0aW9uKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpbGwgdGhlIHNlbGVjdCBib3ggb3B0aW9ucyBkeW5hbWljYWxseS5cclxuICAgKlxyXG4gICAqIENhbGxzIHRoZSBkZWZpbmVkIGZ1bmN0aW9uICNzZWxlY3RPcHRpb25zIGluIHRoZSBlbnRyeSB0byBnZXQgdGhlXHJcbiAgICogdmFsdWVzIGZvciB0aGUgb3B0aW9ucyBhbmQgc2V0IHRoZSB2YWx1ZSB0byB0aGUgaW5wdXROb2RlLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVudHJ5Tm9kZVxyXG4gICAqIEBwYXJhbSB7RW50cnlEZXNjcmlwdG9yfSBpbnB1dE5vZGVcclxuICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXROYW1lXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IG5ld1ZhbHVlXHJcbiAgICovXHJcbiAgcmVzb3VyY2Uuc2V0Q29udHJvbFZhbHVlID0gZnVuY3Rpb24oZWxlbWVudCwgZW50cnlOb2RlLCBpbnB1dE5vZGUsIGlucHV0TmFtZSwgbmV3VmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2Ygc2VsZWN0T3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xyXG5cclxuICAgICAgdmFyIG9wdGlvbnMgPSBzZWxlY3RPcHRpb25zKGVsZW1lbnQsIGlucHV0Tm9kZSk7XHJcblxyXG4gICAgICBpZiAob3B0aW9ucykge1xyXG5cclxuICAgICAgICAvLyByZW1vdmUgZXhpc3Rpbmcgb3B0aW9uc1xyXG4gICAgICAgIHdoaWxlIChpbnB1dE5vZGUuZmlyc3RDaGlsZCkge1xyXG4gICAgICAgICAgaW5wdXROb2RlLnJlbW92ZUNoaWxkKGlucHV0Tm9kZS5maXJzdENoaWxkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGFkZCBvcHRpb25zXHJcbiAgICAgICAgZm9yRWFjaChvcHRpb25zLCBmdW5jdGlvbihvcHRpb24pIHtcclxuICAgICAgICAgIHZhciB0ZW1wbGF0ZSA9IGRvbWlmeShjcmVhdGVPcHRpb24ob3B0aW9uKSk7XHJcblxyXG4gICAgICAgICAgaW5wdXROb2RlLmFwcGVuZENoaWxkKHRlbXBsYXRlKTtcclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gc2V0IHNlbGVjdCB2YWx1ZVxyXG4gICAgaWYgKG5ld1ZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgaW5wdXROb2RlLnZhbHVlID0gbmV3VmFsdWU7XHJcbiAgICB9XHJcblxyXG4gIH07XHJcblxyXG4gIGlmIChjYW5CZURpc2FibGVkKSB7XHJcbiAgICByZXNvdXJjZS5pc0Rpc2FibGVkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgIHJldHVybiBvcHRpb25zLmRpc2FibGVkLmFwcGx5KHJlc291cmNlLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIGlmIChjYW5CZUhpZGRlbikge1xyXG4gICAgcmVzb3VyY2UuaXNIaWRkZW4gPSBmdW5jdGlvbigpIHtcclxuICAgICAgcmV0dXJuICFvcHRpb25zLmhpZGRlbi5hcHBseShyZXNvdXJjZSwgYXJndW1lbnRzKTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICByZXNvdXJjZS5jc3NDbGFzc2VzID0gWydicHAtZHJvcGRvd24nXTtcclxuXHJcbiAgcmV0dXJuIHJlc291cmNlO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzZWxlY3Rib3g7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlc2NhcGVIVE1MID0gcmVxdWlyZSgnLi4vVXRpbHMnKS5lc2NhcGVIVE1MO1xyXG5cclxudmFyIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbnZhciBkb21RdWVyeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeSxcclxuICAgIGRvbUF0dHIgPSByZXF1aXJlKCdtaW4tZG9tJykuYXR0cixcclxuICAgIGRvbUNsb3Nlc3QgPSByZXF1aXJlKCdtaW4tZG9tJykuY2xvc2VzdDtcclxuXHJcbnZhciBmaWx0ZXIgPSByZXF1aXJlKCdsb2Rhc2gvZmlsdGVyJyksXHJcbiAgICBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKSxcclxuICAgIGtleXMgPSByZXF1aXJlKCdsb2Rhc2gva2V5cycpO1xyXG5cclxudmFyIGRvbWlmeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5kb21pZnk7XHJcblxyXG52YXIgZW50cnlGaWVsZERlc2NyaXB0aW9uID0gcmVxdWlyZSgnLi9FbnRyeUZpZWxkRGVzY3JpcHRpb24nKTtcclxuXHJcbnZhciB1cGRhdGVTZWxlY3Rpb24gPSByZXF1aXJlKCdzZWxlY3Rpb24tdXBkYXRlJyk7XHJcblxyXG52YXIgVEFCTEVfUk9XX0RJVl9TTklQUEVUID0gJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlciBicHAtdGFibGUtcm93XCI+JztcclxudmFyIERFTEVURV9ST1dfQlVUVE9OX1NOSVBQRVQgPSAnPGJ1dHRvbiBjbGFzcz1cImNsZWFyXCIgZGF0YS1hY3Rpb249XCJkZWxldGVFbGVtZW50XCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHNwYW4+WDwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JztcclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUlucHV0Um93VGVtcGxhdGUocHJvcGVydGllcywgY2FuUmVtb3ZlKSB7XHJcbiAgdmFyIHRlbXBsYXRlID0gVEFCTEVfUk9XX0RJVl9TTklQUEVUO1xyXG4gIHRlbXBsYXRlICs9IGNyZWF0ZUlucHV0VGVtcGxhdGUocHJvcGVydGllcywgY2FuUmVtb3ZlKTtcclxuICB0ZW1wbGF0ZSArPSBjYW5SZW1vdmUgPyBERUxFVEVfUk9XX0JVVFRPTl9TTklQUEVUIDogJyc7XHJcbiAgdGVtcGxhdGUgKz0gJzwvZGl2Pic7XHJcblxyXG4gIHJldHVybiB0ZW1wbGF0ZTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlSW5wdXRUZW1wbGF0ZShwcm9wZXJ0aWVzLCBjYW5SZW1vdmUpIHtcclxuICB2YXIgY29sdW1ucyA9IHByb3BlcnRpZXMubGVuZ3RoO1xyXG4gIHZhciB0ZW1wbGF0ZSA9ICcnO1xyXG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24ocHJvcCkge1xyXG4gICAgdGVtcGxhdGUgKz0gJzxpbnB1dCBjbGFzcz1cImJwcC10YWJsZS1yb3ctY29sdW1ucy0nICsgY29sdW1ucyArICcgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2FuUmVtb3ZlID8gJ2JwcC10YWJsZS1yb3ctcmVtb3ZhYmxlJyA6ICcnKSArICdcIiAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAnaWQ9XCJhY3Rpdml0aS10YWJsZS1yb3ctY2VsbC1pbnB1dC12YWx1ZVwiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICd0eXBlPVwidGV4dFwiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICduYW1lPVwiJyArIGVzY2FwZUhUTUwocHJvcCkgKyAnXCIgLz4nO1xyXG4gIH0pO1xyXG4gIHJldHVybiB0ZW1wbGF0ZTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlTGFiZWxSb3dUZW1wbGF0ZShsYWJlbHMpIHtcclxuICB2YXIgdGVtcGxhdGUgPSBUQUJMRV9ST1dfRElWX1NOSVBQRVQ7XHJcbiAgdGVtcGxhdGUgKz0gY3JlYXRlTGFiZWxUZW1wbGF0ZShsYWJlbHMpO1xyXG4gIHRlbXBsYXRlICs9ICc8L2Rpdj4nO1xyXG5cclxuICByZXR1cm4gdGVtcGxhdGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUxhYmVsVGVtcGxhdGUobGFiZWxzKSB7XHJcbiAgdmFyIGNvbHVtbnMgPSBsYWJlbHMubGVuZ3RoO1xyXG4gIHZhciB0ZW1wbGF0ZSA9ICcnO1xyXG4gIGZvckVhY2gobGFiZWxzLCBmdW5jdGlvbihsYWJlbCkge1xyXG4gICAgdGVtcGxhdGUgKz0gJzxsYWJlbCBjbGFzcz1cImJwcC10YWJsZS1yb3ctY29sdW1ucy0nICsgY29sdW1ucyArICdcIj4nICsgZXNjYXBlSFRNTChsYWJlbCkgKyAnPC9sYWJlbD4nO1xyXG4gIH0pO1xyXG4gIHJldHVybiB0ZW1wbGF0ZTtcclxufVxyXG5cclxuZnVuY3Rpb24gcGljayhlbGVtZW50cywgcHJvcGVydGllcykge1xyXG4gIHJldHVybiAoZWxlbWVudHMgfHwgW10pLm1hcChmdW5jdGlvbihlbGVtKSB7XHJcbiAgICB2YXIgbmV3RWxlbWVudCA9IHt9O1xyXG4gICAgZm9yRWFjaChwcm9wZXJ0aWVzLCBmdW5jdGlvbihwcm9wKSB7XHJcbiAgICAgIG5ld0VsZW1lbnRbcHJvcF0gPSBlbGVtW3Byb3BdIHx8ICcnO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gbmV3RWxlbWVudDtcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gZGlmZihlbGVtZW50LCBub2RlLCB2YWx1ZXMsIG9sZFZhbHVlcywgZWRpdGFibGUpIHtcclxuICByZXR1cm4gZmlsdGVyKHZhbHVlcywgZnVuY3Rpb24odmFsdWUsIGlkeCkge1xyXG4gICAgcmV0dXJuICF2YWx1ZUVxdWFsKGVsZW1lbnQsIG5vZGUsIHZhbHVlLCBvbGRWYWx1ZXNbaWR4XSwgZWRpdGFibGUsIGlkeCk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHZhbHVlRXF1YWwoZWxlbWVudCwgbm9kZSwgdmFsdWUsIG9sZFZhbHVlLCBlZGl0YWJsZSwgaWR4KSB7XHJcbiAgaWYgKHZhbHVlICYmICFvbGRWYWx1ZSkge1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuICB2YXIgYWxsS2V5cyA9IGtleXModmFsdWUpLmNvbmNhdChrZXlzKG9sZFZhbHVlKSk7XHJcblxyXG4gIHJldHVybiBhbGxLZXlzLmV2ZXJ5KGZ1bmN0aW9uKGtleSkge1xyXG4gICAgdmFyIG4gPSB2YWx1ZVtrZXldIHx8IHVuZGVmaW5lZDtcclxuICAgIHZhciBvID0gb2xkVmFsdWVba2V5XSB8fCB1bmRlZmluZWQ7XHJcbiAgICByZXR1cm4gIWVkaXRhYmxlKGVsZW1lbnQsIG5vZGUsIGtleSwgaWR4KSB8fCBuID09PSBvO1xyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRFbnRyeU5vZGUobm9kZSkge1xyXG4gIHJldHVybiBkb21DbG9zZXN0KG5vZGUsICdbZGF0YS1lbnRyeV0nLCB0cnVlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0Q29udGFpbmVyKG5vZGUpIHtcclxuICByZXR1cm4gZG9tUXVlcnkoJ2RpdltkYXRhLWxpc3QtZW50cnktY29udGFpbmVyXScsIG5vZGUpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb24obm9kZSkge1xyXG4gIHJldHVybiB7XHJcbiAgICBzdGFydDogbm9kZS5zZWxlY3Rpb25TdGFydCxcclxuICAgIGVuZDogbm9kZS5zZWxlY3Rpb25FbmRcclxuICB9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRTZWxlY3Rpb24obm9kZSwgc2VsZWN0aW9uKSB7XHJcbiAgbm9kZS5zZWxlY3Rpb25TdGFydCA9IHNlbGVjdGlvbi5zdGFydDtcclxuICBub2RlLnNlbGVjdGlvbkVuZCA9IHNlbGVjdGlvbi5lbmQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmlkXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5kZXNjcmlwdGlvblxyXG4gKiBAcGFyYW0gIHtBcnJheTxzdHJpbmc+fSBvcHRpb25zLm1vZGVsUHJvcGVydGllc1xyXG4gKiBAcGFyYW0gIHtBcnJheTxzdHJpbmc+fSBvcHRpb25zLmxhYmVsc1xyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gb3B0aW9ucy5nZXRFbGVtZW50cyAtIHRoaXMgY2FsbGJhY2sgZnVuY3Rpb24gbXVzdCByZXR1cm4gYSBsaXN0IG9mIGJ1c2luZXNzIG9iamVjdCBpdGVtc1xyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gb3B0aW9ucy5yZW1vdmVFbGVtZW50XHJcbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBvcHRpb25zLmFkZEVsZW1lbnRcclxuICogQHBhcmFtICB7RnVuY3Rpb259IG9wdGlvbnMudXBkYXRlRWxlbWVudFxyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gb3B0aW9ucy5lZGl0YWJsZVxyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gb3B0aW9ucy5zZXRDb250cm9sVmFsdWVcclxuICogQHBhcmFtICB7RnVuY3Rpb259IG9wdGlvbnMuc2hvd1xyXG4gKlxyXG4gKiBAcmV0dXJuIHtPYmplY3R9XHJcbiAqL1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuXHJcbiAgdmFyIGlkID0gb3B0aW9ucy5pZCxcclxuICAgICAgbW9kZWxQcm9wZXJ0aWVzID0gb3B0aW9ucy5tb2RlbFByb3BlcnRpZXMsXHJcbiAgICAgIGxhYmVscyA9IG9wdGlvbnMubGFiZWxzLFxyXG4gICAgICBkZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb247XHJcblxyXG4gIHZhciBsYWJlbFJvdyA9IGNyZWF0ZUxhYmVsUm93VGVtcGxhdGUobGFiZWxzKTtcclxuXHJcbiAgdmFyIGdldEVsZW1lbnRzID0gb3B0aW9ucy5nZXRFbGVtZW50cztcclxuXHJcbiAgdmFyIHJlbW92ZUVsZW1lbnQgPSBvcHRpb25zLnJlbW92ZUVsZW1lbnQsXHJcbiAgICAgIGNhblJlbW92ZSA9IHR5cGVvZiByZW1vdmVFbGVtZW50ID09PSAnZnVuY3Rpb24nO1xyXG5cclxuICB2YXIgYWRkRWxlbWVudCA9IG9wdGlvbnMuYWRkRWxlbWVudCxcclxuICAgICAgY2FuQWRkID0gdHlwZW9mIGFkZEVsZW1lbnQgPT09ICdmdW5jdGlvbicsXHJcbiAgICAgIGFkZExhYmVsID0gb3B0aW9ucy5hZGRMYWJlbCB8fCAnQWRkIFZhbHVlJztcclxuXHJcbiAgdmFyIHVwZGF0ZUVsZW1lbnQgPSBvcHRpb25zLnVwZGF0ZUVsZW1lbnQsXHJcbiAgICAgIGNhblVwZGF0ZSA9IHR5cGVvZiB1cGRhdGVFbGVtZW50ID09PSAnZnVuY3Rpb24nO1xyXG5cclxuICB2YXIgZWRpdGFibGUgPSBvcHRpb25zLmVkaXRhYmxlIHx8IGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSxcclxuICAgICAgc2V0Q29udHJvbFZhbHVlID0gb3B0aW9ucy5zZXRDb250cm9sVmFsdWU7XHJcblxyXG4gIHZhciBzaG93ID0gb3B0aW9ucy5zaG93LFxyXG4gICAgICBjYW5CZVNob3duID0gdHlwZW9mIHNob3cgPT09ICdmdW5jdGlvbic7XHJcblxyXG4gIHZhciBlbGVtZW50cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHJldHVybiBwaWNrKGdldEVsZW1lbnRzKGVsZW1lbnQsIG5vZGUpLCBtb2RlbFByb3BlcnRpZXMpO1xyXG4gIH07XHJcblxyXG4gIHZhciBmYWN0b3J5ID0ge1xyXG4gICAgaWQ6IGlkLFxyXG4gICAgaHRtbDogKGNhbkFkZCA/XHJcbiAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLXRhYmxlLWFkZC1yb3dcIiAnICsgKGNhbkJlU2hvd24gPyAnZGF0YS1zaG93PVwic2hvd1wiJyA6ICcnKSArICc+JyArXHJcbiAgICAgICAgICAgICc8bGFiZWw+JyArIGVzY2FwZUhUTUwoYWRkTGFiZWwpICsgJzwvbGFiZWw+JyArXHJcbiAgICAgICAgICAgICc8YnV0dG9uIGNsYXNzPVwiYWRkXCIgZGF0YS1hY3Rpb249XCJhZGRFbGVtZW50XCI+PHNwYW4+Kzwvc3Bhbj48L2J1dHRvbj4nICtcclxuICAgICAgICAgICc8L2Rpdj4nIDogJycpICtcclxuICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLXRhYmxlXCIgZGF0YS1zaG93PVwic2hvd1RhYmxlXCI+JyArXHJcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXIgYnBwLXRhYmxlLXJvd1wiPicgK1xyXG4gICAgICAgICAgICAgICBsYWJlbFJvdyArXHJcbiAgICAgICAgICAgICc8L2Rpdj4nICtcclxuICAgICAgICAgICAgJzxkaXYgZGF0YS1saXN0LWVudHJ5LWNvbnRhaW5lcj4nICtcclxuICAgICAgICAgICAgJzwvZGl2PicgK1xyXG4gICAgICAgICAgJzwvZGl2PicgK1xyXG5cclxuICAgICAgICAgIC8vIGFkZCBkZXNjcmlwdGlvbiBiZWxvdyB0YWJsZSBlbnRyeSBmaWVsZFxyXG4gICAgICAgICAgKGRlc2NyaXB0aW9uID8gZW50cnlGaWVsZERlc2NyaXB0aW9uKGRlc2NyaXB0aW9uKSA6ICcnKSxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvRWxlbWVudHMgPSBlbGVtZW50cyhlbGVtZW50LCBub2RlLCB0aGlzLl9faW52YWxpZFZhbHVlcyk7XHJcblxyXG4gICAgICB2YXIgaW52YWxpZFZhbHVlcyA9IHRoaXMuX19pbnZhbGlkVmFsdWVzO1xyXG5cclxuICAgICAgZGVsZXRlIHRoaXMuX19pbnZhbGlkVmFsdWVzO1xyXG5cclxuICAgICAgZm9yRWFjaChpbnZhbGlkVmFsdWVzLCBmdW5jdGlvbih2YWx1ZSwgaWR4KSB7XHJcbiAgICAgICAgdmFyIGVsZW1lbnQgPSBib0VsZW1lbnRzW2lkeF07XHJcblxyXG4gICAgICAgIGZvckVhY2gobW9kZWxQcm9wZXJ0aWVzLCBmdW5jdGlvbihwcm9wKSB7XHJcbiAgICAgICAgICBlbGVtZW50W3Byb3BdID0gdmFsdWVbcHJvcF07XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgcmV0dXJuIGJvRWxlbWVudHM7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBhY3Rpb24gPSB0aGlzLl9fYWN0aW9uIHx8IHt9O1xyXG4gICAgICBkZWxldGUgdGhpcy5fX2FjdGlvbjtcclxuXHJcbiAgICAgIGlmIChhY3Rpb24uaWQgPT09ICdkZWxldGUtZWxlbWVudCcpIHtcclxuICAgICAgICByZXR1cm4gcmVtb3ZlRWxlbWVudChlbGVtZW50LCBub2RlLCBhY3Rpb24uaWR4KTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmIChhY3Rpb24uaWQgPT09ICdhZGQtZWxlbWVudCcpIHtcclxuICAgICAgICByZXR1cm4gYWRkRWxlbWVudChlbGVtZW50LCBub2RlKTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmIChjYW5VcGRhdGUpIHtcclxuICAgICAgICB2YXIgY29tbWFuZHMgPSBbXSxcclxuICAgICAgICAgICAgdmFsdWVzVG9WYWxpZGF0ZSA9IHZhbHVlcztcclxuXHJcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnZhbGlkYXRlICE9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICB2YWx1ZXNUb1ZhbGlkYXRlID0gZGlmZihlbGVtZW50LCBub2RlLCB2YWx1ZXMsIGVsZW1lbnRzKGVsZW1lbnQsIG5vZGUpLCBlZGl0YWJsZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgICAgIGZvckVhY2godmFsdWVzVG9WYWxpZGF0ZSwgZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICAgIHZhciB2YWxpZGF0aW9uRXJyb3IsXHJcbiAgICAgICAgICAgICAgaWR4ID0gdmFsdWVzLmluZGV4T2YodmFsdWUpO1xyXG5cclxuICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy52YWxpZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9uRXJyb3IgPSBvcHRpb25zLnZhbGlkYXRlKGVsZW1lbnQsIHZhbHVlLCBub2RlLCBpZHgpO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGlmICghdmFsaWRhdGlvbkVycm9yKSB7XHJcbiAgICAgICAgICAgIHZhciBjbWQgPSB1cGRhdGVFbGVtZW50KGVsZW1lbnQsIHZhbHVlLCBub2RlLCBpZHgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNtZCkge1xyXG4gICAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goY21kKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gY2FjaGUgaW52YWxpZCB2YWx1ZSBpbiBhbiBvYmplY3QgYnkgaW5kZXggYXMga2V5XHJcbiAgICAgICAgICAgIHNlbGYuX19pbnZhbGlkVmFsdWVzID0gc2VsZi5fX2ludmFsaWRWYWx1ZXMgfHwge307XHJcbiAgICAgICAgICAgIHNlbGYuX19pbnZhbGlkVmFsdWVzW2lkeF0gPSB2YWx1ZTtcclxuXHJcbiAgICAgICAgICAgIC8vIGV4ZWN1dGUgYSBjb21tYW5kLCB3aGljaCBkb2VzIG5vdCBkbyBhbnl0aGluZ1xyXG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHt9KSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIGNyZWF0ZUxpc3RFbnRyeVRlbXBsYXRlOiBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIHNlbGVjdEJveCkge1xyXG4gICAgICByZXR1cm4gY3JlYXRlSW5wdXRSb3dUZW1wbGF0ZShtb2RlbFByb3BlcnRpZXMsIGNhblJlbW92ZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50LCBzY29wZU5vZGUpIHtcclxuICAgICAgdmFyIHRlbXBsYXRlID0gZG9taWZ5KGNyZWF0ZUlucHV0Um93VGVtcGxhdGUobW9kZWxQcm9wZXJ0aWVzLCBjYW5SZW1vdmUpKTtcclxuXHJcbiAgICAgIHZhciBjb250YWluZXIgPSBnZXRDb250YWluZXIobm9kZSk7XHJcbiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0ZW1wbGF0ZSk7XHJcblxyXG4gICAgICB0aGlzLl9fYWN0aW9uID0ge1xyXG4gICAgICAgIGlkOiAnYWRkLWVsZW1lbnQnXHJcbiAgICAgIH07XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgZGVsZXRlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgZXZlbnQsIHNjb3BlTm9kZSkge1xyXG4gICAgICB2YXIgY29udGFpbmVyID0gZ2V0Q29udGFpbmVyKG5vZGUpO1xyXG4gICAgICB2YXIgcm93VG9EZWxldGUgPSBldmVudC5kZWxlZ2F0ZVRhcmdldC5wYXJlbnROb2RlO1xyXG4gICAgICB2YXIgaWR4ID0gcGFyc2VJbnQoZG9tQXR0cihyb3dUb0RlbGV0ZSwgJ2RhdGEtaW5kZXgnKSwgMTApO1xyXG5cclxuICAgICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKHJvd1RvRGVsZXRlKTtcclxuXHJcbiAgICAgIHRoaXMuX19hY3Rpb24gPSB7XHJcbiAgICAgICAgaWQ6ICdkZWxldGUtZWxlbWVudCcsXHJcbiAgICAgICAgaWR4OiBpZHhcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICBlZGl0YWJsZTogZnVuY3Rpb24oZWxlbWVudCwgcm93Tm9kZSwgaW5wdXQsIHByb3AsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGVudHJ5Tm9kZSA9IGRvbUNsb3Nlc3Qocm93Tm9kZSwgJ1tkYXRhLWVudHJ5XScpO1xyXG4gICAgICByZXR1cm4gZWRpdGFibGUoZWxlbWVudCwgZW50cnlOb2RlLCBwcm9wLCBpZHgpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzaG93OiBmdW5jdGlvbihlbGVtZW50LCBlbnRyeU5vZGUsIG5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICBlbnRyeU5vZGUgPSBnZXRFbnRyeU5vZGUoZW50cnlOb2RlKTtcclxuICAgICAgcmV0dXJuIHNob3coZWxlbWVudCwgZW50cnlOb2RlLCBub2RlLCBzY29wZU5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzaG93VGFibGU6IGZ1bmN0aW9uKGVsZW1lbnQsIGVudHJ5Tm9kZSwgbm9kZSwgc2NvcGVOb2RlKSB7XHJcbiAgICAgIGVudHJ5Tm9kZSA9IGdldEVudHJ5Tm9kZShlbnRyeU5vZGUpO1xyXG4gICAgICB2YXIgZWxlbXMgPSBlbGVtZW50cyhlbGVtZW50LCBlbnRyeU5vZGUpO1xyXG4gICAgICByZXR1cm4gZWxlbXMgJiYgZWxlbXMubGVuZ3RoICYmICghY2FuQmVTaG93biB8fCBzaG93KGVsZW1lbnQsIGVudHJ5Tm9kZSwgbm9kZSwgc2NvcGVOb2RlKSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkYXRlTGlzdEl0ZW06IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlLCBub2RlLCBpZHgpIHtcclxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnZhbGlkYXRlID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMudmFsaWRhdGUoZWxlbWVudCwgdmFsdWUsIG5vZGUsIGlkeCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgfTtcclxuXHJcbiAgLy8gVXBkYXRlL3NldCB0aGUgc2VsZWN0aW9uIG9uIHRoZSBjb3JyZWN0IHBvc2l0aW9uLlxyXG4gIC8vIEl0J3MgdGhlIHNhbWUgY29kZSBsaWtlIGZvciBhbiBpbnB1dCB2YWx1ZSBpbiB0aGUgUHJvcGVydGllc1BhbmVsLmpzLlxyXG4gIGlmIChzZXRDb250cm9sVmFsdWUpIHtcclxuICAgIGZhY3Rvcnkuc2V0Q29udHJvbFZhbHVlID0gZnVuY3Rpb24oZWxlbWVudCwgcm93Tm9kZSwgaW5wdXQsIHByb3AsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGVudHJ5Tm9kZSA9IGdldEVudHJ5Tm9kZShyb3dOb2RlKTtcclxuXHJcbiAgICAgIHZhciBpc1JlYWRPbmx5ID0gZG9tQXR0cihpbnB1dCwgJ3JlYWRvbmx5Jyk7XHJcbiAgICAgIHZhciBvbGRWYWx1ZSA9IGlucHV0LnZhbHVlO1xyXG5cclxuICAgICAgdmFyIHNlbGVjdGlvbjtcclxuXHJcbiAgICAgIC8vIHByZXZlbnRzIGlucHV0IGZpZWxkcyBmcm9tIGhhdmluZyB0aGUgdmFsdWUgJ3VuZGVmaW5lZCdcclxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICB2YWx1ZSA9ICcnO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyB3aGVuIHRoZSBhdHRyaWJ1dGUgJ3JlYWRvbmx5JyBleGlzdHMsIGlnbm9yZSB0aGUgY29tcGFyaXNvblxyXG4gICAgICAvLyB3aXRoICdvbGRWYWx1ZScgYW5kICd2YWx1ZSdcclxuICAgICAgaWYgKCEhaXNSZWFkT25seSAmJiBvbGRWYWx1ZSA9PT0gdmFsdWUpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBzZWxlY3Rpb24gb24gdW5kby9yZWRvXHJcbiAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBpbnB1dCkge1xyXG4gICAgICAgIHNlbGVjdGlvbiA9IHVwZGF0ZVNlbGVjdGlvbihnZXRTZWxlY3Rpb24oaW5wdXQpLCBvbGRWYWx1ZSwgdmFsdWUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZXRDb250cm9sVmFsdWUoZWxlbWVudCwgZW50cnlOb2RlLCBpbnB1dCwgcHJvcCwgdmFsdWUsIGlkeCk7XHJcblxyXG4gICAgICBpZiAoc2VsZWN0aW9uKSB7XHJcbiAgICAgICAgc2V0U2VsZWN0aW9uKGlucHV0LCBzZWxlY3Rpb24pO1xyXG4gICAgICB9XHJcblxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJldHVybiBmYWN0b3J5O1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVzY2FwZUhUTUwgPSByZXF1aXJlKCcuLi9VdGlscycpLmVzY2FwZUhUTUw7XHJcblxyXG52YXIgZW50cnlGaWVsZERlc2NyaXB0aW9uID0gcmVxdWlyZSgnLi9FbnRyeUZpZWxkRGVzY3JpcHRpb24nKTtcclxuXHJcblxyXG52YXIgdGV4dEJveCA9IGZ1bmN0aW9uKG9wdGlvbnMsIGRlZmF1bHRQYXJhbWV0ZXJzKSB7XHJcblxyXG4gIHZhciByZXNvdXJjZSA9IGRlZmF1bHRQYXJhbWV0ZXJzLFxyXG4gICAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgcmVzb3VyY2UuaWQsXHJcbiAgICAgIGNhbkJlU2hvd24gPSAhIW9wdGlvbnMuc2hvdyAmJiB0eXBlb2Ygb3B0aW9ucy5zaG93ID09PSAnZnVuY3Rpb24nLFxyXG4gICAgICBkZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb247XHJcblxyXG4gIHJlc291cmNlLmh0bWwgPVxyXG4gICAgJzxsYWJlbCBmb3I9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChyZXNvdXJjZS5pZCkgKyAnXCIgJyArXHJcbiAgICAoY2FuQmVTaG93biA/ICdkYXRhLXNob3c9XCJpc1Nob3duXCInIDogJycpICtcclxuICAgICc+JyArIGxhYmVsICsgJzwvbGFiZWw+JyArXHJcbiAgICAnPGRpdiBjbGFzcz1cImJwcC1maWVsZC13cmFwcGVyXCIgJyArXHJcbiAgICAoY2FuQmVTaG93biA/ICdkYXRhLXNob3c9XCJpc1Nob3duXCInIDogJycpICtcclxuICAgICc+JyArXHJcbiAgICAgICc8ZGl2IGNvbnRlbnRlZGl0YWJsZT1cInRydWVcIiBpZD1cImFjdGl2aXRpLScgKyBlc2NhcGVIVE1MKHJlc291cmNlLmlkKSArICdcIiAnICtcclxuICAgICAgICAgICAgJ25hbWU9XCInICsgZXNjYXBlSFRNTChvcHRpb25zLm1vZGVsUHJvcGVydHkpICsgJ1wiIC8+JyArXHJcbiAgICAnPC9kaXY+JztcclxuXHJcbiAgLy8gYWRkIGRlc2NyaXB0aW9uIGJlbG93IHRleHQgYm94IGVudHJ5IGZpZWxkXHJcbiAgaWYgKGRlc2NyaXB0aW9uKSB7XHJcbiAgICByZXNvdXJjZS5odG1sICs9IGVudHJ5RmllbGREZXNjcmlwdGlvbihkZXNjcmlwdGlvbik7XHJcbiAgfVxyXG5cclxuICBpZiAoY2FuQmVTaG93bikge1xyXG4gICAgcmVzb3VyY2UuaXNTaG93biA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5zaG93LmFwcGx5KHJlc291cmNlLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJlc291cmNlLmNzc0NsYXNzZXMgPSBbJ2JwcC10ZXh0Ym94J107XHJcblxyXG4gIHJldHVybiByZXNvdXJjZTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdGV4dEJveDtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVzY2FwZUhUTUwgPSByZXF1aXJlKCcuLi9VdGlscycpLmVzY2FwZUhUTUw7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnk7XHJcblxyXG52YXIgZW50cnlGaWVsZERlc2NyaXB0aW9uID0gcmVxdWlyZSgnLi9FbnRyeUZpZWxkRGVzY3JpcHRpb24nKTtcclxuXHJcblxyXG52YXIgdGV4dEZpZWxkID0gZnVuY3Rpb24ob3B0aW9ucywgZGVmYXVsdFBhcmFtZXRlcnMpIHtcclxuXHJcbiAgLy8gRGVmYXVsdCBhY3Rpb24gZm9yIHRoZSBidXR0b24gbmV4dCB0byB0aGUgaW5wdXQtZmllbGRcclxuICB2YXIgZGVmYXVsdEJ1dHRvbkFjdGlvbiA9IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSkge1xyXG4gICAgdmFyIGlucHV0ID0gZG9tUXVlcnkoJ2lucHV0W25hbWU9XCInICsgb3B0aW9ucy5tb2RlbFByb3BlcnR5ICsgJ1wiXScsIGlucHV0Tm9kZSk7XHJcbiAgICBpbnB1dC52YWx1ZSA9ICcnO1xyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH07XHJcblxyXG4gIC8vIGRlZmF1bHQgbWV0aG9kIHRvIGRldGVybWluZSBpZiB0aGUgYnV0dG9uIHNob3VsZCBiZSB2aXNpYmxlXHJcbiAgdmFyIGRlZmF1bHRCdXR0b25TaG93ID0gZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlKSB7XHJcbiAgICB2YXIgaW5wdXQgPSBkb21RdWVyeSgnaW5wdXRbbmFtZT1cIicgKyBvcHRpb25zLm1vZGVsUHJvcGVydHkgKyAnXCJdJywgaW5wdXROb2RlKTtcclxuXHJcbiAgICByZXR1cm4gaW5wdXQudmFsdWUgIT09ICcnO1xyXG4gIH07XHJcblxyXG5cclxuICB2YXIgcmVzb3VyY2UgPSBkZWZhdWx0UGFyYW1ldGVycyxcclxuICAgICAgbGFiZWwgPSBvcHRpb25zLmxhYmVsIHx8IHJlc291cmNlLmlkLFxyXG4gICAgICBkYXRhVmFsdWVMYWJlbCA9IG9wdGlvbnMuZGF0YVZhbHVlTGFiZWwsXHJcbiAgICAgIGJ1dHRvbkxhYmVsID0gKG9wdGlvbnMuYnV0dG9uTGFiZWwgfHwgJ1gnKSxcclxuICAgICAgYWN0aW9uTmFtZSA9ICh0eXBlb2Ygb3B0aW9ucy5idXR0b25BY3Rpb24gIT0gJ3VuZGVmaW5lZCcpID8gb3B0aW9ucy5idXR0b25BY3Rpb24ubmFtZSA6ICdjbGVhcicsXHJcbiAgICAgIGFjdGlvbk1ldGhvZCA9ICh0eXBlb2Ygb3B0aW9ucy5idXR0b25BY3Rpb24gIT0gJ3VuZGVmaW5lZCcpID8gb3B0aW9ucy5idXR0b25BY3Rpb24ubWV0aG9kIDogZGVmYXVsdEJ1dHRvbkFjdGlvbixcclxuICAgICAgc2hvd05hbWUgPSAodHlwZW9mIG9wdGlvbnMuYnV0dG9uU2hvdyAhPSAndW5kZWZpbmVkJykgPyBvcHRpb25zLmJ1dHRvblNob3cubmFtZSA6ICdjYW5DbGVhcicsXHJcbiAgICAgIHNob3dNZXRob2QgPSAodHlwZW9mIG9wdGlvbnMuYnV0dG9uU2hvdyAhPSAndW5kZWZpbmVkJykgPyBvcHRpb25zLmJ1dHRvblNob3cubWV0aG9kIDogZGVmYXVsdEJ1dHRvblNob3csXHJcbiAgICAgIGNhbkJlRGlzYWJsZWQgPSAhIW9wdGlvbnMuZGlzYWJsZWQgJiYgdHlwZW9mIG9wdGlvbnMuZGlzYWJsZWQgPT09ICdmdW5jdGlvbicsXHJcbiAgICAgIGNhbkJlSGlkZGVuID0gISFvcHRpb25zLmhpZGRlbiAmJiB0eXBlb2Ygb3B0aW9ucy5oaWRkZW4gPT09ICdmdW5jdGlvbicsXHJcbiAgICAgIGRlc2NyaXB0aW9uID0gb3B0aW9ucy5kZXNjcmlwdGlvbjtcclxuXHJcbiAgcmVzb3VyY2UuaHRtbCA9XHJcbiAgICAnPGxhYmVsIGZvcj1cImFjdGl2aXRpLScgKyBlc2NhcGVIVE1MKHJlc291cmNlLmlkKSArICdcIiAnICtcclxuICAgICAgKGNhbkJlRGlzYWJsZWQgPyAnZGF0YS1kaXNhYmxlPVwiaXNEaXNhYmxlZFwiICcgOiAnJykgK1xyXG4gICAgICAoY2FuQmVIaWRkZW4gPyAnZGF0YS1zaG93PVwiaXNIaWRkZW5cIiAnIDogJycpICtcclxuICAgICAgKGRhdGFWYWx1ZUxhYmVsID8gJ2RhdGEtdmFsdWU9XCInICsgZXNjYXBlSFRNTChkYXRhVmFsdWVMYWJlbCkgKyAnXCInIDogJycpICsgJz4nKyBlc2NhcGVIVE1MKGxhYmVsKSArJzwvbGFiZWw+JyArXHJcbiAgICAnPGRpdiBjbGFzcz1cImJwcC1maWVsZC13cmFwcGVyXCIgJyArXHJcbiAgICAgIChjYW5CZURpc2FibGVkID8gJ2RhdGEtZGlzYWJsZT1cImlzRGlzYWJsZWRcIicgOiAnJykgK1xyXG4gICAgICAoY2FuQmVIaWRkZW4gPyAnZGF0YS1zaG93PVwiaXNIaWRkZW5cIicgOiAnJykgK1xyXG4gICAgICAnPicgK1xyXG4gICAgICAnPGlucHV0IGlkPVwiYWN0aXZpdGktJyArIGVzY2FwZUhUTUwocmVzb3VyY2UuaWQpICsgJ1wiIHR5cGU9XCJ0ZXh0XCIgbmFtZT1cIicgKyBlc2NhcGVIVE1MKG9wdGlvbnMubW9kZWxQcm9wZXJ0eSkgKyAnXCIgJyArXHJcbiAgICAgICAgKGNhbkJlRGlzYWJsZWQgPyAnZGF0YS1kaXNhYmxlPVwiaXNEaXNhYmxlZFwiJyA6ICcnKSArXHJcbiAgICAgICAgKGNhbkJlSGlkZGVuID8gJ2RhdGEtc2hvdz1cImlzSGlkZGVuXCInIDogJycpICtcclxuICAgICAgICAnIC8+JyArXHJcbiAgICAgICc8YnV0dG9uIGNsYXNzPVwiJyArIGVzY2FwZUhUTUwoYWN0aW9uTmFtZSkgKyAnXCIgZGF0YS1hY3Rpb249XCInICsgZXNjYXBlSFRNTChhY3Rpb25OYW1lKSArICdcIiBkYXRhLXNob3c9XCInICsgZXNjYXBlSFRNTChzaG93TmFtZSkgKyAnXCIgJyArXHJcbiAgICAgICAgKGNhbkJlRGlzYWJsZWQgPyAnZGF0YS1kaXNhYmxlPVwiaXNEaXNhYmxlZFwiJyA6ICcnKSArXHJcbiAgICAgICAgKGNhbkJlSGlkZGVuID8gJyBkYXRhLXNob3c9XCJpc0hpZGRlblwiJyA6ICcnKSArICc+JyArXHJcbiAgICAgICAgJzxzcGFuPicgKyBlc2NhcGVIVE1MKGJ1dHRvbkxhYmVsKSArICc8L3NwYW4+JyArXHJcbiAgICAgICc8L2J1dHRvbj4nICtcclxuICAgICc8L2Rpdj4nO1xyXG5cclxuICAvLyBhZGQgZGVzY3JpcHRpb24gYmVsb3cgdGV4dCBpbnB1dCBlbnRyeSBmaWVsZFxyXG4gIGlmIChkZXNjcmlwdGlvbikge1xyXG4gICAgcmVzb3VyY2UuaHRtbCArPSBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgcmVzb3VyY2VbYWN0aW9uTmFtZV0gPSBhY3Rpb25NZXRob2Q7XHJcbiAgcmVzb3VyY2Vbc2hvd05hbWVdID0gc2hvd01ldGhvZDtcclxuXHJcbiAgaWYgKGNhbkJlRGlzYWJsZWQpIHtcclxuICAgIHJlc291cmNlLmlzRGlzYWJsZWQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgcmV0dXJuIG9wdGlvbnMuZGlzYWJsZWQuYXBwbHkocmVzb3VyY2UsIGFyZ3VtZW50cyk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgaWYgKGNhbkJlSGlkZGVuKSB7XHJcbiAgICByZXNvdXJjZS5pc0hpZGRlbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICByZXR1cm4gIW9wdGlvbnMuaGlkZGVuLmFwcGx5KHJlc291cmNlLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJlc291cmNlLmNzc0NsYXNzZXMgPSBbJ2JwcC10ZXh0ZmllbGQnXTtcclxuXHJcbiAgcmV0dXJuIHJlc291cmNlO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0ZXh0RmllbGQ7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciB0ZXh0RmllbGQgPSByZXF1aXJlKCcuL1RleHRJbnB1dEVudHJ5RmFjdG9yeScpO1xyXG5cclxuLyoqXHJcbiAqIFRoaXMgZnVuY3Rpb24gaXMgYSB3cmFwcGVyIGFyb3VuZCBUZXh0SW5wdXRFbnRyeUZhY3RvcnkuXHJcbiAqIEl0IGFkZHMgZnVuY3Rpb25hbGl0eSB0byBjYWNoZSBhbiBpbnZhbGlkIHZhbHVlIGVudGVyZWQgaW4gdGhlXHJcbiAqIHRleHQgaW5wdXQsIGluc3RlYWQgb2Ygc2V0dGluZyBpdCBvbiB0aGUgYnVzaW5lc3Mgb2JqZWN0LlxyXG4gKi9cclxudmFyIHZhbGlkYXRpb25Bd2FyZVRleHRGaWVsZCA9IGZ1bmN0aW9uKG9wdGlvbnMsIGRlZmF1bHRQYXJhbWV0ZXJzKSB7XHJcblxyXG4gIHZhciBtb2RlbFByb3BlcnR5ID0gb3B0aW9ucy5tb2RlbFByb3BlcnR5O1xyXG5cclxuICBkZWZhdWx0UGFyYW1ldGVycy5nZXQgPSBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICB2YXIgdmFsdWUgPSB0aGlzLl9fbGFzdEludmFsaWRWYWx1ZTtcclxuXHJcbiAgICBkZWxldGUgdGhpcy5fX2xhc3RJbnZhbGlkVmFsdWU7XHJcblxyXG4gICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcclxuXHJcbiAgICBwcm9wZXJ0aWVzW21vZGVsUHJvcGVydHldID0gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDogb3B0aW9ucy5nZXRQcm9wZXJ0eShlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICByZXR1cm4gcHJvcGVydGllcztcclxuICB9O1xyXG5cclxuICBkZWZhdWx0UGFyYW1ldGVycy5zZXQgPSBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgIHZhciB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGUuYXBwbHkodGhpcywgWyBlbGVtZW50LCB2YWx1ZXMsIG5vZGUgXSksXHJcbiAgICAgICAgcHJvcGVydHlWYWx1ZSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XTtcclxuXHJcbiAgICAvLyBtYWtlIHN1cmUgd2UgZG8gbm90IHVwZGF0ZSB0aGUgaWRcclxuICAgIGlmICh2YWxpZGF0aW9uRXJyb3JzICYmIHZhbGlkYXRpb25FcnJvcnNbbW9kZWxQcm9wZXJ0eV0pIHtcclxuICAgICAgdGhpcy5fX2xhc3RJbnZhbGlkVmFsdWUgPSBwcm9wZXJ0eVZhbHVlO1xyXG5cclxuICAgICAgcmV0dXJuIG9wdGlvbnMuc2V0UHJvcGVydHkoZWxlbWVudCwge30sIG5vZGUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcclxuXHJcbiAgICAgIHByb3BlcnRpZXNbbW9kZWxQcm9wZXJ0eV0gPSBwcm9wZXJ0eVZhbHVlO1xyXG5cclxuICAgICAgcmV0dXJuIG9wdGlvbnMuc2V0UHJvcGVydHkoZWxlbWVudCwgcHJvcGVydGllcywgbm9kZSk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgdmFyIHZhbGlkYXRlID0gZGVmYXVsdFBhcmFtZXRlcnMudmFsaWRhdGUgPSBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgIHZhciB2YWx1ZSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XSB8fCB0aGlzLl9fbGFzdEludmFsaWRWYWx1ZTtcclxuXHJcbiAgICB2YXIgcHJvcGVydHkgPSB7fTtcclxuICAgIHByb3BlcnR5W21vZGVsUHJvcGVydHldID0gdmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIG9wdGlvbnMudmFsaWRhdGUoZWxlbWVudCwgcHJvcGVydHksIG5vZGUpO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiB0ZXh0RmllbGQob3B0aW9ucywgZGVmYXVsdFBhcmFtZXRlcnMpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB2YWxpZGF0aW9uQXdhcmVUZXh0RmllbGQ7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBtYXAgPSByZXF1aXJlKCdsb2Rhc2gvbWFwJyk7XHJcblxyXG52YXIgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIgPSByZXF1aXJlKCcuL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyJyk7XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgJ2FjdGl2aXRpOmFzeW5jQmVmb3JlJyBpcyBzZXRcclxuICogdG8gdHJ1ZS5cclxuICpcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gYm9cclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBpc0FzeW5jQmVmb3JlKGJvKSB7XHJcbiAgcmV0dXJuICEhKGJvLmdldCgnYWN0aXZpdGk6YXN5bmNCZWZvcmUnKSB8fCBiby5nZXQoJ2FjdGl2aXRpOmFzeW5jJykpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5pc0FzeW5jQmVmb3JlID0gaXNBc3luY0JlZm9yZTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGF0dHJpYnV0ZSAnYWN0aXZpdGk6YXN5bmNBZnRlcicgaXMgc2V0XHJcbiAqIHRvIHRydWUuXHJcbiAqXHJcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnR9IGJvXHJcbiAqXHJcbiAqIEByZXR1cm4ge2Jvb2xlYW59IGEgYm9vbGVhbiB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gaXNBc3luY0FmdGVyKGJvKSB7XHJcbiAgcmV0dXJuICEhYm8uZ2V0KCdhY3Rpdml0aTphc3luY0FmdGVyJyk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmlzQXN5bmNBZnRlciA9IGlzQXN5bmNBZnRlcjtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGF0dHJpYnV0ZSAnYWN0aXZpdGk6ZXhjbHVzaXZlJyBpcyBzZXRcclxuICogdG8gdHJ1ZS5cclxuICpcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gYm9cclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBpc0V4Y2x1c2l2ZShibykge1xyXG4gIHJldHVybiAhIWJvLmdldCgnYWN0aXZpdGk6ZXhjbHVzaXZlJyk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmlzRXhjbHVzaXZlID0gaXNFeGNsdXNpdmU7XHJcblxyXG4vKipcclxuICogR2V0IGZpcnN0ICdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZScgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0LlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50fSBib1xyXG4gKlxyXG4gKiBAcmV0dXJuIHtBcnJheTxNb2RkbGVFbGVtZW50Pn0gYSBsaXN0IG9mICdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZSdcclxuICovXHJcbmZ1bmN0aW9uIGdldEZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGJvKSB7XHJcbiAgcmV0dXJuIChleHRlbnNpb25FbGVtZW50c0hlbHBlci5nZXRFeHRlbnNpb25FbGVtZW50cyhibywgJ2FjdGl2aXRpOkZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlJykgfHwgW10pWzBdO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5nZXRGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZSA9IGdldEZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlO1xyXG5cclxuLyoqXHJcbiAqIFJlbW92ZXMgYWxsIGV4aXN0aW5nICdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZScgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0XHJcbiAqXHJcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnR9IGJvXHJcbiAqXHJcbiAqIEByZXR1cm4ge0FycmF5PE1vZGRsZUVsZW1lbnQ+fSBhIGxpc3Qgb2YgJ2FjdGl2aXRpOkZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlJ1xyXG4gKi9cclxuZnVuY3Rpb24gcmVtb3ZlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUoYm8sIGVsZW1lbnQpIHtcclxuICB2YXIgcmV0cnlUaW1lQ3ljbGVzID0gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZScpO1xyXG4gIHJldHVybiBtYXAocmV0cnlUaW1lQ3ljbGVzLCBmdW5jdGlvbihjeWNsZSkge1xyXG4gICAgcmV0dXJuIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLnJlbW92ZUVudHJ5KGJvLCBlbGVtZW50LCBjeWNsZSk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLnJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlID0gcmVtb3ZlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGU7IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGNvbGxlY3Rpb25BZGQgPSByZXF1aXJlKCdkaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zJykuYWRkLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIENhdGVnb3J5SGVscGVyID0ge307XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IENhdGVnb3J5SGVscGVyO1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgYnBtbjpDYXRlZ29yeVZhbHVlIGluc2lkZSBhIG5ldyBicG1uOkNhdGVnb3J5XHJcbiAqXHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gZGVmaW5pdGlvbnNcclxuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gY2F0ZWdvcnlWYWx1ZS5cclxuICovXHJcbkNhdGVnb3J5SGVscGVyLmNyZWF0ZUNhdGVnb3J5VmFsdWUgPSBmdW5jdGlvbihkZWZpbml0aW9ucywgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgY2F0ZWdvcnlWYWx1ZSA9IGJwbW5GYWN0b3J5LmNyZWF0ZSgnYnBtbjpDYXRlZ29yeVZhbHVlJyksXHJcbiAgICAgIGNhdGVnb3J5ID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkNhdGVnb3J5Jywge1xyXG4gICAgICAgIGNhdGVnb3J5VmFsdWU6IFsgY2F0ZWdvcnlWYWx1ZSBdXHJcbiAgICAgIH0pO1xyXG5cclxuICAvLyBhZGQgdG8gY29ycmVjdCBwbGFjZVxyXG4gIGNvbGxlY3Rpb25BZGQoZGVmaW5pdGlvbnMuZ2V0KCdyb290RWxlbWVudHMnKSwgY2F0ZWdvcnkpO1xyXG4gIGdldEJ1c2luZXNzT2JqZWN0KGNhdGVnb3J5KS4kcGFyZW50ID0gZGVmaW5pdGlvbnM7XHJcbiAgZ2V0QnVzaW5lc3NPYmplY3QoY2F0ZWdvcnlWYWx1ZSkuJHBhcmVudCA9IGNhdGVnb3J5O1xyXG5cclxuICByZXR1cm4gY2F0ZWdvcnlWYWx1ZTtcclxuXHJcbn07IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIENtZEhlbHBlciA9IHt9O1xyXG5tb2R1bGUuZXhwb3J0cyA9IENtZEhlbHBlcjtcclxuXHJcbkNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzID0gZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiB7XHJcbiAgICBjbWQ6ICdlbGVtZW50LnVwZGF0ZVByb3BlcnRpZXMnLFxyXG4gICAgY29udGV4dDogeyBlbGVtZW50OiBlbGVtZW50LCBwcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzIH1cclxuICB9O1xyXG59O1xyXG5cclxuQ21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0ID0gZnVuY3Rpb24oZWxlbWVudCwgYnVzaW5lc3NPYmplY3QsIG5ld1Byb3BlcnRpZXMpIHtcclxuICByZXR1cm4ge1xyXG4gICAgY21kOiAncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QnLFxyXG4gICAgY29udGV4dDoge1xyXG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICBidXNpbmVzc09iamVjdDogYnVzaW5lc3NPYmplY3QsXHJcbiAgICAgIHByb3BlcnRpZXM6IG5ld1Byb3BlcnRpZXNcclxuICAgIH1cclxuICB9O1xyXG59O1xyXG5cclxuQ21kSGVscGVyLmFkZEVsZW1lbnRzVG9saXN0ID0gZnVuY3Rpb24oZWxlbWVudCwgYnVzaW5lc3NPYmplY3QsIGxpc3RQcm9wZXJ0eU5hbWUsIG9iamVjdHNUb0FkZCkge1xyXG4gIHJldHVybiB7XHJcbiAgICBjbWQ6ICdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0JyxcclxuICAgIGNvbnRleHQ6IHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgY3VycmVudE9iamVjdDogYnVzaW5lc3NPYmplY3QsXHJcbiAgICAgIHByb3BlcnR5TmFtZTogbGlzdFByb3BlcnR5TmFtZSxcclxuICAgICAgb2JqZWN0c1RvQWRkOiBvYmplY3RzVG9BZGRcclxuICAgIH1cclxuICB9O1xyXG59O1xyXG5cclxuQ21kSGVscGVyLnJlbW92ZUVsZW1lbnRzRnJvbUxpc3QgPSBmdW5jdGlvbihlbGVtZW50LCBidXNpbmVzc09iamVjdCwgbGlzdFByb3BlcnR5TmFtZSwgcmVmZXJlbmNlUHJvcGVydHlOYW1lLCBvYmplY3RzVG9SZW1vdmUpIHtcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGNtZDogJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0LWxpc3QnLFxyXG4gICAgY29udGV4dDoge1xyXG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICBjdXJyZW50T2JqZWN0OiBidXNpbmVzc09iamVjdCxcclxuICAgICAgcHJvcGVydHlOYW1lOiBsaXN0UHJvcGVydHlOYW1lLFxyXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eU5hbWU6IHJlZmVyZW5jZVByb3BlcnR5TmFtZSxcclxuICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvYmplY3RzVG9SZW1vdmVcclxuICAgIH1cclxuICB9O1xyXG59O1xyXG5cclxuXHJcbkNtZEhlbHBlci5hZGRBbmRSZW1vdmVFbGVtZW50c0Zyb21MaXN0ID0gZnVuY3Rpb24oZWxlbWVudCwgYnVzaW5lc3NPYmplY3QsIGxpc3RQcm9wZXJ0eU5hbWUsIHJlZmVyZW5jZVByb3BlcnR5TmFtZSwgb2JqZWN0c1RvQWRkLCBvYmplY3RzVG9SZW1vdmUpIHtcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGNtZDogJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0LWxpc3QnLFxyXG4gICAgY29udGV4dDoge1xyXG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICBjdXJyZW50T2JqZWN0OiBidXNpbmVzc09iamVjdCxcclxuICAgICAgcHJvcGVydHlOYW1lOiBsaXN0UHJvcGVydHlOYW1lLFxyXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eU5hbWU6IHJlZmVyZW5jZVByb3BlcnR5TmFtZSxcclxuICAgICAgb2JqZWN0c1RvQWRkOiBvYmplY3RzVG9BZGQsXHJcbiAgICAgIG9iamVjdHNUb1JlbW92ZTogb2JqZWN0c1RvUmVtb3ZlXHJcbiAgICB9XHJcbiAgfTtcclxufTtcclxuXHJcblxyXG5DbWRIZWxwZXIuc2V0TGlzdCA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJ1c2luZXNzT2JqZWN0LCBsaXN0UHJvcGVydHlOYW1lLCB1cGRhdGVkT2JqZWN0TGlzdCkge1xyXG4gIHJldHVybiB7XHJcbiAgICBjbWQ6ICdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0JyxcclxuICAgIGNvbnRleHQ6IHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgY3VycmVudE9iamVjdDogYnVzaW5lc3NPYmplY3QsXHJcbiAgICAgIHByb3BlcnR5TmFtZTogbGlzdFByb3BlcnR5TmFtZSxcclxuICAgICAgdXBkYXRlZE9iamVjdExpc3Q6IHVwZGF0ZWRPYmplY3RMaXN0XHJcbiAgICB9XHJcbiAgfTtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIEVsZW1lbnRIZWxwZXIgPSB7fTtcclxubW9kdWxlLmV4cG9ydHMgPSBFbGVtZW50SGVscGVyO1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgZWxlbWVudCBhbmQgc2V0IHRoZSBwYXJlbnQgdG8gaXRcclxuICpcclxuICogQG1ldGhvZCBFbGVtZW50SGVscGVyI2NyZWF0ZUVsZW1lbnRcclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGVsZW1lbnRUeXBlIG9mIHRoZSBuZXcgZWxlbWVudFxyXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBvZiB0aGUgbmV3IGVsZW1lbnQgaW4ga2V5LXZhbHVlIHBhaXJzXHJcbiAqIEBwYXJhbSB7bW9kZGxlLm9iamVjdH0gcGFyZW50IG9mIHRoZSBuZXcgZWxlbWVudFxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBmYWN0b3J5IHdoaWNoIGNyZWF0ZXMgdGhlIG5ldyBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm5zIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudCB3aGljaCBpcyBjcmVhdGVkXHJcbiAqL1xyXG5FbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50VHlwZSwgcHJvcGVydGllcywgcGFyZW50LCBmYWN0b3J5KSB7XHJcbiAgdmFyIGVsZW1lbnQgPSBmYWN0b3J5LmNyZWF0ZShlbGVtZW50VHlwZSwgcHJvcGVydGllcyk7XHJcbiAgZWxlbWVudC4kcGFyZW50ID0gcGFyZW50O1xyXG5cclxuICByZXR1cm4gZWxlbWVudDtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xyXG5cclxudmFyIEV2ZW50RGVmaW5pdGlvbkhlbHBlciA9IHt9O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBFdmVudERlZmluaXRpb25IZWxwZXI7XHJcblxyXG5FdmVudERlZmluaXRpb25IZWxwZXIuZ2V0RXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCwgZXZlbnRUeXBlKSB7XHJcblxyXG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxyXG4gICAgICBldmVudERlZmluaXRpb24gPSBudWxsO1xyXG5cclxuICBpZiAoYm8uZXZlbnREZWZpbml0aW9ucykge1xyXG4gICAgZm9yRWFjaChiby5ldmVudERlZmluaXRpb25zLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgICBpZiAoaXMoZXZlbnQsIGV2ZW50VHlwZSkpIHtcclxuICAgICAgICBldmVudERlZmluaXRpb24gPSBldmVudDtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZXZlbnREZWZpbml0aW9uO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldFRpbWVyRXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLmdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpUaW1lckV2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldE1lc3NhZ2VFdmVudERlZmluaXRpb24gPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0RXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKTtcclxufTtcclxuXHJcbkV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRTaWduYWxFdmVudERlZmluaXRpb24gPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0RXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldEVycm9yRXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLmdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpFcnJvckV2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldEVzY2FsYXRpb25FdmVudERlZmluaXRpb24gPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0RXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOkVzY2FsYXRpb25FdmVudERlZmluaXRpb24nKTtcclxufTtcclxuXHJcbkV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLmdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uJyk7XHJcbn07XHJcblxyXG5FdmVudERlZmluaXRpb25IZWxwZXIuZ2V0TGlua0V2ZW50RGVmaW5pdGlvbiA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gdGhpcy5nZXRFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldENvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLmdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgY21kSGVscGVyID0gcmVxdWlyZSgnLi9DbWRIZWxwZXInKSxcclxuICAgIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuL0VsZW1lbnRIZWxwZXInKTtcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIgPSB7fTtcclxuXHJcbnZhciBnZXRFeHRlbnNpb25FbGVtZW50cyA9IGZ1bmN0aW9uKGJvKSB7XHJcbiAgcmV0dXJuIGJvLmdldCgnZXh0ZW5zaW9uRWxlbWVudHMnKTtcclxufTtcclxuXHJcbkV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLmdldEV4dGVuc2lvbkVsZW1lbnRzID0gZnVuY3Rpb24oYm8sIHR5cGUpIHtcclxuICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBnZXRFeHRlbnNpb25FbGVtZW50cyhibyk7XHJcbiAgaWYgKHR5cGVvZiBleHRlbnNpb25FbGVtZW50cyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHZhciBleHRlbnNpb25WYWx1ZXMgPSBleHRlbnNpb25FbGVtZW50cy5nZXQoJ3ZhbHVlcycpO1xyXG4gICAgaWYgKHR5cGVvZiBleHRlbnNpb25WYWx1ZXMgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHZhciBlbGVtZW50cyA9IGV4dGVuc2lvblZhbHVlcy5maWx0ZXIoZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICByZXR1cm4gaXModmFsdWUsIHR5cGUpO1xyXG4gICAgICB9KTtcclxuICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBlbGVtZW50cztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufTtcclxuXHJcbkV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLmFkZEVudHJ5ID0gZnVuY3Rpb24oYm8sIGVsZW1lbnQsIGVudHJ5LCBicG1uRmFjdG9yeSkge1xyXG4gIHZhciBleHRlbnNpb25FbGVtZW50cyA9IGJvLmdldCgnZXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuXHJcbiAgLy8gaWYgdGhlcmUgaXMgbm8gZXh0ZW5zaW9uRWxlbWVudHMgbGlzdCwgY3JlYXRlIG9uZVxyXG4gIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgIC8vIFRPRE86IEFzayBEYW5pZWwgd2hpY2ggb3BlcmF0aW9uIGNvc3RzIG1vcmVcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJywgeyB2YWx1ZXM6IFtlbnRyeV0gfSwgYm8sIGJwbW5GYWN0b3J5KTtcclxuICAgIHJldHVybiB7IGV4dGVuc2lvbkVsZW1lbnRzIDogZXh0ZW5zaW9uRWxlbWVudHMgfTtcclxuICB9IGVsc2Uge1xyXG4gICAgLy8gYWRkIG5ldyBmYWlsZWRKb2JSZXRyeUV4dGVuc2lvbkVsZW1lbnQgdG8gZXhpc3RpbmcgZXh0ZW5zaW9uRWxlbWVudHMgbGlzdFxyXG4gICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgJ3ZhbHVlcycsIFtlbnRyeV0pO1xyXG4gIH1cclxufTtcclxuXHJcbkV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLnJlbW92ZUVudHJ5ID0gZnVuY3Rpb24oYm8sIGVsZW1lbnQsIGVudHJ5KSB7XHJcbiAgdmFyIGV4dGVuc2lvbkVsZW1lbnRzID0gYm8uZ2V0KCdleHRlbnNpb25FbGVtZW50cycpO1xyXG5cclxuICBpZiAoIWV4dGVuc2lvbkVsZW1lbnRzKSB7XHJcblxyXG4gICAgLy8gcmV0dXJuIGFuIGVtcHR5IGNvbW1hbmQgd2hlbiB0aGVyZSBpcyBubyBleHRlbnNpb25FbGVtZW50cyBsaXN0XHJcbiAgICByZXR1cm4ge307XHJcbiAgfVxyXG5cclxuICByZXR1cm4gY21kSGVscGVyLnJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsICd2YWx1ZXMnLCAnZXh0ZW5zaW9uRWxlbWVudHMnLCBbZW50cnldKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXI7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBnZXRFeHRlbnNpb25FbGVtZW50cyA9IHJlcXVpcmUoJy4vRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXInKS5nZXRFeHRlbnNpb25FbGVtZW50cztcclxuXHJcbnZhciBGb3JtSGVscGVyID0ge307XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEZvcm1IZWxwZXI7XHJcblxyXG4vKipcclxuICogUmV0dXJuIGZvcm0gZGF0YSBmcm9tIGJ1c2luZXNzIG9iamVjdCBvciB1bmRlZmluZWQgaWYgbm9uZSBleGlzdFxyXG4gKlxyXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fHVuZGVmaW5lZH0gZm9ybURhdGFcclxuICpcclxuICog5q2k5pa55rOV5bqf5byDXHJcbiAqXHJcbiAqL1xyXG5Gb3JtSGVscGVyLmdldEZvcm1EYXRhID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gLyogdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBmb3JtRmllbGRzID0gZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpGb3JtUHJvcGVydHknKTtcclxuXHJcbiAgdmFyIGZvcm1EYXRhID0ge31cclxuXHJcbiAgaWYgKHR5cGVvZiBmb3JtRGF0YSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJldHVybiBmb3JtRGF0YVswXTtcclxuICB9Ki9cclxuIHJldHVybiB7fTtcclxufTtcclxuXHJcblxyXG4vKipcclxuICogUmV0dXJuIGFsbCBmb3JtIGZpZWxkcyBleGlzdGluZyBpbiB0aGUgYnVzaW5lc3Mgb2JqZWN0LCBhbmRcclxuICogYW4gZW1wdHkgYXJyYXkgaWYgbm9uZSBleGlzdC5cclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7QXJyYXl9IGEgbGlzdCBvZiBmb3JtIGZpZWxkIG9iamVjdHNcclxuICovXHJcbkZvcm1IZWxwZXIuZ2V0Rm9ybUZpZWxkcyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuXHJcbiAgLyoq55u05o6l6I635Y+WIEV4dGVuc2lvbkVsZW1lbnRz55qEIGFjdGl2aXRpOkZvcm1Qcm9wZXJ0eeWFg+e0oCovXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBmb3JtRmllbGRzID0gZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpGb3JtUHJvcGVydHknKTtcclxuXHJcbiAgcmV0dXJuIGZvcm1GaWVsZHMgfHwgW107XHJcbn07XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBhIGZvcm0gZmllbGQgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0IGF0IGdpdmVuIGluZGV4XHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtIHtudW1iZXJ9IGlkeFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fSB0aGUgZm9ybSBmaWVsZFxyXG4gKi9cclxuRm9ybUhlbHBlci5nZXRGb3JtRmllbGQgPSBmdW5jdGlvbihlbGVtZW50LCBpZHgpIHtcclxuXHJcbiAgdmFyIGZvcm1GaWVsZHMgPSB0aGlzLmdldEZvcm1GaWVsZHMoZWxlbWVudCk7XHJcblxyXG4gIHJldHVybiBmb3JtRmllbGRzW2lkeF07XHJcbn07XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBhbGwgY29uc3RyYWludHMgZm9yIGEgc3BlY2lmaWMgZm9ybSBmaWVsZCBmcm9tIHRoZSBidXNpbmVzcyBvYmplY3RcclxuICpcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gZm9ybUZpZWxkXHJcbiAqXHJcbiAqIEByZXR1cm4ge0FycmF5PE1vZGRsZUVsZW1lbnQ+fSBhIGxpc3Qgb2YgY29uc3RyYWludCBvYmplY3RzXHJcbiAqL1xyXG5Gb3JtSGVscGVyLmdldENvbnN0cmFpbnRzID0gZnVuY3Rpb24oZm9ybUZpZWxkKSB7XHJcbiAgaWYgKGZvcm1GaWVsZCAmJiBmb3JtRmllbGQudmFsaWRhdGlvbiAmJiBmb3JtRmllbGQudmFsaWRhdGlvbi5jb25zdHJhaW50cykge1xyXG4gICAgcmV0dXJuIGZvcm1GaWVsZC52YWxpZGF0aW9uLmNvbnN0cmFpbnRzO1xyXG4gIH1cclxuICByZXR1cm4gW107XHJcbn07XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBhbGwgYWN0aXZpdGk6dmFsdWUgb2JqZWN0cyBmb3IgYSBzcGVjaWZpYyBmb3JtIGZpZWxkIGZyb20gdGhlIGJ1c2luZXNzIG9iamVjdFxyXG4gKlxyXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50fSBmb3JtRmllbGRcclxuICpcclxuICogQHJldHVybiB7QXJyYXk8TW9kZGxlRWxlbWVudD59IGEgbGlzdCBvZiBhY3Rpdml0aTp2YWx1ZSBvYmplY3RzXHJcbiAqL1xyXG5Gb3JtSGVscGVyLmdldEVudW1WYWx1ZXMgPSBmdW5jdGlvbihmb3JtRmllbGQpIHtcclxuICBpZiAoZm9ybUZpZWxkICYmIGZvcm1GaWVsZC52YWx1ZXMpIHtcclxuICAgIHJldHVybiBmb3JtRmllbGQudmFsdWVzO1xyXG4gIH1cclxuICByZXR1cm4gW107XHJcbn07XHJcblxyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgTW9kZWxVdGlsID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKSxcclxuICAgIGlzID0gTW9kZWxVdGlsLmlzLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBNb2RlbFV0aWwuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgZXZlbnREZWZpbml0aW9uSGVscGVyID0gcmVxdWlyZSgnLi9FdmVudERlZmluaXRpb25IZWxwZXInKTtcclxudmFyIGV4dGVuc2lvbnNFbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpO1xyXG5cclxudmFyIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlciA9IHt9O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXI7XHJcblxyXG4vKipcclxuICogUmV0dXJucyAndHJ1ZScgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgJ2FjdGl2aXRpOlNlcnZpY2VUYXNrTGlrZSdcclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtib29sZWFufSBhIGJvb2xlYW4gdmFsdWVcclxuICovXHJcbkltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5pc1NlcnZpY2VUYXNrTGlrZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2FjdGl2aXRpOlNlcnZpY2VUYXNrTGlrZScpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgJ3RydWUnIGlmIHRoZSBnaXZlbiBlbGVtZW50IGlzICdhY3Rpdml0aTpEbW5DYXBhYmxlJ1xyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge2Jvb2xlYW59IGEgYm9vbGVhbiB2YWx1ZVxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzRG1uQ2FwYWJsZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2FjdGl2aXRpOkRtbkNhcGFibGUnKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zICd0cnVlJyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBpcyAnYWN0aXZpdGk6RXh0ZXJuYWxDYXBhYmxlJ1xyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge2Jvb2xlYW59IGEgYm9vbGVhbiB2YWx1ZVxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzRXh0ZXJuYWxDYXBhYmxlID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiBpcyhlbGVtZW50LCAnYWN0aXZpdGk6RXh0ZXJuYWxDYXBhYmxlJyk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyAndHJ1ZScgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgJ2FjdGl2aXRpOlRhc2tMaXN0ZW5lcidcclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtib29sZWFufSBhIGJvb2xlYW4gdmFsdWVcclxuICovXHJcbkltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5pc1Rhc2tMaXN0ZW5lciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2FjdGl2aXRpOlRhc2tMaXN0ZW5lcicpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgJ3RydWUnIGlmIHRoZSBnaXZlbiBlbGVtZW50IGlzICdhY3Rpdml0aTpFeGVjdXRpb25MaXN0ZW5lcidcclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtib29sZWFufSBhIGJvb2xlYW4gdmFsdWVcclxuICovXHJcbkltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5pc0V4ZWN1dGlvbkxpc3RlbmVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiBpcyhlbGVtZW50LCAnYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXInKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zICd0cnVlJyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBpcyAnYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXInIG9yXHJcbiAqICdhY3Rpdml0aTpUYXNrTGlzdGVuZXInXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuaXNMaXN0ZW5lciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gdGhpcy5pc1Rhc2tMaXN0ZW5lcihlbGVtZW50KSB8fCB0aGlzLmlzRXhlY3V0aW9uTGlzdGVuZXIoZWxlbWVudCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyAndHJ1ZScgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgJ2JwbW46U2VxdWVuY2VGbG93J1xyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge2Jvb2xlYW59IGEgYm9vbGVhbiB2YWx1ZVxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzU2VxdWVuY2VGbG93ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpTZXF1ZW5jZUZsb3cnKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSAnYWN0aXZpdGk6U2VydmljZVRhc2tMaWtlJyBidXNpbmVzcyBvYmplY3QuXHJcbiAqXHJcbiAqIElmIHRoZSBnaXZlbiBlbGVtZW50IGlzIG5vdCBhICdhY3Rpdml0aTpTZXJ2aWNlVGFza0xpa2UnLCB0aGVuICdmYWxzZSdcclxuICogaXMgcmV0dXJuZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gdGhlICdhY3Rpdml0aTpTZXJ2aWNlVGFza0xpa2UnIGJ1c2luZXNzIG9iamVjdFxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldFNlcnZpY2VUYXNrTGlrZUJ1c2luZXNzT2JqZWN0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcpIHx8IGlzKGVsZW1lbnQsICdicG1uOkVuZEV2ZW50JykpIHtcclxuXHJcbiAgICAvLyBjaGFuZ2UgYnVzaW5lc3Mgb2JqZWN0IHRvICdtZXNzYWdlRXZlbnREZWZpbml0aW9uJyB3aGVuXHJcbiAgICAvLyB0aGUgZWxlbWVudCBpcyBhIG1lc3NhZ2UgaW50ZXJtZWRpYXRlIHRocm93IGV2ZW50IG9yIG1lc3NhZ2UgZW5kIGV2ZW50XHJcbiAgICAvLyBiZWNhdXNlIHRoZSBhY3Rpdml0aSBleHRlbnNpb25zIChlLmcuIGFjdGl2aXRpOmNsYXNzKSBhcmUgaW4gdGhlIG1lc3NhZ2VcclxuICAgIC8vIGV2ZW50IGRlZmluaXRpb24gdGFnIGFuZCBub3QgaW4gdGhlIGludGVybWVkaWF0ZSB0aHJvdyBldmVudCBvciBlbmQgZXZlbnQgdGFnXHJcbiAgICB2YXIgbWVzc2FnZUV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRNZXNzYWdlRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG4gICAgaWYgKG1lc3NhZ2VFdmVudERlZmluaXRpb24pIHtcclxuICAgICAgZWxlbWVudCA9IG1lc3NhZ2VFdmVudERlZmluaXRpb247XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5pc1NlcnZpY2VUYXNrTGlrZShlbGVtZW50KSAmJiBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgaW1wbGVtZW50YXRpb24gdHlwZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICpcclxuICogUG9zc2libGUgaW1wbGVtZW50YXRpb24gdHlwZXMgYXJlOlxyXG4gKiAtIGRtblxyXG4gKiAtIGNvbm5lY3RvclxyXG4gKiAtIGV4dGVybmFsXHJcbiAqIC0gY2xhc3NcclxuICogLSBleHByZXNzaW9uXHJcbiAqIC0gZGVsZWdhdGVFeHByZXNzaW9uXHJcbiAqIC0gc2NyaXB0XHJcbiAqIC0gb3IgdW5kZWZpbmVkLCB3aGVuIG5vIG1hdGNoaW5nIGltcGxlbWVudGF0aW9uIHR5cGUgaXMgZm91bmRcclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7U3RyaW5nfSB0aGUgaW1wbGVtZW50YXRpb24gdHlwZVxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldEltcGxlbWVudGF0aW9uVHlwZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuXHJcbiAgdmFyIGJvID0gdGhpcy5nZXRTZXJ2aWNlVGFza0xpa2VCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgaWYgKCFibykge1xyXG4gICAgaWYgKHRoaXMuaXNMaXN0ZW5lcihlbGVtZW50KSkge1xyXG4gICAgICBibyA9IGVsZW1lbnQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZiAodGhpcy5pc0RtbkNhcGFibGUoYm8pKSB7XHJcbiAgICB2YXIgZGVjaXNpb25SZWYgPSBiby5nZXQoJ2FjdGl2aXRpOmRlY2lzaW9uUmVmJyk7XHJcbiAgICBpZiAodHlwZW9mIGRlY2lzaW9uUmVmICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICByZXR1cm4gJ2Rtbic7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZiAodGhpcy5pc1NlcnZpY2VUYXNrTGlrZShibykpIHtcclxuICAgIHZhciBjb25uZWN0b3JzID0gZXh0ZW5zaW9uc0VsZW1lbnRIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpDb25uZWN0b3InKTtcclxuICAgIGlmICh0eXBlb2YgY29ubmVjdG9ycyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgcmV0dXJuICdjb25uZWN0b3InO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKHRoaXMuaXNFeHRlcm5hbENhcGFibGUoYm8pKSB7XHJcbiAgICB2YXIgdHlwZSA9IGJvLmdldCgnYWN0aXZpdGk6dHlwZScpO1xyXG4gICAgaWYgKHR5cGUgPT09ICdleHRlcm5hbCcpIHtcclxuICAgICAgcmV0dXJuICdleHRlcm5hbCc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB2YXIgY2xzID0gYm8uZ2V0KCdhY3Rpdml0aTpjbGFzcycpO1xyXG4gIGlmICh0eXBlb2YgY2xzICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmV0dXJuICdjbGFzcyc7XHJcbiAgfVxyXG5cclxuICB2YXIgZXhwcmVzc2lvbiA9IGJvLmdldCgnYWN0aXZpdGk6ZXhwcmVzc2lvbicpO1xyXG4gIGlmICh0eXBlb2YgZXhwcmVzc2lvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJldHVybiAnZXhwcmVzc2lvbic7XHJcbiAgfVxyXG5cclxuICB2YXIgZGVsZWdhdGVFeHByZXNzaW9uID0gYm8uZ2V0KCdhY3Rpdml0aTpkZWxlZ2F0ZUV4cHJlc3Npb24nKTtcclxuICBpZiAodHlwZW9mIGRlbGVnYXRlRXhwcmVzc2lvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJldHVybiAnZGVsZWdhdGVFeHByZXNzaW9uJztcclxuICB9XHJcblxyXG4gIGlmICh0aGlzLmlzTGlzdGVuZXIoYm8pKSB7XHJcbiAgICB2YXIgc2NyaXB0ID0gYm8uZ2V0KCdzY3JpcHQnKTtcclxuICAgIGlmICh0eXBlb2Ygc2NyaXB0ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICByZXR1cm4gJ3NjcmlwdCc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIE1vZGVsVXRpbCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJyksXHJcbiAgICBpcyA9IE1vZGVsVXRpbC5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gTW9kZWxVdGlsLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyID0gcmVxdWlyZSgnLi9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpLFxyXG4gICAgaW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi9JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXInKTtcclxuXHJcbnZhciBJbnB1dE91dHB1dEhlbHBlciA9IHt9O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBJbnB1dE91dHB1dEhlbHBlcjtcclxuXHJcbmZ1bmN0aW9uIGdldEVsZW1lbnRzKGJvLCB0eXBlLCBwcm9wKSB7XHJcbiAgdmFyIGVsZW1zID0gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sIHR5cGUpIHx8IFtdO1xyXG4gIHJldHVybiAhcHJvcCA/IGVsZW1zIDogKGVsZW1zWzBdIHx8IHt9KVtwcm9wXSB8fCBbXTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0UGFyYW1ldGVycyhlbGVtZW50LCBwcm9wLCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICB2YXIgaW5wdXRPdXRwdXQgPSBJbnB1dE91dHB1dEhlbHBlci5nZXRJbnB1dE91dHB1dChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG4gIHJldHVybiAoaW5wdXRPdXRwdXQgJiYgaW5wdXRPdXRwdXQuZ2V0KHByb3ApKSB8fCBbXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBhIGlucHV0T3V0cHV0IGZyb20gdGhlIGJ1c2luZXNzIG9iamVjdFxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGluc2lkZUNvbm5lY3RvclxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fSB0aGUgaW5wdXRPdXRwdXQgb2JqZWN0XHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5nZXRJbnB1dE91dHB1dCA9IGZ1bmN0aW9uKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcikge1xyXG4gIGlmICghaW5zaWRlQ29ubmVjdG9yKSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgIHJldHVybiAoZ2V0RWxlbWVudHMoYm8sICdhY3Rpdml0aTpJbnB1dE91dHB1dCcpIHx8IFtdKVswXTtcclxuICB9XHJcbiAgdmFyIGNvbm5lY3RvciA9IHRoaXMuZ2V0Q29ubmVjdG9yKGVsZW1lbnQpO1xyXG4gIHJldHVybiBjb25uZWN0b3IgJiYgY29ubmVjdG9yLmdldCgnaW5wdXRPdXRwdXQnKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBjb25uZWN0b3IgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0XHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gdGhlIGNvbm5lY3RvciBvYmplY3RcclxuICovXHJcbklucHV0T3V0cHV0SGVscGVyLmdldENvbm5lY3RvciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICB2YXIgYm8gPSBpbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0U2VydmljZVRhc2tMaWtlQnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgcmV0dXJuIGJvICYmIChnZXRFbGVtZW50cyhibywgJ2FjdGl2aXRpOkNvbm5lY3RvcicpIHx8IFtdKVswXTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm4gYWxsIGlucHV0IHBhcmFtZXRlcnMgZXhpc3RpbmcgaW4gdGhlIGJ1c2luZXNzIG9iamVjdCwgYW5kXHJcbiAqIGFuIGVtcHR5IGFycmF5IGlmIG5vbmUgZXhpc3QuXHJcbiAqXHJcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGluc2lkZUNvbm5lY3RvclxyXG4gKlxyXG4gKiBAcmV0dXJuIHtBcnJheX0gYSBsaXN0IG9mIGlucHV0IHBhcmFtZXRlciBvYmplY3RzXHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5nZXRJbnB1dFBhcmFtZXRlcnMgPSBmdW5jdGlvbihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICByZXR1cm4gZ2V0UGFyYW1ldGVycy5hcHBseSh0aGlzLCBbIGVsZW1lbnQsICdpbnB1dFBhcmFtZXRlcnMnLCBpbnNpZGVDb25uZWN0b3IgXSk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJuIGFsbCBvdXRwdXQgcGFyYW1ldGVycyBleGlzdGluZyBpbiB0aGUgYnVzaW5lc3Mgb2JqZWN0LCBhbmRcclxuICogYW4gZW1wdHkgYXJyYXkgaWYgbm9uZSBleGlzdC5cclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtICB7Ym9vbGVhbn0gaW5zaWRlQ29ubmVjdG9yXHJcbiAqXHJcbiAqIEByZXR1cm4ge0FycmF5fSBhIGxpc3Qgb2Ygb3V0cHV0IHBhcmFtZXRlciBvYmplY3RzXHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5nZXRPdXRwdXRQYXJhbWV0ZXJzID0gZnVuY3Rpb24oZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSB7XHJcbiAgcmV0dXJuIGdldFBhcmFtZXRlcnMuYXBwbHkodGhpcywgWyBlbGVtZW50LCAnb3V0cHV0UGFyYW1ldGVycycsIGluc2lkZUNvbm5lY3RvciBdKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBpbnB1dCBwYXJhbWV0ZXIgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0IGF0IGdpdmVuIGluZGV4XHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtICB7Ym9vbGVhbn0gaW5zaWRlQ29ubmVjdG9yXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBpZHhcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gaW5wdXQgcGFyYW1ldGVyXHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5nZXRJbnB1dFBhcmFtZXRlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0SW5wdXRQYXJhbWV0ZXJzKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvcilbaWR4XTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBvdXRwdXQgcGFyYW1ldGVyIGZyb20gdGhlIGJ1c2luZXNzIG9iamVjdCBhdCBnaXZlbiBpbmRleFxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGluc2lkZUNvbm5lY3RvclxyXG4gKiBAcGFyYW0ge251bWJlcn0gaWR4XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9IG91dHB1dCBwYXJhbWV0ZXJcclxuICovXHJcbklucHV0T3V0cHV0SGVscGVyLmdldE91dHB1dFBhcmFtZXRlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0T3V0cHV0UGFyYW1ldGVycyhlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpW2lkeF07XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyAndHJ1ZScgaWYgdGhlIGdpdmVuIGVsZW1lbnQgc3VwcG9ydHMgaW5wdXRPdXRwdXRcclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0gIHtib29sZWFufSBpbnNpZGVDb25uZWN0b3JcclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5pc0lucHV0T3V0cHV0U3VwcG9ydGVkID0gZnVuY3Rpb24oZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSB7XHJcblxyXG4gIGlmIChpbnNpZGVDb25uZWN0b3IpIHtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHJldHVybiAoXHJcbiAgICBpcyhibywgJ2JwbW46Rmxvd05vZGUnKSAmJiAhKFxyXG4gICAgICBpcyhibywgJ2JwbW46U3RhcnRFdmVudCcpIHx8XHJcbiAgICAgIGlzKGJvLCAnYnBtbjpHYXRld2F5JykgfHxcclxuICAgICAgaXMoYm8sICdicG1uOkJvdW5kYXJ5RXZlbnQnKSB8fFxyXG4gICAgICAoXHJcbiAgICAgICAgaXMoYm8sICdicG1uOlN1YlByb2Nlc3MnKSAmJiBiby5nZXQoJ3RyaWdnZXJlZEJ5RXZlbnQnKVxyXG4gICAgICApXHJcbiAgICApXHJcbiAgKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zICd0cnVlJyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBzdXBwb3J0cyBvdXRwdXQgcGFyYW1ldGVyc1xyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGluc2lkZUNvbm5lY3RvclxyXG4gKlxyXG4gKiBAcmV0dXJuIHtib29sZWFufSBhIGJvb2xlYW4gdmFsdWVcclxuICovXHJcbklucHV0T3V0cHV0SGVscGVyLmFyZU91dHB1dFBhcmFtZXRlcnNTdXBwb3J0ZWQgPSBmdW5jdGlvbihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICByZXR1cm4gaW5zaWRlQ29ubmVjdG9yIHx8ICghaXMoYm8sICdicG1uOkVuZEV2ZW50JykgJiYgIWJvLmxvb3BDaGFyYWN0ZXJpc3RpY3MpO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi9DbWRIZWxwZXInKTtcclxuXHJcblxyXG52YXIgUGFydGljaXBhbnRIZWxwZXIgPSB7fTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gUGFydGljaXBhbnRIZWxwZXI7XHJcblxyXG5QYXJ0aWNpcGFudEhlbHBlci5tb2RpZnlQcm9jZXNzQnVzaW5lc3NPYmplY3QgPSBmdW5jdGlvbihlbGVtZW50LCBwcm9wZXJ0eSwgdmFsdWVzKSB7XHJcbiAgaWYgKCFpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICByZXR1cm4ge307XHJcbiAgfVxyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5nZXQoJ3Byb2Nlc3NSZWYnKSxcclxuICAgICAgcHJvcGVydGllcyA9IHt9O1xyXG5cclxuICBwcm9wZXJ0aWVzW3Byb3BlcnR5XSA9IHZhbHVlc1twcm9wZXJ0eV07XHJcblxyXG4gIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHByb3BlcnRpZXMpO1xyXG59O1xyXG5cclxuUGFydGljaXBhbnRIZWxwZXIuZ2V0UHJvY2Vzc0J1c2luZXNzT2JqZWN0ID0gZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydHlOYW1lKSB7XHJcbiAgaWYgKCFpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICByZXR1cm4ge307XHJcbiAgfVxyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5nZXQoJ3Byb2Nlc3NSZWYnKSxcclxuICAgICAgcHJvcGVydGllcyA9IHt9O1xyXG5cclxuICBwcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV0gPSBiby5nZXQocHJvcGVydHlOYW1lKTtcclxuXHJcbiAgcmV0dXJuIHByb3BlcnRpZXM7XHJcbn07IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcclxuXHJcbnZhciBQcm9wZXJ0aWVzQWN0aXZhdG9yID0gcmVxdWlyZSgnLi4vLi4vUHJvcGVydGllc0FjdGl2YXRvcicpO1xyXG5cclxudmFyIGFzeW5jQ2FwYWJsZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uL2hlbHBlci9Bc3luY0NhcGFibGVIZWxwZXInKSxcclxuICAgIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uL2hlbHBlci9JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXInKTtcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG4vLyBicG1uIHByb3BlcnRpZXNcclxudmFyIHByb2Nlc3NQcm9wcyA9IHJlcXVpcmUoJy4uLy4uL3Byb3ZpZGVyL2JwbW4vcGFydHMvUHJvY2Vzc1Byb3BzJyksXHJcbiAgICBldmVudFByb3BzID0gcmVxdWlyZSgnLi4vLi4vcHJvdmlkZXIvYnBtbi9wYXJ0cy9FdmVudFByb3BzJyksXHJcbiAgICBsaW5rUHJvcHMgPSByZXF1aXJlKCcuLi8uLi9wcm92aWRlci9icG1uL3BhcnRzL0xpbmtQcm9wcycpLFxyXG4gICAgZG9jdW1lbnRhdGlvblByb3BzID0gcmVxdWlyZSgnLi4vLi4vcHJvdmlkZXIvYnBtbi9wYXJ0cy9Eb2N1bWVudGF0aW9uUHJvcHMnKSxcclxuICAgIGlkUHJvcHMgPSByZXF1aXJlKCcuLi8uLi9wcm92aWRlci9icG1uL3BhcnRzL0lkUHJvcHMnKSxcclxuICAgIG5hbWVQcm9wcyA9IHJlcXVpcmUoJy4uLy4uL3Byb3ZpZGVyL2JwbW4vcGFydHMvTmFtZVByb3BzJyksXHJcbiAgICBleGVjdXRhYmxlUHJvcHMgPSByZXF1aXJlKCcuLi8uLi9wcm92aWRlci9icG1uL3BhcnRzL0V4ZWN1dGFibGVQcm9wcycpO1xyXG5cclxuLy8gYWN0aXZpdGkgcHJvcGVydGllc1xyXG52YXIgc2VydmljZVRhc2tEZWxlZ2F0ZVByb3BzID0gcmVxdWlyZSgnLi9wYXJ0cy9TZXJ2aWNlVGFza0RlbGVnYXRlUHJvcHMnKSxcclxuICAgIHVzZXJUYXNrUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL1VzZXJUYXNrUHJvcHMnKSxcclxuICAgIGFzeW5jaHJvbm91c0NvbnRpbnVhdGlvblByb3BzID0gcmVxdWlyZSgnLi9wYXJ0cy9Bc3luY2hyb25vdXNDb250aW51YXRpb25Qcm9wcycpLFxyXG4gICAgY2FsbEFjdGl2aXR5UHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL0NhbGxBY3Rpdml0eVByb3BzJyksXHJcbiAgICBtdWx0aUluc3RhbmNlUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL011bHRpSW5zdGFuY2VMb29wUHJvcHMnKSxcclxuICAgIGNvbmRpdGlvbmFsUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL0NvbmRpdGlvbmFsUHJvcHMnKSxcclxuICAgIHNjcmlwdFByb3BzID0gcmVxdWlyZSgnLi9wYXJ0cy9TY3JpcHRUYXNrUHJvcHMnKSxcclxuICAgIGVycm9yUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL0Vycm9yRXZlbnRQcm9wcycpLFxyXG4gICAgZm9ybVByb3BzID0gcmVxdWlyZSgnLi9wYXJ0cy9Gb3JtUHJvcHMnKSxcclxuICAgIHN0YXJ0RXZlbnRJbml0aWF0b3IgPSByZXF1aXJlKCcuL3BhcnRzL1N0YXJ0RXZlbnRJbml0aWF0b3InKSxcclxuICAgIHZhcmlhYmxlTWFwcGluZyA9IHJlcXVpcmUoJy4vcGFydHMvVmFyaWFibGVNYXBwaW5nUHJvcHMnKSxcclxuICAgIHZlcnNpb25UYWcgPSByZXF1aXJlKCcuL3BhcnRzL1ZlcnNpb25UYWdQcm9wcycpO1xyXG5cclxudmFyIGxpc3RlbmVyUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL0xpc3RlbmVyUHJvcHMnKSxcclxuICAgIGxpc3RlbmVyRGV0YWlscyA9IHJlcXVpcmUoJy4vcGFydHMvTGlzdGVuZXJEZXRhaWxQcm9wcycpLFxyXG4gICAgbGlzdGVuZXJGaWVsZHMgPSByZXF1aXJlKCcuL3BhcnRzL0xpc3RlbmVyRmllbGRJbmplY3Rpb25Qcm9wcycpO1xyXG5cclxudmFyIGVsZW1lbnRUZW1wbGF0ZUNob29zZXJQcm9wcyA9IHJlcXVpcmUoJy4vZWxlbWVudC10ZW1wbGF0ZXMvcGFydHMvQ2hvb3NlclByb3BzJyksXHJcbiAgICBlbGVtZW50VGVtcGxhdGVDdXN0b21Qcm9wcyA9IHJlcXVpcmUoJy4vZWxlbWVudC10ZW1wbGF0ZXMvcGFydHMvQ3VzdG9tUHJvcHMnKTtcclxuXHJcbi8vIElucHV0L091dHB1dFxyXG52YXIgaW5wdXRPdXRwdXQgPSByZXF1aXJlKCcuL3BhcnRzL0lucHV0T3V0cHV0UHJvcHMnKSxcclxuICAgIGlucHV0T3V0cHV0UGFyYW1ldGVyID0gcmVxdWlyZSgnLi9wYXJ0cy9JbnB1dE91dHB1dFBhcmFtZXRlclByb3BzJyk7XHJcblxyXG4vLyBDb25uZWN0b3JcclxudmFyIGNvbm5lY3RvckRldGFpbHMgPSByZXF1aXJlKCcuL3BhcnRzL0Nvbm5lY3RvckRldGFpbFByb3BzJyksXHJcbiAgICBjb25uZWN0b3JJbnB1dE91dHB1dCA9IHJlcXVpcmUoJy4vcGFydHMvQ29ubmVjdG9ySW5wdXRPdXRwdXRQcm9wcycpLFxyXG4gICAgY29ubmVjdG9ySW5wdXRPdXRwdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuL3BhcnRzL0Nvbm5lY3RvcklucHV0T3V0cHV0UGFyYW1ldGVyUHJvcHMnKTtcclxuXHJcbi8vIHByb3BlcnRpZXNcclxudmFyIHByb3BlcnRpZXMgPSByZXF1aXJlKCcuL3BhcnRzL1Byb3BlcnRpZXNQcm9wcycpO1xyXG5cclxuLy8gam9iIGNvbmZpZ3VyYXRpb25cclxudmFyIGpvYkNvbmZpZ3VyYXRpb24gPSByZXF1aXJlKCcuL3BhcnRzL0pvYkNvbmZpZ3VyYXRpb25Qcm9wcycpO1xyXG5cclxuLy8gaGlzdG9yeSB0aW1lIHRvIGxpdmVcclxudmFyIGhpc3RvcnlUaW1lVG9MaXZlID0gcmVxdWlyZSgnLi9wYXJ0cy9IaXN0b3J5VGltZVRvTGl2ZVByb3BzJyk7XHJcblxyXG4vLyBjYW5kaWRhdGUgc3RhcnRlciBncm91cHMvdXNlcnNcclxudmFyIGNhbmRpZGF0ZVN0YXJ0ZXIgPSByZXF1aXJlKCcuL3BhcnRzL0NhbmRpZGF0ZVN0YXJ0ZXJQcm9wcycpO1xyXG5cclxuLy8gdGFza2xpc3RcclxudmFyIHRhc2tsaXN0ID0gcmVxdWlyZSgnLi9wYXJ0cy9UYXNrbGlzdFByb3BzJyk7XHJcblxyXG4vLyBleHRlcm5hbCB0YXNrIGNvbmZpZ3VyYXRpb25cclxudmFyIGV4dGVybmFsVGFza0NvbmZpZ3VyYXRpb24gPSByZXF1aXJlKCcuL3BhcnRzL0V4dGVybmFsVGFza0NvbmZpZ3VyYXRpb25Qcm9wcycpO1xyXG5cclxuLy8gZmllbGQgaW5qZWN0aW9uXHJcbnZhciBmaWVsZEluamVjdGlvbnMgPSByZXF1aXJlKCcuL3BhcnRzL0ZpZWxkSW5qZWN0aW9uUHJvcHMnKTtcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyksXHJcbiAgICBpbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi9oZWxwZXIvSW1wbGVtZW50YXRpb25UeXBlSGVscGVyJyk7XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbnZhciBpc0V4dGVybmFsVGFza1ByaW9yaXR5RW5hYmxlZCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgLy8gc2hvdyBvbmx5IGlmIGVsZW1lbnQgaXMgYSBwcm9jZXNzLCBhIHBhcnRpY2lwYW50IC4uLlxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSAmJiBidXNpbmVzc09iamVjdC5nZXQoJ3Byb2Nlc3NSZWYnKSkge1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICB2YXIgZXh0ZXJuYWxCbyA9IEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRTZXJ2aWNlVGFza0xpa2VCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgaXNFeHRlcm5hbFRhc2sgPSBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0SW1wbGVtZW50YXRpb25UeXBlKGV4dGVybmFsQm8pID09PSAnZXh0ZXJuYWwnO1xyXG5cclxuICAvLyAuLi4gb3IgYW4gZXh0ZXJuYWwgdGFzayB3aXRoIHNlbGVjdGVkIGV4dGVybmFsIGltcGxlbWVudGF0aW9uIHR5cGVcclxuICByZXR1cm4gISFJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuaXNFeHRlcm5hbENhcGFibGUoZXh0ZXJuYWxCbykgJiYgaXNFeHRlcm5hbFRhc2s7XHJcbn07XHJcblxyXG52YXIgaXNKb2JDb25maWdFbmFibGVkID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UHJvY2VzcycpIHx8IGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdwcm9jZXNzUmVmJykpIHtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLy8gYXN5bmMgYmVoYXZpb3JcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICBpZiAoYXN5bmNDYXBhYmxlSGVscGVyLmlzQXN5bmNCZWZvcmUoYm8pIHx8IGFzeW5jQ2FwYWJsZUhlbHBlci5pc0FzeW5jQWZ0ZXIoYm8pKSB7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIC8vIHRpbWVyIGRlZmluaXRpb25cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSkge1xyXG4gICAgcmV0dXJuICEhZXZlbnREZWZpbml0aW9uSGVscGVyLmdldFRpbWVyRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGZhbHNlO1xyXG59O1xyXG5cclxudmFyIGdldElucHV0T3V0cHV0UGFyYW1ldGVyTGFiZWwgPSBmdW5jdGlvbihwYXJhbSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlmIChpcyhwYXJhbSwgJ2FjdGl2aXRpOklucHV0UGFyYW1ldGVyJykpIHtcclxuICAgIHJldHVybiB0cmFuc2xhdGUoJ0lucHV0IFBhcmFtZXRlcicpO1xyXG4gIH1cclxuXHJcbiAgaWYgKGlzKHBhcmFtLCAnYWN0aXZpdGk6T3V0cHV0UGFyYW1ldGVyJykpIHtcclxuICAgIHJldHVybiB0cmFuc2xhdGUoJ091dHB1dCBQYXJhbWV0ZXInKTtcclxuICB9XHJcblxyXG4gIHJldHVybiAnJztcclxufTtcclxuXHJcbnZhciBnZXRMaXN0ZW5lckxhYmVsID0gZnVuY3Rpb24ocGFyYW0sIHRyYW5zbGF0ZSkge1xyXG5cclxuICBpZiAoaXMocGFyYW0sICdhY3Rpdml0aTpFeGVjdXRpb25MaXN0ZW5lcicpKSB7XHJcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdFeGVjdXRpb24gTGlzdGVuZXInKTtcclxuICB9XHJcblxyXG4gIGlmIChpcyhwYXJhbSwgJ2FjdGl2aXRpOlRhc2tMaXN0ZW5lcicpKSB7XHJcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdUYXNrIExpc3RlbmVyJyk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gJyc7XHJcbn07XHJcblxyXG52YXIgUFJPQ0VTU19LRVlfSElOVCA9ICdUaGlzIG1hcHMgdG8gdGhlIHByb2Nlc3MgZGVmaW5pdGlvbiBrZXkuJztcclxudmFyIFRBU0tfS0VZX0hJTlQgPSAnVGhpcyBtYXBzIHRvIHRoZSB0YXNrIGRlZmluaXRpb24ga2V5Lic7XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVHZW5lcmFsVGFiR3JvdXBzKFxyXG4gICAgZWxlbWVudCwgY2FudmFzLCBicG1uRmFjdG9yeSxcclxuICAgIGVsZW1lbnRSZWdpc3RyeSwgZWxlbWVudFRlbXBsYXRlcywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIC8vIHJlZmVyIHRvIHRhcmdldCBlbGVtZW50IGZvciBleHRlcm5hbCBsYWJlbHNcclxuICBlbGVtZW50ID0gZWxlbWVudC5sYWJlbFRhcmdldCB8fCBlbGVtZW50O1xyXG5cclxuICB2YXIgZ2VuZXJhbEdyb3VwID0ge1xyXG4gICAgaWQ6ICdnZW5lcmFsJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0dlbmVyYWwnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgdmFyIGlkT3B0aW9ucztcclxuICB2YXIgcHJvY2Vzc09wdGlvbnM7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykpIHtcclxuICAgIGlkT3B0aW9ucyA9IHsgZGVzY3JpcHRpb246IFBST0NFU1NfS0VZX0hJTlQgfTtcclxuICB9XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpVc2VyVGFzaycpKSB7XHJcbiAgICBpZE9wdGlvbnMgPSB7IGRlc2NyaXB0aW9uOiBUQVNLX0tFWV9ISU5UIH07XHJcbiAgfVxyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgcHJvY2Vzc09wdGlvbnMgPSB7IHByb2Nlc3NJZERlc2NyaXB0aW9uOiBQUk9DRVNTX0tFWV9ISU5UIH07XHJcbiAgfVxyXG5cclxuICBpZFByb3BzKGdlbmVyYWxHcm91cCwgZWxlbWVudCwgdHJhbnNsYXRlLCBpZE9wdGlvbnMpO1xyXG4gIG5hbWVQcm9wcyhnZW5lcmFsR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjYW52YXMsIHRyYW5zbGF0ZSk7XHJcbiAgcHJvY2Vzc1Byb3BzKGdlbmVyYWxHcm91cCwgZWxlbWVudCwgdHJhbnNsYXRlLCBwcm9jZXNzT3B0aW9ucyk7XHJcbiAgdmVyc2lvblRhZyhnZW5lcmFsR3JvdXAsIGVsZW1lbnQsIHRyYW5zbGF0ZSk7XHJcbiAgZXhlY3V0YWJsZVByb3BzKGdlbmVyYWxHcm91cCwgZWxlbWVudCwgdHJhbnNsYXRlKTtcclxuICBlbGVtZW50VGVtcGxhdGVDaG9vc2VyUHJvcHMoZ2VuZXJhbEdyb3VwLCBlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzLCB0cmFuc2xhdGUpO1xyXG5cclxuICB2YXIgY3VzdG9tRmllbGRzR3JvdXBzID0gZWxlbWVudFRlbXBsYXRlQ3VzdG9tUHJvcHMoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcywgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBkZXRhaWxzR3JvdXAgPSB7XHJcbiAgICBpZDogJ2RldGFpbHMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnRGV0YWlscycpLFxyXG4gICAgZW50cmllczogW11cclxuICB9O1xyXG4gIHNlcnZpY2VUYXNrRGVsZWdhdGVQcm9wcyhkZXRhaWxzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG4gIHVzZXJUYXNrUHJvcHMoZGV0YWlsc0dyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpO1xyXG4gIHNjcmlwdFByb3BzKGRldGFpbHNHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcbiAgbGlua1Byb3BzKGRldGFpbHNHcm91cCwgZWxlbWVudCwgdHJhbnNsYXRlKTtcclxuICBjYWxsQWN0aXZpdHlQcm9wcyhkZXRhaWxzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG4gIGV2ZW50UHJvcHMoZGV0YWlsc0dyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpO1xyXG4gIGVycm9yUHJvcHMoZGV0YWlsc0dyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuICBjb25kaXRpb25hbFByb3BzKGRldGFpbHNHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcbiAgc3RhcnRFdmVudEluaXRpYXRvcihkZXRhaWxzR3JvdXAsIGVsZW1lbnQsIHRyYW5zbGF0ZSk7IC8vIHRoaXMgbXVzdCBiZSB0aGUgbGFzdCBlbGVtZW50IG9mIHRoZSBkZXRhaWxzIGdyb3VwIVxyXG5cclxuICB2YXIgbXVsdGlJbnN0YW5jZUdyb3VwID0ge1xyXG4gICAgaWQ6ICdtdWx0aUluc3RhbmNlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ011bHRpIEluc3RhbmNlJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcbiAgbXVsdGlJbnN0YW5jZVByb3BzKG11bHRpSW5zdGFuY2VHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBhc3luY0dyb3VwID0ge1xyXG4gICAgaWQgOiAnYXN5bmMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQXN5bmNocm9ub3VzIENvbnRpbnVhdGlvbnMnKSxcclxuICAgIGVudHJpZXMgOiBbXVxyXG4gIH07XHJcbiAgYXN5bmNocm9ub3VzQ29udGludWF0aW9uUHJvcHMoYXN5bmNHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBqb2JDb25maWd1cmF0aW9uR3JvdXAgPSB7XHJcbiAgICBpZCA6ICdqb2JDb25maWd1cmF0aW9uJyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdKb2IgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllcyA6IFtdLFxyXG4gICAgZW5hYmxlZDogaXNKb2JDb25maWdFbmFibGVkXHJcbiAgfTtcclxuICBqb2JDb25maWd1cmF0aW9uKGpvYkNvbmZpZ3VyYXRpb25Hcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBleHRlcm5hbFRhc2tHcm91cCA9IHtcclxuICAgIGlkIDogJ2V4dGVybmFsVGFza0NvbmZpZ3VyYXRpb24nLFxyXG4gICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0V4dGVybmFsIFRhc2sgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllcyA6IFtdLFxyXG4gICAgZW5hYmxlZDogaXNFeHRlcm5hbFRhc2tQcmlvcml0eUVuYWJsZWRcclxuICB9O1xyXG4gIGV4dGVybmFsVGFza0NvbmZpZ3VyYXRpb24oZXh0ZXJuYWxUYXNrR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuXHJcbiAgdmFyIGNhbmRpZGF0ZVN0YXJ0ZXJHcm91cCA9IHtcclxuICAgIGlkOiAnY2FuZGlkYXRlU3RhcnRlckNvbmZpZ3VyYXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ2FuZGlkYXRlIFN0YXJ0ZXIgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllczogW11cclxuICB9O1xyXG4gIGNhbmRpZGF0ZVN0YXJ0ZXIoY2FuZGlkYXRlU3RhcnRlckdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGhpc3RvcnlUaW1lVG9MaXZlR3JvdXAgPSB7XHJcbiAgICBpZDogJ2hpc3RvcnlDb25maWd1cmF0aW9uJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0hpc3RvcnkgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllczogW11cclxuICB9O1xyXG4gIGhpc3RvcnlUaW1lVG9MaXZlKGhpc3RvcnlUaW1lVG9MaXZlR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICB2YXIgdGFza2xpc3RHcm91cCA9IHtcclxuICAgIGlkOiAndGFza2xpc3QnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGFza2xpc3QgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllczogW11cclxuICB9O1xyXG4gIHRhc2tsaXN0KHRhc2tsaXN0R3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICB2YXIgZG9jdW1lbnRhdGlvbkdyb3VwID0ge1xyXG4gICAgaWQ6ICdkb2N1bWVudGF0aW9uJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0RvY3VtZW50YXRpb24nKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuICBkb2N1bWVudGF0aW9uUHJvcHMoZG9jdW1lbnRhdGlvbkdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGdyb3VwcyA9IFtdO1xyXG4gIGdyb3Vwcy5wdXNoKGdlbmVyYWxHcm91cCk7XHJcbiAgY3VzdG9tRmllbGRzR3JvdXBzLmZvckVhY2goZnVuY3Rpb24oZ3JvdXApIHtcclxuICAgIGdyb3Vwcy5wdXNoKGdyb3VwKTtcclxuICB9KTtcclxuICBncm91cHMucHVzaChkZXRhaWxzR3JvdXApO1xyXG4gIGdyb3Vwcy5wdXNoKGV4dGVybmFsVGFza0dyb3VwKTtcclxuICBncm91cHMucHVzaChtdWx0aUluc3RhbmNlR3JvdXApO1xyXG4gIGdyb3Vwcy5wdXNoKGFzeW5jR3JvdXApO1xyXG4gIGdyb3Vwcy5wdXNoKGpvYkNvbmZpZ3VyYXRpb25Hcm91cCk7XHJcbiAgZ3JvdXBzLnB1c2goY2FuZGlkYXRlU3RhcnRlckdyb3VwKTtcclxuICBncm91cHMucHVzaChoaXN0b3J5VGltZVRvTGl2ZUdyb3VwKTtcclxuICBncm91cHMucHVzaCh0YXNrbGlzdEdyb3VwKTtcclxuICBncm91cHMucHVzaChkb2N1bWVudGF0aW9uR3JvdXApO1xyXG5cclxuICByZXR1cm4gZ3JvdXBzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVWYXJpYWJsZXNUYWJHcm91cHMoZWxlbWVudCwgYnBtbkZhY3RvcnksIGVsZW1lbnRSZWdpc3RyeSwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIHZhcmlhYmxlc0dyb3VwID0ge1xyXG4gICAgaWQgOiAndmFyaWFibGVzJyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdWYXJpYWJsZXMnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuICB2YXJpYWJsZU1hcHBpbmcodmFyaWFibGVzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICByZXR1cm4gW1xyXG4gICAgdmFyaWFibGVzR3JvdXBcclxuICBdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVGb3Jtc1RhYkdyb3VwcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpIHtcclxuICB2YXIgZm9ybUdyb3VwID0ge1xyXG4gICAgaWQgOiAnZm9ybXMnLFxyXG4gICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0Zvcm1zJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcbiAgZm9ybVByb3BzKGZvcm1Hcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHJldHVybiBbXHJcbiAgICBmb3JtR3JvdXBcclxuICBdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVMaXN0ZW5lcnNUYWJHcm91cHMoZWxlbWVudCwgYnBtbkZhY3RvcnksIGVsZW1lbnRSZWdpc3RyeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBsaXN0ZW5lcnNHcm91cCA9IHtcclxuICAgIGlkIDogJ2xpc3RlbmVycycsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdMaXN0ZW5lcnMnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgdmFyIG9wdGlvbnMgPSBsaXN0ZW5lclByb3BzKGxpc3RlbmVyc0dyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGxpc3RlbmVyRGV0YWlsc0dyb3VwID0ge1xyXG4gICAgaWQ6ICdsaXN0ZW5lci1kZXRhaWxzJyxcclxuICAgIGVudHJpZXM6IFtdLFxyXG4gICAgZW5hYmxlZDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5nZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuICAgIGxhYmVsOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBwYXJhbSA9IG9wdGlvbnMuZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGdldExpc3RlbmVyTGFiZWwocGFyYW0sIHRyYW5zbGF0ZSk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgbGlzdGVuZXJEZXRhaWxzKGxpc3RlbmVyRGV0YWlsc0dyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGxpc3RlbmVyRmllbGRzR3JvdXAgPSB7XHJcbiAgICBpZDogJ2xpc3RlbmVyLWZpZWxkcycsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdGaWVsZCBJbmplY3Rpb24nKSxcclxuICAgIGVudHJpZXM6IFtdLFxyXG4gICAgZW5hYmxlZDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5nZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIGxpc3RlbmVyRmllbGRzKGxpc3RlbmVyRmllbGRzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpO1xyXG5cclxuICByZXR1cm4gW1xyXG4gICAgbGlzdGVuZXJzR3JvdXAsXHJcbiAgICBsaXN0ZW5lckRldGFpbHNHcm91cCxcclxuICAgIGxpc3RlbmVyRmllbGRzR3JvdXBcclxuICBdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVJbnB1dE91dHB1dFRhYkdyb3VwcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGlucHV0T3V0cHV0R3JvdXAgPSB7XHJcbiAgICBpZDogJ2lucHV0LW91dHB1dCcsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdQYXJhbWV0ZXJzJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcblxyXG4gIHZhciBvcHRpb25zID0gaW5wdXRPdXRwdXQoaW5wdXRPdXRwdXRHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBpbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwID0ge1xyXG4gICAgaWQ6ICdpbnB1dC1vdXRwdXQtcGFyYW1ldGVyJyxcclxuICAgIGVudHJpZXM6IFtdLFxyXG4gICAgZW5hYmxlZDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5nZXRTZWxlY3RlZFBhcmFtZXRlcihlbGVtZW50LCBub2RlKTtcclxuICAgIH0sXHJcbiAgICBsYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgcGFyYW0gPSBvcHRpb25zLmdldFNlbGVjdGVkUGFyYW1ldGVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gZ2V0SW5wdXRPdXRwdXRQYXJhbWV0ZXJMYWJlbChwYXJhbSwgdHJhbnNsYXRlKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBpbnB1dE91dHB1dFBhcmFtZXRlcihpbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKTtcclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIGlucHV0T3V0cHV0R3JvdXAsXHJcbiAgICBpbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwXHJcbiAgXTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlQ29ubmVjdG9yVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSkge1xyXG4gIHZhciBjb25uZWN0b3JEZXRhaWxzR3JvdXAgPSB7XHJcbiAgICBpZDogJ2Nvbm5lY3Rvci1kZXRhaWxzJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0RldGFpbHMnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgY29ubmVjdG9yRGV0YWlscyhjb25uZWN0b3JEZXRhaWxzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICB2YXIgY29ubmVjdG9ySW5wdXRPdXRwdXRHcm91cCA9IHtcclxuICAgIGlkOiAnY29ubmVjdG9yLWlucHV0LW91dHB1dCcsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdJbnB1dC9PdXRwdXQnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgdmFyIG9wdGlvbnMgPSBjb25uZWN0b3JJbnB1dE91dHB1dChjb25uZWN0b3JJbnB1dE91dHB1dEdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGNvbm5lY3RvcklucHV0T3V0cHV0UGFyYW1ldGVyR3JvdXAgPSB7XHJcbiAgICBpZDogJ2Nvbm5lY3Rvci1pbnB1dC1vdXRwdXQtcGFyYW1ldGVyJyxcclxuICAgIGVudHJpZXM6IFtdLFxyXG4gICAgZW5hYmxlZDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5nZXRTZWxlY3RlZFBhcmFtZXRlcihlbGVtZW50LCBub2RlKTtcclxuICAgIH0sXHJcbiAgICBsYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgcGFyYW0gPSBvcHRpb25zLmdldFNlbGVjdGVkUGFyYW1ldGVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gZ2V0SW5wdXRPdXRwdXRQYXJhbWV0ZXJMYWJlbChwYXJhbSwgdHJhbnNsYXRlKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBjb25uZWN0b3JJbnB1dE91dHB1dFBhcmFtZXRlcihjb25uZWN0b3JJbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKTtcclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIGNvbm5lY3RvckRldGFpbHNHcm91cCxcclxuICAgIGNvbm5lY3RvcklucHV0T3V0cHV0R3JvdXAsXHJcbiAgICBjb25uZWN0b3JJbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwXHJcbiAgXTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlRmllbGRJbmplY3Rpb25zVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZmllbGRHcm91cCA9IHtcclxuICAgIGlkOiAnZmllbGQtaW5qZWN0aW9ucy1wcm9wZXJ0aWVzJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0ZpZWxkIEluamVjdGlvbnMnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgZmllbGRJbmplY3Rpb25zKGZpZWxkR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICByZXR1cm4gW1xyXG4gICAgZmllbGRHcm91cFxyXG4gIF07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnRzR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgcHJvcGVydGllc0dyb3VwID0ge1xyXG4gICAgaWQgOiAnZXh0ZW5zaW9uRWxlbWVudHMtcHJvcGVydGllcycsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdQcm9wZXJ0aWVzJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcbiAgcHJvcGVydGllcyhwcm9wZXJ0aWVzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICByZXR1cm4gW1xyXG4gICAgcHJvcGVydGllc0dyb3VwXHJcbiAgXTtcclxufVxyXG5cclxuLy8gYWN0aXZpdGkgUHJvcGVydGllcyBQcm92aWRlciAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5cclxuLyoqXHJcbiAqIEEgcHJvcGVydGllcyBwcm92aWRlciBmb3IgYWN0aXZpdGkgcmVsYXRlZCBwcm9wZXJ0aWVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xyXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcclxuICogQHBhcmFtIHtFbGVtZW50VGVtcGxhdGVzfSBlbGVtZW50VGVtcGxhdGVzXHJcbiAqIEBwYXJhbSB7VHJhbnNsYXRlfSB0cmFuc2xhdGVcclxuICovXHJcbmZ1bmN0aW9uIEFjdGl2aXRpUHJvcGVydGllc1Byb3ZpZGVyKFxyXG4gICAgZXZlbnRCdXMsIGNhbnZhcywgYnBtbkZhY3RvcnksXHJcbiAgICBlbGVtZW50UmVnaXN0cnksIGVsZW1lbnRUZW1wbGF0ZXMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICBQcm9wZXJ0aWVzQWN0aXZhdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xyXG5cclxuICB0aGlzLmdldFRhYnMgPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcblxyXG4gICAgdmFyIGdlbmVyYWxUYWIgPSB7XHJcbiAgICAgIGlkOiAnZ2VuZXJhbCcsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0dlbmVyYWwnKSxcclxuICAgICAgZ3JvdXBzOiBjcmVhdGVHZW5lcmFsVGFiR3JvdXBzKFxyXG4gICAgICAgIGVsZW1lbnQsIGNhbnZhcywgYnBtbkZhY3RvcnksXHJcbiAgICAgICAgZWxlbWVudFJlZ2lzdHJ5LCBlbGVtZW50VGVtcGxhdGVzLCB0cmFuc2xhdGUpXHJcbiAgICB9O1xyXG5cclxuICAgIHZhciB2YXJpYWJsZXNUYWIgPSB7XHJcbiAgICAgIGlkOiAndmFyaWFibGVzJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnVmFyaWFibGVzJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlVmFyaWFibGVzVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSlcclxuICAgIH07XHJcblxyXG4gICAgdmFyIGZvcm1zVGFiID0ge1xyXG4gICAgICBpZDogJ2Zvcm1zJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnRm9ybXMnKSxcclxuICAgICAgZ3JvdXBzOiBjcmVhdGVGb3Jtc1RhYkdyb3VwcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpXHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBsaXN0ZW5lcnNUYWIgPSB7XHJcbiAgICAgIGlkOiAnbGlzdGVuZXJzJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnTGlzdGVuZXJzJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlTGlzdGVuZXJzVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSksXHJcbiAgICAgIGVuYWJsZWQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gIWV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRMaW5rRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpXHJcbiAgICAgICAgICB8fCAoIWlzKGVsZW1lbnQsICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnKVxyXG4gICAgICAgICAgJiYgZXZlbnREZWZpbml0aW9uSGVscGVyLmdldExpbmtFdmVudERlZmluaXRpb24oZWxlbWVudCkpO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBpbnB1dE91dHB1dFRhYiA9IHtcclxuICAgICAgaWQ6ICdpbnB1dC1vdXRwdXQnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdJbnB1dC9PdXRwdXQnKSxcclxuICAgICAgZ3JvdXBzOiBjcmVhdGVJbnB1dE91dHB1dFRhYkdyb3VwcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpXHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBjb25uZWN0b3JUYWIgPSB7XHJcbiAgICAgIGlkOiAnY29ubmVjdG9yJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ29ubmVjdG9yJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlQ29ubmVjdG9yVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSksXHJcbiAgICAgIGVuYWJsZWQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgYm8gPSBpbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0U2VydmljZVRhc2tMaWtlQnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgICAgcmV0dXJuIGJvICYmIGltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRJbXBsZW1lbnRhdGlvblR5cGUoYm8pID09PSAnY29ubmVjdG9yJztcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgZmllbGRJbmplY3Rpb25zVGFiID0ge1xyXG4gICAgICBpZDogJ2ZpZWxkLWluamVjdGlvbnMnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdGaWVsZCBJbmplY3Rpb25zJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlRmllbGRJbmplY3Rpb25zVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSlcclxuICAgIH07XHJcblxyXG4gICAgdmFyIGV4dGVuc2lvbnNUYWIgPSB7XHJcbiAgICAgIGlkOiAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdFeHRlbnNpb25zJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlRXh0ZW5zaW9uRWxlbWVudHNHcm91cHMoZWxlbWVudCwgYnBtbkZhY3RvcnksIGVsZW1lbnRSZWdpc3RyeSwgdHJhbnNsYXRlKVxyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gW1xyXG4gICAgICBnZW5lcmFsVGFiLFxyXG4gICAgICB2YXJpYWJsZXNUYWIsXHJcbiAgICAgIGNvbm5lY3RvclRhYixcclxuICAgICAgZm9ybXNUYWIsXHJcbiAgICAgIGxpc3RlbmVyc1RhYixcclxuICAgICAgaW5wdXRPdXRwdXRUYWIsXHJcbiAgICAgIGZpZWxkSW5qZWN0aW9uc1RhYixcclxuICAgICAgZXh0ZW5zaW9uc1RhYlxyXG4gICAgXTtcclxuICB9O1xyXG5cclxufVxyXG5cclxuQWN0aXZpdGlQcm9wZXJ0aWVzUHJvdmlkZXIuJGluamVjdCA9IFtcclxuICAnZXZlbnRCdXMnLFxyXG4gICdjYW52YXMnLFxyXG4gICdicG1uRmFjdG9yeScsXHJcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXHJcbiAgJ2VsZW1lbnRUZW1wbGF0ZXMnLFxyXG4gICd0cmFuc2xhdGUnXHJcbl07XHJcblxyXG5pbmhlcml0cyhBY3Rpdml0aVByb3BlcnRpZXNQcm92aWRlciwgUHJvcGVydGllc0FjdGl2YXRvcik7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEFjdGl2aXRpUHJvcGVydGllc1Byb3ZpZGVyO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhbiBpbnB1dCBwYXJhbWV0ZXIgcmVwcmVzZW50aW5nIHRoZSBnaXZlblxyXG4gKiBiaW5kaW5nIGFuZCB2YWx1ZS5cclxuICpcclxuICogQHBhcmFtIHtQcm9wZXJ0eUJpbmRpbmd9IGJpbmRpbmdcclxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9XHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVJbnB1dFBhcmFtZXRlcihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgc2NyaXB0Rm9ybWF0ID0gYmluZGluZy5zY3JpcHRGb3JtYXQsXHJcbiAgICAgIHBhcmFtZXRlclZhbHVlLFxyXG4gICAgICBwYXJhbWV0ZXJEZWZpbml0aW9uO1xyXG5cclxuICBpZiAoc2NyaXB0Rm9ybWF0KSB7XHJcbiAgICBwYXJhbWV0ZXJEZWZpbml0aW9uID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdhY3Rpdml0aTpTY3JpcHQnLCB7XHJcbiAgICAgIHNjcmlwdEZvcm1hdDogc2NyaXB0Rm9ybWF0LFxyXG4gICAgICB2YWx1ZTogdmFsdWVcclxuICAgIH0pO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBwYXJhbWV0ZXJWYWx1ZSA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGJwbW5GYWN0b3J5LmNyZWF0ZSgnYWN0aXZpdGk6SW5wdXRQYXJhbWV0ZXInLCB7XHJcbiAgICBuYW1lOiBiaW5kaW5nLm5hbWUsXHJcbiAgICB2YWx1ZTogcGFyYW1ldGVyVmFsdWUsXHJcbiAgICBkZWZpbml0aW9uOiBwYXJhbWV0ZXJEZWZpbml0aW9uXHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmNyZWF0ZUlucHV0UGFyYW1ldGVyID0gY3JlYXRlSW5wdXRQYXJhbWV0ZXI7XHJcblxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhbiBvdXRwdXQgcGFyYW1ldGVyIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW5cclxuICogYmluZGluZyBhbmQgdmFsdWUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UHJvcGVydHlCaW5kaW5nfSBiaW5kaW5nXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlT3V0cHV0UGFyYW1ldGVyKGJpbmRpbmcsIHZhbHVlLCBicG1uRmFjdG9yeSkge1xyXG4gIHZhciBzY3JpcHRGb3JtYXQgPSBiaW5kaW5nLnNjcmlwdEZvcm1hdCxcclxuICAgICAgcGFyYW1ldGVyVmFsdWUsXHJcbiAgICAgIHBhcmFtZXRlckRlZmluaXRpb247XHJcblxyXG4gIGlmIChzY3JpcHRGb3JtYXQpIHtcclxuICAgIHBhcmFtZXRlckRlZmluaXRpb24gPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOlNjcmlwdCcsIHtcclxuICAgICAgc2NyaXB0Rm9ybWF0OiBzY3JpcHRGb3JtYXQsXHJcbiAgICAgIHZhbHVlOiBiaW5kaW5nLnNvdXJjZVxyXG4gICAgfSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHBhcmFtZXRlclZhbHVlID0gYmluZGluZy5zb3VyY2U7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gYnBtbkZhY3RvcnkuY3JlYXRlKCdhY3Rpdml0aTpPdXRwdXRQYXJhbWV0ZXInLCB7XHJcbiAgICBuYW1lOiB2YWx1ZSxcclxuICAgIHZhbHVlOiBwYXJhbWV0ZXJWYWx1ZSxcclxuICAgIGRlZmluaXRpb246IHBhcmFtZXRlckRlZmluaXRpb25cclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuY3JlYXRlT3V0cHV0UGFyYW1ldGVyID0gY3JlYXRlT3V0cHV0UGFyYW1ldGVyO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYWN0aXZpdGkgcHJvcGVydHkgZnJvbSB0aGUgZ2l2ZW4gYmluZGluZy5cclxuICpcclxuICogQHBhcmFtIHtQcm9wZXJ0eUJpbmRpbmd9IGJpbmRpbmdcclxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9XHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aVByb3BlcnR5KGJpbmRpbmcsIHZhbHVlLCBicG1uRmFjdG9yeSkge1xyXG4gIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOlByb3BlcnR5Jywge1xyXG4gICAgbmFtZTogYmluZGluZy5uYW1lLFxyXG4gICAgdmFsdWU6IHZhbHVlIHx8ICcnXHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmNyZWF0ZUFjdGl2aXRpUHJvcGVydHkgPSBjcmVhdGVBY3Rpdml0aVByb3BlcnR5O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYWN0aXZpdGk6aW4gZWxlbWVudCBmcm9tIGdpdmVuIGJpbmRpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UHJvcGVydHlCaW5kaW5nfSBiaW5kaW5nXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQWN0aXZpdGlJbihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuXHJcbiAgdmFyIHByb3BlcnRpZXMgPSBjcmVhdGVBY3Rpdml0aUluT3V0QXR0cnMoYmluZGluZywgdmFsdWUpO1xyXG5cclxuICByZXR1cm4gYnBtbkZhY3RvcnkuY3JlYXRlKCdhY3Rpdml0aTpJbicsIHByb3BlcnRpZXMpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5jcmVhdGVBY3Rpdml0aUluID0gY3JlYXRlQWN0aXZpdGlJbjtcclxuXHJcblxyXG4vKipcclxuICogQ3JlYXRlIGFjdGl2aXRpOmluIHdpdGggYnVzaW5lc3NLZXkgZWxlbWVudCBmcm9tIGdpdmVuIGJpbmRpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UHJvcGVydHlCaW5kaW5nfSBiaW5kaW5nXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleShiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuICByZXR1cm4gYnBtbkZhY3RvcnkuY3JlYXRlKCdhY3Rpdml0aTpJbicsIHtcclxuICAgIGJ1c2luZXNzS2V5OiB2YWx1ZVxyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5jcmVhdGVBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5ID0gY3JlYXRlQWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleTtcclxuXHJcblxyXG4vKipcclxuICogQ3JlYXRlIGFjdGl2aXRpOm91dCBlbGVtZW50IGZyb20gZ2l2ZW4gYmluZGluZy5cclxuICpcclxuICogQHBhcmFtIHtQcm9wZXJ0eUJpbmRpbmd9IGJpbmRpbmdcclxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9XHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aU91dChiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgcHJvcGVydGllcyA9IGNyZWF0ZUFjdGl2aXRpSW5PdXRBdHRycyhiaW5kaW5nLCB2YWx1ZSk7XHJcblxyXG4gIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOk91dCcsIHByb3BlcnRpZXMpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5jcmVhdGVBY3Rpdml0aU91dCA9IGNyZWF0ZUFjdGl2aXRpT3V0O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYWN0aXZpdGk6ZXhlY3V0aW9uTGlzdGVuZXIgZWxlbWVudCBjb250YWluaW5nIGFuIGlubGluZSBzY3JpcHQgZnJvbSBnaXZlbiBiaW5kaW5nLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5QmluZGluZ30gYmluZGluZ1xyXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsdWVcclxuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH1cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUFjdGl2aXRpRXhlY3V0aW9uTGlzdGVuZXJTY3JpcHQoYmluZGluZywgdmFsdWUsIGJwbW5GYWN0b3J5KSB7XHJcbiAgdmFyIHNjcmlwdEZvcm1hdCA9IGJpbmRpbmcuc2NyaXB0Rm9ybWF0LFxyXG4gICAgICBwYXJhbWV0ZXJWYWx1ZSxcclxuICAgICAgcGFyYW1ldGVyRGVmaW5pdGlvbjtcclxuXHJcbiAgaWYgKHNjcmlwdEZvcm1hdCkge1xyXG4gICAgcGFyYW1ldGVyRGVmaW5pdGlvbiA9IGJwbW5GYWN0b3J5LmNyZWF0ZSgnYWN0aXZpdGk6U2NyaXB0Jywge1xyXG4gICAgICBzY3JpcHRGb3JtYXQ6IHNjcmlwdEZvcm1hdCxcclxuICAgICAgdmFsdWU6IHZhbHVlXHJcbiAgICB9KTtcclxuICB9IGVsc2Uge1xyXG4gICAgcGFyYW1ldGVyVmFsdWUgPSB2YWx1ZTtcclxuICB9XHJcblxyXG4gIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOkV4ZWN1dGlvbkxpc3RlbmVyJywge1xyXG4gICAgZXZlbnQ6IGJpbmRpbmcuZXZlbnQsXHJcbiAgICB2YWx1ZTogcGFyYW1ldGVyVmFsdWUsXHJcbiAgICBzY3JpcHQ6IHBhcmFtZXRlckRlZmluaXRpb25cclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuY3JlYXRlQWN0aXZpdGlFeGVjdXRpb25MaXN0ZW5lclNjcmlwdCA9IGNyZWF0ZUFjdGl2aXRpRXhlY3V0aW9uTGlzdGVuZXJTY3JpcHQ7XHJcblxyXG4vKipcclxuICogQ3JlYXRlIGFjdGl2aXRpOmZpZWxkIGVsZW1lbnQgY29udGFpbmluZyBzdHJpbmcgb3IgZXhwcmVzc2lvbiBmcm9tIGdpdmVuIGJpbmRpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UHJvcGVydHlCaW5kaW5nfSBiaW5kaW5nXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQWN0aXZpdGlGaWVsZEluamVjdGlvbihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgREVGQVVMVF9QUk9QUyA9IHtcclxuICAgICdzdHJpbmcnOiB1bmRlZmluZWQsXHJcbiAgICAnZXhwcmVzc2lvbic6IHVuZGVmaW5lZCxcclxuICAgICduYW1lJzogdW5kZWZpbmVkXHJcbiAgfTtcclxuXHJcbiAgdmFyIHByb3BzID0gYXNzaWduKHt9LCBERUZBVUxUX1BST1BTKTtcclxuXHJcbiAgaWYgKCFiaW5kaW5nLmV4cHJlc3Npb24pIHtcclxuICAgIHByb3BzLnN0cmluZyA9IHZhbHVlO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBwcm9wcy5leHByZXNzaW9uID0gdmFsdWU7XHJcbiAgfVxyXG4gIHByb3BzLm5hbWUgPSBiaW5kaW5nLm5hbWU7XHJcblxyXG4gIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOkZpZWxkJywgcHJvcHMpO1xyXG59XHJcbm1vZHVsZS5leHBvcnRzLmNyZWF0ZUFjdGl2aXRpRmllbGRJbmplY3Rpb24gPSBjcmVhdGVBY3Rpdml0aUZpZWxkSW5qZWN0aW9uO1xyXG5cclxuXHJcbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBwcm9wZXJ0aWVzIGZvciBhY3Rpdml0aTppbiBhbmQgYWN0aXZpdGk6b3V0IHR5cGVzLlxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQWN0aXZpdGlJbk91dEF0dHJzKGJpbmRpbmcsIHZhbHVlKSB7XHJcblxyXG4gIHZhciBwcm9wZXJ0aWVzID0ge307XHJcblxyXG4gIC8vIGFjdGl2aXRpOmluIHNvdXJjZShFeHByZXNzaW9uKSB0YXJnZXRcclxuICBpZiAoYmluZGluZy50YXJnZXQpIHtcclxuXHJcbiAgICBwcm9wZXJ0aWVzLnRhcmdldCA9IGJpbmRpbmcudGFyZ2V0O1xyXG5cclxuICAgIGlmIChiaW5kaW5nLmV4cHJlc3Npb24pIHtcclxuICAgICAgcHJvcGVydGllcy5zb3VyY2VFeHByZXNzaW9uID0gdmFsdWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBwcm9wZXJ0aWVzLnNvdXJjZSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gIH0gZWxzZVxyXG5cclxuICAvLyBhY3Rpdml0aTooaW58b3V0KSB2YXJpYWJsZXMgbG9jYWxcclxuICBpZiAoYmluZGluZy52YXJpYWJsZXMpIHtcclxuICAgIHByb3BlcnRpZXMudmFyaWFibGVzID0gJ2FsbCc7XHJcblxyXG4gICAgaWYgKGJpbmRpbmcudmFyaWFibGVzID09PSAnbG9jYWwnKSB7XHJcbiAgICAgIHByb3BlcnRpZXMubG9jYWwgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gYWN0aXZpdGk6b3V0IHNvdXJjZShFeHByZXNzaW9uKSB0YXJnZXRcclxuICBlbHNlIHtcclxuICAgIHByb3BlcnRpZXMudGFyZ2V0ID0gdmFsdWU7XHJcblxyXG4gICAgWyAnc291cmNlJywgJ3NvdXJjZUV4cHJlc3Npb24nIF0uZm9yRWFjaChmdW5jdGlvbihrKSB7XHJcbiAgICAgIGlmIChiaW5kaW5nW2tdKSB7XHJcbiAgICAgICAgcHJvcGVydGllc1trXSA9IGJpbmRpbmdba107XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHByb3BlcnRpZXM7XHJcbn1cclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcclxuXHJcbnZhciBnZXRUZW1wbGF0ZSA9IHJlcXVpcmUoJy4vSGVscGVyJykuZ2V0VGVtcGxhdGU7XHJcblxyXG52YXIgUHJvcGVydGllc0FjdGl2YXRvciA9IHJlcXVpcmUoJy4uLy4uLy4uL1Byb3BlcnRpZXNBY3RpdmF0b3InKTtcclxuXHJcbnZhciBISUdIRVJfUFJJT1JJVFkgPSAxMTAwO1xyXG5cclxuLyoqXHJcbiAqIEFwcGxpZXMgdGVtcGxhdGUgdmlzaWJpbGl0eSBzZXR0aW5ncy5cclxuICpcclxuICogQ29udHJvbGxlZCB1c2luZyBgZW50cmllc1Zpc2libGVgIG9uIHRlbXBsYXRlIGNvbmZpZyBvYmplY3Q6XHJcbiAqXHJcbiAqIGBgYGpzb25cclxuICogICAgIFwiZW50cmllc1Zpc2libGVcIjoge1xyXG4gKiAgICAgICBcIl9hbGxcIjogdHJ1ZXxmYWxzZSxcclxuICogICAgICAgXCJlbnRyeU5hbWVcIjogdHJ1ZXxmYWxzZSxcclxuICogICAgICAgLi4uXHJcbiAqICAgICB9XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xyXG4gKiBAcGFyYW0ge0VsZW1lbnRUZW1wbGF0ZXN9IGVsZW1lbnRUZW1wbGF0ZXNcclxuICovXHJcbmZ1bmN0aW9uIEN1c3RvbUVsZW1lbnRzUHJvcGVydGllc0FjdGl2YXRvcihldmVudEJ1cywgZWxlbWVudFRlbXBsYXRlcykge1xyXG4gIFByb3BlcnRpZXNBY3RpdmF0b3IuY2FsbCh0aGlzLCBldmVudEJ1cywgSElHSEVSX1BSSU9SSVRZKTtcclxuXHJcbiAgdGhpcy5pc0VudHJ5VmlzaWJsZSA9IGZ1bmN0aW9uKGVudHJ5LCBlbGVtZW50KSB7XHJcblxyXG4gICAgdmFyIHRlbXBsYXRlID0gZ2V0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcyk7XHJcblxyXG4gICAgaWYgKHRlbXBsYXRlICYmICFpc0VudHJ5VmlzaWJsZShlbnRyeSwgdGVtcGxhdGUpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICB0aGlzLmlzUHJvcGVydHlFZGl0YWJsZSA9IGZ1bmN0aW9uKGVudHJ5LCBwcm9wZXJ0eU5hbWUsIGVsZW1lbnQpIHtcclxuXHJcbiAgICB2YXIgdGVtcGxhdGUgPSBnZXRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKTtcclxuXHJcbiAgICBpZiAodGVtcGxhdGUgJiYgIWlzRW50cnlFZGl0YWJsZShlbnRyeSwgdGVtcGxhdGUpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICB9O1xyXG59XHJcblxyXG5DdXN0b21FbGVtZW50c1Byb3BlcnRpZXNBY3RpdmF0b3IuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2VsZW1lbnRUZW1wbGF0ZXMnIF07XHJcblxyXG5pbmhlcml0cyhDdXN0b21FbGVtZW50c1Byb3BlcnRpZXNBY3RpdmF0b3IsIFByb3BlcnRpZXNBY3RpdmF0b3IpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBDdXN0b21FbGVtZW50c1Byb3BlcnRpZXNBY3RpdmF0b3I7XHJcblxyXG5cclxuXHJcbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5cclxudmFyIENVU1RPTV9QUk9QRVJUSUVTX1BBVFRFUk4gPSAvXmN1c3RvbS0vO1xyXG5cclxudmFyIERFRkFVTFRfRU5UUklFU19WSVNJQkxFID0ge1xyXG4gIF9hbGw6IGZhbHNlLFxyXG4gIGlkOiB0cnVlLFxyXG4gIG5hbWU6IHRydWVcclxufTtcclxuXHJcbmZ1bmN0aW9uIGlzQ3VzdG9tRW50cnkoZW50cnkpIHtcclxuICByZXR1cm4gQ1VTVE9NX1BST1BFUlRJRVNfUEFUVEVSTi50ZXN0KGVudHJ5LmlkKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNFbnRyeVZpc2libGUoZW50cnksIHRlbXBsYXRlKSB7XHJcblxyXG4gIHZhciBlbnRyeUlkID0gZW50cnkuaWQ7XHJcblxyXG4gIGlmIChlbnRyeUlkID09PSAnZWxlbWVudFRlbXBsYXRlLWNob29zZXInIHx8IGlzQ3VzdG9tRW50cnkoZW50cnkpKSB7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIHZhciBlbnRyaWVzVmlzaWJsZSA9IHRlbXBsYXRlLmVudHJpZXNWaXNpYmxlIHx8IERFRkFVTFRfRU5UUklFU19WSVNJQkxFO1xyXG5cclxuICBpZiAodHlwZW9mIGVudHJpZXNWaXNpYmxlID09PSAnYm9vbGVhbicpIHtcclxuICAgIHJldHVybiBlbnRyaWVzVmlzaWJsZTtcclxuICB9XHJcblxyXG4gIHZhciBkZWZhdWx0VmlzaWJsZSA9IGVudHJpZXNWaXNpYmxlLl9hbGwgfHwgZmFsc2UsXHJcbiAgICAgIGVudHJ5VmlzaWJsZSA9IGVudHJpZXNWaXNpYmxlW2VudHJ5SWRdO1xyXG5cclxuICAvLyBkID0gdHJ1ZSwgZSA9IGZhbHNlID0+IGZhbHNlXHJcbiAgLy8gZCA9IGZhbHNlLCBlID0gdHJ1ZSA9PiB0cnVlXHJcbiAgLy8gZCA9IGZhbHNlLCBlID0gZmFsc2VcclxuICByZXR1cm4gKFxyXG4gICAgKGRlZmF1bHRWaXNpYmxlID09PSB0cnVlICYmIGVudHJ5VmlzaWJsZSAhPT0gZmFsc2UpIHx8XHJcbiAgICAoZGVmYXVsdFZpc2libGUgPT09IGZhbHNlICYmIGVudHJ5VmlzaWJsZSA9PT0gdHJ1ZSlcclxuICApO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0VudHJ5RWRpdGFibGUoZW50cnksIHRlbXBsYXRlKSB7XHJcblxyXG4gIHZhciBwcm9wZXJ0eTtcclxuXHJcbiAgaWYgKGlzQ3VzdG9tRW50cnkoZW50cnkpKSB7XHJcbiAgICBwcm9wZXJ0eSA9IGdldFByb3BlcnR5KHRlbXBsYXRlLCBlbnRyeSk7XHJcblxyXG4gICAgcmV0dXJuIHByb3BlcnR5ICYmIHByb3BlcnR5LmVkaXRhYmxlICE9PSBmYWxzZTtcclxuICB9XHJcblxyXG4gIHJldHVybiB0cnVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRQcm9wZXJ0eSh0ZW1wbGF0ZSwgZW50cnkpIHtcclxuXHJcbiAgdmFyIGluZGV4O1xyXG4gIHZhciBpZHggPSBlbnRyeS5pZC5yZXBsYWNlKCdjdXN0b20tJyArIHRlbXBsYXRlLmlkICsgJy0nLCAnJyk7XHJcbiAgaWYgKGlkeC5pbmRleE9mKCctJykgIT09IC0xKSB7XHJcbiAgICB2YXIgaW5kZXhlcyA9IGlkeC5zcGxpdCgnLScpO1xyXG4gICAgaWYgKGluZGV4ZXMubGVuZ3RoID09IDIpIHtcclxuICAgICAgdmFyIHNjb3BlTmFtZSA9IGluZGV4ZXNbMF0ucmVwbGFjZSgvXy9nLCAnOicpO1xyXG4gICAgICBpbmRleCA9IHBhcnNlSW50KGluZGV4ZXNbMV0sIDEwKTtcclxuICAgICAgaWYgKHNjb3BlTmFtZSAmJiAhaXNOYU4oaW5kZXgpKSB7XHJcbiAgICAgICAgcmV0dXJuIHRlbXBsYXRlLnNjb3Blc1tzY29wZU5hbWVdLnByb3BlcnRpZXNbaW5kZXhdO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIGluZGV4ID0gcGFyc2VJbnQoaWR4LCAxMCk7XHJcbiAgICBpZiAoIWlzTmFOKGluZGV4KSkge1xyXG4gICAgICByZXR1cm4gdGVtcGxhdGUucHJvcGVydGllc1tpbmRleF07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBleHRyYWN0IHByb3BlcnR5IGluZGV4IGZvciBlbnRyeSA8JyArIGVudHJ5LmlkICsgJz4nKTtcclxufVxyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgdmFsdWVzID0gcmVxdWlyZSgnbG9kYXNoL3ZhbHVlcycpO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBndXkga25vd2luZyBhbGwgY29uZmlndXJlZCBlbGVtZW50IHRlbXBsYXRlcy5cclxuICpcclxuICogVGhpcyByZWdpc3RyeSB3b24ndCB2YWxpZGF0ZS4gVXNlIHRoZSB7QGxpbmsgVmFsaWRhdG9yfVxyXG4gKiB0byB2ZXJpZnkgYSB0ZW1wbGF0ZSBpcyB2YWxpZCBwcmlvciB0byBhZGRpbmcgaXQgdG9cclxuICogdGhpcyByZWdpc3RyeS5cclxuICovXHJcbmZ1bmN0aW9uIEVsZW1lbnRUZW1wbGF0ZXMoKSB7XHJcblxyXG4gIHRoaXMuX3RlbXBsYXRlcyA9IHt9O1xyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBrbm93biBlbGVtZW50IHRlbXBsYXRlcy5cclxuICAgKlxyXG4gICAqIEBwYXJhbSB7QXJyYXk8VGVtcGxhdGVEZXNjcmlwdG9yPn0gZGVzY3JpcHRvcnNcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge0VsZW1lbnRUZW1wbGF0ZXN9XHJcbiAgICovXHJcbiAgdGhpcy5zZXQgPSBmdW5jdGlvbihkZXNjcmlwdG9ycykge1xyXG5cclxuICAgIHZhciB0ZW1wbGF0ZXMgPSB0aGlzLl90ZW1wbGF0ZXMgPSB7fTtcclxuXHJcbiAgICBkZXNjcmlwdG9ycy5mb3JFYWNoKGZ1bmN0aW9uKGRlc2NyaXB0b3IpIHtcclxuICAgICAgdGVtcGxhdGVzW2Rlc2NyaXB0b3IuaWRdID0gZGVzY3JpcHRvcjtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0ZW1wbGF0ZSBkZXNjcmlwdG9yIHdpdGggZ2l2ZW4gaWQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge1N0cmluZ30gaWRcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge1RlbXBsYXRlRGVzY3JpcHRvcn1cclxuICAgKi9cclxuICB0aGlzLmdldCA9IGZ1bmN0aW9uKGlkKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fdGVtcGxhdGVzW2lkXTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gYWxsIGtub3duIHRlbXBsYXRlIGRlc2NyaXB0b3JzLlxyXG4gICAqXHJcbiAgICogQHJldHVybiB7QXJyYXk8VGVtcGxhdGVEZXNjcmlwdG9yPn1cclxuICAgKi9cclxuICB0aGlzLmdldEFsbCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHZhbHVlcyh0aGlzLl90ZW1wbGF0ZXMpO1xyXG4gIH07XHJcblxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEVsZW1lbnRUZW1wbGF0ZXM7IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIFZhbGlkYXRvciA9IHJlcXVpcmUoJy4vVmFsaWRhdG9yJyk7XHJcblxyXG4vKipcclxuICogVGhlIGd1eSByZXNwb25zaWJsZSBmb3IgdGVtcGxhdGUgbG9hZGluZy5cclxuICpcclxuICogUHJvdmlkZSB0aGUgYWN0dWFsIHRlbXBsYXRlcyB2aWEgdGhlIGBjb25maWcuZWxlbWVudFRlbXBsYXRlc2AuXHJcbiAqXHJcbiAqIFRoYXQgY29uZmlndXJhdGlvbiBjYW4gZWl0aGVyIGJlIGFuIGFycmF5IG9mIHRlbXBsYXRlXHJcbiAqIGRlc2NyaXB0b3JzIG9yIGEgbm9kZSBzdHlsZSBjYWxsYmFjayB0byByZXRyaWV2ZVxyXG4gKiB0aGUgdGVtcGxhdGVzIGFzeW5jaHJvbm91c2x5LlxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PFRlbXBsYXRlRGVzY3JpcHRvcj58RnVuY3Rpb259IGxvYWRUZW1wbGF0ZXNcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcclxuICogQHBhcmFtIHtFbGVtZW50VGVtcGxhdGVzfSBlbGVtZW50VGVtcGxhdGVzXHJcbiAqL1xyXG5mdW5jdGlvbiBFbGVtZW50VGVtcGxhdGVzTG9hZGVyKGxvYWRUZW1wbGF0ZXMsIGV2ZW50QnVzLCBlbGVtZW50VGVtcGxhdGVzKSB7XHJcbiAgdGhpcy5fbG9hZFRlbXBsYXRlcyA9IGxvYWRUZW1wbGF0ZXM7XHJcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcclxuICB0aGlzLl9lbGVtZW50VGVtcGxhdGVzID0gZWxlbWVudFRlbXBsYXRlcztcclxuXHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5pbml0JywgZnVuY3Rpb24oKSB7XHJcbiAgICBzZWxmLnJlbG9hZCgpO1xyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEVsZW1lbnRUZW1wbGF0ZXNMb2FkZXI7XHJcblxyXG5FbGVtZW50VGVtcGxhdGVzTG9hZGVyLiRpbmplY3QgPSBbXHJcbiAgJ2NvbmZpZy5lbGVtZW50VGVtcGxhdGVzJyxcclxuICAnZXZlbnRCdXMnLFxyXG4gICdlbGVtZW50VGVtcGxhdGVzJ1xyXG5dO1xyXG5cclxuXHJcbkVsZW1lbnRUZW1wbGF0ZXNMb2FkZXIucHJvdG90eXBlLnJlbG9hZCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gIHZhciBsb2FkVGVtcGxhdGVzID0gdGhpcy5fbG9hZFRlbXBsYXRlcztcclxuXHJcbiAgLy8gbm8gdGVtcGxhdGVzIHNwZWNpZmllZFxyXG4gIGlmICh0eXBlb2YgbG9hZFRlbXBsYXRlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIHRlbXBsYXRlIGxvYWRlciBmdW5jdGlvbiBzcGVjaWZpZWRcclxuICBpZiAodHlwZW9mIGxvYWRUZW1wbGF0ZXMgPT09ICdmdW5jdGlvbicpIHtcclxuXHJcbiAgICByZXR1cm4gbG9hZFRlbXBsYXRlcyhmdW5jdGlvbihlcnIsIHRlbXBsYXRlcykge1xyXG5cclxuICAgICAgaWYgKGVycikge1xyXG4gICAgICAgIHJldHVybiBzZWxmLnRlbXBsYXRlRXJyb3JzKFsgZXJyIF0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLnNldFRlbXBsYXRlcyh0ZW1wbGF0ZXMpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyB0ZW1wbGF0ZXMgYXJyYXkgc3BlY2lmaWVkXHJcbiAgaWYgKGxvYWRUZW1wbGF0ZXMubGVuZ3RoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zZXRUZW1wbGF0ZXMobG9hZFRlbXBsYXRlcyk7XHJcbiAgfVxyXG5cclxufTtcclxuXHJcbkVsZW1lbnRUZW1wbGF0ZXNMb2FkZXIucHJvdG90eXBlLnNldFRlbXBsYXRlcyA9IGZ1bmN0aW9uKHRlbXBsYXRlcykge1xyXG5cclxuICB2YXIgZWxlbWVudFRlbXBsYXRlcyA9IHRoaXMuX2VsZW1lbnRUZW1wbGF0ZXM7XHJcblxyXG4gIHZhciB2YWxpZGF0b3IgPSBuZXcgVmFsaWRhdG9yKCkuYWRkQWxsKHRlbXBsYXRlcyk7XHJcblxyXG4gIHZhciBlcnJvcnMgPSB2YWxpZGF0b3IuZ2V0RXJyb3JzKCksXHJcbiAgICAgIHZhbGlkVGVtcGxhdGVzID0gdmFsaWRhdG9yLmdldFZhbGlkVGVtcGxhdGVzKCk7XHJcblxyXG4gIGVsZW1lbnRUZW1wbGF0ZXMuc2V0KHZhbGlkVGVtcGxhdGVzKTtcclxuXHJcbiAgaWYgKGVycm9ycy5sZW5ndGgpIHtcclxuICAgIHRoaXMudGVtcGxhdGVFcnJvcnMoZXJyb3JzKTtcclxuICB9XHJcblxyXG4gIHRoaXMudGVtcGxhdGVzQ2hhbmdlZCgpO1xyXG59O1xyXG5cclxuRWxlbWVudFRlbXBsYXRlc0xvYWRlci5wcm90b3R5cGUudGVtcGxhdGVzQ2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xyXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ2VsZW1lbnRUZW1wbGF0ZXMuY2hhbmdlZCcpO1xyXG59O1xyXG5cclxuRWxlbWVudFRlbXBsYXRlc0xvYWRlci5wcm90b3R5cGUudGVtcGxhdGVFcnJvcnMgPSBmdW5jdGlvbihlcnJvcnMpIHtcclxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdlbGVtZW50VGVtcGxhdGVzLmVycm9ycycsIHtcclxuICAgIGVycm9yczogZXJyb3JzXHJcbiAgfSk7XHJcbn07IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBpc0FueSA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJykuaXNBbnk7XHJcblxyXG52YXIgZmluZCA9IHJlcXVpcmUoJ2xvZGFzaC9maW5kJyk7XHJcblxyXG5cclxudmFyIFRFTVBMQVRFX0FUVFIgPSAnYWN0aXZpdGk6bW9kZWxlclRlbXBsYXRlJztcclxuXHJcbi8qKlxyXG4gKiBUaGUgQlBNTiAyLjAgZXh0ZW5zaW9uIGF0dHJpYnV0ZSBuYW1lIHVuZGVyXHJcbiAqIHdoaWNoIHRoZSBlbGVtZW50IHRlbXBsYXRlIGlzIHN0b3JlZC5cclxuICpcclxuICogQHR5cGUge1N0cmluZ31cclxuICovXHJcbm1vZHVsZS5leHBvcnRzLlRFTVBMQVRFX0FUVFIgPSBURU1QTEFURV9BVFRSO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGVtcGxhdGUgaWQgZm9yIGEgZ2l2ZW4gZGlhZ3JhbSBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge1N0cmluZ31cclxuICovXHJcbmZ1bmN0aW9uIGdldFRlbXBsYXRlSWQoZWxlbWVudCkge1xyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgaWYgKGJvKSB7XHJcbiAgICByZXR1cm4gYm8uZ2V0KFRFTVBMQVRFX0FUVFIpO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuZ2V0VGVtcGxhdGVJZCA9IGdldFRlbXBsYXRlSWQ7XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCB0ZW1wbGF0ZSBvZiBhIGdpdmVuIGVsZW1lbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge0VsZW1lbnRUZW1wbGF0ZXN9IGVsZW1lbnRUZW1wbGF0ZXNcclxuICpcclxuICogQHJldHVybiB7VGVtcGxhdGVEZWZpbml0aW9ufVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcykge1xyXG4gIHZhciBpZCA9IGdldFRlbXBsYXRlSWQoZWxlbWVudCk7XHJcblxyXG4gIHJldHVybiBpZCAmJiBlbGVtZW50VGVtcGxhdGVzLmdldChpZCk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmdldFRlbXBsYXRlID0gZ2V0VGVtcGxhdGU7XHJcblxyXG4vKipcclxuICogR2V0IGRlZmF1bHQgdGVtcGxhdGUgZm9yIGEgZ2l2ZW4gZWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7RWxlbWVudFRlbXBsYXRlc30gZWxlbWVudFRlbXBsYXRlc1xyXG4gKlxyXG4gKiBAcmV0dXJuIHtUZW1wbGF0ZURlZmluaXRpb259XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXREZWZhdWx0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcykge1xyXG5cclxuICAvLyByZXR1cm4gZmlyc3QgZGVmYXVsdCB0ZW1wbGF0ZSwgaWYgYW55IGV4aXN0c1xyXG4gIHJldHVybiAoXHJcbiAgICBlbGVtZW50VGVtcGxhdGVzLmdldEFsbCgpLmZpbHRlcihmdW5jdGlvbih0KSB7XHJcbiAgICAgIHJldHVybiBpc0FueShlbGVtZW50LCB0LmFwcGxpZXNUbykgJiYgdC5pc0RlZmF1bHQ7XHJcbiAgICB9KVxyXG4gIClbMF07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmdldERlZmF1bHRUZW1wbGF0ZSA9IGdldERlZmF1bHRUZW1wbGF0ZTtcclxuXHJcblxyXG4vKipcclxuICogRmluZCBleHRlbnNpb24gd2l0aCBnaXZlbiB0eXBlIGluXHJcbiAqIEJQTU4gZWxlbWVudCwgZGlhZ3JhbSBlbGVtZW50IG9yIEV4dGVuc2lvbkVsZW1lbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudHxkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fSB0aGUgZXh0ZW5zaW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBmaW5kRXh0ZW5zaW9uKGVsZW1lbnQsIHR5cGUpIHtcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgdmFyIGV4dGVuc2lvbkVsZW1lbnRzO1xyXG5cclxuICBpZiAoaXMoYm8sICdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJykpIHtcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzID0gYm87XHJcbiAgfSBlbHNlIHtcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzID0gYm8uZXh0ZW5zaW9uRWxlbWVudHM7XHJcbiAgfVxyXG5cclxuICBpZiAoIWV4dGVuc2lvbkVsZW1lbnRzKSB7XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcblxyXG4gIHJldHVybiBmaW5kKGV4dGVuc2lvbkVsZW1lbnRzLmdldCgndmFsdWVzJyksIGZ1bmN0aW9uKGUpIHtcclxuICAgIHJldHVybiBpcyhlLCB0eXBlKTtcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuZmluZEV4dGVuc2lvbiA9IGZpbmRFeHRlbnNpb247XHJcblxyXG5cclxuZnVuY3Rpb24gZmluZEV4dGVuc2lvbnMoZWxlbWVudCwgdHlwZXMpIHtcclxuICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBnZXRFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuXHJcbiAgaWYgKCFleHRlbnNpb25FbGVtZW50cykge1xyXG4gICAgcmV0dXJuIFtdO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGV4dGVuc2lvbkVsZW1lbnRzLmdldCgndmFsdWVzJykuZmlsdGVyKGZ1bmN0aW9uKGUpIHtcclxuICAgIHJldHVybiBpc0FueShlLCB0eXBlcyk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmZpbmRFeHRlbnNpb25zID0gZmluZEV4dGVuc2lvbnM7XHJcblxyXG5cclxuZnVuY3Rpb24gZmluZEFjdGl2aXRpSW5PdXQoZWxlbWVudCwgYmluZGluZykge1xyXG5cclxuICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBnZXRFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuXHJcbiAgaWYgKCFleHRlbnNpb25FbGVtZW50cykge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIG1hdGNoZXI7XHJcblxyXG4gIGlmIChiaW5kaW5nLnR5cGUgPT09ICdhY3Rpdml0aTppbicpIHtcclxuICAgIG1hdGNoZXIgPSBmdW5jdGlvbihlKSB7XHJcbiAgICAgIHJldHVybiBpcyhlLCAnYWN0aXZpdGk6SW4nKSAmJiBpc0luT3V0KGUsIGJpbmRpbmcpO1xyXG4gICAgfTtcclxuICB9IGVsc2VcclxuICBpZiAoYmluZGluZy50eXBlID09PSAnYWN0aXZpdGk6b3V0Jykge1xyXG4gICAgbWF0Y2hlciA9IGZ1bmN0aW9uKGUpIHtcclxuICAgICAgcmV0dXJuIGlzKGUsICdhY3Rpdml0aTpPdXQnKSAmJiBpc0luT3V0KGUsIGJpbmRpbmcpO1xyXG4gICAgfTtcclxuICB9IGVsc2VcclxuICBpZiAoYmluZGluZy50eXBlID09PSAnYWN0aXZpdGk6aW46YnVzaW5lc3NLZXknKSB7XHJcbiAgICBtYXRjaGVyID0gZnVuY3Rpb24oZSkge1xyXG4gICAgICByZXR1cm4gaXMoZSwgJ2FjdGl2aXRpOkluJykgJiYgJ2J1c2luZXNzS2V5JyBpbiBlO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJldHVybiBmaW5kKGV4dGVuc2lvbkVsZW1lbnRzLmdldCgndmFsdWVzJyksIG1hdGNoZXIpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5maW5kQWN0aXZpdGlJbk91dCA9IGZpbmRBY3Rpdml0aUluT3V0O1xyXG5cclxuZnVuY3Rpb24gZmluZEFjdGl2aXRpUHJvcGVydHkoYWN0aXZpdGlQcm9wZXJ0aWVzLCBiaW5kaW5nKSB7XHJcbiAgcmV0dXJuIGZpbmQoYWN0aXZpdGlQcm9wZXJ0aWVzLmdldCgndmFsdWVzJyksIGZ1bmN0aW9uKHApIHtcclxuICAgIHJldHVybiBwLm5hbWUgPT09IGJpbmRpbmcubmFtZTtcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuZmluZEFjdGl2aXRpUHJvcGVydHkgPSBmaW5kQWN0aXZpdGlQcm9wZXJ0eTtcclxuXHJcblxyXG5mdW5jdGlvbiBmaW5kSW5wdXRQYXJhbWV0ZXIoaW5wdXRPdXRwdXQsIGJpbmRpbmcpIHtcclxuICB2YXIgcGFyYW1ldGVycyA9IGlucHV0T3V0cHV0LmdldCgnaW5wdXRQYXJhbWV0ZXJzJyk7XHJcblxyXG4gIHJldHVybiBmaW5kKHBhcmFtZXRlcnMsIGZ1bmN0aW9uKHApIHtcclxuICAgIHJldHVybiBwLm5hbWUgPT09IGJpbmRpbmcubmFtZTtcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuZmluZElucHV0UGFyYW1ldGVyID0gZmluZElucHV0UGFyYW1ldGVyO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGZpbmRPdXRwdXRQYXJhbWV0ZXIoaW5wdXRPdXRwdXQsIGJpbmRpbmcpIHtcclxuICB2YXIgcGFyYW1ldGVycyA9IGlucHV0T3V0cHV0LmdldCgnb3V0cHV0UGFyYW1ldGVycycpO1xyXG5cclxuICByZXR1cm4gZmluZChwYXJhbWV0ZXJzLCBmdW5jdGlvbihwKSB7XHJcbiAgICB2YXIgdmFsdWUgPSBwLnZhbHVlO1xyXG5cclxuICAgIGlmICghYmluZGluZy5zY3JpcHRGb3JtYXQpIHtcclxuICAgICAgcmV0dXJuIHZhbHVlID09PSBiaW5kaW5nLnNvdXJjZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZGVmaW5pdGlvbiA9IHAuZGVmaW5pdGlvbjtcclxuXHJcbiAgICBpZiAoIWRlZmluaXRpb24gfHwgYmluZGluZy5zY3JpcHRGb3JtYXQgIT09IGRlZmluaXRpb24uc2NyaXB0Rm9ybWF0KSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZGVmaW5pdGlvbi52YWx1ZSA9PT0gYmluZGluZy5zb3VyY2U7XHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmZpbmRPdXRwdXRQYXJhbWV0ZXIgPSBmaW5kT3V0cHV0UGFyYW1ldGVyO1xyXG5cclxuXHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uRWxlbWVudHMoZWxlbWVudCkge1xyXG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoaXMoYm8sICdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJykpIHtcclxuICAgIHJldHVybiBibztcclxuICB9IGVsc2Uge1xyXG4gICAgcmV0dXJuIGJvLmV4dGVuc2lvbkVsZW1lbnRzO1xyXG4gIH1cclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIGlzSW5PdXQoZWxlbWVudCwgYmluZGluZykge1xyXG5cclxuICBpZiAoYmluZGluZy50eXBlID09PSAnYWN0aXZpdGk6aW4nKSB7XHJcbiAgICAvLyBmaW5kIGJhc2VkIG9uIHRhcmdldCBhdHRyaWJ1dGVcclxuICAgIGlmIChiaW5kaW5nLnRhcmdldCkge1xyXG4gICAgICByZXR1cm4gZWxlbWVudC50YXJnZXQgPT09IGJpbmRpbmcudGFyZ2V0O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKGJpbmRpbmcudHlwZSA9PT0gJ2FjdGl2aXRpOm91dCcpIHtcclxuICAgIC8vIGZpbmQgYmFzZWQgb24gc291cmNlIC8gc291cmNlRXhwcmVzc2lvblxyXG4gICAgaWYgKGJpbmRpbmcuc291cmNlKSB7XHJcbiAgICAgIHJldHVybiBlbGVtZW50LnNvdXJjZSA9PT0gYmluZGluZy5zb3VyY2U7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGJpbmRpbmcuc291cmNlRXhwcmVzc2lvbikge1xyXG4gICAgICByZXR1cm4gZWxlbWVudC5zb3VyY2VFeHByZXNzaW9uID09PSBiaW5kaW5nLnNvdXJjZUV4cHJlc3Npb247XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBmaW5kIGJhc2VkIHZhcmlhYmxlcyAvIGxvY2FsIGNvbWJpbmF0aW9uXHJcbiAgaWYgKGJpbmRpbmcudmFyaWFibGVzKSB7XHJcbiAgICByZXR1cm4gZWxlbWVudC52YXJpYWJsZXMgPT09ICdhbGwnICYmIChcclxuICAgICAgYmluZGluZy52YXJpYWJsZXMgIT09ICdsb2NhbCcgfHwgZWxlbWVudC5sb2NhbFxyXG4gICAgKTtcclxuICB9XHJcbn1cclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdsb2Rhc2gvaXNBcnJheScpO1xyXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCdsb2Rhc2gvaXNPYmplY3QnKTtcclxuXHJcbnZhciBEUk9QRE9XTl9UWVBFID0gJ0Ryb3Bkb3duJztcclxuXHJcbnZhciBWQUxJRF9UWVBFUyA9IFsgJ1N0cmluZycsICdUZXh0JywgJ0Jvb2xlYW4nLCAnSGlkZGVuJywgRFJPUERPV05fVFlQRSBdO1xyXG5cclxudmFyIFBST1BFUlRZX1RZUEUgPSAncHJvcGVydHknLFxyXG4gICAgQUNUSVZJVElfUFJPUEVSVFlfVFlQRSA9ICdhY3Rpdml0aTpwcm9wZXJ0eScsXHJcbiAgICBBQ1RJVklUSV9JTlBVVF9QQVJBTUVURVJfVFlQRSA9ICdhY3Rpdml0aTppbnB1dFBhcmFtZXRlcicsXHJcbiAgICBBQ1RJVklUSV9PVVRQVVRfUEFSQU1FVEVSX1RZUEUgPSAnYWN0aXZpdGk6b3V0cHV0UGFyYW1ldGVyJyxcclxuICAgIEFDVElWSVRJX0lOX1RZUEUgPSAnYWN0aXZpdGk6aW4nLFxyXG4gICAgQUNUSVZJVElfT1VUX1RZUEUgPSAnYWN0aXZpdGk6b3V0JyxcclxuICAgIEFDVElWSVRJX0lOX0JVU0lORVNTX0tFWV9UWVBFID0gJ2FjdGl2aXRpOmluOmJ1c2luZXNzS2V5JyxcclxuICAgIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUiA9ICdhY3Rpdml0aTpleGVjdXRpb25MaXN0ZW5lcicsXHJcbiAgICBBQ1RJVklUSV9GSUVMRCA9ICdhY3Rpdml0aTpmaWVsZCc7XHJcblxyXG52YXIgVkFMSURfQklORElOR19UWVBFUyA9IFtcclxuICBQUk9QRVJUWV9UWVBFLFxyXG4gIEFDVElWSVRJX1BST1BFUlRZX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5QVVRfUEFSQU1FVEVSX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUUFVUX1BBUkFNRVRFUl9UWVBFLFxyXG4gIEFDVElWSVRJX0lOX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5fQlVTSU5FU1NfS0VZX1RZUEUsXHJcbiAgQUNUSVZJVElfRVhFQ1VUSU9OX0xJU1RFTkVSLFxyXG4gIEFDVElWSVRJX0ZJRUxEXHJcbl07XHJcblxyXG5cclxuLyoqXHJcbiAqIEEgZWxlbWVudCB0ZW1wbGF0ZSB2YWxpZGF0b3IuXHJcbiAqL1xyXG5mdW5jdGlvbiBWYWxpZGF0b3IoKSB7XHJcblxyXG4gIHRoaXMuX3RlbXBsYXRlc0J5SWQgPSB7fTtcclxuXHJcbiAgdGhpcy5fdmFsaWRUZW1wbGF0ZXMgPSBbXTtcclxuICB0aGlzLl9lcnJvcnMgPSBbXTtcclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZHMgdGhlIHRlbXBsYXRlcy5cclxuICAgKlxyXG4gICAqIEBwYXJhbSB7QXJyYXk8VGVtcGxhdGVEZXNjcmlwdG9yPn0gdGVtcGxhdGVzXHJcbiAgICpcclxuICAgKiBAcmV0dXJuIHtWYWxpZGF0b3J9IHNlbGZcclxuICAgKi9cclxuICB0aGlzLmFkZEFsbCA9IGZ1bmN0aW9uKHRlbXBsYXRlcykge1xyXG5cclxuICAgIGlmICghaXNBcnJheSh0ZW1wbGF0ZXMpKSB7XHJcbiAgICAgIHRoaXMuX2xvZ0Vycm9yKCd0ZW1wbGF0ZXMgbXVzdCBiZSBbXScpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGVtcGxhdGVzLmZvckVhY2godGhpcy5hZGQsIHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZCB0aGUgZ2l2ZW4gZWxlbWVudCB0ZW1wbGF0ZSwgaWYgaXQgaXMgdmFsaWQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge1RlbXBsYXRlRGVzY3JpcHRvcn0gdGVtcGxhdGVcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge1ZhbGlkYXRvcn0gc2VsZlxyXG4gICAqL1xyXG4gIHRoaXMuYWRkID0gZnVuY3Rpb24odGVtcGxhdGUpIHtcclxuXHJcbiAgICB2YXIgZXJyID0gdGhpcy5fdmFsaWRhdGVUZW1wbGF0ZSh0ZW1wbGF0ZSk7XHJcblxyXG4gICAgaWYgKCFlcnIpIHtcclxuICAgICAgdGhpcy5fdGVtcGxhdGVzQnlJZFt0ZW1wbGF0ZS5pZF0gPSB0ZW1wbGF0ZTtcclxuXHJcbiAgICAgIHRoaXMuX3ZhbGlkVGVtcGxhdGVzLnB1c2godGVtcGxhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFZhbGlkYXRlIGdpdmVuIHRlbXBsYXRlIGFuZCByZXR1cm4gZXJyb3IgKGlmIGFueSkuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge1RlbXBsYXRlRGVzY3JpcHRvcn0gdGVtcGxhdGVcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge0Vycm9yfSB2YWxpZGF0aW9uIGVycm9yLCBpZiBhbnlcclxuICAgKi9cclxuICB0aGlzLl92YWxpZGF0ZVRlbXBsYXRlID0gZnVuY3Rpb24odGVtcGxhdGUpIHtcclxuXHJcbiAgICB2YXIgZXJyLFxyXG4gICAgICAgIGlkID0gdGVtcGxhdGUuaWQsXHJcbiAgICAgICAgYXBwbGllc1RvID0gdGVtcGxhdGUuYXBwbGllc1RvLFxyXG4gICAgICAgIHByb3BlcnRpZXMgPSB0ZW1wbGF0ZS5wcm9wZXJ0aWVzLFxyXG4gICAgICAgIHNjb3BlcyA9IHRlbXBsYXRlLnNjb3BlcztcclxuXHJcbiAgICBpZiAoIWlkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9sb2dFcnJvcignbWlzc2luZyB0ZW1wbGF0ZSBpZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpZCBpbiB0aGlzLl90ZW1wbGF0ZXNCeUlkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9sb2dFcnJvcigndGVtcGxhdGUgaWQgPCcgKyBpZCArICc+IGFscmVhZHkgdXNlZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghaXNBcnJheShhcHBsaWVzVG8pKSB7XHJcbiAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKCdtaXNzaW5nIGFwcGxpZXNUbz1bXScsIHRlbXBsYXRlKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWlzQXJyYXkocHJvcGVydGllcykpIHtcclxuICAgICAgZXJyID0gdGhpcy5fbG9nRXJyb3IoJ21pc3NpbmcgcHJvcGVydGllcz1bXScsIHRlbXBsYXRlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICghdGhpcy5fdmFsaWRhdGVQcm9wZXJ0aWVzKHByb3BlcnRpZXMpKSB7XHJcbiAgICAgICAgZXJyID0gbmV3IEVycm9yKCdpbnZhbGlkIHByb3BlcnRpZXMnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChzY29wZXMpIHtcclxuICAgICAgZXJyID0gdGhpcy5fdmFsaWRhdGVTY29wZXModGVtcGxhdGUsIHNjb3Blcyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVycjtcclxuICB9O1xyXG5cclxuICB0aGlzLl92YWxpZGF0ZVNjb3BlcyA9IGZ1bmN0aW9uKHRlbXBsYXRlLCBzY29wZXMpIHtcclxuXHJcbiAgICB2YXIgZXJyLFxyXG4gICAgICAgIHNjb3BlLFxyXG4gICAgICAgIHNjb3BlTmFtZTtcclxuXHJcbiAgICBpZiAoIWlzT2JqZWN0KHNjb3BlcykgfHwgaXNBcnJheShzY29wZXMpKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9sb2dFcnJvcignaW52YWxpZCBzY29wZXMsIHNob3VsZCBiZSBzY29wZXM9e30nLCB0ZW1wbGF0ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChzY29wZU5hbWUgaW4gc2NvcGVzKSB7XHJcbiAgICAgIHNjb3BlID0gc2NvcGVzW3Njb3BlTmFtZV07XHJcblxyXG4gICAgICBpZiAoIWlzT2JqZWN0KHNjb3BlKSB8fCBpc0FycmF5KHNjb3BlKSkge1xyXG4gICAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKCdpbnZhbGlkIHNjb3BlLCBzaG91bGQgYmUgc2NvcGU9e30nLCB0ZW1wbGF0ZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghaXNBcnJheShzY29wZS5wcm9wZXJ0aWVzKSkge1xyXG4gICAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKFxyXG4gICAgICAgICAgJ21pc3NpbmcgcHJvcGVydGllcz1bXSBpbiBzY29wZSA8JyArIHNjb3BlTmFtZSArICc+JywgdGVtcGxhdGVcclxuICAgICAgICApO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICghdGhpcy5fdmFsaWRhdGVQcm9wZXJ0aWVzKHNjb3BlLnByb3BlcnRpZXMpKSB7XHJcbiAgICAgICAgICBlcnIgPSBuZXcgRXJyb3IoJ2ludmFsaWQgcHJvcGVydGllcyBpbiBzY29wZSA8JyArIHNjb3BlTmFtZSArICc+Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVycjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0ZSBwcm9wZXJ0aWVzIGFuZCByZXR1cm4gZmFsc2UgaWYgYW55IGlzIGludmFsaWQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge0FycmF5PFByb3BlcnR5RGVzY3JpcHRvcj59IHByb3BlcnRpZXNcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgYWxsIHByb3BlcnRpZXMgYXJlIHZhbGlkXHJcbiAgICovXHJcbiAgdGhpcy5fdmFsaWRhdGVQcm9wZXJ0aWVzID0gZnVuY3Rpb24ocHJvcGVydGllcykge1xyXG4gICAgdmFyIHZhbGlkUHJvcGVydGllcyA9IHByb3BlcnRpZXMuZmlsdGVyKHRoaXMuX3ZhbGlkYXRlUHJvcGVydHksIHRoaXMpO1xyXG5cclxuICAgIHJldHVybiBwcm9wZXJ0aWVzLmxlbmd0aCA9PT0gdmFsaWRQcm9wZXJ0aWVzLmxlbmd0aDtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0ZSBwcm9wZXJ0eSBhbmQgcmV0dXJuIGZhbHNlLCBpZiB0aGVyZSB3YXNcclxuICAgKiBhIHZhbGlkYXRpb24gZXJyb3IuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgcHJvcGVydHkgaXMgdmFsaWRcclxuICAgKi9cclxuICB0aGlzLl92YWxpZGF0ZVByb3BlcnR5ID0gZnVuY3Rpb24ocHJvcGVydHkpIHtcclxuXHJcbiAgICB2YXIgdHlwZSA9IHByb3BlcnR5LnR5cGUsXHJcbiAgICAgICAgYmluZGluZyA9IHByb3BlcnR5LmJpbmRpbmc7XHJcblxyXG4gICAgdmFyIGVycjtcclxuXHJcbiAgICB2YXIgYmluZGluZ1R5cGUgPSBiaW5kaW5nLnR5cGU7XHJcblxyXG4gICAgaWYgKFZBTElEX1RZUEVTLmluZGV4T2YodHlwZSkgPT09IC0xKSB7XHJcbiAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKFxyXG4gICAgICAgICdpbnZhbGlkIHByb3BlcnR5IHR5cGUgPCcgKyB0eXBlICsgJz47ICcgK1xyXG4gICAgICAgICdtdXN0IGJlIGFueSBvZiB7ICcgKyBWQUxJRF9UWVBFUy5qb2luKCcsICcpICsgJyB9J1xyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSBEUk9QRE9XTl9UWVBFICYmIGJpbmRpbmdUeXBlICE9PSBBQ1RJVklUSV9FWEVDVVRJT05fTElTVEVORVIpIHtcclxuICAgICAgaWYgKCFpc0FycmF5KHByb3BlcnR5LmNob2ljZXMpKSB7XHJcbiAgICAgICAgZXJyID0gdGhpcy5fbG9nRXJyb3IoXHJcbiAgICAgICAgICAnbXVzdCBwcm92aWRlIGNob2ljZXM9W10gd2l0aCAnICsgRFJPUERPV05fVFlQRSArICcgdHlwZSdcclxuICAgICAgICApO1xyXG4gICAgICB9IGVsc2VcclxuXHJcbiAgICAgIGlmICghcHJvcGVydHkuY2hvaWNlcy5ldmVyeShpc0Ryb3Bkb3duQ2hvaWNlVmFsaWQpKSB7XHJcbiAgICAgICAgZXJyID0gdGhpcy5fbG9nRXJyb3IoXHJcbiAgICAgICAgICAneyBuYW1lLCB2YWx1ZSB9IG11c3QgYmUgc3BlY2lmaWVkIGZvciAnICtcclxuICAgICAgICAgIERST1BET1dOX1RZUEUgKyAnIGNob2ljZXMnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghYmluZGluZykge1xyXG4gICAgICByZXR1cm4gdGhpcy5fbG9nRXJyb3IoJ3Byb3BlcnR5IG1pc3NpbmcgYmluZGluZycpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChWQUxJRF9CSU5ESU5HX1RZUEVTLmluZGV4T2YoYmluZGluZ1R5cGUpID09PSAtMSkge1xyXG4gICAgICBlcnIgPSB0aGlzLl9sb2dFcnJvcihcclxuICAgICAgICAnaW52YWxpZCBwcm9wZXJ0eS5iaW5kaW5nIHR5cGUgPCcgKyBiaW5kaW5nVHlwZSArICc+OyAnICtcclxuICAgICAgICAnbXVzdCBiZSBhbnkgb2YgeyAnICsgVkFMSURfQklORElOR19UWVBFUy5qb2luKCcsICcpICsgJyB9J1xyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChiaW5kaW5nVHlwZSA9PT0gUFJPUEVSVFlfVFlQRSB8fFxyXG4gICAgICAgIGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9QUk9QRVJUWV9UWVBFIHx8XHJcbiAgICAgICAgYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX0lOUFVUX1BBUkFNRVRFUl9UWVBFIHx8XHJcbiAgICAgICAgYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX0ZJRUxEKSB7XHJcblxyXG4gICAgICBpZiAoIWJpbmRpbmcubmFtZSkge1xyXG4gICAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKFxyXG4gICAgICAgICAgJ3Byb3BlcnR5LmJpbmRpbmcgPCcgKyBiaW5kaW5nVHlwZSArICc+IHJlcXVpcmVzIG5hbWUnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfT1VUUFVUX1BBUkFNRVRFUl9UWVBFKSB7XHJcbiAgICAgIGlmICghYmluZGluZy5zb3VyY2UpIHtcclxuICAgICAgICBlcnIgPSB0aGlzLl9sb2dFcnJvcihcclxuICAgICAgICAgICdwcm9wZXJ0eS5iaW5kaW5nIDwnICsgYmluZGluZ1R5cGUgKyAnPiByZXF1aXJlcyBzb3VyY2UnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfSU5fVFlQRSkge1xyXG5cclxuICAgICAgaWYgKCFiaW5kaW5nLnZhcmlhYmxlcyAmJiAhYmluZGluZy50YXJnZXQpIHtcclxuICAgICAgICBlcnIgPSB0aGlzLl9sb2dFcnJvcihcclxuICAgICAgICAgICdwcm9wZXJ0eS5iaW5kaW5nIDwnICsgYmluZGluZ1R5cGUgKyAnPiByZXF1aXJlcyAnICtcclxuICAgICAgICAgICd2YXJpYWJsZXMgb3IgdGFyZ2V0J1xyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX09VVF9UWVBFKSB7XHJcblxyXG4gICAgICBpZiAoIWJpbmRpbmcudmFyaWFibGVzICYmICFiaW5kaW5nLnNvdXJjZSAmJiAhYmluZGluZy5zb3VyY2VFeHByZXNzaW9uKSB7XHJcbiAgICAgICAgZXJyID0gdGhpcy5fbG9nRXJyb3IoXHJcbiAgICAgICAgICAncHJvcGVydHkuYmluZGluZyA8JyArIGJpbmRpbmdUeXBlICsgJz4gcmVxdWlyZXMgJyArXHJcbiAgICAgICAgICAndmFyaWFibGVzLCBzb3VyY2VFeHByZXNzaW9uIG9yIHNvdXJjZSdcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9FWEVDVVRJT05fTElTVEVORVIpIHtcclxuXHJcbiAgICAgIGlmICh0eXBlICE9PSAnSGlkZGVuJykge1xyXG4gICAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKFxyXG4gICAgICAgICAgJ2ludmFsaWQgcHJvcGVydHkgdHlwZSA8JyArIHR5cGUgKyAnPiBmb3IgJyArIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUiArICc7ICcgK1xyXG4gICAgICAgICAgJ211c3QgYmUgPEhpZGRlbj4nXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAhZXJyO1xyXG4gIH07XHJcblxyXG5cclxuICB0aGlzLl9sb2dFcnJvciA9IGZ1bmN0aW9uKGVyciwgdGVtcGxhdGUpIHtcclxuXHJcbiAgICBpZiAodHlwZW9mIGVyciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgaWYgKHRlbXBsYXRlKSB7XHJcbiAgICAgICAgZXJyID0gJ3RlbXBsYXRlKGlkOiAnICsgdGVtcGxhdGUuaWQgKyAnKSAnICsgZXJyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBlcnIgPSBuZXcgRXJyb3IoZXJyKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9lcnJvcnMucHVzaChlcnIpO1xyXG5cclxuICAgIHJldHVybiBlcnI7XHJcbiAgfTtcclxuXHJcbiAgdGhpcy5nZXRFcnJvcnMgPSBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLl9lcnJvcnM7XHJcbiAgfTtcclxuXHJcbiAgdGhpcy5nZXRWYWxpZFRlbXBsYXRlcyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX3ZhbGlkVGVtcGxhdGVzO1xyXG4gIH07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gVmFsaWRhdG9yO1xyXG5cclxuXHJcbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIGlzRHJvcGRvd25DaG9pY2VWYWxpZChjKSB7XHJcbiAgcmV0dXJuICduYW1lJyBpbiBjICYmICd2YWx1ZScgaW4gYztcclxufVxyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZmluZEV4dGVuc2lvbiA9IHJlcXVpcmUoJy4uL0hlbHBlcicpLmZpbmRFeHRlbnNpb24sXHJcbiAgICBmaW5kRXh0ZW5zaW9ucyA9IHJlcXVpcmUoJy4uL0hlbHBlcicpLmZpbmRFeHRlbnNpb25zO1xyXG5cclxudmFyIGNyZWF0ZUFjdGl2aXRpUHJvcGVydHkgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aVByb3BlcnR5LFxyXG4gICAgY3JlYXRlSW5wdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVJbnB1dFBhcmFtZXRlcixcclxuICAgIGNyZWF0ZU91dHB1dFBhcmFtZXRlciA9IHJlcXVpcmUoJy4uL0NyZWF0ZUhlbHBlcicpLmNyZWF0ZU91dHB1dFBhcmFtZXRlcixcclxuICAgIGNyZWF0ZUFjdGl2aXRpSW4gPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aUluLFxyXG4gICAgY3JlYXRlQWN0aXZpdGlPdXQgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aU91dCxcclxuICAgIGNyZWF0ZUFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5LFxyXG4gICAgY3JlYXRlQWN0aXZpdGlFeGVjdXRpb25MaXN0ZW5lclNjcmlwdCA9IHJlcXVpcmUoJy4uL0NyZWF0ZUhlbHBlcicpLmNyZWF0ZUFjdGl2aXRpRXhlY3V0aW9uTGlzdGVuZXJTY3JpcHQsXHJcbiAgICBjcmVhdGVBY3Rpdml0aUZpZWxkSW5qZWN0aW9uID0gcmVxdWlyZSgnLi4vQ3JlYXRlSGVscGVyJykuY3JlYXRlQWN0aXZpdGlGaWVsZEluamVjdGlvbjtcclxuXHJcbnZhciBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKTtcclxuXHJcbnZhciBBQ1RJVklUSV9TRVJWSUNFX1RBU0tfTElLRSA9IFtcclxuICAnYWN0aXZpdGk6Y2xhc3MnLFxyXG4gICdhY3Rpdml0aTpkZWxlZ2F0ZUV4cHJlc3Npb24nLFxyXG4gICdhY3Rpdml0aTpleHByZXNzaW9uJ1xyXG5dO1xyXG5cclxuLyoqXHJcbiAqIEEgaGFuZGxlciB0aGF0IGNoYW5nZXMgdGhlIG1vZGVsaW5nIHRlbXBsYXRlIG9mIGEgQlBNTiBlbGVtZW50LlxyXG4gKi9cclxuZnVuY3Rpb24gQ2hhbmdlRWxlbWVudFRlbXBsYXRlSGFuZGxlcihtb2RlbGluZywgY29tbWFuZFN0YWNrLCBicG1uRmFjdG9yeSkge1xyXG5cclxuICBmdW5jdGlvbiBnZXRPckNyZWF0ZUV4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQpIHtcclxuXHJcbiAgICB2YXIgYm8gPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICAgIHZhciBleHRlbnNpb25FbGVtZW50cyA9IGJvLmV4dGVuc2lvbkVsZW1lbnRzO1xyXG5cclxuICAgIC8vIGFkZCBleHRlbnNpb24gZWxlbWVudHNcclxuICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnLCB7XHJcbiAgICAgICAgdmFsdWVzOiBbXVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwge1xyXG4gICAgICAgIGV4dGVuc2lvbkVsZW1lbnRzOiBleHRlbnNpb25FbGVtZW50c1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZXh0ZW5zaW9uRWxlbWVudHM7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiB1cGRhdGVNb2RlbGVyVGVtcGxhdGUoZWxlbWVudCwgbmV3VGVtcGxhdGUpIHtcclxuICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwge1xyXG4gICAgICAnYWN0aXZpdGk6bW9kZWxlclRlbXBsYXRlJzogbmV3VGVtcGxhdGUgJiYgbmV3VGVtcGxhdGUuaWRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlSW9NYXBwaW5ncyhlbGVtZW50LCBuZXdUZW1wbGF0ZSwgY29udGV4dCkge1xyXG5cclxuICAgIHZhciBuZXdNYXBwaW5ncyA9IGNyZWF0ZUlucHV0T3V0cHV0TWFwcGluZ3MobmV3VGVtcGxhdGUsIGJwbW5GYWN0b3J5KSxcclxuICAgICAgICBvbGRNYXBwaW5ncztcclxuXHJcbiAgICBpZiAoIW5ld01hcHBpbmdzKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29udGV4dCkge1xyXG4gICAgICBjb21tYW5kU3RhY2suZXhlY3V0ZSgncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBidXNpbmVzc09iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0aWVzOiB7IGlucHV0T3V0cHV0OiBuZXdNYXBwaW5ncyB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29udGV4dCA9IGdldE9yQ3JlYXRlRXh0ZW5zaW9uRWxlbWVudHMoZWxlbWVudCk7XHJcbiAgICAgIG9sZE1hcHBpbmdzID0gZmluZEV4dGVuc2lvbihlbGVtZW50LCAnYWN0aXZpdGk6SW5wdXRPdXRwdXQnKTtcclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0LWxpc3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBjdXJyZW50T2JqZWN0OiBjb250ZXh0LFxyXG4gICAgICAgIHByb3BlcnR5TmFtZTogJ3ZhbHVlcycsXHJcbiAgICAgICAgb2JqZWN0c1RvQWRkOiBbIG5ld01hcHBpbmdzIF0sXHJcbiAgICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvbGRNYXBwaW5ncyA/IFsgb2xkTWFwcGluZ3MgXSA6IFtdXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlQWN0aXZpdGlGaWVsZChlbGVtZW50LCBuZXdUZW1wbGF0ZSwgY29udGV4dCkge1xyXG5cclxuICAgIHZhciBuZXdNYXBwaW5ncyA9IGNyZWF0ZUFjdGl2aXRpRmllbGRJbmplY3Rpb25zKG5ld1RlbXBsYXRlLCBicG1uRmFjdG9yeSksXHJcbiAgICAgICAgb2xkTWFwcGluZ3M7XHJcblxyXG4gICAgaWYgKCFuZXdNYXBwaW5ncykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAoY29udGV4dCkge1xyXG4gICAgICBjb21tYW5kU3RhY2suZXhlY3V0ZSgncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBidXNpbmVzc09iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0aWVzOiB7IGZpZWxkOiBuZXdNYXBwaW5ncyB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29udGV4dCA9IGdldE9yQ3JlYXRlRXh0ZW5zaW9uRWxlbWVudHMoZWxlbWVudCk7XHJcbiAgICAgIG9sZE1hcHBpbmdzID0gZmluZEV4dGVuc2lvbnMoZWxlbWVudCwgWydhY3Rpdml0aTpGaWVsZCddKTtcclxuXHJcbiAgICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKCdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgY3VycmVudE9iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0eU5hbWU6ICd2YWx1ZXMnLFxyXG4gICAgICAgIG9iamVjdHNUb0FkZDogbmV3TWFwcGluZ3MsXHJcbiAgICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvbGRNYXBwaW5ncyA/IG9sZE1hcHBpbmdzIDogW11cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlQWN0aXZpdGlQcm9wZXJ0aWVzKGVsZW1lbnQsIG5ld1RlbXBsYXRlLCBjb250ZXh0KSB7XHJcblxyXG4gICAgdmFyIG5ld1Byb3BlcnRpZXMgPSBjcmVhdGVBY3Rpdml0aVByb3BlcnRpZXMobmV3VGVtcGxhdGUsIGJwbW5GYWN0b3J5KSxcclxuICAgICAgICBvbGRQcm9wZXJ0aWVzO1xyXG5cclxuICAgIGlmICghbmV3UHJvcGVydGllcykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGNvbnRleHQpIHtcclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgYnVzaW5lc3NPYmplY3Q6IGNvbnRleHQsXHJcbiAgICAgICAgcHJvcGVydGllczogeyBwcm9wZXJ0aWVzOiBuZXdQcm9wZXJ0aWVzIH1cclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0ID0gZ2V0T3JDcmVhdGVFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuICAgICAgb2xkUHJvcGVydGllcyA9IGZpbmRFeHRlbnNpb24oZWxlbWVudCwgJ2FjdGl2aXRpOlByb3BlcnRpZXMnKTtcclxuXHJcbiAgICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKCdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgY3VycmVudE9iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0eU5hbWU6ICd2YWx1ZXMnLFxyXG4gICAgICAgIG9iamVjdHNUb0FkZDogWyBuZXdQcm9wZXJ0aWVzIF0sXHJcbiAgICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvbGRQcm9wZXJ0aWVzID8gWyBvbGRQcm9wZXJ0aWVzIF0gOiBbXVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIHVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgbmV3VGVtcGxhdGUsIGNvbnRleHQpIHtcclxuXHJcbiAgICB2YXIgbmV3UHJvcGVydGllcyA9IGNyZWF0ZUJwbW5Qcm9wZXJ0eVVwZGF0ZXMobmV3VGVtcGxhdGUsIGJwbW5GYWN0b3J5KTtcclxuXHJcbiAgICB2YXIgbmV3UHJvcGVydGllc0NvdW50ID0gT2JqZWN0LmtleXMobmV3UHJvcGVydGllcykubGVuZ3RoO1xyXG5cclxuICAgIGlmICghbmV3UHJvcGVydGllc0NvdW50KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29udGV4dCkge1xyXG4gICAgICBjb21tYW5kU3RhY2suZXhlY3V0ZSgncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBidXNpbmVzc09iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0aWVzOiBuZXdQcm9wZXJ0aWVzXHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbW9kZWxpbmcudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBuZXdQcm9wZXJ0aWVzKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIHVwZGF0ZUluT3V0KGVsZW1lbnQsIG5ld1RlbXBsYXRlLCBjb250ZXh0KSB7XHJcblxyXG4gICAgdmFyIG5ld0luT3V0ID0gY3JlYXRlQWN0aXZpdGlJbk91dChuZXdUZW1wbGF0ZSwgYnBtbkZhY3RvcnkpLFxyXG4gICAgICAgIG9sZEluT3V0O1xyXG5cclxuICAgIGlmICghbmV3SW5PdXQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChjb250ZXh0KSB7XHJcbiAgICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKCdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdCcsIHtcclxuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0OiBjb250ZXh0LFxyXG4gICAgICAgIHByb3BlcnRpZXM6IHsgaW5vdXQ6IG5ld0luT3V0IH1cclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0ID0gZ2V0T3JDcmVhdGVFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuICAgICAgb2xkSW5PdXQgPSBmaW5kRXh0ZW5zaW9ucyhjb250ZXh0LCBbICdhY3Rpdml0aTpJbicsICdhY3Rpdml0aTpPdXQnIF0pO1xyXG5cclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0LWxpc3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBjdXJyZW50T2JqZWN0OiBjb250ZXh0LFxyXG4gICAgICAgIHByb3BlcnR5TmFtZTogJ3ZhbHVlcycsXHJcbiAgICAgICAgb2JqZWN0c1RvQWRkOiBuZXdJbk91dCxcclxuICAgICAgICBvYmplY3RzVG9SZW1vdmU6IG9sZEluT3V0XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlRXhlY3V0aW9uTGlzdGVuZXIoZWxlbWVudCwgbmV3VGVtcGxhdGUsIGNvbnRleHQpIHtcclxuXHJcbiAgICB2YXIgbmV3RXhlY3V0aW9uTGlzdGVuZXJzID0gY3JlYXRlQWN0aXZpdGlFeGVjdXRpb25MaXN0ZW5lcnMobmV3VGVtcGxhdGUsIGJwbW5GYWN0b3J5KSxcclxuICAgICAgICBvbGRFeGVjdXRpb25zTGlzdGVuZXJzO1xyXG5cclxuICAgIGlmICghbmV3RXhlY3V0aW9uTGlzdGVuZXJzLmxlbmd0aCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGNvbnRleHQpIHtcclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgYnVzaW5lc3NPYmplY3Q6IGNvbnRleHQsXHJcbiAgICAgICAgcHJvcGVydGllczogeyBleGVjdXRpb25MaXN0ZW5lcjogbmV3RXhlY3V0aW9uTGlzdGVuZXJzIH1cclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0ID0gZ2V0T3JDcmVhdGVFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuICAgICAgb2xkRXhlY3V0aW9uc0xpc3RlbmVycyA9IGZpbmRFeHRlbnNpb25zKGNvbnRleHQsIFsgJ2FjdGl2aXRpOkV4ZWN1dGlvbkxpc3RlbmVyJyBdKTtcclxuXHJcbiAgICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKCdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgY3VycmVudE9iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0eU5hbWU6ICd2YWx1ZXMnLFxyXG4gICAgICAgIG9iamVjdHNUb0FkZDogbmV3RXhlY3V0aW9uTGlzdGVuZXJzLFxyXG4gICAgICAgIG9iamVjdHNUb1JlbW92ZTogb2xkRXhlY3V0aW9uc0xpc3RlbmVyc1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFVwZGF0ZSAvIHJlY3JlYXRlIGEgc2NvcGVkIGVsZW1lbnQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50IHRoZSBkaWFncmFtIHBhcmVudCBlbGVtZW50XHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHNjb3BlTmFtZSBuYW1lIG9mIHRoZSBzY29wZSwgaS5lLiBhY3Rpdml0aTpDb25uZWN0b3JcclxuICAgKiBAcGFyYW0ge09iamVjdH0gc2NvcGVEZWZpbml0aW9uXHJcbiAgICovXHJcbiAgZnVuY3Rpb24gdXBkYXRlU2NvcGVFbGVtZW50cyhlbGVtZW50LCBzY29wZU5hbWUsIHNjb3BlRGVmaW5pdGlvbikge1xyXG5cclxuICAgIHZhciBzY29wZUVsZW1lbnQgPSBicG1uRmFjdG9yeS5jcmVhdGUoc2NvcGVOYW1lKTtcclxuXHJcbiAgICAvLyB1cGRhdGUgYWN0aXZpdGk6aW5wdXRPdXRwdXRcclxuICAgIHVwZGF0ZUlvTWFwcGluZ3MoZWxlbWVudCwgc2NvcGVEZWZpbml0aW9uLCBzY29wZUVsZW1lbnQpO1xyXG5cclxuICAgIC8vIHVwZGF0ZSBhY3Rpdml0aTpmaWVsZFxyXG4gICAgdXBkYXRlQWN0aXZpdGlGaWVsZChlbGVtZW50LCBzY29wZURlZmluaXRpb24sIHNjb3BlRWxlbWVudCk7XHJcblxyXG4gICAgLy8gdXBkYXRlIGFjdGl2aXRpOnByb3BlcnRpZXNcclxuICAgIHVwZGF0ZUFjdGl2aXRpUHJvcGVydGllcyhlbGVtZW50LCBzY29wZURlZmluaXRpb24sIHNjb3BlRWxlbWVudCk7XHJcblxyXG4gICAgLy8gdXBkYXRlIG90aGVyIHByb3BlcnRpZXMgKGJwbW46Y29uZGl0aW9uLCBhY3Rpdml0aTphc3luYywgLi4uKVxyXG4gICAgdXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBzY29wZURlZmluaXRpb24sIHNjb3BlRWxlbWVudCk7XHJcblxyXG4gICAgLy8gdXBkYXRlIGFjdGl2aXRpOmluIGFuZCBhY3Rpdml0aTpvdXRcclxuICAgIHVwZGF0ZUluT3V0KGVsZW1lbnQsIHNjb3BlRGVmaW5pdGlvbiwgc2NvcGVFbGVtZW50KTtcclxuXHJcbiAgICAvLyB1cGRhdGUgYWN0aXZpdGk6ZXhlY3V0aW9uTGlzdGVuZXJcclxuICAgIHVwZGF0ZUV4ZWN1dGlvbkxpc3RlbmVyKGVsZW1lbnQsIHNjb3BlRGVmaW5pdGlvbiwgc2NvcGVFbGVtZW50KTtcclxuXHJcbiAgICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBnZXRPckNyZWF0ZUV4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQpO1xyXG4gICAgdmFyIG9sZFNjb3BlID0gZmluZEV4dGVuc2lvbihleHRlbnNpb25FbGVtZW50cywgc2NvcGVOYW1lKTtcclxuXHJcbiAgICBjb21tYW5kU3RhY2suZXhlY3V0ZSgncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QtbGlzdCcsIHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgY3VycmVudE9iamVjdDogZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgIHByb3BlcnR5TmFtZTogJ3ZhbHVlcycsXHJcbiAgICAgIG9iamVjdHNUb0FkZDogWyBzY29wZUVsZW1lbnQgXSxcclxuICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvbGRTY29wZSA/IFsgb2xkU2NvcGUgXSA6IFtdXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbXBvc2UgYW4gZWxlbWVudCB0ZW1wbGF0ZSBjaGFuZ2UgYWN0aW9uLCB1cGRhdGluZyBhbGxcclxuICAgKiBuZWNlc3NhcnkgdW5kZXJseWluZyBwcm9wZXJ0aWVzLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcclxuICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dC5lbGVtZW50XHJcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQub2xkVGVtcGxhdGVcclxuICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dC5uZXdUZW1wbGF0ZVxyXG4gICAqL1xyXG4gIHRoaXMucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuXHJcbiAgICB2YXIgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcclxuICAgICAgICBuZXdUZW1wbGF0ZSA9IGNvbnRleHQubmV3VGVtcGxhdGU7XHJcblxyXG4gICAgLy8gdXBkYXRlIGFjdGl2aXRpOm1vZGVsZXJUZW1wbGF0ZSBhdHRyaWJ1dGVcclxuICAgIHVwZGF0ZU1vZGVsZXJUZW1wbGF0ZShlbGVtZW50LCBuZXdUZW1wbGF0ZSk7XHJcblxyXG4gICAgaWYgKG5ld1RlbXBsYXRlKSB7XHJcblxyXG4gICAgICAvLyB1cGRhdGUgYWN0aXZpdGk6aW5wdXRPdXRwdXRcclxuICAgICAgdXBkYXRlSW9NYXBwaW5ncyhlbGVtZW50LCBuZXdUZW1wbGF0ZSk7XHJcblxyXG4gICAgICAvLyB1cGRhdGUgYWN0aXZpdGk6ZmllbGRcclxuICAgICAgdXBkYXRlQWN0aXZpdGlGaWVsZChlbGVtZW50LCBuZXdUZW1wbGF0ZSk7XHJcblxyXG4gICAgICAvLyB1cGRhdGUgYWN0aXZpdGk6cHJvcGVydGllc1xyXG4gICAgICB1cGRhdGVBY3Rpdml0aVByb3BlcnRpZXMoZWxlbWVudCwgbmV3VGVtcGxhdGUpO1xyXG5cclxuICAgICAgLy8gdXBkYXRlIG90aGVyIHByb3BlcnRpZXMgKGJwbW46Y29uZGl0aW9uLCBhY3Rpdml0aTphc3luYywgLi4uKVxyXG4gICAgICB1cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIG5ld1RlbXBsYXRlKTtcclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBhY3Rpdml0aTppbiBhbmQgYWN0aXZpdGk6b3V0XHJcbiAgICAgIHVwZGF0ZUluT3V0KGVsZW1lbnQsIG5ld1RlbXBsYXRlKTtcclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBhY3Rpdml0aTpleGVjdXRpb25MaXN0ZW5lclxyXG4gICAgICB1cGRhdGVFeGVjdXRpb25MaXN0ZW5lcihlbGVtZW50LCBuZXdUZW1wbGF0ZSk7XHJcblxyXG4gICAgICAvLyBsb29wIG9uIHNjb3BlcyBwcm9wZXJ0aWVzXHJcbiAgICAgIGZvckVhY2gobmV3VGVtcGxhdGUuc2NvcGVzLCBmdW5jdGlvbihzY29wZURlZmluaXRpb24sIHNjb3BlTmFtZSkge1xyXG4gICAgICAgIHVwZGF0ZVNjb3BlRWxlbWVudHMoZWxlbWVudCwgc2NvcGVOYW1lLCBzY29wZURlZmluaXRpb24pO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICB9XHJcbiAgfTtcclxufVxyXG5cclxuQ2hhbmdlRWxlbWVudFRlbXBsYXRlSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnLCAnY29tbWFuZFN0YWNrJywgJ2JwbW5GYWN0b3J5JyBdO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBDaGFuZ2VFbGVtZW50VGVtcGxhdGVIYW5kbGVyO1xyXG5cclxuXHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVCcG1uUHJvcGVydHlVcGRhdGVzKHRlbXBsYXRlLCBicG1uRmFjdG9yeSkge1xyXG5cclxuICB2YXIgcHJvcGVydHlVcGRhdGVzID0ge307XHJcblxyXG4gIHRlbXBsYXRlLnByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwKSB7XHJcblxyXG4gICAgdmFyIGJpbmRpbmcgPSBwLmJpbmRpbmcsXHJcbiAgICAgICAgYmluZGluZ1RhcmdldCA9IGJpbmRpbmcubmFtZSxcclxuICAgICAgICBwcm9wZXJ0eVZhbHVlO1xyXG5cclxuICAgIGlmIChiaW5kaW5nLnR5cGUgPT09ICdwcm9wZXJ0eScpIHtcclxuXHJcbiAgICAgIGlmIChiaW5kaW5nVGFyZ2V0ID09PSAnY29uZGl0aW9uRXhwcmVzc2lvbicpIHtcclxuICAgICAgICBwcm9wZXJ0eVZhbHVlID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkZvcm1hbEV4cHJlc3Npb24nLCB7XHJcbiAgICAgICAgICBib2R5OiBwLnZhbHVlLFxyXG4gICAgICAgICAgbGFuZ3VhZ2U6IGJpbmRpbmcuc2NyaXB0Rm9ybWF0XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcHJvcGVydHlWYWx1ZSA9IHAudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIGFzc2lnbmluZyBhY3Rpdml0aTphc3luYyB0byB0cnVlfGZhbHNlXHJcbiAgICAgIC8vIGFzc2lnbmluZyBicG1uOmNvbmRpdGlvbkV4cHJlc3Npb24gdG8geyAkdHlwZTogJ2JwbW46Rm9ybWFsRXhwcmVzc2lvbicsIC4uLiB9XHJcbiAgICAgIHByb3BlcnR5VXBkYXRlc1tiaW5kaW5nVGFyZ2V0XSA9IHByb3BlcnR5VmFsdWU7XHJcblxyXG4gICAgICAvLyBtYWtlIHN1cmUgd2UgdW5zZXQgb3RoZXIgXCJpbXBsZW1lbnRhdGlvbiB0eXBlc1wiXHJcbiAgICAgIC8vIHdoZW4gYXBwbHlpbmcgYSBhY3Rpdml0aTpjbGFzcyB0ZW1wbGF0ZSBvbnRvIGEgcHJlY29uZmlndXJlZFxyXG4gICAgICAvLyBhY3Rpdml0aTpkZWxlZ2F0ZUV4cHJlc3Npb24gZWxlbWVudFxyXG4gICAgICBpZiAoQUNUSVZJVElfU0VSVklDRV9UQVNLX0xJS0UuaW5kZXhPZihiaW5kaW5nVGFyZ2V0KSAhPT0gLTEpIHtcclxuICAgICAgICBBQ1RJVklUSV9TRVJWSUNFX1RBU0tfTElLRS5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApIHtcclxuICAgICAgICAgIGlmIChwcm9wICE9PSBiaW5kaW5nVGFyZ2V0KSB7XHJcbiAgICAgICAgICAgIHByb3BlcnR5VXBkYXRlc1twcm9wXSA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gcHJvcGVydHlVcGRhdGVzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aUZpZWxkSW5qZWN0aW9ucyh0ZW1wbGF0ZSwgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgaW5qZWN0aW9ucyA9IFtdO1xyXG5cclxuICB0ZW1wbGF0ZS5wcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24ocCkge1xyXG4gICAgdmFyIGJpbmRpbmcgPSBwLmJpbmRpbmcsXHJcbiAgICAgICAgYmluZGluZ1R5cGUgPSBiaW5kaW5nLnR5cGU7XHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09ICdhY3Rpdml0aTpmaWVsZCcpIHtcclxuICAgICAgaW5qZWN0aW9ucy5wdXNoKGNyZWF0ZUFjdGl2aXRpRmllbGRJbmplY3Rpb24oXHJcbiAgICAgICAgYmluZGluZywgcC52YWx1ZSwgYnBtbkZhY3RvcnlcclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIGlmIChpbmplY3Rpb25zLmxlbmd0aCkge1xyXG4gICAgcmV0dXJuIGluamVjdGlvbnM7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aVByb3BlcnRpZXModGVtcGxhdGUsIGJwbW5GYWN0b3J5KSB7XHJcblxyXG4gIHZhciBwcm9wZXJ0aWVzID0gW107XHJcblxyXG4gIHRlbXBsYXRlLnByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwKSB7XHJcbiAgICB2YXIgYmluZGluZyA9IHAuYmluZGluZyxcclxuICAgICAgICBiaW5kaW5nVHlwZSA9IGJpbmRpbmcudHlwZTtcclxuXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09ICdhY3Rpdml0aTpwcm9wZXJ0eScpIHtcclxuICAgICAgcHJvcGVydGllcy5wdXNoKGNyZWF0ZUFjdGl2aXRpUHJvcGVydHkoXHJcbiAgICAgICAgYmluZGluZywgcC52YWx1ZSwgYnBtbkZhY3RvcnlcclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIGlmIChwcm9wZXJ0aWVzLmxlbmd0aCkge1xyXG4gICAgcmV0dXJuIGJwbW5GYWN0b3J5LmNyZWF0ZSgnYWN0aXZpdGk6UHJvcGVydGllcycsIHtcclxuICAgICAgdmFsdWVzOiBwcm9wZXJ0aWVzXHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUlucHV0T3V0cHV0TWFwcGluZ3ModGVtcGxhdGUsIGJwbW5GYWN0b3J5KSB7XHJcblxyXG4gIHZhciBpbnB1dFBhcmFtZXRlcnMgPSBbXSxcclxuICAgICAgb3V0cHV0UGFyYW1ldGVycyA9IFtdO1xyXG5cclxuICB0ZW1wbGF0ZS5wcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24ocCkge1xyXG4gICAgdmFyIGJpbmRpbmcgPSBwLmJpbmRpbmcsXHJcbiAgICAgICAgYmluZGluZ1R5cGUgPSBiaW5kaW5nLnR5cGU7XHJcblxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSAnYWN0aXZpdGk6aW5wdXRQYXJhbWV0ZXInKSB7XHJcbiAgICAgIGlucHV0UGFyYW1ldGVycy5wdXNoKGNyZWF0ZUlucHV0UGFyYW1ldGVyKFxyXG4gICAgICAgIGJpbmRpbmcsIHAudmFsdWUsIGJwbW5GYWN0b3J5XHJcbiAgICAgICkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChiaW5kaW5nVHlwZSA9PT0gJ2FjdGl2aXRpOm91dHB1dFBhcmFtZXRlcicpIHtcclxuICAgICAgb3V0cHV0UGFyYW1ldGVycy5wdXNoKGNyZWF0ZU91dHB1dFBhcmFtZXRlcihcclxuICAgICAgICBiaW5kaW5nLCBwLnZhbHVlLCBicG1uRmFjdG9yeVxyXG4gICAgICApKTtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gZG8gd2UgbmVlZCB0byBjcmVhdGUgbmV3IGlvTWFwcGluZ3MgKD8pXHJcbiAgaWYgKG91dHB1dFBhcmFtZXRlcnMubGVuZ3RoIHx8IGlucHV0UGFyYW1ldGVycy5sZW5ndGgpIHtcclxuICAgIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOklucHV0T3V0cHV0Jywge1xyXG4gICAgICBpbnB1dFBhcmFtZXRlcnM6IGlucHV0UGFyYW1ldGVycyxcclxuICAgICAgb3V0cHV0UGFyYW1ldGVyczogb3V0cHV0UGFyYW1ldGVyc1xyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aUluT3V0KHRlbXBsYXRlLCBicG1uRmFjdG9yeSkge1xyXG5cclxuICB2YXIgaW5PdXRzID0gW107XHJcblxyXG4gIHRlbXBsYXRlLnByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwKSB7XHJcbiAgICB2YXIgYmluZGluZyA9IHAuYmluZGluZyxcclxuICAgICAgICBiaW5kaW5nVHlwZSA9IGJpbmRpbmcudHlwZTtcclxuXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09ICdhY3Rpdml0aTppbicpIHtcclxuICAgICAgaW5PdXRzLnB1c2goY3JlYXRlQWN0aXZpdGlJbihcclxuICAgICAgICBiaW5kaW5nLCBwLnZhbHVlLCBicG1uRmFjdG9yeVxyXG4gICAgICApKTtcclxuICAgIH0gZWxzZVxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSAnYWN0aXZpdGk6b3V0Jykge1xyXG4gICAgICBpbk91dHMucHVzaChjcmVhdGVBY3Rpdml0aU91dChcclxuICAgICAgICBiaW5kaW5nLCBwLnZhbHVlLCBicG1uRmFjdG9yeVxyXG4gICAgICApKTtcclxuICAgIH0gZWxzZVxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSAnYWN0aXZpdGk6aW46YnVzaW5lc3NLZXknKSB7XHJcbiAgICAgIGluT3V0cy5wdXNoKGNyZWF0ZUFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkoXHJcbiAgICAgICAgYmluZGluZywgcC52YWx1ZSwgYnBtbkZhY3RvcnlcclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBpbk91dHM7XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aUV4ZWN1dGlvbkxpc3RlbmVycyh0ZW1wbGF0ZSwgYnBtbkZhY3RvcnkpIHtcclxuXHJcbiAgdmFyIGV4ZWN1dGlvbkxpc3RlbmVyID0gW107XHJcblxyXG4gIHRlbXBsYXRlLnByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwKSB7XHJcbiAgICB2YXIgYmluZGluZyA9IHAuYmluZGluZyxcclxuICAgICAgICBiaW5kaW5nVHlwZSA9IGJpbmRpbmcudHlwZTtcclxuXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09ICdhY3Rpdml0aTpleGVjdXRpb25MaXN0ZW5lcicpIHtcclxuICAgICAgZXhlY3V0aW9uTGlzdGVuZXIucHVzaChjcmVhdGVBY3Rpdml0aUV4ZWN1dGlvbkxpc3RlbmVyU2NyaXB0KFxyXG4gICAgICAgIGJpbmRpbmcsIHAudmFsdWUsIGJwbW5GYWN0b3J5XHJcbiAgICAgICkpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gZXhlY3V0aW9uTGlzdGVuZXI7XHJcbn1cclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIENoYW5nZUVsZW1lbnRUZW1wbGF0ZUhhbmRsZXIgPSByZXF1aXJlKCcuL0NoYW5nZUVsZW1lbnRUZW1wbGF0ZUhhbmRsZXInKTtcclxuXHJcbnZhciBnZXRUZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL0hlbHBlcicpLmdldFRlbXBsYXRlLFxyXG4gICAgZ2V0RGVmYXVsdFRlbXBsYXRlID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZ2V0RGVmYXVsdFRlbXBsYXRlO1xyXG5cclxuZnVuY3Rpb24gcmVnaXN0ZXJIYW5kbGVycyhjb21tYW5kU3RhY2ssIGVsZW1lbnRUZW1wbGF0ZXMsIGV2ZW50QnVzLCBlbGVtZW50UmVnaXN0cnkpIHtcclxuICBjb21tYW5kU3RhY2sucmVnaXN0ZXJIYW5kbGVyKFxyXG4gICAgJ3Byb3BlcnRpZXNQYW5lbC5hY3Rpdml0aS5jaGFuZ2VUZW1wbGF0ZScsXHJcbiAgICBDaGFuZ2VFbGVtZW50VGVtcGxhdGVIYW5kbGVyXHJcbiAgKTtcclxuXHJcbiAgLy8gYXBwbHkgZGVmYXVsdCBlbGVtZW50IHRlbXBsYXRlcyBvbiBzaGFwZSBjcmVhdGlvblxyXG4gIGV2ZW50QnVzLm9uKFsgJ2NvbW1hbmRTdGFjay5zaGFwZS5jcmVhdGUucG9zdEV4ZWN1dGVkJyBdLCBmdW5jdGlvbihjb250ZXh0KSB7XHJcbiAgICBhcHBseURlZmF1bHRUZW1wbGF0ZShjb250ZXh0LmNvbnRleHQuc2hhcGUsIGVsZW1lbnRUZW1wbGF0ZXMsIGNvbW1hbmRTdGFjayk7XHJcbiAgfSk7XHJcblxyXG4gIC8vIGFwcGx5IGRlZmF1bHQgZWxlbWVudCB0ZW1wbGF0ZXMgb24gY29ubmVjdGlvbiBjcmVhdGlvblxyXG4gIGV2ZW50QnVzLm9uKFsgJ2NvbW1hbmRTdGFjay5jb25uZWN0aW9uLmNyZWF0ZS5wb3N0RXhlY3V0ZWQnIF0sIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIGFwcGx5RGVmYXVsdFRlbXBsYXRlKGNvbnRleHQuY29udGV4dC5jb25uZWN0aW9uLCBlbGVtZW50VGVtcGxhdGVzLCBjb21tYW5kU3RhY2spO1xyXG4gIH0pO1xyXG59XHJcblxyXG5yZWdpc3RlckhhbmRsZXJzLiRpbmplY3QgPSBbICdjb21tYW5kU3RhY2snLCAnZWxlbWVudFRlbXBsYXRlcycsICdldmVudEJ1cycsICdlbGVtZW50UmVnaXN0cnknIF07XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgX19pbml0X186IFsgcmVnaXN0ZXJIYW5kbGVycyBdXHJcbn07XHJcblxyXG5cclxuZnVuY3Rpb24gYXBwbHlEZWZhdWx0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcywgY29tbWFuZFN0YWNrKSB7XHJcblxyXG4gIGlmICghZ2V0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcylcclxuICAgICAgJiYgZ2V0RGVmYXVsdFRlbXBsYXRlKGVsZW1lbnQsIGVsZW1lbnRUZW1wbGF0ZXMpKSB7XHJcblxyXG4gICAgdmFyIGNvbW1hbmQgPSAncHJvcGVydGllc1BhbmVsLmFjdGl2aXRpLmNoYW5nZVRlbXBsYXRlJztcclxuICAgIHZhciBjb21tYW5kQ29udGV4dCA9IHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgbmV3VGVtcGxhdGU6IGdldERlZmF1bHRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKVxyXG4gICAgfTtcclxuXHJcbiAgICBjb21tYW5kU3RhY2suZXhlY3V0ZShjb21tYW5kLCBjb21tYW5kQ29udGV4dCk7XHJcbiAgfVxyXG59XHJcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xyXG4gIF9fZGVwZW5kc19fOiBbXHJcbiAgICByZXF1aXJlKCcuL2NtZC9pbmRleCcpLFxyXG4gICAgcmVxdWlyZSgnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnKS5kZWZhdWx0XHJcbiAgXSxcclxuICBfX2luaXRfXzogW1xyXG4gICAgJ2N1c3RvbUVsZW1lbnRzUHJvcGVydGllc0FjdGl2YXRvcicsXHJcbiAgICAnZWxlbWVudFRlbXBsYXRlc0xvYWRlcidcclxuICBdLFxyXG4gIGN1c3RvbUVsZW1lbnRzUHJvcGVydGllc0FjdGl2YXRvcjogWyAndHlwZScsIHJlcXVpcmUoJy4vQ3VzdG9tRWxlbWVudHNQcm9wZXJ0aWVzQWN0aXZhdG9yJykgXSxcclxuICBlbGVtZW50VGVtcGxhdGVzOiBbICd0eXBlJywgcmVxdWlyZSgnLi9FbGVtZW50VGVtcGxhdGVzJykgXSxcclxuICBlbGVtZW50VGVtcGxhdGVzTG9hZGVyOiBbICd0eXBlJywgcmVxdWlyZSgnLi9FbGVtZW50VGVtcGxhdGVzTG9hZGVyJykgXVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldFRlbXBsYXRlID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZ2V0VGVtcGxhdGUsXHJcbiAgICBnZXRUZW1wbGF0ZUlkID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZ2V0VGVtcGxhdGVJZDtcclxuXHJcbnZhciBmaW5kID0gcmVxdWlyZSgnbG9kYXNoL2ZpbmQnKTtcclxuXHJcbnZhciBURU1QTEFURV9BVFRSID0gcmVxdWlyZSgnLi4vSGVscGVyJykuVEVNUExBVEVfQVRUUjtcclxuXHJcbmZ1bmN0aW9uIGlzQW55KGVsZW1lbnQsIHR5cGVzKSB7XHJcbiAgcmV0dXJuIHR5cGVzLnJlZHVjZShmdW5jdGlvbihyZXN1bHQsIHR5cGUpIHtcclxuICAgIHJldHVybiByZXN1bHQgfHwgaXMoZWxlbWVudCwgdHlwZSk7XHJcbiAgfSwgZmFsc2UpO1xyXG59XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBvcHRpb25zID0gZ2V0VGVtcGxhdGVPcHRpb25zKGVsZW1lbnQsIGVsZW1lbnRUZW1wbGF0ZXMsIHRyYW5zbGF0ZSk7XHJcblxyXG4gIGlmIChvcHRpb25zLmxlbmd0aCA9PT0gMSAmJiAhb3B0aW9uc1swXS5pc0RlZmF1bHQpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIHNlbGVjdCBlbGVtZW50IHRlbXBsYXRlICh2aWEgZHJvcGRvd24pXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6ICdlbGVtZW50VGVtcGxhdGUtY2hvb3NlcicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdFbGVtZW50IFRlbXBsYXRlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnYWN0aXZpdGk6bW9kZWxlclRlbXBsYXRlJyxcclxuICAgIHNlbGVjdE9wdGlvbnM6IG9wdGlvbnMsXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHByb3BlcnRpZXMpIHtcclxuICAgICAgcmV0dXJuIGFwcGx5VGVtcGxhdGUoZWxlbWVudCwgcHJvcGVydGllc1tURU1QTEFURV9BVFRSXSwgZWxlbWVudFRlbXBsYXRlcyk7XHJcbiAgICB9LFxyXG4gICAgZGlzYWJsZWQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICB2YXIgdGVtcGxhdGUgPSBnZXRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKTtcclxuXHJcbiAgICAgIHJldHVybiB0ZW1wbGF0ZSAmJiBpc0RlZmF1bHRUZW1wbGF0ZSh0ZW1wbGF0ZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxufTtcclxuXHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBhcHBseVRlbXBsYXRlKGVsZW1lbnQsIG5ld1RlbXBsYXRlSWQsIGVsZW1lbnRUZW1wbGF0ZXMpIHtcclxuXHJcbiAgLy8gY2xlYW51cFxyXG4gIC8vIGNsZWFyIGlucHV0IG91dHB1dCBtYXBwaW5nc1xyXG4gIC8vIHVuZG8gY2hhbmdlcyB0byBwcm9wZXJ0aWVzIGRlZmluZWQgaW4gdGVtcGxhdGVcclxuXHJcbiAgLy8gcmUtZXN0YWJsaXNoXHJcbiAgLy8gc2V0IGlucHV0IG91dHB1dCBtYXBwaW5nc1xyXG4gIC8vIGFwcGx5IGNoYW5nZXMgdG8gcHJvcGVydGllcyBhcyBkZWZpbmVkIGluIG5ldyB0ZW1wbGF0ZVxyXG5cclxuICB2YXIgb2xkVGVtcGxhdGUgPSBnZXRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKSxcclxuICAgICAgbmV3VGVtcGxhdGUgPSBlbGVtZW50VGVtcGxhdGVzLmdldChuZXdUZW1wbGF0ZUlkKTtcclxuXHJcbiAgaWYgKG9sZFRlbXBsYXRlID09PSBuZXdUZW1wbGF0ZSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGNtZDogJ3Byb3BlcnRpZXNQYW5lbC5hY3Rpdml0aS5jaGFuZ2VUZW1wbGF0ZScsXHJcbiAgICBjb250ZXh0OiB7XHJcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgIG9sZFRlbXBsYXRlOiBvbGRUZW1wbGF0ZSxcclxuICAgICAgbmV3VGVtcGxhdGU6IG5ld1RlbXBsYXRlXHJcbiAgICB9XHJcbiAgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0VGVtcGxhdGVPcHRpb25zKGVsZW1lbnQsIGVsZW1lbnRUZW1wbGF0ZXMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgY3VycmVudFRlbXBsYXRlSWQgPSBnZXRUZW1wbGF0ZUlkKGVsZW1lbnQpO1xyXG5cclxuICB2YXIgZW1wdHlPcHRpb24gPSB7XHJcbiAgICBuYW1lOiAnJyxcclxuICAgIHZhbHVlOiAnJ1xyXG4gIH07XHJcblxyXG4gIHZhciBhbGxPcHRpb25zID0gZWxlbWVudFRlbXBsYXRlcy5nZXRBbGwoKS5yZWR1Y2UoZnVuY3Rpb24odGVtcGxhdGVzLCB0KSB7XHJcbiAgICBpZiAoIWlzQW55KGVsZW1lbnQsIHQuYXBwbGllc1RvKSkge1xyXG4gICAgICByZXR1cm4gdGVtcGxhdGVzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0ZW1wbGF0ZXMuY29uY2F0KHtcclxuICAgICAgbmFtZTogdHJhbnNsYXRlKHQubmFtZSksXHJcbiAgICAgIHZhbHVlOiB0LmlkLFxyXG4gICAgICBpc0RlZmF1bHQ6IHQuaXNEZWZhdWx0XHJcbiAgICB9KTtcclxuICB9LCBbIGVtcHR5T3B0aW9uIF0pO1xyXG5cclxuXHJcbiAgdmFyIGRlZmF1bHRPcHRpb24gPSBmaW5kKGFsbE9wdGlvbnMsIGZ1bmN0aW9uKG9wdGlvbikge1xyXG4gICAgcmV0dXJuIGlzRGVmYXVsdFRlbXBsYXRlKG9wdGlvbik7XHJcbiAgfSk7XHJcblxyXG4gIHZhciBjdXJyZW50T3B0aW9uID0gZmluZChhbGxPcHRpb25zLCBmdW5jdGlvbihvcHRpb24pIHtcclxuICAgIHJldHVybiBvcHRpb24udmFsdWUgPT09IGN1cnJlbnRUZW1wbGF0ZUlkO1xyXG4gIH0pO1xyXG5cclxuICBpZiAoY3VycmVudFRlbXBsYXRlSWQgJiYgIWN1cnJlbnRPcHRpb24pIHtcclxuICAgIGN1cnJlbnRPcHRpb24gPSB1bmtub3duVGVtcGxhdGUoY3VycmVudFRlbXBsYXRlSWQsIHRyYW5zbGF0ZSk7XHJcblxyXG4gICAgYWxsT3B0aW9ucy5wdXNoKGN1cnJlbnRPcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFkZWZhdWx0T3B0aW9uKSB7XHJcblxyXG4gICAgLy8gcmV0dXJuIGFsbCBvcHRpb25zLCBpbmNsdWRpbmcgZW1wdHlcclxuICAgIC8vIGFuZCBvcHRpb25hbGx5IHVua25vd25UZW1wbGF0ZSBvcHRpb25cclxuICAgIHJldHVybiBhbGxPcHRpb25zO1xyXG4gIH1cclxuXHJcbiAgLy8gc3BlY2lhbCBsaW1pdGVkIGhhbmRsaW5nIGZvclxyXG4gIC8vIGRlZmF1bHQgb3B0aW9uc1xyXG5cclxuICB2YXIgb3B0aW9ucyA9IFtdO1xyXG5cclxuICAvLyBjdXJyZW50IHRlbXBsYXRlIG5vdCBzZXRcclxuICBpZiAoIWN1cnJlbnRUZW1wbGF0ZUlkKSB7XHJcbiAgICBvcHRpb25zLnB1c2goe1xyXG4gICAgICBuYW1lOiAnJyxcclxuICAgICAgdmFsdWU6ICcnXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8vIGN1cnJlbnQgdGVtcGxhdGUgbm90IGRlZmF1bHRcclxuICBpZiAoY3VycmVudE9wdGlvbiAmJiBjdXJyZW50T3B0aW9uICE9PSBkZWZhdWx0T3B0aW9uKSB7XHJcbiAgICBvcHRpb25zLnB1c2goY3VycmVudE9wdGlvbik7XHJcbiAgfVxyXG5cclxuICBvcHRpb25zLnB1c2goZGVmYXVsdE9wdGlvbik7XHJcblxyXG4gIC8vIFsgKGVtcHR5KSwgKGN1cnJlbnQpLCBkZWZhdWx0T3B0aW9uIF1cclxuICByZXR1cm4gb3B0aW9ucztcclxufVxyXG5cclxuZnVuY3Rpb24gdW5rbm93blRlbXBsYXRlKHRlbXBsYXRlSWQsIHRyYW5zbGF0ZSkge1xyXG4gIHJldHVybiB7XHJcbiAgICBuYW1lOiB0cmFuc2xhdGUoJ1t1bmtub3duIHRlbXBsYXRlOiB7dGVtcGxhdGVJZH1dJywgeyB0ZW1wbGF0ZUlkOiB0ZW1wbGF0ZUlkIH0pLFxyXG4gICAgdmFsdWU6IHRlbXBsYXRlSWRcclxuICB9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0RlZmF1bHRUZW1wbGF0ZShlbGVtZW50VGVtcGxhdGUpIHtcclxuICByZXR1cm4gZWxlbWVudFRlbXBsYXRlLmlzRGVmYXVsdDtcclxufSIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyk7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGdldFRlbXBsYXRlID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZ2V0VGVtcGxhdGUsXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKTtcclxuXHJcbnZhciBmaW5kRXh0ZW5zaW9uID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZmluZEV4dGVuc2lvbixcclxuICAgIGZpbmRFeHRlbnNpb25zID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZmluZEV4dGVuc2lvbnMsXHJcbiAgICBmaW5kSW5wdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuLi9IZWxwZXInKS5maW5kSW5wdXRQYXJhbWV0ZXIsXHJcbiAgICBmaW5kT3V0cHV0UGFyYW1ldGVyID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZmluZE91dHB1dFBhcmFtZXRlcixcclxuICAgIGZpbmRBY3Rpdml0aVByb3BlcnR5ID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZmluZEFjdGl2aXRpUHJvcGVydHksXHJcbiAgICBmaW5kQWN0aXZpdGlJbk91dCA9IHJlcXVpcmUoJy4uL0hlbHBlcicpLmZpbmRBY3Rpdml0aUluT3V0O1xyXG5cclxudmFyIGNyZWF0ZUFjdGl2aXRpUHJvcGVydHkgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aVByb3BlcnR5LFxyXG4gICAgY3JlYXRlSW5wdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVJbnB1dFBhcmFtZXRlcixcclxuICAgIGNyZWF0ZU91dHB1dFBhcmFtZXRlciA9IHJlcXVpcmUoJy4uL0NyZWF0ZUhlbHBlcicpLmNyZWF0ZU91dHB1dFBhcmFtZXRlcixcclxuICAgIGNyZWF0ZUFjdGl2aXRpSW4gPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aUluLFxyXG4gICAgY3JlYXRlQWN0aXZpdGlPdXQgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aU91dCxcclxuICAgIGNyZWF0ZUFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5LFxyXG4gICAgY3JlYXRlQWN0aXZpdGlGaWVsZEluamVjdGlvbiA9IHJlcXVpcmUoJy4uL0NyZWF0ZUhlbHBlcicpLmNyZWF0ZUFjdGl2aXRpRmllbGRJbmplY3Rpb247XHJcblxyXG52YXIgQUNUSVZJVElfUFJPUEVSVFlfVFlQRSA9ICdhY3Rpdml0aTpwcm9wZXJ0eScsXHJcbiAgICBBQ1RJVklUSV9JTlBVVF9QQVJBTUVURVJfVFlQRSA9ICdhY3Rpdml0aTppbnB1dFBhcmFtZXRlcicsXHJcbiAgICBBQ1RJVklUSV9PVVRQVVRfUEFSQU1FVEVSX1RZUEUgPSAnYWN0aXZpdGk6b3V0cHV0UGFyYW1ldGVyJyxcclxuICAgIEFDVElWSVRJX0lOX1RZUEUgPSAnYWN0aXZpdGk6aW4nLFxyXG4gICAgQUNUSVZJVElfT1VUX1RZUEUgPSAnYWN0aXZpdGk6b3V0JyxcclxuICAgIEFDVElWSVRJX0lOX0JVU0lORVNTX0tFWV9UWVBFID0gJ2FjdGl2aXRpOmluOmJ1c2luZXNzS2V5JyxcclxuICAgIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUl9UWVBFID0gJ2FjdGl2aXRpOmV4ZWN1dGlvbkxpc3RlbmVyJyxcclxuICAgIEFDVElWSVRJX0ZJRUxEID0gJ2FjdGl2aXRpOmZpZWxkJztcclxuXHJcbnZhciBCQVNJQ19NT0RETEVfVFlQRVMgPSBbXHJcbiAgJ0Jvb2xlYW4nLFxyXG4gICdJbnRlZ2VyJyxcclxuICAnU3RyaW5nJ1xyXG5dO1xyXG5cclxudmFyIEVYVEVOU0lPTl9CSU5ESU5HX1RZUEVTID0gW1xyXG4gIEFDVElWSVRJX1BST1BFUlRZX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5QVVRfUEFSQU1FVEVSX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUUFVUX1BBUkFNRVRFUl9UWVBFLFxyXG4gIEFDVElWSVRJX0lOX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5fQlVTSU5FU1NfS0VZX1RZUEUsXHJcbiAgQUNUSVZJVElfRklFTERcclxuXTtcclxuXHJcbnZhciBJT19CSU5ESU5HX1RZUEVTID0gW1xyXG4gIEFDVElWSVRJX0lOUFVUX1BBUkFNRVRFUl9UWVBFLFxyXG4gIEFDVElWSVRJX09VVFBVVF9QQVJBTUVURVJfVFlQRVxyXG5dO1xyXG5cclxudmFyIElOX09VVF9CSU5ESU5HX1RZUEVTID0gW1xyXG4gIEFDVElWSVRJX0lOX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5fQlVTSU5FU1NfS0VZX1RZUEVcclxuXTtcclxuXHJcbi8qKlxyXG4gKiBJbmplY3RzIGN1c3RvbSBwcm9wZXJ0aWVzIGludG8gdGhlIGdpdmVuIGdyb3VwLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7RWxlbWVudFRlbXBsYXRlc30gZWxlbWVudFRlbXBsYXRlc1xyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2xhdGVcclxuICovXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcywgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgdGVtcGxhdGUgPSBnZXRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKTtcclxuXHJcbiAgaWYgKCF0ZW1wbGF0ZSkge1xyXG4gICAgcmV0dXJuIFtdO1xyXG4gIH1cclxuXHJcbiAgdmFyIHJlbmRlckN1c3RvbUZpZWxkID0gZnVuY3Rpb24oaWQsIHAsIGlkeCkge1xyXG4gICAgdmFyIHByb3BlcnR5VHlwZSA9IHAudHlwZTtcclxuXHJcbiAgICB2YXIgZW50cnlPcHRpb25zID0ge1xyXG4gICAgICBpZDogaWQsXHJcbiAgICAgIGRlc2NyaXB0aW9uOiBwLmRlc2NyaXB0aW9uLFxyXG4gICAgICBsYWJlbDogcC5sYWJlbCA/IHRyYW5zbGF0ZShwLmxhYmVsKSA6IHAubGFiZWwsXHJcbiAgICAgIG1vZGVsUHJvcGVydHk6IGlkLFxyXG4gICAgICBnZXQ6IHByb3BlcnR5R2V0dGVyKGlkLCBwKSxcclxuICAgICAgc2V0OiBwcm9wZXJ0eVNldHRlcihpZCwgcCwgYnBtbkZhY3RvcnkpLFxyXG4gICAgICB2YWxpZGF0ZTogcHJvcGVydHlWYWxpZGF0b3IoaWQsIHAsIHRyYW5zbGF0ZSlcclxuICAgIH07XHJcblxyXG4gICAgdmFyIGVudHJ5O1xyXG5cclxuICAgIGlmIChwcm9wZXJ0eVR5cGUgPT09ICdCb29sZWFuJykge1xyXG4gICAgICBlbnRyeSA9IGVudHJ5RmFjdG9yeS5jaGVja2JveChlbnRyeU9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChwcm9wZXJ0eVR5cGUgPT09ICdTdHJpbmcnKSB7XHJcbiAgICAgIGVudHJ5ID0gZW50cnlGYWN0b3J5LnRleHRGaWVsZChlbnRyeU9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChwcm9wZXJ0eVR5cGUgPT09ICdUZXh0Jykge1xyXG4gICAgICBlbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0Qm94KGVudHJ5T3B0aW9ucyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHByb3BlcnR5VHlwZSA9PT0gJ0Ryb3Bkb3duJykge1xyXG4gICAgICBlbnRyeU9wdGlvbnMuc2VsZWN0T3B0aW9ucyA9IHAuY2hvaWNlcztcclxuXHJcbiAgICAgIGVudHJ5ID0gZW50cnlGYWN0b3J5LnNlbGVjdEJveChlbnRyeU9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBlbnRyeTtcclxuICB9O1xyXG5cclxuICB2YXIgZ3JvdXBzID0gW107XHJcbiAgdmFyIGlkLCBlbnRyeTtcclxuXHJcbiAgdmFyIGN1c3RvbUZpZWxkc0dyb3VwID0ge1xyXG4gICAgaWQ6ICdjdXN0b21GaWVsZCcsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdDdXN0b20gRmllbGRzJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcbiAgdGVtcGxhdGUucHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uKHAsIGlkeCkge1xyXG5cclxuICAgIGlkID0gJ2N1c3RvbS0nICsgdGVtcGxhdGUuaWQgKyAnLScgKyBpZHg7XHJcblxyXG4gICAgZW50cnkgPSByZW5kZXJDdXN0b21GaWVsZChpZCwgcCwgaWR4KTtcclxuICAgIGlmIChlbnRyeSkge1xyXG4gICAgICBjdXN0b21GaWVsZHNHcm91cC5lbnRyaWVzLnB1c2goZW50cnkpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIGlmIChjdXN0b21GaWVsZHNHcm91cC5lbnRyaWVzLmxlbmd0aCA+IDApIHtcclxuICAgIGdyb3Vwcy5wdXNoKGN1c3RvbUZpZWxkc0dyb3VwKTtcclxuICB9XHJcblxyXG4gIGlmICh0ZW1wbGF0ZS5zY29wZXMpIHtcclxuICAgIGZvciAodmFyIHNjb3BlTmFtZSBpbiB0ZW1wbGF0ZS5zY29wZXMpIHtcclxuXHJcbiAgICAgIHZhciBzY29wZSA9IHRlbXBsYXRlLnNjb3Blc1tzY29wZU5hbWVdO1xyXG4gICAgICB2YXIgaWRTY29wZU5hbWUgPSBzY29wZU5hbWUucmVwbGFjZSgvOi9nLCAnXycpO1xyXG5cclxuICAgICAgdmFyIGN1c3RvbVNjb3BlRmllbGRzR3JvdXAgPSB7XHJcbiAgICAgICAgaWQ6ICdjdXN0b21GaWVsZC0nICsgaWRTY29wZU5hbWUsXHJcbiAgICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ3VzdG9tIEZpZWxkcyBmb3Igc2NvcGU6ICcpICsgc2NvcGVOYW1lLFxyXG4gICAgICAgIGVudHJpZXM6IFtdXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBzY29wZS5wcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24ocCwgaWR4KSB7XHJcblxyXG4gICAgICAgIHZhciBwcm9wZXJ0eUlkID0gJ2N1c3RvbS0nICsgdGVtcGxhdGUuaWQgKyAnLScgKyBpZFNjb3BlTmFtZSArICctJyArIGlkeDtcclxuXHJcbiAgICAgICAgdmFyIHNjb3BlZFByb3BlcnR5ID0gcHJvcGVydHlXaXRoU2NvcGUocCwgc2NvcGVOYW1lKTtcclxuXHJcbiAgICAgICAgZW50cnkgPSByZW5kZXJDdXN0b21GaWVsZChwcm9wZXJ0eUlkLCBzY29wZWRQcm9wZXJ0eSwgaWR4KTtcclxuICAgICAgICBpZiAoZW50cnkpIHtcclxuICAgICAgICAgIGN1c3RvbVNjb3BlRmllbGRzR3JvdXAuZW50cmllcy5wdXNoKGVudHJ5KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaWYgKGN1c3RvbVNjb3BlRmllbGRzR3JvdXAuZW50cmllcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgZ3JvdXBzLnB1c2goY3VzdG9tU2NvcGVGaWVsZHNHcm91cCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBncm91cHM7XHJcbn07XHJcblxyXG5cclxuLy8gZ2V0dGVycywgc2V0dGVycyBhbmQgdmFsaWRhdG9ycyAvLy8vLy8vLy8vLy8vLy9cclxuXHJcblxyXG4vKipcclxuICogUmV0dXJuIGEgZ2V0dGVyIHRoYXQgcmV0cmlldmVzIHRoZSBnaXZlbiBwcm9wZXJ0eS5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcclxuICogQHBhcmFtIHtQcm9wZXJ0eURlc2NyaXB0b3J9IHByb3BlcnR5XHJcbiAqXHJcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxyXG4gKi9cclxuZnVuY3Rpb24gcHJvcGVydHlHZXR0ZXIobmFtZSwgcHJvcGVydHkpIHtcclxuXHJcbiAgLyogZ2V0dGVyICovXHJcbiAgcmV0dXJuIGZ1bmN0aW9uIGdldChlbGVtZW50KSB7XHJcbiAgICB2YXIgdmFsdWUgPSBnZXRQcm9wZXJ0eVZhbHVlKGVsZW1lbnQsIHByb3BlcnR5KTtcclxuXHJcbiAgICByZXR1cm4gb2JqZWN0V2l0aEtleShuYW1lLCB2YWx1ZSk7XHJcbiAgfTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybiBhIHNldHRlciB0aGF0IHVwZGF0ZXMgdGhlIGdpdmVuIHByb3BlcnR5LlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICpcclxuICogQHJldHVybiB7RnVuY3Rpb259XHJcbiAqL1xyXG5mdW5jdGlvbiBwcm9wZXJ0eVNldHRlcihuYW1lLCBwcm9wZXJ0eSwgYnBtbkZhY3RvcnkpIHtcclxuXHJcbiAgLyogc2V0dGVyICovXHJcbiAgcmV0dXJuIGZ1bmN0aW9uIHNldChlbGVtZW50LCB2YWx1ZXMpIHtcclxuXHJcbiAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbbmFtZV07XHJcblxyXG4gICAgcmV0dXJuIHNldFByb3BlcnR5VmFsdWUoZWxlbWVudCwgcHJvcGVydHksIHZhbHVlLCBicG1uRmFjdG9yeSk7XHJcbiAgfTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybiBhIHZhbGlkYXRvciB0aGF0IGVuc3VyZXMgdGhlIHByb3BlcnR5IGlzIG9rLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNsYXRlXHJcbiAqXHJcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxyXG4gKi9cclxuZnVuY3Rpb24gcHJvcGVydHlWYWxpZGF0b3IobmFtZSwgcHJvcGVydHksIHRyYW5zbGF0ZSkge1xyXG5cclxuICAvKiB2YWxpZGF0b3IgKi9cclxuICByZXR1cm4gZnVuY3Rpb24gdmFsaWRhdGUoZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbbmFtZV07XHJcblxyXG4gICAgdmFyIGVycm9yID0gdmFsaWRhdGVWYWx1ZSh2YWx1ZSwgcHJvcGVydHksIHRyYW5zbGF0ZSk7XHJcblxyXG4gICAgaWYgKGVycm9yKSB7XHJcbiAgICAgIHJldHVybiBvYmplY3RXaXRoS2V5KG5hbWUsIGVycm9yKTtcclxuICAgIH1cclxuICB9O1xyXG59XHJcblxyXG5cclxuLy8gZ2V0LCBzZXQgYW5kIHZhbGlkYXRlIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuLyoqXHJcbiAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eSBkZXNjcmlwdG9yLFxyXG4gKiBvbiB0aGUgcGFzc2VkIGRpYWdyYW0gZWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICpcclxuICogQHJldHVybiB7QW55fVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UHJvcGVydHlWYWx1ZShlbGVtZW50LCBwcm9wZXJ0eSkge1xyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgdmFyIGJpbmRpbmcgPSBwcm9wZXJ0eS5iaW5kaW5nLFxyXG4gICAgICBzY29wZSA9IHByb3BlcnR5LnNjb3BlO1xyXG5cclxuICB2YXIgYmluZGluZ1R5cGUgPSBiaW5kaW5nLnR5cGUsXHJcbiAgICAgIGJpbmRpbmdOYW1lID0gYmluZGluZy5uYW1lO1xyXG5cclxuICB2YXIgcHJvcGVydHlWYWx1ZSA9IHByb3BlcnR5LnZhbHVlIHx8ICcnO1xyXG5cclxuICBpZiAoc2NvcGUpIHtcclxuICAgIGJvID0gZmluZEV4dGVuc2lvbihibywgc2NvcGUubmFtZSk7XHJcbiAgICBpZiAoIWJvKSB7XHJcbiAgICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gcHJvcGVydHlcclxuICBpZiAoYmluZGluZ1R5cGUgPT09ICdwcm9wZXJ0eScpIHtcclxuXHJcbiAgICB2YXIgdmFsdWUgPSBiby5nZXQoYmluZGluZ05hbWUpO1xyXG5cclxuICAgIGlmIChiaW5kaW5nTmFtZSA9PT0gJ2NvbmRpdGlvbkV4cHJlc3Npb24nKSB7XHJcbiAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgIHJldHVybiB2YWx1ZS5ib2R5O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIHJldHVybiBkZWZpbmVkIGRlZmF1bHRcclxuICAgICAgICByZXR1cm4gcHJvcGVydHlWYWx1ZTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gcmV0dXJuIHZhbHVlOyBkZWZhdWx0IHRvIGRlZmluZWQgZGVmYXVsdFxyXG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJyA/IHZhbHVlIDogcHJvcGVydHlWYWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHZhciBhY3Rpdml0aVByb3BlcnRpZXMsXHJcbiAgICAgIGFjdGl2aXRpUHJvcGVydHk7XHJcblxyXG4gIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfUFJPUEVSVFlfVFlQRSkge1xyXG4gICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgIGFjdGl2aXRpUHJvcGVydGllcyA9IGJvLmdldCgncHJvcGVydGllcycpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgYWN0aXZpdGlQcm9wZXJ0aWVzID0gZmluZEV4dGVuc2lvbihibywgJ2FjdGl2aXRpOlByb3BlcnRpZXMnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoYWN0aXZpdGlQcm9wZXJ0aWVzKSB7XHJcbiAgICAgIGFjdGl2aXRpUHJvcGVydHkgPSBmaW5kQWN0aXZpdGlQcm9wZXJ0eShhY3Rpdml0aVByb3BlcnRpZXMsIGJpbmRpbmcpO1xyXG5cclxuICAgICAgaWYgKGFjdGl2aXRpUHJvcGVydHkpIHtcclxuICAgICAgICByZXR1cm4gYWN0aXZpdGlQcm9wZXJ0eS52YWx1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlO1xyXG4gIH1cclxuXHJcbiAgdmFyIGlucHV0T3V0cHV0LFxyXG4gICAgICBpb1BhcmFtZXRlcjtcclxuXHJcbiAgaWYgKElPX0JJTkRJTkdfVFlQRVMuaW5kZXhPZihiaW5kaW5nVHlwZSkgIT09IC0xKSB7XHJcblxyXG4gICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgIGlucHV0T3V0cHV0ID0gYm8uZ2V0KCdpbnB1dE91dHB1dCcpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaW5wdXRPdXRwdXQgPSBmaW5kRXh0ZW5zaW9uKGJvLCAnYWN0aXZpdGk6SW5wdXRPdXRwdXQnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWlucHV0T3V0cHV0KSB7XHJcbiAgICAgIC8vIGlvUGFyYW1ldGVyIGNhbm5vdCBleGlzdCB5ZXQsIHJldHVybiBwcm9wZXJ0eSB2YWx1ZVxyXG4gICAgICByZXR1cm4gcHJvcGVydHlWYWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIGFjdGl2aXRpIGlucHV0IHBhcmFtZXRlclxyXG4gIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfSU5QVVRfUEFSQU1FVEVSX1RZUEUpIHtcclxuICAgIGlvUGFyYW1ldGVyID0gZmluZElucHV0UGFyYW1ldGVyKGlucHV0T3V0cHV0LCBiaW5kaW5nKTtcclxuXHJcbiAgICBpZiAoaW9QYXJhbWV0ZXIpIHtcclxuICAgICAgaWYgKGJpbmRpbmcuc2NyaXB0Rm9ybWF0KSB7XHJcbiAgICAgICAgaWYgKGlvUGFyYW1ldGVyLmRlZmluaXRpb24pIHtcclxuICAgICAgICAgIHJldHVybiBpb1BhcmFtZXRlci5kZWZpbml0aW9uLnZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gaW9QYXJhbWV0ZXIudmFsdWUgfHwgJyc7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcHJvcGVydHlWYWx1ZTtcclxuICB9XHJcblxyXG4gIC8vIGFjdGl2aXRpIG91dHB1dCBwYXJhbWV0ZXJcclxuICBpZiAoYmluZGluZy50eXBlID09PSBBQ1RJVklUSV9PVVRQVVRfUEFSQU1FVEVSX1RZUEUpIHtcclxuICAgIGlvUGFyYW1ldGVyID0gZmluZE91dHB1dFBhcmFtZXRlcihpbnB1dE91dHB1dCwgYmluZGluZyk7XHJcblxyXG4gICAgaWYgKGlvUGFyYW1ldGVyKSB7XHJcbiAgICAgIHJldHVybiBpb1BhcmFtZXRlci5uYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlO1xyXG4gIH1cclxuXHJcblxyXG4gIHZhciBpb0VsZW1lbnQ7XHJcblxyXG4gIGlmIChJTl9PVVRfQklORElOR19UWVBFUy5pbmRleE9mKGJpbmRpbmdUeXBlKSAhPSAtMSkge1xyXG4gICAgaW9FbGVtZW50ID0gZmluZEFjdGl2aXRpSW5PdXQoYm8sIGJpbmRpbmcpO1xyXG5cclxuICAgIGlmIChpb0VsZW1lbnQpIHtcclxuICAgICAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9JTl9CVVNJTkVTU19LRVlfVFlQRSkge1xyXG4gICAgICAgIHJldHVybiBpb0VsZW1lbnQuYnVzaW5lc3NLZXk7XHJcbiAgICAgIH0gZWxzZVxyXG4gICAgICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX09VVF9UWVBFKSB7XHJcbiAgICAgICAgcmV0dXJuIGlvRWxlbWVudC50YXJnZXQ7XHJcbiAgICAgIH0gZWxzZVxyXG4gICAgICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX0lOX1RZUEUpIHtcclxuICAgICAgICByZXR1cm4gaW9FbGVtZW50W2JpbmRpbmcuZXhwcmVzc2lvbiA/ICdzb3VyY2VFeHByZXNzaW9uJyA6ICdzb3VyY2UnXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlO1xyXG4gIH1cclxuXHJcbiAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9FWEVDVVRJT05fTElTVEVORVJfVFlQRSkge1xyXG4gICAgdmFyIGV4ZWN1dGlvbkxpc3RlbmVyO1xyXG4gICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgIGV4ZWN1dGlvbkxpc3RlbmVyID0gYm8uZ2V0KCdleGVjdXRpb25MaXN0ZW5lcicpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZXhlY3V0aW9uTGlzdGVuZXIgPSBmaW5kRXh0ZW5zaW9uKGJvLCAnYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXInKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZXhlY3V0aW9uTGlzdGVuZXIuc2NyaXB0LnZhbHVlO1xyXG4gIH1cclxuXHJcbiAgdmFyIGZpZWxkSW5qZWN0aW9uO1xyXG4gIGlmIChBQ1RJVklUSV9GSUVMRCA9PT0gYmluZGluZ1R5cGUpIHtcclxuICAgIHZhciBmaWVsZEluamVjdGlvbnMgPSBmaW5kRXh0ZW5zaW9ucyhibywgWyAnYWN0aXZpdGk6RmllbGQnIF0pO1xyXG4gICAgZmllbGRJbmplY3Rpb25zLmZvckVhY2goZnVuY3Rpb24oaXRlbSkge1xyXG4gICAgICBpZiAoaXRlbS5uYW1lID09PSBiaW5kaW5nLm5hbWUpIHtcclxuICAgICAgICBmaWVsZEluamVjdGlvbiA9IGl0ZW07XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgaWYgKGZpZWxkSW5qZWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiBmaWVsZEluamVjdGlvbi5zdHJpbmcgfHwgZmllbGRJbmplY3Rpb24uZXhwcmVzc2lvbjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHRocm93IHVua25vd25Qcm9wZXJ0eUJpbmRpbmcocHJvcGVydHkpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5nZXRQcm9wZXJ0eVZhbHVlID0gZ2V0UHJvcGVydHlWYWx1ZTtcclxuXHJcblxyXG4vKipcclxuICogUmV0dXJuIGFuIHVwZGF0ZSBvcGVyYXRpb24gdGhhdCBjaGFuZ2VzIHRoZSBkaWFncmFtXHJcbiAqIGVsZW1lbnQncyBjdXN0b20gcHJvcGVydHkgdG8gdGhlIGdpdmVuIHZhbHVlLlxyXG4gKlxyXG4gKiBUaGUgcmVzcG9uc2Ugb2YgdGhpcyBtZXRob2Qgd2lsbCBiZSBwcm9jZXNzZWQgdmlhXHJcbiAqIHtAbGluayBQcm9wZXJ0aWVzUGFuZWwjYXBwbHlDaGFuZ2VzfS5cclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm4ge09iamVjdHxBcnJheTxPYmplY3Q+fSByZXN1bHRzIHRvIGJlIHByb2Nlc3NlZFxyXG4gKi9cclxuZnVuY3Rpb24gc2V0UHJvcGVydHlWYWx1ZShlbGVtZW50LCBwcm9wZXJ0eSwgdmFsdWUsIGJwbW5GYWN0b3J5KSB7XHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBiaW5kaW5nID0gcHJvcGVydHkuYmluZGluZyxcclxuICAgICAgc2NvcGUgPSBwcm9wZXJ0eS5zY29wZTtcclxuXHJcbiAgdmFyIGJpbmRpbmdUeXBlID0gYmluZGluZy50eXBlLFxyXG4gICAgICBiaW5kaW5nTmFtZSA9IGJpbmRpbmcubmFtZTtcclxuXHJcbiAgdmFyIHByb3BlcnR5VmFsdWU7XHJcblxyXG4gIHZhciB1cGRhdGVzID0gW107XHJcblxyXG4gIHZhciBleHRlbnNpb25FbGVtZW50cztcclxuXHJcbiAgaWYgKEVYVEVOU0lPTl9CSU5ESU5HX1RZUEVTLmluZGV4T2YoYmluZGluZ1R5cGUpICE9PSAtMSkge1xyXG4gICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBiby5nZXQoJ2V4dGVuc2lvbkVsZW1lbnRzJyk7XHJcblxyXG4gICAgLy8gY3JlYXRlIGV4dGVuc2lvbiBlbGVtZW50cywgaWYgdGhleSBkbyBub3QgZXhpc3QgKHlldClcclxuICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnLCBudWxsLCBlbGVtZW50LCBicG1uRmFjdG9yeSk7XHJcblxyXG4gICAgICB1cGRhdGVzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KFxyXG4gICAgICAgIGVsZW1lbnQsIGJvLCBvYmplY3RXaXRoS2V5KCdleHRlbnNpb25FbGVtZW50cycsIGV4dGVuc2lvbkVsZW1lbnRzKVxyXG4gICAgICApKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChzY29wZSkge1xyXG4gICAgYm8gPSBmaW5kRXh0ZW5zaW9uKGJvLCBzY29wZS5uYW1lKTtcclxuICAgIGlmICghYm8pIHtcclxuICAgICAgYm8gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoc2NvcGUubmFtZSwgbnVsbCwgZWxlbWVudCwgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChcclxuICAgICAgICBibywgZXh0ZW5zaW9uRWxlbWVudHMsICd2YWx1ZXMnLCBbIGJvIF1cclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBwcm9wZXJ0eVxyXG4gIGlmIChiaW5kaW5nVHlwZSA9PT0gJ3Byb3BlcnR5Jykge1xyXG5cclxuICAgIGlmIChiaW5kaW5nTmFtZSA9PT0gJ2NvbmRpdGlvbkV4cHJlc3Npb24nKSB7XHJcblxyXG4gICAgICBwcm9wZXJ0eVZhbHVlID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkZvcm1hbEV4cHJlc3Npb24nLCB7XHJcbiAgICAgICAgYm9keTogdmFsdWUsXHJcbiAgICAgICAgbGFuZ3VhZ2U6IGJpbmRpbmcuc2NyaXB0Rm9ybWF0XHJcbiAgICAgIH0sIGJvLCBicG1uRmFjdG9yeSk7XHJcbiAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgdmFyIG1vZGRsZVByb3BlcnR5RGVzY3JpcHRvciA9IGJvLiRkZXNjcmlwdG9yLnByb3BlcnRpZXNCeU5hbWVbYmluZGluZ05hbWVdO1xyXG5cclxuICAgICAgdmFyIG1vZGRsZVR5cGUgPSBtb2RkbGVQcm9wZXJ0eURlc2NyaXB0b3IudHlwZTtcclxuXHJcbiAgICAgIC8vIG1ha2Ugc3VyZSB3ZSBvbmx5IHVwZGF0ZSBTdHJpbmcsIEludGVnZXIsIFJlYWwgYW5kXHJcbiAgICAgIC8vIEJvb2xlYW4gcHJvcGVydGllcyAoZG8gbm90IGFjY2lkZW50YWxseSBvdmVycmlkZSBjb21wbGV4IG9iamVjdHMuLi4pXHJcbiAgICAgIGlmIChCQVNJQ19NT0RETEVfVFlQRVMuaW5kZXhPZihtb2RkbGVUeXBlKSA9PT0gLTEpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBzZXQgbW9kZGxlIHR5cGUgPCcgKyBtb2RkbGVUeXBlICsgJz4nKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG1vZGRsZVR5cGUgPT09ICdCb29sZWFuJykge1xyXG4gICAgICAgIHByb3BlcnR5VmFsdWUgPSAhIXZhbHVlO1xyXG4gICAgICB9IGVsc2VcclxuICAgICAgaWYgKG1vZGRsZVR5cGUgPT09ICdJbnRlZ2VyJykge1xyXG4gICAgICAgIHByb3BlcnR5VmFsdWUgPSBwYXJzZUludCh2YWx1ZSwgMTApO1xyXG5cclxuICAgICAgICBpZiAoaXNOYU4ocHJvcGVydHlWYWx1ZSkpIHtcclxuICAgICAgICAgIC8vIGRvIG5vdCB3cml0ZSBOYU4gdmFsdWVcclxuICAgICAgICAgIHByb3BlcnR5VmFsdWUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHByb3BlcnR5VmFsdWUgPSB2YWx1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChwcm9wZXJ0eVZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChcclxuICAgICAgICBlbGVtZW50LCBibywgb2JqZWN0V2l0aEtleShiaW5kaW5nTmFtZSwgcHJvcGVydHlWYWx1ZSlcclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBhY3Rpdml0aTpwcm9wZXJ0eVxyXG4gIHZhciBhY3Rpdml0aVByb3BlcnRpZXMsXHJcbiAgICAgIGV4aXN0aW5nQWN0aXZpdGlQcm9wZXJ0eSxcclxuICAgICAgbmV3QWN0aXZpdGlQcm9wZXJ0eTtcclxuXHJcbiAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9QUk9QRVJUWV9UWVBFKSB7XHJcblxyXG4gICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgIGFjdGl2aXRpUHJvcGVydGllcyA9IGJvLmdldCgncHJvcGVydGllcycpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgYWN0aXZpdGlQcm9wZXJ0aWVzID0gZmluZEV4dGVuc2lvbihleHRlbnNpb25FbGVtZW50cywgJ2FjdGl2aXRpOlByb3BlcnRpZXMnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWFjdGl2aXRpUHJvcGVydGllcykge1xyXG4gICAgICBhY3Rpdml0aVByb3BlcnRpZXMgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2FjdGl2aXRpOlByb3BlcnRpZXMnLCBudWxsLCBibywgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChcclxuICAgICAgICAgIGVsZW1lbnQsIGJvLCB7IHByb3BlcnRpZXM6IGFjdGl2aXRpUHJvcGVydGllcyB9XHJcbiAgICAgICAgKSk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChcclxuICAgICAgICAgIGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCAndmFsdWVzJywgWyBhY3Rpdml0aVByb3BlcnRpZXMgXVxyXG4gICAgICAgICkpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZXhpc3RpbmdBY3Rpdml0aVByb3BlcnR5ID0gZmluZEFjdGl2aXRpUHJvcGVydHkoYWN0aXZpdGlQcm9wZXJ0aWVzLCBiaW5kaW5nKTtcclxuXHJcbiAgICBuZXdBY3Rpdml0aVByb3BlcnR5ID0gY3JlYXRlQWN0aXZpdGlQcm9wZXJ0eShiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgIHVwZGF0ZXMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgZWxlbWVudCxcclxuICAgICAgYWN0aXZpdGlQcm9wZXJ0aWVzLFxyXG4gICAgICAndmFsdWVzJyxcclxuICAgICAgbnVsbCxcclxuICAgICAgWyBuZXdBY3Rpdml0aVByb3BlcnR5IF0sXHJcbiAgICAgIGV4aXN0aW5nQWN0aXZpdGlQcm9wZXJ0eSA/IFsgZXhpc3RpbmdBY3Rpdml0aVByb3BlcnR5IF0gOiBbXVxyXG4gICAgKSk7XHJcbiAgfVxyXG5cclxuICAvLyBhY3Rpdml0aTppbnB1dFBhcmFtZXRlclxyXG4gIC8vIGFjdGl2aXRpOm91dHB1dFBhcmFtZXRlclxyXG4gIHZhciBpbnB1dE91dHB1dCxcclxuICAgICAgZXhpc3RpbmdJb1BhcmFtZXRlcixcclxuICAgICAgbmV3SW9QYXJhbWV0ZXI7XHJcblxyXG4gIGlmIChJT19CSU5ESU5HX1RZUEVTLmluZGV4T2YoYmluZGluZ1R5cGUpICE9PSAtMSkge1xyXG5cclxuICAgIGlmIChzY29wZSkge1xyXG4gICAgICBpbnB1dE91dHB1dCA9IGJvLmdldCgnaW5wdXRPdXRwdXQnKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlucHV0T3V0cHV0ID0gZmluZEV4dGVuc2lvbihleHRlbnNpb25FbGVtZW50cywgJ2FjdGl2aXRpOklucHV0T3V0cHV0Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gY3JlYXRlIGlucHV0T3V0cHV0IGVsZW1lbnQsIGlmIGl0IGRvIG5vdCBleGlzdCAoeWV0KVxyXG4gICAgaWYgKCFpbnB1dE91dHB1dCkge1xyXG4gICAgICBpbnB1dE91dHB1dCA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6SW5wdXRPdXRwdXQnLCBudWxsLCBibywgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChcclxuICAgICAgICAgIGVsZW1lbnQsIGJvLCB7IGlucHV0T3V0cHV0OiBpbnB1dE91dHB1dCB9XHJcbiAgICAgICAgKSk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChcclxuICAgICAgICAgIGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCAndmFsdWVzJywgaW5wdXRPdXRwdXRcclxuICAgICAgICApKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9JTlBVVF9QQVJBTUVURVJfVFlQRSkge1xyXG5cclxuICAgIGV4aXN0aW5nSW9QYXJhbWV0ZXIgPSBmaW5kSW5wdXRQYXJhbWV0ZXIoaW5wdXRPdXRwdXQsIGJpbmRpbmcpO1xyXG5cclxuICAgIG5ld0lvUGFyYW1ldGVyID0gY3JlYXRlSW5wdXRQYXJhbWV0ZXIoYmluZGluZywgdmFsdWUsIGJwbW5GYWN0b3J5KTtcclxuXHJcbiAgICB1cGRhdGVzLnB1c2goY21kSGVscGVyLmFkZEFuZFJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoXHJcbiAgICAgIGVsZW1lbnQsXHJcbiAgICAgIGlucHV0T3V0cHV0LFxyXG4gICAgICAnaW5wdXRQYXJhbWV0ZXJzJyxcclxuICAgICAgbnVsbCxcclxuICAgICAgWyBuZXdJb1BhcmFtZXRlciBdLFxyXG4gICAgICBleGlzdGluZ0lvUGFyYW1ldGVyID8gWyBleGlzdGluZ0lvUGFyYW1ldGVyIF0gOiBbXVxyXG4gICAgKSk7XHJcbiAgfVxyXG5cclxuICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX09VVFBVVF9QQVJBTUVURVJfVFlQRSkge1xyXG5cclxuICAgIGV4aXN0aW5nSW9QYXJhbWV0ZXIgPSBmaW5kT3V0cHV0UGFyYW1ldGVyKGlucHV0T3V0cHV0LCBiaW5kaW5nKTtcclxuXHJcbiAgICBuZXdJb1BhcmFtZXRlciA9IGNyZWF0ZU91dHB1dFBhcmFtZXRlcihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgIHVwZGF0ZXMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgZWxlbWVudCxcclxuICAgICAgaW5wdXRPdXRwdXQsXHJcbiAgICAgICdvdXRwdXRQYXJhbWV0ZXJzJyxcclxuICAgICAgbnVsbCxcclxuICAgICAgWyBuZXdJb1BhcmFtZXRlciBdLFxyXG4gICAgICBleGlzdGluZ0lvUGFyYW1ldGVyID8gWyBleGlzdGluZ0lvUGFyYW1ldGVyIF0gOiBbXVxyXG4gICAgKSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgLy8gYWN0aXZpdGk6aW5cclxuICAvLyBhY3Rpdml0aTpvdXRcclxuICAvLyBhY3Rpdml0aTppbjpidXNpbmVzc0tleVxyXG4gIHZhciBleGlzdGluZ0luT3V0LFxyXG4gICAgICBuZXdJbk91dDtcclxuXHJcbiAgaWYgKElOX09VVF9CSU5ESU5HX1RZUEVTLmluZGV4T2YoYmluZGluZ1R5cGUpICE9PSAtMSkge1xyXG5cclxuICAgIGV4aXN0aW5nSW5PdXQgPSBmaW5kQWN0aXZpdGlJbk91dChibywgYmluZGluZyk7XHJcblxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9JTl9UWVBFKSB7XHJcbiAgICAgIG5ld0luT3V0ID0gY3JlYXRlQWN0aXZpdGlJbihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpO1xyXG4gICAgfSBlbHNlXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX09VVF9UWVBFKSB7XHJcbiAgICAgIG5ld0luT3V0ID0gY3JlYXRlQWN0aXZpdGlPdXQoYmluZGluZywgdmFsdWUsIGJwbW5GYWN0b3J5KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG5ld0luT3V0ID0gY3JlYXRlQWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleShiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZXMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgZWxlbWVudCxcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgICd2YWx1ZXMnLFxyXG4gICAgICBudWxsLFxyXG4gICAgICBbIG5ld0luT3V0IF0sXHJcbiAgICAgIGV4aXN0aW5nSW5PdXQgPyBbIGV4aXN0aW5nSW5PdXQgXSA6IFtdXHJcbiAgICApKTtcclxuICB9XHJcblxyXG4gIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfRklFTEQpIHtcclxuICAgIHZhciBleGlzdGluZ0ZpZWxkSW5qZWN0aW9ucyA9IGZpbmRFeHRlbnNpb25zKGJvLCBbICdhY3Rpdml0aTpGaWVsZCcgXSk7XHJcbiAgICB2YXIgbmV3RmllbGRJbmplY3Rpb25zID0gW107XHJcblxyXG4gICAgaWYgKGV4aXN0aW5nRmllbGRJbmplY3Rpb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgZXhpc3RpbmdGaWVsZEluamVjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihpdGVtKSB7XHJcbiAgICAgICAgaWYgKGl0ZW0ubmFtZSA9PT0gYmluZGluZy5uYW1lKSB7XHJcbiAgICAgICAgICBuZXdGaWVsZEluamVjdGlvbnMucHVzaChjcmVhdGVBY3Rpdml0aUZpZWxkSW5qZWN0aW9uKGJpbmRpbmcsIHZhbHVlLCBicG1uRmFjdG9yeSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBuZXdGaWVsZEluamVjdGlvbnMucHVzaChpdGVtKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbmV3RmllbGRJbmplY3Rpb25zLnB1c2goY3JlYXRlQWN0aXZpdGlGaWVsZEluamVjdGlvbihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVzLnB1c2goY21kSGVscGVyLmFkZEFuZFJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoXHJcbiAgICAgIGVsZW1lbnQsXHJcbiAgICAgIGV4dGVuc2lvbkVsZW1lbnRzLFxyXG4gICAgICAndmFsdWVzJyxcclxuICAgICAgbnVsbCxcclxuICAgICAgbmV3RmllbGRJbmplY3Rpb25zLFxyXG4gICAgICBleGlzdGluZ0ZpZWxkSW5qZWN0aW9ucyA/IGV4aXN0aW5nRmllbGRJbmplY3Rpb25zIDogW11cclxuICAgICkpO1xyXG4gIH1cclxuXHJcbiAgaWYgKHVwZGF0ZXMubGVuZ3RoKSB7XHJcbiAgICByZXR1cm4gdXBkYXRlcztcclxuICB9XHJcblxyXG4gIC8vIHF1aWNrIHdhcm5pbmcgZm9yIGJldHRlciBkZWJ1Z2dpbmdcclxuICBjb25zb2xlLndhcm4oJ25vIHVwZGF0ZScsIGVsZW1lbnQsIHByb3BlcnR5LCB2YWx1ZSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLnNldFByb3BlcnR5VmFsdWUgPSBzZXRQcm9wZXJ0eVZhbHVlO1xyXG5cclxuLyoqXHJcbiAqIFZhbGlkYXRlIHZhbHVlIG9mIGEgZ2l2ZW4gcHJvcGVydHkuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNsYXRlXHJcbiAqXHJcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCB2YWxpZGF0aW9uIGVycm9yc1xyXG4gKi9cclxuZnVuY3Rpb24gdmFsaWRhdGVWYWx1ZSh2YWx1ZSwgcHJvcGVydHksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgY29uc3RyYWludHMgPSBwcm9wZXJ0eS5jb25zdHJhaW50cyB8fCB7fTtcclxuXHJcbiAgaWYgKGNvbnN0cmFpbnRzLm5vdEVtcHR5ICYmIGlzRW1wdHkodmFsdWUpKSB7XHJcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdNdXN0IG5vdCBiZSBlbXB0eScpO1xyXG4gIH1cclxuXHJcbiAgaWYgKGNvbnN0cmFpbnRzLm1heExlbmd0aCAmJiB2YWx1ZS5sZW5ndGggPiBjb25zdHJhaW50cy5tYXhMZW5ndGgpIHtcclxuICAgIHJldHVybiB0cmFuc2xhdGUoJ011c3QgaGF2ZSBtYXggbGVuZ3RoIHtsZW5ndGh9JywgeyBsZW5ndGg6IGNvbnN0cmFpbnRzLm1heExlbmd0aCB9KTtcclxuICB9XHJcblxyXG4gIGlmIChjb25zdHJhaW50cy5taW5MZW5ndGggJiYgdmFsdWUubGVuZ3RoIDwgY29uc3RyYWludHMubWluTGVuZ3RoKSB7XHJcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdNdXN0IGhhdmUgbWluIGxlbmd0aCB7bGVuZ3RofScsIHsgbGVuZ3RoOiBjb25zdHJhaW50cy5taW5MZW5ndGggfSk7XHJcbiAgfVxyXG5cclxuICB2YXIgcGF0dGVybiA9IGNvbnN0cmFpbnRzLnBhdHRlcm4sXHJcbiAgICAgIG1lc3NhZ2U7XHJcblxyXG4gIGlmIChwYXR0ZXJuKSB7XHJcblxyXG4gICAgaWYgKHR5cGVvZiBwYXR0ZXJuICE9PSAnc3RyaW5nJykge1xyXG4gICAgICBtZXNzYWdlID0gcGF0dGVybi5tZXNzYWdlO1xyXG4gICAgICBwYXR0ZXJuID0gcGF0dGVybi52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIW1hdGNoZXNQYXR0ZXJuKHZhbHVlLCBwYXR0ZXJuKSkge1xyXG4gICAgICByZXR1cm4gbWVzc2FnZSB8fCB0cmFuc2xhdGUoJ011c3QgbWF0Y2ggcGF0dGVybiB7cGF0dGVybn0nLCB7IHBhdHRlcm46IHBhdHRlcm4gfSk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5cclxuLy8gbWlzYyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIHByb3BlcnR5V2l0aFNjb3BlKHByb3BlcnR5LCBzY29wZU5hbWUpIHtcclxuICBpZiAoIXNjb3BlTmFtZSkge1xyXG4gICAgcmV0dXJuIHByb3BlcnR5O1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGFzc2lnbih7fSwgcHJvcGVydHksIHtcclxuICAgIHNjb3BlOiB7XHJcbiAgICAgIG5hbWU6IHNjb3BlTmFtZVxyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJuIGFuIG9iamVjdCB3aXRoIGEgc2luZ2xlIGtleSAtPiB2YWx1ZSBhc3NvY2lhdGlvbi5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxyXG4gKiBAcGFyYW0ge0FueX0gdmFsdWVcclxuICpcclxuICogQHJldHVybiB7T2JqZWN0fVxyXG4gKi9cclxuZnVuY3Rpb24gb2JqZWN0V2l0aEtleShrZXksIHZhbHVlKSB7XHJcbiAgdmFyIG9iaiA9IHt9O1xyXG5cclxuICBvYmpba2V5XSA9IHZhbHVlO1xyXG5cclxuICByZXR1cm4gb2JqO1xyXG59XHJcblxyXG4vKipcclxuICogRG9lcyB0aGUgZ2l2ZW4gc3RyaW5nIG1hdGNoIHRoZSBzcGVjaWZpZWQgcGF0dGVybj9cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxyXG4gKiBAcGFyYW0ge1N0cmluZ30gcGF0dGVyblxyXG4gKlxyXG4gKiBAcmV0dXJuIHtCb29sZWFufVxyXG4gKi9cclxuZnVuY3Rpb24gbWF0Y2hlc1BhdHRlcm4oc3RyLCBwYXR0ZXJuKSB7XHJcbiAgdmFyIHJlZ2V4cCA9IG5ldyBSZWdFeHAocGF0dGVybik7XHJcblxyXG4gIHJldHVybiByZWdleHAudGVzdChzdHIpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0VtcHR5KHN0cikge1xyXG4gIHJldHVybiAhc3RyIHx8IC9eXFxzKiQvLnRlc3Qoc3RyKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhIG5ldyB7QGxpbmsgRXJyb3J9IGluZGljYXRpbmcgYW4gdW5rbm93blxyXG4gKiBwcm9wZXJ0eSBiaW5kaW5nLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICpcclxuICogQHJldHVybiB7RXJyb3J9XHJcbiAqL1xyXG5mdW5jdGlvbiB1bmtub3duUHJvcGVydHlCaW5kaW5nKHByb3BlcnR5KSB7XHJcbiAgdmFyIGJpbmRpbmcgPSBwcm9wZXJ0eS5iaW5kaW5nO1xyXG5cclxuICByZXR1cm4gbmV3IEVycm9yKCd1bmtub3duIGJpbmRpbmc6IDwnICsgYmluZGluZy50eXBlICsgJz4nKTtcclxufVxyXG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcclxuICBfX2RlcGVuZHNfXzogW1xyXG4gICAgcmVxdWlyZSgnLi9lbGVtZW50LXRlbXBsYXRlcy9pbmRleCcpLFxyXG4gICAgcmVxdWlyZSgnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnKS5kZWZhdWx0XHJcbiAgXSxcclxuICBfX2luaXRfXzogWyAncHJvcGVydGllc1Byb3ZpZGVyJyBdLFxyXG4gIHByb3BlcnRpZXNQcm92aWRlcjogWyAndHlwZScsIHJlcXVpcmUoJy4vQWN0aXZpdGlQcm9wZXJ0aWVzUHJvdmlkZXInKSBdXHJcbn07XHJcblxyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgYXN5bmNDb250aW51YXRpb24gPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0FzeW5jQ29udGludWF0aW9uJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6QXN5bmNDYXBhYmxlJykpIHtcclxuXHJcbiAgICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoYXN5bmNDb250aW51YXRpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGdldEJ1c2luZXNzT2JqZWN0XHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgfVxyXG59OyIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjYWxsYWJsZSA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQ2FsbGFibGUnKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgZmxhdHRlbkRlZXAgPSByZXF1aXJlKCdsb2Rhc2gvZmxhdHRlbkRlZXAnKTtcclxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJ2xvZGFzaC9hc3NpZ24nKTtcclxuXHJcbmZ1bmN0aW9uIGdldENhbGxhYmxlVHlwZShlbGVtZW50KSB7XHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBib0NhbGxlZEVsZW1lbnQgPSBiby5nZXQoJ2NhbGxlZEVsZW1lbnQnKSxcclxuICAgICAgYm9DYXNlUmVmID0gYm8uZ2V0KCdhY3Rpdml0aTpjYXNlUmVmJyk7XHJcblxyXG4gIHZhciBjYWxsQWN0aXZpdHlUeXBlID0gJyc7XHJcbiAgaWYgKHR5cGVvZiBib0NhbGxlZEVsZW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICBjYWxsQWN0aXZpdHlUeXBlID0gJ2JwbW4nO1xyXG4gIH0gZWxzZVxyXG5cclxuICBpZiAodHlwZW9mIGJvQ2FzZVJlZiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIGNhbGxBY3Rpdml0eVR5cGUgPSAnY21tbic7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gY2FsbEFjdGl2aXR5VHlwZTtcclxufVxyXG5cclxudmFyIERFRkFVTFRfUFJPUFMgPSB7XHJcbiAgY2FsbGVkRWxlbWVudDogdW5kZWZpbmVkLFxyXG4gICdhY3Rpdml0aTpjYWxsZWRFbGVtZW50QmluZGluZyc6ICdsYXRlc3QnLFxyXG4gICdhY3Rpdml0aTpjYWxsZWRFbGVtZW50VmVyc2lvbic6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6Y2FsbGVkRWxlbWVudFRlbmFudElkJzogdW5kZWZpbmVkLFxyXG4gICdhY3Rpdml0aTp2YXJpYWJsZU1hcHBpbmdDbGFzcycgOiB1bmRlZmluZWQsXHJcbiAgJ2FjdGl2aXRpOnZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbicgOiB1bmRlZmluZWQsXHJcbiAgJ2FjdGl2aXRpOmNhc2VSZWYnOiB1bmRlZmluZWQsXHJcbiAgJ2FjdGl2aXRpOmNhc2VCaW5kaW5nJzogJ2xhdGVzdCcsXHJcbiAgJ2FjdGl2aXRpOmNhc2VWZXJzaW9uJzogdW5kZWZpbmVkLFxyXG4gICdhY3Rpdml0aTpjYXNlVGVuYW50SWQnOiB1bmRlZmluZWRcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgaWYgKCFpcyhlbGVtZW50LCAnYWN0aXZpdGk6Q2FsbEFjdGl2aXR5JykpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3Rvcnkuc2VsZWN0Qm94KHtcclxuICAgIGlkIDogJ2NhbGxBY3Rpdml0eScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdDYWxsQWN0aXZpdHkgVHlwZScpLFxyXG4gICAgc2VsZWN0T3B0aW9uczogW1xyXG4gICAgICB7IG5hbWU6ICdCUE1OJywgdmFsdWU6ICdicG1uJyB9LFxyXG4gICAgICB7IG5hbWU6ICdDTU1OJywgdmFsdWU6ICdjbW1uJyB9XHJcbiAgICBdLFxyXG4gICAgZW1wdHlQYXJhbWV0ZXI6IHRydWUsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY2FsbEFjdGl2aXR5VHlwZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgY2FsbEFjdGl2aXR5VHlwZTogZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciB0eXBlID0gdmFsdWVzLmNhbGxBY3Rpdml0eVR5cGU7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIERFRkFVTFRfUFJPUFMpO1xyXG5cclxuICAgICAgaWYgKHR5cGUgPT09ICdicG1uJykge1xyXG4gICAgICAgIHByb3BzLmNhbGxlZEVsZW1lbnQgPSAnJztcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmICh0eXBlID09PSAnY21tbicpIHtcclxuICAgICAgICBwcm9wc1snYWN0aXZpdGk6Y2FzZVJlZiddID0gJyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBwcm9wcyk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGNhbGxhYmxlKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBnZXRDYWxsYWJsZVR5cGU6IGdldENhbGxhYmxlVHlwZVxyXG4gIH0sIHRyYW5zbGF0ZSkpO1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZmxhdHRlbkRlZXAoZ3JvdXAuZW50cmllcyk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgY2FuZGlkYXRlU3RhcnRlciA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQ2FuZGlkYXRlU3RhcnRlcicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2FjdGl2aXRpOlByb2Nlc3MnKSB8fFxyXG4gICAgICBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpICYmIGJ1c2luZXNzT2JqZWN0LmdldCgncHJvY2Vzc1JlZicpKSB7XHJcblxyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGNhbmRpZGF0ZVN0YXJ0ZXIoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKCFpcyhibywgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGJvO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGJvLmdldCgncHJvY2Vzc1JlZicpO1xyXG4gICAgICB9XHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgfVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgaXNBbnkgPSByZXF1aXJlKCdicG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCcpLmlzQW55LFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uLy4uLy4uL1V0aWxzJykuZXNjYXBlSFRNTCxcclxuICAgIGRvbVF1ZXJ5ID0gcmVxdWlyZSgnbWluLWRvbScpLnF1ZXJ5LFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyksXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyksXHJcbiAgICBzY3JpcHRJbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vU2NyaXB0Jyk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoIWJvKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgY29uZGl0aW9uYWxFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gIGlmICghKGlzKGVsZW1lbnQsICdicG1uOlNlcXVlbmNlRmxvdycpICYmIGlzQ29uZGl0aW9uYWxTb3VyY2UoZWxlbWVudC5zb3VyY2UpKVxyXG4gICAgJiYgIWNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgc2NyaXB0ID0gc2NyaXB0SW1wbGVtZW50YXRpb24oJ2xhbmd1YWdlJywgJ2JvZHknLCB0cnVlLCB0cmFuc2xhdGUpO1xyXG4gIGdyb3VwLmVudHJpZXMucHVzaCh7XHJcbiAgICBpZDogJ2NvbmRpdGlvbicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdDb25kaXRpb24nKSxcclxuICAgIGh0bWw6ICc8ZGl2IGNsYXNzPVwiYnBwLXJvd1wiPicgK1xyXG4gICAgICAgICAgICAgICc8bGFiZWwgZm9yPVwiY2FtLWNvbmRpdGlvbi10eXBlXCI+JysgZXNjYXBlSFRNTCh0cmFuc2xhdGUoJ0NvbmRpdGlvbiBUeXBlJykpICsgJzwvbGFiZWw+JyArXHJcbiAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlclwiPicgK1xyXG4gICAgICAgICAgICAgICAgJzxzZWxlY3QgaWQ9XCJjYW0tY29uZGl0aW9uLXR5cGVcIiBuYW1lPVwiY29uZGl0aW9uVHlwZVwiIGRhdGEtdmFsdWU+JyArXHJcbiAgICAgICAgICAgICAgICAgICc8b3B0aW9uIHZhbHVlPVwiZXhwcmVzc2lvblwiPicrIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdFeHByZXNzaW9uJykpICsgJzwvb3B0aW9uPicgK1xyXG4gICAgICAgICAgICAgICAgICAnPG9wdGlvbiB2YWx1ZT1cInNjcmlwdFwiPicrIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdTY3JpcHQnKSkgKyAnPC9vcHRpb24+JyArXHJcbiAgICAgICAgICAgICAgICAgICc8b3B0aW9uIHZhbHVlPVwiXCIgc2VsZWN0ZWQ+PC9vcHRpb24+JyArXHJcbiAgICAgICAgICAgICAgICAnPC9zZWxlY3Q+JyArXHJcbiAgICAgICAgICAgICAgJzwvZGl2PicgK1xyXG4gICAgICAgICAgICAnPC9kaXY+JyArXHJcblxyXG4gICAgICAgICAgICAvLyBleHByZXNzaW9uXHJcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLXJvd1wiPicgK1xyXG4gICAgICAgICAgICAgICc8bGFiZWwgZm9yPVwiY2FtLWNvbmRpdGlvblwiIGRhdGEtc2hvdz1cImlzRXhwcmVzc2lvblwiPicgKyBlc2NhcGVIVE1MKHRyYW5zbGF0ZSgnRXhwcmVzc2lvbicpKSArICc8L2xhYmVsPicgK1xyXG4gICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXJcIiBkYXRhLXNob3c9XCJpc0V4cHJlc3Npb25cIj4nICtcclxuICAgICAgICAgICAgICAgICc8aW5wdXQgaWQ9XCJjYW0tY29uZGl0aW9uXCIgdHlwZT1cInRleHRcIiBuYW1lPVwiY29uZGl0aW9uXCIgLz4nICtcclxuICAgICAgICAgICAgICAgICc8YnV0dG9uIGNsYXNzPVwiY2xlYXJcIiBkYXRhLWFjdGlvbj1cImNsZWFyXCIgZGF0YS1zaG93PVwiY2FuQ2xlYXJcIj4nICtcclxuICAgICAgICAgICAgICAgICAgJzxzcGFuPlg8L3NwYW4+JyArXHJcbiAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICAgICAgICAgJzwvZGl2PicgK1xyXG4gICAgICAgICAgICAgICc8ZGl2IGRhdGEtc2hvdz1cImlzU2NyaXB0XCI+JyArXHJcbiAgICAgICAgICAgICAgICBzY3JpcHQudGVtcGxhdGUgK1xyXG4gICAgICAgICAgICAgICc8L2Rpdj4nICtcclxuICAgICAgICAgICAgJzwvZGl2PicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBwcm9wZXJ0eU5hbWUpIHtcclxuICAgICAgdmFyIGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uID0gZXZlbnREZWZpbml0aW9uSGVscGVyLmdldENvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG5cclxuICAgICAgdmFyIGNvbmRpdGlvbkV4cHJlc3Npb24gPSBjb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvblxyXG4gICAgICAgID8gY29uZGl0aW9uYWxFdmVudERlZmluaXRpb24uY29uZGl0aW9uXHJcbiAgICAgICAgOiBiby5jb25kaXRpb25FeHByZXNzaW9uO1xyXG5cclxuICAgICAgdmFyIHZhbHVlcyA9IHt9LFxyXG4gICAgICAgICAgY29uZGl0aW9uVHlwZSA9ICcnO1xyXG5cclxuICAgICAgaWYgKGNvbmRpdGlvbkV4cHJlc3Npb24pIHtcclxuICAgICAgICB2YXIgY29uZGl0aW9uTGFuZ3VhZ2UgPSBjb25kaXRpb25FeHByZXNzaW9uLmxhbmd1YWdlO1xyXG4gICAgICAgIGlmICh0eXBlb2YgY29uZGl0aW9uTGFuZ3VhZ2UgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICBjb25kaXRpb25UeXBlID0gJ3NjcmlwdCc7XHJcbiAgICAgICAgICB2YWx1ZXMgPSBzY3JpcHQuZ2V0KGVsZW1lbnQsIGNvbmRpdGlvbkV4cHJlc3Npb24pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb25kaXRpb25UeXBlID0gJ2V4cHJlc3Npb24nO1xyXG4gICAgICAgICAgdmFsdWVzLmNvbmRpdGlvbiA9IGNvbmRpdGlvbkV4cHJlc3Npb24uZ2V0KCdib2R5Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YWx1ZXMuY29uZGl0aW9uVHlwZSA9IGNvbmRpdGlvblR5cGU7XHJcblxyXG4gICAgICByZXR1cm4gdmFsdWVzO1xyXG5cclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIGNvbnRhaW5lckVsZW1lbnQpIHtcclxuICAgICAgdmFyIGNvbmRpdGlvblR5cGUgPSB2YWx1ZXMuY29uZGl0aW9uVHlwZTtcclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcblxyXG4gICAgICB2YXIgY29uZGl0aW9uUHJvcHMgPSB7XHJcbiAgICAgICAgYm9keTogdW5kZWZpbmVkXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpZiAoY29uZGl0aW9uVHlwZSA9PT0gJ3NjcmlwdCcpIHtcclxuICAgICAgICBjb25kaXRpb25Qcm9wcyA9IHNjcmlwdC5zZXQoZWxlbWVudCwgdmFsdWVzLCBjb250YWluZXJFbGVtZW50KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB2YXIgY29uZGl0aW9uID0gdmFsdWVzLmNvbmRpdGlvbjtcclxuXHJcbiAgICAgICAgY29uZGl0aW9uUHJvcHMuYm9keSA9IGNvbmRpdGlvbjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGNvbmRpdGlvbk9yQ29uZGl0aW9uRXhwcmVzc2lvbjtcclxuXHJcbiAgICAgIGlmIChjb25kaXRpb25UeXBlKSB7XHJcbiAgICAgICAgY29uZGl0aW9uT3JDb25kaXRpb25FeHByZXNzaW9uID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KFxyXG4gICAgICAgICAgJ2JwbW46Rm9ybWFsRXhwcmVzc2lvbicsXHJcbiAgICAgICAgICBjb25kaXRpb25Qcm9wcyxcclxuICAgICAgICAgIGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uIHx8IGJvLFxyXG4gICAgICAgICAgYnBtbkZhY3RvcnlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICB2YXIgc291cmNlID0gZWxlbWVudC5zb3VyY2U7XHJcblxyXG4gICAgICAgIC8vIGlmIGRlZmF1bHQtZmxvdywgcmVtb3ZlIGRlZmF1bHQtcHJvcGVydHkgZnJvbSBzb3VyY2VcclxuICAgICAgICBpZiAoc291cmNlICYmIHNvdXJjZS5idXNpbmVzc09iamVjdC5kZWZhdWx0ID09PSBibykge1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhzb3VyY2UsIHsgJ2RlZmF1bHQnOiB1bmRlZmluZWQgfSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHVwZGF0ZSA9IGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uXHJcbiAgICAgICAgPyB7IGNvbmRpdGlvbjogY29uZGl0aW9uT3JDb25kaXRpb25FeHByZXNzaW9uIH1cclxuICAgICAgICA6IHsgY29uZGl0aW9uRXhwcmVzc2lvbjogY29uZGl0aW9uT3JDb25kaXRpb25FeHByZXNzaW9uIH07XHJcblxyXG4gICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBjb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbiB8fCBibywgdXBkYXRlKSk7XHJcblxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIHZhbGlkYXRpb25SZXN1bHQgPSB7fTtcclxuXHJcbiAgICAgIGlmICghdmFsdWVzLmNvbmRpdGlvbiAmJiB2YWx1ZXMuY29uZGl0aW9uVHlwZSA9PT0gJ2V4cHJlc3Npb24nKSB7XHJcbiAgICAgICAgdmFsaWRhdGlvblJlc3VsdC5jb25kaXRpb24gPSB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAodmFsdWVzLmNvbmRpdGlvblR5cGUgPT09ICdzY3JpcHQnKSB7XHJcbiAgICAgICAgdmFsaWRhdGlvblJlc3VsdCA9IHNjcmlwdC52YWxpZGF0ZShlbGVtZW50LCB2YWx1ZXMpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdmFsaWRhdGlvblJlc3VsdDtcclxuICAgIH0sXHJcblxyXG4gICAgaXNFeHByZXNzaW9uOiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUpIHtcclxuICAgICAgdmFyIGNvbmRpdGlvblR5cGUgPSBkb21RdWVyeSgnc2VsZWN0W25hbWU9Y29uZGl0aW9uVHlwZV0nLCBpbnB1dE5vZGUpO1xyXG4gICAgICBpZiAoY29uZGl0aW9uVHlwZS5zZWxlY3RlZEluZGV4ID49IDApIHtcclxuICAgICAgICByZXR1cm4gY29uZGl0aW9uVHlwZS5vcHRpb25zW2NvbmRpdGlvblR5cGUuc2VsZWN0ZWRJbmRleF0udmFsdWUgPT09ICdleHByZXNzaW9uJztcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBpc1NjcmlwdDogZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlKSB7XHJcbiAgICAgIHZhciBjb25kaXRpb25UeXBlID0gZG9tUXVlcnkoJ3NlbGVjdFtuYW1lPWNvbmRpdGlvblR5cGVdJywgaW5wdXROb2RlKTtcclxuICAgICAgaWYgKGNvbmRpdGlvblR5cGUuc2VsZWN0ZWRJbmRleCA+PSAwKSB7XHJcbiAgICAgICAgcmV0dXJuIGNvbmRpdGlvblR5cGUub3B0aW9uc1tjb25kaXRpb25UeXBlLnNlbGVjdGVkSW5kZXhdLnZhbHVlID09PSAnc2NyaXB0JztcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBjbGVhcjogZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlKSB7XHJcbiAgICAgIC8vIGNsZWFyIHRleHQgaW5wdXRcclxuICAgICAgZG9tUXVlcnkoJ2lucHV0W25hbWU9Y29uZGl0aW9uXScsIGlucHV0Tm9kZSkudmFsdWU9Jyc7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgY2FuQ2xlYXI6IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSkge1xyXG4gICAgICB2YXIgaW5wdXQgPSBkb21RdWVyeSgnaW5wdXRbbmFtZT1jb25kaXRpb25dJywgaW5wdXROb2RlKTtcclxuXHJcbiAgICAgIHJldHVybiBpbnB1dC52YWx1ZSAhPT0gJyc7XHJcbiAgICB9LFxyXG5cclxuICAgIHNjcmlwdCA6IHNjcmlwdCxcclxuXHJcbiAgICBjc3NDbGFzc2VzOiBbICdicHAtdGV4dGZpZWxkJyBdXHJcbiAgfSk7XHJcbn07XHJcblxyXG5cclxuLy8gdXRpbGl0aWVzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG52YXIgQ09ORElUSU9OQUxfU09VUkNFUyA9IFtcclxuICAnYnBtbjpBY3Rpdml0eScsXHJcbiAgJ2JwbW46RXhjbHVzaXZlR2F0ZXdheScsXHJcbiAgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheScsXHJcbiAgJ2JwbW46Q29tcGxleEdhdGV3YXknXHJcbl07XHJcblxyXG5mdW5jdGlvbiBpc0NvbmRpdGlvbmFsU291cmNlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXNBbnkoZWxlbWVudCwgQ09ORElUSU9OQUxfU09VUkNFUyk7XHJcbn1cclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXInKSxcclxuICAgIElucHV0T3V0cHV0SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0lucHV0T3V0cHV0SGVscGVyJyk7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbmZ1bmN0aW9uIGdldEltcGxlbWVudGF0aW9uVHlwZShlbGVtZW50KSB7XHJcbiAgcmV0dXJuIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpIHtcclxuICByZXR1cm4gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldFNlcnZpY2VUYXNrTGlrZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRDb25uZWN0b3IoYm8pIHtcclxuICByZXR1cm4gSW5wdXRPdXRwdXRIZWxwZXIuZ2V0Q29ubmVjdG9yKGJvKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNDb25uZWN0b3IoZWxlbWVudCkge1xyXG4gIHJldHVybiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkgPT09ICdjb25uZWN0b3InO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnY29ubmVjdG9ySWQnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ29ubmVjdG9yIElkJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY29ubmVjdG9ySWQnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIGNvbm5lY3RvciA9IGJvICYmIGdldENvbm5lY3Rvcihibyk7XHJcbiAgICAgIHZhciB2YWx1ZSA9IGNvbm5lY3RvciAmJiBjb25uZWN0b3IuZ2V0KCdjb25uZWN0b3JJZCcpO1xyXG4gICAgICByZXR1cm4geyBjb25uZWN0b3JJZDogdmFsdWUgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHZhciBjb25uZWN0b3IgPSBnZXRDb25uZWN0b3IoYm8pO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGNvbm5lY3Rvciwge1xyXG4gICAgICAgIGNvbm5lY3RvcklkOiB2YWx1ZXMuY29ubmVjdG9ySWQgfHwgdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBpc0Nvbm5lY3RvcihlbGVtZW50KSAmJiAhdmFsdWVzLmNvbm5lY3RvcklkID8geyBjb25uZWN0b3JJZDogdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpIH0gOiB7fTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhaXNDb25uZWN0b3IoZWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyk7XHJcblxyXG52YXIgaW5wdXRPdXRwdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0lucHV0T3V0cHV0UGFyYW1ldGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIG9wdGlvbnMgPSBhc3NpZ24oe1xyXG4gICAgaWRQcmVmaXg6ICdjb25uZWN0b3ItJyxcclxuICAgIGluc2lkZUNvbm5lY3RvcjogdHJ1ZVxyXG4gIH0sIG9wdGlvbnMpO1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoaW5wdXRPdXRwdXRQYXJhbWV0ZXIoZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlucHV0T3V0cHV0ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9JbnB1dE91dHB1dCcpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgaW5wdXRPdXRwdXRFbnRyeSA9IGlucHV0T3V0cHV0KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZFByZWZpeDogJ2Nvbm5lY3Rvci0nLFxyXG4gICAgaW5zaWRlQ29ubmVjdG9yOiB0cnVlXHJcbiAgfSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGlucHV0T3V0cHV0RW50cnkuZW50cmllcyk7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBnZXRTZWxlY3RlZFBhcmFtZXRlcjogaW5wdXRPdXRwdXRFbnRyeS5nZXRTZWxlY3RlZFBhcmFtZXRlclxyXG4gIH07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZXZlbnREZWZpbml0aW9uSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0V2ZW50RGVmaW5pdGlvbkhlbHBlcicpLFxyXG4gICAgZXJyb3IgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0Vycm9yRXZlbnREZWZpbml0aW9uJyk7XHJcblxyXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZXJyb3JFdmVudHMgPSBbXHJcbiAgICAnYnBtbjpTdGFydEV2ZW50JyxcclxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxyXG4gICAgJ2JwbW46RW5kRXZlbnQnXHJcbiAgXTtcclxuXHJcbiAgZm9yRWFjaChlcnJvckV2ZW50cywgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIGlmIChpcyhlbGVtZW50LCBldmVudCkpIHtcclxuXHJcbiAgICAgIHZhciBlcnJvckV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRFcnJvckV2ZW50RGVmaW5pdGlvbihlbGVtZW50KTtcclxuXHJcbiAgICAgIGlmIChlcnJvckV2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgICAgIHZhciBpc0NhdGNoaW5nRXJyb3JFdmVudCA9IGlzKGVsZW1lbnQsICdicG1uOlN0YXJ0RXZlbnQnKSB8fCBpcyAoZWxlbWVudCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpO1xyXG5cclxuICAgICAgICB2YXIgc2hvd0Vycm9yQ29kZVZhcmlhYmxlID0gaXNDYXRjaGluZ0Vycm9yRXZlbnQsXHJcbiAgICAgICAgICAgIHNob3dFcnJvck1lc3NhZ2VWYXJpYWJsZSA9IGlzQ2F0Y2hpbmdFcnJvckV2ZW50O1xyXG5cclxuICAgICAgICBlcnJvcihcclxuICAgICAgICAgIGdyb3VwLFxyXG4gICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgIGJwbW5GYWN0b3J5LFxyXG4gICAgICAgICAgZXJyb3JFdmVudERlZmluaXRpb24sXHJcbiAgICAgICAgICBzaG93RXJyb3JDb2RlVmFyaWFibGUsXHJcbiAgICAgICAgICBzaG93RXJyb3JNZXNzYWdlVmFyaWFibGUsXHJcbiAgICAgICAgICB0cmFuc2xhdGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgSW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0ltcGxlbWVudGF0aW9uVHlwZUhlbHBlcicpO1xyXG5cclxudmFyIGV4dGVybmFsVGFza1ByaW9yaXR5ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9FeHRlcm5hbFRhc2tQcmlvcml0eScpO1xyXG5cclxuZnVuY3Rpb24gZ2V0U2VydmljZVRhc2tMaWtlQnVzaW5lc3NPYmplY3QoZWxlbWVudCkge1xyXG4gIHZhciBibyA9IEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRTZXJ2aWNlVGFza0xpa2VCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgLy8gaWYgdGhlIGVsZW1lbnQgaXMgbm90IGEgc2VydmljZVRhc2tMaWtlIGVsZW1lbnQsIGZldGNoIHRoZSBub3JtYWwgYnVzaW5lc3Mgb2JqZWN0XHJcbiAgLy8gVGhpcyBhdm9pZHMgdGhlIGxvc3Mgb2YgdGhlIHByb2Nlc3MgLyBwYXJ0aWNpcGFudCBidXNpbmVzcyBvYmplY3RcclxuICBpZiAoIWJvKSB7XHJcbiAgICBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGJvO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBibyA9IGdldFNlcnZpY2VUYXNrTGlrZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoIWJvKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBpZiAoaXMoYm8sICdhY3Rpdml0aTpUYXNrUHJpb3JpemVkJykgfHwgKGlzKGJvLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSAmJiBiby5nZXQoJ3Byb2Nlc3NSZWYnKSkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGV4dGVybmFsVGFza1ByaW9yaXR5KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0OiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgICAgaWYgKCFpcyhibywgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGJvO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYm8uZ2V0KCdwcm9jZXNzUmVmJyk7XHJcbiAgICAgIH1cclxuICAgIH0sIHRyYW5zbGF0ZSkpO1xyXG4gIH1cclxufTsiLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgSW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0ltcGxlbWVudGF0aW9uVHlwZUhlbHBlcicpO1xyXG5cclxudmFyIGZpZWxkSW5qZWN0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9GaWVsZEluamVjdGlvbicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgYm8gPSBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0U2VydmljZVRhc2tMaWtlQnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBmaWVsZEluamVjdGlvbkVudHJ5ID0gZmllbGRJbmplY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSwgeyBidXNpbmVzc09iamVjdDogYm8gfSk7XHJcblxyXG4gIGlmIChmaWVsZEluamVjdGlvbkVudHJ5ICYmIGZpZWxkSW5qZWN0aW9uRW50cnkubGVuZ3RoID4gMCkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGZpZWxkSW5qZWN0aW9uRW50cnkpO1xyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBnZXRFeHRlbnNpb25FbGVtZW50cyA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpLmdldEV4dGVuc2lvbkVsZW1lbnRzLFxyXG4gICAgcmVtb3ZlRW50cnkgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXInKS5yZW1vdmVFbnRyeSxcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9FeHRlbnNpb25FbGVtZW50cycpLFxyXG4gICAgcHJvcGVydGllcyA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vUHJvcGVydGllcycpLFxyXG4gICAgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgZm9ybUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9Gb3JtSGVscGVyJyksXHJcbiAgICB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uL1V0aWxzJyksXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBmaW5kID0gcmVxdWlyZSgnbG9kYXNoL2ZpbmQnKSxcclxuICAgIGVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVWYWx1ZUlkKCkge1xyXG4gIHJldHVybiB1dGlscy5uZXh0SWQoJ1ZhbHVlXycpO1xyXG59XHJcblxyXG4vKipcclxuICogR2VuZXJhdGUgYSBmb3JtIGZpZWxkIHNwZWNpZmljIHRleHRGaWVsZCB1c2luZyBlbnRyeUZhY3RvcnkuXHJcbiAqXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5pZFxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMubGFiZWxcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLm1vZGVsUHJvcGVydHlcclxuICogQHBhcmFtICB7ZnVuY3Rpb259IG9wdGlvbnMudmFsaWRhdGVcclxuICpcclxuICogQHJldHVybiB7T2JqZWN0fSBhbiBlbnRyeUZhY3RvcnkudGV4dEZpZWxkIG9iamVjdFxyXG4gKi9cclxuZnVuY3Rpb24gZm9ybUZpZWxkVGV4dEZpZWxkKG9wdGlvbnMsIGdldFNlbGVjdGVkRm9ybUZpZWxkKSB7XHJcblxyXG4gIHZhciBpZCA9IG9wdGlvbnMuaWQsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eSxcclxuICAgICAgdmFsaWRhdGUgPSBvcHRpb25zLnZhbGlkYXRlO1xyXG5cclxuICByZXR1cm4gZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogaWQsXHJcbiAgICBsYWJlbDogbGFiZWwsXHJcbiAgICBtb2RlbFByb3BlcnR5OiBtb2RlbFByb3BlcnR5LFxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpIHx8IHt9LFxyXG4gICAgICAgICAgdmFsdWVzID0ge307XHJcblxyXG4gICAgICB2YWx1ZXNbbW9kZWxQcm9wZXJ0eV0gPSBzZWxlY3RlZEZvcm1GaWVsZFttb2RlbFByb3BlcnR5XTtcclxuXHJcbiAgICAgIHJldHVybiB2YWx1ZXM7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnNldCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIHZhciBjbWQgPSBvcHRpb25zLnNldChlbGVtZW50LCB2YWx1ZXMsIG5vZGUpO1xyXG5cclxuICAgICAgICBpZiAoY21kKSB7XHJcbiAgICAgICAgICBjb21tYW5kcy5wdXNoKGNtZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSksXHJcbiAgICAgICAgICBwcm9wZXJ0aWVzID0ge307XHJcblxyXG4gICAgICBwcm9wZXJ0aWVzW21vZGVsUHJvcGVydHldID0gdmFsdWVzW21vZGVsUHJvcGVydHldIHx8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGZvcm1GaWVsZCwgcHJvcGVydGllcykpO1xyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfSxcclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuICAgIHZhbGlkYXRlOiB2YWxpZGF0ZVxyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBlbnN1cmVGb3JtS2V5QW5kRGF0YVN1cHBvcnRlZChlbGVtZW50KSB7XHJcbiAgcmV0dXJuIChcclxuICAgIGlzKGVsZW1lbnQsICdicG1uOlN0YXJ0RXZlbnQnKSAmJiAhaXMoZWxlbWVudC5wYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKVxyXG4gICkgfHwgaXMoZWxlbWVudCwgJ2JwbW46VXNlclRhc2snKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICBpZiAoIWVuc3VyZUZvcm1LZXlBbmREYXRhU3VwcG9ydGVkKGVsZW1lbnQpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJuIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZm9ybSBmaWVsZCBxdWVyeWluZyB0aGUgZm9ybSBmaWVsZCBzZWxlY3QgYm94XHJcbiAgICogZnJvbSB0aGUgRE9NLlxyXG4gICAqXHJcbiAgICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICAgKiBAcGFyYW0gIHtET01FbGVtZW50fSBub2RlIC0gRE9NIGVsZW1lbnQgb2YgYW55IGZvcm0gZmllbGQgdGV4dCBpbnB1dFxyXG4gICAqXHJcbiAgICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBmb3JtIGZpZWxkXHJcbiAgICovXHJcbiAgZnVuY3Rpb24gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSkge1xyXG4gICAgdmFyIHNlbGVjdGVkID0gZm9ybUZpZWxkc0VudHJ5LmdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUucGFyZW50Tm9kZSk7XHJcblxyXG4gICAgaWYgKHNlbGVjdGVkLmlkeCA9PT0gLTEpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmb3JtSGVscGVyLmdldEZvcm1GaWVsZChlbGVtZW50LCBzZWxlY3RlZC5pZHgpO1xyXG4gIH1cclxuXHJcbiAgLy8gW0Zvcm1LZXldIGZvcm0ga2V5IHRleHQgaW5wdXQgZmllbGRcclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZCA6ICdmb3JtLWtleScsXHJcbiAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnRm9ybSBLZXknKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdmb3JtS2V5JyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZm9ybUtleTogYm8uZ2V0KCdhY3Rpdml0aTpmb3JtS2V5JylcclxuICAgICAgfTtcclxuICAgIH0sXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICAgIGZvcm1LZXkgPSB2YWx1ZXMuZm9ybUtleSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGJvLCB7ICdhY3Rpdml0aTpmb3JtS2V5JzogZm9ybUtleSB9KTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBzZWxlY3QgYm94XHJcbiAgdmFyIGZvcm1GaWVsZHNFbnRyeSA9IGV4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ2Zvcm0tZmllbGRzJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0Zvcm0gRmllbGRzJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnaWQnLFxyXG4gICAgcHJlZml4OiAnRm9ybVByb3BlcnR5JyxcclxuICAgIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCB2YWx1ZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSwgY29tbWFuZHMgPSBbXTtcclxuXHJcbiAgICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgICBleHRlbnNpb25FbGVtZW50cyA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYnBtbjpFeHRlbnNpb25FbGVtZW50cycsIHsgdmFsdWVzOiBbXSB9LCBibywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgeyBleHRlbnNpb25FbGVtZW50czogZXh0ZW5zaW9uRWxlbWVudHMgfSkpO1xyXG4gICAgICB9XHJcbiAgICAgLyogdmFyIGZvcm1EYXRhID0gZm9ybUhlbHBlci5nZXRGb3JtRGF0YShlbGVtZW50KTtcclxuXHJcbiAgICAgIGlmICghZm9ybURhdGEpIHtcclxuICAgICAgICBmb3JtRGF0YSA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6Rm9ybURhdGEnLCB7IGZpZWxkczogW10gfSwgZXh0ZW5zaW9uRWxlbWVudHMsIGJwbW5GYWN0b3J5KTtcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5hZGRBbmRSZW1vdmVFbGVtZW50c0Zyb21MaXN0KFxyXG4gICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgIGV4dGVuc2lvbkVsZW1lbnRzLFxyXG4gICAgICAgICAgJ3ZhbHVlcycsXHJcbiAgICAgICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICAgICAgW2Zvcm1EYXRhXSxcclxuICAgICAgICAgIFtdXHJcbiAgICAgICAgKSk7XHJcbiAgICAgIH0qL1xyXG4gICAgICAvKiphY3Rpdml0aSDmmK/lkJEgZXh0ZW5zaW9uRWxlbWVudHMg5LiL6L+95Yqg5YWD57Sg77yM6ICM5LiN5pivIGZvcm1EYXRhIOS4i++8jCovXHJcbiAgICAgIHZhciBmaWVsZCA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6Rm9ybVByb3BlcnR5JywgeyBpZDogdmFsdWUgfSwgZXh0ZW5zaW9uRWxlbWVudHMsIGJwbW5GYWN0b3J5KTtcclxuICAgICAgaWYgKHR5cGVvZiBleHRlbnNpb25FbGVtZW50cy52YWx1ZXMgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkRWxlbWVudHNUb2xpc3QoZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsICd2YWx1ZXMnLCBbIGZpZWxkIF0pKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywge1xyXG4gICAgICAgICAgICB2YWx1ZXM6IFsgZmllbGQgXVxyXG4gICAgICAgIH0pKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcbiAgICB9LFxyXG4gICAgcmVtb3ZlRXh0ZW5zaW9uRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGZpZWxkcyA9IGZvcm1IZWxwZXIuZ2V0Rm9ybUZpZWxkcyhlbGVtZW50KTtcclxuICAgICAgdmFyIGVudHJ5ID0gZmllbGRzW2lkeF0sXHJcbiAgICAgICAgICBjb21tYW5kcyA9IFtdO1xyXG5cclxuICAgICAgaWYgKGZpZWxkcy5sZW5ndGggPCAyKSB7XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChyZW1vdmVFbnRyeShnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSwgZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMpKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5yZW1vdmVFbGVtZW50c0Zyb21MaXN0KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCAndmFsdWVzJywgbnVsbCwgW2VudHJ5XSkpO1xyXG4gICAgICAgLyogaWYgKGVudHJ5LmlkID09PSBmb3JtRGF0YS5nZXQoJ2J1c2luZXNzS2V5JykpIHtcclxuICAgICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCB7ICdidXNpbmVzc0tleSc6IHVuZGVmaW5lZCB9KSk7XHJcbiAgICAgICAgfSovXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgIH0sXHJcbiAgICBnZXRFeHRlbnNpb25FbGVtZW50czogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICByZXR1cm4gZm9ybUhlbHBlci5nZXRGb3JtRmllbGRzKGVsZW1lbnQpO1xyXG4gICAgfSxcclxuICAgIGhpZGVFeHRlbnNpb25FbGVtZW50czogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGZvcm1GaWVsZHNFbnRyeSk7XHJcblxyXG5cclxuICAvLyBbRm9ybURhdGFdIEZvcm0gRmllbGQgbGFiZWxcclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmxhYmVsKHtcclxuICAgIGlkOiAnZm9ybS1maWVsZC1oZWFkZXInLFxyXG4gICAgbGFiZWxUZXh0OiB0cmFuc2xhdGUoJ0Zvcm0gRmllbGQnKSxcclxuICAgIHNob3dMYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gISFnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBpZCB0ZXh0IGlucHV0IGZpZWxkXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS52YWxpZGF0aW9uQXdhcmVUZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdmb3JtLWZpZWxkLWlkJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0lEJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnaWQnLFxyXG5cclxuICAgIGdldFByb3BlcnR5OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpIHx8IHt9O1xyXG5cclxuICAgICAgcmV0dXJuIHNlbGVjdGVkRm9ybUZpZWxkLmlkO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydGllcywgbm9kZSkge1xyXG4gICAgICB2YXIgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGZvcm1GaWVsZCwgcHJvcGVydGllcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcblxyXG4gICAgICB2YXIgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICBpZiAoZm9ybUZpZWxkKSB7XHJcblxyXG4gICAgICAgIHZhciBpZFZhbHVlID0gdmFsdWVzLmlkO1xyXG5cclxuICAgICAgICBpZiAoIWlkVmFsdWUgfHwgaWRWYWx1ZS50cmltKCkgPT09ICcnKSB7XHJcbiAgICAgICAgICByZXR1cm4geyBpZDogJ0Zvcm0gZmllbGQgaWQgbXVzdCBub3QgYmUgZW1wdHknIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgZm9ybUZpZWxkcyA9IGZvcm1IZWxwZXIuZ2V0Rm9ybUZpZWxkcyhlbGVtZW50KTtcclxuXHJcbiAgICAgICAgdmFyIGV4aXN0aW5nRm9ybUZpZWxkID0gZmluZChmb3JtRmllbGRzLCBmdW5jdGlvbihmKSB7XHJcbiAgICAgICAgICByZXR1cm4gZiAhPT0gZm9ybUZpZWxkICYmIGYuaWQgPT09IGlkVmFsdWU7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGlmIChleGlzdGluZ0Zvcm1GaWVsZCkge1xyXG4gICAgICAgICAgcmV0dXJuIHsgaWQ6ICdGb3JtIGZpZWxkIGlkIGFscmVhZHkgdXNlZCBpbiBmb3JtIGRhdGEuJyB9O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbiAgLy8gW0Zvcm1EYXRhXSBmb3JtIGZpZWxkIHR5cGUgY29tYm8gYm94XHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5jb21ib0JveCh7XHJcbiAgICBpZDogJ2Zvcm0tZmllbGQtdHlwZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdUeXBlJyksXHJcbiAgICBzZWxlY3RPcHRpb25zOiBbXHJcbiAgICAgIHsgbmFtZTogJ3N0cmluZycsIHZhbHVlOiAnc3RyaW5nJyB9LFxyXG4gICAgICB7IG5hbWU6ICdsb25nJywgdmFsdWU6ICdsb25nJyB9LFxyXG4gICAgICB7IG5hbWU6ICdib29sZWFuJywgdmFsdWU6ICdib29sZWFuJyB9LFxyXG4gICAgICB7IG5hbWU6ICdkYXRlJywgdmFsdWU6ICdkYXRlJyB9LFxyXG4gICAgICB7IG5hbWU6ICdlbnVtJywgdmFsdWU6ICdlbnVtJyB9XHJcbiAgICBdLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3R5cGUnLFxyXG4gICAgZW1wdHlQYXJhbWV0ZXI6IHRydWUsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgaWYgKHNlbGVjdGVkRm9ybUZpZWxkKSB7XHJcbiAgICAgICAgcmV0dXJuIHsgdHlwZTogc2VsZWN0ZWRGb3JtRmllbGQudHlwZSB9O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiB7fTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgY29tbWFuZHMgPSBbXTtcclxuXHJcbiAgICAgIGlmIChzZWxlY3RlZEZvcm1GaWVsZC50eXBlID09PSAnZW51bScgJiYgdmFsdWVzLnR5cGUgIT09ICdlbnVtJykge1xyXG4gICAgICAgIC8vIGRlbGV0ZSBhY3Rpdml0aTp2YWx1ZSBvYmplY3RzIGZyb20gZm9ybUZpZWxkLnZhbHVlcyB3aGVuIHN3aXRjaGluZyBmcm9tIHR5cGUgZW51bVxyXG4gICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHNlbGVjdGVkRm9ybUZpZWxkLCB7IHZhbHVlczogdW5kZWZpbmVkIH0pKTtcclxuICAgICAgfVxyXG4gICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBzZWxlY3RlZEZvcm1GaWVsZCwgdmFsdWVzKSk7XHJcblxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcbiAgICB9LFxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuICAvLyBbRm9ybURhdGFdIGZvcm0gZmllbGQgbGFiZWwgdGV4dCBpbnB1dCBmaWVsZFxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChmb3JtRmllbGRUZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdmb3JtLWZpZWxkLWxhYmVsJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0xhYmVsJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnbGFiZWwnXHJcbiAgfSwgZ2V0U2VsZWN0ZWRGb3JtRmllbGQpKTtcclxuXHJcbiAgLy8gW0Zvcm1EYXRhXSBmb3JtIGZpZWxkIGRlZmF1bHRWYWx1ZSB0ZXh0IGlucHV0IGZpZWxkXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGZvcm1GaWVsZFRleHRGaWVsZCh7XHJcbiAgICBpZDogJ2Zvcm0tZmllbGQtZGVmYXVsdFZhbHVlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0RlZmF1bHQgVmFsdWUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdkZWZhdWx0VmFsdWUnXHJcbiAgfSwgZ2V0U2VsZWN0ZWRGb3JtRmllbGQpKTtcclxuXHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBlbnVtIHZhbHVlcyBsYWJlbFxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkubGFiZWwoe1xyXG4gICAgaWQ6ICdmb3JtLWZpZWxkLWVudW0tdmFsdWVzLWhlYWRlcicsXHJcbiAgICBsYWJlbFRleHQ6IHRyYW5zbGF0ZSgnVmFsdWVzJyksXHJcbiAgICBkaXZpZGVyOiB0cnVlLFxyXG4gICAgc2hvd0xhYmVsOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgcmV0dXJuIHNlbGVjdGVkRm9ybUZpZWxkICYmIHNlbGVjdGVkRm9ybUZpZWxkLnR5cGUgPT09ICdlbnVtJztcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBlbnVtIHZhbHVlcyB0YWJsZVxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGFibGUoe1xyXG4gICAgaWQ6ICdmb3JtLWZpZWxkLWVudW0tdmFsdWVzJyxcclxuICAgIGxhYmVsczogWyB0cmFuc2xhdGUoJ0lkJyksIHRyYW5zbGF0ZSgnTmFtZScpIF0sXHJcbiAgICBtb2RlbFByb3BlcnRpZXM6IFsgJ2lkJywgJ25hbWUnIF0sXHJcbiAgICBhZGRMYWJlbDp0cmFuc2xhdGUoJ0FkZCBWYWx1ZScpLFxyXG4gICAgc2hvdzogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgc2VsZWN0ZWRGb3JtRmllbGQgPSBnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICAgIHJldHVybiBzZWxlY3RlZEZvcm1GaWVsZCAmJiBzZWxlY3RlZEZvcm1GaWVsZC50eXBlID09PSAnZW51bSc7XHJcbiAgICB9LFxyXG4gICAgZ2V0RWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIHNlbGVjdGVkRm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gZm9ybUhlbHBlci5nZXRFbnVtVmFsdWVzKHNlbGVjdGVkRm9ybUZpZWxkKTtcclxuICAgIH0sXHJcbiAgICBhZGRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgaWQgPSBnZW5lcmF0ZVZhbHVlSWQoKTtcclxuXHJcbiAgICAgIHZhciBlbnVtVmFsdWUgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoXHJcbiAgICAgICAgJ2FjdGl2aXRpOlZhbHVlJyxcclxuICAgICAgICB7IGlkOiBpZCwgbmFtZTogdW5kZWZpbmVkIH0sXHJcbiAgICAgICAgZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksXHJcbiAgICAgICAgYnBtbkZhY3RvcnlcclxuICAgICAgKTtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIuYWRkRWxlbWVudHNUb2xpc3QoZWxlbWVudCwgc2VsZWN0ZWRGb3JtRmllbGQsICd2YWx1ZXMnLCBbZW51bVZhbHVlXSk7XHJcbiAgICB9LFxyXG4gICAgcmVtb3ZlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgaWR4KSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgZW51bVZhbHVlID0gc2VsZWN0ZWRGb3JtRmllbGQudmFsdWVzW2lkeF07XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoZWxlbWVudCwgc2VsZWN0ZWRGb3JtRmllbGQsICd2YWx1ZXMnLCBudWxsLCBbZW51bVZhbHVlXSk7XHJcbiAgICB9LFxyXG4gICAgdXBkYXRlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWUsIG5vZGUsIGlkeCkge1xyXG4gICAgICB2YXIgc2VsZWN0ZWRGb3JtRmllbGQgPSBnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKSxcclxuICAgICAgICAgIGVudW1WYWx1ZSA9IHNlbGVjdGVkRm9ybUZpZWxkLnZhbHVlc1tpZHhdO1xyXG5cclxuICAgICAgdmFsdWUubmFtZSA9IHZhbHVlLm5hbWUgfHwgdW5kZWZpbmVkO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGVudW1WYWx1ZSwgdmFsdWUpO1xyXG4gICAgfSxcclxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSwgbm9kZSwgaWR4KSB7XHJcblxyXG4gICAgICB2YXIgc2VsZWN0ZWRGb3JtRmllbGQgPSBnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKSxcclxuICAgICAgICAgIGVudW1WYWx1ZSA9IHNlbGVjdGVkRm9ybUZpZWxkLnZhbHVlc1tpZHhdO1xyXG5cclxuICAgICAgaWYgKGVudW1WYWx1ZSkge1xyXG4gICAgICAgIC8vIGNoZWNrIGlmIGlkIGlzIHZhbGlkXHJcbiAgICAgICAgdmFyIHZhbGlkYXRpb25FcnJvciA9IHV0aWxzLmlzSWRWYWxpZChlbnVtVmFsdWUsIHZhbHVlLmlkLCB0cmFuc2xhdGUpO1xyXG5cclxuICAgICAgICBpZiAodmFsaWRhdGlvbkVycm9yKSB7XHJcbiAgICAgICAgICByZXR1cm4geyBpZDogdmFsaWRhdGlvbkVycm9yIH07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuICAvLyBbRm9ybURhdGFdIFZhbGlkYXRpb24gbGFiZWxcclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmxhYmVsKHtcclxuICAgIGlkOiAnZm9ybS1maWVsZC12YWxpZGF0aW9uLWhlYWRlcicsXHJcbiAgICBsYWJlbFRleHQ6IHRyYW5zbGF0ZSgnVmFsaWRhdGlvbicpLFxyXG4gICAgZGl2aWRlcjogdHJ1ZSxcclxuICAgIHNob3dMYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gISFnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBjb25zdHJhaW50cyB0YWJsZVxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGFibGUoe1xyXG4gICAgaWQ6ICdjb25zdHJhaW50cy1saXN0JyxcclxuICAgIG1vZGVsUHJvcGVydGllczogWyAnbmFtZScsICdjb25maWcnIF0sXHJcbiAgICBsYWJlbHM6IFsgdHJhbnNsYXRlKCdOYW1lJyksIHRyYW5zbGF0ZSgnQ29uZmlnJykgXSxcclxuICAgIGFkZExhYmVsOiB0cmFuc2xhdGUoJ0FkZCBDb25zdHJhaW50JyksXHJcbiAgICBnZXRFbGVtZW50czogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gZm9ybUhlbHBlci5nZXRDb25zdHJhaW50cyhmb3JtRmllbGQpO1xyXG4gICAgfSxcclxuICAgIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuXHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdLFxyXG4gICAgICAgICAgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSksXHJcbiAgICAgICAgICB2YWxpZGF0aW9uID0gZm9ybUZpZWxkLnZhbGlkYXRpb247XHJcblxyXG4gICAgICBpZiAoIXZhbGlkYXRpb24pIHtcclxuICAgICAgICAvLyBjcmVhdGUgdmFsaWRhdGlvbiBidXNpbmVzcyBvYmplY3QgYW5kIGFkZCBpdCB0byBmb3JtIGRhdGEsIGlmIGl0IGRvZXNuJ3QgZXhpc3RcclxuICAgICAgICB2YWxpZGF0aW9uID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdhY3Rpdml0aTpWYWxpZGF0aW9uJywge30sIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLCBicG1uRmFjdG9yeSk7XHJcblxyXG4gICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGZvcm1GaWVsZCwgeyAndmFsaWRhdGlvbic6IHZhbGlkYXRpb24gfSkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgbmV3Q29uc3RyYWludCA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudChcclxuICAgICAgICAnYWN0aXZpdGk6Q29uc3RyYWludCcsXHJcbiAgICAgICAgeyBuYW1lOiB1bmRlZmluZWQsIGNvbmZpZzogdW5kZWZpbmVkIH0sXHJcbiAgICAgICAgdmFsaWRhdGlvbixcclxuICAgICAgICBicG1uRmFjdG9yeVxyXG4gICAgICApO1xyXG5cclxuICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkRWxlbWVudHNUb2xpc3QoZWxlbWVudCwgdmFsaWRhdGlvbiwgJ2NvbnN0cmFpbnRzJywgWyBuZXdDb25zdHJhaW50IF0pKTtcclxuXHJcbiAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgIH0sXHJcbiAgICB1cGRhdGVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSwgbm9kZSwgaWR4KSB7XHJcbiAgICAgIHZhciBmb3JtRmllbGQgPSBnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKSxcclxuICAgICAgICAgIGNvbnN0cmFpbnQgPSBmb3JtSGVscGVyLmdldENvbnN0cmFpbnRzKGZvcm1GaWVsZClbaWR4XTtcclxuXHJcbiAgICAgIHZhbHVlLm5hbWUgPSB2YWx1ZS5uYW1lIHx8IHVuZGVmaW5lZDtcclxuICAgICAgdmFsdWUuY29uZmlnID0gdmFsdWUuY29uZmlnIHx8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgY29uc3RyYWludCwgdmFsdWUpO1xyXG4gICAgfSxcclxuICAgIHJlbW92ZUVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGlkeCkge1xyXG4gICAgICB2YXIgY29tbWFuZHMgPSBbXSxcclxuICAgICAgICAgIGZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgY29uc3RyYWludHMgPSBmb3JtSGVscGVyLmdldENvbnN0cmFpbnRzKGZvcm1GaWVsZCksXHJcbiAgICAgICAgICBjdXJyZW50Q29uc3RyYWludCA9IGNvbnN0cmFpbnRzW2lkeF07XHJcblxyXG4gICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5yZW1vdmVFbGVtZW50c0Zyb21MaXN0KFxyXG4gICAgICAgIGVsZW1lbnQsXHJcbiAgICAgICAgZm9ybUZpZWxkLnZhbGlkYXRpb24sXHJcbiAgICAgICAgJ2NvbnN0cmFpbnRzJyxcclxuICAgICAgICBudWxsLFxyXG4gICAgICAgIFsgY3VycmVudENvbnN0cmFpbnQgXVxyXG4gICAgICApKTtcclxuXHJcbiAgICAgIGlmIChjb25zdHJhaW50cy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAvLyByZW1vdmUgYWN0aXZpdGk6dmFsaWRhdGlvbiBpZiB0aGUgbGFzdCBleGlzdGluZyBjb25zdHJhaW50IGhhcyBiZWVuIHJlbW92ZWRcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBmb3JtRmllbGQsIHsgdmFsaWRhdGlvbjogdW5kZWZpbmVkIH0pKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfSxcclxuICAgIHNob3c6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICEhZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuICAvLyBbRm9ybURhdGFdIFByb3BlcnRpZXMgbGFiZWxcclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmxhYmVsKHtcclxuICAgIGlkOiAnZm9ybS1maWVsZC1wcm9wZXJ0aWVzLWhlYWRlcicsXHJcbiAgICBsYWJlbFRleHQ6IHRyYW5zbGF0ZSgnUHJvcGVydGllcycpLFxyXG4gICAgZGl2aWRlcjogdHJ1ZSxcclxuICAgIHNob3dMYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gISFnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gYWN0aXZpdGk6cHJvcGVydGllcyB0YWJsZVxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChwcm9wZXJ0aWVzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ2Zvcm0tZmllbGQtcHJvcGVydGllcycsXHJcbiAgICBtb2RlbFByb3BlcnRpZXM6IFsgJ2lkJywgJ3ZhbHVlJyBdLFxyXG4gICAgbGFiZWxzOiBbIHRyYW5zbGF0ZSgnSWQnKSwgdHJhbnNsYXRlKCdWYWx1ZScpIF0sXHJcbiAgICBnZXRQYXJlbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuICAgIHNob3c6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICEhZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSwgdHJhbnNsYXRlKSk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgaGlzdG9yeVRpbWVUb0xpdmUgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0hpc3RvcnlUaW1lVG9MaXZlJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6UHJvY2VzcycpIHx8XHJcbiAgICAgIGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdwcm9jZXNzUmVmJykpIHtcclxuXHJcbiAgICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoaGlzdG9yeVRpbWVUb0xpdmUoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKCFpcyhibywgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGJvO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGJvLmdldCgncHJvY2Vzc1JlZicpO1xyXG4gICAgICB9XHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgfVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaW5wdXRPdXRwdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0lucHV0T3V0cHV0UGFyYW1ldGVyJyk7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoaW5wdXRPdXRwdXRQYXJhbWV0ZXIoZWxlbWVudCwgYnBtbkZhY3RvcnksIGFzc2lnbih7fSwgb3B0aW9ucyksIHRyYW5zbGF0ZSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlucHV0T3V0cHV0ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9JbnB1dE91dHB1dCcpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgaW5wdXRPdXRwdXRFbnRyeSA9IGlucHV0T3V0cHV0KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7fSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGlucHV0T3V0cHV0RW50cnkuZW50cmllcyk7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBnZXRTZWxlY3RlZFBhcmFtZXRlcjogaW5wdXRPdXRwdXRFbnRyeS5nZXRTZWxlY3RlZFBhcmFtZXRlclxyXG4gIH07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIGpvYlByaW9yaXR5ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9Kb2JQcmlvcml0eScpLFxyXG4gICAgam9iUmV0cnlUaW1lQ3ljbGUgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0pvYlJldHJ5VGltZUN5Y2xlJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6Sm9iUHJpb3JpemVkJykgfHxcclxuICAgICAgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSAmJiBidXNpbmVzc09iamVjdC5nZXQoJ3Byb2Nlc3NSZWYnKSkge1xyXG5cclxuICAgIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChqb2JQcmlvcml0eShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgICBnZXRCdXNpbmVzc09iamVjdDogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgICBpZiAoIWlzKGJvLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICAgICAgICByZXR1cm4gYm87XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYm8uZ2V0KCdwcm9jZXNzUmVmJyk7XHJcbiAgICAgIH1cclxuICAgIH0sIHRyYW5zbGF0ZSkpO1xyXG4gIH1cclxuXHJcbiAgaWYgKGlzKGVsZW1lbnQsICdhY3Rpdml0aTpBc3luY0NhcGFibGUnKSkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGpvYlJldHJ5VGltZUN5Y2xlKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0OiBnZXRCdXNpbmVzc09iamVjdFxyXG4gICAgfSwgdHJhbnNsYXRlKSk7XHJcbiAgfVxyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgSW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0ltcGxlbWVudGF0aW9uVHlwZUhlbHBlcicpLFxyXG5cclxuICAgIHNjcmlwdEltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9TY3JpcHQnKTtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBMSVNURU5FUl9UWVBFX0xBQkVMID0ge1xyXG4gICAgY2xhc3M6IHRyYW5zbGF0ZSgnSmF2YSBDbGFzcycpLFxyXG4gICAgZXhwcmVzc2lvbjogdHJhbnNsYXRlKCdFeHByZXNzaW9uJyksXHJcbiAgICBkZWxlZ2F0ZUV4cHJlc3Npb246IHRyYW5zbGF0ZSgnRGVsZWdhdGUgRXhwcmVzc2lvbicpLFxyXG4gICAgc2NyaXB0OiB0cmFuc2xhdGUoJ1NjcmlwdCcpXHJcbiAgfTtcclxuXHJcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG4gIHZhciBnZXRTZWxlY3RlZExpc3RlbmVyID0gb3B0aW9ucy5nZXRTZWxlY3RlZExpc3RlbmVyO1xyXG5cclxuICB2YXIgY2xhc3NQcm9wID0gJ2NsYXNzJyxcclxuICAgICAgZXhwcmVzc2lvblByb3AgPSAnZXhwcmVzc2lvbicsXHJcbiAgICAgIGRlbGVnYXRlRXhwcmVzc2lvblByb3AgPSAnZGVsZWdhdGVFeHByZXNzaW9uJyxcclxuICAgICAgc2NyaXB0UHJvcCA9ICdzY3JpcHQnO1xyXG5cclxuICB2YXIgZXhlY3V0aW9uTGlzdGVuZXJFdmVudFR5cGVPcHRpb25zID0gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzU2VxdWVuY2VGbG93KGVsZW1lbnQpID8gW1xyXG4gICAgeyBuYW1lOiB0cmFuc2xhdGUoJ3Rha2UnKSwgdmFsdWU6ICd0YWtlJyB9XHJcbiAgXSA6IFtcclxuICAgIHsgbmFtZTogdHJhbnNsYXRlKCdzdGFydCcpLCB2YWx1ZTogJ3N0YXJ0JyB9LFxyXG4gICAgeyBuYW1lOiB0cmFuc2xhdGUoJ2VuZCcpLCB2YWx1ZTogJ2VuZCcgfVxyXG4gIF07XHJcblxyXG4gIHZhciB0YXNrTGlzdGVuZXJFdmVudFR5cGVPcHRpb25zID0gW1xyXG4gICAgeyBuYW1lOiB0cmFuc2xhdGUoJ2NyZWF0ZScpLCB2YWx1ZTogJ2NyZWF0ZScgfSxcclxuICAgIHsgbmFtZTogdHJhbnNsYXRlKCdhc3NpZ25tZW50JyksIHZhbHVlOiAnYXNzaWdubWVudCcgfSxcclxuICAgIHsgbmFtZTogdHJhbnNsYXRlKCdjb21wbGV0ZScpLCB2YWx1ZTogJ2NvbXBsZXRlJyB9LFxyXG4gICAgeyBuYW1lOiB0cmFuc2xhdGUoJ2RlbGV0ZScpLCB2YWx1ZTogJ2RlbGV0ZScgfVxyXG4gIF07XHJcblxyXG4gIHZhciBpc1NlbGVjdGVkID0gZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgcmV0dXJuIGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcbiAgfTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6ICdsaXN0ZW5lci1ldmVudC10eXBlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0V2ZW50IFR5cGUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdldmVudFR5cGUnLFxyXG4gICAgZW1wdHlQYXJhbWV0ZXI6IGZhbHNlLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG5cclxuXHJcbiAgICAgIHZhciBsaXN0ZW5lciA9IGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICB2YXIgZXZlbnRUeXBlID0gbGlzdGVuZXIgJiYgbGlzdGVuZXIuZ2V0KCdldmVudCcpO1xyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBldmVudFR5cGU6IGV2ZW50VHlwZVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgZXZlbnRUeXBlID0gdmFsdWVzLmV2ZW50VHlwZTtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKSwgeyBldmVudDogZXZlbnRUeXBlIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZWxlY3RPcHRpb25zOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBldmVudFR5cGVPcHRpb25zO1xyXG5cclxuICAgICAgdmFyIHNlbGVjdGVkTGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICBpZiAoSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzVGFza0xpc3RlbmVyKHNlbGVjdGVkTGlzdGVuZXIpKSB7XHJcbiAgICAgICAgZXZlbnRUeXBlT3B0aW9ucyA9IHRhc2tMaXN0ZW5lckV2ZW50VHlwZU9wdGlvbnM7XHJcbiAgICAgIH0gZWxzZSBpZiAoSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzRXhlY3V0aW9uTGlzdGVuZXIoc2VsZWN0ZWRMaXN0ZW5lcikpIHtcclxuICAgICAgICBldmVudFR5cGVPcHRpb25zID0gZXhlY3V0aW9uTGlzdGVuZXJFdmVudFR5cGVPcHRpb25zO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gZXZlbnRUeXBlT3B0aW9ucztcclxuXHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3Rvcnkuc2VsZWN0Qm94KHtcclxuICAgIGlkOiAnbGlzdGVuZXItdHlwZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdMaXN0ZW5lciBUeXBlJyksXHJcbiAgICBzZWxlY3RPcHRpb25zOiBbXHJcbiAgICAgIHsgdmFsdWU6IGNsYXNzUHJvcCwgbmFtZTogdHJhbnNsYXRlKCdKYXZhIENsYXNzJykgfSxcclxuICAgICAgeyB2YWx1ZTogZXhwcmVzc2lvblByb3AsIG5hbWU6IHRyYW5zbGF0ZSgnRXhwcmVzc2lvbicpIH0sXHJcbiAgICAgIHsgdmFsdWU6IGRlbGVnYXRlRXhwcmVzc2lvblByb3AsIG5hbWU6IHRyYW5zbGF0ZSgnRGVsZWdhdGUgRXhwcmVzc2lvbicpIH0sXHJcbiAgICAgIHsgdmFsdWU6IHNjcmlwdFByb3AsIG5hbWU6IHRyYW5zbGF0ZSgnU2NyaXB0JykgfVxyXG4gICAgXSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdsaXN0ZW5lclR5cGUnLFxyXG4gICAgZW1wdHlQYXJhbWV0ZXI6IGZhbHNlLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxpc3RlbmVyVHlwZTogSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldEltcGxlbWVudGF0aW9uVHlwZShsaXN0ZW5lcilcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGxpc3RlbmVyID0gZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKSxcclxuICAgICAgICAgIGxpc3RlbmVyVHlwZSA9IHZhbHVlcy5saXN0ZW5lclR5cGUgfHwgdW5kZWZpbmVkLFxyXG4gICAgICAgICAgdXBkYXRlID0ge307XHJcblxyXG4gICAgICB1cGRhdGVbY2xhc3NQcm9wXSA9IGxpc3RlbmVyVHlwZSA9PT0gY2xhc3NQcm9wID8gJycgOiB1bmRlZmluZWQ7XHJcbiAgICAgIHVwZGF0ZVtleHByZXNzaW9uUHJvcF0gPSBsaXN0ZW5lclR5cGUgPT09IGV4cHJlc3Npb25Qcm9wID8gJycgOiB1bmRlZmluZWQ7XHJcbiAgICAgIHVwZGF0ZVtkZWxlZ2F0ZUV4cHJlc3Npb25Qcm9wXSA9IGxpc3RlbmVyVHlwZSA9PT0gZGVsZWdhdGVFeHByZXNzaW9uUHJvcCA/ICcnIDogdW5kZWZpbmVkO1xyXG4gICAgICB1cGRhdGVbc2NyaXB0UHJvcF0gPSBsaXN0ZW5lclR5cGUgPT09IHNjcmlwdFByb3AgPyBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOlNjcmlwdCcpIDogdW5kZWZpbmVkO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBsaXN0ZW5lciwgdXBkYXRlKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhaXNTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuXHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdsaXN0ZW5lci12YWx1ZScsXHJcbiAgICBkYXRhVmFsdWVMYWJlbDogJ2xpc3RlbmVyVmFsdWVMYWJlbCcsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnbGlzdGVuZXJWYWx1ZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciB2YWx1ZSA9IHt9LFxyXG4gICAgICAgICAgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgbGlzdGVuZXJUeXBlID0gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldEltcGxlbWVudGF0aW9uVHlwZShsaXN0ZW5lcik7XHJcblxyXG4gICAgICB2YWx1ZS5saXN0ZW5lclZhbHVlTGFiZWwgPSBMSVNURU5FUl9UWVBFX0xBQkVMW2xpc3RlbmVyVHlwZV0gfHwgJyc7XHJcbiAgICAgIHZhbHVlLmxpc3RlbmVyVmFsdWUgPSAobGlzdGVuZXIgJiYgbGlzdGVuZXIuZ2V0KGxpc3RlbmVyVHlwZSkpIHx8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIHVwZGF0ZSA9IHt9LFxyXG4gICAgICAgICAgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgbGlzdGVuZXJUeXBlID0gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldEltcGxlbWVudGF0aW9uVHlwZShsaXN0ZW5lcik7XHJcblxyXG4gICAgICB1cGRhdGVbbGlzdGVuZXJUeXBlXSA9IHZhbHVlcy5saXN0ZW5lclZhbHVlIHx8ICcnO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBsaXN0ZW5lciwgdXBkYXRlKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBsaXN0ZW5lciA9IGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiAhbGlzdGVuZXIgfHwgbGlzdGVuZXIuc2NyaXB0O1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciB2YWx1ZSA9IHZhbHVlcy5saXN0ZW5lclZhbHVlLFxyXG4gICAgICAgICAgdmFsaWRhdGUgPSB7fTtcclxuXHJcbiAgICAgIGlmICghdmFsdWUpIHtcclxuICAgICAgICB2YWxpZGF0ZS5saXN0ZW5lclZhbHVlID0gdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdmFsaWRhdGU7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgdmFyIHNjcmlwdCA9IHNjcmlwdEltcGxlbWVudGF0aW9uKCdzY3JpcHRGb3JtYXQnLCAndmFsdWUnLCB0cnVlLCB0cmFuc2xhdGUpO1xyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goe1xyXG4gICAgaWQ6ICdsaXN0ZW5lci1zY3JpcHQtdmFsdWUnLFxyXG4gICAgaHRtbDogJzxkaXYgZGF0YS1zaG93PVwiaXNTY3JpcHRcIj4nICtcclxuICAgICAgICAgICAgc2NyaXB0LnRlbXBsYXRlICtcclxuICAgICAgICAgICc8L2Rpdj4nLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gbGlzdGVuZXIgJiYgbGlzdGVuZXIuc2NyaXB0ID8gc2NyaXB0LmdldChlbGVtZW50LCBsaXN0ZW5lci5zY3JpcHQpIDoge307XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBsaXN0ZW5lciA9IGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciB1cGRhdGUgPSBzY3JpcHQuc2V0KGVsZW1lbnQsIHZhbHVlcywgbGlzdGVuZXIpO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGxpc3RlbmVyLnNjcmlwdCwgdXBkYXRlKTtcclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gbGlzdGVuZXIgJiYgbGlzdGVuZXIuc2NyaXB0ID8gc2NyaXB0LnZhbGlkYXRlKGVsZW1lbnQsIHZhbHVlcykgOiB7fTtcclxuICAgIH0sXHJcblxyXG4gICAgaXNTY3JpcHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGxpc3RlbmVyID0gZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGxpc3RlbmVyICYmIGxpc3RlbmVyLnNjcmlwdDtcclxuICAgIH0sXHJcblxyXG4gICAgc2NyaXB0OiBzY3JpcHRcclxuXHJcbiAgfSk7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xyXG5cclxudmFyIGZpZWxkSW5qZWN0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9GaWVsZEluamVjdGlvbicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICBvcHRpb25zID0gYXNzaWduKHtcclxuICAgIGlkUHJlZml4OiAnbGlzdGVuZXItJyxcclxuICAgIGluc2lkZUxpc3RlbmVyOiB0cnVlXHJcbiAgfSwgb3B0aW9ucyk7XHJcblxyXG4gIHZhciBmaWVsZEluamVjdGlvbkVudHJ5ID0gZmllbGRJbmplY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSwgb3B0aW9ucyk7XHJcblxyXG4gIGlmIChmaWVsZEluamVjdGlvbkVudHJ5ICYmIGZpZWxkSW5qZWN0aW9uRW50cnkubGVuZ3RoID4gMCkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGZpZWxkSW5qZWN0aW9uRW50cnkpO1xyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBsaXN0ZW5lciA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vTGlzdGVuZXInKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGxpc3RlbmVyRW50cnkgPSBsaXN0ZW5lcihlbGVtZW50LCBicG1uRmFjdG9yeSwge30sIHRyYW5zbGF0ZSk7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChsaXN0ZW5lckVudHJ5LmVudHJpZXMpO1xyXG5cclxuICByZXR1cm4ge1xyXG4gICAgZ2V0U2VsZWN0ZWRMaXN0ZW5lcjogbGlzdGVuZXJFbnRyeS5nZXRTZWxlY3RlZExpc3RlbmVyXHJcbiAgfTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgbXVsdGlJbnN0YW5jZUxvb3BDaGFyYWN0ZXJpc3RpY3MgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL011bHRpSW5zdGFuY2VMb29wQ2hhcmFjdGVyaXN0aWNzJyk7XHJcblxyXG52YXIgam9iUmV0cnlUaW1lQ3ljbGUgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0pvYlJldHJ5VGltZUN5Y2xlJyksXHJcbiAgICBhc3luY0NvbnRpbnVhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQXN5bmNDb250aW51YXRpb24nKTtcclxuXHJcblxyXG5mdW5jdGlvbiBnZXRMb29wQ2hhcmFjdGVyaXN0aWNzKGVsZW1lbnQpIHtcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICByZXR1cm4gYm8ubG9vcENoYXJhY3RlcmlzdGljcztcclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIGVuc3VyZU11bHRpSW5zdGFuY2VTdXBwb3J0ZWQoZWxlbWVudCkge1xyXG4gIHZhciBsb29wQ2hhcmFjdGVyaXN0aWNzID0gZ2V0TG9vcENoYXJhY3RlcmlzdGljcyhlbGVtZW50KTtcclxuICByZXR1cm4gISFsb29wQ2hhcmFjdGVyaXN0aWNzICYmIGlzKGxvb3BDaGFyYWN0ZXJpc3RpY3MsICdhY3Rpdml0aTpDb2xsZWN0YWJsZScpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlmICghZW5zdXJlTXVsdGlJbnN0YW5jZVN1cHBvcnRlZChlbGVtZW50KSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgLy8gbXVsdGkgaW5zdGFuY2UgcHJvcGVydGllc1xyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChtdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSk7XHJcblxyXG4gIC8vIGFzeW5jIGNvbnRpbnVhdGlvbiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGFzeW5jQ29udGludWF0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBnZXRCdXNpbmVzc09iamVjdDogZ2V0TG9vcENoYXJhY3RlcmlzdGljcyxcclxuICAgIGlkUHJlZml4OiAnbXVsdGlJbnN0YW5jZS0nLFxyXG4gICAgbGFiZWxQcmVmaXg6IHRyYW5zbGF0ZSgnTXVsdGkgSW5zdGFuY2UgJylcclxuICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcblxyXG4gIC8vIHJldHJ5IHRpbWUgY3ljbGUgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChqb2JSZXRyeVRpbWVDeWNsZShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGdldExvb3BDaGFyYWN0ZXJpc3RpY3MsXHJcbiAgICBpZFByZWZpeDogJ211bHRpSW5zdGFuY2UtJyxcclxuICAgIGxhYmVsUHJlZml4OiB0cmFuc2xhdGUoJ011bHRpIEluc3RhbmNlICcpXHJcbiAgfSwgdHJhbnNsYXRlKSk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBwcm9wZXJ0aWVzID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9Qcm9wZXJ0aWVzJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBwcm9wZXJ0aWVzRW50cnkgPSBwcm9wZXJ0aWVzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ3Byb3BlcnRpZXMnLFxyXG4gICAgbW9kZWxQcm9wZXJ0aWVzOiBbICduYW1lJywgJ3ZhbHVlJyBdLFxyXG4gICAgbGFiZWxzOiBbIHRyYW5zbGF0ZSgnTmFtZScpLCB0cmFuc2xhdGUoJ1ZhbHVlJykgXSxcclxuXHJcbiAgICBnZXRQYXJlbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGJvKSB7XHJcbiAgICAgIHJldHVybiBiby5leHRlbnNpb25FbGVtZW50cztcclxuICAgIH0sXHJcblxyXG4gICAgY3JlYXRlUGFyZW50OiBmdW5jdGlvbihlbGVtZW50LCBibykge1xyXG4gICAgICB2YXIgcGFyZW50ID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJywgeyB2YWx1ZXM6IFtdIH0sIGJvLCBicG1uRmFjdG9yeSk7XHJcbiAgICAgIHZhciBjbWQgPSBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgZXh0ZW5zaW9uRWxlbWVudHM6IHBhcmVudCB9KTtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBjbWQ6IGNtZCxcclxuICAgICAgICBwYXJlbnQ6IHBhcmVudFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH0sIHRyYW5zbGF0ZSk7XHJcblxyXG4gIGlmIChwcm9wZXJ0aWVzRW50cnkpIHtcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChwcm9wZXJ0aWVzRW50cnkpO1xyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgc2NyaXB0SW1wbGVtZW50YXRpb24gPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL1NjcmlwdCcpO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuICB2YXIgYm87XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpTY3JpcHRUYXNrJykpIHtcclxuICAgIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICBpZiAoIWJvKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgc2NyaXB0ID0gc2NyaXB0SW1wbGVtZW50YXRpb24oJ3NjcmlwdEZvcm1hdCcsICdzY3JpcHQnLCBmYWxzZSwgdHJhbnNsYXRlKTtcclxuICBncm91cC5lbnRyaWVzLnB1c2goe1xyXG4gICAgaWQ6ICdzY3JpcHQtaW1wbGVtZW50YXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnU2NyaXB0JyksXHJcbiAgICBodG1sOiBzY3JpcHQudGVtcGxhdGUsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBzY3JpcHQuZ2V0KGVsZW1lbnQsIGJvKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIGNvbnRhaW5lckVsZW1lbnQpIHtcclxuICAgICAgdmFyIHByb3BlcnRpZXMgPSBzY3JpcHQuc2V0KGVsZW1lbnQsIHZhbHVlcywgY29udGFpbmVyRWxlbWVudCk7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcHJvcGVydGllcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgcmV0dXJuIHNjcmlwdC52YWxpZGF0ZShlbGVtZW50LCB2YWx1ZXMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzY3JpcHQgOiBzY3JpcHQsXHJcblxyXG4gICAgY3NzQ2xhc3NlczogWydicHAtdGV4dGZpZWxkJ11cclxuXHJcbiAgfSk7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkIDogJ3NjcmlwdFJlc3VsdFZhcmlhYmxlJyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdSZXN1bHQgVmFyaWFibGUnKSxcclxuICAgIG1vZGVsUHJvcGVydHkgOiAnc2NyaXB0UmVzdWx0VmFyaWFibGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydHlOYW1lKSB7XHJcbiAgICAgIHZhciBib1Jlc3VsdFZhcmlhYmxlID0gYm8uZ2V0KCdhY3Rpdml0aTpyZXN1bHRWYXJpYWJsZScpO1xyXG5cclxuICAgICAgcmV0dXJuIHsgc2NyaXB0UmVzdWx0VmFyaWFibGUgOiBib1Jlc3VsdFZhcmlhYmxlIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBjb250YWluZXJFbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOnJlc3VsdFZhcmlhYmxlJzogdmFsdWVzLnNjcmlwdFJlc3VsdFZhcmlhYmxlLmxlbmd0aFxyXG4gICAgICAgICAgPyB2YWx1ZXMuc2NyaXB0UmVzdWx0VmFyaWFibGVcclxuICAgICAgICAgIDogdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgSW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0ltcGxlbWVudGF0aW9uVHlwZUhlbHBlcicpLFxyXG4gICAgSW5wdXRPdXRwdXRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvSW5wdXRPdXRwdXRIZWxwZXInKTtcclxuXHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uL1V0aWxzJyksXHJcbiAgICBlc2NhcGVIVE1MID0gdXRpbHMuZXNjYXBlSFRNTCxcclxuICAgIHRyaWdnZXJDbGlja0V2ZW50ID0gdXRpbHMudHJpZ2dlckNsaWNrRXZlbnQ7XHJcblxyXG52YXIgaW1wbGVtZW50YXRpb25UeXBlID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9JbXBsZW1lbnRhdGlvblR5cGUnKSxcclxuICAgIGRlbGVnYXRlID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9EZWxlZ2F0ZScpLFxyXG4gICAgZXh0ZXJuYWwgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0V4dGVybmFsJyksXHJcbiAgICBjYWxsYWJsZSA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQ2FsbGFibGUnKSxcclxuICAgIHJlc3VsdFZhcmlhYmxlID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9SZXN1bHRWYXJpYWJsZScpO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnksXHJcbiAgICBkb21DbG9zZXN0ID0gcmVxdWlyZSgnbWluLWRvbScpLmNsb3Nlc3QsXHJcbiAgICBkb21DbGFzc2VzID0gcmVxdWlyZSgnbWluLWRvbScpLmNsYXNzZXM7XHJcblxyXG5mdW5jdGlvbiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkge1xyXG4gIHJldHVybiBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0SW1wbGVtZW50YXRpb25UeXBlKGVsZW1lbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSB7XHJcbiAgcmV0dXJuIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRTZXJ2aWNlVGFza0xpa2VCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNEbW5DYXBhYmxlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzRG1uQ2FwYWJsZShlbGVtZW50KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNFeHRlcm5hbENhcGFibGUoZWxlbWVudCkge1xyXG4gIHJldHVybiBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuaXNFeHRlcm5hbENhcGFibGUoZWxlbWVudCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzU2VydmljZVRhc2tMaWtlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzU2VydmljZVRhc2tMaWtlKGVsZW1lbnQpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlmICghaXNTZXJ2aWNlVGFza0xpa2UoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgaGFzRG1uU3VwcG9ydCA9IGlzRG1uQ2FwYWJsZShlbGVtZW50KTtcclxuICB2YXIgaGFzRXh0ZXJuYWxTdXBwb3J0ID0gaXNFeHRlcm5hbENhcGFibGUoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkpO1xyXG5cclxuICAvLyBpbXBsZW1lbnRhdGlvbiB0eXBlIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoaW1wbGVtZW50YXRpb25UeXBlKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBnZXRCdXNpbmVzc09iamVjdDogZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBnZXRJbXBsZW1lbnRhdGlvblR5cGU6IGdldEltcGxlbWVudGF0aW9uVHlwZSxcclxuICAgIGhhc0RtblN1cHBvcnQ6IGhhc0RtblN1cHBvcnQsXHJcbiAgICBoYXNFeHRlcm5hbFN1cHBvcnQ6IGhhc0V4dGVybmFsU3VwcG9ydCxcclxuICAgIGhhc1NlcnZpY2VUYXNrTGlrZVN1cHBvcnQ6IHRydWVcclxuICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcblxyXG4gIC8vIGRlbGVnYXRlIChjbGFzcywgZXhwcmVzc2lvbiwgZGVsZWdhdGVFeHByZXNzaW9uKSAvLy8vLy8vLy8vXHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChkZWxlZ2F0ZShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgZ2V0SW1wbGVtZW50YXRpb25UeXBlOiBnZXRJbXBsZW1lbnRhdGlvblR5cGVcclxuICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcblxyXG4gIC8vIHJlc3VsdCB2YXJpYWJsZSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQocmVzdWx0VmFyaWFibGUoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0OiBnZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGdldEltcGxlbWVudGF0aW9uVHlwZTogZ2V0SW1wbGVtZW50YXRpb25UeXBlLFxyXG4gICAgaGlkZVJlc3VsdFZhcmlhYmxlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkgIT09ICdleHByZXNzaW9uJztcclxuICAgIH1cclxuICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgLy8gZXh0ZXJuYWwgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgaWYgKGhhc0V4dGVybmFsU3VwcG9ydCkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGV4dGVybmFsKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0OiBnZXRCdXNpbmVzc09iamVjdCxcclxuICAgICAgZ2V0SW1wbGVtZW50YXRpb25UeXBlOiBnZXRJbXBsZW1lbnRhdGlvblR5cGVcclxuICAgIH0sIHRyYW5zbGF0ZSkpO1xyXG4gIH1cclxuXHJcblxyXG4gIC8vIGRtbiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBpZiAoaGFzRG1uU3VwcG9ydCkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGNhbGxhYmxlKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGdldENhbGxhYmxlVHlwZTogZ2V0SW1wbGVtZW50YXRpb25UeXBlXHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuICB9XHJcblxyXG5cclxuICAvLyBjb25uZWN0b3IgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIHZhciBpc0Nvbm5lY3RvciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkgPT09ICdjb25uZWN0b3InO1xyXG4gIH07XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkubGluayh7XHJcbiAgICBpZDogJ2NvbmZpZ3VyZUNvbm5lY3RvckxpbmsnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ29uZmlndXJlIENvbm5lY3RvcicpLFxyXG4gICAgaGFuZGxlQ2xpY2s6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50KSB7XHJcblxyXG4gICAgICB2YXIgY29ubmVjdG9yVGFiRWwgPSBnZXRUYWJOb2RlKG5vZGUsICdjb25uZWN0b3InKTtcclxuXHJcbiAgICAgIGlmIChjb25uZWN0b3JUYWJFbCkge1xyXG4gICAgICAgIHRyaWdnZXJDbGlja0V2ZW50KGNvbm5lY3RvclRhYkVsKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gc3VwcHJlc3MgYWN0dWFsIGxpbmsgY2xpY2tcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSxcclxuICAgIHNob3dMaW5rOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBsaW5rID0gZG9tUXVlcnkoJ2EnLCBub2RlKTtcclxuICAgICAgbGluay50ZXh0Q29udGVudCA9ICcnO1xyXG5cclxuICAgICAgZG9tQ2xhc3NlcyhsaW5rKS5yZW1vdmUoJ2JwcC1lcnJvci1tZXNzYWdlJyk7XHJcblxyXG4gICAgICBpZiAoaXNDb25uZWN0b3IoZWxlbWVudCkpIHtcclxuICAgICAgICB2YXIgY29ubmVjdG9ySWQgPSBJbnB1dE91dHB1dEhlbHBlci5nZXRDb25uZWN0b3IoZWxlbWVudCkuZ2V0KCdjb25uZWN0b3JJZCcpO1xyXG4gICAgICAgIGlmIChjb25uZWN0b3JJZCkge1xyXG4gICAgICAgICAgbGluay50ZXh0Q29udGVudCA9IHRyYW5zbGF0ZSgnQ29uZmlndXJlIENvbm5lY3RvcicpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBsaW5rLmlubmVySFRNTCA9ICc8c3BhbiBjbGFzcz1cImJwcC1pY29uLXdhcm5pbmdcIj48L3NwYW4+ICcgKyBlc2NhcGVIVE1MKHRyYW5zbGF0ZSgnTXVzdCBjb25maWd1cmUgQ29ubmVjdG9yJykpO1xyXG4gICAgICAgICAgZG9tQ2xhc3NlcyhsaW5rKS5hZGQoJ2JwcC1lcnJvci1tZXNzYWdlJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbn07XHJcblxyXG5cclxuXHJcbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBnZXRUYWJOb2RlKGVsLCBpZCkge1xyXG4gIHZhciBjb250YWluZXJFbCA9IGRvbUNsb3Nlc3QoZWwsICcuYnBwLXByb3BlcnRpZXMtcGFuZWwnKTtcclxuXHJcbiAgcmV0dXJuIGRvbVF1ZXJ5KCdhW2RhdGEtdGFiLXRhcmdldD1cIicgKyBpZCArICdcIl0nLCBjb250YWluZXJFbCk7XHJcbn0iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6SW5pdGlhdG9yJykgJiYgIWlzKGVsZW1lbnQucGFyZW50LCAnYnBtbjpTdWJQcm9jZXNzJykpIHtcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQ6ICdpbml0aWF0b3InLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdJbml0aWF0b3InKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eTogJ2luaXRpYXRvcidcclxuICAgIH0pKTtcclxuICB9XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgdGFza2xpc3QgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL1Rhc2tsaXN0Jyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6UHJvY2VzcycpIHx8XHJcbiAgICAgIGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdwcm9jZXNzUmVmJykpIHtcclxuXHJcbiAgICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQodGFza2xpc3QoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKCFpcyhibywgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGJvO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGJvLmdldCgncHJvY2Vzc1JlZicpO1xyXG4gICAgICB9XHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgfVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpIHtcclxuICBpZiAoaXMoZWxlbWVudCwgJ2FjdGl2aXRpOkFzc2lnbmFibGUnKSkge1xyXG5cclxuICAgIC8vIEFzc2lnbmVlXHJcbiAgICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICAgIGlkIDogJ2Fzc2lnbmVlJyxcclxuICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0Fzc2lnbmVlJyksXHJcbiAgICAgIG1vZGVsUHJvcGVydHkgOiAnYXNzaWduZWUnXHJcbiAgICB9KSk7XHJcblxyXG4gICAgLy8gQ2FuZGlkYXRlIFVzZXJzXHJcbiAgICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICAgIGlkIDogJ2NhbmRpZGF0ZVVzZXJzJyxcclxuICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0NhbmRpZGF0ZSBVc2VycycpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5IDogJ2NhbmRpZGF0ZVVzZXJzJ1xyXG4gICAgfSkpO1xyXG5cclxuICAgIC8vIENhbmRpZGF0ZSBHcm91cHNcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQgOiAnY2FuZGlkYXRlR3JvdXBzJyxcclxuICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0NhbmRpZGF0ZSBHcm91cHMnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA6ICdjYW5kaWRhdGVHcm91cHMnXHJcbiAgICB9KSk7XHJcblxyXG4gICAgLy8gRHVlIERhdGVcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQgOiAnZHVlRGF0ZScsXHJcbiAgICAgIGRlc2NyaXB0aW9uIDogdHJhbnNsYXRlKCdUaGUgZHVlIGRhdGUgYXMgYW4gRUwgZXhwcmVzc2lvbiAoZS5nLiAke3NvbWVEYXRlfSBvciBhbiBJU08gZGF0ZSAoZS5nLiAyMDE1LTA2LTI2VDA5OjU0OjAwKScpLFxyXG4gICAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnRHVlIERhdGUnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA6ICdkdWVEYXRlJ1xyXG4gICAgfSkpO1xyXG5cclxuICAgIC8vIEZvbGxvd1VwIERhdGVcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQgOiAnZm9sbG93VXBEYXRlJyxcclxuICAgICAgZGVzY3JpcHRpb24gOiB0cmFuc2xhdGUoJ1RoZSBmb2xsb3cgdXAgZGF0ZSBhcyBhbiBFTCBleHByZXNzaW9uIChlLmcuICR7c29tZURhdGV9IG9yIGFuICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICdJU08gZGF0ZSAoZS5nLiAyMDE1LTA2LTI2VDA5OjU0OjAwKScpLFxyXG4gICAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnRm9sbG93IFVwIERhdGUnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA6ICdmb2xsb3dVcERhdGUnXHJcbiAgICB9KSk7XHJcblxyXG4gICAgLy8gcHJpb3JpdHlcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQgOiAncHJpb3JpdHknLFxyXG4gICAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnUHJpb3JpdHknKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA6ICdwcmlvcml0eSdcclxuICAgIH0pKTtcclxuICB9XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBpc0FueSA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJykuaXNBbnksXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgZmlsdGVyID0gcmVxdWlyZSgnbG9kYXNoL2ZpbHRlcicpO1xyXG5cclxudmFyIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKSxcclxuICAgIGV2ZW50RGVmaW5pdGlvbkhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9FdmVudERlZmluaXRpb25IZWxwZXInKTtcclxuXHJcbnZhciBleHRlbnNpb25FbGVtZW50c0VudHJ5ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9FeHRlbnNpb25FbGVtZW50cycpO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG4vKipcclxuICAqIHJldHVybiBkZXBlbmQgb24gcGFyYW1ldGVyICd0eXBlJyBhY3Rpdml0aTppbiBvciBhY3Rpdml0aTpvdXQgZXh0ZW5zaW9uIGVsZW1lbnRzXHJcbiAgKi9cclxuZnVuY3Rpb24gZ2V0QWN0aXZpdGlJbk91dE1hcHBpbmdzKGVsZW1lbnQsIHR5cGUpIHtcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgdmFyIHNpZ25hbEV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRTaWduYWxFdmVudERlZmluaXRpb24oYm8pO1xyXG5cclxuICByZXR1cm4gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoc2lnbmFsRXZlbnREZWZpbml0aW9uIHx8IGJvLCB0eXBlKSB8fCBbXTtcclxufVxyXG5cclxuLyoqXHJcbiAgKiByZXR1cm4gZGVwZW5kIG9uIHBhcmFtZXRlciAndHlwZScgYWN0aXZpdGk6aW4gb3IgYWN0aXZpdGk6b3V0IGV4dGVuc2lvbiBlbGVtZW50c1xyXG4gICogd2l0aCBzb3VyY2Ugb3Igc291cmNlRXhwcmVzc2lvbiBhdHRyaWJ1dGVcclxuICAqL1xyXG5mdW5jdGlvbiBnZXRWYXJpYWJsZU1hcHBpbmdzKGVsZW1lbnQsIHR5cGUpIHtcclxuICB2YXIgYWN0aXZpdGlNYXBwaW5ncyA9IGdldEFjdGl2aXRpSW5PdXRNYXBwaW5ncyhlbGVtZW50LCB0eXBlKTtcclxuXHJcbiAgcmV0dXJuIGZpbHRlcihhY3Rpdml0aU1hcHBpbmdzLCBmdW5jdGlvbihtYXBwaW5nKSB7XHJcbiAgICByZXR1cm4gIW1hcHBpbmcuYnVzaW5lc3NLZXk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEluT3V0VHlwZShtYXBwaW5nKSB7XHJcbiAgdmFyIGluT3V0VHlwZSA9ICdzb3VyY2UnO1xyXG5cclxuICBpZiAobWFwcGluZy52YXJpYWJsZXMgPT09ICdhbGwnKSB7XHJcbiAgICBpbk91dFR5cGUgPSAndmFyaWFibGVzJztcclxuICB9XHJcbiAgZWxzZSBpZiAodHlwZW9mIG1hcHBpbmcuc291cmNlICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgaW5PdXRUeXBlID0gJ3NvdXJjZSc7XHJcbiAgfVxyXG4gIGVsc2UgaWYgKHR5cGVvZiBtYXBwaW5nLnNvdXJjZUV4cHJlc3Npb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICBpbk91dFR5cGUgPSAnc291cmNlRXhwcmVzc2lvbic7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gaW5PdXRUeXBlO1xyXG59XHJcblxyXG52YXIgQUNUSVZJVElfSU5fRVhURU5TSU9OX0VMRU1FTlQgPSAnYWN0aXZpdGk6SW4nLFxyXG4gICAgQUNUSVZJVElfT1VUX0VYVEVOU0lPTl9FTEVNRU5UID0gJ2FjdGl2aXRpOk91dCc7XHJcblxyXG52YXIgV0hJVEVTUEFDRV9SRUdFWCA9IC9cXHMvO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGluT3V0VHlwZU9wdGlvbnMgPSBbXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6IHRyYW5zbGF0ZSgnU291cmNlJyksXHJcbiAgICAgIHZhbHVlOiAnc291cmNlJ1xyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogdHJhbnNsYXRlKCdTb3VyY2UgRXhwcmVzc2lvbicpLFxyXG4gICAgICB2YWx1ZTogJ3NvdXJjZUV4cHJlc3Npb24nXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiB0cmFuc2xhdGUoJ0FsbCcpLFxyXG4gICAgICB2YWx1ZTogJ3ZhcmlhYmxlcydcclxuICAgIH1cclxuICBdO1xyXG5cclxuICB2YXIgc2lnbmFsRXZlbnREZWZpbml0aW9uID0gZXZlbnREZWZpbml0aW9uSGVscGVyLmdldFNpZ25hbEV2ZW50RGVmaW5pdGlvbihlbGVtZW50KTtcclxuXHJcbiAgaWYgKCFpcyhlbGVtZW50LCAnYWN0aXZpdGk6Q2FsbEFjdGl2aXR5JykgJiYgIXNpZ25hbEV2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgaWYgKHNpZ25hbEV2ZW50RGVmaW5pdGlvbiAmJiAhKGlzQW55KGVsZW1lbnQsIFtcclxuICAgICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnLFxyXG4gICAgJ2JwbW46RW5kRXZlbnQnXHJcbiAgXSkpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgaXNTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHJldHVybiAhIWdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gIH07XHJcblxyXG4gIHZhciBnZXRTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciBwYXJlbnROb2RlID0gbm9kZS5wYXJlbnROb2RlO1xyXG4gICAgdmFyIHNlbGVjdGlvbiA9IGluRW50cnkuZ2V0U2VsZWN0ZWQoZWxlbWVudCwgcGFyZW50Tm9kZSk7XHJcblxyXG4gICAgdmFyIHBhcmFtZXRlciA9IGdldFZhcmlhYmxlTWFwcGluZ3MoZWxlbWVudCwgQUNUSVZJVElfSU5fRVhURU5TSU9OX0VMRU1FTlQpW3NlbGVjdGlvbi5pZHhdO1xyXG5cclxuICAgIGlmICghcGFyYW1ldGVyICYmIG91dEVudHJ5KSB7XHJcbiAgICAgIHNlbGVjdGlvbiA9IG91dEVudHJ5LmdldFNlbGVjdGVkKGVsZW1lbnQsIHBhcmVudE5vZGUpO1xyXG4gICAgICBwYXJhbWV0ZXIgPSBnZXRWYXJpYWJsZU1hcHBpbmdzKGVsZW1lbnQsIEFDVElWSVRJX09VVF9FWFRFTlNJT05fRUxFTUVOVClbc2VsZWN0aW9uLmlkeF07XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBhcmFtZXRlcjtcclxuICB9O1xyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBvcHRpb24sIHByb3BlcnR5LCB2YWx1ZSwgaWR4KSB7XHJcbiAgICAgIHZhciB2YXJpYWJsZU1hcHBpbmdzID0gZ2V0VmFyaWFibGVNYXBwaW5ncyhlbGVtZW50LCB0eXBlKTtcclxuICAgICAgdmFyIG1hcHBpbmdWYWx1ZSA9IHZhcmlhYmxlTWFwcGluZ3NbaWR4XTtcclxuICAgICAgdmFyIGxhYmVsID0gKG1hcHBpbmdWYWx1ZS50YXJnZXQgfHwgJzx1bmRlZmluZWQ+JykgKyAnIDo9ICc7XHJcbiAgICAgIHZhciBtYXBwaW5nVHlwZSA9IGdldEluT3V0VHlwZShtYXBwaW5nVmFsdWUpO1xyXG5cclxuICAgICAgaWYgKG1hcHBpbmdUeXBlID09PSAndmFyaWFibGVzJykge1xyXG4gICAgICAgIGxhYmVsID0gJ2FsbCc7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAobWFwcGluZ1R5cGUgPT09ICdzb3VyY2UnKSB7XHJcbiAgICAgICAgbGFiZWwgPSBsYWJlbCArIChtYXBwaW5nVmFsdWUuc291cmNlIHx8ICc8ZW1wdHk+Jyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAobWFwcGluZ1R5cGUgPT09ICdzb3VyY2VFeHByZXNzaW9uJykge1xyXG4gICAgICAgIGxhYmVsID0gbGFiZWwgKyAobWFwcGluZ1ZhbHVlLnNvdXJjZUV4cHJlc3Npb24gfHwgJzxlbXB0eT4nKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBsYWJlbCA9IGxhYmVsICsgJzxlbXB0eT4nO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBvcHRpb24udGV4dCA9IGxhYmVsO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgbmV3RWxlbWVudCA9IGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgdmFsdWUpIHtcclxuICAgICAgdmFyIG5ld0VsZW0gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQodHlwZSwgeyBzb3VyY2U6ICcnIH0sIGV4dGVuc2lvbkVsZW1lbnRzLCBicG1uRmFjdG9yeSk7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLmFkZEVsZW1lbnRzVG9saXN0KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCAndmFsdWVzJywgWyBuZXdFbGVtIF0pO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgcmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgdmFsdWUsIGlkeCkge1xyXG4gICAgICB2YXIgdmFyaWFibGVzTWFwcGluZ3M9IGdldFZhcmlhYmxlTWFwcGluZ3MoZWxlbWVudCwgdHlwZSk7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gdmFyaWFibGVzTWFwcGluZ3NbaWR4XTtcclxuXHJcbiAgICAgIGlmIChtYXBwaW5nKSB7XHJcbiAgICAgICAgcmV0dXJuIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyXHJcbiAgICAgICAgICAucmVtb3ZlRW50cnkoc2lnbmFsRXZlbnREZWZpbml0aW9uIHx8IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLCBlbGVtZW50LCBtYXBwaW5nKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICAvLyBpbiBtYXBwaW5nIGZvciBzb3VyY2UgYW5kIHNvdXJjZUV4cHJlc3Npb24gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIHZhciBpbkVudHJ5ID0gZXh0ZW5zaW9uRWxlbWVudHNFbnRyeShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgaWQ6ICd2YXJpYWJsZU1hcHBpbmctaW4nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSW4gTWFwcGluZycpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3NvdXJjZScsXHJcbiAgICBwcmVmaXg6ICdJbicsXHJcbiAgICBpZEdlbmVyYXRpb246IGZhbHNlLFxyXG4gICAgcmVzaXphYmxlOiB0cnVlLFxyXG4gICAgYnVzaW5lc3NPYmplY3Q6IHNpZ25hbEV2ZW50RGVmaW5pdGlvbiB8fCBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuXHJcbiAgICBjcmVhdGVFeHRlbnNpb25FbGVtZW50OiBuZXdFbGVtZW50KEFDVElWSVRJX0lOX0VYVEVOU0lPTl9FTEVNRU5UKSxcclxuICAgIHJlbW92ZUV4dGVuc2lvbkVsZW1lbnQ6IHJlbW92ZUVsZW1lbnQoQUNUSVZJVElfSU5fRVhURU5TSU9OX0VMRU1FTlQpLFxyXG5cclxuICAgIGdldEV4dGVuc2lvbkVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBnZXRWYXJpYWJsZU1hcHBpbmdzKGVsZW1lbnQsIEFDVElWSVRJX0lOX0VYVEVOU0lPTl9FTEVNRU5UKTtcclxuICAgIH0sXHJcblxyXG4gICAgb25TZWxlY3Rpb25DaGFuZ2U6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50LCBzY29wZSkge1xyXG4gICAgICBvdXRFbnRyeSAmJiBvdXRFbnRyeS5kZXNlbGVjdChlbGVtZW50LCBub2RlLnBhcmVudE5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKEFDVElWSVRJX0lOX0VYVEVOU0lPTl9FTEVNRU5UKVxyXG4gIH0pO1xyXG4gIGdyb3VwLmVudHJpZXMucHVzaChpbkVudHJ5KTtcclxuXHJcbiAgLy8gb3V0IG1hcHBpbmcgZm9yIHNvdXJjZSBhbmQgc291cmNlRXhwcmVzc2lvbiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIGlmICghc2lnbmFsRXZlbnREZWZpbml0aW9uKSB7XHJcbiAgICB2YXIgb3V0RW50cnkgPSBleHRlbnNpb25FbGVtZW50c0VudHJ5KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGlkOiAndmFyaWFibGVNYXBwaW5nLW91dCcsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ091dCBNYXBwaW5nJyksXHJcbiAgICAgIG1vZGVsUHJvcGVydHk6ICdzb3VyY2UnLFxyXG4gICAgICBwcmVmaXg6ICdPdXQnLFxyXG4gICAgICBpZEdlbmVyYXRpb246IGZhbHNlLFxyXG4gICAgICByZXNpemFibGU6IHRydWUsXHJcblxyXG4gICAgICBjcmVhdGVFeHRlbnNpb25FbGVtZW50OiBuZXdFbGVtZW50KEFDVElWSVRJX09VVF9FWFRFTlNJT05fRUxFTUVOVCksXHJcbiAgICAgIHJlbW92ZUV4dGVuc2lvbkVsZW1lbnQ6IHJlbW92ZUVsZW1lbnQoQUNUSVZJVElfT1VUX0VYVEVOU0lPTl9FTEVNRU5UKSxcclxuXHJcbiAgICAgIGdldEV4dGVuc2lvbkVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGdldFZhcmlhYmxlTWFwcGluZ3MoZWxlbWVudCwgQUNUSVZJVElfT1VUX0VYVEVOU0lPTl9FTEVNRU5UKTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIG9uU2VsZWN0aW9uQ2hhbmdlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBldmVudCwgc2NvcGUpIHtcclxuICAgICAgICBpbkVudHJ5LmRlc2VsZWN0KGVsZW1lbnQsIG5vZGUucGFyZW50Tm9kZSk7XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKEFDVElWSVRJX09VVF9FWFRFTlNJT05fRUxFTUVOVClcclxuICAgIH0pO1xyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKG91dEVudHJ5KTtcclxuICB9XHJcblxyXG4gIC8vIGxhYmVsIGZvciBzZWxlY3RlZCBtYXBwaW5nIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5sYWJlbCh7XHJcbiAgICBpZDogJ3ZhcmlhYmxlTWFwcGluZy10eXBlTGFiZWwnLFxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICB2YXIgdmFsdWUgPSAnJztcclxuICAgICAgaWYgKGlzKG1hcHBpbmcsIEFDVElWSVRJX0lOX0VYVEVOU0lPTl9FTEVNRU5UKSkge1xyXG4gICAgICAgIHZhbHVlID0gdHJhbnNsYXRlKCdJbiBNYXBwaW5nJyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAoaXMobWFwcGluZywgQUNUSVZJVElfT1VUX0VYVEVOU0lPTl9FTEVNRU5UKSkge1xyXG4gICAgICAgIHZhbHVlID0gdHJhbnNsYXRlKCdPdXQgTWFwcGluZycpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxhYmVsOiB2YWx1ZVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzaG93TGFiZWw6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6ICd2YXJpYWJsZU1hcHBpbmctaW5PdXRUeXBlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1R5cGUnKSxcclxuICAgIHNlbGVjdE9wdGlvbnM6IGluT3V0VHlwZU9wdGlvbnMsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnaW5PdXRUeXBlJyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgbWFwcGluZyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpIHx8IHt9O1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGluT3V0VHlwZTogZ2V0SW5PdXRUeXBlKG1hcHBpbmcpXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGluT3V0VHlwZSA9IHZhbHVlcy5pbk91dFR5cGU7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgJ3NvdXJjZScgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgJ3NvdXJjZUV4cHJlc3Npb24nIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICd2YXJpYWJsZXMnIDogdW5kZWZpbmVkXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpZiAoaW5PdXRUeXBlID09PSAnc291cmNlJykge1xyXG4gICAgICAgIHByb3BzLnNvdXJjZSA9ICcnO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKGluT3V0VHlwZSA9PT0gJ3NvdXJjZUV4cHJlc3Npb24nKSB7XHJcbiAgICAgICAgcHJvcHMuc291cmNlRXhwcmVzc2lvbiA9ICcnO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKGluT3V0VHlwZSA9PT0gJ3ZhcmlhYmxlcycpIHtcclxuICAgICAgICBwcm9wcy52YXJpYWJsZXMgPSAnYWxsJztcclxuICAgICAgICBwcm9wcy50YXJnZXQgPSB1bmRlZmluZWQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgbWFwcGluZywgcHJvcHMpO1xyXG4gICAgfSxcclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAndmFyaWFibGVNYXBwaW5nLXNvdXJjZScsXHJcbiAgICBkYXRhVmFsdWVMYWJlbDogJ3NvdXJjZUxhYmVsJyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdzb3VyY2UnLFxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSkgfHwge307XHJcblxyXG4gICAgICB2YXIgbGFiZWwgPSAnJztcclxuICAgICAgdmFyIGluT3V0VHlwZSA9IGdldEluT3V0VHlwZShtYXBwaW5nKTtcclxuICAgICAgaWYgKGluT3V0VHlwZSA9PT0gJ3NvdXJjZScpIHtcclxuICAgICAgICBsYWJlbCA9IHRyYW5zbGF0ZSgnU291cmNlJyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAoaW5PdXRUeXBlID09PSAnc291cmNlRXhwcmVzc2lvbicpIHtcclxuICAgICAgICBsYWJlbCA9IHRyYW5zbGF0ZSgnU291cmNlIEV4cHJlc3Npb24nKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBzb3VyY2U6IG1hcHBpbmdbaW5PdXRUeXBlXSxcclxuICAgICAgICBzb3VyY2VMYWJlbDogbGFiZWxcclxuICAgICAgfTtcclxuICAgIH0sXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YWx1ZXMuc291cmNlID0gdmFsdWVzLnNvdXJjZSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICB2YXIgbWFwcGluZyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB2YXIgaW5PdXRUeXBlID0gZ2V0SW5PdXRUeXBlKG1hcHBpbmcpO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW2luT3V0VHlwZV0gPSB2YWx1ZXMuc291cmNlIHx8ICcnO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBtYXBwaW5nLCBwcm9wcyk7XHJcbiAgICB9LFxyXG4gICAgLy8gb25lIG9mIGJvdGggKHNvdXJjZSBvciBzb3VyY2VFeHByZXNzaW9uKSBtdXN0IGhhdmUgYSB2YWx1ZSB0byBtYWtlXHJcbiAgICAvLyB0aGUgY29uZmlndXJhdGlvbiBlYXNpZXIgYW5kIG1vcmUgdW5kZXJzdGFuZGFibGVcclxuICAgIC8vIGl0IGlzIG5vdCBlbmdpbmUgY29uZm9ybVxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgbWFwcGluZyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIHZhbGlkYXRpb24gPSB7fTtcclxuICAgICAgaWYgKG1hcHBpbmcpIHtcclxuICAgICAgICBpZiAoIXZhbHVlcy5zb3VyY2UpIHtcclxuICAgICAgICAgIHZhbGlkYXRpb24uc291cmNlID1cclxuICAgICAgICAgIHZhbGlkYXRpb24uc291cmNlID0gdmFsdWVzLnNvdXJjZUxhYmVsID9cclxuICAgICAgICAgICAgdHJhbnNsYXRlKCdNYXBwaW5nIG11c3QgaGF2ZSBhIHt2YWx1ZX0nLCB7IHZhbHVlOiB2YWx1ZXMuc291cmNlTGFiZWwudG9Mb3dlckNhc2UoKSB9KSA6XHJcbiAgICAgICAgICAgIHRyYW5zbGF0ZSgnTWFwcGluZyBtdXN0IGhhdmUgYSB2YWx1ZScpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGluT3V0VHlwZSA9IGdldEluT3V0VHlwZShtYXBwaW5nKTtcclxuXHJcbiAgICAgICAgaWYgKFdISVRFU1BBQ0VfUkVHRVgudGVzdCh2YWx1ZXMuc291cmNlKSAmJiBpbk91dFR5cGUgIT09ICdzb3VyY2VFeHByZXNzaW9uJykge1xyXG4gICAgICAgICAgdmFsaWRhdGlvbi5zb3VyY2UgPSB0cmFuc2xhdGUoJ3tsYWJlbH0gbXVzdCBub3QgY29udGFpbiB3aGl0ZXNwYWNlJywgeyBsYWJlbDogdmFsdWVzLnNvdXJjZUxhYmVsIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbGlkYXRpb247XHJcbiAgICB9LFxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZE1hcHBpbmcgPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuICFzZWxlY3RlZE1hcHBpbmcgfHwgKHNlbGVjdGVkTWFwcGluZyAmJiBzZWxlY3RlZE1hcHBpbmcudmFyaWFibGVzKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ3ZhcmlhYmxlTWFwcGluZy10YXJnZXQnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGFyZ2V0JyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAndGFyZ2V0JyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHRhcmdldDogKGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpIHx8IHt9KS50YXJnZXRcclxuICAgICAgfTtcclxuICAgIH0sXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YWx1ZXMudGFyZ2V0ID0gdmFsdWVzLnRhcmdldCB8fCB1bmRlZmluZWQ7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgbWFwcGluZywgdmFsdWVzKTtcclxuICAgIH0sXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICB2YXIgdmFsaWRhdGlvbiA9IHt9O1xyXG4gICAgICBpZiAobWFwcGluZykge1xyXG4gICAgICAgIHZhciBtYXBwaW5nVHlwZSA9IGdldEluT3V0VHlwZShtYXBwaW5nKTtcclxuXHJcbiAgICAgICAgaWYgKCF2YWx1ZXMudGFyZ2V0ICYmIG1hcHBpbmdUeXBlICE9PSAndmFyaWFibGVzJykge1xyXG4gICAgICAgICAgdmFsaWRhdGlvbi50YXJnZXQgPSB0cmFuc2xhdGUoJ01hcHBpbmcgbXVzdCBoYXZlIGEgdGFyZ2V0Jyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodmFsdWVzLnRhcmdldFxyXG4gICAgICAgICAgJiYgV0hJVEVTUEFDRV9SRUdFWC50ZXN0KHZhbHVlcy50YXJnZXQpXHJcbiAgICAgICAgICAmJiBtYXBwaW5nVHlwZSAhPT0gJ3ZhcmlhYmxlcycpIHtcclxuICAgICAgICAgIHZhbGlkYXRpb24udGFyZ2V0ID0gdHJhbnNsYXRlKCdUYXJnZXQgbXVzdCBub3QgY29udGFpbiB3aGl0ZXNwYWNlJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdmFsaWRhdGlvbjtcclxuICAgIH0sXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIHNlbGVjdGVkTWFwcGluZyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gIXNlbGVjdGVkTWFwcGluZyB8fCAoc2VsZWN0ZWRNYXBwaW5nICYmIHNlbGVjdGVkTWFwcGluZy52YXJpYWJsZXMpO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkuY2hlY2tib3goe1xyXG4gICAgaWQ6ICd2YXJpYWJsZU1hcHBpbmctbG9jYWwnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnTG9jYWwnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdsb2NhbCcsXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBsb2NhbDogKGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpIHx8IHt9KS5sb2NhbFxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhbHVlcy5sb2NhbCA9IHZhbHVlcy5sb2NhbCB8fCBmYWxzZTtcclxuICAgICAgdmFyIG1hcHBpbmcgPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBtYXBwaW5nLCB2YWx1ZXMpO1xyXG4gICAgfSxcclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSAmJiBiby5nZXQoJ3Byb2Nlc3NSZWYnKSkge1xyXG4gICAgdmFyIHZlcnNpb25UYWdFbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgICBpZDogJ3ZlcnNpb25UYWcnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdWZXJzaW9uIFRhZycpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5OiAndmVyc2lvblRhZydcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIGluIHBhcnRpY2lwYW50cyB3ZSBoYXZlIHRvIGNoYW5nZSB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiBzZXQgYW5kIGdldFxyXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuICAgICAgdmVyc2lvblRhZ0VudHJ5LmdldCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgcHJvY2Vzc0JvID0gYm8uZ2V0KCdwcm9jZXNzUmVmJyk7XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICB2ZXJzaW9uVGFnOiBwcm9jZXNzQm8uZ2V0KCdhY3Rpdml0aTp2ZXJzaW9uVGFnJylcclxuICAgICAgICB9O1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmVyc2lvblRhZ0VudHJ5LnNldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICAgIHZhciBwcm9jZXNzQm8gPSBiby5nZXQoJ3Byb2Nlc3NSZWYnKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBwcm9jZXNzQm8sIHtcclxuICAgICAgICAgICdhY3Rpdml0aTp2ZXJzaW9uVGFnJzogdmFsdWVzLnZlcnNpb25UYWcgfHwgdW5kZWZpbmVkXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKHZlcnNpb25UYWdFbnRyeSk7XHJcblxyXG4gIH1cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJ2xvZGFzaC9hc3NpZ24nKTtcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGFzeW5jQ2FwYWJsZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9Bc3luY0NhcGFibGVIZWxwZXInKSxcclxuICAgIGV2ZW50RGVmaW5pdGlvbkhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FdmVudERlZmluaXRpb25IZWxwZXInKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbmZ1bmN0aW9uIGlzQXN5bmNCZWZvcmUoYm8pIHtcclxuICByZXR1cm4gYXN5bmNDYXBhYmxlSGVscGVyLmlzQXN5bmNCZWZvcmUoYm8pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0FzeW5jQWZ0ZXIoYm8pIHtcclxuICByZXR1cm4gYXN5bmNDYXBhYmxlSGVscGVyLmlzQXN5bmNBZnRlcihibyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzRXhjbHVzaXZlKGJvKSB7XHJcbiAgcmV0dXJuIGFzeW5jQ2FwYWJsZUhlbHBlci5pc0V4Y2x1c2l2ZShibyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGJvLCBlbGVtZW50KSB7XHJcbiAgcmV0dXJuIGFzeW5jQ2FwYWJsZUhlbHBlci5yZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibywgZWxlbWVudCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNhblJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gIWV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRUaW1lckV2ZW50RGVmaW5pdGlvbihlbGVtZW50KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBnZXRCdXNpbmVzc09iamVjdCA9IG9wdGlvbnMuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG4gIHZhciBpZFByZWZpeCA9IG9wdGlvbnMuaWRQcmVmaXggfHwgJycsXHJcbiAgICAgIGxhYmVsUHJlZml4ID0gb3B0aW9ucy5sYWJlbFByZWZpeCB8fCAnJztcclxuXHJcblxyXG4gIHZhciBhc3luY0JlZm9yZUVudHJ5ID0gZW50cnlGYWN0b3J5LmNoZWNrYm94KHtcclxuICAgIGlkOiBpZFByZWZpeCArICdhc3luY0JlZm9yZScsXHJcbiAgICBsYWJlbDogbGFiZWxQcmVmaXggKyB0cmFuc2xhdGUoJ0FzeW5jaHJvbm91cyBCZWZvcmUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdhc3luY0JlZm9yZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGFzeW5jQmVmb3JlOiBpc0FzeW5jQmVmb3JlKGJvKVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIGFzeW5jQmVmb3JlID0gISF2YWx1ZXMuYXN5bmNCZWZvcmU7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOmFzeW5jQmVmb3JlJzogYXN5bmNCZWZvcmUsXHJcbiAgICAgICAgJ2FjdGl2aXRpOmFzeW5jJzogZmFsc2VcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdO1xyXG4gICAgICBpZiAoIWlzQXN5bmNBZnRlcihibykgJiYgIWFzeW5jQmVmb3JlKSB7XHJcbiAgICAgICAgcHJvcHMgPSBhc3NpZ24oeyAnYWN0aXZpdGk6ZXhjbHVzaXZlJyA6IHRydWUgfSwgcHJvcHMpO1xyXG4gICAgICAgIGlmIChjYW5SZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShlbGVtZW50KSkge1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChyZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibywgZWxlbWVudCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHByb3BzKSk7XHJcbiAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgIH1cclxuICB9KTtcclxuXHJcblxyXG4gIHZhciBhc3luY0FmdGVyRW50cnkgPSBlbnRyeUZhY3RvcnkuY2hlY2tib3goe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ2FzeW5jQWZ0ZXInLFxyXG4gICAgbGFiZWw6IGxhYmVsUHJlZml4ICsgdHJhbnNsYXRlKCdBc3luY2hyb25vdXMgQWZ0ZXInKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdhc3luY0FmdGVyJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgYXN5bmNBZnRlcjogaXNBc3luY0FmdGVyKGJvKVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIGFzeW5jQWZ0ZXIgPSAhIXZhbHVlcy5hc3luY0FmdGVyO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge1xyXG4gICAgICAgICdhY3Rpdml0aTphc3luY0FmdGVyJzogYXN5bmNBZnRlclxyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcbiAgICAgIGlmICghaXNBc3luY0JlZm9yZShibykgJiYgIWFzeW5jQWZ0ZXIpIHtcclxuICAgICAgICBwcm9wcyA9IGFzc2lnbih7ICdhY3Rpdml0aTpleGNsdXNpdmUnIDogdHJ1ZSB9LCBwcm9wcyk7XHJcbiAgICAgICAgaWYgKGNhblJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGVsZW1lbnQpKSB7XHJcbiAgICAgICAgICBjb21tYW5kcy5wdXNoKHJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGJvLCBlbGVtZW50KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBibywgcHJvcHMpKTtcclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgdmFyIGV4Y2x1c2l2ZUVudHJ5ID0gZW50cnlGYWN0b3J5LmNoZWNrYm94KHtcclxuICAgIGlkOiBpZFByZWZpeCArICdleGNsdXNpdmUnLFxyXG4gICAgbGFiZWw6IGxhYmVsUHJlZml4ICsgdHJhbnNsYXRlKCdFeGNsdXNpdmUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdleGNsdXNpdmUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgcmV0dXJuIHsgZXhjbHVzaXZlOiBpc0V4Y2x1c2l2ZShibykgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgJ2FjdGl2aXRpOmV4Y2x1c2l2ZSc6ICEhdmFsdWVzLmV4Y2x1c2l2ZSB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gYm8gJiYgIWlzQXN5bmNBZnRlcihibykgJiYgIWlzQXN5bmNCZWZvcmUoYm8pO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gWyBhc3luY0JlZm9yZUVudHJ5LCBhc3luY0FmdGVyRW50cnksIGV4Y2x1c2l2ZUVudHJ5IF07XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyksXHJcbiAgICBleHRlbnNpb25FbGVtZW50c0hlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpO1xyXG5cclxuXHJcbnZhciByZXN1bHRWYXJpYWJsZSA9IHJlcXVpcmUoJy4vUmVzdWx0VmFyaWFibGUnKTtcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XHJcblxyXG52YXIgYXR0cmlidXRlSW5mbyA9IHtcclxuICBicG1uOiB7XHJcbiAgICBlbGVtZW50OiAnY2FsbGVkRWxlbWVudCcsXHJcbiAgICBiaW5kaW5nOiAnYWN0aXZpdGk6Y2FsbGVkRWxlbWVudEJpbmRpbmcnLFxyXG4gICAgdmVyc2lvbjogJ2FjdGl2aXRpOmNhbGxlZEVsZW1lbnRWZXJzaW9uJyxcclxuICAgIHZlcnNpb25UYWc6ICdhY3Rpdml0aTpjYWxsZWRFbGVtZW50VmVyc2lvblRhZycsXHJcbiAgICB0ZW5hbnRJZDogJ2FjdGl2aXRpOmNhbGxlZEVsZW1lbnRUZW5hbnRJZCdcclxuICB9LFxyXG5cclxuICBjbW1uOiB7XHJcbiAgICBlbGVtZW50OiAnYWN0aXZpdGk6Y2FzZVJlZicsXHJcbiAgICBiaW5kaW5nOiAnYWN0aXZpdGk6Y2FzZUJpbmRpbmcnLFxyXG4gICAgdmVyc2lvbjogJ2FjdGl2aXRpOmNhc2VWZXJzaW9uJyxcclxuICAgIHRlbmFudElkOiAnYWN0aXZpdGk6Y2FzZVRlbmFudElkJ1xyXG4gIH0sXHJcblxyXG4gIGRtbjoge1xyXG4gICAgZWxlbWVudDogJ2FjdGl2aXRpOmRlY2lzaW9uUmVmJyxcclxuICAgIGJpbmRpbmc6ICdhY3Rpdml0aTpkZWNpc2lvblJlZkJpbmRpbmcnLFxyXG4gICAgdmVyc2lvbjogJ2FjdGl2aXRpOmRlY2lzaW9uUmVmVmVyc2lvbicsXHJcbiAgICB2ZXJzaW9uVGFnOiAnYWN0aXZpdGk6ZGVjaXNpb25SZWZWZXJzaW9uVGFnJyxcclxuICAgIHRlbmFudElkOiAnYWN0aXZpdGk6ZGVjaXNpb25SZWZUZW5hbnRJZCdcclxuICB9XHJcbn07XHJcblxyXG52YXIgbWFwRGVjaXNpb25SZXN1bHRPcHRpb25zID0gW1xyXG4gIHtcclxuICAgIG5hbWU6ICdzaW5nbGVFbnRyeSAoVHlwZWRWYWx1ZSknLFxyXG4gICAgdmFsdWU6ICdzaW5nbGVFbnRyeSdcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6J3NpbmdsZVJlc3VsdCAoTWFwPFN0cmluZywgT2JqZWN0PiknLFxyXG4gICAgdmFsdWU6J3NpbmdsZVJlc3VsdCdcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6J2NvbGxlY3RFbnRyaWVzIChMaXN0PE9iamVjdD4pJyxcclxuICAgIHZhbHVlOidjb2xsZWN0RW50cmllcydcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6J3Jlc3VsdExpc3QgKExpc3Q8TWFwPFN0cmluZywgT2JqZWN0Pj4pJyxcclxuICAgIHZhbHVlOidyZXN1bHRMaXN0J1xyXG4gIH1cclxuXTtcclxuXHJcbnZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ09wdGlvbnMgPSBbXHJcbiAge1xyXG4gICAgbmFtZTogJ3ZhcmlhYmxlTWFwcGluZ0NsYXNzJyxcclxuICAgIHZhbHVlOiAndmFyaWFibGVNYXBwaW5nQ2xhc3MnXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiAndmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJyxcclxuICAgIHZhbHVlOiAndmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJ1xyXG4gIH1cclxuXTtcclxuXHJcbmZ1bmN0aW9uIGdldEFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkoZWxlbWVudCkge1xyXG4gIHZhciBhY3Rpdml0aUluID0gW10sXHJcbiAgICAgIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBhY3Rpdml0aUluUGFyYW1zID0gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpJbicpO1xyXG4gIGlmIChhY3Rpdml0aUluUGFyYW1zKSB7XHJcbiAgICBmb3JFYWNoKGFjdGl2aXRpSW5QYXJhbXMsIGZ1bmN0aW9uKHBhcmFtKSB7XHJcbiAgICAgIGlmIChwYXJhbS5idXNpbmVzc0tleSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgYWN0aXZpdGlJbi5wdXNoKHBhcmFtKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIHJldHVybiBhY3Rpdml0aUluO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRCdXNpbmVzc0tleShlbGVtZW50LCB0ZXh0LCBicG1uRmFjdG9yeSkge1xyXG4gIHZhciBjb21tYW5kcyA9IFtdO1xyXG5cclxuICB2YXIgYWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleSA9IGdldEFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkoZWxlbWVudCk7XHJcblxyXG4gIGlmIChhY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5Lmxlbmd0aCkge1xyXG4gICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleVswXSwge1xyXG4gICAgICBidXNpbmVzc0tleTogdGV4dFxyXG4gICAgfSkpO1xyXG4gIH0gZWxzZSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICBleHRlbnNpb25FbGVtZW50cyA9IGJvLmV4dGVuc2lvbkVsZW1lbnRzO1xyXG5cclxuICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnLCB7IHZhbHVlczogW10gfSwgYm8sIGJwbW5GYWN0b3J5KTtcclxuICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCB7IGV4dGVuc2lvbkVsZW1lbnRzOiBleHRlbnNpb25FbGVtZW50cyB9KSk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGFjdGl2aXRpSW4gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoXHJcbiAgICAgICdhY3Rpdml0aTpJbicsXHJcbiAgICAgIHsgJ2J1c2luZXNzS2V5JzogdGV4dCB9LFxyXG4gICAgICBleHRlbnNpb25FbGVtZW50cyxcclxuICAgICAgYnBtbkZhY3RvcnlcclxuICAgICk7XHJcblxyXG4gICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgZWxlbWVudCxcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICBbIGFjdGl2aXRpSW4gXSxbXVxyXG4gICAgKSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gY29tbWFuZHM7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRlbGV0ZUJ1c2luZXNzS2V5KGVsZW1lbnQpIHtcclxuICB2YXIgYWN0aXZpdGlJbkV4dGVuc2lvbnMgPSBnZXRBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5KGVsZW1lbnQpO1xyXG4gIHZhciBjb21tYW5kcyA9IFtdO1xyXG4gIGZvckVhY2goYWN0aXZpdGlJbkV4dGVuc2lvbnMsIGZ1bmN0aW9uKGVsZW0pIHtcclxuICAgIGNvbW1hbmRzLnB1c2goZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksIGVsZW1lbnQsIGVsZW0pKTtcclxuICB9KTtcclxuICByZXR1cm4gY29tbWFuZHM7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKHR5cGUpIHtcclxuICByZXR1cm4gWyAnYnBtbicsICdjbW1uJywgJ2RtbicgXS5pbmRleE9mKHR5cGUpICE9PSAtMTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBiaW5kaW5nT3B0aW9ucyA9IFtcclxuICAgIHtcclxuICAgICAgbmFtZTogdHJhbnNsYXRlKCdsYXRlc3QnKSxcclxuICAgICAgdmFsdWU6ICdsYXRlc3QnXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiB0cmFuc2xhdGUoJ2RlcGxveW1lbnQnKSxcclxuICAgICAgdmFsdWU6ICdkZXBsb3ltZW50J1xyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogdHJhbnNsYXRlKCd2ZXJzaW9uJyksXHJcbiAgICAgIHZhbHVlOiAndmVyc2lvbidcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6IHRyYW5zbGF0ZSgndmVyc2lvblRhZycpLFxyXG4gICAgICB2YWx1ZTogJ3ZlcnNpb25UYWcnXHJcbiAgICB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIGdldENhbGxhYmxlVHlwZSA9IG9wdGlvbnMuZ2V0Q2FsbGFibGVUeXBlO1xyXG5cclxuICB2YXIgZW50cmllcyA9IFtdO1xyXG5cclxuICBmdW5jdGlvbiBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgcHJvcCkge1xyXG4gICAgdmFyIHR5cGUgPSBnZXRDYWxsYWJsZVR5cGUoZWxlbWVudCk7XHJcbiAgICByZXR1cm4gKGF0dHJpYnV0ZUluZm9bdHlwZV0gfHwge30pW3Byb3BdO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0Q2FsbEFjdGl2aXR5QmluZGluZ1ZhbHVlKGVsZW1lbnQpIHtcclxuICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICB2YXIgYXR0ciA9IChhdHRyaWJ1dGVJbmZvW3R5cGVdIHx8IHt9KS5iaW5kaW5nO1xyXG4gICAgcmV0dXJuIGJvLmdldChhdHRyKTtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIGdldERlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZShlbGVtZW50KSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICB2YXIgYm9WYXJpYWJsZU1hcHBpbmdDbGFzcyA9IGJvLmdldCgnYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nQ2xhc3MnKSxcclxuICAgICAgICBib1ZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbiA9IGJvLmdldCgnYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJyk7XHJcblxyXG4gICAgdmFyIGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZSA9ICcnO1xyXG4gICAgaWYgKHR5cGVvZiBib1ZhcmlhYmxlTWFwcGluZ0NsYXNzICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUgPSAndmFyaWFibGVNYXBwaW5nQ2xhc3MnO1xyXG4gICAgfSBlbHNlXHJcblxyXG4gICAgaWYgKHR5cGVvZiBib1ZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlID0gJ3ZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbic7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZTtcclxuICB9XHJcblxyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ2NhbGxhYmxlLWVsZW1lbnQtcmVmJyxcclxuICAgIGRhdGFWYWx1ZUxhYmVsOiAnY2FsbGFibGVFbGVtZW50TGFiZWwnLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2NhbGxhYmxlRWxlbWVudFJlZicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBjYWxsYWJsZUVsZW1lbnRSZWY7XHJcblxyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAnZWxlbWVudCcpO1xyXG4gICAgICBpZiAoYXR0cikge1xyXG4gICAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICAgIGNhbGxhYmxlRWxlbWVudFJlZiA9IGJvLmdldChhdHRyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGxhYmVsID0gJyc7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgICBpZiAodHlwZSA9PT0gJ2JwbW4nKSB7XHJcbiAgICAgICAgbGFiZWwgPSB0cmFuc2xhdGUoJ0NhbGxlZCBFbGVtZW50Jyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ2NtbW4nKSB7XHJcbiAgICAgICAgbGFiZWwgPSB0cmFuc2xhdGUoJ0Nhc2UgUmVmJyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ2RtbicpIHtcclxuICAgICAgICBsYWJlbCA9IHRyYW5zbGF0ZSgnRGVjaXNpb24gUmVmJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgY2FsbGFibGVFbGVtZW50UmVmOiBjYWxsYWJsZUVsZW1lbnRSZWYsXHJcbiAgICAgICAgY2FsbGFibGVFbGVtZW50TGFiZWw6IGxhYmVsXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBuZXdDYWxsYWJsZUVsZW1lbnRSZWYgPSB2YWx1ZXMuY2FsbGFibGVFbGVtZW50UmVmO1xyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAnZWxlbWVudCcpO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW2F0dHJdID0gbmV3Q2FsbGFibGVFbGVtZW50UmVmIHx8ICcnO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgZWxlbWVudFJlZiA9IHZhbHVlcy5jYWxsYWJsZUVsZW1lbnRSZWY7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gaXNTdXBwb3J0ZWRDYWxsYWJsZVR5cGUodHlwZSkgJiYgIWVsZW1lbnRSZWYgPyB7IGNhbGxhYmxlRWxlbWVudFJlZjogdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpIH0gOiB7fTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhaXNTdXBwb3J0ZWRDYWxsYWJsZVR5cGUoZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpKTtcclxuICAgIH1cclxuXHJcbiAgfSkpO1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnNlbGVjdEJveCh7XHJcbiAgICBpZDogJ2NhbGxhYmxlLWJpbmRpbmcnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQmluZGluZycpLFxyXG4gICAgc2VsZWN0T3B0aW9uczogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICB2YXIgdHlwZSA9IGdldENhbGxhYmxlVHlwZShlbGVtZW50KTtcclxuICAgICAgdmFyIG9wdGlvbnM7XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ2NtbW4nKSB7XHJcbiAgICAgICAgb3B0aW9ucyA9IGJpbmRpbmdPcHRpb25zLmZpbHRlcihmdW5jdGlvbihiaW5kaW5nT3B0aW9uKSB7XHJcbiAgICAgICAgICByZXR1cm4gYmluZGluZ09wdGlvbi52YWx1ZSAhPT0gJ3ZlcnNpb25UYWcnO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG9wdGlvbnMgPSBiaW5kaW5nT3B0aW9ucztcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gb3B0aW9ucztcclxuICAgIH0sXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY2FsbGFibGVCaW5kaW5nJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGNhbGxhYmxlQmluZGluZztcclxuXHJcbiAgICAgIHZhciBhdHRyID0gZ2V0QXR0cmlidXRlKGVsZW1lbnQsICdiaW5kaW5nJyk7XHJcbiAgICAgIGlmIChhdHRyKSB7XHJcbiAgICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgICAgY2FsbGFibGVCaW5kaW5nID0gYm8uZ2V0KGF0dHIpIHx8ICdsYXRlc3QnO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGNhbGxhYmxlQmluZGluZzogY2FsbGFibGVCaW5kaW5nXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBiaW5kaW5nID0gdmFsdWVzLmNhbGxhYmxlQmluZGluZztcclxuICAgICAgdmFyIGF0dHIgPSBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgJ2JpbmRpbmcnKSxcclxuICAgICAgICAgIGF0dHJWZXIgPSBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgJ3ZlcnNpb24nKSxcclxuICAgICAgICAgIGF0dHJWZXJUYWcgPSBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgJ3ZlcnNpb25UYWcnKTtcclxuXHJcbiAgICAgIHZhciBwcm9wcyA9IHt9O1xyXG4gICAgICBwcm9wc1thdHRyXSA9IGJpbmRpbmc7XHJcblxyXG4gICAgICAvLyBzZXQgdmVyc2lvbiBhbmQgdmVyc2lvblRhZyB2YWx1ZXMgYWx3YXlzIHRvIHVuZGVmaW5lZCB0byBkZWxldGUgdGhlIGV4aXN0aW5nIHZhbHVlXHJcbiAgICAgIHByb3BzW2F0dHJWZXJdID0gdW5kZWZpbmVkO1xyXG4gICAgICBwcm9wc1thdHRyVmVyVGFnXSA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBwcm9wcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKGdldENhbGxhYmxlVHlwZShlbGVtZW50KSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdjYWxsYWJsZS12ZXJzaW9uJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1ZlcnNpb24nKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdjYWxsYWJsZVZlcnNpb24nLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgY2FsbGFibGVWZXJzaW9uO1xyXG5cclxuICAgICAgdmFyIGF0dHIgPSBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgJ3ZlcnNpb24nKTtcclxuICAgICAgaWYgKGF0dHIpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgICBjYWxsYWJsZVZlcnNpb24gPSBiby5nZXQoYXR0cik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgY2FsbGFibGVWZXJzaW9uOiBjYWxsYWJsZVZlcnNpb25cclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIHZlcnNpb24gPSB2YWx1ZXMuY2FsbGFibGVWZXJzaW9uO1xyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndmVyc2lvbicpO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW2F0dHJdID0gdmVyc2lvbiB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcHJvcHMpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciB2ZXJzaW9uID0gdmFsdWVzLmNhbGxhYmxlVmVyc2lvbjtcclxuXHJcbiAgICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIGlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKHR5cGUpICYmXHJcbiAgICAgICAgZ2V0Q2FsbEFjdGl2aXR5QmluZGluZ1ZhbHVlKGVsZW1lbnQpID09PSAndmVyc2lvbicgJiYgKFxyXG4gICAgICAgICAgIXZlcnNpb24gPyB7IGNhbGxhYmxlVmVyc2lvbjogdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpIH0gOiB7fVxyXG4gICAgICAgIClcclxuICAgICAgKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gIWlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKHR5cGUpIHx8IGdldENhbGxBY3Rpdml0eUJpbmRpbmdWYWx1ZShlbGVtZW50KSAhPT0gJ3ZlcnNpb24nO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnY2FsbGFibGUtdmVyc2lvbi10YWcnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVmVyc2lvbiBUYWcnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICd2ZXJzaW9uVGFnJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIHZlcnNpb25UYWc7XHJcblxyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndmVyc2lvblRhZycpO1xyXG5cclxuICAgICAgaWYgKGF0dHIpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgdmVyc2lvblRhZyA9IGJvLmdldChhdHRyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB2ZXJzaW9uVGFnOiB2ZXJzaW9uVGFnXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciB2ZXJzaW9uVGFnID0gdmFsdWVzLnZlcnNpb25UYWc7XHJcblxyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndmVyc2lvblRhZycpO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcblxyXG4gICAgICBwcm9wc1thdHRyXSA9IHZlcnNpb25UYWcgfHwgdW5kZWZpbmVkO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgdmVyc2lvblRhZyA9IHZhbHVlcy52ZXJzaW9uVGFnO1xyXG5cclxuICAgICAgdmFyIHR5cGUgPSBnZXRDYWxsYWJsZVR5cGUoZWxlbWVudCk7XHJcblxyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIGlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKHR5cGUpICYmXHJcbiAgICAgICAgZ2V0Q2FsbEFjdGl2aXR5QmluZGluZ1ZhbHVlKGVsZW1lbnQpID09PSAndmVyc2lvblRhZycgJiYgKFxyXG4gICAgICAgICAgIXZlcnNpb25UYWcgPyB7IHZlcnNpb25UYWc6IHRyYW5zbGF0ZSgnTXVzdCBwcm92aWRlIGEgdmFsdWUnKSB9IDoge31cclxuICAgICAgICApXHJcbiAgICAgICk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgdHlwZSA9IGdldENhbGxhYmxlVHlwZShlbGVtZW50KTtcclxuXHJcbiAgICAgIHJldHVybiAhaXNTdXBwb3J0ZWRDYWxsYWJsZVR5cGUodHlwZSkgfHwgZ2V0Q2FsbEFjdGl2aXR5QmluZGluZ1ZhbHVlKGVsZW1lbnQpICE9PSAndmVyc2lvblRhZyc7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICd0ZW5hbnQtaWQnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGVuYW50IElkJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAndGVuYW50SWQnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgdGVuYW50SWQ7XHJcblxyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndGVuYW50SWQnKTtcclxuICAgICAgaWYgKGF0dHIpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgICB0ZW5hbnRJZCA9IGJvLmdldChhdHRyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB0ZW5hbnRJZDogdGVuYW50SWRcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIHRlbmFudElkID0gdmFsdWVzLnRlbmFudElkO1xyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndGVuYW50SWQnKTtcclxuXHJcbiAgICAgIHZhciBwcm9wcyA9IHt9O1xyXG4gICAgICBwcm9wc1thdHRyXSA9IHRlbmFudElkIHx8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBwcm9wcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgdHlwZSA9IGdldENhbGxhYmxlVHlwZShlbGVtZW50KTtcclxuICAgICAgcmV0dXJuICFpc1N1cHBvcnRlZENhbGxhYmxlVHlwZSh0eXBlKTtcclxuICAgIH1cclxuXHJcbiAgfSkpO1xyXG5cclxuICBpZiAoaXMoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksICdicG1uOkNhbGxBY3Rpdml0eScpKSB7XHJcbiAgICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmNoZWNrYm94KHtcclxuICAgICAgaWQ6ICdjYWxsYWJsZS1idXNpbmVzcy1rZXknLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdCdXNpbmVzcyBLZXknKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eTogJ2NhbGxhYmxlQnVzaW5lc3NLZXknLFxyXG5cclxuICAgICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgICAgdmFyIGFjdGl2aXRpSW4gPSBnZXRBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5KGVsZW1lbnQpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgY2FsbGFibGVCdXNpbmVzc0tleTogISEoYWN0aXZpdGlJbiAmJiBhY3Rpdml0aUluLmxlbmd0aCA+IDApXHJcbiAgICAgICAgfTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlcy5jYWxsYWJsZUJ1c2luZXNzS2V5KSB7XHJcbiAgICAgICAgICByZXR1cm4gc2V0QnVzaW5lc3NLZXkoZWxlbWVudCwgJyN7ZXhlY3V0aW9uLnByb2Nlc3NCdXNpbmVzc0tleX0nLCBicG1uRmFjdG9yeSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHJldHVybiBkZWxldGVCdXNpbmVzc0tleShlbGVtZW50KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pKTtcclxuICB9XHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnYnVzaW5lc3Mta2V5LWV4cHJlc3Npb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQnVzaW5lc3MgS2V5IEV4cHJlc3Npb24nKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdidXNpbmVzc0tleScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBhY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5ID0gZ2V0QWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleShlbGVtZW50KTtcclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgYnVzaW5lc3NLZXk6IChcclxuICAgICAgICAgIGFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkubGVuZ3RoID9cclxuICAgICAgICAgICAgYWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleVswXS5nZXQoJ2FjdGl2aXRpOmJ1c2luZXNzS2V5JykgOlxyXG4gICAgICAgICAgICB1bmRlZmluZWRcclxuICAgICAgICApXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBidXNpbmVzc0tleSA9IHZhbHVlcy5idXNpbmVzc0tleTtcclxuXHJcbiAgICAgIHJldHVybiBzZXRCdXNpbmVzc0tleShlbGVtZW50LCBidXNpbmVzc0tleSwgYnBtbkZhY3RvcnkpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBidXNpbmVzc0tleSA9IHZhbHVlcy5idXNpbmVzc0tleTtcclxuXHJcbiAgICAgIHJldHVybiBidXNpbmVzc0tleSA9PT0gJycgPyB7IGJ1c2luZXNzS2V5OiB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJykgfSA6IHt9O1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICFnZXRBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5KGVsZW1lbnQpLmxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgfSkpO1xyXG5cclxuICBlbnRyaWVzID0gZW50cmllcy5jb25jYXQocmVzdWx0VmFyaWFibGUoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkOiAnZG1uLXJlc3VsdFZhcmlhYmxlJyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0OiBnZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGdldEltcGxlbWVudGF0aW9uVHlwZTogZ2V0Q2FsbGFibGVUeXBlLFxyXG4gICAgaGlkZVJlc3VsdFZhcmlhYmxlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBnZXRDYWxsYWJsZVR5cGUoZWxlbWVudCkgIT09ICdkbW4nO1xyXG4gICAgfVxyXG4gIH0sIHRyYW5zbGF0ZSkpO1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnNlbGVjdEJveCh7XHJcbiAgICBpZDogJ2Rtbi1tYXAtZGVjaXNpb24tcmVzdWx0JyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ01hcCBEZWNpc2lvbiBSZXN1bHQnKSxcclxuICAgIHNlbGVjdE9wdGlvbnM6IG1hcERlY2lzaW9uUmVzdWx0T3B0aW9ucyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdtYXBEZWNpc2lvblJlc3VsdCcsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIG1hcERlY2lzaW9uUmVzdWx0OiBiby5nZXQoJ2FjdGl2aXRpOm1hcERlY2lzaW9uUmVzdWx0JykgfHwgJ3Jlc3VsdExpc3QnXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOm1hcERlY2lzaW9uUmVzdWx0JzogdmFsdWVzLm1hcERlY2lzaW9uUmVzdWx0IHx8ICdyZXN1bHRMaXN0J1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICB2YXIgcmVzdWx0VmFyaWFibGUgPSBiby5nZXQoJ2FjdGl2aXRpOnJlc3VsdFZhcmlhYmxlJyk7XHJcbiAgICAgIHJldHVybiAhKGdldENhbGxhYmxlVHlwZShlbGVtZW50KSA9PT0gJ2RtbicgJiYgdHlwZW9mIHJlc3VsdFZhcmlhYmxlICE9PSAndW5kZWZpbmVkJyk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3Rvcnkuc2VsZWN0Qm94KHtcclxuICAgIGlkOiAnZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0RlbGVnYXRlIFZhcmlhYmxlIE1hcHBpbmcnKSxcclxuICAgIHNlbGVjdE9wdGlvbnM6IGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nT3B0aW9ucyxcclxuICAgIGVtcHR5UGFyYW1ldGVyOiB0cnVlLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2RlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlIDogZ2V0RGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlKGVsZW1lbnQpXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUgPSB2YWx1ZXMuZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge1xyXG4gICAgICAgICdhY3Rpdml0aTp2YXJpYWJsZU1hcHBpbmdDbGFzcycgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgJ2FjdGl2aXRpOnZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbicgOiB1bmRlZmluZWRcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlmIChkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUgPT09ICd2YXJpYWJsZU1hcHBpbmdDbGFzcycpIHtcclxuICAgICAgICBwcm9wc1snYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nQ2xhc3MnXSA9ICcnO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZSA9PT0gJ3ZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbicpIHtcclxuICAgICAgICBwcm9wc1snYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJ10gPSAnJztcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAoZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpICE9PSAnYnBtbicpO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmcnLFxyXG4gICAgZGF0YVZhbHVlTGFiZWw6ICdkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ0xhYmVsJyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZycsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgdmFyIGxhYmVsID0gJyc7XHJcbiAgICAgIHZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyA9IHVuZGVmaW5lZDtcclxuICAgICAgdmFyIHR5cGUgPSBnZXREZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUoZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ3ZhcmlhYmxlTWFwcGluZ0NsYXNzJykge1xyXG4gICAgICAgIGxhYmVsID0gdHJhbnNsYXRlKCdDbGFzcycpO1xyXG4gICAgICAgIGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nID0gYm8uZ2V0KCdhY3Rpdml0aTp2YXJpYWJsZU1hcHBpbmdDbGFzcycpO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICd2YXJpYWJsZU1hcHBpbmdEZWxlZ2F0ZUV4cHJlc3Npb24nKSB7XHJcbiAgICAgICAgbGFiZWwgPSB0cmFuc2xhdGUoJ0RlbGVnYXRlIEV4cHJlc3Npb24nKTtcclxuICAgICAgICBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyA9IGJvLmdldCgnYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmc6IGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nLFxyXG4gICAgICAgIGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nTGFiZWw6IGxhYmVsXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyA9IHZhbHVlcy5kZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZztcclxuXHJcbiAgICAgIHZhciBhdHRyID0gJ2FjdGl2aXRpOicgKyBnZXREZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUoZWxlbWVudCk7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSB7fTtcclxuICAgICAgcHJvcHNbYXR0cl0gPSBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcHJvcHMpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyA9IHZhbHVlcy5kZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZztcclxuICAgICAgcmV0dXJuIChcclxuICAgICAgICBnZXRDYWxsYWJsZVR5cGUoZWxlbWVudCkgPT09ICdicG1uJyAmJiAoXHJcbiAgICAgICAgICAhZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmcgPyB7IGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nOiB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJykgfSA6IHt9XHJcbiAgICAgICAgKVxyXG4gICAgICApO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICEoZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpID09PSAnYnBtbicgJiYgZ2V0RGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlKGVsZW1lbnQpICE9PSAnJyk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICB2YXIgY2FuZGlkYXRlU3RhcnRlckdyb3Vwc0VudHJ5ID0gZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ2NhbmRpZGF0ZVN0YXJ0ZXJHcm91cHMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ2FuZGlkYXRlIFN0YXJ0ZXIgR3JvdXBzJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY2FuZGlkYXRlU3RhcnRlckdyb3VwcycsXHJcbiAgICBkZXNjcmlwdGlvbjogdHJhbnNsYXRlKCdTcGVjaWZ5IG1vcmUgdGhhbiBvbmUgZ3JvdXAgYXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdC4nKSxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHZhciBjYW5kaWRhdGVTdGFydGVyR3JvdXBzID0gYm8uZ2V0KCdhY3Rpdml0aTpjYW5kaWRhdGVTdGFydGVyR3JvdXBzJyk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGNhbmRpZGF0ZVN0YXJ0ZXJHcm91cHM6IGNhbmRpZGF0ZVN0YXJ0ZXJHcm91cHMgPyBjYW5kaWRhdGVTdGFydGVyR3JvdXBzIDogJydcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHtcclxuICAgICAgICAnYWN0aXZpdGk6Y2FuZGlkYXRlU3RhcnRlckdyb3Vwcyc6IHZhbHVlcy5jYW5kaWRhdGVTdGFydGVyR3JvdXBzIHx8IHVuZGVmaW5lZFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHZhciBjYW5kaWRhdGVTdGFydGVyVXNlcnNFbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdjYW5kaWRhdGVTdGFydGVyVXNlcnMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ2FuZGlkYXRlIFN0YXJ0ZXIgVXNlcnMnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdjYW5kaWRhdGVTdGFydGVyVXNlcnMnLFxyXG4gICAgZGVzY3JpcHRpb246IHRyYW5zbGF0ZSgnU3BlY2lmeSBtb3JlIHRoYW4gb25lIHVzZXIgYXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdC4nKSxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHZhciBjYW5kaWRhdGVTdGFydGVyVXNlcnMgPSBiby5nZXQoJ2FjdGl2aXRpOmNhbmRpZGF0ZVN0YXJ0ZXJVc2VycycpO1xyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBjYW5kaWRhdGVTdGFydGVyVXNlcnM6IGNhbmRpZGF0ZVN0YXJ0ZXJVc2VycyA/IGNhbmRpZGF0ZVN0YXJ0ZXJVc2VycyA6ICcnXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGJvLCB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOmNhbmRpZGF0ZVN0YXJ0ZXJVc2Vycyc6IHZhbHVlcy5jYW5kaWRhdGVTdGFydGVyVXNlcnMgfHwgdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIGNhbmRpZGF0ZVN0YXJ0ZXJHcm91cHNFbnRyeSxcclxuICAgIGNhbmRpZGF0ZVN0YXJ0ZXJVc2Vyc0VudHJ5XHJcbiAgXTtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgREVMRUdBVEVfVFlQRVMgPSBbXHJcbiAgJ2NsYXNzJyxcclxuICAnZXhwcmVzc2lvbicsXHJcbiAgJ2RlbGVnYXRlRXhwcmVzc2lvbidcclxuXTtcclxuXHJcbnZhciBQUk9QRVJUSUVTID0ge1xyXG4gIGNsYXNzOiAnYWN0aXZpdGk6Y2xhc3MnLFxyXG4gIGV4cHJlc3Npb246ICdhY3Rpdml0aTpleHByZXNzaW9uJyxcclxuICBkZWxlZ2F0ZUV4cHJlc3Npb246ICdhY3Rpdml0aTpkZWxlZ2F0ZUV4cHJlc3Npb24nXHJcbn07XHJcblxyXG5mdW5jdGlvbiBpc0RlbGVnYXRlKHR5cGUpIHtcclxuICByZXR1cm4gREVMRUdBVEVfVFlQRVMuaW5kZXhPZih0eXBlKSAhPT0gLTE7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEF0dHJpYnV0ZSh0eXBlKSB7XHJcbiAgcmV0dXJuIFBST1BFUlRJRVNbdHlwZV07XHJcbn1cclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldEltcGxlbWVudGF0aW9uVHlwZSA9IG9wdGlvbnMuZ2V0SW1wbGVtZW50YXRpb25UeXBlLFxyXG4gICAgICBnZXRCdXNpbmVzc09iamVjdCA9IG9wdGlvbnMuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG4gIGZ1bmN0aW9uIGdldERlbGVnYXRpb25MYWJlbCh0eXBlKSB7XHJcbiAgICBzd2l0Y2ggKHR5cGUpIHtcclxuICAgIGNhc2UgJ2NsYXNzJzpcclxuICAgICAgcmV0dXJuIHRyYW5zbGF0ZSgnSmF2YSBDbGFzcycpO1xyXG4gICAgY2FzZSAnZXhwcmVzc2lvbic6XHJcbiAgICAgIHJldHVybiB0cmFuc2xhdGUoJ0V4cHJlc3Npb24nKTtcclxuICAgIGNhc2UgJ2RlbGVnYXRlRXhwcmVzc2lvbic6XHJcbiAgICAgIHJldHVybiB0cmFuc2xhdGUoJ0RlbGVnYXRlIEV4cHJlc3Npb24nKTtcclxuICAgIGRlZmF1bHQ6XHJcbiAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHZhciBkZWxlZ2F0ZUVudHJ5ID0gZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ2RlbGVnYXRlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1ZhbHVlJyksXHJcbiAgICBkYXRhVmFsdWVMYWJlbDogJ2RlbGVnYXRpb25MYWJlbCcsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZGVsZWdhdGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIHR5cGUgPSBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCk7XHJcbiAgICAgIHZhciBhdHRyID0gZ2V0QXR0cmlidXRlKHR5cGUpO1xyXG4gICAgICB2YXIgbGFiZWwgPSBnZXREZWxlZ2F0aW9uTGFiZWwodHlwZSk7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZGVsZWdhdGU6IGJvLmdldChhdHRyKSxcclxuICAgICAgICBkZWxlZ2F0aW9uTGFiZWw6IGxhYmVsXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICB2YXIgdHlwZSA9IGdldEltcGxlbWVudGF0aW9uVHlwZShlbGVtZW50KTtcclxuICAgICAgdmFyIGF0dHIgPSBnZXRBdHRyaWJ1dGUodHlwZSk7XHJcbiAgICAgIHZhciBwcm9wID0ge307XHJcbiAgICAgIHByb3BbYXR0cl0gPSB2YWx1ZXMuZGVsZWdhdGUgfHwgJyc7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHByb3ApO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBpc0RlbGVnYXRlKGdldEltcGxlbWVudGF0aW9uVHlwZShlbGVtZW50KSkgJiYgIXZhbHVlcy5kZWxlZ2F0ZSA/IHsgZGVsZWdhdGU6IHRyYW5zbGF0ZSgnTXVzdCBwcm92aWRlIGEgdmFsdWUnKSB9IDoge307XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzRGVsZWdhdGUoZ2V0SW1wbGVtZW50YXRpb25UeXBlKGVsZW1lbnQpKTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBbIGRlbGVnYXRlRW50cnkgXTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgZWxlbWVudFJlZmVyZW5jZVByb3BlcnR5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vcHJvdmlkZXIvYnBtbi9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9FbGVtZW50UmVmZXJlbmNlUHJvcGVydHknKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oXHJcbiAgICBncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIGVycm9yRXZlbnREZWZpbml0aW9uLFxyXG4gICAgc2hvd0Vycm9yQ29kZVZhcmlhYmxlLCBzaG93RXJyb3JNZXNzYWdlVmFyaWFibGUsIHRyYW5zbGF0ZVxyXG4pIHtcclxuXHJcblxyXG4gIHZhciBnZXRWYWx1ZSA9IGZ1bmN0aW9uKG1vZGVsUHJvcGVydHkpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHZhciBtb2RlbFByb3BlcnR5VmFsdWUgPSBlcnJvckV2ZW50RGVmaW5pdGlvbi5nZXQoJ2FjdGl2aXRpOicgKyBtb2RlbFByb3BlcnR5KTtcclxuICAgICAgdmFyIHZhbHVlID0ge307XHJcblxyXG4gICAgICB2YWx1ZVttb2RlbFByb3BlcnR5XSA9IG1vZGVsUHJvcGVydHlWYWx1ZTtcclxuICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgc2V0VmFsdWUgPSBmdW5jdGlvbihtb2RlbFByb3BlcnR5KSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBwcm9wcyA9IHt9O1xyXG5cclxuICAgICAgcHJvcHNbJ2FjdGl2aXRpOicgKyBtb2RlbFByb3BlcnR5XSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGVycm9yRXZlbnREZWZpbml0aW9uLCBwcm9wcyk7XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoXHJcbiAgICBlbGVtZW50UmVmZXJlbmNlUHJvcGVydHkoZWxlbWVudCwgZXJyb3JFdmVudERlZmluaXRpb24sIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGlkOiAnZXJyb3ItZWxlbWVudC1tZXNzYWdlJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXJyb3IgTWVzc2FnZScpLFxyXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eTogJ2Vycm9yUmVmJyxcclxuICAgICAgbW9kZWxQcm9wZXJ0eTogJ2Vycm9yTWVzc2FnZSdcclxuICAgIH0pXHJcbiAgKTtcclxuXHJcbiAgaWYgKHNob3dFcnJvckNvZGVWYXJpYWJsZSkge1xyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgICBpZDogJ2Vycm9yQ29kZVZhcmlhYmxlJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXJyb3IgQ29kZSBWYXJpYWJsZScpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5IDogJ2Vycm9yQ29kZVZhcmlhYmxlJyxcclxuXHJcbiAgICAgIGdldDogZ2V0VmFsdWUoJ2Vycm9yQ29kZVZhcmlhYmxlJyksXHJcbiAgICAgIHNldDogc2V0VmFsdWUoJ2Vycm9yQ29kZVZhcmlhYmxlJylcclxuICAgIH0pKTtcclxuICB9XHJcblxyXG4gIGlmIChzaG93RXJyb3JNZXNzYWdlVmFyaWFibGUpIHtcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQ6ICdlcnJvck1lc3NhZ2VWYXJpYWJsZScsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0Vycm9yIE1lc3NhZ2UgVmFyaWFibGUnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eTogJ2Vycm9yTWVzc2FnZVZhcmlhYmxlJyxcclxuXHJcbiAgICAgIGdldDogZ2V0VmFsdWUoJ2Vycm9yTWVzc2FnZVZhcmlhYmxlJyksXHJcbiAgICAgIHNldDogc2V0VmFsdWUoJ2Vycm9yTWVzc2FnZVZhcmlhYmxlJylcclxuICAgIH0pKTtcclxuICB9XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIGRvbVF1ZXJ5ID0gcmVxdWlyZSgnbWluLWRvbScpLnF1ZXJ5LFxyXG4gICAgZG9tQ2xvc2VzdCA9IHJlcXVpcmUoJ21pbi1kb20nKS5jbG9zZXN0LFxyXG4gICAgZG9taWZ5ID0gcmVxdWlyZSgnbWluLWRvbScpLmRvbWlmeSxcclxuICAgIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgdXRpbHMgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9VdGlscycpLFxyXG4gICAgZXNjYXBlSFRNTCA9IHV0aWxzLmVzY2FwZUhUTUw7XHJcblxyXG5mdW5jdGlvbiBnZXRTZWxlY3RCb3gobm9kZSwgaWQpIHtcclxuICB2YXIgY3VycmVudFRhYiA9IGRvbUNsb3Nlc3Qobm9kZSwgJ2Rpdi5icHAtcHJvcGVydGllcy10YWInKTtcclxuICB2YXIgcXVlcnkgPSAnc2VsZWN0W25hbWU9c2VsZWN0ZWRFeHRlbnNpb25FbGVtZW50XScgKyAoaWQgPyAnW2lkPWNhbS1leHRlbnNpb25FbGVtZW50cy0nICsgaWQgKyAnXScgOiAnJyk7XHJcbiAgcmV0dXJuIGRvbVF1ZXJ5KHF1ZXJ5LCBjdXJyZW50VGFiKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0U2VsZWN0ZWQobm9kZSwgaWQpIHtcclxuICB2YXIgc2VsZWN0Qm94ID0gZ2V0U2VsZWN0Qm94KG5vZGUsIGlkKTtcclxuICByZXR1cm4ge1xyXG4gICAgdmFsdWU6IChzZWxlY3RCb3ggfHwge30pLnZhbHVlLFxyXG4gICAgaWR4OiAoc2VsZWN0Qm94IHx8IHt9KS5zZWxlY3RlZEluZGV4XHJcbiAgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVFbGVtZW50SWQocHJlZml4KSB7XHJcbiAgcHJlZml4ID0gcHJlZml4ICsgJ18nO1xyXG4gIHJldHVybiB1dGlscy5uZXh0SWQocHJlZml4KTtcclxufVxyXG5cclxudmFyIENSRUFURV9FWFRFTlNJT05fRUxFTUVOVF9BQ1RJT04gPSAnY3JlYXRlLWV4dGVuc2lvbi1lbGVtZW50JyxcclxuICAgIFJFTU9WRV9FWFRFTlNJT05fRUxFTUVOVF9BQ1RJT04gPSAncmVtb3ZlLWV4dGVuc2lvbi1lbGVtZW50JztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgaWQgPSBvcHRpb25zLmlkLFxyXG4gICAgICBwcmVmaXggPSBvcHRpb25zLnByZWZpeCB8fCAnZWxlbScsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCB8fCBpZCxcclxuICAgICAgaWRHZW5lcmF0aW9uID0gKG9wdGlvbnMuaWRHZW5lcmF0aW9uID09PSBmYWxzZSkgPyBvcHRpb25zLmlkR2VuZXJhdGlvbiA6IHRydWUsXHJcbiAgICAgIGJ1c2luZXNzT2JqZWN0ID0gb3B0aW9ucy5idXNpbmVzc09iamVjdCB8fCBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgdmFyIG1vZGVsUHJvcGVydHkgPSBvcHRpb25zLm1vZGVsUHJvcGVydHkgfHwgJ2lkJztcclxuXHJcbiAgdmFyIGdldEVsZW1lbnRzID0gb3B0aW9ucy5nZXRFeHRlbnNpb25FbGVtZW50cztcclxuXHJcbiAgdmFyIGNyZWF0ZUVsZW1lbnQgPSBvcHRpb25zLmNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQsXHJcbiAgICAgIGNhbkNyZWF0ZSA9IHR5cGVvZiBjcmVhdGVFbGVtZW50ID09PSAnZnVuY3Rpb24nO1xyXG5cclxuICB2YXIgcmVtb3ZlRWxlbWVudCA9IG9wdGlvbnMucmVtb3ZlRXh0ZW5zaW9uRWxlbWVudCxcclxuICAgICAgY2FuUmVtb3ZlID0gdHlwZW9mIHJlbW92ZUVsZW1lbnQgPT09ICdmdW5jdGlvbic7XHJcblxyXG4gIHZhciBvblNlbGVjdGlvbkNoYW5nZSA9IG9wdGlvbnMub25TZWxlY3Rpb25DaGFuZ2U7XHJcblxyXG4gIHZhciBoaWRlRWxlbWVudHMgPSBvcHRpb25zLmhpZGVFeHRlbnNpb25FbGVtZW50cyxcclxuICAgICAgY2FuQmVIaWRkZW4gPSB0eXBlb2YgaGlkZUVsZW1lbnRzID09PSAnZnVuY3Rpb24nO1xyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IG9wdGlvbnMuc2V0T3B0aW9uTGFiZWxWYWx1ZTtcclxuXHJcbiAgdmFyIGRlZmF1bHRTaXplID0gb3B0aW9ucy5zaXplIHx8IDUsXHJcbiAgICAgIHJlc2l6YWJsZSA9IG9wdGlvbnMucmVzaXphYmxlO1xyXG5cclxuICB2YXIgcmVmZXJlbmNlID0gb3B0aW9ucy5yZWZlcmVuY2UgfHwgdW5kZWZpbmVkO1xyXG5cclxuICB2YXIgc2VsZWN0aW9uQ2hhbmdlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50LCBzY29wZSkge1xyXG4gICAgaWYgKHR5cGVvZiBvblNlbGVjdGlvbkNoYW5nZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICByZXR1cm4gb25TZWxlY3Rpb25DaGFuZ2UoZWxlbWVudCwgbm9kZSwgZXZlbnQsIHNjb3BlKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICB2YXIgY3JlYXRlT3B0aW9uID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgIHJldHVybiAnPG9wdGlvbiB2YWx1ZT1cIicgKyBlc2NhcGVIVE1MKHZhbHVlKSArICdcIiBkYXRhLXZhbHVlIGRhdGEtbmFtZT1cImV4dGVuc2lvbkVsZW1lbnRWYWx1ZVwiPicgKyBlc2NhcGVIVE1MKHZhbHVlKSArICc8L29wdGlvbj4nO1xyXG4gIH07XHJcblxyXG4gIHZhciBpbml0U2VsZWN0aW9uU2l6ZSA9IGZ1bmN0aW9uKHNlbGVjdEJveCwgb3B0aW9uc0xlbmd0aCkge1xyXG4gICAgaWYgKHJlc2l6YWJsZSkge1xyXG4gICAgICBzZWxlY3RCb3guc2l6ZSA9IG9wdGlvbnNMZW5ndGggPiBkZWZhdWx0U2l6ZSA/IG9wdGlvbnNMZW5ndGggOiBkZWZhdWx0U2l6ZTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICByZXR1cm4ge1xyXG4gICAgaWQ6IGlkLFxyXG4gICAgaHRtbDogJzxkaXYgY2xhc3M9XCJicHAtcm93IGJwcC1lbGVtZW50LWxpc3RcIiAnICtcclxuICAgICAgICAgICAgKGNhbkJlSGlkZGVuID8gJ2RhdGEtc2hvdz1cImhpZGVFbGVtZW50c1wiJyA6ICcnKSArICc+JyArXHJcbiAgICAgICAgICAgICc8bGFiZWwgZm9yPVwiY2FtLWV4dGVuc2lvbkVsZW1lbnRzLScgKyBlc2NhcGVIVE1MKGlkKSArICdcIj4nICsgZXNjYXBlSFRNTChsYWJlbCkgKyAnPC9sYWJlbD4nICtcclxuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlclwiPicgK1xyXG4gICAgICAgICAgICAgICc8c2VsZWN0IGlkPVwiY2FtLWV4dGVuc2lvbkVsZW1lbnRzLScgKyBlc2NhcGVIVE1MKGlkKSArICdcIicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgJ25hbWU9XCJzZWxlY3RlZEV4dGVuc2lvbkVsZW1lbnRcIiAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICdzaXplPVwiJyArIGVzY2FwZUhUTUwoZGVmYXVsdFNpemUpICsgJ1wiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgJ2RhdGEtbGlzdC1lbnRyeS1jb250YWluZXIgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAnZGF0YS1vbi1jaGFuZ2U9XCJzZWxlY3RFbGVtZW50XCI+JyArXHJcbiAgICAgICAgICAgICAgJzwvc2VsZWN0PicgK1xyXG4gICAgICAgICAgICAgIChjYW5DcmVhdGUgPyAnPGJ1dHRvbiBjbGFzcz1cImFkZFwiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpZD1cImNhbS1leHRlbnNpb25FbGVtZW50cy1jcmVhdGUtJyArIGVzY2FwZUhUTUwoaWQpICsgJ1wiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkYXRhLWFjdGlvbj1cImNyZWF0ZUVsZW1lbnRcIj4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHNwYW4+Kzwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgOiAnJykgK1xyXG4gICAgICAgICAgICAgIChjYW5SZW1vdmUgPyAnPGJ1dHRvbiBjbGFzcz1cImNsZWFyXCIgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2lkPVwiY2FtLWV4dGVuc2lvbkVsZW1lbnRzLXJlbW92ZS0nICsgZXNjYXBlSFRNTChpZCkgKyAnXCIgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RhdGEtYWN0aW9uPVwicmVtb3ZlRWxlbWVudFwiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkYXRhLWRpc2FibGU9XCJkaXNhYmxlUmVtb3ZlXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuPi08L3NwYW4+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nIDogJycpICtcclxuICAgICAgICAgICAgJzwvZGl2PicgK1xyXG4gICAgICAgICAgJzwvZGl2PicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBlbGVtZW50cyA9IGdldEVsZW1lbnRzKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtKSB7XHJcbiAgICAgICAgcmVzdWx0LnB1c2goe1xyXG4gICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudFZhbHVlOiBlbGVtLmdldChtb2RlbFByb3BlcnR5KVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHZhciBzZWxlY3RCb3ggPSBnZXRTZWxlY3RCb3gobm9kZS5wYXJlbnROb2RlLCBpZCk7XHJcbiAgICAgIGluaXRTZWxlY3Rpb25TaXplKHNlbGVjdEJveCwgcmVzdWx0Lmxlbmd0aCk7XHJcblxyXG4gICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYWN0aW9uID0gdGhpcy5fX2FjdGlvbjtcclxuICAgICAgZGVsZXRlIHRoaXMuX19hY3Rpb247XHJcblxyXG4gICAgICBidXNpbmVzc09iamVjdCA9IGJ1c2luZXNzT2JqZWN0IHx8IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgdmFyIGJvID1cclxuICAgICAgICAocmVmZXJlbmNlICYmIGJ1c2luZXNzT2JqZWN0LmdldChyZWZlcmVuY2UpKVxyXG4gICAgICAgICAgPyBidXNpbmVzc09iamVjdC5nZXQocmVmZXJlbmNlKVxyXG4gICAgICAgICAgOiBidXNpbmVzc09iamVjdDtcclxuXHJcbiAgICAgIHZhciBleHRlbnNpb25FbGVtZW50cyA9IGJvLmdldCgnZXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuXHJcbiAgICAgIGlmIChhY3Rpb24uaWQgPT09IENSRUFURV9FWFRFTlNJT05fRUxFTUVOVF9BQ1RJT04pIHtcclxuICAgICAgICB2YXIgY29tbWFuZHMgPSBbXTtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvbkVsZW1lbnRzKSB7XHJcbiAgICAgICAgICBleHRlbnNpb25FbGVtZW50cyA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYnBtbjpFeHRlbnNpb25FbGVtZW50cycsIHsgdmFsdWVzOiBbXSB9LCBibywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgZXh0ZW5zaW9uRWxlbWVudHM6IGV4dGVuc2lvbkVsZW1lbnRzIH0pKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChjcmVhdGVFbGVtZW50KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCBhY3Rpb24udmFsdWUsIG5vZGUpKTtcclxuICAgICAgICByZXR1cm4gY29tbWFuZHM7XHJcblxyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKGFjdGlvbi5pZCA9PT0gUkVNT1ZFX0VYVEVOU0lPTl9FTEVNRU5UX0FDVElPTikge1xyXG4gICAgICAgIHJldHVybiByZW1vdmVFbGVtZW50KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCBhY3Rpb24udmFsdWUsIGFjdGlvbi5pZHgsIG5vZGUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgfSxcclxuXHJcbiAgICBjcmVhdGVMaXN0RW50cnlUZW1wbGF0ZTogZnVuY3Rpb24odmFsdWUsIGluZGV4LCBzZWxlY3RCb3gpIHtcclxuICAgICAgaW5pdFNlbGVjdGlvblNpemUoc2VsZWN0Qm94LCBzZWxlY3RCb3gub3B0aW9ucy5sZW5ndGggKyAxKTtcclxuICAgICAgcmV0dXJuIGNyZWF0ZU9wdGlvbih2YWx1ZS5leHRlbnNpb25FbGVtZW50VmFsdWUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBkZXNlbGVjdDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgc2VsZWN0Qm94ID0gZ2V0U2VsZWN0Qm94KG5vZGUsIGlkKTtcclxuICAgICAgc2VsZWN0Qm94LnNlbGVjdGVkSW5kZXggPSAtMTtcclxuICAgIH0sXHJcblxyXG4gICAgZ2V0U2VsZWN0ZWQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGdldFNlbGVjdGVkKG5vZGUsIGlkKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0Q29udHJvbFZhbHVlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBvcHRpb24sIHByb3BlcnR5LCB2YWx1ZSwgaWR4KSB7XHJcbiAgICAgIG5vZGUudmFsdWUgPSB2YWx1ZTtcclxuXHJcbiAgICAgIGlmICghc2V0T3B0aW9uTGFiZWxWYWx1ZSkge1xyXG4gICAgICAgIG5vZGUudGV4dCA9IHZhbHVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNldE9wdGlvbkxhYmVsVmFsdWUoZWxlbWVudCwgbm9kZSwgb3B0aW9uLCBwcm9wZXJ0eSwgdmFsdWUsIGlkeCk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgY3JlYXRlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICAvLyBjcmVhdGUgb3B0aW9uIHRlbXBsYXRlXHJcbiAgICAgIHZhciBnZW5lcmF0ZWRJZDtcclxuICAgICAgaWYgKGlkR2VuZXJhdGlvbikge1xyXG4gICAgICAgIGdlbmVyYXRlZElkID0gZ2VuZXJhdGVFbGVtZW50SWQocHJlZml4KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHNlbGVjdEJveCA9IGdldFNlbGVjdEJveChub2RlLCBpZCk7XHJcbiAgICAgIHZhciB0ZW1wbGF0ZSA9IGRvbWlmeShjcmVhdGVPcHRpb24oZ2VuZXJhdGVkSWQpKTtcclxuXHJcbiAgICAgIC8vIGFkZCBuZXcgZW1wdHkgb3B0aW9uIGFzIGxhc3QgY2hpbGQgZWxlbWVudFxyXG4gICAgICBzZWxlY3RCb3guYXBwZW5kQ2hpbGQodGVtcGxhdGUpO1xyXG5cclxuICAgICAgLy8gc2VsZWN0IGxhc3QgY2hpbGQgZWxlbWVudFxyXG4gICAgICBzZWxlY3RCb3gubGFzdENoaWxkLnNlbGVjdGVkID0gJ3NlbGVjdGVkJztcclxuICAgICAgc2VsZWN0aW9uQ2hhbmdlZChlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBzZWxlY3QgYm94IHNpemVcclxuICAgICAgaW5pdFNlbGVjdGlvblNpemUoc2VsZWN0Qm94LCBzZWxlY3RCb3gub3B0aW9ucy5sZW5ndGgpO1xyXG5cclxuICAgICAgdGhpcy5fX2FjdGlvbiA9IHtcclxuICAgICAgICBpZDogQ1JFQVRFX0VYVEVOU0lPTl9FTEVNRU5UX0FDVElPTixcclxuICAgICAgICB2YWx1ZTogZ2VuZXJhdGVkSWRcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICByZW1vdmVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3Rpb24gPSBnZXRTZWxlY3RlZChub2RlLCBpZCk7XHJcblxyXG4gICAgICB2YXIgc2VsZWN0Qm94ID0gZ2V0U2VsZWN0Qm94KG5vZGUsIGlkKTtcclxuICAgICAgc2VsZWN0Qm94LnJlbW92ZUNoaWxkKHNlbGVjdEJveC5vcHRpb25zW3NlbGVjdGlvbi5pZHhdKTtcclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBzZWxlY3QgYm94IHNpemVcclxuICAgICAgaW5pdFNlbGVjdGlvblNpemUoc2VsZWN0Qm94LCBzZWxlY3RCb3gub3B0aW9ucy5sZW5ndGgpO1xyXG5cclxuICAgICAgdGhpcy5fX2FjdGlvbiA9IHtcclxuICAgICAgICBpZDogUkVNT1ZFX0VYVEVOU0lPTl9FTEVNRU5UX0FDVElPTixcclxuICAgICAgICB2YWx1ZTogc2VsZWN0aW9uLnZhbHVlLFxyXG4gICAgICAgIGlkeDogc2VsZWN0aW9uLmlkeFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGVFbGVtZW50czogZnVuY3Rpb24oZWxlbWVudCwgZW50cnlOb2RlLCBub2RlLCBzY29wZU5vZGUpIHtcclxuICAgICAgcmV0dXJuICFoaWRlRWxlbWVudHMoZWxlbWVudCwgZW50cnlOb2RlLCBub2RlLCBzY29wZU5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBkaXNhYmxlUmVtb3ZlOiBmdW5jdGlvbihlbGVtZW50LCBlbnRyeU5vZGUsIG5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICByZXR1cm4gKGdldFNlbGVjdGVkKGVudHJ5Tm9kZSwgaWQpIHx8IHt9KS5pZHggPCAwO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZWxlY3RFbGVtZW50OiBzZWxlY3Rpb25DaGFuZ2VkXHJcbiAgfTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBnZXRJbXBsZW1lbnRhdGlvblR5cGUgPSBvcHRpb25zLmdldEltcGxlbWVudGF0aW9uVHlwZSxcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICBmdW5jdGlvbiBpc0V4dGVybmFsKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkgPT09ICdleHRlcm5hbCc7XHJcbiAgfVxyXG5cclxuICB2YXIgdG9waWNFbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdleHRlcm5hbFRvcGljJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1RvcGljJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZXh0ZXJuYWxUb3BpYycsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4geyBleHRlcm5hbFRvcGljOiBiby5nZXQoJ2FjdGl2aXRpOnRvcGljJykgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHtcclxuICAgICAgICAnYWN0aXZpdGk6dG9waWMnOiB2YWx1ZXMuZXh0ZXJuYWxUb3BpY1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICByZXR1cm4gaXNFeHRlcm5hbChlbGVtZW50KSAmJiAhdmFsdWVzLmV4dGVybmFsVG9waWMgPyB7IGV4dGVybmFsVG9waWM6IHRyYW5zbGF0ZSgnTXVzdCBwcm92aWRlIGEgdmFsdWUnKSB9IDoge307XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzRXh0ZXJuYWwoZWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gWyB0b3BpY0VudHJ5IF07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gb3B0aW9ucy5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbiAgdmFyIGV4dGVybmFsVGFza1ByaW9yaXR5RW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnZXh0ZXJuYWxUYXNrUHJpb3JpdHknLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGFzayBQcmlvcml0eScpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3Rhc2tQcmlvcml0eScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHRhc2tQcmlvcml0eTogYm8uZ2V0KCdhY3Rpdml0aTp0YXNrUHJpb3JpdHknKVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBibywge1xyXG4gICAgICAgICdhY3Rpdml0aTp0YXNrUHJpb3JpdHknOiB2YWx1ZXMudGFza1ByaW9yaXR5IHx8IHVuZGVmaW5lZFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBbIGV4dGVybmFsVGFza1ByaW9yaXR5RW50cnkgXTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBleHRlbnNpb25FbGVtZW50c0hlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpLFxyXG4gICAgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9VdGlscycpO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgZXh0ZW5zaW9uRWxlbWVudHNFbnRyeSA9IHJlcXVpcmUoJy4vRXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuXHJcbnZhciBNb2RlbFV0aWwgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBNb2RlbFV0aWwuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xyXG5cclxuXHJcbnZhciBERUZBVUxUX1BST1BTID0ge1xyXG4gICdzdHJpbmdWYWx1ZSc6IHVuZGVmaW5lZCxcclxuICAnc3RyaW5nJzogdW5kZWZpbmVkLFxyXG4gICdleHByZXNzaW9uJzogdW5kZWZpbmVkXHJcbn07XHJcblxyXG52YXIgQUNUSVZJVElfRklFTERfRVhURU5TSU9OX0VMRU1FTlQgPSAnYWN0aXZpdGk6RmllbGQnO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlLCBvcHRpb25zKSB7XHJcblxyXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG5cclxuICB2YXIgaW5zaWRlTGlzdGVuZXIgPSAhIW9wdGlvbnMuaW5zaWRlTGlzdGVuZXIsXHJcbiAgICAgIGlkUHJlZml4ID0gb3B0aW9ucy5pZFByZWZpeCB8fCAnJyxcclxuICAgICAgZ2V0U2VsZWN0ZWRMaXN0ZW5lciA9IG9wdGlvbnMuZ2V0U2VsZWN0ZWRMaXN0ZW5lcixcclxuICAgICAgYnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmJ1c2luZXNzT2JqZWN0IHx8IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICB2YXIgZW50cmllcyA9IFtdO1xyXG5cclxuICB2YXIgaXNTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHJldHVybiBnZXRTZWxlY3RlZEZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG4gIH07XHJcblxyXG4gIGZ1bmN0aW9uIGdldFNlbGVjdGVkRmllbGQoZWxlbWVudCwgbm9kZSkge1xyXG4gICAgdmFyIHNlbGVjdGVkID0gZmllbGRFbnRyeS5nZXRTZWxlY3RlZChlbGVtZW50LCBub2RlLnBhcmVudE5vZGUpO1xyXG5cclxuICAgIGlmIChzZWxlY3RlZC5pZHggPT09IC0xKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZmllbGRzID0gZ2V0QWN0aXZpdGlGaWVsZHMoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgcmV0dXJuIGZpZWxkc1tzZWxlY3RlZC5pZHhdO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0QWN0aXZpdGlGaWVsZHMoZWxlbWVudCwgbm9kZSkge1xyXG4gICAgaWYgKCFpbnNpZGVMaXN0ZW5lcikge1xyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0ICYmXHJcbiAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYnVzaW5lc3NPYmplY3QsIEFDVElWSVRJX0ZJRUxEX0VYVEVOU0lPTl9FTEVNRU5UKVxyXG4gICAgICApIHx8IFtdO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGdldEFjdGl2aXRpTGlzdGVuZXJGaWVsZHMoZWxlbWVudCwgbm9kZSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBnZXRBY3Rpdml0aUxpc3RlbmVyRmllbGRzKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciBzZWxlY3RlZExpc3RlbmVyID0gZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKTtcclxuICAgIHJldHVybiBzZWxlY3RlZExpc3RlbmVyICYmIHNlbGVjdGVkTGlzdGVuZXIuZmllbGRzIHx8IFtdO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0RmllbGRUeXBlKGJvKSB7XHJcbiAgICB2YXIgZmllbGRUeXBlID0gJ3N0cmluZyc7XHJcblxyXG4gICAgdmFyIGV4cHJlc3Npb25WYWx1ZSA9IGJvICYmIGJvLmV4cHJlc3Npb247XHJcbiAgICB2YXIgc3RyaW5nVmFsdWUgPSBibyAmJiAoYm8uc3RyaW5nIHx8IGJvLnN0cmluZ1ZhbHVlKTtcclxuXHJcbiAgICBpZiAodHlwZW9mIHN0cmluZ1ZhbHVlICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBmaWVsZFR5cGUgPSAnc3RyaW5nJztcclxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cHJlc3Npb25WYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgZmllbGRUeXBlID0gJ2V4cHJlc3Npb24nO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmaWVsZFR5cGU7XHJcbiAgfVxyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIG9wdGlvbiwgcHJvcGVydHksIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGFjdGl2aXRpRmllbGRzID0gZ2V0QWN0aXZpdGlGaWVsZHMoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBmaWVsZCA9IGFjdGl2aXRpRmllbGRzW2lkeF07XHJcblxyXG4gICAgICB2YWx1ZSA9IChmaWVsZC5uYW1lKSA/IGZpZWxkLm5hbWUgOiAnPGVtcHR5Pic7XHJcblxyXG4gICAgICB2YXIgbGFiZWwgPSBpZHggKyAnIDogJyArIHZhbHVlO1xyXG5cclxuICAgICAgb3B0aW9uLnRleHQgPSBsYWJlbDtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgdmFyIG5ld0VsZW1lbnQgPSBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgdmFsdWUsIG5vZGUpIHtcclxuXHJcbiAgICAgIHZhciBwcm9wcyA9IHtcclxuICAgICAgICBuYW1lOiAnJyxcclxuICAgICAgICBzdHJpbmc6ICcnXHJcbiAgICAgIH07XHJcblxyXG4gICAgICB2YXIgbmV3RmllbGRFbGVtO1xyXG5cclxuICAgICAgaWYgKCFpbnNpZGVMaXN0ZW5lcikge1xyXG5cclxuICAgICAgICBuZXdGaWVsZEVsZW0gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoQUNUSVZJVElfRklFTERfRVhURU5TSU9OX0VMRU1FTlQsIHByb3BzLCBleHRlbnNpb25FbGVtZW50cywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgIHJldHVybiBjbWRIZWxwZXIuYWRkRWxlbWVudHNUb2xpc3QoZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsICd2YWx1ZXMnLCBbIG5ld0ZpZWxkRWxlbSBdKTtcclxuXHJcbiAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgIHZhciBzZWxlY3RlZExpc3RlbmVyID0gZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKTtcclxuICAgICAgICBuZXdGaWVsZEVsZW0gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoQUNUSVZJVElfRklFTERfRVhURU5TSU9OX0VMRU1FTlQsIHByb3BzLCBzZWxlY3RlZExpc3RlbmVyLCBicG1uRmFjdG9yeSk7XHJcbiAgICAgICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBzZWxlY3RlZExpc3RlbmVyLCAnZmllbGRzJywgWyBuZXdGaWVsZEVsZW0gXSk7XHJcblxyXG4gICAgICB9XHJcblxyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgcmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCB2YWx1ZSwgaWR4LCBub2RlKSB7XHJcbiAgICAgIHZhciBhY3Rpdml0aUZpZWxkcz0gZ2V0QWN0aXZpdGlGaWVsZHMoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBmaWVsZCA9IGFjdGl2aXRpRmllbGRzW2lkeF07XHJcbiAgICAgIGlmIChmaWVsZCkge1xyXG4gICAgICAgIGlmICghaW5zaWRlTGlzdGVuZXIpIHtcclxuICAgICAgICAgIHJldHVybiBleHRlbnNpb25FbGVtZW50c0hlbHBlci5yZW1vdmVFbnRyeShidXNpbmVzc09iamVjdCwgZWxlbWVudCwgZmllbGQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc2VsZWN0ZWRMaXN0ZW5lciA9IGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgICAgcmV0dXJuIGNtZEhlbHBlci5yZW1vdmVFbGVtZW50c0Zyb21MaXN0KGVsZW1lbnQsIHNlbGVjdGVkTGlzdGVuZXIsICdmaWVsZHMnLCBudWxsLCBbIGZpZWxkIF0pO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG5cclxuICB2YXIgZmllbGRFbnRyeSA9IGV4dGVuc2lvbkVsZW1lbnRzRW50cnkoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkIDogaWRQcmVmaXggKyAnZmllbGRzJyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdGaWVsZHMnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdmaWVsZE5hbWUnLFxyXG4gICAgaWRHZW5lcmF0aW9uOiAnZmFsc2UnLFxyXG5cclxuICAgIGJ1c2luZXNzT2JqZWN0OiBidXNpbmVzc09iamVjdCxcclxuXHJcbiAgICBjcmVhdGVFeHRlbnNpb25FbGVtZW50OiBuZXdFbGVtZW50KCksXHJcbiAgICByZW1vdmVFeHRlbnNpb25FbGVtZW50OiByZW1vdmVFbGVtZW50KCksXHJcblxyXG4gICAgZ2V0RXh0ZW5zaW9uRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGdldEFjdGl2aXRpRmllbGRzKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKClcclxuXHJcbiAgfSk7XHJcbiAgZW50cmllcy5wdXNoKGZpZWxkRW50cnkpO1xyXG5cclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS52YWxpZGF0aW9uQXdhcmVUZXh0RmllbGQoe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ2ZpZWxkLW5hbWUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnTmFtZScpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2ZpZWxkTmFtZScsXHJcblxyXG4gICAgZ2V0UHJvcGVydHk6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIChnZXRTZWxlY3RlZEZpZWxkKGVsZW1lbnQsIG5vZGUpIHx8IHt9KS5uYW1lO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZpZWxkID0gZ2V0U2VsZWN0ZWRGaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBzZWxlY3RlZEZpZWxkLCB7IG5hbWUgOiB2YWx1ZXMuZmllbGROYW1lIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICB2YXIgdmFsaWRhdGlvbiA9IHt9O1xyXG4gICAgICBpZiAoYm8pIHtcclxuICAgICAgICB2YXIgbmFtZVZhbHVlID0gdmFsdWVzLmZpZWxkTmFtZTtcclxuXHJcbiAgICAgICAgaWYgKG5hbWVWYWx1ZSkge1xyXG4gICAgICAgICAgaWYgKHV0aWxzLmNvbnRhaW5zU3BhY2UobmFtZVZhbHVlKSkge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9uLmZpZWxkTmFtZSA9IHRyYW5zbGF0ZSgnTmFtZSBtdXN0IG5vdCBjb250YWluIHNwYWNlcycpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB2YWxpZGF0aW9uLmZpZWxkTmFtZSA9IHRyYW5zbGF0ZSgnUGFyYW1ldGVyIG11c3QgaGF2ZSBhIG5hbWUnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB2YWxpZGF0aW9uO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICFpc1NlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG4gIHZhciBmaWVsZFR5cGVPcHRpb25zID0gW1xyXG4gICAge1xyXG4gICAgICBuYW1lOiB0cmFuc2xhdGUoJ1N0cmluZycpLFxyXG4gICAgICB2YWx1ZTogJ3N0cmluZydcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6IHRyYW5zbGF0ZSgnRXhwcmVzc2lvbicpLFxyXG4gICAgICB2YWx1ZTogJ2V4cHJlc3Npb24nXHJcbiAgICB9XHJcbiAgXTtcclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ2ZpZWxkLXR5cGUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVHlwZScpLFxyXG4gICAgc2VsZWN0T3B0aW9uczogZmllbGRUeXBlT3B0aW9ucyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdmaWVsZFR5cGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZEZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIGZpZWxkVHlwZSA9IGdldEZpZWxkVHlwZShibyk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGZpZWxkVHlwZTogZmllbGRUeXBlXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBwcm9wcyA9IGFzc2lnbih7fSwgREVGQVVMVF9QUk9QUyk7XHJcblxyXG4gICAgICB2YXIgZmllbGRUeXBlID0gdmFsdWVzLmZpZWxkVHlwZTtcclxuXHJcbiAgICAgIGlmIChmaWVsZFR5cGUgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgcHJvcHMuc3RyaW5nID0gJyc7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAoZmllbGRUeXBlID09PSAnZXhwcmVzc2lvbicpIHtcclxuICAgICAgICBwcm9wcy5leHByZXNzaW9uID0gJyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgZ2V0U2VsZWN0ZWRGaWVsZChlbGVtZW50LCBub2RlKSwgcHJvcHMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICFpc1NlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRCb3goe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ2ZpZWxkLXZhbHVlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1ZhbHVlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZmllbGRWYWx1ZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBmaWVsZFR5cGUgPSBnZXRGaWVsZFR5cGUoYm8pO1xyXG5cclxuICAgICAgdmFyIGZpZWxkVmFsdWU7XHJcblxyXG4gICAgICBpZiAoZmllbGRUeXBlID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIGZpZWxkVmFsdWUgPSBibyAmJiAoYm8uc3RyaW5nIHx8IGJvLnN0cmluZ1ZhbHVlKTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmIChmaWVsZFR5cGUgPT09ICdleHByZXNzaW9uJykge1xyXG4gICAgICAgIGZpZWxkVmFsdWUgPSBibyAmJiBiby5leHByZXNzaW9uO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGZpZWxkVmFsdWU6IGZpZWxkVmFsdWVcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWRGaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGZpZWxkVHlwZSA9IGdldEZpZWxkVHlwZShibyk7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIERFRkFVTFRfUFJPUFMpO1xyXG5cclxuICAgICAgdmFyIGZpZWxkVmFsdWUgPSB2YWx1ZXMuZmllbGRWYWx1ZSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICBpZiAoZmllbGRUeXBlID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIHByb3BzLnN0cmluZyA9IGZpZWxkVmFsdWU7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAoZmllbGRUeXBlID09PSAnZXhwcmVzc2lvbicpIHtcclxuICAgICAgICBwcm9wcy5leHByZXNzaW9uID0gZmllbGRWYWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBibywgcHJvcHMpO1xyXG5cclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZEZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIHZhbGlkYXRpb24gPSB7fTtcclxuICAgICAgaWYgKGJvKSB7XHJcbiAgICAgICAgaWYgKCF2YWx1ZXMuZmllbGRWYWx1ZSkge1xyXG4gICAgICAgICAgdmFsaWRhdGlvbi5maWVsZFZhbHVlID0gdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbGlkYXRpb247XHJcbiAgICB9LFxyXG5cclxuICAgIHNob3c6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gb3B0aW9ucy5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbiAgdmFyIGhpc3RvcnlUaW1lVG9MaXZlRW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnaGlzdG9yeVRpbWVUb0xpdmUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSGlzdG9yeSBUaW1lIFRvIExpdmUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdoaXN0b3J5VGltZVRvTGl2ZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICB2YXIgaGlzdG9yeVRpbWVUb0xpdmUgPSBiby5nZXQoJ2FjdGl2aXRpOmhpc3RvcnlUaW1lVG9MaXZlJyk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGhpc3RvcnlUaW1lVG9MaXZlOiBoaXN0b3J5VGltZVRvTGl2ZSA/IGhpc3RvcnlUaW1lVG9MaXZlIDogJydcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHtcclxuICAgICAgICAnYWN0aXZpdGk6aGlzdG9yeVRpbWVUb0xpdmUnOiB2YWx1ZXMuaGlzdG9yeVRpbWVUb0xpdmUgfHwgdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIFsgaGlzdG9yeVRpbWVUb0xpdmVFbnRyeSBdO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKSxcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKTtcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyk7XHJcbnZhciBtYXAgPSByZXF1aXJlKCdsb2Rhc2gvbWFwJyk7XHJcblxyXG52YXIgREVGQVVMVF9ERUxFR0FURV9QUk9QUyA9IFsgJ2NsYXNzJywgJ2V4cHJlc3Npb24nLCAnZGVsZWdhdGVFeHByZXNzaW9uJyBdO1xyXG5cclxudmFyIERFTEVHQVRFX1BST1BTID0ge1xyXG4gICdhY3Rpdml0aTpjbGFzcyc6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6ZXhwcmVzc2lvbic6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6ZGVsZWdhdGVFeHByZXNzaW9uJzogdW5kZWZpbmVkLFxyXG4gICdhY3Rpdml0aTpyZXN1bHRWYXJpYWJsZSc6IHVuZGVmaW5lZFxyXG59O1xyXG5cclxudmFyIERNTl9DQVBBQkxFX1BST1BTID0ge1xyXG4gICdhY3Rpdml0aTpkZWNpc2lvblJlZic6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6ZGVjaXNpb25SZWZCaW5kaW5nJzogJ2xhdGVzdCcsXHJcbiAgJ2FjdGl2aXRpOmRlY2lzaW9uUmVmVmVyc2lvbic6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6bWFwRGVjaXNpb25SZXN1bHQnOiAncmVzdWx0TGlzdCcsXHJcbiAgJ2FjdGl2aXRpOmRlY2lzaW9uUmVmVGVuYW50SWQnOiB1bmRlZmluZWRcclxufTtcclxuXHJcblxyXG52YXIgRVhURVJOQUxfQ0FQQUJMRV9QUk9QUyA9IHtcclxuICAnYWN0aXZpdGk6dHlwZSc6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6dG9waWMnOiB1bmRlZmluZWRcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgREVGQVVMVF9PUFRJT05TID0gW1xyXG4gICAgeyB2YWx1ZTogJ2NsYXNzJywgbmFtZTogdHJhbnNsYXRlKCdKYXZhIENsYXNzJykgfSxcclxuICAgIHsgdmFsdWU6ICdleHByZXNzaW9uJywgbmFtZTogdHJhbnNsYXRlKCdFeHByZXNzaW9uJykgfSxcclxuICAgIHsgdmFsdWU6ICdkZWxlZ2F0ZUV4cHJlc3Npb24nLCBuYW1lOiB0cmFuc2xhdGUoJ0RlbGVnYXRlIEV4cHJlc3Npb24nKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIERNTl9PUFRJT04gPSBbXHJcbiAgICB7IHZhbHVlOiAnZG1uJywgbmFtZTogdHJhbnNsYXRlKCdETU4nKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIEVYVEVSTkFMX09QVElPTiA9IFtcclxuICAgIHsgdmFsdWU6ICdleHRlcm5hbCcsIG5hbWU6IHRyYW5zbGF0ZSgnRXh0ZXJuYWwnKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIENPTk5FQ1RPUl9PUFRJT04gPSBbXHJcbiAgICB7IHZhbHVlOiAnY29ubmVjdG9yJywgbmFtZTogdHJhbnNsYXRlKCdDb25uZWN0b3InKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIFNDUklQVF9PUFRJT04gPSBbXHJcbiAgICB7IHZhbHVlOiAnc2NyaXB0JywgbmFtZTogdHJhbnNsYXRlKCdTY3JpcHQnKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIGdldFR5cGUgPSBvcHRpb25zLmdldEltcGxlbWVudGF0aW9uVHlwZSxcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICB2YXIgaGFzRG1uU3VwcG9ydCA9IG9wdGlvbnMuaGFzRG1uU3VwcG9ydCxcclxuICAgICAgaGFzRXh0ZXJuYWxTdXBwb3J0ID0gb3B0aW9ucy5oYXNFeHRlcm5hbFN1cHBvcnQsXHJcbiAgICAgIGhhc1NlcnZpY2VUYXNrTGlrZVN1cHBvcnQgPSBvcHRpb25zLmhhc1NlcnZpY2VUYXNrTGlrZVN1cHBvcnQsXHJcbiAgICAgIGhhc1NjcmlwdFN1cHBvcnQgPSBvcHRpb25zLmhhc1NjcmlwdFN1cHBvcnQ7XHJcblxyXG4gIHZhciBlbnRyaWVzID0gW107XHJcblxyXG4gIHZhciBzZWxlY3RPcHRpb25zID0gREVGQVVMVF9PUFRJT05TLmNvbmNhdChbXSk7XHJcblxyXG4gIGlmIChoYXNEbW5TdXBwb3J0KSB7XHJcbiAgICBzZWxlY3RPcHRpb25zID0gc2VsZWN0T3B0aW9ucy5jb25jYXQoRE1OX09QVElPTik7XHJcbiAgfVxyXG5cclxuICBpZiAoaGFzRXh0ZXJuYWxTdXBwb3J0KSB7XHJcbiAgICBzZWxlY3RPcHRpb25zID0gc2VsZWN0T3B0aW9ucy5jb25jYXQoRVhURVJOQUxfT1BUSU9OKTtcclxuICB9XHJcblxyXG4gIGlmIChoYXNTZXJ2aWNlVGFza0xpa2VTdXBwb3J0KSB7XHJcbiAgICBzZWxlY3RPcHRpb25zID0gc2VsZWN0T3B0aW9ucy5jb25jYXQoQ09OTkVDVE9SX09QVElPTik7XHJcbiAgfVxyXG5cclxuICBpZiAoaGFzU2NyaXB0U3VwcG9ydCkge1xyXG4gICAgc2VsZWN0T3B0aW9ucyA9IHNlbGVjdE9wdGlvbnMuY29uY2F0KFNDUklQVF9PUFRJT04pO1xyXG4gIH1cclxuXHJcbiAgc2VsZWN0T3B0aW9ucy5wdXNoKHsgdmFsdWU6ICcnIH0pO1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnNlbGVjdEJveCh7XHJcbiAgICBpZCA6ICdpbXBsZW1lbnRhdGlvbicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdJbXBsZW1lbnRhdGlvbicpLFxyXG4gICAgc2VsZWN0T3B0aW9uczogc2VsZWN0T3B0aW9ucyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdpbXBsVHlwZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgaW1wbFR5cGU6IGdldFR5cGUoZWxlbWVudCkgfHwgJydcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHZhciBvbGRUeXBlID0gZ2V0VHlwZShlbGVtZW50KTtcclxuICAgICAgdmFyIG5ld1R5cGUgPSB2YWx1ZXMuaW1wbFR5cGU7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIERFTEVHQVRFX1BST1BTKTtcclxuXHJcbiAgICAgIGlmIChERUZBVUxUX0RFTEVHQVRFX1BST1BTLmluZGV4T2YobmV3VHlwZSkgIT09IC0xKSB7XHJcblxyXG4gICAgICAgIHZhciBuZXdWYWx1ZSA9ICcnO1xyXG4gICAgICAgIGlmIChERUZBVUxUX0RFTEVHQVRFX1BST1BTLmluZGV4T2Yob2xkVHlwZSkgIT09IC0xKSB7XHJcbiAgICAgICAgICBuZXdWYWx1ZSA9IGJvLmdldCgnYWN0aXZpdGk6JyArIG9sZFR5cGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwcm9wc1snYWN0aXZpdGk6JyArIG5ld1R5cGVdID0gbmV3VmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChoYXNEbW5TdXBwb3J0KSB7XHJcbiAgICAgICAgcHJvcHMgPSBhc3NpZ24ocHJvcHMsIERNTl9DQVBBQkxFX1BST1BTKTtcclxuICAgICAgICBpZiAobmV3VHlwZSA9PT0gJ2RtbicpIHtcclxuICAgICAgICAgIHByb3BzWydhY3Rpdml0aTpkZWNpc2lvblJlZiddID0gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaGFzRXh0ZXJuYWxTdXBwb3J0KSB7XHJcbiAgICAgICAgcHJvcHMgPSBhc3NpZ24ocHJvcHMsIEVYVEVSTkFMX0NBUEFCTEVfUFJPUFMpO1xyXG4gICAgICAgIGlmIChuZXdUeXBlID09PSAnZXh0ZXJuYWwnKSB7XHJcbiAgICAgICAgICBwcm9wc1snYWN0aXZpdGk6dHlwZSddID0gJ2V4dGVybmFsJztcclxuICAgICAgICAgIHByb3BzWydhY3Rpdml0aTp0b3BpYyddID0gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaGFzU2NyaXB0U3VwcG9ydCkge1xyXG4gICAgICAgIHByb3BzWydhY3Rpdml0aTpzY3JpcHQnXSA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgaWYgKG5ld1R5cGUgPT09ICdzY3JpcHQnKSB7XHJcbiAgICAgICAgICBwcm9wc1snYWN0aXZpdGk6c2NyaXB0J10gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2FjdGl2aXRpOlNjcmlwdCcsIHt9LCBibywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGJvLCBwcm9wcykpO1xyXG5cclxuICAgICAgaWYgKGhhc1NlcnZpY2VUYXNrTGlrZVN1cHBvcnQpIHtcclxuICAgICAgICB2YXIgY29ubmVjdG9ycyA9IGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLmdldEV4dGVuc2lvbkVsZW1lbnRzKGJvLCAnYWN0aXZpdGk6Q29ubmVjdG9yJyk7XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChtYXAoY29ubmVjdG9ycywgZnVuY3Rpb24oY29ubmVjdG9yKSB7XHJcbiAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoYm8sIGVsZW1lbnQsIGNvbm5lY3Rvcik7XHJcbiAgICAgICAgfSkpO1xyXG5cclxuICAgICAgICBpZiAobmV3VHlwZSA9PT0gJ2Nvbm5lY3RvcicpIHtcclxuICAgICAgICAgIHZhciBleHRlbnNpb25FbGVtZW50cyA9IGJvLmdldCgnZXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuICAgICAgICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnLCB7IHZhbHVlczogW10gfSwgYm8sIGJwbW5GYWN0b3J5KTtcclxuICAgICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgZXh0ZW5zaW9uRWxlbWVudHM6IGV4dGVuc2lvbkVsZW1lbnRzIH0pKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHZhciBjb25uZWN0b3IgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2FjdGl2aXRpOkNvbm5lY3RvcicsIHt9LCBleHRlbnNpb25FbGVtZW50cywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgICAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAgICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICAgICAgICBbIGNvbm5lY3RvciBdLFxyXG4gICAgICAgICAgICBbXVxyXG4gICAgICAgICAgKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcblxyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXInKSxcclxuICAgIGlucHV0T3V0cHV0SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0lucHV0T3V0cHV0SGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgZXh0ZW5zaW9uRWxlbWVudHNFbnRyeSA9IHJlcXVpcmUoJy4vRXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuXHJcblxyXG5mdW5jdGlvbiBnZXRJbnB1dE91dHB1dChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICByZXR1cm4gaW5wdXRPdXRwdXRIZWxwZXIuZ2V0SW5wdXRPdXRwdXQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0Q29ubmVjdG9yKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaW5wdXRPdXRwdXRIZWxwZXIuZ2V0Q29ubmVjdG9yKGVsZW1lbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRJbnB1dFBhcmFtZXRlcnMoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSB7XHJcbiAgcmV0dXJuIGlucHV0T3V0cHV0SGVscGVyLmdldElucHV0UGFyYW1ldGVycyhlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRPdXRwdXRQYXJhbWV0ZXJzKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcikge1xyXG4gIHJldHVybiBpbnB1dE91dHB1dEhlbHBlci5nZXRPdXRwdXRQYXJhbWV0ZXJzKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcik7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldElucHV0UGFyYW1ldGVyKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KSB7XHJcbiAgcmV0dXJuIGlucHV0T3V0cHV0SGVscGVyLmdldElucHV0UGFyYW1ldGVyKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0T3V0cHV0UGFyYW1ldGVyKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KSB7XHJcbiAgcmV0dXJuIGlucHV0T3V0cHV0SGVscGVyLmdldE91dHB1dFBhcmFtZXRlcihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IsIGlkeCk7XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHR5cGUsIHBhcmVudCwgZmFjdG9yeSwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQodHlwZSwgcHJvcGVydGllcywgcGFyZW50LCBmYWN0b3J5KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlSW5wdXRPdXRwdXQocGFyZW50LCBicG1uRmFjdG9yeSwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiBjcmVhdGVFbGVtZW50KCdhY3Rpdml0aTpJbnB1dE91dHB1dCcsIHBhcmVudCwgYnBtbkZhY3RvcnksIHByb3BlcnRpZXMpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVQYXJhbWV0ZXIodHlwZSwgcGFyZW50LCBicG1uRmFjdG9yeSwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiBjcmVhdGVFbGVtZW50KHR5cGUsIHBhcmVudCwgYnBtbkZhY3RvcnksIHByb3BlcnRpZXMpO1xyXG59XHJcblxyXG5cclxuZnVuY3Rpb24gZW5zdXJlSW5wdXRPdXRwdXRTdXBwb3J0ZWQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSB7XHJcbiAgcmV0dXJuIGlucHV0T3V0cHV0SGVscGVyLmlzSW5wdXRPdXRwdXRTdXBwb3J0ZWQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZW5zdXJlT3V0cGFyYW1ldGVyU3VwcG9ydGVkKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcikge1xyXG4gIHJldHVybiBpbnB1dE91dHB1dEhlbHBlci5hcmVPdXRwdXRQYXJhbWV0ZXJzU3VwcG9ydGVkKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcik7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgVFlQRV9MQUJFTCA9IHtcclxuICAgICdhY3Rpdml0aTpNYXAnOiB0cmFuc2xhdGUoJ01hcCcpLFxyXG4gICAgJ2FjdGl2aXRpOkxpc3QnOiB0cmFuc2xhdGUoJ0xpc3QnKSxcclxuICAgICdhY3Rpdml0aTpTY3JpcHQnOiB0cmFuc2xhdGUoJ1NjcmlwdCcpXHJcbiAgfTtcclxuXHJcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG4gIHZhciBpbnNpZGVDb25uZWN0b3IgPSAhIW9wdGlvbnMuaW5zaWRlQ29ubmVjdG9yLFxyXG4gICAgICBpZFByZWZpeCA9IG9wdGlvbnMuaWRQcmVmaXggfHwgJyc7XHJcblxyXG4gIHZhciBnZXRTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciBzZWxlY3Rpb24gPSAoaW5wdXRFbnRyeSAmJiBpbnB1dEVudHJ5LmdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpKSB8fCB7IGlkeDogLTEgfTtcclxuXHJcbiAgICB2YXIgcGFyYW1ldGVyID0gZ2V0SW5wdXRQYXJhbWV0ZXIoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yLCBzZWxlY3Rpb24uaWR4KTtcclxuICAgIGlmICghcGFyYW1ldGVyICYmIG91dHB1dEVudHJ5KSB7XHJcbiAgICAgIHNlbGVjdGlvbiA9IG91dHB1dEVudHJ5LmdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICBwYXJhbWV0ZXIgPSBnZXRPdXRwdXRQYXJhbWV0ZXIoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yLCBzZWxlY3Rpb24uaWR4KTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXJhbWV0ZXI7XHJcbiAgfTtcclxuXHJcbiAgdmFyIHJlc3VsdCA9IHtcclxuICAgIGdldFNlbGVjdGVkUGFyYW1ldGVyOiBnZXRTZWxlY3RlZFxyXG4gIH07XHJcblxyXG4gIHZhciBlbnRyaWVzID0gcmVzdWx0LmVudHJpZXMgPSBbXTtcclxuXHJcbiAgaWYgKCFlbnN1cmVJbnB1dE91dHB1dFN1cHBvcnRlZChlbGVtZW50KSkge1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIHZhciBuZXdFbGVtZW50ID0gZnVuY3Rpb24odHlwZSwgcHJvcCwgZmFjdG9yeSkge1xyXG5cclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgdmFsdWUpIHtcclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcblxyXG4gICAgICB2YXIgaW5wdXRPdXRwdXQgPSBnZXRJbnB1dE91dHB1dChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG4gICAgICBpZiAoIWlucHV0T3V0cHV0KSB7XHJcbiAgICAgICAgdmFyIHBhcmVudCA9ICFpbnNpZGVDb25uZWN0b3IgPyBleHRlbnNpb25FbGVtZW50cyA6IGdldENvbm5lY3RvcihlbGVtZW50KTtcclxuICAgICAgICBpbnB1dE91dHB1dCA9IGNyZWF0ZUlucHV0T3V0cHV0KHBhcmVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgICAgIGlucHV0UGFyYW1ldGVyczogW10sXHJcbiAgICAgICAgICBvdXRwdXRQYXJhbWV0ZXJzOiBbXVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAoIWluc2lkZUNvbm5lY3Rvcikge1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgICAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAgICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICAgICAgICBbIGlucHV0T3V0cHV0IF0sXHJcbiAgICAgICAgICAgIFtdXHJcbiAgICAgICAgICApKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgcGFyZW50LCB7IGlucHV0T3V0cHV0OiBpbnB1dE91dHB1dCB9KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgbmV3RWxlbSA9IGNyZWF0ZVBhcmFtZXRlcih0eXBlLCBpbnB1dE91dHB1dCwgYnBtbkZhY3RvcnksIHsgbmFtZTogdmFsdWUgfSk7XHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLmFkZEVsZW1lbnRzVG9saXN0KGVsZW1lbnQsIGlucHV0T3V0cHV0LCBwcm9wLCBbIG5ld0VsZW0gXSkpO1xyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgcmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uKGdldHRlciwgcHJvcCwgb3RoZXJQcm9wKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24oZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGlucHV0T3V0cHV0ID0gZ2V0SW5wdXRPdXRwdXQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKTtcclxuICAgICAgdmFyIHBhcmFtZXRlciA9IGdldHRlcihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IsIGlkeCk7XHJcblxyXG4gICAgICB2YXIgY29tbWFuZHMgPSBbXTtcclxuICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIucmVtb3ZlRWxlbWVudHNGcm9tTGlzdChlbGVtZW50LCBpbnB1dE91dHB1dCwgcHJvcCwgbnVsbCwgWyBwYXJhbWV0ZXIgXSkpO1xyXG5cclxuICAgICAgdmFyIGZpcnN0TGVuZ3RoID0gaW5wdXRPdXRwdXQuZ2V0KHByb3ApLmxlbmd0aC0xO1xyXG4gICAgICB2YXIgc2Vjb25kTGVuZ3RoID0gKGlucHV0T3V0cHV0LmdldChvdGhlclByb3ApIHx8IFtdKS5sZW5ndGg7XHJcblxyXG4gICAgICBpZiAoIWZpcnN0TGVuZ3RoICYmICFzZWNvbmRMZW5ndGgpIHtcclxuXHJcbiAgICAgICAgaWYgKCFpbnNpZGVDb25uZWN0b3IpIHtcclxuICAgICAgICAgIGNvbW1hbmRzLnB1c2goZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksIGVsZW1lbnQsIGlucHV0T3V0cHV0KSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHZhciBjb25uZWN0b3IgPSBnZXRDb25uZWN0b3IoZWxlbWVudCk7XHJcbiAgICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBjb25uZWN0b3IsIHsgaW5wdXRPdXRwdXQ6IHVuZGVmaW5lZCB9KSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IGZ1bmN0aW9uKGdldHRlcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIG9wdGlvbiwgcHJvcGVydHksIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIHBhcmFtZXRlciA9IGdldHRlcihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IsIGlkeCk7XHJcblxyXG4gICAgICB2YXIgc3VmZml4ID0gJ1RleHQnO1xyXG5cclxuICAgICAgdmFyIGRlZmluaXRpb24gPSBwYXJhbWV0ZXIuZ2V0KCdkZWZpbml0aW9uJyk7XHJcbiAgICAgIGlmICh0eXBlb2YgZGVmaW5pdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICB2YXIgdHlwZSA9IGRlZmluaXRpb24uJHR5cGU7XHJcbiAgICAgICAgc3VmZml4ID0gVFlQRV9MQUJFTFt0eXBlXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgb3B0aW9uLnRleHQgPSAodmFsdWUgfHwgJycpICsgJyA6ICcgKyBzdWZmaXg7XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG5cclxuICAvLyBpbnB1dCBwYXJhbWV0ZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICB2YXIgaW5wdXRFbnRyeSA9IGV4dGVuc2lvbkVsZW1lbnRzRW50cnkoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkOiBpZFByZWZpeCArICdpbnB1dHMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSW5wdXQgUGFyYW1ldGVycycpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ25hbWUnLFxyXG4gICAgcHJlZml4OiAnSW5wdXQnLFxyXG4gICAgcmVzaXphYmxlOiB0cnVlLFxyXG5cclxuICAgIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQ6IG5ld0VsZW1lbnQoJ2FjdGl2aXRpOklucHV0UGFyYW1ldGVyJywgJ2lucHV0UGFyYW1ldGVycycpLFxyXG4gICAgcmVtb3ZlRXh0ZW5zaW9uRWxlbWVudDogcmVtb3ZlRWxlbWVudChnZXRJbnB1dFBhcmFtZXRlciwgJ2lucHV0UGFyYW1ldGVycycsICdvdXRwdXRQYXJhbWV0ZXJzJyksXHJcblxyXG4gICAgZ2V0RXh0ZW5zaW9uRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgcmV0dXJuIGdldElucHV0UGFyYW1ldGVycyhlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG4gICAgfSxcclxuXHJcbiAgICBvblNlbGVjdGlvbkNoYW5nZTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgZXZlbnQsIHNjb3BlKSB7XHJcbiAgICAgIG91dHB1dEVudHJ5ICYmIG91dHB1dEVudHJ5LmRlc2VsZWN0KGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKGdldElucHV0UGFyYW1ldGVyKVxyXG5cclxuICB9KTtcclxuICBlbnRyaWVzLnB1c2goaW5wdXRFbnRyeSk7XHJcblxyXG5cclxuICAvLyBvdXRwdXQgcGFyYW1ldGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIGlmIChlbnN1cmVPdXRwYXJhbWV0ZXJTdXBwb3J0ZWQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSkge1xyXG4gICAgdmFyIG91dHB1dEVudHJ5ID0gZXh0ZW5zaW9uRWxlbWVudHNFbnRyeShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgICBpZDogaWRQcmVmaXggKyAnb3V0cHV0cycsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ091dHB1dCBQYXJhbWV0ZXJzJyksXHJcbiAgICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuICAgICAgcHJlZml4OiAnT3V0cHV0JyxcclxuICAgICAgcmVzaXphYmxlOiB0cnVlLFxyXG5cclxuICAgICAgY3JlYXRlRXh0ZW5zaW9uRWxlbWVudDogbmV3RWxlbWVudCgnYWN0aXZpdGk6T3V0cHV0UGFyYW1ldGVyJywgJ291dHB1dFBhcmFtZXRlcnMnKSxcclxuICAgICAgcmVtb3ZlRXh0ZW5zaW9uRWxlbWVudDogcmVtb3ZlRWxlbWVudChnZXRPdXRwdXRQYXJhbWV0ZXIsICdvdXRwdXRQYXJhbWV0ZXJzJywgJ2lucHV0UGFyYW1ldGVycycpLFxyXG5cclxuICAgICAgZ2V0RXh0ZW5zaW9uRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gZ2V0T3V0cHV0UGFyYW1ldGVycyhlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgb25TZWxlY3Rpb25DaGFuZ2U6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50LCBzY29wZSkge1xyXG4gICAgICAgIGlucHV0RW50cnkuZGVzZWxlY3QoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKGdldE91dHB1dFBhcmFtZXRlcilcclxuXHJcbiAgICB9KTtcclxuICAgIGVudHJpZXMucHVzaChvdXRwdXRFbnRyeSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcmVzdWx0O1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcztcclxuXHJcbnZhciBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKSxcclxuICAgIGlucHV0T3V0cHV0SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0lucHV0T3V0cHV0SGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL1V0aWxzJyk7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIHNjcmlwdEltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9TY3JpcHQnKTtcclxuXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHR5cGUsIHBhcmVudCwgZmFjdG9yeSwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQodHlwZSwgcHJvcGVydGllcywgcGFyZW50LCBmYWN0b3J5KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNTY3JpcHQoZWxlbSkge1xyXG4gIHJldHVybiBpcyhlbGVtLCAnYWN0aXZpdGk6U2NyaXB0Jyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTGlzdChlbGVtKSB7XHJcbiAgcmV0dXJuIGlzKGVsZW0sICdhY3Rpdml0aTpMaXN0Jyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTWFwKGVsZW0pIHtcclxuICByZXR1cm4gaXMoZWxlbSwgJ2FjdGl2aXRpOk1hcCcpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBlbnN1cmVJbnB1dE91dHB1dFN1cHBvcnRlZChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICByZXR1cm4gaW5wdXRPdXRwdXRIZWxwZXIuaXNJbnB1dE91dHB1dFN1cHBvcnRlZChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIHR5cGVJbmZvID0ge1xyXG4gICAgJ2FjdGl2aXRpOk1hcCc6IHtcclxuICAgICAgdmFsdWU6ICdtYXAnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdNYXAnKVxyXG4gICAgfSxcclxuICAgICdhY3Rpdml0aTpMaXN0Jzoge1xyXG4gICAgICB2YWx1ZTogJ2xpc3QnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdMaXN0JylcclxuICAgIH0sXHJcbiAgICAnYWN0aXZpdGk6U2NyaXB0Jzoge1xyXG4gICAgICB2YWx1ZTogJ3NjcmlwdCcsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1NjcmlwdCcpXHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG4gIHZhciBpbnNpZGVDb25uZWN0b3IgPSAhIW9wdGlvbnMuaW5zaWRlQ29ubmVjdG9yLFxyXG4gICAgICBpZFByZWZpeCA9IG9wdGlvbnMuaWRQcmVmaXggfHwgJyc7XHJcblxyXG4gIHZhciBnZXRTZWxlY3RlZCA9IG9wdGlvbnMuZ2V0U2VsZWN0ZWRQYXJhbWV0ZXI7XHJcblxyXG4gIGlmICghZW5zdXJlSW5wdXRPdXRwdXRTdXBwb3J0ZWQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSkge1xyXG4gICAgcmV0dXJuIFtdO1xyXG4gIH1cclxuXHJcbiAgdmFyIGVudHJpZXMgPSBbXTtcclxuXHJcbiAgdmFyIGlzU2VsZWN0ZWQgPSBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICByZXR1cm4gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgfTtcclxuXHJcblxyXG4gIC8vIHBhcmFtZXRlciBuYW1lIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudmFsaWRhdGlvbkF3YXJlVGV4dEZpZWxkKHtcclxuICAgIGlkOiBpZFByZWZpeCArICdwYXJhbWV0ZXJOYW1lJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ05hbWUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuXHJcbiAgICBnZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gKGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpIHx8IHt9KS5uYW1lO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBwYXJhbSA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHBhcmFtLCB2YWx1ZXMpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIHZhbGlkYXRpb24gPSB7fTtcclxuICAgICAgaWYgKGJvKSB7XHJcbiAgICAgICAgdmFyIG5hbWVWYWx1ZSA9IHZhbHVlcy5uYW1lO1xyXG5cclxuICAgICAgICBpZiAobmFtZVZhbHVlKSB7XHJcbiAgICAgICAgICBpZiAodXRpbHMuY29udGFpbnNTcGFjZShuYW1lVmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHZhbGlkYXRpb24ubmFtZSA9IHRyYW5zbGF0ZSgnTmFtZSBtdXN0IG5vdCBjb250YWluIHNwYWNlcycpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB2YWxpZGF0aW9uLm5hbWUgPSB0cmFuc2xhdGUoJ1BhcmFtZXRlciBtdXN0IGhhdmUgYSBuYW1lJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdmFsaWRhdGlvbjtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhaXNTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG5cclxuICAvLyBwYXJhbWV0ZXIgdHlwZSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgdmFyIHNlbGVjdE9wdGlvbnMgPSBbXHJcbiAgICB7IHZhbHVlOiAndGV4dCcsIG5hbWU6IHRyYW5zbGF0ZSgnVGV4dCcpIH0sXHJcbiAgICB7IHZhbHVlOiAnc2NyaXB0JywgbmFtZTogdHJhbnNsYXRlKCdTY3JpcHQnKSB9LFxyXG4gICAgeyB2YWx1ZTogJ2xpc3QnLCBuYW1lOiB0cmFuc2xhdGUoJ0xpc3QnKSB9LFxyXG4gICAgeyB2YWx1ZTogJ21hcCcsIG5hbWU6IHRyYW5zbGF0ZSgnTWFwJykgfVxyXG4gIF07XHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3Rvcnkuc2VsZWN0Qm94KHtcclxuICAgIGlkIDogaWRQcmVmaXggKyAncGFyYW1ldGVyVHlwZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdUeXBlJyksXHJcbiAgICBzZWxlY3RPcHRpb25zOiBzZWxlY3RPcHRpb25zLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3BhcmFtZXRlclR5cGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICAgIHZhciBwYXJhbWV0ZXJUeXBlID0gJ3RleHQnO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiBibyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICB2YXIgZGVmaW5pdGlvbiA9IGJvLmdldCgnZGVmaW5pdGlvbicpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgZGVmaW5pdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgIHZhciB0eXBlID0gZGVmaW5pdGlvbi4kdHlwZTtcclxuICAgICAgICAgIHBhcmFtZXRlclR5cGUgPSB0eXBlSW5mb1t0eXBlXS52YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgcGFyYW1ldGVyVHlwZTogcGFyYW1ldGVyVHlwZVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICAgIHZhciBwcm9wZXJ0aWVzID0ge1xyXG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXHJcbiAgICAgICAgZGVmaW5pdGlvbjogdW5kZWZpbmVkXHJcbiAgICAgIH07XHJcblxyXG4gICAgICB2YXIgY3JlYXRlUGFyYW1ldGVyVHlwZUVsZW0gPSBmdW5jdGlvbih0eXBlKSB7XHJcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUVsZW1lbnQodHlwZSwgYm8sIGJwbW5GYWN0b3J5KTtcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBwYXJhbWV0ZXJUeXBlID0gdmFsdWVzLnBhcmFtZXRlclR5cGU7XHJcblxyXG4gICAgICBpZiAocGFyYW1ldGVyVHlwZSA9PT0gJ3NjcmlwdCcpIHtcclxuICAgICAgICBwcm9wZXJ0aWVzLmRlZmluaXRpb24gPSBjcmVhdGVQYXJhbWV0ZXJUeXBlRWxlbSgnYWN0aXZpdGk6U2NyaXB0Jyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAocGFyYW1ldGVyVHlwZSA9PT0gJ2xpc3QnKSB7XHJcbiAgICAgICAgcHJvcGVydGllcy5kZWZpbml0aW9uID0gY3JlYXRlUGFyYW1ldGVyVHlwZUVsZW0oJ2FjdGl2aXRpOkxpc3QnKTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmIChwYXJhbWV0ZXJUeXBlID09PSAnbWFwJykge1xyXG4gICAgICAgIHByb3BlcnRpZXMuZGVmaW5pdGlvbiA9IGNyZWF0ZVBhcmFtZXRlclR5cGVFbGVtKCdhY3Rpdml0aTpNYXAnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBibywgcHJvcGVydGllcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNob3c6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIC8vIHBhcmFtZXRlciB2YWx1ZSAodHlwZSA9IHRleHQpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0Qm94KHtcclxuICAgIGlkIDogaWRQcmVmaXggKyAncGFyYW1ldGVyVHlwZS10ZXh0JyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdWYWx1ZScpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3ZhbHVlJyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHZhbHVlOiAoZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSkgfHwge30pLnZhbHVlXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBwYXJhbSA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB2YWx1ZXMudmFsdWUgPSB2YWx1ZXMudmFsdWUgfHwgdW5kZWZpbmVkO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHBhcmFtLCB2YWx1ZXMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzaG93OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gYm8gJiYgIWJvLmRlZmluaXRpb247XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIC8vIHBhcmFtZXRlciB2YWx1ZSAodHlwZSA9IHNjcmlwdCkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG4gIHZhciBzY3JpcHQgPSBzY3JpcHRJbXBsZW1lbnRhdGlvbignc2NyaXB0Rm9ybWF0JywgJ3ZhbHVlJywgdHJ1ZSwgdHJhbnNsYXRlKTtcclxuICBlbnRyaWVzLnB1c2goe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ3BhcmFtZXRlclR5cGUtc2NyaXB0JyxcclxuICAgIGh0bWw6ICc8ZGl2IGRhdGEtc2hvdz1cImlzU2NyaXB0XCI+JyArXHJcbiAgICAgICAgICAgIHNjcmlwdC50ZW1wbGF0ZSArXHJcbiAgICAgICAgICAnPC9kaXY+JyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGJvICYmIGlzU2NyaXB0KGJvLmRlZmluaXRpb24pID8gc2NyaXB0LmdldChlbGVtZW50LCBiby5kZWZpbml0aW9uKSA6IHt9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIHVwZGF0ZSA9IHNjcmlwdC5zZXQoZWxlbWVudCwgdmFsdWVzKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBiby5kZWZpbml0aW9uLCB1cGRhdGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gYm8gJiYgaXNTY3JpcHQoYm8uZGVmaW5pdGlvbikgPyBzY3JpcHQudmFsaWRhdGUoZWxlbWVudCwgYm8uZGVmaW5pdGlvbikgOiB7fTtcclxuICAgIH0sXHJcblxyXG4gICAgaXNTY3JpcHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiBibyAmJiBpc1NjcmlwdChiby5kZWZpbml0aW9uKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2NyaXB0OiBzY3JpcHRcclxuXHJcbiAgfSk7XHJcblxyXG5cclxuICAvLyBwYXJhbWV0ZXIgdmFsdWUgKHR5cGUgPSBsaXN0KSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGFibGUoe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ3BhcmFtZXRlclR5cGUtbGlzdCcsXHJcbiAgICBtb2RlbFByb3BlcnRpZXM6IFsgJ3ZhbHVlJyBdLFxyXG4gICAgbGFiZWxzOiBbIHRyYW5zbGF0ZSgnVmFsdWUnKSBdLFxyXG4gICAgYWRkTGFiZWw6IHRyYW5zbGF0ZSgnQWRkIFZhbHVlJyksXHJcblxyXG4gICAgZ2V0RWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICBpZiAoYm8gJiYgaXNMaXN0KGJvLmRlZmluaXRpb24pKSB7XHJcbiAgICAgICAgcmV0dXJuIGJvLmRlZmluaXRpb24uaXRlbXM7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBbXTtcclxuICAgIH0sXHJcblxyXG4gICAgdXBkYXRlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlLCBpZHgpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBpdGVtID0gYm8uZGVmaW5pdGlvbi5pdGVtc1tpZHhdO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGl0ZW0sIHZhbHVlcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBuZXdWYWx1ZSA9IGNyZWF0ZUVsZW1lbnQoJ2FjdGl2aXRpOlZhbHVlJywgYm8uZGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIHsgdmFsdWU6IHVuZGVmaW5lZCB9KTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBiby5kZWZpbml0aW9uLCAnaXRlbXMnLCBbIG5ld1ZhbHVlIF0pO1xyXG4gICAgfSxcclxuXHJcbiAgICByZW1vdmVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBpZHgpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIucmVtb3ZlRWxlbWVudHNGcm9tTGlzdChlbGVtZW50LCBiby5kZWZpbml0aW9uLCAnaXRlbXMnLCBudWxsLCBbIGJvLmRlZmluaXRpb24uaXRlbXNbaWR4XSBdKTtcclxuICAgIH0sXHJcblxyXG4gICAgZWRpdGFibGU6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIHByb3AsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGl0ZW0gPSBiby5kZWZpbml0aW9uLml0ZW1zW2lkeF07XHJcbiAgICAgIHJldHVybiAhaXNNYXAoaXRlbSkgJiYgIWlzTGlzdChpdGVtKSAmJiAhaXNTY3JpcHQoaXRlbSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldENvbnRyb2xWYWx1ZTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgaW5wdXQsIHByb3AsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBpdGVtID0gYm8uZGVmaW5pdGlvbi5pdGVtc1tpZHhdO1xyXG5cclxuICAgICAgaWYgKCFpc01hcChpdGVtKSAmJiAhaXNMaXN0KGl0ZW0pICYmICFpc1NjcmlwdChpdGVtKSkge1xyXG4gICAgICAgIGlucHV0LnZhbHVlID0gdmFsdWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaW5wdXQudmFsdWUgPSB0eXBlSW5mb1tpdGVtLiR0eXBlXS5sYWJlbDtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBzaG93OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gYm8gJiYgYm8uZGVmaW5pdGlvbiAmJiBpc0xpc3QoYm8uZGVmaW5pdGlvbik7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIC8vIHBhcmFtZXRlciB2YWx1ZSAodHlwZSA9IG1hcCkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRhYmxlKHtcclxuICAgIGlkOiBpZFByZWZpeCArICdwYXJhbWV0ZXJUeXBlLW1hcCcsXHJcbiAgICBtb2RlbFByb3BlcnRpZXM6IFsgJ2tleScsICd2YWx1ZScgXSxcclxuICAgIGxhYmVsczogWyB0cmFuc2xhdGUoJ0tleScpLCB0cmFuc2xhdGUoJ1ZhbHVlJykgXSxcclxuICAgIGFkZExhYmVsOiB0cmFuc2xhdGUoJ0FkZCBFbnRyeScpLFxyXG5cclxuICAgIGdldEVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgaWYgKGJvICYmIGlzTWFwKGJvLmRlZmluaXRpb24pKSB7XHJcbiAgICAgICAgcmV0dXJuIGJvLmRlZmluaXRpb24uZW50cmllcztcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGVudHJ5ID0gYm8uZGVmaW5pdGlvbi5lbnRyaWVzW2lkeF07XHJcblxyXG4gICAgICBpZiAoaXNNYXAoZW50cnkuZGVmaW5pdGlvbikgfHwgaXNMaXN0KGVudHJ5LmRlZmluaXRpb24pIHx8IGlzU2NyaXB0KGVudHJ5LmRlZmluaXRpb24pKSB7XHJcbiAgICAgICAgdmFsdWVzID0ge1xyXG4gICAgICAgICAga2V5OiB2YWx1ZXMua2V5XHJcbiAgICAgICAgfTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBlbnRyeSwgdmFsdWVzKTtcclxuICAgIH0sXHJcblxyXG4gICAgYWRkRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIG5ld0VudHJ5ID0gY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6RW50cnknLCBiby5kZWZpbml0aW9uLCBicG1uRmFjdG9yeSwgeyBrZXk6IHVuZGVmaW5lZCwgdmFsdWU6IHVuZGVmaW5lZCB9KTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBiby5kZWZpbml0aW9uLCAnZW50cmllcycsIFsgbmV3RW50cnkgXSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlbW92ZUVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci5yZW1vdmVFbGVtZW50c0Zyb21MaXN0KGVsZW1lbnQsIGJvLmRlZmluaXRpb24sICdlbnRyaWVzJywgbnVsbCwgWyBiby5kZWZpbml0aW9uLmVudHJpZXNbaWR4XSBdKTtcclxuICAgIH0sXHJcblxyXG4gICAgZWRpdGFibGU6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIHByb3AsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGVudHJ5ID0gYm8uZGVmaW5pdGlvbi5lbnRyaWVzW2lkeF07XHJcbiAgICAgIHJldHVybiBwcm9wID09PSAna2V5JyB8fCAoIWlzTWFwKGVudHJ5LmRlZmluaXRpb24pICYmICFpc0xpc3QoZW50cnkuZGVmaW5pdGlvbikgJiYgIWlzU2NyaXB0KGVudHJ5LmRlZmluaXRpb24pKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0Q29udHJvbFZhbHVlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBpbnB1dCwgcHJvcCwgdmFsdWUsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGVudHJ5ID0gYm8uZGVmaW5pdGlvbi5lbnRyaWVzW2lkeF07XHJcblxyXG4gICAgICBpZiAocHJvcCA9PT0gJ2tleScgfHwgKCFpc01hcChlbnRyeS5kZWZpbml0aW9uKSAmJiAhaXNMaXN0KGVudHJ5LmRlZmluaXRpb24pICYmICFpc1NjcmlwdChlbnRyeS5kZWZpbml0aW9uKSkpIHtcclxuICAgICAgICBpbnB1dC52YWx1ZSA9IHZhbHVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlucHV0LnZhbHVlID0gdHlwZUluZm9bZW50cnkuZGVmaW5pdGlvbi4kdHlwZV0ubGFiZWw7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgc2hvdzogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGJvICYmIGJvLmRlZmluaXRpb24gJiYgaXNNYXAoYm8uZGVmaW5pdGlvbik7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gb3B0aW9ucy5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbiAgdmFyIGpvYlByaW9yaXR5RW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnam9iUHJpb3JpdHknLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSm9iIFByaW9yaXR5JyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnam9iUHJpb3JpdHknLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBqb2JQcmlvcml0eTogYm8uZ2V0KCdhY3Rpdml0aTpqb2JQcmlvcml0eScpXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGJvLCB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOmpvYlByaW9yaXR5JzogdmFsdWVzLmpvYlByaW9yaXR5IHx8IHVuZGVmaW5lZFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBbIGpvYlByaW9yaXR5RW50cnkgXTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBhc3luY0NhcGFibGVIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQXN5bmNDYXBhYmxlSGVscGVyJyk7XHJcblxyXG52YXIgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyksXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5mdW5jdGlvbiBpc0FzeW5jQmVmb3JlKGJvKSB7XHJcbiAgcmV0dXJuIGFzeW5jQ2FwYWJsZUhlbHBlci5pc0FzeW5jQmVmb3JlKGJvKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNBc3luY0FmdGVyKGJvKSB7XHJcbiAgcmV0dXJuIGFzeW5jQ2FwYWJsZUhlbHBlci5pc0FzeW5jQWZ0ZXIoYm8pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibykge1xyXG4gIHJldHVybiBhc3luY0NhcGFibGVIZWxwZXIuZ2V0RmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUoYm8pO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibywgZWxlbWVudCkge1xyXG4gIHJldHVybiBhc3luY0NhcGFibGVIZWxwZXIucmVtb3ZlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUoYm8sIGVsZW1lbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVFeHRlbnNpb25FbGVtZW50cyhwYXJlbnQsIGJwbW5GYWN0b3J5KSB7XHJcbiAgcmV0dXJuIGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYnBtbjpFeHRlbnNpb25FbGVtZW50cycsIHsgdmFsdWVzOiBbXSB9LCBwYXJlbnQsIGJwbW5GYWN0b3J5KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUocGFyZW50LCBicG1uRmFjdG9yeSwgY3ljbGUpIHtcclxuICByZXR1cm4gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZScsIHsgYm9keTogY3ljbGUgfSwgcGFyZW50LCBicG1uRmFjdG9yeSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICB2YXIgaWRQcmVmaXggPSBvcHRpb25zLmlkUHJlZml4IHx8ICcnLFxyXG4gICAgICBsYWJlbFByZWZpeCA9IG9wdGlvbnMubGFiZWxQcmVmaXggfHwgJyc7XHJcblxyXG4gIHZhciByZXRyeVRpbWVDeWNsZUVudHJ5ID0gZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogaWRQcmVmaXggKyAncmV0cnlUaW1lQ3ljbGUnLFxyXG4gICAgbGFiZWw6IGxhYmVsUHJlZml4ICsgdHJhbnNsYXRlKCdSZXRyeSBUaW1lIEN5Y2xlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY3ljbGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgcmV0cnlUaW1lQ3ljbGUgPSBnZXRGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSk7XHJcbiAgICAgIHZhciB2YWx1ZSA9IHJldHJ5VGltZUN5Y2xlICYmIHJldHJ5VGltZUN5Y2xlLmdldCgnYm9keScpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGN5Y2xlOiB2YWx1ZVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgbmV3Q3ljbGUgPSB2YWx1ZXMuY3ljbGU7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgaWYgKG5ld0N5Y2xlID09PSAnJyB8fCB0eXBlb2YgbmV3Q3ljbGUgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgLy8gcmVtb3ZlIHJldHJ5IHRpbWUgY3ljbGUgZWxlbWVudChzKVxyXG4gICAgICAgIHJldHVybiByZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibywgZWxlbWVudCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciByZXRyeVRpbWVDeWNsZSA9IGdldEZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGJvKTtcclxuXHJcbiAgICAgIGlmICghcmV0cnlUaW1lQ3ljbGUpIHtcclxuICAgICAgICAvLyBhZGQgbmV3IHJldHJ5IHRpbWUgY3ljbGUgZWxlbWVudFxyXG4gICAgICAgIHZhciBjb21tYW5kcyA9IFtdO1xyXG5cclxuICAgICAgICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBiby5nZXQoJ2V4dGVuc2lvbkVsZW1lbnRzJyk7XHJcbiAgICAgICAgaWYgKCFleHRlbnNpb25FbGVtZW50cykge1xyXG4gICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBjcmVhdGVFeHRlbnNpb25FbGVtZW50cyhibywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgZXh0ZW5zaW9uRWxlbWVudHM6IGV4dGVuc2lvbkVsZW1lbnRzIH0pKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHJ5VGltZUN5Y2xlID0gY3JlYXRlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUoZXh0ZW5zaW9uRWxlbWVudHMsIGJwbW5GYWN0b3J5LCBuZXdDeWNsZSk7XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgICAgIGVsZW1lbnQsXHJcbiAgICAgICAgICBleHRlbnNpb25FbGVtZW50cyxcclxuICAgICAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAgICAgJ2V4dGVuc2lvbkVsZW1lbnRzJyxcclxuICAgICAgICAgIFsgcmV0cnlUaW1lQ3ljbGUgXSxcclxuICAgICAgICAgIFtdXHJcbiAgICAgICAgKSk7XHJcblxyXG4gICAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gdXBkYXRlIGV4aXN0aW5nIHJldHJ5IHRpbWUgY3ljbGUgZWxlbWVudFxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHJldHJ5VGltZUN5Y2xlLCB7IGJvZHk6IG5ld0N5Y2xlIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAoYm8gJiYgKGlzQXN5bmNCZWZvcmUoYm8pIHx8IGlzQXN5bmNBZnRlcihibykpKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSkge1xyXG4gICAgICAgIHJldHVybiAhZXZlbnREZWZpbml0aW9uSGVscGVyLmdldFRpbWVyRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBbIHJldHJ5VGltZUN5Y2xlRW50cnkgXTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgZXh0ZW5zaW9uRWxlbWVudHNFbnRyeSA9IHJlcXVpcmUoJy4vRXh0ZW5zaW9uRWxlbWVudHMnKSxcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKSxcclxuICAgIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXInKTtcclxuXHJcblxyXG5mdW5jdGlvbiBnZXRMaXN0ZW5lcnMoYm8sIHR5cGUpIHtcclxuICByZXR1cm4gYm8gJiYgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sIHR5cGUpIHx8IFtdO1xyXG59XHJcblxyXG52YXIgQUNUSVZJVElfRVhFQ1VUSU9OX0xJU1RFTkVSX0VMRU1FTlQgPSAnYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXInO1xyXG52YXIgQUNUSVZJVElfVEFTS19MSVNURU5FUl9FTEVNRU5UID0gJ2FjdGl2aXRpOlRhc2tMaXN0ZW5lcic7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIExJU1RFTkVSX1RZUEVfTEFCRUwgPSB7XHJcbiAgICBjbGFzczogdHJhbnNsYXRlKCdKYXZhIENsYXNzJyksXHJcbiAgICBleHByZXNzaW9uOiB0cmFuc2xhdGUoJ0V4cHJlc3Npb24nKSxcclxuICAgIGRlbGVnYXRlRXhwcmVzc2lvbjogdHJhbnNsYXRlKCdEZWxlZ2F0ZSBFeHByZXNzaW9uJyksXHJcbiAgICBzY3JpcHQ6IHRyYW5zbGF0ZSgnU2NyaXB0JylcclxuICB9O1xyXG5cclxuICB2YXIgYm87XHJcblxyXG4gIHZhciByZXN1bHQgPSB7XHJcbiAgICBnZXRTZWxlY3RlZExpc3RlbmVyOiBnZXRTZWxlY3RlZExpc3RlbmVyXHJcbiAgfTtcclxuXHJcbiAgdmFyIGVudHJpZXMgPSByZXN1bHQuZW50cmllcyA9IFtdO1xyXG5cclxuICB2YXIgaXNTZXF1ZW5jZUZsb3cgPSBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuaXNTZXF1ZW5jZUZsb3coZWxlbWVudCk7XHJcblxyXG4gIGZ1bmN0aW9uIGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSkge1xyXG4gICAgdmFyIHNlbGVjdGlvbiA9IChleGVjdXRpb25MaXN0ZW5lckVudHJ5ICYmIGV4ZWN1dGlvbkxpc3RlbmVyRW50cnkuZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSkpIHx8IHsgaWR4OiAtMSB9O1xyXG5cclxuICAgIHZhciBsaXN0ZW5lciA9IGdldExpc3RlbmVycyhibywgQUNUSVZJVElfRVhFQ1VUSU9OX0xJU1RFTkVSX0VMRU1FTlQpW3NlbGVjdGlvbi5pZHhdO1xyXG4gICAgaWYgKCFsaXN0ZW5lciAmJiB0YXNrTGlzdGVuZXJFbnRyeSkge1xyXG4gICAgICBzZWxlY3Rpb24gPSB0YXNrTGlzdGVuZXJFbnRyeS5nZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgbGlzdGVuZXIgPSBnZXRMaXN0ZW5lcnMoYm8sIEFDVElWSVRJX1RBU0tfTElTVEVORVJfRUxFTUVOVClbc2VsZWN0aW9uLmlkeF07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGlzdGVuZXI7XHJcbiAgfVxyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBvcHRpb24sIHByb3BlcnR5LCB2YWx1ZSwgaWR4KSB7XHJcbiAgICAgIHZhciBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnMoYm8sIHR5cGUpO1xyXG4gICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaWR4XTtcclxuICAgICAgdmFyIGxpc3RlbmVyVHlwZSA9IEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRJbXBsZW1lbnRhdGlvblR5cGUobGlzdGVuZXIpO1xyXG5cclxuICAgICAgdmFyIGV2ZW50ID0gKGxpc3RlbmVyLmdldCgnZXZlbnQnKSkgPyBsaXN0ZW5lci5nZXQoJ2V2ZW50JykgOiAnPGVtcHR5Pic7XHJcblxyXG4gICAgICB2YXIgbGFiZWwgPSAoZXZlbnQgfHwgJyonKSArICcgOiAnICsgKExJU1RFTkVSX1RZUEVfTEFCRUxbbGlzdGVuZXJUeXBlXSB8fCAnJyk7XHJcblxyXG4gICAgICBvcHRpb24udGV4dCA9IGxhYmVsO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgbmV3RWxlbWVudCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHR5cGUsIGluaXRpYWxFdmVudCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCB2YWx1ZSkge1xyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgZXZlbnQ6IGluaXRpYWxFdmVudCxcclxuICAgICAgICBjbGFzczogJydcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBuZXdFbGVtID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KHR5cGUsIHByb3BzLCBleHRlbnNpb25FbGVtZW50cywgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgJ3ZhbHVlcycsIFsgbmV3RWxlbSBdKTtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgdmFyIHJlbW92ZUVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50LCB0eXBlKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24oZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGxpc3RlbmVycyA9IGdldExpc3RlbmVycyhibywgdHlwZSk7XHJcbiAgICAgIHZhciBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpZHhdO1xyXG4gICAgICBpZiAobGlzdGVuZXIpIHtcclxuICAgICAgICByZXR1cm4gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoYm8sIGVsZW1lbnQsIGxpc3RlbmVyKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuICB9O1xyXG5cclxuXHJcbiAgLy8gRXhlY3V0aW9uIExpc3RlbmVyXHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpGbG93RWxlbWVudCcpIHx8IGlzKGVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSB8fCBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuICAgICAgZWxlbWVudCA9IGVsZW1lbnQucHJvY2Vzc1JlZjtcclxuICAgICAgYm8gPSBiby5nZXQoJ3Byb2Nlc3NSZWYnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoYm8pIHtcclxuXHJcbiAgICAgIHZhciBleGVjdXRpb25MaXN0ZW5lckVudHJ5ID0gZXh0ZW5zaW9uRWxlbWVudHNFbnRyeShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgICAgIGlkIDogJ2V4ZWN1dGlvbkxpc3RlbmVycycsXHJcbiAgICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0V4ZWN1dGlvbiBMaXN0ZW5lcicpLFxyXG4gICAgICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuICAgICAgICBpZEdlbmVyYXRpb246ICdmYWxzZScsXHJcbiAgICAgICAgcmVmZXJlbmNlOiAncHJvY2Vzc1JlZicsXHJcblxyXG4gICAgICAgIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQ6IG5ld0VsZW1lbnQoZWxlbWVudCwgQUNUSVZJVElfRVhFQ1VUSU9OX0xJU1RFTkVSX0VMRU1FTlQsIChpc1NlcXVlbmNlRmxvdykgPyAndGFrZScgOiAnc3RhcnQnKSxcclxuICAgICAgICByZW1vdmVFeHRlbnNpb25FbGVtZW50OiByZW1vdmVFbGVtZW50KGVsZW1lbnQsIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUl9FTEVNRU5UKSxcclxuXHJcbiAgICAgICAgZ2V0RXh0ZW5zaW9uRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICAgIHJldHVybiBnZXRMaXN0ZW5lcnMoYm8sIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUl9FTEVNRU5UKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBvblNlbGVjdGlvbkNoYW5nZTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgZXZlbnQsIHNjb3BlKSB7XHJcbiAgICAgICAgICB0YXNrTGlzdGVuZXJFbnRyeSAmJiB0YXNrTGlzdGVuZXJFbnRyeS5kZXNlbGVjdChlbGVtZW50LCBub2RlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUl9FTEVNRU5UKVxyXG5cclxuICAgICAgfSk7XHJcbiAgICAgIGVudHJpZXMucHVzaChleGVjdXRpb25MaXN0ZW5lckVudHJ5KTtcclxuXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcbiAgLy8gVGFzayBMaXN0ZW5lclxyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46VXNlclRhc2snKSkge1xyXG4gICAgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICB2YXIgdGFza0xpc3RlbmVyRW50cnkgPSBleHRlbnNpb25FbGVtZW50c0VudHJ5KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGlkIDogJ3Rhc2tMaXN0ZW5lcnMnLFxyXG4gICAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnVGFzayBMaXN0ZW5lcicpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5OiAnbmFtZScsXHJcbiAgICAgIGlkR2VuZXJhdGlvbjogJ2ZhbHNlJyxcclxuXHJcbiAgICAgIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQ6IG5ld0VsZW1lbnQoZWxlbWVudCwgQUNUSVZJVElfVEFTS19MSVNURU5FUl9FTEVNRU5ULCAnY3JlYXRlJyksXHJcbiAgICAgIHJlbW92ZUV4dGVuc2lvbkVsZW1lbnQ6IHJlbW92ZUVsZW1lbnQoZWxlbWVudCwgQUNUSVZJVElfVEFTS19MSVNURU5FUl9FTEVNRU5UKSxcclxuXHJcbiAgICAgIGdldEV4dGVuc2lvbkVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGdldExpc3RlbmVycyhibywgQUNUSVZJVElfVEFTS19MSVNURU5FUl9FTEVNRU5UKTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIG9uU2VsZWN0aW9uQ2hhbmdlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBldmVudCwgc2NvcGUpIHtcclxuICAgICAgICBleGVjdXRpb25MaXN0ZW5lckVudHJ5LmRlc2VsZWN0KGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgc2V0T3B0aW9uTGFiZWxWYWx1ZTogc2V0T3B0aW9uTGFiZWxWYWx1ZShBQ1RJVklUSV9UQVNLX0xJU1RFTkVSX0VMRU1FTlQpXHJcblxyXG4gICAgfSk7XHJcbiAgICBlbnRyaWVzLnB1c2godGFza0xpc3RlbmVyRW50cnkpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHJlc3VsdDtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBlc2NhcGVIVE1MID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vVXRpbHMnKS5lc2NhcGVIVE1MO1xyXG5cclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxudmFyIGRvbUNsYXNzZXMgPSByZXF1aXJlKCdtaW4tZG9tJykuY2xhc3NlcztcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgbG9vcCBjaGFyYWN0ZXJpc3RpY3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BlcnR5TmFtZVxyXG4gKlxyXG4gKiBAcmV0dXJuIHthbnl9IHRoZSBwcm9wZXJ0eSB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UHJvcGVydHkoZWxlbWVudCwgcHJvcGVydHlOYW1lKSB7XHJcbiAgdmFyIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSBnZXRMb29wQ2hhcmFjdGVyaXN0aWNzKGVsZW1lbnQpO1xyXG4gIHJldHVybiBsb29wQ2hhcmFjdGVyaXN0aWNzICYmIGxvb3BDaGFyYWN0ZXJpc3RpY3MuZ2V0KHByb3BlcnR5TmFtZSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIGJvZHkgb2YgYSBnaXZlbiBleHByZXNzaW9uLlxyXG4gKlxyXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnQ8YnBtbjpGb3JtYWxFeHByZXNzaW9uPn0gZXhwcmVzc2lvblxyXG4gKlxyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBib2R5ICh2YWx1ZSkgb2YgdGhlIGV4cHJlc3Npb25cclxuICovXHJcbmZ1bmN0aW9uIGdldEJvZHkoZXhwcmVzc2lvbikge1xyXG4gIHJldHVybiBleHByZXNzaW9uICYmIGV4cHJlc3Npb24uZ2V0KCdib2R5Jyk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogR2V0IHRoZSBsb29wIGNoYXJhY3RlcmlzdGljcyBvZiBhbiBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnQ8YnBtbjpNdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljcz59IHRoZSBsb29wIGNoYXJhY3RlcmlzdGljc1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0TG9vcENoYXJhY3RlcmlzdGljcyhlbGVtZW50KSB7XHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgcmV0dXJuIGJvLmxvb3BDaGFyYWN0ZXJpc3RpY3M7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIGxvb3AgY2FyZGluYWxpdHkgb2YgdGhlIGxvb3AgY2hhcmFjdGVyaXN0aWNzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnQ8YnBtbjpGb3JtYWxFeHByZXNzaW9uPn0gYW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGxvb3AgY2FyZGluYWxpdHlcclxuICovXHJcbmZ1bmN0aW9uIGdldExvb3BDYXJkaW5hbGl0eShlbGVtZW50KSB7XHJcbiAgcmV0dXJuIGdldFByb3BlcnR5KGVsZW1lbnQsICdsb29wQ2FyZGluYWxpdHknKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgbG9vcCBjYXJkaW5hbGl0eSB2YWx1ZSBvZiB0aGUgbG9vcCBjaGFyYWN0ZXJpc3RpY3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgbG9vcCBjYXJkaW5hbGl0eSB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0TG9vcENhcmRpbmFsaXR5VmFsdWUoZWxlbWVudCkge1xyXG4gIHZhciBsb29wQ2FyZGluYWxpdHkgPSBnZXRMb29wQ2FyZGluYWxpdHkoZWxlbWVudCk7XHJcbiAgcmV0dXJuIGdldEJvZHkobG9vcENhcmRpbmFsaXR5KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgY29tcGxldGlvbiBjb25kaXRpb24gb2YgdGhlIGxvb3AgY2hhcmFjdGVyaXN0aWNzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnQ8YnBtbjpGb3JtYWxFeHByZXNzaW9uPn0gYW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBsZXRpb24gY29uZGl0aW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRDb21wbGV0aW9uQ29uZGl0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gZ2V0UHJvcGVydHkoZWxlbWVudCwgJ2NvbXBsZXRpb25Db25kaXRpb24nKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgY29tcGxldGlvbiBjb25kaXRpb24gdmFsdWUgb2YgdGhlIGxvb3AgY2hhcmFjdGVyaXN0aWNzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIGNvbXBsZXRpb24gY29uZGl0aW9uIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRDb21wbGV0aW9uQ29uZGl0aW9uVmFsdWUoZWxlbWVudCkge1xyXG4gIHZhciBjb21wbGV0aW9uQ29uZGl0aW9uID0gZ2V0Q29tcGxldGlvbkNvbmRpdGlvbihlbGVtZW50KTtcclxuICByZXR1cm4gZ2V0Qm9keShjb21wbGV0aW9uQ29uZGl0aW9uKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgJ2FjdGl2aXRpOmNvbGxlY3Rpb24nIGF0dHJpYnV0ZSB2YWx1ZSBvZiB0aGUgbG9vcCBjaGFyYWN0ZXJpc3RpY3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgJ2FjdGl2aXRpOmNvbGxlY3Rpb24nIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRDb2xsZWN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gZ2V0UHJvcGVydHkoZWxlbWVudCwgJ2FjdGl2aXRpOmNvbGxlY3Rpb24nKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgJ2FjdGl2aXRpOmVsZW1lbnRWYXJpYWJsZScgYXR0cmlidXRlIHZhbHVlIG9mIHRoZSBsb29wIGNoYXJhY3RlcmlzdGljcy5cclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSAnYWN0aXZpdGk6ZWxlbWVudFZhcmlhYmxlJyB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0RWxlbWVudFZhcmlhYmxlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gZ2V0UHJvcGVydHkoZWxlbWVudCwgJ2FjdGl2aXRpOmVsZW1lbnRWYXJpYWJsZScpO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZXMgJ2JwbW46Rm9ybWFsRXhwcmVzc2lvbicgZWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBwYXJlbnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGJvZHlcclxuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICpcclxuICogQHJlc3VsdCB7TW9kZGxlRWxlbWVudDxicG1uOkZvcm1hbEV4cHJlc3Npb24+fSBhIGZvcm1hbCBleHByZXNzaW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVGb3JtYWxFeHByZXNzaW9uKHBhcmVudCwgYm9keSwgYnBtbkZhY3RvcnkpIHtcclxuICByZXR1cm4gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkZvcm1hbEV4cHJlc3Npb24nLCB7IGJvZHk6IGJvZHkgfSwgcGFyZW50LCBicG1uRmFjdG9yeSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBVcGRhdGVzIGEgc3BlY2lmaWMgZm9ybWFsIGV4cHJlc3Npb24gb2YgdGhlIGxvb3AgY2hhcmFjdGVyaXN0aWNzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eU5hbWVcclxuICogQHBhcmFtIHtzdHJpbmd9IG5ld1ZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqL1xyXG5mdW5jdGlvbiB1cGRhdGVGb3JtYWxFeHByZXNzaW9uKGVsZW1lbnQsIHByb3BlcnR5TmFtZSwgbmV3VmFsdWUsIGJwbW5GYWN0b3J5KSB7XHJcbiAgdmFyIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSBnZXRMb29wQ2hhcmFjdGVyaXN0aWNzKGVsZW1lbnQpO1xyXG5cclxuICB2YXIgZXhwcmVzc2lvblByb3BzID0ge307XHJcblxyXG4gIGlmICghbmV3VmFsdWUpIHtcclxuICAgIC8vIHJlbW92ZSBmb3JtYWwgZXhwcmVzc2lvblxyXG4gICAgZXhwcmVzc2lvblByb3BzW3Byb3BlcnR5TmFtZV0gPSB1bmRlZmluZWQ7XHJcbiAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGxvb3BDaGFyYWN0ZXJpc3RpY3MsIGV4cHJlc3Npb25Qcm9wcyk7XHJcbiAgfVxyXG5cclxuICB2YXIgZXhpc3RpbmdFeHByZXNzaW9uID0gbG9vcENoYXJhY3RlcmlzdGljcy5nZXQocHJvcGVydHlOYW1lKTtcclxuXHJcbiAgaWYgKCFleGlzdGluZ0V4cHJlc3Npb24pIHtcclxuICAgIC8vIGFkZCBmb3JtYWwgZXhwcmVzc2lvblxyXG4gICAgZXhwcmVzc2lvblByb3BzW3Byb3BlcnR5TmFtZV0gPSBjcmVhdGVGb3JtYWxFeHByZXNzaW9uKGxvb3BDaGFyYWN0ZXJpc3RpY3MsIG5ld1ZhbHVlLCBicG1uRmFjdG9yeSk7XHJcbiAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGxvb3BDaGFyYWN0ZXJpc3RpY3MsIGV4cHJlc3Npb25Qcm9wcyk7XHJcbiAgfVxyXG5cclxuICAvLyBlZGl0IGV4aXN0aW5nIGZvcm1hbCBleHByZXNzaW9uXHJcbiAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBleGlzdGluZ0V4cHJlc3Npb24sIHtcclxuICAgIGJvZHk6IG5ld1ZhbHVlXHJcbiAgfSk7XHJcbn1cclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGVudHJpZXMgPSBbXTtcclxuXHJcbiAgLy8gZXJyb3IgbWVzc2FnZSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBlbnRyaWVzLnB1c2goe1xyXG4gICAgaWQ6ICdtdWx0aUluc3RhbmNlLWVycm9yTWVzc2FnZScsXHJcbiAgICBodG1sOiAnPGRpdiBkYXRhLXNob3c9XCJpc1ZhbGlkXCI+JyArXHJcbiAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJicHAtaWNvbi13YXJuaW5nXCI+PC9zcGFuPiAnICtcclxuICAgICAgICAgICAgIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgZWl0aGVyIGxvb3AgY2FyZGluYWxpdHkgb3IgY29sbGVjdGlvbicpKSArXHJcbiAgICAgICAgICAnPC9kaXY+JyxcclxuXHJcbiAgICBpc1ZhbGlkOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBub3RpZmljYXRpb24sIHNjb3BlKSB7XHJcbiAgICAgIHZhciBsb29wQ2hhcmFjdGVyaXN0aWNzID0gZ2V0TG9vcENoYXJhY3RlcmlzdGljcyhlbGVtZW50KTtcclxuXHJcbiAgICAgIHZhciBpc1ZhbGlkID0gdHJ1ZTtcclxuICAgICAgaWYgKGxvb3BDaGFyYWN0ZXJpc3RpY3MpIHtcclxuICAgICAgICB2YXIgbG9vcENhcmRpbmFsaXR5ID0gZ2V0TG9vcENhcmRpbmFsaXR5VmFsdWUoZWxlbWVudCk7XHJcbiAgICAgICAgdmFyIGNvbGxlY3Rpb24gPSBnZXRDb2xsZWN0aW9uKGVsZW1lbnQpO1xyXG5cclxuICAgICAgICBpc1ZhbGlkID0gIWxvb3BDYXJkaW5hbGl0eSAmJiAhY29sbGVjdGlvbjtcclxuICAgICAgfVxyXG5cclxuICAgICAgZG9tQ2xhc3Nlcyhub2RlKS50b2dnbGUoJ2JwcC1oaWRkZW4nLCAhaXNWYWxpZCk7XHJcbiAgICAgIGRvbUNsYXNzZXMobm90aWZpY2F0aW9uKS50b2dnbGUoJ2JwcC1lcnJvci1tZXNzYWdlJywgaXNWYWxpZCk7XHJcblxyXG4gICAgICByZXR1cm4gaXNWYWxpZDtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gbG9vcCBjYXJkaW5hbGl0eSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ211bHRpSW5zdGFuY2UtbG9vcENhcmRpbmFsaXR5JyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0xvb3AgQ2FyZGluYWxpdHknKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdsb29wQ2FyZGluYWxpdHknLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxvb3BDYXJkaW5hbGl0eTogZ2V0TG9vcENhcmRpbmFsaXR5VmFsdWUoZWxlbWVudClcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgcmV0dXJuIHVwZGF0ZUZvcm1hbEV4cHJlc3Npb24oZWxlbWVudCwgJ2xvb3BDYXJkaW5hbGl0eScsIHZhbHVlcy5sb29wQ2FyZGluYWxpdHksIGJwbW5GYWN0b3J5KTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG5cclxuICAvLyBjb2xsZWN0aW9uIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ211bHRpSW5zdGFuY2UtY29sbGVjdGlvbicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdDb2xsZWN0aW9uJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY29sbGVjdGlvbicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgY29sbGVjdGlvbjogZ2V0Q29sbGVjdGlvbihlbGVtZW50KVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgbG9vcENoYXJhY3RlcmlzdGljcyA9IGdldExvb3BDaGFyYWN0ZXJpc3RpY3MoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgbG9vcENoYXJhY3RlcmlzdGljcywge1xyXG4gICAgICAgICdhY3Rpdml0aTpjb2xsZWN0aW9uJzogdmFsdWVzLmNvbGxlY3Rpb24gfHwgdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBjb2xsZWN0aW9uID0gZ2V0Q29sbGVjdGlvbihlbGVtZW50KTtcclxuICAgICAgdmFyIGVsZW1lbnRWYXJpYWJsZSA9IGdldEVsZW1lbnRWYXJpYWJsZShlbGVtZW50KTtcclxuXHJcbiAgICAgIGlmICghY29sbGVjdGlvbiAmJiBlbGVtZW50VmFyaWFibGUpIHtcclxuICAgICAgICByZXR1cm4geyBjb2xsZWN0aW9uIDogJ011c3QgcHJvdmlkZSBhIHZhbHVlJyB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgLy8gZWxlbWVudCB2YXJpYWJsZSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdtdWx0aUluc3RhbmNlLWVsZW1lbnRWYXJpYWJsZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdFbGVtZW50IFZhcmlhYmxlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZWxlbWVudFZhcmlhYmxlJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBlbGVtZW50VmFyaWFibGU6IGdldEVsZW1lbnRWYXJpYWJsZShlbGVtZW50KVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgbG9vcENoYXJhY3RlcmlzdGljcyA9IGdldExvb3BDaGFyYWN0ZXJpc3RpY3MoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgbG9vcENoYXJhY3RlcmlzdGljcywge1xyXG4gICAgICAgICdhY3Rpdml0aTplbGVtZW50VmFyaWFibGUnOiB2YWx1ZXMuZWxlbWVudFZhcmlhYmxlIHx8IHVuZGVmaW5lZFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG5cclxuICAvLyBDb21wbGV0aW9uIENvbmRpdGlvbiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdtdWx0aUluc3RhbmNlLWNvbXBsZXRpb25Db25kaXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ29tcGxldGlvbiBDb25kaXRpb24nKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdjb21wbGV0aW9uQ29uZGl0aW9uJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBjb21wbGV0aW9uQ29uZGl0aW9uOiBnZXRDb21wbGV0aW9uQ29uZGl0aW9uVmFsdWUoZWxlbWVudClcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgcmV0dXJuIHVwZGF0ZUZvcm1hbEV4cHJlc3Npb24oZWxlbWVudCwgJ2NvbXBsZXRpb25Db25kaXRpb24nLCB2YWx1ZXMuY29tcGxldGlvbkNvbmRpdGlvbiwgYnBtbkZhY3RvcnkpO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzO1xyXG5cclxudmFyIGZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXInKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKSxcclxuICAgIHV0aWxzID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vVXRpbHMnKTtcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyksXHJcbiAgICBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKSxcclxuICAgIGZpbmQgPSByZXF1aXJlKCdsb2Rhc2gvZmluZCcpO1xyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVQcm9wZXJ0eUlkKCkge1xyXG4gIHJldHVybiB1dGlscy5uZXh0SWQoJ1Byb3BlcnR5XycpO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IGFsbCBhY3Rpdml0aTpwcm9wZXJ0eSBvYmplY3RzIGZvciBhIHNwZWNpZmljIGJ1c2luZXNzIG9iamVjdFxyXG4gKlxyXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50fSBwYXJlbnRcclxuICpcclxuICogQHJldHVybiB7QXJyYXk8TW9kZGxlRWxlbWVudD59IGEgbGlzdCBvZiBhY3Rpdml0aTpwcm9wZXJ0eSBvYmplY3RzXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRQcm9wZXJ0eVZhbHVlcyhwYXJlbnQpIHtcclxuICB2YXIgcHJvcGVydGllcyA9IHBhcmVudCAmJiBnZXRQcm9wZXJ0aWVzRWxlbWVudChwYXJlbnQpO1xyXG4gIGlmIChwcm9wZXJ0aWVzICYmIHByb3BlcnRpZXMudmFsdWVzKSB7XHJcbiAgICByZXR1cm4gcHJvcGVydGllcy52YWx1ZXM7XHJcbiAgfVxyXG4gIHJldHVybiBbXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBhbGwgYWN0aXZpdGk6UHJvcGVydGllcyBvYmplY3QgZm9yIGEgc3BlY2lmaWMgYnVzaW5lc3Mgb2JqZWN0XHJcbiAqXHJcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnR9IHBhcmVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fSBhIGFjdGl2aXRpOlByb3BlcnRpZXMgb2JqZWN0XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRQcm9wZXJ0aWVzRWxlbWVudChlbGVtZW50KSB7XHJcbiAgaWYgKCFpc0V4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQpKSB7XHJcbiAgICByZXR1cm4gZWxlbWVudC5wcm9wZXJ0aWVzO1xyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4gZ2V0UHJvcGVydGllc0VsZW1lbnRJbnNpZGVFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgZmlyc3QgYWN0aXZpdGk6UHJvcGVydGllcyBvYmplY3QgZm9yIGEgc3BlY2lmaWMgYnBtbjpFeHRlbnNpb25FbGVtZW50c1xyXG4gKiBidXNpbmVzcyBvYmplY3QuXHJcbiAqXHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gZXh0ZW5zaW9uRWxlbWVudHNcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gYSBhY3Rpdml0aTpQcm9wZXJ0aWVzIG9iamVjdFxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UHJvcGVydGllc0VsZW1lbnRJbnNpZGVFeHRlbnNpb25FbGVtZW50cyhleHRlbnNpb25FbGVtZW50cykge1xyXG4gIHJldHVybiBmaW5kKGV4dGVuc2lvbkVsZW1lbnRzLnZhbHVlcywgZnVuY3Rpb24oZWxlbSkge1xyXG4gICAgcmV0dXJuIGlzKGVsZW0sICdhY3Rpdml0aTpQcm9wZXJ0aWVzJyk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRydWUsIGlmIHRoZSBnaXZlbiBidXNpbmVzcyBvYmplY3QgaXMgYSBicG1uOkV4dGVuc2lvbkVsZW1lbnRzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBpc0V4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhIGFjdGl2aXRpOnByb3BlcnR5IGVudHJ5IHVzaW5nIHRhYmxlRW50cnlGYWN0b3J5XHJcbiAqXHJcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmlkXHJcbiAqIEBwYXJhbSAge0FycmF5PHN0cmluZz59IG9wdGlvbnMubW9kZWxQcm9wZXJ0aWVzXHJcbiAqIEBwYXJhbSAge0FycmF5PHN0cmluZz59IG9wdGlvbnMubGFiZWxzXHJcbiAqIEBwYXJhbSAge2Z1bmN0aW9ufSBvcHRpb25zLmdldFBhcmVudCBHZXRzIHRoZSBwYXJlbnQgYnVzaW5lc3Mgb2JqZWN0XHJcbiAqIEBwYXJhbSAge2Z1bmN0aW9ufSBvcHRpb25zLnNob3cgSW5kaWNhdGUgd2hlbiB0aGUgZW50cnkgd2lsbCBiZSBzaG93biwgc2hvdWxkIHJldHVybiBib29sZWFuXHJcbiAqL1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldFBhcmVudCA9IG9wdGlvbnMuZ2V0UGFyZW50O1xyXG5cclxuICB2YXIgbW9kZWxQcm9wZXJ0aWVzID0gb3B0aW9ucy5tb2RlbFByb3BlcnRpZXMsXHJcbiAgICAgIGNyZWF0ZVBhcmVudCA9IG9wdGlvbnMuY3JlYXRlUGFyZW50O1xyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgYm8gPSBiby5nZXQoJ3Byb2Nlc3NSZWYnKTtcclxuICB9XHJcblxyXG4gIC8vIGJ1aWxkIHByb3BlcnRpZXMgZ3JvdXAgb25seSB3aGVuIHRoZSBwYXJ0aWNpcGFudCBoYXZlIGEgcHJvY2Vzc1JlZlxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGFzc2lnbihvcHRpb25zLCB7XHJcbiAgICBhZGRMYWJlbDogdHJhbnNsYXRlKCdBZGQgUHJvcGVydHknKSxcclxuICAgIGdldEVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBwYXJlbnQgPSBnZXRQYXJlbnQoZWxlbWVudCwgbm9kZSwgYm8pO1xyXG4gICAgICByZXR1cm4gZ2V0UHJvcGVydHlWYWx1ZXMocGFyZW50KTtcclxuICAgIH0sXHJcbiAgICBhZGRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdLFxyXG4gICAgICAgICAgcGFyZW50ID0gZ2V0UGFyZW50KGVsZW1lbnQsIG5vZGUsIGJvKTtcclxuXHJcbiAgICAgIGlmICghcGFyZW50ICYmIHR5cGVvZiBjcmVhdGVQYXJlbnQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlUGFyZW50KGVsZW1lbnQsIGJvKTtcclxuICAgICAgICBwYXJlbnQgPSByZXN1bHQucGFyZW50O1xyXG4gICAgICAgIGNvbW1hbmRzLnB1c2gocmVzdWx0LmNtZCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBwcm9wZXJ0aWVzID0gZ2V0UHJvcGVydGllc0VsZW1lbnQocGFyZW50KTtcclxuICAgICAgaWYgKCFwcm9wZXJ0aWVzKSB7XHJcbiAgICAgICAgcHJvcGVydGllcyA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6UHJvcGVydGllcycsIHt9LCBwYXJlbnQsIGJwbW5GYWN0b3J5KTtcclxuXHJcbiAgICAgICAgaWYgKCFpc0V4dGVuc2lvbkVsZW1lbnRzKHBhcmVudCkpIHtcclxuICAgICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHBhcmVudCwgeyAncHJvcGVydGllcyc6IHByb3BlcnRpZXMgfSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5hZGRBbmRSZW1vdmVFbGVtZW50c0Zyb21MaXN0KFxyXG4gICAgICAgICAgICBlbGVtZW50LFxyXG4gICAgICAgICAgICBwYXJlbnQsXHJcbiAgICAgICAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAgICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICAgICAgICBbIHByb3BlcnRpZXMgXSxcclxuICAgICAgICAgICAgW11cclxuICAgICAgICAgICkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHByb3BlcnR5UHJvcHMgPSB7fTtcclxuICAgICAgZm9yRWFjaChtb2RlbFByb3BlcnRpZXMsIGZ1bmN0aW9uKHByb3ApIHtcclxuICAgICAgICBwcm9wZXJ0eVByb3BzW3Byb3BdID0gdW5kZWZpbmVkO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIGNyZWF0ZSBpZCBpZiBuZWNlc3NhcnlcclxuICAgICAgaWYgKG1vZGVsUHJvcGVydGllcy5pbmRleE9mKCdpZCcpID49IDApIHtcclxuICAgICAgICBwcm9wZXJ0eVByb3BzLmlkID0gZ2VuZXJhdGVQcm9wZXJ0eUlkKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBwcm9wZXJ0eSA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6UHJvcGVydHknLCBwcm9wZXJ0eVByb3BzLCBwcm9wZXJ0aWVzLCBicG1uRmFjdG9yeSk7XHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLmFkZEVsZW1lbnRzVG9saXN0KGVsZW1lbnQsIHByb3BlcnRpZXMsICd2YWx1ZXMnLCBbIHByb3BlcnR5IF0pKTtcclxuXHJcbiAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgIH0sXHJcbiAgICB1cGRhdGVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSwgbm9kZSwgaWR4KSB7XHJcbiAgICAgIHZhciBwYXJlbnQgPSBnZXRQYXJlbnQoZWxlbWVudCwgbm9kZSwgYm8pLFxyXG4gICAgICAgICAgcHJvcGVydHkgPSBnZXRQcm9wZXJ0eVZhbHVlcyhwYXJlbnQpW2lkeF07XHJcblxyXG4gICAgICBmb3JFYWNoKG1vZGVsUHJvcGVydGllcywgZnVuY3Rpb24ocHJvcCkge1xyXG4gICAgICAgIHZhbHVlW3Byb3BdID0gdmFsdWVbcHJvcF0gfHwgdW5kZWZpbmVkO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgcHJvcGVydHksIHZhbHVlKTtcclxuICAgIH0sXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWUsIG5vZGUsIGlkeCkge1xyXG4gICAgICAvLyB2YWxpZGF0ZSBpZCBpZiBuZWNlc3NhcnlcclxuICAgICAgaWYgKG1vZGVsUHJvcGVydGllcy5pbmRleE9mKCdpZCcpID49IDApIHtcclxuXHJcbiAgICAgICAgdmFyIHBhcmVudCA9IGdldFBhcmVudChlbGVtZW50LCBub2RlLCBibyksXHJcbiAgICAgICAgICAgIHByb3BlcnRpZXMgPSBnZXRQcm9wZXJ0eVZhbHVlcyhwYXJlbnQpLFxyXG4gICAgICAgICAgICBwcm9wZXJ0eSA9IHByb3BlcnRpZXNbaWR4XTtcclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnR5KSB7XHJcbiAgICAgICAgICAvLyBjaGVjayBpZiBpZCBpcyB2YWxpZFxyXG4gICAgICAgICAgdmFyIHZhbGlkYXRpb25FcnJvciA9IHV0aWxzLmlzSWRWYWxpZChwcm9wZXJ0eSwgdmFsdWUuaWQsIHRyYW5zbGF0ZSk7XHJcblxyXG4gICAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcikge1xyXG4gICAgICAgICAgICByZXR1cm4geyBpZDogdmFsaWRhdGlvbkVycm9yIH07XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAgcmVtb3ZlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgaWR4KSB7XHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdLFxyXG4gICAgICAgICAgcGFyZW50ID0gZ2V0UGFyZW50KGVsZW1lbnQsIG5vZGUsIGJvKSxcclxuICAgICAgICAgIHByb3BlcnRpZXMgPSBnZXRQcm9wZXJ0aWVzRWxlbWVudChwYXJlbnQpLFxyXG4gICAgICAgICAgcHJvcGVydHlWYWx1ZXMgPSBnZXRQcm9wZXJ0eVZhbHVlcyhwYXJlbnQpLFxyXG4gICAgICAgICAgY3VycmVudFByb3BlcnR5ID0gcHJvcGVydHlWYWx1ZXNbaWR4XTtcclxuXHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoZWxlbWVudCwgcHJvcGVydGllcywgJ3ZhbHVlcycsIG51bGwsIFsgY3VycmVudFByb3BlcnR5IF0pKTtcclxuXHJcbiAgICAgIGlmIChwcm9wZXJ0eVZhbHVlcy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAvLyByZW1vdmUgYWN0aXZpdGk6cHJvcGVydGllcyBpZiB0aGUgbGFzdCBleGlzdGluZyBwcm9wZXJ0eSBoYXMgYmVlbiByZW1vdmVkXHJcbiAgICAgICAgaWYgKCFpc0V4dGVuc2lvbkVsZW1lbnRzKHBhcmVudCkpIHtcclxuICAgICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHBhcmVudCwgeyBwcm9wZXJ0aWVzOiB1bmRlZmluZWQgfSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBmb3JFYWNoKHBhcmVudC52YWx1ZXMsIGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmIChpcyh2YWx1ZSwgJ2FjdGl2aXRpOlByb3BlcnRpZXMnKSkge1xyXG4gICAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoYm8sIGVsZW1lbnQsIHZhbHVlKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gZmFjdG9yeS50YWJsZShvcHRpb25zKTtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcztcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyk7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgICBoaWRlUmVzdWx0VmFyaWFibGUgPSBvcHRpb25zLmhpZGVSZXN1bHRWYXJpYWJsZSxcclxuICAgICAgaWQgPSBvcHRpb25zLmlkIHx8ICdyZXN1bHRWYXJpYWJsZSc7XHJcblxyXG5cclxuICB2YXIgcmVzdWx0VmFyaWFibGVFbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6IGlkLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnUmVzdWx0IFZhcmlhYmxlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAncmVzdWx0VmFyaWFibGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgcmV0dXJuIHsgcmVzdWx0VmFyaWFibGU6IGJvLmdldCgnYWN0aXZpdGk6cmVzdWx0VmFyaWFibGUnKSB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgIHZhciByZXN1bHRWYXJpYWJsZSA9IHZhbHVlcy5yZXN1bHRWYXJpYWJsZSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOnJlc3VsdFZhcmlhYmxlJzogcmVzdWx0VmFyaWFibGVcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlmIChpcyhibywgJ2FjdGl2aXRpOkRtbkNhcGFibGUnKSAmJiAhcmVzdWx0VmFyaWFibGUpIHtcclxuICAgICAgICBwcm9wcyA9IGFzc2lnbih7ICdhY3Rpdml0aTptYXBEZWNpc2lvblJlc3VsdCc6ICdyZXN1bHRMaXN0JyB9LCBwcm9wcyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIGlmICh0eXBlb2YgaGlkZVJlc3VsdFZhcmlhYmxlID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgcmV0dXJuIGhpZGVSZXN1bHRWYXJpYWJsZS5hcHBseShyZXN1bHRWYXJpYWJsZUVudHJ5LCBhcmd1bWVudHMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gWyByZXN1bHRWYXJpYWJsZUVudHJ5IF07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnksXHJcbiAgICBlc2NhcGVIVE1MID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vVXRpbHMnKS5lc2NhcGVIVE1MLFxyXG4gICAgdXRpbHMgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9VdGlscycpO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGdldFNjcmlwdFR5cGUobm9kZSkge1xyXG4gIHJldHVybiB1dGlscy5zZWxlY3RlZFR5cGUoJ3NlbGVjdFtuYW1lPXNjcmlwdFR5cGVdJywgbm9kZS5wYXJlbnRFbGVtZW50KTtcclxufVxyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc2NyaXB0TGFuZ3VhZ2VQcm9wTmFtZSwgc2NyaXB0VmFsdWVQcm9wTmFtZSwgaXNGb3JtYXRSZXF1aXJlZCwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICB0ZW1wbGF0ZTpcclxuICAgICc8ZGl2IGNsYXNzPVwiYnBwLXJvdyBicHAtdGV4dGZpZWxkXCI+JyArXHJcbiAgICAgICc8bGFiZWwgZm9yPVwiY2FtLXNjcmlwdC1mb3JtYXRcIj4nICsgZXNjYXBlSFRNTCh0cmFuc2xhdGUoJ1NjcmlwdCBGb3JtYXQnKSkgKyAnPC9sYWJlbD4nICtcclxuICAgICAgJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlclwiPicgK1xyXG4gICAgICAgICc8aW5wdXQgaWQ9XCJjYW0tc2NyaXB0LWZvcm1hdFwiIHR5cGU9XCJ0ZXh0XCIgbmFtZT1cInNjcmlwdEZvcm1hdFwiIC8+JyArXHJcbiAgICAgICAgJzxidXR0b24gY2xhc3M9XCJjbGVhclwiIGRhdGEtYWN0aW9uPVwic2NyaXB0LmNsZWFyU2NyaXB0Rm9ybWF0XCIgZGF0YS1zaG93PVwic2NyaXB0LmNhbkNsZWFyU2NyaXB0Rm9ybWF0XCI+JyArXHJcbiAgICAgICAgICAnPHNwYW4+WDwvc3Bhbj4nICtcclxuICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICc8L2Rpdj4nICtcclxuICAgICc8L2Rpdj4nICtcclxuXHJcbiAgICAnPGRpdiBjbGFzcz1cImJwcC1yb3dcIj4nICtcclxuICAgICAgJzxsYWJlbCBmb3I9XCJjYW0tc2NyaXB0LXR5cGVcIj4nICsgZXNjYXBlSFRNTCh0cmFuc2xhdGUoJ1NjcmlwdCBUeXBlJykpICsgJzwvbGFiZWw+JyArXHJcbiAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXJcIj4nICtcclxuICAgICAgICAnPHNlbGVjdCBpZD1cImNhbS1zY3JpcHQtdHlwZVwiIG5hbWU9XCJzY3JpcHRUeXBlXCIgZGF0YS12YWx1ZT4nICtcclxuICAgICAgICAgICc8b3B0aW9uIHZhbHVlPVwic2NyaXB0XCIgc2VsZWN0ZWQ+JyArIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdJbmxpbmUgU2NyaXB0JykpICsgJzwvb3B0aW9uPicgK1xyXG4gICAgICAgICAgJzxvcHRpb24gdmFsdWU9XCJzY3JpcHRSZXNvdXJjZVwiPicgKyBlc2NhcGVIVE1MKHRyYW5zbGF0ZSgnRXh0ZXJuYWwgUmVzb3VyY2UnKSkgKyAnPC9vcHRpb24+JyArXHJcbiAgICAgICAgJzwvc2VsZWN0PicgK1xyXG4gICAgICAnPC9kaXY+JyArXHJcbiAgICAnPC9kaXY+JyArXHJcblxyXG4gICAgJzxkaXYgY2xhc3M9XCJicHAtcm93IGJwcC10ZXh0ZmllbGRcIj4nICtcclxuICAgICAgJzxsYWJlbCBmb3I9XCJjYW0tc2NyaXB0LXJlc291cmNlLXZhbFwiIGRhdGEtc2hvdz1cInNjcmlwdC5pc1NjcmlwdFJlc291cmNlXCI+JyArIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdSZXNvdXJjZScpKSArICc8L2xhYmVsPicgK1xyXG4gICAgICAnPGRpdiBjbGFzcz1cImJwcC1maWVsZC13cmFwcGVyXCIgZGF0YS1zaG93PVwic2NyaXB0LmlzU2NyaXB0UmVzb3VyY2VcIj4nICtcclxuICAgICAgICAnPGlucHV0IGlkPVwiY2FtLXNjcmlwdC1yZXNvdXJjZS12YWxcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJzY3JpcHRSZXNvdXJjZVZhbHVlXCIgLz4nICtcclxuICAgICAgICAnPGJ1dHRvbiBjbGFzcz1cImNsZWFyXCIgZGF0YS1hY3Rpb249XCJzY3JpcHQuY2xlYXJTY3JpcHRSZXNvdXJjZVwiIGRhdGEtc2hvdz1cInNjcmlwdC5jYW5DbGVhclNjcmlwdFJlc291cmNlXCI+JyArXHJcbiAgICAgICAgICAnPHNwYW4+WDwvc3Bhbj4nICtcclxuICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICc8L2Rpdj4nICtcclxuICAgICc8L2Rpdj4nICtcclxuXHJcbiAgICAnPGRpdiBjbGFzcz1cImJwcC1yb3dcIj4nICtcclxuICAgICAgJzxsYWJlbCBmb3I9XCJjYW0tc2NyaXB0LXZhbFwiIGRhdGEtc2hvdz1cInNjcmlwdC5pc1NjcmlwdFwiPicgKyBlc2NhcGVIVE1MKHRyYW5zbGF0ZSgnU2NyaXB0JykpICsgJzwvbGFiZWw+JyArXHJcbiAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXJcIiBkYXRhLXNob3c9XCJzY3JpcHQuaXNTY3JpcHRcIj4nICtcclxuICAgICAgICAnPHRleHRhcmVhIGlkPVwiY2FtLXNjcmlwdC12YWxcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJzY3JpcHRWYWx1ZVwiPjwvdGV4dGFyZWE+JyArXHJcbiAgICAgICc8L2Rpdj4nK1xyXG4gICAgJzwvZGl2PicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBibykge1xyXG4gICAgICB2YXIgdmFsdWVzID0ge307XHJcblxyXG4gICAgICAvLyByZWFkIHZhbHVlcyBmcm9tIHhtbDpcclxuICAgICAgdmFyIGJvU2NyaXB0UmVzb3VyY2UgPSBiby5nZXQoJ2FjdGl2aXRpOnJlc291cmNlJyksXHJcbiAgICAgICAgICBib1NjcmlwdCA9IGJvLmdldChzY3JpcHRWYWx1ZVByb3BOYW1lKSxcclxuICAgICAgICAgIGJvU2NyaXB0Rm9ybWF0ID0gYm8uZ2V0KHNjcmlwdExhbmd1YWdlUHJvcE5hbWUpO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiBib1NjcmlwdFJlc291cmNlICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHZhbHVlcy5zY3JpcHRSZXNvdXJjZVZhbHVlID0gYm9TY3JpcHRSZXNvdXJjZTtcclxuICAgICAgICB2YWx1ZXMuc2NyaXB0VHlwZSA9ICdzY3JpcHRSZXNvdXJjZSc7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFsdWVzLnNjcmlwdFZhbHVlID0gYm9TY3JpcHQ7XHJcbiAgICAgICAgdmFsdWVzLnNjcmlwdFR5cGUgPSAnc2NyaXB0JztcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFsdWVzLnNjcmlwdEZvcm1hdCA9IGJvU2NyaXB0Rm9ybWF0O1xyXG5cclxuICAgICAgcmV0dXJuIHZhbHVlcztcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIGNvbnRhaW5lckVsZW1lbnQpIHtcclxuICAgICAgdmFyIHNjcmlwdEZvcm1hdCA9IHZhbHVlcy5zY3JpcHRGb3JtYXQsXHJcbiAgICAgICAgICBzY3JpcHRUeXBlID0gdmFsdWVzLnNjcmlwdFR5cGUsXHJcbiAgICAgICAgICBzY3JpcHRSZXNvdXJjZVZhbHVlID0gdmFsdWVzLnNjcmlwdFJlc291cmNlVmFsdWUsXHJcbiAgICAgICAgICBzY3JpcHRWYWx1ZSA9IHZhbHVlcy5zY3JpcHRWYWx1ZTtcclxuXHJcbiAgICAgIC8vIGluaXQgdXBkYXRlXHJcbiAgICAgIHZhciB1cGRhdGUgPSB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOnJlc291cmNlJzogdW5kZWZpbmVkXHJcbiAgICAgIH07XHJcbiAgICAgIHVwZGF0ZVtzY3JpcHRWYWx1ZVByb3BOYW1lXSA9IHVuZGVmaW5lZDtcclxuICAgICAgdXBkYXRlW3NjcmlwdExhbmd1YWdlUHJvcE5hbWVdID0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgaWYgKGlzRm9ybWF0UmVxdWlyZWQpIHtcclxuICAgICAgICAvLyBhbHdheXMgc2V0IGxhbmd1YWdlXHJcbiAgICAgICAgdXBkYXRlW3NjcmlwdExhbmd1YWdlUHJvcE5hbWVdID0gc2NyaXB0Rm9ybWF0IHx8ICcnO1xyXG4gICAgICB9IGVsc2VcclxuICAgICAgLy8gc2V0IGxhbmd1YWdlIG9ubHkgd2hlbiBzY3JpcHRGb3JtYXQgaGFzIGEgdmFsdWVcclxuICAgICAgaWYgKHNjcmlwdEZvcm1hdCAhPT0gJycpIHtcclxuICAgICAgICB1cGRhdGVbc2NyaXB0TGFuZ3VhZ2VQcm9wTmFtZV0gPSBzY3JpcHRGb3JtYXQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHNldCBlaXRoZXIgaW5saW5lIHNjcmlwdCBvciByZXNvdXJjZVxyXG4gICAgICBpZiAoJ3NjcmlwdFJlc291cmNlJyA9PT0gc2NyaXB0VHlwZSkge1xyXG4gICAgICAgIHVwZGF0ZVsnYWN0aXZpdGk6cmVzb3VyY2UnXSA9IHNjcmlwdFJlc291cmNlVmFsdWUgfHwgJyc7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdXBkYXRlW3NjcmlwdFZhbHVlUHJvcE5hbWVdID0gc2NyaXB0VmFsdWUgfHwgJyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB1cGRhdGU7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIHZhbGlkYXRpb25SZXN1bHQgPSB7fTtcclxuXHJcbiAgICAgIGlmICh2YWx1ZXMuc2NyaXB0VHlwZSA9PT0gJ3NjcmlwdCcgJiYgIXZhbHVlcy5zY3JpcHRWYWx1ZSkge1xyXG4gICAgICAgIHZhbGlkYXRpb25SZXN1bHQuc2NyaXB0VmFsdWUgPSB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh2YWx1ZXMuc2NyaXB0VHlwZSA9PT0gJ3NjcmlwdFJlc291cmNlJyAmJiAhdmFsdWVzLnNjcmlwdFJlc291cmNlVmFsdWUpIHtcclxuICAgICAgICB2YWxpZGF0aW9uUmVzdWx0LnNjcmlwdFJlc291cmNlVmFsdWUgPSB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChpc0Zvcm1hdFJlcXVpcmVkICYmICghdmFsdWVzLnNjcmlwdEZvcm1hdCB8fCB2YWx1ZXMuc2NyaXB0Rm9ybWF0Lmxlbmd0aCA9PT0gMCkpIHtcclxuICAgICAgICB2YWxpZGF0aW9uUmVzdWx0LnNjcmlwdEZvcm1hdCA9IHRyYW5zbGF0ZSgnTXVzdCBwcm92aWRlIGEgdmFsdWUnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbGlkYXRpb25SZXN1bHQ7XHJcbiAgICB9LFxyXG5cclxuICAgIGNsZWFyU2NyaXB0Rm9ybWF0OiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUsIGJ0bk5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICBkb21RdWVyeSgnaW5wdXRbbmFtZT1zY3JpcHRGb3JtYXRdJywgc2NvcGVOb2RlKS52YWx1ZT0nJztcclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICBjYW5DbGVhclNjcmlwdEZvcm1hdDogZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlLCBidG5Ob2RlLCBzY29wZU5vZGUpIHtcclxuICAgICAgdmFyIGlucHV0ID0gZG9tUXVlcnkoJ2lucHV0W25hbWU9c2NyaXB0Rm9ybWF0XScsIHNjb3BlTm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gaW5wdXQudmFsdWUgIT09ICcnO1xyXG4gICAgfSxcclxuXHJcbiAgICBjbGVhclNjcmlwdFJlc291cmNlOiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUsIGJ0bk5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICBkb21RdWVyeSgnaW5wdXRbbmFtZT1zY3JpcHRSZXNvdXJjZVZhbHVlXScsIHNjb3BlTm9kZSkudmFsdWU9Jyc7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgY2FuQ2xlYXJTY3JpcHRSZXNvdXJjZTogZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlLCBidG5Ob2RlLCBzY29wZU5vZGUpIHtcclxuICAgICAgdmFyIGlucHV0ID0gZG9tUXVlcnkoJ2lucHV0W25hbWU9c2NyaXB0UmVzb3VyY2VWYWx1ZV0nLCBzY29wZU5vZGUpO1xyXG5cclxuICAgICAgcmV0dXJuIGlucHV0LnZhbHVlICE9PSAnJztcclxuICAgIH0sXHJcblxyXG4gICAgY2xlYXJTY3JpcHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSwgYnRuTm9kZSwgc2NvcGVOb2RlKSB7XHJcbiAgICAgIGRvbVF1ZXJ5KCd0ZXh0YXJlYVtuYW1lPXNjcmlwdFZhbHVlXScsIHNjb3BlTm9kZSkudmFsdWU9Jyc7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgY2FuQ2xlYXJTY3JpcHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSwgYnRuTm9kZSwgc2NvcGVOb2RlKSB7XHJcbiAgICAgIHZhciBpbnB1dCA9IGRvbVF1ZXJ5KCd0ZXh0YXJlYVtuYW1lPXNjcmlwdFZhbHVlXScsIHNjb3BlTm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gaW5wdXQudmFsdWUgIT09ICcnO1xyXG4gICAgfSxcclxuXHJcbiAgICBpc1NjcmlwdFJlc291cmNlOiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUsIGJ0bk5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICB2YXIgc2NyaXB0VHlwZSA9IGdldFNjcmlwdFR5cGUoc2NvcGVOb2RlKTtcclxuICAgICAgcmV0dXJuIHNjcmlwdFR5cGUgPT09ICdzY3JpcHRSZXNvdXJjZSc7XHJcbiAgICB9LFxyXG5cclxuICAgIGlzU2NyaXB0OiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUsIGJ0bk5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICB2YXIgc2NyaXB0VHlwZSA9IGdldFNjcmlwdFR5cGUoc2NvcGVOb2RlKTtcclxuICAgICAgcmV0dXJuIHNjcmlwdFR5cGUgPT09ICdzY3JpcHQnO1xyXG4gICAgfVxyXG5cclxuICB9O1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBnZXRCdXNpbmVzc09iamVjdCA9IG9wdGlvbnMuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG4gIHZhciBpc1N0YXJ0YWJsZUluVGFza2xpc3RFbnRyeSA9IGVudHJ5RmFjdG9yeS5jaGVja2JveCh7XHJcbiAgICBpZDogJ2lzU3RhcnRhYmxlSW5UYXNrbGlzdCcsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdTdGFydGFibGUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdpc1N0YXJ0YWJsZUluVGFza2xpc3QnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIGlzU3RhcnRhYmxlSW5UYXNrbGlzdCA9IGJvLmdldCgnYWN0aXZpdGk6aXNTdGFydGFibGVJblRhc2tsaXN0Jyk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGlzU3RhcnRhYmxlSW5UYXNrbGlzdDogaXNTdGFydGFibGVJblRhc2tsaXN0ID8gaXNTdGFydGFibGVJblRhc2tsaXN0IDogJydcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHtcclxuICAgICAgICAnYWN0aXZpdGk6aXNTdGFydGFibGVJblRhc2tsaXN0JzogISF2YWx1ZXMuaXNTdGFydGFibGVJblRhc2tsaXN0XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIGlzU3RhcnRhYmxlSW5UYXNrbGlzdEVudHJ5XHJcbiAgXTtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgTW9kZWxVdGlsID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKSxcclxuICAgIGlzID0gTW9kZWxVdGlsLmlzLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBNb2RlbFV0aWwuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZ2V0VmFsdWUgPSBmdW5jdGlvbihidXNpbmVzc09iamVjdCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgdmFyIGRvY3VtZW50YXRpb25zID0gYnVzaW5lc3NPYmplY3QgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdkb2N1bWVudGF0aW9uJyksXHJcbiAgICAgICAgICB0ZXh0ID0gKGRvY3VtZW50YXRpb25zICYmIGRvY3VtZW50YXRpb25zLmxlbmd0aCA+IDApID8gZG9jdW1lbnRhdGlvbnNbMF0udGV4dCA6ICcnO1xyXG5cclxuICAgICAgcmV0dXJuIHsgZG9jdW1lbnRhdGlvbjogdGV4dCB9O1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgc2V0VmFsdWUgPSBmdW5jdGlvbihidXNpbmVzc09iamVjdCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgbmV3T2JqZWN0TGlzdCA9IFtdO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZXMuZG9jdW1lbnRhdGlvbiAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWVzLmRvY3VtZW50YXRpb24gIT09ICcnKSB7XHJcbiAgICAgICAgbmV3T2JqZWN0TGlzdC5wdXNoKGJwbW5GYWN0b3J5LmNyZWF0ZSgnYnBtbjpEb2N1bWVudGF0aW9uJywge1xyXG4gICAgICAgICAgdGV4dDogdmFsdWVzLmRvY3VtZW50YXRpb25cclxuICAgICAgICB9KSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIuc2V0TGlzdChlbGVtZW50LCBidXNpbmVzc09iamVjdCwgJ2RvY3VtZW50YXRpb24nLCBuZXdPYmplY3RMaXN0KTtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgLy8gRWxlbWVudCBEb2N1bWVudGF0aW9uXHJcbiAgdmFyIGVsZW1lbnREb2N1RW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEJveCh7XHJcbiAgICBpZDogJ2RvY3VtZW50YXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnRWxlbWVudCBEb2N1bWVudGF0aW9uJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZG9jdW1lbnRhdGlvbidcclxuICB9KTtcclxuXHJcbiAgZWxlbWVudERvY3VFbnRyeS5zZXQgPSBzZXRWYWx1ZShnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSk7XHJcblxyXG4gIGVsZW1lbnREb2N1RW50cnkuZ2V0ID0gZ2V0VmFsdWUoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkpO1xyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZWxlbWVudERvY3VFbnRyeSk7XHJcblxyXG5cclxuICB2YXIgcHJvY2Vzc1JlZjtcclxuXHJcbiAgLy8gUHJvY2VzcyBEb2N1bWVudGF0aW9uIHdoZW4gaGF2aW5nIGEgQ29sbGFib3JhdGlvbiBEaWFncmFtXHJcbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuXHJcbiAgICBwcm9jZXNzUmVmID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkucHJvY2Vzc1JlZjtcclxuXHJcbiAgICAvLyBkbyBub3Qgc2hvdyBmb3IgY29sbGFwc2VkIFBvb2xzL1BhcnRpY2lwYW50c1xyXG4gICAgaWYgKHByb2Nlc3NSZWYpIHtcclxuICAgICAgdmFyIHByb2Nlc3NEb2N1RW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEJveCh7XHJcbiAgICAgICAgaWQ6ICdwcm9jZXNzLWRvY3VtZW50YXRpb24nLFxyXG4gICAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1Byb2Nlc3MgRG9jdW1lbnRhdGlvbicpLFxyXG4gICAgICAgIG1vZGVsUHJvcGVydHk6ICdkb2N1bWVudGF0aW9uJ1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHByb2Nlc3NEb2N1RW50cnkuc2V0ID0gc2V0VmFsdWUocHJvY2Vzc1JlZik7XHJcblxyXG4gICAgICBwcm9jZXNzRG9jdUVudHJ5LmdldCA9IGdldFZhbHVlKHByb2Nlc3NSZWYpO1xyXG5cclxuICAgICAgZ3JvdXAuZW50cmllcy5wdXNoKHByb2Nlc3NEb2N1RW50cnkpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBpc0FueSA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJykuaXNBbnksXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyk7XHJcblxyXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XHJcblxyXG52YXIgbWVzc2FnZSA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vTWVzc2FnZUV2ZW50RGVmaW5pdGlvbicpLFxyXG4gICAgc2lnbmFsID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9TaWduYWxFdmVudERlZmluaXRpb24nKSxcclxuICAgIGVycm9yID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9FcnJvckV2ZW50RGVmaW5pdGlvbicpLFxyXG4gICAgZXNjYWxhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vRXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicpLFxyXG4gICAgdGltZXIgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL1RpbWVyRXZlbnREZWZpbml0aW9uJyksXHJcbiAgICBjb21wZW5zYXRpb24gPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0NvbXBlbnNhdGVFdmVudERlZmluaXRpb24nKSxcclxuICAgIGNvbmRpdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQ29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nKTtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpIHtcclxuICB2YXIgZXZlbnRzID0gW1xyXG4gICAgJ2JwbW46U3RhcnRFdmVudCcsXHJcbiAgICAnYnBtbjpFbmRFdmVudCcsXHJcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcclxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxyXG4gICAgJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCdcclxuICBdO1xyXG5cclxuICAvLyBNZXNzYWdlIGFuZCBTaWduYWwgRXZlbnQgRGVmaW5pdGlvblxyXG4gIGZvckVhY2goZXZlbnRzLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsIGV2ZW50KSkge1xyXG5cclxuICAgICAgdmFyIG1lc3NhZ2VFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0TWVzc2FnZUV2ZW50RGVmaW5pdGlvbihlbGVtZW50KSxcclxuICAgICAgICAgIHNpZ25hbEV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRTaWduYWxFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAobWVzc2FnZUV2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgICAgIG1lc3NhZ2UoZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBtZXNzYWdlRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoc2lnbmFsRXZlbnREZWZpbml0aW9uKSB7XHJcbiAgICAgICAgc2lnbmFsKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgc2lnbmFsRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICAvLyBTcGVjaWFsIENhc2U6IFJlY2VpdmUgVGFza1xyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpSZWNlaXZlVGFzaycpKSB7XHJcbiAgICBtZXNzYWdlKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksIHRyYW5zbGF0ZSk7XHJcbiAgfVxyXG5cclxuICAvLyBFcnJvciBFdmVudCBEZWZpbml0aW9uXHJcbiAgdmFyIGVycm9yRXZlbnRzID0gW1xyXG4gICAgJ2JwbW46U3RhcnRFdmVudCcsXHJcbiAgICAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcclxuICAgICdicG1uOkVuZEV2ZW50J1xyXG4gIF07XHJcblxyXG4gIGZvckVhY2goZXJyb3JFdmVudHMsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICBpZiAoaXMoZWxlbWVudCwgZXZlbnQpKSB7XHJcblxyXG4gICAgICB2YXIgZXJyb3JFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0RXJyb3JFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAoZXJyb3JFdmVudERlZmluaXRpb24pIHtcclxuXHJcbiAgICAgICAgZXJyb3IoZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlcnJvckV2ZW50RGVmaW5pdGlvbiwgdHJhbnNsYXRlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICAvLyBFc2NhbGF0aW9uIEV2ZW50IERlZmluaXRpb25cclxuICB2YXIgZXNjYWxhdGlvbkV2ZW50cyA9IFtcclxuICAgICdicG1uOlN0YXJ0RXZlbnQnLFxyXG4gICAgJ2JwbW46Qm91bmRhcnlFdmVudCcsXHJcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcclxuICAgICdicG1uOkVuZEV2ZW50J1xyXG4gIF07XHJcblxyXG4gIGZvckVhY2goZXNjYWxhdGlvbkV2ZW50cywgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIGlmIChpcyhlbGVtZW50LCBldmVudCkpIHtcclxuXHJcbiAgICAgIHZhciBzaG93RXNjYWxhdGlvbkNvZGVWYXJpYWJsZSA9IGlzKGVsZW1lbnQsICdicG1uOlN0YXJ0RXZlbnQnKSB8fCBpcyhlbGVtZW50LCAnYnBtbjpCb3VuZGFyeUV2ZW50Jyk7XHJcblxyXG4gICAgICAvLyBnZXQgYnVzaW5lc3Mgb2JqZWN0XHJcbiAgICAgIHZhciBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uID0gZXZlbnREZWZpbml0aW9uSGVscGVyLmdldEVzY2FsYXRpb25FdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAoZXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgICAgIGVzY2FsYXRpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uLCBzaG93RXNjYWxhdGlvbkNvZGVWYXJpYWJsZSxcclxuICAgICAgICAgIHRyYW5zbGF0ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIC8vIFRpbWVyIEV2ZW50IERlZmluaXRpb25cclxuICB2YXIgdGltZXJFdmVudHMgPSBbXHJcbiAgICAnYnBtbjpTdGFydEV2ZW50JyxcclxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxyXG4gICAgJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCdcclxuICBdO1xyXG5cclxuICBmb3JFYWNoKHRpbWVyRXZlbnRzLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsIGV2ZW50KSkge1xyXG5cclxuICAgICAgLy8gZ2V0IGJ1c2luZXNzIG9iamVjdFxyXG4gICAgICB2YXIgdGltZXJFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0VGltZXJFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAodGltZXJFdmVudERlZmluaXRpb24pIHtcclxuICAgICAgICB0aW1lcihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRpbWVyRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIC8vIENvbXBlbnNhdGUgRXZlbnQgRGVmaW5pdGlvblxyXG4gIHZhciBjb21wZW5zYXRpb25FdmVudHMgPSBbXHJcbiAgICAnYnBtbjpFbmRFdmVudCcsXHJcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50J1xyXG4gIF07XHJcblxyXG4gIGZvckVhY2goY29tcGVuc2F0aW9uRXZlbnRzLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsIGV2ZW50KSkge1xyXG5cclxuICAgICAgLy8gZ2V0IGJ1c2luZXNzIG9iamVjdFxyXG4gICAgICB2YXIgY29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG5cclxuICAgICAgaWYgKGNvbXBlbnNhdGVFdmVudERlZmluaXRpb24pIHtcclxuICAgICAgICBjb21wZW5zYXRpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxuXHJcblxyXG4gIC8vIENvbmRpdGlvbmFsIEV2ZW50IERlZmluaXRpb25cclxuICB2YXIgY29uZGl0aW9uYWxFdmVudHMgPSBbXHJcbiAgICAnYnBtbjpTdGFydEV2ZW50JyxcclxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxyXG4gICAgJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcsXHJcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50J1xyXG4gIF07XHJcblxyXG4gIGlmIChpc0FueShlbGVtZW50LCBjb25kaXRpb25hbEV2ZW50cykpIHtcclxuXHJcbiAgICAvLyBnZXQgYnVzaW5lc3Mgb2JqZWN0XHJcbiAgICB2YXIgY29uZGl0aW9uYWxFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgaWYgKGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uKSB7XHJcbiAgICAgIGNvbmRpdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uLCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIHBhcnRpY2lwYW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL1BhcnRpY2lwYW50SGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYm8uZ2V0KCdwcm9jZXNzUmVmJykpKSB7XHJcblxyXG4gICAgdmFyIGV4ZWN1dGFibGVFbnRyeSA9IGVudHJ5RmFjdG9yeS5jaGVja2JveCh7XHJcbiAgICAgIGlkOiAncHJvY2Vzcy1pcy1leGVjdXRhYmxlJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXhlY3V0YWJsZScpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5OiAnaXNFeGVjdXRhYmxlJ1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gaW4gcGFydGljaXBhbnRzIHdlIGhhdmUgdG8gY2hhbmdlIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHNldCBhbmQgZ2V0XHJcbiAgICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICBleGVjdXRhYmxlRW50cnkuZ2V0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiBwYXJ0aWNpcGFudEhlbHBlci5nZXRQcm9jZXNzQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgJ2lzRXhlY3V0YWJsZScpO1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgZXhlY3V0YWJsZUVudHJ5LnNldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICAgIHJldHVybiBwYXJ0aWNpcGFudEhlbHBlci5tb2RpZnlQcm9jZXNzQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgJ2lzRXhlY3V0YWJsZScsIHZhbHVlcyk7XHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKGV4ZWN1dGFibGVFbnRyeSk7XHJcbiAgfVxyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uL1V0aWxzJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUsIG9wdGlvbnMpIHtcclxuXHJcbiAgdmFyIGRlc2NyaXB0aW9uID0gb3B0aW9ucyAmJiBvcHRpb25zLmRlc2NyaXB0aW9uO1xyXG5cclxuICAvLyBJZFxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudmFsaWRhdGlvbkF3YXJlVGV4dEZpZWxkKHtcclxuICAgIGlkOiAnaWQnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSWQnKSxcclxuICAgIGRlc2NyaXB0aW9uOiBkZXNjcmlwdGlvbiAmJiB0cmFuc2xhdGUoZGVzY3JpcHRpb24pLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2lkJyxcclxuICAgIGdldFByb3BlcnR5OiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5pZDtcclxuICAgIH0sXHJcbiAgICBzZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydGllcykge1xyXG5cclxuICAgICAgZWxlbWVudCA9IGVsZW1lbnQubGFiZWxUYXJnZXQgfHwgZWxlbWVudDtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBwcm9wZXJ0aWVzKTtcclxuICAgIH0sXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBpZFZhbHVlID0gdmFsdWVzLmlkO1xyXG5cclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gICAgICB2YXIgaWRFcnJvciA9IHV0aWxzLmlzSWRWYWxpZChibywgaWRWYWx1ZSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgICAgIHJldHVybiBpZEVycm9yID8geyBpZDogaWRFcnJvciB9IDoge307XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XHJcblxyXG5mdW5jdGlvbiBnZXRMaW5rRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpIHtcclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBsaW5rRXZlbnREZWZpbml0aW9uID0gbnVsbDtcclxuICBpZiAoYm8uZXZlbnREZWZpbml0aW9ucykge1xyXG4gICAgZm9yRWFjaChiby5ldmVudERlZmluaXRpb25zLCBmdW5jdGlvbihldmVudERlZmluaXRpb24pIHtcclxuICAgICAgaWYgKGlzKGV2ZW50RGVmaW5pdGlvbiwgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpKSB7XHJcbiAgICAgICAgbGlua0V2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbjtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbGlua0V2ZW50RGVmaW5pdGlvbjtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIGxpbmtFdmVudHMgPSBbICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnLCAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyBdO1xyXG5cclxuICBmb3JFYWNoKGxpbmtFdmVudHMsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICBpZiAoaXMoZWxlbWVudCwgZXZlbnQpKSB7XHJcblxyXG4gICAgICB2YXIgbGlua0V2ZW50RGVmaW5pdGlvbiA9IGdldExpbmtFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAobGlua0V2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgICAgIHZhciBlbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgICAgICAgaWQ6ICdsaW5rLWV2ZW50JyxcclxuICAgICAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0xpbmsgTmFtZScpLFxyXG4gICAgICAgICAgbW9kZWxQcm9wZXJ0eTogJ2xpbmstbmFtZSdcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgZW50cnkuZ2V0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICByZXR1cm4geyAnbGluay1uYW1lJzogbGlua0V2ZW50RGVmaW5pdGlvbi5nZXQoJ25hbWUnKSB9O1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGVudHJ5LnNldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICAgICAgdmFyIG5ld1Byb3BlcnRpZXMgPSB7XHJcbiAgICAgICAgICAgIG5hbWU6IHZhbHVlc1snbGluay1uYW1lJ11cclxuICAgICAgICAgIH07XHJcbiAgICAgICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGxpbmtFdmVudERlZmluaXRpb24sIG5ld1Byb3BlcnRpZXMpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxufTtcclxuXHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBuYW1lRW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9OYW1lJyksXHJcbiAgICBjcmVhdGVDYXRlZ29yeVZhbHVlID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NhdGVnb3J5SGVscGVyJykuY3JlYXRlQ2F0ZWdvcnlWYWx1ZSxcclxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjYW52YXMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICBmdW5jdGlvbiBpbml0aWFsaXplQ2F0ZWdvcnkoc2VtYW50aWMpIHtcclxuICAgIHZhciByb290RWxlbWVudCA9IGNhbnZhcy5nZXRSb290RWxlbWVudCgpLFxyXG4gICAgICAgIGRlZmluaXRpb25zID0gZ2V0QnVzaW5lc3NPYmplY3Qocm9vdEVsZW1lbnQpLiRwYXJlbnQsXHJcbiAgICAgICAgY2F0ZWdvcnlWYWx1ZSA9IGNyZWF0ZUNhdGVnb3J5VmFsdWUoZGVmaW5pdGlvbnMsIGJwbW5GYWN0b3J5KTtcclxuXHJcbiAgICBzZW1hbnRpYy5jYXRlZ29yeVZhbHVlUmVmID0gY2F0ZWdvcnlWYWx1ZTtcclxuXHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBzZXRHcm91cE5hbWUoZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICBjYXRlZ29yeVZhbHVlUmVmID0gYm8uY2F0ZWdvcnlWYWx1ZVJlZjtcclxuXHJcbiAgICBpZiAoIWNhdGVnb3J5VmFsdWVSZWYpIHtcclxuICAgICAgaW5pdGlhbGl6ZUNhdGVnb3J5KGJvKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBuZWVkcyBkaXJlY3QgY2FsbCB0byB1cGRhdGUgY2F0ZWdvcnlWYWx1ZSBwcm9wZXJseVxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgY21kOiAnZWxlbWVudC51cGRhdGVMYWJlbCcsXHJcbiAgICAgIGNvbnRleHQ6IHtcclxuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICAgIG5ld0xhYmVsOiB2YWx1ZXMuY2F0ZWdvcnlWYWx1ZVxyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0R3JvdXBOYW1lKGVsZW1lbnQpIHtcclxuICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxyXG4gICAgICAgIHZhbHVlID0gKGJvLmNhdGVnb3J5VmFsdWVSZWYgfHwge30pLnZhbHVlO1xyXG5cclxuICAgIHJldHVybiB7IGNhdGVnb3J5VmFsdWU6IHZhbHVlIH07XHJcbiAgfVxyXG5cclxuICBpZiAoIWlzKGVsZW1lbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKSkge1xyXG5cclxuICAgIHZhciBvcHRpb25zO1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcclxuICAgICAgb3B0aW9ucyA9IHsgbW9kZWxQcm9wZXJ0eTogJ3RleHQnLCBsYWJlbDogdHJhbnNsYXRlKCdUZXh0JykgfTtcclxuICAgIH0gZWxzZSBpZiAoaXMoZWxlbWVudCwgJ2JwbW46R3JvdXAnKSkge1xyXG4gICAgICBvcHRpb25zID0ge1xyXG4gICAgICAgIG1vZGVsUHJvcGVydHk6ICdjYXRlZ29yeVZhbHVlJyxcclxuICAgICAgICBsYWJlbDogdHJhbnNsYXRlKCdDYXRlZ29yeSBWYWx1ZScpLFxyXG4gICAgICAgIGdldDogZ2V0R3JvdXBOYW1lLFxyXG4gICAgICAgIHNldDogc2V0R3JvdXBOYW1lXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gbmFtZVxyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KG5hbWVFbnRyeUZhY3RvcnkoZWxlbWVudCwgb3B0aW9ucywgdHJhbnNsYXRlKSk7XHJcblxyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgcGFydGljaXBhbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvUGFydGljaXBhbnRIZWxwZXInKSxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdCxcclxuICAgIG5hbWVFbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL05hbWUnKSxcclxuICAgIHV0aWxzID0gcmVxdWlyZSgnLi4vLi4vLi4vVXRpbHMnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIHRyYW5zbGF0ZSwgb3B0aW9ucykge1xyXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICB2YXIgcHJvY2Vzc0lkRGVzY3JpcHRpb24gPSBvcHRpb25zICYmIG9wdGlvbnMucHJvY2Vzc0lkRGVzY3JpcHRpb247XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdwcm9jZXNzUmVmJykpKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBwcm9jZXNzSWRcclxuICAgICAqL1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuICAgICAgdmFyIGlkRW50cnkgPSBlbnRyeUZhY3RvcnkudmFsaWRhdGlvbkF3YXJlVGV4dEZpZWxkKHtcclxuICAgICAgICBpZDogJ3Byb2Nlc3MtaWQnLFxyXG4gICAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1Byb2Nlc3MgSWQnKSxcclxuICAgICAgICBkZXNjcmlwdGlvbjogcHJvY2Vzc0lkRGVzY3JpcHRpb24gJiYgdHJhbnNsYXRlKHByb2Nlc3NJZERlc2NyaXB0aW9uKSxcclxuICAgICAgICBtb2RlbFByb3BlcnR5OiAncHJvY2Vzc0lkJ1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIGluIHBhcnRpY2lwYW50cyB3ZSBoYXZlIHRvIGNoYW5nZSB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiBzZXQgYW5kIGdldFxyXG4gICAgICBpZEVudHJ5LmdldCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgcHJvcGVydGllcyA9IHBhcnRpY2lwYW50SGVscGVyLmdldFByb2Nlc3NCdXNpbmVzc09iamVjdChlbGVtZW50LCAnaWQnKTtcclxuICAgICAgICByZXR1cm4geyBwcm9jZXNzSWQ6IHByb3BlcnRpZXMuaWQgfTtcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlkRW50cnkuc2V0ID0gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnRpY2lwYW50SGVscGVyLm1vZGlmeVByb2Nlc3NCdXNpbmVzc09iamVjdChlbGVtZW50LCAnaWQnLCB7IGlkOiB2YWx1ZXMucHJvY2Vzc0lkIH0pO1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgaWRFbnRyeS52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICAgIHZhciBpZFZhbHVlID0gdmFsdWVzLnByb2Nlc3NJZDtcclxuXHJcbiAgICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gICAgICAgIHZhciBwcm9jZXNzSWRFcnJvciA9IHV0aWxzLmlzSWRWYWxpZChiby5wcm9jZXNzUmVmLCBpZFZhbHVlLCB0cmFuc2xhdGUpO1xyXG5cclxuICAgICAgICByZXR1cm4gcHJvY2Vzc0lkRXJyb3IgPyB7IHByb2Nlc3NJZDogcHJvY2Vzc0lkRXJyb3IgfSA6IHt9O1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgZ3JvdXAuZW50cmllcy5wdXNoKGlkRW50cnkpO1xyXG5cclxuXHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBwcm9jZXNzIG5hbWVcclxuICAgICAgICovXHJcbiAgICAgIHZhciBwcm9jZXNzTmFtZUVudHJ5ID0gbmFtZUVudHJ5RmFjdG9yeShlbGVtZW50LCB7XHJcbiAgICAgICAgaWQ6ICdwcm9jZXNzLW5hbWUnLFxyXG4gICAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1Byb2Nlc3MgTmFtZScpXHJcbiAgICAgIH0pWzBdO1xyXG5cclxuICAgICAgLy8gaW4gcGFydGljaXBhbnRzIHdlIGhhdmUgdG8gY2hhbmdlIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHNldCBhbmQgZ2V0XHJcbiAgICAgIHByb2Nlc3NOYW1lRW50cnkuZ2V0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiBwYXJ0aWNpcGFudEhlbHBlci5nZXRQcm9jZXNzQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgJ25hbWUnKTtcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHByb2Nlc3NOYW1lRW50cnkuc2V0ID0gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnRpY2lwYW50SGVscGVyLm1vZGlmeVByb2Nlc3NCdXNpbmVzc09iamVjdChlbGVtZW50LCAnbmFtZScsIHZhbHVlcyk7XHJcbiAgICAgIH07XHJcblxyXG4gICAgICBncm91cC5lbnRyaWVzLnB1c2gocHJvY2Vzc05hbWVFbnRyeSk7XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyksXHJcbiAgICB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL1V0aWxzJyk7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzO1xyXG5cclxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpLFxyXG4gICAgZmluZCA9IHJlcXVpcmUoJ2xvZGFzaC9maW5kJyksXHJcbiAgICBmaWx0ZXIgPSByZXF1aXJlKCdsb2Rhc2gvZmlsdGVyJyk7XHJcblxyXG5cclxuZnVuY3Rpb24gZ2V0Q29udGFpbmVkQWN0aXZpdGllcyhlbGVtZW50KSB7XHJcbiAgcmV0dXJuIGdldEZsb3dFbGVtZW50cyhlbGVtZW50LCAnYnBtbjpBY3Rpdml0eScpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRDb250YWluZWRCb3VuZGFyeUV2ZW50cyhlbGVtZW50KSB7XHJcbiAgcmV0dXJuIGdldEZsb3dFbGVtZW50cyhlbGVtZW50LCAnYnBtbjpCb3VuZGFyeUV2ZW50Jyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEZsb3dFbGVtZW50cyhlbGVtZW50LCB0eXBlKSB7XHJcbiAgcmV0dXJuIHV0aWxzLmZpbHRlckVsZW1lbnRzQnlUeXBlKGVsZW1lbnQuZmxvd0VsZW1lbnRzLCB0eXBlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNDb21wZW5zYXRpb25FdmVudEF0dGFjaGVkVG9BY3Rpdml0eShhY3Rpdml0eSwgYm91bmRhcnlFdmVudHMpIHtcclxuICB2YXIgYWN0aXZpdHlJZCA9IGFjdGl2aXR5LmlkO1xyXG4gIHZhciBib3VuZGFyeUV2ZW50ID0gZmluZChib3VuZGFyeUV2ZW50cywgZnVuY3Rpb24oYm91bmRhcnlFdmVudCkge1xyXG4gICAgdmFyIGNvbXBlbnNhdGVFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0Q29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbihib3VuZGFyeUV2ZW50KTtcclxuICAgIHZhciBhdHRhY2hlZFRvUmVmID0gYm91bmRhcnlFdmVudC5hdHRhY2hlZFRvUmVmO1xyXG4gICAgcmV0dXJuIGNvbXBlbnNhdGVFdmVudERlZmluaXRpb24gJiYgYXR0YWNoZWRUb1JlZiAmJiBhdHRhY2hlZFRvUmVmLmlkID09PSBhY3Rpdml0eUlkO1xyXG4gIH0pO1xyXG4gIHJldHVybiAhIWJvdW5kYXJ5RXZlbnQ7XHJcbn1cclxuXHJcbi8vIHN1YnByb2Nlc3M6IG9ubHkgd2hlbiBpdCBpcyBub3QgdHJpZ2dlcmVkQnlFdmVudFxyXG4vLyBhY3Rpdml0eTogb25seSB3aGVuIGl0IGF0dGFjaCBhIGNvbXBlbnNhdGlvbiBib3VuZGFyeSBldmVudFxyXG4vLyBjYWxsQWN0aXZpdHk6IG5vIGxpbWl0YXRpb25cclxuZnVuY3Rpb24gY2FuQWN0aXZpdHlCZUNvbXBlbnNhdGVkKGFjdGl2aXR5LCBib3VuZGFyeUV2ZW50cykge1xyXG4gIHJldHVybiAoaXMoYWN0aXZpdHksICdicG1uOlN1YlByb2Nlc3MnKSAmJiAhYWN0aXZpdHkudHJpZ2dlcmVkQnlFdmVudCkgfHxcclxuICAgICAgICAgIGlzKGFjdGl2aXR5LCAnYnBtbjpDYWxsQWN0aXZpdHknKSB8fFxyXG4gICAgICAgICAgaXNDb21wZW5zYXRpb25FdmVudEF0dGFjaGVkVG9BY3Rpdml0eShhY3Rpdml0eSwgYm91bmRhcnlFdmVudHMpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRBY3Rpdml0aWVzRm9yQ29tcGVuc2F0aW9uKGVsZW1lbnQpIHtcclxuICB2YXIgYm91bmRhcnlFdmVudHMgPSBnZXRDb250YWluZWRCb3VuZGFyeUV2ZW50cyhlbGVtZW50KTtcclxuICByZXR1cm4gZmlsdGVyKGdldENvbnRhaW5lZEFjdGl2aXRpZXMoZWxlbWVudCksIGZ1bmN0aW9uKGFjdGl2aXR5KSB7XHJcbiAgICByZXR1cm4gY2FuQWN0aXZpdHlCZUNvbXBlbnNhdGVkKGFjdGl2aXR5LCBib3VuZGFyeUV2ZW50cyk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEFjdGl2aXRpZXNGb3JBY3Rpdml0eVJlZihlbGVtZW50KSB7XHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgdmFyIHBhcmVudCA9IGJvLiRwYXJlbnQ7XHJcblxyXG4gIHZhciBhY3Rpdml0aWVzRm9yQWN0aXZpdHlSZWYgPSBnZXRBY3Rpdml0aWVzRm9yQ29tcGVuc2F0aW9uKHBhcmVudCk7XHJcblxyXG4gIC8vIGlmIHRocm93aW5nIGNvbXBlbnNhdGlvbiBldmVudCBpcyBpbiBhbiBldmVudCBzdWIgcHJvY2VzczpcclxuICAvLyBnZXQgYWxzbyBhbGwgYWN0aXZpdGllcyBvdXRzaWRlIG9mIHRoZSBldmVudCBzdWIgcHJvY2Vzc1xyXG4gIGlmIChpcyhwYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJiBwYXJlbnQudHJpZ2dlcmVkQnlFdmVudCkge1xyXG4gICAgcGFyZW50ID0gcGFyZW50LiRwYXJlbnQ7XHJcbiAgICBpZiAocGFyZW50KSB7XHJcbiAgICAgIGFjdGl2aXRpZXNGb3JBY3Rpdml0eVJlZiA9IGFjdGl2aXRpZXNGb3JBY3Rpdml0eVJlZi5jb25jYXQoZ2V0QWN0aXZpdGllc0ZvckNvbXBlbnNhdGlvbihwYXJlbnQpKTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICByZXR1cm4gYWN0aXZpdGllc0ZvckFjdGl2aXR5UmVmO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0eVJlZk9wdGlvbnMoZWxlbWVudCkge1xyXG4gIHZhciBvcHRpb25zID0gWyB7IHZhbHVlOiAnJyB9IF07XHJcblxyXG4gIHZhciBhY3Rpdml0aWVzID0gZ2V0QWN0aXZpdGllc0ZvckFjdGl2aXR5UmVmKGVsZW1lbnQpO1xyXG4gIGZvckVhY2goYWN0aXZpdGllcywgZnVuY3Rpb24oYWN0aXZpdHkpIHtcclxuICAgIHZhciBhY3Rpdml0eUlkID0gYWN0aXZpdHkuaWQ7XHJcbiAgICB2YXIgbmFtZSA9IChhY3Rpdml0eS5uYW1lID8gKGFjdGl2aXR5Lm5hbWUgKyAnICcpIDogJycpICsgJyhpZD0nICsgYWN0aXZpdHlJZCArICcpJztcclxuICAgIG9wdGlvbnMucHVzaCh7IHZhbHVlOiBhY3Rpdml0eUlkLCBuYW1lOiBuYW1lIH0pO1xyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gb3B0aW9ucztcclxufVxyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmNoZWNrYm94KHtcclxuICAgIGlkOiAnd2FpdC1mb3ItY29tcGxldGlvbicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdXYWl0IGZvciBDb21wbGV0aW9uJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnd2FpdEZvckNvbXBsZXRpb24nLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHdhaXRGb3JDb21wbGV0aW9uOiBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLndhaXRGb3JDb21wbGV0aW9uXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhbHVlcy53YWl0Rm9yQ29tcGxldGlvbiA9IHZhbHVlcy53YWl0Rm9yQ29tcGxldGlvbiB8fCBmYWxzZTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLCB2YWx1ZXMpO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6ICdhY3Rpdml0eS1yZWYnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQWN0aXZpdHkgUmVmJyksXHJcbiAgICBzZWxlY3RPcHRpb25zOiBjcmVhdGVBY3Rpdml0eVJlZk9wdGlvbnMoZWxlbWVudCksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnYWN0aXZpdHlSZWYnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYWN0aXZpdHlSZWYgPSBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLmFjdGl2aXR5UmVmO1xyXG4gICAgICBhY3Rpdml0eVJlZiA9IGFjdGl2aXR5UmVmICYmIGFjdGl2aXR5UmVmLmlkO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGFjdGl2aXR5UmVmOiBhY3Rpdml0eVJlZiB8fCAnJ1xyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgYWN0aXZpdHlSZWYgPSB2YWx1ZXMuYWN0aXZpdHlSZWYgfHwgdW5kZWZpbmVkO1xyXG4gICAgICBhY3Rpdml0eVJlZiA9IGFjdGl2aXR5UmVmICYmIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnRSZWdpc3RyeS5nZXQoYWN0aXZpdHlSZWYpKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLCB7XHJcbiAgICAgICAgYWN0aXZpdHlSZWY6IGFjdGl2aXR5UmVmXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGlzRXZlbnRTdWJQcm9jZXNzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9EaVV0aWwnKS5pc0V2ZW50U3ViUHJvY2VzcztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbiwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldFZhbHVlID0gZnVuY3Rpb24obW9kZWxQcm9wZXJ0eSkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgdmFyIG1vZGVsUHJvcGVydHlWYWx1ZSA9IGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uLmdldCgnY2FtdW5kYTonICsgbW9kZWxQcm9wZXJ0eSk7XHJcbiAgICAgIHZhciB2YWx1ZSA9IHt9O1xyXG5cclxuICAgICAgdmFsdWVbbW9kZWxQcm9wZXJ0eV0gPSBtb2RlbFByb3BlcnR5VmFsdWU7XHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgdmFyIHNldFZhbHVlID0gZnVuY3Rpb24obW9kZWxQcm9wZXJ0eSkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgcHJvcHMgPSB7fTtcclxuXHJcbiAgICAgIHByb3BzWydjYW11bmRhOicgKyBtb2RlbFByb3BlcnR5XSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uLCBwcm9wcyk7XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAndmFyaWFibGVOYW1lJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1ZhcmlhYmxlIE5hbWUnKSxcclxuICAgIG1vZGVsUHJvcGVydHkgOiAndmFyaWFibGVOYW1lJyxcclxuXHJcbiAgICBnZXQ6IGdldFZhbHVlKCd2YXJpYWJsZU5hbWUnKSxcclxuICAgIHNldDogc2V0VmFsdWUoJ3ZhcmlhYmxlTmFtZScpXHJcbiAgfSkpO1xyXG5cclxuICB2YXIgaXNDb25kaXRpb25hbFN0YXJ0RXZlbnQgPVxyXG4gICAgaXMoZWxlbWVudCwgJ2JwbW46U3RhcnRFdmVudCcpICYmICFpc0V2ZW50U3ViUHJvY2VzcyhlbGVtZW50LnBhcmVudCk7XHJcblxyXG4gIGlmICghaXNDb25kaXRpb25hbFN0YXJ0RXZlbnQpIHtcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQ6ICd2YXJpYWJsZUV2ZW50JyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnVmFyaWFibGUgRXZlbnQnKSxcclxuICAgICAgZGVzY3JpcHRpb246IHRyYW5zbGF0ZSgnU3BlY2lmeSBtb3JlIHRoYW4gb25lIHZhcmlhYmxlIGNoYW5nZSBldmVudCBhcyBhIGNvbW1hIHNlcGFyYXRlZCBsaXN0LicpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5IDogJ3ZhcmlhYmxlRXZlbnQnLFxyXG5cclxuICAgICAgZ2V0OiBnZXRWYWx1ZSgndmFyaWFibGVFdmVudCcpLFxyXG4gICAgICBzZXQ6IHNldFZhbHVlKCd2YXJpYWJsZUV2ZW50JylcclxuICAgIH0pKTtcclxuICB9XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYW4gZW50cnkgdG8gbW9kaWZ5IGEgcHJvcGVydHkgb2YgYW4gZWxlbWVudCB3aGljaFxyXG4gKiBpcyByZWZlcmVuY2VkIGJ5IGEgZXZlbnQgZGVmaW5pdGlvbi5cclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gZGVmaW5pdGlvblxyXG4gKiBAcGFyYW0gIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5pZCB0aGUgaWQgb2YgdGhlIGVudHJ5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5sYWJlbCB0aGUgbGFiZWwgb2YgdGhlIGVudHJ5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5yZWZlcmVuY2VQcm9wZXJ0eSB0aGUgbmFtZSBvZiByZWZlcmVuY2luZyBwcm9wZXJ0eVxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eSB0aGUgbmFtZSBvZiBwcm9wZXJ0eSB0byBtb2RpZnlcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLnNob3VsZFZhbGlkYXRlIGEgZmxhZyBpbmRpY2F0ZSB3aGV0aGVyIHRvIHZhbGlkYXRlIG9yIG5vdFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtBcnJheTxPYmplY3Q+fSByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyB0aGUgZW50cmllc1xyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBkZWZpbml0aW9uLCBicG1uRmFjdG9yeSwgb3B0aW9ucykge1xyXG5cclxuICB2YXIgaWQgPSBvcHRpb25zLmlkIHx8ICdlbGVtZW50LXByb3BlcnR5JztcclxuICB2YXIgbGFiZWwgPSBvcHRpb25zLmxhYmVsO1xyXG4gIHZhciByZWZlcmVuY2VQcm9wZXJ0eSA9IG9wdGlvbnMucmVmZXJlbmNlUHJvcGVydHk7XHJcbiAgdmFyIG1vZGVsUHJvcGVydHkgPSBvcHRpb25zLm1vZGVsUHJvcGVydHkgfHwgJ25hbWUnO1xyXG4gIHZhciBzaG91bGRWYWxpZGF0ZSA9IG9wdGlvbnMuc2hvdWxkVmFsaWRhdGUgfHwgZmFsc2U7XHJcblxyXG4gIHZhciBlbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6IGlkLFxyXG4gICAgbGFiZWw6IGxhYmVsLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogbW9kZWxQcm9wZXJ0eSxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIHJlZmVyZW5jZSA9IGRlZmluaXRpb24uZ2V0KHJlZmVyZW5jZVByb3BlcnR5KTtcclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW21vZGVsUHJvcGVydHldID0gcmVmZXJlbmNlICYmIHJlZmVyZW5jZS5nZXQobW9kZWxQcm9wZXJ0eSk7XHJcbiAgICAgIHJldHVybiBwcm9wcztcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIHJlZmVyZW5jZSA9IGRlZmluaXRpb24uZ2V0KHJlZmVyZW5jZVByb3BlcnR5KTtcclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW21vZGVsUHJvcGVydHldID0gdmFsdWVzW21vZGVsUHJvcGVydHldIHx8IHVuZGVmaW5lZDtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCByZWZlcmVuY2UsIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhZGVmaW5pdGlvbi5nZXQocmVmZXJlbmNlUHJvcGVydHkpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICBpZiAoc2hvdWxkVmFsaWRhdGUpIHtcclxuICAgIGVudHJ5LnZhbGlkYXRlID0gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciByZWZlcmVuY2UgPSBkZWZpbml0aW9uLmdldChyZWZlcmVuY2VQcm9wZXJ0eSk7XHJcbiAgICAgIGlmIChyZWZlcmVuY2UgJiYgIXZhbHVlc1ttb2RlbFByb3BlcnR5XSkge1xyXG4gICAgICAgIHZhciB2YWxpZGF0aW9uRXJyb3JzID0ge307XHJcbiAgICAgICAgdmFsaWRhdGlvbkVycm9yc1ttb2RlbFByb3BlcnR5XSA9ICdNdXN0IHByb3ZpZGUgYSB2YWx1ZSc7XHJcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRpb25FcnJvcnM7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICByZXR1cm4gWyBlbnRyeSBdO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXZlbnREZWZpbml0aW9uUmVmZXJlbmNlID0gcmVxdWlyZSgnLi9FdmVudERlZmluaXRpb25SZWZlcmVuY2UnKSxcclxuICAgIGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vRWxlbWVudFJlZmVyZW5jZVByb3BlcnR5Jyk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIGVycm9yRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpIHtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChldmVudERlZmluaXRpb25SZWZlcmVuY2UoZWxlbWVudCwgZXJyb3JFdmVudERlZmluaXRpb24sIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdFcnJvcicpLFxyXG4gICAgZWxlbWVudE5hbWU6ICdlcnJvcicsXHJcbiAgICBlbGVtZW50VHlwZTogJ2JwbW46RXJyb3InLFxyXG4gICAgcmVmZXJlbmNlUHJvcGVydHk6ICdlcnJvclJlZicsXHJcbiAgICBuZXdFbGVtZW50SWRQcmVmaXg6ICdFcnJvcl8nXHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eShlbGVtZW50LCBlcnJvckV2ZW50RGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkOiAnZXJyb3ItZWxlbWVudC1uYW1lJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0Vycm9yIE5hbWUnKSxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnZXJyb3JSZWYnLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ25hbWUnLFxyXG4gICAgc2hvdWxkVmFsaWRhdGU6IHRydWVcclxuICB9KSk7XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoZWxlbWVudFJlZmVyZW5jZVByb3BlcnR5KGVsZW1lbnQsIGVycm9yRXZlbnREZWZpbml0aW9uLCBicG1uRmFjdG9yeSwge1xyXG4gICAgaWQ6ICdlcnJvci1lbGVtZW50LWNvZGUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXJyb3IgQ29kZScpLFxyXG4gICAgcmVmZXJlbmNlUHJvcGVydHk6ICdlcnJvclJlZicsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZXJyb3JDb2RlJ1xyXG4gIH0pKTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxudmFyIGV2ZW50RGVmaW5pdGlvblJlZmVyZW5jZSA9IHJlcXVpcmUoJy4vRXZlbnREZWZpbml0aW9uUmVmZXJlbmNlJyksXHJcbiAgICBlbGVtZW50UmVmZXJlbmNlUHJvcGVydHkgPSByZXF1aXJlKCcuL0VsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eScpO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uLCBzaG93RXNjYWxhdGlvbkNvZGVWYXJpYWJsZSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChldmVudERlZmluaXRpb25SZWZlcmVuY2UoZWxlbWVudCwgZXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIHtcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0VzY2FsYXRpb24nKSxcclxuICAgIGVsZW1lbnROYW1lOiAnZXNjYWxhdGlvbicsXHJcbiAgICBlbGVtZW50VHlwZTogJ2JwbW46RXNjYWxhdGlvbicsXHJcbiAgICByZWZlcmVuY2VQcm9wZXJ0eTogJ2VzY2FsYXRpb25SZWYnLFxyXG4gICAgbmV3RWxlbWVudElkUHJlZml4OiAnRXNjYWxhdGlvbl8nXHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eShlbGVtZW50LCBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uLCBicG1uRmFjdG9yeSwge1xyXG4gICAgaWQ6ICdlc2NhbGF0aW9uLWVsZW1lbnQtbmFtZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdFc2NhbGF0aW9uIE5hbWUnKSxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnZXNjYWxhdGlvblJlZicsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnbmFtZScsXHJcbiAgICBzaG91bGRWYWxpZGF0ZTogdHJ1ZVxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChlbGVtZW50UmVmZXJlbmNlUHJvcGVydHkoZWxlbWVudCwgZXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkOiAnZXNjYWxhdGlvbi1lbGVtZW50LWNvZGUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXNjYWxhdGlvbiBDb2RlJyksXHJcbiAgICByZWZlcmVuY2VQcm9wZXJ0eTogJ2VzY2FsYXRpb25SZWYnLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2VzY2FsYXRpb25Db2RlJ1xyXG4gIH0pKTtcclxuXHJcblxyXG4gIGlmIChzaG93RXNjYWxhdGlvbkNvZGVWYXJpYWJsZSkge1xyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgICBpZCA6ICdlc2NhbGF0aW9uQ29kZVZhcmlhYmxlJyxcclxuICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0VzY2FsYXRpb24gQ29kZSBWYXJpYWJsZScpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5IDogJ2VzY2FsYXRpb25Db2RlVmFyaWFibGUnLFxyXG5cclxuICAgICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgICAgdmFyIGNvZGVWYXJpYWJsZSA9IGVzY2FsYXRpb25FdmVudERlZmluaXRpb24uZ2V0KCdjYW11bmRhOmVzY2FsYXRpb25Db2RlVmFyaWFibGUnKTtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgZXNjYWxhdGlvbkNvZGVWYXJpYWJsZTogY29kZVZhcmlhYmxlXHJcbiAgICAgICAgfTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uLCB7XHJcbiAgICAgICAgICAnY2FtdW5kYTplc2NhbGF0aW9uQ29kZVZhcmlhYmxlJzogdmFsdWVzLmVzY2FsYXRpb25Db2RlVmFyaWFibGUgfHwgdW5kZWZpbmVkXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pKTtcclxuICB9XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnksXHJcbiAgICBkb21pZnkgPSByZXF1aXJlKCdtaW4tZG9tJykuZG9taWZ5LFxyXG4gICAgZG9tQXR0ciA9IHJlcXVpcmUoJ21pbi1kb20nKS5hdHRyO1xyXG5cclxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpLFxyXG4gICAgZmluZCA9IHJlcXVpcmUoJ2xvZGFzaC9maW5kJyk7XHJcblxyXG52YXIgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyk7XHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL1V0aWxzJyksXHJcbiAgICBlc2NhcGVIVE1MID0gdXRpbHMuZXNjYXBlSFRNTDtcclxuXHJcbnZhciBzZWxlY3RvciA9ICdzZWxlY3RbbmFtZT1zZWxlY3RlZEVsZW1lbnRdJztcclxuXHJcbi8qKlxyXG4gKiBHZXQgc2VsZWN0IGJveCBjb250YWluaW5nIGFsbCBlbGVtZW50cy5cclxuICpcclxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXHJcbiAqXHJcbiAqIEByZXR1cm4ge0RPTUVsZW1lbnR9IHRoZSBzZWxlY3QgYm94XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRTZWxlY3RCb3gobm9kZSkge1xyXG4gIHJldHVybiBkb21RdWVyeShzZWxlY3Rvciwgbm9kZS5wYXJlbnRFbGVtZW50KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbmQgZWxlbWVudCBieSBnaXZlbiBpZC5cclxuICpcclxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBldmVudERlZmluaXRpb25cclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gYW4gZWxlbWVudFxyXG4gKi9cclxuZnVuY3Rpb24gZmluZEVsZW1lbnRCeUlkKGV2ZW50RGVmaW5pdGlvbiwgdHlwZSwgaWQpIHtcclxuICB2YXIgZWxlbWVudHMgPSB1dGlscy5maW5kUm9vdEVsZW1lbnRzQnlUeXBlKGV2ZW50RGVmaW5pdGlvbiwgdHlwZSk7XHJcbiAgcmV0dXJuIGZpbmQoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBlbGVtZW50LmlkID09PSBpZDtcclxuICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhbiBlbnRyeSB0byBtb2RpZnkgdGhlIHJlZmVyZW5jZSB0byBhbiBlbGVtZW50IGZyb20gYW5cclxuICogZXZlbnQgZGVmaW5pdGlvbi5cclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gZGVmaW5pdGlvblxyXG4gKiBAcGFyYW0gIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5sYWJlbCB0aGUgbGFiZWwgb2YgdGhlIGVudHJ5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5kZXNjcmlwdGlvbiB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGVudHJ5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5lbGVtZW50TmFtZSB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudFxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMuZWxlbWVudFR5cGUgdGhlIHR5cGUgb2YgdGhlIGVsZW1lbnRcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLnJlZmVyZW5jZVByb3BlcnR5IHRoZSBuYW1lIG9mIHJlZmVyZW5jaW5nIHByb3BlcnR5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5uZXdFbGVtZW50SWRQcmVmaXggdGhlIHByZWZpeCBvZiBhIG5ldyBjcmVhdGVkIGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn0gcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIGVudHJpZXNcclxuICovXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgZGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIG9wdGlvbnMpIHtcclxuXHJcbiAgdmFyIGVsZW1lbnROYW1lID0gb3B0aW9ucy5lbGVtZW50TmFtZSB8fCAnJyxcclxuICAgICAgZWxlbWVudFR5cGUgPSBvcHRpb25zLmVsZW1lbnRUeXBlLFxyXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eSA9IG9wdGlvbnMucmVmZXJlbmNlUHJvcGVydHk7XHJcblxyXG4gIHZhciBuZXdFbGVtZW50SWRQcmVmaXggPSBvcHRpb25zLm5ld0VsZW1lbnRJZFByZWZpeCB8fCAnZWxlbV8nO1xyXG5cclxuICB2YXIgbGFiZWwgPSBvcHRpb25zLmxhYmVsIHx8ICcnLFxyXG4gICAgICBkZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb24gfHwgJyc7XHJcblxyXG4gIHZhciBlbnRyaWVzID0gW107XHJcblxyXG4gIGVudHJpZXMucHVzaCh7XHJcblxyXG4gICAgaWQ6ICdldmVudC1kZWZpbml0aW9ucy0nICsgZWxlbWVudE5hbWUsXHJcbiAgICBkZXNjcmlwdGlvbjogZGVzY3JpcHRpb24sXHJcbiAgICBodG1sOiAnPGRpdiBjbGFzcz1cImJwcC1yb3cgYnBwLXNlbGVjdFwiPicgK1xyXG4gICAgICAgICAgICAgJzxsYWJlbCBmb3I9XCJjYW11bmRhLScgKyBlc2NhcGVIVE1MKGVsZW1lbnROYW1lKSArICdcIj4nICsgZXNjYXBlSFRNTChsYWJlbCkgKyAnPC9sYWJlbD4nICtcclxuICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXJcIj4nICtcclxuICAgICAgICAgICAgICAgJzxzZWxlY3QgaWQ9XCJjYW11bmRhLScgKyBlc2NhcGVIVE1MKGVsZW1lbnROYW1lKSArICdcIiBuYW1lPVwic2VsZWN0ZWRFbGVtZW50XCIgZGF0YS12YWx1ZT4nICtcclxuICAgICAgICAgICAgICAgJzwvc2VsZWN0PicgK1xyXG4gICAgICAgICAgICAgICAnPGJ1dHRvbiBjbGFzcz1cImFkZFwiIGlkPVwiYWRkRWxlbWVudFwiIGRhdGEtYWN0aW9uPVwiYWRkRWxlbWVudFwiPjxzcGFuPis8L3NwYW4+PC9idXR0b24+JyArXHJcbiAgICAgICAgICAgICAnPC9kaXY+JyArXHJcbiAgICAgICAgICAnPC9kaXY+JyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGVudHJ5Tm9kZSkge1xyXG4gICAgICB1dGlscy51cGRhdGVPcHRpb25zRHJvcERvd24oc2VsZWN0b3IsIGRlZmluaXRpb24sIGVsZW1lbnRUeXBlLCBlbnRyeU5vZGUpO1xyXG4gICAgICB2YXIgcmVmZXJlbmNlID0gZGVmaW5pdGlvbi5nZXQocmVmZXJlbmNlUHJvcGVydHkpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudDogKHJlZmVyZW5jZSAmJiByZWZlcmVuY2UuaWQpIHx8ICcnXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBzZWxlY3Rpb24gPSB2YWx1ZXMuc2VsZWN0ZWRFbGVtZW50O1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcblxyXG4gICAgICBpZiAoIXNlbGVjdGlvbiB8fCB0eXBlb2Ygc2VsZWN0aW9uID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIC8vIHJlbW92ZSByZWZlcmVuY2UgdG8gZWxlbWVudFxyXG4gICAgICAgIHByb3BzW3JlZmVyZW5jZVByb3BlcnR5XSA9IHVuZGVmaW5lZDtcclxuICAgICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGRlZmluaXRpb24sIHByb3BzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcblxyXG4gICAgICB2YXIgc2VsZWN0ZWRFbGVtZW50ID0gZmluZEVsZW1lbnRCeUlkKGRlZmluaXRpb24sIGVsZW1lbnRUeXBlLCBzZWxlY3Rpb24pO1xyXG4gICAgICBpZiAoIXNlbGVjdGVkRWxlbWVudCkge1xyXG4gICAgICAgIHZhciByb290ID0gdXRpbHMuZ2V0Um9vdChkZWZpbml0aW9uKTtcclxuXHJcbiAgICAgICAgLy8gY3JlYXRlIGEgbmV3IGVsZW1lbnRcclxuICAgICAgICBzZWxlY3RlZEVsZW1lbnQgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoZWxlbWVudFR5cGUsIHsgbmFtZTogc2VsZWN0aW9uIH0sIHJvb3QsIGJwbW5GYWN0b3J5KTtcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5hZGRBbmRSZW1vdmVFbGVtZW50c0Zyb21MaXN0KGVsZW1lbnQsIHJvb3QsICdyb290RWxlbWVudHMnLCBudWxsLCBbIHNlbGVjdGVkRWxlbWVudCBdKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHVwZGF0ZSByZWZlcmVuY2UgdG8gZWxlbWVudFxyXG4gICAgICBwcm9wc1tyZWZlcmVuY2VQcm9wZXJ0eV0gPSBzZWxlY3RlZEVsZW1lbnQ7XHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGRlZmluaXRpb24sIHByb3BzKSk7XHJcblxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcbiAgICB9LFxyXG5cclxuICAgIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSkge1xyXG4gICAgICAvLyBub3RlOiB0aGlzIGdlbmVyYXRlZCBpZCB3aWxsIGJlIHVzZWQgYXMgbmFtZVxyXG4gICAgICAvLyBvZiB0aGUgZWxlbWVudCBhbmQgbm90IGFzIGlkXHJcbiAgICAgIHZhciBpZCA9IHV0aWxzLm5leHRJZChuZXdFbGVtZW50SWRQcmVmaXgpO1xyXG5cclxuICAgICAgdmFyIG9wdGlvblRlbXBsYXRlID0gZG9taWZ5KCc8b3B0aW9uIHZhbHVlPVwiJyArIGVzY2FwZUhUTUwoaWQpICsgJ1wiPiAoaWQ9Jytlc2NhcGVIVE1MKGlkKSsnKScgKyAnPC9vcHRpb24+Jyk7XHJcblxyXG4gICAgICAvLyBhZGQgbmV3IG9wdGlvblxyXG4gICAgICB2YXIgc2VsZWN0Qm94ID0gZ2V0U2VsZWN0Qm94KGlucHV0Tm9kZSk7XHJcbiAgICAgIHNlbGVjdEJveC5pbnNlcnRCZWZvcmUob3B0aW9uVGVtcGxhdGUsIHNlbGVjdEJveC5maXJzdENoaWxkKTtcclxuXHJcbiAgICAgIC8vIHNlbGVjdCBuZXcgZWxlbWVudCBpbiB0aGUgc2VsZWN0IGJveFxyXG4gICAgICBmb3JFYWNoKHNlbGVjdEJveCwgZnVuY3Rpb24ob3B0aW9uKSB7XHJcbiAgICAgICAgaWYgKG9wdGlvbi52YWx1ZSA9PT0gaWQpIHtcclxuICAgICAgICAgIGRvbUF0dHIob3B0aW9uLCAnc2VsZWN0ZWQnLCAnc2VsZWN0ZWQnKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgZG9tQXR0cihvcHRpb24sICdzZWxlY3RlZCcsIG51bGwpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBlbnRyaWVzO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGV2ZW50RGVmaW5pdGlvblJlZmVyZW5jZSA9IHJlcXVpcmUoJy4vRXZlbnREZWZpbml0aW9uUmVmZXJlbmNlJyksXHJcbiAgICBlbGVtZW50UmVmZXJlbmNlUHJvcGVydHkgPSByZXF1aXJlKCcuL0VsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eScpO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBtZXNzYWdlRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGV2ZW50RGVmaW5pdGlvblJlZmVyZW5jZShlbGVtZW50LCBtZXNzYWdlRXZlbnREZWZpbml0aW9uLCBicG1uRmFjdG9yeSwge1xyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnTWVzc2FnZScpLFxyXG4gICAgZWxlbWVudE5hbWU6ICdtZXNzYWdlJyxcclxuICAgIGVsZW1lbnRUeXBlOiAnYnBtbjpNZXNzYWdlJyxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnbWVzc2FnZVJlZicsXHJcbiAgICBuZXdFbGVtZW50SWRQcmVmaXg6ICdNZXNzYWdlXydcclxuICB9KSk7XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoZWxlbWVudFJlZmVyZW5jZVByb3BlcnR5KGVsZW1lbnQsIG1lc3NhZ2VFdmVudERlZmluaXRpb24sIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ21lc3NhZ2UtZWxlbWVudC1uYW1lJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ01lc3NhZ2UgTmFtZScpLFxyXG4gICAgcmVmZXJlbmNlUHJvcGVydHk6ICdtZXNzYWdlUmVmJyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuICAgIHNob3VsZFZhbGlkYXRlOiB0cnVlXHJcbiAgfSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG4vKipcclxuICogQ3JlYXRlIGFuIGVudHJ5IHRvIG1vZGlmeSB0aGUgbmFtZSBvZiBhbiBhbiBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmlkIHRoZSBpZCBvZiB0aGUgZW50cnlcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmxhYmVsIHRoZSBsYWJlbCBvZiB0aGUgZW50cnlcclxuICpcclxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn0gcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmdcclxuICogICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGVudHJ5IHRvIG1vZGlmeSB0aGUgbmFtZVxyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcbiAgdmFyIGlkID0gb3B0aW9ucy5pZCB8fCAnbmFtZScsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCB8fCB0cmFuc2xhdGUoJ05hbWUnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eSB8fCAnbmFtZSc7XHJcblxyXG4gIHZhciBuYW1lRW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEJveCh7XHJcbiAgICBpZDogaWQsXHJcbiAgICBsYWJlbDogbGFiZWwsXHJcbiAgICBtb2RlbFByb3BlcnR5OiBtb2RlbFByb3BlcnR5LFxyXG4gICAgZ2V0OiBvcHRpb25zLmdldCxcclxuICAgIHNldDogb3B0aW9ucy5zZXRcclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIFsgbmFtZUVudHJ5IF07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXZlbnREZWZpbml0aW9uUmVmZXJlbmNlID0gcmVxdWlyZSgnLi9FdmVudERlZmluaXRpb25SZWZlcmVuY2UnKSxcclxuICAgIGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vRWxlbWVudFJlZmVyZW5jZVByb3BlcnR5Jyk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHNpZ25hbEV2ZW50RGVmaW5pdGlvbiwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChldmVudERlZmluaXRpb25SZWZlcmVuY2UoZWxlbWVudCwgc2lnbmFsRXZlbnREZWZpbml0aW9uLCBicG1uRmFjdG9yeSwge1xyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnU2lnbmFsJyksXHJcbiAgICBlbGVtZW50TmFtZTogJ3NpZ25hbCcsXHJcbiAgICBlbGVtZW50VHlwZTogJ2JwbW46U2lnbmFsJyxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnc2lnbmFsUmVmJyxcclxuICAgIG5ld0VsZW1lbnRJZFByZWZpeDogJ1NpZ25hbF8nXHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eShlbGVtZW50LCBzaWduYWxFdmVudERlZmluaXRpb24sIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ3NpZ25hbC1lbGVtZW50LW5hbWUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnU2lnbmFsIE5hbWUnKSxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnc2lnbmFsUmVmJyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuICAgIHNob3VsZFZhbGlkYXRlOiB0cnVlXHJcbiAgfSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG4vKipcclxuICogR2V0IHRoZSB0aW1lciBkZWZpbml0aW9uIHR5cGUgZm9yIGEgZ2l2ZW4gdGltZXIgZXZlbnQgZGVmaW5pdGlvbi5cclxuICpcclxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50PGJwbW46VGltZXJFdmVudERlZmluaXRpb24+fSB0aW1lclxyXG4gKlxyXG4gKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSB0aGUgdGltZXIgZGVmaW5pdGlvbiB0eXBlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRUaW1lckRlZmluaXRpb25UeXBlKHRpbWVyKSB7XHJcbiAgdmFyIHRpbWVEYXRlID0gdGltZXIuZ2V0KCd0aW1lRGF0ZScpO1xyXG4gIGlmICh0eXBlb2YgdGltZURhdGUgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXR1cm4gJ3RpbWVEYXRlJztcclxuICB9XHJcblxyXG4gIHZhciB0aW1lQ3ljbGUgPSB0aW1lci5nZXQoJ3RpbWVDeWNsZScpO1xyXG4gIGlmICh0eXBlb2YgdGltZUN5Y2xlICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmV0dXJuICd0aW1lQ3ljbGUnO1xyXG4gIH1cclxuXHJcbiAgdmFyIHRpbWVEdXJhdGlvbiA9IHRpbWVyLmdldCgndGltZUR1cmF0aW9uJyk7XHJcbiAgaWYgKHR5cGVvZiB0aW1lRHVyYXRpb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXR1cm4gJ3RpbWVEdXJhdGlvbic7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogQ3JlYXRlcyAnYnBtbjpGb3JtYWxFeHByZXNzaW9uJyBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IHBhcmVudFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gYm9keVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50PGJwbW46Rm9ybWFsRXhwcmVzc2lvbj59IGEgZm9ybWFsIGV4cHJlc3Npb25cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUZvcm1hbEV4cHJlc3Npb24ocGFyZW50LCBib2R5LCBicG1uRmFjdG9yeSkge1xyXG4gIGJvZHkgPSBib2R5IHx8IHVuZGVmaW5lZDtcclxuICByZXR1cm4gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkZvcm1hbEV4cHJlc3Npb24nLCB7IGJvZHk6IGJvZHkgfSwgcGFyZW50LCBicG1uRmFjdG9yeSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIFRpbWVyRXZlbnREZWZpbml0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdGltZXJFdmVudERlZmluaXRpb24sIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgc2VsZWN0T3B0aW9ucyA9IFtcclxuICAgIHsgdmFsdWU6ICd0aW1lRGF0ZScsIG5hbWU6IHRyYW5zbGF0ZSgnRGF0ZScpIH0sXHJcbiAgICB7IHZhbHVlOiAndGltZUR1cmF0aW9uJywgbmFtZTogdHJhbnNsYXRlKCdEdXJhdGlvbicpIH0sXHJcbiAgICB7IHZhbHVlOiAndGltZUN5Y2xlJywgbmFtZTogdHJhbnNsYXRlKCdDeWNsZScpIH1cclxuICBdO1xyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnNlbGVjdEJveCh7XHJcbiAgICBpZDogJ3RpbWVyLWV2ZW50LWRlZmluaXRpb24tdHlwZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdUaW1lciBEZWZpbml0aW9uIFR5cGUnKSxcclxuICAgIHNlbGVjdE9wdGlvbnM6IHNlbGVjdE9wdGlvbnMsXHJcbiAgICBlbXB0eVBhcmFtZXRlcjogdHJ1ZSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICd0aW1lckRlZmluaXRpb25UeXBlJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB0aW1lckRlZmluaXRpb25UeXBlOiBnZXRUaW1lckRlZmluaXRpb25UeXBlKHRpbWVyRXZlbnREZWZpbml0aW9uKSB8fCAnJ1xyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgdGltZUR1cmF0aW9uOiB1bmRlZmluZWQsXHJcbiAgICAgICAgdGltZURhdGU6IHVuZGVmaW5lZCxcclxuICAgICAgICB0aW1lQ3ljbGU6IHVuZGVmaW5lZFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmFyIG5ld1R5cGUgPSB2YWx1ZXMudGltZXJEZWZpbml0aW9uVHlwZTtcclxuICAgICAgaWYgKHZhbHVlcy50aW1lckRlZmluaXRpb25UeXBlKSB7XHJcbiAgICAgICAgdmFyIG9sZFR5cGUgPSBnZXRUaW1lckRlZmluaXRpb25UeXBlKHRpbWVyRXZlbnREZWZpbml0aW9uKTtcclxuXHJcbiAgICAgICAgdmFyIHZhbHVlO1xyXG4gICAgICAgIGlmIChvbGRUeXBlKSB7XHJcbiAgICAgICAgICB2YXIgZGVmaW5pdGlvbiA9IHRpbWVyRXZlbnREZWZpbml0aW9uLmdldChvbGRUeXBlKTtcclxuICAgICAgICAgIHZhbHVlID0gZGVmaW5pdGlvbi5nZXQoJ2JvZHknKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHByb3BzW25ld1R5cGVdID0gY3JlYXRlRm9ybWFsRXhwcmVzc2lvbih0aW1lckV2ZW50RGVmaW5pdGlvbiwgdmFsdWUsIGJwbW5GYWN0b3J5KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCB0aW1lckV2ZW50RGVmaW5pdGlvbiwgcHJvcHMpO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ3RpbWVyLWV2ZW50LWRlZmluaXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGltZXIgRGVmaW5pdGlvbicpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3RpbWVyRGVmaW5pdGlvbicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0VGltZXJEZWZpbml0aW9uVHlwZSh0aW1lckV2ZW50RGVmaW5pdGlvbik7XHJcbiAgICAgIHZhciBkZWZpbml0aW9uID0gdHlwZSAmJiB0aW1lckV2ZW50RGVmaW5pdGlvbi5nZXQodHlwZSk7XHJcbiAgICAgIHZhciB2YWx1ZSA9IGRlZmluaXRpb24gJiYgZGVmaW5pdGlvbi5nZXQoJ2JvZHknKTtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB0aW1lckRlZmluaXRpb246IHZhbHVlXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0VGltZXJEZWZpbml0aW9uVHlwZSh0aW1lckV2ZW50RGVmaW5pdGlvbik7XHJcbiAgICAgIHZhciBkZWZpbml0aW9uID0gdHlwZSAmJiB0aW1lckV2ZW50RGVmaW5pdGlvbi5nZXQodHlwZSk7XHJcblxyXG4gICAgICBpZiAoZGVmaW5pdGlvbikge1xyXG4gICAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgZGVmaW5pdGlvbiwge1xyXG4gICAgICAgICAgYm9keTogdmFsdWVzLnRpbWVyRGVmaW5pdGlvbiB8fCB1bmRlZmluZWRcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICB2YXIgdHlwZSA9IGdldFRpbWVyRGVmaW5pdGlvblR5cGUodGltZXJFdmVudERlZmluaXRpb24pO1xyXG4gICAgICB2YXIgZGVmaW5pdGlvbiA9IHR5cGUgJiYgdGltZXJFdmVudERlZmluaXRpb24uZ2V0KHR5cGUpO1xyXG4gICAgICBpZiAoZGVmaW5pdGlvbikge1xyXG4gICAgICAgIHZhciB2YWx1ZSA9IGRlZmluaXRpb24uZ2V0KCdib2R5Jyk7XHJcbiAgICAgICAgaWYgKCF2YWx1ZSkge1xyXG4gICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdGltZXJEZWZpbml0aW9uOiB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJylcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICByZXR1cm4gIWdldFRpbWVyRGVmaW5pdGlvblR5cGUodGltZXJFdmVudERlZmluaXRpb24pO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFRpbWVyRXZlbnREZWZpbml0aW9uO1xyXG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiDlhajlsYDlip/og73lsIHoo4VcbiAqIEBhdXRob3IgenJcbiAqIEB0eXBlIHt7cmVnaXN0ZXJGaWxlRHJvcCgqLCAqKTogdm9pZCwgc2F2ZUJwbW4oT2JqZWN0KTogdm9pZCwgaGFuZGxlRHJhZ092ZXIoKik6IHZvaWQsIHNldENvbG9yKE9iamVjdCk6IHZvaWQsIGRvd25Mb2FkKE9iamVjdCk6IHZvaWQsIHVwbG9hZChPYmplY3QsIE9iamVjdCwgT2JqZWN0KTogdm9pZCwgaGFuZGxlRmlsZVNlbGVjdCgqKTogdm9pZCwgc2V0RW5jb2RlZChPYmplY3QsIHN0cmluZywgc3RyaW5nKTogdm9pZCwgb3BlbkZyb21VcmwoT2JqZWN0LCBPYmplY3QsIE9iamVjdCwgc3RyaW5nKTogdm9pZCwgY3JlYXRlRGlhZ3JhbShzdHJpbmcsIE9iamVjdCwgT2JqZWN0KTogUHJvbWlzZTx2b2lkPiwgZ2V0VXJsUGFyYW06IHRvb2xzLmdldFVybFBhcmFtfX1cbiAqL1xuXG5pbXBvcnQgJCBmcm9tICdqcXVlcnknO1xuY29uc3QgcHJvSG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0O1xuY29uc3QgaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KFwiYnBtbmpzXCIpWzBdO1xuY29uc3Qga2V5ID0gaHJlZi5zcGxpdCh3aW5kb3cubG9jYXRpb24uaG9zdClbMV07XG5jb25zdCBwdWJsaWN1cmwgPSBwcm9Ib3N0ICsga2V5O1xuY29uc3QgdG9vbHMgPSB7XG4gICAgcmVnaXN0ZXJGaWxlRHJvcChjb250YWluZXIsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNvbnRhaW5lci5nZXQoMCkuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCB0b29scy5oYW5kbGVEcmFnT3ZlciwgZmFsc2UpO1xuICAgICAgICBjb250YWluZXIuZ2V0KDApLmFkZEV2ZW50TGlzdGVuZXIoJ2Ryb3AnLCB0b29scy5oYW5kbGVGaWxlU2VsZWN0LCBmYWxzZSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDojrflj5blnLDlnYDmoI/lj4LmlbBcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICAgKi9cbiAgICBnZXRVcmxQYXJhbTogZnVuY3Rpb24gKHVybCkge1xuICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgIGlmICh1cmwuaW5kZXhPZihcIj9cIikgIT0gLTEpIHtcbiAgICAgICAgICAgIHZhciBzdHIgPSB1cmwuc3BsaXQoXCI/XCIpWzFdO1xuICAgICAgICAgICAgdmFyIHN0cnMgPSBzdHIuc3BsaXQoXCImXCIpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0W3N0cnNbaV0uc3BsaXQoXCI9XCIpWzBdXSA9IHN0cnNbaV0uc3BsaXQoXCI9XCIpWzFdXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdFt1cmxdO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog6YCa6L+HeG1s5Yib5bu6YnBtblxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB4bWwg5Yib5bu6YnBtcyB4bWxcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gYnBtbk1vZGVsZXIgYnBtbuWvueixoVxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBjb250YWluZXIg5a655Zmo5a+56LGhXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlRGlhZ3JhbSh4bWwsIGJwbW5Nb2RlbGVyLCBjb250YWluZXIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGJwbW5Nb2RlbGVyLmltcG9ydFhNTCh4bWwpO1xuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKCd3aXRoLWVycm9yJykuYWRkQ2xhc3MoJ3dpdGgtZGlhZ3JhbScpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcygnd2l0aC1kaWFncmFtJykuYWRkQ2xhc3MoJ3dpdGgtZXJyb3InKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5maW5kKCcuZXJyb3IgcHJlJykudGV4dChlcnIubWVzc2FnZSk7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOmAmui/h0pzb27orr7nva7popzoibJcbiAgICAgKiBAcGFyYW0ge29iamVjdH0ganNvbiBqc29uIOWtl+espuS4slxuICAgICAqL1xuICAgIHNldENvbG9yKGpzb24sYnBtbk1vZGVsZXIpIHtcbiAgICAgICAgdmFyIG1vZGVsaW5nID0gYnBtbk1vZGVsZXIuZ2V0KCdtb2RlbGluZycpO1xuICAgICAgICB2YXIgZWxlbWVudFJlZ2lzdHJ5ID0gYnBtbk1vZGVsZXIuZ2V0KCdlbGVtZW50UmVnaXN0cnknKVxuICAgICAgICB2YXIgZWxlbWVudFRvQ29sb3IgPSBlbGVtZW50UmVnaXN0cnkuZ2V0KGpzb24ubmFtZSk7XG4gICAgICAgIGlmKGVsZW1lbnRUb0NvbG9yKXtcbiAgICAgICAgICAgIG1vZGVsaW5nLnNldENvbG9yKFtlbGVtZW50VG9Db2xvcl0sIHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IGpzb24uc3Ryb2tlLFxuICAgICAgICAgICAgICAgIGZpbGw6IGpzb24uZmlsbFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOS/neWtmGJwbW7lr7nosaFcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gYnBtbk1vZGVsZXIgYnBtbuWvueixoVxuICAgICAqL1xuICAgIHNhdmVCcG1uKGJwbW5Nb2RlbGVyKSB7XG4gICAgICAgIGJwbW5Nb2RlbGVyLnNhdmVYTUwoeyBmb3JtYXQ6IHRydWUgfSwgZnVuY3Rpb24gKGVyciwgeG1sKSB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoJ+S/neWtmOWksei0pe+8jOivt+mHjeivlScsIGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh4bWwpXG4gICAgICAgICAgICB2YXIgcGFyYW09e1xuICAgICAgICAgICAgICAgICAgICBcInN0cmluZ0JQTU5cIjp4bWxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJWVUVfQVBQX0JBU0VfQVBJXCIpKycvcHJvY2Vzc0RlZmluaXRpb24vYWRkRGVwbG95bWVudEJ5U3RyaW5nJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6XCJqc29uXCIsXG4gICAgICAgICAgICAgICAgZGF0YTogcGFyYW0sXG4gICAgICAgICAgICAgICAgLy9oZWFkZXJzOnsnQ29udGVudC1UeXBlJzonYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0ZjgnfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmKHJlc3VsdC5jb2RlPT09MjAwKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xzLnN5aGlkZSgnYWxlcnQnKVxuICAgICAgICAgICAgICAgICAgICB9ZWxzZXtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KHJlc3VsdC5tc2cpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycilcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDkuIvovb1icG1uXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGJwbW5Nb2RlbGVyIGJwbW7lr7nosaFcbiAgICAgKi9cbiAgICBkb3duTG9hZChicG1uTW9kZWxlcikge1xuICAgICAgICB2YXIgZG93bmxvYWRMaW5rID0gJChcIiNkb3dubG9hZEJwbW5cIilcbiAgICAgICAgYnBtbk1vZGVsZXIuc2F2ZVhNTCh7IGZvcm1hdDogdHJ1ZSB9LCBmdW5jdGlvbiAoZXJyLCB4bWwpIHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uc29sZS5lcnJvcignY291bGQgbm90IHNhdmUgQlBNTiAyLjAgZGlhZ3JhbScsIGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b29scy5zZXRFbmNvZGVkKGRvd25sb2FkTGluaywgJ2RpYWdyYW0uYnBtbicsIGVyciA/IG51bGwgOiB4bWwpO1xuICAgICAgICB9KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOi9rOeggXhtbOW5tuS4i+i9vVxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBsaW5rIOaMiemSrlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIOS4i+i9veWQjeensFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhIGJhc2U2NFhNTFxuICAgICAqL1xuICAgIHNldEVuY29kZWQobGluaywgbmFtZSwgZGF0YSkge1xuICAgICAgICB2YXIgZW5jb2RlZERhdGEgPSBlbmNvZGVVUklDb21wb25lbnQoZGF0YSk7XG4gICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgICBsaW5rLmFkZENsYXNzKCdhY3RpdmUnKS5hdHRyKHtcbiAgICAgICAgICAgICAgICAnaHJlZic6ICdkYXRhOmFwcGxpY2F0aW9uL2JwbW4yMC14bWw7Y2hhcnNldD1VVEYtOCwnICsgZW5jb2RlZERhdGEsXG4gICAgICAgICAgICAgICAgJ2Rvd25sb2FkJzogbmFtZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsaW5rLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICog5LiK5LygYnBtblxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBicG1uTW9kZWxlciBicG1u5a+56LGhXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGNvbnRhaW5lciDlrrnlmajlr7nosaFcbiAgICAgKi9cbiAgICB1cGxvYWQoYnBtbk1vZGVsZXIsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgRmlsZVVwbG9hZCA9IGRvY3VtZW50Lm15Rm9ybS51cGxvYWRGaWxlLmZpbGVzWzBdO1xuICAgICAgICB2YXIgZm0gPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgICAgZm0uYXBwZW5kKCdwcm9jZXNzRmlsZScsIEZpbGVVcGxvYWQpO1xuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcIlZVRV9BUFBfQkFTRV9BUElcIikrJy9wcm9jZXNzRGVmaW5pdGlvbi91cGxvYWQnLFxuICAgICAgICAgICAgLy8gdXJsOiAnaHR0cDovL2xvY2FsaG9zdDo4MDgwL3Byb2Nlc3NEZWZpbml0aW9uL3VwbG9hZCcsXG4gICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiBmbSxcbiAgICAgICAgICAgIGFzeW5jOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmYWxzZSwgLy/npoHmraLorr7nva7or7fmsYLnsbvlnotcbiAgICAgICAgICAgIHByb2Nlc3NEYXRhOiBmYWxzZSwgLy/npoHmraJqcXVlcnnlr7lEQXRh5pWw5o2u55qE5aSE55CGLOm7mOiupOS8muWkhOeQhlxuICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHZhciB1cmwgPSByZXN1bHQuZGF0YS5zdWJzdHIoMCw0KT09XCJodHRwXCI/cmVzdWx0LmRhdGE6bG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJWVUVfQVBQX0JBU0VfQVBJXCIpKyByZXN1bHQuZGF0YVxuICAgICAgICAgICAgICAgIHRvb2xzLm9wZW5Gcm9tVXJsKGJwbW5Nb2RlbGVyLCBjb250YWluZXIsIHVybClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDmiZPlvIB4bWwgIFVybCDlnLDlnYBcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gYnBtbk1vZGVsZXIgYnBtbuWvueixoVxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBjb250YWluZXIg5a655Zmo5a+56LGhXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVybCB1cmzlnLDlnYBcbiAgICAgKi9cbiAgICBvcGVuRnJvbVVybChicG1uTW9kZWxlciwgY29udGFpbmVyLCB1cmwpIHtcbiAgICAgICAgJC5hamF4KHVybCwgeyBkYXRhVHlwZTogJ3RleHQnIH0pLmRvbmUoYXN5bmMgZnVuY3Rpb24gKHhtbCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBicG1uTW9kZWxlci5pbXBvcnRYTUwoeG1sKTtcbiAgICAgICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3MoJ3dpdGgtZXJyb3InKS5hZGRDbGFzcygnd2l0aC1kaWFncmFtJyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog5omT5byA5by55Ye65qGGXG4gICAgICogQHBhcmFtIGlkXG4gICAgICovXG4gICAgc3lvcGVuKGlkKSB7XG4gICAgICAgIHZhciBkb20gPSAkKFwiI1wiICsgaWQpO1xuICAgICAgICB0aGlzLnN5Y2VudGVyKGRvbSk7XG4gICAgICAgIGRvbS5hZGRDbGFzcyhuYW1lKTtcbiAgICAgICAgZG9tLnNob3coKTtcbiAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgICAkKFwiLnN5LW1hc2tcIikuZmFkZUluKDMwMClcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGRvbS5yZW1vdmVDbGFzcyhuYW1lKVxuICAgICAgICB9LCAzMDApO1xuXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDpmpDol4/lvLnlh7rmoYZcbiAgICAgKiBAcGFyYW0gaWRcbiAgICAgKi9cbiAgICBzeWhpZGUoaWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpZCA9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB2YXIgZG9tID0gJChcIi5zeS1hbGVydFwiKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGRvbSA9ICQoXCIjXCIgKyBpZClcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmFtZSA9IGRvbS5hdHRyKFwic3ktbGVhdmVcIik7XG4gICAgICAgIGRvbS5hZGRDbGFzcyhuYW1lKTtcbiAgICAgICAgJChcIi5zeS1tYXNrXCIpLmZhZGVPdXQoMzAwKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGRvbS5oaWRlKCk7XG4gICAgICAgICAgICBkb20ucmVtb3ZlQ2xhc3MobmFtZSk7XG4gICAgICAgIH0sIDMwMClcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOW8ueWHuuahhuWxheS4rVxuICAgICAqIEBwYXJhbSBkb21cbiAgICAgKi9cbiAgICBzeWNlbnRlcihkb20pIHtcbiAgICAgICAgdmFyIG1ndG9wID0gcGFyc2VGbG9hdChkb20uaGVpZ2h0KCkgLyAyKTtcbiAgICAgICAgZG9tLmNzcyh7XG4gICAgICAgICAgICBcInRvcFwiOiBcIjUwJVwiLFxuICAgICAgICAgICAgXCJtYXJnaW4tdG9wXCI6IFwiLVwiICsgbWd0b3AgKyBcInB4XCJcbiAgICAgICAgfSlcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOWIpOaWreaYr+WQpuaYr+aVsOe7hFxuICAgICAqIEBwYXJhbSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHthcmcgaXMgQXJyYXk8YW55Pnxib29sZWFufVxuICAgICAqL1xuICAgIGlzQXJyYXlGbih2YWx1ZSl7XG4gICAgICAgIGlmICh0eXBlb2YgQXJyYXkuaXNBcnJheSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG4gICAgICAgIH1lbHNle1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT09IFwiW29iamVjdCBBcnJheV1cIjtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICog5qC55o2u5pWw5o2u6K6+572u6aKc6ImyXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9XG4gICAgICovXG4gICAgZ2V0QnlDb2xvcihkYXRhKXtcblxuICAgICAgICB2YXIgQ29sb3JKc29uPVtdXG4gICAgICAgIGZvcih2YXIgayBpbiBkYXRhWydoaWdoTGluZSddKXtcbiAgICAgICAgICAgIHZhciBwYXI9e1xuICAgICAgICAgICAgICAgIFwibmFtZVwiOiBkYXRhWydoaWdoTGluZSddW2tdLFxuICAgICAgICAgICAgICAgIFwic3Ryb2tlXCI6XCJncmVlblwiLFxuICAgICAgICAgICAgICAgIFwiZmlsbFwiOlwiZ3JlZW5cIlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQ29sb3JKc29uLnB1c2gocGFyKVxuICAgICAgICB9XG4gICAgICAgIGZvcih2YXIgayBpbiBkYXRhWydoaWdoUG9pbnQnXSl7XG4gICAgICAgICAgICB2YXIgcGFyPXtcbiAgICAgICAgICAgICAgICBcIm5hbWVcIjogZGF0YVsnaGlnaFBvaW50J11ba10sXG4gICAgICAgICAgICAgICAgXCJzdHJva2VcIjpcImdyYXlcIixcbiAgICAgICAgICAgICAgICBcImZpbGxcIjpcIiNlYWU5ZTlcIlxuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBDb2xvckpzb24ucHVzaChwYXIpXG4gICAgICAgIH1cbiAgICAgICAgZm9yKHZhciBrIGluIGRhdGFbJ2lEbyddKXtcbiAgICAgICAgICAgIHZhciBwYXI9e1xuICAgICAgICAgICAgICAgIFwibmFtZVwiOiBkYXRhWydpRG8nXVtrXSxcbiAgICAgICAgICAgICAgICBcInN0cm9rZVwiOlwiZ3JlZW5cIixcbiAgICAgICAgICAgICAgICBcImZpbGxcIjpcIiNhM2Q2OGVcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQ29sb3JKc29uLnB1c2gocGFyKVxuICAgICAgICB9XG4gICAgICAgIGZvcih2YXIgayBpbiBkYXRhWyd3YWl0aW5nVG9EbyddKXtcbiAgICAgICAgICAgIHZhciBwYXI9e1xuICAgICAgICAgICAgICAgIFwibmFtZVwiOiBkYXRhWyd3YWl0aW5nVG9EbyddW2tdLFxuICAgICAgICAgICAgICAgIFwic3Ryb2tlXCI6XCJncmVlblwiLFxuICAgICAgICAgICAgICAgIFwiZmlsbFwiOlwieWVsbG93XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIENvbG9ySnNvbi5wdXNoKHBhcilcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQ29sb3JKc29uXG4gICAgfVxufVxuXG5cblxuXG5leHBvcnQgZGVmYXVsdCB0b29sc1xuIl19