/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { Injectable } from '@angular/core'; import { Http, Headers, URLSearchParams, RequestOptions } from '@angular/http'; import { Observable } from 'rxjs'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; import { Router } from '@angular/router'; import * as _ from 'lodash'; import * as is from 'is_js'; import { ResultCode as RESULT_CODE } from '../model/result-code'; import { AppConfigService } from '../app-config/app-config.service'; import { Common } from './common.service'; import { B2bService } from './b2b.service'; import { HttpClient, HttpHeaders } from '@angular/common/http'; var Request = /** @class */ (function () { function Request(appConfigService, httpClient, http, router, common, b2bService) { this.appConfigService = appConfigService; this.httpClient = httpClient; this.http = http; this.router = router; this.common = common; this.b2bService = b2bService; this.config = appConfigService.getConfig(); this.api = _.get(this.config, 'apiServers.tomcat.url'); this.system_id = _.get(this.config, 'system_id'); // this.api = 'https://d.gaizers.com/RestAPI'; } /** * fn. get data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น * @param customStoreOptions โยนค่าต่าง ๆ มาในนี้ */ /** * fn. get data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น * @param {?} customStoreOptions โยนค่าต่าง ๆ มาในนี้ * @return {?} */ Request.prototype.getCustomStore = /** * fn. get data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น * @param {?} customStoreOptions โยนค่าต่าง ๆ มาในนี้ * @return {?} */ function (customStoreOptions) { var _this = this; /** @type {?} */ var url = customStoreOptions.url || ''; /** @type {?} */ var data = customStoreOptions.filter || {}; /** @type {?} */ var loadMode = customStoreOptions.loadMode || 'processed'; /** @type {?} */ var params = new URLSearchParams(); for (var key in data) { if (key === 'filter') { if (data[key] !== '{}') { params.set(key, data[key]); } } else { params.set(key, data[key]); } } console.log('​Request -> getCustomStore -> params', params); /** @type {?} */ var userData = this.b2bService.getVerifyToken(); /** @type {?} */ var headerData = { system_id: this.system_id, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; /** @type {?} */ var headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); /** @type {?} */ var options = new RequestOptions({ headers: headers, withCredentials: true }); options.search = params; return this.http.get(this.api + url, options) .map(function (res) { /** @type {?} */ var resData = res.json(); console.log('​Request -> getCustomStore -> resData', resData); if (loadMode === 'processed') { return _this.fnHandleResponseProcessedMode(resData); } else { return _this.fnHandleResponseRawMode(resData); } }) .toPromise() .catch(function (error) { console.log('​Request -> getCustomStore -> error', error); if (loadMode === 'processed') { return _this.fnHandleErrorProcessedMode(error); } else { return _this.fnHandleErrorRawMode(error); } }); }; /** * fn. post data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น * @param customStoreOptions โยนค่าต่าง ๆ มาในนี้ */ /** * fn. post data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น * @param {?} customStoreOptions โยนค่าต่าง ๆ มาในนี้ * @return {?} */ Request.prototype.postCustomStore = /** * fn. post data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น * @param {?} customStoreOptions โยนค่าต่าง ๆ มาในนี้ * @return {?} */ function (customStoreOptions) { return tslib_1.__awaiter(this, void 0, void 0, function () { var url, data, loadMode, userData, headerData, headers, options; var _this = this; return tslib_1.__generator(this, function (_a) { url = customStoreOptions.url || ''; data = JSON.parse(JSON.stringify(customStoreOptions.filter, this.common.replacer)) || {}; loadMode = customStoreOptions.loadMode || 'processed'; userData = this.b2bService.getVerifyToken(); headerData = { system_id: this.system_id, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); options = new RequestOptions({ headers: headers, withCredentials: true }); return [2 /*return*/, this.http.post(this.api + url, data, options) .map(function (res) { /** @type {?} */ var resData = res.json(); console.log('​Request -> getCustomStore -> resData', resData); if (loadMode === 'processed') { return _this.fnHandleResponseProcessedMode(resData); } else { return _this.fnHandleResponseRawMode(resData); } }) .toPromise() .catch(function (error) { console.log('​Request -> getCustomStore -> error', error); if (loadMode === 'processed') { return _this.fnHandleErrorProcessedMode(error); } else { return _this.fnHandleErrorRawMode(error); } })]; }); }); }; /** * fn. post data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น * @param customStoreOptions โยนค่าต่าง ๆ มาในนี้ */ /** * fn. post data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น * @param {?} customStoreOptions โยนค่าต่าง ๆ มาในนี้ * @return {?} */ Request.prototype.postCustomStore31 = /** * fn. post data สำหรับดึงข้อมูลสำหรับ Datagrid เท่านั้น * @param {?} customStoreOptions โยนค่าต่าง ๆ มาในนี้ * @return {?} */ function (customStoreOptions) { return tslib_1.__awaiter(this, void 0, void 0, function () { var url, data, loadMode, userData, headerData, headers, options; var _this = this; return tslib_1.__generator(this, function (_a) { url = customStoreOptions.url || ''; data = JSON.parse(JSON.stringify(customStoreOptions.filter, this.common.replacer)) || {}; loadMode = customStoreOptions.loadMode || 'processed'; userData = this.b2bService.getVerifyToken(); headerData = { system_id: 31, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); options = new RequestOptions({ headers: headers, withCredentials: true }); return [2 /*return*/, this.http.post(this.api + url, data, options) .map(function (res) { /** @type {?} */ var resData = res.json(); console.log('​Request -> getCustomStore -> resData', resData); if (loadMode === 'processed') { return _this.fnHandleResponseProcessedMode(resData); } else { return _this.fnHandleResponseRawMode(resData); } }) .toPromise() .catch(function (error) { console.log('​Request -> getCustomStore -> error', error); if (loadMode === 'processed') { return _this.fnHandleErrorProcessedMode(error); } else { return _this.fnHandleErrorRawMode(error); } })]; }); }); }; /** * ถ้า getCustomStore แล้ว error กรณี loadMode = 'processed' * @param error */ /** * ถ้า getCustomStore แล้ว error กรณี loadMode = 'processed' * @param {?} error * @return {?} */ Request.prototype.fnHandleErrorProcessedMode = /** * ถ้า getCustomStore แล้ว error กรณี loadMode = 'processed' * @param {?} error * @return {?} */ function (error) { // alert('ERROR ' + error); console.error('ERROR ' + error); return { data: [], totalCount: 0 }; }; /** * ถ้า getCustomStore แล้ว error กรณี loadMode = 'raw' * @param error */ /** * ถ้า getCustomStore แล้ว error กรณี loadMode = 'raw' * @param {?} error * @return {?} */ Request.prototype.fnHandleErrorRawMode = /** * ถ้า getCustomStore แล้ว error กรณี loadMode = 'raw' * @param {?} error * @return {?} */ function (error) { // alert('ERROR ' + error); console.error('ERROR ' + error); return []; }; /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ Request.prototype.get = /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ function (url, data) { var _this = this; /** @type {?} */ var params = new URLSearchParams(); for (var key in data) { if (key === 'filter') { if (data[key] !== '{}') { params.set(key, data[key]); } } else { params.set(key, data[key]); } } console.log('​Request -> getCustomStore -> params', params); /** @type {?} */ var userData = this.b2bService.getVerifyToken(); /** @type {?} */ var headerData = { system_id: this.system_id, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; /** @type {?} */ var headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); headers.append('Authorization', 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRlc3QiLCJzZXNzaW9uSWQiOiJjNzQwNDdiZi1jNGUwLTQxOTMtOTRiNy1jOGI4M2ViYjhlMGMiLCJpYXQiOjE1NDM5NDYyNDYsImV4cCI6MTU0NDU1MTA0Nn0.5y9f2ZYieRZHhGIMTryxuvsAjJYzvFnWnpcYLk1hSXw'); /** @type {?} */ var options = new RequestOptions({ headers: headers, withCredentials: true }); options.search = params; return this.http.get(this.api + url, options) .map(function (res) { /** @type {?} */ var resData = res.json(); return _this.fnHandleResponse(resData); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ Request.prototype.get31 = /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ function (url, data) { var _this = this; /** @type {?} */ var params = new URLSearchParams(); for (var key in data) { if (key === 'filter') { if (data[key] !== '{}') { params.set(key, data[key]); } } else { params.set(key, data[key]); } } console.log('​Request -> getCustomStore -> params', params); /** @type {?} */ var userData = this.b2bService.getVerifyToken(); /** @type {?} */ var headerData = { system_id: 31, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; /** @type {?} */ var headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); headers.append('Authorization', 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRlc3QiLCJzZXNzaW9uSWQiOiJjNzQwNDdiZi1jNGUwLTQxOTMtOTRiNy1jOGI4M2ViYjhlMGMiLCJpYXQiOjE1NDM5NDYyNDYsImV4cCI6MTU0NDU1MTA0Nn0.5y9f2ZYieRZHhGIMTryxuvsAjJYzvFnWnpcYLk1hSXw'); /** @type {?} */ var options = new RequestOptions({ headers: headers, withCredentials: true }); options.search = params; return this.http.get(this.api + url, options) .map(function (res) { /** @type {?} */ var resData = res.json(); return _this.fnHandleResponse(resData); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} headers * @return {?} */ Request.prototype.getCustom = /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} headers * @return {?} */ function (url, headers) { var _this = this; if (!headers) { headers = new Headers(); } /** @type {?} */ var options = new RequestOptions({ headers: headers }); return this.http.get(url, options) .map(function (res) { /** @type {?} */ var resData = res.json(); return _this.fnHandleResponse(resData); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} headers * @return {?} */ Request.prototype.getRawResponse = /** * fn. get data สำหรับดึงข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} headers * @return {?} */ function (url, headers) { if (!headers) { headers = new Headers(); } /** @type {?} */ var options = new RequestOptions({ headers: headers }); return this.http.get(url, options) .map(function (res) { return res.json(); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * fn. delete data สำหรับลบข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. delete data สำหรับลบข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ Request.prototype.delete = /** * fn. delete data สำหรับลบข้อมูลทั่วไป * @param {?} url ex /test * @param {?=} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ function (url, data) { /** @type {?} */ var params = new URLSearchParams(); for (var key in data) { if (key === 'filter') { if (data[key] !== '{}') { params.set(key, data[key]); } } else { params.set(key, data[key]); } } console.log('​Request -> getCustomStore -> params', params); /** @type {?} */ var userData = this.b2bService.getVerifyToken(); /** @type {?} */ var headerData = { system_id: this.system_id, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; /** @type {?} */ var headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); /** @type {?} */ var options = new RequestOptions({ headers: headers, withCredentials: true }); options.search = params; return this.http.delete(this.api + url, options) .map(function (res) { return res.json(); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ Request.prototype.post = /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ function (url, data) { data = JSON.parse(JSON.stringify(data, this.common.replacer)); console.log('​post -> data', data); console.log('​post -> data', typeof data); /** @type {?} */ var params = new URLSearchParams(); /** @type {?} */ var userData = this.b2bService.getVerifyToken(); /** @type {?} */ var headerData = { system_id: this.system_id, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; /** @type {?} */ var headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); headers.append('Content-Type', 'application/json'); /** @type {?} */ var options = new RequestOptions({ headers: headers, withCredentials: true }); return this.http.post(this.api + url, data, options) .map(function (res) { return res.json(); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ Request.prototype.post31 = /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ function (url, data) { data = JSON.parse(JSON.stringify(data, this.common.replacer)); console.log('​post -> data', data); console.log('​post -> data', typeof data); /** @type {?} */ var params = new URLSearchParams(); /** @type {?} */ var userData = this.b2bService.getVerifyToken(); /** @type {?} */ var headerData = { system_id: 31, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; /** @type {?} */ var headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); headers.append('Content-Type', 'application/json'); /** @type {?} */ var options = new RequestOptions({ headers: headers, withCredentials: true }); return this.http.post(this.api + url, data, options) .map(function (res) { return res.json(); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ Request.prototype.post14 = /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ function (url, data) { data = JSON.parse(JSON.stringify(data, this.common.replacernotrim)); console.log('​post -> data', data); console.log('​post -> data', typeof data); /** @type {?} */ var params = new URLSearchParams(); /** @type {?} */ var userData = this.b2bService.getVerifyToken(); /** @type {?} */ var headerData = { system_id: this.system_id, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; /** @type {?} */ var headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); headers.append('Content-Type', 'application/json'); /** @type {?} */ var options = new RequestOptions({ headers: headers, withCredentials: true }); return this.http.post(this.api + url, data, options) .map(function (res) { return res.json(); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @param {?=} headers * @return {?} */ Request.prototype.postCustom = /** * fn. post data สำหรับสร้างข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @param {?=} headers * @return {?} */ function (url, data, headers) { console.log('​post -> data', data); console.log('​post -> data', typeof data); if (!headers) { headers = new Headers(); headers.append('Content-Type', 'application/json'); } /** @type {?} */ var options = new RequestOptions({ headers: headers, withCredentials: true }); return this.http.post(url, data, options) .map(function (res) { return res.json(); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * fn. put data สำหรับอัพเดตข้อมูลทั่วไป * @param url ex /test * @param data ค่าต่างที่ต้องการแนบไปกับ API */ /** * fn. put data สำหรับอัพเดตข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ Request.prototype.put = /** * fn. put data สำหรับอัพเดตข้อมูลทั่วไป * @param {?} url ex /test * @param {?} data ค่าต่างที่ต้องการแนบไปกับ API * @return {?} */ function (url, data) { /** @type {?} */ var params = new URLSearchParams(); /** @type {?} */ var userData = this.b2bService.getVerifyToken(); /** @type {?} */ var headerData = { system_id: this.system_id, department: userData.phoneBookData && userData.phoneBookData.length > 0 ? userData.phoneBookData[0].dept : "", username: userData.username }; /** @type {?} */ var headers = new Headers(); headers.append('x-Token', '1'); headers.append('x-user-data', this.utoa(JSON.stringify(headerData))); headers.append('Content-Type', 'application/json'); /** @type {?} */ var options = new RequestOptions({ headers: headers, withCredentials: true }); return this.http.put(this.api + url, data, options) .map(function (res) { return res.json(); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise(); }; /** * ถ้า getCustomStore แล้ว success กรณี loadMode = 'processed' * @param resData */ /** * ถ้า getCustomStore แล้ว success กรณี loadMode = 'processed' * @param {?} resData * @return {?} */ Request.prototype.fnHandleResponseProcessedMode = /** * ถ้า getCustomStore แล้ว success กรณี loadMode = 'processed' * @param {?} resData * @return {?} */ function (resData) { /** @type {?} */ var customStoreData = { data: [], totalCount: 0 }; /** @type {?} */ var code = ''; /** @type {?} */ var description = ''; /** @type {?} */ var data = []; /** @type {?} */ var rowCount = 0; if (is.array(resData)) { data = resData; rowCount = _.size(data); } else { /** เปลี่ยนไปตามรูปแบบ response */ code = resData.resultCode || ''; description = resData.resultDescription || ''; data = resData.resultData || []; rowCount = resData.rowCount || 0; // เปลี่ยนไปตาม Response /** */ } if (code === RESULT_CODE.ERROR) { console.log('​fnHandleResponseProcessedMode -> RESULT_CODE.ERROR', RESULT_CODE.ERROR); } else if (code === RESULT_CODE.NOT_FOUND) { console.log('​fnHandleResponseProcessedMode -> RESULT_CODE.NOT_FOUND', RESULT_CODE.NOT_FOUND); } else { customStoreData.data = data; customStoreData.totalCount = rowCount; } return customStoreData; }; /** * ถ้า getCustomStore แล้ว success กรณี loadMode = 'raw' * @param resData */ /** * ถ้า getCustomStore แล้ว success กรณี loadMode = 'raw' * @param {?} resData * @return {?} */ Request.prototype.fnHandleResponseRawMode = /** * ถ้า getCustomStore แล้ว success กรณี loadMode = 'raw' * @param {?} resData * @return {?} */ function (resData) { /** @type {?} */ var code = ''; /** @type {?} */ var description = ''; /** @type {?} */ var data = []; if (is.array(resData)) { data = resData; } else { /** เปลี่ยนไปตามรูปแบบ response */ code = resData.resultCode || ''; description = resData.resultDescription || ''; data = resData.resultData || []; /** */ } if (code === RESULT_CODE.ERROR) { alert('ERROR:' + RESULT_CODE.ERROR); return []; } else if (code === RESULT_CODE.NOT_FOUND) { alert('ERROR:' + RESULT_CODE.NOT_FOUND); return []; } else { return data; } }; /** * @param {?} resData * @return {?} */ Request.prototype.fnHandleResponse = /** * @param {?} resData * @return {?} */ function (resData) { /** @type {?} */ var code = ''; /** @type {?} */ var description = ''; /** @type {?} */ var data = []; if (is.array(resData)) { data = resData; } else if (resData.data && is.array(resData.data)) { data = resData.data; } else { /** เปลี่ยนไปตามรูปแบบ response */ code = resData.resultCode || ''; description = resData.resultDescription || ''; data = resData.resultData || []; /** */ } if (code === RESULT_CODE.ERROR) { console.log('​fnHandleResponse -> RESULT_CODE.ERROR', RESULT_CODE.ERROR); return []; } else if (code === RESULT_CODE.NOT_FOUND) { console.log('​fnHandleResponse -> RESULT_CODE.NOT_FOUND', RESULT_CODE.NOT_FOUND); return []; } else { return data; } }; /** * fn ดึงข้อมูลเพื่อใช้ใน Dropdown List * @param systemId เลขรหัสระบบที่ต้องการดึง * @param dropDownType ประเภทข้อมูล dropdown ที่ต้องการดึง */ /** * fn ดึงข้อมูลเพื่อใช้ใน Dropdown List * @param {?} systemId เลขรหัสระบบที่ต้องการดึง * @param {?} dropDownType ประเภทข้อมูล dropdown ที่ต้องการดึง * @param {?=} code * @return {?} */ Request.prototype.getDropDown = /** * fn ดึงข้อมูลเพื่อใช้ใน Dropdown List * @param {?} systemId เลขรหัสระบบที่ต้องการดึง * @param {?} dropDownType ประเภทข้อมูล dropdown ที่ต้องการดึง * @param {?=} code * @return {?} */ function (systemId, dropDownType, code) { return tslib_1.__awaiter(this, void 0, void 0, function () { var data, urlDropdown, resData, resData, error_1; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 5, , 6]); data = { filter: { system_id: systemId, dropdown_type: dropDownType, code: code }, limit: 1000, offset: 0, order_by: ['id asc'] }; urlDropdown = _.get(this.config, 'apiServers.tomcat.api.ct_dropdown_search'); if (!(systemId === 31)) return [3 /*break*/, 2]; return [4 /*yield*/, this.post31(urlDropdown, data)]; case 1: resData = _a.sent(); return [2 /*return*/, resData.resultData]; case 2: return [4 /*yield*/, this.post(urlDropdown, data)]; case 3: resData = _a.sent(); return [2 /*return*/, resData.resultData]; case 4: return [3 /*break*/, 6]; case 5: error_1 = _a.sent(); console.log('catch -> error', error_1); return [2 /*return*/, []]; case 6: return [2 /*return*/]; } }); }); }; /** * @param {?=} parentId * @return {?} */ Request.prototype.getDepartment = /** * @param {?=} parentId * @return {?} */ function (parentId) { if (parentId === void 0) { parentId = 0; } return tslib_1.__awaiter(this, void 0, void 0, function () { var data, urlDropdown, resData, error_2; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); data = { filter: { ref_department_id: parentId }, limit: 1000, offset: 0, order_by: ['name asc'] }; urlDropdown = _.get(this.config, 'apiServers.tomcat.api.ct_department_search'); return [4 /*yield*/, this.post(urlDropdown, data)]; case 1: resData = _a.sent(); return [2 /*return*/, resData.resultData]; case 2: error_2 = _a.sent(); console.log('catch -> error', error_2); return [2 /*return*/, []]; case 3: return [2 /*return*/]; } }); }); }; /** * @return {?} */ Request.prototype.getExtDepartment = /** * @return {?} */ function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var data, urlDropdown, resData, error_3; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); data = { filter: {}, limit: 1000, offset: 0, order_by: ['name asc'] }; urlDropdown = _.get(this.config, 'apiServers.tomcat.api.ct_ext_department_search'); return [4 /*yield*/, this.post(urlDropdown, data)]; case 1: resData = _a.sent(); return [2 /*return*/, resData.resultData]; case 2: error_3 = _a.sent(); console.log('catch -> error', error_3); return [2 /*return*/, []]; case 3: return [2 /*return*/]; } }); }); }; /** * @param {?} system_id * @return {?} */ Request.prototype.getCategory = /** * @param {?} system_id * @return {?} */ function (system_id) { return tslib_1.__awaiter(this, void 0, void 0, function () { var urlStep, params, resData, error_4; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); urlStep = _.get(this.config, 'apiServers.tomcat.api.ct_category'); params = "?_where=(system_id,eq," + system_id + ")&_sort=seq_no"; return [4 /*yield*/, this.get(urlStep + params)]; case 1: resData = _a.sent(); return [2 /*return*/, resData]; case 2: error_4 = _a.sent(); console.log('catch -> error', error_4); return [2 /*return*/, []]; case 3: return [2 /*return*/]; } }); }); }; /** * @param {?} category_id * @return {?} */ Request.prototype.getStepName = /** * @param {?} category_id * @return {?} */ function (category_id) { return tslib_1.__awaiter(this, void 0, void 0, function () { var urlStep, params, resData, error_5; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); urlStep = _.get(this.config, 'apiServers.tomcat.api.ct_step'); params = "?_where=(category_id,eq," + category_id + ")&_sort=seq_no"; return [4 /*yield*/, this.get(urlStep + params)]; case 1: resData = _a.sent(); return [2 /*return*/, resData]; case 2: error_5 = _a.sent(); console.log('catch -> error', error_5); return [2 /*return*/, []]; case 3: return [2 /*return*/]; } }); }); }; /** * @param {?} url * @return {?} */ Request.prototype.getAttachment = /** * @param {?} url * @return {?} */ function (url) { return tslib_1.__awaiter(this, void 0, void 0, function () { var headers, resData, error_6; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); headers = new Headers(); headers.append('Authorization', 'Basic ' + btoa('APPSOC:123456')); return [4 /*yield*/, this.getCustom(url, headers)]; case 1: resData = _a.sent(); return [2 /*return*/, resData]; case 2: error_6 = _a.sent(); console.log('catch -> error', error_6); return [2 /*return*/, error_6]; case 3: return [2 /*return*/]; } }); }); }; /** * @param {?} url * @param {?} data * @return {?} */ Request.prototype.postAttachment = /** * @param {?} url * @param {?} data * @return {?} */ function (url, data) { return tslib_1.__awaiter(this, void 0, void 0, function () { var headers, resData, error_7; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); headers = new Headers(); headers.append('Authorization', 'Basic ' + btoa('APPSOC:123456')); headers.append('test', 'test'); return [4 /*yield*/, this.postCustom(url, data, headers)]; case 1: resData = _a.sent(); return [2 /*return*/, resData]; case 2: error_7 = _a.sent(); console.log('catch -> error', error_7); return [2 /*return*/, error_7]; case 3: return [2 /*return*/]; } }); }); }; /** * @return {?} */ Request.prototype.getUserLevel = /** * @return {?} */ function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var data, urlDropdown, resData, error_8; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); data = { filter: {}, limit: 1000, offset: 0, order_by: ['level asc'] }; urlDropdown = _.get(this.config, 'apiServers.tomcat.api.ct_user_level_search'); return [4 /*yield*/, this.post(urlDropdown, data)]; case 1: resData = _a.sent(); return [2 /*return*/, resData]; case 2: error_8 = _a.sent(); console.log('catch -> error', error_8); return [2 /*return*/, []]; case 3: return [2 /*return*/]; } }); }); }; /** * @param {?} table * @param {?} idList * @return {?} */ Request.prototype.multipleDeleteMain = /** * @param {?} table * @param {?} idList * @return {?} */ function (table, idList) { return tslib_1.__awaiter(this, void 0, void 0, function () { var e_1, _a, url, deleteObj, idList_1, idList_1_1, id, tmp, resData, error_9; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 2, , 3]); url = "/" + table.split("_")[0] + "/main"; deleteObj = {}; deleteObj[table] = []; try { for (idList_1 = tslib_1.__values(idList), idList_1_1 = idList_1.next(); !idList_1_1.done; idList_1_1 = idList_1.next()) { id = idList_1_1.value; tmp = { id: id, action: "delete" }; deleteObj[table].push(tmp); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (idList_1_1 && !idList_1_1.done && (_a = idList_1.return)) _a.call(idList_1); } finally { if (e_1) throw e_1.error; } } return [4 /*yield*/, this.post(url, [deleteObj])]; case 1: resData = _b.sent(); if (resData.resultCode === 20000) { idList = []; } return [2 /*return*/, resData]; case 2: error_9 = _b.sent(); console.log('catch -> error', error_9); return [2 /*return*/, []]; case 3: return [2 /*return*/]; } }); }); }; /** * @param {?} url * @return {?} */ Request.prototype.getAttachmentLinkToken = /** * @param {?} url * @return {?} */ function (url) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { return [2 /*return*/, url + '?downloadToken=' + this.b2bService.getAttachmentToken() + '&inline=true']; }); }); }; /** * @param {?} data * @param {?} fieldList * @param {?} modal * @return {?} */ Request.prototype.checkSpell = /** * @param {?} data * @param {?} fieldList * @param {?} modal * @return {?} */ function (data, fieldList, modal) { return tslib_1.__awaiter(this, void 0, void 0, function () { var e_2, _a, url, body, fieldList_1, fieldList_1_1, field, resData, spellCheck; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: url = "/spellCheck"; body = {}; try { for (fieldList_1 = tslib_1.__values(fieldList), fieldList_1_1 = fieldList_1.next(); !fieldList_1_1.done; fieldList_1_1 = fieldList_1.next()) { field = fieldList_1_1.value; if (data[field.field]) { body[field.field] = { value: data[field.field], display: field.display }; } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (fieldList_1_1 && !fieldList_1_1.done && (_a = fieldList_1.return)) _a.call(fieldList_1); } finally { if (e_2) throw e_2.error; } } return [4 /*yield*/, this.post(url, body)]; case 1: resData = _b.sent(); spellCheck = JSON.parse(resData.resultData); if (_.size(spellCheck) === 0) { return [2 /*return*/, true]; } else { modal.open(spellCheck); return [2 /*return*/, false]; } return [2 /*return*/]; } }); }); }; /** * @param {?} url * @param {?=} headers * @return {?} */ Request.prototype.getQualification = /** * @param {?} url * @param {?=} headers * @return {?} */ function (url, headers) { return tslib_1.__awaiter(this, void 0, void 0, function () { var options; return tslib_1.__generator(this, function (_a) { if (!headers) { headers = new Headers(); } options = new RequestOptions({ headers: headers, withCredentials: true }); return [2 /*return*/, this.http.get(url, options) .map(function (res) { return res.json(); }) .catch(function (error) { return Observable.throw(error.json().error || 'Server error'); }).toPromise()]; }); }); }; /** * @return {?} */ Request.prototype.verifyUserName = /** * @return {?} */ function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var verifyToken, data, phoneBookData; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.b2bService.verify()]; case 1: verifyToken = _a.sent(); if (+verifyToken.resultCode === 20000) { data = verifyToken.resultData; phoneBookData = data.phoneBookData && data.phoneBookData.length > 0 ? data.phoneBookData[0] : {}; return [2 /*return*/, phoneBookData.name]; } return [2 /*return*/]; } }); }); }; /** * @param {?} str * @return {?} */ Request.prototype.utoa = /** * @param {?} str * @return {?} */ function (str) { return window.btoa(unescape(encodeURIComponent(str))); }; /** * @param {?} api * @return {?} */ Request.prototype.downloadImgToBase64 = /** * @param {?} api * @return {?} */ function (api) { var _this = this; return new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var httpOptions, blob, reader_1, err_1; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); httpOptions = { headers: new HttpHeaders({ "Authorization": "Basic " + btoa('APPSOC:123456') }) }; return [4 /*yield*/, this.httpClient.get(api, { headers: httpOptions.headers, responseType: "blob" }).toPromise()]; case 1: blob = _a.sent(); reader_1 = new FileReader(); reader_1.readAsDataURL(blob); reader_1.onloadend = function () { /** @type {?} */ var base64data = reader_1.result; resolve(base64data); }; return [3 /*break*/, 3]; case 2: err_1 = _a.sent(); console.log(err_1); resolve(false); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }); }; /** * @param {?} api * @return {?} */ Request.prototype.downloadView = /** * @param {?} api * @return {?} */ function (api) { return tslib_1.__awaiter(this, void 0, void 0, function () { var httpOptions, blob, url, err_2; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); httpOptions = { headers: new HttpHeaders({ "Authorization": "Basic " + btoa('APPSOC:123456') }) }; return [4 /*yield*/, this.httpClient.get(api, { headers: httpOptions.headers, responseType: "blob" }).toPromise()]; case 1: blob = _a.sent(); url = window.URL.createObjectURL(blob, { oneTimeOnly: true }); window.open(url, '_blank'); return [3 /*break*/, 3]; case 2: err_2 = _a.sent(); console.log(err_2); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; /** * @param {?} api * @return {?} */ Request.prototype.download = /** * @param {?} api * @return {?} */ function (api) { return tslib_1.__awaiter(this, void 0, void 0, function () { var w, httpOptions, blob, url, err_3; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); w = window.open(); w.document.writeln(""); httpOptions = { headers: new HttpHeaders({ "Authorization": "Basic " + btoa('APPSOC:123456') }) }; return [4 /*yield*/, this.httpClient.get(api, { headers: httpOptions.headers, responseType: "blob" }).toPromise()]; case 1: blob = _a.sent(); url = window.URL.createObjectURL(blob); w.location.href = url; return [3 /*break*/, 3]; case 2: err_3 = _a.sent(); console.log(err_3); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; Request.decorators = [ { type: Injectable } ]; /** @nocollapse */ Request.ctorParameters = function () { return [ { type: AppConfigService }, { type: HttpClient }, { type: Http }, { type: Router }, { type: Common }, { type: B2bService } ]; }; return Request; }()); export { Request }; if (false) { /** @type {?} */ Request.prototype.config; /** @type {?} */ Request.prototype.api; /** @type {?} */ Request.prototype.system_id; /** @type {?} */ Request.prototype.appConfigService; /** @type {?} */ Request.prototype.httpClient; /** @type {?} */ Request.prototype.http; /** @type {?} */ Request.prototype.router; /** @type {?} */ Request.prototype.common; /** @type {?} */ Request.prototype.b2bService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vc29jLWFwcC1saWJyYXJ5LyIsInNvdXJjZXMiOlsibGliL19zZXJ2aWNlcy9yZXF1ZXN0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFZLGVBQWUsRUFBRSxjQUFjLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDdkYsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUdoQyxPQUFPLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sS0FBSyxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBRzVCLE9BQU8sRUFBQyxVQUFVLElBQUksV0FBVyxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDL0QsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFDbEUsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQ3hDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUFDLFVBQVUsRUFBNEIsV0FBVyxFQUE0QixNQUFNLHNCQUFzQixDQUFDOztJQU85RyxpQkFBb0IsZ0JBQWtDLEVBQVMsVUFBc0IsRUFBUyxJQUFVLEVBQVUsTUFBYyxFQUFVLE1BQWMsRUFBVSxVQUFzQjtRQUFwSyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQVMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUFTLFNBQUksR0FBSixJQUFJLENBQU07UUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQVUsV0FBTSxHQUFOLE1B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QUksR0FBRyxHQUFHLENBQUE7Ozs7d0JBRXZCLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBRyxDQUFDLENBQUM7Ozs7OztLQUVwQjs7Z0JBM3dCUixVQUFVOzs7O2dCQUxILGdCQUFnQjtnQkFJaEIsVUFBVTtnQkFoQlYsSUFBSTtnQkFNSixNQUFNO2dCQU9OLE1BQU07Z0JBQ04sVUFBVTs7a0JBZmxCOztTQW1CYSxPQUFPIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7SHR0cCwgSGVhZGVycywgUmVzcG9uc2UsIFVSTFNlYXJjaFBhcmFtcywgUmVxdWVzdE9wdGlvbnN9IGZyb20gJ0Bhbmd1bGFyL2h0dHAnO1xuaW1wb3J0IHtPYnNlcnZhYmxlfSBmcm9tICdyeGpzJztcbi8vIGltcG9ydCB7IGVudmlyb25tZW50IH0gZnJvbSAnLi4vLi4vLi4vZW52aXJvbm1lbnRzL2Vudmlyb25tZW50Jztcbi8vIEltcG9ydCBSeEpzIHJlcXVpcmVkIG1ldGhvZHNcbmltcG9ydCAncnhqcy9hZGQvb3BlcmF0b3IvbWFwJztcbmltcG9ydCAncnhqcy9hZGQvb3BlcmF0b3IvY2F0Y2gnO1xuaW1wb3J0IHtSb3V0ZXJ9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgKiBhcyBpcyBmcm9tICdpc19qcyc7XG5pbXBvcnQge0N1c3RvbVN0b3JlRGF0YX0gZnJvbSAnLi4vbW9kZWwvY3VzdG9tLXN0b3JlLWRhdGEnO1xuaW1wb3J0IHtDdXN0b21TdG9yZU9wdGlvbnN9IGZyb20gJy4uL21vZGVsL2N1c3RvbS1zdG9yZS1vcHRpb25zJztcbmltcG9ydCB7UmVzdWx0Q29kZSBhcyBSRVNVTFRfQ09ERX0gZnJvbSAnLi4vbW9kZWwvcmVzdWx0LWNvZGUnO1xuaW1wb3J0IHtBcHBDb25maWdTZXJ2aWNlfSBmcm9tICcuLi9hcHAtY29uZmlnL2FwcC1jb25maWcuc2VydmljZSc7XG5pbXBvcnQge0NvbW1vbn0gZnJvbSAnLi9jb21tb24uc2VydmljZSc7XG5pbXBvcnQge0IyYlNlcnZpY2V9IGZyb20gJy4vYjJiLnNlcnZpY2UnO1xuaW1wb3J0IHtNb2RhbFNwZWxsQ2hlY2tDb21wb25lbnR9IGZyb20gJy4uL21vZGFsLXNwZWxsLWNoZWNrL21vZGFsLXNwZWxsLWNoZWNrLmNvbXBvbmVudCc7XG5pbXBvcnQge0h0dHBDbGllbnQsIEh0dHBFdmVudCwgSHR0cEV2ZW50VHlwZSwgSHR0cEhlYWRlcnMsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2V9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBSZXF1ZXN0IHtcbiAgICBjb25maWc6IGFueTtcbiAgICBhcGk6IGFueTtcbiAgICBzeXN0ZW1faWQ6IGFueTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgYXBwQ29uZmlnU2VydmljZTogQXBwQ29uZmlnU2VydmljZSwgcHVibGljIGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsIHB1YmxpYyBodHRwOiBIdHRwLCBwcml2YXRlIHJvdXRlcjogUm91dGVyLCBwcml2YXRlIGNvbW1vbjogQ29tbW9uLCBwcml2YXRlIGIyYlNlcnZpY2U6IEIyYlNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBhcHBDb25maWdTZXJ2aWNlLmdldENvbmZpZygpO1xuICAgICAgICB0aGlzLmFwaSA9IF8uZ2V0KHRoaXMuY29uZmlnLCAnYXBpU2VydmVycy50b21jYXQudXJsJyk7XG4gICAgICAgIHRoaXMuc3lzdGVtX2lkID0gXy5nZXQodGhpcy5jb25maWcsICdzeXN0ZW1faWQnKTtcbiAgICAgICAgLy8gdGhpcy5hcGkgPSAnaHR0cHM6Ly9kLmdhaXplcnMuY29tL1Jlc3RBUEknO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGZuLiBnZXQgZGF0YSDguKrguLPguKvguKPguLHguJrguJTguLbguIfguILguYnguK3guKHguLnguKXguKrguLPguKvguKPguLHguJogRGF0YWdyaWQg4LmA4LiX4LmI4Liy4LiZ4Lix4LmJ4LiZXG4gICAgICogQHBhcmFtIGN1c3RvbVN0b3JlT3B0aW9ucyDguYLguKLguJnguITguYjguLLguJXguYjguLLguIcg4LmGIOC4oeC4suC5g+C4meC4meC4teC5iVxuICAgICAqL1xuICAgIGdldEN1c3RvbVN0b3JlKGN1c3RvbVN0b3JlT3B0aW9uczogQ3VzdG9tU3RvcmVPcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IGN1c3RvbVN0b3JlT3B0aW9ucy51cmwgfHwgJyc7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBjdXN0b21TdG9yZU9wdGlvbnMuZmlsdGVyIHx8IHt9O1xuICAgICAgICBjb25zdCBsb2FkTW9kZSA9IGN1c3RvbVN0b3JlT3B0aW9ucy5sb2FkTW9kZSB8fCAncHJvY2Vzc2VkJztcbiAgICAgICAgY29uc3QgcGFyYW1zOiBVUkxTZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGRhdGEpIHtcbiAgICAgICAgICAgIGlmIChrZXkgPT09ICdmaWx0ZXInKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGFba2V5XSAhPT0gJ3t9Jykge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXMuc2V0KGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmFtcy5zZXQoa2V5LCBkYXRhW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKCfigItSZXF1ZXN0IC0+IGdldEN1c3RvbVN0b3JlIC0+IHBhcmFtcycsIHBhcmFtcyk7XG4gICAgICAgIGxldCB1c2VyRGF0YSA9IHRoaXMuYjJiU2VydmljZS5nZXRWZXJpZnlUb2tlbigpO1xuICAgICAgICBsZXQgaGVhZGVyRGF0YSA6IGFueSA9IHtcbiAgICAgICAgICAgIHN5c3RlbV9pZDogdGhpcy5zeXN0ZW1faWQsXG4gICAgICAgICAgICBkZXBhcnRtZW50OiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhICYmIHVzZXJEYXRhLnBob25lQm9va0RhdGEubGVuZ3RoID4gMCA/IHVzZXJEYXRhLnBob25lQm9va0RhdGFbMF0uZGVwdCA6IFwiXCIsXG4gICAgICAgICAgICB1c2VybmFtZTogdXNlckRhdGEudXNlcm5hbWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtVG9rZW4nLCAnMScpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgneC11c2VyLWRhdGEnLCB0aGlzLnV0b2EoSlNPTi5zdHJpbmdpZnkoaGVhZGVyRGF0YSkpKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIG9wdGlvbnMuc2VhcmNoID0gcGFyYW1zO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldCh0aGlzLmFwaSArIHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNEYXRhID0gcmVzLmpzb24oKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygn4oCLUmVxdWVzdCAtPiBnZXRDdXN0b21TdG9yZSAtPiByZXNEYXRhJywgcmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgaWYgKGxvYWRNb2RlID09PSAncHJvY2Vzc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZVJlc3BvbnNlUHJvY2Vzc2VkTW9kZShyZXNEYXRhKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZVJlc3BvbnNlUmF3TW9kZShyZXNEYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRvUHJvbWlzZSgpXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygn4oCLUmVxdWVzdCAtPiBnZXRDdXN0b21TdG9yZSAtPiBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICBpZiAobG9hZE1vZGUgPT09ICdwcm9jZXNzZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZuSGFuZGxlRXJyb3JQcm9jZXNzZWRNb2RlKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZUVycm9yUmF3TW9kZShlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBmbi4gcG9zdCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4lOC4tuC4h+C4guC5ieC4reC4oeC4ueC4peC4quC4s+C4q+C4o+C4seC4miBEYXRhZ3JpZCDguYDguJfguYjguLLguJnguLHguYnguJlcbiAgICAgKiBAcGFyYW0gY3VzdG9tU3RvcmVPcHRpb25zIOC5guC4ouC4meC4hOC5iOC4suC4leC5iOC4suC4hyDguYYg4Lih4Liy4LmD4LiZ4LiZ4Li14LmJXG4gICAgICovXG4gICAgYXN5bmMgcG9zdEN1c3RvbVN0b3JlKGN1c3RvbVN0b3JlT3B0aW9uczogQ3VzdG9tU3RvcmVPcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IGN1c3RvbVN0b3JlT3B0aW9ucy51cmwgfHwgJyc7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGN1c3RvbVN0b3JlT3B0aW9ucy5maWx0ZXIsIHRoaXMuY29tbW9uLnJlcGxhY2VyKSkgfHwge307XG4gICAgICAgIGNvbnN0IGxvYWRNb2RlID0gY3VzdG9tU3RvcmVPcHRpb25zLmxvYWRNb2RlIHx8ICdwcm9jZXNzZWQnO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IHRoaXMuc3lzdGVtX2lkLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBuZXcgUmVxdWVzdE9wdGlvbnMoe2hlYWRlcnM6IGhlYWRlcnMsIHdpdGhDcmVkZW50aWFsczogdHJ1ZX0pO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QodGhpcy5hcGkgKyB1cmwsIGRhdGEsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzRGF0YSA9IHJlcy5qc29uKCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi1JlcXVlc3QgLT4gZ2V0Q3VzdG9tU3RvcmUgLT4gcmVzRGF0YScsIHJlc0RhdGEpO1xuICAgICAgICAgICAgICAgIGlmIChsb2FkTW9kZSA9PT0gJ3Byb2Nlc3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZVByb2Nlc3NlZE1vZGUocmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZVJhd01vZGUocmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50b1Byb21pc2UoKVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi1JlcXVlc3QgLT4gZ2V0Q3VzdG9tU3RvcmUgLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgaWYgKGxvYWRNb2RlID09PSAncHJvY2Vzc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZUVycm9yUHJvY2Vzc2VkTW9kZShlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVFcnJvclJhd01vZGUoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZm4uIHBvc3QgZGF0YSDguKrguLPguKvguKPguLHguJrguJTguLbguIfguILguYnguK3guKHguLnguKXguKrguLPguKvguKPguLHguJogRGF0YWdyaWQg4LmA4LiX4LmI4Liy4LiZ4Lix4LmJ4LiZXG4gICAgICogQHBhcmFtIGN1c3RvbVN0b3JlT3B0aW9ucyDguYLguKLguJnguITguYjguLLguJXguYjguLLguIcg4LmGIOC4oeC4suC5g+C4meC4meC4teC5iVxuICAgICAqL1xuICAgIGFzeW5jIHBvc3RDdXN0b21TdG9yZTMxKGN1c3RvbVN0b3JlT3B0aW9uczogQ3VzdG9tU3RvcmVPcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IGN1c3RvbVN0b3JlT3B0aW9ucy51cmwgfHwgJyc7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGN1c3RvbVN0b3JlT3B0aW9ucy5maWx0ZXIsIHRoaXMuY29tbW9uLnJlcGxhY2VyKSkgfHwge307XG4gICAgICAgIGNvbnN0IGxvYWRNb2RlID0gY3VzdG9tU3RvcmVPcHRpb25zLmxvYWRNb2RlIHx8ICdwcm9jZXNzZWQnO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IDMxLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBuZXcgUmVxdWVzdE9wdGlvbnMoe2hlYWRlcnM6IGhlYWRlcnMsIHdpdGhDcmVkZW50aWFsczogdHJ1ZX0pO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QodGhpcy5hcGkgKyB1cmwsIGRhdGEsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzRGF0YSA9IHJlcy5qc29uKCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi1JlcXVlc3QgLT4gZ2V0Q3VzdG9tU3RvcmUgLT4gcmVzRGF0YScsIHJlc0RhdGEpO1xuICAgICAgICAgICAgICAgIGlmIChsb2FkTW9kZSA9PT0gJ3Byb2Nlc3NlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZVByb2Nlc3NlZE1vZGUocmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZVJhd01vZGUocmVzRGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50b1Byb21pc2UoKVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi1JlcXVlc3QgLT4gZ2V0Q3VzdG9tU3RvcmUgLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgaWYgKGxvYWRNb2RlID09PSAncHJvY2Vzc2VkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZUVycm9yUHJvY2Vzc2VkTW9kZShlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVFcnJvclJhd01vZGUoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog4LiW4LmJ4LiyIGdldEN1c3RvbVN0b3JlIOC5geC4peC5ieC4pyBlcnJvciDguIHguKPguJPguLUgbG9hZE1vZGUgPSAncHJvY2Vzc2VkJ1xuICAgICAqIEBwYXJhbSBlcnJvclxuICAgICAqL1xuICAgIGZuSGFuZGxlRXJyb3JQcm9jZXNzZWRNb2RlKGVycm9yKSB7XG4gICAgICAgIC8vIGFsZXJ0KCdFUlJPUiAnICsgZXJyb3IpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFUlJPUiAnICsgZXJyb3IpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICB0b3RhbENvdW50OiAwXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog4LiW4LmJ4LiyIGdldEN1c3RvbVN0b3JlIOC5geC4peC5ieC4pyBlcnJvciDguIHguKPguJPguLUgbG9hZE1vZGUgPSAncmF3J1xuICAgICAqIEBwYXJhbSBlcnJvclxuICAgICAqL1xuICAgIGZuSGFuZGxlRXJyb3JSYXdNb2RlKGVycm9yKSB7XG4gICAgICAgIC8vIGFsZXJ0KCdFUlJPUiAnICsgZXJyb3IpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFUlJPUiAnICsgZXJyb3IpO1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZm4uIGdldCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4lOC4tuC4h+C4guC5ieC4reC4oeC4ueC4peC4l+C4seC5iOC4p+C5hOC4m1xuICAgICAqIEBwYXJhbSB1cmwgZXggL3Rlc3RcbiAgICAgKiBAcGFyYW0gZGF0YSDguITguYjguLLguJXguYjguLLguIfguJfguLXguYjguJXguYnguK3guIfguIHguLLguKPguYHguJnguJrguYTguJvguIHguLHguJogQVBJXG4gICAgICovXG4gICAgZ2V0KHVybCwgZGF0YT8pIHtcbiAgICAgICAgY29uc3QgcGFyYW1zOiBVUkxTZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGRhdGEpIHtcbiAgICAgICAgICAgIGlmIChrZXkgPT09ICdmaWx0ZXInKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGFba2V5XSAhPT0gJ3t9Jykge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXMuc2V0KGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmFtcy5zZXQoa2V5LCBkYXRhW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKCfigItSZXF1ZXN0IC0+IGdldEN1c3RvbVN0b3JlIC0+IHBhcmFtcycsIHBhcmFtcyk7XG4gICAgICAgIGxldCB1c2VyRGF0YSA9IHRoaXMuYjJiU2VydmljZS5nZXRWZXJpZnlUb2tlbigpO1xuICAgICAgICBsZXQgaGVhZGVyRGF0YSA6IGFueSA9IHtcbiAgICAgICAgICAgIHN5c3RlbV9pZDogdGhpcy5zeXN0ZW1faWQsXG4gICAgICAgICAgICBkZXBhcnRtZW50OiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhICYmIHVzZXJEYXRhLnBob25lQm9va0RhdGEubGVuZ3RoID4gMCA/IHVzZXJEYXRhLnBob25lQm9va0RhdGFbMF0uZGVwdCA6IFwiXCIsXG4gICAgICAgICAgICB1c2VybmFtZTogdXNlckRhdGEudXNlcm5hbWVcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtVG9rZW4nLCAnMScpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgneC11c2VyLWRhdGEnLCB0aGlzLnV0b2EoSlNPTi5zdHJpbmdpZnkoaGVhZGVyRGF0YSkpKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyIGV5SmhiR2NpT2lKSVV6STFOaUlzSW5SNWNDSTZJa3BYVkNKOS5leUoxYzJWeWJtRnRaU0k2SWxSbGMzUWlMQ0p6WlhOemFXOXVTV1FpT2lKak56UXdORGRpWmkxak5HVXdMVFF4T1RNdE9UUmlOeTFqT0dJNE0yVmlZamhsTUdNaUxDSnBZWFFpT2pFMU5ETTVORFl5TkRZc0ltVjRjQ0k2TVRVME5EVTFNVEEwTm4wLjV5OWYyWllpZVJaSGhHSU1Ucnl4dXZzQWpKWXp2Rm5XbnBjWUxrMWhTWHcnKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIG9wdGlvbnMuc2VhcmNoID0gcGFyYW1zO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldCh0aGlzLmFwaSArIHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNEYXRhID0gcmVzLmpzb24oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZVJlc3BvbnNlKHJlc0RhdGEpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBmbi4gZ2V0IGRhdGEg4Liq4Liz4Lir4Lij4Lix4Lia4LiU4Li24LiH4LiC4LmJ4Lit4Lih4Li54Lil4LiX4Lix4LmI4Lin4LmE4LibXG4gICAgICogQHBhcmFtIHVybCBleCAvdGVzdFxuICAgICAqIEBwYXJhbSBkYXRhIOC4hOC5iOC4suC4leC5iOC4suC4h+C4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C5geC4meC4muC5hOC4m+C4geC4seC4miBBUElcbiAgICAgKi9cbiAgICBnZXQzMSh1cmwsIGRhdGE/KSB7XG4gICAgICAgIGNvbnN0IHBhcmFtczogVVJMU2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSAnZmlsdGVyJykge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhW2tleV0gIT09ICd7fScpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLnNldChrZXksIGRhdGFba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMuc2V0KGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZygn4oCLUmVxdWVzdCAtPiBnZXRDdXN0b21TdG9yZSAtPiBwYXJhbXMnLCBwYXJhbXMpO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IDMxLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciBleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKMWMyVnlibUZ0WlNJNklsUmxjM1FpTENKelpYTnphVzl1U1dRaU9pSmpOelF3TkRkaVppMWpOR1V3TFRReE9UTXRPVFJpTnkxak9HSTRNMlZpWWpobE1HTWlMQ0pwWVhRaU9qRTFORE01TkRZeU5EWXNJbVY0Y0NJNk1UVTBORFUxTVRBME5uMC41eTlmMlpZaWVSWkhoR0lNVHJ5eHV2c0FqSll6dkZuV25wY1lMazFoU1h3Jyk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBuZXcgUmVxdWVzdE9wdGlvbnMoe2hlYWRlcnM6IGhlYWRlcnMsIHdpdGhDcmVkZW50aWFsczogdHJ1ZX0pO1xuICAgICAgICBvcHRpb25zLnNlYXJjaCA9IHBhcmFtcztcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQodGhpcy5hcGkgKyB1cmwsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzRGF0YSA9IHJlcy5qc29uKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm5IYW5kbGVSZXNwb25zZShyZXNEYXRhKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IE9ic2VydmFibGUudGhyb3coZXJyb3IuanNvbigpLmVycm9yIHx8ICdTZXJ2ZXIgZXJyb3InKSkudG9Qcm9taXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZm4uIGdldCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4lOC4tuC4h+C4guC5ieC4reC4oeC4ueC4peC4l+C4seC5iOC4p+C5hOC4m1xuICAgICAqIEBwYXJhbSB1cmwgZXggL3Rlc3RcbiAgICAgKiBAcGFyYW0gZGF0YSDguITguYjguLLguJXguYjguLLguIfguJfguLXguYjguJXguYnguK3guIfguIHguLLguKPguYHguJnguJrguYTguJvguIHguLHguJogQVBJXG4gICAgICovXG4gICAgZ2V0Q3VzdG9tKHVybCwgaGVhZGVycz8pIHtcbiAgICAgICAgaWYgKCFoZWFkZXJzKSB7XG4gICAgICAgICAgICBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0gbmV3IFJlcXVlc3RPcHRpb25zKHtoZWFkZXJzOiBoZWFkZXJzfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNEYXRhID0gcmVzLmpzb24oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkhhbmRsZVJlc3BvbnNlKHJlc0RhdGEpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBmbi4gZ2V0IGRhdGEg4Liq4Liz4Lir4Lij4Lix4Lia4LiU4Li24LiH4LiC4LmJ4Lit4Lih4Li54Lil4LiX4Lix4LmI4Lin4LmE4LibXG4gICAgICogQHBhcmFtIHVybCBleCAvdGVzdFxuICAgICAqIEBwYXJhbSBkYXRhIOC4hOC5iOC4suC4leC5iOC4suC4h+C4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C5geC4meC4muC5hOC4m+C4geC4seC4miBBUElcbiAgICAgKi9cbiAgICBnZXRSYXdSZXNwb25zZSh1cmwsIGhlYWRlcnM/KSB7XG4gICAgICAgIGlmICghaGVhZGVycykge1xuICAgICAgICAgICAgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVyc30pO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldCh1cmwsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogYW55KSA9PiBPYnNlcnZhYmxlLnRocm93KGVycm9yLmpzb24oKS5lcnJvciB8fCAnU2VydmVyIGVycm9yJykpLnRvUHJvbWlzZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGZuLiBkZWxldGUgZGF0YSDguKrguLPguKvguKPguLHguJrguKXguJrguILguYnguK3guKHguLnguKXguJfguLHguYjguKfguYTguJtcbiAgICAgKiBAcGFyYW0gdXJsIGV4IC90ZXN0XG4gICAgICogQHBhcmFtIGRhdGEg4LiE4LmI4Liy4LiV4LmI4Liy4LiH4LiX4Li14LmI4LiV4LmJ4Lit4LiH4LiB4Liy4Lij4LmB4LiZ4Lia4LmE4Lib4LiB4Lix4LiaIEFQSVxuICAgICAqL1xuICAgIGRlbGV0ZSh1cmwsIGRhdGE/KSB7XG4gICAgICAgIGNvbnN0IHBhcmFtczogVVJMU2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSAnZmlsdGVyJykge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhW2tleV0gIT09ICd7fScpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLnNldChrZXksIGRhdGFba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJhbXMuc2V0KGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZygn4oCLUmVxdWVzdCAtPiBnZXRDdXN0b21TdG9yZSAtPiBwYXJhbXMnLCBwYXJhbXMpO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IHRoaXMuc3lzdGVtX2lkLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBuZXcgUmVxdWVzdE9wdGlvbnMoe2hlYWRlcnM6IGhlYWRlcnMsIHdpdGhDcmVkZW50aWFsczogdHJ1ZX0pO1xuICAgICAgICBvcHRpb25zLnNlYXJjaCA9IHBhcmFtcztcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5kZWxldGUodGhpcy5hcGkgKyB1cmwsIG9wdGlvbnMpXG4gICAgICAgICAgICAubWFwKChyZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogYW55KSA9PiBPYnNlcnZhYmxlLnRocm93KGVycm9yLmpzb24oKS5lcnJvciB8fCAnU2VydmVyIGVycm9yJykpLnRvUHJvbWlzZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGZuLiBwb3N0IGRhdGEg4Liq4Liz4Lir4Lij4Lix4Lia4Liq4Lij4LmJ4Liy4LiH4LiC4LmJ4Lit4Lih4Li54Lil4LiX4Lix4LmI4Lin4LmE4LibXG4gICAgICogQHBhcmFtIHVybCBleCAvdGVzdFxuICAgICAqIEBwYXJhbSBkYXRhIOC4hOC5iOC4suC4leC5iOC4suC4h+C4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C5geC4meC4muC5hOC4m+C4geC4seC4miBBUElcbiAgICAgKi9cbiAgICBwb3N0KHVybCwgZGF0YSkge1xuICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkYXRhLCB0aGlzLmNvbW1vbi5yZXBsYWNlcikpO1xuICAgICAgICBjb25zb2xlLmxvZygn4oCLcG9zdCAtPiBkYXRhJywgZGF0YSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCfigItwb3N0IC0+IGRhdGEnLCB0eXBlb2YgZGF0YSk7XG4gICAgICAgIGNvbnN0IHBhcmFtczogVVJMU2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IHRoaXMuc3lzdGVtX2lkLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gbmV3IFJlcXVlc3RPcHRpb25zKHtoZWFkZXJzOiBoZWFkZXJzLCB3aXRoQ3JlZGVudGlhbHM6IHRydWV9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHRoaXMuYXBpICsgdXJsLCBkYXRhLCBvcHRpb25zKVxuICAgICAgICAgICAgLm1hcCgocmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBmbi4gcG9zdCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4quC4o+C5ieC4suC4h+C4guC5ieC4reC4oeC4ueC4peC4l+C4seC5iOC4p+C5hOC4m1xuICAgICAqIEBwYXJhbSB1cmwgZXggL3Rlc3RcbiAgICAgKiBAcGFyYW0gZGF0YSDguITguYjguLLguJXguYjguLLguIfguJfguLXguYjguJXguYnguK3guIfguIHguLLguKPguYHguJnguJrguYTguJvguIHguLHguJogQVBJXG4gICAgICovXG4gICAgcG9zdDMxKHVybCwgZGF0YSkge1xuICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkYXRhLCB0aGlzLmNvbW1vbi5yZXBsYWNlcikpO1xuICAgICAgICBjb25zb2xlLmxvZygn4oCLcG9zdCAtPiBkYXRhJywgZGF0YSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCfigItwb3N0IC0+IGRhdGEnLCB0eXBlb2YgZGF0YSk7XG4gICAgICAgIGNvbnN0IHBhcmFtczogVVJMU2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgICBsZXQgdXNlckRhdGEgPSB0aGlzLmIyYlNlcnZpY2UuZ2V0VmVyaWZ5VG9rZW4oKTtcbiAgICAgICAgbGV0IGhlYWRlckRhdGEgOiBhbnkgPSB7XG4gICAgICAgICAgICBzeXN0ZW1faWQ6IDMxLFxuICAgICAgICAgICAgZGVwYXJ0bWVudDogdXNlckRhdGEucGhvbmVCb29rRGF0YSAmJiB1c2VyRGF0YS5waG9uZUJvb2tEYXRhLmxlbmd0aCA+IDAgPyB1c2VyRGF0YS5waG9uZUJvb2tEYXRhWzBdLmRlcHQgOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IHVzZXJEYXRhLnVzZXJuYW1lXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LVRva2VuJywgJzEnKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ3gtdXNlci1kYXRhJywgdGhpcy51dG9hKEpTT04uc3RyaW5naWZ5KGhlYWRlckRhdGEpKSk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gbmV3IFJlcXVlc3RPcHRpb25zKHtoZWFkZXJzOiBoZWFkZXJzLCB3aXRoQ3JlZGVudGlhbHM6IHRydWV9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHRoaXMuYXBpICsgdXJsLCBkYXRhLCBvcHRpb25zKVxuICAgICAgICAgICAgLm1hcCgocmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogZm4uIHBvc3QgZGF0YSDguKrguLPguKvguKPguLHguJrguKrguKPguYnguLLguIfguILguYnguK3guKHguLnguKXguJfguLHguYjguKfguYTguJtcbiAgICAgKiBAcGFyYW0gdXJsIGV4IC90ZXN0XG4gICAgICogQHBhcmFtIGRhdGEg4LiE4LmI4Liy4LiV4LmI4Liy4LiH4LiX4Li14LmI4LiV4LmJ4Lit4LiH4LiB4Liy4Lij4LmB4LiZ4Lia4LmE4Lib4LiB4Lix4LiaIEFQSVxuICAgICAqL1xuICAgIHBvc3QxNCh1cmwsIGRhdGEpIHtcbiAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGF0YSwgdGhpcy5jb21tb24ucmVwbGFjZXJub3RyaW0pKTtcbiAgICAgICAgY29uc29sZS5sb2coJ+KAi3Bvc3QgLT4gZGF0YScsIGRhdGEpO1xuICAgICAgICBjb25zb2xlLmxvZygn4oCLcG9zdCAtPiBkYXRhJywgdHlwZW9mIGRhdGEpO1xuICAgICAgICBjb25zdCBwYXJhbXM6IFVSTFNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICAgICAgbGV0IHVzZXJEYXRhID0gdGhpcy5iMmJTZXJ2aWNlLmdldFZlcmlmeVRva2VuKCk7XG4gICAgICAgIGxldCBoZWFkZXJEYXRhIDogYW55ID0ge1xuICAgICAgICAgICAgc3lzdGVtX2lkOiB0aGlzLnN5c3RlbV9pZCxcbiAgICAgICAgICAgIGRlcGFydG1lbnQ6IHVzZXJEYXRhLnBob25lQm9va0RhdGEgJiYgdXNlckRhdGEucGhvbmVCb29rRGF0YS5sZW5ndGggPiAwID8gdXNlckRhdGEucGhvbmVCb29rRGF0YVswXS5kZXB0IDogXCJcIixcbiAgICAgICAgICAgIHVzZXJuYW1lOiB1c2VyRGF0YS51c2VybmFtZVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgneC1Ub2tlbicsICcxJyk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LXVzZXItZGF0YScsIHRoaXMudXRvYShKU09OLnN0cmluZ2lmeShoZWFkZXJEYXRhKSkpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh0aGlzLmFwaSArIHVybCwgZGF0YSwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IE9ic2VydmFibGUudGhyb3coZXJyb3IuanNvbigpLmVycm9yIHx8ICdTZXJ2ZXIgZXJyb3InKSkudG9Qcm9taXNlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGZuLiBwb3N0IGRhdGEg4Liq4Liz4Lir4Lij4Lix4Lia4Liq4Lij4LmJ4Liy4LiH4LiC4LmJ4Lit4Lih4Li54Lil4LiX4Lix4LmI4Lin4LmE4LibXG4gICAgICogQHBhcmFtIHVybCBleCAvdGVzdFxuICAgICAqIEBwYXJhbSBkYXRhIOC4hOC5iOC4suC4leC5iOC4suC4h+C4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C5geC4meC4muC5hOC4m+C4geC4seC4miBBUElcbiAgICAgKi9cbiAgICBwb3N0Q3VzdG9tKHVybCwgZGF0YSwgaGVhZGVycz8pIHtcbiAgICAgICAgY29uc29sZS5sb2coJ+KAi3Bvc3QgLT4gZGF0YScsIGRhdGEpO1xuICAgICAgICBjb25zb2xlLmxvZygn4oCLcG9zdCAtPiBkYXRhJywgdHlwZW9mIGRhdGEpXG4gICAgICAgIGlmICghaGVhZGVycykge1xuICAgICAgICAgICAgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgICAgICBoZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0gbmV3IFJlcXVlc3RPcHRpb25zKHtoZWFkZXJzOiBoZWFkZXJzLCB3aXRoQ3JlZGVudGlhbHM6IHRydWV9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHVybCwgZGF0YSwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IE9ic2VydmFibGUudGhyb3coZXJyb3IuanNvbigpLmVycm9yIHx8ICdTZXJ2ZXIgZXJyb3InKSkudG9Qcm9taXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZm4uIHB1dCBkYXRhIOC4quC4s+C4q+C4o+C4seC4muC4reC4seC4nuC5gOC4lOC4leC4guC5ieC4reC4oeC4ueC4peC4l+C4seC5iOC4p+C5hOC4m1xuICAgICAqIEBwYXJhbSB1cmwgZXggL3Rlc3RcbiAgICAgKiBAcGFyYW0gZGF0YSDguITguYjguLLguJXguYjguLLguIfguJfguLXguYjguJXguYnguK3guIfguIHguLLguKPguYHguJnguJrguYTguJvguIHguLHguJogQVBJXG4gICAgICovXG4gICAgcHV0KHVybCwgZGF0YSkge1xuICAgICAgICBjb25zdCBwYXJhbXM6IFVSTFNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICAgICAgbGV0IHVzZXJEYXRhID0gdGhpcy5iMmJTZXJ2aWNlLmdldFZlcmlmeVRva2VuKCk7XG4gICAgICAgIGxldCBoZWFkZXJEYXRhIDogYW55ID0ge1xuICAgICAgICAgICAgc3lzdGVtX2lkOiB0aGlzLnN5c3RlbV9pZCxcbiAgICAgICAgICAgIGRlcGFydG1lbnQ6IHVzZXJEYXRhLnBob25lQm9va0RhdGEgJiYgdXNlckRhdGEucGhvbmVCb29rRGF0YS5sZW5ndGggPiAwID8gdXNlckRhdGEucGhvbmVCb29rRGF0YVswXS5kZXB0IDogXCJcIixcbiAgICAgICAgICAgIHVzZXJuYW1lOiB1c2VyRGF0YS51c2VybmFtZVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgneC1Ub2tlbicsICcxJyk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCd4LXVzZXItZGF0YScsIHRoaXMudXRvYShKU09OLnN0cmluZ2lmeShoZWFkZXJEYXRhKSkpO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAucHV0KHRoaXMuYXBpICsgdXJsLCBkYXRhLCBvcHRpb25zKVxuICAgICAgICAgICAgLm1hcCgocmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IGFueSkgPT4gT2JzZXJ2YWJsZS50aHJvdyhlcnJvci5qc29uKCkuZXJyb3IgfHwgJ1NlcnZlciBlcnJvcicpKS50b1Byb21pc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDguJbguYnguLIgZ2V0Q3VzdG9tU3RvcmUg4LmB4Lil4LmJ4LinIHN1Y2Nlc3Mg4LiB4Lij4LiT4Li1IGxvYWRNb2RlID0gJ3Byb2Nlc3NlZCdcbiAgICAgKiBAcGFyYW0gcmVzRGF0YVxuICAgICAqL1xuICAgIGZuSGFuZGxlUmVzcG9uc2VQcm9jZXNzZWRNb2RlKHJlc0RhdGEpIHtcbiAgICAgICAgY29uc3QgY3VzdG9tU3RvcmVEYXRhID0ge1xuICAgICAgICAgICAgZGF0YTogW10sXG4gICAgICAgICAgICB0b3RhbENvdW50OiAwXG4gICAgICAgIH07XG4gICAgICAgIGxldCBjb2RlID0gJyc7XG4gICAgICAgIGxldCBkZXNjcmlwdGlvbiA9ICcnO1xuICAgICAgICBsZXQgZGF0YSA9IFtdO1xuICAgICAgICBsZXQgcm93Q291bnQgPSAwO1xuICAgICAgICBpZiAoaXMuYXJyYXkocmVzRGF0YSkpIHtcbiAgICAgICAgICAgIGRhdGEgPSByZXNEYXRhO1xuICAgICAgICAgICAgcm93Q291bnQgPSBfLnNpemUoZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvKiog4LmA4Lib4Lil4Li14LmI4Lii4LiZ4LmE4Lib4LiV4Liy4Lih4Lij4Li54Lib4LmB4Lia4LiaIHJlc3BvbnNlICovXG4gICAgICAgICAgICBjb2RlID0gcmVzRGF0YS5yZXN1bHRDb2RlIHx8ICcnO1xuICAgICAgICAgICAgZGVzY3JpcHRpb24gPSByZXNEYXRhLnJlc3VsdERlc2NyaXB0aW9uIHx8ICcnO1xuICAgICAgICAgICAgZGF0YSA9IHJlc0RhdGEucmVzdWx0RGF0YSB8fCBbXTtcbiAgICAgICAgICAgIHJvd0NvdW50ID0gcmVzRGF0YS5yb3dDb3VudCB8fCAwOyAvLyDguYDguJvguKXguLXguYjguKLguJnguYTguJvguJXguLLguKEgUmVzcG9uc2VcbiAgICAgICAgICAgIC8qKiAqL1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb2RlID09PSBSRVNVTFRfQ09ERS5FUlJPUikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi2ZuSGFuZGxlUmVzcG9uc2VQcm9jZXNzZWRNb2RlIC0+IFJFU1VMVF9DT0RFLkVSUk9SJywgUkVTVUxUX0NPREUuRVJST1IpO1xuICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPT09IFJFU1VMVF9DT0RFLk5PVF9GT1VORCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ+KAi2ZuSGFuZGxlUmVzcG9uc2VQcm9jZXNzZWRNb2RlIC0+IFJFU1VMVF9DT0RFLk5PVF9GT1VORCcsIFJFU1VMVF9DT0RFLk5PVF9GT1VORCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdXN0b21TdG9yZURhdGEuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgICBjdXN0b21TdG9yZURhdGEudG90YWxDb3VudCA9IHJvd0NvdW50O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjdXN0b21TdG9yZURhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog4LiW4LmJ4LiyIGdldEN1c3RvbVN0b3JlIOC5geC4peC5ieC4pyBzdWNjZXNzIOC4geC4o+C4k+C4tSBsb2FkTW9kZSA9ICdyYXcnXG4gICAgICogQHBhcmFtIHJlc0RhdGFcbiAgICAgKi9cbiAgICBmbkhhbmRsZVJlc3BvbnNlUmF3TW9kZShyZXNEYXRhKSB7XG4gICAgICAgIGxldCBjb2RlID0gJyc7XG4gICAgICAgIGxldCBkZXNjcmlwdGlvbiA9ICcnO1xuICAgICAgICBsZXQgZGF0YSA9IFtdO1xuICAgICAgICBpZiAoaXMuYXJyYXkocmVzRGF0YSkpIHtcbiAgICAgICAgICAgIGRhdGEgPSByZXNEYXRhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLyoqIOC5gOC4m+C4peC4teC5iOC4ouC4meC5hOC4m+C4leC4suC4oeC4o+C4ueC4m+C5geC4muC4miByZXNwb25zZSAqL1xuICAgICAgICAgICAgY29kZSA9IHJlc0RhdGEucmVzdWx0Q29kZSB8fCAnJztcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gcmVzRGF0YS5yZXN1bHREZXNjcmlwdGlvbiB8fCAnJztcbiAgICAgICAgICAgIGRhdGEgPSByZXNEYXRhLnJlc3VsdERhdGEgfHwgW107XG4gICAgICAgICAgICAvKiogKi9cbiAgICAgICAgfVxuICAgICAgICBpZiAoY29kZSA9PT0gUkVTVUxUX0NPREUuRVJST1IpIHtcbiAgICAgICAgICAgIGFsZXJ0KCdFUlJPUjonICsgUkVTVUxUX0NPREUuRVJST1IpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPT09IFJFU1VMVF9DT0RFLk5PVF9GT1VORCkge1xuICAgICAgICAgICAgYWxlcnQoJ0VSUk9SOicgKyBSRVNVTFRfQ09ERS5OT1RfRk9VTkQpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmbkhhbmRsZVJlc3BvbnNlKHJlc0RhdGEpIHtcbiAgICAgICAgbGV0IGNvZGUgPSAnJztcbiAgICAgICAgbGV0IGRlc2NyaXB0aW9uID0gJyc7XG4gICAgICAgIGxldCBkYXRhID0gW107XG4gICAgICAgIGlmIChpcy5hcnJheShyZXNEYXRhKSkge1xuICAgICAgICAgICAgZGF0YSA9IHJlc0RhdGE7XG4gICAgICAgIH1lbHNlIGlmKHJlc0RhdGEuZGF0YSAmJiBpcy5hcnJheShyZXNEYXRhLmRhdGEpKXtcbiAgICAgICAgICAgIGRhdGEgPSByZXNEYXRhLmRhdGE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvKiog4LmA4Lib4Lil4Li14LmI4Lii4LiZ4LmE4Lib4LiV4Liy4Lih4Lij4Li54Lib4LmB4Lia4LiaIHJlc3BvbnNlICovXG4gICAgICAgICAgICBjb2RlID0gcmVzRGF0YS5yZXN1bHRDb2RlIHx8ICcnO1xuICAgICAgICAgICAgZGVzY3JpcHRpb24gPSByZXNEYXRhLnJlc3VsdERlc2NyaXB0aW9uIHx8ICcnO1xuICAgICAgICAgICAgZGF0YSA9IHJlc0RhdGEucmVzdWx0RGF0YSB8fCBbXTtcbiAgICAgICAgICAgIC8qKiAqL1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvZGUgPT09IFJFU1VMVF9DT0RFLkVSUk9SKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygn4oCLZm5IYW5kbGVSZXNwb25zZSAtPiBSRVNVTFRfQ09ERS5FUlJPUicsIFJFU1VMVF9DT0RFLkVSUk9SKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfSBlbHNlIGlmIChjb2RlID09PSBSRVNVTFRfQ09ERS5OT1RfRk9VTkQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCfigItmbkhhbmRsZVJlc3BvbnNlIC0+IFJFU1VMVF9DT0RFLk5PVF9GT1VORCcsIFJFU1VMVF9DT0RFLk5PVF9GT1VORCk7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGZuIOC4lOC4tuC4h+C4guC5ieC4reC4oeC4ueC4peC5gOC4nuC4t+C5iOC4reC5g+C4iuC5ieC5g+C4mSBEcm9wZG93biBMaXN0XG4gICAgICogQHBhcmFtIHN5c3RlbUlkIOC5gOC4peC4guC4o+C4q+C4seC4quC4o+C4sOC4muC4muC4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C4lOC4tuC4h1xuICAgICAqIEBwYXJhbSBkcm9wRG93blR5cGUg4Lib4Lij4Liw4LmA4Lig4LiX4LiC4LmJ4Lit4Lih4Li54LilIGRyb3Bkb3duIOC4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C4lOC4tuC4h1xuICAgICAqL1xuICAgIGFzeW5jIGdldERyb3BEb3duKHN5c3RlbUlkOiBudW1iZXIsIGRyb3BEb3duVHlwZTogU3RyaW5nLCBjb2RlPzogU3RyaW5nKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgICAgIGZpbHRlcjoge1xuICAgICAgICAgICAgICAgICAgICBzeXN0ZW1faWQ6IHN5c3RlbUlkLFxuICAgICAgICAgICAgICAgICAgICBkcm9wZG93bl90eXBlOiBkcm9wRG93blR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IGNvZGVcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpbWl0OiAxMDAwLFxuICAgICAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgICAgICBvcmRlcl9ieTogWydpZCBhc2MnXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHVybERyb3Bkb3duID0gXy5nZXQodGhpcy5jb25maWcsICdhcGlTZXJ2ZXJzLnRvbWNhdC5hcGkuY3RfZHJvcGRvd25fc2VhcmNoJyk7XG4gICAgICAgICAgICBpZihzeXN0ZW1JZCA9PT0gMzEpe1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QzMSh1cmxEcm9wZG93biwgZGF0YSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc0RhdGEucmVzdWx0RGF0YTtcbiAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QodXJsRHJvcGRvd24sIGRhdGEpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNEYXRhLnJlc3VsdERhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnY2F0Y2ggLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBnZXREZXBhcnRtZW50KHBhcmVudElkOiBudW1iZXIgPSAwKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgICAgIGZpbHRlcjoge3JlZl9kZXBhcnRtZW50X2lkOiBwYXJlbnRJZH0sXG4gICAgICAgICAgICAgICAgbGltaXQ6IDEwMDAsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiAwLFxuICAgICAgICAgICAgICAgIG9yZGVyX2J5OiBbJ25hbWUgYXNjJ11cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCB1cmxEcm9wZG93biA9IF8uZ2V0KHRoaXMuY29uZmlnLCAnYXBpU2VydmVycy50b21jYXQuYXBpLmN0X2RlcGFydG1lbnRfc2VhcmNoJyk7XG4gICAgICAgICAgICBjb25zdCByZXNEYXRhID0gYXdhaXQgdGhpcy5wb3N0KHVybERyb3Bkb3duLCBkYXRhKTtcbiAgICAgICAgICAgIHJldHVybiByZXNEYXRhLnJlc3VsdERhdGE7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnY2F0Y2ggLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBnZXRFeHREZXBhcnRtZW50KCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICBmaWx0ZXI6IHt9LFxuICAgICAgICAgICAgICAgIGxpbWl0OiAxMDAwLFxuICAgICAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgICAgICBvcmRlcl9ieTogWyduYW1lIGFzYyddXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgdXJsRHJvcGRvd24gPSBfLmdldCh0aGlzLmNvbmZpZywgJ2FwaVNlcnZlcnMudG9tY2F0LmFwaS5jdF9leHRfZGVwYXJ0bWVudF9zZWFyY2gnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QodXJsRHJvcGRvd24sIGRhdGEpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc0RhdGEucmVzdWx0RGF0YTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjYXRjaCAtPiBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGdldENhdGVnb3J5KHN5c3RlbV9pZCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgdXJsU3RlcCA9IF8uZ2V0KHRoaXMuY29uZmlnLCAnYXBpU2VydmVycy50b21jYXQuYXBpLmN0X2NhdGVnb3J5Jyk7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBgP193aGVyZT0oc3lzdGVtX2lkLGVxLCR7c3lzdGVtX2lkfSkmX3NvcnQ9c2VxX25vYDtcbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLmdldCh1cmxTdGVwICsgcGFyYW1zKTtcbiAgICAgICAgICAgIHJldHVybiByZXNEYXRhO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ2NhdGNoIC0+IGVycm9yJywgZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0U3RlcE5hbWUoY2F0ZWdvcnlfaWQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHVybFN0ZXAgPSBfLmdldCh0aGlzLmNvbmZpZywgJ2FwaVNlcnZlcnMudG9tY2F0LmFwaS5jdF9zdGVwJyk7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBgP193aGVyZT0oY2F0ZWdvcnlfaWQsZXEsJHtjYXRlZ29yeV9pZH0pJl9zb3J0PXNlcV9ub2A7XG4gICAgICAgICAgICBjb25zdCByZXNEYXRhID0gYXdhaXQgdGhpcy5nZXQodXJsU3RlcCArIHBhcmFtcyk7XG4gICAgICAgICAgICByZXR1cm4gcmVzRGF0YTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjYXRjaCAtPiBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGdldEF0dGFjaG1lbnQodXJsKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgICAgIGhlYWRlcnMuYXBwZW5kKCdBdXRob3JpemF0aW9uJywgJ0Jhc2ljICcgKyBidG9hKCdBUFBTT0M6MTIzNDU2JykpO1xuICAgICAgICAgICAgY29uc3QgcmVzRGF0YSA9IGF3YWl0IHRoaXMuZ2V0Q3VzdG9tKHVybCwgaGVhZGVycyk7XG4gICAgICAgICAgICByZXR1cm4gcmVzRGF0YTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjYXRjaCAtPiBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHBvc3RBdHRhY2htZW50KHVybCwgZGF0YSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgICAgICBoZWFkZXJzLmFwcGVuZCgnQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgYnRvYSgnQVBQU09DOjEyMzQ1NicpKTtcbiAgICAgICAgICAgIGhlYWRlcnMuYXBwZW5kKCd0ZXN0JywgJ3Rlc3QnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3RDdXN0b20odXJsLCBkYXRhLCBoZWFkZXJzKTtcbiAgICAgICAgICAgIHJldHVybiByZXNEYXRhO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ2NhdGNoIC0+IGVycm9yJywgZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0VXNlckxldmVsKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICBmaWx0ZXI6IHt9LFxuICAgICAgICAgICAgICAgIGxpbWl0OiAxMDAwLFxuICAgICAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgICAgICBvcmRlcl9ieTogWydsZXZlbCBhc2MnXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHVybERyb3Bkb3duID0gXy5nZXQodGhpcy5jb25maWcsICdhcGlTZXJ2ZXJzLnRvbWNhdC5hcGkuY3RfdXNlcl9sZXZlbF9zZWFyY2gnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QodXJsRHJvcGRvd24sIGRhdGEpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc0RhdGE7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnY2F0Y2ggLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBtdWx0aXBsZURlbGV0ZU1haW4odGFibGUsIGlkTGlzdCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHVybCA9IFwiL1wiICsgdGFibGUuc3BsaXQoXCJfXCIpWzBdICsgXCIvbWFpblwiO1xuICAgICAgICAgICAgbGV0IGRlbGV0ZU9iajogYW55ID0ge307XG4gICAgICAgICAgICBkZWxldGVPYmpbdGFibGVdID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBpZCBvZiBpZExpc3QpIHtcbiAgICAgICAgICAgICAgICBsZXQgdG1wID0ge1xuICAgICAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbjogXCJkZWxldGVcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGVPYmpbdGFibGVdLnB1c2godG1wKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnBvc3QodXJsLCBbZGVsZXRlT2JqXSk7XG4gICAgICAgICAgICBpZiAocmVzRGF0YS5yZXN1bHRDb2RlID09PSAyMDAwMCkge1xuICAgICAgICAgICAgICAgIGlkTGlzdCA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc0RhdGE7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnY2F0Y2ggLT4gZXJyb3InLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBnZXRBdHRhY2htZW50TGlua1Rva2VuKHVybCkge1xuICAgICAgICByZXR1cm4gdXJsICsgJz9kb3dubG9hZFRva2VuPScgKyB0aGlzLmIyYlNlcnZpY2UuZ2V0QXR0YWNobWVudFRva2VuKCkgKycmaW5saW5lPXRydWUnO1xuICAgIH1cblxuICAgIGFzeW5jIGNoZWNrU3BlbGwoZGF0YSwgZmllbGRMaXN0LCBtb2RhbDogTW9kYWxTcGVsbENoZWNrQ29tcG9uZW50KSB7XG4gICAgICAgIGxldCB1cmwgPSBcIi9zcGVsbENoZWNrXCI7XG4gICAgICAgIGxldCBib2R5OiBhbnkgPSB7fTtcbiAgICAgICAgZm9yIChsZXQgZmllbGQgb2YgZmllbGRMaXN0KSB7XG4gICAgICAgICAgICBpZiAoZGF0YVtmaWVsZC5maWVsZF0pIHtcbiAgICAgICAgICAgICAgICBib2R5W2ZpZWxkLmZpZWxkXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGRhdGFbZmllbGQuZmllbGRdLFxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5OiBmaWVsZC5kaXNwbGF5XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzRGF0YSA9IGF3YWl0IHRoaXMucG9zdCh1cmwsIGJvZHkpO1xuICAgICAgICBsZXQgc3BlbGxDaGVjayA9IEpTT04ucGFyc2UocmVzRGF0YS5yZXN1bHREYXRhKTtcbiAgICAgICAgaWYgKF8uc2l6ZShzcGVsbENoZWNrKSA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtb2RhbC5vcGVuKHNwZWxsQ2hlY2spO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0UXVhbGlmaWNhdGlvbih1cmwsIGhlYWRlcnM/KSB7XG4gICAgICAgIGlmICghaGVhZGVycykge1xuICAgICAgICAgICAgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG5ldyBSZXF1ZXN0T3B0aW9ucyh7aGVhZGVyczogaGVhZGVycywgd2l0aENyZWRlbnRpYWxzOiB0cnVlfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgIC5tYXAoKHJlczogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBhbnkpID0+IE9ic2VydmFibGUudGhyb3coZXJyb3IuanNvbigpLmVycm9yIHx8ICdTZXJ2ZXIgZXJyb3InKSkudG9Qcm9taXNlKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgdmVyaWZ5VXNlck5hbWUoKSB7XG4gICAgICAgIGxldCB2ZXJpZnlUb2tlbjogYW55ID0gYXdhaXQgdGhpcy5iMmJTZXJ2aWNlLnZlcmlmeSgpO1xuICAgICAgICBpZiAoK3ZlcmlmeVRva2VuLnJlc3VsdENvZGUgPT09IDIwMDAwKSB7XG4gICAgICAgICAgICBsZXQgZGF0YSA9IHZlcmlmeVRva2VuLnJlc3VsdERhdGE7XG4gICAgICAgICAgICBsZXQgcGhvbmVCb29rRGF0YSA9IGRhdGEucGhvbmVCb29rRGF0YSAmJiBkYXRhLnBob25lQm9va0RhdGEubGVuZ3RoID4gMCA/IGRhdGEucGhvbmVCb29rRGF0YVswXSA6IHt9O1xuICAgICAgICAgICAgcmV0dXJuIHBob25lQm9va0RhdGEubmFtZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHV0b2Eoc3RyKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuYnRvYSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSkpO1xuICAgIH1cblxuICAgIGRvd25sb2FkSW1nVG9CYXNlNjQoYXBpKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4gIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBodHRwT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiBuZXcgSHR0cEhlYWRlcnMoeyBcIkF1dGhvcml6YXRpb25cIjogXCJCYXNpYyBcIitidG9hKCdBUFBTT0M6MTIzNDU2JykgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgbGV0IGJsb2IgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQuZ2V0KGFwaSwgeyBoZWFkZXJzOiBodHRwT3B0aW9ucy5oZWFkZXJzLCByZXNwb25zZVR5cGU6IFwiYmxvYlwiIH0pLnRvUHJvbWlzZSgpXG4gICAgICAgICAgIGxldCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoYmxvYik7XG4gICAgICAgICAgICByZWFkZXIub25sb2FkZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJhc2U2NGRhdGEgPSByZWFkZXIucmVzdWx0O1xuICAgICAgICAgICAgICAgIHJlc29sdmUoYmFzZTY0ZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBkb3dubG9hZFZpZXcoYXBpOmFueSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGh0dHBPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IG5ldyBIdHRwSGVhZGVycyh7IFwiQXV0aG9yaXphdGlvblwiOiBcIkJhc2ljIFwiK2J0b2EoJ0FQUFNPQzoxMjM0NTYnKSB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGJsb2IgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQuZ2V0KGFwaSwgeyBoZWFkZXJzOiBodHRwT3B0aW9ucy5oZWFkZXJzLCByZXNwb25zZVR5cGU6IFwiYmxvYlwiIH0pLnRvUHJvbWlzZSgpXG4gICAgICAgICAgICBsZXQgdXJsID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYiwgeyBvbmVUaW1lT25seTogdHJ1ZSB9KVxuICAgICAgICAgICAgIHdpbmRvdy5vcGVuKHVybCwnX2JsYW5rJyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYXN5bmMgZG93bmxvYWQoYXBpOmFueSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGxldCB3ID0gd2luZG93Lm9wZW4oKVxuICAgICAgICAgICAgICB3LmRvY3VtZW50LndyaXRlbG4oXCJcIilcbiAgICAgICAgICAgICAgbGV0IGh0dHBPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogbmV3IEh0dHBIZWFkZXJzKHsgXCJBdXRob3JpemF0aW9uXCI6IFwiQmFzaWMgXCIrYnRvYSgnQVBQU09DOjEyMzQ1NicpIH0pXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGV0IGJsb2IgPSBhd2FpdCB0aGlzLmh0dHBDbGllbnQuZ2V0KGFwaSwgeyBoZWFkZXJzOiBodHRwT3B0aW9ucy5oZWFkZXJzLCByZXNwb25zZVR5cGU6IFwiYmxvYlwiIH0pLnRvUHJvbWlzZSgpXG4gICAgICAgICAgICAgIGxldCB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKVxuICAgICAgICAgICAgICB3LmxvY2F0aW9uLmhyZWYgPSB1cmxcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbn1cbiJdfQ==