@ema/js-base-library
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0.
367 lines • 30.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
export class BaseApi {
constructor() {
this.headers = {};
this.routes = {};
this.baseUrl = '/api';
this.idField = 'id';
this.requestCredentials = 'same-origin'; // include, same-origin, *omit (default)
// include, same-origin, *omit (default)
this.corsMode = 'same-origin'; // no-cors, cors, *same-origin (default)
// no-cors, cors, *same-origin (default)
this.cachePolicy = 'no-cache'; // *default, no-cache, reload, force-cache, only-if-cached
this.entities = {};
this.hasDebugger = false;
}
/**
* @param {?} settings
* @return {?}
*/
init(settings) {
this.settings = settings;
if (this.settings.host) {
this.baseUrl = settings.host;
}
if (this.settings.routes) {
this.initApiRoutes(this.settings.routes);
}
if (this.settings.headers) {
/** @type {?} */
const self = this;
this.settings.headers.forEach((/**
* @param {?} obj
* @return {?}
*/
(obj) => {
for (const k in obj) {
self.headers[k] = obj[k];
}
}));
}
if (this['httpHeaders']) {
// AngularJs only
Object.keys(this.headers).forEach((/**
* @param {?} k
* @return {?}
*/
(k) => {
this['httpHeaders'].set(k, this.headers[k]);
}));
}
// if ('withCredentials' in new XMLHttpRequest) {
// this.cors = true;
// }
}
;
/**
* @param {?} url
* @return {?}
*/
route(url) {
/** @type {?} */
let mappedUrl;
Object.keys(this.routes).forEach((/**
* @param {?} k
* @return {?}
*/
(k) => {
if (k === url) {
mappedUrl = this.routes[k];
}
}));
if (mappedUrl) {
return mappedUrl;
}
else {
return url;
}
}
// CRUD
/**
* @param {?} path
* @param {?} data
* @return {?}
*/
post(path, data) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
/** @type {?} */
const result = yield fetch(`${this.baseUrl}${path}`, {
body: JSON.stringify(data),
// must match 'Content-Type' header
cache: this.cachePolicy,
credentials: this.requestCredentials,
headers: this.headers,
mode: this.corsMode,
method: 'POST',
})
.then((/**
* @param {?} response
* @return {?}
*/
(response) => {
if (response.status >= 400) {
console.log(response);
console.error('Bad response from server');
return response;
}
return response.json();
}))
.catch(this.errorHandler)
.then((/**
* @param {?} data
* @return {?}
*/
(data) => {
return data;
}));
return result;
});
}
/**
* @param {?} path
* @param {?=} params
* @return {?}
*/
get(path, params = undefined) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (params) {
path += '?';
Object.keys(params).forEach((/**
* @param {?} key
* @return {?}
*/
key => path += key + '=' + params[key] + '&'));
}
/** @type {?} */
const result = yield fetch(`${this.baseUrl}${path}`, {
cache: this.cachePolicy,
credentials: this.requestCredentials,
headers: this.headers,
mode: this.corsMode,
method: 'GET',
}).then((/**
* @param {?} response
* @return {?}
*/
(response) => {
if (response.status >= 400) {
console.log(response);
console.log('Bad response from server');
return response;
}
return response.json();
}))
.catch(this.errorHandler)
.then((/**
* @param {?} data
* @return {?}
*/
(data) => {
return data;
}));
return result;
});
}
// todo: patch
/**
* @param {?} path
* @param {?} id
* @param {?} data
* @return {?}
*/
patch(path, id, data) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
yield fetch(`${this.baseUrl}${path}/` + id, {
headers: this.headers,
// method: 'PATCH',
method: 'patch',
body: JSON.stringify(data)
});
});
}
// fixme: causes php server error on drupal content page
/**
* @param {?} path
* @param {?} id
* @return {?}
*/
delete(path, id) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
console.log(path, id);
// await fetch(`${this.baseUrl}${path}/` + id, {
// headers: this.headers,
// // method: 'DELETE'
// method: 'delete'
// });
});
}
/**
* @param {?} username
* @param {?} password
* @return {?}
*/
login(username, password) {
console.log(username, password.length);
}
/**
* @param {?=} namespace
* @param {?=} refresh
* @return {?}
*/
logout(namespace = 'app:authData', refresh = false) {
this.clearCredentials(namespace);
this.settings.authenticated = false;
if (refresh) {
// location.href = location.origin;
location.href = location.href;
}
}
// todo: use btoa + atob
/**
* @param {?} credentials
* @param {?=} namespace
* @return {?}
*/
setCredentials(credentials, namespace = 'app-auth') {
this.credentials = credentials;
// window.localStorage.setItem(namespace, btoa(JSON.stringify(credentials)));
if (typeof window !== 'undefined' && window.localStorage) {
window.localStorage.setItem(namespace, JSON.stringify(credentials));
}
}
/**
* @param {?=} namespace
* @return {?}
*/
getCredentials(namespace = 'app:authData') {
if (typeof window !== 'undefined' && window.localStorage && window.localStorage.getItem(namespace)) {
// return JSON.parse(atob(window.localStorage.getItem(namespace)));
return JSON.parse(window.localStorage.getItem(namespace));
}
}
/**
* @param {?=} namespace
* @return {?}
*/
clearCredentials(namespace = 'app:authData') {
if (typeof window !== 'undefined' && window.localStorage.getItem(namespace)) {
window.localStorage.removeItem(namespace);
}
}
/**
* @param {?} routes
* @return {?}
*/
initApiRoutes(routes) {
/** @type {?} */
const self = this;
routes.forEach((/**
* @param {?} obj
* @return {?}
*/
(obj) => {
for (let k in obj) {
self.routes[k] = obj[k];
}
}));
if (self.settings.dev && self.settings.routes_dev) {
self.settings.routes_dev.forEach((/**
* @param {?} obj
* @return {?}
*/
(obj) => {
for (let k in obj) {
self.routes[k] = obj[k];
}
}));
}
}
// todo
/**
* @param {?} error
* @return {?}
*/
errorHandler(error) {
// AppService.scope.$broadcast('formError', error);
console.error(error);
if (!error) {
return;
}
// if(error.data === "token expired"){
// toastr.warning($filter('translate')('LOGIN EXPIRED')+'.');
// service.logOut();
// return;
// }
// if (error.statusText === 'Bad Request' || error.status == 400) {
// if (error.data.message) {
// toastr.warning($filter('translate')(error.data.message));
// } else {
// toastr.warning($filter('translate')('ERROR BAD REQUEST') + '.');
// }
// }
// if(error.statusText === 'Unauthorized' || error.status == 401){
// toastr.warning($filter('translate')('UNAUTHORIZED ERROR')+'.');
// service.logOut();
// return;
// }
// if(error.statusText === 'Not found' || error.status == 404){
// toastr.warning($filter('translate')('ERROR NOT FOUND')+'.');
// }
}
// entities local storage todo: move to storage.js
/**
* @param {?} resource
* @return {?}
*/
saveLocalResource(resource) {
localStorage.setItem(resource[this.idField], resource);
}
/**
* @param {?} ID
* @return {?}
*/
loadLocalResource(ID) {
if (localStorage.getItem(ID)) {
localStorage.getItem(ID);
}
}
/**
* @param {?} ID
* @return {?}
*/
flushLocalResource(ID) {
if (localStorage.getItem(ID)) {
localStorage.removeItem(ID);
}
}
}
if (false) {
/** @type {?} */
BaseApi.prototype.headers;
/** @type {?} */
BaseApi.prototype.settings;
/** @type {?} */
BaseApi.prototype.routes;
/** @type {?} */
BaseApi.prototype.baseUrl;
/** @type {?} */
BaseApi.prototype.idField;
/** @type {?} */
BaseApi.prototype.requestCredentials;
/** @type {?} */
BaseApi.prototype.corsMode;
/** @type {?} */
BaseApi.prototype.cachePolicy;
/** @type {?} */
BaseApi.prototype.credentials;
/** @type {?} */
BaseApi.prototype.entities;
/** @type {?} */
BaseApi.prototype.hasDebugger;
/* Skipping unhandled member: ;*/
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1hcGkuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AZW1hL2pzLWJhc2UtbGlicmFyeS8iLCJzb3VyY2VzIjpbImxpYi9iYXNlL2Jhc2UtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBRUEsTUFBTSxPQUFPLE9BQU87SUFjaEI7UUFaTyxZQUFPLEdBQVEsRUFBRSxDQUFDO1FBRWxCLFdBQU0sR0FBRyxFQUFFLENBQUM7UUFDWixZQUFPLEdBQUcsTUFBTSxDQUFDO1FBQ2pCLFlBQU8sR0FBRyxJQUFJLENBQUM7UUFDZix1QkFBa0IsR0FBRyxhQUFhLENBQUMsQ0FBQyx3Q0FBd0M7O1FBQzVFLGFBQVEsR0FBRyxhQUFhLENBQUMsQ0FBQyx3Q0FBd0M7O1FBQ2xFLGdCQUFXLEdBQUcsVUFBVSxDQUFDLENBQUMsMERBQTBEO1FBRXBGLGFBQVEsR0FBUSxFQUFFLENBQUM7UUFDbkIsZ0JBQVcsR0FBRyxLQUFLLENBQUM7SUFFWCxDQUFDOzs7OztJQUVWLElBQUksQ0FBQyxRQUFRO1FBQ2hCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUU7WUFDcEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO1NBQ2hDO1FBQ0QsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRTtZQUN0QixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDNUM7UUFDRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFOztrQkFDakIsSUFBSSxHQUFHLElBQUk7WUFDakIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTzs7OztZQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ2xDLEtBQUssTUFBTSxDQUFDLElBQUksR0FBRyxFQUFFO29CQUNqQixJQUFJLENBQUMsT0FBTyxD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RTtRQUN0RSx3QkFBd0I7UUFDeEIsY0FBYztRQUNkLElBQUk7UUFDSiwrREFBK0Q7UUFDL0QsbUVBQW1FO1FBQ25FLElBQUk7SUFDUixDQUFDOzs7Ozs7SUFHRCxpQkFBaUIsQ0FBQyxRQUFRO1FBQ3RCLFlBQVksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMzRCxDQUFDOzs7OztJQUVELGlCQUFpQixDQUFDLEVBQUU7UUFDaEIsSUFBSSxZQUFZLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQzFCLFlBQVksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDNUI7SUFDTCxDQUFDOzs7OztJQUVELGtCQUFrQixDQUFDLEVBQUU7UUFDakIsSUFBSSxZQUFZLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQzFCLFlBQVksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDL0I7SUFDTCxDQUFDO0NBQ0o7OztJQXBPRywwQkFBeUI7O0lBQ3pCLDJCQUFxQjs7SUFDckIseUJBQW1COztJQUNuQiwwQkFBd0I7O0lBQ3hCLDBCQUFzQjs7SUFDdEIscUNBQTBDOztJQUMxQywyQkFBZ0M7O0lBQ2hDLDhCQUFnQzs7SUFDaEMsOEJBQXdCOztJQUN4QiwyQkFBMEI7O0lBQzFCLDhCQUEyQiIsInNvdXJjZXNDb250ZW50IjpbImRlY2xhcmUgdmFyIGZldGNoOiBhbnk7XHJcblxyXG5leHBvcnQgY2xhc3MgQmFzZUFwaSB7XHJcblxyXG4gICAgcHVibGljIGhlYWRlcnM6IGFueSA9IHt9O1xyXG4gICAgcHVibGljIHNldHRpbmdzOiBhbnk7XHJcbiAgICBwdWJsaWMgcm91dGVzID0ge307XHJcbiAgICBwdWJsaWMgYmFzZVVybCA9ICcvYXBpJztcclxuICAgIHB1YmxpYyBpZEZpZWxkID0gJ2lkJztcclxuICAgIHB1YmxpYyByZXF1ZXN0Q3JlZGVudGlhbHMgPSAnc2FtZS1vcmlnaW4nOyAvLyBpbmNsdWRlLCBzYW1lLW9yaWdpbiwgKm9taXQgKGRlZmF1bHQpXHJcbiAgICBwdWJsaWMgY29yc01vZGUgPSAnc2FtZS1vcmlnaW4nOyAvLyBuby1jb3JzLCBjb3JzLCAqc2FtZS1vcmlnaW4gKGRlZmF1bHQpXHJcbiAgICBwdWJsaWMgY2FjaGVQb2xpY3kgPSAnbm8tY2FjaGUnOyAvLyAqZGVmYXVsdCwgbm8tY2FjaGUsIHJlbG9hZCwgZm9yY2UtY2FjaGUsIG9ubHktaWYtY2FjaGVkXHJcbiAgICBwdWJsaWMgY3JlZGVudGlhbHM6IGFueTtcclxuICAgIHB1YmxpYyBlbnRpdGllczogYW55ID0ge307XHJcbiAgICBwdWJsaWMgaGFzRGVidWdnZXIgPSBmYWxzZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHsgfVxyXG5cclxuICAgIHB1YmxpYyBpbml0KHNldHRpbmdzKSB7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncyA9IHNldHRpbmdzO1xyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLmhvc3QpIHtcclxuICAgICAgICAgICAgdGhpcy5iYXNlVXJsID0gc2V0dGluZ3MuaG9zdDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Mucm91dGVzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaW5pdEFwaVJvdXRlcyh0aGlzLnNldHRpbmdzLnJvdXRlcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLmhlYWRlcnMpIHtcclxuICAgICAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MuaGVhZGVycy5mb3JFYWNoKChvYmopID0+IHtcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgayBpbiBvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmhlYWRlcnNba10gPSBvYmpba107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZih0aGlzWydodHRwSGVhZGVycyddKSB7XHJcbiAgICAgICAgICAgIC8vIEFuZ3VsYXJKcyBvbmx5XHJcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHRoaXMuaGVhZGVycykuZm9yRWFjaCgoaykgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpc1snaHR0cEhlYWRlcnMnXS5zZXQoaywgdGhpcy5oZWFkZXJzW2tdKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmICgnd2l0aENyZWRlbnRpYWxzJyBpbiBuZXcgWE1MSHR0cFJlcXVlc3QpIHtcclxuICAgICAgICAvLyAgICAgdGhpcy5jb3JzID0gdHJ1ZTtcclxuICAgICAgICAvLyB9XHJcbiAgICB9O1xyXG5cclxuICAgIHB1YmxpYyByb3V0ZSh1cmw6IHN0cmluZykge1xyXG4gICAgICAgIGxldCBtYXBwZWRVcmw6IHN0cmluZztcclxuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLnJvdXRlcykuZm9yRWFjaCgoaykgPT4ge1xyXG4gICAgICAgICAgICBpZihrID09PSB1cmwpIHtcclxuICAgICAgICAgICAgICAgIG1hcHBlZFVybCA9IHRoaXMucm91dGVzW2tdXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAobWFwcGVkVXJsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBtYXBwZWRVcmw7XHJcbiAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIHJldHVybiB1cmw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENSVURcclxuICAgIHB1YmxpYyBhc3luYyBwb3N0KHBhdGgsIGRhdGE6IGFueSkge1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdDogYW55ID0gYXdhaXQgZmV0Y2goYCR7dGhpcy5iYXNlVXJsfSR7cGF0aH1gLCB7XHJcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGRhdGEpLCAvLyBtdXN0IG1hdGNoICdDb250ZW50LVR5cGUnIGhlYWRlclxyXG4gICAgICAgICAgICBjYWNoZTogdGhpcy5jYWNoZVBvbGljeSxcclxuICAgICAgICAgICAgY3JlZGVudGlhbHM6IHRoaXMucmVxdWVzdENyZWRlbnRpYWxzLFxyXG4gICAgICAgICAgICBoZWFkZXJzOiB0aGlzLmhlYWRlcnMsXHJcbiAgICAgICAgICAgIG1vZGU6IHRoaXMuY29yc01vZGUsXHJcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxyXG4gICAgICAgICAgICAvLyByZWRpcmVjdDogJ2ZvbGxvdycsIC8vIG1hbnVhbCwgKmZvbGxvdywgZXJyb3JcclxuICAgICAgICAgICAgLy8gcmVmZXJyZXI6ICduby1yZWZlcnJlcicsIC8vICpjbGllbnQsIG5vLXJlZmVycmVyXHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDQwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdCYWQgcmVzcG9uc2UgZnJvbSBzZXJ2ZXInKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2F0Y2godGhpcy5lcnJvckhhbmRsZXIpXHJcbiAgICAgICAgICAgIC50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0KHBhdGg6IHN0cmluZywgcGFyYW1zOiBhbnkgPSB1bmRlZmluZWQpIHtcclxuICAgICAgICBpZiAocGFyYW1zKSB7XHJcbiAgICAgICAgICAgIHBhdGggKz0gJz8nO1xyXG4gICAgICAgICAgICBPYmplY3Qua2V5cyhwYXJhbXMpLmZvckVhY2goa2V5ID0+IHBhdGggKz0ga2V5ICsgJz0nICsgcGFyYW1zW2tleV0gKyAnJicpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCByZXN1bHQ6IGFueSA9IGF3YWl0IGZldGNoKGAke3RoaXMuYmFzZVVybH0ke3BhdGh9YCwge1xyXG4gICAgICAgICAgICBjYWNoZTogdGhpcy5jYWNoZVBvbGljeSxcclxuICAgICAgICAgICAgY3JlZGVudGlhbHM6IHRoaXMucmVxdWVzdENyZWRlbnRpYWxzLFxyXG4gICAgICAgICAgICBoZWFkZXJzOiB0aGlzLmhlYWRlcnMsXHJcbiAgICAgICAgICAgIG1vZGU6IHRoaXMuY29yc01vZGUsXHJcbiAgICAgICAgICAgIG1ldGhvZDogJ0dFVCcsXHJcbiAgICAgICAgICAgIC8vIHJlZGlyZWN0OiAnZm9sbG93JywgLy8gbWFudWFsLCAqZm9sbG93LCBlcnJvclxyXG4gICAgICAgICAgICAvLyByZWZlcnJlcjogJ25vLXJlZmVycmVyJywgLy8gKmNsaWVudCwgbm8tcmVmZXJyZXJcclxuICAgICAgICB9KS50aGVuKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA+PSA0MDApIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0JhZCByZXNwb25zZSBmcm9tIHNlcnZlcicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXRjaCh0aGlzLmVycm9ySGFuZGxlcilcclxuICAgICAgICAgICAgLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHRvZG86IHBhdGNoXHJcbiAgICBwdWJsaWMgYXN5bmMgcGF0Y2gocGF0aCwgaWQsIGRhdGEpIHtcclxuICAgICAgICBhd2FpdCBmZXRjaChgJHt0aGlzLmJhc2VVcmx9JHtwYXRofS9gK2lkLCB7XHJcbiAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuaGVhZGVycyxcclxuICAgICAgICAgICAgLy8gbWV0aG9kOiAnUEFUQ0gnLFxyXG4gICAgICAgICAgICBtZXRob2Q6ICdwYXRjaCcsXHJcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KCBkYXRhIClcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvLyBmaXhtZTogY2F1c2VzIHBocCBzZXJ2ZXIgZXJyb3Igb24gZHJ1cGFsIGNvbnRlbnQgcGFnZVxyXG4gICAgcHVibGljIGFzeW5jIGRlbGV0ZShwYXRoLCBpZCkge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKHBhdGgsaWQpO1xyXG4gICAgICAgIC8vIGF3YWl0IGZldGNoKGAke3RoaXMuYmFzZVVybH0ke3BhdGh9L2AgKyBpZCwge1xyXG4gICAgICAgIC8v4oCC4oCC4oCC4oCCIGhlYWRlcnM6IHRoaXMuaGVhZGVycyxcclxuICAgICAgICAvLyAvL+KAguKAgm1ldGhvZDogJ0RFTEVURSdcclxuICAgICAgICAvL+KAguKAguKAguKAgiBtZXRob2Q6ICdkZWxldGUnXHJcbiAgICAgICAgLy8gfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGxvZ2luKHVzZXJuYW1lOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcpIHtcclxuICAgICAgICBjb25zb2xlLmxvZyh1c2VybmFtZSxwYXNzd29yZC5sZW5ndGgpO1xyXG4gICAgfVxyXG5cclxuICAgIGxvZ291dChuYW1lc3BhY2U6IHN0cmluZyA9ICdhcHA6YXV0aERhdGEnLCByZWZyZXNoOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgICAgICB0aGlzLmNsZWFyQ3JlZGVudGlhbHMobmFtZXNwYWNlKTtcclxuICAgICAgICB0aGlzLnNldHRpbmdzLmF1dGhlbnRpY2F0ZWQgPSBmYWxzZTtcclxuICAgICAgICBpZiAocmVmcmVzaCkge1xyXG4gICAgICAgICAgICAvLyBsb2NhdGlvbi5ocmVmID0gbG9jYXRpb24ub3JpZ2luO1xyXG4gICAgICAgICAgICBsb2NhdGlvbi5ocmVmID0gbG9jYXRpb24uaHJlZjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gdG9kbzogdXNlIGJ0b2EgKyBhdG9iXHJcbiAgICBzZXRDcmVkZW50aWFscyhjcmVkZW50aWFsczogYW55LCBuYW1lc3BhY2U6IHN0cmluZyA9ICdhcHAtYXV0aCcpIHtcclxuICAgICAgICB0aGlzLmNyZWRlbnRpYWxzID0gY3JlZGVudGlhbHM7XHJcbiAgICAgICAgLy8gd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKG5hbWVzcGFjZSwgYnRvYShKU09OLnN0cmluZ2lmeShjcmVkZW50aWFscykpKTtcclxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmxvY2FsU3RvcmFnZSkge1xyXG4gICAgICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0obmFtZXNwYWNlLCBKU09OLnN0cmluZ2lmeShjcmVkZW50aWFscykpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXRDcmVkZW50aWFscyhuYW1lc3BhY2U6IHN0cmluZyA9ICdhcHA6YXV0aERhdGEnKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5sb2NhbFN0b3JhZ2UgJiYgd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKG5hbWVzcGFjZSkpIHtcclxuICAgICAgICAgICAgLy8gcmV0dXJuIEpTT04ucGFyc2UoYXRvYih3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0obmFtZXNwYWNlKSkpO1xyXG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0obmFtZXNwYWNlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNsZWFyQ3JlZGVudGlhbHMobmFtZXNwYWNlOiBzdHJpbmcgPSAnYXBwOmF1dGhEYXRhJykge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0obmFtZXNwYWNlKSkge1xyXG4gICAgICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0obmFtZXNwYWNlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdEFwaVJvdXRlcyhyb3V0ZXMpIHtcclxuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcclxuICAgICAgICByb3V0ZXMuZm9yRWFjaCgob2JqKSA9PiB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGsgaW4gb2JqKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnJvdXRlc1trXSA9IG9ialtrXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGlmIChzZWxmLnNldHRpbmdzLmRldiAmJiBzZWxmLnNldHRpbmdzLnJvdXRlc19kZXYpIHtcclxuICAgICAgICAgICAgc2VsZi5zZXR0aW5ncy5yb3V0ZXNfZGV2LmZvckVhY2goKG9iaikgPT4ge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayBpbiBvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnJvdXRlc1trXSA9IG9ialtrXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIHRvZG9cclxuICAgIGVycm9ySGFuZGxlcihlcnJvcikge1xyXG4gICAgICAgIC8vIEFwcFNlcnZpY2Uuc2NvcGUuJGJyb2FkY2FzdCgnZm9ybUVycm9yJywgZXJyb3IpO1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xyXG4gICAgICAgIGlmICghZXJyb3IpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBpZihlcnJvci5kYXRhID09PSBcInRva2VuIGV4cGlyZWRcIil7XHJcbiAgICAgICAgLy/igILigILigILigIIgdG9hc3RyLndhcm5pbmcoJGZpbHRlcigndHJhbnNsYXRlJykoJ0xPR0lOIEVYUElSRUQnKSsnLicpO1xyXG4gICAgICAgIC8v4oCC4oCC4oCC4oCCIHNlcnZpY2UubG9nT3V0KCk7XHJcbiAgICAgICAgLy/igILigILigILigIIgcmV0dXJuO1xyXG4gICAgICAgIC8vIH1cclxuICAgICAgICAvLyBpZiAoZXJyb3Iuc3RhdHVzVGV4dCA9PT0gJ0JhZCBSZXF1ZXN0JyB8fCBlcnJvci5zdGF0dXMgPT0gNDAwKSB7XHJcbiAgICAgICAgLy/igILigILigILigIIgaWYgKGVycm9yLmRhdGEubWVzc2FnZSkge1xyXG4gICAgICAgIC8v4oCC4oCC4oCC4oCC4oCC4oCC4oCC4oCCIHRvYXN0ci53YXJuaW5nKCRmaWx0ZXIoJ3RyYW5zbGF0ZScpKGVycm9yLmRhdGEubWVzc2FnZSkpO1xyXG4gICAgICAgIC8v4oCC4oCC4oCC4oCCIH0gZWxzZSB7XHJcbiAgICAgICAgLy/igILigILigILigILigILigILigILigIIgdG9hc3RyLndhcm5pbmcoJGZpbHRlcigndHJhbnNsYXRlJykoJ0VSUk9SIEJBRCBSRVFVRVNUJykgKyAnLicpO1xyXG4gICAgICAgIC8v4oCC4oCC4oCC4oCCIH1cclxuICAgICAgICAvLyB9XHJcbiAgICAgICAgLy8gaWYoZXJyb3Iuc3RhdHVzVGV4dCA9PT0gJ1VuYXV0aG9yaXplZCcgfHwgZXJyb3Iuc3RhdHVzID09IDQwMSl7XHJcbiAgICAgICAgLy/igILigILigILigIIgdG9hc3RyLndhcm5pbmcoJGZpbHRlcigndHJhbnNsYXRlJykoJ1VOQVVUSE9SSVpFRCBFUlJPUicpKycuJyk7XHJcbiAgICAgICAgLy/igILigILigILigIIgc2VydmljZS5sb2dPdXQoKTtcclxuICAgICAgICAvL+KAguKAguKAguKAgiByZXR1cm47XHJcbiAgICAgICAgLy8gfVxyXG4gICAgICAgIC8vIGlmKGVycm9yLnN0YXR1c1RleHQgPT09ICdOb3QgZm91bmQnIHx8IGVycm9yLnN0YXR1cyA9PSA0MDQpe1xyXG4gICAgICAgIC8v4oCC4oCC4oCC4oCCIHRvYXN0ci53YXJuaW5nKCRmaWx0ZXIoJ3RyYW5zbGF0ZScpKCdFUlJPUiBOT1QgRk9VTkQnKSsnLicpO1xyXG4gICAgICAgIC8vIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBlbnRpdGllcyBsb2NhbCBzdG9yYWdlIHRvZG86IG1vdmUgdG8gc3RvcmFnZS5qc1xyXG4gICAgc2F2ZUxvY2FsUmVzb3VyY2UocmVzb3VyY2UpIHtcclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShyZXNvdXJjZVt0aGlzLmlkRmllbGRdLCByZXNvdXJjZSk7XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZExvY2FsUmVzb3VyY2UoSUQpIHtcclxuICAgICAgICBpZiAobG9jYWxTdG9yYWdlLmdldEl0ZW0oSUQpKSB7XHJcbiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5nZXRJdGVtKElEKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZmx1c2hMb2NhbFJlc291cmNlKElEKSB7XHJcbiAgICAgICAgaWYgKGxvY2FsU3RvcmFnZS5nZXRJdGVtKElEKSkge1xyXG4gICAgICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShJRCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59Il19