UNPKG

matrix-react-sdk

Version:
386 lines (380 loc) 56.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _languageHandler = require("../../../languageHandler"); var _SdkConfig = _interopRequireDefault(require("../../../SdkConfig")); var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton")); var _Validation = _interopRequireDefault(require("../elements/Validation")); var _Field = _interopRequireDefault(require("../elements/Field")); var _CountryDropdown = _interopRequireDefault(require("./CountryDropdown")); var _EmailField = _interopRequireDefault(require("./EmailField")); let _LoginField$Email, _LoginField$Phone, _LoginField$MatrixId, _LoginField$Password; /* Copyright 2024 New Vector Ltd. Copyright 2015, 2016 , 2017, 2019 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ // For validating phone numbers without country codes const PHONE_NUMBER_REGEX = /^[0-9()\-\s]*$/; var LoginField = /*#__PURE__*/function (LoginField) { LoginField["Email"] = "login_field_email"; LoginField["MatrixId"] = "login_field_mxid"; LoginField["Phone"] = "login_field_phone"; LoginField["Password"] = "login_field_password"; return LoginField; }(LoginField || {}); /* * A pure UI component which displays a username/password form. * The email/username/phone fields are fully-controlled, the password field is not. */ _LoginField$Email = LoginField.Email; _LoginField$Phone = LoginField.Phone; _LoginField$MatrixId = LoginField.MatrixId; _LoginField$Password = LoginField.Password; class PasswordLogin extends _react.default.PureComponent { constructor(props) { super(props); (0, _defineProperty2.default)(this, _LoginField$Email, null); (0, _defineProperty2.default)(this, _LoginField$Phone, null); (0, _defineProperty2.default)(this, _LoginField$MatrixId, null); (0, _defineProperty2.default)(this, _LoginField$Password, null); (0, _defineProperty2.default)(this, "onForgotPasswordClick", ev => { ev.preventDefault(); ev.stopPropagation(); this.props.onForgotPasswordClick?.(); }); (0, _defineProperty2.default)(this, "onSubmitForm", async ev => { ev.preventDefault(); const allFieldsValid = await this.verifyFieldsBeforeSubmit(); if (!allFieldsValid) { return; } switch (this.state.loginType) { case LoginField.Email: case LoginField.MatrixId: this.props.onSubmit(this.props.username, undefined, undefined, this.state.password); break; case LoginField.Phone: this.props.onSubmit(undefined, this.props.phoneCountry, this.props.phoneNumber, this.state.password); break; } }); (0, _defineProperty2.default)(this, "onUsernameChanged", ev => { this.props.onUsernameChanged?.(ev.target.value); }); (0, _defineProperty2.default)(this, "onUsernameBlur", ev => { this.props.onUsernameBlur?.(ev.target.value); }); (0, _defineProperty2.default)(this, "onLoginTypeChange", ev => { const loginType = ev.target.value; this.setState({ loginType }); this.props.onUsernameChanged?.(""); // Reset because email and username use the same state }); (0, _defineProperty2.default)(this, "onPhoneCountryChanged", country => { this.props.onPhoneCountryChanged?.(country.iso2); }); (0, _defineProperty2.default)(this, "onPhoneNumberChanged", ev => { this.props.onPhoneNumberChanged?.(ev.target.value); }); (0, _defineProperty2.default)(this, "onPasswordChanged", ev => { this.setState({ password: ev.target.value }); }); (0, _defineProperty2.default)(this, "validateUsernameRules", (0, _Validation.default)({ rules: [{ key: "required", test({ value, allowEmpty }) { return allowEmpty || !!value; }, invalid: () => (0, _languageHandler._t)("auth|username_field_required_invalid") }] })); (0, _defineProperty2.default)(this, "onUsernameValidate", async fieldState => { const result = await this.validateUsernameRules(fieldState); this.markFieldValid(LoginField.MatrixId, result.valid); return result; }); (0, _defineProperty2.default)(this, "onEmailValidate", result => { this.markFieldValid(LoginField.Email, result.valid); }); (0, _defineProperty2.default)(this, "validatePhoneNumberRules", (0, _Validation.default)({ rules: [{ key: "required", test({ value, allowEmpty }) { return allowEmpty || !!value; }, invalid: () => (0, _languageHandler._t)("auth|msisdn_field_required_invalid") }, { key: "number", test: ({ value }) => !value || PHONE_NUMBER_REGEX.test(value), invalid: () => (0, _languageHandler._t)("auth|msisdn_field_number_invalid") }] })); (0, _defineProperty2.default)(this, "onPhoneNumberValidate", async fieldState => { const result = await this.validatePhoneNumberRules(fieldState); this.markFieldValid(LoginField.Password, result.valid); return result; }); (0, _defineProperty2.default)(this, "validatePasswordRules", (0, _Validation.default)({ rules: [{ key: "required", test({ value, allowEmpty }) { return allowEmpty || !!value; }, invalid: () => (0, _languageHandler._t)("auth|password_field_label") }] })); (0, _defineProperty2.default)(this, "onPasswordValidate", async fieldState => { const result = await this.validatePasswordRules(fieldState); this.markFieldValid(LoginField.Password, result.valid); return result; }); this.state = { // Field error codes by field ID fieldValid: {}, loginType: LoginField.MatrixId, password: "" }; } async verifyFieldsBeforeSubmit() { // Blur the active element if any, so we first run its blur validation, // which is less strict than the pass we're about to do below for all fields. const activeElement = document.activeElement; if (activeElement) { activeElement.blur(); } const fieldIDsInDisplayOrder = [this.state.loginType, LoginField.Password]; // Run all fields with stricter validation that no longer allows empty // values for required fields. for (const fieldID of fieldIDsInDisplayOrder) { const field = this[fieldID]; if (!field) { continue; } // We must wait for these validations to finish before queueing // up the setState below so our setState goes in the queue after // all the setStates from these validate calls (that's how we // know they've finished). await field.validate({ allowEmpty: false }); } // Validation and state updates are async, so we need to wait for them to complete // first. Queue a `setState` callback and wait for it to resolve. await new Promise(resolve => this.setState({}, resolve)); if (this.allFieldsValid()) { return true; } const invalidField = this.findFirstInvalidField(fieldIDsInDisplayOrder); if (!invalidField) { return true; } // Focus the first invalid field and show feedback in the stricter mode // that no longer allows empty values for required fields. invalidField.focus(); invalidField.validate({ allowEmpty: false, focused: true }); return false; } allFieldsValid() { return Object.values(this.state.fieldValid).every(Boolean); } findFirstInvalidField(fieldIDs) { for (const fieldID of fieldIDs) { if (!this.state.fieldValid[fieldID] && this[fieldID]) { return this[fieldID]; } } return null; } markFieldValid(fieldID, valid) { const { fieldValid } = this.state; fieldValid[fieldID] = valid; this.setState({ fieldValid }); } renderLoginField(loginType, autoFocus) { const classes = { error: false }; switch (loginType) { case LoginField.Email: classes.error = this.props.loginIncorrect && !this.props.username; return /*#__PURE__*/_react.default.createElement(_EmailField.default, { id: "mx_LoginForm_email", className: (0, _classnames.default)(classes), name: "username" // make it a little easier for browser's remember-password , autoComplete: "email", type: "email", key: "email_input", placeholder: "joe@example.com", value: this.props.username, onChange: this.onUsernameChanged, onBlur: this.onUsernameBlur, disabled: this.props.busy, autoFocus: autoFocus, onValidate: this.onEmailValidate, fieldRef: field => { this[LoginField.Email] = field; } }); case LoginField.MatrixId: classes.error = this.props.loginIncorrect && !this.props.username; return /*#__PURE__*/_react.default.createElement(_Field.default, { id: "mx_LoginForm_username", className: (0, _classnames.default)(classes), name: "username" // make it a little easier for browser's remember-password , autoComplete: "username", key: "username_input", type: "text", label: (0, _languageHandler._t)("common|username"), placeholder: (0, _languageHandler._t)("common|username"), value: this.props.username, onChange: this.onUsernameChanged, onBlur: this.onUsernameBlur, disabled: this.props.busy, autoFocus: autoFocus, onValidate: this.onUsernameValidate, ref: field => { this[LoginField.MatrixId] = field; } }); case LoginField.Phone: { classes.error = this.props.loginIncorrect && !this.props.phoneNumber; const phoneCountry = /*#__PURE__*/_react.default.createElement(_CountryDropdown.default, { value: this.props.phoneCountry, isSmall: true, showPrefix: true, onOptionChange: this.onPhoneCountryChanged }); return /*#__PURE__*/_react.default.createElement(_Field.default, { id: "mx_LoginForm_phone", className: (0, _classnames.default)(classes), name: "phoneNumber", autoComplete: "tel-national", key: "phone_input", type: "text", label: (0, _languageHandler._t)("auth|msisdn_field_label"), value: this.props.phoneNumber, prefixComponent: phoneCountry, onChange: this.onPhoneNumberChanged, disabled: this.props.busy, autoFocus: autoFocus, onValidate: this.onPhoneNumberValidate, ref: field => { this[LoginField.Password] = field; } }); } } } isLoginEmpty() { switch (this.state.loginType) { case LoginField.Email: case LoginField.MatrixId: return !this.props.username; case LoginField.Phone: return !this.props.phoneCountry || !this.props.phoneNumber; } } render() { let forgotPasswordJsx; if (this.props.onForgotPasswordClick) { forgotPasswordJsx = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { className: "mx_Login_forgot", disabled: this.props.busy, kind: "link", onClick: this.onForgotPasswordClick }, (0, _languageHandler._t)("auth|reset_password_button")); } const pwFieldClass = (0, _classnames.default)({ error: this.props.loginIncorrect && !this.isLoginEmpty() // only error password if error isn't top field }); // If login is empty, autoFocus login, otherwise autoFocus password. // this is for when auto server discovery remounts us when the user tries to tab from username to password const autoFocusPassword = !this.isLoginEmpty(); const loginField = this.renderLoginField(this.state.loginType, !autoFocusPassword); let loginType; if (!_SdkConfig.default.get().disable_3pid_login) { loginType = /*#__PURE__*/_react.default.createElement("div", { className: "mx_Login_type_container" }, /*#__PURE__*/_react.default.createElement("label", { className: "mx_Login_type_label" }, (0, _languageHandler._t)("auth|identifier_label")), /*#__PURE__*/_react.default.createElement(_Field.default, { element: "select", value: this.state.loginType, onChange: this.onLoginTypeChange, disabled: this.props.busy }, /*#__PURE__*/_react.default.createElement("option", { key: LoginField.MatrixId, value: LoginField.MatrixId }, (0, _languageHandler._t)("common|username")), /*#__PURE__*/_react.default.createElement("option", { key: LoginField.Email, value: LoginField.Email }, (0, _languageHandler._t)("common|email_address")), /*#__PURE__*/_react.default.createElement("option", { key: LoginField.Password, value: LoginField.Password }, (0, _languageHandler._t)("auth|msisdn_field_label")))); } return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("form", { onSubmit: this.onSubmitForm }, loginType, loginField, /*#__PURE__*/_react.default.createElement(_Field.default, { id: "mx_LoginForm_password", className: pwFieldClass, autoComplete: "current-password", type: "password", name: "password", label: (0, _languageHandler._t)("common|password"), value: this.state.password, onChange: this.onPasswordChanged, disabled: this.props.busy, autoFocus: autoFocusPassword, onValidate: this.onPasswordValidate, ref: field => this[LoginField.Password] = field }), forgotPasswordJsx, !this.props.busy && /*#__PURE__*/_react.default.createElement("input", { className: "mx_Login_submit", type: "submit", value: (0, _languageHandler._t)("action|sign_in"), disabled: this.props.disableSubmit }))); } } exports.default = PasswordLogin; (0, _defineProperty2.default)(PasswordLogin, "defaultProps", { onUsernameChanged: function () {}, onUsernameBlur: function () {}, onPhoneCountryChanged: function () {}, onPhoneNumberChanged: function () {}, loginIncorrect: false, disableSubmit: false }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9jbGFzc25hbWVzIiwiX2xhbmd1YWdlSGFuZGxlciIsIl9TZGtDb25maWciLCJfQWNjZXNzaWJsZUJ1dHRvbiIsIl9WYWxpZGF0aW9uIiwiX0ZpZWxkIiwiX0NvdW50cnlEcm9wZG93biIsIl9FbWFpbEZpZWxkIiwiX0xvZ2luRmllbGQkRW1haWwiLCJfTG9naW5GaWVsZCRQaG9uZSIsIl9Mb2dpbkZpZWxkJE1hdHJpeElkIiwiX0xvZ2luRmllbGQkUGFzc3dvcmQiLCJQSE9ORV9OVU1CRVJfUkVHRVgiLCJMb2dpbkZpZWxkIiwiRW1haWwiLCJQaG9uZSIsIk1hdHJpeElkIiwiUGFzc3dvcmQiLCJQYXNzd29yZExvZ2luIiwiUmVhY3QiLCJQdXJlQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiZXYiLCJwcmV2ZW50RGVmYXVsdCIsInN0b3BQcm9wYWdhdGlvbiIsIm9uRm9yZ290UGFzc3dvcmRDbGljayIsImFsbEZpZWxkc1ZhbGlkIiwidmVyaWZ5RmllbGRzQmVmb3JlU3VibWl0Iiwic3RhdGUiLCJsb2dpblR5cGUiLCJvblN1Ym1pdCIsInVzZXJuYW1lIiwidW5kZWZpbmVkIiwicGFzc3dvcmQiLCJwaG9uZUNvdW50cnkiLCJwaG9uZU51bWJlciIsIm9uVXNlcm5hbWVDaGFuZ2VkIiwidGFyZ2V0IiwidmFsdWUiLCJvblVzZXJuYW1lQmx1ciIsInNldFN0YXRlIiwiY291bnRyeSIsIm9uUGhvbmVDb3VudHJ5Q2hhbmdlZCIsImlzbzIiLCJvblBob25lTnVtYmVyQ2hhbmdlZCIsIndpdGhWYWxpZGF0aW9uIiwicnVsZXMiLCJrZXkiLCJ0ZXN0IiwiYWxsb3dFbXB0eSIsImludmFsaWQiLCJfdCIsImZpZWxkU3RhdGUiLCJyZXN1bHQiLCJ2YWxpZGF0ZVVzZXJuYW1lUnVsZXMiLCJtYXJrRmllbGRWYWxpZCIsInZhbGlkIiwidmFsaWRhdGVQaG9uZU51bWJlclJ1bGVzIiwidmFsaWRhdGVQYXNzd29yZFJ1bGVzIiwiZmllbGRWYWxpZCIsImFjdGl2ZUVsZW1lbnQiLCJkb2N1bWVudCIsImJsdXIiLCJmaWVsZElEc0luRGlzcGxheU9yZGVyIiwiZmllbGRJRCIsImZpZWxkIiwidmFsaWRhdGUiLCJQcm9taXNlIiwicmVzb2x2ZSIsImludmFsaWRGaWVsZCIsImZpbmRGaXJzdEludmFsaWRGaWVsZCIsImZvY3VzIiwiZm9jdXNlZCIsIk9iamVjdCIsInZhbHVlcyIsImV2ZXJ5IiwiQm9vbGVhbiIsImZpZWxkSURzIiwicmVuZGVyTG9naW5GaWVsZCIsImF1dG9Gb2N1cyIsImNsYXNzZXMiLCJlcnJvciIsImxvZ2luSW5jb3JyZWN0IiwiY3JlYXRlRWxlbWVudCIsImlkIiwiY2xhc3NOYW1lIiwiY2xhc3NOYW1lcyIsIm5hbWUiLCJhdXRvQ29tcGxldGUiLCJ0eXBlIiwicGxhY2Vob2xkZXIiLCJvbkNoYW5nZSIsIm9uQmx1ciIsImRpc2FibGVkIiwiYnVzeSIsIm9uVmFsaWRhdGUiLCJvbkVtYWlsVmFsaWRhdGUiLCJmaWVsZFJlZiIsImxhYmVsIiwib25Vc2VybmFtZVZhbGlkYXRlIiwicmVmIiwiaXNTbWFsbCIsInNob3dQcmVmaXgiLCJvbk9wdGlvbkNoYW5nZSIsInByZWZpeENvbXBvbmVudCIsIm9uUGhvbmVOdW1iZXJWYWxpZGF0ZSIsImlzTG9naW5FbXB0eSIsInJlbmRlciIsImZvcmdvdFBhc3N3b3JkSnN4Iiwia2luZCIsIm9uQ2xpY2siLCJwd0ZpZWxkQ2xhc3MiLCJhdXRvRm9jdXNQYXNzd29yZCIsImxvZ2luRmllbGQiLCJTZGtDb25maWciLCJnZXQiLCJkaXNhYmxlXzNwaWRfbG9naW4iLCJlbGVtZW50Iiwib25Mb2dpblR5cGVDaGFuZ2UiLCJvblN1Ym1pdEZvcm0iLCJvblBhc3N3b3JkQ2hhbmdlZCIsIm9uUGFzc3dvcmRWYWxpZGF0ZSIsImRpc2FibGVTdWJtaXQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdmlld3MvYXV0aC9QYXNzd29yZExvZ2luLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG5Db3B5cmlnaHQgMjAxNSwgMjAxNiAsIDIwMTcsIDIwMTkgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7IFN5bnRoZXRpY0V2ZW50IH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tIFwiY2xhc3NuYW1lc1wiO1xuXG5pbXBvcnQgeyBfdCB9IGZyb20gXCIuLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXJcIjtcbmltcG9ydCBTZGtDb25maWcgZnJvbSBcIi4uLy4uLy4uL1Nka0NvbmZpZ1wiO1xuaW1wb3J0IHsgVmFsaWRhdGVkU2VydmVyQ29uZmlnIH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL1ZhbGlkYXRlZFNlcnZlckNvbmZpZ1wiO1xuaW1wb3J0IEFjY2Vzc2libGVCdXR0b24sIHsgQnV0dG9uRXZlbnQgfSBmcm9tIFwiLi4vZWxlbWVudHMvQWNjZXNzaWJsZUJ1dHRvblwiO1xuaW1wb3J0IHdpdGhWYWxpZGF0aW9uLCB7IElGaWVsZFN0YXRlLCBJVmFsaWRhdGlvblJlc3VsdCB9IGZyb20gXCIuLi9lbGVtZW50cy9WYWxpZGF0aW9uXCI7XG5pbXBvcnQgRmllbGQgZnJvbSBcIi4uL2VsZW1lbnRzL0ZpZWxkXCI7XG5pbXBvcnQgQ291bnRyeURyb3Bkb3duIGZyb20gXCIuL0NvdW50cnlEcm9wZG93blwiO1xuaW1wb3J0IEVtYWlsRmllbGQgZnJvbSBcIi4vRW1haWxGaWVsZFwiO1xuaW1wb3J0IHsgUGhvbmVOdW1iZXJDb3VudHJ5RGVmaW5pdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9waG9uZW51bWJlclwiO1xuXG4vLyBGb3IgdmFsaWRhdGluZyBwaG9uZSBudW1iZXJzIHdpdGhvdXQgY291bnRyeSBjb2Rlc1xuY29uc3QgUEhPTkVfTlVNQkVSX1JFR0VYID0gL15bMC05KClcXC1cXHNdKiQvO1xuXG5pbnRlcmZhY2UgSVByb3BzIHtcbiAgICB1c2VybmFtZTogc3RyaW5nOyAvLyBhbHNvIHVzZWQgZm9yIGVtYWlsIGFkZHJlc3NcbiAgICBwaG9uZUNvdW50cnk6IHN0cmluZztcbiAgICBwaG9uZU51bWJlcjogc3RyaW5nO1xuXG4gICAgc2VydmVyQ29uZmlnOiBWYWxpZGF0ZWRTZXJ2ZXJDb25maWc7XG4gICAgbG9naW5JbmNvcnJlY3Q6IGJvb2xlYW47XG4gICAgZGlzYWJsZVN1Ym1pdD86IGJvb2xlYW47XG4gICAgYnVzeT86IGJvb2xlYW47XG5cbiAgICBvblN1Ym1pdCh1c2VybmFtZTogc3RyaW5nLCBwaG9uZUNvdW50cnk6IHZvaWQsIHBob25lTnVtYmVyOiB2b2lkLCBwYXNzd29yZDogc3RyaW5nKTogdm9pZDtcbiAgICBvblN1Ym1pdCh1c2VybmFtZTogdm9pZCwgcGhvbmVDb3VudHJ5OiBzdHJpbmcsIHBob25lTnVtYmVyOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcpOiB2b2lkO1xuICAgIG9uVXNlcm5hbWVDaGFuZ2VkPyh1c2VybmFtZTogc3RyaW5nKTogdm9pZDtcbiAgICBvblVzZXJuYW1lQmx1cj8odXNlcm5hbWU6IHN0cmluZyk6IHZvaWQ7XG4gICAgb25QaG9uZUNvdW50cnlDaGFuZ2VkPyhwaG9uZUNvdW50cnk6IHN0cmluZyk6IHZvaWQ7XG4gICAgb25QaG9uZU51bWJlckNoYW5nZWQ/KHBob25lTnVtYmVyOiBzdHJpbmcpOiB2b2lkO1xuICAgIG9uRm9yZ290UGFzc3dvcmRDbGljaz8oKTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgZmllbGRWYWxpZDogUGFydGlhbDxSZWNvcmQ8TG9naW5GaWVsZCwgYm9vbGVhbj4+O1xuICAgIGxvZ2luVHlwZTogTG9naW5GaWVsZC5FbWFpbCB8IExvZ2luRmllbGQuTWF0cml4SWQgfCBMb2dpbkZpZWxkLlBob25lO1xuICAgIHBhc3N3b3JkOiBzdHJpbmc7XG59XG5cbmNvbnN0IGVudW0gTG9naW5GaWVsZCB7XG4gICAgRW1haWwgPSBcImxvZ2luX2ZpZWxkX2VtYWlsXCIsXG4gICAgTWF0cml4SWQgPSBcImxvZ2luX2ZpZWxkX214aWRcIixcbiAgICBQaG9uZSA9IFwibG9naW5fZmllbGRfcGhvbmVcIixcbiAgICBQYXNzd29yZCA9IFwibG9naW5fZmllbGRfcGFzc3dvcmRcIixcbn1cblxuLypcbiAqIEEgcHVyZSBVSSBjb21wb25lbnQgd2hpY2ggZGlzcGxheXMgYSB1c2VybmFtZS9wYXNzd29yZCBmb3JtLlxuICogVGhlIGVtYWlsL3VzZXJuYW1lL3Bob25lIGZpZWxkcyBhcmUgZnVsbHktY29udHJvbGxlZCwgdGhlIHBhc3N3b3JkIGZpZWxkIGlzIG5vdC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGFzc3dvcmRMb2dpbiBleHRlbmRzIFJlYWN0LlB1cmVDb21wb25lbnQ8SVByb3BzLCBJU3RhdGU+IHtcbiAgICBwcml2YXRlIFtMb2dpbkZpZWxkLkVtYWlsXTogRmllbGQgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIFtMb2dpbkZpZWxkLlBob25lXTogRmllbGQgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIFtMb2dpbkZpZWxkLk1hdHJpeElkXTogRmllbGQgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIFtMb2dpbkZpZWxkLlBhc3N3b3JkXTogRmllbGQgfCBudWxsID0gbnVsbDtcblxuICAgIHB1YmxpYyBzdGF0aWMgZGVmYXVsdFByb3BzID0ge1xuICAgICAgICBvblVzZXJuYW1lQ2hhbmdlZDogZnVuY3Rpb24gKCkge30sXG4gICAgICAgIG9uVXNlcm5hbWVCbHVyOiBmdW5jdGlvbiAoKSB7fSxcbiAgICAgICAgb25QaG9uZUNvdW50cnlDaGFuZ2VkOiBmdW5jdGlvbiAoKSB7fSxcbiAgICAgICAgb25QaG9uZU51bWJlckNoYW5nZWQ6IGZ1bmN0aW9uICgpIHt9LFxuICAgICAgICBsb2dpbkluY29ycmVjdDogZmFsc2UsXG4gICAgICAgIGRpc2FibGVTdWJtaXQ6IGZhbHNlLFxuICAgIH07XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJvcHM6IElQcm9wcykge1xuICAgICAgICBzdXBlcihwcm9wcyk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICAvLyBGaWVsZCBlcnJvciBjb2RlcyBieSBmaWVsZCBJRFxuICAgICAgICAgICAgZmllbGRWYWxpZDoge30sXG4gICAgICAgICAgICBsb2dpblR5cGU6IExvZ2luRmllbGQuTWF0cml4SWQsXG4gICAgICAgICAgICBwYXNzd29yZDogXCJcIixcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uRm9yZ290UGFzc3dvcmRDbGljayA9IChldjogQnV0dG9uRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMucHJvcHMub25Gb3Jnb3RQYXNzd29yZENsaWNrPy4oKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblN1Ym1pdEZvcm0gPSBhc3luYyAoZXY6IFN5bnRoZXRpY0V2ZW50KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgY29uc3QgYWxsRmllbGRzVmFsaWQgPSBhd2FpdCB0aGlzLnZlcmlmeUZpZWxkc0JlZm9yZVN1Ym1pdCgpO1xuICAgICAgICBpZiAoIWFsbEZpZWxkc1ZhbGlkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzd2l0Y2ggKHRoaXMuc3RhdGUubG9naW5UeXBlKSB7XG4gICAgICAgICAgICBjYXNlIExvZ2luRmllbGQuRW1haWw6XG4gICAgICAgICAgICBjYXNlIExvZ2luRmllbGQuTWF0cml4SWQ6XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vblN1Ym1pdCh0aGlzLnByb3BzLnVzZXJuYW1lLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGhpcy5zdGF0ZS5wYXNzd29yZCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIExvZ2luRmllbGQuUGhvbmU6XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vblN1Ym1pdCh1bmRlZmluZWQsIHRoaXMucHJvcHMucGhvbmVDb3VudHJ5LCB0aGlzLnByb3BzLnBob25lTnVtYmVyLCB0aGlzLnN0YXRlLnBhc3N3b3JkKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIG9uVXNlcm5hbWVDaGFuZ2VkID0gKGV2OiBSZWFjdC5DaGFuZ2VFdmVudDxIVE1MSW5wdXRFbGVtZW50Pik6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnByb3BzLm9uVXNlcm5hbWVDaGFuZ2VkPy4oZXYudGFyZ2V0LnZhbHVlKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblVzZXJuYW1lQmx1ciA9IChldjogUmVhY3QuRm9jdXNFdmVudDxIVE1MSW5wdXRFbGVtZW50Pik6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnByb3BzLm9uVXNlcm5hbWVCbHVyPy4oZXYudGFyZ2V0LnZhbHVlKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkxvZ2luVHlwZUNoYW5nZSA9IChldjogUmVhY3QuQ2hhbmdlRXZlbnQ8SFRNTFNlbGVjdEVsZW1lbnQ+KTogdm9pZCA9PiB7XG4gICAgICAgIGNvbnN0IGxvZ2luVHlwZSA9IGV2LnRhcmdldC52YWx1ZSBhcyBJU3RhdGVbXCJsb2dpblR5cGVcIl07XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsb2dpblR5cGUgfSk7XG4gICAgICAgIHRoaXMucHJvcHMub25Vc2VybmFtZUNoYW5nZWQ/LihcIlwiKTsgLy8gUmVzZXQgYmVjYXVzZSBlbWFpbCBhbmQgdXNlcm5hbWUgdXNlIHRoZSBzYW1lIHN0YXRlXG4gICAgfTtcblxuICAgIHByaXZhdGUgb25QaG9uZUNvdW50cnlDaGFuZ2VkID0gKGNvdW50cnk6IFBob25lTnVtYmVyQ291bnRyeURlZmluaXRpb24pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblBob25lQ291bnRyeUNoYW5nZWQ/Lihjb3VudHJ5LmlzbzIpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIG9uUGhvbmVOdW1iZXJDaGFuZ2VkID0gKGV2OiBSZWFjdC5DaGFuZ2VFdmVudDxIVE1MSW5wdXRFbGVtZW50Pik6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnByb3BzLm9uUGhvbmVOdW1iZXJDaGFuZ2VkPy4oZXYudGFyZ2V0LnZhbHVlKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblBhc3N3b3JkQ2hhbmdlZCA9IChldjogUmVhY3QuQ2hhbmdlRXZlbnQ8SFRNTElucHV0RWxlbWVudD4pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHBhc3N3b3JkOiBldi50YXJnZXQudmFsdWUgfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgYXN5bmMgdmVyaWZ5RmllbGRzQmVmb3JlU3VibWl0KCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICAvLyBCbHVyIHRoZSBhY3RpdmUgZWxlbWVudCBpZiBhbnksIHNvIHdlIGZpcnN0IHJ1biBpdHMgYmx1ciB2YWxpZGF0aW9uLFxuICAgICAgICAvLyB3aGljaCBpcyBsZXNzIHN0cmljdCB0aGFuIHRoZSBwYXNzIHdlJ3JlIGFib3V0IHRvIGRvIGJlbG93IGZvciBhbGwgZmllbGRzLlxuICAgICAgICBjb25zdCBhY3RpdmVFbGVtZW50ID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKGFjdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIGFjdGl2ZUVsZW1lbnQuYmx1cigpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmllbGRJRHNJbkRpc3BsYXlPcmRlciA9IFt0aGlzLnN0YXRlLmxvZ2luVHlwZSwgTG9naW5GaWVsZC5QYXNzd29yZF07XG5cbiAgICAgICAgLy8gUnVuIGFsbCBmaWVsZHMgd2l0aCBzdHJpY3RlciB2YWxpZGF0aW9uIHRoYXQgbm8gbG9uZ2VyIGFsbG93cyBlbXB0eVxuICAgICAgICAvLyB2YWx1ZXMgZm9yIHJlcXVpcmVkIGZpZWxkcy5cbiAgICAgICAgZm9yIChjb25zdCBmaWVsZElEIG9mIGZpZWxkSURzSW5EaXNwbGF5T3JkZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpZWxkID0gdGhpc1tmaWVsZElEXTtcbiAgICAgICAgICAgIGlmICghZmllbGQpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFdlIG11c3Qgd2FpdCBmb3IgdGhlc2UgdmFsaWRhdGlvbnMgdG8gZmluaXNoIGJlZm9yZSBxdWV1ZWluZ1xuICAgICAgICAgICAgLy8gdXAgdGhlIHNldFN0YXRlIGJlbG93IHNvIG91ciBzZXRTdGF0ZSBnb2VzIGluIHRoZSBxdWV1ZSBhZnRlclxuICAgICAgICAgICAgLy8gYWxsIHRoZSBzZXRTdGF0ZXMgZnJvbSB0aGVzZSB2YWxpZGF0ZSBjYWxscyAodGhhdCdzIGhvdyB3ZVxuICAgICAgICAgICAgLy8ga25vdyB0aGV5J3ZlIGZpbmlzaGVkKS5cbiAgICAgICAgICAgIGF3YWl0IGZpZWxkLnZhbGlkYXRlKHsgYWxsb3dFbXB0eTogZmFsc2UgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBWYWxpZGF0aW9uIGFuZCBzdGF0ZSB1cGRhdGVzIGFyZSBhc3luYywgc28gd2UgbmVlZCB0byB3YWl0IGZvciB0aGVtIHRvIGNvbXBsZXRlXG4gICAgICAgIC8vIGZpcnN0LiBRdWV1ZSBhIGBzZXRTdGF0ZWAgY2FsbGJhY2sgYW5kIHdhaXQgZm9yIGl0IHRvIHJlc29sdmUuXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB0aGlzLnNldFN0YXRlKHt9LCByZXNvbHZlKSk7XG5cbiAgICAgICAgaWYgKHRoaXMuYWxsRmllbGRzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbnZhbGlkRmllbGQgPSB0aGlzLmZpbmRGaXJzdEludmFsaWRGaWVsZChmaWVsZElEc0luRGlzcGxheU9yZGVyKTtcblxuICAgICAgICBpZiAoIWludmFsaWRGaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb2N1cyB0aGUgZmlyc3QgaW52YWxpZCBmaWVsZCBhbmQgc2hvdyBmZWVkYmFjayBpbiB0aGUgc3RyaWN0ZXIgbW9kZVxuICAgICAgICAvLyB0aGF0IG5vIGxvbmdlciBhbGxvd3MgZW1wdHkgdmFsdWVzIGZvciByZXF1aXJlZCBmaWVsZHMuXG4gICAgICAgIGludmFsaWRGaWVsZC5mb2N1cygpO1xuICAgICAgICBpbnZhbGlkRmllbGQudmFsaWRhdGUoeyBhbGxvd0VtcHR5OiBmYWxzZSwgZm9jdXNlZDogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgYWxsRmllbGRzVmFsaWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMuc3RhdGUuZmllbGRWYWxpZCkuZXZlcnkoQm9vbGVhbik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmaW5kRmlyc3RJbnZhbGlkRmllbGQoZmllbGRJRHM6IExvZ2luRmllbGRbXSk6IEZpZWxkIHwgbnVsbCB7XG4gICAgICAgIGZvciAoY29uc3QgZmllbGRJRCBvZiBmaWVsZElEcykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmZpZWxkVmFsaWRbZmllbGRJRF0gJiYgdGhpc1tmaWVsZElEXSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW2ZpZWxkSURdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgbWFya0ZpZWxkVmFsaWQoZmllbGRJRDogTG9naW5GaWVsZCwgdmFsaWQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHsgZmllbGRWYWxpZCB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgICAgZmllbGRWYWxpZFtmaWVsZElEXSA9IHZhbGlkO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGZpZWxkVmFsaWQsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgdmFsaWRhdGVVc2VybmFtZVJ1bGVzID0gd2l0aFZhbGlkYXRpb24oe1xuICAgICAgICBydWxlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGtleTogXCJyZXF1aXJlZFwiLFxuICAgICAgICAgICAgICAgIHRlc3QoeyB2YWx1ZSwgYWxsb3dFbXB0eSB9KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbGxvd0VtcHR5IHx8ICEhdmFsdWU7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpbnZhbGlkOiAoKSA9PiBfdChcImF1dGh8dXNlcm5hbWVfZmllbGRfcmVxdWlyZWRfaW52YWxpZFwiKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBwcml2YXRlIG9uVXNlcm5hbWVWYWxpZGF0ZSA9IGFzeW5jIChmaWVsZFN0YXRlOiBJRmllbGRTdGF0ZSk6IFByb21pc2U8SVZhbGlkYXRpb25SZXN1bHQ+ID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy52YWxpZGF0ZVVzZXJuYW1lUnVsZXMoZmllbGRTdGF0ZSk7XG4gICAgICAgIHRoaXMubWFya0ZpZWxkVmFsaWQoTG9naW5GaWVsZC5NYXRyaXhJZCwgcmVzdWx0LnZhbGlkKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkVtYWlsVmFsaWRhdGUgPSAocmVzdWx0OiBJVmFsaWRhdGlvblJlc3VsdCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLm1hcmtGaWVsZFZhbGlkKExvZ2luRmllbGQuRW1haWwsIHJlc3VsdC52YWxpZCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgdmFsaWRhdGVQaG9uZU51bWJlclJ1bGVzID0gd2l0aFZhbGlkYXRpb24oe1xuICAgICAgICBydWxlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGtleTogXCJyZXF1aXJlZFwiLFxuICAgICAgICAgICAgICAgIHRlc3QoeyB2YWx1ZSwgYWxsb3dFbXB0eSB9KTogYm9vbGVhbiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbGxvd0VtcHR5IHx8ICEhdmFsdWU7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpbnZhbGlkOiAoKTogc3RyaW5nID0+IF90KFwiYXV0aHxtc2lzZG5fZmllbGRfcmVxdWlyZWRfaW52YWxpZFwiKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2V5OiBcIm51bWJlclwiLFxuICAgICAgICAgICAgICAgIHRlc3Q6ICh7IHZhbHVlIH0pOiBib29sZWFuID0+ICF2YWx1ZSB8fCBQSE9ORV9OVU1CRVJfUkVHRVgudGVzdCh2YWx1ZSksXG4gICAgICAgICAgICAgICAgaW52YWxpZDogKCk6IHN0cmluZyA9PiBfdChcImF1dGh8bXNpc2RuX2ZpZWxkX251bWJlcl9pbnZhbGlkXCIpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICB9KTtcblxuICAgIHByaXZhdGUgb25QaG9uZU51bWJlclZhbGlkYXRlID0gYXN5bmMgKGZpZWxkU3RhdGU6IElGaWVsZFN0YXRlKTogUHJvbWlzZTxJVmFsaWRhdGlvblJlc3VsdD4gPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnZhbGlkYXRlUGhvbmVOdW1iZXJSdWxlcyhmaWVsZFN0YXRlKTtcbiAgICAgICAgdGhpcy5tYXJrRmllbGRWYWxpZChMb2dpbkZpZWxkLlBhc3N3b3JkLCByZXN1bHQudmFsaWQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBwcml2YXRlIHZhbGlkYXRlUGFzc3dvcmRSdWxlcyA9IHdpdGhWYWxpZGF0aW9uKHtcbiAgICAgICAgcnVsZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBrZXk6IFwicmVxdWlyZWRcIixcbiAgICAgICAgICAgICAgICB0ZXN0KHsgdmFsdWUsIGFsbG93RW1wdHkgfSk6IGJvb2xlYW4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWxsb3dFbXB0eSB8fCAhIXZhbHVlO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaW52YWxpZDogKCk6IHN0cmluZyA9PiBfdChcImF1dGh8cGFzc3dvcmRfZmllbGRfbGFiZWxcIiksXG4gICAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgIH0pO1xuXG4gICAgcHJpdmF0ZSBvblBhc3N3b3JkVmFsaWRhdGUgPSBhc3luYyAoZmllbGRTdGF0ZTogSUZpZWxkU3RhdGUpOiBQcm9taXNlPElWYWxpZGF0aW9uUmVzdWx0PiA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMudmFsaWRhdGVQYXNzd29yZFJ1bGVzKGZpZWxkU3RhdGUpO1xuICAgICAgICB0aGlzLm1hcmtGaWVsZFZhbGlkKExvZ2luRmllbGQuUGFzc3dvcmQsIHJlc3VsdC52YWxpZCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIHByaXZhdGUgcmVuZGVyTG9naW5GaWVsZChsb2dpblR5cGU6IElTdGF0ZVtcImxvZ2luVHlwZVwiXSwgYXV0b0ZvY3VzOiBib29sZWFuKTogSlNYLkVsZW1lbnQge1xuICAgICAgICBjb25zdCBjbGFzc2VzID0ge1xuICAgICAgICAgICAgZXJyb3I6IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIHN3aXRjaCAobG9naW5UeXBlKSB7XG4gICAgICAgICAgICBjYXNlIExvZ2luRmllbGQuRW1haWw6XG4gICAgICAgICAgICAgICAgY2xhc3Nlcy5lcnJvciA9IHRoaXMucHJvcHMubG9naW5JbmNvcnJlY3QgJiYgIXRoaXMucHJvcHMudXNlcm5hbWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPEVtYWlsRmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwibXhfTG9naW5Gb3JtX2VtYWlsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcyhjbGFzc2VzKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ1c2VybmFtZVwiIC8vIG1ha2UgaXQgYSBsaXR0bGUgZWFzaWVyIGZvciBicm93c2VyJ3MgcmVtZW1iZXItcGFzc3dvcmRcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9Db21wbGV0ZT1cImVtYWlsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJlbWFpbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXk9XCJlbWFpbF9pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImpvZUBleGFtcGxlLmNvbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5wcm9wcy51c2VybmFtZX1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLm9uVXNlcm5hbWVDaGFuZ2VkfVxuICAgICAgICAgICAgICAgICAgICAgICAgb25CbHVyPXt0aGlzLm9uVXNlcm5hbWVCbHVyfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e3RoaXMucHJvcHMuYnVzeX1cbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9Gb2N1cz17YXV0b0ZvY3VzfVxuICAgICAgICAgICAgICAgICAgICAgICAgb25WYWxpZGF0ZT17dGhpcy5vbkVtYWlsVmFsaWRhdGV9XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWVsZFJlZj17KGZpZWxkKTogdm9pZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1tMb2dpbkZpZWxkLkVtYWlsXSA9IGZpZWxkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSBMb2dpbkZpZWxkLk1hdHJpeElkOlxuICAgICAgICAgICAgICAgIGNsYXNzZXMuZXJyb3IgPSB0aGlzLnByb3BzLmxvZ2luSW5jb3JyZWN0ICYmICF0aGlzLnByb3BzLnVzZXJuYW1lO1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJteF9Mb2dpbkZvcm1fdXNlcm5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKGNsYXNzZXMpfVxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInVzZXJuYW1lXCIgLy8gbWFrZSBpdCBhIGxpdHRsZSBlYXNpZXIgZm9yIGJyb3dzZXIncyByZW1lbWJlci1wYXNzd29yZFxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b0NvbXBsZXRlPVwidXNlcm5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAga2V5PVwidXNlcm5hbWVfaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9e190KFwiY29tbW9ufHVzZXJuYW1lXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9e190KFwiY29tbW9ufHVzZXJuYW1lXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMucHJvcHMudXNlcm5hbWV9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5vblVzZXJuYW1lQ2hhbmdlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQmx1cj17dGhpcy5vblVzZXJuYW1lQmx1cn1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXt0aGlzLnByb3BzLmJ1c3l9XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvRm9jdXM9e2F1dG9Gb2N1c31cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uVmFsaWRhdGU9e3RoaXMub25Vc2VybmFtZVZhbGlkYXRlfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmPXsoZmllbGQpOiB2b2lkID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzW0xvZ2luRmllbGQuTWF0cml4SWRdID0gZmllbGQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjYXNlIExvZ2luRmllbGQuUGhvbmU6IHtcbiAgICAgICAgICAgICAgICBjbGFzc2VzLmVycm9yID0gdGhpcy5wcm9wcy5sb2dpbkluY29ycmVjdCAmJiAhdGhpcy5wcm9wcy5waG9uZU51bWJlcjtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHBob25lQ291bnRyeSA9IChcbiAgICAgICAgICAgICAgICAgICAgPENvdW50cnlEcm9wZG93blxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMucHJvcHMucGhvbmVDb3VudHJ5fVxuICAgICAgICAgICAgICAgICAgICAgICAgaXNTbWFsbD17dHJ1ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dQcmVmaXg9e3RydWV9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbk9wdGlvbkNoYW5nZT17dGhpcy5vblBob25lQ291bnRyeUNoYW5nZWR9XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJteF9Mb2dpbkZvcm1fcGhvbmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKGNsYXNzZXMpfVxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBob25lTnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9Db21wbGV0ZT1cInRlbC1uYXRpb25hbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXk9XCJwaG9uZV9pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJhdXRofG1zaXNkbl9maWVsZF9sYWJlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXt0aGlzLnByb3BzLnBob25lTnVtYmVyfVxuICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4Q29tcG9uZW50PXtwaG9uZUNvdW50cnl9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5vblBob25lTnVtYmVyQ2hhbmdlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXt0aGlzLnByb3BzLmJ1c3l9XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvRm9jdXM9e2F1dG9Gb2N1c31cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uVmFsaWRhdGU9e3RoaXMub25QaG9uZU51bWJlclZhbGlkYXRlfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmPXsoZmllbGQpOiB2b2lkID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzW0xvZ2luRmllbGQuUGFzc3dvcmRdID0gZmllbGQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGlzTG9naW5FbXB0eSgpOiBib29sZWFuIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLnN0YXRlLmxvZ2luVHlwZSkge1xuICAgICAgICAgICAgY2FzZSBMb2dpbkZpZWxkLkVtYWlsOlxuICAgICAgICAgICAgY2FzZSBMb2dpbkZpZWxkLk1hdHJpeElkOlxuICAgICAgICAgICAgICAgIHJldHVybiAhdGhpcy5wcm9wcy51c2VybmFtZTtcbiAgICAgICAgICAgIGNhc2UgTG9naW5GaWVsZC5QaG9uZTpcbiAgICAgICAgICAgICAgICByZXR1cm4gIXRoaXMucHJvcHMucGhvbmVDb3VudHJ5IHx8ICF0aGlzLnByb3BzLnBob25lTnVtYmVyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHJlbmRlcigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgICAgICBsZXQgZm9yZ290UGFzc3dvcmRKc3g6IEpTWC5FbGVtZW50IHwgdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uRm9yZ290UGFzc3dvcmRDbGljaykge1xuICAgICAgICAgICAgZm9yZ290UGFzc3dvcmRKc3ggPSAoXG4gICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfTG9naW5fZm9yZ290XCJcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e3RoaXMucHJvcHMuYnVzeX1cbiAgICAgICAgICAgICAgICAgICAga2luZD1cImxpbmtcIlxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLm9uRm9yZ290UGFzc3dvcmRDbGlja31cbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIHtfdChcImF1dGh8cmVzZXRfcGFzc3dvcmRfYnV0dG9uXCIpfVxuICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwd0ZpZWxkQ2xhc3MgPSBjbGFzc05hbWVzKHtcbiAgICAgICAgICAgIGVycm9yOiB0aGlzLnByb3BzLmxvZ2luSW5jb3JyZWN0ICYmICF0aGlzLmlzTG9naW5FbXB0eSgpLCAvLyBvbmx5IGVycm9yIHBhc3N3b3JkIGlmIGVycm9yIGlzbid0IHRvcCBmaWVsZFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBJZiBsb2dpbiBpcyBlbXB0eSwgYXV0b0ZvY3VzIGxvZ2luLCBvdGhlcndpc2UgYXV0b0ZvY3VzIHBhc3N3b3JkLlxuICAgICAgICAvLyB0aGlzIGlzIGZvciB3aGVuIGF1dG8gc2VydmVyIGRpc2NvdmVyeSByZW1vdW50cyB1cyB3aGVuIHRoZSB1c2VyIHRyaWVzIHRvIHRhYiBmcm9tIHVzZXJuYW1lIHRvIHBhc3N3b3JkXG4gICAgICAgIGNvbnN0IGF1dG9Gb2N1c1Bhc3N3b3JkID0gIXRoaXMuaXNMb2dpbkVtcHR5KCk7XG4gICAgICAgIGNvbnN0IGxvZ2luRmllbGQgPSB0aGlzLnJlbmRlckxvZ2luRmllbGQodGhpcy5zdGF0ZS5sb2dpblR5cGUsICFhdXRvRm9jdXNQYXNzd29yZCk7XG5cbiAgICAgICAgbGV0IGxvZ2luVHlwZTtcbiAgICAgICAgaWYgKCFTZGtDb25maWcuZ2V0KCkuZGlzYWJsZV8zcGlkX2xvZ2luKSB7XG4gICAgICAgICAgICBsb2dpblR5cGUgPSAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Mb2dpbl90eXBlX2NvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPVwibXhfTG9naW5fdHlwZV9sYWJlbFwiPntfdChcImF1dGh8aWRlbnRpZmllcl9sYWJlbFwiKX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8RmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ9XCJzZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMuc3RhdGUubG9naW5UeXBlfVxuICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e3RoaXMub25Mb2dpblR5cGVDaGFuZ2V9XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17dGhpcy5wcm9wcy5idXN5fVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIGtleT17TG9naW5GaWVsZC5NYXRyaXhJZH0gdmFsdWU9e0xvZ2luRmllbGQuTWF0cml4SWR9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcImNvbW1vbnx1c2VybmFtZVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBrZXk9e0xvZ2luRmllbGQuRW1haWx9IHZhbHVlPXtMb2dpbkZpZWxkLkVtYWlsfT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJjb21tb258ZW1haWxfYWRkcmVzc1wiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBrZXk9e0xvZ2luRmllbGQuUGFzc3dvcmR9IHZhbHVlPXtMb2dpbkZpZWxkLlBhc3N3b3JkfT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJhdXRofG1zaXNkbl9maWVsZF9sYWJlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L0ZpZWxkPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxmb3JtIG9uU3VibWl0PXt0aGlzLm9uU3VibWl0Rm9ybX0+XG4gICAgICAgICAgICAgICAgICAgIHtsb2dpblR5cGV9XG4gICAgICAgICAgICAgICAgICAgIHtsb2dpbkZpZWxkfVxuICAgICAgICAgICAgICAgICAgICA8RmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwibXhfTG9naW5Gb3JtX3Bhc3N3b3JkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17cHdGaWVsZENsYXNzfVxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b0NvbXBsZXRlPVwiY3VycmVudC1wYXNzd29yZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwicGFzc3dvcmRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhc3N3b3JkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPXtfdChcImNvbW1vbnxwYXNzd29yZFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXt0aGlzLnN0YXRlLnBhc3N3b3JkfVxuICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e3RoaXMub25QYXNzd29yZENoYW5nZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17dGhpcy5wcm9wcy5idXN5fVxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b0ZvY3VzPXthdXRvRm9jdXNQYXNzd29yZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uVmFsaWRhdGU9e3RoaXMub25QYXNzd29yZFZhbGlkYXRlfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmPXsoZmllbGQpID0+ICh0aGlzW0xvZ2luRmllbGQuUGFzc3dvcmRdID0gZmllbGQpfVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICB7Zm9yZ290UGFzc3dvcmRKc3h9XG4gICAgICAgICAgICAgICAgICAgIHshdGhpcy5wcm9wcy5idXN5ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X0xvZ2luX3N1Ym1pdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e190KFwiYWN0aW9ufHNpZ25faW5cIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e3RoaXMucHJvcHMuZGlzYWJsZVN1Ym1pdH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQVFBLElBQUFBLE1BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLFdBQUEsR0FBQUYsc0JBQUEsQ0FBQUMsT0FBQTtBQUVBLElBQUFFLGdCQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxVQUFBLEdBQUFKLHNCQUFBLENBQUFDLE9BQUE7QUFFQSxJQUFBSSxpQkFBQSxHQUFBTCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUssV0FBQSxHQUFBTixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQU0sTUFBQSxHQUFBUCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQU8sZ0JBQUEsR0FBQVIsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFRLFdBQUEsR0FBQVQsc0JBQUEsQ0FBQUMsT0FB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