diff --git a/API.md b/API.md
index 718148c..9475abe 100644
--- a/API.md
+++ b/API.md
@@ -36,14 +36,14 @@ Constructs a new instance of XlsxDataFill with given options.
| --- | --- | --- |
| accessor | object
| An instance of XLSX spreadsheet accessing class. |
| opts | Object
| Options to be used during processing. |
-| opts.templateRegExp | RegExp
| The regular expression to be used for template recognizing. Default is `/\{\{([^}]*)\}\}/`, i.e. Mustache. |
-| opts.fieldSplitter | string
| The string to be expected as template field splitter. Default is `|`. |
-| opts.joinText | string
| The string to be used when the extracted value for a single cell is an array, and it needs to be joined. Default is `,`. |
-| opts.mergeCells | string
\| boolean
| Whether to merge the higher dimension cells in the output. Default is true. |
-| opts.duplicateCells | string
\| boolean
| Whether to duplicate the content of higher dimension cells, when not merged. Default is false. |
+| opts.templateRegExp | RegExp
| The regular expression to be used for template recognizing. Default is `/\{\{([^}]*)\}\}/`, i.e. Mustache. |
+| opts.fieldSplitter | string
\| RegExo
| The string or regular expression to be used as template fields splitter. Default is `|`. |
+| opts.joinText | string
| The string to be used when the extracted value for a single cell is an array, and it needs to be joined. Default is `,`. |
+| opts.mergeCells | string
\| boolean
| Whether to merge the higher dimension cells in the output. Default is true, but valid values are also `"both"`, `"vertical"` and `"horizontal"`. |
+| opts.duplicateCells | string
\| boolean
| Whether to duplicate the content of higher dimension cells, when not merged. Default is false. Same valud values as `mergeCells`. |
| opts.followFormulae | boolean
| If a template is located as a result of a formula, whether to still process it. Default is false. |
| opts.copyStyle | boolean
| Copy the style of the template cell when populating. Even when `false`, the template styling _is_ applied. Default is true. |
-| opts.callbacksMap | object.<string, function()>
| A map of handlers to be used for data and value extraction. There is one default - the empty one, for object key extraction. |
+| opts.callbacksMap | object.<string, function()>
| A map of handlers to be used for data and value extraction. |
@@ -52,11 +52,10 @@ Setter/getter for XlsxDataFill's options as set during construction.
**Kind**: instance method of [XlsxDataFill
](#XlsxDataFill)
**Returns**: [XlsxDataFill
](#XlsxDataFill) \| Object
- The required options (in getter mode) or XlsxDataFill (in setter mode) for chaining.
-**See**: {@constructor}.
| Param | Type | Description |
| --- | --- | --- |
-| newOpts | Object
\| null
| If set - the new options to be used. |
+| newOpts | Object
\| null
| If set - the new options to be used. Check [up here](#new-xlsxdatafillaccessor-opts). |
diff --git a/README.md b/README.md
index 6be3b3f..3ec1a30 100644
--- a/README.md
+++ b/README.md
@@ -194,7 +194,7 @@ Here are the options and their defaults.
{
templateRegExp: new RegExp(/\{\{([^}]*)\}\}/),
fieldSplitter: "|",
- joinText: ",",
+ joinText: ",",
mergeCells: true,
duplicateCells: false,
followFormulae: false,
@@ -207,6 +207,22 @@ Here are the options and their defaults.
```
+Check the [detailed description in the API](API.md#new-xlsxdatafillaccessor-opts). It is worth noting the `mergeCells` and `duplicateCells` behavior.
+
+First, they both have the same set of possible values: `true`, `false`, `”both”`, `”vertical”`, `”horizontal”` – in which direction the cells need to be merged/duplicated. As expected `true` and `”both”` have the same meaning.
+
+Second, cells duplication is valid only when merging is disabled, in other words, if `mergeCells == true`, `duplicateCells` is ignored. Given these options:
+
+```js
+mergeCells: "vertical",
+duplicateCells: true
+```
+
+Is interpreted as follow:
+
+* If during data expansion a value in higher dimension occupies more than one cell in a **column**, they are merged – because these are _vertical_.
+* If a value from higher dimension occupies more than one cell in a **row**, then duplication options is taken into account and same value is duplicated on all these cells.
+
## Formulae handling
As formulas are a key Excel feature, so `xlsx-datafill` is trying to keep them alive and meaningful. As a basic rule _Raw formulas are kept as they are, only those put in a template format, are handled_.
diff --git a/browser/xlsx-datafill.js b/browser/xlsx-datafill.js
index 854814e..ead35a3 100644
--- a/browser/xlsx-datafill.js
+++ b/browser/xlsx-datafill.js
@@ -51,19 +51,14 @@ var XlsxDataFill = /*#__PURE__*/function () {
* Constructs a new instance of XlsxDataFill with given options.
* @param {object} accessor An instance of XLSX spreadsheet accessing class.
* @param {{}} opts Options to be used during processing.
- * @param {RegExp} opts.templateRegExp The regular expression to be used for template recognizing.
- * Default is `/\{\{([^}]*)\}\}/`, i.e. Mustache.
- * @param {string} opts.fieldSplitter The string to be expected as template field splitter. Default is `|`.
- * @param {string} opts.joinText The string to be used when the extracted value for a single cell is an array,
- * and it needs to be joined. Default is `,`.
- * @param {string|boolean} opts.mergeCells Whether to merge the higher dimension cells in the output. Default is true.
- * @param {string|boolean} opts.duplicateCells Whether to duplicate the content of higher dimension cells, when not merged. Default is false.
- * @param {boolean} opts.followFormulae If a template is located as a result of a formula, whether to still process it.
- * Default is false.
- * @param {boolean} opts.copyStyle Copy the style of the template cell when populating. Even when `false`, the template
- * styling _is_ applied. Default is true.
+ * @param {RegExp} opts.templateRegExp The regular expression to be used for template recognizing. Default is `/\{\{([^}]*)\}\}/`, i.e. Mustache.
+ * @param {string|RegExo} opts.fieldSplitter The string or regular expression to be used as template fields splitter. Default is `|`.
+ * @param {string} opts.joinText The string to be used when the extracted value for a single cell is an array, and it needs to be joined. Default is `,`.
+ * @param {string|boolean} opts.mergeCells Whether to merge the higher dimension cells in the output. Default is true, but valid values are also `"both"`, `"vertical"` and `"horizontal"`.
+ * @param {string|boolean} opts.duplicateCells Whether to duplicate the content of higher dimension cells, when not merged. Default is false. Same valud values as `mergeCells`.
+ * @param {boolean} opts.followFormulae If a template is located as a result of a formula, whether to still process it. Default is false.
+ * @param {boolean} opts.copyStyle Copy the style of the template cell when populating. Even when `false`, the template styling _is_ applied. Default is true.
* @param {object.} opts.callbacksMap A map of handlers to be used for data and value extraction.
- * There is one default - the empty one, for object key extraction.
*/
function XlsxDataFill(accessor, opts) {
_classCallCheck(this, XlsxDataFill);
@@ -75,8 +70,7 @@ var XlsxDataFill = /*#__PURE__*/function () {
}
/**
* Setter/getter for XlsxDataFill's options as set during construction.
- * @param {{}|null} newOpts If set - the new options to be used.
- * @see {@constructor}.
+ * @param {{}|null} newOpts If set - the new options to be used. Check [up here]{@link #new-xlsxdatafillaccessor-opts}.
* @returns {XlsxDataFill|{}} The required options (in getter mode) or XlsxDataFill (in setter mode) for chaining.
*/
@@ -954,4 +948,4 @@ module.exports = XlsxPopulateAccess;
},{}]},{},[1])(1)
});
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvWGxzeERhdGFGaWxsLmpzIiwic3JjL1hsc3hQb3B1bGF0ZUFjY2Vzcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUNBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLElBQU0sRUFBQyxHQUFHLE9BQU8sQ0FBQyxRQUFELENBQWpCOztBQUVBLElBQU0sV0FBVyxHQUFHO0FBQ2hCLEVBQUEsY0FBYyxFQUFFLGlCQURBO0FBRWhCLEVBQUEsYUFBYSxFQUFFLEdBRkM7QUFHaEIsRUFBQSxRQUFRLEVBQUUsR0FITTtBQUloQixFQUFBLFVBQVUsRUFBRSxJQUpJO0FBS2hCLEVBQUEsY0FBYyxFQUFFLEtBTEE7QUFNaEIsRUFBQSxjQUFjLEVBQUUsS0FOQTtBQU9oQixFQUFBLFNBQVMsRUFBRSxJQVBLO0FBUWhCLEVBQUEsWUFBWSxFQUFFO0FBQ1YsUUFBSSxXQUFBLElBQUk7QUFBQSxhQUFJLEVBQUMsQ0FBQyxJQUFGLENBQU8sSUFBUCxDQUFKO0FBQUEsS0FERTtBQUVWLElBQUEsQ0FBQyxFQUFFLFdBQUEsSUFBSTtBQUFBLGFBQUksRUFBQyxDQUFDLE1BQUYsQ0FBUyxJQUFULENBQUo7QUFBQTtBQUZHO0FBUkUsQ0FBcEI7QUFjQSxJQUFNLFNBQVMsR0FBRyw0Q0FBbEI7QUFFQTs7OztJQUdNLFk7QUFDRjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0JBLHdCQUFZLFFBQVosRUFBc0IsSUFBdEIsRUFBNEI7QUFBQTs7QUFDeEIsU0FBSyxLQUFMLEdBQWEsRUFBQyxDQUFDLFlBQUYsQ0FBZSxFQUFmLEVBQW1CLElBQW5CLEVBQXlCLFdBQXpCLENBQWI7QUFDQSxTQUFLLFNBQUwsR0FBaUIsRUFBakI7QUFDQSxTQUFLLFNBQUwsR0FBaUIsRUFBakI7QUFDQSxTQUFLLE9BQUwsR0FBZSxRQUFmO0FBQ0g7QUFFRDs7Ozs7Ozs7Ozs0QkFNUSxPLEVBQVM7QUFDYixVQUFJLE9B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QyxLQUFMLEdBQWEsSUFBYixFQUFwQjtBQUFBLFVBQ0ksS0FBSyxjQUFPLFdBQVAsZUFBdUIsSUFBSSxDQUFDLFNBQUwsRUFBdkIsQ0FEVDtBQUFBLFVBRUksS0FBSyxjQUFPLFdBQVAsZUFBdUIsSUFBSSxDQUFDLFlBQUwsRUFBdkIsQ0FGVDtBQUlBLFVBQUksS0FBSyxTQUFMLENBQWUsS0FBZixNQUEwQixTQUE5QixFQUNJLElBQUksQ0FBQyxHQUFMLEdBQVcsTUFBWCxDQUFrQixLQUFLLFNBQUwsQ0FBZSxLQUFmLElBQXdCLEdBQUcsQ0FBQyxHQUFKLEdBQVUsTUFBVixFQUExQztBQUVKLFVBQUksS0FBSyxTQUFMLENBQWUsS0FBZixNQUEwQixTQUE5QixFQUNJLElBQUksQ0FBQyxNQUFMLEdBQWMsS0FBZCxDQUFvQixLQUFLLFNBQUwsQ0FBZSxLQUFmLElBQXdCLEdBQUcsQ0FBQyxNQUFKLEdBQWEsS0FBYixFQUE1QztBQUVKLGFBQU8sSUFBUDtBQUNIOzs7Ozs7QUFHTCxNQUFNLENBQUMsT0FBUCxHQUFpQixrQkFBakIiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCJcInVzZSBzdHJpY3RcIjtcblxuY29uc3QgXyA9IHJlcXVpcmUoJ2xvZGFzaCcpO1xuXG5jb25zdCBkZWZhdWx0T3B0cyA9IHtcbiAgICB0ZW1wbGF0ZVJlZ0V4cDogL1xce1xceyhbXn1dKilcXH1cXH0vLFxuICAgIGZpZWxkU3BsaXR0ZXI6IFwifFwiLFxuICAgIGpvaW5UZXh0OiBcIixcIixcbiAgICBtZXJnZUNlbGxzOiB0cnVlLFxuICAgIGR1cGxpY2F0ZUNlbGxzOiBmYWxzZSxcbiAgICBmb2xsb3dGb3JtdWxhZTogZmFsc2UsXG4gICAgY29weVN0eWxlOiB0cnVlLFxuICAgIGNhbGxiYWNrc01hcDoge1xuICAgICAgICAnJzogZGF0YSA9PiBfLmtleXMoZGF0YSksXG4gICAgICAgICQ6IGRhdGEgPT4gXy52YWx1ZXMoZGF0YSlcbiAgICB9XG59O1xuXG5jb25zdCByZWZSZWdFeHAgPSAvKCc/KFteIV0qKT8nPyEpPyhbQS1aXStcXGQrKSg6KFtBLVpdK1xcZCspKT8vO1xuXG4vKipcbiAqIERhdGEgZmlsbCBlbmdpbmUsIHRha2luZyBhbiBpbnN0YW5jZSBvZiBFeGNlbCBzaGVldCBhY2Nlc3NvciBhbmQgYSBKU09OIG9iamVjdCBhcyBkYXRhLCBhbmQgZmlsbGluZyB0aGUgdmFsdWVzIGZyb20gdGhlIGxhdHRlciBpbnRvIHRoZSBmb3JtZXIuXG4gKi9cbmNsYXNzIFhsc3hEYXRhRmlsbCB7XG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiBYbHN4RGF0YUZpbGwgd2l0aCBnaXZlbiBvcHRpb25zLlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBhY2Nlc3NvciBBbiBpbnN0YW5jZSBvZiBYTFNYIHNwcmVhZHNoZWV0IGFjY2Vzc2luZyBjbGFzcy5cbiAgICAgKiBAcGFyYW0ge3t9fSBvcHRzIE9wdGlvbnMgdG8gYmUgdXNlZCBkdXJpbmcgcHJvY2Vzc2luZy5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cH0gb3B0cy50ZW1wbGF0ZVJlZ0V4cCBUaGUgcmVndWxhciBleHByZXNzaW9uIHRvIGJlIHVzZWQgZm9yIHRlbXBsYXRlIHJlY29nbml6aW5nLiBcbiAgICAgKiBEZWZhdWx0IGlzIGAvXFx7XFx7KFtefV0qKVxcfVxcfS9gLCBpLmUuIE11c3RhY2hlLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLmZpZWxkU3BsaXR0ZXIgVGhlIHN0cmluZyB0byBiZSBleHBlY3RlZCBhcyB0ZW1wbGF0ZSBmaWVsZCBzcGxpdHRlci4gRGVmYXVsdCBpcyBgfGAuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG9wdHMuam9pblRleHQgVGhlIHN0cmluZyB0byBiZSB1c2VkIHdoZW4gdGhlIGV4dHJhY3RlZCB2YWx1ZSBmb3IgYSBzaW5nbGUgY2VsbCBpcyBhbiBhcnJheSwgXG4gICAgICogYW5kIGl0IG5lZWRzIHRvIGJlIGpvaW5lZC4gRGVmYXVsdCBpcyBgLGAuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8Ym9vbGVhbn0gb3B0cy5tZXJnZUNlbGxzIFdoZXRoZXIgdG8gbWVyZ2UgdGhlIGhpZ2hlciBkaW1lbnNpb24gY2VsbHMgaW4gdGhlIG91dHB1dC4gRGVmYXVsdCBpcyB0cnVlLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGJvb2xlYW59IG9wdHMuZHVwbGljYXRlQ2VsbHMgV2hldGhlciB0byBkdXBsaWNhdGUgdGhlIGNvbnRlbnQgb2YgaGlnaGVyIGRpbWVuc2lvbiBjZWxscywgd2hlbiBub3QgbWVyZ2VkLiBEZWZhdWx0IGlzIGZhbHNlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0cy5mb2xsb3dGb3JtdWxhZSBJZiBhIHRlbXBsYXRlIGlzIGxvY2F0ZWQgYXMgYSByZXN1bHQgb2YgYSBmb3JtdWxhLCB3aGV0aGVyIHRvIHN0aWxsIHByb2Nlc3MgaXQuXG4gICAgICogRGVmYXVsdCBpcyBmYWxzZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG9wdHMuY29weVN0eWxlIENvcHkgdGhlIHN0eWxlIG9mIHRoZSB0ZW1wbGF0ZSBjZWxsIHdoZW4gcG9wdWxhdGluZy4gRXZlbiB3aGVuIGBmYWxzZWAsIHRoZSB0ZW1wbGF0ZVxuICAgICAqIHN0eWxpbmcgX2lzXyBhcHBsaWVkLiBEZWZhdWx0IGlzIHRydWUuXG4gICAgICogQHBhcmFtIHtvYmplY3QuPHN0cmluZywgZnVuY3Rpb24+fSBvcHRzLmNhbGxiYWNrc01hcCBBIG1hcCBvZiBoYW5kbGVycyB0byBiZSB1c2VkIGZvciBkYXRhIGFuZCB2YWx1ZSBleHRyYWN0aW9uLlxuICAgICAqIFRoZXJlIGlzIG9uZSBkZWZhdWx0IC0gdGhlIGVtcHR5IG9uZSwgZm9yIG9iamVjdCBrZXkgZXh0cmFjdGlvbi5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihhY2Nlc3Nvciwgb3B0cykge1xuICAgICAgICB0aGlzLl9vcHRzID0gXy5kZWZhdWx0c0RlZXAoe30sIG9wdHMsIGRlZmF1bHRPcHRzKTtcbiAgICAgICAgdGhpcy5fcm93U2l6ZXMgPSB7fTtcbiAgICAgICAgdGhpcy5fY29sU2l6ZXMgPSB7fTtcbiAgICAgICAgdGhpcy5fYWNjZXNzID0gYWNjZXNzb3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0dGVyL2dldHRlciBmb3IgWGxzeERhdGFGaWxsJ3Mgb3B0aW9ucyBhcyBzZXQgZHVyaW5nIGNvbnN0cnVjdGlvbi5cbiAgICAgKiBAcGFyYW0ge3t9fG51bGx9IG5ld09wdHMgSWYgc2V0IC0gdGhlIG5ldyBvcHRpb25zIHRvIGJlIHVzZWQuIFxuICAgICAqIEBzZWUge0Bjb25zdHJ1Y3Rvcn0uXG4gICAgICogQHJldHVybnMge1hsc3hEYXRhRmlsbHx7fX0gVGhlIHJlcXVpcmVkIG9wdGlvbnMgKGluIGdldHRlciBtb2RlKSBvciBYbHN4RGF0YUZpbGwgKGluIHNldHRlciBtb2RlKSBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgb3B0aW9ucyhuZXdPcHRzKSB7XG4gICAgICAgIGlmIChuZXdPcHRzICE9PSBudWxsKSB7XG4gICAgICAgICAgICBfLm1lcmdlKHRoaXMuX29wdHMsIG5ld09wdHMpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29wdHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG1haW4gZW50cnkgcG9pbnQgZm9yIHdob2xlIGRhdGEgcG9wdWxhdGlvbiBtZWNoYW5pc20uXG4gICAgICogQHBhcmFtIHt7fX0gZGF0YSBUaGUgZGF0YSB0byBiZSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtYbHN4RGF0YUZpbGx9IEZvciBpbnZvY2F0aW9uIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGZpbGxEYXRhKGRhdGEpIHtcbiAgICAgICAgY29uc3QgZGF0YUZpbGxzID0ge307XG5cdFxuICAgICAgICAvLyBCdWlsZCB0aGUgZGVwZW5kZW5jeSBjb25uZWN0aW9ucyBiZXR3ZWVuIHRlbXBsYXRlcy5cbiAgICAgICAgdGhpcy5jb2xsZWN0VGVtcGxhdGVzKHRlbXBsYXRlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFGaWxsID0geyAgXG4gICAgICAgICAgICAgICAgdGVtcGxhdGU6IHRlbXBsYXRlLCBcbiAgICAgICAgICAgICAgICBkZXBlbmRlbnRzOiBbXSxcbiAgICAgICAgICAgICAgICBmb3JtdWxhczogW10sXG4gICAgICAgICAgICAgICAgcHJvY2Vzc2VkOiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRlbXBsYXRlLnJlZmVyZW5jZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZkZpbGwgPSBkYXRhRmlsbHNbdGVtcGxhdGUucmVmZXJlbmNlXTtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBpZiAoIXJlZkZpbGwpIFxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBmaW5kIGEgcmVmZXJlbmNlICcke3RlbXBsYXRlLnJlZmVyZW5jZX0nIWApO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmICh0ZW1wbGF0ZS5mb3JtdWxhKSBcbiAgICAgICAgICAgICAgICAgICAgcmVmRmlsbC5mb3JtdWxhcy5wdXNoKGFGaWxsKTtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIHJlZkZpbGwuZGVwZW5kZW50cy5wdXNoKGFGaWxsKTtcbiAgICBcbiAgICAgICAgICAgICAgICBhRmlsbC5vZmZzZXQgPSB0aGlzLl9hY2Nlc3MuY2VsbERpc3RhbmNlKHJlZkZpbGwudGVtcGxhdGUuY2VsbCwgdGVtcGxhdGUuY2VsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkYXRhRmlsbHNbdGVtcGxhdGUuaWRdID0gYUZpbGw7XG4gICAgICAgIH0pO1xuICAgIFxuICAgICAgICAvLyBBcHBseSBlYWNoIGZpbGwgb250byB0aGUgc2hlZXQuXG4gICAgICAgIF8uZWFjaChkYXRhRmlsbHMsIGZpbGwgPT4ge1xuICAgICAgICAgICAgaWYgKGZpbGwucHJvY2Vzc2VkKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGVsc2UgaWYgKGZpbGwudGVtcGxhdGUuZm9ybXVsYSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vbi1yZWZlcmVuY2luZyBmb3JtdWxhIGZvdW5kICcke2ZpbGwuZXh0cmFjdG9yfScuIFVzZSBhIG5vbi10ZW1wbGF0ZWQgb25lIWApO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlGaWxsKGZpbGwsIGRhdGEsIGZpbGwudGVtcGxhdGUuY2VsbCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgcHJvdmlkZWQgaGFuZGxlciBmcm9tIHRoZSBtYXAuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGhhbmRsZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSBoYW5kbGVyLlxuICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbn0gVGhlIGhhbmRsZXIgZnVuY3Rpb24gaXRzZWxmLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBnZXRIYW5kbGVyKGhhbmRsZXJOYW1lKSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXJGbiA9IHRoaXMuX29wdHMuY2FsbGJhY2tzTWFwW2hhbmRsZXJOYW1lXTtcblxuICAgICAgICBpZiAoIWhhbmRsZXJGbilcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSGFuZGxlciAnJHtoYW5kbGVyTmFtZX0nIGNhbm5vdCBiZSBmb3VuZCFgKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGhhbmRsZXJGbiAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSGFuZGxlciAnJHtoYW5kbGVyTmFtZX0nIGlzIG5vdCBhIGZ1bmN0aW9uIWApO1xuICAgICAgICBlbHNlIFxuICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXJGbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIHByb3ZpZGVkIGV4dHJhY3RvciAob3QgaXRlcmF0b3IpIHN0cmluZyB0byBmaW5kIGEgY2FsbGJhY2sgaWQgaW5zaWRlLCBpZiBwcmVzZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBleHRyYWN0b3IgVGhlIGl0ZXJhdG9yL2V4dHJhY3RvciBzdHJpbmcgdG8gYmUgaW52ZXN0aWdhdGVkLlxuICAgICAqIEByZXR1cm5zIHtvYmplY3QuPHN0cmluZywgZnVuY3Rpb24+fSBBIHsgYHBhdGhgLCBgaGFuZGxlcmAgfSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBKU09OIHBhdGhcbiAgICAgKiByZWFkeSBmb3IgdXNlIGFuZCB0aGUgcHJvdmlkZWQgYGhhbmRsZXJgIF9mdW5jdGlvbl8gLSByZWFkeSBmb3IgaW52b2tpbmcsIGlmIHN1Y2ggaXMgcHJvdmlkZWQuXG4gICAgICogSWYgbm90IC0gdGhlIGBwYXRoYCBwcm9wZXJ0eSBjb250YWlucyB0aGUgcHJvdmlkZWQgYGV4dHJhY3RvcmAsIGFuZCB0aGUgYGhhbmRsZXJgIGlzIGBudWxsYC5cbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgcGFyc2VFeHRyYWN0b3IoZXh0cmFjdG9yKSB7XG4gICAgICAgIC8vIEEgc3BlY2lmaWMgZXh0cmFjdG9yIGNhbiBiZSBzcGVjaWZpZWQgYWZ0ZXIgc2VtaWxvbiAtIGZpbmQgYW5kIHJlbWVtYmVyIGl0LlxuICAgICAgICBjb25zdCBleHRyYWN0UGFydHMgPSBleHRyYWN0b3Iuc3BsaXQoXCI6XCIpLFxuICAgICAgICAgICAgaGFuZGxlck5hbWUgPSBfLnRyaW0oZXh0cmFjdFBhcnRzWzFdKTtcblxuICAgICAgICByZXR1cm4gZXh0cmFjdFBhcnRzLmxlbmd0aCA9PSAxXG4gICAgICAgICAgICA/IHsgcGF0aDogZXh0cmFjdG9yLCBoYW5kbGVyOiBudWxsIH1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIHBhdGg6IF8udHJpbShleHRyYWN0UGFydHNbMF0pLFxuICAgICAgICAgICAgICAgIGhhbmRsZXI6IHRoaXMuZ2V0SGFuZGxlcihoYW5kbGVyTmFtZSlcbiAgICAgICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwbGllcyB0aGUgc3R5bGUgcGFydCBvZiB0aGUgdGVtcGxhdGUgb250byBhIGdpdmVuIGNlbGwuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIFRoZSBkZXN0aW5hdGlvbiBjZWxsIHRvIGFwcGx5IHN0eWxpbmcgdG8uXG4gICAgICogQHBhcmFtIHt7fX0gZGF0YSBUaGUgZGF0YSBjaHVuayBmb3IgdGhhdCBjZWxsLlxuICAgICAqIEBwYXJhbSB7e319IHRlbXBsYXRlIFRoZSB0ZW1wbGF0ZSB0byBiZSB1c2VkIGZvciB0aGF0IGNlbGwuXG4gICAgICogQHJldHVybnMge0RhdGFGaWxsZXJ9IEZvciBpbnZvY2F0aW9uIGNoYWluaW5nLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBhcHBseURhdGFTdHlsZShjZWxsLCBkYXRhLCB0ZW1wbGF0ZSkge1xuICAgICAgICBjb25zdCBzdHlsZXMgPSB0ZW1wbGF0ZS5zdHlsZXM7XG5cbiAgICAgICAgaWYgKHRoaXMuX29wdHMuY29weVN0eWxlKVxuICAgICAgICAgICAgdGhpcy5fYWNjZXNzLmNvcHlTdHlsZShjZWxsLCB0ZW1wbGF0ZS5jZWxsKTtcbiAgICAgICAgXG4gICAgICAgIGlmIChzdHlsZXMgJiYgZGF0YSkge1xuICAgICAgICAgICAgXy5lYWNoKHN0eWxlcywgcGFpciA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKF8uc3RhcnRzV2l0aChwYWlyLm5hbWUsIFwiOlwiKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldEhhbmRsZXIocGFpci5uYW1lLnN1YnN0cigxKSkuY2FsbCh0aGlzLl9vcHRzLCBkYXRhLCBjZWxsKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFfLnN0YXJ0c1dpdGgocGFpci5uYW1lLCBcIiFcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsID0gdGhpcy5leHRyYWN0VmFsdWVzKGRhdGEsIHBhaXIuZXh0cmFjdG9yLCBjZWxsKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FjY2Vzcy5zZXRDZWxsU3R5bGUoY2VsbCwgcGFpci5uYW1lLCBKU09OLnBhcnNlKHZhbCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdCB0aGUgb3B0aW9ucy1zcGVjaWZpYyBwYXJhbWV0ZXJzIGZyb20gdGhlIHN0eWxlcyBmaWVsZCBhbmQgbWVyZ2UgdGhlbSB3aXRoIHRoZSBnbG9iYWwgb25lcy5cbiAgICAgKiBAcGFyYW0ge3t9fSB0ZW1wbGF0ZSBUaGUgdGVtcGxhdGUgdG8gZXh0cmFjdCBvcHRpb25zIHByb3BlcnRpZXMgZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSBmdWxsIG9wdGlvbnMsIFxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBnZXRUZW1wbGF0ZU9wdHModGVtcGxhdGUpIHtcbiAgICAgICAgaWYgKCF0ZW1wbGF0ZS5zdHlsZXMpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3B0cztcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IG9wdHMgPSBfLmNsb25lKHRoaXMuX29wdHMpO1xuICAgICAgICBfLmVhY2godGVtcGxhdGUuc3R5bGVzLCBwYWlyID0+IHtcbiAgICAgICAgICAgIGlmIChfLnN0YXJ0c1dpdGgocGFpci5uYW1lLCBcIiFcIikpXG4gICAgICAgICAgICAgICAgb3B0c1twYWlyLm5hbWUuc3Vic3RyKDEpXSA9IEpTT04ucGFyc2UocGFpci5leHRyYWN0b3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gb3B0cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBjZWxsIGludG8gYSB2YWxpZCB0ZW1wbGF0ZSBpbmZvLlxuICAgICAqIEBwYXJhbSB7Q2VsbH0gY2VsbCBUaGUgY2VsbCBjb250YWluaW5nIHRoZSB0ZW1wbGF0ZSB0byBiZSBwYXJzZWQuXG4gICAgICogQHJldHVybnMge3t9fSBUaGUgcGFyc2VkIHRlbXBsYXRlLlxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBidWlsZHMgdGVtcGxhdGUgaW5mbywgdGFraW5nIGludG8gYWNjb3VudCB0aGUgc3VwcGxpZWQgb3B0aW9ucy5cbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgcGFyc2VUZW1wbGF0ZShjZWxsKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fYWNjZXNzLmNlbGxWYWx1ZShjZWxsKTtcbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwgfHwgdHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgcmVNYXRjaCA9IHZhbHVlLm1hdGNoKHRoaXMuX29wdHMudGVtcGxhdGVSZWdFeHApO1xuICAgICAgICBpZiAoIXJlTWF0Y2ggfHwgIXRoaXMuX29wdHMuZm9sbG93Rm9ybXVsYWUgJiYgdGhpcy5fYWNjZXNzLmNlbGxUeXBlKGNlbGwpID09PSAnZm9ybXVsYScpIFxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgXG4gICAgICAgIGNvbnN0IHBhcnRzID0gcmVNYXRjaFsxXS5zcGxpdCh0aGlzLl9vcHRzLmZpZWxkU3BsaXR0ZXIpLm1hcChfLnRyaW0pLFxuICAgICAgICAgICAgc3R5bGVzID0gIXBhcnRzWzRdID8gbnVsbCA6IHBhcnRzWzRdLnNwbGl0KFwiLFwiKSxcbiAgICAgICAgICAgIGV4dHJhY3RvciA9IHBhcnRzWzJdIHx8IFwiXCIsXG4gICAgICAgICAgICBjZWxsUmVmID0gdGhpcy5fYWNjZXNzLmJ1aWxkUmVmKGNlbGwsIHBhcnRzWzBdKTtcbiAgICAgICAgXG4gICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPCAyKSBcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm90IGVub3VnaCBjb21wb25lbnRzIG9mIHRoZSB0ZW1wbGF0ZSAnJHtyZU1hdGNoWzBdfSdgKTtcbiAgICAgICAgaWYgKCEhcGFydHNbMF0gJiYgIWNlbGxSZWYpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmVmZXJlbmNlIHBhc3NlZDogJyR7cGFydHNbMF19J2ApO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpZDogdGhpcy5fYWNjZXNzLmNlbGxSZWYoY2VsbCksXG4gICAgICAgICAgICByZWZlcmVuY2U6IGNlbGxSZWYsXG4gICAgICAgICAgICBpdGVyYXRvcnM6IHBhcnRzWzFdLnNwbGl0KC94fFxcKi8pLm1hcChfLnRyaW0pLFxuICAgICAgICAgICAgZXh0cmFjdG9yOiBleHRyYWN0b3IsXG4gICAgICAgICAgICBmb3JtdWxhOiBleHRyYWN0b3Iuc3RhcnRzV2l0aChcIj1cIiksXG4gICAgICAgICAgICBjZWxsOiBjZWxsLFxuICAgICAgICAgICAgY2VsbFNpemU6IHRoaXMuX2FjY2Vzcy5jZWxsU2l6ZShjZWxsKSxcbiAgICAgICAgICAgIHBhZGRpbmc6IChwYXJ0c1szXSB8fCBcIlwiKS5zcGxpdCgvOnwsfHh8XFwqLykubWFwKHYgPT4gcGFyc2VJbnQodikgfHwgMCksXG4gICAgICAgICAgICBzdHlsZXM6ICFzdHlsZXMgPyBudWxsIDogXy5tYXAoc3R5bGVzLCBzID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYWlyID0gXy50cmltKHMpLnNwbGl0KFwiPVwiKTtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBuYW1lOiBfLnRyaW0ocGFpclswXSksIGV4dHJhY3RvcjogXy50cmltKHBhaXJbMV0pIH07XG4gICAgICAgICAgICB9KVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHNvcnRUZW1wbGF0ZXMobGlzdCkge1xuICAgICAgICBjb25zdCBzb3J0ZWQgPSBbXSxcbiAgICAgICAgICAgIHJlbGF0ZWQgPSB7fSxcbiAgICAgICAgICAgIG1hcCA9IHt9LFxuICAgICAgICAgICAgZnJlZUxpc3QgPSBbXTtcblxuICAgICAgICAvLyBGaXJzdCwgbWFrZSB0aGUgZGVwZW5kZW5jeSBtYXAgYW5kIGFkZCB0aGUgbGlzdCBvZiBub24tcmVmZXJlbmNpbmcgdGVtcGxhdGVzXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgY29uc3QgdCA9IGxpc3RbaV07XG4gICAgICAgICAgICBtYXBbdC5pZF0gPSBpO1xuXG4gICAgICAgICAgICBpZiAoIXQucmVmZXJlbmNlKVxuICAgICAgICAgICAgICAgIGZyZWVMaXN0LnB1c2godC5pZCk7XG4gICAgICAgICAgICBlbHNlIFxuICAgICAgICAgICAgICAgIChyZWxhdGVkW3QucmVmZXJlbmNlXSA9IHJlbGF0ZWRbdC5yZWZlcmVuY2VdIHx8IFtdKS5wdXNoKHQuaWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTm93LCBtYWtlIHRoZSBhY3R1YWwgc29ydGluZy5cbiAgICAgICAgd2hpbGUgKGZyZWVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gZnJlZUxpc3Quc2hpZnQoKSxcbiAgICAgICAgICAgICAgICB0ID0gbGlzdFttYXBbaWRdXTtcblxuICAgICAgICAgICAgc29ydGVkLnB1c2godCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIFdlIHVzZSB0aGUgZmFjdCB0aGF0IHRoZXJlIGlzIGEgc2luZ2xlIHByZWRlY2Vzc29yIGluIG91ciBzZXR1cC5cbiAgICAgICAgICAgIGlmIChyZWxhdGVkW3QuaWRdKVxuICAgICAgICAgICAgICAgIGZyZWVMaXN0LnB1c2goLi4ucmVsYXRlZFt0LmlkXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc29ydGVkLmxlbmd0aCA8IGxpc3QubGVuZ3RoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBIHJlZmVyZW5jZSBjeWNsZSBmb3VuZCwgaW52b2x2aW5nIFwiJHtfLm1hcChfLnhvcihsaXN0LCBzb3J0ZWQpLCAnaWQnKS5qb2luKCcsJyl9XCIhYCk7XG5cbiAgICAgICAgcmV0dXJuIHNvcnRlZDtcbiAgICB9XG4gICAgXG4gICAgLyoqXG4gICAgICogU2VhcmNoZXMgdGhlIHdob2xlIHdvcmtib29rIGZvciB0ZW1wbGF0ZSBwYXR0ZXJuIGFuZCBjb25zdHJ1Y3RzIHRoZSB0ZW1wbGF0ZXMgZm9yIHByb2Nlc3NpbmcuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2IgVGhlIGNhbGxiYWNrIHRvIGJlIGludm9rZWQgb24gZWFjaCB0ZW1wbGF0ZWQsIGFmdGVyIHRoZXkgYXJlIHNvcnRlZC5cbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGUgdGVtcGxhdGVzIGNvbGxlY3RlZCBhcmUgc29ydGVkLCBiYXNlZCBvbiB0aGUgaW50cmEtdGVtcGxhdGUgcmVmZXJlbmNlIC0gaWYgb25lIHRlbXBsYXRlXG4gICAgICogaXMgcmVmZXJyaW5nIGFub3RoZXIgb25lLCBpdCdsbCBhcHBlYXIgX2xhdGVyXyBpbiB0aGUgcmV0dXJuZWQgYXJyYXksIHRoYW4gdGhlIHJlZmVycmVkIHRlbXBsYXRlLlxuICAgICAqIFRoaXMgaXMgdGhlIG9yZGVyIHRoZSBjYWxsYmFjayBpcyBiZWluZyBpbnZva2VkIG9uLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBjb2xsZWN0VGVtcGxhdGVzKGNiKSB7XG4gICAgICAgIGNvbnN0IGFsbFRlbXBsYXRlcyA9IFtdO1xuICAgIFxuICAgICAgICB0aGlzLl9hY2Nlc3MuZm9yQWxsQ2VsbHMoY2VsbCA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMucGFyc2VUZW1wbGF0ZShjZWxsKTtcbiAgICAgICAgICAgIGlmICh0ZW1wbGF0ZSlcbiAgICAgICAgICAgICAgICBhbGxUZW1wbGF0ZXMucHVzaCh0ZW1wbGF0ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIHRoaXMuc29ydFRlbXBsYXRlcyhhbGxUZW1wbGF0ZXMpLmZvckVhY2goY2IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHRoZSB2YWx1ZShzKSBmcm9tIHRoZSBwcm92aWRlZCBkYXRhIGByb290YCB0byBiZSBzZXQgaW4gdGhlIHByb3ZpZGVkIGBjZWxsYC5cbiAgICAgKiBAcGFyYW0ge3t9fSByb290IFRoZSBkYXRhIHJvb3QgdG8gYmUgZXh0cmFjdGVkIHZhbHVlcyBmcm9tLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBleHRyYWN0b3IgVGhlIGV4dHJhY3Rpb24gc3RyaW5nIHByb3ZpZGVkIGJ5IHRoZSB0ZW1wbGF0ZS4gVXN1YWxseSBhIEpTT04gcGF0aCB3aXRoaW4gdGhlIGRhdGEgYHJvb3RgLlxuICAgICAqIEBwYXJhbSB7Q2VsbH0gY2VsbCBBIHJlZmVyZW5jZSBjZWxsLCBpZiBzdWNoIGV4aXN0cy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bWJlcnxEYXRlfEFycmF5fEFycmF5LjxBcnJheS48Kj4+fSBUaGUgdmFsdWUgdG8gYmUgdXNlZC5cbiAgICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgaXMgdXNlZCBldmVuIHdoZW4gYSB3aG9sZSAtIHBvc3NpYmx5IHJlY3Rhbmd1bGFyIC0gcmFuZ2UgaXMgYWJvdXQgdG8gYmUgc2V0LCBzbyBpdCBjYW5cbiAgICAgKiByZXR1cm4gYW4gYXJyYXkgb2YgYXJyYXlzLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBleHRyYWN0VmFsdWVzKHJvb3QsIGV4dHJhY3RvciwgY2VsbCkge1xuICAgICAgICBjb25zdCB7IHBhdGgsIGhhbmRsZXIgfSA9IHRoaXMucGFyc2VFeHRyYWN0b3IoZXh0cmFjdG9yKTtcblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkocm9vdCkpXG4gICAgICAgICAgICByb290ID0gXy5nZXQocm9vdCwgcGF0aCwgcm9vdCk7XG4gICAgICAgIGVsc2UgaWYgKHJvb3Quc2l6ZXMgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgIHJvb3QgPSAhZXh0cmFjdG9yID8gcm9vdCA6IF8ubWFwKHJvb3QsIGVudHJ5ID0+IHRoaXMuZXh0cmFjdFZhbHVlcyhlbnRyeSwgZXh0cmFjdG9yLCBjZWxsKSk7XG4gICAgICAgIGVsc2UgaWYgKCFoYW5kbGVyKVxuICAgICAgICAgICAgcmV0dXJuIHJvb3Quam9pbih0aGlzLl9vcHRzLmpvaW5UZXh0IHx8IFwiLFwiKTtcblxuICAgICAgICByZXR1cm4gIWhhbmRsZXIgPyByb290IDogaGFuZGxlci5jYWxsKHRoaXMuX29wdHMsIHJvb3QsIGNlbGwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIGFuIGFycmF5IChwb3NzaWJseSBvZiBhcnJheXMpIHdpdGggZGF0YSBmb3IgdGhlIGdpdmVuIGZpbGwsIGJhc2VkIG9uIHRoZSBnaXZlblxuICAgICAqIHJvb3Qgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7e319IHJvb3QgVGhlIG1haW4gcmVmZXJlbmNlIG9iamVjdCB0byBhcHBseSBpdGVyYXRvcnMgdG8uXG4gICAgICogQHBhcmFtIHtBcnJheX0gaXRlcmF0b3JzIExpc3Qgb2YgaXRlcmF0b3JzIC0gc3RyaW5nIEpTT04gcGF0aHMgaW5zaWRlIHRoZSByb290IG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaWR4IFRoZSBpbmRleCBpbiB0aGUgaXRlcmF0b3JzIGFycmF5IHRvIHdvcmsgb24uXG4gICAgICogQHJldHVybnMge0FycmF5fEFycmF5LjxBcnJheT59IEFuIGFycmF5IChwb3NzaWJseSBvZiBhcnJheXMpIHdpdGggZXh0cmFjdGVkIGRhdGEuXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIGV4dHJhY3REYXRhKHJvb3QsIGl0ZXJhdG9ycywgaWR4KSB7XG4gICAgICAgIGxldCBpdGVyID0gaXRlcmF0b3JzW2lkeF0sXG4gICAgICAgICAgICBzaXplcyA9IFtdLFxuICAgICAgICAgICAgdHJhbnNwb3NlZCA9IGZhbHNlLFxuICAgICAgICAgICAgZGF0YSA9IG51bGw7XG5cbiAgICAgICAgaWYgKGl0ZXIgPT0gJzEnKSB7XG4gICAgICAgICAgICB0cmFuc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGl0ZXIgPSBpdGVyYXRvcnNbKytpZHhdO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpdGVyKSByZXR1cm4gcm9vdDtcblxuICAgICAgICAvLyBBIHNwZWNpZmljIGV4dHJhY3RvciBjYW4gYmUgc3BlY2lmaWVkIGFmdGVyIHNlbWlsb24gLSBmaW5kIGFuZCByZW1lbWJlciBpdC5cbiAgICAgICAgY29uc3QgcGFyc2VkSXRlciA9IHRoaXMucGFyc2VFeHRyYWN0b3IoaXRlcik7XG5cbiAgICAgICAgZGF0YSA9IF8uZ2V0KHJvb3QsIHBhcnNlZEl0ZXIucGF0aCwgcm9vdCk7XG4gICAgICAgIFxuICAgICAgICBpZiAodHlwZW9mIHBhcnNlZEl0ZXIuaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICAgIGRhdGEgPSBwYXJzZWRJdGVyLmhhbmRsZXIuY2FsbCh0aGlzLl9vcHRzLCBkYXRhKTtcblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkgJiYgdHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIGVsc2UgaWYgKGlkeCA8IGl0ZXJhdG9ycy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBkYXRhID0gXy5tYXAoZGF0YSwgaW5Sb290ID0+IHRoaXMuZXh0cmFjdERhdGEoaW5Sb290LCBpdGVyYXRvcnMsIGlkeCArIDEpKTtcbiAgICAgICAgICAgIHNpemVzID0gZGF0YVswXS5zaXplcyB8fCBbXTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gZGF0YSA9IF8udmFsdWVzKGRhdGEpO1xuXG4gICAgICAgIC8vIFNvbWUgZGF0YSBzYW5pdHkgY2hlY2tzLlxuICAgICAgICBpZiAoIWRhdGEpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBpdGVyYXRvciAnJHtpdGVyfScgZXh0cmFjdGVkIG5vIGRhdGEhYCk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkYXRhICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGRhdGEgZXh0cmFjdGVkIGZyb20gaXRlcmF0b3IgJyR7aXRlcn0nIGlzIG5laXRoZXIgYW4gYXJyYXksIG5vciBvYmplY3QhYCk7XG5cbiAgICAgICAgc2l6ZXMudW5zaGlmdCh0cmFuc3Bvc2VkID8gLWRhdGEubGVuZ3RoIDogZGF0YS5sZW5ndGgpO1xuICAgICAgICBkYXRhLnNpemVzID0gc2l6ZXM7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFB1dCB0aGUgZGF0YSB2YWx1ZXMgaW50byB0aGUgcHJvcGVyIGNlbGxzLCB3aXRoIGNvcnJlY3QgZXh0cmFjdGVkIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge3t9fSBjZWxsIFRoZSBzdGFydGluZyBjZWxsIGZvciB0aGUgZGF0YSB0byBiZSBwdXQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gZGF0YSBUaGUgYWN0dWFsIGRhdGEgdG8gYmUgcHV0LiBUaGUgdmFsdWVzIHdpbGwgYmUgX2V4dHJhY3RlZF8gZnJvbSBoZXJlIGZpcnN0LlxuICAgICAqIEBwYXJhbSB7e319IHRlbXBsYXRlIFRoZSB0ZW1wbGF0ZSB0aGF0IGlzIGJlaW5nIGltcGxlbWVudGVkIHdpdGggdGhhdCBkYXRhIGZpbGwuXG4gICAgICogQHJldHVybnMge0FycmF5fSBNYXRyaXggc2l6ZSB0aGF0IHRoaXMgZGF0YSBoYXMgb2NjdXBpZWQgb24gdGhlIHNoZWV0IFtyb3dzLCBjb2xzXS5cbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgcHV0VmFsdWVzKGNlbGwsIGRhdGEsIHRlbXBsYXRlKSB7XG4gICAgICAgIGlmICghY2VsbCkgdGhyb3cgbmV3IEVycm9yKFwiQ3Jhc2ghIE51bGwgcmVmZXJlbmNlIGNlbGwgaW4gJ3B1dFZhbHVlcygpJyFcIik7XG5cbiAgICAgICAgbGV0IGVudHJ5U2l6ZSA9IGRhdGEuc2l6ZXMsXG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMuZXh0cmFjdFZhbHVlcyhkYXRhLCB0ZW1wbGF0ZS5leHRyYWN0b3IsIGNlbGwpO1xuXG4gICAgICAgIC8vIGlmIHdlJ3ZlIGNvbWUgdXAgd2l0aCBhIHJhdyBkYXRhXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkgfHwgIWVudHJ5U2l6ZSB8fCAhZW50cnlTaXplLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5fYWNjZXNzLnNldENlbGxWYWx1ZShjZWxsLCB2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLmFwcGx5RGF0YVN0eWxlKGNlbGwsIGRhdGEsIHRlbXBsYXRlKTtcbiAgICAgICAgICAgIGVudHJ5U2l6ZSA9IHRlbXBsYXRlLmNlbGxTaXplO1xuICAgICAgICB9IGVsc2UgaWYgKGVudHJ5U2l6ZS5sZW5ndGggPD0gMikge1xuICAgICAgICAgICAgLy8gTm9ybWFsaXplIHRoZSBzaXplIGFuZCBkYXRhLlxuICAgICAgICAgICAgaWYgKGVudHJ5U2l6ZVswXSA8IDApIHtcbiAgICAgICAgICAgICAgICBlbnRyeVNpemUgPSBbMSwgLWVudHJ5U2l6ZVswXV07XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBbdmFsdWVdO1xuICAgICAgICAgICAgICAgIGRhdGEgPSBbZGF0YV07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVudHJ5U2l6ZS5sZW5ndGggPT0gMSkge1xuICAgICAgICAgICAgICAgIGVudHJ5U2l6ZSA9IGVudHJ5U2l6ZS5jb25jYXQoWzFdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IF8uY2h1bmsodmFsdWUsIDEpO1xuICAgICAgICAgICAgICAgIGRhdGEgPSBfLmNodW5rKGRhdGEsIDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3MuZ2V0Q2VsbFJhbmdlKGNlbGwsIGVudHJ5U2l6ZVswXSAtIDEsIGVudHJ5U2l6ZVsxXSAtIDEpLmZvckVhY2goKGNlbGwsIHJpLCBjaSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX2FjY2Vzcy5zZXRDZWxsVmFsdWUoY2VsbCwgdmFsdWVbcmldW2NpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5hcHBseURhdGFTdHlsZShjZWxsLCBkYXRhW3JpXVtjaV0sIHRlbXBsYXRlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVmFsdWVzIGV4dHJhY3RlZCB3aXRoICcke3RlbXBsYXRlLmV4dHJhY3Rvcn0nIGFyZSBtb3JlIHRoYW4gMiBkaW1lbnNpb24hJ2ApO1xuXG4gICAgICAgIHJldHVybiBlbnRyeVNpemU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwbHkgdGhlIGdpdmVuIGZpbHRlciBvbnRvIHRoZSBzaGVldCAtIGV4dHJhY3RpbmcgdGhlIHByb3BlciBkYXRhLCBmb2xsb3dpbmcgZGVwZW5kZW50IGZpbGxzLCBldGMuXG4gICAgICogQHBhcmFtIHt7fX0gYUZpbGwgVGhlIGZpbGwgdG8gYmUgYXBwbGllZCwgYXMgY29uc3RydWN0ZWQgaW4gdGhlIHtAbGluayBmaWxsRGF0YX0gbWV0aG9kLlxuICAgICAqIEBwYXJhbSB7e319IHJvb3QgVGhlIGRhdGEgcm9vdCB0byBiZSB1c2VkIGZvciBkYXRhIGV4dHJhY3Rpb24uXG4gICAgICogQHBhcmFtIHtDZWxsfSBtYWluQ2VsbCBUaGUgc3RhcnRpbmcgY2VsbCBmb3IgZGF0YSBwbGFjZW1lbnQgcHJvY2VkdXJlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gVGhlIHNpemUgb2YgdGhlIGRhdGEgcHV0IGluIFtyb3csIGNvbF0gZm9ybWF0LlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBhcHBseUZpbGwoYUZpbGwsIHJvb3QsIG1haW5DZWxsKSB7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gYUZpbGwudGVtcGxhdGUsXG4gICAgICAgICAgICB0aGVEYXRhID0gdGhpcy5leHRyYWN0RGF0YShyb290LCB0ZW1wbGF0ZS5pdGVyYXRvcnMsIDApO1xuXG4gICAgICAgIGxldCBlbnRyeVNpemUgPSBbMSwgMV07XG5cbiAgICAgICAgaWYgKCFhRmlsbC5kZXBlbmRlbnRzIHx8ICFhRmlsbC5kZXBlbmRlbnRzLmxlbmd0aClcbiAgICAgICAgICAgIGVudHJ5U2l6ZSA9IHRoaXMucHV0VmFsdWVzKG1haW5DZWxsLCB0aGVEYXRhLCB0ZW1wbGF0ZSk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IG5leHRDZWxsID0gbWFpbkNlbGw7XG4gICAgICAgICAgICBjb25zdCBzaXplTWF4eGVyID0gKHZhbCwgaWR4KSA9PiBlbnRyeVNpemVbaWR4XSA9IE1hdGgubWF4KGVudHJ5U2l6ZVtpZHhdLCB2YWwpO1xuXG4gICAgICAgICAgICBmb3IgKGxldCBkID0gMDsgZCA8IHRoZURhdGEubGVuZ3RoOyArK2QpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpblJvb3QgPSB0aGVEYXRhW2RdO1xuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZiA9IDA7IGYgPCBhRmlsbC5kZXBlbmRlbnRzLmxlbmd0aDsgKytmKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluRmlsbCA9IGFGaWxsLmRlcGVuZGVudHNbZl0sXG4gICAgICAgICAgICAgICAgICAgICAgICBpbkNlbGwgPSB0aGlzLl9hY2Nlc3Mub2Zmc2V0Q2VsbChuZXh0Q2VsbCwgaW5GaWxsLm9mZnNldFswXSwgaW5GaWxsLm9mZnNldFsxXSk7XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBfLmZvckVhY2godGhpcy5hcHBseUZpbGwoaW5GaWxsLCBpblJvb3QsIGluQ2VsbCksIHNpemVNYXh4ZXIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIE5vdyB3ZSBoYXZlIHRoZSBpbm5lciBkYXRhIHB1dCBhbmQgdGhlIHNpemUgY2FsY3VsYXRlZC5cbiAgICAgICAgICAgICAgICBfLmZvckVhY2godGhpcy5wdXRWYWx1ZXMobmV4dENlbGwsIGluUm9vdCwgdGVtcGxhdGUpLCBzaXplTWF4eGVyKTtcblxuICAgICAgICAgICAgICAgIGxldCByb3dPZmZzZXQgPSBlbnRyeVNpemVbMF0sXG4gICAgICAgICAgICAgICAgICAgIGNvbE9mZnNldCA9IGVudHJ5U2l6ZVsxXSxcbiAgICAgICAgICAgICAgICAgICAgcm93UGFkZGluZyA9IHRlbXBsYXRlLnBhZGRpbmdbMF0gfHwgMCxcbiAgICAgICAgICAgICAgICAgICAgY29sUGFkZGluZyA9IHRlbXBsYXRlLnBhZGRpbmdbMV0gfHwgMDtcblxuICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB3ZSBncm93IG9ubHkgb24gb25lIGRpbWVuc2lvbi5cbiAgICAgICAgICAgICAgICBpZiAodGhlRGF0YS5zaXplc1swXSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXBsYXRlLnBhZGRpbmcubGVuZ3RoIDwgMilcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbFBhZGRpbmcgPSByb3dQYWRkaW5nO1xuICAgICAgICAgICAgICAgICAgICByb3dPZmZzZXQgPSByb3dQYWRkaW5nID0gMDtcbiAgICAgICAgICAgICAgICAgICAgZW50cnlTaXplWzFdID0gMTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoZURhdGEuc2l6ZXMubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgICAgICBjb2xPZmZzZXQgPSBjb2xQYWRkaW5nID0gMDtcbiAgICAgICAgICAgICAgICAgICAgZW50cnlTaXplWzBdID0gMTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocm93T2Zmc2V0ID4gMSB8fCBjb2xPZmZzZXQgPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJuZyA9IHRoaXMuX2FjY2Vzcy5nZXRDZWxsUmFuZ2UobmV4dENlbGwsIE1hdGgubWF4KHJvd09mZnNldCAtIDEsIDApLCBNYXRoLm1heChjb2xPZmZzZXQgLSAxLCAwKSksXG4gICAgICAgICAgICAgICAgICAgICAgICBfb3B0cyA9IHRoaXMuZ2V0VGVtcGxhdGVPcHRzKHRlbXBsYXRlKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoX29wdHMubWVyZ2VDZWxscyA9PT0gdHJ1ZSB8fCBfb3B0cy5tZXJnZUNlbGwgPT09ICdib3RoJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfHwgcm93T2Zmc2V0ID4gMSAmJiBfb3B0cy5tZXJnZUNlbGxzID09PSAndmVydGljYWwnIFxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgY29sT2Zmc2V0ID4gMSAmJiBfb3B0cy5tZXJnZUNlbGxzID09PSAnaG9yaXpvbnRhbCcpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9hY2Nlc3MucmFuZ2VNZXJnZWQocm5nLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoX29wdHMuZHVwbGljYXRlQ2VsbHMgPT09IHRydWUgfHwgX29wdHMuZHVwbGljYXRlQ2VsbHMgPT09ICdib3RoJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfHwgcm93T2Zmc2V0ID4gMSAmJiBfb3B0cy5kdXBsaWNhdGVDZWxscyA9PT0gJ3ZlcnRpY2FsJyBcbiAgICAgICAgICAgICAgICAgICAgICAgIHx8IGNvbE9mZnNldCA+IDEgJiYgX29wdHMuZHVwbGljYXRlQ2VsbHMgPT09ICdob3Jpem9udGFsJylcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FjY2Vzcy5kdXBsaWNhdGVDZWxsKG5leHRDZWxsLCBybmcpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJuZy5mb3JFYWNoKGNlbGwgPT4gdGhpcy5hcHBseURhdGFTdHlsZShjZWxsLCBpblJvb3QsIHRlbXBsYXRlKSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gRmluYWxseSwgY2FsY3VsYXRlIHRoZSBuZXh0IGNlbGwuXG4gICAgICAgICAgICAgICAgbmV4dENlbGwgPSB0aGlzLl9hY2Nlc3Mub2Zmc2V0Q2VsbChuZXh0Q2VsbCwgcm93T2Zmc2V0ICsgcm93UGFkZGluZywgY29sT2Zmc2V0ICsgY29sUGFkZGluZyk7XHRcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gTm93IHJlY2FsYyBjb21iaW5lZCBlbnRyeSBzaXplLlxuICAgICAgICAgICAgXy5mb3JFYWNoKHRoaXMuX2FjY2Vzcy5jZWxsRGlzdGFuY2UobWFpbkNlbGwsIG5leHRDZWxsKSwgc2l6ZU1heHhlcik7XG4gICAgICAgIH1cblxuICAgICAgICBfLmZvckVhY2goYUZpbGwuZm9ybXVsYXMsIGYgPT4gdGhpcy5hcHBseUZvcm11bGEoZiwgZW50cnlTaXplLCBtYWluQ2VsbCkpO1xuXG4gICAgICAgIGFGaWxsLnByb2Nlc3NlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiBlbnRyeVNpemU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvY2VzcyBhIGZvcm11bGEgYmUgc2hpZnRpbmcgYWxsIHRoZSBmaXhlZCBvZmZzZXQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGZvcm11bGEgVGhlIGZvcm11bGEgdG8gYmUgc2hpZnRlZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5PE51bWJlcixOdW1iZXI+fSBvZmZzZXQgVGhlIG9mZnNldCBvZiB0aGUgcmVmZXJlbmNlZCB0ZW1wbGF0ZSB0byB0aGUgZm9ybXVsYSBvbmUuXG4gICAgICogQHBhcmFtIHtBcnJheTxOdW1iZXIsTnVtYmVyPn0gc2l6ZSBUaGUgc2l6ZSBvZiB0aGUgcmFuZ2VzIGFzIHRoZXkgc2hvdWxkIGJlLlxuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBwcm9jZXNzZWQgdGV4dC5cbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgc2hpZnRGb3JtdWxhKGZvcm11bGEsIG9mZnNldCwgc2l6ZSkge1xuICAgICAgICBsZXQgbmV3Rm9ybXVsYSA9ICcnO1xuXG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gZm9ybXVsYS5tYXRjaChyZWZSZWdFeHApO1xuICAgICAgICAgICAgaWYgKCFtYXRjaCkgYnJlYWs7XG5cbiAgICAgICAgICAgIGxldCBmcm9tID0gdGhpcy5fYWNjZXNzLmdldENlbGwobWF0Y2hbM10sIG1hdGNoWzJdKSxcbiAgICAgICAgICAgICAgICBuZXdSZWYgPSBudWxsO1xuXG4gICAgICAgICAgICBpZiAob2Zmc2V0WzBdID4gMCB8fCBvZmZzZXRbMV0gPiAwKVxuICAgICAgICAgICAgICAgIGZyb20gPSB0aGlzLl9hY2Nlc3Mub2Zmc2V0Q2VsbChmcm9tLCBvZmZzZXRbMF0sIG9mZnNldFsxXSk7XG5cbiAgICAgICAgICAgIG5ld1JlZiA9ICFtYXRjaFs1XVxuICAgICAgICAgICAgICAgID8gdGhpcy5fYWNjZXNzLmNlbGxSZWYoZnJvbSwgISFtYXRjaFsyXSlcbiAgICAgICAgICAgICAgICA6IHRoaXMuX2FjY2Vzcy5yYW5nZVJlZih0aGlzLl9hY2Nlc3MuZ2V0Q2VsbFJhbmdlKGZyb20sIHNpemVbMF0sIHNpemVbMV0pLCAhIW1hdGNoWzJdKTtcblxuICAgICAgICAgICAgbmV3Rm9ybXVsYSArPSBmb3JtdWxhLnN1YnN0cigwLCBtYXRjaC5pbmRleCkgKyBuZXdSZWY7XG4gICAgICAgICAgICBmb3JtdWxhID0gZm9ybXVsYS5zdWJzdHIobWF0Y2guaW5kZXggKyBtYXRjaFswXS5sZW5ndGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3Rm9ybXVsYSArPSBmb3JtdWxhO1xuICAgICAgICByZXR1cm4gbmV3Rm9ybXVsYTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBseSB0aGUgZ2l2ZW4gZm9ybXVsYSBpbiB0aGUgc2hlZXQsIGkuZS4gY2hhbmdpbmcgaXQgdG8gbWF0Y2ggdGhlIFxuICAgICAqIHNpemVzIG9mIHRoZSByZWZlcmVuY2VzIHRlbXBsYXRlcy5cbiAgICAgKiBAcGFyYW0ge3t9fSBhRmlsbCBUaGUgZmlsbCB0byBiZSBhcHBsaWVkLCBhcyBjb25zdHJ1Y3RlZCBpbiB0aGUge0BsaW5rIGZpbGxEYXRhfSBtZXRob2QuXG4gICAgICogQHBhcmFtIHtBcnJheTxOdW1iZXI+fSBlbnRyeVNpemUgVGhlIGZpbGwtdG8tc2l6ZSBtYXAsIGFzIGNvbnN0cnVjdGVkIHNvIGZhclxuICAgICAqIEBwYXJhbSB7Q2VsbH0gY2VsbCBUaGUgY2VsbCB0byBwdXQvc3RhcnQgdGhpcyBmb3JtdWxhIGludG9cbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBhcHBseUZvcm11bGEoYUZpbGwsIGVudHJ5U2l6ZSwgY2VsbCkge1xuICAgICAgICBjZWxsID0gdGhpcy5fYWNjZXNzLm9mZnNldENlbGwoY2VsbCwgYUZpbGwub2Zmc2V0WzBdLCBhRmlsbC5vZmZzZXRbMV0pO1xuXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gYUZpbGwudGVtcGxhdGUsXG4gICAgICAgICAgICBpdGVyID0gXy50cmltKHRlbXBsYXRlLml0ZXJhdG9yc1swXSksXG4gICAgICAgICAgICBvZmZzZXQgPSB0aGlzLl9hY2Nlc3MuY2VsbERpc3RhbmNlKHRlbXBsYXRlLmNlbGwsIGNlbGwpO1xuICAgICAgICAgICAgXG4gICAgICAgIGxldCBmb3JtdWxhID0gdGVtcGxhdGUuZXh0cmFjdG9yLCBcbiAgICAgICAgICAgIHJuZztcbiAgICAgICAgICAgIFxuICAgICAgICBhRmlsbC5wcm9jZXNzZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLl9hY2Nlc3Muc2V0Q2VsbFZhbHVlKGNlbGwsIG51bGwpO1xuXG4gICAgICAgIGlmIChlbnRyeVNpemVbMF0gPCAyICYmIGVudHJ5U2l6ZVsxXSA8IDIgfHwgaXRlciA9PT0gJ2JvdGgnKSB7XG4gICAgICAgICAgICBmb3JtdWxhID0gdGhpcy5zaGlmdEZvcm11bGEoZm9ybXVsYSwgb2Zmc2V0LCBbMCwgMF0pO1xuICAgICAgICAgICAgcm5nID0gdGhpcy5fYWNjZXNzLmdldENlbGxSYW5nZShjZWxsLCBlbnRyeVNpemVbMF0gLSAxLCBlbnRyeVNpemVbMV0gLSAxKTtcbiAgICAgICAgfSBlbHNlIGlmIChpdGVyID09PSAnY29scycpIHtcbiAgICAgICAgICAgIGZvcm11bGEgPSB0aGlzLnNoaWZ0Rm9ybXVsYShmb3JtdWxhLCBvZmZzZXQsIFtlbnRyeVNpemVbMF0gLSAxLCAwXSk7XG4gICAgICAgICAgICBybmcgPSB0aGlzLl9hY2Nlc3MuZ2V0Q2VsbFJhbmdlKGNlbGwsIDAsIGVudHJ5U2l6ZVsxXSAtIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGl0ZXIgPT09ICdyb3dzJykge1xuICAgICAgICAgICAgZm9ybXVsYSA9IHRoaXMuc2hpZnRGb3JtdWxhKGZvcm11bGEsIG9mZnNldCwgWzAsIGVudHJ5U2l6ZVsxXSAtIDFdKTtcbiAgICAgICAgICAgIHJuZyA9IHRoaXMuX2FjY2Vzcy5nZXRDZWxsUmFuZ2UoY2VsbCwgZW50cnlTaXplWzBdIC0gMSwgMCk7XG4gICAgICAgIH0gZWxzZSB7IC8vIGkuZS4gJ25vbmUnXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3Muc2V0Q2VsbEZvcm11bGEoY2VsbCwgdGhpcy5zaGlmdEZvcm11bGEoZm9ybXVsYSwgb2Zmc2V0LCBbZW50cnlTaXplWzBdIC0gMSwgZW50cnlTaXplWzFdIC0gMV0pKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2FjY2Vzcy5zZXRSYW5nZUZvcm11bGEocm5nLCBmb3JtdWxhKTtcbiAgICB9XG59XG5cbi8qKlxuICogVGhlIGJ1aWx0LWluIGFjY2Vzc29yIGJhc2VkIG9uIHhsc3gtcG9wdWxhdGUgbnBtIG1vZHVsZVxuICogQHR5cGUge1hsc3hQb3B1bGF0ZUFjY2Vzc31cbiAqL1xuWGxzeERhdGFGaWxsLlhsc3hQb3B1bGF0ZUFjY2VzcyA9IHJlcXVpcmUoJy4vWGxzeFBvcHVsYXRlQWNjZXNzJyk7XG5YbHN4RGF0YUZpbGwudmVyc2lvbiA9IFwie3tWRVJTSU9OfX1cIjtcblxubW9kdWxlLmV4cG9ydHMgPSBYbHN4RGF0YUZpbGw7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuY29uc3QgXyA9IHJlcXVpcmUoJ2xvZGFzaCcpO1xuXG4vLyBjb25zdCBhbGxTdHlsZXMgPSBbXG4vLyAgICAgXCJib2xkXCIsIFxuLy8gICAgIFwiaXRhbGljXCIsIFxuLy8gICAgIFwidW5kZXJsaW5lXCIsIFxuLy8gICAgIFwic3RyaWtldGhyb3VnaFwiLCBcbi8vICAgICBcInN1YnNjcmlwdFwiLCBcbi8vICAgICBcInN1cGVyc2NyaXB0XCIsIFxuLy8gICAgIFwiZm9udFNpemVcIiwgXG4vLyAgICAgXCJmb250RmFtaWx5XCIsIFxuLy8gICAgIFwiZm9udEdlbmVyaWNGYW1pbHlcIiwgXG4vLyAgICAgXCJmb250U2NoZW1lXCIsIFxuLy8gICAgIFwiZm9udENvbG9yXCIsIFxuLy8gICAgIFwiaG9yaXpvbnRhbEFsaWdubWVudFwiLCBcbi8vICAgICBcImp1c3RpZnlMYXN0TGluZVwiLCBcbi8vICAgICBcImluZGVudFwiLCBcbi8vICAgICBcInZlcnRpY2FsQWxpZ25tZW50XCIsIFxuLy8gICAgIFwid3JhcFRleHRcIiwgXG4vLyAgICAgXCJzaHJpbmtUb0ZpdFwiLCBcbi8vICAgICBcInRleHREaXJlY3Rpb25cIiwgXG4vLyAgICAgXCJ0ZXh0Um90YXRpb25cIiwgXG4vLyAgICAgXCJhbmdsZVRleHRDb3VudGVyY2xvY2t3aXNlXCIsIFxuLy8gICAgIFwiYW5nbGVUZXh0Q2xvY2t3aXNlXCIsIFxuLy8gICAgIFwicm90YXRlVGV4dFVwXCIsIFxuLy8gICAgIFwicm90YXRlVGV4dERvd25cIiwgXG4vLyAgICAgXCJ2ZXJ0aWNhbFRleHRcIiwgXG4vLyAgICAgXCJmaWxsXCIsIFxuLy8gICAgIFwiYm9yZGVyXCIsIFxuLy8gICAgIFwiYm9yZGVyQ29sb3JcIiwgXG4vLyAgICAgXCJib3JkZXJTdHlsZVwiLCBcbi8vICAgICBcImxlZnRCb3JkZXJcIiwgXCJyaWdodEJvcmRlclwiLCBcInRvcEJvcmRlclwiLCBcImJvdHRvbUJvcmRlclwiLCBcImRpYWdvbmFsQm9yZGVyXCIsIFxuLy8gICAgIFwibGVmdEJvcmRlckNvbG9yXCIsIFwicmlnaHRCb3JkZXJDb2xvclwiLCBcInRvcEJvcmRlckNvbG9yXCIsIFwiYm90dG9tQm9yZGVyQ29sb3JcIiwgXCJkaWFnb25hbEJvcmRlckNvbG9yXCIsIFxuLy8gICAgIFwibGVmdEJvcmRlclN0eWxlXCIsIFwicmlnaHRCb3JkZXJTdHlsZVwiLCBcInRvcEJvcmRlclN0eWxlXCIsIFwiYm90dG9tQm9yZGVyU3R5bGVcIiwgXCJkaWFnb25hbEJvcmRlclN0eWxlXCIsIFxuLy8gICAgIFwiZGlhZ29uYWxCb3JkZXJEaXJlY3Rpb25cIiwgXG4vLyAgICAgXCJudW1iZXJGb3JtYXRcIlxuLy8gXTtcblxubGV0IF9SaWNoVGV4dCA9IG51bGw7XG5cbi8qKlxuICogYHhzbHgtcG9wdWxhdGVgIGxpYnJhcnkgYmFzZWQgYWNjZXNzb3IgdG8gYSBnaXZlbiBFeGNlbCB3b3JrYm9vay4gQWxsIHRoZXNlIG1ldGhvZHMgYXJlIGludGVybmFsbHkgdXNlZCBieSB7QGxpbmsgWGxzeERhdGFGaWxsfSwgXG4gKiBidXQgY2FuIGJlIHVzZWQgYXMgYSByZWZlcmVuY2UgZm9yIGltcGxlbWVudGluZyBjdXN0b20gc3ByZWFkc2hlZXQgYWNjZXNzb3JzLlxuICovXG5jbGFzcyBYbHN4UG9wdWxhdGVBY2Nlc3Mge1xuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgWGxzeFNtYXJ0VGVtcGxhdGUgd2l0aCBnaXZlbiBvcHRpb25zLlxuICAgICAqIEBwYXJhbSB7V29ya2Jvb2t9IHdvcmtib29rIC0gVGhlIHdvcmtib29rIHRvIGJlIGFjY2Vzc2VkLlxuICAgICAqIEBwYXJhbSB7WGxzeFBvcHVsYXRlfSBYbHN4UG9wdWxhdGUgLSBUaGUgYWN0dWFsIHhsc3gtcG9wdWxhdGUgbGlicmFyeSBvYmplY3QuXG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSBgWGxzeFBvcHVsYXRlYCBvYmplY3QgbmVlZCB0byBiZSBwYXNzZWQgaW4gb3JkZXIgdG8gZXh0cmFjdFxuICAgICAqIGNlcnRhaW4gaW5mb3JtYXRpb24gZnJvbSBpdCwgX3dpdGhvdXRfIHJlZmVycmluZyB0aGUgd2hvbGUgbGlicmFyeSwgdGh1c1xuICAgICAqIGF2b2lkaW5nIG1ha2luZyB0aGUgYHhsc3gtZGF0YWZpbGxgIHBhY2thZ2UgYSBkZXBlbmRlbmN5LlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdvcmtib29rLCBYbHN4UG9wdWxhdGUpIHtcbiAgICAgICAgdGhpcy5fd29ya2Jvb2sgPSB3b3JrYm9vaztcbiAgICAgICAgdGhpcy5fcm93U2l6ZXMgPSB7fTtcbiAgICAgICAgdGhpcy5fY29sU2l6ZXMgPSB7fTtcbiAgICBcbiAgICAgICAgX1JpY2hUZXh0ID0gWGxzeFBvcHVsYXRlLlJpY2hUZXh0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGNvbmZpZ3VyZWQgd29ya2Jvb2sgZm9yIGRpcmVjdCBYbHN4UG9wdWxhdGUgbWFuaXB1bGF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtXb3JrYm9va30gVGhlIHdvcmtib29rIGludm9sdmVkLlxuICAgICAqL1xuICAgIHdvcmtib29rKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fd29ya2Jvb2s7IFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNlbGwgdmFsdWUuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIC0gVGhlIGNlbGwgdG8gcmV0cmlldmUgdGhlIHZhbHVlIGZyb20uXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgY2VsbCdzIGNvbnRlbnRzLlxuICAgICAqL1xuICAgIGNlbGxWYWx1ZShjZWxsKSB7XG4gICAgICAgIGNvbnN0IHRoZVZhbHVlID0gY2VsbC52YWx1ZSgpO1xuICAgICAgICByZXR1cm4gdGhlVmFsdWUgaW5zdGFuY2VvZiBfUmljaFRleHQgPyB0aGVWYWx1ZS50ZXh0KCkgOiB0aGVWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBjZWxsIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Q2VsbH0gY2VsbCAtIFRoZSBjZWxsIHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmcm9tLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgcmVxdWVzdGVkIHZhbHVlIGZvciBzZXR0aW5nLlxuICAgICAqIEByZXR1cm5zIHtYbHN4UG9wdWxhdGVBY2Nlc3N9IEVpdGhlciB0aGUgcmVxdWVzdGVkIHZhbHVlIG9yIGNoYWluYWJsZSB0aGlzLlxuICAgICAqL1xuICAgIHNldENlbGxWYWx1ZShjZWxsLCB2YWx1ZSkge1xuICAgICAgICBjZWxsLnZhbHVlKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2VsbCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgLSBUaGUgY2VsbCB0byByZXRyaWV2ZSB0aGUgdmFsdWUgZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgdHlwZSBvZiB0aGUgY2VsbCAtICdmb3JtdWxhJywgJ3JpY2h0ZXh0JywgXG4gICAgICogJ3RleHQnLCAnbnVtYmVyJywgJ2RhdGUnLCAnaHlwZXJsaW5rJywgb3IgJ3Vua25vd24nO1xuICAgICAqL1xuICAgIGNlbGxUeXBlKGNlbGwpIHtcbiAgICAgICAgaWYgKGNlbGwuZm9ybXVsYSgpKVxuICAgICAgICAgICAgcmV0dXJuICdmb3JtdWxhJztcbiAgICAgICAgZWxzZSBpZiAoY2VsbC5oeXBlcmxpbmsoKSlcbiAgICAgICAgICAgIHJldHVybiAnaHlwZXJsaW5rJztcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IHRoZVZhbHVlID0gY2VsbC52YWx1ZSgpO1xuICAgICAgICBpZiAodGhlVmFsdWUgaW5zdGFuY2VvZiBfUmljaFRleHQpXG4gICAgICAgICAgICByZXR1cm4gJ3JpY2h0ZXh0JztcbiAgICAgICAgZWxzZSBpZiAodGhlVmFsdWUgaW5zdGFuY2VvZiBEYXRlKVxuICAgICAgICAgICAgcmV0dXJuICdkYXRlJztcbiAgICAgICAgZWxzZSBcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgdGhlVmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgZm9ybXVsYSBpbiB0aGUgY2VsbFxuICAgICAqIEBwYXJhbSB7Q2VsbH0gY2VsbCAtIFRoZSBjZWxsIHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmcm9tLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtdWxhIC0gdGhlIHRleHQgb2YgdGhlIGZvcm11bGEgdG8gYmUgc2V0LlxuICAgICAqIEByZXR1cm5zIHtYbHN4UG9wdWxhdGVBY2Nlc3N9IEZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBzZXRDZWxsRm9ybXVsYShjZWxsLCBmb3JtdWxhKSB7XG4gICAgICAgIGNlbGwuZm9ybXVsYShfLnRyaW1TdGFydChmb3JtdWxhLCAnID0nKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1lYXN1cmVzIHRoZSBkaXN0YW5jZSwgYXMgYSB2ZWN0b3IgYmV0d2VlbiB0d28gZ2l2ZW4gY2VsbHMuXG4gICAgICogQHBhcmFtIHtDZWxsfSBmcm9tIFRoZSBmaXJzdCBjZWxsLlxuICAgICAqIEBwYXJhbSB7Q2VsbH0gdG8gVGhlIHNlY29uZCBjZWxsLlxuICAgICAqIEByZXR1cm5zIHtBcnJheS48TnVtYmVyPn0gQW4gYXJyYXkgd2l0aCB0d28gdmFsdWVzIFs8cm93cz4sIDxjb2xzPl0sIHJlcHJlc2VudGluZyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgdHdvIGNlbGxzLlxuICAgICAqL1xuICAgIGNlbGxEaXN0YW5jZShmcm9tLCB0bykge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgdG8ucm93TnVtYmVyKCkgLSBmcm9tLnJvd051bWJlcigpLFxuICAgICAgICAgICAgdG8uY29sdW1uTnVtYmVyKCkgLSBmcm9tLmNvbHVtbk51bWJlcigpXG4gICAgICAgIF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5lcyB0aGUgc2l6ZSBvZiBjZWxsLCB0YWtpbmcgaW50byBhY2NvdW50IGlmIGl0IGlzIHBhcnQgb2YgYSBtZXJnZWQgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIFRoZSBjZWxsIHRvIGJlIGludmVzdGlnYXRlZC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXkuPE51bWJlcj59IEFuIGFycmF5IHdpdGggdHdvIHZhbHVlcyBbPHJvd3M+LCA8Y29scz5dLCByZXByZXNlbnRpbmcgdGhlIG9jY3VwaWVkIHNpemUuXG4gICAgICovXG4gICAgY2VsbFNpemUoY2VsbCkge1xuICAgICAgICBjb25zdCBjZWxsQWRkciA9IGNlbGwuYWRkcmVzcygpO1xuICAgICAgICBsZXQgdGhlU2l6ZSA9IFsxLCAxXTtcbiAgICBcbiAgICAgICAgXy5mb3JFYWNoKGNlbGwuc2hlZXQoKS5fbWVyZ2VDZWxscywgcmFuZ2UgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmFuZ2VBZGRyID0gcmFuZ2UuYXR0cmlidXRlcy5yZWYuc3BsaXQoXCI6XCIpO1xuICAgICAgICAgICAgaWYgKHJhbmdlQWRkclswXSA9PSBjZWxsQWRkcikge1xuICAgICAgICAgICAgICAgIHRoZVNpemUgPSB0aGlzLmNlbGxEaXN0YW5jZShjZWxsLCBjZWxsLnNoZWV0KCkuY2VsbChyYW5nZUFkZHJbMV0pKTtcbiAgICAgICAgICAgICAgICArK3RoZVNpemVbMF07XG4gICAgICAgICAgICAgICAgKyt0aGVTaXplWzFdO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgXG4gICAgICAgIHJldHVybiB0aGVTaXplO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgYSBuYW1lZCBzdHlsZSBvZiBhIGdpdmVuIGNlbGwuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIFRoZSBjZWxsIHRvIGJlIG9wZXJhdGVkLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBzdHlsZSBwcm9wZXJ0eSB0byBiZSBzZXQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8b2JqZWN0fSB2YWx1ZSBUaGUgdmFsdWUgZm9yIHRoaXMgcHJvcGVydHkgdG8gYmUgc2V0LlxuICAgICAqIEByZXR1cm5zIHtYbHN4UG9wdWxhdGVBY2Nlc3N9IEZvciBpbnZvY2F0aW9uIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNldENlbGxTdHlsZShjZWxsLCBuYW1lLCB2YWx1ZSkge1xuICAgICAgICBjZWxsLnN0eWxlKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHJlZmVyZW5jZSBJZCBmb3IgYSBnaXZlbiBjZWxsLCBiYXNlZCBvbiBpdHMgc2hlZXQgYW5kIGFkZHJlc3MuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIFRoZSBjZWxsIHRvIGNyZWF0ZSBhIHJlZmVyZW5jZSBJZCB0by5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHdpdGhTaGVldCBXaGV0aGVyIHRvIGluY2x1ZGUgdGhlIHNoZWV0IG5hbWUgaW4gdGhlIHJlZmVyZW5jZS4gRGVmYXVsdHMgdG8gdHJ1ZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgaWQgdG8gYmUgdXNlZCBhcyBhIHJlZmVyZW5jZSBmb3IgdGhpcyBjZWxsLlxuICAgICAqL1xuICAgIGNlbGxSZWYoY2VsbCwgd2l0aFNoZWV0KSB7XG4gICAgICAgIGlmICh3aXRoU2hlZXQgPT0gbnVsbClcbiAgICAgICAgICAgIHdpdGhTaGVldCA9IHRydWU7XG4gICAgICAgIHJldHVybiBjZWxsLmFkZHJlc3MoeyBpbmNsdWRlU2hlZXROYW1lOiB3aXRoU2hlZXQgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnVpbGQgYSByZWZlcmVuY2Ugc3RyaW5nIGZvciBhIGNlbGwgaWRlbnRpZmllZCBieSBAcGFyYW0gYWRyLCBmcm9tIHRoZSBAcGFyYW0gY2VsbC5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgQSBjZWxsIHRoYXQgaXMgYSBiYXNlIG9mIHRoZSByZWZlcmVuY2UuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGFkciBUaGUgYWRkcmVzcyBvZiB0aGUgdGFyZ2V0IGNlbGwsIGFzIG1lbnRpb25lZCBpbiBAcGFyYW0gY2VsbC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHdpdGhTaGVldCBXaGV0aGVyIHRvIGluY2x1ZGUgdGhlIHNoZWV0IG5hbWUgaW4gdGhlIHJlZmVyZW5jZS4gRGVmYXVsdHMgdG8gdHJ1ZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHJlZmVyZW5jZSBzdHJpbmcgaWRlbnRpZnlpbmcgdGhlIHRhcmdldCBjZWxsIHVuaXF1ZWx5LlxuICAgICAqL1xuICAgIGJ1aWxkUmVmKGNlbGwsIGFkciwgd2l0aFNoZWV0KSB7XG4gICAgICAgIGlmICh3aXRoU2hlZXQgPT0gbnVsbClcbiAgICAgICAgICAgIHdpdGhTaGVldCA9IHRydWU7XG4gICAgICAgIHJldHVybiBhZHIgPyBjZWxsLnNoZWV0KCkuY2VsbChhZHIpLmFkZHJlc3MoeyBpbmNsdWRlU2hlZXROYW1lOiB3aXRoU2hlZXQgfSkgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhIGdpdmVuIGNlbGwgZnJvbSBhIGdpdmVuIHNoZWV0IChvciBhbiBhY3RpdmUgb25lKS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R8YXJyYXl9IGFkZHJlc3MgVGhlIGNlbGwgYWRyZXNzIHRvIGJlIHVzZWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xpZHh9IHNoZWV0SWQgVGhlIGlkL25hbWUgb2YgdGhlIHNoZWV0IHRvIHJldHJpZXZlIHRoZSBjZWxsIGZyb20uIERlZmF1bHRzIHRvIGFuIGFjdGl2ZSBvbmUuXG4gICAgICogQHJldHVybnMge0NlbGx9IEEgcmVmZXJlbmNlIHRvIHRoZSByZXF1aXJlZCBjZWxsLlxuICAgICAqL1xuICAgIGdldENlbGwoYWRkcmVzcywgc2hlZXRJZCkge1xuICAgICAgICBjb25zdCB0aGVTaGVldCA9IHNoZWV0SWQgPT0gbnVsbCA/IHRoaXMuX3dvcmtib29rLmFjdGl2ZVNoZWV0KCkgOiB0aGlzLl93b3JrYm9vay5zaGVldChzaGVldElkKTtcbiAgICAgICAgcmV0dXJuIHRoZVNoZWV0LmNlbGwoYWRkcmVzcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRHVwbGljYXRlcyBhIGNlbGwgYWNyb3NzIGEgZ2l2ZW4gcmFuZ2UuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIENlbGwsIHdoaWNoIG5lZWRzIGR1cGxpY2F0aW5nLlxuICAgICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIFRoZSByYW5nZSwgYXMgcmV0dXJuZWQgZnJvbSB7QGxpbmsgZ2V0Q2VsbFJhbmdlfVxuICAgICAqIEByZXR1cm5zIHtYbHN4UG9wdWxhdGVBY2Nlc3N9IEZvciBjaGFpbiBpbnZva2VzLlxuICAgICAqL1xuICAgIGR1cGxpY2F0ZUNlbGwoY2VsbCwgcmFuZ2UpIHtcbiAgICAgICAgcmFuZ2UudmFsdWUoY2VsbC52YWx1ZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhbmQgcmV0dXJucyB0aGUgcmFuZ2Ugc3RhcnRpbmcgZnJvbSB0aGUgZ2l2ZW4gY2VsbCBhbmQgc3Bhd25pbmcgZ2l2ZW4gcm93cyBhbmQgY2VsbHMuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIFRoZSBzdGFydGluZyBjZWxsIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcm93T2Zmc2V0IE51bWJlciBvZiByb3dzIGF3YXkgZnJvbSB0aGUgc3RhcnRpbmcgY2VsbC4gMCBtZWFucyBzYW1lIHJvdy5cbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY29sT2Zmc2V0IE51bWJlciBvZiBjb2x1bW5zIGF3YXkgZnJvbSB0aGUgc3RhcnRpbmcgY2VsbC4gMCBtZWFucyBzYW1lIGNvbHVtbi5cbiAgICAgKiBAcmV0dXJucyB7UmFuZ2V9IFRoZSBjb25zdHJ1Y3RlZCByYW5nZS5cbiAgICAgKi9cbiAgICBnZXRDZWxsUmFuZ2UoY2VsbCwgcm93T2Zmc2V0LCBjb2xPZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGNlbGwucmFuZ2VUbyhjZWxsLnJlbGF0aXZlQ2VsbChyb3dPZmZzZXQsIGNvbE9mZnNldCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGNlbGwgYXQgYSBjZXJ0YWluIG9mZnNldCBmcm9tIGEgZ2l2ZW4gb25lLlxuICAgICAqIEBwYXJhbSB7Q2VsbH0gY2VsbCBUaGUgcmVmZXJlbmNlIGNlbGwgdG8gbWFrZSB0aGUgb2Zmc2V0IGZyb20uXG4gICAgICogQHBhcmFtIHtpbnR9IHJvd3MgTnVtYmVyIG9mIHJvd3MgdG8gb2Zmc2V0LlxuICAgICAqIEBwYXJhbSB7aW50fSBjb2xzIE51bWJlciBvZiBjb2x1bW5zIHRvIG9mZnNldC5cbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIHJlc3VsdGluZyBjZWxsLlxuICAgICAqL1xuICAgIG9mZnNldENlbGwoY2VsbCwgcm93cywgY29scykge1xuICAgICAgICByZXR1cm4gY2VsbC5yZWxhdGl2ZUNlbGwocm93cywgY29scyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWVyZ2Ugb3Igc3BsaXQgcmFuZ2Ugb2YgY2VsbHMuXG4gICAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2UgVGhlIHJhbmdlLCBhcyByZXR1cm5lZCBmcm9tIHtAbGluayBnZXRDZWxsUmFuZ2V9XG4gICAgICogQHBhcmFtIHtib29sZWFufSBzdGF0dXMgVGhlIG1lcmdlZCBzdGF0dXMgdG8gYmUgc2V0LlxuICAgICAqIEByZXR1cm5zIHtYbHN4UG9wdWxhdGVBY2Nlc3N9IEZvciBjaGFpbiBpbnZva2VzLlxuICAgICAqL1xuICAgIHJhbmdlTWVyZ2VkKHJhbmdlLCBzdGF0dXMpIHtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgcmV0dXJuIHJhbmdlLm1lcmdlZCgpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJhbmdlLm1lcmdlZChzdGF0dXMpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIGEgZm9ybXVsYSBmb3IgdGhlIHdob2xlIHJhbmdlLiBJZiBpdCBjb250YWlucyBvbmx5IG9uZSAtIGl0IGlzIHNldCBkaXJlY3RseS5cbiAgICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSBUaGUgcmFuZ2UsIGFzIHJldHVybmVkIGZyb20ge0BsaW5rIGdldENlbGxSYW5nZX1cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZm9ybXVsYSBUaGUgZm9ybXVsYSB0byBiZSBzZXQuXG4gICAgICogQHJldHVybnMge1hsc3hQb3B1bGF0ZUFjY2Vzc30gRm9yIGNoYWluIGludm9rZXMuXG4gICAgICovXG4gICAgc2V0UmFuZ2VGb3JtdWxhKHJhbmdlLCBmb3JtdWxhKSB7XG4gICAgICAgIHJhbmdlLmZvcm11bGEoXy50cmltU3RhcnQoZm9ybXVsYSwgJyA9JykpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIGdpdmVuIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIFRoZSByYW5nZSB3aGljaCBhZGRyZXNzIHdlJ3JlIGludGVyZXN0ZWQgaW4uXG4gICAgICogQHBhcmFtIHtib29sZWFufSB3aXRoU2hlZXQgV2hldGhlciB0byBpbmNsdWRlIHNoZWV0IG5hbWUgaW4gdGhlIGFkZHJlc3MuXG4gICAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nLCByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHJhbmdlLlxuICAgICAqL1xuICAgIHJhbmdlUmVmKHJhbmdlLCB3aXRoU2hlZXQpIHtcbiAgICAgICAgaWYgKHdpdGhTaGVldCA9PSBudWxsKVxuICAgICAgICAgICAgd2l0aFNoZWV0ID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHJhbmdlLmFkZHJlc3MoeyBpbmNsdWRlU2hlZXROYW1lOiB3aXRoU2hlZXQgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGFsbCB1c2VkIGNlbGxzIG9mIHRoZSBnaXZlbiB3b3JrYm9vay5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYiBUaGUgY2FsbGJhY2sgdG8gYmUgaW52b2tlZCB3aXRoIGBjZWxsYCBhcmd1bWVudCBmb3IgZWFjaCB1c2VkIGNlbGwuXG4gICAgICogQHJldHVybnMge1hsc3hQb3B1bGF0ZUFjY2Vzc30gRm9yIGNoYWluIGludm9rZXMuXG4gICAgICovXG4gICAgZm9yQWxsQ2VsbHMoY2IpIHtcbiAgICAgICAgdGhpcy5fd29ya2Jvb2suc2hlZXRzKCkuZm9yRWFjaChzaGVldCA9PiB7XG4gICAgICAgICAgICBjb25zdCB0aGVSYW5nZSA9IHNoZWV0LnVzZWRSYW5nZSgpO1xuICAgICAgICAgICAgaWYgKHRoZVJhbmdlKSBcbiAgICAgICAgICAgICAgICB0aGVSYW5nZS5mb3JFYWNoKGNiKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvcGllcyB0aGUgc3R5bGVzIGZyb20gYHNyY2AgY2VsbCB0byB0aGUgYGRlc3RgLWluYXRpb24gb25lLlxuICAgICAqIEBwYXJhbSB7Q2VsbH0gZGVzdCBEZXN0aW5hdGlvbiBjZWxsLlxuICAgICAqIEBwYXJhbSB7Q2VsbH0gc3JjIFNvdXJjZSBjZWxsLlxuICAgICAqIEByZXR1cm5zIHtYbHN4UG9wdWxhdGVBY2Nlc3N9IEZvciBpbnZvY2F0aW9uIGNoYWluaW5nLlxuICAgICAqL1xuICAgIGNvcHlTdHlsZShkZXN0LCBzcmMpIHtcbiAgICAgICAgaWYgKCFzcmMgfHwgIWRlc3QpIHRocm93IG5ldyBFcnJvcihcIkNyYXNoISBOdWxsICdzcmMnIG9yICdkZXN0JyBmb3IgY29weVN0eWxlKCkhXCIpO1xuICAgICAgICBpZiAoc3JjID09IGRlc3QpIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChzcmMuX3N0eWxlICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICBkZXN0LnN0eWxlKHNyYy5fc3R5bGUpO1xuICAgICAgICBlbHNlIGlmIChzcmMuX3N0eWxlSWQgPiAwKVxuICAgICAgICAgICAgZGVzdC5fc3R5bGVJZCA9IHNyYy5fc3R5bGVJZDtcblxuICAgICAgICBjb25zdCBkZXN0U2hlZXRJZCA9IGRlc3Quc2hlZXQoKS5uYW1lKCksXG4gICAgICAgICAgICByb3dJZCA9IGAnJHtkZXN0U2hlZXRJZH0nOiR7ZGVzdC5yb3dOdW1iZXIoKX1gLFxuICAgICAgICAgICAgY29sSWQgPSBgJyR7ZGVzdFNoZWV0SWR9Jzoke2Rlc3QuY29sdW1uTnVtYmVyKCl9YDtcblxuICAgICAgICBpZiAodGhpcy5fcm93U2l6ZXNbcm93SWRdID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgICBkZXN0LnJvdygpLmhlaWdodCh0aGlzLl9yb3dTaXplc1tyb3dJZF0gPSBzcmMucm93KCkuaGVpZ2h0KCkpO1xuICAgICAgICBcbiAgICAgICAgaWYgKHRoaXMuX2NvbFNpemVzW2NvbElkXSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgZGVzdC5jb2x1bW4oKS53aWR0aCh0aGlzLl9jb2xTaXplc1tjb2xJZF0gPSBzcmMuY29sdW1uKCkud2lkdGgoKSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFhsc3hQb3B1bGF0ZUFjY2VzcztcbiJdfQ==
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvWGxzeERhdGFGaWxsLmpzIiwic3JjL1hsc3hQb3B1bGF0ZUFjY2Vzcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUNBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLElBQU0sRUFBQyxHQUFHLE9BQU8sQ0FBQyxRQUFELENBQWpCOztBQUVBLElBQU0sV0FBVyxHQUFHO0FBQ2hCLEVBQUEsY0FBYyxFQUFFLGlCQURBO0FBRWhCLEVBQUEsYUFBYSxFQUFFLEdBRkM7QUFHaEIsRUFBQSxRQUFRLEVBQUUsR0FITTtBQUloQixFQUFBLFVBQVUsRUFBRSxJQUpJO0FBS2hCLEVBQUEsY0FBYyxFQUFFLEtBTEE7QUFNaEIsRUFBQSxjQUFjLEVBQUUsS0FOQTtBQU9oQixFQUFBLFNBQVMsRUFBRSxJQVBLO0FBUWhCLEVBQUEsWUFBWSxFQUFFO0FBQ1YsUUFBSSxXQUFBLElBQUk7QUFBQSxhQUFJLEVBQUMsQ0FBQyxJQUFGLENBQU8sSUFBUCxDQUFKO0FBQUEsS0FERTtBQUVWLElBQUEsQ0FBQyxFQUFFLFdBQUEsSUFBSTtBQUFBLGFBQUksRUFBQyxDQUFDLE1BQUYsQ0FBUyxJQUFULENBQUo7QUFBQTtBQUZHO0FBUkUsQ0FBcEI7QUFjQSxJQUFNLFNBQVMsR0FBRyw0Q0FBbEI7QUFFQTs7OztJQUdNLFk7QUFDRjs7Ozs7Ozs7Ozs7OztBQWFBLHdCQUFZLFFBQVosRUFBc0IsSUFBdEIsRUFBNEI7QUFBQTs7QUFDeEIsU0FBSyxLQUFMLEdBQWEsRUFBQyxDQUFDLFlBQUYsQ0FBZSxFQUFmLEVBQW1CLElBQW5CLEVBQXlCLFdBQXpCLENBQWI7QUFDQSxTQUFLLFNBQUwsR0FBaUIsRUFBakI7QUFDQSxTQUFLLFNBQUwsR0FBaUIsRUFBakI7QUFDQSxTQUFLLE9BQUwsR0FBZSxRQUFmO0FBQ0g7QUFFRDs7Ozs7Ozs7OzRCQUtRLE8sRUFBUztBQUNiLFVBQUksT0FBTyxLQUFL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R0FBYSxJQUFiLEVBQXBCO0FBQUEsVUFDSSxLQUFLLGNBQU8sV0FBUCxlQUF1QixJQUFJLENBQUMsU0FBTCxFQUF2QixDQURUO0FBQUEsVUFFSSxLQUFLLGNBQU8sV0FBUCxlQUF1QixJQUFJLENBQUMsWUFBTCxFQUF2QixDQUZUO0FBSUEsVUFBSSxLQUFLLFNBQUwsQ0FBZSxLQUFmLE1BQTBCLFNBQTlCLEVBQ0ksSUFBSSxDQUFDLEdBQUwsR0FBVyxNQUFYLENBQWtCLEtBQUssU0FBTCxDQUFlLEtBQWYsSUFBd0IsR0FBRyxDQUFDLEdBQUosR0FBVSxNQUFWLEVBQTFDO0FBRUosVUFBSSxLQUFLLFNBQUwsQ0FBZSxLQUFmLE1BQTBCLFNBQTlCLEVBQ0ksSUFBSSxDQUFDLE1BQUwsR0FBYyxLQUFkLENBQW9CLEtBQUssU0FBTCxDQUFlLEtBQWYsSUFBd0IsR0FBRyxDQUFDLE1BQUosR0FBYSxLQUFiLEVBQTVDO0FBRUosYUFBTyxJQUFQO0FBQ0g7Ozs7OztBQUdMLE1BQU0sQ0FBQyxPQUFQLEdBQWlCLGtCQUFqQiIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIlwidXNlIHN0cmljdFwiO1xuXG5jb25zdCBfID0gcmVxdWlyZSgnbG9kYXNoJyk7XG5cbmNvbnN0IGRlZmF1bHRPcHRzID0ge1xuICAgIHRlbXBsYXRlUmVnRXhwOiAvXFx7XFx7KFtefV0qKVxcfVxcfS8sXG4gICAgZmllbGRTcGxpdHRlcjogXCJ8XCIsXG4gICAgam9pblRleHQ6IFwiLFwiLFxuICAgIG1lcmdlQ2VsbHM6IHRydWUsXG4gICAgZHVwbGljYXRlQ2VsbHM6IGZhbHNlLFxuICAgIGZvbGxvd0Zvcm11bGFlOiBmYWxzZSxcbiAgICBjb3B5U3R5bGU6IHRydWUsXG4gICAgY2FsbGJhY2tzTWFwOiB7XG4gICAgICAgICcnOiBkYXRhID0+IF8ua2V5cyhkYXRhKSxcbiAgICAgICAgJDogZGF0YSA9PiBfLnZhbHVlcyhkYXRhKVxuICAgIH1cbn07XG5cbmNvbnN0IHJlZlJlZ0V4cCA9IC8oJz8oW14hXSopPyc/ISk/KFtBLVpdK1xcZCspKDooW0EtWl0rXFxkKykpPy87XG5cbi8qKlxuICogRGF0YSBmaWxsIGVuZ2luZSwgdGFraW5nIGFuIGluc3RhbmNlIG9mIEV4Y2VsIHNoZWV0IGFjY2Vzc29yIGFuZCBhIEpTT04gb2JqZWN0IGFzIGRhdGEsIGFuZCBmaWxsaW5nIHRoZSB2YWx1ZXMgZnJvbSB0aGUgbGF0dGVyIGludG8gdGhlIGZvcm1lci5cbiAqL1xuY2xhc3MgWGxzeERhdGFGaWxsIHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIFhsc3hEYXRhRmlsbCB3aXRoIGdpdmVuIG9wdGlvbnMuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGFjY2Vzc29yIEFuIGluc3RhbmNlIG9mIFhMU1ggc3ByZWFkc2hlZXQgYWNjZXNzaW5nIGNsYXNzLlxuICAgICAqIEBwYXJhbSB7e319IG9wdHMgT3B0aW9ucyB0byBiZSB1c2VkIGR1cmluZyBwcm9jZXNzaW5nLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBvcHRzLnRlbXBsYXRlUmVnRXhwIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gdG8gYmUgdXNlZCBmb3IgdGVtcGxhdGUgcmVjb2duaXppbmcuIERlZmF1bHQgaXMgYC9cXHtcXHsoW159XSopXFx9XFx9L2AsIGkuZS4gTXVzdGFjaGUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8UmVnRXhvfSBvcHRzLmZpZWxkU3BsaXR0ZXIgVGhlIHN0cmluZyBvciByZWd1bGFyIGV4cHJlc3Npb24gdG8gYmUgdXNlZCBhcyB0ZW1wbGF0ZSBmaWVsZHMgc3BsaXR0ZXIuIERlZmF1bHQgaXMgYHxgLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLmpvaW5UZXh0IFRoZSBzdHJpbmcgdG8gYmUgdXNlZCB3aGVuIHRoZSBleHRyYWN0ZWQgdmFsdWUgZm9yIGEgc2luZ2xlIGNlbGwgaXMgYW4gYXJyYXksIGFuZCBpdCBuZWVkcyB0byBiZSBqb2luZWQuIERlZmF1bHQgaXMgYCxgLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGJvb2xlYW59IG9wdHMubWVyZ2VDZWxscyBXaGV0aGVyIHRvIG1lcmdlIHRoZSBoaWdoZXIgZGltZW5zaW9uIGNlbGxzIGluIHRoZSBvdXRwdXQuIERlZmF1bHQgaXMgdHJ1ZSwgYnV0IHZhbGlkIHZhbHVlcyBhcmUgYWxzbyBgXCJib3RoXCJgLCBgXCJ2ZXJ0aWNhbFwiYCBhbmQgYFwiaG9yaXpvbnRhbFwiYC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xib29sZWFufSBvcHRzLmR1cGxpY2F0ZUNlbGxzIFdoZXRoZXIgdG8gZHVwbGljYXRlIHRoZSBjb250ZW50IG9mIGhpZ2hlciBkaW1lbnNpb24gY2VsbHMsIHdoZW4gbm90IG1lcmdlZC4gRGVmYXVsdCBpcyBmYWxzZS4gU2FtZSB2YWx1ZCB2YWx1ZXMgYXMgYG1lcmdlQ2VsbHNgLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gb3B0cy5mb2xsb3dGb3JtdWxhZSBJZiBhIHRlbXBsYXRlIGlzIGxvY2F0ZWQgYXMgYSByZXN1bHQgb2YgYSBmb3JtdWxhLCB3aGV0aGVyIHRvIHN0aWxsIHByb2Nlc3MgaXQuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBvcHRzLmNvcHlTdHlsZSBDb3B5IHRoZSBzdHlsZSBvZiB0aGUgdGVtcGxhdGUgY2VsbCB3aGVuIHBvcHVsYXRpbmcuIEV2ZW4gd2hlbiBgZmFsc2VgLCB0aGUgdGVtcGxhdGUgc3R5bGluZyBfaXNfIGFwcGxpZWQuIERlZmF1bHQgaXMgdHJ1ZS5cbiAgICAgKiBAcGFyYW0ge29iamVjdC48c3RyaW5nLCBmdW5jdGlvbj59IG9wdHMuY2FsbGJhY2tzTWFwIEEgbWFwIG9mIGhhbmRsZXJzIHRvIGJlIHVzZWQgZm9yIGRhdGEgYW5kIHZhbHVlIGV4dHJhY3Rpb24uXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoYWNjZXNzb3IsIG9wdHMpIHtcbiAgICAgICAgdGhpcy5fb3B0cyA9IF8uZGVmYXVsdHNEZWVwKHt9LCBvcHRzLCBkZWZhdWx0T3B0cyk7XG4gICAgICAgIHRoaXMuX3Jvd1NpemVzID0ge307XG4gICAgICAgIHRoaXMuX2NvbFNpemVzID0ge307XG4gICAgICAgIHRoaXMuX2FjY2VzcyA9IGFjY2Vzc29yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHRlci9nZXR0ZXIgZm9yIFhsc3hEYXRhRmlsbCdzIG9wdGlvbnMgYXMgc2V0IGR1cmluZyBjb25zdHJ1Y3Rpb24uXG4gICAgICogQHBhcmFtIHt7fXxudWxsfSBuZXdPcHRzIElmIHNldCAtIHRoZSBuZXcgb3B0aW9ucyB0byBiZSB1c2VkLiBDaGVjayBbdXAgaGVyZV17QGxpbmsgI25ldy14bHN4ZGF0YWZpbGxhY2Nlc3Nvci1vcHRzfS5cbiAgICAgKiBAcmV0dXJucyB7WGxzeERhdGFGaWxsfHt9fSBUaGUgcmVxdWlyZWQgb3B0aW9ucyAoaW4gZ2V0dGVyIG1vZGUpIG9yIFhsc3hEYXRhRmlsbCAoaW4gc2V0dGVyIG1vZGUpIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBvcHRpb25zKG5ld09wdHMpIHtcbiAgICAgICAgaWYgKG5ld09wdHMgIT09IG51bGwpIHtcbiAgICAgICAgICAgIF8ubWVyZ2UodGhpcy5fb3B0cywgbmV3T3B0cyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3B0cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWFpbiBlbnRyeSBwb2ludCBmb3Igd2hvbGUgZGF0YSBwb3B1bGF0aW9uIG1lY2hhbmlzbS5cbiAgICAgKiBAcGFyYW0ge3t9fSBkYXRhIFRoZSBkYXRhIHRvIGJlIGFwcGxpZWQuXG4gICAgICogQHJldHVybnMge1hsc3hEYXRhRmlsbH0gRm9yIGludm9jYXRpb24gY2hhaW5pbmcuXG4gICAgICovXG4gICAgZmlsbERhdGEoZGF0YSkge1xuICAgICAgICBjb25zdCBkYXRhRmlsbHMgPSB7fTtcblx0XG4gICAgICAgIC8vIEJ1aWxkIHRoZSBkZXBlbmRlbmN5IGNvbm5lY3Rpb25zIGJldHdlZW4gdGVtcGxhdGVzLlxuICAgICAgICB0aGlzLmNvbGxlY3RUZW1wbGF0ZXModGVtcGxhdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgYUZpbGwgPSB7ICBcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZTogdGVtcGxhdGUsIFxuICAgICAgICAgICAgICAgIGRlcGVuZGVudHM6IFtdLFxuICAgICAgICAgICAgICAgIGZvcm11bGFzOiBbXSxcbiAgICAgICAgICAgICAgICBwcm9jZXNzZWQ6IGZhbHNlXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGVtcGxhdGUucmVmZXJlbmNlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVmRmlsbCA9IGRhdGFGaWxsc1t0ZW1wbGF0ZS5yZWZlcmVuY2VdO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmICghcmVmRmlsbCkgXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGZpbmQgYSByZWZlcmVuY2UgJyR7dGVtcGxhdGUucmVmZXJlbmNlfSchYCk7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgaWYgKHRlbXBsYXRlLmZvcm11bGEpIFxuICAgICAgICAgICAgICAgICAgICByZWZGaWxsLmZvcm11bGFzLnB1c2goYUZpbGwpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgcmVmRmlsbC5kZXBlbmRlbnRzLnB1c2goYUZpbGwpO1xuICAgIFxuICAgICAgICAgICAgICAgIGFGaWxsLm9mZnNldCA9IHRoaXMuX2FjY2Vzcy5jZWxsRGlzdGFuY2UocmVmRmlsbC50ZW1wbGF0ZS5jZWxsLCB0ZW1wbGF0ZS5jZWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRhdGFGaWxsc1t0ZW1wbGF0ZS5pZF0gPSBhRmlsbDtcbiAgICAgICAgfSk7XG4gICAgXG4gICAgICAgIC8vIEFwcGx5IGVhY2ggZmlsbCBvbnRvIHRoZSBzaGVldC5cbiAgICAgICAgXy5lYWNoKGRhdGFGaWxscywgZmlsbCA9PiB7XG4gICAgICAgICAgICBpZiAoZmlsbC5wcm9jZXNzZWQpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgZWxzZSBpZiAoZmlsbC50ZW1wbGF0ZS5mb3JtdWxhKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm9uLXJlZmVyZW5jaW5nIGZvcm11bGEgZm91bmQgJyR7ZmlsbC5leHRyYWN0b3J9Jy4gVXNlIGEgbm9uLXRlbXBsYXRlZCBvbmUhYCk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdGhpcy5hcHBseUZpbGwoZmlsbCwgZGF0YSwgZmlsbC50ZW1wbGF0ZS5jZWxsKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBwcm92aWRlZCBoYW5kbGVyIGZyb20gdGhlIG1hcC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaGFuZGxlck5hbWUgVGhlIG5hbWUgb2YgdGhlIGhhbmRsZXIuXG4gICAgICogQHJldHVybnMge2Z1bmN0aW9ufSBUaGUgaGFuZGxlciBmdW5jdGlvbiBpdHNlbGYuXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIGdldEhhbmRsZXIoaGFuZGxlck5hbWUpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlckZuID0gdGhpcy5fb3B0cy5jYWxsYmFja3NNYXBbaGFuZGxlck5hbWVdO1xuXG4gICAgICAgIGlmICghaGFuZGxlckZuKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBIYW5kbGVyICcke2hhbmRsZXJOYW1lfScgY2Fubm90IGJlIGZvdW5kIWApO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2YgaGFuZGxlckZuICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBIYW5kbGVyICcke2hhbmRsZXJOYW1lfScgaXMgbm90IGEgZnVuY3Rpb24hYCk7XG4gICAgICAgIGVsc2UgXG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlckZuO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgcHJvdmlkZWQgZXh0cmFjdG9yIChvdCBpdGVyYXRvcikgc3RyaW5nIHRvIGZpbmQgYSBjYWxsYmFjayBpZCBpbnNpZGUsIGlmIHByZXNlbnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV4dHJhY3RvciBUaGUgaXRlcmF0b3IvZXh0cmFjdG9yIHN0cmluZyB0byBiZSBpbnZlc3RpZ2F0ZWQuXG4gICAgICogQHJldHVybnMge29iamVjdC48c3RyaW5nLCBmdW5jdGlvbj59IEEgeyBgcGF0aGAsIGBoYW5kbGVyYCB9IG9iamVjdCByZXByZXNlbnRpbmcgdGhlIEpTT04gcGF0aFxuICAgICAqIHJlYWR5IGZvciB1c2UgYW5kIHRoZSBwcm92aWRlZCBgaGFuZGxlcmAgX2Z1bmN0aW9uXyAtIHJlYWR5IGZvciBpbnZva2luZywgaWYgc3VjaCBpcyBwcm92aWRlZC5cbiAgICAgKiBJZiBub3QgLSB0aGUgYHBhdGhgIHByb3BlcnR5IGNvbnRhaW5zIHRoZSBwcm92aWRlZCBgZXh0cmFjdG9yYCwgYW5kIHRoZSBgaGFuZGxlcmAgaXMgYG51bGxgLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBwYXJzZUV4dHJhY3RvcihleHRyYWN0b3IpIHtcbiAgICAgICAgLy8gQSBzcGVjaWZpYyBleHRyYWN0b3IgY2FuIGJlIHNwZWNpZmllZCBhZnRlciBzZW1pbG9uIC0gZmluZCBhbmQgcmVtZW1iZXIgaXQuXG4gICAgICAgIGNvbnN0IGV4dHJhY3RQYXJ0cyA9IGV4dHJhY3Rvci5zcGxpdChcIjpcIiksXG4gICAgICAgICAgICBoYW5kbGVyTmFtZSA9IF8udHJpbShleHRyYWN0UGFydHNbMV0pO1xuXG4gICAgICAgIHJldHVybiBleHRyYWN0UGFydHMubGVuZ3RoID09IDFcbiAgICAgICAgICAgID8geyBwYXRoOiBleHRyYWN0b3IsIGhhbmRsZXI6IG51bGwgfVxuICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgcGF0aDogXy50cmltKGV4dHJhY3RQYXJ0c1swXSksXG4gICAgICAgICAgICAgICAgaGFuZGxlcjogdGhpcy5nZXRIYW5kbGVyKGhhbmRsZXJOYW1lKVxuICAgICAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIHRoZSBzdHlsZSBwYXJ0IG9mIHRoZSB0ZW1wbGF0ZSBvbnRvIGEgZ2l2ZW4gY2VsbC5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgVGhlIGRlc3RpbmF0aW9uIGNlbGwgdG8gYXBwbHkgc3R5bGluZyB0by5cbiAgICAgKiBAcGFyYW0ge3t9fSBkYXRhIFRoZSBkYXRhIGNodW5rIGZvciB0aGF0IGNlbGwuXG4gICAgICogQHBhcmFtIHt7fX0gdGVtcGxhdGUgVGhlIHRlbXBsYXRlIHRvIGJlIHVzZWQgZm9yIHRoYXQgY2VsbC5cbiAgICAgKiBAcmV0dXJucyB7RGF0YUZpbGxlcn0gRm9yIGludm9jYXRpb24gY2hhaW5pbmcuXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIGFwcGx5RGF0YVN0eWxlKGNlbGwsIGRhdGEsIHRlbXBsYXRlKSB7XG4gICAgICAgIGNvbnN0IHN0eWxlcyA9IHRlbXBsYXRlLnN0eWxlcztcblxuICAgICAgICBpZiAodGhpcy5fb3B0cy5jb3B5U3R5bGUpXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3MuY29weVN0eWxlKGNlbGwsIHRlbXBsYXRlLmNlbGwpO1xuICAgICAgICBcbiAgICAgICAgaWYgKHN0eWxlcyAmJiBkYXRhKSB7XG4gICAgICAgICAgICBfLmVhY2goc3R5bGVzLCBwYWlyID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoXy5zdGFydHNXaXRoKHBhaXIubmFtZSwgXCI6XCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0SGFuZGxlcihwYWlyLm5hbWUuc3Vic3RyKDEpKS5jYWxsKHRoaXMuX29wdHMsIGRhdGEsIGNlbGwpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIV8uc3RhcnRzV2l0aChwYWlyLm5hbWUsIFwiIVwiKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWwgPSB0aGlzLmV4dHJhY3RWYWx1ZXMoZGF0YSwgcGFpci5leHRyYWN0b3IsIGNlbGwpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWNjZXNzLnNldENlbGxTdHlsZShjZWxsLCBwYWlyLm5hbWUsIEpTT04ucGFyc2UodmFsKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0IHRoZSBvcHRpb25zLXNwZWNpZmljIHBhcmFtZXRlcnMgZnJvbSB0aGUgc3R5bGVzIGZpZWxkIGFuZCBtZXJnZSB0aGVtIHdpdGggdGhlIGdsb2JhbCBvbmVzLlxuICAgICAqIEBwYXJhbSB7e319IHRlbXBsYXRlIFRoZSB0ZW1wbGF0ZSB0byBleHRyYWN0IG9wdGlvbnMgcHJvcGVydGllcyBmcm9tLlxuICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIGZ1bGwgb3B0aW9ucywgXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIGdldFRlbXBsYXRlT3B0cyh0ZW1wbGF0ZSkge1xuICAgICAgICBpZiAoIXRlbXBsYXRlLnN0eWxlcylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcHRzO1xuICAgICAgICBcbiAgICAgICAgY29uc3Qgb3B0cyA9IF8uY2xvbmUodGhpcy5fb3B0cyk7XG4gICAgICAgIF8uZWFjaCh0ZW1wbGF0ZS5zdHlsZXMsIHBhaXIgPT4ge1xuICAgICAgICAgICAgaWYgKF8uc3RhcnRzV2l0aChwYWlyLm5hbWUsIFwiIVwiKSlcbiAgICAgICAgICAgICAgICBvcHRzW3BhaXIubmFtZS5zdWJzdHIoMSldID0gSlNPTi5wYXJzZShwYWlyLmV4dHJhY3Rvcik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBvcHRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgY29udGVudHMgb2YgdGhlIGNlbGwgaW50byBhIHZhbGlkIHRlbXBsYXRlIGluZm8uXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIFRoZSBjZWxsIGNvbnRhaW5pbmcgdGhlIHRlbXBsYXRlIHRvIGJlIHBhcnNlZC5cbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSBwYXJzZWQgdGVtcGxhdGUuXG4gICAgICogQGRlc2NyaXB0aW9uIFRoaXMgbWV0aG9kIGJ1aWxkcyB0ZW1wbGF0ZSBpbmZvLCB0YWtpbmcgaW50byBhY2NvdW50IHRoZSBzdXBwbGllZCBvcHRpb25zLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBwYXJzZVRlbXBsYXRlKGNlbGwpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl9hY2Nlc3MuY2VsbFZhbHVlKGNlbGwpO1xuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCB0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIFxuICAgICAgICBjb25zdCByZU1hdGNoID0gdmFsdWUubWF0Y2godGhpcy5fb3B0cy50ZW1wbGF0ZVJlZ0V4cCk7XG4gICAgICAgIGlmICghcmVNYXRjaCB8fCAhdGhpcy5fb3B0cy5mb2xsb3dGb3JtdWxhZSAmJiB0aGlzLl9hY2Nlc3MuY2VsbFR5cGUoY2VsbCkgPT09ICdmb3JtdWxhJykgXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBcbiAgICAgICAgY29uc3QgcGFydHMgPSByZU1hdGNoWzFdLnNwbGl0KHRoaXMuX29wdHMuZmllbGRTcGxpdHRlcikubWFwKF8udHJpbSksXG4gICAgICAgICAgICBzdHlsZXMgPSAhcGFydHNbNF0gPyBudWxsIDogcGFydHNbNF0uc3BsaXQoXCIsXCIpLFxuICAgICAgICAgICAgZXh0cmFjdG9yID0gcGFydHNbMl0gfHwgXCJcIixcbiAgICAgICAgICAgIGNlbGxSZWYgPSB0aGlzLl9hY2Nlc3MuYnVpbGRSZWYoY2VsbCwgcGFydHNbMF0pO1xuICAgICAgICBcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA8IDIpIFxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBOb3QgZW5vdWdoIGNvbXBvbmVudHMgb2YgdGhlIHRlbXBsYXRlICcke3JlTWF0Y2hbMF19J2ApO1xuICAgICAgICBpZiAoISFwYXJ0c1swXSAmJiAhY2VsbFJlZilcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByZWZlcmVuY2UgcGFzc2VkOiAnJHtwYXJ0c1swXX0nYCk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLl9hY2Nlc3MuY2VsbFJlZihjZWxsKSxcbiAgICAgICAgICAgIHJlZmVyZW5jZTogY2VsbFJlZixcbiAgICAgICAgICAgIGl0ZXJhdG9yczogcGFydHNbMV0uc3BsaXQoL3h8XFwqLykubWFwKF8udHJpbSksXG4gICAgICAgICAgICBleHRyYWN0b3I6IGV4dHJhY3RvcixcbiAgICAgICAgICAgIGZvcm11bGE6IGV4dHJhY3Rvci5zdGFydHNXaXRoKFwiPVwiKSxcbiAgICAgICAgICAgIGNlbGw6IGNlbGwsXG4gICAgICAgICAgICBjZWxsU2l6ZTogdGhpcy5fYWNjZXNzLmNlbGxTaXplKGNlbGwpLFxuICAgICAgICAgICAgcGFkZGluZzogKHBhcnRzWzNdIHx8IFwiXCIpLnNwbGl0KC86fCx8eHxcXCovKS5tYXAodiA9PiBwYXJzZUludCh2KSB8fCAwKSxcbiAgICAgICAgICAgIHN0eWxlczogIXN0eWxlcyA/IG51bGwgOiBfLm1hcChzdHlsZXMsIHMgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhaXIgPSBfLnRyaW0ocykuc3BsaXQoXCI9XCIpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7IG5hbWU6IF8udHJpbShwYWlyWzBdKSwgZXh0cmFjdG9yOiBfLnRyaW0ocGFpclsxXSkgfTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc29ydFRlbXBsYXRlcyhsaXN0KSB7XG4gICAgICAgIGNvbnN0IHNvcnRlZCA9IFtdLFxuICAgICAgICAgICAgcmVsYXRlZCA9IHt9LFxuICAgICAgICAgICAgbWFwID0ge30sXG4gICAgICAgICAgICBmcmVlTGlzdCA9IFtdO1xuXG4gICAgICAgIC8vIEZpcnN0LCBtYWtlIHRoZSBkZXBlbmRlbmN5IG1hcCBhbmQgYWRkIHRoZSBsaXN0IG9mIG5vbi1yZWZlcmVuY2luZyB0ZW1wbGF0ZXNcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBjb25zdCB0ID0gbGlzdFtpXTtcbiAgICAgICAgICAgIG1hcFt0LmlkXSA9IGk7XG5cbiAgICAgICAgICAgIGlmICghdC5yZWZlcmVuY2UpXG4gICAgICAgICAgICAgICAgZnJlZUxpc3QucHVzaCh0LmlkKTtcbiAgICAgICAgICAgIGVsc2UgXG4gICAgICAgICAgICAgICAgKHJlbGF0ZWRbdC5yZWZlcmVuY2VdID0gcmVsYXRlZFt0LnJlZmVyZW5jZV0gfHwgW10pLnB1c2godC5pZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBOb3csIG1ha2UgdGhlIGFjdHVhbCBzb3J0aW5nLlxuICAgICAgICB3aGlsZSAoZnJlZUxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgaWQgPSBmcmVlTGlzdC5zaGlmdCgpLFxuICAgICAgICAgICAgICAgIHQgPSBsaXN0W21hcFtpZF1dO1xuXG4gICAgICAgICAgICBzb3J0ZWQucHVzaCh0KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gV2UgdXNlIHRoZSBmYWN0IHRoYXQgdGhlcmUgaXMgYSBzaW5nbGUgcHJlZGVjZXNzb3IgaW4gb3VyIHNldHVwLlxuICAgICAgICAgICAgaWYgKHJlbGF0ZWRbdC5pZF0pXG4gICAgICAgICAgICAgICAgZnJlZUxpc3QucHVzaCguLi5yZWxhdGVkW3QuaWRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzb3J0ZWQubGVuZ3RoIDwgbGlzdC5sZW5ndGgpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEEgcmVmZXJlbmNlIGN5Y2xlIGZvdW5kLCBpbnZvbHZpbmcgXCIke18ubWFwKF8ueG9yKGxpc3QsIHNvcnRlZCksICdpZCcpLmpvaW4oJywnKX1cIiFgKTtcblxuICAgICAgICByZXR1cm4gc29ydGVkO1xuICAgIH1cbiAgICBcbiAgICAvKipcbiAgICAgKiBTZWFyY2hlcyB0aGUgd2hvbGUgd29ya2Jvb2sgZm9yIHRlbXBsYXRlIHBhdHRlcm4gYW5kIGNvbnN0cnVjdHMgdGhlIHRlbXBsYXRlcyBmb3IgcHJvY2Vzc2luZy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYiBUaGUgY2FsbGJhY2sgdG8gYmUgaW52b2tlZCBvbiBlYWNoIHRlbXBsYXRlZCwgYWZ0ZXIgdGhleSBhcmUgc29ydGVkLlxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gICAgICogQGRlc2NyaXB0aW9uIFRoZSB0ZW1wbGF0ZXMgY29sbGVjdGVkIGFyZSBzb3J0ZWQsIGJhc2VkIG9uIHRoZSBpbnRyYS10ZW1wbGF0ZSByZWZlcmVuY2UgLSBpZiBvbmUgdGVtcGxhdGVcbiAgICAgKiBpcyByZWZlcnJpbmcgYW5vdGhlciBvbmUsIGl0J2xsIGFwcGVhciBfbGF0ZXJfIGluIHRoZSByZXR1cm5lZCBhcnJheSwgdGhhbiB0aGUgcmVmZXJyZWQgdGVtcGxhdGUuXG4gICAgICogVGhpcyBpcyB0aGUgb3JkZXIgdGhlIGNhbGxiYWNrIGlzIGJlaW5nIGludm9rZWQgb24uXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIGNvbGxlY3RUZW1wbGF0ZXMoY2IpIHtcbiAgICAgICAgY29uc3QgYWxsVGVtcGxhdGVzID0gW107XG4gICAgXG4gICAgICAgIHRoaXMuX2FjY2Vzcy5mb3JBbGxDZWxscyhjZWxsID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlID0gdGhpcy5wYXJzZVRlbXBsYXRlKGNlbGwpO1xuICAgICAgICAgICAgaWYgKHRlbXBsYXRlKVxuICAgICAgICAgICAgICAgIGFsbFRlbXBsYXRlcy5wdXNoKHRlbXBsYXRlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICByZXR1cm4gdGhpcy5zb3J0VGVtcGxhdGVzKGFsbFRlbXBsYXRlcykuZm9yRWFjaChjYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIHZhbHVlKHMpIGZyb20gdGhlIHByb3ZpZGVkIGRhdGEgYHJvb3RgIHRvIGJlIHNldCBpbiB0aGUgcHJvdmlkZWQgYGNlbGxgLlxuICAgICAqIEBwYXJhbSB7e319IHJvb3QgVGhlIGRhdGEgcm9vdCB0byBiZSBleHRyYWN0ZWQgdmFsdWVzIGZyb20uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV4dHJhY3RvciBUaGUgZXh0cmFjdGlvbiBzdHJpbmcgcHJvdmlkZWQgYnkgdGhlIHRlbXBsYXRlLiBVc3VhbGx5IGEgSlNPTiBwYXRoIHdpdGhpbiB0aGUgZGF0YSBgcm9vdGAuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIEEgcmVmZXJlbmNlIGNlbGwsIGlmIHN1Y2ggZXhpc3RzLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVtYmVyfERhdGV8QXJyYXl8QXJyYXkuPEFycmF5LjwqPj59IFRoZSB2YWx1ZSB0byBiZSB1c2VkLlxuICAgICAqIEBkZXNjcmlwdGlvbiBUaGlzIG1ldGhvZCBpcyB1c2VkIGV2ZW4gd2hlbiBhIHdob2xlIC0gcG9zc2libHkgcmVjdGFuZ3VsYXIgLSByYW5nZSBpcyBhYm91dCB0byBiZSBzZXQsIHNvIGl0IGNhblxuICAgICAqIHJldHVybiBhbiBhcnJheSBvZiBhcnJheXMuXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIGV4dHJhY3RWYWx1ZXMocm9vdCwgZXh0cmFjdG9yLCBjZWxsKSB7XG4gICAgICAgIGNvbnN0IHsgcGF0aCwgaGFuZGxlciB9ID0gdGhpcy5wYXJzZUV4dHJhY3RvcihleHRyYWN0b3IpO1xuXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShyb290KSlcbiAgICAgICAgICAgIHJvb3QgPSBfLmdldChyb290LCBwYXRoLCByb290KTtcbiAgICAgICAgZWxzZSBpZiAocm9vdC5zaXplcyAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgcm9vdCA9ICFleHRyYWN0b3IgPyByb290IDogXy5tYXAocm9vdCwgZW50cnkgPT4gdGhpcy5leHRyYWN0VmFsdWVzKGVudHJ5LCBleHRyYWN0b3IsIGNlbGwpKTtcbiAgICAgICAgZWxzZSBpZiAoIWhhbmRsZXIpXG4gICAgICAgICAgICByZXR1cm4gcm9vdC5qb2luKHRoaXMuX29wdHMuam9pblRleHQgfHwgXCIsXCIpO1xuXG4gICAgICAgIHJldHVybiAhaGFuZGxlciA/IHJvb3QgOiBoYW5kbGVyLmNhbGwodGhpcy5fb3B0cywgcm9vdCwgY2VsbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgYW4gYXJyYXkgKHBvc3NpYmx5IG9mIGFycmF5cykgd2l0aCBkYXRhIGZvciB0aGUgZ2l2ZW4gZmlsbCwgYmFzZWQgb24gdGhlIGdpdmVuXG4gICAgICogcm9vdCBvYmplY3QuXG4gICAgICogQHBhcmFtIHt7fX0gcm9vdCBUaGUgbWFpbiByZWZlcmVuY2Ugb2JqZWN0IHRvIGFwcGx5IGl0ZXJhdG9ycyB0by5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBpdGVyYXRvcnMgTGlzdCBvZiBpdGVyYXRvcnMgLSBzdHJpbmcgSlNPTiBwYXRocyBpbnNpZGUgdGhlIHJvb3Qgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpZHggVGhlIGluZGV4IGluIHRoZSBpdGVyYXRvcnMgYXJyYXkgdG8gd29yayBvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8QXJyYXkuPEFycmF5Pn0gQW4gYXJyYXkgKHBvc3NpYmx5IG9mIGFycmF5cykgd2l0aCBleHRyYWN0ZWQgZGF0YS5cbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgZXh0cmFjdERhdGEocm9vdCwgaXRlcmF0b3JzLCBpZHgpIHtcbiAgICAgICAgbGV0IGl0ZXIgPSBpdGVyYXRvcnNbaWR4XSxcbiAgICAgICAgICAgIHNpemVzID0gW10sXG4gICAgICAgICAgICB0cmFuc3Bvc2VkID0gZmFsc2UsXG4gICAgICAgICAgICBkYXRhID0gbnVsbDtcblxuICAgICAgICBpZiAoaXRlciA9PSAnMScpIHtcbiAgICAgICAgICAgIHRyYW5zcG9zZWQgPSB0cnVlO1xuICAgICAgICAgICAgaXRlciA9IGl0ZXJhdG9yc1srK2lkeF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWl0ZXIpIHJldHVybiByb290O1xuXG4gICAgICAgIC8vIEEgc3BlY2lmaWMgZXh0cmFjdG9yIGNhbiBiZSBzcGVjaWZpZWQgYWZ0ZXIgc2VtaWxvbiAtIGZpbmQgYW5kIHJlbWVtYmVyIGl0LlxuICAgICAgICBjb25zdCBwYXJzZWRJdGVyID0gdGhpcy5wYXJzZUV4dHJhY3RvcihpdGVyKTtcblxuICAgICAgICBkYXRhID0gXy5nZXQocm9vdCwgcGFyc2VkSXRlci5wYXRoLCByb290KTtcbiAgICAgICAgXG4gICAgICAgIGlmICh0eXBlb2YgcGFyc2VkSXRlci5oYW5kbGVyID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgICAgZGF0YSA9IHBhcnNlZEl0ZXIuaGFuZGxlci5jYWxsKHRoaXMuX29wdHMsIGRhdGEpO1xuXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShkYXRhKSAmJiB0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgZWxzZSBpZiAoaWR4IDwgaXRlcmF0b3JzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIGRhdGEgPSBfLm1hcChkYXRhLCBpblJvb3QgPT4gdGhpcy5leHRyYWN0RGF0YShpblJvb3QsIGl0ZXJhdG9ycywgaWR4ICsgMSkpO1xuICAgICAgICAgICAgc2l6ZXMgPSBkYXRhWzBdLnNpemVzIHx8IFtdO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBkYXRhID0gXy52YWx1ZXMoZGF0YSk7XG5cbiAgICAgICAgLy8gU29tZSBkYXRhIHNhbml0eSBjaGVja3MuXG4gICAgICAgIGlmICghZGF0YSlcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGl0ZXJhdG9yICcke2l0ZXJ9JyBleHRyYWN0ZWQgbm8gZGF0YSFgKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRhdGEgIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgZGF0YSBleHRyYWN0ZWQgZnJvbSBpdGVyYXRvciAnJHtpdGVyfScgaXMgbmVpdGhlciBhbiBhcnJheSwgbm9yIG9iamVjdCFgKTtcblxuICAgICAgICBzaXplcy51bnNoaWZ0KHRyYW5zcG9zZWQgPyAtZGF0YS5sZW5ndGggOiBkYXRhLmxlbmd0aCk7XG4gICAgICAgIGRhdGEuc2l6ZXMgPSBzaXplcztcbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHV0IHRoZSBkYXRhIHZhbHVlcyBpbnRvIHRoZSBwcm9wZXIgY2VsbHMsIHdpdGggY29ycmVjdCBleHRyYWN0ZWQgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7e319IGNlbGwgVGhlIHN0YXJ0aW5nIGNlbGwgZm9yIHRoZSBkYXRhIHRvIGJlIHB1dC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBkYXRhIFRoZSBhY3R1YWwgZGF0YSB0byBiZSBwdXQuIFRoZSB2YWx1ZXMgd2lsbCBiZSBfZXh0cmFjdGVkXyBmcm9tIGhlcmUgZmlyc3QuXG4gICAgICogQHBhcmFtIHt7fX0gdGVtcGxhdGUgVGhlIHRlbXBsYXRlIHRoYXQgaXMgYmVpbmcgaW1wbGVtZW50ZWQgd2l0aCB0aGF0IGRhdGEgZmlsbC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IE1hdHJpeCBzaXplIHRoYXQgdGhpcyBkYXRhIGhhcyBvY2N1cGllZCBvbiB0aGUgc2hlZXQgW3Jvd3MsIGNvbHNdLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBwdXRWYWx1ZXMoY2VsbCwgZGF0YSwgdGVtcGxhdGUpIHtcbiAgICAgICAgaWYgKCFjZWxsKSB0aHJvdyBuZXcgRXJyb3IoXCJDcmFzaCEgTnVsbCByZWZlcmVuY2UgY2VsbCBpbiAncHV0VmFsdWVzKCknIVwiKTtcblxuICAgICAgICBsZXQgZW50cnlTaXplID0gZGF0YS5zaXplcyxcbiAgICAgICAgICAgIHZhbHVlID0gdGhpcy5leHRyYWN0VmFsdWVzKGRhdGEsIHRlbXBsYXRlLmV4dHJhY3RvciwgY2VsbCk7XG5cbiAgICAgICAgLy8gaWYgd2UndmUgY29tZSB1cCB3aXRoIGEgcmF3IGRhdGFcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSB8fCAhZW50cnlTaXplIHx8ICFlbnRyeVNpemUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3Muc2V0Q2VsbFZhbHVlKGNlbGwsIHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuYXBwbHlEYXRhU3R5bGUoY2VsbCwgZGF0YSwgdGVtcGxhdGUpO1xuICAgICAgICAgICAgZW50cnlTaXplID0gdGVtcGxhdGUuY2VsbFNpemU7XG4gICAgICAgIH0gZWxzZSBpZiAoZW50cnlTaXplLmxlbmd0aCA8PSAyKSB7XG4gICAgICAgICAgICAvLyBOb3JtYWxpemUgdGhlIHNpemUgYW5kIGRhdGEuXG4gICAgICAgICAgICBpZiAoZW50cnlTaXplWzBdIDwgMCkge1xuICAgICAgICAgICAgICAgIGVudHJ5U2l6ZSA9IFsxLCAtZW50cnlTaXplWzBdXTtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IFt2YWx1ZV07XG4gICAgICAgICAgICAgICAgZGF0YSA9IFtkYXRhXTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZW50cnlTaXplLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgICAgICAgICAgZW50cnlTaXplID0gZW50cnlTaXplLmNvbmNhdChbMV0pO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gXy5jaHVuayh2YWx1ZSwgMSk7XG4gICAgICAgICAgICAgICAgZGF0YSA9IF8uY2h1bmsoZGF0YSwgMSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX2FjY2Vzcy5nZXRDZWxsUmFuZ2UoY2VsbCwgZW50cnlTaXplWzBdIC0gMSwgZW50cnlTaXplWzFdIC0gMSkuZm9yRWFjaCgoY2VsbCwgcmksIGNpKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWNjZXNzLnNldENlbGxWYWx1ZShjZWxsLCB2YWx1ZVtyaV1bY2ldKTtcbiAgICAgICAgICAgICAgICB0aGlzLmFwcGx5RGF0YVN0eWxlKGNlbGwsIGRhdGFbcmldW2NpXSwgdGVtcGxhdGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBWYWx1ZXMgZXh0cmFjdGVkIHdpdGggJyR7dGVtcGxhdGUuZXh0cmFjdG9yfScgYXJlIG1vcmUgdGhhbiAyIGRpbWVuc2lvbiEnYCk7XG5cbiAgICAgICAgcmV0dXJuIGVudHJ5U2l6ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBseSB0aGUgZ2l2ZW4gZmlsdGVyIG9udG8gdGhlIHNoZWV0IC0gZXh0cmFjdGluZyB0aGUgcHJvcGVyIGRhdGEsIGZvbGxvd2luZyBkZXBlbmRlbnQgZmlsbHMsIGV0Yy5cbiAgICAgKiBAcGFyYW0ge3t9fSBhRmlsbCBUaGUgZmlsbCB0byBiZSBhcHBsaWVkLCBhcyBjb25zdHJ1Y3RlZCBpbiB0aGUge0BsaW5rIGZpbGxEYXRhfSBtZXRob2QuXG4gICAgICogQHBhcmFtIHt7fX0gcm9vdCBUaGUgZGF0YSByb290IHRvIGJlIHVzZWQgZm9yIGRhdGEgZXh0cmFjdGlvbi5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IG1haW5DZWxsIFRoZSBzdGFydGluZyBjZWxsIGZvciBkYXRhIHBsYWNlbWVudCBwcm9jZWR1cmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBUaGUgc2l6ZSBvZiB0aGUgZGF0YSBwdXQgaW4gW3JvdywgY29sXSBmb3JtYXQuXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIGFwcGx5RmlsbChhRmlsbCwgcm9vdCwgbWFpbkNlbGwpIHtcbiAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBhRmlsbC50ZW1wbGF0ZSxcbiAgICAgICAgICAgIHRoZURhdGEgPSB0aGlzLmV4dHJhY3REYXRhKHJvb3QsIHRlbXBsYXRlLml0ZXJhdG9ycywgMCk7XG5cbiAgICAgICAgbGV0IGVudHJ5U2l6ZSA9IFsxLCAxXTtcblxuICAgICAgICBpZiAoIWFGaWxsLmRlcGVuZGVudHMgfHwgIWFGaWxsLmRlcGVuZGVudHMubGVuZ3RoKVxuICAgICAgICAgICAgZW50cnlTaXplID0gdGhpcy5wdXRWYWx1ZXMobWFpbkNlbGwsIHRoZURhdGEsIHRlbXBsYXRlKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgbmV4dENlbGwgPSBtYWluQ2VsbDtcbiAgICAgICAgICAgIGNvbnN0IHNpemVNYXh4ZXIgPSAodmFsLCBpZHgpID0+IGVudHJ5U2l6ZVtpZHhdID0gTWF0aC5tYXgoZW50cnlTaXplW2lkeF0sIHZhbCk7XG5cbiAgICAgICAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgdGhlRGF0YS5sZW5ndGg7ICsrZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluUm9vdCA9IHRoZURhdGFbZF07XG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBmID0gMDsgZiA8IGFGaWxsLmRlcGVuZGVudHMubGVuZ3RoOyArK2YpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5GaWxsID0gYUZpbGwuZGVwZW5kZW50c1tmXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluQ2VsbCA9IHRoaXMuX2FjY2Vzcy5vZmZzZXRDZWxsKG5leHRDZWxsLCBpbkZpbGwub2Zmc2V0WzBdLCBpbkZpbGwub2Zmc2V0WzFdKTtcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIF8uZm9yRWFjaCh0aGlzLmFwcGx5RmlsbChpbkZpbGwsIGluUm9vdCwgaW5DZWxsKSwgc2l6ZU1heHhlcik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gTm93IHdlIGhhdmUgdGhlIGlubmVyIGRhdGEgcHV0IGFuZCB0aGUgc2l6ZSBjYWxjdWxhdGVkLlxuICAgICAgICAgICAgICAgIF8uZm9yRWFjaCh0aGlzLnB1dFZhbHVlcyhuZXh0Q2VsbCwgaW5Sb290LCB0ZW1wbGF0ZSksIHNpemVNYXh4ZXIpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHJvd09mZnNldCA9IGVudHJ5U2l6ZVswXSxcbiAgICAgICAgICAgICAgICAgICAgY29sT2Zmc2V0ID0gZW50cnlTaXplWzFdLFxuICAgICAgICAgICAgICAgICAgICByb3dQYWRkaW5nID0gdGVtcGxhdGUucGFkZGluZ1swXSB8fCAwLFxuICAgICAgICAgICAgICAgICAgICBjb2xQYWRkaW5nID0gdGVtcGxhdGUucGFkZGluZ1sxXSB8fCAwO1xuXG4gICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHdlIGdyb3cgb25seSBvbiBvbmUgZGltZW5zaW9uLlxuICAgICAgICAgICAgICAgIGlmICh0aGVEYXRhLnNpemVzWzBdIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGVtcGxhdGUucGFkZGluZy5sZW5ndGggPCAyKVxuICAgICAgICAgICAgICAgICAgICAgICAgY29sUGFkZGluZyA9IHJvd1BhZGRpbmc7XG4gICAgICAgICAgICAgICAgICAgIHJvd09mZnNldCA9IHJvd1BhZGRpbmcgPSAwO1xuICAgICAgICAgICAgICAgICAgICBlbnRyeVNpemVbMV0gPSAxO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhlRGF0YS5zaXplcy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbE9mZnNldCA9IGNvbFBhZGRpbmcgPSAwO1xuICAgICAgICAgICAgICAgICAgICBlbnRyeVNpemVbMF0gPSAxO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChyb3dPZmZzZXQgPiAxIHx8IGNvbE9mZnNldCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgcm5nID0gdGhpcy5fYWNjZXNzLmdldENlbGxSYW5nZShuZXh0Q2VsbCwgTWF0aC5tYXgocm93T2Zmc2V0IC0gMSwgMCksIE1hdGgubWF4KGNvbE9mZnNldCAtIDEsIDApKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIF9vcHRzID0gdGhpcy5nZXRUZW1wbGF0ZU9wdHModGVtcGxhdGUpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChfb3B0cy5tZXJnZUNlbGxzID09PSB0cnVlIHx8IF9vcHRzLm1lcmdlQ2VsbCA9PT0gJ2JvdGgnXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCByb3dPZmZzZXQgPiAxICYmIF9vcHRzLm1lcmdlQ2VsbHMgPT09ICd2ZXJ0aWNhbCcgXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCBjb2xPZmZzZXQgPiAxICYmIF9vcHRzLm1lcmdlQ2VsbHMgPT09ICdob3Jpem9udGFsJylcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FjY2Vzcy5yYW5nZU1lcmdlZChybmcsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChfb3B0cy5kdXBsaWNhdGVDZWxscyA9PT0gdHJ1ZSB8fCBfb3B0cy5kdXBsaWNhdGVDZWxscyA9PT0gJ2JvdGgnXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCByb3dPZmZzZXQgPiAxICYmIF9vcHRzLmR1cGxpY2F0ZUNlbGxzID09PSAndmVydGljYWwnIFxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgY29sT2Zmc2V0ID4gMSAmJiBfb3B0cy5kdXBsaWNhdGVDZWxscyA9PT0gJ2hvcml6b250YWwnKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWNjZXNzLmR1cGxpY2F0ZUNlbGwobmV4dENlbGwsIHJuZyk7XG5cbiAgICAgICAgICAgICAgICAgICAgcm5nLmZvckVhY2goY2VsbCA9PiB0aGlzLmFwcGx5RGF0YVN0eWxlKGNlbGwsIGluUm9vdCwgdGVtcGxhdGUpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBGaW5hbGx5LCBjYWxjdWxhdGUgdGhlIG5leHQgY2VsbC5cbiAgICAgICAgICAgICAgICBuZXh0Q2VsbCA9IHRoaXMuX2FjY2Vzcy5vZmZzZXRDZWxsKG5leHRDZWxsLCByb3dPZmZzZXQgKyByb3dQYWRkaW5nLCBjb2xPZmZzZXQgKyBjb2xQYWRkaW5nKTtcdFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBOb3cgcmVjYWxjIGNvbWJpbmVkIGVudHJ5IHNpemUuXG4gICAgICAgICAgICBfLmZvckVhY2godGhpcy5fYWNjZXNzLmNlbGxEaXN0YW5jZShtYWluQ2VsbCwgbmV4dENlbGwpLCBzaXplTWF4eGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIF8uZm9yRWFjaChhRmlsbC5mb3JtdWxhcywgZiA9PiB0aGlzLmFwcGx5Rm9ybXVsYShmLCBlbnRyeVNpemUsIG1haW5DZWxsKSk7XG5cbiAgICAgICAgYUZpbGwucHJvY2Vzc2VkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGVudHJ5U2l6ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm9jZXNzIGEgZm9ybXVsYSBiZSBzaGlmdGluZyBhbGwgdGhlIGZpeGVkIG9mZnNldC5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZm9ybXVsYSBUaGUgZm9ybXVsYSB0byBiZSBzaGlmdGVkLlxuICAgICAqIEBwYXJhbSB7QXJyYXk8TnVtYmVyLE51bWJlcj59IG9mZnNldCBUaGUgb2Zmc2V0IG9mIHRoZSByZWZlcmVuY2VkIHRlbXBsYXRlIHRvIHRoZSBmb3JtdWxhIG9uZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5PE51bWJlcixOdW1iZXI+fSBzaXplIFRoZSBzaXplIG9mIHRoZSByYW5nZXMgYXMgdGhleSBzaG91bGQgYmUuXG4gICAgICogQHJldHVybnMge1N0cmluZ30gVGhlIHByb2Nlc3NlZCB0ZXh0LlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBzaGlmdEZvcm11bGEoZm9ybXVsYSwgb2Zmc2V0LCBzaXplKSB7XG4gICAgICAgIGxldCBuZXdGb3JtdWxhID0gJyc7XG5cbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgY29uc3QgbWF0Y2ggPSBmb3JtdWxhLm1hdGNoKHJlZlJlZ0V4cCk7XG4gICAgICAgICAgICBpZiAoIW1hdGNoKSBicmVhaztcblxuICAgICAgICAgICAgbGV0IGZyb20gPSB0aGlzLl9hY2Nlc3MuZ2V0Q2VsbChtYXRjaFszXSwgbWF0Y2hbMl0pLFxuICAgICAgICAgICAgICAgIG5ld1JlZiA9IG51bGw7XG5cbiAgICAgICAgICAgIGlmIChvZmZzZXRbMF0gPiAwIHx8IG9mZnNldFsxXSA+IDApXG4gICAgICAgICAgICAgICAgZnJvbSA9IHRoaXMuX2FjY2Vzcy5vZmZzZXRDZWxsKGZyb20sIG9mZnNldFswXSwgb2Zmc2V0WzFdKTtcblxuICAgICAgICAgICAgbmV3UmVmID0gIW1hdGNoWzVdXG4gICAgICAgICAgICAgICAgPyB0aGlzLl9hY2Nlc3MuY2VsbFJlZihmcm9tLCAhIW1hdGNoWzJdKVxuICAgICAgICAgICAgICAgIDogdGhpcy5fYWNjZXNzLnJhbmdlUmVmKHRoaXMuX2FjY2Vzcy5nZXRDZWxsUmFuZ2UoZnJvbSwgc2l6ZVswXSwgc2l6ZVsxXSksICEhbWF0Y2hbMl0pO1xuXG4gICAgICAgICAgICBuZXdGb3JtdWxhICs9IGZvcm11bGEuc3Vic3RyKDAsIG1hdGNoLmluZGV4KSArIG5ld1JlZjtcbiAgICAgICAgICAgIGZvcm11bGEgPSBmb3JtdWxhLnN1YnN0cihtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCk7XG4gICAgICAgIH1cblxuICAgICAgICBuZXdGb3JtdWxhICs9IGZvcm11bGE7XG4gICAgICAgIHJldHVybiBuZXdGb3JtdWxhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFwcGx5IHRoZSBnaXZlbiBmb3JtdWxhIGluIHRoZSBzaGVldCwgaS5lLiBjaGFuZ2luZyBpdCB0byBtYXRjaCB0aGUgXG4gICAgICogc2l6ZXMgb2YgdGhlIHJlZmVyZW5jZXMgdGVtcGxhdGVzLlxuICAgICAqIEBwYXJhbSB7e319IGFGaWxsIFRoZSBmaWxsIHRvIGJlIGFwcGxpZWQsIGFzIGNvbnN0cnVjdGVkIGluIHRoZSB7QGxpbmsgZmlsbERhdGF9IG1ldGhvZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5PE51bWJlcj59IGVudHJ5U2l6ZSBUaGUgZmlsbC10by1zaXplIG1hcCwgYXMgY29uc3RydWN0ZWQgc28gZmFyXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIFRoZSBjZWxsIHRvIHB1dC9zdGFydCB0aGlzIGZvcm11bGEgaW50b1xuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIGFwcGx5Rm9ybXVsYShhRmlsbCwgZW50cnlTaXplLCBjZWxsKSB7XG4gICAgICAgIGNlbGwgPSB0aGlzLl9hY2Nlc3Mub2Zmc2V0Q2VsbChjZWxsLCBhRmlsbC5vZmZzZXRbMF0sIGFGaWxsLm9mZnNldFsxXSk7XG5cbiAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBhRmlsbC50ZW1wbGF0ZSxcbiAgICAgICAgICAgIGl0ZXIgPSBfLnRyaW0odGVtcGxhdGUuaXRlcmF0b3JzWzBdKSxcbiAgICAgICAgICAgIG9mZnNldCA9IHRoaXMuX2FjY2Vzcy5jZWxsRGlzdGFuY2UodGVtcGxhdGUuY2VsbCwgY2VsbCk7XG4gICAgICAgICAgICBcbiAgICAgICAgbGV0IGZvcm11bGEgPSB0ZW1wbGF0ZS5leHRyYWN0b3IsIFxuICAgICAgICAgICAgcm5nO1xuICAgICAgICAgICAgXG4gICAgICAgIGFGaWxsLnByb2Nlc3NlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuX2FjY2Vzcy5zZXRDZWxsVmFsdWUoY2VsbCwgbnVsbCk7XG5cbiAgICAgICAgaWYgKGVudHJ5U2l6ZVswXSA8IDIgJiYgZW50cnlTaXplWzFdIDwgMiB8fCBpdGVyID09PSAnYm90aCcpIHtcbiAgICAgICAgICAgIGZvcm11bGEgPSB0aGlzLnNoaWZ0Rm9ybXVsYShmb3JtdWxhLCBvZmZzZXQsIFswLCAwXSk7XG4gICAgICAgICAgICBybmcgPSB0aGlzLl9hY2Nlc3MuZ2V0Q2VsbFJhbmdlKGNlbGwsIGVudHJ5U2l6ZVswXSAtIDEsIGVudHJ5U2l6ZVsxXSAtIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGl0ZXIgPT09ICdjb2xzJykge1xuICAgICAgICAgICAgZm9ybXVsYSA9IHRoaXMuc2hpZnRGb3JtdWxhKGZvcm11bGEsIG9mZnNldCwgW2VudHJ5U2l6ZVswXSAtIDEsIDBdKTtcbiAgICAgICAgICAgIHJuZyA9IHRoaXMuX2FjY2Vzcy5nZXRDZWxsUmFuZ2UoY2VsbCwgMCwgZW50cnlTaXplWzFdIC0gMSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXRlciA9PT0gJ3Jvd3MnKSB7XG4gICAgICAgICAgICBmb3JtdWxhID0gdGhpcy5zaGlmdEZvcm11bGEoZm9ybXVsYSwgb2Zmc2V0LCBbMCwgZW50cnlTaXplWzFdIC0gMV0pO1xuICAgICAgICAgICAgcm5nID0gdGhpcy5fYWNjZXNzLmdldENlbGxSYW5nZShjZWxsLCBlbnRyeVNpemVbMF0gLSAxLCAwKTtcbiAgICAgICAgfSBlbHNlIHsgLy8gaS5lLiAnbm9uZSdcbiAgICAgICAgICAgIHRoaXMuX2FjY2Vzcy5zZXRDZWxsRm9ybXVsYShjZWxsLCB0aGlzLnNoaWZ0Rm9ybXVsYShmb3JtdWxhLCBvZmZzZXQsIFtlbnRyeVNpemVbMF0gLSAxLCBlbnRyeVNpemVbMV0gLSAxXSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fYWNjZXNzLnNldFJhbmdlRm9ybXVsYShybmcsIGZvcm11bGEpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGUgYnVpbHQtaW4gYWNjZXNzb3IgYmFzZWQgb24geGxzeC1wb3B1bGF0ZSBucG0gbW9kdWxlXG4gKiBAdHlwZSB7WGxzeFBvcHVsYXRlQWNjZXNzfVxuICovXG5YbHN4RGF0YUZpbGwuWGxzeFBvcHVsYXRlQWNjZXNzID0gcmVxdWlyZSgnLi9YbHN4UG9wdWxhdGVBY2Nlc3MnKTtcblhsc3hEYXRhRmlsbC52ZXJzaW9uID0gXCJ7e1ZFUlNJT059fVwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFhsc3hEYXRhRmlsbDtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG5jb25zdCBfID0gcmVxdWlyZSgnbG9kYXNoJyk7XG5cbi8vIGNvbnN0IGFsbFN0eWxlcyA9IFtcbi8vICAgICBcImJvbGRcIiwgXG4vLyAgICAgXCJpdGFsaWNcIiwgXG4vLyAgICAgXCJ1bmRlcmxpbmVcIiwgXG4vLyAgICAgXCJzdHJpa2V0aHJvdWdoXCIsIFxuLy8gICAgIFwic3Vic2NyaXB0XCIsIFxuLy8gICAgIFwic3VwZXJzY3JpcHRcIiwgXG4vLyAgICAgXCJmb250U2l6ZVwiLCBcbi8vICAgICBcImZvbnRGYW1pbHlcIiwgXG4vLyAgICAgXCJmb250R2VuZXJpY0ZhbWlseVwiLCBcbi8vICAgICBcImZvbnRTY2hlbWVcIiwgXG4vLyAgICAgXCJmb250Q29sb3JcIiwgXG4vLyAgICAgXCJob3Jpem9udGFsQWxpZ25tZW50XCIsIFxuLy8gICAgIFwianVzdGlmeUxhc3RMaW5lXCIsIFxuLy8gICAgIFwiaW5kZW50XCIsIFxuLy8gICAgIFwidmVydGljYWxBbGlnbm1lbnRcIiwgXG4vLyAgICAgXCJ3cmFwVGV4dFwiLCBcbi8vICAgICBcInNocmlua1RvRml0XCIsIFxuLy8gICAgIFwidGV4dERpcmVjdGlvblwiLCBcbi8vICAgICBcInRleHRSb3RhdGlvblwiLCBcbi8vICAgICBcImFuZ2xlVGV4dENvdW50ZXJjbG9ja3dpc2VcIiwgXG4vLyAgICAgXCJhbmdsZVRleHRDbG9ja3dpc2VcIiwgXG4vLyAgICAgXCJyb3RhdGVUZXh0VXBcIiwgXG4vLyAgICAgXCJyb3RhdGVUZXh0RG93blwiLCBcbi8vICAgICBcInZlcnRpY2FsVGV4dFwiLCBcbi8vICAgICBcImZpbGxcIiwgXG4vLyAgICAgXCJib3JkZXJcIiwgXG4vLyAgICAgXCJib3JkZXJDb2xvclwiLCBcbi8vICAgICBcImJvcmRlclN0eWxlXCIsIFxuLy8gICAgIFwibGVmdEJvcmRlclwiLCBcInJpZ2h0Qm9yZGVyXCIsIFwidG9wQm9yZGVyXCIsIFwiYm90dG9tQm9yZGVyXCIsIFwiZGlhZ29uYWxCb3JkZXJcIiwgXG4vLyAgICAgXCJsZWZ0Qm9yZGVyQ29sb3JcIiwgXCJyaWdodEJvcmRlckNvbG9yXCIsIFwidG9wQm9yZGVyQ29sb3JcIiwgXCJib3R0b21Cb3JkZXJDb2xvclwiLCBcImRpYWdvbmFsQm9yZGVyQ29sb3JcIiwgXG4vLyAgICAgXCJsZWZ0Qm9yZGVyU3R5bGVcIiwgXCJyaWdodEJvcmRlclN0eWxlXCIsIFwidG9wQm9yZGVyU3R5bGVcIiwgXCJib3R0b21Cb3JkZXJTdHlsZVwiLCBcImRpYWdvbmFsQm9yZGVyU3R5bGVcIiwgXG4vLyAgICAgXCJkaWFnb25hbEJvcmRlckRpcmVjdGlvblwiLCBcbi8vICAgICBcIm51bWJlckZvcm1hdFwiXG4vLyBdO1xuXG5sZXQgX1JpY2hUZXh0ID0gbnVsbDtcblxuLyoqXG4gKiBgeHNseC1wb3B1bGF0ZWAgbGlicmFyeSBiYXNlZCBhY2Nlc3NvciB0byBhIGdpdmVuIEV4Y2VsIHdvcmtib29rLiBBbGwgdGhlc2UgbWV0aG9kcyBhcmUgaW50ZXJuYWxseSB1c2VkIGJ5IHtAbGluayBYbHN4RGF0YUZpbGx9LCBcbiAqIGJ1dCBjYW4gYmUgdXNlZCBhcyBhIHJlZmVyZW5jZSBmb3IgaW1wbGVtZW50aW5nIGN1c3RvbSBzcHJlYWRzaGVldCBhY2Nlc3NvcnMuXG4gKi9cbmNsYXNzIFhsc3hQb3B1bGF0ZUFjY2VzcyB7XG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiBYbHN4U21hcnRUZW1wbGF0ZSB3aXRoIGdpdmVuIG9wdGlvbnMuXG4gICAgICogQHBhcmFtIHtXb3JrYm9va30gd29ya2Jvb2sgLSBUaGUgd29ya2Jvb2sgdG8gYmUgYWNjZXNzZWQuXG4gICAgICogQHBhcmFtIHtYbHN4UG9wdWxhdGV9IFhsc3hQb3B1bGF0ZSAtIFRoZSBhY3R1YWwgeGxzeC1wb3B1bGF0ZSBsaWJyYXJ5IG9iamVjdC5cbiAgICAgKiBAZGVzY3JpcHRpb24gVGhlIGBYbHN4UG9wdWxhdGVgIG9iamVjdCBuZWVkIHRvIGJlIHBhc3NlZCBpbiBvcmRlciB0byBleHRyYWN0XG4gICAgICogY2VydGFpbiBpbmZvcm1hdGlvbiBmcm9tIGl0LCBfd2l0aG91dF8gcmVmZXJyaW5nIHRoZSB3aG9sZSBsaWJyYXJ5LCB0aHVzXG4gICAgICogYXZvaWRpbmcgbWFraW5nIHRoZSBgeGxzeC1kYXRhZmlsbGAgcGFja2FnZSBhIGRlcGVuZGVuY3kuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod29ya2Jvb2ssIFhsc3hQb3B1bGF0ZSkge1xuICAgICAgICB0aGlzLl93b3JrYm9vayA9IHdvcmtib29rO1xuICAgICAgICB0aGlzLl9yb3dTaXplcyA9IHt9O1xuICAgICAgICB0aGlzLl9jb2xTaXplcyA9IHt9O1xuICAgIFxuICAgICAgICBfUmljaFRleHQgPSBYbHN4UG9wdWxhdGUuUmljaFRleHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY29uZmlndXJlZCB3b3JrYm9vayBmb3IgZGlyZWN0IFhsc3hQb3B1bGF0ZSBtYW5pcHVsYXRpb24uXG4gICAgICogQHJldHVybnMge1dvcmtib29rfSBUaGUgd29ya2Jvb2sgaW52b2x2ZWQuXG4gICAgICovXG4gICAgd29ya2Jvb2soKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93b3JrYm9vazsgXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2VsbCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgLSBUaGUgY2VsbCB0byByZXRyaWV2ZSB0aGUgdmFsdWUgZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiBjZWxsJ3MgY29udGVudHMuXG4gICAgICovXG4gICAgY2VsbFZhbHVlKGNlbGwpIHtcbiAgICAgICAgY29uc3QgdGhlVmFsdWUgPSBjZWxsLnZhbHVlKCk7XG4gICAgICAgIHJldHVybiB0aGVWYWx1ZSBpbnN0YW5jZW9mIF9SaWNoVGV4dCA/IHRoZVZhbHVlLnRleHQoKSA6IHRoZVZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGNlbGwgdmFsdWUuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIC0gVGhlIGNlbGwgdG8gcmV0cmlldmUgdGhlIHZhbHVlIGZyb20uXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSAtIFRoZSByZXF1ZXN0ZWQgdmFsdWUgZm9yIHNldHRpbmcuXG4gICAgICogQHJldHVybnMge1hsc3hQb3B1bGF0ZUFjY2Vzc30gRWl0aGVyIHRoZSByZXF1ZXN0ZWQgdmFsdWUgb3IgY2hhaW5hYmxlIHRoaXMuXG4gICAgICovXG4gICAgc2V0Q2VsbFZhbHVlKGNlbGwsIHZhbHVlKSB7XG4gICAgICAgIGNlbGwudmFsdWUodmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjZWxsIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Q2VsbH0gY2VsbCAtIFRoZSBjZWxsIHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSB0eXBlIG9mIHRoZSBjZWxsIC0gJ2Zvcm11bGEnLCAncmljaHRleHQnLCBcbiAgICAgKiAndGV4dCcsICdudW1iZXInLCAnZGF0ZScsICdoeXBlcmxpbmsnLCBvciAndW5rbm93bic7XG4gICAgICovXG4gICAgY2VsbFR5cGUoY2VsbCkge1xuICAgICAgICBpZiAoY2VsbC5mb3JtdWxhKCkpXG4gICAgICAgICAgICByZXR1cm4gJ2Zvcm11bGEnO1xuICAgICAgICBlbHNlIGlmIChjZWxsLmh5cGVybGluaygpKVxuICAgICAgICAgICAgcmV0dXJuICdoeXBlcmxpbmsnO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgdGhlVmFsdWUgPSBjZWxsLnZhbHVlKCk7XG4gICAgICAgIGlmICh0aGVWYWx1ZSBpbnN0YW5jZW9mIF9SaWNoVGV4dClcbiAgICAgICAgICAgIHJldHVybiAncmljaHRleHQnO1xuICAgICAgICBlbHNlIGlmICh0aGVWYWx1ZSBpbnN0YW5jZW9mIERhdGUpXG4gICAgICAgICAgICByZXR1cm4gJ2RhdGUnO1xuICAgICAgICBlbHNlIFxuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB0aGVWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBmb3JtdWxhIGluIHRoZSBjZWxsXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIC0gVGhlIGNlbGwgdG8gcmV0cmlldmUgdGhlIHZhbHVlIGZyb20uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZvcm11bGEgLSB0aGUgdGV4dCBvZiB0aGUgZm9ybXVsYSB0byBiZSBzZXQuXG4gICAgICogQHJldHVybnMge1hsc3hQb3B1bGF0ZUFjY2Vzc30gRm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHNldENlbGxGb3JtdWxhKGNlbGwsIGZvcm11bGEpIHtcbiAgICAgICAgY2VsbC5mb3JtdWxhKF8udHJpbVN0YXJ0KGZvcm11bGEsICcgPScpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWVhc3VyZXMgdGhlIGRpc3RhbmNlLCBhcyBhIHZlY3RvciBiZXR3ZWVuIHR3byBnaXZlbiBjZWxscy5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGZyb20gVGhlIGZpcnN0IGNlbGwuXG4gICAgICogQHBhcmFtIHtDZWxsfSB0byBUaGUgc2Vjb25kIGNlbGwuXG4gICAgICogQHJldHVybnMge0FycmF5LjxOdW1iZXI+fSBBbiBhcnJheSB3aXRoIHR3byB2YWx1ZXMgWzxyb3dzPiwgPGNvbHM+XSwgcmVwcmVzZW50aW5nIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSB0d28gY2VsbHMuXG4gICAgICovXG4gICAgY2VsbERpc3RhbmNlKGZyb20sIHRvKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICB0by5yb3dOdW1iZXIoKSAtIGZyb20ucm93TnVtYmVyKCksXG4gICAgICAgICAgICB0by5jb2x1bW5OdW1iZXIoKSAtIGZyb20uY29sdW1uTnVtYmVyKClcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmVzIHRoZSBzaXplIG9mIGNlbGwsIHRha2luZyBpbnRvIGFjY291bnQgaWYgaXQgaXMgcGFydCBvZiBhIG1lcmdlZCByYW5nZS5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgVGhlIGNlbGwgdG8gYmUgaW52ZXN0aWdhdGVkLlxuICAgICAqIEByZXR1cm5zIHtBcnJheS48TnVtYmVyPn0gQW4gYXJyYXkgd2l0aCB0d28gdmFsdWVzIFs8cm93cz4sIDxjb2xzPl0sIHJlcHJlc2VudGluZyB0aGUgb2NjdXBpZWQgc2l6ZS5cbiAgICAgKi9cbiAgICBjZWxsU2l6ZShjZWxsKSB7XG4gICAgICAgIGNvbnN0IGNlbGxBZGRyID0gY2VsbC5hZGRyZXNzKCk7XG4gICAgICAgIGxldCB0aGVTaXplID0gWzEsIDFdO1xuICAgIFxuICAgICAgICBfLmZvckVhY2goY2VsbC5zaGVldCgpLl9tZXJnZUNlbGxzLCByYW5nZSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYW5nZUFkZHIgPSByYW5nZS5hdHRyaWJ1dGVzLnJlZi5zcGxpdChcIjpcIik7XG4gICAgICAgICAgICBpZiAocmFuZ2VBZGRyWzBdID09IGNlbGxBZGRyKSB7XG4gICAgICAgICAgICAgICAgdGhlU2l6ZSA9IHRoaXMuY2VsbERpc3RhbmNlKGNlbGwsIGNlbGwuc2hlZXQoKS5jZWxsKHJhbmdlQWRkclsxXSkpO1xuICAgICAgICAgICAgICAgICsrdGhlU2l6ZVswXTtcbiAgICAgICAgICAgICAgICArK3RoZVNpemVbMV07XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICBcbiAgICAgICAgcmV0dXJuIHRoZVNpemU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBhIG5hbWVkIHN0eWxlIG9mIGEgZ2l2ZW4gY2VsbC5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgVGhlIGNlbGwgdG8gYmUgb3BlcmF0ZWQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIHN0eWxlIHByb3BlcnR5IHRvIGJlIHNldC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHZhbHVlIFRoZSB2YWx1ZSBmb3IgdGhpcyBwcm9wZXJ0eSB0byBiZSBzZXQuXG4gICAgICogQHJldHVybnMge1hsc3hQb3B1bGF0ZUFjY2Vzc30gRm9yIGludm9jYXRpb24gY2hhaW5pbmcuXG4gICAgICovXG4gICAgc2V0Q2VsbFN0eWxlKGNlbGwsIG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIGNlbGwuc3R5bGUobmFtZSwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcmVmZXJlbmNlIElkIGZvciBhIGdpdmVuIGNlbGwsIGJhc2VkIG9uIGl0cyBzaGVldCBhbmQgYWRkcmVzcy5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgVGhlIGNlbGwgdG8gY3JlYXRlIGEgcmVmZXJlbmNlIElkIHRvLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gd2l0aFNoZWV0IFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgc2hlZXQgbmFtZSBpbiB0aGUgcmVmZXJlbmNlLiBEZWZhdWx0cyB0byB0cnVlLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBpZCB0byBiZSB1c2VkIGFzIGEgcmVmZXJlbmNlIGZvciB0aGlzIGNlbGwuXG4gICAgICovXG4gICAgY2VsbFJlZihjZWxsLCB3aXRoU2hlZXQpIHtcbiAgICAgICAgaWYgKHdpdGhTaGVldCA9PSBudWxsKVxuICAgICAgICAgICAgd2l0aFNoZWV0ID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGNlbGwuYWRkcmVzcyh7IGluY2x1ZGVTaGVldE5hbWU6IHdpdGhTaGVldCB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBCdWlsZCBhIHJlZmVyZW5jZSBzdHJpbmcgZm9yIGEgY2VsbCBpZGVudGlmaWVkIGJ5IEBwYXJhbSBhZHIsIGZyb20gdGhlIEBwYXJhbSBjZWxsLlxuICAgICAqIEBwYXJhbSB7Q2VsbH0gY2VsbCBBIGNlbGwgdGhhdCBpcyBhIGJhc2Ugb2YgdGhlIHJlZmVyZW5jZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWRyIFRoZSBhZGRyZXNzIG9mIHRoZSB0YXJnZXQgY2VsbCwgYXMgbWVudGlvbmVkIGluIEBwYXJhbSBjZWxsLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gd2l0aFNoZWV0IFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgc2hlZXQgbmFtZSBpbiB0aGUgcmVmZXJlbmNlLiBEZWZhdWx0cyB0byB0cnVlLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEEgcmVmZXJlbmNlIHN0cmluZyBpZGVudGlmeWluZyB0aGUgdGFyZ2V0IGNlbGwgdW5pcXVlbHkuXG4gICAgICovXG4gICAgYnVpbGRSZWYoY2VsbCwgYWRyLCB3aXRoU2hlZXQpIHtcbiAgICAgICAgaWYgKHdpdGhTaGVldCA9PSBudWxsKVxuICAgICAgICAgICAgd2l0aFNoZWV0ID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGFkciA/IGNlbGwuc2hlZXQoKS5jZWxsKGFkcikuYWRkcmVzcyh7IGluY2x1ZGVTaGVldE5hbWU6IHdpdGhTaGVldCB9KSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGEgZ2l2ZW4gY2VsbCBmcm9tIGEgZ2l2ZW4gc2hlZXQgKG9yIGFuIGFjdGl2ZSBvbmUpLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdHxhcnJheX0gYWRkcmVzcyBUaGUgY2VsbCBhZHJlc3MgdG8gYmUgdXNlZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGlkeH0gc2hlZXRJZCBUaGUgaWQvbmFtZSBvZiB0aGUgc2hlZXQgdG8gcmV0cmlldmUgdGhlIGNlbGwgZnJvbS4gRGVmYXVsdHMgdG8gYW4gYWN0aXZlIG9uZS5cbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gQSByZWZlcmVuY2UgdG8gdGhlIHJlcXVpcmVkIGNlbGwuXG4gICAgICovXG4gICAgZ2V0Q2VsbChhZGRyZXNzLCBzaGVldElkKSB7XG4gICAgICAgIGNvbnN0IHRoZVNoZWV0ID0gc2hlZXRJZCA9PSBudWxsID8gdGhpcy5fd29ya2Jvb2suYWN0aXZlU2hlZXQoKSA6IHRoaXMuX3dvcmtib29rLnNoZWV0KHNoZWV0SWQpO1xuICAgICAgICByZXR1cm4gdGhlU2hlZXQuY2VsbChhZGRyZXNzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEdXBsaWNhdGVzIGEgY2VsbCBhY3Jvc3MgYSBnaXZlbiByYW5nZS5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgQ2VsbCwgd2hpY2ggbmVlZHMgZHVwbGljYXRpbmcuXG4gICAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2UgVGhlIHJhbmdlLCBhcyByZXR1cm5lZCBmcm9tIHtAbGluayBnZXRDZWxsUmFuZ2V9XG4gICAgICogQHJldHVybnMge1hsc3hQb3B1bGF0ZUFjY2Vzc30gRm9yIGNoYWluIGludm9rZXMuXG4gICAgICovXG4gICAgZHVwbGljYXRlQ2VsbChjZWxsLCByYW5nZSkge1xuICAgICAgICByYW5nZS52YWx1ZShjZWxsLnZhbHVlKCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGFuZCByZXR1cm5zIHRoZSByYW5nZSBzdGFydGluZyBmcm9tIHRoZSBnaXZlbiBjZWxsIGFuZCBzcGF3bmluZyBnaXZlbiByb3dzIGFuZCBjZWxscy5cbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgVGhlIHN0YXJ0aW5nIGNlbGwgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSByb3dPZmZzZXQgTnVtYmVyIG9mIHJvd3MgYXdheSBmcm9tIHRoZSBzdGFydGluZyBjZWxsLiAwIG1lYW5zIHNhbWUgcm93LlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjb2xPZmZzZXQgTnVtYmVyIG9mIGNvbHVtbnMgYXdheSBmcm9tIHRoZSBzdGFydGluZyBjZWxsLiAwIG1lYW5zIHNhbWUgY29sdW1uLlxuICAgICAqIEByZXR1cm5zIHtSYW5nZX0gVGhlIGNvbnN0cnVjdGVkIHJhbmdlLlxuICAgICAqL1xuICAgIGdldENlbGxSYW5nZShjZWxsLCByb3dPZmZzZXQsIGNvbE9mZnNldCkge1xuICAgICAgICByZXR1cm4gY2VsbC5yYW5nZVRvKGNlbGwucmVsYXRpdmVDZWxsKHJvd09mZnNldCwgY29sT2Zmc2V0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgY2VsbCBhdCBhIGNlcnRhaW4gb2Zmc2V0IGZyb20gYSBnaXZlbiBvbmUuXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIFRoZSByZWZlcmVuY2UgY2VsbCB0byBtYWtlIHRoZSBvZmZzZXQgZnJvbS5cbiAgICAgKiBAcGFyYW0ge2ludH0gcm93cyBOdW1iZXIgb2Ygcm93cyB0byBvZmZzZXQuXG4gICAgICogQHBhcmFtIHtpbnR9IGNvbHMgTnVtYmVyIG9mIGNvbHVtbnMgdG8gb2Zmc2V0LlxuICAgICAqIEByZXR1cm5zIHtDZWxsfSBUaGUgcmVzdWx0aW5nIGNlbGwuXG4gICAgICovXG4gICAgb2Zmc2V0Q2VsbChjZWxsLCByb3dzLCBjb2xzKSB7XG4gICAgICAgIHJldHVybiBjZWxsLnJlbGF0aXZlQ2VsbChyb3dzLCBjb2xzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXJnZSBvciBzcGxpdCByYW5nZSBvZiBjZWxscy5cbiAgICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSBUaGUgcmFuZ2UsIGFzIHJldHVybmVkIGZyb20ge0BsaW5rIGdldENlbGxSYW5nZX1cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHN0YXR1cyBUaGUgbWVyZ2VkIHN0YXR1cyB0byBiZSBzZXQuXG4gICAgICogQHJldHVybnMge1hsc3hQb3B1bGF0ZUFjY2Vzc30gRm9yIGNoYWluIGludm9rZXMuXG4gICAgICovXG4gICAgcmFuZ2VNZXJnZWQocmFuZ2UsIHN0YXR1cykge1xuICAgICAgICBpZiAoc3RhdHVzID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgICByZXR1cm4gcmFuZ2UubWVyZ2VkKCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmFuZ2UubWVyZ2VkKHN0YXR1cyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgYSBmb3JtdWxhIGZvciB0aGUgd2hvbGUgcmFuZ2UuIElmIGl0IGNvbnRhaW5zIG9ubHkgb25lIC0gaXQgaXMgc2V0IGRpcmVjdGx5LlxuICAgICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIFRoZSByYW5nZSwgYXMgcmV0dXJuZWQgZnJvbSB7QGxpbmsgZ2V0Q2VsbFJhbmdlfVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBmb3JtdWxhIFRoZSBmb3JtdWxhIHRvIGJlIHNldC5cbiAgICAgKiBAcmV0dXJucyB7WGxzeFBvcHVsYXRlQWNjZXNzfSBGb3IgY2hhaW4gaW52b2tlcy5cbiAgICAgKi9cbiAgICBzZXRSYW5nZUZvcm11bGEocmFuZ2UsIGZvcm11bGEpIHtcbiAgICAgICAgcmFuZ2UuZm9ybXVsYShfLnRyaW1TdGFydChmb3JtdWxhLCAnID0nKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZ2l2ZW4gcmFuZ2UuXG4gICAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2UgVGhlIHJhbmdlIHdoaWNoIGFkZHJlc3Mgd2UncmUgaW50ZXJlc3RlZCBpbi5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHdpdGhTaGVldCBXaGV0aGVyIHRvIGluY2x1ZGUgc2hlZXQgbmFtZSBpbiB0aGUgYWRkcmVzcy5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBzdHJpbmcsIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gcmFuZ2UuXG4gICAgICovXG4gICAgcmFuZ2VSZWYocmFuZ2UsIHdpdGhTaGVldCkge1xuICAgICAgICBpZiAod2l0aFNoZWV0ID09IG51bGwpXG4gICAgICAgICAgICB3aXRoU2hlZXQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gcmFuZ2UuYWRkcmVzcyh7IGluY2x1ZGVTaGVldE5hbWU6IHdpdGhTaGVldCB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgYWxsIHVzZWQgY2VsbHMgb2YgdGhlIGdpdmVuIHdvcmtib29rLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNiIFRoZSBjYWxsYmFjayB0byBiZSBpbnZva2VkIHdpdGggYGNlbGxgIGFyZ3VtZW50IGZvciBlYWNoIHVzZWQgY2VsbC5cbiAgICAgKiBAcmV0dXJucyB7WGxzeFBvcHVsYXRlQWNjZXNzfSBGb3IgY2hhaW4gaW52b2tlcy5cbiAgICAgKi9cbiAgICBmb3JBbGxDZWxscyhjYikge1xuICAgICAgICB0aGlzLl93b3JrYm9vay5zaGVldHMoKS5mb3JFYWNoKHNoZWV0ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRoZVJhbmdlID0gc2hlZXQudXNlZFJhbmdlKCk7XG4gICAgICAgICAgICBpZiAodGhlUmFuZ2UpIFxuICAgICAgICAgICAgICAgIHRoZVJhbmdlLmZvckVhY2goY2IpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIHRoZSBzdHlsZXMgZnJvbSBgc3JjYCBjZWxsIHRvIHRoZSBgZGVzdGAtaW5hdGlvbiBvbmUuXG4gICAgICogQHBhcmFtIHtDZWxsfSBkZXN0IERlc3RpbmF0aW9uIGNlbGwuXG4gICAgICogQHBhcmFtIHtDZWxsfSBzcmMgU291cmNlIGNlbGwuXG4gICAgICogQHJldHVybnMge1hsc3hQb3B1bGF0ZUFjY2Vzc30gRm9yIGludm9jYXRpb24gY2hhaW5pbmcuXG4gICAgICovXG4gICAgY29weVN0eWxlKGRlc3QsIHNyYykge1xuICAgICAgICBpZiAoIXNyYyB8fCAhZGVzdCkgdGhyb3cgbmV3IEVycm9yKFwiQ3Jhc2ghIE51bGwgJ3NyYycgb3IgJ2Rlc3QnIGZvciBjb3B5U3R5bGUoKSFcIik7XG4gICAgICAgIGlmIChzcmMgPT0gZGVzdCkgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHNyYy5fc3R5bGUgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgIGRlc3Quc3R5bGUoc3JjLl9zdHlsZSk7XG4gICAgICAgIGVsc2UgaWYgKHNyYy5fc3R5bGVJZCA+IDApXG4gICAgICAgICAgICBkZXN0Ll9zdHlsZUlkID0gc3JjLl9zdHlsZUlkO1xuXG4gICAgICAgIGNvbnN0IGRlc3RTaGVldElkID0gZGVzdC5zaGVldCgpLm5hbWUoKSxcbiAgICAgICAgICAgIHJvd0lkID0gYCcke2Rlc3RTaGVldElkfSc6JHtkZXN0LnJvd051bWJlcigpfWAsXG4gICAgICAgICAgICBjb2xJZCA9IGAnJHtkZXN0U2hlZXRJZH0nOiR7ZGVzdC5jb2x1bW5OdW1iZXIoKX1gO1xuXG4gICAgICAgIGlmICh0aGlzLl9yb3dTaXplc1tyb3dJZF0gPT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgIGRlc3Qucm93KCkuaGVpZ2h0KHRoaXMuX3Jvd1NpemVzW3Jvd0lkXSA9IHNyYy5yb3coKS5oZWlnaHQoKSk7XG4gICAgICAgIFxuICAgICAgICBpZiAodGhpcy5fY29sU2l6ZXNbY29sSWRdID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgICBkZXN0LmNvbHVtbigpLndpZHRoKHRoaXMuX2NvbFNpemVzW2NvbElkXSA9IHNyYy5jb2x1bW4oKS53aWR0aCgpKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gWGxzeFBvcHVsYXRlQWNjZXNzO1xuIl19
diff --git a/browser/xlsx-datafill.min.js.map b/browser/xlsx-datafill.min.js.map
index a905f98..ef7feb9 100644
--- a/browser/xlsx-datafill.min.js.map
+++ b/browser/xlsx-datafill.min.js.map
@@ -1 +1 @@
-{"version":3,"sources":["node_modules/browser-pack/_prelude.js","src/XlsxDataFill.js","src/XlsxPopulateAccess.js"],"names":["f","exports","module","define","amd","window","global","self","this","XlsxDataFill","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","1","_2","defaultOpts","templateRegExp","fieldSplitter","joinText","mergeCells","duplicateCells","followFormulae","copyStyle","callbacksMap","","data","keys","$","values","refRegExp","accessor","opts","_classCallCheck","_opts","defaultsDeep","_rowSizes","_colSizes","_access","newOpts","merge","_this","dataFills","collectTemplates","template","aFill","dependents","formulas","processed","reference","refFill","concat","formula","push","offset","cellDistance","cell","id","each","fill","extractor","applyFill","handlerName","handlerFn","extractParts","split","trim","path","handler","getHandler","_this2","styles","pair","startsWith","name","substr","val","extractValues","setCellStyle","JSON","parse","clone","value","cellValue","reMatch","match","cellType","parts","map","cellRef","buildRef","iterators","cellSize","padding","v","parseInt","s","list","sorted","related","freeList","_t","shift","apply","_toConsumableArray","xor","join","cb","_this3","allTemplates","forAllCells","parseTemplate","sortTemplates","forEach","root","_this4","_this$parseExtractor","parseExtractor","Array","isArray","undefined","sizes","entry","get","idx","_this5","iter","transposed","parsedIter","_typeof","inRoot","extractData","unshift","_this6","entrySize","chunk","getCellRange","ri","ci","setCellValue","applyDataStyle","mainCell","_this7","theData","nextCell","sizeMaxxer","Math","max","_loop","d","inFill","inCell","offsetCell","putValues","rowOffset","colOffset","rowPadding","colPadding","rng","getTemplateOpts","mergeCell","rangeMerged","duplicateCell","applyFormula","size","newFormula","newRef","from","getCell","rangeRef","index","shiftFormula","setCellFormula","setRangeFormula","XlsxPopulateAccess","version","_","_RichText","workbook","XlsxPopulate","_workbook","RichText","theValue","text","hyperlink","Date","trimStart","to","rowNumber","columnNumber","cellAddr","address","theSize","sheet","_mergeCells","range","rangeAddr","attributes","ref","style","withSheet","includeSheetName","adr","sheetId","activeSheet","rangeTo","relativeCell","rows","cols","status","merged","sheets","theRange","usedRange","dest","src","_style","_styleId","destSheetId","rowId","colId","row","height","column","width"],"mappings":"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","file":"xlsx-datafill.min.js","sourcesContent":["(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 _.keys(data),\n $: data => _.values(data)\n }\n};\n\nconst refRegExp = /('?([^!]*)?'?!)?([A-Z]+\\d+)(:([A-Z]+\\d+))?/;\n\n/**\n * Data fill engine, taking an instance of Excel sheet accessor and a JSON object as data, and filling the values from the latter into the former.\n */\nclass XlsxDataFill {\n /**\n * Constructs a new instance of XlsxDataFill with given options.\n * @param {object} accessor An instance of XLSX spreadsheet accessing class.\n * @param {{}} opts Options to be used during processing.\n * @param {RegExp} opts.templateRegExp The regular expression to be used for template recognizing. \n * Default is `/\\{\\{([^}]*)\\}\\}/`, i.e. Mustache.\n * @param {string} opts.fieldSplitter The string to be expected as template field splitter. Default is `|`.\n * @param {string} opts.joinText The string to be used when the extracted value for a single cell is an array, \n * and it needs to be joined. Default is `,`.\n * @param {string|boolean} opts.mergeCells Whether to merge the higher dimension cells in the output. Default is true.\n * @param {string|boolean} opts.duplicateCells Whether to duplicate the content of higher dimension cells, when not merged. Default is false.\n * @param {boolean} opts.followFormulae If a template is located as a result of a formula, whether to still process it.\n * Default is false.\n * @param {boolean} opts.copyStyle Copy the style of the template cell when populating. Even when `false`, the template\n * styling _is_ applied. Default is true.\n * @param {object.} opts.callbacksMap A map of handlers to be used for data and value extraction.\n * There is one default - the empty one, for object key extraction.\n */\n constructor(accessor, opts) {\n this._opts = _.defaultsDeep({}, opts, defaultOpts);\n this._rowSizes = {};\n this._colSizes = {};\n this._access = accessor;\n }\n\n /**\n * Setter/getter for XlsxDataFill's options as set during construction.\n * @param {{}|null} newOpts If set - the new options to be used. \n * @see {@constructor}.\n * @returns {XlsxDataFill|{}} The required options (in getter mode) or XlsxDataFill (in setter mode) for chaining.\n */\n options(newOpts) {\n if (newOpts !== null) {\n _.merge(this._opts, newOpts);\n return this;\n } else\n return this._opts;\n }\n\n /**\n * The main entry point for whole data population mechanism.\n * @param {{}} data The data to be applied.\n * @returns {XlsxDataFill} For invocation chaining.\n */\n fillData(data) {\n const dataFills = {};\n\t\n // Build the dependency connections between templates.\n this.collectTemplates(template => {\n const aFill = { \n template: template, \n dependents: [],\n formulas: [],\n processed: false\n };\n\n if (template.reference) {\n const refFill = dataFills[template.reference];\n \n if (!refFill) \n throw new Error(`Unable to find a reference '${template.reference}'!`);\n \n if (template.formula) \n refFill.formulas.push(aFill);\n else\n refFill.dependents.push(aFill);\n \n aFill.offset = this._access.cellDistance(refFill.template.cell, template.cell);\n }\n dataFills[template.id] = aFill;\n });\n \n // Apply each fill onto the sheet.\n _.each(dataFills, fill => {\n if (fill.processed)\n return;\n else if (fill.template.formula)\n throw new Error(`Non-referencing formula found '${fill.extractor}'. Use a non-templated one!`);\n else\n this.applyFill(fill, data, fill.template.cell);\n });\n\n return this;\n }\n\n /**\n * Retrieves the provided handler from the map.\n * @param {string} handlerName The name of the handler.\n * @returns {function} The handler function itself.\n * @ignore\n */\n getHandler(handlerName) {\n const handlerFn = this._opts.callbacksMap[handlerName];\n\n if (!handlerFn)\n throw new Error(`Handler '${handlerName}' cannot be found!`);\n else if (typeof handlerFn !== 'function')\n throw new Error(`Handler '${handlerName}' is not a function!`);\n else \n return handlerFn;\n }\n\n /**\n * Parses the provided extractor (ot iterator) string to find a callback id inside, if present.\n * @param {string} extractor The iterator/extractor string to be investigated.\n * @returns {object.} A { `path`, `handler` } object representing the JSON path\n * ready for use and the provided `handler` _function_ - ready for invoking, if such is provided.\n * If not - the `path` property contains the provided `extractor`, and the `handler` is `null`.\n * @ignore\n */\n parseExtractor(extractor) {\n // A specific extractor can be specified after semilon - find and remember it.\n const extractParts = extractor.split(\":\"),\n handlerName = _.trim(extractParts[1]);\n\n return extractParts.length == 1\n ? { path: extractor, handler: null }\n : {\n path: _.trim(extractParts[0]),\n handler: this.getHandler(handlerName)\n };\n }\n\n /**\n * Applies the style part of the template onto a given cell.\n * @param {Cell} cell The destination cell to apply styling to.\n * @param {{}} data The data chunk for that cell.\n * @param {{}} template The template to be used for that cell.\n * @returns {DataFiller} For invocation chaining.\n * @ignore\n */\n applyDataStyle(cell, data, template) {\n const styles = template.styles;\n\n if (this._opts.copyStyle)\n this._access.copyStyle(cell, template.cell);\n \n if (styles && data) {\n _.each(styles, pair => {\n if (_.startsWith(pair.name, \":\")) {\n this.getHandler(pair.name.substr(1)).call(this._opts, data, cell);\n } else if (!_.startsWith(pair.name, \"!\")) {\n const val = this.extractValues(data, pair.extractor, cell);\n if (val)\n this._access.setCellStyle(cell, pair.name, JSON.parse(val));\n }\n });\n }\n\n return this;\n }\n\n /**\n * Extract the options-specific parameters from the styles field and merge them with the global ones.\n * @param {{}} template The template to extract options properties from.\n * @returns {{}} The full options, \n * @ignore\n */\n getTemplateOpts(template) {\n if (!template.styles)\n return this._opts;\n \n const opts = _.clone(this._opts);\n _.each(template.styles, pair => {\n if (_.startsWith(pair.name, \"!\"))\n opts[pair.name.substr(1)] = JSON.parse(pair.extractor);\n });\n\n return opts;\n }\n\n /**\n * Parses the contents of the cell into a valid template info.\n * @param {Cell} cell The cell containing the template to be parsed.\n * @returns {{}} The parsed template.\n * @description This method builds template info, taking into account the supplied options.\n * @ignore\n */\n parseTemplate(cell) {\n const value = this._access.cellValue(cell);\n if (value == null || typeof value !== 'string')\n return null;\n \n const reMatch = value.match(this._opts.templateRegExp);\n if (!reMatch || !this._opts.followFormulae && this._access.cellType(cell) === 'formula') \n return null;\n \n const parts = reMatch[1].split(this._opts.fieldSplitter).map(_.trim),\n styles = !parts[4] ? null : parts[4].split(\",\"),\n extractor = parts[2] || \"\",\n cellRef = this._access.buildRef(cell, parts[0]);\n \n if (parts.length < 2) \n throw new Error(`Not enough components of the template '${reMatch[0]}'`);\n if (!!parts[0] && !cellRef)\n throw new Error(`Invalid reference passed: '${parts[0]}'`);\n\n return {\n id: this._access.cellRef(cell),\n reference: cellRef,\n iterators: parts[1].split(/x|\\*/).map(_.trim),\n extractor: extractor,\n formula: extractor.startsWith(\"=\"),\n cell: cell,\n cellSize: this._access.cellSize(cell),\n padding: (parts[3] || \"\").split(/:|,|x|\\*/).map(v => parseInt(v) || 0),\n styles: !styles ? null : _.map(styles, s => {\n const pair = _.trim(s).split(\"=\");\n return { name: _.trim(pair[0]), extractor: _.trim(pair[1]) };\n })\n };\n }\n\n sortTemplates(list) {\n const sorted = [],\n related = {},\n map = {},\n freeList = [];\n\n // First, make the dependency map and add the list of non-referencing templates\n for (let i = 0; i < list.length; ++i) {\n const t = list[i];\n map[t.id] = i;\n\n if (!t.reference)\n freeList.push(t.id);\n else \n (related[t.reference] = related[t.reference] || []).push(t.id);\n }\n\n // Now, make the actual sorting.\n while (freeList.length > 0) {\n const id = freeList.shift(),\n t = list[map[id]];\n\n sorted.push(t);\n \n // We use the fact that there is a single predecessor in our setup.\n if (related[t.id])\n freeList.push(...related[t.id]);\n }\n\n if (sorted.length < list.length)\n throw new Error(`A reference cycle found, involving \"${_.map(_.xor(list, sorted), 'id').join(',')}\"!`);\n\n return sorted;\n }\n \n /**\n * Searches the whole workbook for template pattern and constructs the templates for processing.\n * @param {Function} cb The callback to be invoked on each templated, after they are sorted.\n * @returns {undefined}\n * @description The templates collected are sorted, based on the intra-template reference - if one template\n * is referring another one, it'll appear _later_ in the returned array, than the referred template.\n * This is the order the callback is being invoked on.\n * @ignore\n */\n collectTemplates(cb) {\n const allTemplates = [];\n \n this._access.forAllCells(cell => {\n const template = this.parseTemplate(cell);\n if (template)\n allTemplates.push(template);\n });\n \n return this.sortTemplates(allTemplates).forEach(cb);\n }\n\n /**\n * Extracts the value(s) from the provided data `root` to be set in the provided `cell`.\n * @param {{}} root The data root to be extracted values from.\n * @param {string} extractor The extraction string provided by the template. Usually a JSON path within the data `root`.\n * @param {Cell} cell A reference cell, if such exists.\n * @returns {string|number|Date|Array|Array.>} The value to be used.\n * @description This method is used even when a whole - possibly rectangular - range is about to be set, so it can\n * return an array of arrays.\n * @ignore\n */\n extractValues(root, extractor, cell) {\n const { path, handler } = this.parseExtractor(extractor);\n\n if (!Array.isArray(root))\n root = _.get(root, path, root);\n else if (root.sizes !== undefined)\n root = !extractor ? root : _.map(root, entry => this.extractValues(entry, extractor, cell));\n else if (!handler)\n return root.join(this._opts.joinText || \",\");\n\n return !handler ? root : handler.call(this._opts, root, cell);\n }\n\n /**\n * Extracts an array (possibly of arrays) with data for the given fill, based on the given\n * root object.\n * @param {{}} root The main reference object to apply iterators to.\n * @param {Array} iterators List of iterators - string JSON paths inside the root object.\n * @param {Number} idx The index in the iterators array to work on.\n * @returns {Array|Array.} An array (possibly of arrays) with extracted data.\n * @ignore\n */\n extractData(root, iterators, idx) {\n let iter = iterators[idx],\n sizes = [],\n transposed = false,\n data = null;\n\n if (iter == '1') {\n transposed = true;\n iter = iterators[++idx];\n }\n\n if (!iter) return root;\n\n // A specific extractor can be specified after semilon - find and remember it.\n const parsedIter = this.parseExtractor(iter);\n\n data = _.get(root, parsedIter.path, root);\n \n if (typeof parsedIter.handler === 'function')\n data = parsedIter.handler.call(this._opts, data);\n\n if (!Array.isArray(data) && typeof data === 'object')\n return data;\n else if (idx < iterators.length - 1) {\n data = _.map(data, inRoot => this.extractData(inRoot, iterators, idx + 1));\n sizes = data[0].sizes || [];\n }\n \n // data = _.values(data);\n\n // Some data sanity checks.\n if (!data)\n throw new Error(`The iterator '${iter}' extracted no data!`);\n else if (typeof data !== 'object')\n throw new Error(`The data extracted from iterator '${iter}' is neither an array, nor object!`);\n\n sizes.unshift(transposed ? -data.length : data.length);\n data.sizes = sizes;\n return data;\n }\n\n /**\n * Put the data values into the proper cells, with correct extracted values.\n * @param {{}} cell The starting cell for the data to be put.\n * @param {Array} data The actual data to be put. The values will be _extracted_ from here first.\n * @param {{}} template The template that is being implemented with that data fill.\n * @returns {Array} Matrix size that this data has occupied on the sheet [rows, cols].\n * @ignore\n */\n putValues(cell, data, template) {\n if (!cell) throw new Error(\"Crash! Null reference cell in 'putValues()'!\");\n\n let entrySize = data.sizes,\n value = this.extractValues(data, template.extractor, cell);\n\n // if we've come up with a raw data\n if (!Array.isArray(value) || !entrySize || !entrySize.length) {\n this._access.setCellValue(cell, value);\n this.applyDataStyle(cell, data, template);\n entrySize = template.cellSize;\n } else if (entrySize.length <= 2) {\n // Normalize the size and data.\n if (entrySize[0] < 0) {\n entrySize = [1, -entrySize[0]];\n value = [value];\n data = [data];\n } else if (entrySize.length == 1) {\n entrySize = entrySize.concat([1]);\n value = _.chunk(value, 1);\n data = _.chunk(data, 1);\n }\n\n this._access.getCellRange(cell, entrySize[0] - 1, entrySize[1] - 1).forEach((cell, ri, ci) => {\n this._access.setCellValue(cell, value[ri][ci]);\n this.applyDataStyle(cell, data[ri][ci], template);\n });\n } else\n throw new Error(`Values extracted with '${template.extractor}' are more than 2 dimension!'`);\n\n return entrySize;\n }\n\n /**\n * Apply the given filter onto the sheet - extracting the proper data, following dependent fills, etc.\n * @param {{}} aFill The fill to be applied, as constructed in the {@link fillData} method.\n * @param {{}} root The data root to be used for data extraction.\n * @param {Cell} mainCell The starting cell for data placement procedure.\n * @returns {Array} The size of the data put in [row, col] format.\n * @ignore\n */\n applyFill(aFill, root, mainCell) {\n const template = aFill.template,\n theData = this.extractData(root, template.iterators, 0);\n\n let entrySize = [1, 1];\n\n if (!aFill.dependents || !aFill.dependents.length)\n entrySize = this.putValues(mainCell, theData, template);\n else {\n let nextCell = mainCell;\n const sizeMaxxer = (val, idx) => entrySize[idx] = Math.max(entrySize[idx], val);\n\n for (let d = 0; d < theData.length; ++d) {\n const inRoot = theData[d];\n\n for (let f = 0; f < aFill.dependents.length; ++f) {\n const inFill = aFill.dependents[f],\n inCell = this._access.offsetCell(nextCell, inFill.offset[0], inFill.offset[1]);\n \n _.forEach(this.applyFill(inFill, inRoot, inCell), sizeMaxxer);\n }\n\n // Now we have the inner data put and the size calculated.\n _.forEach(this.putValues(nextCell, inRoot, template), sizeMaxxer);\n\n let rowOffset = entrySize[0],\n colOffset = entrySize[1],\n rowPadding = template.padding[0] || 0,\n colPadding = template.padding[1] || 0;\n\n // Make sure we grow only on one dimension.\n if (theData.sizes[0] < 0) {\n if (template.padding.length < 2)\n colPadding = rowPadding;\n rowOffset = rowPadding = 0;\n entrySize[1] = 1;\n } else if (theData.sizes.length < 2) {\n colOffset = colPadding = 0;\n entrySize[0] = 1;\n }\n\n if (rowOffset > 1 || colOffset > 1) {\n const rng = this._access.getCellRange(nextCell, Math.max(rowOffset - 1, 0), Math.max(colOffset - 1, 0)),\n _opts = this.getTemplateOpts(template);\n\n if (_opts.mergeCells === true || _opts.mergeCell === 'both'\n || rowOffset > 1 && _opts.mergeCells === 'vertical' \n || colOffset > 1 && _opts.mergeCells === 'horizontal')\n this._access.rangeMerged(rng, true);\n else if (_opts.duplicateCells === true || _opts.duplicateCells === 'both'\n || rowOffset > 1 && _opts.duplicateCells === 'vertical' \n || colOffset > 1 && _opts.duplicateCells === 'horizontal')\n this._access.duplicateCell(nextCell, rng);\n\n rng.forEach(cell => this.applyDataStyle(cell, inRoot, template));\n }\n\n // Finally, calculate the next cell.\n nextCell = this._access.offsetCell(nextCell, rowOffset + rowPadding, colOffset + colPadding);\t\n }\n\n // Now recalc combined entry size.\n _.forEach(this._access.cellDistance(mainCell, nextCell), sizeMaxxer);\n }\n\n _.forEach(aFill.formulas, f => this.applyFormula(f, entrySize, mainCell));\n\n aFill.processed = true;\n return entrySize;\n }\n\n /**\n * Process a formula be shifting all the fixed offset.\n * @param {String} formula The formula to be shifted.\n * @param {Array} offset The offset of the referenced template to the formula one.\n * @param {Array} size The size of the ranges as they should be.\n * @returns {String} The processed text.\n * @ignore\n */\n shiftFormula(formula, offset, size) {\n let newFormula = '';\n\n for (;;) {\n const match = formula.match(refRegExp);\n if (!match) break;\n\n let from = this._access.getCell(match[3], match[2]),\n newRef = null;\n\n if (offset[0] > 0 || offset[1] > 0)\n from = this._access.offsetCell(from, offset[0], offset[1]);\n\n newRef = !match[5]\n ? this._access.cellRef(from, !!match[2])\n : this._access.rangeRef(this._access.getCellRange(from, size[0], size[1]), !!match[2]);\n\n newFormula += formula.substr(0, match.index) + newRef;\n formula = formula.substr(match.index + match[0].length);\n }\n\n newFormula += formula;\n return newFormula;\n }\n\n /**\n * Apply the given formula in the sheet, i.e. changing it to match the \n * sizes of the references templates.\n * @param {{}} aFill The fill to be applied, as constructed in the {@link fillData} method.\n * @param {Array} entrySize The fill-to-size map, as constructed so far\n * @param {Cell} cell The cell to put/start this formula into\n * @returns {undefined}\n * @ignore\n */\n applyFormula(aFill, entrySize, cell) {\n cell = this._access.offsetCell(cell, aFill.offset[0], aFill.offset[1]);\n\n const template = aFill.template,\n iter = _.trim(template.iterators[0]),\n offset = this._access.cellDistance(template.cell, cell);\n \n let formula = template.extractor, \n rng;\n \n aFill.processed = true;\n this._access.setCellValue(cell, null);\n\n if (entrySize[0] < 2 && entrySize[1] < 2 || iter === 'both') {\n formula = this.shiftFormula(formula, offset, [0, 0]);\n rng = this._access.getCellRange(cell, entrySize[0] - 1, entrySize[1] - 1);\n } else if (iter === 'cols') {\n formula = this.shiftFormula(formula, offset, [entrySize[0] - 1, 0]);\n rng = this._access.getCellRange(cell, 0, entrySize[1] - 1);\n } else if (iter === 'rows') {\n formula = this.shiftFormula(formula, offset, [0, entrySize[1] - 1]);\n rng = this._access.getCellRange(cell, entrySize[0] - 1, 0);\n } else { // i.e. 'none'\n this._access.setCellFormula(cell, this.shiftFormula(formula, offset, [entrySize[0] - 1, entrySize[1] - 1]));\n return;\n }\n\n this._access.setRangeFormula(rng, formula);\n }\n}\n\n/**\n * The built-in accessor based on xlsx-populate npm module\n * @type {XlsxPopulateAccess}\n */\nXlsxDataFill.XlsxPopulateAccess = require('./XlsxPopulateAccess');\nXlsxDataFill.version = \"{{VERSION}}\";\n\nmodule.exports = XlsxDataFill;\n","\"use strict\";\n\nconst _ = require('lodash');\n\n// const allStyles = [\n// \"bold\", \n// \"italic\", \n// \"underline\", \n// \"strikethrough\", \n// \"subscript\", \n// \"superscript\", \n// \"fontSize\", \n// \"fontFamily\", \n// \"fontGenericFamily\", \n// \"fontScheme\", \n// \"fontColor\", \n// \"horizontalAlignment\", \n// \"justifyLastLine\", \n// \"indent\", \n// \"verticalAlignment\", \n// \"wrapText\", \n// \"shrinkToFit\", \n// \"textDirection\", \n// \"textRotation\", \n// \"angleTextCounterclockwise\", \n// \"angleTextClockwise\", \n// \"rotateTextUp\", \n// \"rotateTextDown\", \n// \"verticalText\", \n// \"fill\", \n// \"border\", \n// \"borderColor\", \n// \"borderStyle\", \n// \"leftBorder\", \"rightBorder\", \"topBorder\", \"bottomBorder\", \"diagonalBorder\", \n// \"leftBorderColor\", \"rightBorderColor\", \"topBorderColor\", \"bottomBorderColor\", \"diagonalBorderColor\", \n// \"leftBorderStyle\", \"rightBorderStyle\", \"topBorderStyle\", \"bottomBorderStyle\", \"diagonalBorderStyle\", \n// \"diagonalBorderDirection\", \n// \"numberFormat\"\n// ];\n\nlet _RichText = null;\n\n/**\n * `xslx-populate` library based accessor to a given Excel workbook. All these methods are internally used by {@link XlsxDataFill}, \n * but can be used as a reference for implementing custom spreadsheet accessors.\n */\nclass XlsxPopulateAccess {\n /**\n * Constructs a new instance of XlsxSmartTemplate with given options.\n * @param {Workbook} workbook - The workbook to be accessed.\n * @param {XlsxPopulate} XlsxPopulate - The actual xlsx-populate library object.\n * @description The `XlsxPopulate` object need to be passed in order to extract\n * certain information from it, _without_ referring the whole library, thus\n * avoiding making the `xlsx-datafill` package a dependency.\n */\n constructor(workbook, XlsxPopulate) {\n this._workbook = workbook;\n this._rowSizes = {};\n this._colSizes = {};\n \n _RichText = XlsxPopulate.RichText;\n }\n\n /**\n * Returns the configured workbook for direct XlsxPopulate manipulation.\n * @returns {Workbook} The workbook involved.\n */\n workbook() {\n return this._workbook; \n }\n\n /**\n * Gets the textual representation of the cell value.\n * @param {Cell} cell - The cell to retrieve the value from.\n * @returns {string} The textual representation of cell's contents.\n */\n cellValue(cell) {\n const theValue = cell.value();\n return theValue instanceof _RichText ? theValue.text() : theValue;\n }\n\n /**\n * Sets the cell value.\n * @param {Cell} cell - The cell to retrieve the value from.\n * @param {*} value - The requested value for setting.\n * @returns {XlsxPopulateAccess} Either the requested value or chainable this.\n */\n setCellValue(cell, value) {\n cell.value(value);\n return this;\n }\n\n /**\n * Gets the textual representation of the cell value.\n * @param {Cell} cell - The cell to retrieve the value from.\n * @returns {string} The type of the cell - 'formula', 'richtext', \n * 'text', 'number', 'date', 'hyperlink', or 'unknown';\n */\n cellType(cell) {\n if (cell.formula())\n return 'formula';\n else if (cell.hyperlink())\n return 'hyperlink';\n \n const theValue = cell.value();\n if (theValue instanceof _RichText)\n return 'richtext';\n else if (theValue instanceof Date)\n return 'date';\n else \n return typeof theValue;\n }\n\n /**\n * Sets the formula in the cell\n * @param {Cell} cell - The cell to retrieve the value from.\n * @param {string} formula - the text of the formula to be set.\n * @returns {XlsxPopulateAccess} For chaining.\n */\n setCellFormula(cell, formula) {\n cell.formula(_.trimStart(formula, ' ='));\n return this;\n }\n\n /**\n * Measures the distance, as a vector between two given cells.\n * @param {Cell} from The first cell.\n * @param {Cell} to The second cell.\n * @returns {Array.} An array with two values [, ], representing the distance between the two cells.\n */\n cellDistance(from, to) {\n return [\n to.rowNumber() - from.rowNumber(),\n to.columnNumber() - from.columnNumber()\n ];\n }\n\n /**\n * Determines the size of cell, taking into account if it is part of a merged range.\n * @param {Cell} cell The cell to be investigated.\n * @returns {Array.} An array with two values [, ], representing the occupied size.\n */\n cellSize(cell) {\n const cellAddr = cell.address();\n let theSize = [1, 1];\n \n _.forEach(cell.sheet()._mergeCells, range => {\n const rangeAddr = range.attributes.ref.split(\":\");\n if (rangeAddr[0] == cellAddr) {\n theSize = this.cellDistance(cell, cell.sheet().cell(rangeAddr[1]));\n ++theSize[0];\n ++theSize[1];\n return false;\n }\n });\n \n return theSize;\n }\n\n /**\n * Sets a named style of a given cell.\n * @param {Cell} cell The cell to be operated.\n * @param {string} name The name of the style property to be set.\n * @param {string|object} value The value for this property to be set.\n * @returns {XlsxPopulateAccess} For invocation chaining.\n */\n setCellStyle(cell, name, value) {\n cell.style(name, value);\n return this;\n }\n\n /**\n * Creates a reference Id for a given cell, based on its sheet and address.\n * @param {Cell} cell The cell to create a reference Id to.\n * @param {boolean} withSheet Whether to include the sheet name in the reference. Defaults to true.\n * @returns {string} The id to be used as a reference for this cell.\n */\n cellRef(cell, withSheet) {\n if (withSheet == null)\n withSheet = true;\n return cell.address({ includeSheetName: withSheet });\n }\n\n /**\n * Build a reference string for a cell identified by @param adr, from the @param cell.\n * @param {Cell} cell A cell that is a base of the reference.\n * @param {string} adr The address of the target cell, as mentioned in @param cell.\n * @param {boolean} withSheet Whether to include the sheet name in the reference. Defaults to true.\n * @returns {string} A reference string identifying the target cell uniquely.\n */\n buildRef(cell, adr, withSheet) {\n if (withSheet == null)\n withSheet = true;\n return adr ? cell.sheet().cell(adr).address({ includeSheetName: withSheet }) : null;\n }\n\n /**\n * Retrieves a given cell from a given sheet (or an active one).\n * @param {string|object|array} address The cell adress to be used\n * @param {string|idx} sheetId The id/name of the sheet to retrieve the cell from. Defaults to an active one.\n * @returns {Cell} A reference to the required cell.\n */\n getCell(address, sheetId) {\n const theSheet = sheetId == null ? this._workbook.activeSheet() : this._workbook.sheet(sheetId);\n return theSheet.cell(address);\n }\n\n /**\n * Duplicates a cell across a given range.\n * @param {Cell} cell Cell, which needs duplicating.\n * @param {Range} range The range, as returned from {@link getCellRange}\n * @returns {XlsxPopulateAccess} For chain invokes.\n */\n duplicateCell(cell, range) {\n range.value(cell.value());\n return this;\n }\n\n /**\n * Constructs and returns the range starting from the given cell and spawning given rows and cells.\n * @param {Cell} cell The starting cell of the range.\n * @param {Number} rowOffset Number of rows away from the starting cell. 0 means same row.\n * @param {Number} colOffset Number of columns away from the starting cell. 0 means same column.\n * @returns {Range} The constructed range.\n */\n getCellRange(cell, rowOffset, colOffset) {\n return cell.rangeTo(cell.relativeCell(rowOffset, colOffset));\n }\n\n /**\n * Gets the cell at a certain offset from a given one.\n * @param {Cell} cell The reference cell to make the offset from.\n * @param {int} rows Number of rows to offset.\n * @param {int} cols Number of columns to offset.\n * @returns {Cell} The resulting cell.\n */\n offsetCell(cell, rows, cols) {\n return cell.relativeCell(rows, cols);\n }\n\n /**\n * Merge or split range of cells.\n * @param {Range} range The range, as returned from {@link getCellRange}\n * @param {boolean} status The merged status to be set.\n * @returns {XlsxPopulateAccess} For chain invokes.\n */\n rangeMerged(range, status) {\n if (status === undefined)\n return range.merged();\n else {\n range.merged(status);\n return this;\n }\n }\n\n /**\n * Sets a formula for the whole range. If it contains only one - it is set directly.\n * @param {Range} range The range, as returned from {@link getCellRange}\n * @param {String} formula The formula to be set.\n * @returns {XlsxPopulateAccess} For chain invokes.\n */\n setRangeFormula(range, formula) {\n range.formula(_.trimStart(formula, ' ='));\n return this;\n }\n\n /**\n * Return the string representation of a given range.\n * @param {Range} range The range which address we're interested in.\n * @param {boolean} withSheet Whether to include sheet name in the address.\n * @return {String} The string, representing the given range.\n */\n rangeRef(range, withSheet) {\n if (withSheet == null)\n withSheet = true;\n return range.address({ includeSheetName: withSheet });\n }\n\n /**\n * Iterate over all used cells of the given workbook.\n * @param {function} cb The callback to be invoked with `cell` argument for each used cell.\n * @returns {XlsxPopulateAccess} For chain invokes.\n */\n forAllCells(cb) {\n this._workbook.sheets().forEach(sheet => {\n const theRange = sheet.usedRange();\n if (theRange) \n theRange.forEach(cb);\n });\n return this;\n }\n\n /**\n * Copies the styles from `src` cell to the `dest`-ination one.\n * @param {Cell} dest Destination cell.\n * @param {Cell} src Source cell.\n * @returns {XlsxPopulateAccess} For invocation chaining.\n */\n copyStyle(dest, src) {\n if (!src || !dest) throw new Error(\"Crash! Null 'src' or 'dest' for copyStyle()!\");\n if (src == dest) return this;\n\n if (src._style !== undefined)\n dest.style(src._style);\n else if (src._styleId > 0)\n dest._styleId = src._styleId;\n\n const destSheetId = dest.sheet().name(),\n rowId = `'${destSheetId}':${dest.rowNumber()}`,\n colId = `'${destSheetId}':${dest.columnNumber()}`;\n\n if (this._rowSizes[rowId] === undefined)\n dest.row().height(this._rowSizes[rowId] = src.row().height());\n \n if (this._colSizes[colId] === undefined)\n dest.column().width(this._colSizes[colId] = src.column().width());\n\n return this;\n }\n}\n\nmodule.exports = XlsxPopulateAccess;\n"]}
\ No newline at end of file
+{"version":3,"sources":["node_modules/browser-pack/_prelude.js","src/XlsxDataFill.js","src/XlsxPopulateAccess.js"],"names":["f","exports","module","define","amd","window","global","self","this","XlsxDataFill","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","1","_2","defaultOpts","templateRegExp","fieldSplitter","joinText","mergeCells","duplicateCells","followFormulae","copyStyle","callbacksMap","","data","keys","$","values","refRegExp","accessor","opts","_classCallCheck","_opts","defaultsDeep","_rowSizes","_colSizes","_access","newOpts","merge","_this","dataFills","collectTemplates","template","aFill","dependents","formulas","processed","reference","refFill","concat","formula","push","offset","cellDistance","cell","id","each","fill","extractor","applyFill","handlerName","handlerFn","extractParts","split","trim","path","handler","getHandler","_this2","styles","pair","startsWith","name","substr","val","extractValues","setCellStyle","JSON","parse","clone","value","cellValue","reMatch","match","cellType","parts","map","cellRef","buildRef","iterators","cellSize","padding","v","parseInt","s","list","sorted","related","freeList","_t","shift","apply","_toConsumableArray","xor","join","cb","_this3","allTemplates","forAllCells","parseTemplate","sortTemplates","forEach","root","_this4","_this$parseExtractor","parseExtractor","Array","isArray","undefined","sizes","entry","get","idx","_this5","iter","transposed","parsedIter","_typeof","inRoot","extractData","unshift","_this6","entrySize","chunk","getCellRange","ri","ci","setCellValue","applyDataStyle","mainCell","_this7","theData","nextCell","sizeMaxxer","Math","max","_loop","d","inFill","inCell","offsetCell","putValues","rowOffset","colOffset","rowPadding","colPadding","rng","getTemplateOpts","mergeCell","rangeMerged","duplicateCell","applyFormula","size","newFormula","newRef","from","getCell","rangeRef","index","shiftFormula","setCellFormula","setRangeFormula","XlsxPopulateAccess","version","_","_RichText","workbook","XlsxPopulate","_workbook","RichText","theValue","text","hyperlink","Date","trimStart","to","rowNumber","columnNumber","cellAddr","address","theSize","sheet","_mergeCells","range","rangeAddr","attributes","ref","style","withSheet","includeSheetName","adr","sheetId","activeSheet","rangeTo","relativeCell","rows","cols","status","merged","sheets","theRange","usedRange","dest","src","_style","_styleId","destSheetId","rowId","colId","row","height","column","width"],"mappings":"CAAA,SAAAA,GAAA,GAAA,iBAAAC,SAAA,oBAAAC,OAAAA,OAAAD,QAAAD,SAAA,GAAA,mBAAAG,QAAAA,OAAAC,IAAAD,OAAA,GAAAH,OAAA,EAAA,oBAAAK,OAAAA,OAAA,oBAAAC,OAAAA,OAAA,oBAAAC,KAAAA,KAAAC,MAAAC,aAAAT,KAAA,EAAA,WAAA,OAAA,SAAAU,EAAAC,EAAAC,EAAAC,GAAA,SAAAC,EAAAC,EAAAf,GAAA,IAAAY,EAAAG,GAAA,CAAA,IAAAJ,EAAAI,GAAA,CAAA,IAAAC,EAAA,mBAAAC,SAAAA,QAAA,IAAAjB,GAAAgB,EAAA,OAAAA,EAAAD,GAAA,GAAA,GAAAG,EAAA,OAAAA,EAAAH,GAAA,GAAA,IAAAI,EAAA,IAAAC,MAAA,uBAAAL,EAAA,KAAA,MAAAI,EAAAE,KAAA,mBAAAF,EAAA,IAAAG,EAAAV,EAAAG,GAAA,CAAAd,QAAA,IAAAU,EAAAI,GAAA,GAAAQ,KAAAD,EAAArB,SAAA,SAAAS,GAAA,OAAAI,EAAAH,EAAAI,GAAA,GAAAL,IAAAA,KAAAY,EAAAA,EAAArB,QAAAS,EAAAC,EAAAC,EAAAC,GAAA,OAAAD,EAAAG,GAAAd,QAAA,IAAA,IAAAiB,EAAA,mBAAAD,SAAAA,QAAAF,EAAA,EAAAA,EAAAF,EAAAW,OAAAT,IAAAD,EAAAD,EAAAE,IAAA,OAAAD,EAAA,CAAA,CAAAW,EAAA,CAAA,SAAAR,EAAAf,EAAAD,gBCAA,koCAEA,IAAMyB,EAAN,oBAAkBrB,OAAlBA,OAAA,OAAA,IAAAC,EAAAA,EAAA,EAAA,KAEMqB,EAAc,CAChBC,eAAgB,kBAChBC,cAAe,IACfC,SAAU,IACVC,YAAY,EACZC,gBAAgB,EAChBC,gBAAgB,EAChBC,WAAW,EACXC,aAAc,CACVC,GAAI,SAAAC,GAAI,OAAIX,EAAEY,KAAKD,IACnBE,EAAG,SAAAF,GAAI,OAAIX,EAAEc,OAAOH,MAItBI,EAAY,6CAKZhC,aAcF,SAAAA,EAAYiC,EAAUC,gGAAMC,CAAApC,KAAAC,GACxBD,KAAKqC,MAAQnB,EAAEoB,aAAa,GAAIH,EAAMhB,GACtCnB,KAAKuC,UAAY,GACjBvC,KAAKwC,UAAY,GACjBxC,KAAKyC,QAAUP,yDAQXQ,GACJ,OAAgB,OAAZA,GACAxB,EAAEyB,MAAM3C,KAAKqC,MAAOK,GACb1C,MAEAA,KAAKqC,uCAQXR,GAAM,IAAAe,EAAA5C,KACL6C,EAAY,GAqClB,OAlCA7C,KAAK8C,kBAAiB,SAAAC,GAClB,IAAMC,EAAQ,CACVD,SAAUA,EACVE,WAAY,GACZC,SAAU,GACVC,WAAW,GAGf,GAAIJ,EAASK,UAAW,CACpB,IAAMC,EAAUR,EAAUE,EAASK,WAEnC,IAAKC,EACD,MAAM,IAAIzC,MAAJ,+BAAA0C,OAAyCP,EAASK,UAAlD,OAENL,EAASQ,QACTF,EAAQH,SAASM,KAAKR,GAEtBK,EAAQJ,WAAWO,KAAKR,GAE5BA,EAAMS,OAASb,EAAKH,QAAQiB,aAAaL,EAAQN,SAASY,KAAMZ,EAASY,MAE7Ed,EAAUE,EAASa,IAAMZ,KAI7B9B,EAAE2C,KAAKhB,GAAW,SAAAiB,GACd,IAAIA,EAAKX,UAAT,CAEK,GAAIW,EAAKf,SAASQ,QACnB,MAAM,IAAI3C,MAAJ,kCAAA0C,OAA4CQ,EAAKC,UAAjD,gCAENnB,EAAKoB,UAAUF,EAAMjC,EAAMiC,EAAKf,SAASY,UAG1C3D,wCASAiE,GACP,IAAMC,EAAYlE,KAAKqC,MAAMV,aAAasC,GAE1C,GAAKC,EAEA,CAAA,GAAyB,mBAAdA,EACZ,MAAM,IAAItD,MAAJ,YAAA0C,OAAsBW,EAAtB,yBAEN,OAAOC,EAJP,MAAM,IAAItD,MAAJ,YAAA0C,OAAsBW,EAAtB,8DAeCF,GAEX,IAAMI,EAAeJ,EAAUK,MAAM,KACjCH,EAAc/C,EAAEmD,KAAKF,EAAa,IAEtC,OAA8B,GAAvBA,EAAanD,OACd,CAAEsD,KAAMP,EAAWQ,QAAS,MAC5B,CACED,KAAMpD,EAAEmD,KAAKF,EAAa,IAC1BI,QAASvE,KAAKwE,WAAWP,2CAYtBN,EAAM9B,EAAMkB,GAAU,IAAA0B,EAAAzE,KAC3B0E,EAAS3B,EAAS2B,OAiBxB,OAfI1E,KAAKqC,MAAMX,WACX1B,KAAKyC,QAAQf,UAAUiC,EAAMZ,EAASY,MAEtCe,GAAU7C,GACVX,EAAE2C,KAAKa,GAAQ,SAAAC,GACX,GAAIzD,EAAE0D,WAAWD,EAAKE,KAAM,KACxBJ,EAAKD,WAAWG,EAAKE,KAAKC,OAAO,IAAI/D,KAAK0D,EAAKpC,MAAOR,EAAM8B,QACzD,IAAKzC,EAAE0D,WAAWD,EAAKE,KAAM,KAAM,CACtC,IAAME,EAAMN,EAAKO,cAAcnD,EAAM8C,EAAKZ,UAAWJ,GACjDoB,GACAN,EAAKhC,QAAQwC,aAAatB,EAAMgB,EAAKE,KAAMK,KAAKC,MAAMJ,QAK/D/E,6CASK+C,GACZ,IAAKA,EAAS2B,OACV,OAAO1E,KAAKqC,MAEhB,IAAMF,EAAOjB,EAAEkE,MAAMpF,KAAKqC,OAM1B,OALAnB,EAAE2C,KAAKd,EAAS2B,QAAQ,SAAAC,GAChBzD,EAAE0D,WAAWD,EAAKE,KAAM,OACxB1C,EAAKwC,EAAKE,KAAKC,OAAO,IAAMI,KAAKC,MAAMR,EAAKZ,eAG7C5B,wCAUGwB,GACV,IAAM0B,EAAQrF,KAAKyC,QAAQ6C,UAAU3B,GACrC,GAAa,MAAT0B,GAAkC,iBAAVA,EACxB,OAAO,KAEX,IAAME,EAAUF,EAAMG,MAAMxF,KAAKqC,MAAMjB,gBACvC,IAAKmE,IAAYvF,KAAKqC,MAAMZ,gBAAkD,YAAhCzB,KAAKyC,QAAQgD,SAAS9B,GAChE,OAAO,KAEX,IAAM+B,EAAQH,EAAQ,GAAGnB,MAAMpE,KAAKqC,MAAMhB,eAAesE,IAAIzE,EAAEmD,MAC3DK,EAAUgB,EAAM,GAAYA,EAAM,GAAGtB,MAAM,KAAtB,KACrBL,EAAY2B,EAAM,IAAM,GACxBE,EAAU5F,KAAKyC,QAAQoD,SAASlC,EAAM+B,EAAM,IAEhD,GAAIA,EAAM1E,OAAS,EACf,MAAM,IAAIJ,MAAJ,0CAAA0C,OAAoDiC,EAAQ,GAA5D,MACV,GAAMG,EAAM,KAAOE,EACf,MAAM,IAAIhF,MAAJ,8BAAA0C,OAAwCoC,EAAM,GAA9C,MAEV,MAAO,CACH9B,GAAI5D,KAAKyC,QAAQmD,QAAQjC,GACzBP,UAAWwC,EACXE,UAAWJ,EAAM,GAAGtB,MAAM,QAAQuB,IAAIzE,EAAEmD,MACxCN,UAAWA,EACXR,QAASQ,EAAUa,WAAW,KAC9BjB,KAAMA,EACNoC,SAAU/F,KAAKyC,QAAQsD,SAASpC,GAChCqC,SAAUN,EAAM,IAAM,IAAItB,MAAM,YAAYuB,KAAI,SAAAM,GAAC,OAAIC,SAASD,IAAM,KACpEvB,OAASA,EAAgBxD,EAAEyE,IAAIjB,GAAQ,SAAAyB,GACnC,IAAMxB,EAAOzD,EAAEmD,KAAK8B,GAAG/B,MAAM,KAC7B,MAAO,CAAES,KAAM3D,EAAEmD,KAAKM,EAAK,IAAKZ,UAAW7C,EAAEmD,KAAKM,EAAK,QAFzC,4CAOZyB,GAOV,IANA,IAAMC,EAAS,GACXC,EAAU,GACVX,EAAM,GACNY,EAAW,GAGNhG,EAAI,EAAGA,EAAI6F,EAAKpF,SAAUT,EAAG,CAClC,IAAMF,EAAI+F,EAAK7F,GACfoF,EAAItF,EAAEuD,IAAMrD,EAEPF,EAAE+C,WAGFkD,EAAQjG,EAAE+C,WAAakD,EAAQjG,EAAE+C,YAAc,IAAII,KAAKnD,EAAEuD,IAF3D2C,EAAS/C,KAAKnD,EAAEuD,IAMxB,KAAO2C,EAASvF,OAAS,GAAG,CACxB,IACIwF,EAAIJ,EAAKT,EADFY,EAASE,UAGpBJ,EAAO7C,KAAKgD,GAGRF,EAAQE,EAAE5C,KACV2C,EAAS/C,KAATkD,MAAAH,EAAQI,EAASL,EAAQE,EAAE5C,MAGnC,GAAIyC,EAAOrF,OAASoF,EAAKpF,OACrB,MAAM,IAAIJ,MAAJ,uCAAA0C,OAAiDpC,EAAEyE,IAAIzE,EAAE0F,IAAIR,EAAMC,GAAS,MAAMQ,KAAK,KAAvF,OAEV,OAAOR,2CAYMS,GAAI,IAAAC,EAAA/G,KACXgH,EAAe,GAQrB,OANAhH,KAAKyC,QAAQwE,aAAY,SAAAtD,GACrB,IAAMZ,EAAWgE,EAAKG,cAAcvD,GAChCZ,GACAiE,EAAaxD,KAAKT,MAGnB/C,KAAKmH,cAAcH,GAAcI,QAAQN,yCAatCO,EAAMtD,EAAWJ,GAAM,IAAA2D,EAAAtH,KAAAuH,EACPvH,KAAKwH,eAAezD,GAAtCO,EADyBiD,EACzBjD,KAAMC,EADmBgD,EACnBhD,QAEd,GAAKkD,MAAMC,QAAQL,IAEd,QAAmBM,IAAfN,EAAKO,MACVP,EAAQtD,EAAmB7C,EAAEyE,IAAI0B,GAAM,SAAAQ,GAAK,OAAIP,EAAKtC,cAAc6C,EAAO9D,EAAWJ,MAAjE0D,OACnB,IAAK9C,EACN,OAAO8C,EAAKR,KAAK7G,KAAKqC,MAAMf,UAAY,UAJxC+F,EAAOnG,EAAE4G,IAAIT,EAAM/C,EAAM+C,GAM7B,OAAQ9C,EAAiBA,EAAQxD,KAAKf,KAAKqC,MAAOgF,EAAM1D,GAAtC0D,sCAYVA,EAAMvB,EAAWiC,GAAK,IAAAC,EAAAhI,KAC1BiI,EAAOnC,EAAUiC,GACjBH,EAAQ,GACRM,GAAa,EACbrG,EAAO,KAOX,GALY,KAARoG,IACAC,GAAa,EACbD,EAAOnC,IAAYiC,KAGlBE,EAAM,OAAOZ,EAGlB,IAAMc,EAAanI,KAAKwH,eAAeS,GAOvC,GALApG,EAAOX,EAAE4G,IAAIT,EAAMc,EAAW7D,KAAM+C,GAEF,mBAAvBc,EAAW5D,UAClB1C,EAAOsG,EAAW5D,QAAQxD,KAAKf,KAAKqC,MAAOR,KAE1C4F,MAAMC,QAAQ7F,IAAyB,WAAhBuG,EAAOvG,GAC/B,OAAOA,EASX,GARSkG,EAAMjC,EAAU9E,OAAS,IAE9B4G,GADA/F,EAAOX,EAAEyE,IAAI9D,GAAM,SAAAwG,GAAM,OAAIL,EAAKM,YAAYD,EAAQvC,EAAWiC,EAAM,OAC1D,GAAGH,OAAS,KAMxB/F,EACD,MAAM,IAAIjB,MAAJ,iBAAA0C,OAA2B2E,EAA3B,yBACL,GAAoB,WAAhBG,EAAOvG,GACZ,MAAM,IAAIjB,MAAJ,qCAAA0C,OAA+C2E,EAA/C,uCAIV,OAFAL,EAAMW,QAAQL,GAAcrG,EAAKb,OAASa,EAAKb,QAC/Ca,EAAK+F,MAAQA,EACN/F,oCAWD8B,EAAM9B,EAAMkB,GAAU,IAAAyF,EAAAxI,KAC5B,IAAK2D,EAAM,MAAM,IAAI/C,MAAM,gDAE3B,IAAI6H,EAAY5G,EAAK+F,MACjBvC,EAAQrF,KAAKgF,cAAcnD,EAAMkB,EAASgB,UAAWJ,GAGzD,GAAK8D,MAAMC,QAAQrC,IAAWoD,GAAcA,EAAUzH,OAI/C,CAAA,KAAIyH,EAAUzH,QAAU,GAiB3B,MAAM,IAAIJ,MAAJ,0BAAA0C,OAAoCP,EAASgB,UAA7C,kCAfF0E,EAAU,GAAK,GACfA,EAAY,CAAC,GAAIA,EAAU,IAC3BpD,EAAQ,CAACA,GACTxD,EAAO,CAACA,IACmB,GAApB4G,EAAUzH,SACjByH,EAAYA,EAAUnF,OAAO,CAAC,IAC9B+B,EAAQnE,EAAEwH,MAAMrD,EAAO,GACvBxD,EAAOX,EAAEwH,MAAM7G,EAAM,IAGzB7B,KAAKyC,QAAQkG,aAAahF,EAAM8E,EAAU,GAAK,EAAGA,EAAU,GAAK,GAAGrB,SAAQ,SAACzD,EAAMiF,EAAIC,GACnFL,EAAK/F,QAAQqG,aAAanF,EAAM0B,EAAMuD,GAAIC,IAC1CL,EAAKO,eAAepF,EAAM9B,EAAK+G,GAAIC,GAAK9F,WAjB5C/C,KAAKyC,QAAQqG,aAAanF,EAAM0B,GAChCrF,KAAK+I,eAAepF,EAAM9B,EAAMkB,GAChC0F,EAAY1F,EAASgD,SAoBzB,OAAO0C,oCAWDzF,EAAOqE,EAAM2B,GAAU,IAAAC,EAAAjJ,KACvB+C,EAAWC,EAAMD,SACnBmG,EAAUlJ,KAAKsI,YAAYjB,EAAMtE,EAAS+C,UAAW,GAErD2C,EAAY,CAAC,EAAG,GAEpB,GAAKzF,EAAMC,YAAeD,EAAMC,WAAWjC,OAEtC,CAID,IAHA,IAAImI,EAAWH,EACTI,EAAa,SAACrE,EAAKgD,GAAN,OAAcU,EAAUV,GAAOsB,KAAKC,IAAIb,EAAUV,GAAMhD,IAF1EwE,EAAA,SAIQC,GAGL,IAFA,IAAMnB,EAASa,EAAQM,GAEdhK,EAAI,EAAGA,EAAIwD,EAAMC,WAAWjC,SAAUxB,EAAG,CAC9C,IAAMiK,EAASzG,EAAMC,WAAWzD,GAC5BkK,EAAST,EAAKxG,QAAQkH,WAAWR,EAAUM,EAAOhG,OAAO,GAAIgG,EAAOhG,OAAO,IAE/EvC,EAAEkG,QAAQ6B,EAAKjF,UAAUyF,EAAQpB,EAAQqB,GAASN,GAItDlI,EAAEkG,QAAQ6B,EAAKW,UAAUT,EAAUd,EAAQtF,GAAWqG,GAEtD,IAAIS,EAAYpB,EAAU,GACtBqB,EAAYrB,EAAU,GACtBsB,EAAahH,EAASiD,QAAQ,IAAM,EACpCgE,EAAajH,EAASiD,QAAQ,IAAM,EAaxC,GAVIkD,EAAQtB,MAAM,GAAK,GACf7E,EAASiD,QAAQhF,OAAS,IAC1BgJ,EAAaD,GACjBF,EAAYE,EAAa,EACzBtB,EAAU,GAAK,GACRS,EAAQtB,MAAM5G,OAAS,IAC9B8I,EAAYE,EAAa,EACzBvB,EAAU,GAAK,GAGfoB,EAAY,GAAKC,EAAY,EAAG,CAChC,IAAMG,EAAMhB,EAAKxG,QAAQkG,aAAaQ,EAAUE,KAAKC,IAAIO,EAAY,EAAG,GAAIR,KAAKC,IAAIQ,EAAY,EAAG,IAChGzH,EAAQ4G,EAAKiB,gBAAgBnH,IAER,IAArBV,EAAMd,YAA2C,SAApBc,EAAM8H,WAChCN,EAAY,GAA0B,aAArBxH,EAAMd,YACvBuI,EAAY,GAA0B,eAArBzH,EAAMd,WAC1B0H,EAAKxG,QAAQ2H,YAAYH,GAAK,KACA,IAAzB5H,EAAMb,gBAAoD,SAAzBa,EAAMb,gBACzCqI,EAAY,GAA8B,aAAzBxH,EAAMb,gBACvBsI,EAAY,GAA8B,eAAzBzH,EAAMb,iBAC1ByH,EAAKxG,QAAQ4H,cAAclB,EAAUc,GAEzCA,EAAI7C,SAAQ,SAAAzD,GAAI,OAAIsF,EAAKF,eAAepF,EAAM0E,EAAQtF,MAI1DoG,EAAWF,EAAKxG,QAAQkH,WAAWR,EAAUU,EAAYE,EAAYD,EAAYE,IA9C5ER,EAAI,EAAGA,EAAIN,EAAQlI,SAAUwI,EAAGD,EAAhCC,GAkDTtI,EAAEkG,QAAQpH,KAAKyC,QAAQiB,aAAasF,EAAUG,GAAWC,QAvDzDX,EAAYzI,KAAK4J,UAAUZ,EAAUE,EAASnG,GA6DlD,OAHA7B,EAAEkG,QAAQpE,EAAME,UAAU,SAAA1D,GAAC,OAAIyJ,EAAKqB,aAAa9K,EAAGiJ,EAAWO,MAE/DhG,EAAMG,WAAY,EACXsF,uCAWElF,EAASE,EAAQ8G,GAG1B,IAFA,IAAIC,EAAa,KAER,CACL,IAAMhF,EAAQjC,EAAQiC,MAAMvD,GAC5B,IAAKuD,EAAO,MAEZ,IACIiF,EADAC,EAAO1K,KAAKyC,QAAQkI,QAAQnF,EAAM,GAAIA,EAAM,KAG5C/B,EAAO,GAAK,GAAKA,EAAO,GAAK,KAC7BiH,EAAO1K,KAAKyC,QAAQkH,WAAWe,EAAMjH,EAAO,GAAIA,EAAO,KAE3DgH,EAAUjF,EAAM,GAEVxF,KAAKyC,QAAQmI,SAAS5K,KAAKyC,QAAQkG,aAAa+B,EAAMH,EAAK,GAAIA,EAAK,MAAO/E,EAAM,IADjFxF,KAAKyC,QAAQmD,QAAQ8E,IAAQlF,EAAM,IAGzCgF,GAAcjH,EAAQuB,OAAO,EAAGU,EAAMqF,OAASJ,EAC/ClH,EAAUA,EAAQuB,OAAOU,EAAMqF,MAAQrF,EAAM,GAAGxE,QAIpD,OADAwJ,GAAcjH,uCAaLP,EAAOyF,EAAW9E,GAC3BA,EAAO3D,KAAKyC,QAAQkH,WAAWhG,EAAMX,EAAMS,OAAO,GAAIT,EAAMS,OAAO,IAEnE,IAKIwG,EALElH,EAAWC,EAAMD,SACnBkF,EAAO/G,EAAEmD,KAAKtB,EAAS+C,UAAU,IACjCrC,EAASzD,KAAKyC,QAAQiB,aAAaX,EAASY,KAAMA,GAElDJ,EAAUR,EAASgB,UAMvB,GAHAf,EAAMG,WAAY,EAClBnD,KAAKyC,QAAQqG,aAAanF,EAAM,MAE5B8E,EAAU,GAAK,GAAKA,EAAU,GAAK,GAAc,SAATR,EACxC1E,EAAUvD,KAAK8K,aAAavH,EAASE,EAAQ,CAAC,EAAG,IACjDwG,EAAMjK,KAAKyC,QAAQkG,aAAahF,EAAM8E,EAAU,GAAK,EAAGA,EAAU,GAAK,QACpE,GAAa,SAATR,EACP1E,EAAUvD,KAAK8K,aAAavH,EAASE,EAAQ,CAACgF,EAAU,GAAK,EAAG,IAChEwB,EAAMjK,KAAKyC,QAAQkG,aAAahF,EAAM,EAAG8E,EAAU,GAAK,OACrD,CAAA,GAAa,SAATR,EAKP,YADAjI,KAAKyC,QAAQsI,eAAepH,EAAM3D,KAAK8K,aAAavH,EAASE,EAAQ,CAACgF,EAAU,GAAK,EAAGA,EAAU,GAAK,KAHvGlF,EAAUvD,KAAK8K,aAAavH,EAASE,EAAQ,CAAC,EAAGgF,EAAU,GAAK,IAChEwB,EAAMjK,KAAKyC,QAAQkG,aAAahF,EAAM8E,EAAU,GAAK,EAAG,GAM5DzI,KAAKyC,QAAQuI,gBAAgBf,EAAK1G,wCAQ1CtD,EAAagL,mBAAqBxK,EAAQ,wBAC1CR,EAAaiL,QAAU,QAEvBxL,EAAOD,QAAUQ,iLChjBjB,wZAEA,IAAMkL,EAEN,oBAFkBtL,OAElBA,OAAA,OAAA,IAAAC,EAAAA,EAAA,EAAA,KAoCIsL,EAAY,KAMVH,aASF,SAAAA,EAAYI,EAAUC,gGAAclJ,CAAApC,KAAAiL,GAChCjL,KAAKuL,UAAYF,EACjBrL,KAAKuC,UAAY,GACjBvC,KAAKwC,UAAY,GAEjB4I,EAAYE,EAAaE,mEAQzB,OAAOxL,KAAKuL,4CAQN5H,GACN,IAAM8H,EAAW9H,EAAK0B,QACtB,OAAOoG,aAAoBL,EAAYK,EAASC,OAASD,uCAShD9H,EAAM0B,GAEf,OADA1B,EAAK0B,MAAMA,GACJrF,sCASF2D,GACL,GAAIA,EAAKJ,UACL,MAAO,UACN,GAAII,EAAKgI,YACV,MAAO,YAEX,IAAMF,EAAW9H,EAAK0B,QACtB,OAAIoG,aAAoBL,EACb,WACFK,aAAoBG,KAClB,OAEPxD,EAAcqD,0CASP9H,EAAMJ,GAEjB,OADAI,EAAKJ,QAAQ4H,EAAEU,UAAUtI,EAAS,OAC3BvD,0CASE0K,EAAMoB,GACf,MAAO,CACHA,EAAGC,YAAcrB,EAAKqB,YACtBD,EAAGE,eAAiBtB,EAAKsB,iDASxBrI,GAAM,IAAAf,EAAA5C,KACLiM,EAAWtI,EAAKuI,UAClBC,EAAU,CAAC,EAAG,GAYlB,OAVAhB,EAAE/D,QAAQzD,EAAKyI,QAAQC,aAAa,SAAAC,GAChC,IAAMC,EAAYD,EAAME,WAAWC,IAAIrI,MAAM,KAC7C,GAAImI,EAAU,IAAMN,EAIhB,SAHAE,EAAUvJ,EAAKc,aAAaC,EAAMA,EAAKyI,QAAQzI,KAAK4I,EAAU,MACpD,KACRJ,EAAQ,IACH,KAIRA,uCAUExI,EAAMkB,EAAMQ,GAErB,OADA1B,EAAK+I,MAAM7H,EAAMQ,GACVrF,qCASH2D,EAAMgJ,GAGV,OAFiB,MAAbA,IACAA,GAAY,GACThJ,EAAKuI,QAAQ,CAAEU,iBAAkBD,qCAUnChJ,EAAMkJ,EAAKF,GAGhB,OAFiB,MAAbA,IACAA,GAAY,GACTE,EAAMlJ,EAAKyI,QAAQzI,KAAKkJ,GAAKX,QAAQ,CAAEU,iBAAkBD,IAAe,qCAS3ET,EAASY,GAEb,OAD4B,MAAXA,EAAkB9M,KAAKuL,UAAUwB,cAAgB/M,KAAKuL,UAAUa,MAAMU,IACvEnJ,KAAKuI,yCASXvI,EAAM2I,GAEhB,OADAA,EAAMjH,MAAM1B,EAAK0B,SACVrF,0CAUE2D,EAAMkG,EAAWC,GAC1B,OAAOnG,EAAKqJ,QAAQrJ,EAAKsJ,aAAapD,EAAWC,uCAU1CnG,EAAMuJ,EAAMC,GACnB,OAAOxJ,EAAKsJ,aAAaC,EAAMC,uCASvBb,EAAOc,GACf,YAAezF,IAAXyF,EACOd,EAAMe,UAEbf,EAAMe,OAAOD,GACNpN,8CAUCsM,EAAO/I,GAEnB,OADA+I,EAAM/I,QAAQ4H,EAAEU,UAAUtI,EAAS,OAC5BvD,sCASFsM,EAAOK,GAGZ,OAFiB,MAAbA,IACAA,GAAY,GACTL,EAAMJ,QAAQ,CAAEU,iBAAkBD,wCAQjC7F,GAMR,OALA9G,KAAKuL,UAAU+B,SAASlG,SAAQ,SAAAgF,GAC5B,IAAMmB,EAAWnB,EAAMoB,YACnBD,GACAA,EAASnG,QAAQN,MAElB9G,uCASDyN,EAAMC,GACZ,IAAKA,IAAQD,EAAM,MAAM,IAAI7M,MAAM,gDACnC,GAAI8M,GAAOD,EAAM,OAAOzN,UAEL2H,IAAf+F,EAAIC,OACJF,EAAKf,MAAMgB,EAAIC,QACVD,EAAIE,SAAW,IACpBH,EAAKG,SAAWF,EAAIE,UAExB,IAAMC,EAAcJ,EAAKrB,QAAQvH,OAC7BiJ,EAAK,IAAAxK,OAAOuK,EAAP,MAAAvK,OAAuBmK,EAAK1B,aACjCgC,EAAK,IAAAzK,OAAOuK,EAAP,MAAAvK,OAAuBmK,EAAKzB,gBAQrC,YAN8BrE,IAA1B3H,KAAKuC,UAAUuL,IACfL,EAAKO,MAAMC,OAAOjO,KAAKuC,UAAUuL,GAASJ,EAAIM,MAAMC,eAE1BtG,IAA1B3H,KAAKwC,UAAUuL,IACfN,EAAKS,SAASC,MAAMnO,KAAKwC,UAAUuL,GAASL,EAAIQ,SAASC,SAEtDnO,0CAIfN,EAAOD,QAAUwL,iIFjUjB","file":"xlsx-datafill.min.js","sourcesContent":["(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 _.keys(data),\n $: data => _.values(data)\n }\n};\n\nconst refRegExp = /('?([^!]*)?'?!)?([A-Z]+\\d+)(:([A-Z]+\\d+))?/;\n\n/**\n * Data fill engine, taking an instance of Excel sheet accessor and a JSON object as data, and filling the values from the latter into the former.\n */\nclass XlsxDataFill {\n /**\n * Constructs a new instance of XlsxDataFill with given options.\n * @param {object} accessor An instance of XLSX spreadsheet accessing class.\n * @param {{}} opts Options to be used during processing.\n * @param {RegExp} opts.templateRegExp The regular expression to be used for template recognizing. Default is `/\\{\\{([^}]*)\\}\\}/`, i.e. Mustache.\n * @param {string|RegExo} opts.fieldSplitter The string or regular expression to be used as template fields splitter. Default is `|`.\n * @param {string} opts.joinText The string to be used when the extracted value for a single cell is an array, and it needs to be joined. Default is `,`.\n * @param {string|boolean} opts.mergeCells Whether to merge the higher dimension cells in the output. Default is true, but valid values are also `\"both\"`, `\"vertical\"` and `\"horizontal\"`.\n * @param {string|boolean} opts.duplicateCells Whether to duplicate the content of higher dimension cells, when not merged. Default is false. Same valud values as `mergeCells`.\n * @param {boolean} opts.followFormulae If a template is located as a result of a formula, whether to still process it. Default is false.\n * @param {boolean} opts.copyStyle Copy the style of the template cell when populating. Even when `false`, the template styling _is_ applied. Default is true.\n * @param {object.} opts.callbacksMap A map of handlers to be used for data and value extraction.\n */\n constructor(accessor, opts) {\n this._opts = _.defaultsDeep({}, opts, defaultOpts);\n this._rowSizes = {};\n this._colSizes = {};\n this._access = accessor;\n }\n\n /**\n * Setter/getter for XlsxDataFill's options as set during construction.\n * @param {{}|null} newOpts If set - the new options to be used. Check [up here]{@link #new-xlsxdatafillaccessor-opts}.\n * @returns {XlsxDataFill|{}} The required options (in getter mode) or XlsxDataFill (in setter mode) for chaining.\n */\n options(newOpts) {\n if (newOpts !== null) {\n _.merge(this._opts, newOpts);\n return this;\n } else\n return this._opts;\n }\n\n /**\n * The main entry point for whole data population mechanism.\n * @param {{}} data The data to be applied.\n * @returns {XlsxDataFill} For invocation chaining.\n */\n fillData(data) {\n const dataFills = {};\n\t\n // Build the dependency connections between templates.\n this.collectTemplates(template => {\n const aFill = { \n template: template, \n dependents: [],\n formulas: [],\n processed: false\n };\n\n if (template.reference) {\n const refFill = dataFills[template.reference];\n \n if (!refFill) \n throw new Error(`Unable to find a reference '${template.reference}'!`);\n \n if (template.formula) \n refFill.formulas.push(aFill);\n else\n refFill.dependents.push(aFill);\n \n aFill.offset = this._access.cellDistance(refFill.template.cell, template.cell);\n }\n dataFills[template.id] = aFill;\n });\n \n // Apply each fill onto the sheet.\n _.each(dataFills, fill => {\n if (fill.processed)\n return;\n else if (fill.template.formula)\n throw new Error(`Non-referencing formula found '${fill.extractor}'. Use a non-templated one!`);\n else\n this.applyFill(fill, data, fill.template.cell);\n });\n\n return this;\n }\n\n /**\n * Retrieves the provided handler from the map.\n * @param {string} handlerName The name of the handler.\n * @returns {function} The handler function itself.\n * @ignore\n */\n getHandler(handlerName) {\n const handlerFn = this._opts.callbacksMap[handlerName];\n\n if (!handlerFn)\n throw new Error(`Handler '${handlerName}' cannot be found!`);\n else if (typeof handlerFn !== 'function')\n throw new Error(`Handler '${handlerName}' is not a function!`);\n else \n return handlerFn;\n }\n\n /**\n * Parses the provided extractor (ot iterator) string to find a callback id inside, if present.\n * @param {string} extractor The iterator/extractor string to be investigated.\n * @returns {object.} A { `path`, `handler` } object representing the JSON path\n * ready for use and the provided `handler` _function_ - ready for invoking, if such is provided.\n * If not - the `path` property contains the provided `extractor`, and the `handler` is `null`.\n * @ignore\n */\n parseExtractor(extractor) {\n // A specific extractor can be specified after semilon - find and remember it.\n const extractParts = extractor.split(\":\"),\n handlerName = _.trim(extractParts[1]);\n\n return extractParts.length == 1\n ? { path: extractor, handler: null }\n : {\n path: _.trim(extractParts[0]),\n handler: this.getHandler(handlerName)\n };\n }\n\n /**\n * Applies the style part of the template onto a given cell.\n * @param {Cell} cell The destination cell to apply styling to.\n * @param {{}} data The data chunk for that cell.\n * @param {{}} template The template to be used for that cell.\n * @returns {DataFiller} For invocation chaining.\n * @ignore\n */\n applyDataStyle(cell, data, template) {\n const styles = template.styles;\n\n if (this._opts.copyStyle)\n this._access.copyStyle(cell, template.cell);\n \n if (styles && data) {\n _.each(styles, pair => {\n if (_.startsWith(pair.name, \":\")) {\n this.getHandler(pair.name.substr(1)).call(this._opts, data, cell);\n } else if (!_.startsWith(pair.name, \"!\")) {\n const val = this.extractValues(data, pair.extractor, cell);\n if (val)\n this._access.setCellStyle(cell, pair.name, JSON.parse(val));\n }\n });\n }\n\n return this;\n }\n\n /**\n * Extract the options-specific parameters from the styles field and merge them with the global ones.\n * @param {{}} template The template to extract options properties from.\n * @returns {{}} The full options, \n * @ignore\n */\n getTemplateOpts(template) {\n if (!template.styles)\n return this._opts;\n \n const opts = _.clone(this._opts);\n _.each(template.styles, pair => {\n if (_.startsWith(pair.name, \"!\"))\n opts[pair.name.substr(1)] = JSON.parse(pair.extractor);\n });\n\n return opts;\n }\n\n /**\n * Parses the contents of the cell into a valid template info.\n * @param {Cell} cell The cell containing the template to be parsed.\n * @returns {{}} The parsed template.\n * @description This method builds template info, taking into account the supplied options.\n * @ignore\n */\n parseTemplate(cell) {\n const value = this._access.cellValue(cell);\n if (value == null || typeof value !== 'string')\n return null;\n \n const reMatch = value.match(this._opts.templateRegExp);\n if (!reMatch || !this._opts.followFormulae && this._access.cellType(cell) === 'formula') \n return null;\n \n const parts = reMatch[1].split(this._opts.fieldSplitter).map(_.trim),\n styles = !parts[4] ? null : parts[4].split(\",\"),\n extractor = parts[2] || \"\",\n cellRef = this._access.buildRef(cell, parts[0]);\n \n if (parts.length < 2) \n throw new Error(`Not enough components of the template '${reMatch[0]}'`);\n if (!!parts[0] && !cellRef)\n throw new Error(`Invalid reference passed: '${parts[0]}'`);\n\n return {\n id: this._access.cellRef(cell),\n reference: cellRef,\n iterators: parts[1].split(/x|\\*/).map(_.trim),\n extractor: extractor,\n formula: extractor.startsWith(\"=\"),\n cell: cell,\n cellSize: this._access.cellSize(cell),\n padding: (parts[3] || \"\").split(/:|,|x|\\*/).map(v => parseInt(v) || 0),\n styles: !styles ? null : _.map(styles, s => {\n const pair = _.trim(s).split(\"=\");\n return { name: _.trim(pair[0]), extractor: _.trim(pair[1]) };\n })\n };\n }\n\n sortTemplates(list) {\n const sorted = [],\n related = {},\n map = {},\n freeList = [];\n\n // First, make the dependency map and add the list of non-referencing templates\n for (let i = 0; i < list.length; ++i) {\n const t = list[i];\n map[t.id] = i;\n\n if (!t.reference)\n freeList.push(t.id);\n else \n (related[t.reference] = related[t.reference] || []).push(t.id);\n }\n\n // Now, make the actual sorting.\n while (freeList.length > 0) {\n const id = freeList.shift(),\n t = list[map[id]];\n\n sorted.push(t);\n \n // We use the fact that there is a single predecessor in our setup.\n if (related[t.id])\n freeList.push(...related[t.id]);\n }\n\n if (sorted.length < list.length)\n throw new Error(`A reference cycle found, involving \"${_.map(_.xor(list, sorted), 'id').join(',')}\"!`);\n\n return sorted;\n }\n \n /**\n * Searches the whole workbook for template pattern and constructs the templates for processing.\n * @param {Function} cb The callback to be invoked on each templated, after they are sorted.\n * @returns {undefined}\n * @description The templates collected are sorted, based on the intra-template reference - if one template\n * is referring another one, it'll appear _later_ in the returned array, than the referred template.\n * This is the order the callback is being invoked on.\n * @ignore\n */\n collectTemplates(cb) {\n const allTemplates = [];\n \n this._access.forAllCells(cell => {\n const template = this.parseTemplate(cell);\n if (template)\n allTemplates.push(template);\n });\n \n return this.sortTemplates(allTemplates).forEach(cb);\n }\n\n /**\n * Extracts the value(s) from the provided data `root` to be set in the provided `cell`.\n * @param {{}} root The data root to be extracted values from.\n * @param {string} extractor The extraction string provided by the template. Usually a JSON path within the data `root`.\n * @param {Cell} cell A reference cell, if such exists.\n * @returns {string|number|Date|Array|Array.>} The value to be used.\n * @description This method is used even when a whole - possibly rectangular - range is about to be set, so it can\n * return an array of arrays.\n * @ignore\n */\n extractValues(root, extractor, cell) {\n const { path, handler } = this.parseExtractor(extractor);\n\n if (!Array.isArray(root))\n root = _.get(root, path, root);\n else if (root.sizes !== undefined)\n root = !extractor ? root : _.map(root, entry => this.extractValues(entry, extractor, cell));\n else if (!handler)\n return root.join(this._opts.joinText || \",\");\n\n return !handler ? root : handler.call(this._opts, root, cell);\n }\n\n /**\n * Extracts an array (possibly of arrays) with data for the given fill, based on the given\n * root object.\n * @param {{}} root The main reference object to apply iterators to.\n * @param {Array} iterators List of iterators - string JSON paths inside the root object.\n * @param {Number} idx The index in the iterators array to work on.\n * @returns {Array|Array.} An array (possibly of arrays) with extracted data.\n * @ignore\n */\n extractData(root, iterators, idx) {\n let iter = iterators[idx],\n sizes = [],\n transposed = false,\n data = null;\n\n if (iter == '1') {\n transposed = true;\n iter = iterators[++idx];\n }\n\n if (!iter) return root;\n\n // A specific extractor can be specified after semilon - find and remember it.\n const parsedIter = this.parseExtractor(iter);\n\n data = _.get(root, parsedIter.path, root);\n \n if (typeof parsedIter.handler === 'function')\n data = parsedIter.handler.call(this._opts, data);\n\n if (!Array.isArray(data) && typeof data === 'object')\n return data;\n else if (idx < iterators.length - 1) {\n data = _.map(data, inRoot => this.extractData(inRoot, iterators, idx + 1));\n sizes = data[0].sizes || [];\n }\n \n // data = _.values(data);\n\n // Some data sanity checks.\n if (!data)\n throw new Error(`The iterator '${iter}' extracted no data!`);\n else if (typeof data !== 'object')\n throw new Error(`The data extracted from iterator '${iter}' is neither an array, nor object!`);\n\n sizes.unshift(transposed ? -data.length : data.length);\n data.sizes = sizes;\n return data;\n }\n\n /**\n * Put the data values into the proper cells, with correct extracted values.\n * @param {{}} cell The starting cell for the data to be put.\n * @param {Array} data The actual data to be put. The values will be _extracted_ from here first.\n * @param {{}} template The template that is being implemented with that data fill.\n * @returns {Array} Matrix size that this data has occupied on the sheet [rows, cols].\n * @ignore\n */\n putValues(cell, data, template) {\n if (!cell) throw new Error(\"Crash! Null reference cell in 'putValues()'!\");\n\n let entrySize = data.sizes,\n value = this.extractValues(data, template.extractor, cell);\n\n // if we've come up with a raw data\n if (!Array.isArray(value) || !entrySize || !entrySize.length) {\n this._access.setCellValue(cell, value);\n this.applyDataStyle(cell, data, template);\n entrySize = template.cellSize;\n } else if (entrySize.length <= 2) {\n // Normalize the size and data.\n if (entrySize[0] < 0) {\n entrySize = [1, -entrySize[0]];\n value = [value];\n data = [data];\n } else if (entrySize.length == 1) {\n entrySize = entrySize.concat([1]);\n value = _.chunk(value, 1);\n data = _.chunk(data, 1);\n }\n\n this._access.getCellRange(cell, entrySize[0] - 1, entrySize[1] - 1).forEach((cell, ri, ci) => {\n this._access.setCellValue(cell, value[ri][ci]);\n this.applyDataStyle(cell, data[ri][ci], template);\n });\n } else\n throw new Error(`Values extracted with '${template.extractor}' are more than 2 dimension!'`);\n\n return entrySize;\n }\n\n /**\n * Apply the given filter onto the sheet - extracting the proper data, following dependent fills, etc.\n * @param {{}} aFill The fill to be applied, as constructed in the {@link fillData} method.\n * @param {{}} root The data root to be used for data extraction.\n * @param {Cell} mainCell The starting cell for data placement procedure.\n * @returns {Array} The size of the data put in [row, col] format.\n * @ignore\n */\n applyFill(aFill, root, mainCell) {\n const template = aFill.template,\n theData = this.extractData(root, template.iterators, 0);\n\n let entrySize = [1, 1];\n\n if (!aFill.dependents || !aFill.dependents.length)\n entrySize = this.putValues(mainCell, theData, template);\n else {\n let nextCell = mainCell;\n const sizeMaxxer = (val, idx) => entrySize[idx] = Math.max(entrySize[idx], val);\n\n for (let d = 0; d < theData.length; ++d) {\n const inRoot = theData[d];\n\n for (let f = 0; f < aFill.dependents.length; ++f) {\n const inFill = aFill.dependents[f],\n inCell = this._access.offsetCell(nextCell, inFill.offset[0], inFill.offset[1]);\n \n _.forEach(this.applyFill(inFill, inRoot, inCell), sizeMaxxer);\n }\n\n // Now we have the inner data put and the size calculated.\n _.forEach(this.putValues(nextCell, inRoot, template), sizeMaxxer);\n\n let rowOffset = entrySize[0],\n colOffset = entrySize[1],\n rowPadding = template.padding[0] || 0,\n colPadding = template.padding[1] || 0;\n\n // Make sure we grow only on one dimension.\n if (theData.sizes[0] < 0) {\n if (template.padding.length < 2)\n colPadding = rowPadding;\n rowOffset = rowPadding = 0;\n entrySize[1] = 1;\n } else if (theData.sizes.length < 2) {\n colOffset = colPadding = 0;\n entrySize[0] = 1;\n }\n\n if (rowOffset > 1 || colOffset > 1) {\n const rng = this._access.getCellRange(nextCell, Math.max(rowOffset - 1, 0), Math.max(colOffset - 1, 0)),\n _opts = this.getTemplateOpts(template);\n\n if (_opts.mergeCells === true || _opts.mergeCell === 'both'\n || rowOffset > 1 && _opts.mergeCells === 'vertical' \n || colOffset > 1 && _opts.mergeCells === 'horizontal')\n this._access.rangeMerged(rng, true);\n else if (_opts.duplicateCells === true || _opts.duplicateCells === 'both'\n || rowOffset > 1 && _opts.duplicateCells === 'vertical' \n || colOffset > 1 && _opts.duplicateCells === 'horizontal')\n this._access.duplicateCell(nextCell, rng);\n\n rng.forEach(cell => this.applyDataStyle(cell, inRoot, template));\n }\n\n // Finally, calculate the next cell.\n nextCell = this._access.offsetCell(nextCell, rowOffset + rowPadding, colOffset + colPadding);\t\n }\n\n // Now recalc combined entry size.\n _.forEach(this._access.cellDistance(mainCell, nextCell), sizeMaxxer);\n }\n\n _.forEach(aFill.formulas, f => this.applyFormula(f, entrySize, mainCell));\n\n aFill.processed = true;\n return entrySize;\n }\n\n /**\n * Process a formula be shifting all the fixed offset.\n * @param {String} formula The formula to be shifted.\n * @param {Array} offset The offset of the referenced template to the formula one.\n * @param {Array} size The size of the ranges as they should be.\n * @returns {String} The processed text.\n * @ignore\n */\n shiftFormula(formula, offset, size) {\n let newFormula = '';\n\n for (;;) {\n const match = formula.match(refRegExp);\n if (!match) break;\n\n let from = this._access.getCell(match[3], match[2]),\n newRef = null;\n\n if (offset[0] > 0 || offset[1] > 0)\n from = this._access.offsetCell(from, offset[0], offset[1]);\n\n newRef = !match[5]\n ? this._access.cellRef(from, !!match[2])\n : this._access.rangeRef(this._access.getCellRange(from, size[0], size[1]), !!match[2]);\n\n newFormula += formula.substr(0, match.index) + newRef;\n formula = formula.substr(match.index + match[0].length);\n }\n\n newFormula += formula;\n return newFormula;\n }\n\n /**\n * Apply the given formula in the sheet, i.e. changing it to match the \n * sizes of the references templates.\n * @param {{}} aFill The fill to be applied, as constructed in the {@link fillData} method.\n * @param {Array} entrySize The fill-to-size map, as constructed so far\n * @param {Cell} cell The cell to put/start this formula into\n * @returns {undefined}\n * @ignore\n */\n applyFormula(aFill, entrySize, cell) {\n cell = this._access.offsetCell(cell, aFill.offset[0], aFill.offset[1]);\n\n const template = aFill.template,\n iter = _.trim(template.iterators[0]),\n offset = this._access.cellDistance(template.cell, cell);\n \n let formula = template.extractor, \n rng;\n \n aFill.processed = true;\n this._access.setCellValue(cell, null);\n\n if (entrySize[0] < 2 && entrySize[1] < 2 || iter === 'both') {\n formula = this.shiftFormula(formula, offset, [0, 0]);\n rng = this._access.getCellRange(cell, entrySize[0] - 1, entrySize[1] - 1);\n } else if (iter === 'cols') {\n formula = this.shiftFormula(formula, offset, [entrySize[0] - 1, 0]);\n rng = this._access.getCellRange(cell, 0, entrySize[1] - 1);\n } else if (iter === 'rows') {\n formula = this.shiftFormula(formula, offset, [0, entrySize[1] - 1]);\n rng = this._access.getCellRange(cell, entrySize[0] - 1, 0);\n } else { // i.e. 'none'\n this._access.setCellFormula(cell, this.shiftFormula(formula, offset, [entrySize[0] - 1, entrySize[1] - 1]));\n return;\n }\n\n this._access.setRangeFormula(rng, formula);\n }\n}\n\n/**\n * The built-in accessor based on xlsx-populate npm module\n * @type {XlsxPopulateAccess}\n */\nXlsxDataFill.XlsxPopulateAccess = require('./XlsxPopulateAccess');\nXlsxDataFill.version = \"{{VERSION}}\";\n\nmodule.exports = XlsxDataFill;\n","\"use strict\";\n\nconst _ = require('lodash');\n\n// const allStyles = [\n// \"bold\", \n// \"italic\", \n// \"underline\", \n// \"strikethrough\", \n// \"subscript\", \n// \"superscript\", \n// \"fontSize\", \n// \"fontFamily\", \n// \"fontGenericFamily\", \n// \"fontScheme\", \n// \"fontColor\", \n// \"horizontalAlignment\", \n// \"justifyLastLine\", \n// \"indent\", \n// \"verticalAlignment\", \n// \"wrapText\", \n// \"shrinkToFit\", \n// \"textDirection\", \n// \"textRotation\", \n// \"angleTextCounterclockwise\", \n// \"angleTextClockwise\", \n// \"rotateTextUp\", \n// \"rotateTextDown\", \n// \"verticalText\", \n// \"fill\", \n// \"border\", \n// \"borderColor\", \n// \"borderStyle\", \n// \"leftBorder\", \"rightBorder\", \"topBorder\", \"bottomBorder\", \"diagonalBorder\", \n// \"leftBorderColor\", \"rightBorderColor\", \"topBorderColor\", \"bottomBorderColor\", \"diagonalBorderColor\", \n// \"leftBorderStyle\", \"rightBorderStyle\", \"topBorderStyle\", \"bottomBorderStyle\", \"diagonalBorderStyle\", \n// \"diagonalBorderDirection\", \n// \"numberFormat\"\n// ];\n\nlet _RichText = null;\n\n/**\n * `xslx-populate` library based accessor to a given Excel workbook. All these methods are internally used by {@link XlsxDataFill}, \n * but can be used as a reference for implementing custom spreadsheet accessors.\n */\nclass XlsxPopulateAccess {\n /**\n * Constructs a new instance of XlsxSmartTemplate with given options.\n * @param {Workbook} workbook - The workbook to be accessed.\n * @param {XlsxPopulate} XlsxPopulate - The actual xlsx-populate library object.\n * @description The `XlsxPopulate` object need to be passed in order to extract\n * certain information from it, _without_ referring the whole library, thus\n * avoiding making the `xlsx-datafill` package a dependency.\n */\n constructor(workbook, XlsxPopulate) {\n this._workbook = workbook;\n this._rowSizes = {};\n this._colSizes = {};\n \n _RichText = XlsxPopulate.RichText;\n }\n\n /**\n * Returns the configured workbook for direct XlsxPopulate manipulation.\n * @returns {Workbook} The workbook involved.\n */\n workbook() {\n return this._workbook; \n }\n\n /**\n * Gets the textual representation of the cell value.\n * @param {Cell} cell - The cell to retrieve the value from.\n * @returns {string} The textual representation of cell's contents.\n */\n cellValue(cell) {\n const theValue = cell.value();\n return theValue instanceof _RichText ? theValue.text() : theValue;\n }\n\n /**\n * Sets the cell value.\n * @param {Cell} cell - The cell to retrieve the value from.\n * @param {*} value - The requested value for setting.\n * @returns {XlsxPopulateAccess} Either the requested value or chainable this.\n */\n setCellValue(cell, value) {\n cell.value(value);\n return this;\n }\n\n /**\n * Gets the textual representation of the cell value.\n * @param {Cell} cell - The cell to retrieve the value from.\n * @returns {string} The type of the cell - 'formula', 'richtext', \n * 'text', 'number', 'date', 'hyperlink', or 'unknown';\n */\n cellType(cell) {\n if (cell.formula())\n return 'formula';\n else if (cell.hyperlink())\n return 'hyperlink';\n \n const theValue = cell.value();\n if (theValue instanceof _RichText)\n return 'richtext';\n else if (theValue instanceof Date)\n return 'date';\n else \n return typeof theValue;\n }\n\n /**\n * Sets the formula in the cell\n * @param {Cell} cell - The cell to retrieve the value from.\n * @param {string} formula - the text of the formula to be set.\n * @returns {XlsxPopulateAccess} For chaining.\n */\n setCellFormula(cell, formula) {\n cell.formula(_.trimStart(formula, ' ='));\n return this;\n }\n\n /**\n * Measures the distance, as a vector between two given cells.\n * @param {Cell} from The first cell.\n * @param {Cell} to The second cell.\n * @returns {Array.} An array with two values [, ], representing the distance between the two cells.\n */\n cellDistance(from, to) {\n return [\n to.rowNumber() - from.rowNumber(),\n to.columnNumber() - from.columnNumber()\n ];\n }\n\n /**\n * Determines the size of cell, taking into account if it is part of a merged range.\n * @param {Cell} cell The cell to be investigated.\n * @returns {Array.} An array with two values [, ], representing the occupied size.\n */\n cellSize(cell) {\n const cellAddr = cell.address();\n let theSize = [1, 1];\n \n _.forEach(cell.sheet()._mergeCells, range => {\n const rangeAddr = range.attributes.ref.split(\":\");\n if (rangeAddr[0] == cellAddr) {\n theSize = this.cellDistance(cell, cell.sheet().cell(rangeAddr[1]));\n ++theSize[0];\n ++theSize[1];\n return false;\n }\n });\n \n return theSize;\n }\n\n /**\n * Sets a named style of a given cell.\n * @param {Cell} cell The cell to be operated.\n * @param {string} name The name of the style property to be set.\n * @param {string|object} value The value for this property to be set.\n * @returns {XlsxPopulateAccess} For invocation chaining.\n */\n setCellStyle(cell, name, value) {\n cell.style(name, value);\n return this;\n }\n\n /**\n * Creates a reference Id for a given cell, based on its sheet and address.\n * @param {Cell} cell The cell to create a reference Id to.\n * @param {boolean} withSheet Whether to include the sheet name in the reference. Defaults to true.\n * @returns {string} The id to be used as a reference for this cell.\n */\n cellRef(cell, withSheet) {\n if (withSheet == null)\n withSheet = true;\n return cell.address({ includeSheetName: withSheet });\n }\n\n /**\n * Build a reference string for a cell identified by @param adr, from the @param cell.\n * @param {Cell} cell A cell that is a base of the reference.\n * @param {string} adr The address of the target cell, as mentioned in @param cell.\n * @param {boolean} withSheet Whether to include the sheet name in the reference. Defaults to true.\n * @returns {string} A reference string identifying the target cell uniquely.\n */\n buildRef(cell, adr, withSheet) {\n if (withSheet == null)\n withSheet = true;\n return adr ? cell.sheet().cell(adr).address({ includeSheetName: withSheet }) : null;\n }\n\n /**\n * Retrieves a given cell from a given sheet (or an active one).\n * @param {string|object|array} address The cell adress to be used\n * @param {string|idx} sheetId The id/name of the sheet to retrieve the cell from. Defaults to an active one.\n * @returns {Cell} A reference to the required cell.\n */\n getCell(address, sheetId) {\n const theSheet = sheetId == null ? this._workbook.activeSheet() : this._workbook.sheet(sheetId);\n return theSheet.cell(address);\n }\n\n /**\n * Duplicates a cell across a given range.\n * @param {Cell} cell Cell, which needs duplicating.\n * @param {Range} range The range, as returned from {@link getCellRange}\n * @returns {XlsxPopulateAccess} For chain invokes.\n */\n duplicateCell(cell, range) {\n range.value(cell.value());\n return this;\n }\n\n /**\n * Constructs and returns the range starting from the given cell and spawning given rows and cells.\n * @param {Cell} cell The starting cell of the range.\n * @param {Number} rowOffset Number of rows away from the starting cell. 0 means same row.\n * @param {Number} colOffset Number of columns away from the starting cell. 0 means same column.\n * @returns {Range} The constructed range.\n */\n getCellRange(cell, rowOffset, colOffset) {\n return cell.rangeTo(cell.relativeCell(rowOffset, colOffset));\n }\n\n /**\n * Gets the cell at a certain offset from a given one.\n * @param {Cell} cell The reference cell to make the offset from.\n * @param {int} rows Number of rows to offset.\n * @param {int} cols Number of columns to offset.\n * @returns {Cell} The resulting cell.\n */\n offsetCell(cell, rows, cols) {\n return cell.relativeCell(rows, cols);\n }\n\n /**\n * Merge or split range of cells.\n * @param {Range} range The range, as returned from {@link getCellRange}\n * @param {boolean} status The merged status to be set.\n * @returns {XlsxPopulateAccess} For chain invokes.\n */\n rangeMerged(range, status) {\n if (status === undefined)\n return range.merged();\n else {\n range.merged(status);\n return this;\n }\n }\n\n /**\n * Sets a formula for the whole range. If it contains only one - it is set directly.\n * @param {Range} range The range, as returned from {@link getCellRange}\n * @param {String} formula The formula to be set.\n * @returns {XlsxPopulateAccess} For chain invokes.\n */\n setRangeFormula(range, formula) {\n range.formula(_.trimStart(formula, ' ='));\n return this;\n }\n\n /**\n * Return the string representation of a given range.\n * @param {Range} range The range which address we're interested in.\n * @param {boolean} withSheet Whether to include sheet name in the address.\n * @return {String} The string, representing the given range.\n */\n rangeRef(range, withSheet) {\n if (withSheet == null)\n withSheet = true;\n return range.address({ includeSheetName: withSheet });\n }\n\n /**\n * Iterate over all used cells of the given workbook.\n * @param {function} cb The callback to be invoked with `cell` argument for each used cell.\n * @returns {XlsxPopulateAccess} For chain invokes.\n */\n forAllCells(cb) {\n this._workbook.sheets().forEach(sheet => {\n const theRange = sheet.usedRange();\n if (theRange) \n theRange.forEach(cb);\n });\n return this;\n }\n\n /**\n * Copies the styles from `src` cell to the `dest`-ination one.\n * @param {Cell} dest Destination cell.\n * @param {Cell} src Source cell.\n * @returns {XlsxPopulateAccess} For invocation chaining.\n */\n copyStyle(dest, src) {\n if (!src || !dest) throw new Error(\"Crash! Null 'src' or 'dest' for copyStyle()!\");\n if (src == dest) return this;\n\n if (src._style !== undefined)\n dest.style(src._style);\n else if (src._styleId > 0)\n dest._styleId = src._styleId;\n\n const destSheetId = dest.sheet().name(),\n rowId = `'${destSheetId}':${dest.rowNumber()}`,\n colId = `'${destSheetId}':${dest.columnNumber()}`;\n\n if (this._rowSizes[rowId] === undefined)\n dest.row().height(this._rowSizes[rowId] = src.row().height());\n \n if (this._colSizes[colId] === undefined)\n dest.column().width(this._colSizes[colId] = src.column().width());\n\n return this;\n }\n}\n\nmodule.exports = XlsxPopulateAccess;\n"]}
\ No newline at end of file
diff --git a/src/XlsxDataFill.js b/src/XlsxDataFill.js
index c1f08e7..def07a8 100644
--- a/src/XlsxDataFill.js
+++ b/src/XlsxDataFill.js
@@ -26,19 +26,14 @@ class XlsxDataFill {
* Constructs a new instance of XlsxDataFill with given options.
* @param {object} accessor An instance of XLSX spreadsheet accessing class.
* @param {{}} opts Options to be used during processing.
- * @param {RegExp} opts.templateRegExp The regular expression to be used for template recognizing.
- * Default is `/\{\{([^}]*)\}\}/`, i.e. Mustache.
- * @param {string} opts.fieldSplitter The string to be expected as template field splitter. Default is `|`.
- * @param {string} opts.joinText The string to be used when the extracted value for a single cell is an array,
- * and it needs to be joined. Default is `,`.
- * @param {string|boolean} opts.mergeCells Whether to merge the higher dimension cells in the output. Default is true.
- * @param {string|boolean} opts.duplicateCells Whether to duplicate the content of higher dimension cells, when not merged. Default is false.
- * @param {boolean} opts.followFormulae If a template is located as a result of a formula, whether to still process it.
- * Default is false.
- * @param {boolean} opts.copyStyle Copy the style of the template cell when populating. Even when `false`, the template
- * styling _is_ applied. Default is true.
+ * @param {RegExp} opts.templateRegExp The regular expression to be used for template recognizing. Default is `/\{\{([^}]*)\}\}/`, i.e. Mustache.
+ * @param {string|RegExo} opts.fieldSplitter The string or regular expression to be used as template fields splitter. Default is `|`.
+ * @param {string} opts.joinText The string to be used when the extracted value for a single cell is an array, and it needs to be joined. Default is `,`.
+ * @param {string|boolean} opts.mergeCells Whether to merge the higher dimension cells in the output. Default is true, but valid values are also `"both"`, `"vertical"` and `"horizontal"`.
+ * @param {string|boolean} opts.duplicateCells Whether to duplicate the content of higher dimension cells, when not merged. Default is false. Same valud values as `mergeCells`.
+ * @param {boolean} opts.followFormulae If a template is located as a result of a formula, whether to still process it. Default is false.
+ * @param {boolean} opts.copyStyle Copy the style of the template cell when populating. Even when `false`, the template styling _is_ applied. Default is true.
* @param {object.} opts.callbacksMap A map of handlers to be used for data and value extraction.
- * There is one default - the empty one, for object key extraction.
*/
constructor(accessor, opts) {
this._opts = _.defaultsDeep({}, opts, defaultOpts);
@@ -49,8 +44,7 @@ class XlsxDataFill {
/**
* Setter/getter for XlsxDataFill's options as set during construction.
- * @param {{}|null} newOpts If set - the new options to be used.
- * @see {@constructor}.
+ * @param {{}|null} newOpts If set - the new options to be used. Check [up here]{@link #new-xlsxdatafillaccessor-opts}.
* @returns {XlsxDataFill|{}} The required options (in getter mode) or XlsxDataFill (in setter mode) for chaining.
*/
options(newOpts) {