blast-graph-angular2
Version:
 **with** 
583 lines (582 loc) • 40.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { BlastHelpers } from './blast-helpers';
import { Subject } from 'rxjs/index';
/** @type {?} */
export var BLAST_VERSION = '0.0.1';
/** @type {?} */
export var LOG_LEVEL = {
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3
};
/**
* @record
*/
export function BlastServiceConfig() { }
/** @type {?} */
BlastServiceConfig.prototype.initialTimeout;
/** @type {?} */
BlastServiceConfig.prototype.maxTimeout;
/** @type {?} */
BlastServiceConfig.prototype.reconnectIfNotNormalClose;
var BlastService = /** @class */ (function () {
function BlastService(url, connectNow, protocols, config) {
this.url = url;
this.protocols = protocols;
this.config = config;
this.reconnectAttempts = 0;
this.sendQueue = [];
this.onMessageCallbacks = [];
this.onOpenCallbacks = [];
this.onErrorCallbacks = [];
this.onCloseCallbacks = [];
this.readyStateConstants = {
'CONNECTING': 0,
'OPEN': 1,
'CLOSING': 2,
'CLOSED': 3,
'RECONNECT_ABORTED': 4
};
this.normalCloseCode = 1000;
this.reconnectableStatusCodes = [4000];
this.logLevel = LOG_LEVEL.ERROR;
/** @type {?} */
var match = new RegExp('wss?:\/\/').test(url);
if (!match) {
throw new Error('Invalid url provided');
}
this.config = config || { initialTimeout: 500, maxTimeout: 300000, reconnectIfNotNormalClose: true };
this.dataStream = new Subject();
if (connectNow === undefined || connectNow) {
this.connect(true);
}
}
/**
* @param {?=} force
* @return {?}
*/
BlastService.prototype.connect = /**
* @param {?=} force
* @return {?}
*/
function (force) {
var _this = this;
if (force === void 0) { force = false; }
/** @type {?} */
var self = this;
if (force || !this.socket || this.socket.readyState !== this.readyStateConstants.OPEN) {
self.socket = this.protocols ? new WebSocket(this.url, this.protocols) : new WebSocket(this.url);
self.socket.onopen = function (ev) {
_this.onOpenHandler(ev);
};
self.socket.onmessage = function (ev) {
if (BlastHelpers.isJson(ev.data)) {
/** @type {?} */
var message = JSON.parse(ev.data);
_this.debug('BlastService', 'jsonMessage', 'passing to handlers', ev.data);
// call a json message handler - if true, then message handled mustn't carry on
if (self.handleJsonMessage(message) === true) {
return;
}
}
self.onMessageHandler(ev.data);
_this.dataStream.next(ev.data);
};
this.socket.onclose = function (ev) {
self.onCloseHandler(ev);
};
this.socket.onerror = function (ev) {
self.onErrorHandler(ev);
_this.dataStream.error(ev);
};
}
};
/**
* Run in Block Mode
* Return true when can send and false in socket closed
* @param {?} data
* @param {?=} binary
* @return {?}
*/
BlastService.prototype.sendMessage = /**
* Run in Block Mode
* Return true when can send and false in socket closed
* @param {?} data
* @param {?=} binary
* @return {?}
*/
function (data, binary) {
/** @type {?} */
var self = this;
if (this.getReadyState() !== this.readyStateConstants.OPEN
&& this.getReadyState() !== this.readyStateConstants.CONNECTING) {
this.connect();
}
this.debug('BlastService', 'sendMessage', data);
self.sendQueue.push({ message: data, binary: binary });
if (self.socket.readyState === self.readyStateConstants.OPEN) {
self.fireQueue();
return true;
}
else {
return false;
}
};
/**
* Use {mode} mode to send {data} data
* If no specify, Default SendMode is Observable mode
* @param data
* @param mode
* @param binary
* @returns
*/
/**
* Use {mode} mode to send {data} data
* If no specify, Default SendMode is Observable mode
* @param {?} data
* @param {?=} binary
* @return {?}
*/
BlastService.prototype.send = /**
* Use {mode} mode to send {data} data
* If no specify, Default SendMode is Observable mode
* @param {?} data
* @param {?=} binary
* @return {?}
*/
function (data, binary) {
return this.sendMessage(data, binary);
};
/**
* @return {?}
*/
BlastService.prototype.getDataStream = /**
* @return {?}
*/
function () {
return this.dataStream;
};
/**
* @param {?} event
* @return {?}
*/
BlastService.prototype.notifyOpenCallbacks = /**
* @param {?} event
* @return {?}
*/
function (event) {
for (var i = 0; i < this.onOpenCallbacks.length; i++) {
this.onOpenCallbacks[i].call(this, event);
}
};
/**
* @return {?}
*/
BlastService.prototype.fireQueue = /**
* @return {?}
*/
function () {
while (this.sendQueue.length && this.socket.readyState === this.readyStateConstants.OPEN) {
/** @type {?} */
var data = this.sendQueue.shift();
if (data.binary) {
this.socket.send(data.message);
}
else {
this.socket.send(BlastHelpers.isString(data.message) ? data.message : JSON.stringify(data.message));
}
}
};
/**
* @param {?} event
* @return {?}
*/
BlastService.prototype.notifyCloseCallbacks = /**
* @param {?} event
* @return {?}
*/
function (event) {
for (var i = 0; i < this.onCloseCallbacks.length; i++) {
this.onCloseCallbacks[i].call(this, event);
}
};
/**
* @param {?} event
* @return {?}
*/
BlastService.prototype.notifyErrorCallbacks = /**
* @param {?} event
* @return {?}
*/
function (event) {
for (var i = 0; i < this.onErrorCallbacks.length; i++) {
this.onErrorCallbacks[i].call(this, event);
}
};
/**
* @param {?} cb
* @return {?}
*/
BlastService.prototype.onOpen = /**
* @param {?} cb
* @return {?}
*/
function (cb) {
this.onOpenCallbacks.push(cb);
return this;
};
;
/**
* @param {?} cb
* @return {?}
*/
BlastService.prototype.onClose = /**
* @param {?} cb
* @return {?}
*/
function (cb) {
this.onCloseCallbacks.push(cb);
return this;
};
/**
* @param {?} cb
* @return {?}
*/
BlastService.prototype.onError = /**
* @param {?} cb
* @return {?}
*/
function (cb) {
this.onErrorCallbacks.push(cb);
return this;
};
;
/**
* @param {?} callback
* @param {?=} options
* @return {?}
*/
BlastService.prototype.onMessage = /**
* @param {?} callback
* @param {?=} options
* @return {?}
*/
function (callback, options) {
if (!BlastHelpers.isFunction(callback)) {
throw new Error('Callback must be a function');
}
this.onMessageCallbacks.push({
fn: callback,
pattern: options ? options.filter : undefined,
autoApply: options ? options.autoApply : true
});
return this;
};
/**
* @param {?} message
* @return {?}
*/
BlastService.prototype.handleJsonMessage = /**
* @param {?} message
* @return {?}
*/
function (message) {
// as a default return false i.e. don't change message flow
// enables extended classes to override this function
return false;
};
/**
* @param {?} message
* @return {?}
*/
BlastService.prototype.onMessageHandler = /**
* @param {?} message
* @return {?}
*/
function (message) {
this.debug('BlastService', 'onMessageHandler', message.data);
/** @type {?} */
var self = this;
/** @type {?} */
var currentCallback;
for (var i = 0; i < self.onMessageCallbacks.length; i++) {
currentCallback = self.onMessageCallbacks[i];
currentCallback.fn.apply(self, [message]);
}
};
;
/**
* @param {?} event
* @return {?}
*/
BlastService.prototype.onOpenHandler = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.debug('BlastService', 'connected');
this.reconnectAttempts = 0;
this.notifyOpenCallbacks(event);
this.fireQueue();
};
/**
* @param {?} event
* @return {?}
*/
BlastService.prototype.onCloseHandler = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.debug('BlastService', 'closed');
this.notifyCloseCallbacks(event);
if ((this.config.reconnectIfNotNormalClose && event.code !== this.normalCloseCode)
|| this.reconnectableStatusCodes.indexOf(event.code) > -1) {
this.reconnect();
}
else {
this.sendQueue = [];
this.dataStream.complete();
}
};
;
/**
* @param {?} event
* @return {?}
*/
BlastService.prototype.onErrorHandler = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.debug('BlastService', 'onErrorHandler', event);
this.notifyErrorCallbacks(event);
};
;
/**
* @return {?}
*/
BlastService.prototype.reconnect = /**
* @return {?}
*/
function () {
var _this = this;
this.close(true);
/** @type {?} */
var backoffDelay = this.getBackoffDelay(++this.reconnectAttempts);
// let backoffDelaySeconds = backoffDelay / 1000;
// // console.log('Reconnecting in ' + backoffDelaySeconds + ' seconds');
this.debug('BlastService', 'reconnectDelay', backoffDelay);
setTimeout(function () { return _this.connect(); }, backoffDelay);
return this;
};
/**
* @param {?=} force
* @return {?}
*/
BlastService.prototype.close = /**
* @param {?=} force
* @return {?}
*/
function (force) {
if (force === void 0) { force = false; }
if (force || !this.socket.bufferedAmount) {
this.socket.close(this.normalCloseCode);
}
return this;
};
;
/**
* @param {?} attempt
* @return {?}
*/
BlastService.prototype.getBackoffDelay = /**
* @param {?} attempt
* @return {?}
*/
function (attempt) {
/** @type {?} */
var R = Math.random() + 1;
/** @type {?} */
var T = this.config.initialTimeout;
/** @type {?} */
var F = 2;
/** @type {?} */
var N = attempt;
/** @type {?} */
var M = this.config.maxTimeout;
return Math.floor(Math.min(R * T * Math.pow(F, N), M));
};
;
/**
* @param {?} state
* @return {?}
*/
BlastService.prototype.setInternalState = /**
* @param {?} state
* @return {?}
*/
function (state) {
if (Math.floor(state) !== state || state < 0 || state > 4) {
throw new Error('state must be an integer between 0 and 4, got: ' + state);
}
this.internalConnectionState = state;
};
/**
* Could be -1 if not initzialized yet
* @returns
*/
/**
* Could be -1 if not initzialized yet
* @return {?}
*/
BlastService.prototype.getReadyState = /**
* Could be -1 if not initzialized yet
* @return {?}
*/
function () {
if (this.socket == null) {
return -1;
}
return this.internalConnectionState || this.socket.readyState;
};
/**
* @return {?}
*/
BlastService.prototype.getVersion = /**
* @return {?}
*/
function () {
return BLAST_VERSION;
};
/**
* @return {?}
*/
BlastService.prototype.hasConsole = /**
* @return {?}
*/
function () {
if (console === undefined) {
return false;
}
return true;
};
/**
* @param {...?} args
* @return {?}
*/
BlastService.prototype.debug = /**
* @param {...?} args
* @return {?}
*/
function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this.hasConsole() && this.logLevel < 1) {
console.debug.apply(console, args);
}
};
/**
* @param {...?} args
* @return {?}
*/
BlastService.prototype.info = /**
* @param {...?} args
* @return {?}
*/
function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this.hasConsole() && this.logLevel < 2) {
console.debug.apply(console, args);
}
};
/**
* @param {...?} args
* @return {?}
*/
BlastService.prototype.warn = /**
* @param {...?} args
* @return {?}
*/
function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this.hasConsole() && this.logLevel < 4) {
console.debug.apply(console, args);
}
};
/**
* @param {...?} args
* @return {?}
*/
BlastService.prototype.error = /**
* @param {...?} args
* @return {?}
*/
function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
console.error.apply(console, args);
};
/**
* @param {?} level
* @return {?}
*/
BlastService.prototype.setLogLevel = /**
* @param {?} level
* @return {?}
*/
function (level) {
this.logLevel = level;
};
return BlastService;
}());
export { BlastService };
if (false) {
/** @type {?} */
BlastService.prototype.reconnectAttempts;
/** @type {?} */
BlastService.prototype.sendQueue;
/** @type {?} */
BlastService.prototype.onMessageCallbacks;
/** @type {?} */
BlastService.prototype.onOpenCallbacks;
/** @type {?} */
BlastService.prototype.onErrorCallbacks;
/** @type {?} */
BlastService.prototype.onCloseCallbacks;
/** @type {?} */
BlastService.prototype.readyStateConstants;
/** @type {?} */
BlastService.prototype.normalCloseCode;
/** @type {?} */
BlastService.prototype.reconnectableStatusCodes;
/** @type {?} */
BlastService.prototype.socket;
/** @type {?} */
BlastService.prototype.dataStream;
/** @type {?} */
BlastService.prototype.internalConnectionState;
/** @type {?} */
BlastService.prototype.logLevel;
/** @type {?} */
BlastService.prototype.url;
/** @type {?} */
BlastService.prototype.protocols;
/** @type {?} */
BlastService.prototype.config;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxhc3QtYW5ndWxhcjIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9ibGFzdC1ncmFwaC1hbmd1bGFyMi8iLCJzb3VyY2VzIjpbInNyYy9ibGFzdC1hbmd1bGFyMi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBSUEsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxZQUFZLENBQUM7O0FBRW5DLFdBQWEsYUFBYSxHQUFHLE9BQU8sQ0FBQzs7QUFFckMsV0FBYSxTQUFTLEdBQUc7SUFDckIsS0FBSyxFQUFFLENBQUM7SUFDUixJQUFJLEVBQUUsQ0FBQztJQUNQLElBQUksRUFBRSxDQUFDO0lBQ1AsS0FBSyxFQUFFLENBQUM7Q0FDWCxDQUFDOzs7Ozs7Ozs7OztBQVNGLElBQUE7SUF3Qkksc0JBQW9CLEdBQVcsRUFDM0IsVUFBb0IsRUFDWixXQUNBO1FBSFEsUUFBRyxHQUFILEdBQUcsQ0FBUTtRQUVuQixjQUFTLEdBQVQsU0FBUztRQUNULFdBQU0sR0FBTixNQUFNO2lDQXpCVSxDQUFDO3lCQUNGLEVBQUU7a0NBQ08sRUFBRTsrQkFDQSxFQUFFO2dDQUNELEVBQUU7Z0NBQ0YsRUFBRTttQ0FDWDtZQUMxQixZQUFZLEVBQUUsQ0FBQztZQUNmLE1BQU0sRUFBRSxDQUFDO1lBQ1QsU0FBUyxFQUFFLENBQUM7WUFDWixRQUFRLEVBQUUsQ0FBQztZQUNYLG1CQUFtQixFQUFFLENBQUM7U0FDekI7K0JBRXlCLElBQUk7d0NBQ0ssQ0FBQyxJQUFJLENBQUM7d0JBS3ZCLFNBQVMsQ0FBQyxLQUFLOztRQVE3QixJQUFNLEtBQUssR0FBRyxJQUFJLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEQsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ1QsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFD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Vzs7OztJQUFYLFVBQVksS0FBYTtRQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztLQUN6Qjt1QkE5VEw7SUErVEMsQ0FBQTtBQXhTRCx3QkF3U0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdGFibGUsIE9wdGlvbmFsfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbi8qKlxuICogYmxhc3QtYW5ndWxhcjJcbiAqL1xuaW1wb3J0IHtCbGFzdEhlbHBlcnN9IGZyb20gJy4vYmxhc3QtaGVscGVycyc7XG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMvaW5kZXgnO1xuXG5leHBvcnQgY29uc3QgQkxBU1RfVkVSU0lPTiA9ICcwLjAuMSc7XG5cbmV4cG9ydCBjb25zdCBMT0dfTEVWRUwgPSB7XG4gICAgREVCVUc6IDAsXG4gICAgSU5GTzogMSxcbiAgICBXQVJOOiAyLFxuICAgIEVSUk9SOiAzXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEJsYXN0U2VydmljZUNvbmZpZyB7XG4gICAgaW5pdGlhbFRpbWVvdXQ6IG51bWJlcjtcbiAgICBtYXhUaW1lb3V0OiBudW1iZXI7XG4gICAgcmVjb25uZWN0SWZOb3ROb3JtYWxDbG9zZTogYm9vbGVhbjtcbn1cblxuLy9ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQmxhc3RTZXJ2aWNlIHtcblxuICAgIHByaXZhdGUgcmVjb25uZWN0QXR0ZW1wdHMgPSAwO1xuICAgIHByaXZhdGUgc2VuZFF1ZXVlOiBhbnlbXSA9IFtdO1xuICAgIHByaXZhdGUgb25NZXNzYWdlQ2FsbGJhY2tzOiBhbnlbXSA9IFtdO1xuICAgIHByaXZhdGUgb25PcGVuQ2FsbGJhY2tzOiBGdW5jdGlvbltdID0gW107XG4gICAgcHJpdmF0ZSBvbkVycm9yQ2FsbGJhY2tzOiBGdW5jdGlvbltdID0gW107XG4gICAgcHJpdmF0ZSBvbkNsb3NlQ2FsbGJhY2tzOiBGdW5jdGlvbltdID0gW107XG4gICAgcHJpdmF0ZSByZWFkeVN0YXRlQ29uc3RhbnRzID0ge1xuICAgICAgICAnQ09OTkVDVElORyc6IDAsXG4gICAgICAgICdPUEVOJzogMSxcbiAgICAgICAgJ0NMT1NJTkcnOiAyLFxuICAgICAgICAnQ0xPU0VEJzogMyxcbiAgICAgICAgJ1JFQ09OTkVDVF9BQk9SVEVEJzogNFxuICAgIH07XG5cbiAgICBwcml2YXRlIG5vcm1hbENsb3NlQ29kZSA9IDEwMDA7XG4gICAgcHJpdmF0ZSByZWNvbm5lY3RhYmxlU3RhdHVzQ29kZXMgPSBbNDAwMF07XG4gICAgcHJpdmF0ZSBzb2NrZXQ6IFdlYlNvY2tldDtcbiAgICBwcml2YXRlIGRhdGFTdHJlYW06IFN1YmplY3Q8YW55PjtcbiAgICBwcml2YXRlIGludGVybmFsQ29ubmVjdGlvblN0YXRlOiBudW1iZXI7XG5cbiAgICBwdWJsaWMgbG9nTGV2ZWwgPSBMT0dfTEVWRUwuRVJST1I7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHVybDogc3RyaW5nLFxuICAgICAgICBjb25uZWN0Tm93PzogYm9vbGVhbixcbiAgICAgICAgcHJpdmF0ZSBwcm90b2NvbHM/OiBBcnJheTxzdHJpbmc+LFxuICAgICAgICBwcml2YXRlIGNvbmZpZz86IEJsYXN0U2VydmljZUNvbmZpZ1xuICAgICkge1xuXG4gICAgICAgIGNvbnN0IG1hdGNoID0gbmV3IFJlZ0V4cCgnd3NzPzpcXC9cXC8nKS50ZXN0KHVybCk7XG4gICAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB1cmwgcHJvdmlkZWQnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCB7aW5pdGlhbFRpbWVvdXQ6IDUwMCwgbWF4VGltZW91dDogMzAwMDAwLCByZWNvbm5lY3RJZk5vdE5vcm1hbENsb3NlOiB0cnVlfTtcbiAgICAgICAgdGhpcy5kYXRhU3RyZWFtID0gbmV3IFN1YmplY3QoKTtcblxuICAgICAgICBpZiAoY29ubmVjdE5vdyA9PT0gdW5kZWZpbmVkIHx8IGNvbm5lY3ROb3cpIHtcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdCh0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbm5lY3QoZm9yY2UgPSBmYWxzZSkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgaWYgKGZvcmNlIHx8ICF0aGlzLnNvY2tldCB8fCB0aGlzLnNvY2tldC5yZWFkeVN0YXRlICE9PSB0aGlzLnJlYWR5U3RhdGVDb25zdGFudHMuT1BFTikge1xuICAgICAgICAgICAgc2VsZi5zb2NrZXQgPSB0aGlzLnByb3RvY29scyA/IG5ldyBXZWJTb2NrZXQodGhpcy51cmwsIHRoaXMucHJvdG9jb2xzKSA6IG5ldyBXZWJTb2NrZXQodGhpcy51cmwpO1xuXG4gICAgICAgICAgICBzZWxmLnNvY2tldC5vbm9wZW4gPSAoZXY6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vbk9wZW5IYW5kbGVyKGV2KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzZWxmLnNvY2tldC5vbm1lc3NhZ2UgPSAoZXY6IE1lc3NhZ2VFdmVudCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgaWYgKEJsYXN0SGVscGVycy5pc0pzb24oZXYuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IEpTT04ucGFyc2UoZXYuZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVidWcoJ0JsYXN0U2VydmljZScsICdqc29uTWVzc2FnZScsICdwYXNzaW5nIHRvIGhhbmRsZXJzJywgZXYuZGF0YSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gY2FsbCBhIGpzb24gbWVzc2FnZSBoYW5kbGVyIC0gaWYgdHJ1ZSwgdGhlbiBtZXNzYWdlIGhhbmRsZWQgbXVzdG4ndCBjYXJyeSBvblxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5oYW5kbGVKc29uTWVzc2FnZShtZXNzYWdlKSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNlbGYub25NZXNzYWdlSGFuZGxlcihldi5kYXRhKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFTdHJlYW0ubmV4dChldi5kYXRhKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuc29ja2V0Lm9uY2xvc2UgPSAoZXY6IENsb3NlRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBzZWxmLm9uQ2xvc2VIYW5kbGVyKGV2KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuc29ja2V0Lm9uZXJyb3IgPSAoZXY6IEVycm9yRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBzZWxmLm9uRXJyb3JIYW5kbGVyKGV2KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFTdHJlYW0uZXJyb3IoZXYpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVuIGluIEJsb2NrIE1vZGVcbiAgICAgKiBSZXR1cm4gdHJ1ZSB3aGVuIGNhbiBzZW5kIGFuZCBmYWxzZSBpbiBzb2NrZXQgY2xvc2VkXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBwcml2YXRlIHNlbmRNZXNzYWdlKGRhdGE6IGFueSwgYmluYXJ5PzogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgaWYgKHRoaXMuZ2V0UmVhZHlTdGF0ZSgpICE9PSB0aGlzLnJlYWR5U3RhdGVDb25zdGFudHMuT1BFTlxuICAgICAgICAgICAgJiYgdGhpcy5nZXRSZWFkeVN0YXRlKCkgIT09IHRoaXMucmVhZHlTdGF0ZUNvbnN0YW50cy5DT05ORUNUSU5HKSB7XG4gICAgICAgICAgICB0aGlzLmNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlYnVnKCdCbGFzdFNlcnZpY2UnLCAnc2VuZE1lc3NhZ2UnLCBkYXRhKTtcbiAgICAgICAgc2VsZi5zZW5kUXVldWUucHVzaCh7bWVzc2FnZTogZGF0YSwgYmluYXJ5OiBiaW5hcnl9KTtcbiAgICAgICAgaWYgKHNlbGYuc29ja2V0LnJlYWR5U3RhdGUgPT09IHNlbGYucmVhZHlTdGF0ZUNvbnN0YW50cy5PUEVOKSB7XG4gICAgICAgICAgICBzZWxmLmZpcmVRdWV1ZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2Uge21vZGV9IG1vZGUgdG8gc2VuZCB7ZGF0YX0gZGF0YVxuICAgICAqIElmIG5vIHNwZWNpZnksIERlZmF1bHQgU2VuZE1vZGUgaXMgT2JzZXJ2YWJsZSBtb2RlXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKiBAcGFyYW0gbW9kZVxuICAgICAqIEBwYXJhbSBiaW5hcnlcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzZW5kKGRhdGE6IGFueSwgYmluYXJ5PzogYm9vbGVhbik6IGFueSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlbmRNZXNzYWdlKGRhdGEsIGJpbmFyeSk7XG4gICAgfVxuXG4gICAgZ2V0RGF0YVN0cmVhbSgpOiBTdWJqZWN0PGFueT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhU3RyZWFtO1xuICAgIH1cblxuXG4gICAgbm90aWZ5T3BlbkNhbGxiYWNrcyhldmVudDogRXZlbnQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm9uT3BlbkNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5vbk9wZW5DYWxsYmFja3NbaV0uY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmaXJlUXVldWUoKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLnNlbmRRdWV1ZS5sZW5ndGggJiYgdGhpcy5zb2NrZXQucmVhZHlTdGF0ZSA9PT0gdGhpcy5yZWFkeVN0YXRlQ29uc3RhbnRzLk9QRU4pIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLnNlbmRRdWV1ZS5zaGlmdCgpO1xuXG4gICAgICAgICAgICBpZiAoZGF0YS5iaW5hcnkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNvY2tldC5zZW5kKGRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc29ja2V0LnNlbmQoXG4gICAgICAgICAgICAgICAgICAgIEJsYXN0SGVscGVycy5pc1N0cmluZyhkYXRhLm1lc3NhZ2UpID8gZGF0YS5tZXNzYWdlIDogSlNPTi5zdHJpbmdpZnkoZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBub3RpZnlDbG9zZUNhbGxiYWNrcyhldmVudDogRXZlbnQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm9uQ2xvc2VDYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMub25DbG9zZUNhbGxiYWNrc1tpXS5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5vdGlmeUVycm9yQ2FsbGJhY2tzKGV2ZW50OiBFdmVudCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMub25FcnJvckNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5vbkVycm9yQ2FsbGJhY2tzW2ldLmNhbGwodGhpcywgZXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25PcGVuKGNiOiBGdW5jdGlvbikge1xuICAgICAgICB0aGlzLm9uT3BlbkNhbGxiYWNrcy5wdXNoKGNiKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIG9uQ2xvc2UoY2I6IEZ1bmN0aW9uKSB7XG4gICAgICAgIHRoaXMub25DbG9zZUNhbGxiYWNrcy5wdXNoKGNiKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgb25FcnJvcihjYjogRnVuY3Rpb24pIHtcbiAgICAgICAgdGhpcy5vbkVycm9yQ2FsbGJhY2tzLnB1c2goY2IpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgb25NZXNzYWdlKGNhbGxiYWNrOiBGdW5jdGlvbiwgb3B0aW9ucz8pIHtcbiAgICAgICAgaWYgKCFCbGFzdEhlbHBlcnMuaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9uTWVzc2FnZUNhbGxiYWNrcy5wdXNoKHtcbiAgICAgICAgICAgIGZuOiBjYWxsYmFjayxcbiAgICAgICAgICAgIHBhdHRlcm46IG9wdGlvbnMgPyBvcHRpb25zLmZpbHRlciA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGF1dG9BcHBseTogb3B0aW9ucyA/IG9wdGlvbnMuYXV0b0FwcGx5IDogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgaGFuZGxlSnNvbk1lc3NhZ2UobWVzc2FnZTogYW55KTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGFzIGEgZGVmYXVsdCByZXR1cm4gZmFsc2UgaS5lLiBkb24ndCBjaGFuZ2UgbWVzc2FnZSBmbG93XG4gICAgICAgIC8vIGVuYWJsZXMgZXh0ZW5kZWQgY2xhc3NlcyB0byBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBvbk1lc3NhZ2VIYW5kbGVyKG1lc3NhZ2U6IE1lc3NhZ2VFdmVudCkge1xuICAgICAgICB0aGlzLmRlYnVnKCdCbGFzdFNlcnZpY2UnLCAnb25NZXNzYWdlSGFuZGxlcicsIG1lc3NhZ2UuZGF0YSk7XG5cbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGxldCBjdXJyZW50Q2FsbGJhY2s7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5vbk1lc3NhZ2VDYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGN1cnJlbnRDYWxsYmFjayA9IHNlbGYub25NZXNzYWdlQ2FsbGJhY2tzW2ldO1xuICAgICAgICAgICAgY3VycmVudENhbGxiYWNrLmZuLmFwcGx5KHNlbGYsIFttZXNzYWdlXSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgb25PcGVuSGFuZGxlcihldmVudDogRXZlbnQpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZygnQmxhc3RTZXJ2aWNlJywgJ2Nvbm5lY3RlZCcpO1xuICAgICAgICB0aGlzLnJlY29ubmVjdEF0dGVtcHRzID0gMDtcbiAgICAgICAgdGhpcy5ub3RpZnlPcGVuQ2FsbGJhY2tzKGV2ZW50KTtcbiAgICAgICAgdGhpcy5maXJlUXVldWUoKTtcbiAgICB9XG5cbiAgICBvbkNsb3NlSGFuZGxlcihldmVudDogQ2xvc2VFdmVudCkge1xuICAgICAgICB0aGlzLmRlYnVnKCdCbGFzdFNlcnZpY2UnLCAnY2xvc2VkJyk7XG4gICAgICAgIHRoaXMubm90aWZ5Q2xvc2VDYWxsYmFja3MoZXZlbnQpO1xuICAgICAgICBpZiAoKHRoaXMuY29uZmlnLnJlY29ubmVjdElmTm90Tm9ybWFsQ2xvc2UgJiYgZXZlbnQuY29kZSAhPT0gdGhpcy5ub3JtYWxDbG9zZUNvZGUpXG4gICAgICAgICAgICB8fCB0aGlzLnJlY29ubmVjdGFibGVTdGF0dXNDb2Rlcy5pbmRleE9mKGV2ZW50LmNvZGUpID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlbmRRdWV1ZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5kYXRhU3RyZWFtLmNvbXBsZXRlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgb25FcnJvckhhbmRsZXIoZXZlbnQ6IEVycm9yRXZlbnQpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZygnQmxhc3RTZXJ2aWNlJywgJ29uRXJyb3JIYW5kbGVyJywgZXZlbnQpO1xuICAgICAgICB0aGlzLm5vdGlmeUVycm9yQ2FsbGJhY2tzKGV2ZW50KTtcbiAgICB9O1xuXG4gICAgcmVjb25uZWN0KCkge1xuICAgICAgICB0aGlzLmNsb3NlKHRydWUpO1xuICAgICAgICBjb25zdCBiYWNrb2ZmRGVsYXkgPSB0aGlzLmdldEJhY2tvZmZEZWxheSgrK3RoaXMucmVjb25uZWN0QXR0ZW1wdHMpO1xuICAgICAgICAvLyAgICAgICAgIGxldCBiYWNrb2ZmRGVsYXlTZWNvbmRzID0gYmFja29mZkRlbGF5IC8gMTAwMDtcbiAgICAgICAgLy8gICAgICAgICAvLyBjb25zb2xlLmxvZygnUmVjb25uZWN0aW5nIGluICcgKyBiYWNrb2ZmRGVsYXlTZWNvbmRzICsgJyBzZWNvbmRzJyk7XG4gICAgICAgIHRoaXMuZGVidWcoJ0JsYXN0U2VydmljZScsICdyZWNvbm5lY3REZWxheScsIGJhY2tvZmZEZWxheSk7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jb25uZWN0KCksIGJhY2tvZmZEZWxheSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGNsb3NlKGZvcmNlOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKGZvcmNlIHx8ICF0aGlzLnNvY2tldC5idWZmZXJlZEFtb3VudCkge1xuICAgICAgICAgICAgdGhpcy5zb2NrZXQuY2xvc2UodGhpcy5ub3JtYWxDbG9zZUNvZGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBnZXRCYWNrb2ZmRGVsYXkoYXR0ZW1wdDogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IFIgPSBNYXRoLnJhbmRvbSgpICsgMTtcbiAgICAgICAgY29uc3QgVCA9IHRoaXMuY29uZmlnLmluaXRpYWxUaW1lb3V0O1xuICAgICAgICBjb25zdCBGID0gMjtcbiAgICAgICAgY29uc3QgTiA9IGF0dGVtcHQ7XG4gICAgICAgIGNvbnN0IE0gPSB0aGlzLmNvbmZpZy5tYXhUaW1lb3V0O1xuXG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKE1hdGgubWluKFIgKiBUICogTWF0aC5wb3coRiwgTiksIE0pKTtcbiAgICB9O1xuXG4gICAgc2V0SW50ZXJuYWxTdGF0ZShzdGF0ZTogbnVtYmVyKSB7XG4gICAgICAgIGlmIChNYXRoLmZsb29yKHN0YXRlKSAhPT0gc3RhdGUgfHwgc3RhdGUgPCAwIHx8IHN0YXRlID4gNCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdGF0ZSBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAwIGFuZCA0LCBnb3Q6ICcgKyBzdGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbnRlcm5hbENvbm5lY3Rpb25TdGF0ZSA9IHN0YXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvdWxkIGJlIC0xIGlmIG5vdCBpbml0emlhbGl6ZWQgeWV0XG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgZ2V0UmVhZHlTdGF0ZSgpOiBudW1iZXIge1xuICAgICAgICBpZiAodGhpcy5zb2NrZXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmludGVybmFsQ29ubmVjdGlvblN0YXRlIHx8IHRoaXMuc29ja2V0LnJlYWR5U3RhdGU7XG4gICAgfVxuXG4gICAgZ2V0VmVyc2lvbigpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gQkxBU1RfVkVSU0lPTjtcbiAgICB9XG5cblxuICAgIHByaXZhdGUgaGFzQ29uc29sZSgpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKGNvbnNvbGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBwcml2YXRlIGRlYnVnKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc0NvbnNvbGUoKSAmJiB0aGlzLmxvZ0xldmVsIDwgMSkge1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1Zy5hcHBseShjb25zb2xlLCBhcmdzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGluZm8oLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQ29uc29sZSgpICYmIHRoaXMubG9nTGV2ZWwgPCAyKSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHdhcm4oLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQ29uc29sZSgpICYmIHRoaXMubG9nTGV2ZWwgPCA0KSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVycm9yKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IuYXBwbHkoY29uc29sZSwgYXJncyk7XG4gICAgfVxuXG4gICAgc2V0TG9nTGV2ZWwobGV2ZWw6IG51bWJlcikge1xuICAgICAgICB0aGlzLmxvZ0xldmVsID0gbGV2ZWw7XG4gICAgfVxufVxuXG4iXX0=