UNPKG

@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
/** * @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