UNPKG

@uex/web-extensions

Version:

Uex extensions for Angular 6+ web projects

620 lines 54.2 kB
/** * @fileoverview added by tsickle * Generated from: lib/modules/generic/base/model.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { HttpHeaders, HttpParams, HttpRequest, HttpEventType } from '@angular/common/http'; import * as _ from 'lodash'; import { timeout } from 'rxjs/operators'; /** * @abstract */ export class BaseModel { /** * @param {?} _http * @param {?} _toastService */ constructor(_http, _toastService) { this._http = _http; this._toastService = _toastService; this.path = ''; this.timeout = 30000; } /** * @param {?} resource_params * @return {?} */ buildResource(resource_params) { // Define os valores padrão para o ResourceParams resource_params = this._setResourceParamsDefaults(resource_params); // Declara o Resource que será retornado /** @type {?} */ const resource = (/** * @param {?=} request_params * @return {?} */ (request_params = {}) => { /** @type {?} */ let request; /** @type {?} */ let request_subscription; /** @type {?} */ let reject_promise; /** @type {?} */ const resource_path = this.getPath(resource_params); // Inicializa o cacheamento para essa requisição if (resource_params.method != RequestMethod.Get) { resource_params.cache = null; } /** @type {?} */ const child_name = _.snakeCase(this.constructor.name.replace('Model', '')); /** @type {?} */ const schema_name = resource_params.cache ? `${child_name}_${resource_params.cache.name}` : null; /** @type {?} */ const logout_on_unauthorized = this._getLogoutOnUnauthorized(resource_params, request_params); /** @type {?} */ const cache_info = { enabled: resource_params.cache ? true : false, replace: true, name: schema_name, params: request_params }; // Restorna uma Promise /** @type {?} */ const promise = new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { reject_promise = reject; /** @type {?} */ const request_url = this.url + this.parseResourcePath(resource_path, request_params); /** @type {?} */ const request_options = this.getOptions(resource_params, request_params); /** @type {?} */ const request_timeout = resource_params.timeout ? resource_params.timeout : this.timeout; /** @type {?} */ const has_body = this._hasBody(resource_params.method); if (has_body) { /** @type {?} */ const request_body = request_options.params; request_options.params = null; request = new HttpRequest(resource_params.method, request_url, request_body, request_options); } else { request = new HttpRequest(resource_params.method, request_url, request_options); } request_subscription = this._http.request(request) .pipe(timeout(request_timeout)) .subscribe((/** * @param {?} response * @return {?} */ (response) => { if (response.type == HttpEventType.Response) { resolve(this._handleSuccess(response, cache_info, resource_params.responseInterceptor)); } }), (/** * @param {?} err * @return {?} */ (err) => reject(this._handleError(err, cache_info, logout_on_unauthorized, resource_params.responseInterceptor)))); })); /** @type {?} */ const response = { then: (/** * @param {?} on_success * @param {?=} on_error * @return {?} */ (on_success, on_error) => { promise.then(on_success, on_error); return response; }), catch: (/** * @param {?} on_error * @return {?} */ (on_error) => { promise.catch(on_error); return response; }), finally: (/** * @param {?} on_finally * @return {?} */ (on_finally) => { promise.then(on_finally, on_finally); return response; }), abort: (/** * @return {?} */ () => { if (request_subscription && !request_subscription.closed) { request_subscription.unsubscribe(); reject_promise(this._handleError({ name: 'Cancelled' }, cache_info, logout_on_unauthorized, resource_params.responseInterceptor)); } }) }; return response; }); return resource; } /** * @param {?} resource_params * @return {?} */ getPath(resource_params) { /** @type {?} */ const _path = `${this.path ? this.path : ''}${resource_params.path ? resource_params.path : ''}`; /** @type {?} */ const _keys = _path ? _path.match(/\{([^\{\}]*)\}/g) : []; /** @type {?} */ const resource_path = { template: _path ? _path : '', keys: _keys ? _keys : [] }; resource_path.keys.forEach((/** * @param {?} key * @param {?} index * @return {?} */ (key, index) => { resource_path.template = resource_path.template.replace(key, '{$' + (index + 1) + '}'); resource_path.keys[index] = key.replace(/[\{\}]/g, ''); })); return resource_path; } /** * @param {?} resource_path * @param {?} request_params * @return {?} */ parseResourcePath(resource_path, request_params) { /** @type {?} */ let path = resource_path.template; resource_path.keys.forEach((/** * @param {?} key * @param {?} index * @return {?} */ (key, index) => { /** @type {?} */ const is_optional = key[0] == '?' || key[1] == '?'; /** @type {?} */ const ignore_from_payload = key[0] == '!' || key[1] == '!'; /** @type {?} */ const clean_key = (is_optional || ignore_from_payload) ? key.replace(/[\?\!]/g, '') : key; /** @type {?} */ const value = this._findParamsKey(request_params, clean_key.split('.'), ignore_from_payload); /** @type {?} */ const path_key = (value == '' && is_optional && path.indexOf('/{$' + (index + 1) + '}') > -1) ? '/{$' + (index + 1) + '}' : '{$' + (index + 1) + '}'; path = path.replace(path_key, value); })); return path; } /** * @param {?} headers * @param {?} resource_params * @param {?} request_params * @return {?} */ headerInterceptor(headers, resource_params, request_params) { return headers; } /** * @return {?} */ clearSession() { } /** * @private * @param {?} resource_params * @param {?} request_params * @return {?} */ getOptions(resource_params, request_params) { /** @type {?} */ const request_options = { headers: this._getHeaders(resource_params, request_params), params: (/** @type {?} */ (this._getParams(resource_params, request_params))), withCredentials: resource_params.withCredentials, responseType: 'json', reportProgress: false }; if (_.isFunction(resource_params.requestInterceptor)) { return resource_params.requestInterceptor(request_options); } return request_options; } /** * @private * @param {?} resource_params * @param {?} request_params * @return {?} */ _getHeaders(resource_params, request_params) { /** @type {?} */ const headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }; if (_.isFunction(this.headerInterceptor)) { return new HttpHeaders(this.headerInterceptor(headers, resource_params, request_params)); } return new HttpHeaders(headers); } /** * @private * @param {?} resource_params * @param {?} request_params * @return {?} */ _getLogoutOnUnauthorized(resource_params, request_params) { /** @type {?} */ let logout_on_unauthorized = true; if (!_.isEmpty(resource_params) && _.isBoolean(resource_params.logoutOnUnauthorized)) { logout_on_unauthorized = resource_params.logoutOnUnauthorized; } else if (!_.isEmpty(request_params) && _.isBoolean(request_params.logoutOnUnauthorized)) { logout_on_unauthorized = request_params.logoutOnUnauthorized; } return logout_on_unauthorized; } /** * @private * @param {?} resource_params * @param {?} request_params * @return {?} */ _getParams(resource_params, request_params) { if (this._hasBody(resource_params.method)) { return request_params; } else { /** @type {?} */ const params = {}; this._setParams(params, request_params); /** @type {?} */ const http_params = new HttpParams({ fromObject: params }); return http_params; } } /** * @private * @param {?} method * @return {?} */ _hasBody(method) { return ['POST', 'PUT', 'PATCH'].indexOf(method) > -1; } /** * @private * @param {?} params * @param {?} request_params * @param {?=} prefix * @return {?} */ _setParams(params, request_params, prefix) { /** @type {?} */ let count = 0; if (_.isPlainObject(request_params)) { _.each(request_params, (/** * @param {?} item * @param {?} key * @return {?} */ (item, key) => { if (_.isEmpty(item) && !_.isBoolean(item) && !_.isNumber(item)) { return; } /** @type {?} */ const param_prefix = prefix ? `${prefix}[${key}]` : key; if (_.isPlainObject(item) || _.isArray(item)) { if (this._setParams(params, item, param_prefix)) { count++; } } else { params[param_prefix] = item; count++; } })); } else if (_.isArray(request_params) && prefix) { /** @type {?} */ let index = 0; request_params.forEach((/** * @param {?} item * @return {?} */ (item) => { if (_.isEmpty(item) && !_.isBoolean(item) && !_.isNumber(item)) { return; } /** @type {?} */ const param_prefix = `${prefix}[${index}]`; if (_.isPlainObject(item) || _.isArray(item)) { if (this._setParams(params, item, param_prefix)) { count++; return; } } else { params[param_prefix] = item; count++; } index++; })); } return count > 0; } /** * @private * @param {?} params * @param {?} key_arr * @param {?} ignore_from_payload * @return {?} */ _findParamsKey(params, key_arr, ignore_from_payload) { /** @type {?} */ let value = ''; if (params instanceof Object) { if (key_arr.length > 1) { value = this._findParamsKey(params[key_arr[0]], key_arr.splice(1), ignore_from_payload); } else if (params[key_arr[0]] || _.isNumber(params[key_arr[0]])) { value = params[key_arr[0]]; if (ignore_from_payload) { delete params[key_arr[0]]; } } } return (value || _.isNumber(value)) ? `${value}` : ''; } /** * @private * @param {?} resource_params * @return {?} */ _setResourceParamsDefaults(resource_params) { return Object.assign({ method: RequestMethod.Get, path: '', requestInterceptor: null, responseInterceptor: null, withCredentials: false, logoutOnUnauthorized: true }, resource_params); } /** * @private * @param {?} response * @param {?} cache_info * @param {?=} responseInterceptor * @return {?} */ _handleSuccess(response, cache_info, responseInterceptor) { /** @type {?} */ let response_data; if (!cache_info.enabled || (cache_info.enabled && cache_info.replace)) { response_data = { data: response.body, cached: false, status: response.status, statusText: response.statusText }; } else { response_data = response; response_data.cached = true; } if (_.isFunction(responseInterceptor)) { return responseInterceptor(response_data); } return response_data; } /** * @private * @param {?} err * @param {?} cache_info * @param {?} logout_on_unauthorized * @param {?=} responseInterceptor * @return {?} */ _handleError(err, cache_info, logout_on_unauthorized, responseInterceptor) { /** @type {?} */ let response_data; if (err.status == 401 && logout_on_unauthorized) { this.clearSession(); self.location.reload(); } else if (err.status == 403) { this._toastService.open({ message: 'Você não tem autorização para utilizar esse recurso.' }); } if (cache_info && (!cache_info.enabled || (cache_info.enabled && cache_info.replace))) { response_data = { data: err.error || null, cached: false, status: err.status, statusText: err.statusText }; if (err.name == 'TimeoutError') { response_data.status = 504; response_data.statusText = 'TimeoutError'; } } else { response_data = { data: null, cached: !!cache_info, status: 0, statusText: err.message || err.name }; } if (_.isFunction(responseInterceptor)) { return responseInterceptor(response_data); } return response_data; } } if (false) { /** @type {?} */ BaseModel.prototype.url; /** @type {?} */ BaseModel.prototype.path; /** @type {?} */ BaseModel.prototype.timeout; /** * @type {?} * @private */ BaseModel.prototype._http; /** * @type {?} * @private */ BaseModel.prototype._toastService; } /** @enum {string} */ const RequestMethod = { Post: "POST", Put: "PUT", Path: "PATH", Get: "GET", Delete: "DELETE", Head: "HEAD", Options: "OPTIONS", Jsonp: "JSONP", }; export { RequestMethod }; /** * @record */ export function RequestOptions() { } if (false) { /** @type {?|undefined} */ RequestOptions.prototype.headers; /** @type {?|undefined} */ RequestOptions.prototype.reportProgress; /** @type {?|undefined} */ RequestOptions.prototype.params; /** @type {?|undefined} */ RequestOptions.prototype.responseType; /** @type {?|undefined} */ RequestOptions.prototype.withCredentials; } /** * @record */ export function ResourcePromise() { } if (false) { /** @type {?} */ ResourcePromise.prototype.then; /** @type {?} */ ResourcePromise.prototype.catch; /** @type {?} */ ResourcePromise.prototype.finally; /** @type {?} */ ResourcePromise.prototype.abort; } /** * @record */ export function ResourceParams() { } if (false) { /** @type {?|undefined} */ ResourceParams.prototype.method; /** @type {?|undefined} */ ResourceParams.prototype.path; /** @type {?|undefined} */ ResourceParams.prototype.requestInterceptor; /** @type {?|undefined} */ ResourceParams.prototype.responseInterceptor; /** @type {?|undefined} */ ResourceParams.prototype.withCredentials; /** @type {?|undefined} */ ResourceParams.prototype.logoutOnUnauthorized; /** @type {?|undefined} */ ResourceParams.prototype.timeout; /** @type {?|undefined} */ ResourceParams.prototype.cache; } /** * @record */ export function CacheSettings() { } if (false) { /** @type {?} */ CacheSettings.prototype.name; /** @type {?|undefined} */ CacheSettings.prototype.ignore_params; } /** * @record */ export function ResourcePath() { } if (false) { /** @type {?} */ ResourcePath.prototype.template; /** @type {?} */ ResourcePath.prototype.keys; } /** * @record */ export function CacheInfo() { } if (false) { /** @type {?} */ CacheInfo.prototype.enabled; /** @type {?} */ CacheInfo.prototype.replace; /** @type {?} */ CacheInfo.prototype.name; /** @type {?} */ CacheInfo.prototype.params; } /** * @record */ export function RequestParams() { } if (false) { /** @type {?|undefined} */ RequestParams.prototype.logoutOnUnauthorized; /* Skipping unhandled member: [key: string]: any;*/ } /** * @record */ export function ResourceResponse() { } if (false) { /** @type {?} */ ResourceResponse.prototype.data; /** @type {?} */ ResourceResponse.prototype.cached; /** @type {?} */ ResourceResponse.prototype.status; /** @type {?} */ ResourceResponse.prototype.statusText; } /** * @record */ export function DefaultRequestData() { } /** * @record */ export function DefaultResponseData() { } if (false) { /** @type {?|undefined} */ DefaultResponseData.prototype.error; /** @type {?|undefined} */ DefaultResponseData.prototype.success; /** @type {?|undefined} */ DefaultResponseData.prototype.id; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AdWV4L3dlYi1leHRlbnNpb25zLyIsInNvdXJjZXMiOlsibGliL21vZHVsZXMvZ2VuZXJpYy9iYXNlL21vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFjLFdBQVcsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBcUIsTUFBTSxzQkFBc0IsQ0FBQztBQUUxSCxPQUFPLEtBQUssQ0FBQyxNQUFNLFFBQVEsQ0FBQztBQUU1QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7QUFJekMsTUFBTSxPQUFnQixTQUFTOzs7OztJQUU3QixZQUNVLEtBQWlCLEVBQ2pCLGFBQTJCO1FBRDNCLFVBQUssR0FBTCxLQUFLLENBQVk7UUFDakIsa0JBQWEsR0FBYixhQUFhLENBQWM7UUFJOUIsU0FBSSxHQUFHLEVBQUUsQ0FBQztRQUNWLFlBQU8sR0FBRyxLQUFLLENBQUM7SUFKbkIsQ0FBQzs7Ozs7SUFNRSxhQUFhLENBQUMsZUFBK0I7UUFFbEQsaURBQWlEO1FBQ2pELGVBQWUsR0FBRyxJQUFJLENBQUMsMEJBQTBCLENBQUMsZUFBZSxDQUFDLENBQUM7OztjQUc3RCxRQUFROzs7O1FBQWEsQ0FBQyxpQkFBZ0MsRUFBRSxFQUFtQixFQUFFOztnQkFFN0UsT0FBd0I7O2dCQUN4QixvQkFBa0M7O2dCQUNsQyxjQUFtRDs7a0JBRWpELGFBQWEsR0FBaUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUM7WUFFakUsZ0RBQWdEO1lBQ2hELElBQUksZUFBZSxDQUFDLE1BQU0sSUFBSSxhQUFhLENBQUMsR0FBRyxFQUFFO2dCQUMvQyxlQUFlLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQzthQUM5Qjs7a0JBQ0ssVUFBVSxHQUFXLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxF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O0lBQ2pCLHlCQUFhOztJQUNiLDJCQUFlOzs7OztBQUdqQixtQ0FHQzs7O0lBRkMsNkNBQStCOzs7Ozs7QUFRakMsc0NBS0M7OztJQUpDLGdDQUFVOztJQUNWLGtDQUFnQjs7SUFDaEIsa0NBQWU7O0lBQ2Ysc0NBQW1COzs7OztBQUdyQix3Q0FFQzs7OztBQUVELHlDQUlDOzs7SUFIQyxvQ0FBZTs7SUFDZixzQ0FBaUI7O0lBQ2pCLGlDQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEhlYWRlcnMsIEh0dHBQYXJhbXMsIEh0dHBSZXF1ZXN0LCBIdHRwRXZlbnRUeXBlLCBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuXHJcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IHRpbWVvdXQgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBUb2FzdFNlcnZpY2UgfSBmcm9tICcuLi8uLi90b2FzdC90b2FzdC5zZXJ2aWNlJztcclxuXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlTW9kZWwge1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgX2h0dHA6IEh0dHBDbGllbnQsXHJcbiAgICBwcml2YXRlIF90b2FzdFNlcnZpY2U6IFRvYXN0U2VydmljZVxyXG4gICkgeyB9XHJcblxyXG4gIHB1YmxpYyB1cmw6IHN0cmluZztcclxuICBwdWJsaWMgcGF0aCA9ICcnO1xyXG4gIHB1YmxpYyB0aW1lb3V0ID0gMzAwMDA7XHJcblxyXG4gIHB1YmxpYyBidWlsZFJlc291cmNlKHJlc291cmNlX3BhcmFtczogUmVzb3VyY2VQYXJhbXMpOiBSZXNvdXJjZSB7XHJcblxyXG4gICAgLy8gRGVmaW5lIG9zIHZhbG9yZXMgcGFkcsOjbyBwYXJhIG8gUmVzb3VyY2VQYXJhbXNcclxuICAgIHJlc291cmNlX3BhcmFtcyA9IHRoaXMuX3NldFJlc291cmNlUGFyYW1zRGVmYXVsdHMocmVzb3VyY2VfcGFyYW1zKTtcclxuXHJcbiAgICAvLyBEZWNsYXJhIG8gUmVzb3VyY2UgcXVlIHNlcsOhIHJldG9ybmFkb1xyXG4gICAgY29uc3QgcmVzb3VyY2U6IFJlc291cmNlID0gKHJlcXVlc3RfcGFyYW1zOiBSZXF1ZXN0UGFyYW1zID0ge30pOiBSZXNvdXJjZVByb21pc2UgPT4ge1xyXG5cclxuICAgICAgbGV0IHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PHt9PjtcclxuICAgICAgbGV0IHJlcXVlc3Rfc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcbiAgICAgIGxldCByZWplY3RfcHJvbWlzZTogKHJlc3BvbnNlOiBSZXNvdXJjZVJlc3BvbnNlKSA9PiBhbnk7XHJcblxyXG4gICAgICBjb25zdCByZXNvdXJjZV9wYXRoOiBSZXNvdXJjZVBhdGggPSB0aGlzLmdldFBhdGgocmVzb3VyY2VfcGFyYW1zKTtcclxuXHJcbiAgICAgIC8vIEluaWNpYWxpemEgbyBjYWNoZWFtZW50byBwYXJhIGVzc2EgcmVxdWlzacOnw6NvXHJcbiAgICAgIGlmIChyZXNvdXJjZV9wYXJhbXMubWV0aG9kICE9IFJlcXVlc3RNZXRob2QuR2V0KSB7XHJcbiAgICAgICAgcmVzb3VyY2VfcGFyYW1zLmNhY2hlID0gbnVsbDtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBjaGlsZF9uYW1lOiBzdHJpbmcgPSBfLnNuYWtlQ2FzZSh0aGlzLmNvbnN0cnVjdG9yLm5hbWUucmVwbGFjZSgnTW9kZWwnLCAnJykpO1xyXG4gICAgICBjb25zdCBzY2hlbWFfbmFtZTogc3RyaW5nID0gcmVzb3VyY2VfcGFyYW1zLmNhY2hlID8gYCR7Y2hpbGRfbmFtZX1fJHtyZXNvdXJjZV9wYXJhbXMuY2FjaGUubmFtZX1gIDogbnVsbDtcclxuXHJcbiAgICAgIGNvbnN0IGxvZ291dF9vbl91bmF1dGhvcml6ZWQ6IGJvb2xlYW4gPSB0aGlzLl9nZXRMb2dvdXRPblVuYXV0aG9yaXplZChyZXNvdXJjZV9wYXJhbXMsIHJlcXVlc3RfcGFyYW1zKTtcclxuICAgICAgY29uc3QgY2FjaGVfaW5mbzogQ2FjaGVJbmZvID0ge1xyXG4gICAgICAgIGVuYWJsZWQ6IHJlc291cmNlX3BhcmFtcy5jYWNoZSA/IHRydWUgOiBmYWxzZSxcclxuICAgICAgICByZXBsYWNlOiB0cnVlLFxyXG4gICAgICAgIG5hbWU6IHNjaGVtYV9uYW1lLFxyXG4gICAgICAgIHBhcmFtczogcmVxdWVzdF9wYXJhbXNcclxuICAgICAgfTtcclxuXHJcbiAgICAgIC8vIFJlc3Rvcm5hIHVtYSBQcm9taXNlXHJcbiAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZTxSZXNvdXJjZVJlc3BvbnNlPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgcmVqZWN0X3Byb21pc2UgPSByZWplY3Q7XHJcblxyXG4gICAgICAgIGNvbnN0IHJlcXVlc3RfdXJsOiBzdHJpbmcgPSB0aGlzLnVybCArIHRoaXMucGFyc2VSZXNvdXJjZVBhdGgocmVzb3VyY2VfcGF0aCwgcmVxdWVzdF9wYXJhbXMpO1xyXG4gICAgICAgIGNvbnN0IHJlcXVlc3Rfb3B0aW9uczogUmVxdWVzdE9wdGlvbnMgPSB0aGlzLmdldE9wdGlvbnMocmVzb3VyY2VfcGFyYW1zLCByZXF1ZXN0X3BhcmFtcyk7XHJcbiAgICAgICAgY29uc3QgcmVxdWVzdF90aW1lb3V0ID0gcmVzb3VyY2VfcGFyYW1zLnRpbWVvdXQgPyByZXNvdXJjZV9wYXJhbXMudGltZW91dCA6IHRoaXMudGltZW91dDtcclxuXHJcbiAgICAgICAgY29uc3QgaGFzX2JvZHkgPSB0aGlzLl9oYXNCb2R5KHJlc291cmNlX3BhcmFtcy5tZXRob2QpO1xyXG4gICAgICAgIGlmIChoYXNfYm9keSkge1xyXG4gICAgICAgICAgY29uc3QgcmVxdWVzdF9ib2R5ID0gcmVxdWVzdF9vcHRpb25zLnBhcmFtcztcclxuICAgICAgICAgIHJlcXVlc3Rfb3B0aW9ucy5wYXJhbXMgPSBudWxsO1xyXG4gICAgICAgICAgcmVxdWVzdCA9IG5ldyBIdHRwUmVxdWVzdChyZXNvdXJjZV9wYXJhbXMubWV0aG9kLCByZXF1ZXN0X3VybCwgcmVxdWVzdF9ib2R5LCByZXF1ZXN0X29wdGlvbnMpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICByZXF1ZXN0ID0gbmV3IEh0dHBSZXF1ZXN0KHJlc291cmNlX3BhcmFtcy5tZXRob2QsIHJlcXVlc3RfdXJsLCByZXF1ZXN0X29wdGlvbnMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmVxdWVzdF9zdWJzY3JpcHRpb24gPSB0aGlzLl9odHRwLnJlcXVlc3QocmVxdWVzdClcclxuICAgICAgICAgIC5waXBlKHRpbWVvdXQocmVxdWVzdF90aW1lb3V0KSlcclxuICAgICAgICAgIC5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgIChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgICAgIGlmIChyZXNwb25zZS50eXBlID09IEh0dHBFdmVudFR5cGUuUmVzcG9uc2UpIHsgcmVzb2x2ZSh0aGlzLl9oYW5kbGVTdWNjZXNzKHJlc3BvbnNlLCBjYWNoZV9pbmZvLCByZXNvdXJjZV9wYXJhbXMucmVzcG9uc2VJbnRlcmNlcHRvcikpOyB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIChlcnIpID0+IHJlamVjdCh0aGlzLl9oYW5kbGVFcnJvcihlcnIsIGNhY2hlX2luZm8sIGxvZ291dF9vbl91bmF1dGhvcml6ZWQsIHJlc291cmNlX3BhcmFtcy5yZXNwb25zZUludGVyY2VwdG9yKSkpO1xyXG5cclxuICAgICAgfSk7XHJcblxyXG4gICAgICBjb25zdCByZXNwb25zZSA9IHtcclxuICAgICAgICB0aGVuOiAob25fc3VjY2VzczogUmVzb3VyY2VSZXNwb25zZVByb21pc2UsIG9uX2Vycm9yPzogUmVzb3VyY2VSZXNwb25zZVByb21pc2UpID0+IHtcclxuICAgICAgICAgIHByb21pc2UudGhlbihvbl9zdWNjZXNzLCBvbl9lcnJvcik7XHJcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjYXRjaDogKG9uX2Vycm9yOiBSZXNvdXJjZVJlc3BvbnNlUHJvbWlzZSkgPT4ge1xyXG4gICAgICAgICAgcHJvbWlzZS5jYXRjaChvbl9lcnJvcik7XHJcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBmaW5hbGx5OiAob25fZmluYWxseTogKCkgPT4gdm9pZCkgPT4ge1xyXG4gICAgICAgICAgcHJvbWlzZS50aGVuKG9uX2ZpbmFsbHksIG9uX2ZpbmFsbHkpO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgYWJvcnQ6ICgpID0+IHtcclxuICAgICAgICAgIGlmIChyZXF1ZXN0X3N1YnNjcmlwdGlvbiAmJiAhcmVxdWVzdF9zdWJzY3JpcHRpb24uY2xvc2VkKSB7XHJcbiAgICAgICAgICAgIHJlcXVlc3Rfc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIHJlamVjdF9wcm9taXNlKHRoaXMuX2hhbmRsZUVycm9yKHsgbmFtZTogJ0NhbmNlbGxlZCcgfSwgY2FjaGVfaW5mbywgbG9nb3V0X29uX3VuYXV0aG9yaXplZCwgcmVzb3VyY2VfcGFyYW1zLnJlc3BvbnNlSW50ZXJjZXB0b3IpKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH07XHJcblxyXG4gICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiByZXNvdXJjZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRQYXRoKHJlc291cmNlX3BhcmFtczogUmVzb3VyY2VQYXJhbXMpOiBSZXNvdXJjZVBhdGgge1xyXG4gICAgY29uc3QgX3BhdGggPSBgJHt0aGlzLnBhdGggPyB0aGlzLnBhdGggOiAnJ30ke3Jlc291cmNlX3BhcmFtcy5wYXRoID8gcmVzb3VyY2VfcGFyYW1zLnBhdGggOiAnJ31gO1xyXG4gICAgY29uc3QgX2tleXMgPSBfcGF0aCA/IF9wYXRoLm1hdGNoKC9cXHsoW15cXHtcXH1dKilcXH0vZykgOiBbXTtcclxuICAgIGNvbnN0IHJlc291cmNlX3BhdGg6IFJlc291cmNlUGF0aCA9IHtcclxuICAgICAgdGVtcGxhdGU6IF9wYXRoID8gX3BhdGggOiAnJyxcclxuICAgICAga2V5czogX2tleXMgPyBfa2V5cyA6IFtdXHJcbiAgICB9O1xyXG5cclxuICAgIHJlc291cmNlX3BhdGgua2V5cy5mb3JFYWNoKChrZXksIGluZGV4KSA9PiB7XHJcbiAgICAgIHJlc291cmNlX3BhdGgudGVtcGxhdGUgPSByZXNvdXJjZV9wYXRoLnRlbXBsYXRlLnJlcGxhY2Uoa2V5LCAneyQnICsgKGluZGV4ICsgMSkgKyAnfScpO1xyXG4gICAgICByZXNvdXJjZV9wYXRoLmtleXNbaW5kZXhdID0ga2V5LnJlcGxhY2UoL1tcXHtcXH1dL2csICcnKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiByZXNvdXJjZV9wYXRoO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHBhcnNlUmVzb3VyY2VQYXRoKHJlc291cmNlX3BhdGg6IFJlc291cmNlUGF0aCwgcmVxdWVzdF9wYXJhbXM6IFJlcXVlc3RQYXJhbXMpOiBzdHJpbmcge1xyXG4gICAgbGV0IHBhdGg6IHN0cmluZyA9IHJlc291cmNlX3BhdGgudGVtcGxhdGU7XHJcbiAgICByZXNvdXJjZV9wYXRoLmtleXMuZm9yRWFjaCgoa2V5LCBpbmRleCkgPT4ge1xyXG4gICAgICBjb25zdCBpc19vcHRpb25hbCA9IGtleVswXSA9PSAnPycgfHwga2V5WzFdID09ICc/JztcclxuICAgICAgY29uc3QgaWdub3JlX2Zyb21fcGF5bG9hZCA9IGtleVswXSA9PSAnIScgfHwga2V5WzFdID09ICchJztcclxuICAgICAgY29uc3QgY2xlYW5fa2V5ID0gKGlzX29wdGlvbmFsIHx8IGlnbm9yZV9mcm9tX3BheWxvYWQpID8ga2V5LnJlcGxhY2UoL1tcXD9cXCFdL2csICcnKSA6IGtleTtcclxuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl9maW5kUGFyYW1zS2V5KHJlcXVlc3RfcGFyYW1zLCBjbGVhbl9rZXkuc3BsaXQoJy4nKSwgaWdub3JlX2Zyb21fcGF5bG9hZCk7XHJcbiAgICAgIGNvbnN0IHBhdGhfa2V5ID0gKHZhbHVlID09ICcnICYmIGlzX29wdGlvbmFsICYmIHBhdGguaW5kZXhPZignL3skJyArIChpbmRleCArIDEpICsgJ30nKSA+IC0xKSA/ICcveyQnICsgKGluZGV4ICsgMSkgKyAnfScgOiAneyQnICsgKGluZGV4ICsgMSkgKyAnfSc7XHJcbiAgICAgIHBhdGggPSBwYXRoLnJlcGxhY2UocGF0aF9rZXksIHZhbHVlKTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHBhdGg7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgaGVhZGVySW50ZXJjZXB0b3IoaGVhZGVyczogYW55LCByZXNvdXJjZV9wYXJhbXM6IFJlc291cmNlUGFyYW1zLCByZXF1ZXN0X3BhcmFtczogUmVxdWVzdFBhcmFtcyk6IHN0cmluZyB8IHsgW2tleTogc3RyaW5nXTogYW55IH0ge1xyXG4gICAgcmV0dXJuIGhlYWRlcnM7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2xlYXJTZXNzaW9uKCkgeyB9XHJcblxyXG4gIHByaXZhdGUgZ2V0T3B0aW9ucyhyZXNvdXJjZV9wYXJhbXM6IFJlc291cmNlUGFyYW1zLCByZXF1ZXN0X3BhcmFtczogUmVxdWVzdFBhcmFtcyk6IFJlcXVlc3RPcHRpb25zIHtcclxuICAgIGNvbnN0IHJlcXVlc3Rfb3B0aW9uczogUmVxdWVzdE9wdGlvbnMgPSB7XHJcbiAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMocmVzb3VyY2VfcGFyYW1zLCByZXF1ZXN0X3BhcmFtcyksXHJcbiAgICAgIHBhcmFtczogPEh0dHBQYXJhbXM+dGhpcy5fZ2V0UGFyYW1zKHJlc291cmNlX3BhcmFtcywgcmVxdWVzdF9wYXJhbXMpLFxyXG4gICAgICB3aXRoQ3JlZGVudGlhbHM6IHJlc291cmNlX3BhcmFtcy53aXRoQ3JlZGVudGlhbHMsXHJcbiAgICAgIHJlc3BvbnNlVHlwZTogJ2pzb24nLFxyXG4gICAgICByZXBvcnRQcm9ncmVzczogZmFsc2VcclxuICAgIH07XHJcblxyXG4gICAgaWYgKF8uaXNGdW5jdGlvbihyZXNvdXJjZV9wYXJhbXMucmVxdWVzdEludGVyY2VwdG9yKSkge1xyXG4gICAgICByZXR1cm4gcmVzb3VyY2VfcGFyYW1zLnJlcXVlc3RJbnRlcmNlcHRvcihyZXF1ZXN0X29wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByZXF1ZXN0X29wdGlvbnM7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9nZXRIZWFkZXJzKHJlc291cmNlX3BhcmFtczogUmVzb3VyY2VQYXJhbXMsIHJlcXVlc3RfcGFyYW1zOiBSZXF1ZXN0UGFyYW1zKTogSHR0cEhlYWRlcnMge1xyXG4gICAgY29uc3QgaGVhZGVyczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcclxuICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcclxuICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcclxuICAgICAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbic6ICcqJ1xyXG4gICAgfTtcclxuXHJcbiAgICBpZiAoXy5pc0Z1bmN0aW9uKHRoaXMuaGVhZGVySW50ZXJjZXB0b3IpKSB7XHJcbiAgICAgIHJldHVybiBuZXcgSHR0cEhlYWRlcnModGhpcy5oZWFkZXJJbnRlcmNlcHRvcihoZWFkZXJzLCByZXNvdXJjZV9wYXJhbXMsIHJlcXVlc3RfcGFyYW1zKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG5ldyBIdHRwSGVhZGVycyhoZWFkZXJzKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2dldExvZ291dE9uVW5hdXRob3JpemVkKHJlc291cmNlX3BhcmFtczogUmVzb3VyY2VQYXJhbXMsIHJlcXVlc3RfcGFyYW1zOiBSZXF1ZXN0UGFyYW1zKTogYm9vbGVhbiB7XHJcbiAgICBsZXQgbG9nb3V0X29uX3VuYXV0aG9yaXplZCA9IHRydWU7XHJcblxyXG4gICAgaWYgKCFfLmlzRW1wdHkocmVzb3VyY2VfcGFyYW1zKSAmJiBfLmlzQm9vbGVhbihyZXNvdXJjZV9wYXJhbXMubG9nb3V0T25VbmF1dGhvcml6ZWQpKSB7XHJcbiAgICAgIGxvZ291dF9vbl91bmF1dGhvcml6ZWQgPSByZXNvdXJjZV9wYXJhbXMubG9nb3V0T25VbmF1dGhvcml6ZWQ7XHJcbiAgICB9IGVsc2UgaWYgKCFfLmlzRW1wdHkocmVxdWVzdF9wYXJhbXMpICYmIF8uaXNCb29sZWFuKHJlcXVlc3RfcGFyYW1zLmxvZ291dE9uVW5hdXRob3JpemVkKSkge1xyXG4gICAgICBsb2dvdXRfb25fdW5hdXRob3JpemVkID0gcmVxdWVzdF9wYXJhbXMubG9nb3V0T25VbmF1dGhvcml6ZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGxvZ291dF9vbl91bmF1dGhvcml6ZWQ7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9nZXRQYXJhbXMocmVzb3VyY2VfcGFyYW1zOiBSZXNvdXJjZVBhcmFtcywgcmVxdWVzdF9wYXJhbXM6IFJlcXVlc3RQYXJhbXMpOiBIdHRwUGFyYW1zIHwgUmVxdWVzdFBhcmFtcyB7XHJcbiAgICBpZiAodGhpcy5faGFzQm9keShyZXNvdXJjZV9wYXJhbXMubWV0aG9kKSkge1xyXG4gICAgICByZXR1cm4gcmVxdWVzdF9wYXJhbXM7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBwYXJhbXMgPSB7fTtcclxuICAgICAgdGhpcy5fc2V0UGFyYW1zKHBhcmFtcywgcmVxdWVzdF9wYXJhbXMpO1xyXG4gICAgICBjb25zdCBodHRwX3BhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKHsgZnJvbU9iamVjdDogcGFyYW1zIH0pO1xyXG4gICAgICByZXR1cm4gaHR0cF9wYXJhbXM7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9oYXNCb2R5KG1ldGhvZDogUmVxdWVzdE1ldGhvZCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIFsnUE9TVCcsICdQVVQnLCAnUEFUQ0gnXS5pbmRleE9mKG1ldGhvZCkgPiAtMTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3NldFBhcmFtcyhwYXJhbXM6IHt9LCByZXF1ZXN0X3BhcmFtczogYW55LCBwcmVmaXg/OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIGxldCBjb3VudCA9IDA7XHJcblxyXG4gICAgaWYgKF8uaXNQbGFpbk9iamVjdChyZXF1ZXN0X3BhcmFtcykpIHtcclxuICAgICAgXy5lYWNoKHJlcXVlc3RfcGFyYW1zLCAoaXRlbSwga2V5KSA9PiB7XHJcbiAgICAgICAgaWYgKF8uaXNFbXB0eShpdGVtKSAmJiAhXy5pc0Jvb2xlYW4oaXRlbSkgJiYgIV8uaXNOdW1iZXIoaXRlbSkpIHsgcmV0dXJuOyB9XHJcblxyXG4gICAgICAgIGNvbnN0IHBhcmFtX3ByZWZpeCA9IHByZWZpeCA/IGAke3ByZWZpeH1bJHtrZXl9XWAgOiBrZXk7XHJcblxyXG4gICAgICAgIGlmIChfLmlzUGxhaW5PYmplY3QoaXRlbSkgfHwgXy5pc0FycmF5KGl0ZW0pKSB7XHJcbiAgICAgICAgICBpZiAodGhpcy5fc2V0UGFyYW1zKHBhcmFtcywgaXRlbSwgcGFyYW1fcHJlZml4KSkgeyBjb3VudCsrOyB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHBhcmFtc1twYXJhbV9wcmVmaXhdID0gaXRlbTtcclxuICAgICAgICAgIGNvdW50Kys7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSBpZiAoXy5pc0FycmF5KHJlcXVlc3RfcGFyYW1zKSAmJiBwcmVmaXgpIHtcclxuICAgICAgbGV0IGluZGV4ID0gMDtcclxuICAgICAgcmVxdWVzdF9wYXJhbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG4gICAgICAgIGlmIChfLmlzRW1wdHkoaXRlbSkgJiYgIV8uaXNCb29sZWFuKGl0ZW0pICYmICFfLmlzTnVtYmVyKGl0ZW0pKSB7IHJldHVybjsgfVxyXG4gICAgICAgIGNvbnN0IHBhcmFtX3ByZWZpeCA9IGAke3ByZWZpeH1bJHtpbmRleH1dYDtcclxuXHJcbiAgICAgICAgaWYgKF8uaXNQbGFpbk9iamVjdChpdGVtKSB8fCBfLmlzQXJyYXkoaXRlbSkpIHtcclxuICAgICAgICAgIGlmICh0aGlzLl9zZXRQYXJhbXMocGFyYW1zLCBpdGVtLCBwYXJhbV9wcmVmaXgpKSB7XHJcbiAgICAgICAgICAgIGNvdW50Kys7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgcGFyYW1zW3BhcmFtX3ByZWZpeF0gPSBpdGVtO1xyXG4gICAgICAgICAgY291bnQrKztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGluZGV4Kys7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjb3VudCA+IDA7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9maW5kUGFyYW1zS2V5KHBhcmFtczogUmVxdWVzdFBhcmFtcywga2V5X2FycjogQXJyYXk8c3RyaW5nPiwgaWdub3JlX2Zyb21fcGF5bG9hZDogYm9vbGVhbik6IHN0cmluZyB7XHJcbiAgICBsZXQgdmFsdWUgPSAnJztcclxuXHJcbiAgICBpZiAocGFyYW1zIGluc3RhbmNlb2YgT2JqZWN0KSB7XHJcbiAgICAgIGlmIChrZXlfYXJyLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICB2YWx1ZSA9IHRoaXMuX2ZpbmRQYXJhbXNLZXkocGFyYW1zW2tleV9hcnJbMF1dLCBrZXlfYXJyLnNwbGljZSgxKSwgaWdub3JlX2Zyb21fcGF5bG9hZCk7XHJcbiAgICAgIH0gZWxzZSBpZiAocGFyYW1zW2tleV9hcnJbMF1dIHx8IF8uaXNOdW1iZXIocGFyYW1zW2tleV9hcnJbMF1dKSkge1xyXG4gICAgICAgIHZhbHVlID0gcGFyYW1zW2tleV9hcnJbMF1dO1xyXG4gICAgICAgIGlmIChpZ25vcmVfZnJvbV9wYXlsb2FkKSB7XHJcbiAgICAgICAgICBkZWxldGUgcGFyYW1zW2tleV9hcnJbMF1dO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAodmFsdWUgfHwgXy5pc051bWJlcih2YWx1ZSkpID8gYCR7dmFsdWV9YCA6ICcnO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfc2V0UmVzb3VyY2VQYXJhbXNEZWZhdWx0cyhyZXNvdXJjZV9wYXJhbXM6IFJlc291cmNlUGFyYW1zKTogUmVzb3VyY2VQYXJhbXMge1xyXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe1xyXG4gICAgICBtZXRob2Q6IFJlcXVlc3RNZXRob2QuR2V0LFxyXG4gICAgICBwYXRoOiAnJyxcclxuICAgICAgcmVxdWVzdEludGVyY2VwdG9yOiBudWxsLFxyXG4gICAgICByZXNwb25zZUludGVyY2VwdG9yOiBudWxsLFxyXG4gICAgICB3aXRoQ3JlZGVudGlhbHM6IGZhbHNlLFxyXG4gICAgICBsb2dvdXRPblVuYXV0aG9yaXplZDogdHJ1ZVxyXG4gICAgfSwgcmVzb3VyY2VfcGFyYW1zKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2hhbmRsZVN1Y2Nlc3MocmVzcG9uc2U6IGFueSwgY2FjaGVfaW5mbzogQ2FjaGVJbmZvLCByZXNwb25zZUludGVyY2VwdG9yPzogUmVzcG9uc2VJbnRlcmNlcHRvcik6IFJlc291cmNlUmVzcG9uc2Uge1xyXG4gICAgbGV0IHJlc3BvbnNlX2RhdGE6IFJlc291cmNlUmVzcG9uc2U7XHJcblxyXG4gICAgaWYgKCFjYWNoZV9pbmZvLmVuYWJsZWQgfHwgKGNhY2hlX2luZm8uZW5hYmxlZCAmJiBjYWNoZV9pbmZvLnJlcGxhY2UpKSB7XHJcbiAgICAgIHJlc3BvbnNlX2RhdGEgPSB7XHJcbiAgICAgICAgZGF0YTogcmVzcG9uc2UuYm9keSxcclxuICAgICAgICBjYWNoZWQ6IGZhbHNlLFxyXG4gICAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxyXG4gICAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHRcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJlc3BvbnNlX2RhdGEgPSByZXNwb25zZTtcclxuICAgICAgcmVzcG9uc2VfZGF0YS5jYWNoZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChfLmlzRnVuY3Rpb24ocmVzcG9uc2VJbnRlcmNlcHRvcikpIHtcclxuICAgICAgcmV0dXJuIHJlc3BvbnNlSW50ZXJjZXB0b3IocmVzcG9uc2VfZGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3BvbnNlX2RhdGE7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9oYW5kbGVFcnJvcihlcnI6IEh0dHBFcnJvclJlc3BvbnNlIHwgYW55LCBjYWNoZV9pbmZvOiBDYWNoZUluZm8sIGxvZ291dF9vbl91bmF1dGhvcml6ZWQ6IGJvb2xlYW4sIHJlc3BvbnNlSW50ZXJjZXB0b3I/OiBSZXNwb25zZUludGVyY2VwdG9yKTogUmVzb3VyY2VSZXNwb25zZSB7XHJcbiAgICBsZXQgcmVzcG9uc2VfZGF0YTogUmVzb3VyY2VSZXNwb25zZTtcclxuXHJcbiAgICBpZiAoZXJyLnN0YXR1cyA9PSA0MDEgJiYgbG9nb3V0X29uX3VuYXV0aG9yaXplZCkge1xyXG4gICAgICB0aGlzLmNsZWFyU2Vzc2lvbigpO1xyXG4gICAgICBzZWxmLmxvY2F0aW9uLnJlbG9hZCgpO1xyXG4gICAgfSBlbHNlIGlmIChlcnIuc3RhdHVzID09IDQwMykge1xyXG4gICAgICB0aGlzLl90b2FzdFNlcnZpY2Uub3Blbih7XHJcbiAgICAgICAgbWVzc2FnZTogJ1ZvY8O