matrix-react-sdk
Version:
SDK for matrix.org using React
173 lines (167 loc) • 22.8 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = withValidation;
var _react = _interopRequireDefault(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _memoizeOne = _interopRequireDefault(require("memoize-one"));
/*
Copyright 2024 New Vector Ltd.
Copyright 2020 The Matrix.org Foundation C.I.C.
Copyright 2019 New Vector Ltd
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
/**
* Creates a validation function from a set of rules describing what to validate.
* Generic T is the "this" type passed to the rule methods
*
* @param {Function} description
* Function that returns a string summary of the kind of value that will
* meet the validation rules. Shown at the top of the validation feedback.
* @param {boolean} hideDescriptionIfValid
* If true, don't show the description if the validation passes validation.
* @param {Function} deriveData
* Optional function that returns a Promise to an object of generic type D.
* The result of this Promise is passed to rule methods `skip`, `test`, `valid`, and `invalid`.
* Useful for doing calculations per-value update once rather than in each of the above rule methods.
* @param {Object} rules
* An array of rules describing how to check to input value. Each rule in an object
* and may have the following properties:
* - `key`: A unique ID for the rule. Required.
* - `skip`: A function used to determine whether the rule should even be evaluated.
* - `test`: A function used to determine the rule's current validity. Required.
* - `valid`: Function returning text to show when the rule is valid. Only shown if set.
* - `invalid`: Function returning text to show when the rule is invalid. Only shown if set.
* - `final`: A Boolean if true states that this rule will only be considered if all rules before it returned valid.
* @param {boolean?} memoize
* If true, will use memoization to avoid calling deriveData & rules unless the value or allowEmpty change.
* Be careful to not use this if your validation is not pure and depends on other fields, such as "repeat password".
* @returns {Function}
* A validation function that takes in the current input value and returns
* the overall validity and a feedback UI that can be rendered for more detail.
*/
function withValidation({
description,
hideDescriptionIfValid,
deriveData,
rules,
memoize
}) {
let checkRules = async function (data, derivedData) {
const results = [];
let valid = true;
for (const rule of rules) {
if (!rule.key || !rule.test) {
continue;
}
if (!valid && rule.final) {
continue;
}
if (rule.skip?.call(this, data, derivedData)) {
continue;
}
// We're setting `this` to whichever component holds the validation
// function. That allows rules to access the state of the component.
const ruleValid = await rule.test.call(this, data, derivedData);
valid = valid && ruleValid;
if (ruleValid && rule.valid) {
// If the rule's result is valid and has text to show for
// the valid state, show it.
const text = rule.valid.call(this, derivedData);
if (!text) {
continue;
}
results.push({
key: rule.key,
valid: true,
text
});
} else if (!ruleValid && rule.invalid) {
// If the rule's result is invalid and has text to show for
// the invalid state, show it.
const text = rule.invalid.call(this, derivedData);
if (!text) {
continue;
}
results.push({
key: rule.key,
valid: false,
text
});
}
}
return [valid, results];
};
// We have to memoize it in chunks as `focused` can change frequently, but it isn't passed to these methods
if (memoize) {
if (deriveData) deriveData = (0, _memoizeOne.default)(deriveData, isDataEqual);
checkRules = (0, _memoizeOne.default)(checkRules, isDerivedDataEqual);
}
return async function onValidate({
value,
focused,
allowEmpty = true
}) {
if (!value && allowEmpty) {
return {};
}
const data = {
value,
allowEmpty
};
// We know that if deriveData is set then D will not be undefined
const derivedData = await deriveData?.call(this, data);
const [valid, results] = await checkRules.call(this, data, derivedData);
// Hide feedback when not focused
if (!focused) {
return {
valid
};
}
let details;
if (results && results.length) {
details = /*#__PURE__*/_react.default.createElement("ul", {
className: "mx_Validation_details"
}, results.map(result => {
const classes = (0, _classnames.default)({
mx_Validation_detail: true,
mx_Validation_valid: result.valid,
mx_Validation_invalid: !result.valid
});
return /*#__PURE__*/_react.default.createElement("li", {
key: result.key,
className: classes
}, result.text);
}));
}
let summary;
if (description && (details || !hideDescriptionIfValid)) {
// We're setting `this` to whichever component holds the validation
// function. That allows rules to access the state of the component.
const content = description.call(this, derivedData, results);
summary = content ? /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Validation_description"
}, content) : undefined;
}
let feedback;
if (summary || details) {
feedback = /*#__PURE__*/_react.default.createElement("div", {
className: "mx_Validation"
}, summary, details);
}
return {
valid,
feedback
};
};
}
function isDataEqual([a], [b]) {
return a.value === b.value && a.allowEmpty === b.allowEmpty;
}
function isDerivedDataEqual([a1, a2], [b1, b2]) {
return a2 === b2 && isDataEqual([a1], [b1]);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9jbGFzc25hbWVzIiwiX21lbW9pemVPbmUiLCJ3aXRoVmFsaWRhdGlvbiIsImRlc2NyaXB0aW9uIiwiaGlkZURlc2NyaXB0aW9uSWZWYWxpZCIsImRlcml2ZURhdGEiLCJydWxlcyIsIm1lbW9pemUiLCJjaGVja1J1bGVzIiwiZGF0YSIsImRlcml2ZWREYXRhIiwicmVzdWx0cyIsInZhbGlkIiwicnVsZSIsImtleSIsInRlc3QiLCJmaW5hbCIsInNraXAiLCJjYWxsIiwicnVsZVZhbGlkIiwidGV4dCIsInB1c2giLCJpbnZhbGlkIiwibWVtb2l6ZU9uZSIsImlzRGF0YUVxdWFsIiwiaXNEZXJpdmVkRGF0YUVxdWFsIiwib25WYWxpZGF0ZSIsInZhbHVlIiwiZm9jdXNlZCIsImFsbG93RW1wdHkiLCJkZXRhaWxzIiwibGVuZ3RoIiwiZGVmYXVsdCIsImNyZWF0ZUVsZW1lbnQiLCJjbGFzc05hbWUiLCJtYXAiLCJyZXN1bHQiLCJjbGFzc2VzIiwiY2xhc3NOYW1lcyIsIm14X1ZhbGlkYXRpb25fZGV0YWlsIiwibXhfVmFsaWRhdGlvbl92YWxpZCIsIm14X1ZhbGlkYXRpb25faW52YWxpZCIsInN1bW1hcnkiLCJjb250ZW50IiwidW5kZWZpbmVkIiwiZmVlZGJhY2siLCJhIiwiYiIsImExIiwiYTIiLCJiMSIsImIyIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdmlld3MvZWxlbWVudHMvVmFsaWRhdGlvbi50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjAgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cbkNvcHlyaWdodCAyMDE5IE5ldyBWZWN0b3IgTHRkXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBSZWFjdCwgeyBSZWFjdENoaWxkLCBSZWFjdE5vZGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gXCJjbGFzc25hbWVzXCI7XG5pbXBvcnQgbWVtb2l6ZU9uZSBmcm9tIFwibWVtb2l6ZS1vbmVcIjtcblxudHlwZSBEYXRhID0gUGljazxJRmllbGRTdGF0ZSwgXCJ2YWx1ZVwiIHwgXCJhbGxvd0VtcHR5XCI+O1xuXG5pbnRlcmZhY2UgSVJlc3VsdCB7XG4gICAga2V5OiBzdHJpbmc7XG4gICAgdmFsaWQ6IGJvb2xlYW47XG4gICAgdGV4dDogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgSVJ1bGU8VCwgRCA9IHVuZGVmaW5lZD4ge1xuICAgIGtleTogc3RyaW5nO1xuICAgIGZpbmFsPzogYm9vbGVhbjtcbiAgICBza2lwPyh0aGlzOiBULCBkYXRhOiBEYXRhLCBkZXJpdmVkRGF0YTogRCk6IGJvb2xlYW47XG4gICAgdGVzdCh0aGlzOiBULCBkYXRhOiBEYXRhLCBkZXJpdmVkRGF0YTogRCk6IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+O1xuICAgIHZhbGlkPyh0aGlzOiBULCBkZXJpdmVkRGF0YTogRCk6IHN0cmluZyB8IG51bGw7XG4gICAgaW52YWxpZD8odGhpczogVCwgZGVyaXZlZERhdGE6IEQpOiBzdHJpbmcgfCBudWxsO1xufVxuXG5pbnRlcmZhY2UgSUFyZ3M8VCwgRCA9IHZvaWQ+IHtcbiAgICBydWxlczogSVJ1bGU8VCwgRD5bXTtcbiAgICBkZXNjcmlwdGlvbj8odGhpczogVCwgZGVyaXZlZERhdGE6IEQsIHJlc3VsdHM6IElSZXN1bHRbXSk6IFJlYWN0Tm9kZTtcbiAgICBoaWRlRGVzY3JpcHRpb25JZlZhbGlkPzogYm9vbGVhbjtcbiAgICBkZXJpdmVEYXRhPyhkYXRhOiBEYXRhKTogUHJvbWlzZTxEPjtcbiAgICBtZW1vaXplPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRmllbGRTdGF0ZSB7XG4gICAgdmFsdWU6IHN0cmluZyB8IG51bGw7XG4gICAgZm9jdXNlZDogYm9vbGVhbjtcbiAgICBhbGxvd0VtcHR5PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgdmFsaWQ/OiBib29sZWFuO1xuICAgIGZlZWRiYWNrPzogUmVhY3QuUmVhY3RDaGlsZDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgdmFsaWRhdGlvbiBmdW5jdGlvbiBmcm9tIGEgc2V0IG9mIHJ1bGVzIGRlc2NyaWJpbmcgd2hhdCB0byB2YWxpZGF0ZS5cbiAqIEdlbmVyaWMgVCBpcyB0aGUgXCJ0aGlzXCIgdHlwZSBwYXNzZWQgdG8gdGhlIHJ1bGUgbWV0aG9kc1xuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGRlc2NyaXB0aW9uXG4gKiAgICAgRnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgc3RyaW5nIHN1bW1hcnkgb2YgdGhlIGtpbmQgb2YgdmFsdWUgdGhhdCB3aWxsXG4gKiAgICAgbWVldCB0aGUgdmFsaWRhdGlvbiBydWxlcy4gU2hvd24gYXQgdGhlIHRvcCBvZiB0aGUgdmFsaWRhdGlvbiBmZWVkYmFjay5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaGlkZURlc2NyaXB0aW9uSWZWYWxpZFxuICogICAgIElmIHRydWUsIGRvbid0IHNob3cgdGhlIGRlc2NyaXB0aW9uIGlmIHRoZSB2YWxpZGF0aW9uIHBhc3NlcyB2YWxpZGF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZGVyaXZlRGF0YVxuICogICAgIE9wdGlvbmFsIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIFByb21pc2UgdG8gYW4gb2JqZWN0IG9mIGdlbmVyaWMgdHlwZSBELlxuICogICAgIFRoZSByZXN1bHQgb2YgdGhpcyBQcm9taXNlIGlzIHBhc3NlZCB0byBydWxlIG1ldGhvZHMgYHNraXBgLCBgdGVzdGAsIGB2YWxpZGAsIGFuZCBgaW52YWxpZGAuXG4gKiAgICAgVXNlZnVsIGZvciBkb2luZyBjYWxjdWxhdGlvbnMgcGVyLXZhbHVlIHVwZGF0ZSBvbmNlIHJhdGhlciB0aGFuIGluIGVhY2ggb2YgdGhlIGFib3ZlIHJ1bGUgbWV0aG9kcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBydWxlc1xuICogICAgIEFuIGFycmF5IG9mIHJ1bGVzIGRlc2NyaWJpbmcgaG93IHRvIGNoZWNrIHRvIGlucHV0IHZhbHVlLiBFYWNoIHJ1bGUgaW4gYW4gb2JqZWN0XG4gKiAgICAgYW5kIG1heSBoYXZlIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqICAgICAtIGBrZXlgOiBBIHVuaXF1ZSBJRCBmb3IgdGhlIHJ1bGUuIFJlcXVpcmVkLlxuICogICAgIC0gYHNraXBgOiBBIGZ1bmN0aW9uIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHJ1bGUgc2hvdWxkIGV2ZW4gYmUgZXZhbHVhdGVkLlxuICogICAgIC0gYHRlc3RgOiBBIGZ1bmN0aW9uIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBydWxlJ3MgY3VycmVudCB2YWxpZGl0eS4gUmVxdWlyZWQuXG4gKiAgICAgLSBgdmFsaWRgOiBGdW5jdGlvbiByZXR1cm5pbmcgdGV4dCB0byBzaG93IHdoZW4gdGhlIHJ1bGUgaXMgdmFsaWQuIE9ubHkgc2hvd24gaWYgc2V0LlxuICogICAgIC0gYGludmFsaWRgOiBGdW5jdGlvbiByZXR1cm5pbmcgdGV4dCB0byBzaG93IHdoZW4gdGhlIHJ1bGUgaXMgaW52YWxpZC4gT25seSBzaG93biBpZiBzZXQuXG4gKiAgICAgLSBgZmluYWxgOiBBIEJvb2xlYW4gaWYgdHJ1ZSBzdGF0ZXMgdGhhdCB0aGlzIHJ1bGUgd2lsbCBvbmx5IGJlIGNvbnNpZGVyZWQgaWYgYWxsIHJ1bGVzIGJlZm9yZSBpdCByZXR1cm5lZCB2YWxpZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj99IG1lbW9pemVcbiAqICAgICBJZiB0cnVlLCB3aWxsIHVzZSBtZW1vaXphdGlvbiB0byBhdm9pZCBjYWxsaW5nIGRlcml2ZURhdGEgJiBydWxlcyB1bmxlc3MgdGhlIHZhbHVlIG9yIGFsbG93RW1wdHkgY2hhbmdlLlxuICogICAgIEJlIGNhcmVmdWwgdG8gbm90IHVzZSB0aGlzIGlmIHlvdXIgdmFsaWRhdGlvbiBpcyBub3QgcHVyZSBhbmQgZGVwZW5kcyBvbiBvdGhlciBmaWVsZHMsIHN1Y2ggYXMgXCJyZXBlYXQgcGFzc3dvcmRcIi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn1cbiAqICAgICBBIHZhbGlkYXRpb24gZnVuY3Rpb24gdGhhdCB0YWtlcyBpbiB0aGUgY3VycmVudCBpbnB1dCB2YWx1ZSBhbmQgcmV0dXJuc1xuICogICAgIHRoZSBvdmVyYWxsIHZhbGlkaXR5IGFuZCBhIGZlZWRiYWNrIFVJIHRoYXQgY2FuIGJlIHJlbmRlcmVkIGZvciBtb3JlIGRldGFpbC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gd2l0aFZhbGlkYXRpb248VCA9IHZvaWQsIEQgPSB2b2lkPih7XG4gICAgZGVzY3JpcHRpb24sXG4gICAgaGlkZURlc2NyaXB0aW9uSWZWYWxpZCxcbiAgICBkZXJpdmVEYXRhLFxuICAgIHJ1bGVzLFxuICAgIG1lbW9pemUsXG59OiBJQXJnczxULCBEPik6IChmaWVsZFN0YXRlOiBJRmllbGRTdGF0ZSkgPT4gUHJvbWlzZTxJVmFsaWRhdGlvblJlc3VsdD4ge1xuICAgIGxldCBjaGVja1J1bGVzID0gYXN5bmMgZnVuY3Rpb24gKFxuICAgICAgICB0aGlzOiBULFxuICAgICAgICBkYXRhOiBEYXRhLFxuICAgICAgICBkZXJpdmVkRGF0YTogRCxcbiAgICApOiBQcm9taXNlPFt2YWxpZDogYm9vbGVhbiwgcmVzdWx0czogSVJlc3VsdFtdXT4ge1xuICAgICAgICBjb25zdCByZXN1bHRzOiBJUmVzdWx0W10gPSBbXTtcbiAgICAgICAgbGV0IHZhbGlkID0gdHJ1ZTtcbiAgICAgICAgZm9yIChjb25zdCBydWxlIG9mIHJ1bGVzKSB7XG4gICAgICAgICAgICBpZiAoIXJ1bGUua2V5IHx8ICFydWxlLnRlc3QpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF2YWxpZCAmJiBydWxlLmZpbmFsKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChydWxlLnNraXA/LmNhbGwodGhpcywgZGF0YSwgZGVyaXZlZERhdGEpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFdlJ3JlIHNldHRpbmcgYHRoaXNgIHRvIHdoaWNoZXZlciBjb21wb25lbnQgaG9sZHMgdGhlIHZhbGlkYXRpb25cbiAgICAgICAgICAgIC8vIGZ1bmN0aW9uLiBUaGF0IGFsbG93cyBydWxlcyB0byBhY2Nlc3MgdGhlIHN0YXRlIG9mIHRoZSBjb21wb25lbnQuXG4gICAgICAgICAgICBjb25zdCBydWxlVmFsaWQ6IGJvb2xlYW4gPSBhd2FpdCBydWxlLnRlc3QuY2FsbCh0aGlzLCBkYXRhLCBkZXJpdmVkRGF0YSk7XG4gICAgICAgICAgICB2YWxpZCA9IHZhbGlkICYmIHJ1bGVWYWxpZDtcbiAgICAgICAgICAgIGlmIChydWxlVmFsaWQgJiYgcnVsZS52YWxpZCkge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBydWxlJ3MgcmVzdWx0IGlzIHZhbGlkIGFuZCBoYXMgdGV4dCB0byBzaG93IGZvclxuICAgICAgICAgICAgICAgIC8vIHRoZSB2YWxpZCBzdGF0ZSwgc2hvdyBpdC5cbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gcnVsZS52YWxpZC5jYWxsKHRoaXMsIGRlcml2ZWREYXRhKTtcbiAgICAgICAgICAgICAgICBpZiAoIXRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGtleTogcnVsZS5rZXksXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghcnVsZVZhbGlkICYmIHJ1bGUuaW52YWxpZCkge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBydWxlJ3MgcmVzdWx0IGlzIGludmFsaWQgYW5kIGhhcyB0ZXh0IHRvIHNob3cgZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIGludmFsaWQgc3RhdGUsIHNob3cgaXQuXG4gICAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IHJ1bGUuaW52YWxpZC5jYWxsKHRoaXMsIGRlcml2ZWREYXRhKTtcbiAgICAgICAgICAgICAgICBpZiAoIXRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGtleTogcnVsZS5rZXksXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgdGV4dCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbdmFsaWQsIHJlc3VsdHNdO1xuICAgIH07XG5cbiAgICAvLyBXZSBoYXZlIHRvIG1lbW9pemUgaXQgaW4gY2h1bmtzIGFzIGBmb2N1c2VkYCBjYW4gY2hhbmdlIGZyZXF1ZW50bHksIGJ1dCBpdCBpc24ndCBwYXNzZWQgdG8gdGhlc2UgbWV0aG9kc1xuICAgIGlmIChtZW1vaXplKSB7XG4gICAgICAgIGlmIChkZXJpdmVEYXRhKSBkZXJpdmVEYXRhID0gbWVtb2l6ZU9uZShkZXJpdmVEYXRhLCBpc0RhdGFFcXVhbCk7XG4gICAgICAgIGNoZWNrUnVsZXMgPSBtZW1vaXplT25lKGNoZWNrUnVsZXMsIGlzRGVyaXZlZERhdGFFcXVhbCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzeW5jIGZ1bmN0aW9uIG9uVmFsaWRhdGUoXG4gICAgICAgIHRoaXM6IFQsXG4gICAgICAgIHsgdmFsdWUsIGZvY3VzZWQsIGFsbG93RW1wdHkgPSB0cnVlIH06IElGaWVsZFN0YXRlLFxuICAgICk6IFByb21pc2U8SVZhbGlkYXRpb25SZXN1bHQ+IHtcbiAgICAgICAgaWYgKCF2YWx1ZSAmJiBhbGxvd0VtcHR5KSB7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkYXRhID0geyB2YWx1ZSwgYWxsb3dFbXB0eSB9O1xuICAgICAgICAvLyBXZSBrbm93IHRoYXQgaWYgZGVyaXZlRGF0YSBpcyBzZXQgdGhlbiBEIHdpbGwgbm90IGJlIHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBkZXJpdmVkRGF0YSA9IChhd2FpdCBkZXJpdmVEYXRhPy5jYWxsKHRoaXMsIGRhdGEpKSBhcyBEO1xuICAgICAgICBjb25zdCBbdmFsaWQsIHJlc3VsdHNdID0gYXdhaXQgY2hlY2tSdWxlcy5jYWxsKHRoaXMsIGRhdGEsIGRlcml2ZWREYXRhKTtcblxuICAgICAgICAvLyBIaWRlIGZlZWRiYWNrIHdoZW4gbm90IGZvY3VzZWRcbiAgICAgICAgaWYgKCFmb2N1c2VkKSB7XG4gICAgICAgICAgICByZXR1cm4geyB2YWxpZCB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGRldGFpbHM6IFJlYWN0Tm9kZSB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHJlc3VsdHMgJiYgcmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRldGFpbHMgPSAoXG4gICAgICAgICAgICAgICAgPHVsIGNsYXNzTmFtZT1cIm14X1ZhbGlkYXRpb25fZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICB7cmVzdWx0cy5tYXAoKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2xhc3NlcyA9IGNsYXNzTmFtZXMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG14X1ZhbGlkYXRpb25fZGV0YWlsOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG14X1ZhbGlkYXRpb25fdmFsaWQ6IHJlc3VsdC52YWxpZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBteF9WYWxpZGF0aW9uX2ludmFsaWQ6ICFyZXN1bHQudmFsaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGtleT17cmVzdWx0LmtleX0gY2xhc3NOYW1lPXtjbGFzc2VzfT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3Jlc3VsdC50ZXh0fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzdW1tYXJ5OiBSZWFjdE5vZGUgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChkZXNjcmlwdGlvbiAmJiAoZGV0YWlscyB8fCAhaGlkZURlc2NyaXB0aW9uSWZWYWxpZCkpIHtcbiAgICAgICAgICAgIC8vIFdlJ3JlIHNldHRpbmcgYHRoaXNgIHRvIHdoaWNoZXZlciBjb21wb25lbnQgaG9sZHMgdGhlIHZhbGlkYXRpb25cbiAgICAgICAgICAgIC8vIGZ1bmN0aW9uLiBUaGF0IGFsbG93cyBydWxlcyB0byBhY2Nlc3MgdGhlIHN0YXRlIG9mIHRoZSBjb21wb25lbnQuXG4gICAgICAgICAgICBjb25zdCBjb250ZW50ID0gZGVzY3JpcHRpb24uY2FsbCh0aGlzLCBkZXJpdmVkRGF0YSwgcmVzdWx0cyk7XG4gICAgICAgICAgICBzdW1tYXJ5ID0gY29udGVudCA/IDxkaXYgY2xhc3NOYW1lPVwibXhfVmFsaWRhdGlvbl9kZXNjcmlwdGlvblwiPntjb250ZW50fTwvZGl2PiA6IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBmZWVkYmFjazogUmVhY3RDaGlsZCB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHN1bW1hcnkgfHwgZGV0YWlscykge1xuICAgICAgICAgICAgZmVlZGJhY2sgPSAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9WYWxpZGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgIHtzdW1tYXJ5fVxuICAgICAgICAgICAgICAgICAgICB7ZGV0YWlsc31cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsaWQsXG4gICAgICAgICAgICBmZWVkYmFjayxcbiAgICAgICAgfTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpc0RhdGFFcXVhbChbYV06IFtEYXRhXSwgW2JdOiBbRGF0YV0pOiBib29sZWFuIHtcbiAgICByZXR1cm4gYS52YWx1ZSA9PT0gYi52YWx1ZSAmJiBhLmFsbG93RW1wdHkgPT09IGIuYWxsb3dFbXB0eTtcbn1cblxuZnVuY3Rpb24gaXNEZXJpdmVkRGF0YUVxdWFsKFthMSwgYTJdOiBbRGF0YSwgYW55XSwgW2IxLCBiMl06IFtEYXRhLCBhbnldKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGEyID09PSBiMiAmJiBpc0RhdGFFcXVhbChbYTFdLCBbYjFdKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVNBLElBQUFBLE1BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLFdBQUEsR0FBQUYsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFFLFdBQUEsR0FBQUgsc0JBQUEsQ0FBQUMsT0FBQTtBQVhBO0FB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