ngx-paypal-with-intent
Version:
Paypal integration for Angular 6, 7 and beyond
495 lines • 55.2 kB
JavaScript
import { ChangeDetectionStrategy, Component, Input, ViewChild, NgModule } from '@angular/core';
import { interval, Subject } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {number} */
var PayPalFunding = {
Card: 0,
Credit: 1,
Elv: 2,
};
PayPalFunding[PayPalFunding.Card] = 'Card';
PayPalFunding[PayPalFunding.Credit] = 'Credit';
PayPalFunding[PayPalFunding.Elv] = 'Elv';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {number} */
var PayPalIntegrationType = {
ClientSideREST: 0,
ServerSideREST: 1,
};
PayPalIntegrationType[PayPalIntegrationType.ClientSideREST] = 'ClientSideREST';
PayPalIntegrationType[PayPalIntegrationType.ServerSideREST] = 'ServerSideREST';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var PayPalConfig = /** @class */ (function () {
function PayPalConfig(integrationType, environment, config) {
this.integrationType = integrationType;
this.environment = environment;
/**
* Show 'Pay Now' button config
*/
this.commit = true;
/**
* Set the intent of the payment.
*/
this.intent = 'sale';
Object.assign(this, config);
}
return PayPalConfig;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var NgxPaypalComponent = /** @class */ (function () {
function NgxPaypalComponent() {
/**
* Indicates if global configuration (provided via 'forRoot') is used
*/
this.useGlobalConfig = false;
/**
* Used for indicating delayed rendered if container is not yet ready in DOM
*/
this.registerPayPalScriptWhenContainerIsReady = false;
/**
* Polling interval if paypal script is pending
*/
this.defaultPollInterval = 50;
/**
* Polling will stop after polling reaches this number
*/
this.maximumPollWaitTime = 5000;
/**
* Name of the global variable where paypal is stored
*/
this.paypalWindowName = 'paypal';
/**
* Name of the global variable indicating that script was initiated (added to page)
*/
this.paypalWindowScriptInitiated = 'ngx-paypal-script-initiated';
/**
* PayPal integration script url
*/
this.paypalScriptUrl = 'https://www.paypalobjects.com/api/checkout.js';
this.payPalButtonContainerIdPrefix = 'ngx-paypal-button-container-';
this.ngUnsubscribe = new Subject();
}
Object.defineProperty(NgxPaypalComponent.prototype, "payPalButtonContainerElem", {
set: /**
* @param {?} content
* @return {?}
*/
function (content) {
if (content) {
this._payPalButtonContainerElem = content;
}
},
enumerable: true,
configurable: true
});
/**
* @param {?} changes
* @return {?}
*/
NgxPaypalComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
// init when config once its available
if (this.config) {
this.initPayPal();
}
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
// register script if element is ready in dom
if (this.registerPayPalScriptWhenContainerIsReady && this._payPalButtonContainerElem) {
this.setupScript();
this.registerPayPalScriptWhenContainerIsReady = false;
}
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.initPayPal = /**
* @return {?}
*/
function () {
// set unique paypal container button id
this.payPalButtonContainerId = "" + this.payPalButtonContainerIdPrefix + this.getPseudoUniqueNumber();
// check if paypal was already register and if so, don't add it to page again
if (!window[this.paypalWindowName]) {
// check if script is pending
if (window[this.paypalWindowScriptInitiated] === true) {
this.pollUntilScriptAvailable();
}
else {
// register script and set global flag
window[this.paypalWindowScriptInitiated] = true;
this.addPayPalScriptToPage();
}
}
else {
// just register payment
this.handleScriptRegistering();
}
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.getPseudoUniqueNumber = /**
* @return {?}
*/
function () {
return new Date().valueOf();
};
/**
* Used when there are multiple paypal components on the same page beacuse only 1 of them
* may register paypal script. The other has to be polling until paypal is available or component destroyed
*/
/**
* Used when there are multiple paypal components on the same page beacuse only 1 of them
* may register paypal script. The other has to be polling until paypal is available or component destroyed
* @return {?}
*/
NgxPaypalComponent.prototype.pollUntilScriptAvailable = /**
* Used when there are multiple paypal components on the same page beacuse only 1 of them
* may register paypal script. The other has to be polling until paypal is available or component destroyed
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var obs = interval(this.defaultPollInterval)
.pipe(takeUntil(this.ngUnsubscribe), map(function (x) {
if (x >= _this.maximumPollWaitTime) {
console.warn("PayPal script was not loaded after '" + _this.maximumPollWaitTime + "' maximum polling time.");
obs.unsubscribe();
return;
}
// check if paypal script exists
if (window[_this.paypalWindowName]) {
// register script
_this.handleScriptRegistering();
// stop execution
obs.unsubscribe();
}
}))
.subscribe();
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.addPayPalScriptToPage = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var script = document.createElement('script');
script.innerHTML = '';
script.src = this.paypalScriptUrl;
script.onload = function () { return _this.handleScriptRegistering(); };
script.async = true;
script.defer = true;
this.paypalScriptElem.nativeElement.appendChild(script);
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.handleScriptRegistering = /**
* @return {?}
*/
function () {
// check if container with requested id exists
// this is here because dynamically switching between components would cause PayPal to
// throw an error if the container already existed before
if (this._payPalButtonContainerElem && this._payPalButtonContainerElem.nativeElement &&
this._payPalButtonContainerElem.nativeElement.id === this.payPalButtonContainerId) {
// container is ready, setup script right away
this.setupScript();
}
else {
// container is not ready, delay registering until it is
this.registerPayPalScriptWhenContainerIsReady = true;
}
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.setupScript = /**
* @return {?}
*/
function () {
var _this = this;
// first clear container
if (!this._payPalButtonContainerElem) {
throw Error("Cannot setup script because paypal button container with id '" + this.payPalButtonContainerId + "' is not yet ready");
}
this._payPalButtonContainerElem.nativeElement.innerHTML = '';
if (!window[this.paypalWindowName]) {
throw Error('PayPal script is not available');
}
// render PayPal button as per their docs at
// https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/add-paypal-button/
window[this.paypalWindowName].Button.render({
// set environment
env: this.config.environment.toString(),
// Show the buyer a 'Pay Now' button in the checkout flow
commit: this.config.commit,
// init client for client side integration
client: this.getClient(),
// set button config if available
style: this.config.button,
// set funding if available
funding: this.getFunding(),
// payment() is called when the button is clicked
payment: function (data, actions) {
if (_this.config.integrationType === PayPalIntegrationType.ServerSideREST) {
// client needs to create payment on server side
if (!_this.config.payment) {
throw Error("You need set up a create payment method and return\n PayPal's payment id when using server side integration");
}
// Paypal expects promise with payment id (string) to be returned
return _this.config.payment().toPromise()
.then(function (paymentId) {
return paymentId;
});
}
if (_this.config.integrationType === PayPalIntegrationType.ClientSideREST) {
if (!_this.config.transactions || !Array.isArray(_this.config.transactions) || _this.config.transactions.length <= 0) {
throw Error("You need to provide at least 1 transaction for client side integration");
}
/** @type {?} */
var experienceConfig = _this.config.experience;
return actions.payment.create({
// Allow user to specifify intent, else use default 'sale'.
intent: _this.config.intent ? _this.config.intent : 'sale',
payment: {
transactions: _this.config.transactions
},
experience: {
input_fields: {
no_shipping: (experienceConfig && experienceConfig.noShipping) ? 1 : 0
},
presentation: {
brand_name: (experienceConfig && experienceConfig.brandName) ? experienceConfig.brandName : null,
logo_image: (experienceConfig && experienceConfig.logoImage) ? experienceConfig.logoImage : null,
locale_code: (experienceConfig && experienceConfig.localeCode) ? experienceConfig.localeCode : null
}
}
});
}
},
// onAuthorize() is called when the buyer approves the payment
onAuthorize: function (data, actions) {
if (_this.config.integrationType === PayPalIntegrationType.ServerSideREST) {
// client needs to server to execute the payment
if (!_this.config.onAuthorize) {
throw Error("You need set up an execute method when using server side integration");
}
// Paypal expects promise
return _this.config.onAuthorize(data, actions).toPromise();
}
if (_this.config.integrationType === PayPalIntegrationType.ClientSideREST) {
// Make a call to the REST api to execute the payment
return actions.payment.execute().then(function () {
if (!_this.config.onPaymentComplete) {
throw Error("You should provide some callback when payment is finished when using client side integration");
}
_this.config.onPaymentComplete(data, actions);
});
}
},
onError: function (err) {
if (_this.config.onError) {
_this.config.onError(err);
}
},
onCancel: function (data, actions) {
if (_this.config.onCancel) {
_this.config.onCancel(data, actions);
}
},
onClick: function () {
if (_this.config.onClick) {
_this.config.onClick();
}
},
validate: function (actions) {
if (_this.config.validate) {
_this.config.validate(actions);
}
}
}, "#" + this.payPalButtonContainerId);
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.getClient = /**
* @return {?}
*/
function () {
if (this.config.integrationType === PayPalIntegrationType.ClientSideREST) {
if (!this.config.client) {
throw Error("You need to setup client information when using client side integration");
}
return {
production: this.config.client.production,
sandbox: this.config.client.sandbox
};
}
return undefined;
};
/**
* @return {?}
*/
NgxPaypalComponent.prototype.getFunding = /**
* @return {?}
*/
function () {
var _this = this;
// resolve funding to use paypal's properties
if (!this.config.funding) {
// no funding provided
return undefined;
}
/** @type {?} */
var allowed = [];
/** @type {?} */
var disallowed = [];
if (this.config.funding.allowed) {
this.config.funding.allowed.forEach(function (type) {
allowed.push(_this.mapFundingType(type));
});
}
if (this.config.funding.disallowed) {
this.config.funding.disallowed.forEach(function (type) {
disallowed.push(_this.mapFundingType(type));
});
}
return {
allowed: allowed,
disallowed: disallowed
};
};
/**
* @param {?} type
* @return {?}
*/
NgxPaypalComponent.prototype.mapFundingType = /**
* @param {?} type
* @return {?}
*/
function (type) {
if (type === PayPalFunding.Card) {
return paypal.FUNDING.CARD;
}
if (type === PayPalFunding.Credit) {
return paypal.FUNDING.CREDIT;
}
if (type === PayPalFunding.Elv) {
return paypal.FUNDING.ELV;
}
throw Error("Unsupported funding type '" + type + "'");
};
NgxPaypalComponent.decorators = [
{ type: Component, args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'ngx-paypal',
template: "\n <div #payPalScriptElem></div>\n <div #payPalButtonContainerElem [id]=\"payPalButtonContainerId\"></div>\n "
}] }
];
/** @nocollapse */
NgxPaypalComponent.ctorParameters = function () { return []; };
NgxPaypalComponent.propDecorators = {
config: [{ type: Input }],
useGlobalConfig: [{ type: Input }],
paypalScriptElem: [{ type: ViewChild, args: ['payPalScriptElem',] }],
payPalButtonContainerElem: [{ type: ViewChild, args: ['payPalButtonContainerElem',] }]
};
return NgxPaypalComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var NgxPayPalModule = /** @class */ (function () {
function NgxPayPalModule() {
}
NgxPayPalModule.decorators = [
{ type: NgModule, args: [{
imports: [],
declarations: [
NgxPaypalComponent,
],
exports: [
NgxPaypalComponent,
]
},] }
];
return NgxPayPalModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @enum {string} */
var PayPalEnvironment = {
Sandbox: 'sandbox',
Production: 'production',
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
export { NgxPayPalModule, PayPalEnvironment, PayPalFunding, PayPalIntegrationType, PayPalConfig, NgxPaypalComponent, NgxPaypalComponent as ɵa };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXBheXBhbC5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmd4LXBheXBhbC9saWIvbW9kZWxzL3BheXBhbC1mdW5kaW5nLnRzIiwibmc6Ly9uZ3gtcGF5cGFsL2xpYi9tb2RlbHMvcGF5cGFsLWludGVncmF0aW9uLnRzIiwibmc6Ly9uZ3gtcGF5cGFsL2xpYi9tb2RlbHMvcGF5cGFsLW1vZGVscy50cyIsIm5nOi8vbmd4LXBheXBhbC9saWIvY29tcG9uZW50cy9wYXlwYWwtY29tcG9uZW50LnRzIiwibmc6Ly9uZ3gtcGF5cGFsL2xpYi9uZ3gtcGF5cGFsLm1vZHVsZS50cyIsIm5nOi8vbmd4LXBheXBhbC9saWIvbW9kZWxzL3BheXBhbC1lbnZpcm9ubWVudC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZW51bSBQYXlQYWxGdW5kaW5nIHtcbiAgICBDYXJkLFxuICAgIENyZWRpdCxcbiAgICBFbHZcbn1cbiIsImV4cG9ydCBlbnVtIFBheVBhbEludGVncmF0aW9uVHlwZSB7XG4gICAgQ2xpZW50U2lkZVJFU1QsXG4gICAgU2VydmVyU2lkZVJFU1QsXG59XG4iLCJpbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFBheVBhbEZ1bmRpbmcgfSBmcm9tICcuL3BheXBhbC1mdW5kaW5nJztcbmltcG9ydCB7IFBheVBhbEVudmlyb25tZW50IH0gZnJvbSAnLi9wYXlwYWwtZW52aXJvbm1lbnQnO1xuaW1wb3J0IHsgUGF5UGFsSW50ZWdyYXRpb25UeXBlIH0gZnJvbSAnLi9wYXlwYWwtaW50ZWdyYXRpb24nO1xuXG5leHBvcnQgY2xhc3MgUGF5UGFsQ29uZmlnIHtcblxuICAgIC8qKlxuICAgICAqIFNob3cgJ1BheSBOb3cnIGJ1dHRvbiBjb25maWdcbiAgICAgKi9cbiAgICBwdWJsaWMgY29tbWl0ID0gdHJ1ZTtcblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgaW50ZW50IG9mIHRoZSBwYXltZW50LlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnRlbnQgPSAnc2FsZSc7XG5cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgdG8gY3JlYXRlIG5ldyBwYXltZW50IGZvciBzZXJ2ZXIgc2lkZSBpbnRlZ3JhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBwYXltZW50PzogKCkgPT4gT2JzZXJ2YWJsZTxzdHJpbmc+O1xuXG4gICAgLyoqXG4gICAgICogQ2FsbGVkIHRvIGV4ZWN1dGUgcGF5bWVudCBmb3Igc2VydmVyIHNpZGUgaW50ZWdyYXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgb25BdXRob3JpemU/OiAoZGF0YTogSVBheVBhbFBheW1lbnRDb21wbGV0ZURhdGEsIGFjdGlvbnM6IGFueSkgPT4gT2JzZXJ2YWJsZTx2b2lkPjtcblxuICAgIC8qKlxuICAgICAqIENsaWVudCB0b2tlbnMgZm9yIGNsaWVudCBzaWRlIGludGVncmF0aW9uXG4gICAgICovXG4gICAgcHVibGljIGNsaWVudD86IElQYXlwYWxDbGllbnQ7XG5cbiAgICAvKipcbiAgICAgKiBBcnJheSBvZiB0cmFuc2FjdGlvbiwgcmVxdWlyZWQgZm9yIGNsaWVudCBzaWRlIGludGVncmF0aW9uXG4gICAgICovXG4gICAgcHVibGljIHRyYW5zYWN0aW9ucz86IElQYXlQYWxUcmFuc2FjdGlvbltdO1xuXG4gICAgLyoqXG4gICAgICogUGF5bWVudCBFeHBlcmllbmNlIGNvbmZpZ3VyYXRpb25zXG4gICAgICovXG4gICAgcHVibGljIGV4cGVyaWVuY2U/OiBJUGF5UGFsRXhwZXJpZW5jZTtcblxuICAgIC8qKlxuICAgICAqIENhbGxlZCBmb3IgY2xpZW50IHNpZGUgaW50ZWdyYXRpb24gd2hlbiBwYXltZW50IGlzIGV4ZWN1dGVkXG4gICAgICovXG4gICAgcHVibGljIG9uUGF5bWVudENvbXBsZXRlPzogKGRhdGE6IElQYXlQYWxQYXltZW50Q29tcGxldGVEYXRhLCBhY3Rpb25zOiBhbnkpID0+IHZvaWQ7XG5cbiAgICAvKipcbiAgICAgKiBCdXR0b24gY29uZmlndXJhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBidXR0b24/OiBJUGF5UGFsQnV0dG9uU3R5bGU7XG5cbiAgICAvKipcbiAgICAgKiBQYXlwYWwgZnVuZGluZyBjb25maWd1cmF0aW9uXG4gICAgICovXG4gICAgcHVibGljIGZ1bmRpbmc/OiBJUGF5UGFsRnVuZGluZztcblxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIFBheVBhbCBleHBlcmllbmNlcyBhbiBlcnJvclxuICAgICAqL1xuICAgIHB1YmxpYyBvbkVycm9yPzogKGVycjogYW55KSA9PiB2b2lkO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIGZvciBldmVyeSBjbGljayBvbiB0aGUgUGF5UGFsIGJ1dHRvblxuICAgICAqL1xuICAgIHB1YmxpYyBvbkNsaWNrPzogKCkgPT4gdm9pZDtcblxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIHVzZXIgY2FuY2VscyBwYXltZW50XG4gICAgICovXG4gICAgcHVibGljIG9uQ2FuY2VsPzogKGRhdGE6IElQYXlQYWxDYW5jZWxQYXltZW50LCBhY3Rpb25zOiBhbnkpID0+IHZvaWQ7XG5cbiAgICAvKipcbiAgICAgKiBDYW4gYmUgdXNlZCB0byB2YWxpZGF0aW9uIGFzIGNhbiBiZSBzZWVuIGhlcmU6IGh0dHBzOi8vZGV2ZWxvcGVyLnBheXBhbC5jb20vZGVtby9jaGVja291dC8jL3BhdHRlcm4vdmFsaWRhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyB2YWxpZGF0ZT86IChhY3Rpb25zOiBhbnkpID0+IHZvaWQ7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFR5cGUgb2YgdGhlIGludGVncmF0aW9uXG4gICAgICAgICAqL1xuICAgICAgICBwdWJsaWMgaW50ZWdyYXRpb25UeXBlOiBQYXlQYWxJbnRlZ3JhdGlvblR5cGUsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbnZpcm9ubWVudFxuICAgICAgICAgKi9cbiAgICAgICAgcHVibGljIGVudmlyb25tZW50OiBQYXlQYWxFbnZpcm9ubWVudCxcbiAgICAgICAgY29uZmlnOiB7XG4gICAgICAgICAgICBvbkVycm9yPzogKGVycjogYW55KSA9PiB2b2lkLFxuICAgICAgICAgICAgb25DbGljaz86ICgpID0+IHZvaWQsXG4gICAgICAgICAgICB2YWxpZGF0ZT86IChhY3Rpb25zOiBhbnkpID0+IHZvaWQ7XG4gICAgICAgICAgICBvbkNhbmNlbD86IChkYXRhOiBJUGF5UGFsQ2FuY2VsUGF5bWVudCwgYWN0aW9uczogYW55KSA9PiB2b2lkLFxuICAgICAgICAgICAgcGF5bWVudD86ICgpID0+IE9ic2VydmFibGU8c3RyaW5nPixcbiAgICAgICAgICAgIG9uQXV0aG9yaXplPzogKGRhdGE6IElQYXlQYWxQYXltZW50Q29tcGxldGVEYXRhLCBhY3Rpb25zOiBhbnkpID0+IE9ic2VydmFibGU8dm9pZD4sXG4gICAgICAgICAgICBjbGllbnQ/OiBJUGF5cGFsQ2xpZW50LFxuICAgICAgICAgICAgb25QYXltZW50Q29tcGxldGU/OiAoZGF0YTogSVBheVBhbFBheW1lbnRDb21wbGV0ZURhdGEsIGFjdGlvbnM6IGFueSkgPT4gdm9pZCxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9ucz86IElQYXlQYWxUcmFuc2FjdGlvbltdLFxuICAgICAgICAgICAgbm90ZV90b19wYXllcj86IHN0cmluZztcbiAgICAgICAgICAgIGV4cGVyaWVuY2U/OiBJUGF5UGFsRXhwZXJpZW5jZSxcbiAgICAgICAgICAgIGNvbW1pdD86IGJvb2xlYW4sXG4gICAgICAgICAgICBidXR0b24/OiBJUGF5UGFsQnV0dG9uU3R5bGUsXG4gICAgICAgICAgICBmdW5kaW5nPzogSVBheVBhbEZ1bmRpbmdcbiAgICAgICAgfSkge1xuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGNvbmZpZyk7XG4gICAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlQYWxQYXltZW50Q29tcGxldGVEYXRhIHtcbiAgICBpbnRlbnQ6IHN0cmluZztcbiAgICBvcmRlcklEOiBzdHJpbmc7XG4gICAgcGF5ZXJJRDogc3RyaW5nO1xuICAgIHBheW1lbnRJRDogc3RyaW5nO1xuICAgIHBheW1lbnRUb2tlbjogc3RyaW5nO1xuICAgIHJldHVyblVybDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlQYWxDYW5jZWxQYXltZW50IHtcbiAgICBkYXRhOiBJUGF5UGFsQ2FuY2VsUGF5bWVudERhdGE7XG4gICAgYWN0aW9uczogYW55O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlQYWxDYW5jZWxQYXltZW50RGF0YSB7XG4gICAgYmlsbGluZ0lEOiBzdHJpbmc7XG4gICAgY2FuY2VsVXJsOiBzdHJpbmc7XG4gICAgaW50ZW50OiBzdHJpbmc7XG4gICAgcGF5bWVudElEOiBzdHJpbmc7XG4gICAgcGF5bWVudFRva2VuOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBheXBhbENsaWVudCB7XG4gICAgc2FuZGJveD86IHN0cmluZztcbiAgICBwcm9kdWN0aW9uPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlQYWxUcmFuc2FjdGlvbiB7XG4gICAgYW1vdW50OiBJUGF5UGFsQW1vdW50O1xuICAgIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICAgIGN1c3RvbT86IHN0cmluZztcbiAgICBwYXltZW50X29wdGlvbnM/OiBJUGF5UGFsVHJhbnNhY3Rpb25QYXltZW50T3B0aW9ucztcbiAgICBpbnZvaWNlX251bWJlcj86IHN0cmluZztcbiAgICBzb2Z0X2Rlc2NyaXB0b3I/OiBzdHJpbmc7XG4gICAgaXRlbV9saXN0PzogSVBheVBhbFRyYW5zYWN0aW9uSXRlbUxpc3Q7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBheVBhbFRyYW5zYWN0aW9uSXRlbUxpc3Qge1xuICAgIGl0ZW1zPzogSVBheVBhbFRyYW5zYWN0aW9uSXRlbVtdO1xuICAgIHNoaXBwaW5nX2FkZHJlc3M/OiBJUGF5UGFsVHJhbnNhY3Rpb25TaGlwcGluZ0FkZHJlc3M7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBheVBhbFRyYW5zYWN0aW9uSXRlbSB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGN1cnJlbmN5OiBzdHJpbmc7XG4gICAgcHJpY2U6IG51bWJlcjtcbiAgICBxdWFudGl0eTogbnVtYmVyO1xuXG4gICAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gICAgdGF4PzogbnVtYmVyO1xuICAgIHNrdT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUGF5UGFsQW1vdW50IHtcbiAgICB0b3RhbDogbnVtYmVyO1xuICAgIGN1cnJlbmN5OiBzdHJpbmc7XG4gICAgZGV0YWlscz86IElQYXlQYWxBbW91bnREZXRhaWxzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElQYXlQYWxUcmFuc2FjdGlvblNoaXBwaW5nQWRkcmVzcyB7XG4gICAgcmVjaXBpZW50X25hbWU6IHN0cmluZztcbiAgICBsaW5lMTogc3RyaW5nO1xuICAgIGxpbmUyPzogc3RyaW5nO1xuICAgIGNpdHk6IHN0cmluZztcbiAgICBjb3VudHJ5X2NvZGU6IHN0cmluZztcbiAgICBwb3N0YWxfY29kZTogc3RyaW5nO1xuICAgIHBob25lOiBzdHJpbmc7XG4gICAgc3RhdGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUGF5UGFsQW1vdW50RGV0YWlscyB7XG4gICAgc3VidG90YWw6IG51bWJlcjtcbiAgICB0YXg6IG51bWJlcjtcbiAgICBzaGlwcGluZzogbnVtYmVyO1xuICAgIGhhbmRsaW5nX2ZlZTogbnVtYmVyO1xuICAgIHNoaXBwaW5nX2Rpc2NvdW50OiBudW1iZXI7XG4gICAgaW5zdXJhbmNlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBheVBhbFRyYW5zYWN0aW9uUGF5bWVudE9wdGlvbnMge1xuICAgIGFsbG93ZWRfcGF5bWVudF9tZXRob2Q/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBheVBhbEV4cGVyaWVuY2Uge1xuICAgIC8qKiBJbmRpY2F0ZXMgd2hldGhlciBQYXlQYWwgZGlzcGxheXMgc2hpcHBpbmcgYWRkcmVzcyBmaWVsZHMgb24gdGhlIGV4cGVyaWVuY2UgcGFnZXMgKi9cbiAgICBub1NoaXBwaW5nPzogYm9vbGVhbjtcbiAgICAvKiogQSBsYWJlbCB0aGF0IG92ZXJyaWRlcyB0aGUgYnVzaW5lc3MgbmFtZSBpbiB0aGUgUGF5UGFsIGFjY291bnQgb24gdGhlIFBheVBhbCBwYWdlcy4gTWF4IGxlbmd0aDogMTI3IGNoYXJhY3RlcnMuICovXG4gICAgYnJhbmROYW1lPzogc3RyaW5nO1xuICAgIC8qKiBVUkwgdG8gdGhlIGxvZ28gaW1hZ2UgKGdpZiwganBnLCBvciBwbmcpLiBUaGUgaW1hZ2UncyBtYXhpbXVtIHdpZHRoIGlzIDE5MCBwaXhlbHMgYW5kIG1heGltdW0gaGVpZ2h0IGlzIDYwIHBpeGVscy4gKi9cbiAgICBsb2dvSW1hZ2U/OiBzdHJpbmc7XG4gICAgLyoqIExvY2FsZSBpbiB3aGljaCB0byBkaXNwbGF5IFBheVBhbCBwYWdlICovXG4gICAgbG9jYWxlQ29kZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUGF5UGFsQnV0dG9uU3R5bGUge1xuICAgIGxhYmVsPzogJ2NoZWNrb3V0JyB8ICdwYXknIHwgJ2J1eW5vdycgfCAncGF5cGFsJztcbiAgICBzaXplPzogJ3NtYWxsJyB8ICdtZWRpdW0nIHwgJ2xhcmdlJyB8ICdyZXNwb25zaXZlJztcbiAgICBzaGFwZT86ICdwaWxsJyB8ICdyZWN0JztcbiAgICBjb2xvcj86ICdnb2xkJyB8ICdibHVlJyB8ICdzaWx2ZXInIHwgJ2JsYWNrJztcbiAgICBsYXlvdXQ/OiAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnO1xuICAgIHRhZ2xpbmU/OiBmYWxzZTtcbiAgICBmdW5kaW5naWNvbnM/OiBib29sZWFuO1xuICAgIGJyYW5kaW5nPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUGF5UGFsRnVuZGluZyB7XG4gICAgYWxsb3dlZDogUGF5UGFsRnVuZGluZ1tdO1xuICAgIGRpc2FsbG93ZWQ6IFBheVBhbEZ1bmRpbmdbXTtcbn1cblxuIiwiaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgU2ltcGxlQ2hhbmdlcyxcbiAgICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgaW50ZXJ2YWwsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBQYXlQYWxGdW5kaW5nIH0gZnJvbSAnLi4vbW9kZWxzL3BheXBhbC1mdW5kaW5nJztcbmltcG9ydCB7IFBheVBhbEludGVncmF0aW9uVHlwZSB9IGZyb20gJy4uL21vZGVscy9wYXlwYWwtaW50ZWdyYXRpb24nO1xuaW1wb3J0IHsgSVBheXBhbENsaWVudCwgSVBheVBhbFBheW1lbnRDb21wbGV0ZURhdGEsIFBheVBhbENvbmZpZyB9IGZyb20gJy4uL21vZGVscy9wYXlwYWwtbW9kZWxzJztcblxuLyoqXG4gKiBHbG9iYWwgdmFyaWFibGUgd2hlcmUgUGF5UGFsIGlzIGxvYWRlZCB0b1xuICovXG5kZWNsYXJlIHZhciBwYXlwYWw6IGFueTtcblxuQENvbXBvbmVudCh7XG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgc2VsZWN0b3I6ICduZ3gtcGF5cGFsJyxcbiAgICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgI3BheVBhbFNjcmlwdEVsZW0+PC9kaXY+XG4gICAgPGRpdiAjcGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbSBbaWRdPVwicGF5UGFsQnV0dG9uQ29udGFpbmVySWRcIj48L2Rpdj5cbiAgICBgXG59KVxuZXhwb3J0IGNsYXNzIE5neFBheXBhbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICAgIC8qKlxuICAgICAqIENvbmZpZ3VyYXRpb24gZm9yIHBheXBhbC5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBjb25maWc6IFBheVBhbENvbmZpZztcblxuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyBpZiBnbG9iYWwgY29uZmlndXJhdGlvbiAocHJvdmlkZWQgdmlhICdmb3JSb290JykgaXMgdXNlZFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHVzZUdsb2JhbENvbmZpZyA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQ29udGFpbmVyIGZvciBwYXlwYWwgc2NyaXB0XG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgncGF5UGFsU2NyaXB0RWxlbScpIHBheXBhbFNjcmlwdEVsZW06IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGZvciBpbmRpY2F0aW5nIGRlbGF5ZWQgcmVuZGVyZWQgaWYgY29udGFpbmVyIGlzIG5vdCB5ZXQgcmVhZHkgaW4gRE9NXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWdpc3RlclBheVBhbFNjcmlwdFdoZW5Db250YWluZXJJc1JlYWR5ID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBIb2xkcyBjdXJyZW50IGNvbnRhaW5lciBlbGVtZW50XG4gICAgICovXG4gICAgcHJpdmF0ZSBfcGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbT86IEVsZW1lbnRSZWY7XG4gICAgQFZpZXdDaGlsZCgncGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbScpIHNldCBwYXlQYWxCdXR0b25Db250YWluZXJFbGVtKGNvbnRlbnQ6IEVsZW1lbnRSZWYpIHtcbiAgICAgICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3BheVBhbEJ1dHRvbkNvbnRhaW5lckVsZW0gPSBjb250ZW50O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUG9sbGluZyBpbnRlcnZhbCBpZiBwYXlwYWwgc2NyaXB0IGlzIHBlbmRpbmdcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRQb2xsSW50ZXJ2YWwgPSA1MDtcblxuICAgIC8qKlxuICAgICAqIFBvbGxpbmcgd2lsbCBzdG9wIGFmdGVyIHBvbGxpbmcgcmVhY2hlcyB0aGlzIG51bWJlclxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbWF4aW11bVBvbGxXYWl0VGltZSA9IDUwMDA7XG5cbiAgICAvKipcbiAgICAqIE5hbWUgb2YgdGhlIGdsb2JhbCB2YXJpYWJsZSB3aGVyZSBwYXlwYWwgaXMgc3RvcmVkXG4gICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IHBheXBhbFdpbmRvd05hbWUgPSAncGF5cGFsJztcblxuICAgIC8qKlxuICAgICAqIE5hbWUgb2YgdGhlIGdsb2JhbCB2YXJpYWJsZSBpbmRpY2F0aW5nIHRoYXQgc2NyaXB0IHdhcyBpbml0aWF0ZWQgKGFkZGVkIHRvIHBhZ2UpXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBwYXlwYWxXaW5kb3dTY3JpcHRJbml0aWF0ZWQgPSAnbmd4LXBheXBhbC1zY3JpcHQtaW5pdGlhdGVkJztcblxuICAgIC8qKlxuICAgICAqIFBheVBhbCBpbnRlZ3JhdGlvbiBzY3JpcHQgdXJsXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBwYXlwYWxTY3JpcHRVcmwgPSAnaHR0cHM6Ly93d3cucGF5cGFsb2JqZWN0cy5jb20vYXBpL2NoZWNrb3V0LmpzJztcblxuICAgIC8qKlxuICAgICAqIElkIG9mIHRoZSBlbGVtZW50IHdoZXJlIFBheVBhbCBidXR0b24gd2lsbCBiZSByZW5kZXJlZFxuICAgICAqL1xuICAgIHB1YmxpYyBwYXlQYWxCdXR0b25Db250YWluZXJJZD86IHN0cmluZztcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgcGF5UGFsQnV0dG9uQ29udGFpbmVySWRQcmVmaXggPSAnbmd4LXBheXBhbC1idXR0b24tY29udGFpbmVyLSc7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IG5nVW5zdWJzY3JpYmU6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgKSB7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgICAgICAvLyBpbml0IHdoZW4gY29uZmlnIG9uY2UgaXRzIGF2YWlsYWJsZVxuICAgICAgICBpZiAodGhpcy5jb25maWcpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFBheVBhbCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICAvLyByZWdpc3RlciBzY3JpcHQgaWYgZWxlbWVudCBpcyByZWFkeSBpbiBkb21cbiAgICAgICAgaWYgKHRoaXMucmVnaXN0ZXJQYXlQYWxTY3JpcHRXaGVuQ29udGFpbmVySXNSZWFkeSAmJiB0aGlzLl9wYXlQYWxCdXR0b25Db250YWluZXJFbGVtKSB7XG4gICAgICAgICAgICB0aGlzLnNldHVwU2NyaXB0KCk7XG4gICAgICAgICAgICB0aGlzLnJlZ2lzdGVyUGF5UGFsU2NyaXB0V2hlbkNvbnRhaW5lcklzUmVhZHkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLm5nVW5zdWJzY3JpYmUubmV4dCgpO1xuICAgICAgICB0aGlzLm5nVW5zdWJzY3JpYmUuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRQYXlQYWwoKTogdm9pZCB7XG4gICAgICAgIC8vIHNldCB1bmlxdWUgcGF5cGFsIGNvbnRhaW5lciBidXR0b24gaWRcbiAgICAgICAgdGhpcy5wYXlQYWxCdXR0b25Db250YWluZXJJZCA9IGAke3RoaXMucGF5UGFsQnV0dG9uQ29udGFpbmVySWRQcmVmaXh9JHt0aGlzLmdldFBzZXVkb1VuaXF1ZU51bWJlcigpfWA7XG4gICAgICAgIC8vIGNoZWNrIGlmIHBheXBhbCB3YXMgYWxyZWFkeSByZWdpc3RlciBhbmQgaWYgc28sIGRvbid0IGFkZCBpdCB0byBwYWdlIGFnYWluXG4gICAgICAgIGlmICghd2luZG93W3RoaXMucGF5cGFsV2luZG93TmFtZV0pIHtcbiAgICAgICAgICAgIC8vIGNoZWNrIGlmIHNjcmlwdCBpcyBwZW5kaW5nXG4gICAgICAgICAgICBpZiAod2luZG93W3RoaXMucGF5cGFsV2luZG93U2NyaXB0SW5pdGlhdGVkXSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMucG9sbFVudGlsU2NyaXB0QXZhaWxhYmxlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIHJlZ2lzdGVyIHNjcmlwdCBhbmQgc2V0IGdsb2JhbCBmbGFnXG4gICAgICAgICAgICAgICAgd2luZG93W3RoaXMucGF5cGFsV2luZG93U2NyaXB0SW5pdGlhdGVkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRQYXlQYWxTY3JpcHRUb1BhZ2UoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8ganVzdCByZWdpc3RlciBwYXltZW50XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVNjcmlwdFJlZ2lzdGVyaW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFBzZXVkb1VuaXF1ZU51bWJlcigpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gbmV3IERhdGUoKS52YWx1ZU9mKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCB3aGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBwYXlwYWwgY29tcG9uZW50cyBvbiB0aGUgc2FtZSBwYWdlIGJlYWN1c2Ugb25seSAxIG9mIHRoZW1cbiAgICAgKiBtYXkgcmVnaXN0ZXIgcGF5cGFsIHNjcmlwdC4gVGhlIG90aGVyIGhhcyB0byBiZSBwb2xsaW5nIHVudGlsIHBheXBhbCBpcyBhdmFpbGFibGUgb3IgY29tcG9uZW50IGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHByaXZhdGUgcG9sbFVudGlsU2NyaXB0QXZhaWxhYmxlKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBvYnMgPSBpbnRlcnZhbCh0aGlzLmRlZmF1bHRQb2xsSW50ZXJ2YWwpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICB0YWtlVW50aWwodGhpcy5uZ1Vuc3Vic2NyaWJlKSxcbiAgICAgICAgICAgICAgICBtYXAoKHgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHggPj0gdGhpcy5tYXhpbXVtUG9sbFdhaXRUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFBheVBhbCBzY3JpcHQgd2FzIG5vdCBsb2FkZWQgYWZ0ZXIgJyR7dGhpcy5tYXhpbXVtUG9sbFdhaXRUaW1lfScgbWF4aW11bSBwb2xsaW5nIHRpbWUuYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBvYnMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHBheXBhbCBzY3JpcHQgZXhpc3RzXG4gICAgICAgICAgICAgICAgICAgIGlmICh3aW5kb3dbdGhpcy5wYXlwYWxXaW5kb3dOYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVnaXN0ZXIgc2NyaXB0XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZVNjcmlwdFJlZ2lzdGVyaW5nKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0b3AgZXhlY3V0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhZGRQYXlQYWxTY3JpcHRUb1BhZ2UoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICBzY3JpcHQuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgIHNjcmlwdC5zcmMgPSB0aGlzLnBheXBhbFNjcmlwdFVybDtcbiAgICAgICAgc2NyaXB0Lm9ubG9hZCA9ICgpID0+IHRoaXMuaGFuZGxlU2NyaXB0UmVnaXN0ZXJpbmcoKTtcbiAgICAgICAgc2NyaXB0LmFzeW5jID0gdHJ1ZTtcbiAgICAgICAgc2NyaXB0LmRlZmVyID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLnBheXBhbFNjcmlwdEVsZW0ubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlU2NyaXB0UmVnaXN0ZXJpbmcoKTogdm9pZCB7XG4gICAgICAgIC8vIGNoZWNrIGlmIGNvbnRhaW5lciB3aXRoIHJlcXVlc3RlZCBpZCBleGlzdHNcbiAgICAgICAgLy8gdGhpcyBpcyBoZXJlIGJlY2F1c2UgZHluYW1pY2FsbHkgc3dpdGNoaW5nIGJldHdlZW4gY29tcG9uZW50cyB3b3VsZCBjYXVzZSBQYXlQYWwgdG9cbiAgICAgICAgLy8gdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGNvbnRhaW5lciBhbHJlYWR5IGV4aXN0ZWQgYmVmb3JlXG4gICAgICAgIGlmICh0aGlzLl9wYXlQYWxCdXR0b25Db250YWluZXJFbGVtICYmIHRoaXMuX3BheVBhbEJ1dHRvbkNvbnRhaW5lckVsZW0ubmF0aXZlRWxlbWVudCAmJlxuICAgICAgICAgICAgdGhpcy5fcGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbS5uYXRpdmVFbGVtZW50LmlkID09PSB0aGlzLnBheVBhbEJ1dHRvbkNvbnRhaW5lcklkKSB7XG4gICAgICAgICAgICAvLyBjb250YWluZXIgaXMgcmVhZHksIHNldHVwIHNjcmlwdCByaWdodCBhd2F5XG4gICAgICAgICAgICB0aGlzLnNldHVwU2NyaXB0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBjb250YWluZXIgaXMgbm90IHJlYWR5LCBkZWxheSByZWdpc3RlcmluZyB1bnRpbCBpdCBpc1xuICAgICAgICAgICAgdGhpcy5yZWdpc3RlclBheVBhbFNjcmlwdFdoZW5Db250YWluZXJJc1JlYWR5ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2V0dXBTY3JpcHQoKTogdm9pZCB7XG4gICAgICAgIC8vIGZpcnN0IGNsZWFyIGNvbnRhaW5lclxuICAgICAgICBpZiAoIXRoaXMuX3BheVBhbEJ1dHRvbkNvbnRhaW5lckVsZW0pIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKGBDYW5ub3Qgc2V0dXAgc2NyaXB0IGJlY2F1c2UgcGF5cGFsIGJ1dHRvbiBjb250YWluZXIgd2l0aCBpZCAnJHt0aGlzLnBheVBhbEJ1dHRvbkNvbnRhaW5lcklkfScgaXMgbm90IHlldCByZWFkeWApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcGF5UGFsQnV0dG9uQ29udGFpbmVyRWxlbS5uYXRpdmVFbGVtZW50LmlubmVySFRNTCA9ICcnO1xuXG4gICAgICAgIGlmICghd2luZG93W3RoaXMucGF5cGFsV2luZG93TmFtZV0pIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdQYXlQYWwgc2NyaXB0IGlzIG5vdCBhdmFpbGFibGUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlbmRlciBQYXlQYWwgYnV0dG9uIGFzIHBlciB0aGVpciBkb2NzIGF0XG4gICAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLnBheXBhbC5jb20vZG9jcy9pbnRlZ3JhdGlvbi9kaXJlY3QvZXhwcmVzcy1jaGVja291dC9pbnRlZ3JhdGlvbi1qc3Y0L2FkZC1wYXlwYWwtYnV0dG9uL1xuICAgICAgICB3aW5kb3dbdGhpcy5wYXlwYWxXaW5kb3dOYW1lXS5CdXR0b24ucmVuZGVyKHtcbiAgICAgICAgICAgIC8vIHNldCBlbnZpcm9ubWVudFxuICAgICAgICAgICAgZW52OiB0aGlzLmNvbmZpZy5lbnZpcm9ubWVudC50b1N0cmluZygpLFxuXG4gICAgICAgICAgICAvLyBTaG93IHRoZSBidXllciBhICdQYXkgTm93JyBidXR0b24gaW4gdGhlIGNoZWNrb3V0IGZsb3dcbiAgICAgICAgICAgIGNvbW1pdDogdGhpcy5jb25maWcuY29tbWl0LFxuXG4gICAgICAgICAgICAvLyBpbml0IGNsaWVudCBmb3IgY2xpZW50IHNpZGUgaW50ZWdyYXRpb25cbiAgICAgICAgICAgIGNsaWVudDogdGhpcy5nZXRDbGllbnQoKSxcblxuICAgICAgICAgICAgLy8gc2V0IGJ1dHRvbiBjb25maWcgaWYgYXZhaWxhYmxlXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuYnV0dG9uLFxuXG4gICAgICAgICAgICAvLyBzZXQgZnVuZGluZyBpZiBhdmFpbGFibGVcbiAgICAgICAgICAgIGZ1bmRpbmc6IHRoaXMuZ2V0RnVuZGluZygpLFxuXG4gICAgICAgICAgICAvLyBwYXltZW50KCkgaXMgY2FsbGVkIHdoZW4gdGhlIGJ1dHRvbiBpcyBjbGlja2VkXG4gICAgICAgICAgICBwYXltZW50OiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5pbnRlZ3JhdGlvblR5cGUgPT09IFBheVBhbEludGVncmF0aW9uVHlwZS5TZXJ2ZXJTaWRlUkVTVCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBjbGllbnQgbmVlZHMgdG8gY3JlYXRlIHBheW1lbnQgb24gc2VydmVyIHNpZGVcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5wYXltZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgWW91IG5lZWQgc2V0IHVwIGEgY3JlYXRlIHBheW1lbnQgbWV0aG9kIGFuZCByZXR1cm5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXlQYWwncyBwYXltZW50IGlkIHdoZW4gdXNpbmcgc2VydmVyIHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFBheXBhbCBleHBlY3RzIHByb21pc2Ugd2l0aCBwYXltZW50IGlkIChzdHJpbmcpIHRvIGJlIHJldHVybmVkXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5wYXltZW50KCkudG9Qcm9taXNlKClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHBheW1lbnRJZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBheW1lbnRJZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5pbnRlZ3JhdGlvblR5cGUgPT09IFBheVBhbEludGVncmF0aW9uVHlwZS5DbGllbnRTaWRlUkVTVCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnRyYW5zYWN0aW9ucyB8fCAhQXJyYXkuaXNBcnJheSh0aGlzLmNvbmZpZy50cmFuc2FjdGlvbnMpIHx8IHRoaXMuY29uZmlnLnRyYW5zYWN0aW9ucy5sZW5ndGggPD0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoYFlvdSBuZWVkIHRvIHByb3ZpZGUgYXQgbGVhc3QgMSB0cmFuc2FjdGlvbiBmb3IgY2xpZW50IHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cGVyaWVuY2VDb25maWcgPSB0aGlzLmNvbmZpZy5leHBlcmllbmNlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5wYXltZW50LmNyZWF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBbGxvdyB1c2VyIHRvIHNwZWNpZmlmeSBpbnRlbnQsIGVsc2UgdXNlIGRlZmF1bHQgJ3NhbGUnLlxuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZW50OiB0aGlzLmNvbmZpZy5pbnRlbnQgPyB0aGlzLmNvbmZpZy5pbnRlbnQgOiAnc2FsZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXltZW50OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25zOiB0aGlzLmNvbmZpZy50cmFuc2FjdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlcmllbmNlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRfZmllbGRzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vX3NoaXBwaW5nOiAoZXhwZXJpZW5jZUNvbmZpZyAmJiBleHBlcmllbmNlQ29uZmlnLm5vU2hpcHBpbmcpID8gMSA6IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlbnRhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmFuZF9uYW1lOiAoZXhwZXJpZW5jZUNvbmZpZyAmJiBleHBlcmllbmNlQ29uZmlnLmJyYW5kTmFtZSkgPyBleHBlcmllbmNlQ29uZmlnLmJyYW5kTmFtZSA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ29faW1hZ2U6IChleHBlcmllbmNlQ29uZmlnICYmIGV4cGVyaWVuY2VDb25maWcubG9nb0ltYWdlKSA/IGV4cGVyaWVuY2VDb25maWcubG9nb0ltYWdlIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlX2NvZGU6IChleHBlcmllbmNlQ29uZmlnICYmIGV4cGVyaWVuY2VDb25maWcubG9jYWxlQ29kZSkgPyBleHBlcmllbmNlQ29uZmlnLmxvY2FsZUNvZGUgOiBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvLyBvbkF1dGhvcml6ZSgpIGlzIGNhbGxlZCB3aGVuIHRoZSBidXllciBhcHByb3ZlcyB0aGUgcGF5bWVudFxuICAgICAgICAgICAgb25BdXRob3JpemU6IChkYXRhOiBJUGF5UGFsUGF5bWVudENvbXBsZXRlRGF0YSwgYWN0aW9uczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLmludGVncmF0aW9uVHlwZSA9PT0gUGF5UGFsSW50ZWdyYXRpb25UeXBlLlNlcnZlclNpZGVSRVNUKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNsaWVudCBuZWVkcyB0byBzZXJ2ZXIgdG8gZXhlY3V0ZSB0aGUgcGF5bWVudFxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLm9uQXV0aG9yaXplKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgWW91IG5lZWQgc2V0IHVwIGFuIGV4ZWN1dGUgbWV0aG9kIHdoZW4gdXNpbmcgc2VydmVyIHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFBheXBhbCBleHBlY3RzIHByb21pc2VcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLm9uQXV0aG9yaXplKGRhdGEsIGFjdGlvbnMpLnRvUHJvbWlzZSgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5pbnRlZ3JhdGlvblR5cGUgPT09IFBheVBhbEludGVncmF0aW9uVHlwZS5DbGllbnRTaWRlUkVTVCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIGEgY2FsbCB0byB0aGUgUkVTVCBhcGkgdG8gZXhlY3V0ZSB0aGUgcGF5bWVudFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5wYXltZW50LmV4ZWN1dGUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5jb25maWcub25QYXltZW50Q29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgWW91IHNob3VsZCBwcm92aWRlIHNvbWUgY2FsbGJhY2sgd2hlbiBwYXltZW50IGlzIGZpbmlzaGVkIHdoZW4gdXNpbmcgY2xpZW50IHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLm9uUGF5bWVudENvbXBsZXRlKGRhdGEsIGFjdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLm9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcub25FcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIG9uQ2FuY2VsOiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5vbkNhbmNlbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5vbkNhbmNlbChkYXRhLCBhY3Rpb25zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb25DbGljazogKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5vbkNsaWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLm9uQ2xpY2soKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmFsaWRhdGU6IChhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLnZhbGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLnZhbGlkYXRlKGFjdGlvbnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgYCMke3RoaXMucGF5UGFsQnV0dG9uQ29udGFpbmVySWR9YCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRDbGllbnQoKTogSVBheXBhbENsaWVudCB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5pbnRlZ3JhdGlvblR5cGUgPT09IFBheVBhbEludGVncmF0aW9uVHlwZS5DbGllbnRTaWRlUkVTVCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5jbGllbnQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgWW91IG5lZWQgdG8gc2V0dXAgY2xpZW50IGluZm9ybWF0aW9uIHdoZW4gdXNpbmcgY2xpZW50IHNpZGUgaW50ZWdyYXRpb25gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBwcm9kdWN0aW9uOiB0aGlzLmNvbmZpZy5jbGllbnQucHJvZHVjdGlvbixcbiAgICAgICAgICAgICAgICBzYW5kYm94OiB0aGlzLmNvbmZpZy5jbGllbnQuc2FuZGJveFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRGdW5kaW5nKCk6IHtcbiAgICAgICAgYWxsb3dlZDogYW55W10sXG4gICAgICAgIGRpc2FsbG93ZWQ6IGFueVtdXG4gICAgfSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIC8vIHJlc29sdmUgZnVuZGluZyB0byB1c2UgcGF5cGFsJ3MgcHJvcGVydGllc1xuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLmZ1bmRpbmcpIHtcbiAgICAgICAgICAgIC8vIG5vIGZ1bmRpbmcgcHJvdmlkZWRcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhbGxvd2VkOiBhbnlbXSA9IFtdO1xuICAgICAgICBjb25zdCBkaXNhbGxvd2VkOiBhbnlbXSA9IFtdO1xuXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5mdW5kaW5nLmFsbG93ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmZ1bmRpbmcuYWxsb3dlZC5mb3JFYWNoKHR5cGUgPT4ge1xuICAgICAgICAgICAgICAgIGFsbG93ZWQucHVzaCh0aGlzLm1hcEZ1bmRpbmdUeXBlKHR5cGUpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmZ1bmRpbmcuZGlzYWxsb3dlZCkge1xuICAgICAgICAgICAgdGhpcy5jb25maWcuZnVuZGluZy5kaXNhbGxvd2VkLmZvckVhY2godHlwZSA9PiB7XG4gICAgICAgICAgICAgICAgZGlzYWxsb3dlZC5wdXNoKHRoaXMubWFwRnVuZGluZ1R5cGUodHlwZSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYWxsb3dlZDogYWxsb3dlZCxcbiAgICAgICAgICAgIGRpc2FsbG93ZWQ6IGRpc2FsbG93ZWRcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG1hcEZ1bmRpbmdUeXBlKHR5cGU6IFBheVBhbEZ1bmRpbmcpOiBhbnkge1xuICAgICAgICBpZiAodHlwZSA9PT0gUGF5UGFsRnVuZGluZy5DYXJkKSB7XG4gICAgICAgICAgICByZXR1cm4gcGF5cGFsLkZVTkRJTkcuQ0FSRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gUGF5UGFsRnVuZGluZy5DcmVkaXQpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXlwYWwuRlVORElORy5DUkVESVQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09IFBheVBhbEZ1bmRpbmcuRWx2KSB7XG4gICAgICAgICAgICByZXR1cm4gcGF5cGFsLkZVTkRJTkcuRUxWO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IEVycm9yKGBVbnN1cHBvcnRlZCBmdW5kaW5nIHR5cGUgJyR7dHlwZX0nYCk7XG4gICAgfVxufVxuXG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBOZ3hQYXlwYWxDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvcGF5cGFsLWNvbXBvbmVudCc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgXSxcbiAgZGVjbGFyYXRpb25zOiBbXG4gICAgTmd4UGF5cGFsQ29tcG9uZW50LFxuICBdLFxuICBleHBvcnRzOiBbXG4gICAgTmd4UGF5cGFsQ29tcG9uZW50LFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIE5neFBheVBhbE1vZHVsZSB7XG59XG5cblxuIiwiZXhwb3J0IGVudW0gUGF5UGFsRW52aXJvbm1lbnQge1xuICAgIFNhbmRib3ggPSAnc2FuZGJveCcsXG4gICAgUHJvZHVjdGlvbiA9ICdwcm9kdWN0aW9uJ1xufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7SUFDSSxPQUFJO0lBQ0osU0FBTTtJQUNOLE1BQUc7Ozs7Ozs7Ozs7OztJQ0ZILGlCQUFjO0lBQ2QsaUJBQWM7Ozs7Ozs7OztBQ0lsQjtJ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