kwikid-forms
Version:
KwikID's JSON Configuration based Forms Renderer and Builder
251 lines • 36.2 kB
JavaScript
import { __awaiter, __decorate } from "tslib";
/* eslint-disable no-unused-vars */
/* eslint-disable @typescript-eslint/no-unused-vars */
import axios from "axios";
import { decryptWithAES, encryptWithAES, isNotEmptyValue, logMethod } from "kwikid-toolkit";
import { Observable } from "rxjs";
import { v4 as uuidv4 } from "uuid";
import { resolveFormsStorageConfig, resolveFormsStorageString } from "../helpers/forms-storage.helper";
export class KwikIDFormViewApiService {
constructor() {
this.bytecode = [0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38];
this.reduxData = {};
this.userConfig = undefined;
}
setStorageContext(reduxData = {}, userConfig) {
this.reduxData = reduxData !== null && reduxData !== void 0 ? reduxData : {};
this.userConfig = userConfig;
}
/** Fresh config from host utilityFlags / formsStorage on every resolve. */
getStorageConfig() {
return resolveFormsStorageConfig(this.userConfig);
}
// Function to derive logic from data
dataDerivativeLogic(data) {
if (isNotEmptyValue(data)) {
const dataString = JSON.stringify(data);
const charCounts = {};
const targetCharacters = ["a", "i", "p", "t"];
// Count occurrences of target characters in the data string
for (const char of dataString) {
if (targetCharacters.includes(char)) {
charCounts[char] = (charCounts[char] || 0) + 1;
}
}
// Construct the output string based on the character counts
const outputString = targetCharacters
.map((char) => char + (charCounts[char] || 0))
.join("");
return outputString;
}
return undefined;
}
// Function to preprocess header data
preProcessHeader(headerData, isVerifySignature) {
if (!headerData) {
headerData = {};
}
if (!headerData.headers) {
headerData.headers = {};
}
// Generate a unique identifier if signature verification is required
if (isVerifySignature) {
headerData.headers.xrid = uuidv4();
}
const sessionId = resolveFormsStorageString("session_id", this.reduxData, this.getStorageConfig());
if (sessionId) {
headerData.headers.ses = sessionId;
}
return headerData;
}
// Function to verify the signature
verifySignature(data, header, url, isVerifySignature) {
return new Promise((resolve, reject) => {
// Check if the signature is disabled
if (!isVerifySignature) {
resolve(true);
}
else if (!data) {
// Check if data is invalid
resolve(true);
}
else if (isVerifySignature && header && !(header === null || header === void 0 ? void 0 : header.sig)) {
// Check if the signature is missing in headers when authentication is not skipped
reject(false);
}
else if (isVerifySignature && header && (header === null || header === void 0 ? void 0 : header.sig)) {
// Verify the signature when public key and header with signature are present and authentication is not skipped
// Extract the signature and decode it
let signature = header.sig.split(".")[0];
const rawSignature = atob(signature);
// Split the decoded signature to get the parts
signature = rawSignature.split(".")[0];
const exp = `${rawSignature.split(".")[1]}000`; // Expiration time in milliseconds
const iat = `${rawSignature.split(".")[2]}000`; // Issued at time in milliseconds
// Check if the signature is valid
if (signature) {
// Check if the current time is before the expiration time
const dateValue = new Date().valueOf();
const dateCheck = dateValue < parseInt(exp, 10);
// Check if the signature matches the data
const res = signature === data;
// Resolve the promise if the signature is valid and the date check passes
if (res && dateCheck) {
resolve(res);
}
else {
// Reject the promise if the signature is invalid or the date check fails
reject(res);
}
}
else {
// Reject the promise if the signature is not in the required format
reject(false);
}
}
else {
// Resolve the promise if the signature is missing in headers
resolve(true);
}
});
}
// Function to perform POST request
post(url, body, headerData, isEncrypt = false, isDecrypt = false, isVerifySignature = false, isSkipHeaderAlteration = false) {
let preProcessedHeader = headerData;
// Preprocess header data unless instructed to skip
if (!isSkipHeaderAlteration) {
preProcessedHeader = this.preProcessHeader(headerData, isVerifySignature);
}
else {
preProcessedHeader.observe = "response";
}
// Encrypt body if required
if (isEncrypt) {
body = encryptWithAES(JSON.stringify(body));
}
return new Observable((subscriber) => {
axios.post(url, body, headerData).then((res) => __awaiter(this, void 0, void 0, function* () {
let { data } = res;
// Decrypt response if required
if (data && isDecrypt) {
const encryptedResponse = data;
const decryptedResponse = yield decryptWithAES(encryptedResponse);
data = JSON.parse(decryptedResponse);
res.data = data;
}
// Verify signature and handle response
this.verifySignature(this.dataDerivativeLogic(data), res === null || res === void 0 ? void 0 : res.headers, url, isVerifySignature)
.then((verification) => {
subscriber.next(res);
subscriber.complete();
})
.catch((err) => {
subscriber.error(err === null || err === void 0 ? void 0 : err.response);
});
}), (err) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
let data = (_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.data;
// Decrypt error response if required
if (data && isDecrypt) {
const encryptedResponse = data;
const decryptedResponse = yield decryptWithAES(encryptedResponse);
data = JSON.parse(decryptedResponse);
err.response.data = data;
}
// Verify signature and handle response
this.verifySignature(this.dataDerivativeLogic(data), (_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.headers, url, isVerifySignature)
.then((verification) => {
subscriber.error(err === null || err === void 0 ? void 0 : err.response);
})
.catch((err) => {
subscriber.error(err === null || err === void 0 ? void 0 : err.response);
});
}));
});
}
// Function to perform GET request
get(url, headerData = undefined, isDecrypt = false, isVerifySignature = false, isSkipHeaderAlteration = false) {
let preProcessedHeader = headerData;
// Preprocess header data unless instructed to skip
if (!isSkipHeaderAlteration) {
preProcessedHeader = this.preProcessHeader(headerData, isVerifySignature);
}
else {
preProcessedHeader.observe = "response";
}
return new Observable((subscriber) => {
axios.get(url, preProcessedHeader).then((res) => __awaiter(this, void 0, void 0, function* () {
let { data } = res;
// Decrypt response if required
if (isDecrypt) {
const encryptedResponse = data;
const decryptedResponse = yield decryptWithAES(encryptedResponse);
data = JSON.parse(decryptedResponse);
res.data = data;
}
// Verify signature and handle response
this.verifySignature(this.dataDerivativeLogic(data), res === null || res === void 0 ? void 0 : res.headers, url, isVerifySignature)
.then((verification) => {
subscriber.next(res);
subscriber.complete();
})
.catch((err) => {
subscriber.error(err === null || err === void 0 ? void 0 : err.response);
});
}), (err) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
let data = (_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.data;
// Decrypt error response if required
if (data && isDecrypt) {
const encryptedResponse = data;
const decryptedResponse = yield decryptWithAES(encryptedResponse);
data = JSON.parse(decryptedResponse);
err.response.data = data;
}
// Verify signature and handle response
this.verifySignature(this.dataDerivativeLogic(data), (_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.headers, url, isVerifySignature)
.then((verification) => {
subscriber.error(err === null || err === void 0 ? void 0 : err.response);
})
.catch((err) => {
subscriber.error(err === null || err === void 0 ? void 0 : err.response);
});
}));
});
}
// Function to execute API call based on method type
executeApiCall(url, method, body, headers, isEncrypt, isDecrypt, isVerifySignature) {
return new Promise((resolve) => {
if (method === "GET") {
this.get(url, { headers }, isDecrypt, isVerifySignature).subscribe((res) => {
resolve(res);
}, (err) => {
resolve(err);
});
}
else {
this.post(url, body, { headers }, isEncrypt, isDecrypt, isVerifySignature).subscribe((res) => {
resolve(res);
}, (err) => {
resolve(err);
});
}
});
}
}
__decorate([
logMethod
], KwikIDFormViewApiService.prototype, "dataDerivativeLogic", null);
__decorate([
logMethod
], KwikIDFormViewApiService.prototype, "preProcessHeader", null);
__decorate([
logMethod
], KwikIDFormViewApiService.prototype, "verifySignature", null);
__decorate([
logMethod
], KwikIDFormViewApiService.prototype, "post", null);
__decorate([
logMethod
], KwikIDFormViewApiService.prototype, "get", null);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS12aWV3LmFwaS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva3dpa2lkLWZvcm1zL3NyYy9saWIvcmVuZGVyZXIvZm9ybS12aWV3L2Zvcm0tdmlldy5hcGkuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsbUNBQW1DO0FBQ25DLHNEQUFzRDtBQUN0RCxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDMUIsT0FBTyxFQUNMLGNBQWMsRUFDZCxjQUFjLEVBQ2QsZUFBZSxFQUNmLFNBQVMsRUFDVixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFFLEVBQUUsSUFBSSxNQUFNLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxFQUVMLHlCQUF5QixFQUN6Qix5QkFBeUIsRUFDMUIsTUFBTSxpQ0FBaUMsQ0FBQztBQUV6QyxNQUFNLE9BQU8sd0JBQXdCO0lBQXJDO1FBQ1UsYUFBUSxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTVELGNBQVMsR0FBNEIsRUFBRSxDQUFDO1FBRXhDLGVBQVUsR0FBUSxTQUFTLENBQUM7SUEyVHRDLENBQUM7SUF6VEMsaUJBQWlCLENBQ2YsWUFBcUMsRUFBRSxFQUN2QyxVQUFnQjtRQUVoQixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsYUFBVCxTQUFTLGNBQVQsU0FBUyxHQUFJLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztJQUMvQixDQUFDO0lBRUQsMkVBQTJFO0lBQ25FLGdCQUFnQjtRQUN0QixPQUFPLHlCQUF5QixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJ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QyxFQUNELENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQ04sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNmLENBQUMsQ0FDRixDQUFDO2FBQ0g7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQTFTQztJQURDLFNBQVM7bUVBcUJUO0FBSUQ7SUFEQyxTQUFTO2dFQXdCVDtBQUlEO0lBREMsU0FBUzsrREFrRFQ7QUFJRDtJQURDLFNBQVM7b0RBK0VUO0FBSUQ7SUFEQyxTQUFTO21EQXdFVCIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbmltcG9ydCBheGlvcyBmcm9tIFwiYXhpb3NcIjtcbmltcG9ydCB7XG4gIGRlY3J5cHRXaXRoQUVTLFxuICBlbmNyeXB0V2l0aEFFUyxcbiAgaXNOb3RFbXB0eVZhbHVlLFxuICBsb2dNZXRob2Rcbn0gZnJvbSBcImt3aWtpZC10b29sa2l0XCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQge1xuICBGb3Jtc1N0b3JhZ2VDb25maWcsXG4gIHJlc29sdmVGb3Jtc1N0b3JhZ2VDb25maWcsXG4gIHJlc29sdmVGb3Jtc1N0b3JhZ2VTdHJpbmdcbn0gZnJvbSBcIi4uL2hlbHBlcnMvZm9ybXMtc3RvcmFnZS5oZWxwZXJcIjtcblxuZXhwb3J0IGNsYXNzIEt3aWtJREZvcm1WaWV3QXBpU2VydmljZSB7XG4gIHByaXZhdGUgYnl0ZWNvZGUgPSBbMHgzOCwgMHgzOCwgMHgzOCwgMHgzOCwgMHgzOCwgMHgzOCwgMHgzOCwgMHgzOF07XG5cbiAgcHJpdmF0ZSByZWR1eERhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgcHJpdmF0ZSB1c2VyQ29uZmlnOiBhbnkgPSB1bmRlZmluZWQ7XG5cbiAgc2V0U3RvcmFnZUNvbnRleHQoXG4gICAgcmVkdXhEYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9LFxuICAgIHVzZXJDb25maWc/OiBhbnlcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5yZWR1eERhdGEgPSByZWR1eERhdGEgPz8ge307XG4gICAgdGhpcy51c2VyQ29uZmlnID0gdXNlckNvbmZpZztcbiAgfVxuXG4gIC8qKiBGcmVzaCBjb25maWcgZnJvbSBob3N0IHV0aWxpdHlGbGFncyAvIGZvcm1zU3RvcmFnZSBvbiBldmVyeSByZXNvbHZlLiAqL1xuICBwcml2YXRlIGdldFN0b3JhZ2VDb25maWcoKTogRm9ybXNTdG9yYWdlQ29uZmlnIHtcbiAgICByZXR1cm4gcmVzb2x2ZUZvcm1zU3RvcmFnZUNvbmZpZyh0aGlzLnVzZXJDb25maWcpO1xuICB9XG5cbiAgLy8gRnVuY3Rpb24gdG8gZGVyaXZlIGxvZ2ljIGZyb20gZGF0YVxuICBAbG9nTWV0aG9kXG4gIGRhdGFEZXJpdmF0aXZlTG9naWMoZGF0YSkge1xuICAgIGlmIChpc05vdEVtcHR5VmFsdWUoZGF0YSkpIHtcbiAgICAgIGNvbnN0IGRhdGFTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShkYXRhKTtcbiAgICAgIGNvbnN0IGNoYXJDb3VudHMgPSB7fTtcbiAgICAgIGNvbnN0IHRhcmdldENoYXJhY3RlcnMgPSBbXCJhXCIsIFwiaVwiLCBcInBcIiwgXCJ0XCJdO1xuXG4gICAgICAvLyBDb3VudCBvY2N1cnJlbmNlcyBvZiB0YXJnZXQgY2hhcmFjdGVycyBpbiB0aGUgZGF0YSBzdHJpbmdcbiAgICAgIGZvciAoY29uc3QgY2hhciBvZiBkYXRhU3RyaW5nKSB7XG4gICAgICAgIGlmICh0YXJnZXRDaGFyYWN0ZXJzLmluY2x1ZGVzKGNoYXIpKSB7XG4gICAgICAgICAgY2hhckNvdW50c1tjaGFyXSA9IChjaGFyQ291bnRzW2NoYXJdIHx8IDApICsgMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBDb25zdHJ1Y3QgdGhlIG91dHB1dCBzdHJpbmcgYmFzZWQgb24gdGhlIGNoYXJhY3RlciBjb3VudHNcbiAgICAgIGNvbnN0IG91dHB1dFN0cmluZyA9IHRhcmdldENoYXJhY3RlcnNcbiAgICAgICAgLm1hcCgoY2hhcikgPT4gY2hhciArIChjaGFyQ291bnRzW2NoYXJdIHx8IDApKVxuICAgICAgICAuam9pbihcIlwiKTtcbiAgICAgIHJldHVybiBvdXRwdXRTdHJpbmc7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyBGdW5jdGlvbiB0byBwcmVwcm9jZXNzIGhlYWRlciBkYXRhXG4gIEBsb2dNZXRob2RcbiAgcHJlUHJvY2Vzc0hlYWRlcihoZWFkZXJEYXRhOiBhbnksIGlzVmVyaWZ5U2lnbmF0dXJlOiBib29sZWFuKTogYW55IHtcbiAgICBpZiAoIWhlYWRlckRhdGEpIHtcbiAgICAgIGhlYWRlckRhdGEgPSB7fTtcbiAgICB9XG4gICAgaWYgKCFoZWFkZXJEYXRhLmhlYWRlcnMpIHtcbiAgICAgIGhlYWRlckRhdGEuaGVhZGVycyA9IHt9O1xuICAgIH1cblxuICAgIC8vIEdlbmVyYXRlIGEgdW5pcXVlIGlkZW50aWZpZXIgaWYgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBpcyByZXF1aXJlZFxuICAgIGlmIChpc1ZlcmlmeVNpZ25hdHVyZSkge1xuICAgICAgaGVhZGVyRGF0YS5oZWFkZXJzLnhyaWQgPSB1dWlkdjQoKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZXNzaW9uSWQgPSByZXNvbHZlRm9ybXNTdG9yYWdlU3RyaW5nKFxuICAgICAgXCJzZXNzaW9uX2lkXCIsXG4gICAgICB0aGlzLnJlZHV4RGF0YSxcbiAgICAgIHRoaXMuZ2V0U3RvcmFnZUNvbmZpZygpXG4gICAgKTtcbiAgICBpZiAoc2Vzc2lvbklkKSB7XG4gICAgICBoZWFkZXJEYXRhLmhlYWRlcnMuc2VzID0gc2Vzc2lvbklkO1xuICAgIH1cblxuICAgIHJldHVybiBoZWFkZXJEYXRhO1xuICB9XG5cbiAgLy8gRnVuY3Rpb24gdG8gdmVyaWZ5IHRoZSBzaWduYXR1cmVcbiAgQGxvZ01ldGhvZFxuICB2ZXJpZnlTaWduYXR1cmUoZGF0YSwgaGVhZGVyLCB1cmwsIGlzVmVyaWZ5U2lnbmF0dXJlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIENoZWNrIGlmIHRoZSBzaWduYXR1cmUgaXMgZGlzYWJsZWRcbiAgICAgIGlmICghaXNWZXJpZnlTaWduYXR1cmUpIHtcbiAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgIH0gZWxzZSBpZiAoIWRhdGEpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgZGF0YSBpcyBpbnZhbGlkXG4gICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGlzVmVyaWZ5U2lnbmF0dXJlICYmIGhlYWRlciAmJiAhaGVhZGVyPy5zaWcpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHNpZ25hdHVyZSBpcyBtaXNzaW5nIGluIGhlYWRlcnMgd2hlbiBhdXRoZW50aWNhdGlvbiBpcyBub3Qgc2tpcHBlZFxuICAgICAgICByZWplY3QoZmFsc2UpO1xuICAgICAgfSBlbHNlIGlmIChpc1ZlcmlmeVNpZ25hdHVyZSAmJiBoZWFkZXIgJiYgaGVhZGVyPy5zaWcpIHtcbiAgICAgICAgLy8gVmVyaWZ5IHRoZSBzaWduYXR1cmUgd2hlbiBwdWJsaWMga2V5IGFuZCBoZWFkZXIgd2l0aCBzaWduYXR1cmUgYXJlIHByZXNlbnQgYW5kIGF1dGhlbnRpY2F0aW9uIGlzIG5vdCBza2lwcGVkXG5cbiAgICAgICAgLy8gRXh0cmFjdCB0aGUgc2lnbmF0dXJlIGFuZCBkZWNvZGUgaXRcbiAgICAgICAgbGV0IHNpZ25hdHVyZSA9IGhlYWRlci5zaWcuc3BsaXQoXCIuXCIpWzBdO1xuICAgICAgICBjb25zdCByYXdTaWduYXR1cmUgPSBhdG9iKHNpZ25hdHVyZSk7XG5cbiAgICAgICAgLy8gU3BsaXQgdGhlIGRlY29kZWQgc2lnbmF0dXJlIHRvIGdldCB0aGUgcGFydHNcbiAgICAgICAgc2lnbmF0dXJlID0gcmF3U2lnbmF0dXJlLnNwbGl0KFwiLlwiKVswXTtcbiAgICAgICAgY29uc3QgZXhwID0gYCR7cmF3U2lnbmF0dXJlLnNwbGl0KFwiLlwiKVsxXX0wMDBgOyAvLyBFeHBpcmF0aW9uIHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gICAgICAgIGNvbnN0IGlhdCA9IGAke3Jhd1NpZ25hdHVyZS5zcGxpdChcIi5cIilbMl19MDAwYDsgLy8gSXNzdWVkIGF0IHRpbWUgaW4gbWlsbGlzZWNvbmRzXG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHNpZ25hdHVyZSBpcyB2YWxpZFxuICAgICAgICBpZiAoc2lnbmF0dXJlKSB7XG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGN1cnJlbnQgdGltZSBpcyBiZWZvcmUgdGhlIGV4cGlyYXRpb24gdGltZVxuICAgICAgICAgIGNvbnN0IGRhdGVWYWx1ZSA9IG5ldyBEYXRlKCkudmFsdWVPZigpO1xuICAgICAgICAgIGNvbnN0IGRhdGVDaGVjayA9IGRhdGVWYWx1ZSA8IHBhcnNlSW50KGV4cCwgMTApO1xuXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHNpZ25hdHVyZSBtYXRjaGVzIHRoZSBkYXRhXG4gICAgICAgICAgY29uc3QgcmVzID0gc2lnbmF0dXJlID09PSBkYXRhO1xuXG4gICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgcHJvbWlzZSBpZiB0aGUgc2lnbmF0dXJlIGlzIHZhbGlkIGFuZCB0aGUgZGF0ZSBjaGVjayBwYXNzZXNcbiAgICAgICAgICBpZiAocmVzICYmIGRhdGVDaGVjaykge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZWplY3QgdGhlIHByb21pc2UgaWYgdGhlIHNpZ25hdHVyZSBpcyBpbnZhbGlkIG9yIHRoZSBkYXRlIGNoZWNrIGZhaWxzXG4gICAgICAgICAgICByZWplY3QocmVzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmVqZWN0IHRoZSBwcm9taXNlIGlmIHRoZSBzaWduYXR1cmUgaXMgbm90IGluIHRoZSByZXF1aXJlZCBmb3JtYXRcblxuICAgICAgICAgIHJlamVjdChmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFJlc29sdmUgdGhlIHByb21pc2UgaWYgdGhlIHNpZ25hdHVyZSBpcyBtaXNzaW5nIGluIGhlYWRlcnNcbiAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIEZ1bmN0aW9uIHRvIHBlcmZvcm0gUE9TVCByZXF1ZXN0XG4gIEBsb2dNZXRob2RcbiAgcG9zdChcbiAgICB1cmwsXG4gICAgYm9keSxcbiAgICBoZWFkZXJEYXRhLFxuICAgIGlzRW5jcnlwdCA9IGZhbHNlLFxuICAgIGlzRGVjcnlwdCA9IGZhbHNlLFxuICAgIGlzVmVyaWZ5U2lnbmF0dXJlID0gZmFsc2UsXG4gICAgaXNTa2lwSGVhZGVyQWx0ZXJhdGlvbiA9IGZhbHNlXG4gICkge1xuICAgIGxldCBwcmVQcm9jZXNzZWRIZWFkZXIgPSBoZWFkZXJEYXRhO1xuXG4gICAgLy8gUHJlcHJvY2VzcyBoZWFkZXIgZGF0YSB1bmxlc3MgaW5zdHJ1Y3RlZCB0byBza2lwXG4gICAgaWYgKCFpc1NraXBIZWFkZXJBbHRlcmF0aW9uKSB7XG4gICAgICBwcmVQcm9jZXNzZWRIZWFkZXIgPSB0aGlzLnByZVByb2Nlc3NIZWFkZXIoaGVhZGVyRGF0YSwgaXNWZXJpZnlTaWduYXR1cmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcmVQcm9jZXNzZWRIZWFkZXIub2JzZXJ2ZSA9IFwicmVzcG9uc2VcIjtcbiAgICB9XG5cbiAgICAvLyBFbmNyeXB0IGJvZHkgaWYgcmVxdWlyZWRcbiAgICBpZiAoaXNFbmNyeXB0KSB7XG4gICAgICBib2R5ID0gZW5jcnlwdFdpdGhBRVMoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgoc3Vic2NyaWJlcikgPT4ge1xuICAgICAgYXhpb3MucG9zdCh1cmwsIGJvZHksIGhlYWRlckRhdGEpLnRoZW4oXG4gICAgICAgIGFzeW5jIChyZXMpID0+IHtcbiAgICAgICAgICBsZXQgeyBkYXRhIH0gPSByZXM7XG5cbiAgICAgICAgICAvLyBEZWNyeXB0IHJlc3BvbnNlIGlmIHJlcXVpcmVkXG4gICAgICAgICAgaWYgKGRhdGEgJiYgaXNEZWNyeXB0KSB7XG4gICAgICAgICAgICBjb25zdCBlbmNyeXB0ZWRSZXNwb25zZSA9IGRhdGE7XG4gICAgICAgICAgICBjb25zdCBkZWNyeXB0ZWRSZXNwb25zZSA9IGF3YWl0IGRlY3J5cHRXaXRoQUVTKGVuY3J5cHRlZFJlc3BvbnNlKTtcbiAgICAgICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKGRlY3J5cHRlZFJlc3BvbnNlKTtcbiAgICAgICAgICAgIHJlcy5kYXRhID0gZGF0YTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBWZXJpZnkgc2lnbmF0dXJlIGFuZCBoYW5kbGUgcmVzcG9uc2VcbiAgICAgICAgICB0aGlzLnZlcmlmeVNpZ25hdHVyZShcbiAgICAgICAgICAgIHRoaXMuZGF0YURlcml2YXRpdmVMb2dpYyhkYXRhKSxcbiAgICAgICAgICAgIHJlcz8uaGVhZGVycyxcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIGlzVmVyaWZ5U2lnbmF0dXJlXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKHZlcmlmaWNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQocmVzKTtcbiAgICAgICAgICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHN1YnNjcmliZXIuZXJyb3IoZXJyPy5yZXNwb25zZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgKGVycikgPT4ge1xuICAgICAgICAgIGxldCBkYXRhID0gZXJyPy5yZXNwb25zZT8uZGF0YTtcblxuICAgICAgICAgIC8vIERlY3J5cHQgZXJyb3IgcmVzcG9uc2UgaWYgcmVxdWlyZWRcbiAgICAgICAgICBpZiAoZGF0YSAmJiBpc0RlY3J5cHQpIHtcbiAgICAgICAgICAgIGNvbnN0IGVuY3J5cHRlZFJlc3BvbnNlID0gZGF0YTtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZFJlc3BvbnNlID0gYXdhaXQgZGVjcnlwdFdpdGhBRVMoZW5jcnlwdGVkUmVzcG9uc2UpO1xuICAgICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZGVjcnlwdGVkUmVzcG9uc2UpO1xuICAgICAgICAgICAgZXJyLnJlc3BvbnNlLmRhdGEgPSBkYXRhO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFZlcmlmeSBzaWduYXR1cmUgYW5kIGhhbmRsZSByZXNwb25zZVxuICAgICAgICAgIHRoaXMudmVyaWZ5U2lnbmF0dXJlKFxuICAgICAgICAgICAgdGhpcy5kYXRhRGVyaXZhdGl2ZUxvZ2ljKGRhdGEpLFxuICAgICAgICAgICAgZXJyPy5yZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIGlzVmVyaWZ5U2lnbmF0dXJlXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKHZlcmlmaWNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICBzdWJzY3JpYmVyLmVycm9yKGVycj8ucmVzcG9uc2UpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHN1YnNjcmliZXIuZXJyb3IoZXJyPy5yZXNwb25zZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEZ1bmN0aW9uIHRvIHBlcmZvcm0gR0VUIHJlcXVlc3RcbiAgQGxvZ01ldGhvZFxuICBnZXQoXG4gICAgdXJsLFxuICAgIGhlYWRlckRhdGEgPSB1bmRlZmluZWQsXG4gICAgaXNEZWNyeXB0ID0gZmFsc2UsXG4gICAgaXNWZXJpZnlTaWduYXR1cmUgPSBmYWxzZSxcbiAgICBpc1NraXBIZWFkZXJBbHRlcmF0aW9uID0gZmFsc2VcbiAgKSB7XG4gICAgbGV0IHByZVByb2Nlc3NlZEhlYWRlciA9IGhlYWRlckRhdGE7XG5cbiAgICAvLyBQcmVwcm9jZXNzIGhlYWRlciBkYXRhIHVubGVzcyBpbnN0cnVjdGVkIHRvIHNraXBcbiAgICBpZiAoIWlzU2tpcEhlYWRlckFsdGVyYXRpb24pIHtcbiAgICAgIHByZVByb2Nlc3NlZEhlYWRlciA9IHRoaXMucHJlUHJvY2Vzc0hlYWRlcihoZWFkZXJEYXRhLCBpc1ZlcmlmeVNpZ25hdHVyZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByZVByb2Nlc3NlZEhlYWRlci5vYnNlcnZlID0gXCJyZXNwb25zZVwiO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgoc3Vic2NyaWJlcikgPT4ge1xuICAgICAgYXhpb3MuZ2V0KHVybCwgcHJlUHJvY2Vzc2VkSGVhZGVyKS50aGVuKFxuICAgICAgICBhc3luYyAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICBsZXQgeyBkYXRhIH0gPSByZXM7XG5cbiAgICAgICAgICAvLyBEZWNyeXB0IHJlc3BvbnNlIGlmIHJlcXVpcmVkXG4gICAgICAgICAgaWYgKGlzRGVjcnlwdCkge1xuICAgICAgICAgICAgY29uc3QgZW5jcnlwdGVkUmVzcG9uc2UgPSBkYXRhO1xuICAgICAgICAgICAgY29uc3QgZGVjcnlwdGVkUmVzcG9uc2UgPSBhd2FpdCBkZWNyeXB0V2l0aEFFUyhlbmNyeXB0ZWRSZXNwb25zZSk7XG4gICAgICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShkZWNyeXB0ZWRSZXNwb25zZSk7XG4gICAgICAgICAgICByZXMuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gVmVyaWZ5IHNpZ25hdHVyZSBhbmQgaGFuZGxlIHJlc3BvbnNlXG4gICAgICAgICAgdGhpcy52ZXJpZnlTaWduYXR1cmUoXG4gICAgICAgICAgICB0aGlzLmRhdGFEZXJpdmF0aXZlTG9naWMoZGF0YSksXG4gICAgICAgICAgICByZXM/LmhlYWRlcnMsXG4gICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICBpc1ZlcmlmeVNpZ25hdHVyZVxuICAgICAgICAgIClcbiAgICAgICAgICAgIC50aGVuKCh2ZXJpZmljYXRpb246IGFueSkgPT4ge1xuICAgICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQocmVzKTtcbiAgICAgICAgICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHN1YnNjcmliZXIuZXJyb3IoZXJyPy5yZXNwb25zZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgKGVycikgPT4ge1xuICAgICAgICAgIGxldCBkYXRhID0gZXJyPy5yZXNwb25zZT8uZGF0YTtcblxuICAgICAgICAgIC8vIERlY3J5cHQgZXJyb3IgcmVzcG9uc2UgaWYgcmVxdWlyZWRcbiAgICAgICAgICBpZiAoZGF0YSAmJiBpc0RlY3J5cHQpIHtcbiAgICAgICAgICAgIGNvbnN0IGVuY3J5cHRlZFJlc3BvbnNlID0gZGF0YTtcbiAgICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZFJlc3BvbnNlID0gYXdhaXQgZGVjcnlwdFdpdGhBRVMoZW5jcnlwdGVkUmVzcG9uc2UpO1xuICAgICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZGVjcnlwdGVkUmVzcG9uc2UpO1xuICAgICAgICAgICAgZXJyLnJlc3BvbnNlLmRhdGEgPSBkYXRhO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFZlcmlmeSBzaWduYXR1cmUgYW5kIGhhbmRsZSByZXNwb25zZVxuICAgICAgICAgIHRoaXMudmVyaWZ5U2lnbmF0dXJlKFxuICAgICAgICAgICAgdGhpcy5kYXRhRGVyaXZhdGl2ZUxvZ2ljKGRhdGEpLFxuICAgICAgICAgICAgZXJyPy5yZXNwb25zZT8uaGVhZGVycyxcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIGlzVmVyaWZ5U2lnbmF0dXJlXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKHZlcmlmaWNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICBzdWJzY3JpYmVyLmVycm9yKGVycj8ucmVzcG9uc2UpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHN1YnNjcmliZXIuZXJyb3IoZXJyPy5yZXNwb25zZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEZ1bmN0aW9uIHRvIGV4ZWN1dGUgQVBJIGNhbGwgYmFzZWQgb24gbWV0aG9kIHR5cGVcbiAgZXhlY3V0ZUFwaUNhbGwoXG4gICAgdXJsLFxuICAgIG1ldGhvZCxcbiAgICBib2R5LFxuICAgIGhlYWRlcnMsXG4gICAgaXNFbmNyeXB0LFxuICAgIGlzRGVjcnlwdCxcbiAgICBpc1ZlcmlmeVNpZ25hdHVyZVxuICApIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIGlmIChtZXRob2QgPT09IFwiR0VUXCIpIHtcbiAgICAgICAgdGhpcy5nZXQodXJsLCB7IGhlYWRlcnMgfSwgaXNEZWNyeXB0LCBpc1ZlcmlmeVNpZ25hdHVyZSkuc3Vic2NyaWJlKFxuICAgICAgICAgIChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucG9zdChcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgYm9keSxcbiAgICAgICAgICB7IGhlYWRlcnMgfSxcbiAgICAgICAgICBpc0VuY3J5cHQsXG4gICAgICAgICAgaXNEZWNyeXB0LFxuICAgICAgICAgIGlzVmVyaWZ5U2lnbmF0dXJlXG4gICAgICAgICkuc3Vic2NyaWJlKFxuICAgICAgICAgIChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIl19