ngx-captcha
Version:
Dynamic captcha (Google reCaptcha) implementation for Angular
127 lines • 16.9 kB
JavaScript
import { Injectable, NgZone } from "@angular/core";
import * as i0 from "@angular/core";
export class ScriptService {
constructor(zone) {
this.zone = zone;
this.scriptElemId = "ngx-catpcha-script";
/**
* Name of the global google recaptcha script
*/
this.windowGrecaptcha = "grecaptcha";
/**
* Name of enterpise property in the global google recaptcha script
*/
this.windowGrecaptchaEnterprise = "enterprise";
/**
* Name of the global callback
*/
this.windowOnLoadCallbackProperty = "ngx_captcha_onload_callback";
/**
* Name of the global callback for enterprise
*/
this.windowOnLoadEnterpriseCallbackProperty = "ngx_captcha_onload_enterprise_callback";
this.globalDomain = "recaptcha.net";
this.defaultDomain = "google.com";
this.enterpriseApi = "enterprise.js";
this.defaultApi = "api.js";
}
registerCaptchaScript(config, render, onLoad, language) {
if (this.grecaptchaScriptLoaded(config.useEnterprise)) {
// recaptcha script is already loaded
// just call the callback
if (config.useEnterprise) {
this.zone.run(() => {
onLoad(window[this.windowGrecaptcha][this.windowGrecaptchaEnterprise]);
});
}
else {
this.zone.run(() => {
onLoad(window[this.windowGrecaptcha]);
});
}
return;
}
// we need to patch the callback through global variable, otherwise callback is not accessible
// note: https://github.com/Enngage/ngx-captcha/issues/2
if (config.useEnterprise) {
window[this.getCallbackName(true)] = ((() => this.zone.run(onLoad.bind(this, window[this.windowGrecaptcha][this.windowGrecaptchaEnterprise]))));
}
else {
window[this.getCallbackName(false)] = ((() => this.zone.run(onLoad.bind(this, window[this.windowGrecaptcha]))));
}
// prepare script elem
const scriptElem = document.createElement("script");
scriptElem.id = this.scriptElemId;
scriptElem.innerHTML = "";
scriptElem.src = this.getCaptchaScriptUrl(config, render, language);
scriptElem.async = true;
scriptElem.defer = true;
// add script to header
document.getElementsByTagName("head")[0].appendChild(scriptElem);
}
cleanup() {
const elem = document.getElementById(this.scriptElemId);
if (elem) {
elem.remove();
}
window[this.getCallbackName()] = undefined;
window[this.windowGrecaptcha] = undefined;
}
/**
* Indicates if google recaptcha script is available and ready to be used
*/
grecaptchaScriptLoaded(useEnterprise) {
if (!window[this.getCallbackName(useEnterprise)] ||
!window[this.windowGrecaptcha]) {
return false;
}
else if (useEnterprise &&
window[this.windowGrecaptcha][this.windowGrecaptchaEnterprise]) {
return true;
// if only enterprise script is loaded we need to check some v3's method
}
else if (window[this.windowGrecaptcha].execute) {
return true;
}
return false;
}
/**
* Gets global callback name
* @param useEnterprise Optional flag for enterprise script
* @private
*/
getCallbackName(useEnterprise) {
return useEnterprise
? this.windowOnLoadEnterpriseCallbackProperty
: this.windowOnLoadCallbackProperty;
}
/**
* Gets language param used in script url
*/
getLanguageParam(hl) {
if (!hl) {
return "";
}
return `&hl=${hl}`;
}
/**
* Url to google api script
*/
getCaptchaScriptUrl(config, render, language) {
const domain = config.useGlobalDomain
? this.globalDomain
: this.defaultDomain;
const api = config.useEnterprise ? this.enterpriseApi : this.defaultApi;
const callback = this.getCallbackName(config.useEnterprise);
return `https://www.${domain}/recaptcha/${api}?onload=${callback}&render=${render}${this.getLanguageParam(language)}`;
}
}
/** @nocollapse */ ScriptService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ScriptService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ ScriptService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ScriptService, providedIn: "root" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: ScriptService, decorators: [{
type: Injectable,
args: [{
providedIn: "root",
}]
}], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyaXB0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL3NjcmlwdC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQU1uRCxNQUFNLE9BQU8sYUFBYTtJQWlDeEIsWUFBc0IsSUFBWTtRQUFaLFNBQUksR0FBSixJQUFJLENBQVE7UUFoQ2pCLGlCQUFZLEdBQVcsb0JBQW9CLENBQUM7UUFFN0Q7O1dBRUc7UUFDZ0IscUJBQWdCLEdBQUcsWUFBWSxDQUFDO1FBRW5EOztXQUVHO1FBQ2dCLCtCQUEwQixHQUFHLFlBQVksQ0FBQztRQUU3RDs7V0FFRztRQUNnQixpQ0FBNEIsR0FDN0MsNkJBQTZCLENBQUM7UUFFaEM7O1dBRUc7UUFDZ0IsMkNBQXNDLEdBQ3ZELHdDQUF3QyxDQUFDO1FBRXhCLGlCQUFZLEdBQVcsZUFBZSxDQUFDO1FBRXZDLGtCQUFhLEdBQVcsWUFBWSxDQUFDO1FBRXJDLGtCQUFhLEdBQVcsZUFBZSxDQUFDO1FBRXhDLGVBQVUsR0FBVyxRQUFRLENBQUM7SUFFWixDQUFDO0lBRXRDLHFCQUFxQixDQUNuQixNQUE4QixFQUM5QixNQUFjLEVBQ2QsTUFBaUMsRUFDakMsUUFBaUI7UUFFakIsSUFBSSxJQUFJLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFO1lBQ3JELHFDQUFxQztZQUNyQyx5QkFBeUI7WUFDekIsSUFBSSxNQUFNLENBQUMsYUFBYSxFQUFFO2dCQUN4QixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ2pCLE1BQU0sQ0FDSCxNQUFjLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQ3BDLElBQUksQ0FBQywwQkFBMEIsQ0FDaEMsQ0FDRixDQUFDO2dCQUNKLENBQUMsQ0FBQyxDQUFDO2FBQ0o7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO29CQUNqQixNQUFNLENBQUUsTUFBYyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pELENBQUMsQ0FBQyxDQUFDO2FBQ0o7WUFDRCxPQUFPO1NBQ1I7UUFFRCw4RkFBOEY7UUFDOUYsd0RBQXdEO1FBQ3hELElBQUksTUFBTSxDQUFDLGFBQWEsRUFBRTtZQUN2QixNQUFjLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFRLENBQ2pELENBQUMsR0FBRyxFQUFFLENBQ0osSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsTUFBTSxDQUFDLElBQUksQ0FDVCxJQUFJLEVBQ0gsTUFBYyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUNwQyxJQUFJLENBQUMsMEJBQTBCLENBQ2hDLENBQ0YsQ0FDRixDQUFDLENBQ0wsQ0FBQztTQUNIO2FBQU07WUFDSixNQUFjLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFRLENBQ2xELENBQUMsR0FBRyxFQUFFLENBQ0osSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUcsTUFBYyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQzFELENBQUMsQ0FDTCxDQUFDO1NBQ0g7UUFFRCxzQkFBc0I7UUFDdEIsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNwRCxVQUFVLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDbEMsVUFBVSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDMUIsVUFBVSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNwRSxVQUFVLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUN4QixVQUFVLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUV4Qix1QkFBdUI7UUFDdkIsUUFBUSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRUQsT0FBTztRQUNMLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXhELElBQUksSUFBSSxFQUFFO1lBQ1IsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ2Y7UUFDQSxNQUFjLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDO1FBQ25ELE1BQWMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxTQUFTLENBQUM7SUFDckQsQ0FBQztJQUVEOztPQUVHO0lBQ0ssc0JBQXNCLENBQUMsYUFBdUI7UUFDcEQsSUFDRSxDQUFFLE1BQWMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3JELENBQUUsTUFBYyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUN2QztZQUNBLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7YUFBTSxJQUNMLGFBQWE7WUFDWixNQUFjLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLEVBQ3ZFO1lBQ0EsT0FBTyxJQUFJLENBQUM7WUFDWix3RUFBd0U7U0FDekU7YUFBTSxJQUFLLE1BQWMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxPQUFPLEVBQUU7WUFDekQsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxlQUFlLENBQUMsYUFBdUI7UUFDN0MsT0FBTyxhQUFhO1lBQ2xCLENBQUMsQ0FBQyxJQUFJLENBQUMsc0NBQXNDO1lBQzdDLENBQUMsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLENBQUM7SUFDeEMsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZ0JBQWdCLENBQUMsRUFBVztRQUNsQyxJQUFJLENBQUMsRUFBRSxFQUFFO1lBQ1AsT0FBTyxFQUFFLENBQUM7U0FDWDtRQUVELE9BQU8sT0FBTyxFQUFFLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQ7O09BRUc7SUFDSyxtQkFBbUIsQ0FDekIsTUFBOEIsRUFDOUIsTUFBYyxFQUNkLFFBQWlCO1FBRWpCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxlQUFlO1lBQ25DLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWTtZQUNuQixDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUN2QixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ3hFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRTVELE9BQU8sZUFBZSxNQUFNLGNBQWMsR0FBRyxXQUFXLFFBQVEsV0FBVyxNQUFNLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUN2RyxRQUFRLENBQ1QsRUFBRSxDQUFDO0lBQ04sQ0FBQzs7NkhBcktVLGFBQWE7aUlBQWIsYUFBYSxjQUZaLE1BQU07MkZBRVAsYUFBYTtrQkFIekIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBOZ1pvbmUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBSZWNhcHRjaGFDb25maWd1cmF0aW9uIH0gZnJvbSBcIi4uL21vZGVscy9yZWNhcHRjaGEtY29uZmlndXJhdGlvblwiO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46IFwicm9vdFwiLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2NyaXB0U2VydmljZSB7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBzY3JpcHRFbGVtSWQ6IHN0cmluZyA9IFwibmd4LWNhdHBjaGEtc2NyaXB0XCI7XHJcblxyXG4gIC8qKlxyXG4gICAqIE5hbWUgb2YgdGhlIGdsb2JhbCBnb29nbGUgcmVjYXB0Y2hhIHNjcmlwdFxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCByZWFkb25seSB3aW5kb3dHcmVjYXB0Y2hhID0gXCJncmVjYXB0Y2hhXCI7XHJcblxyXG4gIC8qKlxyXG4gICAqIE5hbWUgb2YgZW50ZXJwaXNlIHByb3BlcnR5IGluIHRoZSBnbG9iYWwgZ29vZ2xlIHJlY2FwdGNoYSBzY3JpcHRcclxuICAgKi9cclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgd2luZG93R3JlY2FwdGNoYUVudGVycHJpc2UgPSBcImVudGVycHJpc2VcIjtcclxuXHJcbiAgLyoqXHJcbiAgICogTmFtZSBvZiB0aGUgZ2xvYmFsIGNhbGxiYWNrXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHdpbmRvd09uTG9hZENhbGxiYWNrUHJvcGVydHkgPVxyXG4gICAgXCJuZ3hfY2FwdGNoYV9vbmxvYWRfY2FsbGJhY2tcIjtcclxuXHJcbiAgLyoqXHJcbiAgICogTmFtZSBvZiB0aGUgZ2xvYmFsIGNhbGxiYWNrIGZvciBlbnRlcnByaXNlXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHdpbmRvd09uTG9hZEVudGVycHJpc2VDYWxsYmFja1Byb3BlcnR5ID1cclxuICAgIFwibmd4X2NhcHRjaGFfb25sb2FkX2VudGVycHJpc2VfY2FsbGJhY2tcIjtcclxuXHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGdsb2JhbERvbWFpbjogc3RyaW5nID0gXCJyZWNhcHRjaGEubmV0XCI7XHJcblxyXG4gIHByb3RlY3RlZCByZWFkb25seSBkZWZhdWx0RG9tYWluOiBzdHJpbmcgPSBcImdvb2dsZS5jb21cIjtcclxuXHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGVudGVycHJpc2VBcGk6IHN0cmluZyA9IFwiZW50ZXJwcmlzZS5qc1wiO1xyXG5cclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGVmYXVsdEFwaTogc3RyaW5nID0gXCJhcGkuanNcIjtcclxuXHJcbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIHpvbmU6IE5nWm9uZSkge31cclxuXHJcbiAgcmVnaXN0ZXJDYXB0Y2hhU2NyaXB0KFxyXG4gICAgY29uZmlnOiBSZWNhcHRjaGFDb25maWd1cmF0aW9uLFxyXG4gICAgcmVuZGVyOiBzdHJpbmcsXHJcbiAgICBvbkxvYWQ6IChncmVjYXB0Y2hhOiBhbnkpID0+IHZvaWQsXHJcbiAgICBsYW5ndWFnZT86IHN0cmluZ1xyXG4gICk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZ3JlY2FwdGNoYVNjcmlwdExvYWRlZChjb25maWcudXNlRW50ZXJwcmlzZSkpIHtcclxuICAgICAgLy8gcmVjYXB0Y2hhIHNjcmlwdCBpcyBhbHJlYWR5IGxvYWRlZFxyXG4gICAgICAvLyBqdXN0IGNhbGwgdGhlIGNhbGxiYWNrXHJcbiAgICAgIGlmIChjb25maWcudXNlRW50ZXJwcmlzZSkge1xyXG4gICAgICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xyXG4gICAgICAgICAgb25Mb2FkKFxyXG4gICAgICAgICAgICAod2luZG93IGFzIGFueSlbdGhpcy53aW5kb3dHcmVjYXB0Y2hhXVtcclxuICAgICAgICAgICAgICB0aGlzLndpbmRvd0dyZWNhcHRjaGFFbnRlcnByaXNlXHJcbiAgICAgICAgICAgIF1cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgICBvbkxvYWQoKHdpbmRvdyBhcyBhbnkpW3RoaXMud2luZG93R3JlY2FwdGNoYV0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyB3ZSBuZWVkIHRvIHBhdGNoIHRoZSBjYWxsYmFjayB0aHJvdWdoIGdsb2JhbCB2YXJpYWJsZSwgb3RoZXJ3aXNlIGNhbGxiYWNrIGlzIG5vdCBhY2Nlc3NpYmxlXHJcbiAgICAvLyBub3RlOiBodHRwczovL2dpdGh1Yi5jb20vRW5uZ2FnZS9uZ3gtY2FwdGNoYS9pc3N1ZXMvMlxyXG4gICAgaWYgKGNvbmZpZy51c2VFbnRlcnByaXNlKSB7XHJcbiAgICAgICh3aW5kb3cgYXMgYW55KVt0aGlzLmdldENhbGxiYWNrTmFtZSh0cnVlKV0gPSA8YW55PihcclxuICAgICAgICAoKCkgPT5cclxuICAgICAgICAgIHRoaXMuem9uZS5ydW4oXHJcbiAgICAgICAgICAgIG9uTG9hZC5iaW5kKFxyXG4gICAgICAgICAgICAgIHRoaXMsXHJcbiAgICAgICAgICAgICAgKHdpbmRvdyBhcyBhbnkpW3RoaXMud2luZG93R3JlY2FwdGNoYV1bXHJcbiAgICAgICAgICAgICAgICB0aGlzLndpbmRvd0dyZWNhcHRjaGFFbnRlcnByaXNlXHJcbiAgICAgICAgICAgICAgXVxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgICApKVxyXG4gICAgICApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgKHdpbmRvdyBhcyBhbnkpW3RoaXMuZ2V0Q2FsbGJhY2tOYW1lKGZhbHNlKV0gPSA8YW55PihcclxuICAgICAgICAoKCkgPT5cclxuICAgICAgICAgIHRoaXMuem9uZS5ydW4oXHJcbiAgICAgICAgICAgIG9uTG9hZC5iaW5kKHRoaXMsICh3aW5kb3cgYXMgYW55KVt0aGlzLndpbmRvd0dyZWNhcHRjaGFdKVxyXG4gICAgICAgICAgKSlcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBwcmVwYXJlIHNjcmlwdCBlbGVtXHJcbiAgICBjb25zdCBzY3JpcHRFbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKTtcclxuICAgIHNjcmlwdEVsZW0uaWQgPSB0aGlzLnNjcmlwdEVsZW1JZDtcclxuICAgIHNjcmlwdEVsZW0uaW5uZXJIVE1MID0gXCJcIjtcclxuICAgIHNjcmlwdEVsZW0uc3JjID0gdGhpcy5nZXRDYXB0Y2hhU2NyaXB0VXJsKGNvbmZpZywgcmVuZGVyLCBsYW5ndWFnZSk7XHJcbiAgICBzY3JpcHRFbGVtLmFzeW5jID0gdHJ1ZTtcclxuICAgIHNjcmlwdEVsZW0uZGVmZXIgPSB0cnVlO1xyXG5cclxuICAgIC8vIGFkZCBzY3JpcHQgdG8gaGVhZGVyXHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQoc2NyaXB0RWxlbSk7XHJcbiAgfVxyXG5cclxuICBjbGVhbnVwKCk6IHZvaWQge1xyXG4gICAgY29uc3QgZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuc2NyaXB0RWxlbUlkKTtcclxuXHJcbiAgICBpZiAoZWxlbSkge1xyXG4gICAgICBlbGVtLnJlbW92ZSgpO1xyXG4gICAgfVxyXG4gICAgKHdpbmRvdyBhcyBhbnkpW3RoaXMuZ2V0Q2FsbGJhY2tOYW1lKCldID0gdW5kZWZpbmVkO1xyXG4gICAgKHdpbmRvdyBhcyBhbnkpW3RoaXMud2luZG93R3JlY2FwdGNoYV0gPSB1bmRlZmluZWQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbmRpY2F0ZXMgaWYgZ29vZ2xlIHJlY2FwdGNoYSBzY3JpcHQgaXMgYXZhaWxhYmxlIGFuZCByZWFkeSB0byBiZSB1c2VkXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBncmVjYXB0Y2hhU2NyaXB0TG9hZGVkKHVzZUVudGVycHJpc2U/OiBib29sZWFuKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoXHJcbiAgICAgICEod2luZG93IGFzIGFueSlbdGhpcy5nZXRDYWxsYmFja05hbWUodXNlRW50ZXJwcmlzZSldIHx8XHJcbiAgICAgICEod2luZG93IGFzIGFueSlbdGhpcy53aW5kb3dHcmVjYXB0Y2hhXVxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgIHVzZUVudGVycHJpc2UgJiZcclxuICAgICAgKHdpbmRvdyBhcyBhbnkpW3RoaXMud2luZG93R3JlY2FwdGNoYV1bdGhpcy53aW5kb3dHcmVjYXB0Y2hhRW50ZXJwcmlzZV1cclxuICAgICkge1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgLy8gaWYgb25seSBlbnRlcnByaXNlIHNjcmlwdCBpcyBsb2FkZWQgd2UgbmVlZCB0byBjaGVjayBzb21lIHYzJ3MgbWV0aG9kXHJcbiAgICB9IGVsc2UgaWYgKCh3aW5kb3cgYXMgYW55KVt0aGlzLndpbmRvd0dyZWNhcHRjaGFdLmV4ZWN1dGUpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXRzIGdsb2JhbCBjYWxsYmFjayBuYW1lXHJcbiAgICogQHBhcmFtIHVzZUVudGVycHJpc2UgT3B0aW9uYWwgZmxhZyBmb3IgZW50ZXJwcmlzZSBzY3JpcHRcclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0Q2FsbGJhY2tOYW1lKHVzZUVudGVycHJpc2U/OiBib29sZWFuKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB1c2VFbnRlcnByaXNlXHJcbiAgICAgID8gdGhpcy53aW5kb3dPbkxvYWRFbnRlcnByaXNlQ2FsbGJhY2tQcm9wZXJ0eVxyXG4gICAgICA6IHRoaXMud2luZG93T25Mb2FkQ2FsbGJhY2tQcm9wZXJ0eTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgbGFuZ3VhZ2UgcGFyYW0gdXNlZCBpbiBzY3JpcHQgdXJsXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRMYW5ndWFnZVBhcmFtKGhsPzogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGlmICghaGwpIHtcclxuICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGAmaGw9JHtobH1gO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXJsIHRvIGdvb2dsZSBhcGkgc2NyaXB0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRDYXB0Y2hhU2NyaXB0VXJsKFxyXG4gICAgY29uZmlnOiBSZWNhcHRjaGFDb25maWd1cmF0aW9uLFxyXG4gICAgcmVuZGVyOiBzdHJpbmcsXHJcbiAgICBsYW5ndWFnZT86IHN0cmluZ1xyXG4gICk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBkb21haW4gPSBjb25maWcudXNlR2xvYmFsRG9tYWluXHJcbiAgICAgID8gdGhpcy5nbG9iYWxEb21haW5cclxuICAgICAgOiB0aGlzLmRlZmF1bHREb21haW47XHJcbiAgICBjb25zdCBhcGkgPSBjb25maWcudXNlRW50ZXJwcmlzZSA/IHRoaXMuZW50ZXJwcmlzZUFwaSA6IHRoaXMuZGVmYXVsdEFwaTtcclxuICAgIGNvbnN0IGNhbGxiYWNrID0gdGhpcy5nZXRDYWxsYmFja05hbWUoY29uZmlnLnVzZUVudGVycHJpc2UpO1xyXG5cclxuICAgIHJldHVybiBgaHR0cHM6Ly93d3cuJHtkb21haW59L3JlY2FwdGNoYS8ke2FwaX0/b25sb2FkPSR7Y2FsbGJhY2t9JnJlbmRlcj0ke3JlbmRlcn0ke3RoaXMuZ2V0TGFuZ3VhZ2VQYXJhbShcclxuICAgICAgbGFuZ3VhZ2VcclxuICAgICl9YDtcclxuICB9XHJcbn1cclxuIl19