ngx-appkey-webauthn
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.2.0.
741 lines • 78.4 kB
JavaScript
import { Injectable } from '@angular/core';
import localeData from './locales.json';
import { User } from './models/user';
import * as i0 from "@angular/core";
export class NgxAppkeyWebauthnService {
localeList = localeData.list;
appLocales = [];
user = new User();
apiConfig = {};
constructor() {
}
async configure(config) {
if (!config || !config.appToken) {
throw ("invalid api config for app token");
}
this.apiConfig = config;
}
async getApp() {
return await this.apiRequest("GET", "appuser/app");
}
/**
*
* @param {
* handle :string,
* displayName :string,
* locale? :string
* }
* @returns
*/
async loginAnonymous(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.handle && data.handle.startsWith("ANON_");
if (!valid) {
let error = {
message: "Invalid login anonymous data"
};
reject(error);
return;
}
this.apiRequest('POST', 'appuser/loginAnonymous', data).then(result => {
if (result.code)
reject(result);
else {
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
* https://w3c.github.io/webauthn/#dictdef-registrationresponsejson
* @param
* handle: string,
* {
*
* id: Base64URLString;
* rawId: Base64URLString;
* response: {
* clientDataJSON: Base64URLString;
* attestationObject: Base64URLString;
* authenticatorData?: Base64URLString;
* };
* authenticatorAttachment?: string;
* type: string;
* } attestation
* @returns
*/
loginAnonymousComplete(handle, attestation) {
return new Promise((resolve, reject) => {
try {
let valid = handle &&
attestation.id &&
attestation.rawId &&
attestation.response &&
attestation.response.clientDataJSON &&
attestation.response.attestationObject &&
attestation.type;
if (!valid) {
reject({ message: "Invalid data" });
return;
}
this.apiRequest('POST', 'appuser/loginAnonymousComplete', attestation).then(result => {
if (result.code)
reject(result);
else {
this.user = result;
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {
* handle :string,
* displayName :string,
* locale? :string
* }
* @returns
*/
async signup(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.handle && data.displayName;
if (!valid) {
let error = {
message: "invalid signup data"
};
reject(error);
}
data.handle = data.handle.toLowerCase();
this.apiRequest('POST', 'appuser/signup', data).then(result => {
if (result.code)
reject(result);
else {
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
* https://w3c.github.io/webauthn/#dictdef-registrationresponsejson
* @param
* handle: string,
* {
*
* id: Base64URLString;
* rawId: Base64URLString;
* response: {
* clientDataJSON: Base64URLString;
* attestationObject: Base64URLString;
* authenticatorData?: Base64URLString;
* };
* authenticatorAttachment?: string;
* type: string;
* } attestation
* @returns
*/
signupConfirm(handle, attestation) {
return new Promise((resolve, reject) => {
try {
let valid = handle &&
attestation.id &&
attestation.rawId &&
attestation.response &&
attestation.response.clientDataJSON &&
attestation.response.attestationObject &&
attestation.type;
if (!valid) {
reject({ message: "invalid attestation" });
return;
}
attestation.handle = handle.toLowerCase();
this.apiRequest('POST', 'appuser/signupConfirm', attestation).then(result => {
if (result.code)
reject(result);
else {
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param { handle:string, code:string} data
* @returns
*/
signupComplete(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.code;
if (!valid) {
reject({ message: "invalid singup data" });
return;
}
this.apiRequest('POST', 'appuser/signupComplete', data).then(result => {
if (result.code)
reject(result);
else {
this.user = result;
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {handle:string} data
*
* @returns
*/
login(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.handle;
if (!valid) {
reject({ message: "invalid login data" });
return;
}
this.logout();
data.handle = data.handle.toLowerCase();
this.apiRequest('POST', 'appuser/login', data).then(result => {
if (result.code)
reject(result);
else {
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
* https://w3c.github.io/webauthn/#dictdef-authenticationresponsejson
* @param
* handle:string,
* {
* id: Base64URLString;
* rawId: Base64URLString;
* response: {
* clientDataJSON:Base64URLString,
* authenticatorData:Base64URLString,
* signature:Base64URLString,
* userHandle?: Base64URLString
* };
* authenticatorAttachment?: string;
* type: string;
* } assertion
*
* @returns
*/
loginComplete(handle, assertion) {
return new Promise((resolve, reject) => {
try {
let valid = handle &&
assertion.id &&
assertion.rawId &&
assertion.response.clientDataJSON &&
assertion.response.authenticatorData &&
assertion.response.signature &&
assertion.type;
if (!valid) {
reject({ message: "invalid assertion" });
return;
}
assertion.handle = handle.toLowerCase();
this.apiRequest('POST', 'appuser/loginComplete', assertion).then(result => {
if (result && result['access-token']) {
this.user = result;
resolve(result);
}
else
reject(result);
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {token:string, provider:string} data
*
* @returns
*/
socialLogin(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.token && data.provider;
if (!valid) {
reject({ message: "invalid data" });
return;
}
let that = this;
this.apiRequest('POST', 'appuser/socialLogin', data).then(result => {
if (result && result['access-token']) {
that.user = result;
resolve(result);
}
else
reject(result);
});
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {token:string, provider:string, handle:string} data
*
* @returns
*/
socialSignup(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.token && data.provider && data.handle;
if (!valid) {
reject({ message: "invalid data" });
return;
}
this.logout();
let that = this;
this.apiRequest('POST', 'appuser/socialSignup', data).then(result => {
if (result && result['access-token']) {
that.user = result;
resolve(result);
}
else
reject(result);
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {handle:string} data
*
* @returns
*/
verify(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.handle;
if (!valid) {
reject({ message: "invalid data" });
return;
}
data.handle = data.handle.toLowerCase();
this.apiRequest('POST', 'appuser/verify', data).then(result => {
if (result.code)
reject(result);
else {
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
* https://w3c.github.io/webauthn/#dictdef-authenticationresponsejson
* @param
* handle:string,
* {
* id: Base64URLString;
* rawId: Base64URLString;
* response: {
* clientDataJSON:Base64URLString,
* authenticatorData:Base64URLString,
* signature:Base64URLString,
* userHandle?: Base64URLString
* };
* authenticatorAttachment?: string;
* type: string
* } assertion
*
* @returns
*/
verifyComplete(handle, assertion) {
return new Promise((resolve, reject) => {
try {
let valid = handle &&
assertion.id &&
assertion.rawId &&
assertion.response.clientDataJSON &&
assertion.response.authenticatorData &&
assertion.response.signature &&
assertion.type;
if (!valid) {
reject({ message: "invalid assertion" });
return;
}
assertion.handle = handle.toLowerCase();
let that = this;
this.apiRequest('POST', 'appuser/verifyComplete', assertion).then(result => {
if (result && result['access-token']) {
that.user = result;
resolve(result);
}
else
reject(result);
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {token:string, provider:string} data
* @returns
*/
verifySocialAccount(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.token && data.provider;
if (!valid) {
reject({ message: "invalid data" });
return;
}
let that = this;
this.apiRequest('POST', 'appuser/verifySocialAccount', data).then(result => {
if (result && result['access-token']) {
that.user = result;
resolve(result);
}
else
reject(result);
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
logout() {
this.user = new User();
}
/**
*
* @returns application user
*/
getAppUser() {
return new Promise((resolve, reject) => {
try {
this.apiRequest('GET', 'appuser/user').then(result => {
if (result.code)
reject(result);
else {
this.user = result;
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {locale:string} data
* @returns
*/
setLocale(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.locale;
if (!valid) {
reject({ message: "invalid data" });
return;
}
this.apiRequest('POST', 'appuser/setLocale', data).then(result => {
if (result == true)
resolve(result);
else
reject(result);
}).catch((error) => reject(error));
}
catch (error) {
resolve(error);
}
});
}
/**
*
* @param {displayName:string} data
* @returns
*/
updateProfile(data) {
return new Promise((resolve, reject) => {
try {
let valid = data.displayName;
if (!valid) {
reject({ message: "invalid data" });
return;
}
this.apiRequest('POST', 'appuser/updateProfile', data).then(result => {
if (result.code)
resolve(result);
else
reject(result);
}).catch((error) => reject(error));
}
catch (error) {
}
});
}
/**
*
* @param {userName:string} data
* @returns
*/
setUserName(data) {
return new Promise((resolve, reject) => {
try {
if (!data.userName) {
reject({ message: "invalid data" });
return;
}
data.userName = data.userName.toLowerCase();
this.apiRequest('POST', 'appuser/setUserName', data).then(result => {
if (result.code)
reject(result);
else
resolve(result);
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {userName:string} data
* @returns
*/
userNameAvailable(data) {
return new Promise((resolve, reject) => {
try {
if (!data.userName) {
reject({ message: "invalid data" });
return;
}
data.userName = data.userName.toLowerCase();
this.apiRequest('GET', `appuser/userNameAvailable?userName=${data.userName}`).then(result => {
if (result.code)
reject(result);
else
resolve(result);
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
*
* @returns
*/
deleteAccount() {
return new Promise((resolve, reject) => {
try {
this.apiRequest('POST', 'appuser/deleteAccount', {}).then(result => {
if (result.code)
reject(result);
else
resolve(result);
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
*
* @returns challenge
*/
addPasskey(data = {}) {
return new Promise((resolve, reject) => {
try {
this.apiRequest('POST', 'appuser/addPasskey', data).then(result => {
if (result.code)
reject(result);
else
resolve(result);
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
* https://w3c.github.io/webauthn/#dictdef-registrationresponsejson
* @param
* {
*
* id: Base64URLString;
* rawId: Base64URLString;
* response: {
* clientDataJSON: Base64URLString;
* attestationObject: Base64URLString;
* authenticatorData?: Base64URLString;
* };
* authenticatorAttachment?: string;
* type: string;
* } attestation
* @returns
*/
addPasskeyComplete(attestation) {
return new Promise((resolve, reject) => {
try {
let valid = attestation.id &&
attestation.rawId &&
attestation.response &&
attestation.response.clientDataJSON &&
attestation.response.attestationObject &&
attestation.type;
if (!valid) {
reject({ message: "invalid attestation" });
return;
}
this.apiRequest('POST', 'appuser/addPasskeyComplete', attestation).then(result => {
if (result.code)
reject(result);
else {
this.user = result;
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {keyId:string, keyName:string} data
* @returns user
*/
updatePasskey(data) {
return new Promise((resolve, reject) => {
try {
this.apiRequest('POST', 'appuser/updatePasskey', data).then(result => {
if (result.code)
reject(result);
else {
this.user = result;
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
/**
*
* @param {keyId:string} data
* @returns user
*/
removePasskey(data) {
return new Promise((resolve, reject) => {
try {
this.apiRequest('POST', 'appuser/removePasskey', data).then(result => {
if (result.code)
reject(result);
else {
this.user = result;
resolve(result);
}
}).catch((error) => reject(error));
}
catch (error) {
reject(error);
}
});
}
async apiRequest(method, endpoint, data) {
try {
if (!this.apiConfig.appToken) {
console.log("apiRequest this.apiConfig ", this.apiConfig);
throw ("invalid api config for app token");
}
let options = {
method: method ? method : 'POST',
headers: {
'Content-Type': 'application/json',
}
};
if (this.user && this.user['access-token'] != "")
options.headers['access-token'] = this.user['access-token'];
else if (data && data['access-token'])
options.headers['access-token'] = data['access-token'];
else if (data && data.signupToken)
options.headers['signup-token'] = data.signupToken;
else
options.headers['app-token'] = this.apiConfig.appToken;
if (data && method == "POST" || method == "PUT")
options.body = JSON.stringify(data);
const response = await fetch(`${this.apiConfig.apiUrl}/api/${endpoint}`, options);
let result = await response.json();
console.log(`apiRequest path: ${endpoint} - result: `, result);
// if (response.status !== 200) return { error: result }
// else return result
return result;
}
catch (error) {
console.log(`apiRequest error:`, error);
return error;
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxAppkeyWebauthnService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxAppkeyWebauthnService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgxAppkeyWebauthnService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWFwcGtleS13ZWJhdXRobi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWFwcGtleS13ZWJhdXRobi9zcmMvbGliL25neC1hcHBrZXktd2ViYXV0aG4uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sVUFBVSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBTXJDLE1BQU0sT0FBTyx3QkFBd0I7SUFHMUIsVUFBVSxHQUFlLFVBQVUsQ0FBQyxJQUFJLENBQUM7SUFDekMsVUFBVSxHQUFlLEVBQUUsQ0FBQztJQUM1QixJQUFJLEdBQVMsSUFBSSxJQUFJLEVBQUUsQ0FBQTtJQUN0QixTQUFTLEdBQVEsRUFBRSxDQUFBO0lBRTNCO0lBRUEsQ0FBQztJQUVELEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBVztRQUN2QixJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzlCLE1BQU0sQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFBO1FBQzlDLENBQUM7UUFDRCxJQUFJLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQTtJQUMzQixDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU07UUFDUixPQUFPLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsYUFBYSxDQUFDLENBQUE7SUFDdEQsQ0FBQztJQUlEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFTO1FBQzFCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDbkMsSUFBSSxDQUFDO2dCQUNELElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFD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QUFDLElBQUksQ0FBQyxDQUFDO1lBRXJGLE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLFFBQVEsUUFBUSxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDbEYsSUFBSSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7WUFFbkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsUUFBUSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUE7WUFFOUQsd0RBQXdEO1lBQ3hELHFCQUFxQjtZQUVyQixPQUFPLE1BQU0sQ0FBQztRQUVsQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUViLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLENBQUE7WUFDdkMsT0FBTyxLQUFLLENBQUM7UUFDakIsQ0FBQztJQUNMLENBQUM7d0dBcHlCUSx3QkFBd0I7NEdBQXhCLHdCQUF3QixjQUZyQixNQUFNOzs0RkFFVCx3QkFBd0I7a0JBSHBDLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IGxvY2FsZURhdGEgZnJvbSAnLi9sb2NhbGVzLmpzb24nO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4vbW9kZWxzL3VzZXInO1xuaW1wb3J0IHsgQXBwbGljYXRpb24gfSBmcm9tICcuL21vZGVscy9hcHBsaWNhdGlvbic7XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgTmd4QXBwa2V5V2ViYXV0aG5TZXJ2aWNlIHtcblxuXG4gICAgcHVibGljIGxvY2FsZUxpc3Q6IEFycmF5PGFueT4gPSBsb2NhbGVEYXRhLmxpc3Q7XG4gICAgcHVibGljIGFwcExvY2FsZXM6IEFycmF5PGFueT4gPSBbXTtcbiAgICBwdWJsaWMgdXNlcjogVXNlciA9IG5ldyBVc2VyKCkgXG4gICAgcHJpdmF0ZSBhcGlDb25maWc6IGFueSA9IHt9XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIH1cblxuICAgIGFzeW5jIGNvbmZpZ3VyZShjb25maWc6IGFueSkge1xuICAgICAgICBpZiAoIWNvbmZpZyB8fCAhY29uZmlnLmFwcFRva2VuKSB7XG4gICAgICAgICAgICB0aHJvdyAoXCJpbnZhbGlkIGFwaSBjb25maWcgZm9yIGFwcCB0b2tlblwiKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuYXBpQ29uZmlnID0gY29uZmlnXG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0QXBwKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmFwaVJlcXVlc3QoXCJHRVRcIiwgXCJhcHB1c2VyL2FwcFwiKVxuICAgIH1cblxuXG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0ge1xuICAgICAqICAgaGFuZGxlIDpzdHJpbmcsXG4gICAgICogICBkaXNwbGF5TmFtZSA6c3RyaW5nLFxuICAgICAqICAgbG9jYWxlPyA6c3RyaW5nXG4gICAgICogfVxuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIGFzeW5jIGxvZ2luQW5vbnltb3VzKGRhdGE6IGFueSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXQgdmFsaWQgPSBkYXRhLmhhbmRsZSAmJiBkYXRhLmhhbmRsZS5zdGFydHNXaXRoKFwiQU5PTl9cIilcbiAgICAgICAgICAgICAgICBpZiAoIXZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBlcnJvciA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IFwiSW52YWxpZCBsb2dpbiBhbm9ueW1vdXMgZGF0YVwiXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9IFxuICAgICAgICAgICAgICBcblxuICAgICAgICAgICAgICAgIHRoaXMuYXBpUmVxdWVzdCgnUE9TVCcsICdhcHB1c2VyL2xvZ2luQW5vbnltb3VzJywgZGF0YSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNvZGUpIHJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHsgXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpOyBcblxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoIGVycm9yIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJhdXRobi8jZGljdGRlZi1yZWdpc3RyYXRpb25yZXNwb25zZWpzb25cbiAgICAgKiBAcGFyYW0gXG4gICAgICogIGhhbmRsZTogc3RyaW5nLFxuICAgICAqICB7XG4gICAgICogXG4gICAgICogIGlkOiBCYXNlNjRVUkxTdHJpbmc7XG4gICAgICogIHJhd0lkOiBCYXNlNjRVUkxTdHJpbmc7XG4gICAgICogIHJlc3BvbnNlOiB7XG4gICAgICogICAgICBjbGllbnREYXRhSlNPTjogQmFzZTY0VVJMU3RyaW5nO1xuICAgICAqICAgICAgYXR0ZXN0YXRpb25PYmplY3Q6IEJhc2U2NFVSTFN0cmluZztcbiAgICAgKiAgICAgIGF1dGhlbnRpY2F0b3JEYXRhPzogQmFzZTY0VVJMU3RyaW5nOyBcbiAgICAgKiAgICB9O1xuICAgICAqICBhdXRoZW50aWNhdG9yQXR0YWNobWVudD86IHN0cmluZzsgXG4gICAgICogIHR5cGU6IHN0cmluZztcbiAgICAgKiB9IGF0dGVzdGF0aW9uIFxuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIGxvZ2luQW5vbnltb3VzQ29tcGxldGUoaGFuZGxlOiBzdHJpbmcsIGF0dGVzdGF0aW9uOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgdmFsaWQgPSBoYW5kbGUgJiZcbiAgICAgICAgICAgICAgICAgICAgYXR0ZXN0YXRpb24uaWQgJiZcbiAgICAgICAgICAgICAgICAgICAgYXR0ZXN0YXRpb24ucmF3SWQgJiZcbiAgICAgICAgICAgICAgICAgICAgYXR0ZXN0YXRpb24ucmVzcG9uc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgYXR0ZXN0YXRpb24ucmVzcG9uc2UuY2xpZW50RGF0YUpTT04gJiZcbiAgICAgICAgICAgICAgICAgICAgYXR0ZXN0YXRpb24ucmVzcG9uc2UuYXR0ZXN0YXRpb25PYmplY3QgJiZcbiAgICAgICAgICAgICAgICAgICAgYXR0ZXN0YXRpb24udHlwZTtcblxuICAgICAgICAgICAgICAgIGlmICghdmFsaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KHsgbWVzc2FnZTogXCJJbnZhbGlkIGRhdGFcIiB9KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9IFxuXG4gICAgICAgICAgICAgICAgdGhpcy5hcGlSZXF1ZXN0KCdQT1NUJywgJ2FwcHVzZXIvbG9naW5Bbm9ueW1vdXNDb21wbGV0ZScsIGF0dGVzdGF0aW9uKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuY29kZSkgcmVqZWN0KHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51c2VyID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuXG5cblxuXG4gICAgLyoqXG4gICAgICogXG4gICAgICogQHBhcmFtIHtcbiAgICAgICogICBoYW5kbGUgOnN0cmluZyxcbiAgICAgICogICBkaXNwbGF5TmFtZSA6c3RyaW5nLFxuICAgICAgKiAgIGxvY2FsZT8gOnN0cmluZ1xuICAgICAgKiB9XG4gICAgICAqIEByZXR1cm5zIFxuICAgICAgKi9cbiAgICBhc3luYyBzaWdudXAoZGF0YTogYW55KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxldCB2YWxpZCA9IGRhdGEuaGFuZGxlICYmIGRhdGEuZGlzcGxheU5hbWVcbiAgICAgICAgICAgICAgICBpZiAoIXZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBlcnJvciA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IFwiaW52YWxpZCBzaWdudXAgZGF0YVwiXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkYXRhLmhhbmRsZSA9IGRhdGEuaGFuZGxlLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgXG5cbiAgICAgICAgICAgICAgICB0aGlzLmFwaVJlcXVlc3QoJ1BPU1QnLCAnYXBwdXNlci9zaWdudXAnLCBkYXRhKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuY29kZSkgcmVqZWN0KHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgeyBcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7IFxuXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cblxuXG4gICAgLyoqXG4gICAgICogaHR0cHM6Ly93M2MuZ2l0aHViLmlvL3dlYmF1dGhuLyNkaWN0ZGVmLXJlZ2lzdHJhdGlvbnJlc3BvbnNlanNvblxuICAgICAqIEBwYXJhbSBcbiAgICAgKiAgaGFuZGxlOiBzdHJpbmcsXG4gICAgICogIHtcbiAgICAgKiBcbiAgICAgKiAgaWQ6IEJhc2U2NFVSTFN0cmluZztcbiAgICAgKiAgcmF3SWQ6IEJhc2U2NFVSTFN0cmluZztcbiAgICAgKiAgcmVzcG9uc2U6IHtcbiAgICAgKiAgICAgIGNsaWVudERhdGFKU09OOiBCYXNlNjRVUkxTdHJpbmc7XG4gICAgICogICAgICBhdHRlc3RhdGlvbk9iamVjdDogQmFzZTY0VVJMU3RyaW5nO1xuICAgICAqICAgICAgYXV0aGVudGljYXRvckRhdGE/OiBCYXNlNjRVUkxTdHJpbmc7IFxuICAgICAqICAgIH07XG4gICAgICogIGF1dGhlbnRpY2F0b3JBdHRhY2htZW50Pzogc3RyaW5nOyBcbiAgICAgKiAgdHlwZTogc3RyaW5nO1xuICAgICAqIH0gYXR0ZXN0YXRpb24gXG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgc2lnbnVwQ29uZmlybShoYW5kbGU6IHN0cmluZywgYXR0ZXN0YXRpb246IGFueSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcblxuICAgICAgICAgICAgICAgIGxldCB2YWxpZCA9IGhhbmRsZSAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5pZCAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5yYXdJZCAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5yZXNwb25zZSAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5yZXNwb25zZS5jbGllbnREYXRhSlNPTiAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5yZXNwb25zZS5hdHRlc3RhdGlvbk9iamVjdCAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi50eXBlO1xuXG4gICAgICAgICAgICAgICAgaWYgKCF2YWxpZCkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoeyBtZXNzYWdlOiBcImludmFsaWQgYXR0ZXN0YXRpb25cIiB9KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5oYW5kbGUgPSBoYW5kbGUudG9Mb3dlckNhc2UoKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuYXBpUmVxdWVzdCgnUE9TVCcsICdhcHB1c2VyL3NpZ251cENvbmZpcm0nLCBhdHRlc3RhdGlvbikudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNvZGUpIHJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHsgXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuXG5cblxuXG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0geyBoYW5kbGU6c3RyaW5nLCBjb2RlOnN0cmluZ30gZGF0YSBcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzaWdudXBDb21wbGV0ZShkYXRhOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgdmFsaWQgPSBkYXRhLmNvZGU7XG4gICAgICAgICAgICAgICAgaWYgKCF2YWxpZCkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoeyBtZXNzYWdlOiBcImludmFsaWQgc2luZ3VwIGRhdGFcIiB9KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmFwaVJlcXVlc3QoJ1BPU1QnLCAnYXBwdXNlci9zaWdudXBDb21wbGV0ZScsIGRhdGEpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5jb2RlKSByZWplY3QocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVzZXIgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cblxuXG4gICAgLyoqXG4gICAgICogXG4gICAgICogQHBhcmFtIHtoYW5kbGU6c3RyaW5nfSBkYXRhIFxuICAgICAqIFxuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIGxvZ2luKGRhdGE6IGFueSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXQgdmFsaWQgPSBkYXRhLmhhbmRsZTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdCh7IG1lc3NhZ2U6IFwiaW52YWxpZCBsb2dpbiBkYXRhXCIgfSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dvdXQoKVxuXG4gICAgICAgICAgICAgICAgZGF0YS5oYW5kbGUgPSBkYXRhLmhhbmRsZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuYXBpUmVxdWVzdCgnUE9TVCcsICdhcHB1c2VyL2xvZ2luJywgZGF0YSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNvZGUpIHJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cblxuXG4gICAgLyoqXG4gICAgICogaHR0cHM6Ly93M2MuZ2l0aHViLmlvL3dlYmF1dGhuLyNkaWN0ZGVmLWF1dGhlbnRpY2F0aW9ucmVzcG9uc2Vqc29uXG4gICAgICogQHBhcmFtIFxuICAgICAqIGhhbmRsZTpzdHJpbmcsXG4gICAgICogIHtcbiAgICAgKiAgICAgIGlkOiBCYXNlNjRVUkxTdHJpbmc7XG4gICAgICogICAgICByYXdJZDogQmFzZTY0VVJMU3RyaW5nO1xuICAgICAqICAgICAgcmVzcG9uc2U6IHtcbiAgICAgKiAgICAgICAgICBjbGllbnREYXRhSlNPTjpCYXNlNjRVUkxTdHJpbmcsXG4gICAgICogICAgICAgICAgYXV0aGVudGljYXRvckRhdGE6QmFzZTY0VVJMU3RyaW5nLFxuICAgICAqICAgICAgICAgIHNpZ25hdHVyZTpCYXNlNjRVUkxTdHJpbmcsXG4gICAgICogICAgICAgICAgdXNlckhhbmRsZT86IEJhc2U2NFVSTFN0cmluZ1xuICAgICAqICAgICAgICAgIH07XG4gICAgICogICAgICBhdXRoZW50aWNhdG9yQXR0YWNobWVudD86IHN0cmluZzsgXG4gICAgICogICAgICB0eXBlOiBzdHJpbmc7XG4gICAgICogIH0gYXNzZXJ0aW9uXG4gICAgICogIFxuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIGxvZ2luQ29tcGxldGUoaGFuZGxlOiBzdHJpbmcsIGFzc2VydGlvbjogYW55KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuXG4gICAgICAgICAgICAgICAgbGV0IHZhbGlkID0gaGFuZGxlICYmXG4gICAgICAgICAgICAgICAgICAgIGFzc2VydGlvbi5pZCAmJlxuICAgICAgICAgICAgICAgICAgICBhc3NlcnRpb24ucmF3SWQgJiZcbiAgICAgICAgICAgICAgICAgICAgYXNzZXJ0aW9uLnJlc3BvbnNlLmNsaWVudERhdGFKU09OICYmXG4gICAgICAgICAgICAgICAgICAgIGFzc2VydGlvbi5yZXNwb25zZS5hdXRoZW50aWNhdG9yRGF0YSAmJlxuICAgICAgICAgICAgICAgICAgICBhc3NlcnRpb24ucmVzcG9uc2Uuc2lnbmF0dXJlICYmXG4gICAgICAgICAgICAgICAgICAgIGFzc2VydGlvbi50eXBlO1xuICAgICAgICAgICAgICAgIGlmICghdmFsaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KHsgbWVzc2FnZTogXCJpbnZhbGlkIGFzc2VydGlvblwiIH0pXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGFzc2VydGlvbi5oYW5kbGUgPSBoYW5kbGUudG9Mb3dlckNhc2UoKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuYXBpUmVxdWVzdCgnUE9TVCcsICdhcHB1c2VyL2xvZ2luQ29tcGxldGUnLCBhc3NlcnRpb24pLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHRbJ2FjY2Vzcy10b2tlbiddKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVzZXIgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSByZWplY3QocmVzdWx0KTtcblxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cblxuICAgIC8qKlxuICAgICAqIFxuICAgICAqIEBwYXJhbSB7dG9rZW46c3RyaW5nLCBwcm92aWRlcjpzdHJpbmd9IGRhdGEgXG4gICAgICogXG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgc29jaWFsTG9naW4oZGF0YTogYW55KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxldCB2YWxpZCA9IGRhdGEudG9rZW4gJiYgZGF0YS5wcm92aWRlcjtcblxuICAgICAgICAgICAgICAgIGlmICghdmFsaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KHsgbWVzc2FnZTogXCJpbnZhbGlkIGRhdGFcIiB9KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICAgICAgdGhpcy5hcGlSZXF1ZXN0KCdQT1NUJywgJ2FwcHVzZXIvc29jaWFsTG9naW4nLCBkYXRhKS50aGVuKHJlc3VsdCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHRbJ2FjY2Vzcy10b2tlbiddKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQudXNlciA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHJlamVjdChyZXN1bHQpO1xuXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIFxuICAgICogQHBhcmFtIHt0b2tlbjpzdHJpbmcsIHByb3ZpZGVyOnN0cmluZywgaGFuZGxlOnN0cmluZ30gZGF0YSBcbiAgICAqIFxuICAgICogQHJldHVybnMgXG4gICAgKi9cbiAgICBzb2NpYWxTaWdudXAoZGF0YTogYW55KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxldCB2YWxpZCA9IGRhdGEudG9rZW4gJiYgZGF0YS5wcm92aWRlciAmJiBkYXRhLmhhbmRsZTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdCh7IG1lc3NhZ2U6IFwiaW52YWxpZCBkYXRhXCIgfSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMubG9nb3V0KClcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICAgICAgdGhpcy5hcGlSZXF1ZXN0KCdQT1NUJywgJ2FwcHVzZXIvc29jaWFsU2lnbnVwJywgZGF0YSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICYmIHJlc3VsdFsnYWNjZXNzLXRva2VuJ10pIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC51c2VyID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgcmVqZWN0KHJlc3VsdCk7XG5cbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogXG4gICAgICogQHBhcmFtIHtoYW5kbGU6c3RyaW5nfSBkYXRhIFxuICAgICAqIFxuICAgICAqIEByZXR1cm5zIFxuICAgICAqL1xuICAgIHZlcmlmeShkYXRhOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IHZhbGlkID0gZGF0YS5oYW5kbGU7XG4gICAgICAgICAgICAgICAgaWYgKCF2YWxpZCkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoeyBtZXNzYWdlOiBcImludmFsaWQgZGF0YVwiIH0pXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkYXRhLmhhbmRsZSA9IGRhdGEuaGFuZGxlLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hcGlSZXF1ZXN0KCdQT1NUJywgJ2FwcHVzZXIvdmVyaWZ5JywgZGF0YSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNvZGUpIHJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBodHRwczovL3czYy5naXRodWIuaW8vd2ViYXV0aG4vI2RpY3RkZWYtYXV0aGVudGljYXRpb25yZXNwb25zZWpzb25cbiAgICAqIEBwYXJhbSBcbiAgICAqIGhhbmRsZTpzdHJpbmcsXG4gICAgKiB7ICBcbiAgICogICAgICBpZDogQmFzZTY0VVJMU3RyaW5nO1xuICAgKiAgICAgIHJhd0lkOiBCYXNlNjRVUkxTdHJpbmc7XG4gICAqICAgICAgcmVzcG9uc2U6IHtcbiAgICogICAgICAgICAgY2xpZW50RGF0YUpTT046QmFzZTY0VVJMU3RyaW5nLFxuICAgKiAgICAgICAgICBhdXRoZW50aWNhdG9yRGF0YTpCYXNlNjRVUkxTdHJpbmcsXG4gICAqICAgICAgICAgIHNpZ25hdHVyZTpCYXNlNjRVUkxTdHJpbmcsXG4gICAqICAgICAgICAgIHVzZXJIYW5kbGU/OiBCYXNlNjRVUkxTdHJpbmdcbiAgICogICAgICAgICAgfTtcbiAgICogICAgICBhdXRoZW50aWNhdG9yQXR0YWNobWVudD86IHN0cmluZzsgXG4gICAqICAgICAgdHlwZTogc3RyaW5nXG4gICAgKiB9IGFzc2VydGlvblxuICAgICogIFxuICAgICogQHJldHVybnMgXG4gICAgKi9cbiAgICB2ZXJpZnlDb21wbGV0ZShoYW5kbGU6IHN0cmluZywgYXNzZXJ0aW9uOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgdmFsaWQgPSBoYW5kbGUgJiZcbiAgICAgICAgICAgICAgICAgICAgYXNzZXJ0aW9uLmlkICYmXG4gICAgICAgICAgICAgICAgICAgIGFzc2VydGlvbi5yYXdJZCAmJlxuICAgICAgICAgICAgICAgICAgICBhc3NlcnRpb24ucmVzcG9uc2UuY2xpZW50RGF0YUpTT04gJiZcbiAgICAgICAgICAgICAgICAgICAgYXNzZXJ0aW9uLnJlc3BvbnNlLmF1dGhlbnRpY2F0b3JEYXRhICYmXG4gICAgICAgICAgICAgICAgICAgIGFzc2VydGlvbi5yZXNwb25zZS5zaWduYXR1cmUgJiZcbiAgICAgICAgICAgICAgICAgICAgYXNzZXJ0aW9uLnR5cGU7XG4gICAgICAgICAgICAgICAgaWYgKCF2YWxpZCkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoeyBtZXNzYWdlOiBcImludmFsaWQgYXNzZXJ0aW9uXCIgfSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYXNzZXJ0aW9uLmhhbmRsZSA9IGhhbmRsZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIGxldCB0aGF0ID0gdGhpcztcbiAgICAgICAgICAgICAgICB0aGlzLmFwaVJlcXVlc3QoJ1BPU1QnLCAnYXBwdXNlci92ZXJpZnlDb21wbGV0ZScsIGFzc2VydGlvbikudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICYmIHJlc3VsdFsnYWNjZXNzLXRva2VuJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQudXNlciA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHJlamVjdChyZXN1bHQpO1xuXG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuXG4gICAgLyoqXG4gICAgICogXG4gICAgICogQHBhcmFtIHt0b2tlbjpzdHJpbmcsIHByb3ZpZGVyOnN0cmluZ30gZGF0YSAgXG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgdmVyaWZ5U29jaWFsQWNjb3VudChkYXRhOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgdmFsaWQgPSBkYXRhLnRva2VuICYmIGRhdGEucHJvdmlkZXI7XG4gICAgICAgICAgICAgICAgaWYgKCF2YWxpZCkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoeyBtZXNzYWdlOiBcImludmFsaWQgZGF0YVwiIH0pXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICAgICAgdGhpcy5hcGlSZXF1ZXN0KCdQT1NUJywgJ2FwcHVzZXIvdmVyaWZ5U29jaWFsQWNjb3VudCcsIGRhdGEpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHRbJ2FjY2Vzcy10b2tlbiddKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnVzZXIgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSByZWplY3QocmVzdWx0KTtcblxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICBsb2dvdXQoKSB7XG4gICAgICAgIHRoaXMudXNlciA9IG5ldyBVc2VyKClcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFxuICAgICAqIEByZXR1cm5zIGFwcGxpY2F0aW9uIHVzZXJcbiAgICAgKi9cbiAgICBnZXRBcHBVc2VyKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwaVJlcXVlc3QoJ0dFVCcsICdhcHB1c2VyL3VzZXInKS50aGVuKHJlc3VsdCA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5jb2RlKSByZWplY3QocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVzZXIgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSlcbiAgICB9XG5cblxuXG4gICAgLyoqXG4gICAgKiBcbiAgICAqIEBwYXJhbSB7bG9jYWxlOnN0cmluZ30gZGF0YSBcbiAgICAqIEByZXR1cm5zIFxuICAgICovXG4gICAgc2V0TG9jYWxlKGRhdGE6IGFueSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXQgdmFsaWQgPSBkYXRhLmxvY2FsZTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdCh7IG1lc3NhZ2U6IFwiaW52YWxpZCBkYXRhXCIgfSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5hcGlSZXF1ZXN0KCdQT1NUJywgJ2FwcHVzZXIvc2V0TG9jYWxlJywgZGF0YSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IHRydWUpIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSByZWplY3QocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGVycm9yKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuXG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0ge2Rpc3BsYXlOYW1lOnN0cmluZ30gZGF0YSBcbiAgICAgKiBAcmV0dXJucyAgXG4gICAgICovXG4gICAgdXBkYXRlUHJvZmlsZShkYXRhOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IHZhbGlkID0gZGF0YS5kaXNwbGF5TmFtZTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdCh7IG1lc3NhZ2U6IFwiaW52YWxpZCBkYXRhXCIgfSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICB0aGlzLmFwaVJlcXVlc3QoJ1BPU1QnLCAnYXBwdXNlci91cGRhdGVQcm9maWxlJywgZGF0YSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNvZGUpIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSByZWplY3QocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcblxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFxuICAgICAqIEBwYXJhbSB7dXNlck5hbWU6c3RyaW5nfSBkYXRhIFxuICAgICAqIEByZXR1cm5zICBcbiAgICAgKi9cbiAgICBzZXRVc2VyTmFtZShkYXRhOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoIWRhdGEudXNlck5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KHsgbWVzc2FnZTogXCJpbnZhbGlkIGRhdGFcIiB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZGF0YS51c2VyTmFtZSA9IGRhdGEudXNlck5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuYXBpUmVxdWVzdCgnUE9TVCcsICdhcHB1c2VyL3NldFVzZXJOYW1lJywgZGF0YSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNvZGUpIHJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuXG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0ge3VzZXJOYW1lOnN0cmluZ30gZGF0YSBcbiAgICAgKiBAcmV0dXJucyAgXG4gICAgICovXG4gICAgdXNlck5hbWVBdmFpbGFibGUoZGF0YTogYW55KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuXG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnVzZXJOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdCh7IG1lc3NhZ2U6IFwiaW52YWxpZCBkYXRhXCIgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGRhdGEudXNlck5hbWUgPSBkYXRhLnVzZXJOYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmFwaVJlcXVlc3QoJ0dFVCcsIGBhcHB1c2VyL3VzZXJOYW1lQXZhaWxhYmxlP3VzZXJOYW1lPSR7ZGF0YS51c2VyTmFtZX1gKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuY29kZSkgcmVqZWN0KHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFxuICAgICAqIFxuICAgICAqIEByZXR1cm5zICBcbiAgICAgKi9cbiAgICBkZWxldGVBY2NvdW50KCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcblxuICAgICAgICAgICAgICAgIHRoaXMuYXBpUmVxdWVzdCgnUE9TVCcsICdhcHB1c2VyL2RlbGV0ZUFjY291bnQnLCB7fSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNvZGUpIHJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIGNoYWxsZW5nZVxuICAgICAqL1xuICAgIGFkZFBhc3NrZXkoZGF0YTphbnkgPSB7fSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwaVJlcXVlc3QoJ1BPU1QnLCAnYXBwdXNlci9hZGRQYXNza2V5JywgZGF0YSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNvZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgIH0pLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICBcbiAgICBcblxuICAgIC8qKlxuICAgICAqIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJhdXRobi8jZGljdGRlZi1yZWdpc3RyYXRpb25yZXNwb25zZWpzb25cbiAgICAgKiBAcGFyYW0gXG4gICAgICogIHtcbiAgICAgKiBcbiAgICAgKiAgaWQ6IEJhc2U2NFVSTFN0cmluZztcbiAgICAgKiAgcmF3SWQ6IEJhc2U2NFVSTFN0cmluZztcbiAgICAgKiAgcmVzcG9uc2U6IHtcbiAgICAgKiAgICAgIGNsaWVudERhdGFKU09OOiBCYXNlNjRVUkxTdHJpbmc7XG4gICAgICogICAgICBhdHRlc3RhdGlvbk9iamVjdDogQmFzZTY0VVJMU3RyaW5nO1xuICAgICAqICAgICAgYXV0aGVudGljYXRvckRhdGE/OiBCYXNlNjRVUkxTdHJpbmc7IFxuICAgICAqICAgIH07XG4gICAgICogIGF1dGhlbnRpY2F0b3JBdHRhY2htZW50Pzogc3RyaW5nOyBcbiAgICAgKiAgdHlwZTogc3RyaW5nO1xuICAgICAqIH0gYXR0ZXN0YXRpb24gXG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgYWRkUGFzc2tleUNvbXBsZXRlKGF0dGVzdGF0aW9uOmFueSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXQgdmFsaWQgPSBhdHRlc3RhdGlvbi5pZCAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5yYXdJZCAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5yZXNwb25zZSAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5yZXNwb25zZS5jbGllbnREYXRhSlNPTiAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi5yZXNwb25zZS5hdHRlc3RhdGlvbk9iamVjdCAmJlxuICAgICAgICAgICAgICAgICAgICBhdHRlc3RhdGlvbi50eXBlO1xuXG4gICAgICAgICAgICAgICAgaWYgKCF2YWxpZCkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoeyBtZXNzYWdlOiBcImludmFsaWQgYXR0ZXN0YXRpb25cIiB9KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9IFxuXG4gICAgICAgICAgICAgICAgdGhpcy5hcGlSZXF1ZXN0KCdQT1NUJywgJ2FwcHVzZXIvYWRkUGFzc2tleUNvbXBsZXRlJywgYXR0ZXN0YXRpb24pLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5jb2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51c2VyID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAqXG4gICAgKiBAcGFyYW0ge2tleUlkOnN0cmluZywga2V5TmFtZTpzdHJpbmd9IGRhdGFcbiAgICAqIEByZXR1cm5zIHVzZXJcbiAgICAqL1xuICAgIHVwZGF0ZVBhc3NrZXkoZGF0YTphbnkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcGlSZXF1ZXN0KCdQT1NUJywgJ2FwcHVzZXIvdXBkYXRlUGFzc2tleScsIGRhdGEpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5jb2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51c2VyID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAqXG4gICAgKiBAcGFyYW0ge2tleUlkOnN0cmluZ30gZGF0YVxuICAgICogQHJldHVybnMgdXNlclxuICAgICovXG4gICAgcmVtb3ZlUGFzc2tleShkYXRhOmFueSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwaVJlcXVlc3QoJ1BPU1QnLCAnYXBwdXNlci9yZW1vdmVQYXNza2V5JywgZGF0YSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNvZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVzZXIgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG5cblxuICAgIHByaXZhdGUgYXN5bmMgYXBpUmVxdWVzdChtZXRob2Q6IHN0cmluZywgZW5kcG9pbnQ6IHN0cmluZywgZGF0YT86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuYXBpQ29uZmlnLmFwcFRva2VuKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJhcGlSZXF1ZXN0IHRoaXMuYXBpQ29uZmlnIFwiLCB0aGlzLmFwaUNvbmZpZyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgKFwiaW52YWxpZCBhcGkgY29uZmlnIGZvciBhcHAgdG9rZW5cIilcbiAgICAgICAgICAgIH0gXG5cbiAgICAgICAgICAgIGxldCBvcHRpb25zOiBhbnkgPSB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QgPyBtZXRob2QgOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnVzZXIgJiYgdGhpcy51c2VyWydhY2Nlc3MtdG9rZW4nXSAhPSBcIlwiKSBvcHRpb25zLmhlYWRlcnNbJ2FjY2Vzcy10b2tlbiddID0gdGhpcy51c2VyWydhY2Nlc3MtdG9rZW4nXTtcbiAgICAgICAgICAgIGVsc2UgaWYgKGRhdGEgJiYgZGF0YVsnYWNjZXNzLXRva2VuJ10pIG9wdGlvbnMuaGVhZGVyc1snYWNjZXNzLXRva2VuJ10gPSBkYXRhWydhY2Nlc3MtdG9rZW4nXTtcbiAgICAgICAgICAgIGVsc2UgaWYgKGRhdGEgJiYgZGF0YS5zaWdudXBUb2tlbikgb3B0aW9ucy5oZWFkZXJzWydzaWdudXAtdG9rZW4nXSA9IGRhdGEuc2lnbnVwVG9rZW47XG4gICAgICAgICAgICBlbHNlIG9wdGlvbnMuaGVhZGVyc1snYXBwLXRva2VuJ10gPSB0aGlzLmFwaUNvbmZpZy5hcHBUb2tlblxuXG4gICAgICAgICAgICBpZiAoZGF0YSAmJiBtZXRob2QgPT0gXCJQT1NUXCIgfHwgbWV0aG9kID09IFwiUFVUXCIpIG9wdGlvbnMuYm9keSA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuXG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke3RoaXMuYXBpQ29uZmlnLmFwaVVybH0vYXBpLyR7ZW5kcG9pbnR9YCwgb3B0aW9ucyk7XG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgYXBpUmVxdWVzdCBwYXRoOiAke2VuZHBvaW50fSAtIHJlc3VsdDogYCwgcmVzdWx0KVxuXG4gICAgICAgICAgICAvLyBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHJldHVybiB7IGVycm9yOiByZXN1bHQgfVxuICAgICAgICAgICAgLy8gZWxzZSByZXR1cm4gcmVzdWx0XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcblxuICAgICAgICAgICAgY29uc29sZS5sb2coYGFwaVJlcXVlc3QgZXJyb3I6YCwgZXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuIl19