7573 lines
797 KiB
JavaScript
7573 lines
797 KiB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Tinode = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
|
|
function _classStaticPrivateMethodGet(receiver, classConstructor, method) { _classCheckPrivateStaticAccess(receiver, classConstructor); return method; }
|
|
|
|
function _classCheckPrivateStaticAccess(receiver, classConstructor) { if (receiver !== classConstructor) { throw new TypeError("Private static access of wrong provenance"); } }
|
|
|
|
class AccessMode {
|
|
constructor(acs) {
|
|
if (acs) {
|
|
this.given = typeof acs.given == 'number' ? acs.given : AccessMode.decode(acs.given);
|
|
this.want = typeof acs.want == 'number' ? acs.want : AccessMode.decode(acs.want);
|
|
this.mode = acs.mode ? typeof acs.mode == 'number' ? acs.mode : AccessMode.decode(acs.mode) : this.given & this.want;
|
|
}
|
|
}
|
|
|
|
static decode(str) {
|
|
if (!str) {
|
|
return null;
|
|
} else if (typeof str == 'number') {
|
|
return str & AccessMode._BITMASK;
|
|
} else if (str === 'N' || str === 'n') {
|
|
return AccessMode._NONE;
|
|
}
|
|
|
|
const bitmask = {
|
|
'J': AccessMode._JOIN,
|
|
'R': AccessMode._READ,
|
|
'W': AccessMode._WRITE,
|
|
'P': AccessMode._PRES,
|
|
'A': AccessMode._APPROVE,
|
|
'S': AccessMode._SHARE,
|
|
'D': AccessMode._DELETE,
|
|
'O': AccessMode._OWNER
|
|
};
|
|
let m0 = AccessMode._NONE;
|
|
|
|
for (let i = 0; i < str.length; i++) {
|
|
const bit = bitmask[str.charAt(i).toUpperCase()];
|
|
|
|
if (!bit) {
|
|
continue;
|
|
}
|
|
|
|
m0 |= bit;
|
|
}
|
|
|
|
return m0;
|
|
}
|
|
|
|
static encode(val) {
|
|
if (val === null || val === AccessMode._INVALID) {
|
|
return null;
|
|
} else if (val === AccessMode._NONE) {
|
|
return 'N';
|
|
}
|
|
|
|
const bitmask = ['J', 'R', 'W', 'P', 'A', 'S', 'D', 'O'];
|
|
let res = '';
|
|
|
|
for (let i = 0; i < bitmask.length; i++) {
|
|
if ((val & 1 << i) != 0) {
|
|
res = res + bitmask[i];
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static update(val, upd) {
|
|
if (!upd || typeof upd != 'string') {
|
|
return val;
|
|
}
|
|
|
|
let action = upd.charAt(0);
|
|
|
|
if (action == '+' || action == '-') {
|
|
let val0 = val;
|
|
const parts = upd.split(/([-+])/);
|
|
|
|
for (let i = 1; i < parts.length - 1; i += 2) {
|
|
action = parts[i];
|
|
const m0 = AccessMode.decode(parts[i + 1]);
|
|
|
|
if (m0 == AccessMode._INVALID) {
|
|
return val;
|
|
}
|
|
|
|
if (m0 == null) {
|
|
continue;
|
|
}
|
|
|
|
if (action === '+') {
|
|
val0 |= m0;
|
|
} else if (action === '-') {
|
|
val0 &= ~m0;
|
|
}
|
|
}
|
|
|
|
val = val0;
|
|
} else {
|
|
const val0 = AccessMode.decode(upd);
|
|
|
|
if (val0 != AccessMode._INVALID) {
|
|
val = val0;
|
|
}
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
static diff(a1, a2) {
|
|
a1 = AccessMode.decode(a1);
|
|
a2 = AccessMode.decode(a2);
|
|
|
|
if (a1 == AccessMode._INVALID || a2 == AccessMode._INVALID) {
|
|
return AccessMode._INVALID;
|
|
}
|
|
|
|
return a1 & ~a2;
|
|
}
|
|
|
|
toString() {
|
|
return '{"mode": "' + AccessMode.encode(this.mode) + '", "given": "' + AccessMode.encode(this.given) + '", "want": "' + AccessMode.encode(this.want) + '"}';
|
|
}
|
|
|
|
jsonHelper() {
|
|
return {
|
|
mode: AccessMode.encode(this.mode),
|
|
given: AccessMode.encode(this.given),
|
|
want: AccessMode.encode(this.want)
|
|
};
|
|
}
|
|
|
|
setMode(m) {
|
|
this.mode = AccessMode.decode(m);
|
|
return this;
|
|
}
|
|
|
|
updateMode(u) {
|
|
this.mode = AccessMode.update(this.mode, u);
|
|
return this;
|
|
}
|
|
|
|
getMode() {
|
|
return AccessMode.encode(this.mode);
|
|
}
|
|
|
|
setGiven(g) {
|
|
this.given = AccessMode.decode(g);
|
|
return this;
|
|
}
|
|
|
|
updateGiven(u) {
|
|
this.given = AccessMode.update(this.given, u);
|
|
return this;
|
|
}
|
|
|
|
getGiven() {
|
|
return AccessMode.encode(this.given);
|
|
}
|
|
|
|
setWant(w) {
|
|
this.want = AccessMode.decode(w);
|
|
return this;
|
|
}
|
|
|
|
updateWant(u) {
|
|
this.want = AccessMode.update(this.want, u);
|
|
return this;
|
|
}
|
|
|
|
getWant() {
|
|
return AccessMode.encode(this.want);
|
|
}
|
|
|
|
getMissing() {
|
|
return AccessMode.encode(this.want & ~this.given);
|
|
}
|
|
|
|
getExcessive() {
|
|
return AccessMode.encode(this.given & ~this.want);
|
|
}
|
|
|
|
updateAll(val) {
|
|
if (val) {
|
|
this.updateGiven(val.given);
|
|
this.updateWant(val.want);
|
|
this.mode = this.given & this.want;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
isOwner(side) {
|
|
return _classStaticPrivateMethodGet(AccessMode, AccessMode, _checkFlag).call(AccessMode, this, side, AccessMode._OWNER);
|
|
}
|
|
|
|
isPresencer(side) {
|
|
return _classStaticPrivateMethodGet(AccessMode, AccessMode, _checkFlag).call(AccessMode, this, side, AccessMode._PRES);
|
|
}
|
|
|
|
isMuted(side) {
|
|
return !this.isPresencer(side);
|
|
}
|
|
|
|
isJoiner(side) {
|
|
return _classStaticPrivateMethodGet(AccessMode, AccessMode, _checkFlag).call(AccessMode, this, side, AccessMode._JOIN);
|
|
}
|
|
|
|
isReader(side) {
|
|
return _classStaticPrivateMethodGet(AccessMode, AccessMode, _checkFlag).call(AccessMode, this, side, AccessMode._READ);
|
|
}
|
|
|
|
isWriter(side) {
|
|
return _classStaticPrivateMethodGet(AccessMode, AccessMode, _checkFlag).call(AccessMode, this, side, AccessMode._WRITE);
|
|
}
|
|
|
|
isApprover(side) {
|
|
return _classStaticPrivateMethodGet(AccessMode, AccessMode, _checkFlag).call(AccessMode, this, side, AccessMode._APPROVE);
|
|
}
|
|
|
|
isAdmin(side) {
|
|
return this.isOwner(side) || this.isApprover(side);
|
|
}
|
|
|
|
isSharer(side) {
|
|
return this.isAdmin(side) || _classStaticPrivateMethodGet(AccessMode, AccessMode, _checkFlag).call(AccessMode, this, side, AccessMode._SHARE);
|
|
}
|
|
|
|
isDeleter(side) {
|
|
return _classStaticPrivateMethodGet(AccessMode, AccessMode, _checkFlag).call(AccessMode, this, side, AccessMode._DELETE);
|
|
}
|
|
|
|
}
|
|
|
|
exports.default = AccessMode;
|
|
|
|
function _checkFlag(val, side, flag) {
|
|
side = side || 'mode';
|
|
|
|
if (['given', 'want', 'mode'].includes(side)) {
|
|
return (val[side] & flag) != 0;
|
|
}
|
|
|
|
throw new Error(`Invalid AccessMode component '${side}'`);
|
|
}
|
|
|
|
AccessMode._NONE = 0x00;
|
|
AccessMode._JOIN = 0x01;
|
|
AccessMode._READ = 0x02;
|
|
AccessMode._WRITE = 0x04;
|
|
AccessMode._PRES = 0x08;
|
|
AccessMode._APPROVE = 0x10;
|
|
AccessMode._SHARE = 0x20;
|
|
AccessMode._DELETE = 0x40;
|
|
AccessMode._OWNER = 0x80;
|
|
AccessMode._BITMASK = AccessMode._JOIN | AccessMode._READ | AccessMode._WRITE | AccessMode._PRES | AccessMode._APPROVE | AccessMode._SHARE | AccessMode._DELETE | AccessMode._OWNER;
|
|
AccessMode._INVALID = 0x100000;
|
|
|
|
},{}],2:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
|
|
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
|
|
|
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
|
|
function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
|
|
|
|
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
|
|
|
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
|
|
|
|
function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
|
|
|
|
function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
|
|
|
|
function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
|
|
|
|
var _comparator = new WeakMap();
|
|
|
|
var _unique = new WeakMap();
|
|
|
|
var _findNearest = new WeakSet();
|
|
|
|
var _insertSorted = new WeakSet();
|
|
|
|
class CBuffer {
|
|
constructor(compare_, unique_) {
|
|
_classPrivateMethodInitSpec(this, _insertSorted);
|
|
|
|
_classPrivateMethodInitSpec(this, _findNearest);
|
|
|
|
_classPrivateFieldInitSpec(this, _comparator, {
|
|
writable: true,
|
|
value: undefined
|
|
});
|
|
|
|
_classPrivateFieldInitSpec(this, _unique, {
|
|
writable: true,
|
|
value: false
|
|
});
|
|
|
|
_defineProperty(this, "buffer", []);
|
|
|
|
_classPrivateFieldSet(this, _comparator, compare_ || ((a, b) => {
|
|
return a === b ? 0 : a < b ? -1 : 1;
|
|
}));
|
|
|
|
_classPrivateFieldSet(this, _unique, unique_);
|
|
}
|
|
|
|
getAt(at) {
|
|
return this.buffer[at];
|
|
}
|
|
|
|
getLast(at) {
|
|
at |= 0;
|
|
return this.buffer.length > at ? this.buffer[this.buffer.length - 1 - at] : undefined;
|
|
}
|
|
|
|
put() {
|
|
let insert;
|
|
|
|
if (arguments.length == 1 && Array.isArray(arguments[0])) {
|
|
insert = arguments[0];
|
|
} else {
|
|
insert = arguments;
|
|
}
|
|
|
|
for (let idx in insert) {
|
|
_classPrivateMethodGet(this, _insertSorted, _insertSorted2).call(this, insert[idx], this.buffer);
|
|
}
|
|
}
|
|
|
|
delAt(at) {
|
|
at |= 0;
|
|
let r = this.buffer.splice(at, 1);
|
|
|
|
if (r && r.length > 0) {
|
|
return r[0];
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
delRange(since, before) {
|
|
return this.buffer.splice(since, before - since);
|
|
}
|
|
|
|
length() {
|
|
return this.buffer.length;
|
|
}
|
|
|
|
reset() {
|
|
this.buffer = [];
|
|
}
|
|
|
|
forEach(callback, startIdx, beforeIdx, context) {
|
|
startIdx = startIdx | 0;
|
|
beforeIdx = beforeIdx || this.buffer.length;
|
|
|
|
for (let i = startIdx; i < beforeIdx; i++) {
|
|
callback.call(context, this.buffer[i], i > startIdx ? this.buffer[i - 1] : undefined, i < beforeIdx - 1 ? this.buffer[i + 1] : undefined, i);
|
|
}
|
|
}
|
|
|
|
find(elem, nearest) {
|
|
const {
|
|
idx
|
|
} = _classPrivateMethodGet(this, _findNearest, _findNearest2).call(this, elem, this.buffer, !nearest);
|
|
|
|
return idx;
|
|
}
|
|
|
|
filter(callback, context) {
|
|
let count = 0;
|
|
|
|
for (let i = 0; i < this.buffer.length; i++) {
|
|
if (callback.call(context, this.buffer[i], i)) {
|
|
this.buffer[count] = this.buffer[i];
|
|
count++;
|
|
}
|
|
}
|
|
|
|
this.buffer.splice(count);
|
|
}
|
|
|
|
}
|
|
|
|
exports.default = CBuffer;
|
|
|
|
function _findNearest2(elem, arr, exact) {
|
|
let start = 0;
|
|
let end = arr.length - 1;
|
|
let pivot = 0;
|
|
let diff = 0;
|
|
let found = false;
|
|
|
|
while (start <= end) {
|
|
pivot = (start + end) / 2 | 0;
|
|
diff = _classPrivateFieldGet(this, _comparator).call(this, arr[pivot], elem);
|
|
|
|
if (diff < 0) {
|
|
start = pivot + 1;
|
|
} else if (diff > 0) {
|
|
end = pivot - 1;
|
|
} else {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (found) {
|
|
return {
|
|
idx: pivot,
|
|
exact: true
|
|
};
|
|
}
|
|
|
|
if (exact) {
|
|
return {
|
|
idx: -1
|
|
};
|
|
}
|
|
|
|
return {
|
|
idx: diff < 0 ? pivot + 1 : pivot
|
|
};
|
|
}
|
|
|
|
function _insertSorted2(elem, arr) {
|
|
const found = _classPrivateMethodGet(this, _findNearest, _findNearest2).call(this, elem, arr, false);
|
|
|
|
const count = found.exact && _classPrivateFieldGet(this, _unique) ? 1 : 0;
|
|
arr.splice(found.idx, count, elem);
|
|
return arr;
|
|
}
|
|
|
|
},{}],3:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.VERSION = exports.USER_NEW = exports.TOPIC_SYS = exports.TOPIC_P2P = exports.TOPIC_NEW_CHAN = exports.TOPIC_NEW = exports.TOPIC_ME = exports.TOPIC_GRP = exports.TOPIC_FND = exports.TOPIC_CHAN = exports.RECV_TIMEOUT = exports.PROTOCOL_VERSION = exports.MESSAGE_STATUS_TO_ME = exports.MESSAGE_STATUS_SENT = exports.MESSAGE_STATUS_SENDING = exports.MESSAGE_STATUS_RECEIVED = exports.MESSAGE_STATUS_READ = exports.MESSAGE_STATUS_QUEUED = exports.MESSAGE_STATUS_NONE = exports.MESSAGE_STATUS_FAILED = exports.MESSAGE_STATUS_DEL_RANGE = exports.LOCAL_SEQID = exports.LIBRARY = exports.EXPIRE_PROMISES_TIMEOUT = exports.EXPIRE_PROMISES_PERIOD = exports.DEL_CHAR = exports.DEFAULT_MESSAGES_PAGE = void 0;
|
|
|
|
var _version = require("../version.json");
|
|
|
|
const PROTOCOL_VERSION = '0';
|
|
exports.PROTOCOL_VERSION = PROTOCOL_VERSION;
|
|
const VERSION = _version.version || '0.20';
|
|
exports.VERSION = VERSION;
|
|
const LIBRARY = 'tinodejs/' + VERSION;
|
|
exports.LIBRARY = LIBRARY;
|
|
const TOPIC_NEW = 'new';
|
|
exports.TOPIC_NEW = TOPIC_NEW;
|
|
const TOPIC_NEW_CHAN = 'nch';
|
|
exports.TOPIC_NEW_CHAN = TOPIC_NEW_CHAN;
|
|
const TOPIC_ME = 'me';
|
|
exports.TOPIC_ME = TOPIC_ME;
|
|
const TOPIC_FND = 'fnd';
|
|
exports.TOPIC_FND = TOPIC_FND;
|
|
const TOPIC_SYS = 'sys';
|
|
exports.TOPIC_SYS = TOPIC_SYS;
|
|
const TOPIC_CHAN = 'chn';
|
|
exports.TOPIC_CHAN = TOPIC_CHAN;
|
|
const TOPIC_GRP = 'grp;';
|
|
exports.TOPIC_GRP = TOPIC_GRP;
|
|
const TOPIC_P2P = 'p2p';
|
|
exports.TOPIC_P2P = TOPIC_P2P;
|
|
const USER_NEW = 'new';
|
|
exports.USER_NEW = USER_NEW;
|
|
const LOCAL_SEQID = 0xFFFFFFF;
|
|
exports.LOCAL_SEQID = LOCAL_SEQID;
|
|
const MESSAGE_STATUS_NONE = 0;
|
|
exports.MESSAGE_STATUS_NONE = MESSAGE_STATUS_NONE;
|
|
const MESSAGE_STATUS_QUEUED = 1;
|
|
exports.MESSAGE_STATUS_QUEUED = MESSAGE_STATUS_QUEUED;
|
|
const MESSAGE_STATUS_SENDING = 2;
|
|
exports.MESSAGE_STATUS_SENDING = MESSAGE_STATUS_SENDING;
|
|
const MESSAGE_STATUS_FAILED = 3;
|
|
exports.MESSAGE_STATUS_FAILED = MESSAGE_STATUS_FAILED;
|
|
const MESSAGE_STATUS_SENT = 4;
|
|
exports.MESSAGE_STATUS_SENT = MESSAGE_STATUS_SENT;
|
|
const MESSAGE_STATUS_RECEIVED = 5;
|
|
exports.MESSAGE_STATUS_RECEIVED = MESSAGE_STATUS_RECEIVED;
|
|
const MESSAGE_STATUS_READ = 6;
|
|
exports.MESSAGE_STATUS_READ = MESSAGE_STATUS_READ;
|
|
const MESSAGE_STATUS_TO_ME = 7;
|
|
exports.MESSAGE_STATUS_TO_ME = MESSAGE_STATUS_TO_ME;
|
|
const MESSAGE_STATUS_DEL_RANGE = 8;
|
|
exports.MESSAGE_STATUS_DEL_RANGE = MESSAGE_STATUS_DEL_RANGE;
|
|
const EXPIRE_PROMISES_TIMEOUT = 5000;
|
|
exports.EXPIRE_PROMISES_TIMEOUT = EXPIRE_PROMISES_TIMEOUT;
|
|
const EXPIRE_PROMISES_PERIOD = 1000;
|
|
exports.EXPIRE_PROMISES_PERIOD = EXPIRE_PROMISES_PERIOD;
|
|
const RECV_TIMEOUT = 100;
|
|
exports.RECV_TIMEOUT = RECV_TIMEOUT;
|
|
const DEFAULT_MESSAGES_PAGE = 24;
|
|
exports.DEFAULT_MESSAGES_PAGE = DEFAULT_MESSAGES_PAGE;
|
|
const DEL_CHAR = '\u2421';
|
|
exports.DEL_CHAR = DEL_CHAR;
|
|
|
|
},{"../version.json":12}],4:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
|
|
var _utils = require("./utils.js");
|
|
|
|
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
|
|
|
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
|
|
function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
|
|
|
|
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
|
|
|
function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
|
|
|
|
function _classStaticPrivateFieldSpecSet(receiver, classConstructor, descriptor, value) { _classCheckPrivateStaticAccess(receiver, classConstructor); _classCheckPrivateStaticFieldDescriptor(descriptor, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
|
|
|
|
function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
|
|
|
|
function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) { _classCheckPrivateStaticAccess(receiver, classConstructor); _classCheckPrivateStaticFieldDescriptor(descriptor, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
|
|
|
function _classCheckPrivateStaticFieldDescriptor(descriptor, action) { if (descriptor === undefined) { throw new TypeError("attempted to " + action + " private static field before its declaration"); } }
|
|
|
|
function _classCheckPrivateStaticAccess(receiver, classConstructor) { if (receiver !== classConstructor) { throw new TypeError("Private static access of wrong provenance"); } }
|
|
|
|
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
|
|
|
|
function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
|
|
|
|
let WebSocketProvider;
|
|
let XHRProvider;
|
|
const NETWORK_ERROR = 503;
|
|
const NETWORK_ERROR_TEXT = "Connection failed";
|
|
const NETWORK_USER = 418;
|
|
const NETWORK_USER_TEXT = "Disconnected by client";
|
|
const _BOFF_BASE = 2000;
|
|
const _BOFF_MAX_ITER = 10;
|
|
const _BOFF_JITTER = 0.3;
|
|
|
|
function makeBaseUrl(host, protocol, version, apiKey) {
|
|
let url = null;
|
|
|
|
if (['http', 'https', 'ws', 'wss'].includes(protocol)) {
|
|
url = `${protocol}://${host}`;
|
|
|
|
if (url.charAt(url.length - 1) !== '/') {
|
|
url += '/';
|
|
}
|
|
|
|
url += 'v' + version + '/channels';
|
|
|
|
if (['http', 'https'].includes(protocol)) {
|
|
url += '/lp';
|
|
}
|
|
|
|
url += '?apikey=' + apiKey;
|
|
}
|
|
|
|
return url;
|
|
}
|
|
|
|
var _boffTimer = new WeakMap();
|
|
|
|
var _boffIteration = new WeakMap();
|
|
|
|
var _boffClosed = new WeakMap();
|
|
|
|
var _socket = new WeakMap();
|
|
|
|
var _boffReconnect = new WeakSet();
|
|
|
|
var _boffStop = new WeakSet();
|
|
|
|
var _boffReset = new WeakSet();
|
|
|
|
var _init_lp = new WeakSet();
|
|
|
|
var _init_ws = new WeakSet();
|
|
|
|
class Connection {
|
|
constructor(config, version_, autoreconnect_) {
|
|
_classPrivateMethodInitSpec(this, _init_ws);
|
|
|
|
_classPrivateMethodInitSpec(this, _init_lp);
|
|
|
|
_classPrivateMethodInitSpec(this, _boffReset);
|
|
|
|
_classPrivateMethodInitSpec(this, _boffStop);
|
|
|
|
_classPrivateMethodInitSpec(this, _boffReconnect);
|
|
|
|
_classPrivateFieldInitSpec(this, _boffTimer, {
|
|
writable: true,
|
|
value: null
|
|
});
|
|
|
|
_classPrivateFieldInitSpec(this, _boffIteration, {
|
|
writable: true,
|
|
value: 0
|
|
});
|
|
|
|
_classPrivateFieldInitSpec(this, _boffClosed, {
|
|
writable: true,
|
|
value: false
|
|
});
|
|
|
|
_classPrivateFieldInitSpec(this, _socket, {
|
|
writable: true,
|
|
value: null
|
|
});
|
|
|
|
_defineProperty(this, "host", void 0);
|
|
|
|
_defineProperty(this, "secure", void 0);
|
|
|
|
_defineProperty(this, "apiKey", void 0);
|
|
|
|
_defineProperty(this, "version", void 0);
|
|
|
|
_defineProperty(this, "autoreconnect", void 0);
|
|
|
|
_defineProperty(this, "initialized", void 0);
|
|
|
|
_defineProperty(this, "onMessage", undefined);
|
|
|
|
_defineProperty(this, "onDisconnect", undefined);
|
|
|
|
_defineProperty(this, "onOpen", undefined);
|
|
|
|
_defineProperty(this, "onAutoreconnectIteration", undefined);
|
|
|
|
this.host = config.host;
|
|
this.secure = config.secure;
|
|
this.apiKey = config.apiKey;
|
|
this.version = version_;
|
|
this.autoreconnect = autoreconnect_;
|
|
|
|
if (config.transport === 'lp') {
|
|
_classPrivateMethodGet(this, _init_lp, _init_lp2).call(this);
|
|
|
|
this.initialized = 'lp';
|
|
} else if (config.transport === 'ws') {
|
|
_classPrivateMethodGet(this, _init_ws, _init_ws2).call(this);
|
|
|
|
this.initialized = 'ws';
|
|
}
|
|
|
|
if (!this.initialized) {
|
|
_classStaticPrivateFieldSpecGet(Connection, Connection, _log).call(Connection, "Unknown or invalid network transport. Running under Node? Call 'Tinode.setNetworkProviders()'.");
|
|
|
|
throw new Error("Unknown or invalid network transport. Running under Node? Call 'Tinode.setNetworkProviders()'.");
|
|
}
|
|
}
|
|
|
|
static setNetworkProviders(wsProvider, xhrProvider) {
|
|
WebSocketProvider = wsProvider;
|
|
XHRProvider = xhrProvider;
|
|
}
|
|
|
|
static set logger(l) {
|
|
_classStaticPrivateFieldSpecSet(Connection, Connection, _log, l);
|
|
}
|
|
|
|
connect(host_, force) {
|
|
return Promise.reject(null);
|
|
}
|
|
|
|
reconnect(force) {}
|
|
|
|
disconnect() {}
|
|
|
|
sendText(msg) {}
|
|
|
|
isConnected() {
|
|
return false;
|
|
}
|
|
|
|
transport() {
|
|
return this.initialized;
|
|
}
|
|
|
|
probe() {
|
|
this.sendText('1');
|
|
}
|
|
|
|
backoffReset() {
|
|
_classPrivateMethodGet(this, _boffReset, _boffReset2).call(this);
|
|
}
|
|
|
|
}
|
|
|
|
exports.default = Connection;
|
|
|
|
function _boffReconnect2() {
|
|
clearTimeout(_classPrivateFieldGet(this, _boffTimer));
|
|
|
|
const timeout = _BOFF_BASE * (Math.pow(2, _classPrivateFieldGet(this, _boffIteration)) * (1.0 + _BOFF_JITTER * Math.random()));
|
|
|
|
_classPrivateFieldSet(this, _boffIteration, _classPrivateFieldGet(this, _boffIteration) >= _BOFF_MAX_ITER ? _classPrivateFieldGet(this, _boffIteration) : _classPrivateFieldGet(this, _boffIteration) + 1);
|
|
|
|
if (this.onAutoreconnectIteration) {
|
|
this.onAutoreconnectIteration(timeout);
|
|
}
|
|
|
|
_classPrivateFieldSet(this, _boffTimer, setTimeout(_ => {
|
|
_classStaticPrivateFieldSpecGet(Connection, Connection, _log).call(Connection, `Reconnecting, iter=${_classPrivateFieldGet(this, _boffIteration)}, timeout=${timeout}`);
|
|
|
|
if (!_classPrivateFieldGet(this, _boffClosed)) {
|
|
const prom = this.connect();
|
|
|
|
if (this.onAutoreconnectIteration) {
|
|
this.onAutoreconnectIteration(0, prom);
|
|
} else {
|
|
prom.catch(() => {});
|
|
}
|
|
} else if (this.onAutoreconnectIteration) {
|
|
this.onAutoreconnectIteration(-1);
|
|
}
|
|
}, timeout));
|
|
}
|
|
|
|
function _boffStop2() {
|
|
clearTimeout(_classPrivateFieldGet(this, _boffTimer));
|
|
|
|
_classPrivateFieldSet(this, _boffTimer, null);
|
|
}
|
|
|
|
function _boffReset2() {
|
|
_classPrivateFieldSet(this, _boffIteration, 0);
|
|
}
|
|
|
|
function _init_lp2() {
|
|
const XDR_UNSENT = 0;
|
|
const XDR_OPENED = 1;
|
|
const XDR_HEADERS_RECEIVED = 2;
|
|
const XDR_LOADING = 3;
|
|
const XDR_DONE = 4;
|
|
let _lpURL = null;
|
|
let _poller = null;
|
|
let _sender = null;
|
|
|
|
let lp_sender = url_ => {
|
|
const sender = new XHRProvider();
|
|
|
|
sender.onreadystatechange = evt => {
|
|
if (sender.readyState == XDR_DONE && sender.status >= 400) {
|
|
throw new Error(`LP sender failed, ${sender.status}`);
|
|
}
|
|
};
|
|
|
|
sender.open('POST', url_, true);
|
|
return sender;
|
|
};
|
|
|
|
let lp_poller = (url_, resolve, reject) => {
|
|
let poller = new XHRProvider();
|
|
let promiseCompleted = false;
|
|
|
|
poller.onreadystatechange = evt => {
|
|
if (poller.readyState == XDR_DONE) {
|
|
if (poller.status == 201) {
|
|
let pkt = JSON.parse(poller.responseText, _utils.jsonParseHelper);
|
|
_lpURL = url_ + '&sid=' + pkt.ctrl.params.sid;
|
|
poller = lp_poller(_lpURL);
|
|
poller.send(null);
|
|
|
|
if (this.onOpen) {
|
|
this.onOpen();
|
|
}
|
|
|
|
if (resolve) {
|
|
promiseCompleted = true;
|
|
resolve();
|
|
}
|
|
|
|
if (this.autoreconnect) {
|
|
_classPrivateMethodGet(this, _boffStop, _boffStop2).call(this);
|
|
}
|
|
} else if (poller.status < 400) {
|
|
if (this.onMessage) {
|
|
this.onMessage(poller.responseText);
|
|
}
|
|
|
|
poller = lp_poller(_lpURL);
|
|
poller.send(null);
|
|
} else {
|
|
if (reject && !promiseCompleted) {
|
|
promiseCompleted = true;
|
|
reject(poller.responseText);
|
|
}
|
|
|
|
if (this.onMessage && poller.responseText) {
|
|
this.onMessage(poller.responseText);
|
|
}
|
|
|
|
if (this.onDisconnect) {
|
|
const code = poller.status || (_classPrivateFieldGet(this, _boffClosed) ? NETWORK_USER : NETWORK_ERROR);
|
|
const text = poller.responseText || (_classPrivateFieldGet(this, _boffClosed) ? NETWORK_USER_TEXT : NETWORK_ERROR_TEXT);
|
|
this.onDisconnect(new Error(text + ' (' + code + ')'), code);
|
|
}
|
|
|
|
poller = null;
|
|
|
|
if (!_classPrivateFieldGet(this, _boffClosed) && this.autoreconnect) {
|
|
_classPrivateMethodGet(this, _boffReconnect, _boffReconnect2).call(this);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
poller.open('POST', url_, true);
|
|
return poller;
|
|
};
|
|
|
|
this.connect = (host_, force) => {
|
|
_classPrivateFieldSet(this, _boffClosed, false);
|
|
|
|
if (_poller) {
|
|
if (!force) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
_poller.onreadystatechange = undefined;
|
|
|
|
_poller.abort();
|
|
|
|
_poller = null;
|
|
}
|
|
|
|
if (host_) {
|
|
this.host = host_;
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const url = makeBaseUrl(this.host, this.secure ? 'https' : 'http', this.version, this.apiKey);
|
|
|
|
_classStaticPrivateFieldSpecGet(Connection, Connection, _log).call(Connection, "LP connecting to:", url);
|
|
|
|
_poller = lp_poller(url, resolve, reject);
|
|
|
|
_poller.send(null);
|
|
}).catch(err => {
|
|
_classStaticPrivateFieldSpecGet(Connection, Connection, _log).call(Connection, "LP connection failed:", err);
|
|
});
|
|
};
|
|
|
|
this.reconnect = force => {
|
|
_classPrivateMethodGet(this, _boffStop, _boffStop2).call(this);
|
|
|
|
this.connect(null, force);
|
|
};
|
|
|
|
this.disconnect = () => {
|
|
_classPrivateFieldSet(this, _boffClosed, true);
|
|
|
|
_classPrivateMethodGet(this, _boffStop, _boffStop2).call(this);
|
|
|
|
if (_sender) {
|
|
_sender.onreadystatechange = undefined;
|
|
|
|
_sender.abort();
|
|
|
|
_sender = null;
|
|
}
|
|
|
|
if (_poller) {
|
|
_poller.onreadystatechange = undefined;
|
|
|
|
_poller.abort();
|
|
|
|
_poller = null;
|
|
}
|
|
|
|
if (this.onDisconnect) {
|
|
this.onDisconnect(new Error(NETWORK_USER_TEXT + ' (' + NETWORK_USER + ')'), NETWORK_USER);
|
|
}
|
|
|
|
_lpURL = null;
|
|
};
|
|
|
|
this.sendText = msg => {
|
|
_sender = lp_sender(_lpURL);
|
|
|
|
if (_sender && _sender.readyState == XDR_OPENED) {
|
|
_sender.send(msg);
|
|
} else {
|
|
throw new Error("Long poller failed to connect");
|
|
}
|
|
};
|
|
|
|
this.isConnected = () => {
|
|
return _poller && true;
|
|
};
|
|
}
|
|
|
|
function _init_ws2() {
|
|
this.connect = (host_, force) => {
|
|
_classPrivateFieldSet(this, _boffClosed, false);
|
|
|
|
if (_classPrivateFieldGet(this, _socket)) {
|
|
if (!force && _classPrivateFieldGet(this, _socket).readyState == _classPrivateFieldGet(this, _socket).OPEN) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
_classPrivateFieldGet(this, _socket).close();
|
|
|
|
_classPrivateFieldSet(this, _socket, null);
|
|
}
|
|
|
|
if (host_) {
|
|
this.host = host_;
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const url = makeBaseUrl(this.host, this.secure ? 'wss' : 'ws', this.version, this.apiKey);
|
|
|
|
_classStaticPrivateFieldSpecGet(Connection, Connection, _log).call(Connection, "WS connecting to: ", url);
|
|
|
|
const conn = new WebSocketProvider(url);
|
|
|
|
conn.onerror = err => {
|
|
reject(err);
|
|
};
|
|
|
|
conn.onopen = evt => {
|
|
if (this.autoreconnect) {
|
|
_classPrivateMethodGet(this, _boffStop, _boffStop2).call(this);
|
|
}
|
|
|
|
if (this.onOpen) {
|
|
this.onOpen();
|
|
}
|
|
|
|
resolve();
|
|
};
|
|
|
|
conn.onclose = evt => {
|
|
_classPrivateFieldSet(this, _socket, null);
|
|
|
|
if (this.onDisconnect) {
|
|
const code = _classPrivateFieldGet(this, _boffClosed) ? NETWORK_USER : NETWORK_ERROR;
|
|
this.onDisconnect(new Error(_classPrivateFieldGet(this, _boffClosed) ? NETWORK_USER_TEXT : NETWORK_ERROR_TEXT + ' (' + code + ')'), code);
|
|
}
|
|
|
|
if (!_classPrivateFieldGet(this, _boffClosed) && this.autoreconnect) {
|
|
_classPrivateMethodGet(this, _boffReconnect, _boffReconnect2).call(this);
|
|
}
|
|
};
|
|
|
|
conn.onmessage = evt => {
|
|
if (this.onMessage) {
|
|
this.onMessage(evt.data);
|
|
}
|
|
};
|
|
|
|
_classPrivateFieldSet(this, _socket, conn);
|
|
});
|
|
};
|
|
|
|
this.reconnect = force => {
|
|
_classPrivateMethodGet(this, _boffStop, _boffStop2).call(this);
|
|
|
|
this.connect(null, force);
|
|
};
|
|
|
|
this.disconnect = () => {
|
|
_classPrivateFieldSet(this, _boffClosed, true);
|
|
|
|
_classPrivateMethodGet(this, _boffStop, _boffStop2).call(this);
|
|
|
|
if (!_classPrivateFieldGet(this, _socket)) {
|
|
return;
|
|
}
|
|
|
|
_classPrivateFieldGet(this, _socket).close();
|
|
|
|
_classPrivateFieldSet(this, _socket, null);
|
|
};
|
|
|
|
this.sendText = msg => {
|
|
if (_classPrivateFieldGet(this, _socket) && _classPrivateFieldGet(this, _socket).readyState == _classPrivateFieldGet(this, _socket).OPEN) {
|
|
_classPrivateFieldGet(this, _socket).send(msg);
|
|
} else {
|
|
throw new Error("Websocket is not connected");
|
|
}
|
|
};
|
|
|
|
this.isConnected = () => {
|
|
return _classPrivateFieldGet(this, _socket) && _classPrivateFieldGet(this, _socket).readyState == _classPrivateFieldGet(this, _socket).OPEN;
|
|
};
|
|
}
|
|
|
|
var _log = {
|
|
writable: true,
|
|
value: _ => {}
|
|
};
|
|
Connection.NETWORK_ERROR = NETWORK_ERROR;
|
|
Connection.NETWORK_ERROR_TEXT = NETWORK_ERROR_TEXT;
|
|
Connection.NETWORK_USER = NETWORK_USER;
|
|
Connection.NETWORK_USER_TEXT = NETWORK_USER_TEXT;
|
|
|
|
},{"./utils.js":11}],5:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
|
|
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
|
|
|
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
|
|
function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) { _classCheckPrivateStaticAccess(receiver, classConstructor); _classCheckPrivateStaticFieldDescriptor(descriptor, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
|
|
|
function _classCheckPrivateStaticFieldDescriptor(descriptor, action) { if (descriptor === undefined) { throw new TypeError("attempted to " + action + " private static field before its declaration"); } }
|
|
|
|
function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
|
|
|
|
function _classStaticPrivateMethodGet(receiver, classConstructor, method) { _classCheckPrivateStaticAccess(receiver, classConstructor); return method; }
|
|
|
|
function _classCheckPrivateStaticAccess(receiver, classConstructor) { if (receiver !== classConstructor) { throw new TypeError("Private static access of wrong provenance"); } }
|
|
|
|
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
|
|
|
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
|
|
|
|
function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
|
|
|
|
function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
|
|
|
|
function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
|
|
|
|
const DB_VERSION = 1;
|
|
const DB_NAME = 'tinode-web';
|
|
let IDBProvider;
|
|
|
|
var _onError = new WeakMap();
|
|
|
|
var _logger = new WeakMap();
|
|
|
|
var _mapObjects = new WeakSet();
|
|
|
|
class DB {
|
|
constructor(onError, logger) {
|
|
_classPrivateMethodInitSpec(this, _mapObjects);
|
|
|
|
_classPrivateFieldInitSpec(this, _onError, {
|
|
writable: true,
|
|
value: _ => {}
|
|
});
|
|
|
|
_classPrivateFieldInitSpec(this, _logger, {
|
|
writable: true,
|
|
value: _ => {}
|
|
});
|
|
|
|
_defineProperty(this, "db", null);
|
|
|
|
_defineProperty(this, "disabled", false);
|
|
|
|
_classPrivateFieldSet(this, _onError, onError || _classPrivateFieldGet(this, _onError));
|
|
|
|
_classPrivateFieldSet(this, _logger, logger || _classPrivateFieldGet(this, _logger));
|
|
}
|
|
|
|
initDatabase() {
|
|
return new Promise((resolve, reject) => {
|
|
const req = IDBProvider.open(DB_NAME, DB_VERSION);
|
|
|
|
req.onsuccess = event => {
|
|
this.db = event.target.result;
|
|
this.disabled = false;
|
|
resolve(this.db);
|
|
};
|
|
|
|
req.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', "failed to initialize", event);
|
|
|
|
reject(event.target.error);
|
|
|
|
_classPrivateFieldGet(this, _onError).call(this, event.target.error);
|
|
};
|
|
|
|
req.onupgradeneeded = event => {
|
|
this.db = event.target.result;
|
|
|
|
this.db.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', "failed to create storage", event);
|
|
|
|
_classPrivateFieldGet(this, _onError).call(this, event.target.error);
|
|
};
|
|
|
|
this.db.createObjectStore('topic', {
|
|
keyPath: 'name'
|
|
});
|
|
this.db.createObjectStore('user', {
|
|
keyPath: 'uid'
|
|
});
|
|
this.db.createObjectStore('subscription', {
|
|
keyPath: ['topic', 'uid']
|
|
});
|
|
this.db.createObjectStore('message', {
|
|
keyPath: ['topic', 'seq']
|
|
});
|
|
};
|
|
});
|
|
}
|
|
|
|
deleteDatabase() {
|
|
if (this.db) {
|
|
this.db.close();
|
|
this.db = null;
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const req = IDBProvider.deleteDatabase(DB_NAME);
|
|
|
|
req.onblocked = event => {
|
|
if (this.db) {
|
|
this.db.close();
|
|
}
|
|
|
|
const err = new Error("blocked");
|
|
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'deleteDatabase', err);
|
|
|
|
reject(err);
|
|
};
|
|
|
|
req.onsuccess = event => {
|
|
this.db = null;
|
|
this.disabled = true;
|
|
resolve(true);
|
|
};
|
|
|
|
req.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'deleteDatabase', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
});
|
|
}
|
|
|
|
isReady() {
|
|
return !!this.db;
|
|
}
|
|
|
|
updTopic(topic) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['topic'], 'readwrite');
|
|
|
|
trx.oncomplete = event => {
|
|
resolve(event.target.result);
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'updTopic', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
const req = trx.objectStore('topic').get(topic.name);
|
|
|
|
req.onsuccess = event => {
|
|
trx.objectStore('topic').put(_classStaticPrivateMethodGet(DB, DB, _serializeTopic).call(DB, req.result, topic));
|
|
trx.commit();
|
|
};
|
|
});
|
|
}
|
|
|
|
markTopicAsDeleted(name) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['topic'], 'readwrite');
|
|
|
|
trx.oncomplete = event => {
|
|
resolve(event.target.result);
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'markTopicAsDeleted', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
const req = trx.objectStore('topic').get(name);
|
|
|
|
req.onsuccess = event => {
|
|
const topic = event.target.result;
|
|
topic._deleted = true;
|
|
trx.objectStore('topic').put(topic);
|
|
trx.commit();
|
|
};
|
|
});
|
|
}
|
|
|
|
remTopic(name) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['topic', 'subscription', 'message'], 'readwrite');
|
|
|
|
trx.oncomplete = event => {
|
|
resolve(event.target.result);
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'remTopic', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore('topic').delete(IDBKeyRange.only(name));
|
|
trx.objectStore('subscription').delete(IDBKeyRange.bound([name, '-'], [name, '~']));
|
|
trx.objectStore('message').delete(IDBKeyRange.bound([name, 0], [name, Number.MAX_SAFE_INTEGER]));
|
|
trx.commit();
|
|
});
|
|
}
|
|
|
|
mapTopics(callback, context) {
|
|
return _classPrivateMethodGet(this, _mapObjects, _mapObjects2).call(this, 'topic', callback, context);
|
|
}
|
|
|
|
deserializeTopic(topic, src) {
|
|
_classStaticPrivateMethodGet(DB, DB, _deserializeTopic).call(DB, topic, src);
|
|
}
|
|
|
|
updUser(uid, pub) {
|
|
if (arguments.length < 2 || pub === undefined) {
|
|
return;
|
|
}
|
|
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['user'], 'readwrite');
|
|
|
|
trx.oncomplete = event => {
|
|
resolve(event.target.result);
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'updUser', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore('user').put({
|
|
uid: uid,
|
|
public: pub
|
|
});
|
|
trx.commit();
|
|
});
|
|
}
|
|
|
|
remUser(uid) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['user'], 'readwrite');
|
|
|
|
trx.oncomplete = event => {
|
|
resolve(event.target.result);
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'remUser', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore('user').delete(IDBKeyRange.only(uid));
|
|
trx.commit();
|
|
});
|
|
}
|
|
|
|
mapUsers(callback, context) {
|
|
return _classPrivateMethodGet(this, _mapObjects, _mapObjects2).call(this, 'user', callback, context);
|
|
}
|
|
|
|
getUser(uid) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['user']);
|
|
|
|
trx.oncomplete = event => {
|
|
const user = event.target.result;
|
|
resolve({
|
|
user: user.uid,
|
|
public: user.public
|
|
});
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'getUser', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore('user').get(uid);
|
|
});
|
|
}
|
|
|
|
updSubscription(topicName, uid, sub) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['subscription'], 'readwrite');
|
|
|
|
trx.oncomplete = event => {
|
|
resolve(event.target.result);
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'updSubscription', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore('subscription').get([topicName, uid]).onsuccess = event => {
|
|
trx.objectStore('subscription').put(_classStaticPrivateMethodGet(DB, DB, _serializeSubscription).call(DB, event.target.result, topicName, uid, sub));
|
|
trx.commit();
|
|
};
|
|
});
|
|
}
|
|
|
|
mapSubscriptions(topicName, callback, context) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve([]) : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['subscription']);
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'mapSubscriptions', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore('subscription').getAll(IDBKeyRange.bound([topicName, '-'], [topicName, '~'])).onsuccess = event => {
|
|
if (callback) {
|
|
event.target.result.forEach(topic => {
|
|
callback.call(context, topic);
|
|
});
|
|
}
|
|
|
|
resolve(event.target.result);
|
|
};
|
|
});
|
|
}
|
|
|
|
addMessage(msg) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['message'], 'readwrite');
|
|
|
|
trx.onsuccess = event => {
|
|
resolve(event.target.result);
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'addMessage', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore('message').add(_classStaticPrivateMethodGet(DB, DB, _serializeMessage).call(DB, null, msg));
|
|
trx.commit();
|
|
});
|
|
}
|
|
|
|
updMessageStatus(topicName, seq, status) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction(['message'], 'readwrite');
|
|
|
|
trx.onsuccess = event => {
|
|
resolve(event.target.result);
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'updMessageStatus', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
const req = trx.objectStore('message').get(IDBKeyRange.only([topicName, seq]));
|
|
|
|
req.onsuccess = event => {
|
|
const src = req.result || event.target.result;
|
|
|
|
if (!src || src._status == status) {
|
|
trx.commit();
|
|
return;
|
|
}
|
|
|
|
trx.objectStore('message').put(_classStaticPrivateMethodGet(DB, DB, _serializeMessage).call(DB, src, {
|
|
topic: topicName,
|
|
seq: seq,
|
|
_status: status
|
|
}));
|
|
trx.commit();
|
|
};
|
|
});
|
|
}
|
|
|
|
remMessages(topicName, from, to) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
if (!from && !to) {
|
|
from = 0;
|
|
to = Number.MAX_SAFE_INTEGER;
|
|
}
|
|
|
|
const range = to > 0 ? IDBKeyRange.bound([topicName, from], [topicName, to], false, true) : IDBKeyRange.only([topicName, from]);
|
|
const trx = this.db.transaction(['message'], 'readwrite');
|
|
|
|
trx.onsuccess = event => {
|
|
resolve(event.target.result);
|
|
};
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'remMessages', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore('message').delete(range);
|
|
trx.commit();
|
|
});
|
|
}
|
|
|
|
readMessages(topicName, query, callback, context) {
|
|
if (!this.isReady()) {
|
|
return this.disabled ? Promise.resolve([]) : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
query = query || {};
|
|
const since = query.since > 0 ? query.since : 0;
|
|
const before = query.before > 0 ? query.before : Number.MAX_SAFE_INTEGER;
|
|
const limit = query.limit | 0;
|
|
const result = [];
|
|
const range = IDBKeyRange.bound([topicName, since], [topicName, before], false, true);
|
|
const trx = this.db.transaction(['message']);
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'readMessages', event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore('message').openCursor(range, 'prev').onsuccess = event => {
|
|
const cursor = event.target.result;
|
|
|
|
if (cursor) {
|
|
if (callback) {
|
|
callback.call(context, cursor.value);
|
|
}
|
|
|
|
result.push(cursor.value);
|
|
|
|
if (limit <= 0 || result.length < limit) {
|
|
cursor.continue();
|
|
} else {
|
|
resolve(result);
|
|
}
|
|
} else {
|
|
resolve(result);
|
|
}
|
|
};
|
|
});
|
|
}
|
|
|
|
static setDatabaseProvider(idbProvider) {
|
|
IDBProvider = idbProvider;
|
|
}
|
|
|
|
}
|
|
|
|
exports.default = DB;
|
|
|
|
function _mapObjects2(source, callback, context) {
|
|
if (!this.db) {
|
|
return disabled ? Promise.resolve([]) : Promise.reject(new Error("not initialized"));
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const trx = this.db.transaction([source]);
|
|
|
|
trx.onerror = event => {
|
|
_classPrivateFieldGet(this, _logger).call(this, 'PCache', 'mapObjects', source, event.target.error);
|
|
|
|
reject(event.target.error);
|
|
};
|
|
|
|
trx.objectStore(source).getAll().onsuccess = event => {
|
|
if (callback) {
|
|
event.target.result.forEach(topic => {
|
|
callback.call(context, topic);
|
|
});
|
|
}
|
|
|
|
resolve(event.target.result);
|
|
};
|
|
});
|
|
}
|
|
|
|
function _deserializeTopic(topic, src) {
|
|
_classStaticPrivateFieldSpecGet(DB, DB, _topic_fields).forEach(f => {
|
|
if (src.hasOwnProperty(f)) {
|
|
topic[f] = src[f];
|
|
}
|
|
});
|
|
|
|
if (Array.isArray(src.tags)) {
|
|
topic._tags = src.tags;
|
|
}
|
|
|
|
if (src.acs) {
|
|
topic.setAccessMode(src.acs);
|
|
}
|
|
|
|
topic.seq |= 0;
|
|
topic.read |= 0;
|
|
topic.unread = Math.max(0, topic.seq - topic.read);
|
|
}
|
|
|
|
function _serializeTopic(dst, src) {
|
|
const res = dst || {
|
|
name: src.name
|
|
};
|
|
|
|
_classStaticPrivateFieldSpecGet(DB, DB, _topic_fields).forEach(f => {
|
|
if (src.hasOwnProperty(f)) {
|
|
res[f] = src[f];
|
|
}
|
|
});
|
|
|
|
if (Array.isArray(src._tags)) {
|
|
res.tags = src._tags;
|
|
}
|
|
|
|
if (src.acs) {
|
|
res.acs = src.getAccessMode().jsonHelper();
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
function _serializeSubscription(dst, topicName, uid, sub) {
|
|
const fields = ['updated', 'mode', 'read', 'recv', 'clear', 'lastSeen', 'userAgent'];
|
|
const res = dst || {
|
|
topic: topicName,
|
|
uid: uid
|
|
};
|
|
fields.forEach(f => {
|
|
if (sub.hasOwnProperty(f)) {
|
|
res[f] = sub[f];
|
|
}
|
|
});
|
|
return res;
|
|
}
|
|
|
|
function _serializeMessage(dst, msg) {
|
|
const fields = ['topic', 'seq', 'ts', '_status', 'from', 'head', 'content'];
|
|
const res = dst || {};
|
|
fields.forEach(f => {
|
|
if (msg.hasOwnProperty(f)) {
|
|
res[f] = msg[f];
|
|
}
|
|
});
|
|
return res;
|
|
}
|
|
|
|
var _topic_fields = {
|
|
writable: true,
|
|
value: ['created', 'updated', 'deleted', 'read', 'recv', 'seq', 'clear', 'defacs', 'creds', 'public', 'trusted', 'private', 'touched', '_deleted']
|
|
};
|
|
|
|
},{}],6:[function(require,module,exports){
|
|
/**
|
|
* @copyright 2015-2022 Tinode LLC.
|
|
* @summary Minimally rich text representation and formatting for Tinode.
|
|
* @license Apache 2.0
|
|
*
|
|
* @file Basic parser and formatter for very simple text markup. Mostly targeted at
|
|
* mobile use cases similar to Telegram, WhatsApp, and FB Messenger.
|
|
*
|
|
* <p>Supports conversion of user keyboard input to formatted text:</p>
|
|
* <ul>
|
|
* <li>*abc* → <b>abc</b></li>
|
|
* <li>_abc_ → <i>abc</i></li>
|
|
* <li>~abc~ → <del>abc</del></li>
|
|
* <li>`abc` → <tt>abc</tt></li>
|
|
* </ul>
|
|
* Also supports forms and buttons.
|
|
*
|
|
* Nested formatting is supported, e.g. *abc _def_* -> <b>abc <i>def</i></b>
|
|
* URLs, @mentions, and #hashtags are extracted and converted into links.
|
|
* Forms and buttons can be added procedurally.
|
|
* JSON data representation is inspired by Draft.js raw formatting.
|
|
*
|
|
*
|
|
* @example
|
|
* Text:
|
|
* <pre>
|
|
* this is *bold*, `code` and _italic_, ~strike~
|
|
* combined *bold and _italic_*
|
|
* an url: https://www.example.com/abc#fragment and another _www.tinode.co_
|
|
* this is a @mention and a #hashtag in a string
|
|
* second #hashtag
|
|
* </pre>
|
|
*
|
|
* Sample JSON representation of the text above:
|
|
* {
|
|
* "txt": "this is bold, code and italic, strike combined bold and italic an url: https://www.example.com/abc#fragment " +
|
|
* "and another www.tinode.co this is a @mention and a #hashtag in a string second #hashtag",
|
|
* "fmt": [
|
|
* { "at":8, "len":4,"tp":"ST" },{ "at":14, "len":4, "tp":"CO" },{ "at":23, "len":6, "tp":"EM"},
|
|
* { "at":31, "len":6, "tp":"DL" },{ "tp":"BR", "len":1, "at":37 },{ "at":56, "len":6, "tp":"EM" },
|
|
* { "at":47, "len":15, "tp":"ST" },{ "tp":"BR", "len":1, "at":62 },{ "at":120, "len":13, "tp":"EM" },
|
|
* { "at":71, "len":36, "key":0 },{ "at":120, "len":13, "key":1 },{ "tp":"BR", "len":1, "at":133 },
|
|
* { "at":144, "len":8, "key":2 },{ "at":159, "len":8, "key":3 },{ "tp":"BR", "len":1, "at":179 },
|
|
* { "at":187, "len":8, "key":3 },{ "tp":"BR", "len":1, "at":195 }
|
|
* ],
|
|
* "ent": [
|
|
* { "tp":"LN", "data":{ "url":"https://www.example.com/abc#fragment" } },
|
|
* { "tp":"LN", "data":{ "url":"http://www.tinode.co" } },
|
|
* { "tp":"MN", "data":{ "val":"mention" } },
|
|
* { "tp":"HT", "data":{ "val":"hashtag" } }
|
|
* ]
|
|
* }
|
|
*/
|
|
'use strict';
|
|
|
|
const MAX_FORM_ELEMENTS = 8;
|
|
const MAX_PREVIEW_ATTACHMENTS = 3;
|
|
const MAX_PREVIEW_DATA_SIZE = 64;
|
|
const JSON_MIME_TYPE = 'application/json';
|
|
const DRAFTY_MIME_TYPE = 'text/x-drafty';
|
|
const ALLOWED_ENT_FIELDS = ['act', 'height', 'duration', 'incoming', 'mime', 'name', 'preview', 'ref', 'size', 'state', 'url', 'val', 'width'];
|
|
const INLINE_STYLES = [{
|
|
name: 'ST',
|
|
start: /(?:^|[\W_])(\*)[^\s*]/,
|
|
end: /[^\s*](\*)(?=$|[\W_])/
|
|
}, {
|
|
name: 'EM',
|
|
start: /(?:^|\W)(_)[^\s_]/,
|
|
end: /[^\s_](_)(?=$|\W)/
|
|
}, {
|
|
name: 'DL',
|
|
start: /(?:^|[\W_])(~)[^\s~]/,
|
|
end: /[^\s~](~)(?=$|[\W_])/
|
|
}, {
|
|
name: 'CO',
|
|
start: /(?:^|\W)(`)[^`]/,
|
|
end: /[^`](`)(?=$|\W)/
|
|
}];
|
|
const FMT_WEIGHT = ['QQ'];
|
|
const ENTITY_TYPES = [{
|
|
name: 'LN',
|
|
dataName: 'url',
|
|
pack: function (val) {
|
|
if (!/^[a-z]+:\/\//i.test(val)) {
|
|
val = 'http://' + val;
|
|
}
|
|
|
|
return {
|
|
url: val
|
|
};
|
|
},
|
|
re: /(?:(?:https?|ftp):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/ig
|
|
}, {
|
|
name: 'MN',
|
|
dataName: 'val',
|
|
pack: function (val) {
|
|
return {
|
|
val: val.slice(1)
|
|
};
|
|
},
|
|
re: /\B@([\p{L}\p{N}][._\p{L}\p{N}]*[\p{L}\p{N}])/ug
|
|
}, {
|
|
name: 'HT',
|
|
dataName: 'val',
|
|
pack: function (val) {
|
|
return {
|
|
val: val.slice(1)
|
|
};
|
|
},
|
|
re: /\B#([\p{L}\p{N}][._\p{L}\p{N}]*[\p{L}\p{N}])/ug
|
|
}];
|
|
const HTML_TAGS = {
|
|
AU: {
|
|
name: 'audio',
|
|
isVoid: false
|
|
},
|
|
BN: {
|
|
name: 'button',
|
|
isVoid: false
|
|
},
|
|
BR: {
|
|
name: 'br',
|
|
isVoid: true
|
|
},
|
|
CO: {
|
|
name: 'tt',
|
|
isVoid: false
|
|
},
|
|
DL: {
|
|
name: 'del',
|
|
isVoid: false
|
|
},
|
|
EM: {
|
|
name: 'i',
|
|
isVoid: false
|
|
},
|
|
EX: {
|
|
name: '',
|
|
isVoid: true
|
|
},
|
|
FM: {
|
|
name: 'div',
|
|
isVoid: false
|
|
},
|
|
HD: {
|
|
name: '',
|
|
isVoid: false
|
|
},
|
|
HL: {
|
|
name: 'span',
|
|
isVoid: false
|
|
},
|
|
HT: {
|
|
name: 'a',
|
|
isVoid: false
|
|
},
|
|
IM: {
|
|
name: 'img',
|
|
isVoid: false
|
|
},
|
|
LN: {
|
|
name: 'a',
|
|
isVoid: false
|
|
},
|
|
MN: {
|
|
name: 'a',
|
|
isVoid: false
|
|
},
|
|
RW: {
|
|
name: 'div',
|
|
isVoid: false
|
|
},
|
|
QQ: {
|
|
name: 'div',
|
|
isVoid: false
|
|
},
|
|
ST: {
|
|
name: 'b',
|
|
isVoid: false
|
|
},
|
|
VC: {
|
|
name: 'div',
|
|
isVoid: false
|
|
}
|
|
};
|
|
|
|
function base64toObjectUrl(b64, contentType, logger) {
|
|
if (!b64) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const bin = atob(b64);
|
|
const length = bin.length;
|
|
const buf = new ArrayBuffer(length);
|
|
const arr = new Uint8Array(buf);
|
|
|
|
for (let i = 0; i < length; i++) {
|
|
arr[i] = bin.charCodeAt(i);
|
|
}
|
|
|
|
return URL.createObjectURL(new Blob([buf], {
|
|
type: contentType
|
|
}));
|
|
} catch (err) {
|
|
if (logger) {
|
|
logger("Drafty: failed to convert object.", err.message);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function base64toDataUrl(b64, contentType) {
|
|
if (!b64) {
|
|
return null;
|
|
}
|
|
|
|
contentType = contentType || 'image/jpeg';
|
|
return 'data:' + contentType + ';base64,' + b64;
|
|
}
|
|
|
|
const DECORATORS = {
|
|
ST: {
|
|
open: _ => '<b>',
|
|
close: _ => '</b>'
|
|
},
|
|
EM: {
|
|
open: _ => '<i>',
|
|
close: _ => '</i>'
|
|
},
|
|
DL: {
|
|
open: _ => '<del>',
|
|
close: _ => '</del>'
|
|
},
|
|
CO: {
|
|
open: _ => '<tt>',
|
|
close: _ => '</tt>'
|
|
},
|
|
BR: {
|
|
open: _ => '<br/>',
|
|
close: _ => ''
|
|
},
|
|
HD: {
|
|
open: _ => '',
|
|
close: _ => ''
|
|
},
|
|
HL: {
|
|
open: _ => '<span style="color:teal">',
|
|
close: _ => '</span>'
|
|
},
|
|
LN: {
|
|
open: data => {
|
|
return '<a href="' + data.url + '">';
|
|
},
|
|
close: _ => '</a>',
|
|
props: data => {
|
|
return data ? {
|
|
href: data.url,
|
|
target: '_blank'
|
|
} : null;
|
|
}
|
|
},
|
|
MN: {
|
|
open: data => {
|
|
return '<a href="#' + data.val + '">';
|
|
},
|
|
close: _ => '</a>',
|
|
props: data => {
|
|
return data ? {
|
|
id: data.val
|
|
} : null;
|
|
}
|
|
},
|
|
HT: {
|
|
open: data => {
|
|
return '<a href="#' + data.val + '">';
|
|
},
|
|
close: _ => '</a>',
|
|
props: data => {
|
|
return data ? {
|
|
id: data.val
|
|
} : null;
|
|
}
|
|
},
|
|
BN: {
|
|
open: _ => '<button>',
|
|
close: _ => '</button>',
|
|
props: data => {
|
|
return data ? {
|
|
'data-act': data.act,
|
|
'data-val': data.val,
|
|
'data-name': data.name,
|
|
'data-ref': data.ref
|
|
} : null;
|
|
}
|
|
},
|
|
AU: {
|
|
open: data => {
|
|
const url = data.ref || base64toObjectUrl(data.val, data.mime, Drafty.logger);
|
|
return '<audio controls src="' + url + '">';
|
|
},
|
|
close: _ => '</audio>',
|
|
props: data => {
|
|
if (!data) return null;
|
|
return {
|
|
src: data.ref || base64toObjectUrl(data.val, data.mime, Drafty.logger),
|
|
'data-preload': data.ref ? 'metadata' : 'auto',
|
|
'data-duration': data.duration,
|
|
'data-name': data.name,
|
|
'data-size': data.val ? data.val.length * 0.75 | 0 : data.size | 0,
|
|
'data-mime': data.mime
|
|
};
|
|
}
|
|
},
|
|
IM: {
|
|
open: data => {
|
|
const tmpPreviewUrl = base64toDataUrl(data._tempPreview, data.mime);
|
|
const previewUrl = base64toObjectUrl(data.val, data.mime, Drafty.logger);
|
|
const downloadUrl = data.ref || previewUrl;
|
|
return (data.name ? '<a href="' + downloadUrl + '" download="' + data.name + '">' : '') + '<img src="' + (tmpPreviewUrl || previewUrl) + '"' + (data.width ? ' width="' + data.width + '"' : '') + (data.height ? ' height="' + data.height + '"' : '') + ' border="0" />';
|
|
},
|
|
close: data => {
|
|
return data.name ? '</a>' : '';
|
|
},
|
|
props: data => {
|
|
if (!data) return null;
|
|
return {
|
|
src: base64toDataUrl(data._tempPreview, data.mime) || data.ref || base64toObjectUrl(data.val, data.mime, Drafty.logger),
|
|
title: data.name,
|
|
alt: data.name,
|
|
'data-width': data.width,
|
|
'data-height': data.height,
|
|
'data-name': data.name,
|
|
'data-size': data.val ? data.val.length * 0.75 | 0 : data.size | 0,
|
|
'data-mime': data.mime
|
|
};
|
|
}
|
|
},
|
|
FM: {
|
|
open: _ => '<div>',
|
|
close: _ => '</div>'
|
|
},
|
|
RW: {
|
|
open: _ => '<div>',
|
|
close: _ => '</div>'
|
|
},
|
|
QQ: {
|
|
open: _ => '<div>',
|
|
close: _ => '</div>',
|
|
props: data => {
|
|
return data ? {} : null;
|
|
}
|
|
},
|
|
VC: {
|
|
open: _ => '<div>',
|
|
close: _ => '</div>',
|
|
props: data => {
|
|
if (!data) return {};
|
|
return {
|
|
'data-duration': data.duration,
|
|
'data-state': data.state
|
|
};
|
|
}
|
|
}
|
|
};
|
|
|
|
const Drafty = function () {
|
|
this.txt = '';
|
|
this.fmt = [];
|
|
this.ent = [];
|
|
};
|
|
|
|
Drafty.init = function (plainText) {
|
|
if (typeof plainText == 'undefined') {
|
|
plainText = '';
|
|
} else if (typeof plainText != 'string') {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
txt: plainText
|
|
};
|
|
};
|
|
|
|
Drafty.parse = function (content) {
|
|
if (typeof content != 'string') {
|
|
return null;
|
|
}
|
|
|
|
const lines = content.split(/\r?\n/);
|
|
const entityMap = [];
|
|
const entityIndex = {};
|
|
const blx = [];
|
|
lines.forEach(line => {
|
|
let spans = [];
|
|
let entities;
|
|
INLINE_STYLES.forEach(tag => {
|
|
spans = spans.concat(spannify(line, tag.start, tag.end, tag.name));
|
|
});
|
|
let block;
|
|
|
|
if (spans.length == 0) {
|
|
block = {
|
|
txt: line
|
|
};
|
|
} else {
|
|
spans.sort((a, b) => {
|
|
const diff = a.at - b.at;
|
|
return diff != 0 ? diff : b.end - a.end;
|
|
});
|
|
spans = toSpanTree(spans);
|
|
const chunks = chunkify(line, 0, line.length, spans);
|
|
const drafty = draftify(chunks, 0);
|
|
block = {
|
|
txt: drafty.txt,
|
|
fmt: drafty.fmt
|
|
};
|
|
}
|
|
|
|
entities = extractEntities(block.txt);
|
|
|
|
if (entities.length > 0) {
|
|
const ranges = [];
|
|
|
|
for (let i in entities) {
|
|
const entity = entities[i];
|
|
let index = entityIndex[entity.unique];
|
|
|
|
if (!index) {
|
|
index = entityMap.length;
|
|
entityIndex[entity.unique] = index;
|
|
entityMap.push({
|
|
tp: entity.type,
|
|
data: entity.data
|
|
});
|
|
}
|
|
|
|
ranges.push({
|
|
at: entity.offset,
|
|
len: entity.len,
|
|
key: index
|
|
});
|
|
}
|
|
|
|
block.ent = ranges;
|
|
}
|
|
|
|
blx.push(block);
|
|
});
|
|
const result = {
|
|
txt: ''
|
|
};
|
|
|
|
if (blx.length > 0) {
|
|
result.txt = blx[0].txt;
|
|
result.fmt = (blx[0].fmt || []).concat(blx[0].ent || []);
|
|
|
|
for (let i = 1; i < blx.length; i++) {
|
|
const block = blx[i];
|
|
const offset = result.txt.length + 1;
|
|
result.fmt.push({
|
|
tp: 'BR',
|
|
len: 1,
|
|
at: offset - 1
|
|
});
|
|
result.txt += ' ' + block.txt;
|
|
|
|
if (block.fmt) {
|
|
result.fmt = result.fmt.concat(block.fmt.map(s => {
|
|
s.at += offset;
|
|
return s;
|
|
}));
|
|
}
|
|
|
|
if (block.ent) {
|
|
result.fmt = result.fmt.concat(block.ent.map(s => {
|
|
s.at += offset;
|
|
return s;
|
|
}));
|
|
}
|
|
}
|
|
|
|
if (result.fmt.length == 0) {
|
|
delete result.fmt;
|
|
}
|
|
|
|
if (entityMap.length > 0) {
|
|
result.ent = entityMap;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
Drafty.append = function (first, second) {
|
|
if (!first) {
|
|
return second;
|
|
}
|
|
|
|
if (!second) {
|
|
return first;
|
|
}
|
|
|
|
first.txt = first.txt || '';
|
|
const len = first.txt.length;
|
|
|
|
if (typeof second == 'string') {
|
|
first.txt += second;
|
|
} else if (second.txt) {
|
|
first.txt += second.txt;
|
|
}
|
|
|
|
if (Array.isArray(second.fmt)) {
|
|
first.fmt = first.fmt || [];
|
|
|
|
if (Array.isArray(second.ent)) {
|
|
first.ent = first.ent || [];
|
|
}
|
|
|
|
second.fmt.forEach(src => {
|
|
const fmt = {
|
|
at: (src.at | 0) + len,
|
|
len: src.len | 0
|
|
};
|
|
|
|
if (src.at == -1) {
|
|
fmt.at = -1;
|
|
fmt.len = 0;
|
|
}
|
|
|
|
if (src.tp) {
|
|
fmt.tp = src.tp;
|
|
} else {
|
|
fmt.key = first.ent.length;
|
|
first.ent.push(second.ent[src.key || 0]);
|
|
}
|
|
|
|
first.fmt.push(fmt);
|
|
});
|
|
}
|
|
|
|
return first;
|
|
};
|
|
|
|
Drafty.insertImage = function (content, at, imageDesc) {
|
|
content = content || {
|
|
txt: ' '
|
|
};
|
|
content.ent = content.ent || [];
|
|
content.fmt = content.fmt || [];
|
|
content.fmt.push({
|
|
at: at | 0,
|
|
len: 1,
|
|
key: content.ent.length
|
|
});
|
|
const ex = {
|
|
tp: 'IM',
|
|
data: {
|
|
mime: imageDesc.mime,
|
|
val: imageDesc.preview,
|
|
width: imageDesc.width,
|
|
height: imageDesc.height,
|
|
name: imageDesc.filename,
|
|
size: imageDesc.size | 0,
|
|
ref: imageDesc.refurl
|
|
}
|
|
};
|
|
|
|
if (imageDesc.urlPromise) {
|
|
ex.data._tempPreview = imageDesc._tempPreview;
|
|
ex.data._processing = true;
|
|
imageDesc.urlPromise.then(url => {
|
|
ex.data.ref = url;
|
|
ex.data._tempPreview = undefined;
|
|
ex.data._processing = undefined;
|
|
}, _ => {
|
|
ex.data._processing = undefined;
|
|
});
|
|
}
|
|
|
|
content.ent.push(ex);
|
|
return content;
|
|
};
|
|
|
|
Drafty.insertAudio = function (content, at, audioDesc) {
|
|
content = content || {
|
|
txt: ' '
|
|
};
|
|
content.ent = content.ent || [];
|
|
content.fmt = content.fmt || [];
|
|
content.fmt.push({
|
|
at: at | 0,
|
|
len: 1,
|
|
key: content.ent.length
|
|
});
|
|
const ex = {
|
|
tp: 'AU',
|
|
data: {
|
|
mime: audioDesc.mime,
|
|
val: audioDesc.data,
|
|
duration: audioDesc.duration | 0,
|
|
preview: audioDesc.preview,
|
|
name: audioDesc.filename,
|
|
size: audioDesc.size | 0,
|
|
ref: audioDesc.refurl
|
|
}
|
|
};
|
|
|
|
if (audioDesc.urlPromise) {
|
|
ex.data._processing = true;
|
|
audioDesc.urlPromise.then(url => {
|
|
ex.data.ref = url;
|
|
ex.data._processing = undefined;
|
|
}, _ => {
|
|
ex.data._processing = undefined;
|
|
});
|
|
}
|
|
|
|
content.ent.push(ex);
|
|
return content;
|
|
};
|
|
|
|
Drafty.videoCall = function () {
|
|
const content = {
|
|
txt: ' ',
|
|
fmt: [{
|
|
at: 0,
|
|
len: 1,
|
|
key: 0
|
|
}],
|
|
ent: [{
|
|
tp: 'VC'
|
|
}]
|
|
};
|
|
return content;
|
|
};
|
|
|
|
Drafty.updateVideoEnt = function (content, params) {
|
|
const fmt = ((content || {}).fmt || [])[0];
|
|
|
|
if (!fmt) {
|
|
return content;
|
|
}
|
|
|
|
let ent;
|
|
|
|
if (fmt.tp == 'VC') {
|
|
delete fmt.tp;
|
|
fmt.key = 0;
|
|
ent = {
|
|
tp: 'VC'
|
|
};
|
|
content.ent = [ent];
|
|
} else {
|
|
ent = (content.ent || [])[fmt.key | 0];
|
|
|
|
if (!ent || ent.tp != 'VC') {
|
|
return content;
|
|
}
|
|
}
|
|
|
|
ent.data = ent.data || {};
|
|
Object.assign(ent.data, params);
|
|
return content;
|
|
};
|
|
|
|
Drafty.quote = function (header, uid, body) {
|
|
const quote = Drafty.append(Drafty.appendLineBreak(Drafty.mention(header, uid)), body);
|
|
quote.fmt.push({
|
|
at: 0,
|
|
len: quote.txt.length,
|
|
tp: 'QQ'
|
|
});
|
|
return quote;
|
|
};
|
|
|
|
Drafty.mention = function (name, uid) {
|
|
return {
|
|
txt: name || '',
|
|
fmt: [{
|
|
at: 0,
|
|
len: (name || '').length,
|
|
key: 0
|
|
}],
|
|
ent: [{
|
|
tp: 'MN',
|
|
data: {
|
|
val: uid
|
|
}
|
|
}]
|
|
};
|
|
};
|
|
|
|
Drafty.appendLink = function (content, linkData) {
|
|
content = content || {
|
|
txt: ''
|
|
};
|
|
content.ent = content.ent || [];
|
|
content.fmt = content.fmt || [];
|
|
content.fmt.push({
|
|
at: content.txt.length,
|
|
len: linkData.txt.length,
|
|
key: content.ent.length
|
|
});
|
|
content.txt += linkData.txt;
|
|
const ex = {
|
|
tp: 'LN',
|
|
data: {
|
|
url: linkData.url
|
|
}
|
|
};
|
|
content.ent.push(ex);
|
|
return content;
|
|
};
|
|
|
|
Drafty.appendImage = function (content, imageDesc) {
|
|
content = content || {
|
|
txt: ''
|
|
};
|
|
content.txt += ' ';
|
|
return Drafty.insertImage(content, content.txt.length - 1, imageDesc);
|
|
};
|
|
|
|
Drafty.appendAudio = function (content, audioDesc) {
|
|
content = content || {
|
|
txt: ''
|
|
};
|
|
content.txt += ' ';
|
|
return Drafty.insertAudio(content, content.txt.length - 1, audioDesc);
|
|
};
|
|
|
|
Drafty.attachFile = function (content, attachmentDesc) {
|
|
content = content || {
|
|
txt: ''
|
|
};
|
|
content.ent = content.ent || [];
|
|
content.fmt = content.fmt || [];
|
|
content.fmt.push({
|
|
at: -1,
|
|
len: 0,
|
|
key: content.ent.length
|
|
});
|
|
const ex = {
|
|
tp: 'EX',
|
|
data: {
|
|
mime: attachmentDesc.mime,
|
|
val: attachmentDesc.data,
|
|
name: attachmentDesc.filename,
|
|
ref: attachmentDesc.refurl,
|
|
size: attachmentDesc.size | 0
|
|
}
|
|
};
|
|
|
|
if (attachmentDesc.urlPromise) {
|
|
ex.data._processing = true;
|
|
attachmentDesc.urlPromise.then(url => {
|
|
ex.data.ref = url;
|
|
ex.data._processing = undefined;
|
|
}, err => {
|
|
ex.data._processing = undefined;
|
|
});
|
|
}
|
|
|
|
content.ent.push(ex);
|
|
return content;
|
|
};
|
|
|
|
Drafty.wrapInto = function (content, style, at, len) {
|
|
if (typeof content == 'string') {
|
|
content = {
|
|
txt: content
|
|
};
|
|
}
|
|
|
|
content.fmt = content.fmt || [];
|
|
content.fmt.push({
|
|
at: at || 0,
|
|
len: len || content.txt.length,
|
|
tp: style
|
|
});
|
|
return content;
|
|
};
|
|
|
|
Drafty.wrapAsForm = function (content, at, len) {
|
|
return Drafty.wrapInto(content, 'FM', at, len);
|
|
};
|
|
|
|
Drafty.insertButton = function (content, at, len, name, actionType, actionValue, refUrl) {
|
|
if (typeof content == 'string') {
|
|
content = {
|
|
txt: content
|
|
};
|
|
}
|
|
|
|
if (!content || !content.txt || content.txt.length < at + len) {
|
|
return null;
|
|
}
|
|
|
|
if (len <= 0 || ['url', 'pub'].indexOf(actionType) == -1) {
|
|
return null;
|
|
}
|
|
|
|
if (actionType == 'url' && !refUrl) {
|
|
return null;
|
|
}
|
|
|
|
refUrl = '' + refUrl;
|
|
content.ent = content.ent || [];
|
|
content.fmt = content.fmt || [];
|
|
content.fmt.push({
|
|
at: at | 0,
|
|
len: len,
|
|
key: content.ent.length
|
|
});
|
|
content.ent.push({
|
|
tp: 'BN',
|
|
data: {
|
|
act: actionType,
|
|
val: actionValue,
|
|
ref: refUrl,
|
|
name: name
|
|
}
|
|
});
|
|
return content;
|
|
};
|
|
|
|
Drafty.appendButton = function (content, title, name, actionType, actionValue, refUrl) {
|
|
content = content || {
|
|
txt: ''
|
|
};
|
|
const at = content.txt.length;
|
|
content.txt += title;
|
|
return Drafty.insertButton(content, at, title.length, name, actionType, actionValue, refUrl);
|
|
};
|
|
|
|
Drafty.attachJSON = function (content, data) {
|
|
content = content || {
|
|
txt: ''
|
|
};
|
|
content.ent = content.ent || [];
|
|
content.fmt = content.fmt || [];
|
|
content.fmt.push({
|
|
at: -1,
|
|
len: 0,
|
|
key: content.ent.length
|
|
});
|
|
content.ent.push({
|
|
tp: 'EX',
|
|
data: {
|
|
mime: JSON_MIME_TYPE,
|
|
val: data
|
|
}
|
|
});
|
|
return content;
|
|
};
|
|
|
|
Drafty.appendLineBreak = function (content) {
|
|
content = content || {
|
|
txt: ''
|
|
};
|
|
content.fmt = content.fmt || [];
|
|
content.fmt.push({
|
|
at: content.txt.length,
|
|
len: 1,
|
|
tp: 'BR'
|
|
});
|
|
content.txt += ' ';
|
|
return content;
|
|
};
|
|
|
|
Drafty.UNSAFE_toHTML = function (doc) {
|
|
let tree = draftyToTree(doc);
|
|
|
|
const htmlFormatter = function (type, data, values) {
|
|
const tag = DECORATORS[type];
|
|
let result = values ? values.join('') : '';
|
|
|
|
if (tag) {
|
|
result = tag.open(data) + result + tag.close(data);
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
return treeBottomUp(tree, htmlFormatter, 0);
|
|
};
|
|
|
|
Drafty.format = function (original, formatter, context) {
|
|
return treeBottomUp(draftyToTree(original), formatter, 0, [], context);
|
|
};
|
|
|
|
Drafty.shorten = function (original, limit, light) {
|
|
let tree = draftyToTree(original);
|
|
tree = shortenTree(tree, limit, '…');
|
|
|
|
if (tree && light) {
|
|
tree = lightEntity(tree);
|
|
}
|
|
|
|
return treeToDrafty({}, tree, []);
|
|
};
|
|
|
|
Drafty.forwardedContent = function (original) {
|
|
let tree = draftyToTree(original);
|
|
|
|
const rmMention = function (node) {
|
|
if (node.type == 'MN') {
|
|
if (!node.parent || !node.parent.type) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
return node;
|
|
};
|
|
|
|
tree = treeTopDown(tree, rmMention);
|
|
tree = lTrim(tree);
|
|
return treeToDrafty({}, tree, []);
|
|
};
|
|
|
|
Drafty.replyContent = function (original, limit) {
|
|
const convMNnQQnBR = function (node) {
|
|
if (node.type == 'QQ') {
|
|
return null;
|
|
} else if (node.type == 'MN') {
|
|
if ((!node.parent || !node.parent.type) && (node.text || '').startsWith('➦')) {
|
|
node.text = '➦';
|
|
delete node.children;
|
|
delete node.data;
|
|
}
|
|
} else if (node.type == 'BR') {
|
|
node.text = ' ';
|
|
delete node.type;
|
|
delete node.children;
|
|
}
|
|
|
|
return node;
|
|
};
|
|
|
|
let tree = draftyToTree(original);
|
|
|
|
if (!tree) {
|
|
return original;
|
|
}
|
|
|
|
tree = treeTopDown(tree, convMNnQQnBR);
|
|
tree = attachmentsToEnd(tree, MAX_PREVIEW_ATTACHMENTS);
|
|
tree = shortenTree(tree, limit, '…');
|
|
tree = lightEntity(tree, node => node.type == 'IM' ? ['val'] : null);
|
|
return treeToDrafty({}, tree, []);
|
|
};
|
|
|
|
Drafty.preview = function (original, limit, forwarding) {
|
|
let tree = draftyToTree(original);
|
|
tree = attachmentsToEnd(tree, MAX_PREVIEW_ATTACHMENTS);
|
|
|
|
const convMNnQQnBR = function (node) {
|
|
if (node.type == 'MN') {
|
|
if ((!node.parent || !node.parent.type) && (node.text || '').startsWith('➦')) {
|
|
node.text = '➦';
|
|
delete node.children;
|
|
}
|
|
} else if (node.type == 'QQ') {
|
|
node.text = ' ';
|
|
delete node.children;
|
|
} else if (node.type == 'BR') {
|
|
node.text = ' ';
|
|
delete node.children;
|
|
delete node.type;
|
|
}
|
|
|
|
return node;
|
|
};
|
|
|
|
tree = treeTopDown(tree, convMNnQQnBR);
|
|
tree = shortenTree(tree, limit, '…');
|
|
|
|
if (forwarding) {
|
|
tree = lightEntity(tree, node => node.type == 'IM' ? ['val'] : null);
|
|
} else {
|
|
tree = lightEntity(tree);
|
|
}
|
|
|
|
return treeToDrafty({}, tree, []);
|
|
};
|
|
|
|
Drafty.toPlainText = function (content) {
|
|
return typeof content == 'string' ? content : content.txt;
|
|
};
|
|
|
|
Drafty.isPlainText = function (content) {
|
|
return typeof content == 'string' || !(content.fmt || content.ent);
|
|
};
|
|
|
|
Drafty.isValid = function (content) {
|
|
if (!content) {
|
|
return false;
|
|
}
|
|
|
|
const {
|
|
txt,
|
|
fmt,
|
|
ent
|
|
} = content;
|
|
|
|
if (!txt && txt !== '' && !fmt && !ent) {
|
|
return false;
|
|
}
|
|
|
|
const txt_type = typeof txt;
|
|
|
|
if (txt_type != 'string' && txt_type != 'undefined' && txt !== null) {
|
|
return false;
|
|
}
|
|
|
|
if (typeof fmt != 'undefined' && !Array.isArray(fmt) && fmt !== null) {
|
|
return false;
|
|
}
|
|
|
|
if (typeof ent != 'undefined' && !Array.isArray(ent) && ent !== null) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
Drafty.hasAttachments = function (content) {
|
|
if (!Array.isArray(content.fmt)) {
|
|
return false;
|
|
}
|
|
|
|
for (let i in content.fmt) {
|
|
const fmt = content.fmt[i];
|
|
|
|
if (fmt && fmt.at < 0) {
|
|
const ent = content.ent[fmt.key | 0];
|
|
return ent && ent.tp == 'EX' && ent.data;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
Drafty.attachments = function (content, callback, context) {
|
|
if (!Array.isArray(content.fmt)) {
|
|
return;
|
|
}
|
|
|
|
let i = 0;
|
|
content.fmt.forEach(fmt => {
|
|
if (fmt && fmt.at < 0) {
|
|
const ent = content.ent[fmt.key | 0];
|
|
|
|
if (ent && ent.tp == 'EX' && ent.data) {
|
|
callback.call(context, ent.data, i++, 'EX');
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
Drafty.hasEntities = function (content) {
|
|
return content.ent && content.ent.length > 0;
|
|
};
|
|
|
|
Drafty.entities = function (content, callback, context) {
|
|
if (content.ent && content.ent.length > 0) {
|
|
for (let i in content.ent) {
|
|
if (content.ent[i]) {
|
|
callback.call(context, content.ent[i].data, i, content.ent[i].tp);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
Drafty.sanitizeEntities = function (content) {
|
|
if (content && content.ent && content.ent.length > 0) {
|
|
for (let i in content.ent) {
|
|
const ent = content.ent[i];
|
|
|
|
if (ent && ent.data) {
|
|
const data = copyEntData(ent.data);
|
|
|
|
if (data) {
|
|
content.ent[i].data = data;
|
|
} else {
|
|
delete content.ent[i].data;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return content;
|
|
};
|
|
|
|
Drafty.getDownloadUrl = function (entData) {
|
|
let url = null;
|
|
|
|
if (entData.mime != JSON_MIME_TYPE && entData.val) {
|
|
url = base64toObjectUrl(entData.val, entData.mime, Drafty.logger);
|
|
} else if (typeof entData.ref == 'string') {
|
|
url = entData.ref;
|
|
}
|
|
|
|
return url;
|
|
};
|
|
|
|
Drafty.isProcessing = function (entData) {
|
|
return !!entData._processing;
|
|
};
|
|
|
|
Drafty.getPreviewUrl = function (entData) {
|
|
return entData.val ? base64toObjectUrl(entData.val, entData.mime, Drafty.logger) : null;
|
|
};
|
|
|
|
Drafty.getEntitySize = function (entData) {
|
|
return entData.size ? entData.size : entData.val ? entData.val.length * 0.75 | 0 : 0;
|
|
};
|
|
|
|
Drafty.getEntityMimeType = function (entData) {
|
|
return entData.mime || 'text/plain';
|
|
};
|
|
|
|
Drafty.tagName = function (style) {
|
|
return HTML_TAGS[style] && HTML_TAGS[style].name;
|
|
};
|
|
|
|
Drafty.attrValue = function (style, data) {
|
|
if (data && DECORATORS[style]) {
|
|
return DECORATORS[style].props(data);
|
|
}
|
|
|
|
return undefined;
|
|
};
|
|
|
|
Drafty.getContentType = function () {
|
|
return DRAFTY_MIME_TYPE;
|
|
};
|
|
|
|
function chunkify(line, start, end, spans) {
|
|
const chunks = [];
|
|
|
|
if (spans.length == 0) {
|
|
return [];
|
|
}
|
|
|
|
for (let i in spans) {
|
|
const span = spans[i];
|
|
|
|
if (span.at > start) {
|
|
chunks.push({
|
|
txt: line.slice(start, span.at)
|
|
});
|
|
}
|
|
|
|
const chunk = {
|
|
tp: span.tp
|
|
};
|
|
const chld = chunkify(line, span.at + 1, span.end, span.children);
|
|
|
|
if (chld.length > 0) {
|
|
chunk.children = chld;
|
|
} else {
|
|
chunk.txt = span.txt;
|
|
}
|
|
|
|
chunks.push(chunk);
|
|
start = span.end + 1;
|
|
}
|
|
|
|
if (start < end) {
|
|
chunks.push({
|
|
txt: line.slice(start, end)
|
|
});
|
|
}
|
|
|
|
return chunks;
|
|
}
|
|
|
|
function spannify(original, re_start, re_end, type) {
|
|
const result = [];
|
|
let index = 0;
|
|
let line = original.slice(0);
|
|
|
|
while (line.length > 0) {
|
|
const start = re_start.exec(line);
|
|
|
|
if (start == null) {
|
|
break;
|
|
}
|
|
|
|
let start_offset = start['index'] + start[0].lastIndexOf(start[1]);
|
|
line = line.slice(start_offset + 1);
|
|
start_offset += index;
|
|
index = start_offset + 1;
|
|
const end = re_end ? re_end.exec(line) : null;
|
|
|
|
if (end == null) {
|
|
break;
|
|
}
|
|
|
|
let end_offset = end['index'] + end[0].indexOf(end[1]);
|
|
line = line.slice(end_offset + 1);
|
|
end_offset += index;
|
|
index = end_offset + 1;
|
|
result.push({
|
|
txt: original.slice(start_offset + 1, end_offset),
|
|
children: [],
|
|
at: start_offset,
|
|
end: end_offset,
|
|
tp: type
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function toSpanTree(spans) {
|
|
if (spans.length == 0) {
|
|
return [];
|
|
}
|
|
|
|
const tree = [spans[0]];
|
|
let last = spans[0];
|
|
|
|
for (let i = 1; i < spans.length; i++) {
|
|
if (spans[i].at > last.end) {
|
|
tree.push(spans[i]);
|
|
last = spans[i];
|
|
} else if (spans[i].end <= last.end) {
|
|
last.children.push(spans[i]);
|
|
}
|
|
}
|
|
|
|
for (let i in tree) {
|
|
tree[i].children = toSpanTree(tree[i].children);
|
|
}
|
|
|
|
return tree;
|
|
}
|
|
|
|
function draftyToTree(doc) {
|
|
if (!doc) {
|
|
return null;
|
|
}
|
|
|
|
doc = typeof doc == 'string' ? {
|
|
txt: doc
|
|
} : doc;
|
|
let {
|
|
txt,
|
|
fmt,
|
|
ent
|
|
} = doc;
|
|
txt = txt || '';
|
|
|
|
if (!Array.isArray(ent)) {
|
|
ent = [];
|
|
}
|
|
|
|
if (!Array.isArray(fmt) || fmt.length == 0) {
|
|
if (ent.length == 0) {
|
|
return {
|
|
text: txt
|
|
};
|
|
}
|
|
|
|
fmt = [{
|
|
at: 0,
|
|
len: 0,
|
|
key: 0
|
|
}];
|
|
}
|
|
|
|
const spans = [];
|
|
const attachments = [];
|
|
fmt.forEach(span => {
|
|
if (!span || typeof span != 'object') {
|
|
return;
|
|
}
|
|
|
|
if (!['undefined', 'number'].includes(typeof span.at)) {
|
|
return;
|
|
}
|
|
|
|
if (!['undefined', 'number'].includes(typeof span.len)) {
|
|
return;
|
|
}
|
|
|
|
let at = span.at | 0;
|
|
let len = span.len | 0;
|
|
|
|
if (len < 0) {
|
|
return;
|
|
}
|
|
|
|
let key = span.key || 0;
|
|
|
|
if (ent.length > 0 && (typeof key != 'number' || key < 0 || key >= ent.length)) {
|
|
return;
|
|
}
|
|
|
|
if (at <= -1) {
|
|
attachments.push({
|
|
start: -1,
|
|
end: 0,
|
|
key: key
|
|
});
|
|
return;
|
|
} else if (at + len > txt.length) {
|
|
return;
|
|
}
|
|
|
|
if (!span.tp) {
|
|
if (ent.length > 0 && typeof ent[key] == 'object') {
|
|
spans.push({
|
|
start: at,
|
|
end: at + len,
|
|
key: key
|
|
});
|
|
}
|
|
} else {
|
|
spans.push({
|
|
type: span.tp,
|
|
start: at,
|
|
end: at + len
|
|
});
|
|
}
|
|
});
|
|
spans.sort((a, b) => {
|
|
let diff = a.start - b.start;
|
|
|
|
if (diff != 0) {
|
|
return diff;
|
|
}
|
|
|
|
diff = b.end - a.end;
|
|
|
|
if (diff != 0) {
|
|
return diff;
|
|
}
|
|
|
|
return FMT_WEIGHT.indexOf(b.type) - FMT_WEIGHT.indexOf(a.type);
|
|
});
|
|
|
|
if (attachments.length > 0) {
|
|
spans.push(...attachments);
|
|
}
|
|
|
|
spans.forEach(span => {
|
|
if (ent.length > 0 && !span.type && ent[span.key] && typeof ent[span.key] == 'object') {
|
|
span.type = ent[span.key].tp;
|
|
span.data = ent[span.key].data;
|
|
}
|
|
|
|
if (!span.type) {
|
|
span.type = 'HD';
|
|
}
|
|
});
|
|
let tree = spansToTree({}, txt, 0, txt.length, spans);
|
|
|
|
const flatten = function (node) {
|
|
if (Array.isArray(node.children) && node.children.length == 1) {
|
|
const child = node.children[0];
|
|
|
|
if (!node.type) {
|
|
const parent = node.parent;
|
|
node = child;
|
|
node.parent = parent;
|
|
} else if (!child.type && !child.children) {
|
|
node.text = child.text;
|
|
delete node.children;
|
|
}
|
|
}
|
|
|
|
return node;
|
|
};
|
|
|
|
tree = treeTopDown(tree, flatten);
|
|
return tree;
|
|
}
|
|
|
|
function addNode(parent, n) {
|
|
if (!n) {
|
|
return parent;
|
|
}
|
|
|
|
if (!parent.children) {
|
|
parent.children = [];
|
|
}
|
|
|
|
if (parent.text) {
|
|
parent.children.push({
|
|
text: parent.text,
|
|
parent: parent
|
|
});
|
|
delete parent.text;
|
|
}
|
|
|
|
n.parent = parent;
|
|
parent.children.push(n);
|
|
return parent;
|
|
}
|
|
|
|
function spansToTree(parent, text, start, end, spans) {
|
|
if (!spans || spans.length == 0) {
|
|
if (start < end) {
|
|
addNode(parent, {
|
|
text: text.substring(start, end)
|
|
});
|
|
}
|
|
|
|
return parent;
|
|
}
|
|
|
|
for (let i = 0; i < spans.length; i++) {
|
|
const span = spans[i];
|
|
|
|
if (span.start < 0 && span.type == 'EX') {
|
|
addNode(parent, {
|
|
type: span.type,
|
|
data: span.data,
|
|
key: span.key,
|
|
att: true
|
|
});
|
|
continue;
|
|
}
|
|
|
|
if (start < span.start) {
|
|
addNode(parent, {
|
|
text: text.substring(start, span.start)
|
|
});
|
|
start = span.start;
|
|
}
|
|
|
|
const subspans = [];
|
|
|
|
while (i < spans.length - 1) {
|
|
const inner = spans[i + 1];
|
|
|
|
if (inner.start < 0) {
|
|
break;
|
|
} else if (inner.start < span.end) {
|
|
if (inner.end <= span.end) {
|
|
const tag = HTML_TAGS[inner.tp] || {};
|
|
|
|
if (inner.start < inner.end || tag.isVoid) {
|
|
subspans.push(inner);
|
|
}
|
|
}
|
|
|
|
i++;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
addNode(parent, spansToTree({
|
|
type: span.type,
|
|
data: span.data,
|
|
key: span.key
|
|
}, text, start, span.end, subspans));
|
|
start = span.end;
|
|
}
|
|
|
|
if (start < end) {
|
|
addNode(parent, {
|
|
text: text.substring(start, end)
|
|
});
|
|
}
|
|
|
|
return parent;
|
|
}
|
|
|
|
function treeToDrafty(doc, tree, keymap) {
|
|
if (!tree) {
|
|
return doc;
|
|
}
|
|
|
|
doc.txt = doc.txt || '';
|
|
const start = doc.txt.length;
|
|
|
|
if (tree.text) {
|
|
doc.txt += tree.text;
|
|
} else if (Array.isArray(tree.children)) {
|
|
tree.children.forEach(c => {
|
|
treeToDrafty(doc, c, keymap);
|
|
});
|
|
}
|
|
|
|
if (tree.type) {
|
|
const len = doc.txt.length - start;
|
|
doc.fmt = doc.fmt || [];
|
|
|
|
if (Object.keys(tree.data || {}).length > 0) {
|
|
doc.ent = doc.ent || [];
|
|
const newKey = typeof keymap[tree.key] == 'undefined' ? doc.ent.length : keymap[tree.key];
|
|
keymap[tree.key] = newKey;
|
|
doc.ent[newKey] = {
|
|
tp: tree.type,
|
|
data: tree.data
|
|
};
|
|
|
|
if (tree.att) {
|
|
doc.fmt.push({
|
|
at: -1,
|
|
len: 0,
|
|
key: newKey
|
|
});
|
|
} else {
|
|
doc.fmt.push({
|
|
at: start,
|
|
len: len,
|
|
key: newKey
|
|
});
|
|
}
|
|
} else {
|
|
doc.fmt.push({
|
|
tp: tree.type,
|
|
at: start,
|
|
len: len
|
|
});
|
|
}
|
|
}
|
|
|
|
return doc;
|
|
}
|
|
|
|
function treeTopDown(src, transformer, context) {
|
|
if (!src) {
|
|
return null;
|
|
}
|
|
|
|
let dst = transformer.call(context, src);
|
|
|
|
if (!dst || !dst.children) {
|
|
return dst;
|
|
}
|
|
|
|
const children = [];
|
|
|
|
for (let i in dst.children) {
|
|
let n = dst.children[i];
|
|
|
|
if (n) {
|
|
n = treeTopDown(n, transformer, context);
|
|
|
|
if (n) {
|
|
children.push(n);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (children.length == 0) {
|
|
dst.children = null;
|
|
} else {
|
|
dst.children = children;
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
function treeBottomUp(src, formatter, index, stack, context) {
|
|
if (!src) {
|
|
return null;
|
|
}
|
|
|
|
if (stack && src.type) {
|
|
stack.push(src.type);
|
|
}
|
|
|
|
let values = [];
|
|
|
|
for (let i in src.children) {
|
|
const n = treeBottomUp(src.children[i], formatter, i, stack, context);
|
|
|
|
if (n) {
|
|
values.push(n);
|
|
}
|
|
}
|
|
|
|
if (values.length == 0) {
|
|
if (src.text) {
|
|
values = [src.text];
|
|
} else {
|
|
values = null;
|
|
}
|
|
}
|
|
|
|
if (stack && src.type) {
|
|
stack.pop();
|
|
}
|
|
|
|
return formatter.call(context, src.type, src.data, values, index, stack);
|
|
}
|
|
|
|
function shortenTree(tree, limit, tail) {
|
|
if (!tree) {
|
|
return null;
|
|
}
|
|
|
|
if (tail) {
|
|
limit -= tail.length;
|
|
}
|
|
|
|
const shortener = function (node) {
|
|
if (limit <= -1) {
|
|
return null;
|
|
}
|
|
|
|
if (node.att) {
|
|
return node;
|
|
}
|
|
|
|
if (limit == 0) {
|
|
node.text = tail;
|
|
limit = -1;
|
|
} else if (node.text) {
|
|
const len = node.text.length;
|
|
|
|
if (len > limit) {
|
|
node.text = node.text.substring(0, limit) + tail;
|
|
limit = -1;
|
|
} else {
|
|
limit -= len;
|
|
}
|
|
}
|
|
|
|
return node;
|
|
};
|
|
|
|
return treeTopDown(tree, shortener);
|
|
}
|
|
|
|
function lightEntity(tree, allow) {
|
|
const lightCopy = node => {
|
|
const data = copyEntData(node.data, true, allow ? allow(node) : null);
|
|
|
|
if (data) {
|
|
node.data = data;
|
|
} else {
|
|
delete node.data;
|
|
}
|
|
|
|
return node;
|
|
};
|
|
|
|
return treeTopDown(tree, lightCopy);
|
|
}
|
|
|
|
function lTrim(tree) {
|
|
if (tree.type == 'BR') {
|
|
tree = null;
|
|
} else if (tree.text) {
|
|
if (!tree.type) {
|
|
tree.text = tree.text.trimStart();
|
|
|
|
if (!tree.text) {
|
|
tree = null;
|
|
}
|
|
}
|
|
} else if (!tree.type && tree.children && tree.children.length > 0) {
|
|
const c = lTrim(tree.children[0]);
|
|
|
|
if (c) {
|
|
tree.children[0] = c;
|
|
} else {
|
|
tree.children.shift();
|
|
|
|
if (!tree.type && tree.children.length == 0) {
|
|
tree = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
return tree;
|
|
}
|
|
|
|
function attachmentsToEnd(tree, limit) {
|
|
if (!tree) {
|
|
return null;
|
|
}
|
|
|
|
if (tree.att) {
|
|
tree.text = ' ';
|
|
delete tree.att;
|
|
delete tree.children;
|
|
} else if (tree.children) {
|
|
const attachments = [];
|
|
const children = [];
|
|
|
|
for (let i in tree.children) {
|
|
const c = tree.children[i];
|
|
|
|
if (c.att) {
|
|
if (attachments.length == limit) {
|
|
continue;
|
|
}
|
|
|
|
if (c.data['mime'] == JSON_MIME_TYPE) {
|
|
continue;
|
|
}
|
|
|
|
delete c.att;
|
|
delete c.children;
|
|
c.text = ' ';
|
|
attachments.push(c);
|
|
} else {
|
|
children.push(c);
|
|
}
|
|
}
|
|
|
|
tree.children = children.concat(attachments);
|
|
}
|
|
|
|
return tree;
|
|
}
|
|
|
|
function extractEntities(line) {
|
|
let match;
|
|
let extracted = [];
|
|
ENTITY_TYPES.forEach(entity => {
|
|
while ((match = entity.re.exec(line)) !== null) {
|
|
extracted.push({
|
|
offset: match['index'],
|
|
len: match[0].length,
|
|
unique: match[0],
|
|
data: entity.pack(match[0]),
|
|
type: entity.name
|
|
});
|
|
}
|
|
});
|
|
|
|
if (extracted.length == 0) {
|
|
return extracted;
|
|
}
|
|
|
|
extracted.sort((a, b) => {
|
|
return a.offset - b.offset;
|
|
});
|
|
let idx = -1;
|
|
extracted = extracted.filter(el => {
|
|
const result = el.offset > idx;
|
|
idx = el.offset + el.len;
|
|
return result;
|
|
});
|
|
return extracted;
|
|
}
|
|
|
|
function draftify(chunks, startAt) {
|
|
let plain = '';
|
|
let ranges = [];
|
|
|
|
for (let i in chunks) {
|
|
const chunk = chunks[i];
|
|
|
|
if (!chunk.txt) {
|
|
const drafty = draftify(chunk.children, plain.length + startAt);
|
|
chunk.txt = drafty.txt;
|
|
ranges = ranges.concat(drafty.fmt);
|
|
}
|
|
|
|
if (chunk.tp) {
|
|
ranges.push({
|
|
at: plain.length + startAt,
|
|
len: chunk.txt.length,
|
|
tp: chunk.tp
|
|
});
|
|
}
|
|
|
|
plain += chunk.txt;
|
|
}
|
|
|
|
return {
|
|
txt: plain,
|
|
fmt: ranges
|
|
};
|
|
}
|
|
|
|
function copyEntData(data, light, allow) {
|
|
if (data && Object.entries(data).length > 0) {
|
|
allow = allow || [];
|
|
const dc = {};
|
|
ALLOWED_ENT_FIELDS.forEach(key => {
|
|
if (data[key]) {
|
|
if (light && !allow.includes(key) && (typeof data[key] == 'string' || Array.isArray(data[key])) && data[key].length > MAX_PREVIEW_DATA_SIZE) {
|
|
return;
|
|
}
|
|
|
|
if (typeof data[key] == 'object') {
|
|
return;
|
|
}
|
|
|
|
dc[key] = data[key];
|
|
}
|
|
});
|
|
|
|
if (Object.entries(dc).length != 0) {
|
|
return dc;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
if (typeof module != 'undefined') {
|
|
module.exports = Drafty;
|
|
}
|
|
|
|
},{}],7:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
|
|
var _utils = require("./utils.js");
|
|
|
|
let XHRProvider;
|
|
|
|
class LargeFileHelper {
|
|
constructor(tinode, version) {
|
|
this._tinode = tinode;
|
|
this._version = version;
|
|
this._apiKey = tinode._apiKey;
|
|
this._authToken = tinode.getAuthToken();
|
|
this._reqId = tinode.getNextUniqueId();
|
|
this.xhr = new XHRProvider();
|
|
this.toResolve = null;
|
|
this.toReject = null;
|
|
this.onProgress = null;
|
|
this.onSuccess = null;
|
|
this.onFailure = null;
|
|
}
|
|
|
|
uploadWithBaseUrl(baseUrl, data, avatarFor, onProgress, onSuccess, onFailure) {
|
|
const instance = this;
|
|
let url = `/v${this._version}/file/u/`;
|
|
|
|
if (baseUrl) {
|
|
let base = baseUrl;
|
|
|
|
if (base.endsWith('/')) {
|
|
base = base.slice(0, -1);
|
|
}
|
|
|
|
if (base.startsWith('http://') || base.startsWith('https://')) {
|
|
url = base + url;
|
|
} else {
|
|
throw new Error(`Invalid base URL '${baseUrl}'`);
|
|
}
|
|
}
|
|
|
|
this.xhr.open('POST', url, true);
|
|
this.xhr.setRequestHeader('X-Tinode-APIKey', this._apiKey);
|
|
|
|
if (this._authToken) {
|
|
this.xhr.setRequestHeader('X-Tinode-Auth', `Token ${this._authToken.token}`);
|
|
}
|
|
|
|
const result = new Promise((resolve, reject) => {
|
|
this.toResolve = resolve;
|
|
this.toReject = reject;
|
|
});
|
|
this.onProgress = onProgress;
|
|
this.onSuccess = onSuccess;
|
|
this.onFailure = onFailure;
|
|
|
|
this.xhr.upload.onprogress = e => {
|
|
if (e.lengthComputable && instance.onProgress) {
|
|
instance.onProgress(e.loaded / e.total);
|
|
}
|
|
};
|
|
|
|
this.xhr.onload = function () {
|
|
let pkt;
|
|
|
|
try {
|
|
pkt = JSON.parse(this.response, _utils.jsonParseHelper);
|
|
} catch (err) {
|
|
instance._tinode.logger("ERROR: Invalid server response in LargeFileHelper", this.response);
|
|
|
|
pkt = {
|
|
ctrl: {
|
|
code: this.status,
|
|
text: this.statusText
|
|
}
|
|
};
|
|
}
|
|
|
|
if (this.status >= 200 && this.status < 300) {
|
|
if (instance.toResolve) {
|
|
instance.toResolve(pkt.ctrl.params.url);
|
|
}
|
|
|
|
if (instance.onSuccess) {
|
|
instance.onSuccess(pkt.ctrl);
|
|
}
|
|
} else if (this.status >= 400) {
|
|
if (instance.toReject) {
|
|
instance.toReject(new Error(`${pkt.ctrl.text} (${pkt.ctrl.code})`));
|
|
}
|
|
|
|
if (instance.onFailure) {
|
|
instance.onFailure(pkt.ctrl);
|
|
}
|
|
} else {
|
|
instance._tinode.logger("ERROR: Unexpected server response status", this.status, this.response);
|
|
}
|
|
};
|
|
|
|
this.xhr.onerror = function (e) {
|
|
if (instance.toReject) {
|
|
instance.toReject(new Error("failed"));
|
|
}
|
|
|
|
if (instance.onFailure) {
|
|
instance.onFailure(null);
|
|
}
|
|
};
|
|
|
|
this.xhr.onabort = function (e) {
|
|
if (instance.toReject) {
|
|
instance.toReject(new Error("upload cancelled by user"));
|
|
}
|
|
|
|
if (instance.onFailure) {
|
|
instance.onFailure(null);
|
|
}
|
|
};
|
|
|
|
try {
|
|
const form = new FormData();
|
|
form.append('file', data);
|
|
form.set('id', this._reqId);
|
|
|
|
if (avatarFor) {
|
|
form.set('topic', avatarFor);
|
|
}
|
|
|
|
this.xhr.send(form);
|
|
} catch (err) {
|
|
if (this.toReject) {
|
|
this.toReject(err);
|
|
}
|
|
|
|
if (this.onFailure) {
|
|
this.onFailure(null);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
upload(data, avatarFor, onProgress, onSuccess, onFailure) {
|
|
const baseUrl = (this._tinode._secure ? 'https://' : 'http://') + this._tinode._host;
|
|
return this.uploadWithBaseUrl(baseUrl, data, avatarFor, onProgress, onSuccess, onFailure);
|
|
}
|
|
|
|
download(relativeUrl, filename, mimetype, onProgress, onError) {
|
|
if (!Tinode.isRelativeURL(relativeUrl)) {
|
|
if (onError) {
|
|
onError(`The URL '${relativeUrl}' must be relative, not absolute`);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (!this._authToken) {
|
|
if (onError) {
|
|
onError("Must authenticate first");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
const instance = this;
|
|
this.xhr.open('GET', relativeUrl, true);
|
|
this.xhr.setRequestHeader('X-Tinode-APIKey', this._apiKey);
|
|
this.xhr.setRequestHeader('X-Tinode-Auth', 'Token ' + this._authToken.token);
|
|
this.xhr.responseType = 'blob';
|
|
this.onProgress = onProgress;
|
|
|
|
this.xhr.onprogress = function (e) {
|
|
if (instance.onProgress) {
|
|
instance.onProgress(e.loaded);
|
|
}
|
|
};
|
|
|
|
const result = new Promise((resolve, reject) => {
|
|
this.toResolve = resolve;
|
|
this.toReject = reject;
|
|
});
|
|
|
|
this.xhr.onload = function () {
|
|
if (this.status == 200) {
|
|
const link = document.createElement('a');
|
|
link.href = window.URL.createObjectURL(new Blob([this.response], {
|
|
type: mimetype
|
|
}));
|
|
link.style.display = 'none';
|
|
link.setAttribute('download', filename);
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
window.URL.revokeObjectURL(link.href);
|
|
|
|
if (instance.toResolve) {
|
|
instance.toResolve();
|
|
}
|
|
} else if (this.status >= 400 && instance.toReject) {
|
|
const reader = new FileReader();
|
|
|
|
reader.onload = function () {
|
|
try {
|
|
const pkt = JSON.parse(this.result, _utils.jsonParseHelper);
|
|
instance.toReject(new Error(`${pkt.ctrl.text} (${pkt.ctrl.code})`));
|
|
} catch (err) {
|
|
instance._tinode.logger("ERROR: Invalid server response in LargeFileHelper", this.result);
|
|
|
|
instance.toReject(err);
|
|
}
|
|
};
|
|
|
|
reader.readAsText(this.response);
|
|
}
|
|
};
|
|
|
|
this.xhr.onerror = function (e) {
|
|
if (instance.toReject) {
|
|
instance.toReject(new Error("failed"));
|
|
}
|
|
};
|
|
|
|
this.xhr.onabort = function () {
|
|
if (instance.toReject) {
|
|
instance.toReject(null);
|
|
}
|
|
};
|
|
|
|
try {
|
|
this.xhr.send();
|
|
} catch (err) {
|
|
if (this.toReject) {
|
|
this.toReject(err);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
cancel() {
|
|
if (this.xhr && this.xhr.readyState < 4) {
|
|
this.xhr.abort();
|
|
}
|
|
}
|
|
|
|
getId() {
|
|
return this._reqId;
|
|
}
|
|
|
|
static setNetworkProvider(xhrProvider) {
|
|
XHRProvider = xhrProvider;
|
|
}
|
|
|
|
}
|
|
|
|
exports.default = LargeFileHelper;
|
|
|
|
},{"./utils.js":11}],8:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
|
|
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
|
|
|
|
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
|
|
function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
|
|
|
|
var _get_desc_ims = new WeakSet();
|
|
|
|
var _get_subs_ims = new WeakSet();
|
|
|
|
class MetaGetBuilder {
|
|
constructor(parent) {
|
|
_classPrivateMethodInitSpec(this, _get_subs_ims);
|
|
|
|
_classPrivateMethodInitSpec(this, _get_desc_ims);
|
|
|
|
this.topic = parent;
|
|
this.what = {};
|
|
}
|
|
|
|
withData(since, before, limit) {
|
|
this.what['data'] = {
|
|
since: since,
|
|
before: before,
|
|
limit: limit
|
|
};
|
|
return this;
|
|
}
|
|
|
|
withLaterData(limit) {
|
|
return this.withData(this.topic._maxSeq > 0 ? this.topic._maxSeq + 1 : undefined, undefined, limit);
|
|
}
|
|
|
|
withEarlierData(limit) {
|
|
return this.withData(undefined, this.topic._minSeq > 0 ? this.topic._minSeq : undefined, limit);
|
|
}
|
|
|
|
withDesc(ims) {
|
|
this.what['desc'] = {
|
|
ims: ims
|
|
};
|
|
return this;
|
|
}
|
|
|
|
withLaterDesc() {
|
|
return this.withDesc(_classPrivateMethodGet(this, _get_desc_ims, _get_desc_ims2).call(this));
|
|
}
|
|
|
|
withSub(ims, limit, userOrTopic) {
|
|
const opts = {
|
|
ims: ims,
|
|
limit: limit
|
|
};
|
|
|
|
if (this.topic.getType() == 'me') {
|
|
opts.topic = userOrTopic;
|
|
} else {
|
|
opts.user = userOrTopic;
|
|
}
|
|
|
|
this.what['sub'] = opts;
|
|
return this;
|
|
}
|
|
|
|
withOneSub(ims, userOrTopic) {
|
|
return this.withSub(ims, undefined, userOrTopic);
|
|
}
|
|
|
|
withLaterOneSub(userOrTopic) {
|
|
return this.withOneSub(this.topic._lastSubsUpdate, userOrTopic);
|
|
}
|
|
|
|
withLaterSub(limit) {
|
|
return this.withSub(_classPrivateMethodGet(this, _get_subs_ims, _get_subs_ims2).call(this), limit);
|
|
}
|
|
|
|
withTags() {
|
|
this.what['tags'] = true;
|
|
return this;
|
|
}
|
|
|
|
withCred() {
|
|
if (this.topic.getType() == 'me') {
|
|
this.what['cred'] = true;
|
|
} else {
|
|
this.topic._tinode.logger("ERROR: Invalid topic type for MetaGetBuilder:withCreds", this.topic.getType());
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
withDel(since, limit) {
|
|
if (since || limit) {
|
|
this.what['del'] = {
|
|
since: since,
|
|
limit: limit
|
|
};
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
withLaterDel(limit) {
|
|
return this.withDel(this.topic._maxSeq > 0 ? this.topic._maxDel + 1 : undefined, limit);
|
|
}
|
|
|
|
extract(what) {
|
|
return this.what[what];
|
|
}
|
|
|
|
build() {
|
|
const what = [];
|
|
let params = {};
|
|
['data', 'sub', 'desc', 'tags', 'cred', 'del'].forEach(key => {
|
|
if (this.what.hasOwnProperty(key)) {
|
|
what.push(key);
|
|
|
|
if (Object.getOwnPropertyNames(this.what[key]).length > 0) {
|
|
params[key] = this.what[key];
|
|
}
|
|
}
|
|
});
|
|
|
|
if (what.length > 0) {
|
|
params.what = what.join(' ');
|
|
} else {
|
|
params = undefined;
|
|
}
|
|
|
|
return params;
|
|
}
|
|
|
|
}
|
|
|
|
exports.default = MetaGetBuilder;
|
|
|
|
function _get_desc_ims2() {
|
|
return this.topic.updated;
|
|
}
|
|
|
|
function _get_subs_ims2() {
|
|
if (this.topic.isP2PType()) {
|
|
return _classPrivateMethodGet(this, _get_desc_ims, _get_desc_ims2).call(this);
|
|
}
|
|
|
|
return this.topic._lastSubsUpdate;
|
|
}
|
|
|
|
},{}],9:[function(require,module,exports){
|
|
(function (global){(function (){
|
|
/**
|
|
* @module tinode-sdk
|
|
*
|
|
* @copyright 2015-2022 Tinode LLC.
|
|
* @summary Javascript bindings for Tinode.
|
|
* @license Apache 2.0
|
|
* @version 0.20
|
|
*
|
|
* See <a href="https://github.com/tinode/webapp">https://github.com/tinode/webapp</a> for real-life usage.
|
|
*
|
|
* @example
|
|
* <head>
|
|
* <script src=".../tinode.js"></script>
|
|
* </head>
|
|
*
|
|
* <body>
|
|
* ...
|
|
* <script>
|
|
* // Instantiate tinode.
|
|
* const tinode = new Tinode(config, () => {
|
|
* // Called on init completion.
|
|
* });
|
|
* tinode.enableLogging(true);
|
|
* tinode.onDisconnect = (err) => {
|
|
* // Handle disconnect.
|
|
* };
|
|
* // Connect to the server.
|
|
* tinode.connect('https://example.com/').then(() => {
|
|
* // Connected. Login now.
|
|
* return tinode.loginBasic(login, password);
|
|
* }).then((ctrl) => {
|
|
* // Logged in fine, attach callbacks, subscribe to 'me'.
|
|
* const me = tinode.getMeTopic();
|
|
* me.onMetaDesc = function(meta) { ... };
|
|
* // Subscribe, fetch topic description and the list of contacts.
|
|
* me.subscribe({get: {desc: {}, sub: {}}});
|
|
* }).catch((err) => {
|
|
* // Login or subscription failed, do something.
|
|
* ...
|
|
* });
|
|
* ...
|
|
* </script>
|
|
* </body>
|
|
*/
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
Object.defineProperty(exports, "AccessMode", {
|
|
enumerable: true,
|
|
get: function () {
|
|
return _accessMode.default;
|
|
}
|
|
});
|
|
Object.defineProperty(exports, "Drafty", {
|
|
enumerable: true,
|
|
get: function () {
|
|
return _drafty.default;
|
|
}
|
|
});
|
|
exports.Tinode = void 0;
|
|
|
|
var _accessMode = _interopRequireDefault(require("./access-mode.js"));
|
|
|
|
var Const = _interopRequireWildcard(require("./config.js"));
|
|
|
|
var _connection = _interopRequireDefault(require("./connection.js"));
|
|
|
|
var _db = _interopRequireDefault(require("./db.js"));
|
|
|
|
var _drafty = _interopRequireDefault(require("./drafty.js"));
|
|
|
|
var _largeFile = _interopRequireDefault(require("./large-file.js"));
|
|
|
|
var _metaBuilder = _interopRequireDefault(require("./meta-builder.js"));
|
|
|
|
var _topic = require("./topic.js");
|
|
|
|
var _utils = require("./utils.js");
|
|
|
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
|
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
|
|
|
|
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
|
|
|
|
let WebSocketProvider;
|
|
|
|
if (typeof WebSocket != 'undefined') {
|
|
WebSocketProvider = WebSocket;
|
|
}
|
|
|
|
let XHRProvider;
|
|
|
|
if (typeof XMLHttpRequest != 'undefined') {
|
|
XHRProvider = XMLHttpRequest;
|
|
}
|
|
|
|
let IndexedDBProvider;
|
|
|
|
if (typeof indexedDB != 'undefined') {
|
|
IndexedDBProvider = indexedDB;
|
|
}
|
|
|
|
initForNonBrowserApp();
|
|
|
|
function initForNonBrowserApp() {
|
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
|
|
if (typeof btoa == 'undefined') {
|
|
global.btoa = function () {
|
|
let input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
let str = input;
|
|
let output = '';
|
|
|
|
for (let block = 0, charCode, i = 0, map = chars; str.charAt(i | 0) || (map = '=', i % 1); output += map.charAt(63 & block >> 8 - i % 1 * 8)) {
|
|
charCode = str.charCodeAt(i += 3 / 4);
|
|
|
|
if (charCode > 0xFF) {
|
|
throw new Error("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
|
|
}
|
|
|
|
block = block << 8 | charCode;
|
|
}
|
|
|
|
return output;
|
|
};
|
|
}
|
|
|
|
if (typeof atob == 'undefined') {
|
|
global.atob = function () {
|
|
let input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
let str = input.replace(/=+$/, '');
|
|
let output = '';
|
|
|
|
if (str.length % 4 == 1) {
|
|
throw new Error("'atob' failed: The string to be decoded is not correctly encoded.");
|
|
}
|
|
|
|
for (let bc = 0, bs = 0, buffer, i = 0; buffer = str.charAt(i++); ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0) {
|
|
buffer = chars.indexOf(buffer);
|
|
}
|
|
|
|
return output;
|
|
};
|
|
}
|
|
|
|
if (typeof window == 'undefined') {
|
|
global.window = {
|
|
WebSocket: WebSocketProvider,
|
|
XMLHttpRequest: XHRProvider,
|
|
indexedDB: IndexedDBProvider,
|
|
URL: {
|
|
createObjectURL: function () {
|
|
throw new Error("Unable to use URL.createObjectURL in a non-browser application");
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
_connection.default.setNetworkProviders(WebSocketProvider, XHRProvider);
|
|
|
|
_largeFile.default.setNetworkProvider(XHRProvider);
|
|
|
|
_db.default.setDatabaseProvider(IndexedDBProvider);
|
|
}
|
|
|
|
function detectTransport() {
|
|
if (typeof window == 'object') {
|
|
if (window['WebSocket']) {
|
|
return 'ws';
|
|
} else if (window['XMLHttpRequest']) {
|
|
return 'lp';
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function b64EncodeUnicode(str) {
|
|
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) {
|
|
return String.fromCharCode('0x' + p1);
|
|
}));
|
|
}
|
|
|
|
function jsonBuildHelper(key, val) {
|
|
if (val instanceof Date) {
|
|
val = (0, _utils.rfc3339DateString)(val);
|
|
} else if (val instanceof _accessMode.default) {
|
|
val = val.jsonHelper();
|
|
} else if (val === undefined || val === null || val === false || Array.isArray(val) && val.length == 0 || typeof val == 'object' && Object.keys(val).length == 0) {
|
|
return undefined;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
;
|
|
|
|
function jsonLoggerHelper(key, val) {
|
|
if (typeof val == 'string' && val.length > 128) {
|
|
return '<' + val.length + ', bytes: ' + val.substring(0, 12) + '...' + val.substring(val.length - 12) + '>';
|
|
}
|
|
|
|
return jsonBuildHelper(key, val);
|
|
}
|
|
|
|
;
|
|
|
|
function getBrowserInfo(ua, product) {
|
|
ua = ua || '';
|
|
let reactnative = '';
|
|
|
|
if (/reactnative/i.test(product)) {
|
|
reactnative = 'ReactNative; ';
|
|
}
|
|
|
|
let result;
|
|
ua = ua.replace(' (KHTML, like Gecko)', '');
|
|
let m = ua.match(/(AppleWebKit\/[.\d]+)/i);
|
|
|
|
if (m) {
|
|
const priority = ['edg', 'chrome', 'safari', 'mobile', 'version'];
|
|
let tmp = ua.substr(m.index + m[0].length).split(' ');
|
|
let tokens = [];
|
|
let version;
|
|
|
|
for (let i = 0; i < tmp.length; i++) {
|
|
let m2 = /([\w.]+)[\/]([\.\d]+)/.exec(tmp[i]);
|
|
|
|
if (m2) {
|
|
tokens.push([m2[1], m2[2], priority.findIndex(e => {
|
|
return m2[1].toLowerCase().startsWith(e);
|
|
})]);
|
|
|
|
if (m2[1] == 'Version') {
|
|
version = m2[2];
|
|
}
|
|
}
|
|
}
|
|
|
|
tokens.sort((a, b) => {
|
|
return a[2] - b[2];
|
|
});
|
|
|
|
if (tokens.length > 0) {
|
|
if (tokens[0][0].toLowerCase().startsWith('edg')) {
|
|
tokens[0][0] = 'Edge';
|
|
} else if (tokens[0][0] == 'OPR') {
|
|
tokens[0][0] = 'Opera';
|
|
} else if (tokens[0][0] == 'Safari' && version) {
|
|
tokens[0][1] = version;
|
|
}
|
|
|
|
result = tokens[0][0] + '/' + tokens[0][1];
|
|
} else {
|
|
result = m[1];
|
|
}
|
|
} else if (/firefox/i.test(ua)) {
|
|
m = /Firefox\/([.\d]+)/g.exec(ua);
|
|
|
|
if (m) {
|
|
result = 'Firefox/' + m[1];
|
|
} else {
|
|
result = 'Firefox/?';
|
|
}
|
|
} else {
|
|
m = /([\w.]+)\/([.\d]+)/.exec(ua);
|
|
|
|
if (m) {
|
|
result = m[1] + '/' + m[2];
|
|
} else {
|
|
m = ua.split(' ');
|
|
result = m[0];
|
|
}
|
|
}
|
|
|
|
m = result.split('/');
|
|
|
|
if (m.length > 1) {
|
|
const v = m[1].split('.');
|
|
const minor = v[1] ? '.' + v[1].substr(0, 2) : '';
|
|
result = `${m[0]}/${v[0]}${minor}`;
|
|
}
|
|
|
|
return reactnative + result;
|
|
}
|
|
|
|
var _makePromise = new WeakSet();
|
|
|
|
var _execPromise = new WeakSet();
|
|
|
|
var _send = new WeakSet();
|
|
|
|
var _dispatchMessage = new WeakSet();
|
|
|
|
var _connectionOpen = new WeakSet();
|
|
|
|
var _disconnected = new WeakSet();
|
|
|
|
var _getUserAgent = new WeakSet();
|
|
|
|
var _initPacket = new WeakSet();
|
|
|
|
var _cachePut = new WeakSet();
|
|
|
|
var _cacheGet = new WeakSet();
|
|
|
|
var _cacheDel = new WeakSet();
|
|
|
|
var _cacheMap = new WeakSet();
|
|
|
|
var _attachCacheToTopic = new WeakSet();
|
|
|
|
var _loginSuccessful = new WeakSet();
|
|
|
|
class Tinode {
|
|
constructor(config, onComplete) {
|
|
_classPrivateMethodInitSpec(this, _loginSuccessful);
|
|
|
|
_classPrivateMethodInitSpec(this, _attachCacheToTopic);
|
|
|
|
_classPrivateMethodInitSpec(this, _cacheMap);
|
|
|
|
_classPrivateMethodInitSpec(this, _cacheDel);
|
|
|
|
_classPrivateMethodInitSpec(this, _cacheGet);
|
|
|
|
_classPrivateMethodInitSpec(this, _cachePut);
|
|
|
|
_classPrivateMethodInitSpec(this, _initPacket);
|
|
|
|
_classPrivateMethodInitSpec(this, _getUserAgent);
|
|
|
|
_classPrivateMethodInitSpec(this, _disconnected);
|
|
|
|
_classPrivateMethodInitSpec(this, _connectionOpen);
|
|
|
|
_classPrivateMethodInitSpec(this, _dispatchMessage);
|
|
|
|
_classPrivateMethodInitSpec(this, _send);
|
|
|
|
_classPrivateMethodInitSpec(this, _execPromise);
|
|
|
|
_classPrivateMethodInitSpec(this, _makePromise);
|
|
|
|
_defineProperty(this, "_host", void 0);
|
|
|
|
_defineProperty(this, "_secure", void 0);
|
|
|
|
_defineProperty(this, "_appName", void 0);
|
|
|
|
_defineProperty(this, "_apiKey", void 0);
|
|
|
|
_defineProperty(this, "_browser", '');
|
|
|
|
_defineProperty(this, "_platform", void 0);
|
|
|
|
_defineProperty(this, "_hwos", 'undefined');
|
|
|
|
_defineProperty(this, "_humanLanguage", 'xx');
|
|
|
|
_defineProperty(this, "_loggingEnabled", false);
|
|
|
|
_defineProperty(this, "_trimLongStrings", false);
|
|
|
|
_defineProperty(this, "_myUID", null);
|
|
|
|
_defineProperty(this, "_authenticated", false);
|
|
|
|
_defineProperty(this, "_login", null);
|
|
|
|
_defineProperty(this, "_authToken", null);
|
|
|
|
_defineProperty(this, "_inPacketCount", 0);
|
|
|
|
_defineProperty(this, "_messageId", Math.floor(Math.random() * 0xFFFF + 0xFFFF));
|
|
|
|
_defineProperty(this, "_serverInfo", null);
|
|
|
|
_defineProperty(this, "_deviceToken", null);
|
|
|
|
_defineProperty(this, "_pendingPromises", {});
|
|
|
|
_defineProperty(this, "_expirePromises", null);
|
|
|
|
_defineProperty(this, "_connection", null);
|
|
|
|
_defineProperty(this, "_persist", false);
|
|
|
|
_defineProperty(this, "_db", null);
|
|
|
|
_defineProperty(this, "_cache", {});
|
|
|
|
_defineProperty(this, "onWebsocketOpen", undefined);
|
|
|
|
_defineProperty(this, "onConnect", undefined);
|
|
|
|
_defineProperty(this, "onDisconnect", undefined);
|
|
|
|
_defineProperty(this, "onLogin", undefined);
|
|
|
|
_defineProperty(this, "onCtrlMessage", undefined);
|
|
|
|
_defineProperty(this, "onDataMessage", undefined);
|
|
|
|
_defineProperty(this, "onPresMessage", undefined);
|
|
|
|
_defineProperty(this, "onMessage", undefined);
|
|
|
|
_defineProperty(this, "onRawMessage", undefined);
|
|
|
|
_defineProperty(this, "onNetworkProbe", undefined);
|
|
|
|
_defineProperty(this, "onAutoreconnectIteration", undefined);
|
|
|
|
this._host = config.host;
|
|
this._secure = config.secure;
|
|
this._appName = config.appName || "Undefined";
|
|
this._apiKey = config.apiKey;
|
|
this._platform = config.platform || 'web';
|
|
|
|
if (typeof navigator != 'undefined') {
|
|
this._browser = getBrowserInfo(navigator.userAgent, navigator.product);
|
|
this._hwos = navigator.platform;
|
|
this._humanLanguage = navigator.language || 'en-US';
|
|
}
|
|
|
|
_connection.default.logger = this.logger;
|
|
_drafty.default.logger = this.logger;
|
|
|
|
if (config.transport != 'lp' && config.transport != 'ws') {
|
|
config.transport = detectTransport();
|
|
}
|
|
|
|
this._connection = new _connection.default(config, Const.PROTOCOL_VERSION, true);
|
|
|
|
this._connection.onMessage = data => {
|
|
_classPrivateMethodGet(this, _dispatchMessage, _dispatchMessage2).call(this, data);
|
|
};
|
|
|
|
this._connection.onOpen = () => {
|
|
_classPrivateMethodGet(this, _connectionOpen, _connectionOpen2).call(this);
|
|
};
|
|
|
|
this._connection.onDisconnect = (err, code) => {
|
|
_classPrivateMethodGet(this, _disconnected, _disconnected2).call(this, err, code);
|
|
};
|
|
|
|
this._connection.onAutoreconnectIteration = (timeout, promise) => {
|
|
if (this.onAutoreconnectIteration) {
|
|
this.onAutoreconnectIteration(timeout, promise);
|
|
}
|
|
};
|
|
|
|
this._persist = config.persist;
|
|
this._db = new _db.default(err => {
|
|
this.logger('DB', err);
|
|
}, this.logger);
|
|
|
|
if (this._persist) {
|
|
const prom = [];
|
|
|
|
this._db.initDatabase().then(_ => {
|
|
return this._db.mapTopics(data => {
|
|
let topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', data.name);
|
|
|
|
if (topic) {
|
|
return;
|
|
}
|
|
|
|
if (data.name == Const.TOPIC_ME) {
|
|
topic = new _topic.TopicMe();
|
|
} else if (data.name == Const.TOPIC_FND) {
|
|
topic = new _topic.TopicFnd();
|
|
} else {
|
|
topic = new _topic.Topic(data.name);
|
|
}
|
|
|
|
this._db.deserializeTopic(topic, data);
|
|
|
|
_classPrivateMethodGet(this, _attachCacheToTopic, _attachCacheToTopic2).call(this, topic);
|
|
|
|
topic._cachePutSelf();
|
|
|
|
delete topic._new;
|
|
prom.push(topic._loadMessages(this._db));
|
|
});
|
|
}).then(_ => {
|
|
return this._db.mapUsers(data => {
|
|
_classPrivateMethodGet(this, _cachePut, _cachePut2).call(this, 'user', data.uid, (0, _utils.mergeObj)({}, data.public));
|
|
});
|
|
}).then(_ => {
|
|
return Promise.all(prom);
|
|
}).then(_ => {
|
|
if (onComplete) {
|
|
onComplete();
|
|
}
|
|
|
|
this.logger("Persistent cache initialized.");
|
|
}).catch(err => {
|
|
if (onComplete) {
|
|
onComplete(err);
|
|
}
|
|
|
|
this.logger("Failed to initialize persistent cache:", err);
|
|
});
|
|
} else {
|
|
this._db.deleteDatabase().then(_ => {
|
|
if (onComplete) {
|
|
onComplete();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
logger(str) {
|
|
if (this._loggingEnabled) {
|
|
const d = new Date();
|
|
const dateString = ('0' + d.getUTCHours()).slice(-2) + ':' + ('0' + d.getUTCMinutes()).slice(-2) + ':' + ('0' + d.getUTCSeconds()).slice(-2) + '.' + ('00' + d.getUTCMilliseconds()).slice(-3);
|
|
|
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
args[_key - 1] = arguments[_key];
|
|
}
|
|
|
|
console.log('[' + dateString + ']', str, args.join(' '));
|
|
}
|
|
}
|
|
|
|
static credential(meth, val, params, resp) {
|
|
if (typeof meth == 'object') {
|
|
({
|
|
val,
|
|
params,
|
|
resp,
|
|
meth
|
|
} = meth);
|
|
}
|
|
|
|
if (meth && (val || resp)) {
|
|
return [{
|
|
'meth': meth,
|
|
'val': val,
|
|
'resp': resp,
|
|
'params': params
|
|
}];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
static topicType(name) {
|
|
return _topic.Topic.topicType(name);
|
|
}
|
|
|
|
static isMeTopicName(name) {
|
|
return _topic.Topic.isMeTopicName(name);
|
|
}
|
|
|
|
static isGroupTopicName(name) {
|
|
return _topic.Topic.isGroupTopicName(name);
|
|
}
|
|
|
|
static isP2PTopicName(name) {
|
|
return _topic.Topic.isP2PTopicName(name);
|
|
}
|
|
|
|
static isCommTopicName(name) {
|
|
return _topic.Topic.isCommTopicName(name);
|
|
}
|
|
|
|
static isNewGroupTopicName(name) {
|
|
return _topic.Topic.isNewGroupTopicName(name);
|
|
}
|
|
|
|
static isChannelTopicName(name) {
|
|
return _topic.Topic.isChannelTopicName(name);
|
|
}
|
|
|
|
static getVersion() {
|
|
return Const.VERSION;
|
|
}
|
|
|
|
static setNetworkProviders(wsProvider, xhrProvider) {
|
|
WebSocketProvider = wsProvider;
|
|
XHRProvider = xhrProvider;
|
|
|
|
_connection.default.setNetworkProviders(WebSocketProvider, XHRProvider);
|
|
|
|
_largeFile.default.setNetworkProvider(XHRProvider);
|
|
}
|
|
|
|
static setDatabaseProvider(idbProvider) {
|
|
IndexedDBProvider = idbProvider;
|
|
|
|
_db.default.setDatabaseProvider(IndexedDBProvider);
|
|
}
|
|
|
|
static getLibrary() {
|
|
return Const.LIBRARY;
|
|
}
|
|
|
|
static isNullValue(str) {
|
|
return str === Const.DEL_CHAR;
|
|
}
|
|
|
|
static isRelativeURL(url) {
|
|
return !/^\s*([a-z][a-z0-9+.-]*:|\/\/)/im.test(url);
|
|
}
|
|
|
|
getNextUniqueId() {
|
|
return this._messageId != 0 ? '' + this._messageId++ : undefined;
|
|
}
|
|
|
|
connect(host_) {
|
|
return this._connection.connect(host_);
|
|
}
|
|
|
|
reconnect(force) {
|
|
this._connection.reconnect(force);
|
|
}
|
|
|
|
disconnect() {
|
|
this._connection.disconnect();
|
|
}
|
|
|
|
clearStorage() {
|
|
if (this._db.isReady()) {
|
|
return this._db.deleteDatabase();
|
|
}
|
|
|
|
return Promise.resolve();
|
|
}
|
|
|
|
initStorage() {
|
|
if (!this._db.isReady()) {
|
|
return this._db.initDatabase();
|
|
}
|
|
|
|
return Promise.resolve();
|
|
}
|
|
|
|
networkProbe() {
|
|
this._connection.probe();
|
|
}
|
|
|
|
isConnected() {
|
|
return this._connection.isConnected();
|
|
}
|
|
|
|
isAuthenticated() {
|
|
return this._authenticated;
|
|
}
|
|
|
|
authorizeURL(url) {
|
|
if (typeof url != 'string') {
|
|
return url;
|
|
}
|
|
|
|
if (Tinode.isRelativeURL(url)) {
|
|
const base = 'scheme://host/';
|
|
const parsed = new URL(url, base);
|
|
|
|
if (this._apiKey) {
|
|
parsed.searchParams.append('apikey', this._apiKey);
|
|
}
|
|
|
|
if (this._authToken && this._authToken.token) {
|
|
parsed.searchParams.append('auth', 'token');
|
|
parsed.searchParams.append('secret', this._authToken.token);
|
|
}
|
|
|
|
url = parsed.toString().substring(base.length - 1);
|
|
}
|
|
|
|
return url;
|
|
}
|
|
|
|
account(uid, scheme, secret, login, params) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'acc');
|
|
|
|
pkt.acc.user = uid;
|
|
pkt.acc.scheme = scheme;
|
|
pkt.acc.secret = secret;
|
|
pkt.acc.login = login;
|
|
|
|
if (params) {
|
|
pkt.acc.desc.defacs = params.defacs;
|
|
pkt.acc.desc.public = params.public;
|
|
pkt.acc.desc.private = params.private;
|
|
pkt.acc.desc.trusted = params.trusted;
|
|
pkt.acc.tags = params.tags;
|
|
pkt.acc.cred = params.cred;
|
|
pkt.acc.token = params.token;
|
|
|
|
if (Array.isArray(params.attachments) && params.attachments.length > 0) {
|
|
pkt.extra = {
|
|
attachments: params.attachments.filter(ref => Tinode.isRelativeURL(ref))
|
|
};
|
|
}
|
|
}
|
|
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.acc.id);
|
|
}
|
|
|
|
createAccount(scheme, secret, login, params) {
|
|
let promise = this.account(Const.USER_NEW, scheme, secret, login, params);
|
|
|
|
if (login) {
|
|
promise = promise.then(ctrl => {
|
|
return _classPrivateMethodGet(this, _loginSuccessful, _loginSuccessful2).call(this, ctrl);
|
|
});
|
|
}
|
|
|
|
return promise;
|
|
}
|
|
|
|
createAccountBasic(username, password, params) {
|
|
username = username || '';
|
|
password = password || '';
|
|
return this.createAccount('basic', b64EncodeUnicode(username + ':' + password), true, params);
|
|
}
|
|
|
|
updateAccountBasic(uid, username, password, params) {
|
|
username = username || '';
|
|
password = password || '';
|
|
return this.account(uid, 'basic', b64EncodeUnicode(username + ':' + password), false, params);
|
|
}
|
|
|
|
hello() {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'hi');
|
|
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.hi.id).then(ctrl => {
|
|
this._connection.backoffReset();
|
|
|
|
if (ctrl.params) {
|
|
this._serverInfo = ctrl.params;
|
|
}
|
|
|
|
if (this.onConnect) {
|
|
this.onConnect();
|
|
}
|
|
|
|
return ctrl;
|
|
}).catch(err => {
|
|
this._connection.reconnect(true);
|
|
|
|
if (this.onDisconnect) {
|
|
this.onDisconnect(err);
|
|
}
|
|
});
|
|
}
|
|
|
|
setDeviceToken(dt) {
|
|
let sent = false;
|
|
dt = dt || null;
|
|
|
|
if (dt != this._deviceToken) {
|
|
this._deviceToken = dt;
|
|
|
|
if (this.isConnected() && this.isAuthenticated()) {
|
|
_classPrivateMethodGet(this, _send, _send2).call(this, {
|
|
'hi': {
|
|
'dev': dt || Tinode.DEL_CHAR
|
|
}
|
|
});
|
|
|
|
sent = true;
|
|
}
|
|
}
|
|
|
|
return sent;
|
|
}
|
|
|
|
login(scheme, secret, cred) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'login');
|
|
|
|
pkt.login.scheme = scheme;
|
|
pkt.login.secret = secret;
|
|
pkt.login.cred = cred;
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.login.id).then(ctrl => {
|
|
return _classPrivateMethodGet(this, _loginSuccessful, _loginSuccessful2).call(this, ctrl);
|
|
});
|
|
}
|
|
|
|
loginBasic(uname, password, cred) {
|
|
return this.login('basic', b64EncodeUnicode(uname + ':' + password), cred).then(ctrl => {
|
|
this._login = uname;
|
|
return ctrl;
|
|
});
|
|
}
|
|
|
|
loginToken(token, cred) {
|
|
return this.login('token', token, cred);
|
|
}
|
|
|
|
requestResetAuthSecret(scheme, method, value) {
|
|
return this.login('reset', b64EncodeUnicode(scheme + ':' + method + ':' + value));
|
|
}
|
|
|
|
getAuthToken() {
|
|
if (this._authToken && this._authToken.expires.getTime() > Date.now()) {
|
|
return this._authToken;
|
|
} else {
|
|
this._authToken = null;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
setAuthToken(token) {
|
|
this._authToken = token;
|
|
}
|
|
|
|
subscribe(topicName, getParams, setParams) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'sub', topicName);
|
|
|
|
if (!topicName) {
|
|
topicName = Const.TOPIC_NEW;
|
|
}
|
|
|
|
pkt.sub.get = getParams;
|
|
|
|
if (setParams) {
|
|
if (setParams.sub) {
|
|
pkt.sub.set.sub = setParams.sub;
|
|
}
|
|
|
|
if (setParams.desc) {
|
|
const desc = setParams.desc;
|
|
|
|
if (Tinode.isNewGroupTopicName(topicName)) {
|
|
pkt.sub.set.desc = desc;
|
|
} else if (Tinode.isP2PTopicName(topicName) && desc.defacs) {
|
|
pkt.sub.set.desc = {
|
|
defacs: desc.defacs
|
|
};
|
|
}
|
|
}
|
|
|
|
if (Array.isArray(setParams.attachments) && setParams.attachments.length > 0) {
|
|
pkt.extra = {
|
|
attachments: setParams.attachments.filter(ref => Tinode.isRelativeURL(ref))
|
|
};
|
|
}
|
|
|
|
if (setParams.tags) {
|
|
pkt.sub.set.tags = setParams.tags;
|
|
}
|
|
}
|
|
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.sub.id);
|
|
}
|
|
|
|
leave(topic, unsub) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'leave', topic);
|
|
|
|
pkt.leave.unsub = unsub;
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.leave.id);
|
|
}
|
|
|
|
createMessage(topic, content, noEcho) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'pub', topic);
|
|
|
|
let dft = typeof content == 'string' ? _drafty.default.parse(content) : content;
|
|
|
|
if (dft && !_drafty.default.isPlainText(dft)) {
|
|
pkt.pub.head = {
|
|
mime: _drafty.default.getContentType()
|
|
};
|
|
content = dft;
|
|
}
|
|
|
|
pkt.pub.noecho = noEcho;
|
|
pkt.pub.content = content;
|
|
return pkt.pub;
|
|
}
|
|
|
|
publish(topicName, content, noEcho) {
|
|
return this.publishMessage(this.createMessage(topicName, content, noEcho));
|
|
}
|
|
|
|
publishMessage(pub, attachments) {
|
|
pub = Object.assign({}, pub);
|
|
pub.seq = undefined;
|
|
pub.from = undefined;
|
|
pub.ts = undefined;
|
|
const msg = {
|
|
pub: pub
|
|
};
|
|
|
|
if (attachments) {
|
|
msg.extra = {
|
|
attachments: attachments.filter(ref => Tinode.isRelativeURL(ref))
|
|
};
|
|
}
|
|
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, msg, pub.id);
|
|
}
|
|
|
|
oobNotification(data) {
|
|
this.logger("oob: " + (this._trimLongStrings ? JSON.stringify(data, jsonLoggerHelper) : data));
|
|
|
|
switch (data.what) {
|
|
case 'msg':
|
|
if (!data.seq || data.seq < 1 || !data.topic) {
|
|
break;
|
|
}
|
|
|
|
if (!this.isConnected()) {
|
|
break;
|
|
}
|
|
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', data.topic);
|
|
|
|
if (!topic) {
|
|
break;
|
|
}
|
|
|
|
if (topic.isSubscribed()) {
|
|
break;
|
|
}
|
|
|
|
if (topic.maxMsgSeq() < data.seq) {
|
|
if (topic.isChannelType()) {
|
|
topic._updateReceived(data.seq, 'fake-uid');
|
|
}
|
|
|
|
if (data.xfrom && !_classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'user', data.xfrom)) {
|
|
this.getMeta(data.xfrom, new _metaBuilder.default().withDesc().build()).catch(err => {
|
|
this.logger("Failed to get the name of a new sender", err);
|
|
});
|
|
}
|
|
|
|
topic.subscribe(null).then(_ => {
|
|
return topic.getMeta(new _metaBuilder.default(topic).withLaterData(24).withLaterDel(24).build());
|
|
}).then(_ => {
|
|
topic.leaveDelayed(false, 1000);
|
|
}).catch(err => {
|
|
this.logger("On push data fetch failed", err);
|
|
}).finally(_ => {
|
|
this.getMeTopic()._refreshContact('msg', topic);
|
|
});
|
|
}
|
|
|
|
break;
|
|
|
|
case 'read':
|
|
this.getMeTopic()._routePres({
|
|
what: 'read',
|
|
seq: data.seq
|
|
});
|
|
|
|
break;
|
|
|
|
case 'sub':
|
|
if (!this.isMe(data.xfrom)) {
|
|
break;
|
|
}
|
|
|
|
let mode = {
|
|
given: data.modeGiven,
|
|
want: data.modeWant
|
|
};
|
|
let acs = new _accessMode.default(mode);
|
|
let pres = !acs.mode || acs.mode == _accessMode.default._NONE ? {
|
|
what: 'gone',
|
|
src: data.topic
|
|
} : {
|
|
what: 'acs',
|
|
src: data.topic,
|
|
dacs: mode
|
|
};
|
|
|
|
this.getMeTopic()._routePres(pres);
|
|
|
|
break;
|
|
|
|
default:
|
|
this.logger("Unknown push type ignored", data.what);
|
|
}
|
|
}
|
|
|
|
getMeta(topic, params) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'get', topic);
|
|
|
|
pkt.get = (0, _utils.mergeObj)(pkt.get, params);
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.get.id);
|
|
}
|
|
|
|
setMeta(topic, params) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'set', topic);
|
|
|
|
const what = [];
|
|
|
|
if (params) {
|
|
['desc', 'sub', 'tags', 'cred', 'ephemeral'].forEach(function (key) {
|
|
if (params.hasOwnProperty(key)) {
|
|
what.push(key);
|
|
pkt.set[key] = params[key];
|
|
}
|
|
});
|
|
|
|
if (Array.isArray(params.attachments) && params.attachments.length > 0) {
|
|
pkt.extra = {
|
|
attachments: params.attachments.filter(ref => Tinode.isRelativeURL(ref))
|
|
};
|
|
}
|
|
}
|
|
|
|
if (what.length == 0) {
|
|
return Promise.reject(new Error("Invalid {set} parameters"));
|
|
}
|
|
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.set.id);
|
|
}
|
|
|
|
delMessages(topic, ranges, hard) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'del', topic);
|
|
|
|
pkt.del.what = 'msg';
|
|
pkt.del.delseq = ranges;
|
|
pkt.del.hard = hard;
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.del.id);
|
|
}
|
|
|
|
delTopic(topicName, hard) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'del', topicName);
|
|
|
|
pkt.del.what = 'topic';
|
|
pkt.del.hard = hard;
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.del.id);
|
|
}
|
|
|
|
delSubscription(topicName, user) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'del', topicName);
|
|
|
|
pkt.del.what = 'sub';
|
|
pkt.del.user = user;
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.del.id);
|
|
}
|
|
|
|
delCredential(method, value) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'del', Const.TOPIC_ME);
|
|
|
|
pkt.del.what = 'cred';
|
|
pkt.del.cred = {
|
|
meth: method,
|
|
val: value
|
|
};
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.del.id);
|
|
}
|
|
|
|
delCurrentUser(hard) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'del', null);
|
|
|
|
pkt.del.what = 'user';
|
|
pkt.del.hard = hard;
|
|
return _classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.del.id).then(ctrl => {
|
|
this._myUID = null;
|
|
});
|
|
}
|
|
|
|
note(topicName, what, seq) {
|
|
if (seq <= 0 || seq >= Const.LOCAL_SEQID) {
|
|
throw new Error(`Invalid message id ${seq}`);
|
|
}
|
|
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'note', topicName);
|
|
|
|
pkt.note.what = what;
|
|
pkt.note.seq = seq;
|
|
|
|
_classPrivateMethodGet(this, _send, _send2).call(this, pkt);
|
|
}
|
|
|
|
noteKeyPress(topicName) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'note', topicName);
|
|
|
|
pkt.note.what = 'kp';
|
|
|
|
_classPrivateMethodGet(this, _send, _send2).call(this, pkt);
|
|
}
|
|
|
|
videoCall(topicName, seq, evt, payload) {
|
|
const pkt = _classPrivateMethodGet(this, _initPacket, _initPacket2).call(this, 'note', topicName);
|
|
|
|
pkt.note.seq = seq;
|
|
pkt.note.what = 'call';
|
|
pkt.note.event = evt;
|
|
pkt.note.payload = payload;
|
|
|
|
_classPrivateMethodGet(this, _send, _send2).call(this, pkt, pkt.note.id);
|
|
}
|
|
|
|
getTopic(topicName) {
|
|
let topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', topicName);
|
|
|
|
if (!topic && topicName) {
|
|
if (topicName == Const.TOPIC_ME) {
|
|
topic = new _topic.TopicMe();
|
|
} else if (topicName == Const.TOPIC_FND) {
|
|
topic = new _topic.TopicFnd();
|
|
} else {
|
|
topic = new _topic.Topic(topicName);
|
|
}
|
|
|
|
_classPrivateMethodGet(this, _attachCacheToTopic, _attachCacheToTopic2).call(this, topic);
|
|
|
|
topic._cachePutSelf();
|
|
}
|
|
|
|
return topic;
|
|
}
|
|
|
|
cacheGetTopic(topicName) {
|
|
return _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', topicName);
|
|
}
|
|
|
|
cacheRemTopic(topicName) {
|
|
_classPrivateMethodGet(this, _cacheDel, _cacheDel2).call(this, 'topic', topicName);
|
|
}
|
|
|
|
mapTopics(func, context) {
|
|
_classPrivateMethodGet(this, _cacheMap, _cacheMap2).call(this, 'topic', func, context);
|
|
}
|
|
|
|
isTopicCached(topicName) {
|
|
return !!_classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', topicName);
|
|
}
|
|
|
|
newGroupTopicName(isChan) {
|
|
return (isChan ? Const.TOPIC_NEW_CHAN : Const.TOPIC_NEW) + this.getNextUniqueId();
|
|
}
|
|
|
|
getMeTopic() {
|
|
return this.getTopic(Const.TOPIC_ME);
|
|
}
|
|
|
|
getFndTopic() {
|
|
return this.getTopic(Const.TOPIC_FND);
|
|
}
|
|
|
|
getLargeFileHelper() {
|
|
return new _largeFile.default(this, Const.PROTOCOL_VERSION);
|
|
}
|
|
|
|
getCurrentUserID() {
|
|
return this._myUID;
|
|
}
|
|
|
|
isMe(uid) {
|
|
return this._myUID === uid;
|
|
}
|
|
|
|
getCurrentLogin() {
|
|
return this._login;
|
|
}
|
|
|
|
getServerInfo() {
|
|
return this._serverInfo;
|
|
}
|
|
|
|
report(action, target) {
|
|
return this.publish(Const.TOPIC_SYS, _drafty.default.attachJSON(null, {
|
|
'action': action,
|
|
'target': target
|
|
}));
|
|
}
|
|
|
|
getServerParam(name, defaultValue) {
|
|
return this._serverInfo && this._serverInfo[name] || defaultValue;
|
|
}
|
|
|
|
enableLogging(enabled, trimLongStrings) {
|
|
this._loggingEnabled = enabled;
|
|
this._trimLongStrings = enabled && trimLongStrings;
|
|
}
|
|
|
|
setHumanLanguage(hl) {
|
|
if (hl) {
|
|
this._humanLanguage = hl;
|
|
}
|
|
}
|
|
|
|
isTopicOnline(name) {
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', name);
|
|
|
|
return topic && topic.online;
|
|
}
|
|
|
|
getTopicAccessMode(name) {
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', name);
|
|
|
|
return topic ? topic.acs : null;
|
|
}
|
|
|
|
wantAkn(status) {
|
|
if (status) {
|
|
this._messageId = Math.floor(Math.random() * 0xFFFFFF + 0xFFFFFF);
|
|
} else {
|
|
this._messageId = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
exports.Tinode = Tinode;
|
|
|
|
function _makePromise2(id) {
|
|
let promise = null;
|
|
|
|
if (id) {
|
|
promise = new Promise((resolve, reject) => {
|
|
this._pendingPromises[id] = {
|
|
'resolve': resolve,
|
|
'reject': reject,
|
|
'ts': new Date()
|
|
};
|
|
});
|
|
}
|
|
|
|
return promise;
|
|
}
|
|
|
|
function _execPromise2(id, code, onOK, errorText) {
|
|
const callbacks = this._pendingPromises[id];
|
|
|
|
if (callbacks) {
|
|
delete this._pendingPromises[id];
|
|
|
|
if (code >= 200 && code < 400) {
|
|
if (callbacks.resolve) {
|
|
callbacks.resolve(onOK);
|
|
}
|
|
} else if (callbacks.reject) {
|
|
callbacks.reject(new Error(`${errorText} (${code})`));
|
|
}
|
|
}
|
|
}
|
|
|
|
function _send2(pkt, id) {
|
|
let promise;
|
|
|
|
if (id) {
|
|
promise = _classPrivateMethodGet(this, _makePromise, _makePromise2).call(this, id);
|
|
}
|
|
|
|
pkt = (0, _utils.simplify)(pkt);
|
|
let msg = JSON.stringify(pkt);
|
|
this.logger("out: " + (this._trimLongStrings ? JSON.stringify(pkt, jsonLoggerHelper) : msg));
|
|
|
|
try {
|
|
this._connection.sendText(msg);
|
|
} catch (err) {
|
|
if (id) {
|
|
_classPrivateMethodGet(this, _execPromise, _execPromise2).call(this, id, _connection.default.NETWORK_ERROR, null, err.message);
|
|
} else {
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
return promise;
|
|
}
|
|
|
|
function _dispatchMessage2(data) {
|
|
if (!data) return;
|
|
this._inPacketCount++;
|
|
|
|
if (this.onRawMessage) {
|
|
this.onRawMessage(data);
|
|
}
|
|
|
|
if (data === '0') {
|
|
if (this.onNetworkProbe) {
|
|
this.onNetworkProbe();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
let pkt = JSON.parse(data, _utils.jsonParseHelper);
|
|
|
|
if (!pkt) {
|
|
this.logger("in: " + data);
|
|
this.logger("ERROR: failed to parse data");
|
|
} else {
|
|
this.logger("in: " + (this._trimLongStrings ? JSON.stringify(pkt, jsonLoggerHelper) : data));
|
|
|
|
if (this.onMessage) {
|
|
this.onMessage(pkt);
|
|
}
|
|
|
|
if (pkt.ctrl) {
|
|
if (this.onCtrlMessage) {
|
|
this.onCtrlMessage(pkt.ctrl);
|
|
}
|
|
|
|
if (pkt.ctrl.id) {
|
|
_classPrivateMethodGet(this, _execPromise, _execPromise2).call(this, pkt.ctrl.id, pkt.ctrl.code, pkt.ctrl, pkt.ctrl.text);
|
|
}
|
|
|
|
setTimeout(() => {
|
|
if (pkt.ctrl.code == 205 && pkt.ctrl.text == 'evicted') {
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', pkt.ctrl.topic);
|
|
|
|
if (topic) {
|
|
topic._resetSub();
|
|
|
|
if (pkt.ctrl.params && pkt.ctrl.params.unsub) {
|
|
topic._gone();
|
|
}
|
|
}
|
|
} else if (pkt.ctrl.code < 300 && pkt.ctrl.params) {
|
|
if (pkt.ctrl.params.what == 'data') {
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', pkt.ctrl.topic);
|
|
|
|
if (topic) {
|
|
topic._allMessagesReceived(pkt.ctrl.params.count);
|
|
}
|
|
} else if (pkt.ctrl.params.what == 'sub') {
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', pkt.ctrl.topic);
|
|
|
|
if (topic) {
|
|
topic._processMetaSub([]);
|
|
}
|
|
}
|
|
}
|
|
}, 0);
|
|
} else {
|
|
setTimeout(() => {
|
|
if (pkt.meta) {
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', pkt.meta.topic);
|
|
|
|
if (topic) {
|
|
topic._routeMeta(pkt.meta);
|
|
}
|
|
|
|
if (pkt.meta.id) {
|
|
_classPrivateMethodGet(this, _execPromise, _execPromise2).call(this, pkt.meta.id, 200, pkt.meta, 'META');
|
|
}
|
|
|
|
if (this.onMetaMessage) {
|
|
this.onMetaMessage(pkt.meta);
|
|
}
|
|
} else if (pkt.data) {
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', pkt.data.topic);
|
|
|
|
if (topic) {
|
|
topic._routeData(pkt.data);
|
|
}
|
|
|
|
if (this.onDataMessage) {
|
|
this.onDataMessage(pkt.data);
|
|
}
|
|
} else if (pkt.pres) {
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', pkt.pres.topic);
|
|
|
|
if (topic) {
|
|
topic._routePres(pkt.pres);
|
|
}
|
|
|
|
if (this.onPresMessage) {
|
|
this.onPresMessage(pkt.pres);
|
|
}
|
|
} else if (pkt.info) {
|
|
const topic = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'topic', pkt.info.topic);
|
|
|
|
if (topic) {
|
|
topic._routeInfo(pkt.info);
|
|
}
|
|
|
|
if (this.onInfoMessage) {
|
|
this.onInfoMessage(pkt.info);
|
|
}
|
|
} else {
|
|
this.logger("ERROR: Unknown packet received.");
|
|
}
|
|
}, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
function _connectionOpen2() {
|
|
if (!this._expirePromises) {
|
|
this._expirePromises = setInterval(() => {
|
|
const err = new Error("Timeout (504)");
|
|
const expires = new Date(new Date().getTime() - Const.EXPIRE_PROMISES_TIMEOUT);
|
|
|
|
for (let id in this._pendingPromises) {
|
|
let callbacks = this._pendingPromises[id];
|
|
|
|
if (callbacks && callbacks.ts < expires) {
|
|
this.logger("Promise expired", id);
|
|
delete this._pendingPromises[id];
|
|
|
|
if (callbacks.reject) {
|
|
callbacks.reject(err);
|
|
}
|
|
}
|
|
}
|
|
}, Const.EXPIRE_PROMISES_PERIOD);
|
|
}
|
|
|
|
this.hello();
|
|
}
|
|
|
|
function _disconnected2(err, code) {
|
|
this._inPacketCount = 0;
|
|
this._serverInfo = null;
|
|
this._authenticated = false;
|
|
|
|
if (this._expirePromises) {
|
|
clearInterval(this._expirePromises);
|
|
this._expirePromises = null;
|
|
}
|
|
|
|
_classPrivateMethodGet(this, _cacheMap, _cacheMap2).call(this, 'topic', (topic, key) => {
|
|
topic._resetSub();
|
|
});
|
|
|
|
for (let key in this._pendingPromises) {
|
|
const callbacks = this._pendingPromises[key];
|
|
|
|
if (callbacks && callbacks.reject) {
|
|
callbacks.reject(err);
|
|
}
|
|
}
|
|
|
|
this._pendingPromises = {};
|
|
|
|
if (this.onDisconnect) {
|
|
this.onDisconnect(err);
|
|
}
|
|
}
|
|
|
|
function _getUserAgent2() {
|
|
return this._appName + ' (' + (this._browser ? this._browser + '; ' : '') + this._hwos + '); ' + Const.LIBRARY;
|
|
}
|
|
|
|
function _initPacket2(type, topic) {
|
|
switch (type) {
|
|
case 'hi':
|
|
return {
|
|
'hi': {
|
|
'id': this.getNextUniqueId(),
|
|
'ver': Const.VERSION,
|
|
'ua': _classPrivateMethodGet(this, _getUserAgent, _getUserAgent2).call(this),
|
|
'dev': this._deviceToken,
|
|
'lang': this._humanLanguage,
|
|
'platf': this._platform
|
|
}
|
|
};
|
|
|
|
case 'acc':
|
|
return {
|
|
'acc': {
|
|
'id': this.getNextUniqueId(),
|
|
'user': null,
|
|
'scheme': null,
|
|
'secret': null,
|
|
'login': false,
|
|
'tags': null,
|
|
'desc': {},
|
|
'cred': {}
|
|
}
|
|
};
|
|
|
|
case 'login':
|
|
return {
|
|
'login': {
|
|
'id': this.getNextUniqueId(),
|
|
'scheme': null,
|
|
'secret': null
|
|
}
|
|
};
|
|
|
|
case 'sub':
|
|
return {
|
|
'sub': {
|
|
'id': this.getNextUniqueId(),
|
|
'topic': topic,
|
|
'set': {},
|
|
'get': {}
|
|
}
|
|
};
|
|
|
|
case 'leave':
|
|
return {
|
|
'leave': {
|
|
'id': this.getNextUniqueId(),
|
|
'topic': topic,
|
|
'unsub': false
|
|
}
|
|
};
|
|
|
|
case 'pub':
|
|
return {
|
|
'pub': {
|
|
'id': this.getNextUniqueId(),
|
|
'topic': topic,
|
|
'noecho': false,
|
|
'head': null,
|
|
'content': {}
|
|
}
|
|
};
|
|
|
|
case 'get':
|
|
return {
|
|
'get': {
|
|
'id': this.getNextUniqueId(),
|
|
'topic': topic,
|
|
'what': null,
|
|
'desc': {},
|
|
'sub': {},
|
|
'data': {}
|
|
}
|
|
};
|
|
|
|
case 'set':
|
|
return {
|
|
'set': {
|
|
'id': this.getNextUniqueId(),
|
|
'topic': topic,
|
|
'desc': {},
|
|
'sub': {},
|
|
'tags': [],
|
|
'ephemeral': {}
|
|
}
|
|
};
|
|
|
|
case 'del':
|
|
return {
|
|
'del': {
|
|
'id': this.getNextUniqueId(),
|
|
'topic': topic,
|
|
'what': null,
|
|
'delseq': null,
|
|
'user': null,
|
|
'hard': false
|
|
}
|
|
};
|
|
|
|
case 'note':
|
|
return {
|
|
'note': {
|
|
'topic': topic,
|
|
'what': null,
|
|
'seq': undefined
|
|
}
|
|
};
|
|
|
|
default:
|
|
throw new Error(`Unknown packet type requested: ${type}`);
|
|
}
|
|
}
|
|
|
|
function _cachePut2(type, name, obj) {
|
|
this._cache[type + ':' + name] = obj;
|
|
}
|
|
|
|
function _cacheGet2(type, name) {
|
|
return this._cache[type + ':' + name];
|
|
}
|
|
|
|
function _cacheDel2(type, name) {
|
|
delete this._cache[type + ':' + name];
|
|
}
|
|
|
|
function _cacheMap2(type, func, context) {
|
|
const key = type ? type + ':' : undefined;
|
|
|
|
for (let idx in this._cache) {
|
|
if (!key || idx.indexOf(key) == 0) {
|
|
if (func.call(context, this._cache[idx], idx)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function _attachCacheToTopic2(topic) {
|
|
topic._tinode = this;
|
|
|
|
topic._cacheGetUser = uid => {
|
|
const pub = _classPrivateMethodGet(this, _cacheGet, _cacheGet2).call(this, 'user', uid);
|
|
|
|
if (pub) {
|
|
return {
|
|
user: uid,
|
|
public: (0, _utils.mergeObj)({}, pub)
|
|
};
|
|
}
|
|
|
|
return undefined;
|
|
};
|
|
|
|
topic._cachePutUser = (uid, user) => {
|
|
_classPrivateMethodGet(this, _cachePut, _cachePut2).call(this, 'user', uid, (0, _utils.mergeObj)({}, user.public));
|
|
};
|
|
|
|
topic._cacheDelUser = uid => {
|
|
_classPrivateMethodGet(this, _cacheDel, _cacheDel2).call(this, 'user', uid);
|
|
};
|
|
|
|
topic._cachePutSelf = _ => {
|
|
_classPrivateMethodGet(this, _cachePut, _cachePut2).call(this, 'topic', topic.name, topic);
|
|
};
|
|
|
|
topic._cacheDelSelf = _ => {
|
|
_classPrivateMethodGet(this, _cacheDel, _cacheDel2).call(this, 'topic', topic.name);
|
|
};
|
|
}
|
|
|
|
function _loginSuccessful2(ctrl) {
|
|
if (!ctrl.params || !ctrl.params.user) {
|
|
return ctrl;
|
|
}
|
|
|
|
this._myUID = ctrl.params.user;
|
|
this._authenticated = ctrl && ctrl.code >= 200 && ctrl.code < 300;
|
|
|
|
if (ctrl.params && ctrl.params.token && ctrl.params.expires) {
|
|
this._authToken = {
|
|
token: ctrl.params.token,
|
|
expires: ctrl.params.expires
|
|
};
|
|
} else {
|
|
this._authToken = null;
|
|
}
|
|
|
|
if (this.onLogin) {
|
|
this.onLogin(ctrl.code, ctrl.text);
|
|
}
|
|
|
|
return ctrl;
|
|
}
|
|
|
|
;
|
|
Tinode.MESSAGE_STATUS_NONE = Const.MESSAGE_STATUS_NONE;
|
|
Tinode.MESSAGE_STATUS_QUEUED = Const.MESSAGE_STATUS_QUEUED;
|
|
Tinode.MESSAGE_STATUS_SENDING = Const.MESSAGE_STATUS_SENDING;
|
|
Tinode.MESSAGE_STATUS_FAILED = Const.MESSAGE_STATUS_FAILED;
|
|
Tinode.MESSAGE_STATUS_SENT = Const.MESSAGE_STATUS_SENT;
|
|
Tinode.MESSAGE_STATUS_RECEIVED = Const.MESSAGE_STATUS_RECEIVED;
|
|
Tinode.MESSAGE_STATUS_READ = Const.MESSAGE_STATUS_READ;
|
|
Tinode.MESSAGE_STATUS_TO_ME = Const.MESSAGE_STATUS_TO_ME;
|
|
Tinode.MESSAGE_STATUS_DEL_RANGE = Const.MESSAGE_STATUS_DEL_RANGE;
|
|
Tinode.DEL_CHAR = Const.DEL_CHAR;
|
|
Tinode.MAX_MESSAGE_SIZE = 'maxMessageSize';
|
|
Tinode.MAX_SUBSCRIBER_COUNT = 'maxSubscriberCount';
|
|
Tinode.MAX_TAG_COUNT = 'maxTagCount';
|
|
Tinode.MAX_FILE_UPLOAD_SIZE = 'maxFileUploadSize';
|
|
|
|
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
|
|
},{"./access-mode.js":1,"./config.js":3,"./connection.js":4,"./db.js":5,"./drafty.js":6,"./large-file.js":7,"./meta-builder.js":8,"./topic.js":10,"./utils.js":11}],10:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.TopicMe = exports.TopicFnd = exports.Topic = void 0;
|
|
|
|
var _accessMode = _interopRequireDefault(require("./access-mode.js"));
|
|
|
|
var _cbuffer = _interopRequireDefault(require("./cbuffer.js"));
|
|
|
|
var Const = _interopRequireWildcard(require("./config.js"));
|
|
|
|
var _drafty = _interopRequireDefault(require("./drafty.js"));
|
|
|
|
var _metaBuilder = _interopRequireDefault(require("./meta-builder.js"));
|
|
|
|
var _utils = require("./utils.js");
|
|
|
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
|
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
class Topic {
|
|
constructor(name, callbacks) {
|
|
this._tinode = null;
|
|
this.name = name;
|
|
this.created = null;
|
|
this.updated = null;
|
|
this.touched = new Date(0);
|
|
this.acs = new _accessMode.default(null);
|
|
this.private = null;
|
|
this.public = null;
|
|
this.trusted = null;
|
|
this._users = {};
|
|
this._queuedSeqId = Const.LOCAL_SEQID;
|
|
this._maxSeq = 0;
|
|
this._minSeq = 0;
|
|
this._noEarlierMsgs = false;
|
|
this._maxDel = 0;
|
|
this._recvNotificationTimer = null;
|
|
this._tags = [];
|
|
this._credentials = [];
|
|
this._messageVersions = {};
|
|
this._messages = new _cbuffer.default((a, b) => {
|
|
return a.seq - b.seq;
|
|
}, true);
|
|
this._attached = false;
|
|
this._lastSubsUpdate = new Date(0);
|
|
this._new = true;
|
|
this._deleted = false;
|
|
this._delayedLeaveTimer = null;
|
|
|
|
if (callbacks) {
|
|
this.onData = callbacks.onData;
|
|
this.onMeta = callbacks.onMeta;
|
|
this.onPres = callbacks.onPres;
|
|
this.onInfo = callbacks.onInfo;
|
|
this.onMetaDesc = callbacks.onMetaDesc;
|
|
this.onMetaSub = callbacks.onMetaSub;
|
|
this.onSubsUpdated = callbacks.onSubsUpdated;
|
|
this.onTagsUpdated = callbacks.onTagsUpdated;
|
|
this.onCredsUpdated = callbacks.onCredsUpdated;
|
|
this.onDeleteTopic = callbacks.onDeleteTopic;
|
|
this.onAllMessagesReceived = callbacks.onAllMessagesReceived;
|
|
}
|
|
}
|
|
|
|
static topicType(name) {
|
|
const types = {
|
|
'me': Const.TOPIC_ME,
|
|
'fnd': Const.TOPIC_FND,
|
|
'grp': Const.TOPIC_GRP,
|
|
'new': Const.TOPIC_GRP,
|
|
'nch': Const.TOPIC_GRP,
|
|
'chn': Const.TOPIC_GRP,
|
|
'usr': Const.TOPIC_P2P,
|
|
'sys': Const.TOPIC_SYS
|
|
};
|
|
return types[typeof name == 'string' ? name.substring(0, 3) : 'xxx'];
|
|
}
|
|
|
|
static isMeTopicName(name) {
|
|
return Topic.topicType(name) == Const.TOPIC_ME;
|
|
}
|
|
|
|
static isGroupTopicName(name) {
|
|
return Topic.topicType(name) == Const.TOPIC_GRP;
|
|
}
|
|
|
|
static isP2PTopicName(name) {
|
|
return Topic.topicType(name) == Const.TOPIC_P2P;
|
|
}
|
|
|
|
static isCommTopicName(name) {
|
|
return Topic.isP2PTopicName(name) || Topic.isGroupTopicName(name);
|
|
}
|
|
|
|
static isNewGroupTopicName(name) {
|
|
return typeof name == 'string' && (name.substring(0, 3) == Const.TOPIC_NEW || name.substring(0, 3) == Const.TOPIC_NEW_CHAN);
|
|
}
|
|
|
|
static isChannelTopicName(name) {
|
|
return typeof name == 'string' && (name.substring(0, 3) == Const.TOPIC_CHAN || name.substring(0, 3) == Const.TOPIC_NEW_CHAN);
|
|
}
|
|
|
|
isSubscribed() {
|
|
return this._attached;
|
|
}
|
|
|
|
subscribe(getParams, setParams) {
|
|
clearTimeout(this._delayedLeaveTimer);
|
|
this._delayedLeaveTimer = null;
|
|
|
|
if (this._attached) {
|
|
return Promise.resolve(this);
|
|
}
|
|
|
|
if (this._deleted) {
|
|
return Promise.reject(new Error("Conversation deleted"));
|
|
}
|
|
|
|
return this._tinode.subscribe(this.name || Const.TOPIC_NEW, getParams, setParams).then(ctrl => {
|
|
if (ctrl.code >= 300) {
|
|
return ctrl;
|
|
}
|
|
|
|
this._attached = true;
|
|
this._deleted = false;
|
|
this.acs = ctrl.params && ctrl.params.acs ? ctrl.params.acs : this.acs;
|
|
|
|
if (this._new) {
|
|
delete this._new;
|
|
|
|
if (this.name != ctrl.topic) {
|
|
this._cacheDelSelf();
|
|
|
|
this.name = ctrl.topic;
|
|
}
|
|
|
|
this._cachePutSelf();
|
|
|
|
this.created = ctrl.ts;
|
|
this.updated = ctrl.ts;
|
|
|
|
if (this.name != Const.TOPIC_ME && this.name != Const.TOPIC_FND) {
|
|
const me = this._tinode.getMeTopic();
|
|
|
|
if (me.onMetaSub) {
|
|
me.onMetaSub(this);
|
|
}
|
|
|
|
if (me.onSubsUpdated) {
|
|
me.onSubsUpdated([this.name], 1);
|
|
}
|
|
}
|
|
|
|
if (setParams && setParams.desc) {
|
|
setParams.desc._noForwarding = true;
|
|
|
|
this._processMetaDesc(setParams.desc);
|
|
}
|
|
}
|
|
|
|
return ctrl;
|
|
});
|
|
}
|
|
|
|
createMessage(data, noEcho) {
|
|
return this._tinode.createMessage(this.name, data, noEcho);
|
|
}
|
|
|
|
publish(data, noEcho) {
|
|
return this.publishMessage(this.createMessage(data, noEcho));
|
|
}
|
|
|
|
publishMessage(pub) {
|
|
if (!this._attached) {
|
|
return Promise.reject(new Error("Cannot publish on inactive topic"));
|
|
}
|
|
|
|
if (this._sending) {
|
|
return Promise.reject(new Error("The message is already being sent"));
|
|
}
|
|
|
|
pub._sending = true;
|
|
pub._failed = false;
|
|
let attachments = null;
|
|
|
|
if (_drafty.default.hasEntities(pub.content)) {
|
|
attachments = [];
|
|
|
|
_drafty.default.entities(pub.content, data => {
|
|
if (data && data.ref) {
|
|
attachments.push(data.ref);
|
|
}
|
|
});
|
|
|
|
if (attachments.length == 0) {
|
|
attachments = null;
|
|
}
|
|
}
|
|
|
|
return this._tinode.publishMessage(pub, attachments).then(ctrl => {
|
|
pub._sending = false;
|
|
pub.ts = ctrl.ts;
|
|
this.swapMessageId(pub, ctrl.params.seq);
|
|
|
|
this._routeData(pub);
|
|
|
|
return ctrl;
|
|
}).catch(err => {
|
|
this._tinode.logger("WARNING: Message rejected by the server", err);
|
|
|
|
pub._sending = false;
|
|
pub._failed = true;
|
|
|
|
if (this.onData) {
|
|
this.onData();
|
|
}
|
|
});
|
|
}
|
|
|
|
publishDraft(pub, prom) {
|
|
const seq = pub.seq || this._getQueuedSeqId();
|
|
|
|
if (!pub._noForwarding) {
|
|
pub._noForwarding = true;
|
|
pub.seq = seq;
|
|
pub.ts = new Date();
|
|
pub.from = this._tinode.getCurrentUserID();
|
|
pub.noecho = true;
|
|
|
|
this._messages.put(pub);
|
|
|
|
this._tinode._db.addMessage(pub);
|
|
|
|
if (this.onData) {
|
|
this.onData(pub);
|
|
}
|
|
}
|
|
|
|
return (prom || Promise.resolve()).then(_ => {
|
|
if (pub._cancelled) {
|
|
return {
|
|
code: 300,
|
|
text: "cancelled"
|
|
};
|
|
}
|
|
|
|
return this.publishMessage(pub);
|
|
}).catch(err => {
|
|
this._tinode.logger("WARNING: Message draft rejected", err);
|
|
|
|
pub._sending = false;
|
|
pub._failed = true;
|
|
|
|
if (this.onData) {
|
|
this.onData();
|
|
}
|
|
|
|
throw err;
|
|
});
|
|
}
|
|
|
|
leave(unsub) {
|
|
if (!this._attached && !unsub) {
|
|
return Promise.reject(new Error("Cannot leave inactive topic"));
|
|
}
|
|
|
|
return this._tinode.leave(this.name, unsub).then(ctrl => {
|
|
this._resetSub();
|
|
|
|
if (unsub) {
|
|
this._gone();
|
|
}
|
|
|
|
return ctrl;
|
|
});
|
|
}
|
|
|
|
leaveDelayed(unsub, delay) {
|
|
clearTimeout(this._delayedLeaveTimer);
|
|
this._delayedLeaveTimer = setTimeout(_ => {
|
|
this._delayedLeaveTimer = null;
|
|
this.leave(unsub);
|
|
}, delay);
|
|
}
|
|
|
|
getMeta(params) {
|
|
return this._tinode.getMeta(this.name, params);
|
|
}
|
|
|
|
getMessagesPage(limit, forward) {
|
|
let query = forward ? this.startMetaQuery().withLaterData(limit) : this.startMetaQuery().withEarlierData(limit);
|
|
return this._loadMessages(this._tinode._db, query.extract('data')).then(count => {
|
|
if (count == limit) {
|
|
return Promise.resolve({
|
|
topic: this.name,
|
|
code: 200,
|
|
params: {
|
|
count: count
|
|
}
|
|
});
|
|
}
|
|
|
|
limit -= count;
|
|
query = forward ? this.startMetaQuery().withLaterData(limit) : this.startMetaQuery().withEarlierData(limit);
|
|
let promise = this.getMeta(query.build());
|
|
|
|
if (!forward) {
|
|
promise = promise.then(ctrl => {
|
|
if (ctrl && ctrl.params && !ctrl.params.count) {
|
|
this._noEarlierMsgs = true;
|
|
}
|
|
});
|
|
}
|
|
|
|
return promise;
|
|
});
|
|
}
|
|
|
|
setMeta(params) {
|
|
if (params.tags) {
|
|
params.tags = (0, _utils.normalizeArray)(params.tags);
|
|
}
|
|
|
|
return this._tinode.setMeta(this.name, params).then(ctrl => {
|
|
if (ctrl && ctrl.code >= 300) {
|
|
return ctrl;
|
|
}
|
|
|
|
if (params.sub) {
|
|
params.sub.topic = this.name;
|
|
|
|
if (ctrl.params && ctrl.params.acs) {
|
|
params.sub.acs = ctrl.params.acs;
|
|
params.sub.updated = ctrl.ts;
|
|
}
|
|
|
|
if (!params.sub.user) {
|
|
params.sub.user = this._tinode.getCurrentUserID();
|
|
|
|
if (!params.desc) {
|
|
params.desc = {};
|
|
}
|
|
}
|
|
|
|
params.sub._noForwarding = true;
|
|
|
|
this._processMetaSub([params.sub]);
|
|
}
|
|
|
|
if (params.desc) {
|
|
if (ctrl.params && ctrl.params.acs) {
|
|
params.desc.acs = ctrl.params.acs;
|
|
params.desc.updated = ctrl.ts;
|
|
}
|
|
|
|
this._processMetaDesc(params.desc);
|
|
}
|
|
|
|
if (params.tags) {
|
|
this._processMetaTags(params.tags);
|
|
}
|
|
|
|
if (params.cred) {
|
|
this._processMetaCreds([params.cred], true);
|
|
}
|
|
|
|
return ctrl;
|
|
});
|
|
}
|
|
|
|
updateMode(uid, update) {
|
|
const user = uid ? this.subscriber(uid) : null;
|
|
const am = user ? user.acs.updateGiven(update).getGiven() : this.getAccessMode().updateWant(update).getWant();
|
|
return this.setMeta({
|
|
sub: {
|
|
user: uid,
|
|
mode: am
|
|
}
|
|
});
|
|
}
|
|
|
|
invite(uid, mode) {
|
|
return this.setMeta({
|
|
sub: {
|
|
user: uid,
|
|
mode: mode
|
|
}
|
|
});
|
|
}
|
|
|
|
archive(arch) {
|
|
if (this.private && !this.private.arch == !arch) {
|
|
return Promise.resolve(arch);
|
|
}
|
|
|
|
return this.setMeta({
|
|
desc: {
|
|
private: {
|
|
arch: arch ? true : Const.DEL_CHAR
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
delMessages(ranges, hard) {
|
|
if (!this._attached) {
|
|
return Promise.reject(new Error("Cannot delete messages in inactive topic"));
|
|
}
|
|
|
|
ranges.sort((r1, r2) => {
|
|
if (r1.low < r2.low) {
|
|
return true;
|
|
}
|
|
|
|
if (r1.low == r2.low) {
|
|
return !r2.hi || r1.hi >= r2.hi;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
let tosend = ranges.reduce((out, r) => {
|
|
if (r.low < Const.LOCAL_SEQID) {
|
|
if (!r.hi || r.hi < Const.LOCAL_SEQID) {
|
|
out.push(r);
|
|
} else {
|
|
out.push({
|
|
low: r.low,
|
|
hi: this._maxSeq + 1
|
|
});
|
|
}
|
|
}
|
|
|
|
return out;
|
|
}, []);
|
|
let result;
|
|
|
|
if (tosend.length > 0) {
|
|
result = this._tinode.delMessages(this.name, tosend, hard);
|
|
} else {
|
|
result = Promise.resolve({
|
|
params: {
|
|
del: 0
|
|
}
|
|
});
|
|
}
|
|
|
|
return result.then(ctrl => {
|
|
if (ctrl.params.del > this._maxDel) {
|
|
this._maxDel = ctrl.params.del;
|
|
}
|
|
|
|
ranges.forEach(r => {
|
|
if (r.hi) {
|
|
this.flushMessageRange(r.low, r.hi);
|
|
} else {
|
|
this.flushMessage(r.low);
|
|
}
|
|
});
|
|
|
|
this._updateDeletedRanges();
|
|
|
|
if (this.onData) {
|
|
this.onData();
|
|
}
|
|
|
|
return ctrl;
|
|
});
|
|
}
|
|
|
|
delMessagesAll(hardDel) {
|
|
if (!this._maxSeq || this._maxSeq <= 0) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
return this.delMessages([{
|
|
low: 1,
|
|
hi: this._maxSeq + 1,
|
|
_all: true
|
|
}], hardDel);
|
|
}
|
|
|
|
delMessagesList(list, hardDel) {
|
|
list.sort((a, b) => a - b);
|
|
let ranges = list.reduce((out, id) => {
|
|
if (out.length == 0) {
|
|
out.push({
|
|
low: id
|
|
});
|
|
} else {
|
|
let prev = out[out.length - 1];
|
|
|
|
if (!prev.hi && id != prev.low + 1 || id > prev.hi) {
|
|
out.push({
|
|
low: id
|
|
});
|
|
} else {
|
|
prev.hi = prev.hi ? Math.max(prev.hi, id + 1) : id + 1;
|
|
}
|
|
}
|
|
|
|
return out;
|
|
}, []);
|
|
return this.delMessages(ranges, hardDel);
|
|
}
|
|
|
|
delTopic(hard) {
|
|
if (this._deleted) {
|
|
this._gone();
|
|
|
|
return Promise.resolve(null);
|
|
}
|
|
|
|
return this._tinode.delTopic(this.name, hard).then(ctrl => {
|
|
this._deleted = true;
|
|
|
|
this._resetSub();
|
|
|
|
this._gone();
|
|
|
|
return ctrl;
|
|
});
|
|
}
|
|
|
|
delSubscription(user) {
|
|
if (!this._attached) {
|
|
return Promise.reject(new Error("Cannot delete subscription in inactive topic"));
|
|
}
|
|
|
|
return this._tinode.delSubscription(this.name, user).then(ctrl => {
|
|
delete this._users[user];
|
|
|
|
if (this.onSubsUpdated) {
|
|
this.onSubsUpdated(Object.keys(this._users));
|
|
}
|
|
|
|
return ctrl;
|
|
});
|
|
}
|
|
|
|
note(what, seq) {
|
|
if (!this._attached) {
|
|
return;
|
|
}
|
|
|
|
const user = this._users[this._tinode.getCurrentUserID()];
|
|
|
|
let update = false;
|
|
|
|
if (user) {
|
|
if (!user[what] || user[what] < seq) {
|
|
user[what] = seq;
|
|
update = true;
|
|
}
|
|
} else {
|
|
update = (this[what] | 0) < seq;
|
|
}
|
|
|
|
if (update) {
|
|
this._tinode.note(this.name, what, seq);
|
|
|
|
this._updateReadRecv(what, seq);
|
|
|
|
if (this.acs != null && !this.acs.isMuted()) {
|
|
const me = this._tinode.getMeTopic();
|
|
|
|
me._refreshContact(what, this);
|
|
}
|
|
}
|
|
}
|
|
|
|
noteRecv(seq) {
|
|
this.note('recv', seq);
|
|
}
|
|
|
|
noteRead(seq) {
|
|
seq = seq || this._maxSeq;
|
|
|
|
if (seq > 0) {
|
|
this.note('read', seq);
|
|
}
|
|
}
|
|
|
|
noteKeyPress() {
|
|
if (this._attached) {
|
|
this._tinode.noteKeyPress(this.name);
|
|
} else {
|
|
this._tinode.logger("INFO: Cannot send notification in inactive topic");
|
|
}
|
|
}
|
|
|
|
videoCall(evt, seq, payload) {
|
|
if (!this._attached && !['ringing', 'hang-up'].includes(evt)) {
|
|
return;
|
|
}
|
|
|
|
return this._tinode.videoCall(this.name, seq, evt, payload);
|
|
}
|
|
|
|
_updateReadRecv(what, seq, ts) {
|
|
let oldVal,
|
|
doUpdate = false;
|
|
seq = seq | 0;
|
|
this.seq = this.seq | 0;
|
|
this.read = this.read | 0;
|
|
this.recv = this.recv | 0;
|
|
|
|
switch (what) {
|
|
case 'recv':
|
|
oldVal = this.recv;
|
|
this.recv = Math.max(this.recv, seq);
|
|
doUpdate = oldVal != this.recv;
|
|
break;
|
|
|
|
case 'read':
|
|
oldVal = this.read;
|
|
this.read = Math.max(this.read, seq);
|
|
doUpdate = oldVal != this.read;
|
|
break;
|
|
|
|
case 'msg':
|
|
oldVal = this.seq;
|
|
this.seq = Math.max(this.seq, seq);
|
|
|
|
if (!this.touched || this.touched < ts) {
|
|
this.touched = ts;
|
|
}
|
|
|
|
doUpdate = oldVal != this.seq;
|
|
break;
|
|
}
|
|
|
|
if (this.recv < this.read) {
|
|
this.recv = this.read;
|
|
doUpdate = true;
|
|
}
|
|
|
|
if (this.seq < this.recv) {
|
|
this.seq = this.recv;
|
|
|
|
if (!this.touched || this.touched < ts) {
|
|
this.touched = ts;
|
|
}
|
|
|
|
doUpdate = true;
|
|
}
|
|
|
|
this.unread = this.seq - this.read;
|
|
return doUpdate;
|
|
}
|
|
|
|
userDesc(uid) {
|
|
const user = this._cacheGetUser(uid);
|
|
|
|
if (user) {
|
|
return user;
|
|
}
|
|
}
|
|
|
|
p2pPeerDesc() {
|
|
if (!this.isP2PType()) {
|
|
return undefined;
|
|
}
|
|
|
|
return this._users[this.name];
|
|
}
|
|
|
|
subscribers(callback, context) {
|
|
const cb = callback || this.onMetaSub;
|
|
|
|
if (cb) {
|
|
for (let idx in this._users) {
|
|
cb.call(context, this._users[idx], idx, this._users);
|
|
}
|
|
}
|
|
}
|
|
|
|
tags() {
|
|
return this._tags.slice(0);
|
|
}
|
|
|
|
subscriber(uid) {
|
|
return this._users[uid];
|
|
}
|
|
|
|
messageVersions(message, callback, context) {
|
|
if (!callback) {
|
|
return;
|
|
}
|
|
|
|
const origSeq = this._isReplacementMsg(message) ? parseInt(message.head.replace.split(':')[1]) : message.seq;
|
|
const versions = this._messageVersions[origSeq];
|
|
|
|
if (!versions) {
|
|
return;
|
|
}
|
|
|
|
versions.forEach(callback, undefined, undefined, context);
|
|
}
|
|
|
|
messages(callback, sinceId, beforeId, context) {
|
|
const cb = callback || this.onData;
|
|
|
|
if (cb) {
|
|
const startIdx = typeof sinceId == 'number' ? this._messages.find({
|
|
seq: sinceId
|
|
}, true) : undefined;
|
|
const beforeIdx = typeof beforeId == 'number' ? this._messages.find({
|
|
seq: beforeId
|
|
}, true) : undefined;
|
|
|
|
if (startIdx != -1 && beforeIdx != -1) {
|
|
let msgs = [];
|
|
|
|
this._messages.forEach((msg, unused1, unused2, i) => {
|
|
if (this._isReplacementMsg(msg)) {
|
|
return;
|
|
}
|
|
|
|
msgs.push({
|
|
data: this.latestMsgVersion(msg.seq) || msg,
|
|
idx: i
|
|
});
|
|
}, startIdx, beforeIdx, {});
|
|
|
|
msgs.forEach((val, i) => {
|
|
cb.call(context, val.data, i > 0 ? msgs[i - 1].data : undefined, i < msgs.length - 1 ? msgs[i + 1].data : undefined, val.idx);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
findMessage(seq) {
|
|
const idx = this._messages.find({
|
|
seq: seq
|
|
});
|
|
|
|
if (idx >= 0) {
|
|
return this._messages.getAt(idx);
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
latestMessage(skipDeleted) {
|
|
const msg = this._messages.getLast();
|
|
|
|
if (!skipDeleted || !msg || msg._status != Const.MESSAGE_STATUS_DEL_RANGE) {
|
|
return msg;
|
|
}
|
|
|
|
return this._messages.getLast(1);
|
|
}
|
|
|
|
latestMsgVersion(seq) {
|
|
const versions = this._messageVersions[seq];
|
|
return versions ? versions.getLast() : null;
|
|
}
|
|
|
|
maxMsgSeq() {
|
|
return this._maxSeq;
|
|
}
|
|
|
|
maxClearId() {
|
|
return this._maxDel;
|
|
}
|
|
|
|
messageCount() {
|
|
return this._messages.length();
|
|
}
|
|
|
|
queuedMessages(callback, context) {
|
|
if (!callback) {
|
|
throw new Error("Callback must be provided");
|
|
}
|
|
|
|
this.messages(callback, Const.LOCAL_SEQID, undefined, context);
|
|
}
|
|
|
|
msgReceiptCount(what, seq) {
|
|
let count = 0;
|
|
|
|
if (seq > 0) {
|
|
const me = this._tinode.getCurrentUserID();
|
|
|
|
for (let idx in this._users) {
|
|
const user = this._users[idx];
|
|
|
|
if (user.user !== me && user[what] >= seq) {
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
msgReadCount(seq) {
|
|
return this.msgReceiptCount('read', seq);
|
|
}
|
|
|
|
msgRecvCount(seq) {
|
|
return this.msgReceiptCount('recv', seq);
|
|
}
|
|
|
|
msgHasMoreMessages(newer) {
|
|
return newer ? this.seq > this._maxSeq : this._minSeq > 1 && !this._noEarlierMsgs;
|
|
}
|
|
|
|
isNewMessage(seqId) {
|
|
return this._maxSeq <= seqId;
|
|
}
|
|
|
|
flushMessage(seqId) {
|
|
const idx = this._messages.find({
|
|
seq: seqId
|
|
});
|
|
|
|
if (idx >= 0) {
|
|
this._tinode._db.remMessages(this.name, seqId);
|
|
|
|
return this._messages.delAt(idx);
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
swapMessageId(pub, newSeqId) {
|
|
const idx = this._messages.find(pub);
|
|
|
|
const numMessages = this._messages.length();
|
|
|
|
if (0 <= idx && idx < numMessages) {
|
|
this._messages.delAt(idx);
|
|
|
|
this._tinode._db.remMessages(this.name, pub.seq);
|
|
|
|
pub.seq = newSeqId;
|
|
|
|
this._messages.put(pub);
|
|
|
|
this._tinode._db.addMessage(pub);
|
|
}
|
|
}
|
|
|
|
flushMessageRange(fromId, untilId) {
|
|
this._tinode._db.remMessages(this.name, fromId, untilId);
|
|
|
|
const since = this._messages.find({
|
|
seq: fromId
|
|
}, true);
|
|
|
|
return since >= 0 ? this._messages.delRange(since, this._messages.find({
|
|
seq: untilId
|
|
}, true)) : [];
|
|
}
|
|
|
|
cancelSend(seqId) {
|
|
const idx = this._messages.find({
|
|
seq: seqId
|
|
});
|
|
|
|
if (idx >= 0) {
|
|
const msg = this._messages.getAt(idx);
|
|
|
|
const status = this.msgStatus(msg);
|
|
|
|
if (status == Const.MESSAGE_STATUS_QUEUED || status == Const.MESSAGE_STATUS_FAILED) {
|
|
this._tinode._db.remMessages(this.name, seqId);
|
|
|
|
msg._cancelled = true;
|
|
|
|
this._messages.delAt(idx);
|
|
|
|
if (this.onData) {
|
|
this.onData();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
getType() {
|
|
return Topic.topicType(this.name);
|
|
}
|
|
|
|
getAccessMode() {
|
|
return this.acs;
|
|
}
|
|
|
|
setAccessMode(acs) {
|
|
return this.acs = new _accessMode.default(acs);
|
|
}
|
|
|
|
getDefaultAccess() {
|
|
return this.defacs;
|
|
}
|
|
|
|
startMetaQuery() {
|
|
return new _metaBuilder.default(this);
|
|
}
|
|
|
|
isArchived() {
|
|
return this.private && !!this.private.arch;
|
|
}
|
|
|
|
isMeType() {
|
|
return Topic.isMeTopicName(this.name);
|
|
}
|
|
|
|
isChannelType() {
|
|
return Topic.isChannelTopicName(this.name);
|
|
}
|
|
|
|
isGroupType() {
|
|
return Topic.isGroupTopicName(this.name);
|
|
}
|
|
|
|
isP2PType() {
|
|
return Topic.isP2PTopicName(this.name);
|
|
}
|
|
|
|
isCommType() {
|
|
return Topic.isCommTopicName(this.name);
|
|
}
|
|
|
|
msgStatus(msg, upd) {
|
|
let status = Const.MESSAGE_STATUS_NONE;
|
|
|
|
if (this._tinode.isMe(msg.from)) {
|
|
if (msg._sending) {
|
|
status = Const.MESSAGE_STATUS_SENDING;
|
|
} else if (msg._failed || msg._cancelled) {
|
|
status = Const.MESSAGE_STATUS_FAILED;
|
|
} else if (msg.seq >= Const.LOCAL_SEQID) {
|
|
status = Const.MESSAGE_STATUS_QUEUED;
|
|
} else if (this.msgReadCount(msg.seq) > 0) {
|
|
status = Const.MESSAGE_STATUS_READ;
|
|
} else if (this.msgRecvCount(msg.seq) > 0) {
|
|
status = Const.MESSAGE_STATUS_RECEIVED;
|
|
} else if (msg.seq > 0) {
|
|
status = Const.MESSAGE_STATUS_SENT;
|
|
}
|
|
} else if (msg._status == Const.MESSAGE_STATUS_DEL_RANGE) {
|
|
status == Const.MESSAGE_STATUS_DEL_RANGE;
|
|
} else {
|
|
status = Const.MESSAGE_STATUS_TO_ME;
|
|
}
|
|
|
|
if (upd && msg._status != status) {
|
|
msg._status = status;
|
|
|
|
this._tinode._db.updMessageStatus(this.name, msg.seq, status);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
_isReplacementMsg(pub) {
|
|
return pub.head && pub.head.replace;
|
|
}
|
|
|
|
_maybeUpdateMessageVersionsCache(msg) {
|
|
if (!this._isReplacementMsg(msg)) {
|
|
return;
|
|
}
|
|
|
|
const targetSeq = parseInt(msg.head.replace.split(':')[1]);
|
|
|
|
if (targetSeq > msg.seq) {
|
|
return false;
|
|
}
|
|
|
|
let versions = this._messageVersions[targetSeq] || new _cbuffer.default((a, b) => {
|
|
return a.seq - b.seq;
|
|
}, true);
|
|
versions.put(msg);
|
|
this._messageVersions[targetSeq] = versions;
|
|
}
|
|
|
|
_routeData(data) {
|
|
if (data.content) {
|
|
if (!this.touched || this.touched < data.ts) {
|
|
this.touched = data.ts;
|
|
|
|
this._tinode._db.updTopic(this);
|
|
}
|
|
}
|
|
|
|
if (data.seq > this._maxSeq) {
|
|
this._maxSeq = data.seq;
|
|
this.msgStatus(data, true);
|
|
clearTimeout(this._recvNotificationTimer);
|
|
this._recvNotificationTimer = setTimeout(_ => {
|
|
this._recvNotificationTimer = null;
|
|
this.noteRecv(this._maxSeq);
|
|
}, Const.RECV_TIMEOUT);
|
|
}
|
|
|
|
if (data.seq < this._minSeq || this._minSeq == 0) {
|
|
this._minSeq = data.seq;
|
|
}
|
|
|
|
const outgoing = !this.isChannelType() && !data.from || this._tinode.isMe(data.from);
|
|
|
|
if (data.head && data.head.webrtc && data.head.mime == _drafty.default.getContentType() && data.content) {
|
|
data.content = _drafty.default.updateVideoEnt(data.content, {
|
|
state: data.head.webrtc,
|
|
duration: data.head['webrtc-duration'],
|
|
incoming: !outgoing
|
|
});
|
|
}
|
|
|
|
if (!data._noForwarding) {
|
|
this._messages.put(data);
|
|
|
|
this._tinode._db.addMessage(data);
|
|
|
|
this._maybeUpdateMessageVersionsCache(data);
|
|
|
|
this._updateDeletedRanges();
|
|
}
|
|
|
|
if (this.onData) {
|
|
this.onData(data);
|
|
}
|
|
|
|
const what = outgoing ? 'read' : 'msg';
|
|
|
|
this._updateReadRecv(what, data.seq, data.ts);
|
|
|
|
this._tinode.getMeTopic()._refreshContact(what, this);
|
|
}
|
|
|
|
_routeMeta(meta) {
|
|
if (meta.desc) {
|
|
this._processMetaDesc(meta.desc);
|
|
}
|
|
|
|
if (meta.sub && meta.sub.length > 0) {
|
|
this._processMetaSub(meta.sub);
|
|
}
|
|
|
|
if (meta.del) {
|
|
this._processDelMessages(meta.del.clear, meta.del.delseq);
|
|
}
|
|
|
|
if (meta.tags) {
|
|
this._processMetaTags(meta.tags);
|
|
}
|
|
|
|
if (meta.cred) {
|
|
this._processMetaCreds(meta.cred);
|
|
}
|
|
|
|
if (this.onMeta) {
|
|
this.onMeta(meta);
|
|
}
|
|
}
|
|
|
|
_routePres(pres) {
|
|
let user, uid;
|
|
|
|
switch (pres.what) {
|
|
case 'del':
|
|
this._processDelMessages(pres.clear, pres.delseq);
|
|
|
|
break;
|
|
|
|
case 'on':
|
|
case 'off':
|
|
user = this._users[pres.src];
|
|
|
|
if (user) {
|
|
user.online = pres.what == 'on';
|
|
} else {
|
|
this._tinode.logger("WARNING: Presence update for an unknown user", this.name, pres.src);
|
|
}
|
|
|
|
break;
|
|
|
|
case 'term':
|
|
this._resetSub();
|
|
|
|
break;
|
|
|
|
case 'upd':
|
|
if (pres.src && !this._tinode.isTopicCached(pres.src)) {
|
|
this.getMeta(this.startMetaQuery().withLaterOneSub(pres.src).build());
|
|
}
|
|
|
|
break;
|
|
|
|
case 'acs':
|
|
uid = pres.src || this._tinode.getCurrentUserID();
|
|
user = this._users[uid];
|
|
|
|
if (!user) {
|
|
const acs = new _accessMode.default().updateAll(pres.dacs);
|
|
|
|
if (acs && acs.mode != _accessMode.default._NONE) {
|
|
user = this._cacheGetUser(uid);
|
|
|
|
if (!user) {
|
|
user = {
|
|
user: uid,
|
|
acs: acs
|
|
};
|
|
this.getMeta(this.startMetaQuery().withOneSub(undefined, uid).build());
|
|
} else {
|
|
user.acs = acs;
|
|
}
|
|
|
|
user.updated = new Date();
|
|
|
|
this._processMetaSub([user]);
|
|
}
|
|
} else {
|
|
user.acs.updateAll(pres.dacs);
|
|
|
|
this._processMetaSub([{
|
|
user: uid,
|
|
updated: new Date(),
|
|
acs: user.acs
|
|
}]);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
this._tinode.logger("INFO: Ignored presence update", pres.what);
|
|
|
|
}
|
|
|
|
if (this.onPres) {
|
|
this.onPres(pres);
|
|
}
|
|
}
|
|
|
|
_routeInfo(info) {
|
|
if (info.what !== 'kp') {
|
|
const user = this._users[info.from];
|
|
|
|
if (user) {
|
|
user[info.what] = info.seq;
|
|
|
|
if (user.recv < user.read) {
|
|
user.recv = user.read;
|
|
}
|
|
}
|
|
|
|
const msg = this.latestMessage();
|
|
|
|
if (msg) {
|
|
this.msgStatus(msg, true);
|
|
}
|
|
|
|
if (this._tinode.isMe(info.from)) {
|
|
this._updateReadRecv(info.what, info.seq);
|
|
}
|
|
|
|
this._tinode.getMeTopic()._refreshContact(info.what, this);
|
|
}
|
|
|
|
if (this.onInfo) {
|
|
this.onInfo(info);
|
|
}
|
|
}
|
|
|
|
_processMetaDesc(desc) {
|
|
if (this.isP2PType()) {
|
|
delete desc.defacs;
|
|
|
|
this._tinode._db.updUser(this.name, desc.public);
|
|
}
|
|
|
|
(0, _utils.mergeObj)(this, desc);
|
|
|
|
this._tinode._db.updTopic(this);
|
|
|
|
if (this.name !== Const.TOPIC_ME && !desc._noForwarding) {
|
|
const me = this._tinode.getMeTopic();
|
|
|
|
if (me.onMetaSub) {
|
|
me.onMetaSub(this);
|
|
}
|
|
|
|
if (me.onSubsUpdated) {
|
|
me.onSubsUpdated([this.name], 1);
|
|
}
|
|
}
|
|
|
|
if (this.onMetaDesc) {
|
|
this.onMetaDesc(this);
|
|
}
|
|
}
|
|
|
|
_processMetaSub(subs) {
|
|
for (let idx in subs) {
|
|
const sub = subs[idx];
|
|
sub.online = !!sub.online;
|
|
this._lastSubsUpdate = new Date(Math.max(this._lastSubsUpdate, sub.updated));
|
|
let user = null;
|
|
|
|
if (!sub.deleted) {
|
|
if (this._tinode.isMe(sub.user) && sub.acs) {
|
|
this._processMetaDesc({
|
|
updated: sub.updated,
|
|
touched: sub.touched,
|
|
acs: sub.acs
|
|
});
|
|
}
|
|
|
|
user = this._updateCachedUser(sub.user, sub);
|
|
} else {
|
|
delete this._users[sub.user];
|
|
user = sub;
|
|
}
|
|
|
|
if (this.onMetaSub) {
|
|
this.onMetaSub(user);
|
|
}
|
|
}
|
|
|
|
if (this.onSubsUpdated) {
|
|
this.onSubsUpdated(Object.keys(this._users));
|
|
}
|
|
}
|
|
|
|
_processMetaTags(tags) {
|
|
if (tags.length == 1 && tags[0] == Const.DEL_CHAR) {
|
|
tags = [];
|
|
}
|
|
|
|
this._tags = tags;
|
|
|
|
if (this.onTagsUpdated) {
|
|
this.onTagsUpdated(tags);
|
|
}
|
|
}
|
|
|
|
_processMetaCreds(creds) {}
|
|
|
|
_processDelMessages(clear, delseq) {
|
|
this._maxDel = Math.max(clear, this._maxDel);
|
|
this.clear = Math.max(clear, this.clear);
|
|
const topic = this;
|
|
let count = 0;
|
|
|
|
if (Array.isArray(delseq)) {
|
|
delseq.forEach(function (range) {
|
|
if (!range.hi) {
|
|
count++;
|
|
topic.flushMessage(range.low);
|
|
} else {
|
|
for (let i = range.low; i < range.hi; i++) {
|
|
count++;
|
|
topic.flushMessage(i);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
if (count > 0) {
|
|
this._updateDeletedRanges();
|
|
|
|
if (this.onData) {
|
|
this.onData();
|
|
}
|
|
}
|
|
}
|
|
|
|
_allMessagesReceived(count) {
|
|
this._updateDeletedRanges();
|
|
|
|
if (this.onAllMessagesReceived) {
|
|
this.onAllMessagesReceived(count);
|
|
}
|
|
}
|
|
|
|
_resetSub() {
|
|
this._attached = false;
|
|
}
|
|
|
|
_gone() {
|
|
this._messages.reset();
|
|
|
|
this._tinode._db.remMessages(this.name);
|
|
|
|
this._users = {};
|
|
this.acs = new _accessMode.default(null);
|
|
this.private = null;
|
|
this.public = null;
|
|
this.trusted = null;
|
|
this._maxSeq = 0;
|
|
this._minSeq = 0;
|
|
this._attached = false;
|
|
|
|
const me = this._tinode.getMeTopic();
|
|
|
|
if (me) {
|
|
me._routePres({
|
|
_noForwarding: true,
|
|
what: 'gone',
|
|
topic: Const.TOPIC_ME,
|
|
src: this.name
|
|
});
|
|
}
|
|
|
|
if (this.onDeleteTopic) {
|
|
this.onDeleteTopic();
|
|
}
|
|
}
|
|
|
|
_updateCachedUser(uid, obj) {
|
|
let cached = this._cacheGetUser(uid);
|
|
|
|
cached = (0, _utils.mergeObj)(cached || {}, obj);
|
|
|
|
this._cachePutUser(uid, cached);
|
|
|
|
return (0, _utils.mergeToCache)(this._users, uid, cached);
|
|
}
|
|
|
|
_getQueuedSeqId() {
|
|
return this._queuedSeqId++;
|
|
}
|
|
|
|
_updateDeletedRanges() {
|
|
const ranges = [];
|
|
let prev = null;
|
|
|
|
const first = this._messages.getAt(0);
|
|
|
|
if (first && this._minSeq > 1 && !this._noEarlierMsgs) {
|
|
if (first.hi) {
|
|
if (first.seq > 1) {
|
|
first.seq = 1;
|
|
}
|
|
|
|
if (first.hi < this._minSeq - 1) {
|
|
first.hi = this._minSeq - 1;
|
|
}
|
|
|
|
prev = first;
|
|
} else {
|
|
prev = {
|
|
seq: 1,
|
|
hi: this._minSeq - 1
|
|
};
|
|
ranges.push(prev);
|
|
}
|
|
} else {
|
|
prev = {
|
|
seq: 0,
|
|
hi: 0
|
|
};
|
|
}
|
|
|
|
this._messages.filter(data => {
|
|
if (data.seq >= Const.LOCAL_SEQID) {
|
|
return true;
|
|
}
|
|
|
|
if (data.seq == (prev.hi || prev.seq) + 1) {
|
|
if (data.hi && prev.hi) {
|
|
prev.hi = data.hi;
|
|
return false;
|
|
}
|
|
|
|
prev = data;
|
|
return true;
|
|
}
|
|
|
|
if (prev.hi) {
|
|
prev.hi = data.hi || data.seq;
|
|
} else {
|
|
prev = {
|
|
seq: prev.seq + 1,
|
|
hi: data.hi || data.seq
|
|
};
|
|
ranges.push(prev);
|
|
}
|
|
|
|
if (!data.hi) {
|
|
prev = data;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
const last = this._messages.getLast();
|
|
|
|
const maxSeq = Math.max(this.seq, this._maxSeq) || 0;
|
|
|
|
if (maxSeq > 0 && !last || last && (last.hi || last.seq) < maxSeq) {
|
|
if (last && last.hi) {
|
|
last.hi = maxSeq;
|
|
} else {
|
|
ranges.push({
|
|
seq: last ? last.seq + 1 : 1,
|
|
hi: maxSeq
|
|
});
|
|
}
|
|
}
|
|
|
|
ranges.forEach(gap => {
|
|
gap._status = Const.MESSAGE_STATUS_DEL_RANGE;
|
|
|
|
this._messages.put(gap);
|
|
});
|
|
}
|
|
|
|
_loadMessages(db, params) {
|
|
const {
|
|
since,
|
|
before,
|
|
limit
|
|
} = params || {};
|
|
return db.readMessages(this.name, {
|
|
since: since,
|
|
before: before,
|
|
limit: limit || Const.DEFAULT_MESSAGES_PAGE
|
|
}).then(msgs => {
|
|
msgs.forEach(data => {
|
|
if (data.seq > this._maxSeq) {
|
|
this._maxSeq = data.seq;
|
|
}
|
|
|
|
if (data.seq < this._minSeq || this._minSeq == 0) {
|
|
this._minSeq = data.seq;
|
|
}
|
|
|
|
this._messages.put(data);
|
|
|
|
this._maybeUpdateMessageVersionsCache(data);
|
|
});
|
|
|
|
if (msgs.length > 0) {
|
|
this._updateDeletedRanges();
|
|
}
|
|
|
|
return msgs.length;
|
|
});
|
|
}
|
|
|
|
_updateReceived(seq, act) {
|
|
this.touched = new Date();
|
|
this.seq = seq | 0;
|
|
|
|
if (!act || this._tinode.isMe(act)) {
|
|
this.read = this.read ? Math.max(this.read, this.seq) : this.seq;
|
|
this.recv = this.recv ? Math.max(this.read, this.recv) : this.read;
|
|
}
|
|
|
|
this.unread = this.seq - (this.read | 0);
|
|
|
|
this._tinode._db.updTopic(this);
|
|
}
|
|
|
|
}
|
|
|
|
exports.Topic = Topic;
|
|
|
|
class TopicMe extends Topic {
|
|
constructor(callbacks) {
|
|
super(Const.TOPIC_ME, callbacks);
|
|
|
|
_defineProperty(this, "onContactUpdate", void 0);
|
|
|
|
if (callbacks) {
|
|
this.onContactUpdate = callbacks.onContactUpdate;
|
|
}
|
|
}
|
|
|
|
_processMetaDesc(desc) {
|
|
const turnOff = desc.acs && !desc.acs.isPresencer() && this.acs && this.acs.isPresencer();
|
|
(0, _utils.mergeObj)(this, desc);
|
|
|
|
this._tinode._db.updTopic(this);
|
|
|
|
this._updateCachedUser(this._tinode._myUID, desc);
|
|
|
|
if (turnOff) {
|
|
this._tinode.mapTopics(cont => {
|
|
if (cont.online) {
|
|
cont.online = false;
|
|
cont.seen = Object.assign(cont.seen || {}, {
|
|
when: new Date()
|
|
});
|
|
|
|
this._refreshContact('off', cont);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (this.onMetaDesc) {
|
|
this.onMetaDesc(this);
|
|
}
|
|
}
|
|
|
|
_processMetaSub(subs) {
|
|
let updateCount = 0;
|
|
subs.forEach(sub => {
|
|
const topicName = sub.topic;
|
|
|
|
if (topicName == Const.TOPIC_FND || topicName == Const.TOPIC_ME) {
|
|
return;
|
|
}
|
|
|
|
sub.online = !!sub.online;
|
|
let cont = null;
|
|
|
|
if (sub.deleted) {
|
|
cont = sub;
|
|
|
|
this._tinode.cacheRemTopic(topicName);
|
|
|
|
this._tinode._db.remTopic(topicName);
|
|
} else {
|
|
if (typeof sub.seq != 'undefined') {
|
|
sub.seq = sub.seq | 0;
|
|
sub.recv = sub.recv | 0;
|
|
sub.read = sub.read | 0;
|
|
sub.unread = sub.seq - sub.read;
|
|
}
|
|
|
|
const topic = this._tinode.getTopic(topicName);
|
|
|
|
if (topic._new) {
|
|
delete topic._new;
|
|
}
|
|
|
|
cont = (0, _utils.mergeObj)(topic, sub);
|
|
|
|
this._tinode._db.updTopic(cont);
|
|
|
|
if (Topic.isP2PTopicName(topicName)) {
|
|
this._cachePutUser(topicName, cont);
|
|
|
|
this._tinode._db.updUser(topicName, cont.public);
|
|
}
|
|
|
|
if (!sub._noForwarding && topic) {
|
|
sub._noForwarding = true;
|
|
|
|
topic._processMetaDesc(sub);
|
|
}
|
|
}
|
|
|
|
updateCount++;
|
|
|
|
if (this.onMetaSub) {
|
|
this.onMetaSub(cont);
|
|
}
|
|
});
|
|
|
|
if (this.onSubsUpdated && updateCount > 0) {
|
|
const keys = [];
|
|
subs.forEach(s => {
|
|
keys.push(s.topic);
|
|
});
|
|
this.onSubsUpdated(keys, updateCount);
|
|
}
|
|
}
|
|
|
|
_processMetaCreds(creds, upd) {
|
|
if (creds.length == 1 && creds[0] == Const.DEL_CHAR) {
|
|
creds = [];
|
|
}
|
|
|
|
if (upd) {
|
|
creds.forEach(cr => {
|
|
if (cr.val) {
|
|
let idx = this._credentials.findIndex(el => {
|
|
return el.meth == cr.meth && el.val == cr.val;
|
|
});
|
|
|
|
if (idx < 0) {
|
|
if (!cr.done) {
|
|
idx = this._credentials.findIndex(el => {
|
|
return el.meth == cr.meth && !el.done;
|
|
});
|
|
|
|
if (idx >= 0) {
|
|
this._credentials.splice(idx, 1);
|
|
}
|
|
}
|
|
|
|
this._credentials.push(cr);
|
|
} else {
|
|
this._credentials[idx].done = cr.done;
|
|
}
|
|
} else if (cr.resp) {
|
|
const idx = this._credentials.findIndex(el => {
|
|
return el.meth == cr.meth && !el.done;
|
|
});
|
|
|
|
if (idx >= 0) {
|
|
this._credentials[idx].done = true;
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
this._credentials = creds;
|
|
}
|
|
|
|
if (this.onCredsUpdated) {
|
|
this.onCredsUpdated(this._credentials);
|
|
}
|
|
}
|
|
|
|
_routePres(pres) {
|
|
if (pres.what == 'term') {
|
|
this._resetSub();
|
|
|
|
return;
|
|
}
|
|
|
|
if (pres.what == 'upd' && pres.src == Const.TOPIC_ME) {
|
|
this.getMeta(this.startMetaQuery().withDesc().build());
|
|
return;
|
|
}
|
|
|
|
const cont = this._tinode.cacheGetTopic(pres.src);
|
|
|
|
if (cont) {
|
|
switch (pres.what) {
|
|
case 'on':
|
|
cont.online = true;
|
|
break;
|
|
|
|
case 'off':
|
|
if (cont.online) {
|
|
cont.online = false;
|
|
cont.seen = Object.assign(cont.seen || {}, {
|
|
when: new Date()
|
|
});
|
|
}
|
|
|
|
break;
|
|
|
|
case 'msg':
|
|
cont._updateReceived(pres.seq, pres.act);
|
|
|
|
break;
|
|
|
|
case 'upd':
|
|
this.getMeta(this.startMetaQuery().withLaterOneSub(pres.src).build());
|
|
break;
|
|
|
|
case 'acs':
|
|
if (cont.acs) {
|
|
cont.acs.updateAll(pres.dacs);
|
|
} else {
|
|
cont.acs = new _accessMode.default().updateAll(pres.dacs);
|
|
}
|
|
|
|
cont.touched = new Date();
|
|
break;
|
|
|
|
case 'ua':
|
|
cont.seen = {
|
|
when: new Date(),
|
|
ua: pres.ua
|
|
};
|
|
break;
|
|
|
|
case 'recv':
|
|
pres.seq = pres.seq | 0;
|
|
cont.recv = cont.recv ? Math.max(cont.recv, pres.seq) : pres.seq;
|
|
break;
|
|
|
|
case 'read':
|
|
pres.seq = pres.seq | 0;
|
|
cont.read = cont.read ? Math.max(cont.read, pres.seq) : pres.seq;
|
|
cont.recv = cont.recv ? Math.max(cont.read, cont.recv) : cont.recv;
|
|
cont.unread = cont.seq - cont.read;
|
|
break;
|
|
|
|
case 'gone':
|
|
if (!cont._deleted) {
|
|
cont._deleted = true;
|
|
cont._attached = false;
|
|
|
|
this._tinode._db.markTopicAsDeleted(pres.src);
|
|
} else {
|
|
this._tinode._db.remTopic(pres.src);
|
|
}
|
|
|
|
break;
|
|
|
|
case 'del':
|
|
break;
|
|
|
|
default:
|
|
this._tinode.logger("INFO: Unsupported presence update in 'me'", pres.what);
|
|
|
|
}
|
|
|
|
this._refreshContact(pres.what, cont);
|
|
} else {
|
|
if (pres.what == 'acs') {
|
|
const acs = new _accessMode.default(pres.dacs);
|
|
|
|
if (!acs || acs.mode == _accessMode.default._INVALID) {
|
|
this._tinode.logger("ERROR: Invalid access mode update", pres.src, pres.dacs);
|
|
|
|
return;
|
|
} else if (acs.mode == _accessMode.default._NONE) {
|
|
this._tinode.logger("WARNING: Removing non-existent subscription", pres.src, pres.dacs);
|
|
|
|
return;
|
|
} else {
|
|
this.getMeta(this.startMetaQuery().withOneSub(undefined, pres.src).build());
|
|
|
|
const dummy = this._tinode.getTopic(pres.src);
|
|
|
|
dummy.topic = pres.src;
|
|
dummy.online = false;
|
|
dummy.acs = acs;
|
|
|
|
this._tinode._db.updTopic(dummy);
|
|
}
|
|
} else if (pres.what == 'tags') {
|
|
this.getMeta(this.startMetaQuery().withTags().build());
|
|
}
|
|
}
|
|
|
|
if (this.onPres) {
|
|
this.onPres(pres);
|
|
}
|
|
}
|
|
|
|
_refreshContact(what, cont) {
|
|
if (this.onContactUpdate) {
|
|
this.onContactUpdate(what, cont);
|
|
}
|
|
}
|
|
|
|
publish() {
|
|
return Promise.reject(new Error("Publishing to 'me' is not supported"));
|
|
}
|
|
|
|
delCredential(method, value) {
|
|
if (!this._attached) {
|
|
return Promise.reject(new Error("Cannot delete credential in inactive 'me' topic"));
|
|
}
|
|
|
|
return this._tinode.delCredential(method, value).then(ctrl => {
|
|
const index = this._credentials.findIndex(el => {
|
|
return el.meth == method && el.val == value;
|
|
});
|
|
|
|
if (index > -1) {
|
|
this._credentials.splice(index, 1);
|
|
}
|
|
|
|
if (this.onCredsUpdated) {
|
|
this.onCredsUpdated(this._credentials);
|
|
}
|
|
|
|
return ctrl;
|
|
});
|
|
}
|
|
|
|
contacts(callback, filter, context) {
|
|
this._tinode.mapTopics((c, idx) => {
|
|
if (c.isCommType() && (!filter || filter(c))) {
|
|
callback.call(context, c, idx);
|
|
}
|
|
});
|
|
}
|
|
|
|
getContact(name) {
|
|
return this._tinode.cacheGetTopic(name);
|
|
}
|
|
|
|
getAccessMode(name) {
|
|
if (name) {
|
|
const cont = this._tinode.cacheGetTopic(name);
|
|
|
|
return cont ? cont.acs : null;
|
|
}
|
|
|
|
return this.acs;
|
|
}
|
|
|
|
isArchived(name) {
|
|
const cont = this._tinode.cacheGetTopic(name);
|
|
|
|
return cont && cont.private && !!cont.private.arch;
|
|
}
|
|
|
|
getCredentials() {
|
|
return this._credentials;
|
|
}
|
|
|
|
}
|
|
|
|
exports.TopicMe = TopicMe;
|
|
|
|
class TopicFnd extends Topic {
|
|
constructor(callbacks) {
|
|
super(Const.TOPIC_FND, callbacks);
|
|
|
|
_defineProperty(this, "_contacts", {});
|
|
}
|
|
|
|
_processMetaSub(subs) {
|
|
let updateCount = Object.getOwnPropertyNames(this._contacts).length;
|
|
this._contacts = {};
|
|
|
|
for (let idx in subs) {
|
|
let sub = subs[idx];
|
|
const indexBy = sub.topic ? sub.topic : sub.user;
|
|
sub = (0, _utils.mergeToCache)(this._contacts, indexBy, sub);
|
|
updateCount++;
|
|
|
|
if (this.onMetaSub) {
|
|
this.onMetaSub(sub);
|
|
}
|
|
}
|
|
|
|
if (updateCount > 0 && this.onSubsUpdated) {
|
|
this.onSubsUpdated(Object.keys(this._contacts));
|
|
}
|
|
}
|
|
|
|
publish() {
|
|
return Promise.reject(new Error("Publishing to 'fnd' is not supported"));
|
|
}
|
|
|
|
setMeta(params) {
|
|
return Object.getPrototypeOf(TopicFnd.prototype).setMeta.call(this, params).then(() => {
|
|
if (Object.keys(this._contacts).length > 0) {
|
|
this._contacts = {};
|
|
|
|
if (this.onSubsUpdated) {
|
|
this.onSubsUpdated([]);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
contacts(callback, context) {
|
|
const cb = callback || this.onMetaSub;
|
|
|
|
if (cb) {
|
|
for (let idx in this._contacts) {
|
|
cb.call(context, this._contacts[idx], idx, this._contacts);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
exports.TopicFnd = TopicFnd;
|
|
|
|
},{"./access-mode.js":1,"./cbuffer.js":2,"./config.js":3,"./drafty.js":6,"./meta-builder.js":8,"./utils.js":11}],11:[function(require,module,exports){
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.isUrlRelative = isUrlRelative;
|
|
exports.jsonParseHelper = jsonParseHelper;
|
|
exports.mergeObj = mergeObj;
|
|
exports.mergeToCache = mergeToCache;
|
|
exports.normalizeArray = normalizeArray;
|
|
exports.rfc3339DateString = rfc3339DateString;
|
|
exports.simplify = simplify;
|
|
|
|
var _accessMode = _interopRequireDefault(require("./access-mode.js"));
|
|
|
|
var _config = require("./config.js");
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function jsonParseHelper(key, val) {
|
|
if (typeof val == 'string' && val.length >= 20 && val.length <= 24 && ['ts', 'touched', 'updated', 'created', 'when', 'deleted', 'expires'].includes(key)) {
|
|
const date = new Date(val);
|
|
|
|
if (!isNaN(date)) {
|
|
return date;
|
|
}
|
|
} else if (key === 'acs' && typeof val === 'object') {
|
|
return new _accessMode.default(val);
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
function isUrlRelative(url) {
|
|
return url && !/^\s*([a-z][a-z0-9+.-]*:|\/\/)/im.test(url);
|
|
}
|
|
|
|
function isValidDate(d) {
|
|
return d instanceof Date && !isNaN(d) && d.getTime() != 0;
|
|
}
|
|
|
|
function rfc3339DateString(d) {
|
|
if (!isValidDate(d)) {
|
|
return undefined;
|
|
}
|
|
|
|
const pad = function (val, sp) {
|
|
sp = sp || 2;
|
|
return '0'.repeat(sp - ('' + val).length) + val;
|
|
};
|
|
|
|
const millis = d.getUTCMilliseconds();
|
|
return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + (millis ? '.' + pad(millis, 3) : '') + 'Z';
|
|
}
|
|
|
|
function mergeObj(dst, src, ignore) {
|
|
if (typeof src != 'object') {
|
|
if (src === undefined) {
|
|
return dst;
|
|
}
|
|
|
|
if (src === _config.DEL_CHAR) {
|
|
return undefined;
|
|
}
|
|
|
|
return src;
|
|
}
|
|
|
|
if (src === null) {
|
|
return src;
|
|
}
|
|
|
|
if (src instanceof Date && !isNaN(src)) {
|
|
return !dst || !(dst instanceof Date) || isNaN(dst) || dst < src ? src : dst;
|
|
}
|
|
|
|
if (src instanceof _accessMode.default) {
|
|
return new _accessMode.default(src);
|
|
}
|
|
|
|
if (src instanceof Array) {
|
|
return src;
|
|
}
|
|
|
|
if (!dst || dst === _config.DEL_CHAR) {
|
|
dst = src.constructor();
|
|
}
|
|
|
|
for (let prop in src) {
|
|
if (src.hasOwnProperty(prop) && (!ignore || !ignore[prop]) && prop != '_noForwarding') {
|
|
try {
|
|
dst[prop] = mergeObj(dst[prop], src[prop]);
|
|
} catch (err) {}
|
|
}
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
function mergeToCache(cache, key, newval, ignore) {
|
|
cache[key] = mergeObj(cache[key], newval, ignore);
|
|
return cache[key];
|
|
}
|
|
|
|
function simplify(obj) {
|
|
Object.keys(obj).forEach(key => {
|
|
if (key[0] == '_') {
|
|
delete obj[key];
|
|
} else if (!obj[key]) {
|
|
delete obj[key];
|
|
} else if (Array.isArray(obj[key]) && obj[key].length == 0) {
|
|
delete obj[key];
|
|
} else if (!obj[key]) {
|
|
delete obj[key];
|
|
} else if (obj[key] instanceof Date) {
|
|
if (!isValidDate(obj[key])) {
|
|
delete obj[key];
|
|
}
|
|
} else if (typeof obj[key] == 'object') {
|
|
simplify(obj[key]);
|
|
|
|
if (Object.getOwnPropertyNames(obj[key]).length == 0) {
|
|
delete obj[key];
|
|
}
|
|
}
|
|
});
|
|
return obj;
|
|
}
|
|
|
|
;
|
|
|
|
function normalizeArray(arr) {
|
|
let out = [];
|
|
|
|
if (Array.isArray(arr)) {
|
|
for (let i = 0, l = arr.length; i < l; i++) {
|
|
let t = arr[i];
|
|
|
|
if (t) {
|
|
t = t.trim().toLowerCase();
|
|
|
|
if (t.length > 1) {
|
|
out.push(t);
|
|
}
|
|
}
|
|
}
|
|
|
|
out.sort().filter(function (item, pos, ary) {
|
|
return !pos || item != ary[pos - 1];
|
|
});
|
|
}
|
|
|
|
if (out.length == 0) {
|
|
out.push(_config.DEL_CHAR);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
},{"./access-mode.js":1,"./config.js":3}],12:[function(require,module,exports){
|
|
module.exports={"version": "0.20.0-rc2"}
|
|
|
|
},{}]},{},[9])(9)
|
|
});
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYWNjZXNzLW1vZGUuanMiLCJzcmMvY2J1ZmZlci5qcyIsInNyYy9jb25maWcuanMiLCJzcmMvY29ubmVjdGlvbi5qcyIsInNyYy9kYi5qcyIsInNyYy9kcmFmdHkuanMiLCJzcmMvbGFyZ2UtZmlsZS5qcyIsInNyYy9tZXRhLWJ1aWxkZXIuanMiLCJzcmMvdGlub2RlLmpzIiwic3JjL3RvcGljLmpzIiwic3JjL3V0aWxzLmpzIiwidmVyc2lvbi5qc29uIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDS0E7Ozs7Ozs7Ozs7O0FBY2UsTUFBTSxVQUFOLENBQWlCO0VBQzlCLFdBQVcsQ0FBQyxHQUFELEVBQU07SUFDZixJQUFJLEdBQUosRUFBUztNQUNQLEtBQUssS0FBTCxHQUFhLE9BQU8sR0FBRyxDQUFDLEtBQVgsSUFBb0IsUUFBcEIsR0FBK0IsR0FBRyxDQUFDLEtBQW5DLEdBQTJDLFVBQVUsQ0FBQyxNQUFYLENBQWtCLEdBQUcsQ0FBQyxLQUF0QixDQUF4RDtNQUNBLEtBQUssSUFBTCxHQUFZLE9BQU8sR0FBRyxDQUFDLElBQVgsSUFBbUIsUUFBbkIsR0FBOEIsR0FBRyxDQUFDLElBQWxDLEdBQXlDLFVBQVUsQ0FBQyxNQUFYLENBQWtCLEdBQUcsQ0FBQyxJQUF0QixDQUFyRDtNQUNBLEtBQUssSUFBTCxHQUFZLEdBQUcsQ0FBQyxJQUFKLEdBQVksT0FBTyxHQUFHLENBQUMsSUFBWCxJQUFtQixRQUFuQixHQUE4QixHQUFHLENBQUMsSUFBbEMsR0FBeUMsVUFBVSxDQUFDLE1BQVgsQ0FBa0IsR0FBRyxDQUFDLElBQXRCLENBQXJELEdBQ1QsS0FBSyxLQUFMLEdBQWEsS0FBSyxJQURyQjtJQUVEO0VBQ0Y7O0VBaUJZLE9BQU4sTUFBTSxDQUFDLEdBQUQsRUFBTTtJQUNqQixJQUFJLENBQUMsR0FBTCxFQUFVO01BQ1IsT0FBTyxJQUFQO0lBQ0QsQ0FGRCxNQUVPLElB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RjtJQUNGOztJQUNELEdBQUcsQ0FBQyxJQUFKLEdBQVcsTUFBWCxDQUFrQixVQUFTLElBQVQsRUFBZSxHQUFmLEVBQW9CLEdBQXBCLEVBQXlCO01BQ3pDLE9BQU8sQ0FBQyxHQUFELElBQVEsSUFBSSxJQUFJLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBUCxDQUExQjtJQUNELENBRkQ7RUFHRDs7RUFDRCxJQUFJLEdBQUcsQ0FBQyxNQUFKLElBQWMsQ0FBbEIsRUFBcUI7SUFHbkIsR0FBRyxDQUFDLElBQUosQ0FBUyxnQkFBVDtFQUNEOztFQUNELE9BQU8sR0FBUDtBQUNEOzs7QUM1S0Q7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8qKlxuICogQGZpbGUgQWNjZXNzIGNvbnRyb2wgbW9kZWwuXG4gKlxuICogQGNvcHlyaWdodCAyMDE1LTIwMjIgVGlub2RlIExMQy5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBOT1RFIFRPIERFVkVMT1BFUlM6XG4vLyBMb2NhbGl6YWJsZSBzdHJpbmdzIHNob3VsZCBiZSBkb3VibGUgcXVvdGVkIFwi0YHRgtGA0L7QutCwINC90LAg0LTRgNGD0LPQvtC8INGP0LfRi9C60LVcIixcbi8vIG5vbi1sb2NhbGl6YWJsZSBzdHJpbmdzIHNob3VsZCBiZSBzaW5nbGUgcXVvdGVkICdub24tbG9jYWxpemVkJy5cblxuLyoqXG4gKiBIZWxwZXIgY2xhc3MgZm9yIGhhbmRsaW5nIGFjY2VzcyBtb2RlLlxuICpcbiAqIEBjbGFzcyBBY2Nlc3NNb2RlXG4gKiBAbWVtYmVyb2YgVGlub2RlXG4gKlxuICogQHBhcmFtIHtBY2Nlc3NNb2RlfE9iamVjdD19IGFjcyAtIEFjY2Vzc01vZGUgdG8gY29weSBvciBhY2Nlc3MgbW9kZSBvYmplY3QgcmVjZWl2ZWQgZnJvbSB0aGUgc2VydmVyLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBY2Nlc3NNb2RlIHtcbiAgY29uc3RydWN0b3IoYWNzKSB7XG4gICAgaWYgKGFjcykge1xuICAgICAgdGhpcy5naXZlbiA9IHR5cGVvZiBhY3MuZ2l2ZW4gPT0gJ251bWJlcicgPyBhY3MuZ2l2ZW4gOiBBY2Nlc3NNb2RlLmRlY29kZShhY3MuZ2l2ZW4pO1xuICAgICAgdGhpcy53YW50ID0gdHlwZW9mIGFjcy53YW50ID09ICdudW1iZXInID8gYWNzLndhbnQgOiBBY2Nlc3NNb2RlLmRlY29kZShhY3Mud2FudCk7XG4gICAgICB0aGlzLm1vZGUgPSBhY3MubW9kZSA/ICh0eXBlb2YgYWNzLm1vZGUgPT0gJ251bWJlcicgPyBhY3MubW9kZSA6IEFjY2Vzc01vZGUuZGVjb2RlKGFjcy5tb2RlKSkgOlxuICAgICAgICAodGhpcy5naXZlbiAmIHRoaXMud2FudCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljICNjaGVja0ZsYWcodmFsLCBzaWRlLCBmbGFnKSB7XG4gICAgc2lkZSA9IHNpZGUgfHwgJ21vZGUnO1xuICAgIGlmIChbJ2dpdmVuJywgJ3dhbnQnLCAnbW9kZSddLmluY2x1ZGVzKHNpZGUpKSB7XG4gICAgICByZXR1cm4gKCh2YWxbc2lkZV0gJiBmbGFnKSAhPSAwKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIEFjY2Vzc01vZGUgY29tcG9uZW50ICcke3NpZGV9J2ApO1xuICB9XG4gIC8qKlxuICAgKiBQYXJzZSBzdHJpbmcgaW50byBhbiBhY2Nlc3MgbW9kZSB2YWx1ZS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqIEBzdGF0aWNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBOdW1iZXJ9IG1vZGUgLSBlaXRoZXIgYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFjY2VzcyBtb2RlIHRvIHBhcnNlIG9yIGEgc2V0IG9mIGJpdHMgdG8gYXNzaWduLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIEFjY2VzcyBtb2RlIGFzIGEgbnVtZXJpYyB2YWx1ZS5cbiAgICovXG4gIHN0YXRpYyBkZWNvZGUoc3RyKSB7XG4gICAgaWYgKCFzdHIpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHN0ciA9PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHN0ciAmIEFjY2Vzc01vZGUuX0JJVE1BU0s7XG4gICAgfSBlbHNlIGlmIChzdHIgPT09ICdOJyB8fCBzdHIgPT09ICduJykge1xuICAgICAgcmV0dXJuIEFjY2Vzc01vZGUuX05PTkU7XG4gICAgfVxuXG4gICAgY29uc3QgYml0bWFzayA9IHtcbiAgICAgICdKJzogQWNjZXNzTW9kZS5fSk9JTixcbiAgICAgICdSJzogQWNjZXNzTW9kZS5fUkVBRCxcbiAgICAgICdXJzogQWNjZXNzTW9kZS5fV1JJVEUsXG4gICAgICAnUCc6IEFjY2Vzc01vZGUuX1BSRVMsXG4gICAgICAnQSc6IEFjY2Vzc01vZGUuX0FQUFJPVkUsXG4gICAgICAnUyc6IEFjY2Vzc01vZGUuX1NIQVJFLFxuICAgICAgJ0QnOiBBY2Nlc3NNb2RlLl9ERUxFVEUsXG4gICAgICAnTyc6IEFjY2Vzc01vZGUuX09XTkVSXG4gICAgfTtcblxuICAgIGxldCBtMCA9IEFjY2Vzc01vZGUuX05PTkU7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgYml0ID0gYml0bWFza1tzdHIuY2hhckF0KGkpLnRvVXBwZXJDYXNlKCldO1xuICAgICAgaWYgKCFiaXQpIHtcbiAgICAgICAgLy8gVW5yZWNvZ25pemVkIGJpdCwgc2tpcC5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBtMCB8PSBiaXQ7XG4gICAgfVxuICAgIHJldHVybiBtMDtcbiAgfVxuICAvKipcbiAgICogQ29udmVydCBudW1lcmljIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhY2Nlc3MgbW9kZSBpbnRvIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkFjY2Vzc01vZGVcbiAgICogQHN0YXRpY1xuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdmFsIC0gYWNjZXNzIG1vZGUgdmFsdWUgdG8gY29udmVydCB0byBhIHN0cmluZy5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBBY2Nlc3MgbW9kZSBhcyBhIHN0cmluZy5cbiAgICovXG4gIHN0YXRpYyBlbmNvZGUodmFsKSB7XG4gICAgaWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IEFjY2Vzc01vZGUuX0lOVkFMSUQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAodmFsID09PSBBY2Nlc3NNb2RlLl9OT05FKSB7XG4gICAgICByZXR1cm4gJ04nO1xuICAgIH1cblxuICAgIGNvbnN0IGJpdG1hc2sgPSBbJ0onLCAnUicsICdXJywgJ1AnLCAnQScsICdTJywgJ0QnLCAnTyddO1xuICAgIGxldCByZXMgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJpdG1hc2subGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICgodmFsICYgKDEgPDwgaSkpICE9IDApIHtcbiAgICAgICAgcmVzID0gcmVzICsgYml0bWFza1tpXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuICAvKipcbiAgICogVXBkYXRlIG51bWVyaWMgcmVwcmVzZW50YXRpb24gb2YgYWNjZXNzIG1vZGUgd2l0aCB0aGUgbmV3IHZhbHVlLiBUaGUgdmFsdWVcbiAgICogaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6XG4gICAqICAtIGEgc3RyaW5nIHN0YXJ0aW5nIHdpdGggPGNvZGU+JysnPC9jb2RlPiBvciA8Y29kZT4nLSc8L2NvZGU+IHRoZW4gdGhlIGJpdHMgdG8gYWRkIG9yIHJlbW92ZSwgZS5nLiA8Y29kZT4nK1ItVyc8L2NvZGU+IG9yIDxjb2RlPictUFMnPC9jb2RlPi5cbiAgICogIC0gYSBuZXcgdmFsdWUgb2YgYWNjZXNzIG1vZGVcbiAgICpcbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqIEBzdGF0aWNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHZhbCAtIGFjY2VzcyBtb2RlIHZhbHVlIHRvIHVwZGF0ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHVwZCAtIHVwZGF0ZSB0byBhcHBseSB0byB2YWwuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gdXBkYXRlZCBhY2Nlc3MgbW9kZS5cbiAgICovXG4gIHN0YXRpYyB1cGRhdGUodmFsLCB1cGQpIHtcbiAgICBpZiAoIXVwZCB8fCB0eXBlb2YgdXBkICE9ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdmFsO1xuICAgIH1cblxuICAgIGxldCBhY3Rpb24gPSB1cGQuY2hhckF0KDApO1xuICAgIGlmIChhY3Rpb24gPT0gJysnIHx8IGFjdGlvbiA9PSAnLScpIHtcbiAgICAgIGxldCB2YWwwID0gdmFsO1xuICAgICAgLy8gU3BsaXQgZGVsdGEtc3RyaW5nIGxpa2UgJytBQkMtREVGK1onIGludG8gYW4gYXJyYXkgb2YgcGFydHMgaW5jbHVkaW5nICsgYW5kIC0uXG4gICAgICBjb25zdCBwYXJ0cyA9IHVwZC5zcGxpdCgvKFstK10pLyk7XG4gICAgICAvLyBTdGFydGluZyBpdGVyYXRpb24gZnJvbSAxIGJlY2F1c2UgU3RyaW5nLnNwbGl0KCkgY3JlYXRlcyBhbiBhcnJheSB3aXRoIHRoZSBmaXJzdCBlbXB0eSBlbGVtZW50LlxuICAgICAgLy8gSXRlcmF0aW5nIGJ5IDIgYmVjYXVzZSB3ZSBwYXJzZSBwYWlycyArLy0gdGhlbiBkYXRhLlxuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBwYXJ0cy5sZW5ndGggLSAxOyBpICs9IDIpIHtcbiAgICAgICAgYWN0aW9uID0gcGFydHNbaV07XG4gICAgICAgIGNvbnN0IG0wID0gQWNjZXNzTW9kZS5kZWNvZGUocGFydHNbaSArIDFdKTtcbiAgICAgICAgaWYgKG0wID09IEFjY2Vzc01vZGUuX0lOVkFMSUQpIHtcbiAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtMCA9PSBudWxsKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFjdGlvbiA9PT0gJysnKSB7XG4gICAgICAgICAgdmFsMCB8PSBtMDtcbiAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24gPT09ICctJykge1xuICAgICAgICAgIHZhbDAgJj0gfm0wO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB2YWwgPSB2YWwwO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGUgc3RyaW5nIGlzIGFuIGV4cGxpY2l0IG5ldyB2YWx1ZSAnQUJDJyByYXRoZXIgdGhhbiBkZWx0YS5cbiAgICAgIGNvbnN0IHZhbDAgPSBBY2Nlc3NNb2RlLmRlY29kZSh1cGQpO1xuICAgICAgaWYgKHZhbDAgIT0gQWNjZXNzTW9kZS5fSU5WQUxJRCkge1xuICAgICAgICB2YWwgPSB2YWwwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWw7XG4gIH1cbiAgLyoqXG4gICAqIEJpdHMgcHJlc2VudCBpbiBhMSBidXQgbWlzc2luZyBpbiBhMi5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyb2YgVGlub2RlXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyIHwgc3RyaW5nfSBhMSAtIGFjY2VzcyBtb2RlIHRvIHN1YnRyYWN0IGZyb20uXG4gICAqIEBwYXJhbSB7bnVtYmVyIHwgc3RyaW5nfSBhMiAtIGFjY2VzcyBtb2RlIHRvIHN1YnRyYWN0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBhY2Nlc3MgbW9kZSB3aXRoIGJpdHMgcHJlc2VudCBpbiA8Y29kZT5hMTwvY29kZT4gYnV0IG1pc3NpbmcgaW4gPGNvZGU+YTI8L2NvZGU+LlxuICAgKi9cbiAgc3RhdGljIGRpZmYoYTEsIGEyKSB7XG4gICAgYTEgPSBBY2Nlc3NNb2RlLmRlY29kZShhMSk7XG4gICAgYTIgPSBBY2Nlc3NNb2RlLmRlY29kZShhMik7XG5cbiAgICBpZiAoYTEgPT0gQWNjZXNzTW9kZS5fSU5WQUxJRCB8fCBhMiA9PSBBY2Nlc3NNb2RlLl9JTlZBTElEKSB7XG4gICAgICByZXR1cm4gQWNjZXNzTW9kZS5fSU5WQUxJRDtcbiAgICB9XG4gICAgcmV0dXJuIGExICYgfmEyO1xuICB9XG4gIC8qKlxuICAgKiBBY2Nlc3NNb2RlIGlzIGEgY2xhc3MgcmVwcmVzZW50aW5nIHRvcGljIGFjY2VzcyBtb2RlLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgVGlub2RlXG4gICAqIEBjbGFzcyBBY2Nlc3NNb2RlXG4gICAqL1xuICAvKipcbiAgICogQ3VzdG9tIGZvcm1hdHRlclxuICAgKi9cbiAgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuICd7XCJtb2RlXCI6IFwiJyArIEFjY2Vzc01vZGUuZW5jb2RlKHRoaXMubW9kZSkgK1xuICAgICAgJ1wiLCBcImdpdmVuXCI6IFwiJyArIEFjY2Vzc01vZGUuZW5jb2RlKHRoaXMuZ2l2ZW4pICtcbiAgICAgICdcIiwgXCJ3YW50XCI6IFwiJyArIEFjY2Vzc01vZGUuZW5jb2RlKHRoaXMud2FudCkgKyAnXCJ9JztcbiAgfVxuICAvKipcbiAgICogQWNjZXNzTW9kZSBpcyBhIGNsYXNzIHJlcHJlc2VudGluZyB0b3BpYyBhY2Nlc3MgbW9kZS5cbiAgICpcbiAgICogQG1lbWJlcm9mIFRpbm9kZVxuICAgKiBAY2xhc3MgQWNjZXNzTW9kZVxuICAgKi9cbiAgLyoqXG4gICAqIENvbnZlcnRzIG51bWVyaWMgdmFsdWVzIHRvIHN0cmluZ3MuXG4gICAqL1xuICBqc29uSGVscGVyKCkge1xuICAgIHJldHVybiB7XG4gICAgICBtb2RlOiBBY2Nlc3NNb2RlLmVuY29kZSh0aGlzLm1vZGUpLFxuICAgICAgZ2l2ZW46IEFjY2Vzc01vZGUuZW5jb2RlKHRoaXMuZ2l2ZW4pLFxuICAgICAgd2FudDogQWNjZXNzTW9kZS5lbmNvZGUodGhpcy53YW50KVxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBBc3NpZ24gdmFsdWUgdG8gJ21vZGUnLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkFjY2Vzc01vZGVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBOdW1iZXJ9IG0gLSBlaXRoZXIgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFjY2VzcyBtb2RlIG9yIGEgc2V0IG9mIGJpdHMuXG4gICAqIEByZXR1cm5zIHtBY2Nlc3NNb2RlfSAtIDxjb2RlPnRoaXM8L2NvZGU+IEFjY2Vzc01vZGUuXG4gICAqL1xuICBzZXRNb2RlKG0pIHtcbiAgICB0aGlzLm1vZGUgPSBBY2Nlc3NNb2RlLmRlY29kZShtKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQWNjZXNzTW9kZSBpcyBhIGNsYXNzIHJlcHJlc2VudGluZyB0b3BpYyBhY2Nlc3MgbW9kZS5cbiAgICpcbiAgICogQG1lbWJlcm9mIFRpbm9kZVxuICAgKiBAY2xhc3MgQWNjZXNzTW9kZVxuICAgKi9cbiAgLyoqXG4gICAqIFVwZGF0ZSA8Y29kZT5tb2RlPC9jb2RlPiB2YWx1ZS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1IC0gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjaGFuZ2VzIHRvIGFwcGx5IHRvIGFjY2VzcyBtb2RlLlxuICAgKiBAcmV0dXJucyB7QWNjZXNzTW9kZX0gLSA8Y29kZT50aGlzPC9jb2RlPiBBY2Nlc3NNb2RlLlxuICAgKi9cbiAgdXBkYXRlTW9kZSh1KSB7XG4gICAgdGhpcy5tb2RlID0gQWNjZXNzTW9kZS51cGRhdGUodGhpcy5tb2RlLCB1KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQWNjZXNzTW9kZSBpcyBhIGNsYXNzIHJlcHJlc2VudGluZyB0b3BpYyBhY2Nlc3MgbW9kZS5cbiAgICpcbiAgICogQG1lbWJlcm9mIFRpbm9kZVxuICAgKiBAY2xhc3MgQWNjZXNzTW9kZVxuICAgKi9cbiAgLyoqXG4gICAqIEdldCA8Y29kZT5tb2RlPC9jb2RlPiB2YWx1ZSBhcyBhIHN0cmluZy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gPGNvZGU+bW9kZTwvY29kZT4gdmFsdWUuXG4gICAqL1xuICBnZXRNb2RlKCkge1xuICAgIHJldHVybiBBY2Nlc3NNb2RlLmVuY29kZSh0aGlzLm1vZGUpO1xuICB9XG4gIC8qKlxuICAgKiBBY2Nlc3NNb2RlIGlzIGEgY2xhc3MgcmVwcmVzZW50aW5nIHRvcGljIGFjY2VzcyBtb2RlLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgVGlub2RlXG4gICAqIEBjbGFzcyBBY2Nlc3NNb2RlXG4gICAqL1xuICAvKipcbiAgICogQXNzaWduIDxjb2RlPmdpdmVuPC9jb2RlPiAgdmFsdWUuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQWNjZXNzTW9kZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IE51bWJlcn0gZyAtIGVpdGhlciBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgYWNjZXNzIG1vZGUgb3IgYSBzZXQgb2YgYml0cy5cbiAgICogQHJldHVybnMge0FjY2Vzc01vZGV9IC0gPGNvZGU+dGhpczwvY29kZT4gQWNjZXNzTW9kZS5cbiAgICovXG4gIHNldEdpdmVuKGcpIHtcbiAgICB0aGlzLmdpdmVuID0gQWNjZXNzTW9kZS5kZWNvZGUoZyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBVcGRhdGUgJ2dpdmVuJyB2YWx1ZS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1IC0gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjaGFuZ2VzIHRvIGFwcGx5IHRvIGFjY2VzcyBtb2RlLlxuICAgKiBAcmV0dXJucyB7QWNjZXNzTW9kZX0gLSA8Y29kZT50aGlzPC9jb2RlPiBBY2Nlc3NNb2RlLlxuICAgKi9cbiAgdXBkYXRlR2l2ZW4odSkge1xuICAgIHRoaXMuZ2l2ZW4gPSBBY2Nlc3NNb2RlLnVwZGF0ZSh0aGlzLmdpdmVuLCB1KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQWNjZXNzTW9kZSBpcyBhIGNsYXNzIHJlcHJlc2VudGluZyB0b3BpYyBhY2Nlc3MgbW9kZS5cbiAgICpcbiAgICogQG1lbWJlcm9mIFRpbm9kZVxuICAgKiBAY2xhc3MgQWNjZXNzTW9kZVxuICAgKi9cbiAgLyoqXG4gICAqIEdldCAnZ2l2ZW4nIHZhbHVlIGFzIGEgc3RyaW5nLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkFjY2Vzc01vZGVcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gLSA8Yj5naXZlbjwvYj4gdmFsdWUuXG4gICAqL1xuICBnZXRHaXZlbigpIHtcbiAgICByZXR1cm4gQWNjZXNzTW9kZS5lbmNvZGUodGhpcy5naXZlbik7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBBc3NpZ24gJ3dhbnQnIHZhbHVlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkFjY2Vzc01vZGVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBOdW1iZXJ9IHcgLSBlaXRoZXIgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFjY2VzcyBtb2RlIG9yIGEgc2V0IG9mIGJpdHMuXG4gICAqIEByZXR1cm5zIHtBY2Nlc3NNb2RlfSAtIDxjb2RlPnRoaXM8L2NvZGU+IEFjY2Vzc01vZGUuXG4gICAqL1xuICBzZXRXYW50KHcpIHtcbiAgICB0aGlzLndhbnQgPSBBY2Nlc3NNb2RlLmRlY29kZSh3KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQWNjZXNzTW9kZSBpcyBhIGNsYXNzIHJlcHJlc2VudGluZyB0b3BpYyBhY2Nlc3MgbW9kZS5cbiAgICpcbiAgICogQG1lbWJlcm9mIFRpbm9kZVxuICAgKiBAY2xhc3MgQWNjZXNzTW9kZVxuICAgKi9cbiAgLyoqXG4gICAqIFVwZGF0ZSAnd2FudCcgdmFsdWUuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQWNjZXNzTW9kZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdSAtIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2hhbmdlcyB0byBhcHBseSB0byBhY2Nlc3MgbW9kZS5cbiAgICogQHJldHVybnMge0FjY2Vzc01vZGV9IC0gPGNvZGU+dGhpczwvY29kZT4gQWNjZXNzTW9kZS5cbiAgICovXG4gIHVwZGF0ZVdhbnQodSkge1xuICAgIHRoaXMud2FudCA9IEFjY2Vzc01vZGUudXBkYXRlKHRoaXMud2FudCwgdSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBHZXQgJ3dhbnQnIHZhbHVlIGFzIGEgc3RyaW5nLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkFjY2Vzc01vZGVcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gLSA8Yj53YW50PC9iPiB2YWx1ZS5cbiAgICovXG4gIGdldFdhbnQoKSB7XG4gICAgcmV0dXJuIEFjY2Vzc01vZGUuZW5jb2RlKHRoaXMud2FudCk7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBHZXQgcGVybWlzc2lvbnMgcHJlc2VudCBpbiAnd2FudCcgYnV0IG1pc3NpbmcgaW4gJ2dpdmVuJy5cbiAgICogSW52ZXJzZSBvZiB7QGxpbmsgVGlub2RlLkFjY2Vzc01vZGUjZ2V0RXhjZXNzaXZlfVxuICAgKlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkFjY2Vzc01vZGVcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gcGVybWlzc2lvbnMgcHJlc2VudCBpbiA8Yj53YW50PC9iPiBidXQgbWlzc2luZyBpbiA8Yj5naXZlbjwvYj4uXG4gICAqL1xuICBnZXRNaXNzaW5nKCkge1xuICAgIHJldHVybiBBY2Nlc3NNb2RlLmVuY29kZSh0aGlzLndhbnQgJiB+dGhpcy5naXZlbik7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBHZXQgcGVybWlzc2lvbnMgcHJlc2VudCBpbiAnZ2l2ZW4nIGJ1dCBtaXNzaW5nIGluICd3YW50Jy5cbiAgICogSW52ZXJzZSBvZiB7QGxpbmsgVGlub2RlLkFjY2Vzc01vZGUjZ2V0TWlzc2luZ31cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IHBlcm1pc3Npb25zIHByZXNlbnQgaW4gPGI+Z2l2ZW48L2I+IGJ1dCBtaXNzaW5nIGluIDxiPndhbnQ8L2I+LlxuICAgKi9cbiAgZ2V0RXhjZXNzaXZlKCkge1xuICAgIHJldHVybiBBY2Nlc3NNb2RlLmVuY29kZSh0aGlzLmdpdmVuICYgfnRoaXMud2FudCk7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBVcGRhdGUgJ3dhbnQnLCAnZ2l2ZScsIGFuZCAnbW9kZScgdmFsdWVzLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkFjY2Vzc01vZGVcbiAgICpcbiAgICogQHBhcmFtIHtBY2Nlc3NNb2RlfSB2YWwgLSBuZXcgYWNjZXNzIG1vZGUgdmFsdWUuXG4gICAqIEByZXR1cm5zIHtBY2Nlc3NNb2RlfSAtIDxjb2RlPnRoaXM8L2NvZGU+IEFjY2Vzc01vZGUuXG4gICAqL1xuICB1cGRhdGVBbGwodmFsKSB7XG4gICAgaWYgKHZhbCkge1xuICAgICAgdGhpcy51cGRhdGVHaXZlbih2YWwuZ2l2ZW4pO1xuICAgICAgdGhpcy51cGRhdGVXYW50KHZhbC53YW50KTtcbiAgICAgIHRoaXMubW9kZSA9IHRoaXMuZ2l2ZW4gJiB0aGlzLndhbnQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBY2Nlc3NNb2RlIGlzIGEgY2xhc3MgcmVwcmVzZW50aW5nIHRvcGljIGFjY2VzcyBtb2RlLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgVGlub2RlXG4gICAqIEBjbGFzcyBBY2Nlc3NNb2RlXG4gICAqL1xuICAvKipcbiAgICogQ2hlY2sgaWYgT3duZXIgKE8pIGZsYWcgaXMgc2V0LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkFjY2Vzc01vZGVcbiAgICogQHBhcmFtIHtzdHJpbmc9fSBzaWRlIC0gd2hpY2ggcGVybWlzc2lvbiB0byBjaGVjazogZ2l2ZW4sIHdhbnQsIG1vZGU7IGRlZmF1bHQ6IG1vZGUuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIDxjb2RlPnRydWU8L2NvZGU+IGlmIGZsYWcgaXMgc2V0LlxuICAgKi9cbiAgaXNPd25lcihzaWRlKSB7XG4gICAgcmV0dXJuIEFjY2Vzc01vZGUuI2NoZWNrRmxhZyh0aGlzLCBzaWRlLCBBY2Nlc3NNb2RlLl9PV05FUik7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBDaGVjayBpZiBQcmVzZW5jZSAoUCkgZmxhZyBpcyBzZXQuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQWNjZXNzTW9kZVxuICAgKiBAcGFyYW0ge3N0cmluZz19IHNpZGUgLSB3aGljaCBwZXJtaXNzaW9uIHRvIGNoZWNrOiBnaXZlbiwgd2FudCwgbW9kZTsgZGVmYXVsdDogbW9kZS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgZmxhZyBpcyBzZXQuXG4gICAqL1xuICBpc1ByZXNlbmNlcihzaWRlKSB7XG4gICAgcmV0dXJuIEFjY2Vzc01vZGUuI2NoZWNrRmxhZyh0aGlzLCBzaWRlLCBBY2Nlc3NNb2RlLl9QUkVTKTtcbiAgfVxuICAvKipcbiAgICogQWNjZXNzTW9kZSBpcyBhIGNsYXNzIHJlcHJlc2VudGluZyB0b3BpYyBhY2Nlc3MgbW9kZS5cbiAgICpcbiAgICogQG1lbWJlcm9mIFRpbm9kZVxuICAgKiBAY2xhc3MgQWNjZXNzTW9kZVxuICAgKi9cbiAgLyoqXG4gICAqIENoZWNrIGlmIFByZXNlbmNlIChQKSBmbGFnIGlzIE5PVCBzZXQuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQWNjZXNzTW9kZVxuICAgKiBAcGFyYW0ge3N0cmluZz19IHNpZGUgLSB3aGljaCBwZXJtaXNzaW9uIHRvIGNoZWNrOiBnaXZlbiwgd2FudCwgbW9kZTsgZGVmYXVsdDogbW9kZS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgZmxhZyBpcyBzZXQuXG4gICAqL1xuICBpc011dGVkKHNpZGUpIHtcbiAgICByZXR1cm4gIXRoaXMuaXNQcmVzZW5jZXIoc2lkZSk7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBDaGVjayBpZiBKb2luIChKKSBmbGFnIGlzIHNldC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gc2lkZSAtIHdoaWNoIHBlcm1pc3Npb24gdG8gY2hlY2s6IGdpdmVuLCB3YW50LCBtb2RlOyBkZWZhdWx0OiBtb2RlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSA8Y29kZT50cnVlPC9jb2RlPiBpZiBmbGFnIGlzIHNldC5cbiAgICovXG4gIGlzSm9pbmVyKHNpZGUpIHtcbiAgICByZXR1cm4gQWNjZXNzTW9kZS4jY2hlY2tGbGFnKHRoaXMsIHNpZGUsIEFjY2Vzc01vZGUuX0pPSU4pO1xuICB9XG4gIC8qKlxuICAgKiBBY2Nlc3NNb2RlIGlzIGEgY2xhc3MgcmVwcmVzZW50aW5nIHRvcGljIGFjY2VzcyBtb2RlLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgVGlub2RlXG4gICAqIEBjbGFzcyBBY2Nlc3NNb2RlXG4gICAqL1xuICAvKipcbiAgICogQ2hlY2sgaWYgUmVhZGVyIChSKSBmbGFnIGlzIHNldC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gc2lkZSAtIHdoaWNoIHBlcm1pc3Npb24gdG8gY2hlY2s6IGdpdmVuLCB3YW50LCBtb2RlOyBkZWZhdWx0OiBtb2RlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSA8Y29kZT50cnVlPC9jb2RlPiBpZiBmbGFnIGlzIHNldC5cbiAgICovXG4gIGlzUmVhZGVyKHNpZGUpIHtcbiAgICByZXR1cm4gQWNjZXNzTW9kZS4jY2hlY2tGbGFnKHRoaXMsIHNpZGUsIEFjY2Vzc01vZGUuX1JFQUQpO1xuICB9XG4gIC8qKlxuICAgKiBBY2Nlc3NNb2RlIGlzIGEgY2xhc3MgcmVwcmVzZW50aW5nIHRvcGljIGFjY2VzcyBtb2RlLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgVGlub2RlXG4gICAqIEBjbGFzcyBBY2Nlc3NNb2RlXG4gICAqL1xuICAvKipcbiAgICogQ2hlY2sgaWYgV3JpdGVyIChXKSBmbGFnIGlzIHNldC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gc2lkZSAtIHdoaWNoIHBlcm1pc3Npb24gdG8gY2hlY2s6IGdpdmVuLCB3YW50LCBtb2RlOyBkZWZhdWx0OiBtb2RlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSA8Y29kZT50cnVlPC9jb2RlPiBpZiBmbGFnIGlzIHNldC5cbiAgICovXG4gIGlzV3JpdGVyKHNpZGUpIHtcbiAgICByZXR1cm4gQWNjZXNzTW9kZS4jY2hlY2tGbGFnKHRoaXMsIHNpZGUsIEFjY2Vzc01vZGUuX1dSSVRFKTtcbiAgfVxuICAvKipcbiAgICogQWNjZXNzTW9kZSBpcyBhIGNsYXNzIHJlcHJlc2VudGluZyB0b3BpYyBhY2Nlc3MgbW9kZS5cbiAgICpcbiAgICogQG1lbWJlcm9mIFRpbm9kZVxuICAgKiBAY2xhc3MgQWNjZXNzTW9kZVxuICAgKi9cbiAgLyoqXG4gICAqIENoZWNrIGlmIEFwcHJvdmVyIChBKSBmbGFnIGlzIHNldC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gc2lkZSAtIHdoaWNoIHBlcm1pc3Npb24gdG8gY2hlY2s6IGdpdmVuLCB3YW50LCBtb2RlOyBkZWZhdWx0OiBtb2RlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSA8Y29kZT50cnVlPC9jb2RlPiBpZiBmbGFnIGlzIHNldC5cbiAgICovXG4gIGlzQXBwcm92ZXIoc2lkZSkge1xuICAgIHJldHVybiBBY2Nlc3NNb2RlLiNjaGVja0ZsYWcodGhpcywgc2lkZSwgQWNjZXNzTW9kZS5fQVBQUk9WRSk7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBDaGVjayBpZiBlaXRoZXIgb25lIG9mIE93bmVyIChPKSBvciBBcHByb3ZlciAoQSkgZmxhZ3MgaXMgc2V0LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkFjY2Vzc01vZGVcbiAgICogQHBhcmFtIHtzdHJpbmc9fSBzaWRlIC0gd2hpY2ggcGVybWlzc2lvbiB0byBjaGVjazogZ2l2ZW4sIHdhbnQsIG1vZGU7IGRlZmF1bHQ6IG1vZGUuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIDxjb2RlPnRydWU8L2NvZGU+IGlmIGZsYWcgaXMgc2V0LlxuICAgKi9cbiAgaXNBZG1pbihzaWRlKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNPd25lcihzaWRlKSB8fCB0aGlzLmlzQXBwcm92ZXIoc2lkZSk7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBDaGVjayBpZiBlaXRoZXIgb25lIG9mIE93bmVyIChPKSwgQXBwcm92ZXIgKEEpLCBvciBTaGFyZXIgKFMpIGZsYWdzIGlzIHNldC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gc2lkZSAtIHdoaWNoIHBlcm1pc3Npb24gdG8gY2hlY2s6IGdpdmVuLCB3YW50LCBtb2RlOyBkZWZhdWx0OiBtb2RlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSA8Y29kZT50cnVlPC9jb2RlPiBpZiBmbGFnIGlzIHNldC5cbiAgICovXG4gIGlzU2hhcmVyKHNpZGUpIHtcbiAgICByZXR1cm4gdGhpcy5pc0FkbWluKHNpZGUpIHx8IEFjY2Vzc01vZGUuI2NoZWNrRmxhZyh0aGlzLCBzaWRlLCBBY2Nlc3NNb2RlLl9TSEFSRSk7XG4gIH1cbiAgLyoqXG4gICAqIEFjY2Vzc01vZGUgaXMgYSBjbGFzcyByZXByZXNlbnRpbmcgdG9waWMgYWNjZXNzIG1vZGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBUaW5vZGVcbiAgICogQGNsYXNzIEFjY2Vzc01vZGVcbiAgICovXG4gIC8qKlxuICAgKiBDaGVjayBpZiBEZWxldGVyIChEKSBmbGFnIGlzIHNldC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5BY2Nlc3NNb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gc2lkZSAtIHdoaWNoIHBlcm1pc3Npb24gdG8gY2hlY2s6IGdpdmVuLCB3YW50LCBtb2RlOyBkZWZhdWx0OiBtb2RlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSA8Y29kZT50cnVlPC9jb2RlPiBpZiBmbGFnIGlzIHNldC5cbiAgICovXG4gIGlzRGVsZXRlcihzaWRlKSB7XG4gICAgcmV0dXJuIEFjY2Vzc01vZGUuI2NoZWNrRmxhZyh0aGlzLCBzaWRlLCBBY2Nlc3NNb2RlLl9ERUxFVEUpO1xuICB9XG59XG5cbkFjY2Vzc01vZGUuX05PTkUgPSAweDAwO1xuQWNjZXNzTW9kZS5fSk9JTiA9IDB4MDE7XG5BY2Nlc3NNb2RlLl9SRUFEID0gMHgwMjtcbkFjY2Vzc01vZGUuX1dSSVRFID0gMHgwNDtcbkFjY2Vzc01vZGUuX1BSRVMgPSAweDA4O1xuQWNjZXNzTW9kZS5fQVBQUk9WRSA9IDB4MTA7XG5BY2Nlc3NNb2RlLl9TSEFSRSA9IDB4MjA7XG5BY2Nlc3NNb2RlLl9ERUxFVEUgPSAweDQwO1xuQWNjZXNzTW9kZS5fT1dORVIgPSAweDgwO1xuXG5BY2Nlc3NNb2RlLl9CSVRNQVNLID0gQWNjZXNzTW9kZS5fSk9JTiB8IEFjY2Vzc01vZGUuX1JFQUQgfCBBY2Nlc3NNb2RlLl9XUklURSB8IEFjY2Vzc01vZGUuX1BSRVMgfFxuICBBY2Nlc3NNb2RlLl9BUFBST1ZFIHwgQWNjZXNzTW9kZS5fU0hBUkUgfCBBY2Nlc3NNb2RlLl9ERUxFVEUgfCBBY2Nlc3NNb2RlLl9PV05FUjtcbkFjY2Vzc01vZGUuX0lOVkFMSUQgPSAweDEwMDAwMDtcbiIsIi8qKlxuICogQGZpbGUgSW4tbWVtb3J5IHNvcnRlZCBjYWNoZSBvZiBvYmplY3RzLlxuICpcbiAqIEBjb3B5cmlnaHQgMjAxNS0yMDIyIFRpbm9kZSBMTEMuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBJbi1tZW1vcnkgc29ydGVkIGNhY2hlIG9mIG9iamVjdHMuXG4gKlxuICogQGNsYXNzIENCdWZmZXJcbiAqIEBtZW1iZXJvZiBUaW5vZGVcbiAqIEBwcm90ZWN0ZWRcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjb21wYXJlIGN1c3RvbSBjb21wYXJhdG9yIG9mIG9iamVjdHMuIFRha2VzIHR3byBwYXJhbWV0ZXJzIDxjb2RlPmE8L2NvZGU+IGFuZCA8Y29kZT5iPC9jb2RlPjtcbiAqICAgIHJldHVybnMgPGNvZGU+LTE8L2NvZGU+IGlmIDxjb2RlPmEgPCBiPC9jb2RlPiwgPGNvZGU+MDwvY29kZT4gaWYgPGNvZGU+YSA9PSBiPC9jb2RlPiwgPGNvZGU+MTwvY29kZT4gb3RoZXJ3aXNlLlxuICogQHBhcmFtIHtib29sZWFufSB1bmlxdWUgZW5mb3JjZSBlbGVtZW50IHVuaXF1ZW5lc3M6IHdoZW4gPGNvZGU+dHJ1ZTwvY29kZT4gcmVwbGFjZSBleGlzdGluZyBlbGVtZW50IHdpdGggYSBuZXdcbiAqICAgIG9uZSBvbiBjb25mbGljdDsgd2hlbiA8Y29kZT5mYWxzZTwvY29kZT4ga2VlcCBib3RoIGVsZW1lbnRzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDQnVmZmVyIHtcbiAgI2NvbXBhcmF0b3IgPSB1bmRlZmluZWQ7XG4gICN1bmlxdWUgPSBmYWxzZTtcbiAgYnVmZmVyID0gW107XG5cbiAgY29uc3RydWN0b3IoY29tcGFyZV8sIHVuaXF1ZV8pIHtcbiAgICB0aGlzLiNjb21wYXJhdG9yID0gY29tcGFyZV8gfHwgKChhLCBiKSA9PiB7XG4gICAgICByZXR1cm4gYSA9PT0gYiA/IDAgOiBhIDwgYiA/IC0xIDogMTtcbiAgICB9KTtcbiAgICB0aGlzLiN1bmlxdWUgPSB1bmlxdWVfO1xuICB9XG5cbiAgI2ZpbmROZWFyZXN0KGVsZW0sIGFyciwgZXhhY3QpIHtcbiAgICBsZXQgc3RhcnQgPSAwO1xuICAgIGxldCBlbmQgPSBhcnIubGVuZ3RoIC0gMTtcbiAgICBsZXQgcGl2b3QgPSAwO1xuICAgIGxldCBkaWZmID0gMDtcbiAgICBsZXQgZm91bmQgPSBmYWxzZTtcblxuICAgIHdoaWxlIChzdGFydCA8PSBlbmQpIHtcbiAgICAgIHBpdm90ID0gKHN0YXJ0ICsgZW5kKSAvIDIgfCAwO1xuICAgICAgZGlmZiA9IHRoaXMuI2NvbXBhcmF0b3IoYXJyW3Bpdm90XSwgZWxlbSk7XG4gICAgICBpZiAoZGlmZiA8IDApIHtcbiAgICAgICAgc3RhcnQgPSBwaXZvdCArIDE7XG4gICAgICB9IGVsc2UgaWYgKGRpZmYgPiAwKSB7XG4gICAgICAgIGVuZCA9IHBpdm90IC0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChmb3VuZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaWR4OiBwaXZvdCxcbiAgICAgICAgZXhhY3Q6IHRydWVcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChleGFjdCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaWR4OiAtMVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gTm90IGV4YWN0IC0gaW5zZXJ0aW9uIHBvaW50XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkeDogZGlmZiA8IDAgPyBwaXZvdCArIDEgOiBwaXZvdFxuICAgIH07XG4gIH1cblxuICAvLyBJbnNlcnQgZWxlbWVudCBpbnRvIGEgc29ydGVkIGFycmF5LlxuICAjaW5zZXJ0U29ydGVkKGVsZW0sIGFycikge1xuICAgIGNvbnN0IGZvdW5kID0gdGhpcy4jZmluZE5lYXJlc3QoZWxlbSwgYXJyLCBmYWxzZSk7XG4gICAgY29uc3QgY291bnQgPSAoZm91bmQuZXhhY3QgJiYgdGhpcy4jdW5pcXVlKSA/IDEgOiAwO1xuICAgIGFyci5zcGxpY2UoZm91bmQuaWR4LCBjb3VudCwgZWxlbSk7XG4gICAgcmV0dXJuIGFycjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYW4gZWxlbWVudCBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQ0J1ZmZlciNcbiAgICogQHBhcmFtIHtudW1iZXJ9IGF0IC0gUG9zaXRpb24gdG8gZmV0Y2ggZnJvbS5cbiAgICogQHJldHVybnMge09iamVjdH0gRWxlbWVudCBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24gb3IgPGNvZGU+dW5kZWZpbmVkPC9jb2RlPi5cbiAgICovXG4gIGdldEF0KGF0KSB7XG4gICAgcmV0dXJuIHRoaXMuYnVmZmVyW2F0XTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIGdldHRpbmcgdGhlIGVsZW1lbnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXIuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQ0J1ZmZlciNcbiAgICogQHBhcmFtIHtudW1iZXJ9IGF0IC0gcG9zaXRpb24gdG8gZmV0Y2ggZnJvbSwgY291bnRpbmcgZnJvbSB0aGUgZW5kO1xuICAgKiAgICA8Y29kZT51bmRlZmluZWQ8L2NvZGU+IG9yIDxjb2RlPm51bGw8L2NvZGU+ICBtZWFuIFwibGFzdFwiLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgbGFzdCBlbGVtZW50IGluIHRoZSBidWZmZXIgb3IgPGNvZGU+dW5kZWZpbmVkPC9jb2RlPiBpZiBidWZmZXIgaXMgZW1wdHkuXG4gICAqL1xuICBnZXRMYXN0KGF0KSB7XG4gICAgYXQgfD0gMDtcbiAgICByZXR1cm4gdGhpcy5idWZmZXIubGVuZ3RoID4gYXQgPyB0aGlzLmJ1ZmZlclt0aGlzLmJ1ZmZlci5sZW5ndGggLSAxIC0gYXRdIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBuZXcgZWxlbWVudChzKSB0byB0aGUgYnVmZmVyLiBWYXJpYWRpYzogdGFrZXMgb25lIG9yIG1vcmUgYXJndW1lbnRzLiBJZiBhbiBhcnJheSBpcyBwYXNzZWQgYXMgYSBzaW5nbGVcbiAgICogYXJndW1lbnQsIGl0cyBlbGVtZW50cyBhcmUgaW5zZXJ0ZWQgaW5kaXZpZHVhbGx5LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNCdWZmZXIjXG4gICAqXG4gICAqIEBwYXJhbSB7Li4uT2JqZWN0fEFycmF5fSAtIE9uZSBvciBtb3JlIG9iamVjdHMgdG8gaW5zZXJ0LlxuICAgKi9cbiAgcHV0KCkge1xuICAgIGxldCBpbnNlcnQ7XG4gICAgLy8gaW5zcGVjdCBhcmd1bWVudHM6IGlmIGFycmF5LCBpbnNlcnQgaXRzIGVsZW1lbnRzLCBpZiBvbmUgb3IgbW9yZSBub24tYXJyYXkgYXJndW1lbnRzLCBpbnNlcnQgdGhlbSBvbmUgYnkgb25lXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMSAmJiBBcnJheS5pc0FycmF5KGFyZ3VtZW50c1swXSkpIHtcbiAgICAgIGluc2VydCA9IGFyZ3VtZW50c1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5zZXJ0ID0gYXJndW1lbnRzO1xuICAgIH1cbiAgICBmb3IgKGxldCBpZHggaW4gaW5zZXJ0KSB7XG4gICAgICB0aGlzLiNpbnNlcnRTb3J0ZWQoaW5zZXJ0W2lkeF0sIHRoaXMuYnVmZmVyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGVsZW1lbnQgYXQgdGhlIGdpdmVuIHBvc2l0aW9uLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNCdWZmZXIjXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhdCAtIFBvc2l0aW9uIHRvIGRlbGV0ZSBhdC5cbiAgICogQHJldHVybnMge09iamVjdH0gRWxlbWVudCBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24gb3IgPGNvZGU+dW5kZWZpbmVkPC9jb2RlPi5cbiAgICovXG4gIGRlbEF0KGF0KSB7XG4gICAgYXQgfD0gMDtcbiAgICBsZXQgciA9IHRoaXMuYnVmZmVyLnNwbGljZShhdCwgMSk7XG4gICAgaWYgKHIgJiYgci5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gclswXTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgZWxlbWVudHMgYmV0d2VlbiB0d28gcG9zaXRpb25zLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNCdWZmZXIjXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaW5jZSAtIFBvc2l0aW9uIHRvIGRlbGV0ZSBmcm9tIChpbmNsdXNpdmUpLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYmVmb3JlIC0gUG9zaXRpb24gdG8gZGVsZXRlIHRvIChleGNsdXNpdmUpLlxuICAgKlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IGFycmF5IG9mIHJlbW92ZWQgZWxlbWVudHMgKGNvdWxkIGJlIHplcm8gbGVuZ3RoKS5cbiAgICovXG4gIGRlbFJhbmdlKHNpbmNlLCBiZWZvcmUpIHtcbiAgICByZXR1cm4gdGhpcy5idWZmZXIuc3BsaWNlKHNpbmNlLCBiZWZvcmUgLSBzaW5jZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgdGhlIGJ1ZmZlciBob2xkcy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5DQnVmZmVyI1xuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgYnVmZmVyLlxuICAgKi9cbiAgbGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLmJ1ZmZlci5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgdGhlIGJ1ZmZlciBkaXNjYXJkaW5nIGFsbCBlbGVtZW50c1xuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNCdWZmZXIjXG4gICAqL1xuICByZXNldCgpIHtcbiAgICB0aGlzLmJ1ZmZlciA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIGZvciBpdGVyYXRpbmcgY29udGVudHMgb2YgYnVmZmVyLiBTZWUge0BsaW5rIFRpbm9kZS5DQnVmZmVyI2ZvckVhY2h9LlxuICAgKiBAY2FsbGJhY2sgRm9yRWFjaENhbGxiYWNrVHlwZVxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNCdWZmZXIjXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtIC0gQ3VycmVudCBlbGVtZW50IG9mIHRoZSBidWZmZXIuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcmV2IC0gUHJldmlvdXMgZWxlbWVudCBvZiB0aGUgYnVmZmVyLlxuICAgKiBAcGFyYW0ge09iamVjdH0gbmV4dCAtIE5leHQgZWxlbWVudCBvZiB0aGUgYnVmZmVyLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBJbmRleCBvZiB0aGUgY3VycmVudCBlbGVtZW50LlxuICAgKi9cblxuICAvKipcbiAgICogQXBwbHkgZ2l2ZW4gPGNvZGU+Y2FsbGJhY2s8L2NvZGU+IHRvIGFsbCBlbGVtZW50cyBvZiB0aGUgYnVmZmVyLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNCdWZmZXIjXG4gICAqXG4gICAqIEBwYXJhbSB7VGlub2RlLkZvckVhY2hDYWxsYmFja1R5cGV9IGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBlbGVtZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRJZHggLSBPcHRpb25hbCBpbmRleCB0byBzdGFydCBpdGVyYXRpbmcgZnJvbSAoaW5jbHVzaXZlKS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGJlZm9yZUlkeCAtIE9wdGlvbmFsIGluZGV4IHRvIHN0b3AgaXRlcmF0aW5nIGJlZm9yZSAoZXhjbHVzaXZlKS5cbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgLSBjYWxsaW5nIGNvbnRleHQgKGkuZS4gdmFsdWUgb2YgPGNvZGU+dGhpczwvY29kZT4gaW4gY2FsbGJhY2spXG4gICAqL1xuICBmb3JFYWNoKGNhbGxiYWNrLCBzdGFydElkeCwgYmVmb3JlSWR4LCBjb250ZXh0KSB7XG4gICAgc3RhcnRJZHggPSBzdGFydElkeCB8IDA7XG4gICAgYmVmb3JlSWR4ID0gYmVmb3JlSWR4IHx8IHRoaXMuYnVmZmVyLmxlbmd0aDtcblxuICAgIGZvciAobGV0IGkgPSBzdGFydElkeDsgaSA8IGJlZm9yZUlkeDsgaSsrKSB7XG4gICAgICBjYWxsYmFjay5jYWxsKGNvbnRleHQsIHRoaXMuYnVmZmVyW2ldLFxuICAgICAgICAoaSA+IHN0YXJ0SWR4ID8gdGhpcy5idWZmZXJbaSAtIDFdIDogdW5kZWZpbmVkKSxcbiAgICAgICAgKGkgPCBiZWZvcmVJZHggLSAxID8gdGhpcy5idWZmZXJbaSArIDFdIDogdW5kZWZpbmVkKSwgaSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgZWxlbWVudCBpbiBidWZmZXIgdXNpbmcgYnVmZmVyJ3MgY29tcGFyaXNvbiBmdW5jdGlvbi5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5DQnVmZmVyI1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZWxlbSAtIGVsZW1lbnQgdG8gZmluZC5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gbmVhcmVzdCAtIHdoZW4gdHJ1ZSBhbmQgZXhhY3QgbWF0Y2ggaXMgbm90IGZvdW5kLCByZXR1cm4gdGhlIG5lYXJlc3QgZWxlbWVudCAoaW5zZXJ0aW9uIHBvaW50KS5cbiAgICogQHJldHVybnMge251bWJlcn0gaW5kZXggb2YgdGhlIGVsZW1lbnQgaW4gdGhlIGJ1ZmZlciBvciAtMS5cbiAgICovXG4gIGZpbmQoZWxlbSwgbmVhcmVzdCkge1xuICAgIGNvbnN0IHtcbiAgICAgIGlkeFxuICAgIH0gPSB0aGlzLiNmaW5kTmVhcmVzdChlbGVtLCB0aGlzLmJ1ZmZlciwgIW5lYXJlc3QpO1xuICAgIHJldHVybiBpZHg7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGJhY2sgZm9yIGZpbHRlcmluZyB0aGUgYnVmZmVyLiBTZWUge0BsaW5rIFRpbm9kZS5DQnVmZmVyI2ZpbHRlcn0uXG4gICAqIEBjYWxsYmFjayBGb3JFYWNoQ2FsbGJhY2tUeXBlXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQ0J1ZmZlciNcbiAgICogQHBhcmFtIHtPYmplY3R9IGVsZW0gLSBDdXJyZW50IGVsZW1lbnQgb2YgdGhlIGJ1ZmZlci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gSW5kZXggb2YgdGhlIGN1cnJlbnQgZWxlbWVudC5cbiAgICogQHJldHVybnMge2Jvb2xlbn0gPGNvZGU+dHJ1ZTwvY29kZT4gdG8ga2VlcCB0aGUgZWxlbWVudCwgPGNvZGU+ZmFsc2U8L2NvZGU+IHRvIHJlbW92ZS5cbiAgICovXG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbGwgZWxlbWVudHMgdGhhdCBkbyBub3QgcGFzcyB0aGUgdGVzdCBpbXBsZW1lbnRlZCBieSB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQ0J1ZmZlciNcbiAgICpcbiAgICogQHBhcmFtIHtUaW5vZGUuRmlsdGVyQ2FsbGJhY2tUeXBlfSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggZWxlbWVudC5cbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgLSBjYWxsaW5nIGNvbnRleHQgKGkuZS4gdmFsdWUgb2YgPGNvZGU+dGhpczwvY29kZT4gaW4gdGhlIGNhbGxiYWNrKVxuICAgKi9cbiAgZmlsdGVyKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYnVmZmVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoY2FsbGJhY2suY2FsbChjb250ZXh0LCB0aGlzLmJ1ZmZlcltpXSwgaSkpIHtcbiAgICAgICAgdGhpcy5idWZmZXJbY291bnRdID0gdGhpcy5idWZmZXJbaV07XG4gICAgICAgIGNvdW50Kys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5idWZmZXIuc3BsaWNlKGNvdW50KTtcbiAgfVxufVxuIiwiLyoqXG4gKiBAZmlsZSBHbG9iYWwgY29uc3RhbnRzIGFuZCBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMuXG4gKlxuICogQGNvcHlyaWdodCAyMDE1LTIwMjIgVGlub2RlIExMQ1xuICovXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7XG4gIHZlcnNpb24gYXMgcGFja2FnZV92ZXJzaW9uXG59IGZyb20gJy4uL3ZlcnNpb24uanNvbic7XG5cbi8vIEdsb2JhbCBjb25zdGFudHNcbmV4cG9ydCBjb25zdCBQUk9UT0NPTF9WRVJTSU9OID0gJzAnOyAvLyBNYWpvciBjb21wb25lbnQgb2YgdGhlIHZlcnNpb24sIGUuZy4gJzAnIGluICcwLjE3LjEnLlxuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBwYWNrYWdlX3ZlcnNpb24gfHwgJzAuMjAnO1xuZXhwb3J0IGNvbnN0IExJQlJBUlkgPSAndGlub2RlanMvJyArIFZFUlNJT047XG5cbi8vIFRvcGljIG5hbWUgcHJlZml4ZXMuXG5leHBvcnQgY29uc3QgVE9QSUNfTkVXID0gJ25ldyc7XG5leHBvcnQgY29uc3QgVE9QSUNfTkVXX0NIQU4gPSAnbmNoJztcbmV4cG9ydCBjb25zdCBUT1BJQ19NRSA9ICdtZSc7XG5leHBvcnQgY29uc3QgVE9QSUNfRk5EID0gJ2ZuZCc7XG5leHBvcnQgY29uc3QgVE9QSUNfU1lTID0gJ3N5cyc7XG5leHBvcnQgY29uc3QgVE9QSUNfQ0hBTiA9ICdjaG4nO1xuZXhwb3J0IGNvbnN0IFRPUElDX0dSUCA9ICdncnA7J1xuZXhwb3J0IGNvbnN0IFRPUElDX1AyUCA9ICdwMnAnO1xuZXhwb3J0IGNvbnN0IFVTRVJfTkVXID0gJ25ldyc7XG5cbi8vIFN0YXJ0aW5nIHZhbHVlIG9mIGEgbG9jYWxseS1nZW5lcmF0ZWQgc2VxSWQgdXNlZCBmb3IgcGVuZGluZyBtZXNzYWdlcy5cbmV4cG9ydCBjb25zdCBMT0NBTF9TRVFJRCA9IDB4RkZGRkZGRjtcblxuLy8gU3RhdHVzIGNvZGVzLlxuZXhwb3J0IGNvbnN0IE1FU1NBR0VfU1RBVFVTX05PTkUgPSAwOyAvLyBTdGF0dXMgbm90IGFzc2lnbmVkLlxuZXhwb3J0IGNvbnN0IE1FU1NBR0VfU1RBVFVTX1FVRVVFRCA9IDE7IC8vIExvY2FsIElEIGFzc2lnbmVkLCBpbiBwcm9ncmVzcyB0byBiZSBzZW50LlxuZXhwb3J0IGNvbnN0IE1FU1NBR0VfU1RBVFVTX1NFTkRJTkcgPSAyOyAvLyBUcmFuc21pc3Npb24gc3RhcnRlZC5cbmV4cG9ydCBjb25zdCBNRVNTQUdFX1NUQVRVU19GQUlMRUQgPSAzOyAvLyBBdCBsZWFzdCBvbmUgYXR0ZW1wdCB3YXMgbWFkZSB0byBzZW5kIHRoZSBtZXNzYWdlLlxuZXhwb3J0IGNvbnN0IE1FU1NBR0VfU1RBVFVTX1NFTlQgPSA0OyAvLyBEZWxpdmVyZWQgdG8gdGhlIHNlcnZlci5cbmV4cG9ydCBjb25zdCBNRVNTQUdFX1NUQVRVU19SRUNFSVZFRCA9IDU7IC8vIFJlY2VpdmVkIGJ5IHRoZSBjbGllbnQuXG5leHBvcnQgY29uc3QgTUVTU0FHRV9TVEFUVVNfUkVBRCA9IDY7IC8vIFJlYWQgYnkgdGhlIHVzZXIuXG5leHBvcnQgY29uc3QgTUVTU0FHRV9TVEFUVVNfVE9fTUUgPSA3OyAvLyBUaGUgbWVzc2FnZSBpcyByZWNlaXZlZCBmcm9tIGFub3RoZXIgdXNlci5cbmV4cG9ydCBjb25zdCBNRVNTQUdFX1NUQVRVU19ERUxfUkFOR0UgPSA4OyAvLyBUaGUgbWVzc2FnZSByZXByZXNlbnRzIGEgZGVsZXRlZCByYW5nZS5cblxuLy8gUmVqZWN0IHVucmVzb2x2ZWQgZnV0dXJlcyBhZnRlciB0aGlzIG1hbnkgbWlsbGlzZWNvbmRzLlxuZXhwb3J0IGNvbnN0IEVYUElSRV9QUk9NSVNFU19USU1FT1VUID0gNV8wMDA7XG4vLyBQZXJpb2RpY2l0eSBvZiBnYXJiYWdlIGNvbGxlY3Rpb24gb2YgdW5yZXNvbHZlZCBmdXR1cmVzLlxuZXhwb3J0IGNvbnN0IEVYUElSRV9QUk9NSVNFU19QRVJJT0QgPSAxXzAwMDtcblxuLy8gRGVsYXkgYmVmb3JlIGFja25vd2xlZGdpbmcgdGhhdCBhIG1lc3NhZ2Ugd2FzIHJlY2l2ZWQuXG5leHBvcnQgY29uc3QgUkVDVl9USU1FT1VUID0gMTAwO1xuXG4vLyBEZWZhdWx0IG51bWJlciBvZiBtZXNzYWdlcyB0byBwdWxsIGludG8gbWVtb3J5IGZyb20gcGVyc2lzdGVudCBjYWNoZS5cbmV4cG9ydCBjb25zdCBERUZBVUxUX01FU1NBR0VTX1BBR0UgPSAyNDtcblxuLy8gVW5pY29kZSBERUwgY2hhcmFjdGVyIGluZGljYXRpbmcgZGF0YSB3YXMgZGVsZXRlZC5cbmV4cG9ydCBjb25zdCBERUxfQ0hBUiA9ICdcXHUyNDIxJztcbiIsIi8qKlxuICogQGZpbGUgQWJzdHJhY3Rpb24gbGF5ZXIgZm9yIHdlYnNvY2tldCBhbmQgbG9uZyBwb2xsaW5nIGNvbm5lY3Rpb25zLlxuICpcbiAqIEBjb3B5cmlnaHQgMjAxNS0yMDIyIFRpbm9kZSBMTEMuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtcbiAganNvblBhcnNlSGVscGVyXG59IGZyb20gJy4vdXRpbHMuanMnO1xuXG5sZXQgV2ViU29ja2V0UHJvdmlkZXI7XG5sZXQgWEhSUHJvdmlkZXI7XG5cbi8vIEVycm9yIGNvZGUgdG8gcmV0dXJuIGluIGNhc2Ugb2YgYSBuZXR3b3JrIHByb2JsZW0uXG5jb25zdCBORVRXT1JLX0VSUk9SID0gNTAzO1xuY29uc3QgTkVUV09SS19FUlJPUl9URVhUID0gXCJDb25uZWN0aW9uIGZhaWxlZFwiO1xuXG4vLyBFcnJvciBjb2RlIHRvIHJldHVybiB3aGVuIHVzZXIgZGlzY29ubmVjdGVkIGZyb20gc2VydmVyLlxuY29uc3QgTkVUV09SS19VU0VSID0gNDE4O1xuY29uc3QgTkVUV09SS19VU0VSX1RFWFQgPSBcIkRpc2Nvbm5lY3RlZCBieSBjbGllbnRcIjtcblxuLy8gU2V0dGluZ3MgZm9yIGV4cG9uZW50aWFsIGJhY2tvZmZcbmNvbnN0IF9CT0ZGX0JBU0UgPSAyMDAwOyAvLyAyMDAwIG1pbGxpc2Vjb25kcywgbWluaW11bSBkZWxheSBiZXR3ZWVuIHJlY29ubmVjdHNcbmNvbnN0IF9CT0ZGX01BWF9JVEVSID0gMTA7IC8vIE1heGltdW0gZGVsYXkgYmV0d2VlbiByZWNvbm5lY3RzIDJeMTAgKiAyMDAwIH4gMzQgbWludXRlc1xuY29uc3QgX0JPRkZfSklUVEVSID0gMC4zOyAvLyBBZGQgcmFuZG9tIGRlbGF5XG5cbi8vIEhlbHBlciBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgYW4gZW5kcG9pbnQgVVJMLlxuZnVuY3Rpb24gbWFrZUJhc2VVcmwoaG9zdCwgcHJvdG9jb2wsIHZlcnNpb24sIGFwaUtleSkge1xuICBsZXQgdXJsID0gbnVsbDtcblxuICBpZiAoWydodHRwJywgJ2h0dHBzJywgJ3dzJywgJ3dzcyddLmluY2x1ZGVzKHByb3RvY29sKSkge1xuICAgIHVybCA9IGAke3Byb3RvY29sfTovLyR7aG9zdH1gO1xuICAgIGlmICh1cmwuY2hhckF0KHVybC5sZW5ndGggLSAxKSAhPT0gJy8nKSB7XG4gICAgICB1cmwgKz0gJy8nO1xuICAgIH1cbiAgICB1cmwgKz0gJ3YnICsgdmVyc2lvbiArICcvY2hhbm5lbHMnO1xuICAgIGlmIChbJ2h0dHAnLCAnaHR0cHMnXS5pbmNsdWRlcyhwcm90b2NvbCkpIHtcbiAgICAgIC8vIExvbmcgcG9sbGluZyBlbmRwb2ludCBlbmRzIHdpdGggXCJscFwiLCBpLmUuXG4gICAgICAvLyAnL3YwL2NoYW5uZWxzL2xwJyB2cyBqdXN0ICcvdjAvY2hhbm5lbHMnIGZvciB3c1xuICAgICAgdXJsICs9ICcvbHAnO1xuICAgIH1cbiAgICB1cmwgKz0gJz9hcGlrZXk9JyArIGFwaUtleTtcbiAgfVxuICByZXR1cm4gdXJsO1xufVxuXG4vKipcbiAqIEFuIGFic3RyYWN0aW9uIGZvciBhIHdlYnNvY2tldCBvciBhIGxvbmcgcG9sbGluZyBjb25uZWN0aW9uLlxuICpcbiAqIEBjbGFzcyBDb25uZWN0aW9uXG4gKiBAbWVtYmVyb2YgVGlub2RlXG5cbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgLSBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnLmhvc3QgLSBIb3N0IG5hbWUgYW5kIG9wdGlvbmFsIHBvcnQgbnVtYmVyIHRvIGNvbm5lY3QgdG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnLmFwaUtleSAtIEFQSSBrZXkgZ2VuZXJhdGVkIGJ5IDxjb2RlPmtleWdlbjwvY29kZT4uXG4gKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnLnRyYW5zcG9ydCAtIE5ldHdvcmsgdHJhbnNwb3J0IHRvIHVzZSwgZWl0aGVyIDxjb2RlPlwid3NcIjxjb2RlPi88Y29kZT5cIndzc1wiPC9jb2RlPiBmb3Igd2Vic29ja2V0IG9yXG4gKiAgICAgIDxjb2RlPmxwPC9jb2RlPiBmb3IgbG9uZyBwb2xsaW5nLlxuICogQHBhcmFtIHtib29sZWFufSBjb25maWcuc2VjdXJlIC0gVXNlIFNlY3VyZSBXZWJTb2NrZXQgaWYgPGNvZGU+dHJ1ZTwvY29kZT4uXG4gKiBAcGFyYW0ge3N0cmluZ30gdmVyc2lvbl8gLSBNYWpvciB2YWx1ZSBvZiB0aGUgcHJvdG9jb2wgdmVyc2lvbiwgZS5nLiAnMCcgaW4gJzAuMTcuMScuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGF1dG9yZWNvbm5lY3RfIC0gSWYgY29ubmVjdGlvbiBpcyBsb3N0LCB0cnkgdG8gcmVjb25uZWN0IGF1dG9tYXRpY2FsbHkuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENvbm5lY3Rpb24ge1xuICAvLyBMb2dnZXIsIGRvZXMgbm90aGluZyBieSBkZWZhdWx0LlxuICBzdGF0aWMgI2xvZyA9IF8gPT4ge307XG5cbiAgI2JvZmZUaW1lciA9IG51bGw7XG4gICNib2ZmSXRlcmF0aW9uID0gMDtcbiAgI2JvZmZDbG9zZWQgPSBmYWxzZTsgLy8gSW5kaWNhdG9yIGlmIHRoZSBzb2NrZXQgd2FzIG1hbnVhbGx5IGNsb3NlZCAtIGRvbid0IGF1dG9yZWNvbm5lY3QgaWYgdHJ1ZS5cblxuICAvLyBXZWJzb2NrZXQuXG4gICNzb2NrZXQgPSBudWxsO1xuXG4gIGhvc3Q7XG4gIHNlY3VyZTtcbiAgYXBpS2V5O1xuXG4gIHZlcnNpb247XG4gIGF1dG9yZWNvbm5lY3Q7XG5cbiAgaW5pdGlhbGl6ZWQ7XG5cbiAgLy8gKGNvbmZpZy5ob3N0LCBjb25maWcuYXBpS2V5LCBjb25maWcudHJhbnNwb3J0LCBjb25maWcuc2VjdXJlKSwgUFJPVE9DT0xfVkVSU0lPTiwgdHJ1ZVxuICBjb25zdHJ1Y3Rvcihjb25maWcsIHZlcnNpb25fLCBhdXRvcmVjb25uZWN0Xykge1xuICAgIHRoaXMuaG9zdCA9IGNvbmZpZy5ob3N0O1xuICAgIHRoaXMuc2VjdXJlID0gY29uZmlnLnNlY3VyZTtcbiAgICB0aGlzLmFwaUtleSA9IGNvbmZpZy5hcGlLZXk7XG5cbiAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uXztcbiAgICB0aGlzLmF1dG9yZWNvbm5lY3QgPSBhdXRvcmVjb25uZWN0XztcblxuICAgIGlmIChjb25maWcudHJhbnNwb3J0ID09PSAnbHAnKSB7XG4gICAgICAvLyBleHBsaWNpdCByZXF1ZXN0IHRvIHVzZSBsb25nIHBvbGxpbmdcbiAgICAgIHRoaXMuI2luaXRfbHAoKTtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSAnbHAnO1xuICAgIH0gZWxzZSBpZiAoY29uZmlnLnRyYW5zcG9ydCA9PT0gJ3dzJykge1xuICAgICAgLy8gZXhwbGljaXQgcmVxdWVzdCB0byB1c2Ugd2ViIHNvY2tldFxuICAgICAgLy8gaWYgd2Vic29ja2V0cyBhcmUgbm90IGF2YWlsYWJsZSwgaG9ycmlibGUgdGhpbmdzIHdpbGwgaGFwcGVuXG4gICAgICB0aGlzLiNpbml0X3dzKCk7XG4gICAgICB0aGlzLmluaXRpYWxpemVkID0gJ3dzJztcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICAgIC8vIEludmFsaWQgb3IgdW5kZWZpbmVkIG5ldHdvcmsgdHJhbnNwb3J0LlxuICAgICAgQ29ubmVjdGlvbi4jbG9nKFwiVW5rbm93biBvciBpbnZhbGlkIG5ldHdvcmsgdHJhbnNwb3J0LiBSdW5uaW5nIHVuZGVyIE5vZGU/IENhbGwgJ1Rpbm9kZS5zZXROZXR3b3JrUHJvdmlkZXJzKCknLlwiKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb3IgaW52YWxpZCBuZXR3b3JrIHRyYW5zcG9ydC4gUnVubmluZyB1bmRlciBOb2RlPyBDYWxsICdUaW5vZGUuc2V0TmV0d29ya1Byb3ZpZGVycygpJy5cIik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRvIHVzZSBDb25uZWN0aW9uIGluIGEgbm9uIGJyb3dzZXIgY29udGV4dCwgc3VwcGx5IFdlYlNvY2tldCBhbmQgWE1MSHR0cFJlcXVlc3QgcHJvdmlkZXJzLlxuICAgKiBAc3RhdGljXG4gICAqIEBtZW1iZXJvZiBDb25uZWN0aW9uXG4gICAqIEBwYXJhbSB3c1Byb3ZpZGVyIFdlYlNvY2tldCBwcm92aWRlciwgZS5nLiBmb3Igbm9kZUpTICwgPGNvZGU+cmVxdWlyZSgnd3MnKTwvY29kZT4uXG4gICAqIEBwYXJhbSB4aHJQcm92aWRlciBYTUxIdHRwUmVxdWVzdCBwcm92aWRlciwgZS5nLiBmb3Igbm9kZSA8Y29kZT5yZXF1aXJlKCd4aHInKTwvY29kZT4uXG4gICAqL1xuICBzdGF0aWMgc2V0TmV0d29ya1Byb3ZpZGVycyh3c1Byb3ZpZGVyLCB4aHJQcm92aWRlcikge1xuICAgIFdlYlNvY2tldFByb3ZpZGVyID0gd3NQcm92aWRlcjtcbiAgICBYSFJQcm92aWRlciA9IHhoclByb3ZpZGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2lnbiBhIG5vbi1kZWZhdWx0IGxvZ2dlci5cbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyb2YgQ29ubmVjdGlvblxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsIHZhcmlhZGljIGxvZ2dpbmcgZnVuY3Rpb24uXG4gICAqL1xuICBzdGF0aWMgc2V0IGxvZ2dlcihsKSB7XG4gICAgQ29ubmVjdGlvbi4jbG9nID0gbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWF0ZSBhIG5ldyBjb25uZWN0aW9uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQ29ubmVjdGlvbiNcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhvc3RfIEhvc3QgbmFtZSB0byBjb25uZWN0IHRvOyBpZiA8Y29kZT5udWxsPC9jb2RlPiB0aGUgb2xkIGhvc3QgbmFtZSB3aWxsIGJlIHVzZWQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZm9yY2UgRm9yY2UgbmV3IGNvbm5lY3Rpb24gZXZlbiBpZiBvbmUgYWxyZWFkeSBleGlzdHMuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgY29ubmVjdGlvbiBjYWxsIGNvbXBsZXRlcywgcmVzb2x1dGlvbiBpcyBjYWxsZWQgd2l0aG91dFxuICAgKiAgcGFyYW1ldGVycywgcmVqZWN0aW9uIHBhc3NlcyB0aGUge0Vycm9yfSBhcyBwYXJhbWV0ZXIuXG4gICAqL1xuICBjb25uZWN0KGhvc3RfLCBmb3JjZSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChudWxsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcnkgdG8gcmVzdG9yZSBhIG5ldHdvcmsgY29ubmVjdGlvbiwgYWxzbyByZXNldCBiYWNrb2ZmLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNvbm5lY3Rpb24jXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZm9yY2UgLSByZWNvbm5lY3QgZXZlbiBpZiB0aGVyZSBpcyBhIGxpdmUgY29ubmVjdGlvbiBhbHJlYWR5LlxuICAgKi9cbiAgcmVjb25uZWN0KGZvcmNlKSB7fVxuXG4gIC8qKlxuICAgKiBUZXJtaW5hdGUgdGhlIG5ldHdvcmsgY29ubmVjdGlvblxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNvbm5lY3Rpb24jXG4gICAqL1xuICBkaXNjb25uZWN0KCkge31cblxuICAvKipcbiAgICogU2VuZCBhIHN0cmluZyB0byB0aGUgc2VydmVyLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNvbm5lY3Rpb24jXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtc2cgLSBTdHJpbmcgdG8gc2VuZC5cbiAgICogQHRocm93cyBUaHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZSB1bmRlcmx5aW5nIGNvbm5lY3Rpb24gaXMgbm90IGxpdmUuXG4gICAqL1xuICBzZW5kVGV4dChtc2cpIHt9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGNvbm5lY3Rpb24gaXMgYWxpdmUuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQ29ubmVjdGlvbiNcbiAgICogQHJldHVybnMge2Jvb2xlYW59IDxjb2RlPnRydWU8L2NvZGU+IGlmIGNvbm5lY3Rpb24gaXMgbGl2ZSwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cbiAgICovXG4gIGlzQ29ubmVjdGVkKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG5hbWUgb2YgdGhlIGN1cnJlbnQgbmV0d29yayB0cmFuc3BvcnQuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQ29ubmVjdGlvbiNcbiAgICogQHJldHVybnMge3N0cmluZ30gbmFtZSBvZiB0aGUgdHJhbnNwb3J0IHN1Y2ggYXMgPGNvZGU+XCJ3c1wiPC9jb2RlPiBvciA8Y29kZT5cImxwXCI8L2NvZGU+LlxuICAgKi9cbiAgdHJhbnNwb3J0KCkge1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxpemVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgbmV0d29yayBwcm9iZSB0byBjaGVjayBpZiBjb25uZWN0aW9uIGlzIGluZGVlZCBsaXZlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNvbm5lY3Rpb24jXG4gICAqL1xuICBwcm9iZSgpIHtcbiAgICB0aGlzLnNlbmRUZXh0KCcxJyk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgYXV0b3JlY29ubmVjdCBjb3VudGVyIHRvIHplcm8uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuQ29ubmVjdGlvbiNcbiAgICovXG4gIGJhY2tvZmZSZXNldCgpIHtcbiAgICB0aGlzLiNib2ZmUmVzZXQoKTtcbiAgfVxuXG4gIC8vIEJhY2tvZmYgaW1wbGVtZW50YXRpb24gLSByZWNvbm5lY3QgYWZ0ZXIgYSB0aW1lb3V0LlxuICAjYm9mZlJlY29ubmVjdCgpIHtcbiAgICAvLyBDbGVhciB0aW1lclxuICAgIGNsZWFyVGltZW91dCh0aGlzLiNib2ZmVGltZXIpO1xuICAgIC8vIENhbGN1bGF0ZSB3aGVuIHRvIGZpcmUgdGhlIHJlY29ubmVjdCBhdHRlbXB0XG4gICAgY29uc3QgdGltZW91dCA9IF9CT0ZGX0JBU0UgKiAoTWF0aC5wb3coMiwgdGhpcy4jYm9mZkl0ZXJhdGlvbikgKiAoMS4wICsgX0JPRkZfSklUVEVSICogTWF0aC5yYW5kb20oKSkpO1xuICAgIC8vIFVwZGF0ZSBpdGVyYXRpb24gY291bnRlciBmb3IgZnV0dXJlIHVzZVxuICAgIHRoaXMuI2JvZmZJdGVyYXRpb24gPSAodGhpcy4jYm9mZkl0ZXJhdGlvbiA+PSBfQk9GRl9NQVhfSVRFUiA/IHRoaXMuI2JvZmZJdGVyYXRpb24gOiB0aGlzLiNib2ZmSXRlcmF0aW9uICsgMSk7XG4gICAgaWYgKHRoaXMub25BdXRvcmVjb25uZWN0SXRlcmF0aW9uKSB7XG4gICAgICB0aGlzLm9uQXV0b3JlY29ubmVjdEl0ZXJhdGlvbih0aW1lb3V0KTtcbiAgICB9XG5cbiAgICB0aGlzLiNib2ZmVGltZXIgPSBzZXRUaW1lb3V0KF8gPT4ge1xuICAgICAgQ29ubmVjdGlvbi4jbG9nKGBSZWNvbm5lY3RpbmcsIGl0ZXI9JHt0aGlzLiNib2ZmSXRlcmF0aW9ufSwgdGltZW91dD0ke3RpbWVvdXR9YCk7XG4gICAgICAvLyBNYXliZSB0aGUgc29ja2V0IHdhcyBjbG9zZWQgd2hpbGUgd2Ugd2FpdGVkIGZvciB0aGUgdGltZXI/XG4gICAgICBpZiAoIXRoaXMuI2JvZmZDbG9zZWQpIHtcbiAgICAgICAgY29uc3QgcHJvbSA9IHRoaXMuY29ubmVjdCgpO1xuICAgICAgICBpZiAodGhpcy5vbkF1dG9yZWNvbm5lY3RJdGVyYXRpb24pIHtcbiAgICAgICAgICB0aGlzLm9uQXV0b3JlY29ubmVjdEl0ZXJhdGlvbigwLCBwcm9tKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBTdXBwcmVzcyBlcnJvciBpZiBpdCdzIG5vdCB1c2VkLlxuICAgICAgICAgIHByb20uY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgLyogZG8gbm90aGluZyAqL1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMub25BdXRvcmVjb25uZWN0SXRlcmF0aW9uKSB7XG4gICAgICAgIHRoaXMub25BdXRvcmVjb25uZWN0SXRlcmF0aW9uKC0xKTtcbiAgICAgIH1cbiAgICB9LCB0aW1lb3V0KTtcbiAgfVxuXG4gIC8vIFRlcm1pbmF0ZSBhdXRvLXJlY29ubmVjdCBwcm9jZXNzLlxuICAjYm9mZlN0b3AoKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuI2JvZmZUaW1lcik7XG4gICAgdGhpcy4jYm9mZlRpbWVyID0gbnVsbDtcbiAgfVxuXG4gIC8vIFJlc2V0IGF1dG8tcmVjb25uZWN0IGl0ZXJhdGlvbiBjb3VudGVyLlxuICAjYm9mZlJlc2V0KCkge1xuICAgIHRoaXMuI2JvZmZJdGVyYXRpb24gPSAwO1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6YXRpb24gZm9yIGxvbmcgcG9sbGluZy5cbiAgI2luaXRfbHAoKSB7XG4gICAgY29uc3QgWERSX1VOU0VOVCA9IDA7IC8vIENsaWVudCBoYXMgYmVlbiBjcmVhdGVkLiBvcGVuKCkgbm90IGNhbGxlZCB5ZXQuXG4gICAgY29uc3QgWERSX09QRU5FRCA9IDE7IC8vIG9wZW4oKSBoYXMgYmVlbiBjYWxsZWQuXG4gICAgY29uc3QgWERSX0hFQURFUlNfUkVDRUlWRUQgPSAyOyAvLyBzZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgaGVhZGVycyBhbmQgc3RhdHVzIGFyZSBhdmFpbGFibGUuXG4gICAgY29uc3QgWERSX0xPQURJTkcgPSAzOyAvLyBEb3dubG9hZGluZzsgcmVzcG9uc2VUZXh0IGhvbGRzIHBhcnRpYWwgZGF0YS5cbiAgICBjb25zdCBYRFJfRE9ORSA9IDQ7IC8vIFRoZSBvcGVyYXRpb24gaXMgY29tcGxldGUuXG5cbiAgICAvLyBGdWxseSBjb21wb3NlZCBlbmRwb2ludCBVUkwsIHdpdGggQVBJIGtleSAmIFNJRFxuICAgIGxldCBfbHBVUkwgPSBudWxsO1xuXG4gICAgbGV0IF9wb2xsZXIgPSBudWxsO1xuICAgIGxldCBfc2VuZGVyID0gbnVsbDtcblxuICAgIGxldCBscF9zZW5kZXIgPSAodXJsXykgPT4ge1xuICAgICAgY29uc3Qgc2VuZGVyID0gbmV3IFhIUlByb3ZpZGVyKCk7XG4gICAgICBzZW5kZXIub25yZWFkeXN0YXRlY2hhbmdlID0gKGV2dCkgPT4ge1xuICAgICAgICBpZiAoc2VuZGVyLnJlYWR5U3RhdGUgPT0gWERSX0RPTkUgJiYgc2VuZGVyLnN0YXR1cyA+PSA0MDApIHtcbiAgICAgICAgICAvLyBTb21lIHNvcnQgb2YgZXJyb3IgcmVzcG9uc2VcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYExQIHNlbmRlciBmYWlsZWQsICR7c2VuZGVyLnN0YXR1c31gKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgc2VuZGVyLm9wZW4oJ1BPU1QnLCB1cmxfLCB0cnVlKTtcbiAgICAgIHJldHVybiBzZW5kZXI7XG4gICAgfVxuXG4gICAgbGV0IGxwX3BvbGxlciA9ICh1cmxfLCByZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBwb2xsZXIgPSBuZXcgWEhSUHJvdmlkZXIoKTtcbiAgICAgIGxldCBwcm9taXNlQ29tcGxldGVkID0gZmFsc2U7XG5cbiAgICAgIHBvbGxlci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoZXZ0KSA9PiB7XG4gICAgICAgIGlmIChwb2xsZXIucmVhZHlTdGF0ZSA9PSBYRFJfRE9ORSkge1xuICAgICAgICAgIGlmIChwb2xsZXIuc3RhdHVzID09IDIwMSkgeyAvLyAyMDEgPT0gSFRUUC5DcmVhdGVkLCBnZXQgU0lEXG4gICAgICAgICAgICBsZXQgcGt0ID0gSlNPTi5wYXJzZShwb2xsZXIucmVzcG9uc2VUZXh0LCBqc29uUGFyc2VIZWxwZXIpO1xuICAgICAgICAgICAgX2xwVVJMID0gdXJsXyArICcmc2lkPScgKyBwa3QuY3RybC5wYXJhbXMuc2lkO1xuICAgICAgICAgICAgcG9sbGVyID0gbHBfcG9sbGVyKF9scFVSTCk7XG4gICAgICAgICAgICBwb2xsZXIuc2VuZChudWxsKTtcbiAgICAgICAgICAgIGlmICh0aGlzLm9uT3Blbikge1xuICAgICAgICAgICAgICB0aGlzLm9uT3BlbigpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgICBwcm9taXNlQ29tcGxldGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5hdXRvcmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgIHRoaXMuI2JvZmZTdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChwb2xsZXIuc3RhdHVzIDwgNDAwKSB7IC8vIDQwMCA9IEhUVFAuQmFkUmVxdWVzdFxuICAgICAgICAgICAgaWYgKHRoaXMub25NZXNzYWdlKSB7XG4gICAgICAgICAgICAgIHRoaXMub25NZXNzYWdlKHBvbGxlci5yZXNwb25zZVRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcG9sbGVyID0gbHBfcG9sbGVyKF9scFVSTCk7XG4gICAgICAgICAgICBwb2xsZXIuc2VuZChudWxsKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gRG9uJ3QgdGhyb3cgYW4gZXJyb3IgaGVyZSwgZ3JhY2VmdWxseSBoYW5kbGUgc2VydmVyIGVycm9yc1xuICAgICAgICAgICAgaWYgKHJlamVjdCAmJiAhcHJvbWlzZUNvbXBsZXRlZCkge1xuICAgICAgICAgICAgICBwcm9taXNlQ29tcGxldGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgcmVqZWN0KHBvbGxlci5yZXNwb25zZVRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMub25NZXNzYWdlICYmIHBvbGxlci5yZXNwb25zZVRleHQpIHtcbiAgICAgICAgICAgICAgdGhpcy5vbk1lc3NhZ2UocG9sbGVyLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5vbkRpc2Nvbm5lY3QpIHtcbiAgICAgICAgICAgICAgY29uc3QgY29kZSA9IHBvbGxlci5zdGF0dXMgfHwgKHRoaXMuI2JvZmZDbG9zZWQgPyBORVRXT1JLX1VTRVIgOiBORVRXT1JLX0VSUk9SKTtcbiAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IHBvbGxlci5yZXNwb25zZVRleHQgfHwgKHRoaXMuI2JvZmZDbG9zZWQgPyBORVRXT1JLX1VTRVJfVEVYVCA6IE5FVFdPUktfRVJST1JfVEVYVCk7XG4gICAgICAgICAgICAgIHRoaXMub25EaXNjb25uZWN0KG5ldyBFcnJvcih0ZXh0ICsgJyAoJyArIGNvZGUgKyAnKScpLCBjb2RlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUG9sbGluZyBoYXMgc3RvcHBlZC4gSW5kaWNhdGUgaXQgYnkgc2V0dGluZyBwb2xsZXIgdG8gbnVsbC5cbiAgICAgICAgICAgIHBvbGxlciA9IG51bGw7XG4gICAgICAgICAgICBpZiAoIXRoaXMuI2JvZmZDbG9zZWQgJiYgdGhpcy5hdXRvcmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgIHRoaXMuI2JvZmZSZWNvbm5lY3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICAvLyBVc2luZyBQT1NUIHRvIGF2b2lkIGNhY2hpbmcgcmVzcG9uc2UgYnkgc2VydmljZSB3b3JrZXIuXG4gICAgICBwb2xsZXIub3BlbignUE9TVCcsIHVybF8sIHRydWUpO1xuICAgICAgcmV0dXJuIHBvbGxlcjtcbiAgICB9XG5cbiAgICB0aGlzLmNvbm5lY3QgPSAoaG9zdF8sIGZvcmNlKSA9PiB7XG4gICAgICB0aGlzLiNib2ZmQ2xvc2VkID0gZmFsc2U7XG5cbiAgICAgIGlmIChfcG9sbGVyKSB7XG4gICAgICAgIGlmICghZm9yY2UpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgX3BvbGxlci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIF9wb2xsZXIuYWJvcnQoKTtcbiAgICAgICAgX3BvbGxlciA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChob3N0Xykge1xuICAgICAgICB0aGlzLmhvc3QgPSBob3N0XztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgdXJsID0gbWFrZUJhc2VVcmwodGhpcy5ob3N0LCB0aGlzLnNlY3VyZSA/ICdodHRwcycgOiAnaHR0cCcsIHRoaXMudmVyc2lvbiwgdGhpcy5hcGlLZXkpO1xuICAgICAgICBDb25uZWN0aW9uLiNsb2coXCJMUCBjb25uZWN0aW5nIHRvOlwiLCB1cmwpO1xuICAgICAgICBfcG9sbGVyID0gbHBfcG9sbGVyKHVybCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgX3BvbGxlci5zZW5kKG51bGwpO1xuICAgICAgfSkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICBDb25uZWN0aW9uLiNsb2coXCJMUCBjb25uZWN0aW9uIGZhaWxlZDpcIiwgZXJyKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IChmb3JjZSkgPT4ge1xuICAgICAgdGhpcy4jYm9mZlN0b3AoKTtcbiAgICAgIHRoaXMuY29ubmVjdChudWxsLCBmb3JjZSk7XG4gICAgfTtcblxuICAgIHRoaXMuZGlzY29ubmVjdCA9ICgpID0+IHtcbiAgICAgIHRoaXMuI2JvZmZDbG9zZWQgPSB0cnVlO1xuICAgICAgdGhpcy4jYm9mZlN0b3AoKTtcblxuICAgICAgaWYgKF9zZW5kZXIpIHtcbiAgICAgICAgX3NlbmRlci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIF9zZW5kZXIuYWJvcnQoKTtcbiAgICAgICAgX3NlbmRlciA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAoX3BvbGxlcikge1xuICAgICAgICBfcG9sbGVyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgX3BvbGxlci5hYm9ydCgpO1xuICAgICAgICBfcG9sbGVyID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMub25EaXNjb25uZWN0KSB7XG4gICAgICAgIHRoaXMub25EaXNjb25uZWN0KG5ldyBFcnJvcihORVRXT1JLX1VTRVJfVEVYVCArICcgKCcgKyBORVRXT1JLX1VTRVIgKyAnKScpLCBORVRXT1JLX1VTRVIpO1xuICAgICAgfVxuICAgICAgLy8gRW5zdXJlIGl0J3MgcmVjb25zdHJ1Y3RlZFxuICAgICAgX2xwVVJMID0gbnVsbDtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kVGV4dCA9IChtc2cpID0+IHtcbiAgICAgIF9zZW5kZXIgPSBscF9zZW5kZXIoX2xwVVJMKTtcbiAgICAgIGlmIChfc2VuZGVyICYmIChfc2VuZGVyLnJlYWR5U3RhdGUgPT0gWERSX09QRU5FRCkpIHsgLy8gMSA9PSBPUEVORURcbiAgICAgICAgX3NlbmRlci5zZW5kKG1zZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJMb25nIHBvbGxlciBmYWlsZWQgdG8gY29ubmVjdFwiKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5pc0Nvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgIHJldHVybiAoX3BvbGxlciAmJiB0cnVlKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6YXRpb24gZm9yIFdlYnNvY2tldFxuICAjaW5pdF93cygpIHtcbiAgICB0aGlzLmNvbm5lY3QgPSAoaG9zdF8sIGZvcmNlKSA9PiB7XG4gICAgICB0aGlzLiNib2ZmQ2xvc2VkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0aGlzLiNzb2NrZXQpIHtcbiAgICAgICAgaWYgKCFmb3JjZSAmJiB0aGlzLiNzb2NrZXQucmVhZHlTdGF0ZSA9PSB0aGlzLiNzb2NrZXQuT1BFTikge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLiNzb2NrZXQuY2xvc2UoKTtcbiAgICAgICAgdGhpcy4jc29ja2V0ID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKGhvc3RfKSB7XG4gICAgICAgIHRoaXMuaG9zdCA9IGhvc3RfO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCB1cmwgPSBtYWtlQmFzZVVybCh0aGlzLmhvc3QsIHRoaXMuc2VjdXJlID8gJ3dzcycgOiAnd3MnLCB0aGlzLnZlcnNpb24sIHRoaXMuYXBpS2V5KTtcblxuICAgICAgICBDb25uZWN0aW9uLiNsb2coXCJXUyBjb25uZWN0aW5nIHRvOiBcIiwgdXJsKTtcblxuICAgICAgICAvLyBJdCB0aHJvd3Mgd2hlbiB0aGUgc2VydmVyIGlzIG5vdCBhY2Nlc3NpYmxlIGJ1dCB0aGUgZXhjZXB0aW9uIGNhbm5vdCBiZSBjYXVnaHQ6XG4gICAgICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzMxMDAyNTkyL2phdmFzY3JpcHQtZG9lc250LWNhdGNoLWVycm9yLWluLXdlYnNvY2tldC1pbnN0YW50aWF0aW9uLzMxMDAzMDU3XG4gICAgICAgIGNvbnN0IGNvbm4gPSBuZXcgV2ViU29ja2V0UHJvdmlkZXIodXJsKTtcblxuICAgICAgICBjb25uLm9uZXJyb3IgPSAoZXJyKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29ubi5vbm9wZW4gPSAoZXZ0KSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuYXV0b3JlY29ubmVjdCkge1xuICAgICAgICAgICAgdGhpcy4jYm9mZlN0b3AoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGhpcy5vbk9wZW4pIHtcbiAgICAgICAgICAgIHRoaXMub25PcGVuKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbm4ub25jbG9zZSA9IChldnQpID0+IHtcbiAgICAgICAgICB0aGlzLiNzb2NrZXQgPSBudWxsO1xuXG4gICAgICAgICAgaWYgKHRoaXMub25EaXNjb25uZWN0KSB7XG4gICAgICAgICAgICBjb25zdCBjb2RlID0gdGhpcy4jYm9mZkNsb3NlZCA/IE5FVFdPUktfVVNFUiA6IE5FVFdPUktfRVJST1I7XG4gICAgICAgICAgICB0aGlzLm9uRGlzY29ubmVjdChuZXcgRXJyb3IodGhpcy4jYm9mZkNsb3NlZCA/IE5FVFdPUktfVVNFUl9URVhUIDogTkVUV09SS19FUlJPUl9URVhUICtcbiAgICAgICAgICAgICAgJyAoJyArIGNvZGUgKyAnKScpLCBjb2RlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXRoaXMuI2JvZmZDbG9zZWQgJiYgdGhpcy5hdXRvcmVjb25uZWN0KSB7XG4gICAgICAgICAgICB0aGlzLiNib2ZmUmVjb25uZWN0KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbm4ub25tZXNzYWdlID0gKGV2dCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLm9uTWVzc2FnZSkge1xuICAgICAgICAgICAgdGhpcy5vbk1lc3NhZ2UoZXZ0LmRhdGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLiNzb2NrZXQgPSBjb25uO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSAoZm9yY2UpID0+IHtcbiAgICAgIHRoaXMuI2JvZmZTdG9wKCk7XG4gICAgICB0aGlzLmNvbm5lY3QobnVsbCwgZm9yY2UpO1xuICAgIH07XG5cbiAgICB0aGlzLmRpc2Nvbm5lY3QgPSAoKSA9PiB7XG4gICAgICB0aGlzLiNib2ZmQ2xvc2VkID0gdHJ1ZTtcbiAgICAgIHRoaXMuI2JvZmZTdG9wKCk7XG5cbiAgICAgIGlmICghdGhpcy4jc29ja2V0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuI3NvY2tldC5jbG9zZSgpO1xuICAgICAgdGhpcy4jc29ja2V0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kVGV4dCA9IChtc2cpID0+IHtcbiAgICAgIGlmICh0aGlzLiNzb2NrZXQgJiYgKHRoaXMuI3NvY2tldC5yZWFkeVN0YXRlID09IHRoaXMuI3NvY2tldC5PUEVOKSkge1xuICAgICAgICB0aGlzLiNzb2NrZXQuc2VuZChtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV2Vic29ja2V0IGlzIG5vdCBjb25uZWN0ZWRcIik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMuaXNDb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICByZXR1cm4gKHRoaXMuI3NvY2tldCAmJiAodGhpcy4jc29ja2V0LnJlYWR5U3RhdGUgPT0gdGhpcy4jc29ja2V0Lk9QRU4pKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gQ2FsbGJhY2tzOlxuXG4gIC8qKlxuICAgKiBBIGNhbGxiYWNrIHRvIHBhc3MgaW5jb21pbmcgbWVzc2FnZXMgdG8uIFNlZSB7QGxpbmsgVGlub2RlLkNvbm5lY3Rpb24jb25NZXNzYWdlfS5cbiAgICogQGNhbGxiYWNrIFRpbm9kZS5Db25uZWN0aW9uLk9uTWVzc2FnZVxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNvbm5lY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBNZXNzYWdlIHRvIHByb2Nlc3MuXG4gICAqL1xuICBvbk1lc3NhZ2UgPSB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEEgY2FsbGJhY2sgZm9yIHJlcG9ydGluZyBhIGRyb3BwZWQgY29ubmVjdGlvbi5cbiAgICogQHR5cGUge2Z1bmN0aW9ufVxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNvbm5lY3Rpb24jXG4gICAqL1xuICBvbkRpc2Nvbm5lY3QgPSB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEEgY2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgcmVhZHkgdG8gYmUgdXNlZCBmb3Igc2VuZGluZy4gRm9yIHdlYnNvY2tldHMgaXQncyBzb2NrZXQgb3BlbixcbiAgICogZm9yIGxvbmcgcG9sbGluZyBpdCdzIDxjb2RlPnJlYWR5U3RhdGU9MTwvY29kZT4gKE9QRU5FRClcbiAgICogQHR5cGUge2Z1bmN0aW9ufVxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNvbm5lY3Rpb24jXG4gICAqL1xuICBvbk9wZW4gPSB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEEgY2FsbGJhY2sgdG8gbm90aWZ5IG9mIHJlY29ubmVjdGlvbiBhdHRlbXB0cy4gU2VlIHtAbGluayBUaW5vZGUuQ29ubmVjdGlvbiNvbkF1dG9yZWNvbm5lY3RJdGVyYXRpb259LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNvbm5lY3Rpb25cbiAgICogQGNhbGxiYWNrIEF1dG9yZWNvbm5lY3RJdGVyYXRpb25UeXBlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0aW1lb3V0IC0gdGltZSB0aWxsIHRoZSBuZXh0IHJlY29ubmVjdCBhdHRlbXB0IGluIG1pbGxpc2Vjb25kcy4gPGNvZGU+LTE8L2NvZGU+IG1lYW5zIHJlY29ubmVjdCB3YXMgc2tpcHBlZC5cbiAgICogQHBhcmFtIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmVkIG9yIHJlamVjdGVkIHdoZW4gdGhlIHJlY29ubmVjdCBhdHRlbXAgY29tcGxldGVzLlxuICAgKlxuICAgKi9cbiAgLyoqXG4gICAqIEEgY2FsbGJhY2sgdG8gaW5mb3JtIHdoZW4gdGhlIG5leHQgYXR0YW1wdCB0byByZWNvbm5lY3Qgd2lsbCBoYXBwZW4gYW5kIHRvIHJlY2VpdmUgY29ubmVjdGlvbiBwcm9taXNlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkNvbm5lY3Rpb24jXG4gICAqIEB0eXBlIHtUaW5vZGUuQ29ubmVjdGlvbi5BdXRvcmVjb25uZWN0SXRlcmF0aW9uVHlwZX1cbiAgICovXG4gIG9uQXV0b3JlY29ubmVjdEl0ZXJhdGlvbiA9IHVuZGVmaW5lZDtcbn1cblxuQ29ubmVjdGlvbi5ORVRXT1JLX0VSUk9SID0gTkVUV09SS19FUlJPUjtcbkNvbm5lY3Rpb24uTkVUV09SS19FUlJPUl9URVhUID0gTkVUV09SS19FUlJPUl9URVhUO1xuQ29ubmVjdGlvbi5ORVRXT1JLX1VTRVIgPSBORVRXT1JLX1VTRVI7XG5Db25uZWN0aW9uLk5FVFdPUktfVVNFUl9URVhUID0gTkVUV09SS19VU0VSX1RFWFQ7XG4iLCIvKipcbiAqIEBmaWxlIEhlbHBlciBtZXRob2RzIGZvciBkZWFsaW5nIHdpdGggSW5kZXhlZERCIGNhY2hlIG9mIG1lc3NhZ2VzLCB1c2VycywgYW5kIHRvcGljcy5cbiAqXG4gKiBAY29weXJpZ2h0IDIwMTUtMjAyMiBUaW5vZGUgTExDLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbi8vIE5PVEUgVE8gREVWRUxPUEVSUzpcbi8vIExvY2FsaXphYmxlIHN0cmluZ3Mgc2hvdWxkIGJlIGRvdWJsZSBxdW90ZWQgXCLRgdGC0YDQvtC60LAg0L3QsCDQtNGA0YPQs9C+0Lwg0Y/Qt9GL0LrQtVwiLFxuLy8gbm9uLWxvY2FsaXphYmxlIHN0cmluZ3Mgc2hvdWxkIGJlIHNpbmdsZSBxdW90ZWQgJ25vbi1sb2NhbGl6ZWQnLlxuXG5jb25zdCBEQl9WRVJTSU9OID0gMTtcbmNvbnN0IERCX05BTUUgPSAndGlub2RlLXdlYic7XG5cbmxldCBJREJQcm92aWRlcjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgREIge1xuICAjb25FcnJvciA9IF8gPT4ge307XG4gICNsb2dnZXIgPSBfID0+IHt9O1xuXG4gIC8vIEluc3RhbmNlIG9mIEluZGV4REIuXG4gIGRiID0gbnVsbDtcbiAgLy8gSW5kaWNhdG9yIHRoYXQgdGhlIGNhY2hlIGlzIGRpc2FibGVkLlxuICBkaXNhYmxlZCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKG9uRXJyb3IsIGxvZ2dlcikge1xuICAgIHRoaXMuI29uRXJyb3IgPSBvbkVycm9yIHx8IHRoaXMuI29uRXJyb3I7XG4gICAgdGhpcy4jbG9nZ2VyID0gbG9nZ2VyIHx8IHRoaXMuI2xvZ2dlcjtcbiAgfVxuXG4gICNtYXBPYmplY3RzKHNvdXJjZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICBpZiAoIXRoaXMuZGIpIHtcbiAgICAgIHJldHVybiBkaXNhYmxlZCA/XG4gICAgICAgIFByb21pc2UucmVzb2x2ZShbXSkgOlxuICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJub3QgaW5pdGlhbGl6ZWRcIikpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0cnggPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFtzb3VyY2VdKTtcbiAgICAgIHRyeC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ21hcE9iamVjdHMnLCBzb3VyY2UsIGV2ZW50LnRhcmdldC5lcnJvcik7XG4gICAgICAgIHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgfTtcbiAgICAgIHRyeC5vYmplY3RTdG9yZShzb3VyY2UpLmdldEFsbCgpLm9uc3VjY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICBldmVudC50YXJnZXQucmVzdWx0LmZvckVhY2goKHRvcGljKSA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjay5jYWxsKGNvbnRleHQsIHRvcGljKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKGV2ZW50LnRhcmdldC5yZXN1bHQpO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHBlcnNpc3RlbnQgY2FjaGU6IG9wZW4gb3IgY3JlYXRlL3VwZ3JhZGUgaWYgbmVlZGVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gcHJvbWlzZSB0byBiZSByZXNvbHZlZC9yZWplY3RlZCB3aGVuIHRoZSBEQiBpcyBpbml0aWFsaXplZC5cbiAgICovXG4gIGluaXREYXRhYmFzZSgpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gT3BlbiB0aGUgZGF0YWJhc2UgYW5kIGluaXRpYWxpemUgY2FsbGJhY2tzLlxuICAgICAgY29uc3QgcmVxID0gSURCUHJvdmlkZXIub3BlbihEQl9OQU1FLCBEQl9WRVJTSU9OKTtcbiAgICAgIHJlcS5vbnN1Y2Nlc3MgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5kYiA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgcmVzb2x2ZSh0aGlzLmRiKTtcbiAgICAgIH07XG4gICAgICByZXEub25lcnJvciA9IChldmVudCkgPT4ge1xuICAgICAgICB0aGlzLiNsb2dnZXIoJ1BDYWNoZScsIFwiZmFpbGVkIHRvIGluaXRpYWxpemVcIiwgZXZlbnQpO1xuICAgICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgICAgdGhpcy4jb25FcnJvcihldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgfTtcbiAgICAgIHJlcS5vbnVwZ3JhZGVuZWVkZWQgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5kYiA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG5cbiAgICAgICAgdGhpcy5kYi5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgdGhpcy4jbG9nZ2VyKCdQQ2FjaGUnLCBcImZhaWxlZCB0byBjcmVhdGUgc3RvcmFnZVwiLCBldmVudCk7XG4gICAgICAgICAgdGhpcy4jb25FcnJvcihldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEluZGl2aWR1YWwgb2JqZWN0IHN0b3Jlcy5cbiAgICAgICAgLy8gT2JqZWN0IHN0b3JlICh0YWJsZSkgZm9yIHRvcGljcy4gVGhlIHByaW1hcnkga2V5IGlzIHRvcGljIG5hbWUuXG4gICAgICAgIHRoaXMuZGIuY3JlYXRlT2JqZWN0U3RvcmUoJ3RvcGljJywge1xuICAgICAgICAgIGtleVBhdGg6ICduYW1lJ1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBVc2VycyBvYmplY3Qgc3RvcmUuIFVJRCBpcyB0aGUgcHJpbWFyeSBrZXkuXG4gICAgICAgIHRoaXMuZGIuY3JlYXRlT2JqZWN0U3RvcmUoJ3VzZXInLCB7XG4gICAgICAgICAga2V5UGF0aDogJ3VpZCdcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3Vic2NyaXB0aW9ucyBvYmplY3Qgc3RvcmUgdG9waWMgPC0+IHVzZXIuIFRvcGljIG5hbWUgKyBVSUQgaXMgdGhlIHByaW1hcnkga2V5LlxuICAgICAgICB0aGlzLmRiLmNyZWF0ZU9iamVjdFN0b3JlKCdzdWJzY3JpcHRpb24nLCB7XG4gICAgICAgICAga2V5UGF0aDogWyd0b3BpYycsICd1aWQnXVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNZXNzYWdlcyBvYmplY3Qgc3RvcmUuIFRoZSBwcmltYXJ5IGtleSBpcyB0b3BpYyBuYW1lICsgc2VxLlxuICAgICAgICB0aGlzLmRiLmNyZWF0ZU9iamVjdFN0b3JlKCdtZXNzYWdlJywge1xuICAgICAgICAgIGtleVBhdGg6IFsndG9waWMnLCAnc2VxJ11cbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBwZXJzaXN0ZW50IGNhY2hlLlxuICAgKi9cbiAgZGVsZXRlRGF0YWJhc2UoKSB7XG4gICAgLy8gQ2xvc2UgY29ubmVjdGlvbiwgb3RoZXJ3aXNlIG9wZXJhdGlvbnMgd2lsbCBmYWlsIHdpdGggJ29uYmxvY2tlZCcuXG4gICAgaWYgKHRoaXMuZGIpIHtcbiAgICAgIHRoaXMuZGIuY2xvc2UoKTtcbiAgICAgIHRoaXMuZGIgPSBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgcmVxID0gSURCUHJvdmlkZXIuZGVsZXRlRGF0YWJhc2UoREJfTkFNRSk7XG4gICAgICByZXEub25ibG9ja2VkID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmRiKSB7XG4gICAgICAgICAgdGhpcy5kYi5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihcImJsb2NrZWRcIik7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ2RlbGV0ZURhdGFiYXNlJywgZXJyKTtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9O1xuICAgICAgcmVxLm9uc3VjY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICB0aGlzLmRiID0gbnVsbDtcbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IHRydWU7XG4gICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICB9O1xuICAgICAgcmVxLm9uZXJyb3IgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy4jbG9nZ2VyKCdQQ2FjaGUnLCAnZGVsZXRlRGF0YWJhc2UnLCBldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgcGVyc2lzdGVudCBjYWNoZSBpcyByZWFkeSBmb3IgdXNlLlxuICAgKiBAbWVtYmVyT2YgREJcbiAgICogQHJldHVybnMge2Jvb2xlYW59IDxjb2RlPnRydWU8L2NvZGU+IGlmIGNhY2hlIGlzIHJlYWR5LCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxuICAgKi9cbiAgaXNSZWFkeSgpIHtcbiAgICByZXR1cm4gISF0aGlzLmRiO1xuICB9XG5cbiAgLy8gVG9waWNzLlxuXG4gIC8qKlxuICAgKiBTYXZlIHRvIGNhY2hlIG9yIHVwZGF0ZSB0b3BpYyBpbiBwZXJzaXN0ZW50IGNhY2hlLlxuICAgKiBAbWVtYmVyT2YgREJcbiAgICogQHBhcmFtIHtUb3BpY30gdG9waWMgLSB0b3BpYyB0byBiZSBhZGRlZCBvciB1cGRhdGVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gcHJvbWlzZSByZXNvbHZlZC9yZWplY3RlZCBvbiBvcGVyYXRpb24gY29tcGxldGlvbi5cbiAgICovXG4gIHVwZFRvcGljKHRvcGljKSB7XG4gICAgaWYgKCF0aGlzLmlzUmVhZHkoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQgP1xuICAgICAgICBQcm9taXNlLnJlc29sdmUoKSA6XG4gICAgICAgIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIm5vdCBpbml0aWFsaXplZFwiKSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0cnggPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFsndG9waWMnXSwgJ3JlYWR3cml0ZScpO1xuICAgICAgdHJ4Lm9uY29tcGxldGUgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgcmVzb2x2ZShldmVudC50YXJnZXQucmVzdWx0KTtcbiAgICAgIH07XG4gICAgICB0cngub25lcnJvciA9IChldmVudCkgPT4ge1xuICAgICAgICB0aGlzLiNsb2dnZXIoJ1BDYWNoZScsICd1cGRUb3BpYycsIGV2ZW50LnRhcmdldC5lcnJvcik7XG4gICAgICAgIHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlcSA9IHRyeC5vYmplY3RTdG9yZSgndG9waWMnKS5nZXQodG9waWMubmFtZSk7XG4gICAgICByZXEub25zdWNjZXNzID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRyeC5vYmplY3RTdG9yZSgndG9waWMnKS5wdXQoREIuI3NlcmlhbGl6ZVRvcGljKHJlcS5yZXN1bHQsIHRvcGljKSk7XG4gICAgICAgIHRyeC5jb21taXQoKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWFyayBvciB1bm1hcmsgdG9waWMgYXMgZGVsZXRlZC5cbiAgICogQG1lbWJlck9mIERCXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gbmFtZSBvZiB0aGUgdG9waWMgdG8gbWFyayBvciB1bm1hcmsuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2UgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gb3BlcmF0aW9uIGNvbXBsZXRpb24uXG4gICAqL1xuICBtYXJrVG9waWNBc0RlbGV0ZWQobmFtZSkge1xuICAgIGlmICghdGhpcy5pc1JlYWR5KCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRpc2FibGVkID9cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkgOlxuICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJub3QgaW5pdGlhbGl6ZWRcIikpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdHJ4ID0gdGhpcy5kYi50cmFuc2FjdGlvbihbJ3RvcGljJ10sICdyZWFkd3JpdGUnKTtcbiAgICAgIHRyeC5vbmNvbXBsZXRlID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHJlc29sdmUoZXZlbnQudGFyZ2V0LnJlc3VsdCk7XG4gICAgICB9O1xuICAgICAgdHJ4Lm9uZXJyb3IgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy4jbG9nZ2VyKCdQQ2FjaGUnLCAnbWFya1RvcGljQXNEZWxldGVkJywgZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgICAgcmVqZWN0KGV2ZW50LnRhcmdldC5lcnJvcik7XG4gICAgICB9O1xuICAgICAgY29uc3QgcmVxID0gdHJ4Lm9iamVjdFN0b3JlKCd0b3BpYycpLmdldChuYW1lKTtcbiAgICAgIHJlcS5vbnN1Y2Nlc3MgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgY29uc3QgdG9waWMgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgICB0b3BpYy5fZGVsZXRlZCA9IHRydWU7XG4gICAgICAgIHRyeC5vYmplY3RTdG9yZSgndG9waWMnKS5wdXQodG9waWMpO1xuICAgICAgICB0cnguY29tbWl0KCk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSB0b3BpYyBmcm9tIHBlcnNpc3RlbnQgY2FjaGUuXG4gICAqIEBtZW1iZXJPZiBEQlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIG5hbWUgb2YgdGhlIHRvcGljIHRvIHJlbW92ZSBmcm9tIGRhdGFiYXNlLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmVkL3JlamVjdGVkIG9uIG9wZXJhdGlvbiBjb21wbGV0aW9uLlxuICAgKi9cbiAgcmVtVG9waWMobmFtZSkge1xuICAgIGlmICghdGhpcy5pc1JlYWR5KCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRpc2FibGVkID9cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkgOlxuICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJub3QgaW5pdGlhbGl6ZWRcIikpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdHJ4ID0gdGhpcy5kYi50cmFuc2FjdGlvbihbJ3RvcGljJywgJ3N1YnNjcmlwdGlvbicsICdtZXNzYWdlJ10sICdyZWFkd3JpdGUnKTtcbiAgICAgIHRyeC5vbmNvbXBsZXRlID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHJlc29sdmUoZXZlbnQudGFyZ2V0LnJlc3VsdCk7XG4gICAgICB9O1xuICAgICAgdHJ4Lm9uZXJyb3IgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy4jbG9nZ2VyKCdQQ2FjaGUnLCAncmVtVG9waWMnLCBldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgIH07XG4gICAgICB0cngub2JqZWN0U3RvcmUoJ3RvcGljJykuZGVsZXRlKElEQktleVJhbmdlLm9ubHkobmFtZSkpO1xuICAgICAgdHJ4Lm9iamVjdFN0b3JlKCdzdWJzY3JpcHRpb24nKS5kZWxldGUoSURCS2V5UmFuZ2UuYm91bmQoW25hbWUsICctJ10sIFtuYW1lLCAnfiddKSk7XG4gICAgICB0cngub2JqZWN0U3RvcmUoJ21lc3NhZ2UnKS5kZWxldGUoSURCS2V5UmFuZ2UuYm91bmQoW25hbWUsIDBdLCBbbmFtZSwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJdKSk7XG4gICAgICB0cnguY29tbWl0KCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhIGNhbGxiYWNrIGZvciBlYWNoIHN0b3JlZCB0b3BpYy5cbiAgICogQG1lbWJlck9mIERCXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrIC0gZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCB0b3BpYy5cbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgLSB0aGUgdmFsdWUgb3IgPGNvZGU+dGhpczwvY29kZT4gaW5zaWRlIHRoZSBjYWxsYmFjay5cbiAgICogQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSByZXNvbHZlZC9yZWplY3RlZCBvbiBvcGVyYXRpb24gY29tcGxldGlvbi5cbiAgICovXG4gIG1hcFRvcGljcyhjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHJldHVybiB0aGlzLiNtYXBPYmplY3RzKCd0b3BpYycsIGNhbGxiYWNrLCBjb250ZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3B5IGRhdGEgZnJvbSBzZXJpYWxpemVkIG9iamVjdCB0byB0b3BpYy5cbiAgICogQG1lbWJlck9mIERCXG4gICAqIEBwYXJhbSB7VG9waWN9IHRvcGljIC0gdGFyZ2V0IHRvIGRlc2VyaWFsaXplIHRvLlxuICAgKiBAcGFyYW0ge09iamVjdH0gc3JjIC0gc2VyaWFsaXplZCBkYXRhIHRvIGNvcHkgZnJvbS5cbiAgICovXG4gIGRlc2VyaWFsaXplVG9waWModG9waWMsIHNyYykge1xuICAgIERCLiNkZXNlcmlhbGl6ZVRvcGljKHRvcGljLCBzcmMpO1xuICB9XG5cbiAgLy8gVXNlcnMuXG4gIC8qKlxuICAgKiBBZGQgb3IgdXBkYXRlIHVzZXIgb2JqZWN0IGluIHRoZSBwZXJzaXN0ZW50IGNhY2hlLlxuICAgKiBAbWVtYmVyT2YgREJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVpZCAtIElEIG9mIHRoZSB1c2VyIHRvIHNhdmUgb3IgdXBkYXRlLlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHViIC0gdXNlcidzIDxjb2RlPnB1YmxpYzwvY29kZT4gaW5mb3JtYXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmVkL3JlamVjdGVkIG9uIG9wZXJhdGlvbiBjb21wbGV0aW9uLlxuICAgKi9cbiAgdXBkVXNlcih1aWQsIHB1Yikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMiB8fCBwdWIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gTm8gcG9pbnQgaW51cGRhdGluZyB1c2VyIHdpdGggaW52YWxpZCBkYXRhLlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaXNSZWFkeSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5kaXNhYmxlZCA/XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSgpIDpcbiAgICAgICAgUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwibm90IGluaXRpYWxpemVkXCIpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHRyeCA9IHRoaXMuZGIudHJhbnNhY3Rpb24oWyd1c2VyJ10sICdyZWFkd3JpdGUnKTtcbiAgICAgIHRyeC5vbmNvbXBsZXRlID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHJlc29sdmUoZXZlbnQudGFyZ2V0LnJlc3VsdCk7XG4gICAgICB9O1xuICAgICAgdHJ4Lm9uZXJyb3IgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy4jbG9nZ2VyKCdQQ2FjaGUnLCAndXBkVXNlcicsIGV2ZW50LnRhcmdldC5lcnJvcik7XG4gICAgICAgIHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgfTtcbiAgICAgIHRyeC5vYmplY3RTdG9yZSgndXNlcicpLnB1dCh7XG4gICAgICAgIHVpZDogdWlkLFxuICAgICAgICBwdWJsaWM6IHB1YlxuICAgICAgfSk7XG4gICAgICB0cnguY29tbWl0KCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIHVzZXIgZnJvbSBwZXJzaXN0ZW50IGNhY2hlLlxuICAgKiBAbWVtYmVyT2YgREJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVpZCAtIElEIG9mIHRoZSB1c2VyIHRvIHJlbW92ZSBmcm9tIHRoZSBjYWNoZS5cbiAgICogQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSByZXNvbHZlZC9yZWplY3RlZCBvbiBvcGVyYXRpb24gY29tcGxldGlvbi5cbiAgICovXG4gIHJlbVVzZXIodWlkKSB7XG4gICAgaWYgKCF0aGlzLmlzUmVhZHkoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQgP1xuICAgICAgICBQcm9taXNlLnJlc29sdmUoKSA6XG4gICAgICAgIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIm5vdCBpbml0aWFsaXplZFwiKSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0cnggPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFsndXNlciddLCAncmVhZHdyaXRlJyk7XG4gICAgICB0cngub25jb21wbGV0ZSA9IChldmVudCkgPT4ge1xuICAgICAgICByZXNvbHZlKGV2ZW50LnRhcmdldC5yZXN1bHQpO1xuICAgICAgfTtcbiAgICAgIHRyeC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ3JlbVVzZXInLCBldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgIH07XG4gICAgICB0cngub2JqZWN0U3RvcmUoJ3VzZXInKS5kZWxldGUoSURCS2V5UmFuZ2Uub25seSh1aWQpKTtcbiAgICAgIHRyeC5jb21taXQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGEgY2FsbGJhY2sgZm9yIGVhY2ggc3RvcmVkIHVzZXIuXG4gICAqIEBtZW1iZXJPZiBEQlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayAtIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggdG9waWMuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC0gdGhlIHZhbHVlIG9yIDxjb2RlPnRoaXM8L2NvZGU+IGluc2lkZSB0aGUgY2FsbGJhY2suXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2UgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gb3BlcmF0aW9uIGNvbXBsZXRpb24uXG4gICAqL1xuICBtYXBVc2VycyhjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHJldHVybiB0aGlzLiNtYXBPYmplY3RzKCd1c2VyJywgY2FsbGJhY2ssIGNvbnRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgYSBzaW5nbGUgdXNlciBmcm9tIHBlcnNpc3RlbnQgY2FjaGUuXG4gICAqIEBtZW1iZXJPZiBEQlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdWlkIC0gSUQgb2YgdGhlIHVzZXIgdG8gZmV0Y2ggZnJvbSBjYWNoZS5cbiAgICogQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSByZXNvbHZlZC9yZWplY3RlZCBvbiBvcGVyYXRpb24gY29tcGxldGlvbi5cbiAgICovXG4gIGdldFVzZXIodWlkKSB7XG4gICAgaWYgKCF0aGlzLmlzUmVhZHkoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQgP1xuICAgICAgICBQcm9taXNlLnJlc29sdmUoKSA6XG4gICAgICAgIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIm5vdCBpbml0aWFsaXplZFwiKSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0cnggPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFsndXNlciddKTtcbiAgICAgIHRyeC5vbmNvbXBsZXRlID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IHVzZXIgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICB1c2VyOiB1c2VyLnVpZCxcbiAgICAgICAgICBwdWJsaWM6IHVzZXIucHVibGljXG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICAgIHRyeC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ2dldFVzZXInLCBldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgIH07XG4gICAgICB0cngub2JqZWN0U3RvcmUoJ3VzZXInKS5nZXQodWlkKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFN1YnNjcmlwdGlvbnMuXG4gIC8qKlxuICAgKiBBZGQgb3IgdXBkYXRlIHN1YnNjcmlwdGlvbiBpbiBwZXJzaXN0ZW50IGNhY2hlLlxuICAgKiBAbWVtYmVyT2YgREJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljTmFtZSAtIG5hbWUgb2YgdGhlIHRvcGljIHdoaWNoIG93bnMgdGhlIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1aWQgLSBJRCBvZiB0aGUgc3Vic2NyaWJlZCB1c2VyLlxuICAgKiBAcGFyYW0ge09iamVjdH0gc3ViIC0gc3Vic2NyaXB0aW9uIHRvIHNhdmUuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2UgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gb3BlcmF0aW9uIGNvbXBsZXRpb24uXG4gICAqL1xuICB1cGRTdWJzY3JpcHRpb24odG9waWNOYW1lLCB1aWQsIHN1Yikge1xuICAgIGlmICghdGhpcy5pc1JlYWR5KCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRpc2FibGVkID9cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkgOlxuICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJub3QgaW5pdGlhbGl6ZWRcIikpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdHJ4ID0gdGhpcy5kYi50cmFuc2FjdGlvbihbJ3N1YnNjcmlwdGlvbiddLCAncmVhZHdyaXRlJyk7XG4gICAgICB0cngub25jb21wbGV0ZSA9IChldmVudCkgPT4ge1xuICAgICAgICByZXNvbHZlKGV2ZW50LnRhcmdldC5yZXN1bHQpO1xuICAgICAgfTtcbiAgICAgIHRyeC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ3VwZFN1YnNjcmlwdGlvbicsIGV2ZW50LnRhcmdldC5lcnJvcik7XG4gICAgICAgIHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgfTtcbiAgICAgIHRyeC5vYmplY3RTdG9yZSgnc3Vic2NyaXB0aW9uJykuZ2V0KFt0b3BpY05hbWUsIHVpZF0pLm9uc3VjY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICB0cngub2JqZWN0U3RvcmUoJ3N1YnNjcmlwdGlvbicpLnB1dChEQi4jc2VyaWFsaXplU3Vic2NyaXB0aW9uKGV2ZW50LnRhcmdldC5yZXN1bHQsIHRvcGljTmFtZSwgdWlkLCBzdWIpKTtcbiAgICAgICAgdHJ4LmNvbW1pdCgpO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGEgY2FsbGJhY2sgZm9yIGVhY2ggY2FjaGVkIHN1YnNjcmlwdGlvbiBpbiBhIGdpdmVuIHRvcGljLlxuICAgKiBAbWVtYmVyT2YgREJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljTmFtZSAtIG5hbWUgb2YgdGhlIHRvcGljIHdoaWNoIG93bnMgdGhlIHN1YnNjcmlwdGlvbnMuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrIC0gZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBzdWJzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC0gdGhlIHZhbHVlIG9yIDxjb2RlPnRoaXM8L2NvZGU+IGluc2lkZSB0aGUgY2FsbGJhY2suXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2UgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gb3BlcmF0aW9uIGNvbXBsZXRpb24uXG4gICAqL1xuICBtYXBTdWJzY3JpcHRpb25zKHRvcGljTmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICBpZiAoIXRoaXMuaXNSZWFkeSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5kaXNhYmxlZCA/XG4gICAgICAgIFByb21pc2UucmVzb2x2ZShbXSkgOlxuICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJub3QgaW5pdGlhbGl6ZWRcIikpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdHJ4ID0gdGhpcy5kYi50cmFuc2FjdGlvbihbJ3N1YnNjcmlwdGlvbiddKTtcbiAgICAgIHRyeC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ21hcFN1YnNjcmlwdGlvbnMnLCBldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgIH07XG4gICAgICB0cngub2JqZWN0U3RvcmUoJ3N1YnNjcmlwdGlvbicpLmdldEFsbChJREJLZXlSYW5nZS5ib3VuZChbdG9waWNOYW1lLCAnLSddLCBbdG9waWNOYW1lLCAnfiddKSkub25zdWNjZXNzID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgIGV2ZW50LnRhcmdldC5yZXN1bHQuZm9yRWFjaCgodG9waWMpID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgdG9waWMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUoZXZlbnQudGFyZ2V0LnJlc3VsdCk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLy8gTWVzc2FnZXMuXG5cbiAgLyoqXG4gICAqIFNhdmUgbWVzc2FnZSB0byBwZXJzaXN0ZW50IGNhY2hlLlxuICAgKiBAbWVtYmVyT2YgREJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljTmFtZSAtIG5hbWUgb2YgdGhlIHRvcGljIHdoaWNoIG93bnMgdGhlIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtc2cgLSBtZXNzYWdlIHRvIHNhdmUuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2UgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gb3BlcmF0aW9uIGNvbXBsZXRpb24uXG4gICAqL1xuICBhZGRNZXNzYWdlKG1zZykge1xuICAgIGlmICghdGhpcy5pc1JlYWR5KCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRpc2FibGVkID9cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkgOlxuICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJub3QgaW5pdGlhbGl6ZWRcIikpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdHJ4ID0gdGhpcy5kYi50cmFuc2FjdGlvbihbJ21lc3NhZ2UnXSwgJ3JlYWR3cml0ZScpO1xuICAgICAgdHJ4Lm9uc3VjY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICByZXNvbHZlKGV2ZW50LnRhcmdldC5yZXN1bHQpO1xuICAgICAgfTtcbiAgICAgIHRyeC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ2FkZE1lc3NhZ2UnLCBldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgIH07XG4gICAgICB0cngub2JqZWN0U3RvcmUoJ21lc3NhZ2UnKS5hZGQoREIuI3NlcmlhbGl6ZU1lc3NhZ2UobnVsbCwgbXNnKSk7XG4gICAgICB0cnguY29tbWl0KCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGRlbGl2ZXJ5IHN0YXR1cyBvZiBhIG1lc3NhZ2Ugc3RvcmVkIGluIHBlcnNpc3RlbnQgY2FjaGUuXG4gICAqIEBtZW1iZXJPZiBEQlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWNOYW1lIC0gbmFtZSBvZiB0aGUgdG9waWMgd2hpY2ggb3ducyB0aGUgbWVzc2FnZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHNlcSAtIElEIG9mIHRoZSBtZXNzYWdlIHRvIHVwZGF0ZVxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhdHVzIC0gbmV3IGRlbGl2ZXJ5IHN0YXR1cyBvZiB0aGUgbWVzc2FnZS5cbiAgICogQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSByZXNvbHZlZC9yZWplY3RlZCBvbiBvcGVyYXRpb24gY29tcGxldGlvbi5cbiAgICovXG4gIHVwZE1lc3NhZ2VTdGF0dXModG9waWNOYW1lLCBzZXEsIHN0YXR1cykge1xuICAgIGlmICghdGhpcy5pc1JlYWR5KCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRpc2FibGVkID9cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkgOlxuICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJub3QgaW5pdGlhbGl6ZWRcIikpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdHJ4ID0gdGhpcy5kYi50cmFuc2FjdGlvbihbJ21lc3NhZ2UnXSwgJ3JlYWR3cml0ZScpO1xuICAgICAgdHJ4Lm9uc3VjY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICByZXNvbHZlKGV2ZW50LnRhcmdldC5yZXN1bHQpO1xuICAgICAgfTtcbiAgICAgIHRyeC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ3VwZE1lc3NhZ2VTdGF0dXMnLCBldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgIH07XG4gICAgICBjb25zdCByZXEgPSB0cngub2JqZWN0U3RvcmUoJ21lc3NhZ2UnKS5nZXQoSURCS2V5UmFuZ2Uub25seShbdG9waWNOYW1lLCBzZXFdKSk7XG4gICAgICByZXEub25zdWNjZXNzID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IHNyYyA9IHJlcS5yZXN1bHQgfHwgZXZlbnQudGFyZ2V0LnJlc3VsdDtcbiAgICAgICAgaWYgKCFzcmMgfHwgc3JjLl9zdGF0dXMgPT0gc3RhdHVzKSB7XG4gICAgICAgICAgdHJ4LmNvbW1pdCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0cngub2JqZWN0U3RvcmUoJ21lc3NhZ2UnKS5wdXQoREIuI3NlcmlhbGl6ZU1lc3NhZ2Uoc3JjLCB7XG4gICAgICAgICAgdG9waWM6IHRvcGljTmFtZSxcbiAgICAgICAgICBzZXE6IHNlcSxcbiAgICAgICAgICBfc3RhdHVzOiBzdGF0dXNcbiAgICAgICAgfSkpO1xuICAgICAgICB0cnguY29tbWl0KCk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBvbmUgb3IgbW9yZSBtZXNzYWdlcyBmcm9tIHBlcnNpc3RlbnQgY2FjaGUuXG4gICAqIEBtZW1iZXJPZiBEQlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWNOYW1lIC0gbmFtZSBvZiB0aGUgdG9waWMgd2hpY2ggb3ducyB0aGUgbWVzc2FnZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb20gLSBpZCBvZiB0aGUgbWVzc2FnZSB0byByZW1vdmUgb3IgbG93ZXIgYm91bmRhcnkgd2hlbiByZW1vdmluZyByYW5nZSAoaW5jbHVzaXZlKS5cbiAgICogQHBhcmFtIHtudW1iZXI9fSB0byAtIHVwcGVyIGJvdW5kYXJ5IChleGNsdXNpdmUpIHdoZW4gcmVtb3ZpbmcgYSByYW5nZSBvZiBtZXNzYWdlcy5cbiAgICogQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSByZXNvbHZlZC9yZWplY3RlZCBvbiBvcGVyYXRpb24gY29tcGxldGlvbi5cbiAgICovXG4gIHJlbU1lc3NhZ2VzKHRvcGljTmFtZSwgZnJvbSwgdG8pIHtcbiAgICBpZiAoIXRoaXMuaXNSZWFkeSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5kaXNhYmxlZCA/XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSgpIDpcbiAgICAgICAgUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwibm90IGluaXRpYWxpemVkXCIpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGlmICghZnJvbSAmJiAhdG8pIHtcbiAgICAgICAgZnJvbSA9IDA7XG4gICAgICAgIHRvID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI7XG4gICAgICB9XG4gICAgICBjb25zdCByYW5nZSA9IHRvID4gMCA/IElEQktleVJhbmdlLmJvdW5kKFt0b3BpY05hbWUsIGZyb21dLCBbdG9waWNOYW1lLCB0b10sIGZhbHNlLCB0cnVlKSA6XG4gICAgICAgIElEQktleVJhbmdlLm9ubHkoW3RvcGljTmFtZSwgZnJvbV0pO1xuICAgICAgY29uc3QgdHJ4ID0gdGhpcy5kYi50cmFuc2FjdGlvbihbJ21lc3NhZ2UnXSwgJ3JlYWR3cml0ZScpO1xuICAgICAgdHJ4Lm9uc3VjY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICByZXNvbHZlKGV2ZW50LnRhcmdldC5yZXN1bHQpO1xuICAgICAgfTtcbiAgICAgIHRyeC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ3JlbU1lc3NhZ2VzJywgZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICAgICAgcmVqZWN0KGV2ZW50LnRhcmdldC5lcnJvcik7XG4gICAgICB9O1xuICAgICAgdHJ4Lm9iamVjdFN0b3JlKCdtZXNzYWdlJykuZGVsZXRlKHJhbmdlKTtcbiAgICAgIHRyeC5jb21taXQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBtZXNzYWdlcyBmcm9tIHBlcnNpc3RlbnQgc3RvcmUuXG4gICAqIEBtZW1iZXJPZiBEQlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWNOYW1lIC0gbmFtZSBvZiB0aGUgdG9waWMgdG8gcmV0cmlldmUgbWVzc2FnZXMgZnJvbS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgdG8gY2FsbCBmb3IgZWFjaCByZXRyaWV2ZWQgbWVzc2FnZS5cbiAgICogQHBhcmFtIHtPYmplY3R9IHF1ZXJ5IC0gcGFyYW1ldGVycyBvZiB0aGUgbWVzc2FnZSByYW5nZSB0byByZXRyaWV2ZS5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBxdWVyeS5zaW5jZSAtIHRoZSBsZWFzdCBtZXNzYWdlIElEIHRvIHJldHJpZXZlIChpbmNsdXNpdmUpLlxuICAgKiBAcGFyYW0ge251bWJlcj19IHF1ZXJ5LmJlZm9yZSAtIHRoZSBncmVhdGVzdCBtZXNzYWdlIElEIHRvIHJldHJpZXZlIChleGNsdXNpdmUpLlxuICAgKiBAcGFyYW0ge251bWJlcj19IHF1ZXJ5LmxpbWl0IC0gdGhlIG1heGltdW0gbnVtYmVyIG9mIG1lc3NhZ2VzIHRvIHJldHJpZXZlLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmVkL3JlamVjdGVkIG9uIG9wZXJhdGlvbiBjb21wbGV0aW9uLlxuICAgKi9cbiAgcmVhZE1lc3NhZ2VzKHRvcGljTmFtZSwgcXVlcnksIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgaWYgKCF0aGlzLmlzUmVhZHkoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQgP1xuICAgICAgICBQcm9taXNlLnJlc29sdmUoW10pIDpcbiAgICAgICAgUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwibm90IGluaXRpYWxpemVkXCIpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHF1ZXJ5ID0gcXVlcnkgfHwge307XG4gICAgICBjb25zdCBzaW5jZSA9IHF1ZXJ5LnNpbmNlID4gMCA/IHF1ZXJ5LnNpbmNlIDogMDtcbiAgICAgIGNvbnN0IGJlZm9yZSA9IHF1ZXJ5LmJlZm9yZSA+IDAgPyBxdWVyeS5iZWZvcmUgOiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbiAgICAgIGNvbnN0IGxpbWl0ID0gcXVlcnkubGltaXQgfCAwO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICAgIGNvbnN0IHJhbmdlID0gSURCS2V5UmFuZ2UuYm91bmQoW3RvcGljTmFtZSwgc2luY2VdLCBbdG9waWNOYW1lLCBiZWZvcmVdLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICBjb25zdCB0cnggPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFsnbWVzc2FnZSddKTtcbiAgICAgIHRyeC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuI2xvZ2dlcignUENhY2hlJywgJ3JlYWRNZXNzYWdlcycsIGV2ZW50LnRhcmdldC5lcnJvcik7XG4gICAgICAgIHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgfTtcbiAgICAgIC8vIEl0ZXJhdGUgaW4gZGVzY2VuZGluZyBvcmRlci5cbiAgICAgIHRyeC5vYmplY3RTdG9yZSgnbWVzc2FnZScpLm9wZW5DdXJzb3IocmFuZ2UsICdwcmV2Jykub25zdWNjZXNzID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGN1cnNvciA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG4gICAgICAgIGlmIChjdXJzb3IpIHtcbiAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgY3Vyc29yLnZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2goY3Vyc29yLnZhbHVlKTtcbiAgICAgICAgICBpZiAobGltaXQgPD0gMCB8fCByZXN1bHQubGVuZ3RoIDwgbGltaXQpIHtcbiAgICAgICAgICAgIGN1cnNvci5jb250aW51ZSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFByaXZhdGUgbWV0aG9kcy5cblxuICAvLyBTZXJpYWxpemFibGUgdG9waWMgZmllbGRzLlxuICBzdGF0aWMgI3RvcGljX2ZpZWxkcyA9IFsnY3JlYXRlZCcsICd1cGRhdGVkJywgJ2RlbGV0ZWQnLCAncmVhZCcsICdyZWN2JywgJ3NlcScsICdjbGVhcicsICdkZWZhY3MnLFxuICAgICdjcmVkcycsICdwdWJsaWMnLCAndHJ1c3RlZCcsICdwcml2YXRlJywgJ3RvdWNoZWQnLCAnX2RlbGV0ZWQnXG4gIF07XG5cbiAgLy8gQ29weSBkYXRhIGZyb20gc3JjIHRvIFRvcGljIG9iamVjdC5cbiAgc3RhdGljICNkZXNlcmlhbGl6ZVRvcGljKHRvcGljLCBzcmMpIHtcbiAgICBEQi4jdG9waWNfZmllbGRzLmZvckVhY2goKGYpID0+IHtcbiAgICAgIGlmIChzcmMuaGFzT3duUHJvcGVydHkoZikpIHtcbiAgICAgICAgdG9waWNbZl0gPSBzcmNbZl07XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc3JjLnRhZ3MpKSB7XG4gICAgICB0b3BpYy5fdGFncyA9IHNyYy50YWdzO1xuICAgIH1cbiAgICBpZiAoc3JjLmFjcykge1xuICAgICAgdG9waWMuc2V0QWNjZXNzTW9kZShzcmMuYWNzKTtcbiAgICB9XG4gICAgdG9waWMuc2VxIHw9IDA7XG4gICAgdG9waWMucmVhZCB8PSAwO1xuICAgIHRvcGljLnVucmVhZCA9IE1hdGgubWF4KDAsIHRvcGljLnNlcSAtIHRvcGljLnJlYWQpO1xuICB9XG5cbiAgLy8gQ29weSB2YWx1ZXMgZnJvbSAnc3JjJyB0byAnZHN0Jy4gQWxsb2NhdGUgZHN0IGlmIGl0J3MgbnVsbCBvciB1bmRlZmluZWQuXG4gIHN0YXRpYyAjc2VyaWFsaXplVG9waWMoZHN0LCBzcmMpIHtcbiAgICBjb25zdCByZXMgPSBkc3QgfHwge1xuICAgICAgbmFtZTogc3JjLm5hbWVcbiAgICB9O1xuICAgIERCLiN0b3BpY19maWVsZHMuZm9yRWFjaCgoZikgPT4ge1xuICAgICAgaWYgKHNyYy5oYXNPd25Qcm9wZXJ0eShmKSkge1xuICAgICAgICByZXNbZl0gPSBzcmNbZl07XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc3JjLl90YWdzKSkge1xuICAgICAgcmVzLnRhZ3MgPSBzcmMuX3RhZ3M7XG4gICAgfVxuICAgIGlmIChzcmMuYWNzKSB7XG4gICAgICByZXMuYWNzID0gc3JjLmdldEFjY2Vzc01vZGUoKS5qc29uSGVscGVyKCk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBzdGF0aWMgI3NlcmlhbGl6ZVN1YnNjcmlwdGlvbihkc3QsIHRvcGljTmFtZSwgdWlkLCBzdWIpIHtcbiAgICBjb25zdCBmaWVsZHMgPSBbJ3VwZGF0ZWQnLCAnbW9kZScsICdyZWFkJywgJ3JlY3YnLCAnY2xlYXInLCAnbGFzdFNlZW4nLCAndXNlckFnZW50J107XG4gICAgY29uc3QgcmVzID0gZHN0IHx8IHtcbiAgICAgIHRvcGljOiB0b3BpY05hbWUsXG4gICAgICB1aWQ6IHVpZFxuICAgIH07XG5cbiAgICBmaWVsZHMuZm9yRWFjaCgoZikgPT4ge1xuICAgICAgaWYgKHN1Yi5oYXNPd25Qcm9wZXJ0eShmKSkge1xuICAgICAgICByZXNbZl0gPSBzdWJbZl07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgc3RhdGljICNzZXJpYWxpemVNZXNzYWdlKGRzdCwgbXNnKSB7XG4gICAgLy8gU2VyaWFsaXphYmxlIGZpZWxkcy5cbiAgICBjb25zdCBmaWVsZHMgPSBbJ3RvcGljJywgJ3NlcScsICd0cycsICdfc3RhdHVzJywgJ2Zyb20nLCAnaGVhZCcsICdjb250ZW50J107XG4gICAgY29uc3QgcmVzID0gZHN0IHx8IHt9O1xuICAgIGZpZWxkcy5mb3JFYWNoKChmKSA9PiB7XG4gICAgICBpZiAobXNnLmhhc093blByb3BlcnR5KGYpKSB7XG4gICAgICAgIHJlc1tmXSA9IG1zZ1tmXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvIHVzZSBEQiBpbiBhIG5vbiBicm93c2VyIGNvbnRleHQsIHN1cHBseSBpbmRleGVkREIgcHJvdmlkZXIuXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlcm9mIERCXG4gICAqIEBwYXJhbSBpZGJQcm92aWRlciBpbmRleGVkREIgcHJvdmlkZXIsIGUuZy4gZm9yIG5vZGUgPGNvZGU+cmVxdWlyZSgnZmFrZS1pbmRleGVkZGInKTwvY29kZT4uXG4gICAqL1xuICBzdGF0aWMgc2V0RGF0YWJhc2VQcm92aWRlcihpZGJQcm92aWRlcikge1xuICAgIElEQlByb3ZpZGVyID0gaWRiUHJvdmlkZXI7XG4gIH1cbn1cbiIsIi8qKlxuICogQGNvcHlyaWdodCAyMDE1LTIwMjIgVGlub2RlIExMQy5cbiAqIEBzdW1tYXJ5IE1pbmltYWxseSByaWNoIHRleHQgcmVwcmVzZW50YXRpb24gYW5kIGZvcm1hdHRpbmcgZm9yIFRpbm9kZS5cbiAqIEBsaWNlbnNlIEFwYWNoZSAyLjBcbiAqXG4gKiBAZmlsZSBCYXNpYyBwYXJzZXIgYW5kIGZvcm1hdHRlciBmb3IgdmVyeSBzaW1wbGUgdGV4dCBtYXJrdXAuIE1vc3RseSB0YXJnZXRlZCBhdFxuICogbW9iaWxlIHVzZSBjYXNlcyBzaW1pbGFyIHRvIFRlbGVncmFtLCBXaGF0c0FwcCwgYW5kIEZCIE1lc3Nlbmdlci5cbiAqXG4gKiA8cD5TdXBwb3J0cyBjb252ZXJzaW9uIG9mIHVzZXIga2V5Ym9hcmQgaW5wdXQgdG8gZm9ybWF0dGVkIHRleHQ6PC9wPlxuICogPHVsPlxuICogICA8bGk+KmFiYyogJnJhcnI7IDxiPmFiYzwvYj48L2xpPlxuICogICA8bGk+X2FiY18gJnJhcnI7IDxpPmFiYzwvaT48L2xpPlxuICogICA8bGk+fmFiY34gJnJhcnI7IDxkZWw+YWJjPC9kZWw+PC9saT5cbiAqICAgPGxpPmBhYmNgICZyYXJyOyA8dHQ+YWJjPC90dD48L2xpPlxuICogPC91bD5cbiAqIEFsc28gc3VwcG9ydHMgZm9ybXMgYW5kIGJ1dHRvbnMuXG4gKlxuICogTmVzdGVkIGZvcm1hdHRpbmcgaXMgc3VwcG9ydGVkLCBlLmcuICphYmMgX2RlZl8qIC0+IDxiPmFiYyA8aT5kZWY8L2k+PC9iPlxuICogVVJMcywgQG1lbnRpb25zLCBhbmQgI2hhc2h0YWdzIGFyZSBleHRyYWN0ZWQgYW5kIGNvbnZlcnRlZCBpbnRvIGxpbmtzLlxuICogRm9ybXMgYW5kIGJ1dHRvbnMgY2FuIGJlIGFkZGVkIHByb2NlZHVyYWxseS5cbiAqIEpTT04gZGF0YSByZXByZXNlbnRhdGlvbiBpcyBpbnNwaXJlZCBieSBEcmFmdC5qcyByYXcgZm9ybWF0dGluZy5cbiAqXG4gKlxuICogQGV4YW1wbGVcbiAqIFRleHQ6XG4gKiA8cHJlPlxuICogICAgIHRoaXMgaXMgKmJvbGQqLCBgY29kZWAgYW5kIF9pdGFsaWNfLCB+c3RyaWtlflxuICogICAgIGNvbWJpbmVkICpib2xkIGFuZCBfaXRhbGljXypcbiAqICAgICBhbiB1cmw6IGh0dHBzOi8vd3d3LmV4YW1wbGUuY29tL2FiYyNmcmFnbWVudCBhbmQgYW5vdGhlciBfd3d3LnRpbm9kZS5jb19cbiAqICAgICB0aGlzIGlzIGEgQG1lbnRpb24gYW5kIGEgI2hhc2h0YWcgaW4gYSBzdHJpbmdcbiAqICAgICBzZWNvbmQgI2hhc2h0YWdcbiAqIDwvcHJlPlxuICpcbiAqICBTYW1wbGUgSlNPTiByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGV4dCBhYm92ZTpcbiAqICB7XG4gKiAgICAgXCJ0eHRcIjogXCJ0aGlzIGlzIGJvbGQsIGNvZGUgYW5kIGl0YWxpYywgc3RyaWtlIGNvbWJpbmVkIGJvbGQgYW5kIGl0YWxpYyBhbiB1cmw6IGh0dHBzOi8vd3d3LmV4YW1wbGUuY29tL2FiYyNmcmFnbWVudCBcIiArXG4gKiAgICAgICAgICAgICBcImFuZCBhbm90aGVyIHd3dy50aW5vZGUuY28gdGhpcyBpcyBhIEBtZW50aW9uIGFuZCBhICNoYXNodGFnIGluIGEgc3RyaW5nIHNlY29uZCAjaGFzaHRhZ1wiLFxuICogICAgIFwiZm10XCI6IFtcbiAqICAgICAgICAgeyBcImF0XCI6OCwgXCJsZW5cIjo0LFwidHBcIjpcIlNUXCIgfSx7IFwiYXRcIjoxNCwgXCJsZW5cIjo0LCBcInRwXCI6XCJDT1wiIH0seyBcImF0XCI6MjMsIFwibGVuXCI6NiwgXCJ0cFwiOlwiRU1cIn0sXG4gKiAgICAgICAgIHsgXCJhdFwiOjMxLCBcImxlblwiOjYsIFwidHBcIjpcIkRMXCIgfSx7IFwidHBcIjpcIkJSXCIsIFwibGVuXCI6MSwgXCJhdFwiOjM3IH0seyBcImF0XCI6NTYsIFwibGVuXCI6NiwgXCJ0cFwiOlwiRU1cIiB9LFxuICogICAgICAgICB7IFwiYXRcIjo0NywgXCJsZW5cIjoxNSwgXCJ0cFwiOlwiU1RcIiB9LHsgXCJ0cFwiOlwiQlJcIiwgXCJsZW5cIjoxLCBcImF0XCI6NjIgfSx7IFwiYXRcIjoxMjAsIFwibGVuXCI6MTMsIFwidHBcIjpcIkVNXCIgfSxcbiAqICAgICAgICAgeyBcImF0XCI6NzEsIFwibGVuXCI6MzYsIFwia2V5XCI6MCB9LHsgXCJhdFwiOjEyMCwgXCJsZW5cIjoxMywgXCJrZXlcIjoxIH0seyBcInRwXCI6XCJCUlwiLCBcImxlblwiOjEsIFwiYXRcIjoxMzMgfSxcbiAqICAgICAgICAgeyBcImF0XCI6MTQ0LCBcImxlblwiOjgsIFwia2V5XCI6MiB9LHsgXCJhdFwiOjE1OSwgXCJsZW5cIjo4LCBcImtleVwiOjMgfSx7IFwidHBcIjpcIkJSXCIsIFwibGVuXCI6MSwgXCJhdFwiOjE3OSB9LFxuICogICAgICAgICB7IFwiYXRcIjoxODcsIFwibGVuXCI6OCwgXCJrZXlcIjozIH0seyBcInRwXCI6XCJCUlwiLCBcImxlblwiOjEsIFwiYXRcIjoxOTUgfVxuICogICAgIF0sXG4gKiAgICAgXCJlbnRcIjogW1xuICogICAgICAgICB7IFwidHBcIjpcIkxOXCIsIFwiZGF0YVwiOnsgXCJ1cmxcIjpcImh0dHBzOi8vd3d3LmV4YW1wbGUuY29tL2FiYyNmcmFnbWVudFwiIH0gfSxcbiAqICAgICAgICAgeyBcInRwXCI6XCJMTlwiLCBcImRhdGFcIjp7IFwidXJsXCI6XCJodHRwOi8vd3d3LnRpbm9kZS5jb1wiIH0gfSxcbiAqICAgICAgICAgeyBcInRwXCI6XCJNTlwiLCBcImRhdGFcIjp7IFwidmFsXCI6XCJtZW50aW9uXCIgfSB9LFxuICogICAgICAgICB7IFwidHBcIjpcIkhUXCIsIFwiZGF0YVwiOnsgXCJ2YWxcIjpcImhhc2h0YWdcIiB9IH1cbiAqICAgICBdXG4gKiAgfVxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuLy8gTk9URSBUTyBERVZFTE9QRVJTOlxuLy8gTG9jYWxpemFibGUgc3RyaW5ncyBzaG91bGQgYmUgZG91YmxlIHF1b3RlZCBcItGB0YLRgNC+0LrQsCDQvdCwINC00YDRg9Cz0L7QvCDRj9C30YvQutC1XCIsXG4vLyBub24tbG9jYWxpemFibGUgc3RyaW5ncyBzaG91bGQgYmUgc2luZ2xlIHF1b3RlZCAnbm9uLWxvY2FsaXplZCcuXG5cbmNvbnN0IE1BWF9GT1JNX0VMRU1FTlRTID0gODtcbmNvbnN0IE1BWF9QUkVWSUVXX0FUVEFDSE1FTlRTID0gMztcbmNvbnN0IE1BWF9QUkVWSUVXX0RBVEFfU0laRSA9IDY0O1xuY29uc3QgSlNPTl9NSU1FX1RZUEUgPSAnYXBwbGljYXRpb24vanNvbic7XG5jb25zdCBEUkFGVFlfTUlNRV9UWVBFID0gJ3RleHQveC1kcmFmdHknO1xuY29uc3QgQUxMT1dFRF9FTlRfRklFTERTID0gWydhY3QnLCAnaGVpZ2h0JywgJ2R1cmF0aW9uJywgJ2luY29taW5nJywgJ21pbWUnLCAnbmFtZScsICdwcmV2aWV3JyxcbiAgJ3JlZicsICdzaXplJywgJ3N0YXRlJywgJ3VybCcsICd2YWwnLCAnd2lkdGgnXG5dO1xuXG4vLyBSZWd1bGFyIGV4cHJlc3Npb25zIGZvciBwYXJzaW5nIGlubGluZSBmb3JtYXRzLiBKYXZhc2NyaXB0IGRvZXMgbm90IHN1cHBvcnQgbG9va2JlaGluZCxcbi8vIHNvIGl0J3MgYSBiaXQgbWVzc3kuXG5jb25zdCBJTkxJTkVfU1RZTEVTID0gW1xuICAvLyBTdHJvbmcgPSBib2xkLCAqYm9sZCB0ZXh0KlxuICB7XG4gICAgbmFtZTogJ1NUJyxcbiAgICBzdGFydDogLyg/Ol58W1xcV19dKShcXCopW15cXHMqXS8sXG4gICAgZW5kOiAvW15cXHMqXShcXCopKD89JHxbXFxXX10pL1xuICB9LFxuICAvLyBFbXBoZXNpemVkID0gaXRhbGljLCBfaXRhbGljIHRleHRfXG4gIHtcbiAgICBuYW1lOiAnRU0nLFxuICAgIHN0YXJ0OiAvKD86XnxcXFcpKF8pW15cXHNfXS8sXG4gICAgZW5kOiAvW15cXHNfXShfKSg/PSR8XFxXKS9cbiAgfSxcbiAgLy8gRGVsZXRlZCwgfnN0cmlrZSB0aGlzIHRob3VnaH5cbiAge1xuICAgIG5hbWU6ICdETCcsXG4gICAgc3RhcnQ6IC8oPzpefFtcXFdfXSkofilbXlxcc35dLyxcbiAgICBlbmQ6IC9bXlxcc35dKH4pKD89JHxbXFxXX10pL1xuICB9LFxuICAvLyBDb2RlIGJsb2NrIGB0aGlzIGlzIG1vbm9zcGFjZWBcbiAge1xuICAgIG5hbWU6ICdDTycsXG4gICAgc3RhcnQ6IC8oPzpefFxcVykoYClbXmBdLyxcbiAgICBlbmQ6IC9bXmBdKGApKD89JHxcXFcpL1xuICB9XG5dO1xuXG4vLyBSZWxhdGl2ZSB3ZWlnaHRzIG9mIGZvcm1hdHRpbmcgc3BhbnMuIEdyZWF0ZXIgaW5kZXggaW4gYXJyYXkgbWVhbnMgZ3JlYXRlciB3ZWlnaHQuXG5jb25zdCBGTVRfV0VJR0hUID0gWydRUSddO1xuXG4vLyBSZWdFeHBzIGZvciBlbnRpdHkgZXh0cmFjdGlvbiAoUkYgPSByZWZlcmVuY2UpXG5jb25zdCBFTlRJVFlfVFlQRVMgPSBbXG4gIC8vIFVSTHNcbiAge1xuICAgIG5hbWU6ICdMTicsXG4gICAgZGF0YU5hbWU6ICd1cmwnLFxuICAgIHBhY2s6IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgLy8gQ2hlY2sgaWYgdGhlIHByb3RvY29sIGlzIHNwZWNpZmllZCwgaWYgbm90IHVzZSBodHRwXG4gICAgICBpZiAoIS9eW2Etel0rOlxcL1xcLy9pLnRlc3QodmFsKSkge1xuICAgICAgICB2YWwgPSAnaHR0cDovLycgKyB2YWw7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICB1cmw6IHZhbFxuICAgICAgfTtcbiAgICB9LFxuICAgIHJlOiAvKD86KD86aHR0cHM/fGZ0cCk6XFwvXFwvfHd3d1xcLnxmdHBcXC4pWy1BLVowLTkrJkAjXFwvJT1+X3wkPyE6LC5dKltBLVowLTkrJkAjXFwvJT1+X3wkXS9pZ1xuICB9LFxuICAvLyBNZW50aW9ucyBAdXNlciAobXVzdCBiZSAyIG9yIG1vcmUgY2hhcmFjdGVycylcbiAge1xuICAgIG5hbWU6ICdNTicsXG4gICAgZGF0YU5hbWU6ICd2YWwnLFxuICAgIHBhY2s6IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsOiB2YWwuc2xpY2UoMSlcbiAgICAgIH07XG4gICAgfSxcbiAgICByZTogL1xcQkAoW1xccHtMfVxccHtOfV1bLl9cXHB7TH1cXHB7Tn1dKltcXHB7TH1cXHB7Tn1dKS91Z1xuICB9LFxuICAvLyBIYXNodGFncyAjaGFzaHRhZywgbGlrZSBtZXRpb24gMiBvciBtb3JlIGNoYXJhY3RlcnMuXG4gIHtcbiAgICBuYW1lOiAnSFQnLFxuICAgIGRhdGFOYW1lOiAndmFsJyxcbiAgICBwYWNrOiBmdW5jdGlvbih2YWwpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbDogdmFsLnNsaWNlKDEpXG4gICAgICB9O1xuICAgIH0sXG4gICAgcmU6IC9cXEIjKFtcXHB7TH1cXHB7Tn1dWy5fXFxwe0x9XFxwe059XSpbXFxwe0x9XFxwe059XSkvdWdcbiAgfVxuXTtcblxuLy8gSFRNTCB0YWcgbmFtZSBzdWdnZXN0aW9uc1xuY29uc3QgSFRNTF9UQUdTID0ge1xuICBBVToge1xuICAgIG5hbWU6ICdhdWRpbycsXG4gICAgaXNWb2lkOiBmYWxzZVxuICB9LFxuICBCTjoge1xuICAgIG5hbWU6ICdidXR0b24nLFxuICAgIGlzVm9pZDogZmFsc2VcbiAgfSxcbiAgQlI6IHtcbiAgICBuYW1lOiAnYnInLFxuICAgIGlzVm9pZDogdHJ1ZVxuICB9LFxuICBDTzoge1xuICAgIG5hbWU6ICd0dCcsXG4gICAgaXNWb2lkOiBmYWxzZVxuICB9LFxuICBETDoge1xuICAgIG5hbWU6ICdkZWwnLFxuICAgIGlzVm9pZDogZmFsc2VcbiAgfSxcbiAgRU06IHtcbiAgICBuYW1lOiAnaScsXG4gICAgaXNWb2lkOiBmYWxzZVxuICB9LFxuICBFWDoge1xuICAgIG5hbWU6ICcnLFxuICAgIGlzVm9pZDogdHJ1ZVxuICB9LFxuICBGTToge1xuICAgIG5hbWU6ICdkaXYnLFxuICAgIGlzVm9pZDogZmFsc2VcbiAgfSxcbiAgSEQ6IHtcbiAgICBuYW1lOiAnJyxcbiAgICBpc1ZvaWQ6IGZhbHNlXG4gIH0sXG4gIEhMOiB7XG4gICAgbmFtZTogJ3NwYW4nLFxuICAgIGlzVm9pZDogZmFsc2VcbiAgfSxcbiAgSFQ6IHtcbiAgICBuYW1lOiAnYScsXG4gICAgaXNWb2lkOiBmYWxzZVxuICB9LFxuICBJTToge1xuICAgIG5hbWU6ICdpbWcnLFxuICAgIGlzVm9pZDogZmFsc2VcbiAgfSxcbiAgTE46IHtcbiAgICBuYW1lOiAnYScsXG4gICAgaXNWb2lkOiBmYWxzZVxuICB9LFxuICBNTjoge1xuICAgIG5hbWU6ICdhJyxcbiAgICBpc1ZvaWQ6IGZhbHNlXG4gIH0sXG4gIFJXOiB7XG4gICAgbmFtZTogJ2RpdicsXG4gICAgaXNWb2lkOiBmYWxzZSxcbiAgfSxcbiAgUVE6IHtcbiAgICBuYW1lOiAnZGl2JyxcbiAgICBpc1ZvaWQ6IGZhbHNlXG4gIH0sXG4gIFNUOiB7XG4gICAgbmFtZTogJ2InLFxuICAgIGlzVm9pZDogZmFsc2VcbiAgfSxcbiAgVkM6IHtcbiAgICBuYW1lOiAnZGl2JyxcbiAgICBpc1ZvaWQ6IGZhbHNlXG4gIH0sXG59O1xuXG4vLyBDb252ZXJ0IGJhc2U2NC1lbmNvZGVkIHN0cmluZyBpbnRvIEJsb2IuXG5mdW5jdGlvbiBiYXNlNjR0b09iamVjdFVybChiNjQsIGNvbnRlbnRUeXBlLCBsb2dnZXIpIHtcbiAgaWYgKCFiNjQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgYmluID0gYXRvYihiNjQpO1xuICAgIGNvbnN0IGxlbmd0aCA9IGJpbi5sZW5ndGg7XG4gICAgY29uc3QgYnVmID0gbmV3IEFycmF5QnVmZmVyKGxlbmd0aCk7XG4gICAgY29uc3QgYXJyID0gbmV3IFVpbnQ4QXJyYXkoYnVmKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBhcnJbaV0gPSBiaW4uY2hhckNvZGVBdChpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbYnVmXSwge1xuICAgICAgdHlwZTogY29udGVudFR5cGVcbiAgICB9KSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmIChsb2dnZXIpIHtcbiAgICAgIGxvZ2dlcihcIkRyYWZ0eTogZmFpbGVkIHRvIGNvbnZlcnQgb2JqZWN0LlwiLCBlcnIubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NHRvRGF0YVVybChiNjQsIGNvbnRlbnRUeXBlKSB7XG4gIGlmICghYjY0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZSB8fCAnaW1hZ2UvanBlZyc7XG4gIHJldHVybiAnZGF0YTonICsgY29udGVudFR5cGUgKyAnO2Jhc2U2NCwnICsgYjY0O1xufVxuXG4vLyBIZWxwZXJzIGZvciBjb252ZXJ0aW5nIERyYWZ0eSB0byBIVE1MLlxuY29uc3QgREVDT1JBVE9SUyA9IHtcbiAgLy8gVmlzaWFsIHN0eWxlc1xuICBTVDoge1xuICAgIG9wZW46IF8gPT4gJzxiPicsXG4gICAgY2xvc2U6IF8gPT4gJzwvYj4nXG4gIH0sXG4gIEVNOiB7XG4gICAgb3BlbjogXyA9PiAnPGk+JyxcbiAgICBjbG9zZTogXyA9PiAnPC9pPidcbiAgfSxcbiAgREw6IHtcbiAgICBvcGVuOiBfID0+ICc8ZGVsPicsXG4gICAgY2xvc2U6IF8gPT4gJzwvZGVsPidcbiAgfSxcbiAgQ086IHtcbiAgICBvcGVuOiBfID0+ICc8dHQ+JyxcbiAgICBjbG9zZTogXyA9PiAnPC90dD4nXG4gIH0sXG4gIC8vIExpbmUgYnJlYWtcbiAgQlI6IHtcbiAgICBvcGVuOiBfID0+ICc8YnIvPicsXG4gICAgY2xvc2U6IF8gPT4gJydcbiAgfSxcbiAgLy8gSGlkZGVuIGVsZW1lbnRcbiAgSEQ6IHtcbiAgICBvcGVuOiBfID0+ICcnLFxuICAgIGNsb3NlOiBfID0+ICcnXG4gIH0sXG4gIC8vIEhpZ2hsaWdodGVkIGVsZW1lbnQuXG4gIEhMOiB7XG4gICAgb3BlbjogXyA9PiAnPHNwYW4gc3R5bGU9XCJjb2xvcjp0ZWFsXCI+JyxcbiAgICBjbG9zZTogXyA9PiAnPC9zcGFuPidcbiAgfSxcbiAgLy8gTGluayAoVVJMKVxuICBMTjoge1xuICAgIG9wZW46IChkYXRhKSA9PiB7XG4gICAgICByZXR1cm4gJzxhIGhyZWY9XCInICsgZGF0YS51cmwgKyAnXCI+JztcbiAgICB9LFxuICAgIGNsb3NlOiBfID0+ICc8L2E+JyxcbiAgICBwcm9wczogKGRhdGEpID0+IHtcbiAgICAgIHJldHVybiBkYXRhID8ge1xuICAgICAgICBocmVmOiBkYXRhLnVybCxcbiAgICAgICAgdGFyZ2V0OiAnX2JsYW5rJ1xuICAgICAgfSA6IG51bGw7XG4gICAgfSxcbiAgfSxcbiAgLy8gTWVudGlvblxuICBNTjoge1xuICAgIG9wZW46IChkYXRhKSA9PiB7XG4gICAgICByZXR1cm4gJzxhIGhyZWY9XCIjJyArIGRhdGEudmFsICsgJ1wiPic7XG4gICAgfSxcbiAgICBjbG9zZTogXyA9PiAnPC9hPicsXG4gICAgcHJvcHM6IChkYXRhKSA9PiB7XG4gICAgICByZXR1cm4gZGF0YSA/IHtcbiAgICAgICAgaWQ6IGRhdGEudmFsXG4gICAgICB9IDogbnVsbDtcbiAgICB9LFxuICB9LFxuICAvLyBIYXNodGFnXG4gIEhUOiB7XG4gICAgb3BlbjogKGRhdGEpID0+IHtcbiAgICAgIHJldHVybiAnPGEgaHJlZj1cIiMnICsgZGF0YS52YWwgKyAnXCI+JztcbiAgICB9LFxuICAgIGNsb3NlOiBfID0+ICc8L2E+JyxcbiAgICBwcm9wczogKGRhdGEpID0+IHtcbiAgICAgIHJldHVybiBkYXRhID8ge1xuICAgICAgICBpZDogZGF0YS52YWxcbiAgICAgIH0gOiBudWxsO1xuICAgIH0sXG4gIH0sXG4gIC8vIEJ1dHRvblxuICBCTjoge1xuICAgIG9wZW46IF8gPT4gJzxidXR0b24+JyxcbiAgICBjbG9zZTogXyA9PiAnPC9idXR0b24+JyxcbiAgICBwcm9wczogKGRhdGEpID0+IHtcbiAgICAgIHJldHVybiBkYXRhID8ge1xuICAgICAgICAnZGF0YS1hY3QnOiBkYXRhLmFjdCxcbiAgICAgICAgJ2RhdGEtdmFsJzogZGF0YS52YWwsXG4gICAgICAgICdkYXRhLW5hbWUnOiBkYXRhLm5hbWUsXG4gICAgICAgICdkYXRhLXJlZic6IGRhdGEucmVmXG4gICAgICB9IDogbnVsbDtcbiAgICB9LFxuICB9LFxuICAvLyBBdWRpbyByZWNvcmRpbmdcbiAgQVU6IHtcbiAgICBvcGVuOiAoZGF0YSkgPT4ge1xuICAgICAgY29uc3QgdXJsID0gZGF0YS5yZWYgfHwgYmFzZTY0dG9PYmplY3RVcmwoZGF0YS52YWwsIGRhdGEubWltZSwgRHJhZnR5LmxvZ2dlcik7XG4gICAgICByZXR1cm4gJzxhdWRpbyBjb250cm9scyBzcmM9XCInICsgdXJsICsgJ1wiPic7XG4gICAgfSxcbiAgICBjbG9zZTogXyA9PiAnPC9hdWRpbz4nLFxuICAgIHByb3BzOiAoZGF0YSkgPT4ge1xuICAgICAgaWYgKCFkYXRhKSByZXR1cm4gbnVsbDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC8vIEVtYmVkZGVkIGRhdGEgb3IgZXh0ZXJuYWwgbGluay5cbiAgICAgICAgc3JjOiBkYXRhLnJlZiB8fCBiYXNlNjR0b09iamVjdFVybChkYXRhLnZhbCwgZGF0YS5taW1lLCBEcmFmdHkubG9nZ2VyKSxcbiAgICAgICAgJ2RhdGEtcHJlbG9hZCc6IGRhdGEucmVmID8gJ21ldGFkYXRhJyA6ICdhdXRvJyxcbiAgICAgICAgJ2RhdGEtZHVyYXRpb24nOiBkYXRhLmR1cmF0aW9uLFxuICAgICAgICAnZGF0YS1uYW1lJzogZGF0YS5uYW1lLFxuICAgICAgICAnZGF0YS1zaXplJzogZGF0YS52YWwgPyAoKGRhdGEudmFsLmxlbmd0aCAqIDAuNzUpIHwgMCkgOiAoZGF0YS5zaXplIHwgMCksXG4gICAgICAgICdkYXRhLW1pbWUnOiBkYXRhLm1pbWUsXG4gICAgICB9O1xuICAgIH1cbiAgfSxcbiAgLy8gSW1hZ2VcbiAgSU06IHtcbiAgICBvcGVuOiAoZGF0YSkgPT4ge1xuICAgICAgLy8gRG9uJ3QgdXNlIGRhdGEucmVmIGZvciBwcmV2aWV3OiBpdCdzIGEgc2VjdXJpdHkgcmlzay5cbiAgICAgIGNvbnN0IHRtcFByZXZpZXdVcmwgPSBiYXNlNjR0b0RhdGFVcmwoZGF0YS5fdGVtcFByZXZpZXcsIGRhdGEubWltZSk7XG4gICAgICBjb25zdCBwcmV2aWV3VXJsID0gYmFzZTY0dG9PYmplY3RVcmwoZGF0YS52YWwsIGRhdGEubWltZSwgRHJhZnR5LmxvZ2dlcik7XG4gICAgICBjb25zdCBkb3dubG9hZFVybCA9IGRhdGEucmVmIHx8IHByZXZpZXdVcmw7XG4gICAgICByZXR1cm4gKGRhdGEubmFtZSA/ICc8YSBocmVmPVwiJyArIGRvd25sb2FkVXJsICsgJ1wiIGRvd25sb2FkPVwiJyArIGRhdGEubmFtZSArICdcIj4nIDogJycpICtcbiAgICAgICAgJzxpbWcgc3JjPVwiJyArICh0bXBQcmV2aWV3VXJsIHx8IHByZXZpZXdVcmwpICsgJ1wiJyArXG4gICAgICAgIChkYXRhLndpZHRoID8gJyB3aWR0aD1cIicgKyBkYXRhLndpZHRoICsgJ1wiJyA6ICcnKSArXG4gICAgICAgIChkYXRhLmhlaWdodCA/ICcgaGVpZ2h0PVwiJyArIGRhdGEuaGVpZ2h0ICsgJ1wiJyA6ICcnKSArICcgYm9yZGVyPVwiMFwiIC8+JztcbiAgICB9LFxuICAgIGNsb3NlOiAoZGF0YSkgPT4ge1xuICAgICAgcmV0dXJuIChkYXRhLm5hbWUgPyAnPC9hPicgOiAnJyk7XG4gICAgfSxcbiAgICBwcm9wczogKGRhdGEpID0+IHtcbiAgICAgIGlmICghZGF0YSkgcmV0dXJuIG51bGw7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAvLyBUZW1wb3JhcnkgcHJldmlldywgb3IgcGVybWFuZW50IHByZXZpZXcsIG9yIGV4dGVybmFsIGxpbmsuXG4gICAgICAgIHNyYzogYmFzZTY0dG9EYXRhVXJsKGRhdGEuX3RlbXBQcmV2aWV3LCBkYXRhLm1pbWUpIHx8XG4gICAgICAgICAgZGF0YS5yZWYgfHwgYmFzZTY0dG9PYmplY3RVcmwoZGF0YS52YWwsIGRhdGEubWltZSwgRHJhZnR5LmxvZ2dlciksXG4gICAgICAgIHRpdGxlOiBkYXRhLm5hbWUsXG4gICAgICAgIGFsdDogZGF0YS5uYW1lLFxuICAgICAgICAnZGF0YS13aWR0aCc6IGRhdGEud2lkdGgsXG4gICAgICAgICdkYXRhLWhlaWdodCc6IGRhdGEuaGVpZ2h0LFxuICAgICAgICAnZGF0YS1uYW1lJzogZGF0YS5uYW1lLFxuICAgICAgICAnZGF0YS1zaXplJzogZGF0YS52YWwgPyAoKGRhdGEudmFsLmxlbmd0aCAqIDAuNzUpIHwgMCkgOiAoZGF0YS5zaXplIHwgMCksXG4gICAgICAgICdkYXRhLW1pbWUnOiBkYXRhLm1pbWUsXG4gICAgICB9O1xuICAgIH0sXG4gIH0sXG4gIC8vIEZvcm0gLSBzdHJ1Y3R1cmVkIGxheW91dCBvZiBlbGVtZW50cy5cbiAgRk06IHtcbiAgICBvcGVuOiBfID0+ICc8ZGl2PicsXG4gICAgY2xvc2U6IF8gPT4gJzwvZGl2PidcbiAgfSxcbiAgLy8gUm93OiBsb2dpYyBncm91cGluZyBvZiBlbGVtZW50c1xuICBSVzoge1xuICAgIG9wZW46IF8gPT4gJzxkaXY+JyxcbiAgICBjbG9zZTogXyA9PiAnPC9kaXY+J1xuICB9LFxuICAvLyBRdW90ZWQgYmxvY2suXG4gIFFROiB7XG4gICAgb3BlbjogXyA9PiAnPGRpdj4nLFxuICAgIGNsb3NlOiBfID0+ICc8L2Rpdj4nLFxuICAgIHByb3BzOiAoZGF0YSkgPT4ge1xuICAgICAgcmV0dXJuIGRhdGEgPyB7fSA6IG51bGw7XG4gICAgfSxcbiAgfSxcbiAgLy8gVmlkZW8gY2FsbFxuICBWQzoge1xuICAgIG9wZW46IF8gPT4gJzxkaXY+JyxcbiAgICBjbG9zZTogXyA9PiAnPC9kaXY+JyxcbiAgICBwcm9wczogZGF0YSA9PiB7XG4gICAgICBpZiAoIWRhdGEpIHJldHVybiB7fTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgICdkYXRhLWR1cmF0aW9uJzogZGF0YS5kdXJhdGlvbixcbiAgICAgICAgJ2RhdGEtc3RhdGUnOiBkYXRhLnN0YXRlLFxuICAgICAgfTtcbiAgICB9XG4gIH0sXG59O1xuXG4vKipcbiAqIFRoZSBtYWluIG9iamVjdCB3aGljaCBwZXJmb3JtcyBhbGwgdGhlIGZvcm1hdHRpbmcgYWN0aW9ucy5cbiAqIEBjbGFzcyBEcmFmdHlcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5jb25zdCBEcmFmdHkgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy50eHQgPSAnJztcbiAgdGhpcy5mbXQgPSBbXTtcbiAgdGhpcy5lbnQgPSBbXTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIERyYWZ0eSBkb2N1bWVudCB0byBhIHBsYWluIHRleHQgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwbGFpblRleHQgLSBzdHJpbmcgdG8gdXNlIGFzIERyYWZ0eSBjb250ZW50LlxuICpcbiAqIEByZXR1cm5zIG5ldyBEcmFmdHkgZG9jdW1lbnQgb3IgbnVsbCBpcyBwbGFpblRleHQgaXMgbm90IGEgc3RyaW5nIG9yIHVuZGVmaW5lZC5cbiAqL1xuRHJhZnR5LmluaXQgPSBmdW5jdGlvbihwbGFpblRleHQpIHtcbiAgaWYgKHR5cGVvZiBwbGFpblRleHQgPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBwbGFpblRleHQgPSAnJztcbiAgfSBlbHNlIGlmICh0eXBlb2YgcGxhaW5UZXh0ICE9ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHR4dDogcGxhaW5UZXh0XG4gIH07XG59XG5cbi8qKlxuICogUGFyc2UgcGxhaW4gdGV4dCBpbnRvIERyYWZ0eSBkb2N1bWVudC5cbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEBzdGF0aWNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGVudCAtIHBsYWluLXRleHQgY29udGVudCB0byBwYXJzZS5cbiAqIEByZXR1cm4ge0RyYWZ0eX0gcGFyc2VkIGRvY3VtZW50IG9yIG51bGwgaWYgdGhlIHNvdXJjZSBpcyBub3QgcGxhaW4gdGV4dC5cbiAqL1xuRHJhZnR5LnBhcnNlID0gZnVuY3Rpb24oY29udGVudCkge1xuICAvLyBNYWtlIHN1cmUgd2UgYXJlIHBhcnNpbmcgc3RyaW5ncyBvbmx5LlxuICBpZiAodHlwZW9mIGNvbnRlbnQgIT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIFNwbGl0IHRleHQgaW50byBsaW5lcy4gSXQgbWFrZXMgZnVydGhlciBwcm9jZXNzaW5nIGVhc2llci5cbiAgY29uc3QgbGluZXMgPSBjb250ZW50LnNwbGl0KC9cXHI/XFxuLyk7XG5cbiAgLy8gSG9sZHMgZW50aXRpZXMgcmVmZXJlbmNlZCBmcm9tIHRleHRcbiAgY29uc3QgZW50aXR5TWFwID0gW107XG4gIGNvbnN0IGVudGl0eUluZGV4ID0ge307XG5cbiAgLy8gUHJvY2Vzc2luZyBsaW5lcyBvbmUgYnkgb25lLCBob2xkIGludGVybWVkaWF0ZSByZXN1bHQgaW4gYmx4LlxuICBjb25zdCBibHggPSBbXTtcbiAgbGluZXMuZm9yRWFjaCgobGluZSkgPT4ge1xuICAgIGxldCBzcGFucyA9IFtdO1xuICAgIGxldCBlbnRpdGllcztcblxuICAgIC8vIEZpbmQgZm9ybWF0dGVkIHNwYW5zIGluIHRoZSBzdHJpbmcuXG4gICAgLy8gVHJ5IHRvIG1hdGNoIGVhY2ggc3R5bGUuXG4gICAgSU5MSU5FX1NUWUxFUy5mb3JFYWNoKCh0YWcpID0+IHtcbiAgICAgIC8vIEVhY2ggc3R5bGUgY291bGQgYmUgbWF0Y2hlZCBtdWx0aXBsZSB0aW1lcy5cbiAgICAgIHNwYW5zID0gc3BhbnMuY29uY2F0KHNwYW5uaWZ5KGxpbmUsIHRhZy5zdGFydCwgdGFnLmVuZCwgdGFnLm5hbWUpKTtcbiAgICB9KTtcblxuICAgIGxldCBibG9jaztcbiAgICBpZiAoc3BhbnMubGVuZ3RoID09IDApIHtcbiAgICAgIGJsb2NrID0ge1xuICAgICAgICB0eHQ6IGxpbmVcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFNvcnQgc3BhbnMgYnkgc3R5bGUgb2NjdXJlbmNlIGVhcmx5IC0+IGxhdGUsIHRoZW4gYnkgbGVuZ3RoOiBmaXJzdCBsb25nIHRoZW4gc2hvcnQuXG4gICAgICBzcGFucy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgIGNvbnN0IGRpZmYgPSBhLmF0IC0gYi5hdDtcbiAgICAgICAgcmV0dXJuIGRpZmYgIT0gMCA/IGRpZmYgOiBiLmVuZCAtIGEuZW5kO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIENvbnZlcnQgYW4gYXJyYXkgb2YgcG9zc2libHkgb3ZlcmxhcHBpbmcgc3BhbnMgaW50byBhIHRyZWUuXG4gICAgICBzcGFucyA9IHRvU3BhblRyZWUoc3BhbnMpO1xuXG4gICAgICAvLyBCdWlsZCBhIHRyZWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVudGlyZSBzdHJpbmcsIG5vdFxuICAgICAgLy8ganVzdCB0aGUgZm9ybWF0dGVkIHBhcnRzLlxuICAgICAgY29uc3QgY2h1bmtzID0gY2h1bmtpZnkobGluZSwgMCwgbGluZS5sZW5ndGgsIHNwYW5zKTtcblxuICAgICAgY29uc3QgZHJhZnR5ID0gZHJhZnRpZnkoY2h1bmtzLCAwKTtcblxuICAgICAgYmxvY2sgPSB7XG4gICAgICAgIHR4dDogZHJhZnR5LnR4dCxcbiAgICAgICAgZm10OiBkcmFmdHkuZm10XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEV4dHJhY3QgZW50aXRpZXMgZnJvbSB0aGUgY2xlYW5lZCB1cCBzdHJpbmcuXG4gICAgZW50aXRpZXMgPSBleHRyYWN0RW50aXRpZXMoYmxvY2sudHh0KTtcbiAgICBpZiAoZW50aXRpZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgcmFuZ2VzID0gW107XG4gICAgICBmb3IgKGxldCBpIGluIGVudGl0aWVzKSB7XG4gICAgICAgIC8vIHtvZmZzZXQ6IG1hdGNoWydpbmRleCddLCB1bmlxdWU6IG1hdGNoWzBdLCBsZW46IG1hdGNoWzBdLmxlbmd0aCwgZGF0YTogZW50LnBhY2tlcigpLCB0eXBlOiBlbnQubmFtZX1cbiAgICAgICAgY29uc3QgZW50aXR5ID0gZW50aXRpZXNbaV07XG4gICAgICAgIGxldCBpbmRleCA9IGVudGl0eUluZGV4W2VudGl0eS51bmlxdWVdO1xuICAgICAgICBpZiAoIWluZGV4KSB7XG4gICAgICAgICAgaW5kZXggPSBlbnRpdHlNYXAubGVuZ3RoO1xuICAgICAgICAgIGVudGl0eUluZGV4W2VudGl0eS51bmlxdWVdID0gaW5kZXg7XG4gICAgICAgICAgZW50aXR5TWFwLnB1c2goe1xuICAgICAgICAgICAgdHA6IGVudGl0eS50eXBlLFxuICAgICAgICAgICAgZGF0YTogZW50aXR5LmRhdGFcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByYW5nZXMucHVzaCh7XG4gICAgICAgICAgYXQ6IGVudGl0eS5vZmZzZXQsXG4gICAgICAgICAgbGVuOiBlbnRpdHkubGVuLFxuICAgICAgICAgIGtleTogaW5kZXhcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBibG9jay5lbnQgPSByYW5nZXM7XG4gICAgfVxuXG4gICAgYmx4LnB1c2goYmxvY2spO1xuICB9KTtcblxuICBjb25zdCByZXN1bHQgPSB7XG4gICAgdHh0OiAnJ1xuICB9O1xuXG4gIC8vIE1lcmdlIGxpbmVzIGFuZCBzYXZlIGxpbmUgYnJlYWtzIGFzIEJSIGlubGluZSBmb3JtYXR0aW5nLlxuICBpZiAoYmx4Lmxlbmd0aCA+IDApIHtcbiAgICByZXN1bHQudHh0ID0gYmx4WzBdLnR4dDtcbiAgICByZXN1bHQuZm10ID0gKGJseFswXS5mbXQgfHwgW10pLmNvbmNhdChibHhbMF0uZW50IHx8IFtdKTtcblxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgYmx4Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBibG9jayA9IGJseFtpXTtcbiAgICAgIGNvbnN0IG9mZnNldCA9IHJlc3VsdC50eHQubGVuZ3RoICsgMTtcblxuICAgICAgcmVzdWx0LmZtdC5wdXNoKHtcbiAgICAgICAgdHA6ICdCUicsXG4gICAgICAgIGxlbjogMSxcbiAgICAgICAgYXQ6IG9mZnNldCAtIDFcbiAgICAgIH0pO1xuXG4gICAgICByZXN1bHQudHh0ICs9ICcgJyArIGJsb2NrLnR4dDtcbiAgICAgIGlmIChibG9jay5mbXQpIHtcbiAgICAgICAgcmVzdWx0LmZtdCA9IHJlc3VsdC5mbXQuY29uY2F0KGJsb2NrLmZtdC5tYXAoKHMpID0+IHtcbiAgICAgICAgICBzLmF0ICs9IG9mZnNldDtcbiAgICAgICAgICByZXR1cm4gcztcbiAgICAgICAgfSkpO1xuICAgICAgfVxuICAgICAgaWYgKGJsb2NrLmVudCkge1xuICAgICAgICByZXN1bHQuZm10ID0gcmVzdWx0LmZtdC5jb25jYXQoYmxvY2suZW50Lm1hcCgocykgPT4ge1xuICAgICAgICAgIHMuYXQgKz0gb2Zmc2V0O1xuICAgICAgICAgIHJldHVybiBzO1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHJlc3VsdC5mbXQubGVuZ3RoID09IDApIHtcbiAgICAgIGRlbGV0ZSByZXN1bHQuZm10O1xuICAgIH1cblxuICAgIGlmIChlbnRpdHlNYXAubGVuZ3RoID4gMCkge1xuICAgICAgcmVzdWx0LmVudCA9IGVudGl0eU1hcDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBBcHBlbmQgb25lIERyYWZ0eSBkb2N1bWVudCB0byBhbm90aGVyLlxuICpcbiAqIEBwYXJhbSB7RHJhZnR5fSBmaXJzdCAtIERyYWZ0eSBkb2N1bWVudCB0byBhcHBlbmQgdG8uXG4gKiBAcGFyYW0ge0RyYWZ0eXxzdHJpbmd9IHNlY29uZCAtIERyYWZ0eSBkb2N1bWVudCBvciBzdHJpbmcgYmVpbmcgYXBwZW5kZWQuXG4gKlxuICogQHJldHVybiB7RHJhZnR5fSBmaXJzdCBkb2N1bWVudCB3aXRoIHRoZSBzZWNvbmQgYXBwZW5kZWQgdG8gaXQuXG4gKi9cbkRyYWZ0eS5hcHBlbmQgPSBmdW5jdGlvbihmaXJzdCwgc2Vjb25kKSB7XG4gIGlmICghZmlyc3QpIHtcbiAgICByZXR1cm4gc2Vjb25kO1xuICB9XG4gIGlmICghc2Vjb25kKSB7XG4gICAgcmV0dXJuIGZpcnN0O1xuICB9XG5cbiAgZmlyc3QudHh0ID0gZmlyc3QudHh0IHx8ICcnO1xuICBjb25zdCBsZW4gPSBmaXJzdC50eHQubGVuZ3RoO1xuXG4gIGlmICh0eXBlb2Ygc2Vjb25kID09ICdzdHJpbmcnKSB7XG4gICAgZmlyc3QudHh0ICs9IHNlY29uZDtcbiAgfSBlbHNlIGlmIChzZWNvbmQudHh0KSB7XG4gICAgZmlyc3QudHh0ICs9IHNlY29uZC50eHQ7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShzZWNvbmQuZm10KSkge1xuICAgIGZpcnN0LmZtdCA9IGZpcnN0LmZtdCB8fCBbXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShzZWNvbmQuZW50KSkge1xuICAgICAgZmlyc3QuZW50ID0gZmlyc3QuZW50IHx8IFtdO1xuICAgIH1cbiAgICBzZWNvbmQuZm10LmZvckVhY2goc3JjID0+IHtcbiAgICAgIGNvbnN0IGZtdCA9IHtcbiAgICAgICAgYXQ6IChzcmMuYXQgfCAwKSArIGxlbixcbiAgICAgICAgbGVuOiBzcmMubGVuIHwgMFxuICAgICAgfTtcbiAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgdGhlIG91dHNpZGUgb2YgdGhlIG5vcm1hbCByZW5kZXJpbmcgZmxvdyBzdHlsZXMuXG4gICAgICBpZiAoc3JjLmF0ID09IC0xKSB7XG4gICAgICAgIGZtdC5hdCA9IC0xO1xuICAgICAgICBmbXQubGVuID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChzcmMudHApIHtcbiAgICAgICAgZm10LnRwID0gc3JjLnRwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm10LmtleSA9IGZpcnN0LmVudC5sZW5ndGg7XG4gICAgICAgIGZpcnN0LmVudC5wdXNoKHNlY29uZC5lbnRbc3JjLmtleSB8fCAwXSk7XG4gICAgICB9XG4gICAgICBmaXJzdC5mbXQucHVzaChmbXQpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGZpcnN0O1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIERyYWZ0eS5JbWFnZURlc2NcbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEB0eXBlIE9iamVjdFxuICogQHBhcmFtIHtzdHJpbmd9IG1pbWUgLSBtaW1lLXR5cGUgb2YgdGhlIGltYWdlLCBlLmcuIFwiaW1hZ2UvcG5nXCJcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcmV2aWV3IC0gYmFzZTY0LWVuY29kZWQgaW1hZ2UgY29udGVudCAob3IgcHJldmlldywgaWYgbGFyZ2UgaW1hZ2UgaXMgYXR0YWNoZWQpLiBDb3VsZCBiZSBudWxsL3VuZGVmaW5lZC5cbiAqIEBwYXJhbSB7aW50ZWdlcn0gd2lkdGggLSB3aWR0aCBvZiB0aGUgaW1hZ2VcbiAqIEBwYXJhbSB7aW50ZWdlcn0gaGVpZ2h0IC0gaGVpZ2h0IG9mIHRoZSBpbWFnZVxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gZmlsZSBuYW1lIHN1Z2dlc3Rpb24gZm9yIGRvd25sb2FkaW5nIHRoZSBpbWFnZS5cbiAqIEBwYXJhbSB7aW50ZWdlcn0gc2l6ZSAtIHNpemUgb2YgdGhlIGltYWdlIGluIGJ5dGVzLiBUcmVhdCBpcyBhcyBhbiB1bnRydXN0ZWQgaGludC5cbiAqIEBwYXJhbSB7c3RyaW5nfSByZWZ1cmwgLSByZWZlcmVuY2UgdG8gdGhlIGNvbnRlbnQuIENvdWxkIGJlIG51bGwvdW5kZWZpbmVkLlxuICogQHBhcmFtIHtzdHJpbmd9IF90ZW1wUHJldmlldyAtIGJhc2U2NC1lbmNvZGVkIGltYWdlIHByZXZpZXcgdXNlZCBkdXJpbmcgdXBsb2FkIHByb2Nlc3M7IG5vdCBzZXJpYWxpemFibGUuXG4gKiBAcGFyYW0ge1Byb21pc2V9IHVybFByb21pc2UgLSBQcm9taXNlIHdoaWNoIHJldHVybnMgY29udGVudCBVUkwgd2hlbiByZXNvbHZlZC5cbiAqL1xuXG4vKipcbiAqIEluc2VydCBpbmxpbmUgaW1hZ2UgaW50byBEcmFmdHkgZG9jdW1lbnQuXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtEcmFmdHl9IGNvbnRlbnQgLSBkb2N1bWVudCB0byBhZGQgaW1hZ2UgdG8uXG4gKiBAcGFyYW0ge2ludGVnZXJ9IGF0IC0gaW5kZXggd2hlcmUgdGhlIG9iamVjdCBpcyBpbnNlcnRlZC4gVGhlIGxlbmd0aCBvZiB0aGUgaW1hZ2UgaXMgYWx3YXlzIDEuXG4gKiBAcGFyYW0ge0ltYWdlRGVzY30gaW1hZ2VEZXNjIC0gb2JqZWN0IHdpdGggaW1hZ2UgcGFyYW1lbmV0cyBhbmQgZGF0YS5cbiAqXG4gKiBAcmV0dXJuIHtEcmFmdHl9IHVwZGF0ZWQgZG9jdW1lbnQuXG4gKi9cbkRyYWZ0eS5pbnNlcnRJbWFnZSA9IGZ1bmN0aW9uKGNvbnRlbnQsIGF0LCBpbWFnZURlc2MpIHtcbiAgY29udGVudCA9IGNvbnRlbnQgfHwge1xuICAgIHR4dDogJyAnXG4gIH07XG4gIGNvbnRlbnQuZW50ID0gY29udGVudC5lbnQgfHwgW107XG4gIGNvbnRlbnQuZm10ID0gY29udGVudC5mbXQgfHwgW107XG5cbiAgY29udGVudC5mbXQucHVzaCh7XG4gICAgYXQ6IGF0IHwgMCxcbiAgICBsZW46IDEsXG4gICAga2V5OiBjb250ZW50LmVudC5sZW5ndGhcbiAgfSk7XG5cbiAgY29uc3QgZXggPSB7XG4gICAgdHA6ICdJTScsXG4gICAgZGF0YToge1xuICAgICAgbWltZTogaW1hZ2VEZXNjLm1pbWUsXG4gICAgICB2YWw6IGltYWdlRGVzYy5wcmV2aWV3LFxuICAgICAgd2lkdGg6IGltYWdlRGVzYy53aWR0aCxcbiAgICAgIGhlaWdodDogaW1hZ2VEZXNjLmhlaWdodCxcbiAgICAgIG5hbWU6IGltYWdlRGVzYy5maWxlbmFtZSxcbiAgICAgIHNpemU6IGltYWdlRGVzYy5zaXplIHwgMCxcbiAgICAgIHJlZjogaW1hZ2VEZXNjLnJlZnVybFxuICAgIH1cbiAgfTtcblxuICBpZiAoaW1hZ2VEZXNjLnVybFByb21pc2UpIHtcbiAgICBleC5kYXRhLl90ZW1wUHJldmlldyA9IGltYWdlRGVzYy5fdGVtcFByZXZpZXc7XG4gICAgZXguZGF0YS5fcHJvY2Vzc2luZyA9IHRydWU7XG4gICAgaW1hZ2VEZXNjLnVybFByb21pc2UudGhlbihcbiAgICAgIHVybCA9PiB7XG4gICAgICAgIGV4LmRhdGEucmVmID0gdXJsO1xuICAgICAgICBleC5kYXRhLl90ZW1wUHJldmlldyA9IHVuZGVmaW5lZDtcbiAgICAgICAgZXguZGF0YS5fcHJvY2Vzc2luZyA9IHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgICBfID0+IHtcbiAgICAgICAgLy8gQ2F0Y2ggdGhlIGVycm9yLCBvdGhlcndpc2UgaXQgd2lsbCBhcHBlYXIgaW4gdGhlIGNvbnNvbGUuXG4gICAgICAgIGV4LmRhdGEuX3Byb2Nlc3NpbmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIGNvbnRlbnQuZW50LnB1c2goZXgpO1xuXG4gIHJldHVybiBjb250ZW50O1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIERyYWZ0eS5BdWRpb0Rlc2NcbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEB0eXBlIE9iamVjdFxuICogQHBhcmFtIHtzdHJpbmd9IG1pbWUgLSBtaW1lLXR5cGUgb2YgdGhlIGF1ZGlvLCBlLmcuIFwiYXVkaW8vb2dnXCIuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGF0YSAtIGJhc2U2NC1lbmNvZGVkIGF1ZGlvIGNvbnRlbnQuIENvdWxkIGJlIG51bGwvdW5kZWZpbmVkLlxuICogQHBhcmFtIHtpbnRlZ2VyfSBkdXJhdGlvbiAtIGR1cmF0aW9uIG9mIHRoZSByZWNvcmQgaW4gbWlsbGlzZWNvbmRzLlxuICogQHBhcmFtIHtzdHJpbmd9IHByZXZpZXcgLSBiYXNlNjQgZW5jb2RlZCBzaG9ydCBhcnJheSBvZiBhbXBsaXR1ZGUgdmFsdWVzIDAuLjEwMC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIGZpbGUgbmFtZSBzdWdnZXN0aW9uIGZvciBkb3dubG9hZGluZyB0aGUgYXVkaW8uXG4gKiBAcGFyYW0ge2ludGVnZXJ9IHNpemUgLSBzaXplIG9mIHRoZSByZWNvcmRpbmcgaW4gYnl0ZXMuIFRyZWF0IGlzIGFzIGFuIHVudHJ1c3RlZCBoaW50LlxuICogQHBhcmFtIHtzdHJpbmd9IHJlZnVybCAtIHJlZmVyZW5jZSB0byB0aGUgY29udGVudC4gQ291bGQgYmUgbnVsbC91bmRlZmluZWQuXG4gKiBAcGFyYW0ge1Byb21pc2V9IHVybFByb21pc2UgLSBQcm9taXNlIHdoaWNoIHJldHVybnMgY29udGVudCBVUkwgd2hlbiByZXNvbHZlZC5cbiAqL1xuXG4vKipcbiAqIEluc2VydCBhdWRpbyByZWNvcmRpbmcgaW50byBEcmFmdHkgZG9jdW1lbnQuXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtEcmFmdHl9IGNvbnRlbnQgLSBkb2N1bWVudCB0byBhZGQgYXVkaW8gcmVjb3JkIHRvLlxuICogQHBhcmFtIHtpbnRlZ2VyfSBhdCAtIGluZGV4IHdoZXJlIHRoZSBvYmplY3QgaXMgaW5zZXJ0ZWQuIFRoZSBsZW5ndGggb2YgdGhlIHJlY29yZCBpcyBhbHdheXMgMS5cbiAqIEBwYXJhbSB7QXVkaW9EZXNjfSBhdWRpb0Rlc2MgLSBvYmplY3Qgd2l0aCB0aGUgYXVkaW8gcGFyYW1lbmV0cyBhbmQgZGF0YS5cbiAqXG4gKiBAcmV0dXJuIHtEcmFmdHl9IHVwZGF0ZWQgZG9jdW1lbnQuXG4gKi9cbkRyYWZ0eS5pbnNlcnRBdWRpbyA9IGZ1bmN0aW9uKGNvbnRlbnQsIGF0LCBhdWRpb0Rlc2MpIHtcbiAgY29udGVudCA9IGNvbnRlbnQgfHwge1xuICAgIHR4dDogJyAnXG4gIH07XG4gIGNvbnRlbnQuZW50ID0gY29udGVudC5lbnQgfHwgW107XG4gIGNvbnRlbnQuZm10ID0gY29udGVudC5mbXQgfHwgW107XG5cbiAgY29udGVudC5mbXQucHVzaCh7XG4gICAgYXQ6IGF0IHwgMCxcbiAgICBsZW46IDEsXG4gICAga2V5OiBjb250ZW50LmVudC5sZW5ndGhcbiAgfSk7XG5cbiAgY29uc3QgZXggPSB7XG4gICAgdHA6ICdBVScsXG4gICAgZGF0YToge1xuICAgICAgbWltZTogYXVkaW9EZXNjLm1pbWUsXG4gICAgICB2YWw6IGF1ZGlvRGVzYy5kYXRhLFxuICAgICAgZHVyYXRpb246IGF1ZGlvRGVzYy5kdXJhdGlvbiB8IDAsXG4gICAgICBwcmV2aWV3OiBhdWRpb0Rlc2MucHJldmlldyxcbiAgICAgIG5hbWU6IGF1ZGlvRGVzYy5maWxlbmFtZSxcbiAgICAgIHNpemU6IGF1ZGlvRGVzYy5zaXplIHwgMCxcbiAgICAgIHJlZjogYXVkaW9EZXNjLnJlZnVybFxuICAgIH1cbiAgfTtcblxuICBpZiAoYXVkaW9EZXNjLnVybFByb21pc2UpIHtcbiAgICBleC5kYXRhLl9wcm9jZXNzaW5nID0gdHJ1ZTtcbiAgICBhdWRpb0Rlc2MudXJsUHJvbWlzZS50aGVuKFxuICAgICAgdXJsID0+IHtcbiAgICAgICAgZXguZGF0YS5yZWYgPSB1cmw7XG4gICAgICAgIGV4LmRhdGEuX3Byb2Nlc3NpbmcgPSB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgICAgXyA9PiB7XG4gICAgICAgIC8vIENhdGNoIHRoZSBlcnJvciwgb3RoZXJ3aXNlIGl0IHdpbGwgYXBwZWFyIGluIHRoZSBjb25zb2xlLlxuICAgICAgICBleC5kYXRhLl9wcm9jZXNzaW5nID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBjb250ZW50LmVudC5wdXNoKGV4KTtcblxuICByZXR1cm4gY29udGVudDtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSAoc2VsZi1jb250YWluZWQpIHZpZGVvIGNhbGwgRHJhZnR5IGRvY3VtZW50LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEByZXR1cm5zIFZpZGVvIENhbGwgZHJhZnR5IGRvY3VtZW50LlxuICovXG5EcmFmdHkudmlkZW9DYWxsID0gZnVuY3Rpb24oKSB7XG4gIGNvbnN0IGNvbnRlbnQgPSB7XG4gICAgdHh0OiAnICcsXG4gICAgZm10OiBbe1xuICAgICAgYXQ6IDAsXG4gICAgICBsZW46IDEsXG4gICAgICBrZXk6IDBcbiAgICB9XSxcbiAgICBlbnQ6IFt7XG4gICAgICB0cDogJ1ZDJ1xuICAgIH1dXG4gIH07XG4gIHJldHVybiBjb250ZW50O1xufVxuXG4vKipcbiAqIFVwZGF0ZSB2aWRlbyBjYWxsIChWQykgZW50aXR5IHdpdGggdGhlIG5ldyBzdGF0dXMgYW5kIGR1cmF0aW9uLlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fSBjb250ZW50IC0gVkMgZG9jdW1lbnQgdG8gdXBkYXRlLlxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIG5ldyB2aWRlbyBjYWxsIHBhcmFtZXRlcnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zLnN0YXRlIC0gc3RhdGUgb2YgdmlkZW8gY2FsbC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBwYXJhbXMuZHVyYXRpb24gLSBkdXJhdGlvbiBvZiB0aGUgdmlkZW8gY2FsbCBpbiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHJldHVybnMgdGhlIHNhbWUgZG9jdW1lbnQgd2l0aCB1cGRhdGUgYXBwbGllZC5cbiAqL1xuRHJhZnR5LnVwZGF0ZVZpZGVvRW50ID0gZnVuY3Rpb24oY29udGVudCwgcGFyYW1zKSB7XG4gIC8vIFRoZSB2aWRlbyBlbGVtZW50IGNvdWxkIGJlIGp1c3QgYSBmb3JtYXQgb3IgYSBmb3JtYXQgKyBlbnRpdHkuXG4gIC8vIE11c3QgZW5zdXJlIGl0J3MgdGhlIGxhdHRlciBmaXJzdC5cbiAgY29uc3QgZm10ID0gKChjb250ZW50IHx8IHt9KS5mbXQgfHwgW10pWzBdO1xuICBpZiAoIWZtdCkge1xuICAgIC8vIFVucmVjb2duaXplZCBjb250ZW50LlxuICAgIHJldHVybiBjb250ZW50O1xuICB9XG5cbiAgbGV0IGVudDtcbiAgaWYgKGZtdC50cCA9PSAnVkMnKSB7XG4gICAgLy8gSnVzdCBhIGZvcm1hdCwgY29udmVydCB0byBmb3JtYXQgKyBlbnRpdHkuXG4gICAgZGVsZXRlIGZtdC50cDtcbiAgICBmbXQua2V5ID0gMDtcbiAgICBlbnQgPSB7XG4gICAgICB0cDogJ1ZDJ1xuICAgIH07XG4gICAgY29udGVudC5lbnQgPSBbZW50XTtcbiAgfSBlbHNlIHtcbiAgICBlbnQgPSAoY29udGVudC5lbnQgfHwgW10pW2ZtdC5rZXkgfCAwXTtcbiAgICBpZiAoIWVudCB8fCBlbnQudHAgIT0gJ1ZDJykge1xuICAgICAgLy8gTm90IGEgVkMgZW50aXR5LlxuICAgICAgcmV0dXJuIGNvbnRlbnQ7XG4gICAgfVxuICB9XG4gIGVudC5kYXRhID0gZW50LmRhdGEgfHwge307XG4gIE9iamVjdC5hc3NpZ24oZW50LmRhdGEsIHBhcmFtcyk7XG4gIHJldHVybiBjb250ZW50O1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIHF1b3RlIHRvIERyYWZ0eSBkb2N1bWVudC5cbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEBzdGF0aWNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaGVhZGVyIC0gUXVvdGUgaGVhZGVyICh0aXRsZSwgZXRjLikuXG4gKiBAcGFyYW0ge3N0cmluZ30gdWlkIC0gVUlEIG9mIHRoZSBhdXRob3IgdG8gbWVudGlvbi5cbiAqIEBwYXJhbSB7RHJhZnR5fSBib2R5IC0gQm9keSBvZiB0aGUgcXVvdGVkIG1lc3NhZ2UuXG4gKlxuICogQHJldHVybnMgUmVwbHkgcXVvdGUgRHJhZnR5IGRvYyB3aXRoIHRoZSBxdW90ZSBmb3JtYXR0aW5nLlxuICovXG5EcmFmdHkucXVvdGUgPSBmdW5jdGlvbihoZWFkZXIsIHVpZCwgYm9keSkge1xuICBjb25zdCBxdW90ZSA9IERyYWZ0eS5hcHBlbmQoRHJhZnR5LmFwcGVuZExpbmVCcmVhayhEcmFmdHkubWVudGlvbihoZWFkZXIsIHVpZCkpLCBib2R5KTtcblxuICAvLyBXcmFwIGludG8gYSBxdW90ZS5cbiAgcXVvdGUuZm10LnB1c2goe1xuICAgIGF0OiAwLFxuICAgIGxlbjogcXVvdGUudHh0Lmxlbmd0aCxcbiAgICB0cDogJ1FRJ1xuICB9KTtcblxuICByZXR1cm4gcXVvdGU7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgRHJhZnR5IGRvY3VtZW50IHdpdGggYSBtZW50aW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gbWVudGlvbmVkIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdWlkIC0gbWVudGlvbmVkIHVzZXIgSUQuXG4gKlxuICogQHJldHVybnMge0RyYWZ0eX0gZG9jdW1lbnQgd2l0aCB0aGUgbWVudGlvbi5cbiAqL1xuRHJhZnR5Lm1lbnRpb24gPSBmdW5jdGlvbihuYW1lLCB1aWQpIHtcbiAgcmV0dXJuIHtcbiAgICB0eHQ6IG5hbWUgfHwgJycsXG4gICAgZm10OiBbe1xuICAgICAgYXQ6IDAsXG4gICAgICBsZW46IChuYW1lIHx8ICcnKS5sZW5ndGgsXG4gICAgICBrZXk6IDBcbiAgICB9XSxcbiAgICBlbnQ6IFt7XG4gICAgICB0cDogJ01OJyxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgdmFsOiB1aWRcbiAgICAgIH1cbiAgICB9XVxuICB9O1xufVxuXG4vKipcbiAqIEFwcGVuZCBhIGxpbmsgdG8gYSBEcmFmdHkgZG9jdW1lbnQuXG4gKlxuICogQHBhcmFtIHtEcmFmdHl9IGNvbnRlbnQgLSBEcmFmdHkgZG9jdW1lbnQgdG8gYXBwZW5kIGxpbmsgdG8uXG4gKiBAcGFyYW0ge09iamVjdH0gbGlua0RhdGEgLSBMaW5rIGluZm8gaW4gZm9ybWF0IDxjb2RlPnt0eHQ6ICdhbmtvciB0ZXh0JywgdXJsOiAnaHR0cDovLy4uLid9PC9jb2RlPi5cbiAqXG4gKiBAcmV0dXJucyB7RHJhZnR5fSB0aGUgc2FtZSBkb2N1bWVudCBhcyA8Y29kZT5jb250ZW50PC9jb2RlPi5cbiAqL1xuRHJhZnR5LmFwcGVuZExpbmsgPSBmdW5jdGlvbihjb250ZW50LCBsaW5rRGF0YSkge1xuICBjb250ZW50ID0gY29udGVudCB8fCB7XG4gICAgdHh0OiAnJ1xuICB9O1xuXG4gIGNvbnRlbnQuZW50ID0gY29udGVudC5lbnQgfHwgW107XG4gIGNvbnRlbnQuZm10ID0gY29udGVudC5mbXQgfHwgW107XG5cbiAgY29udGVudC5mbXQucHVzaCh7XG4gICAgYXQ6IGNvbnRlbnQudHh0Lmxlbmd0aCxcbiAgICBsZW46IGxpbmtEYXRhLnR4dC5sZW5ndGgsXG4gICAga2V5OiBjb250ZW50LmVudC5sZW5ndGhcbiAgfSk7XG4gIGNvbnRlbnQudHh0ICs9IGxpbmtEYXRhLnR4dDtcblxuICBjb25zdCBleCA9IHtcbiAgICB0cDogJ0xOJyxcbiAgICBkYXRhOiB7XG4gICAgICB1cmw6IGxpbmtEYXRhLnVybFxuICAgIH1cbiAgfVxuICBjb250ZW50LmVudC5wdXNoKGV4KTtcblxuICByZXR1cm4gY29udGVudDtcbn1cblxuLyoqXG4gKiBBcHBlbmQgaW1hZ2UgdG8gRHJhZnR5IGRvY3VtZW50LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fSBjb250ZW50IC0gZG9jdW1lbnQgdG8gYWRkIGltYWdlIHRvLlxuICogQHBhcmFtIHtJbWFnZURlc2N9IGltYWdlRGVzYyAtIG9iamVjdCB3aXRoIGltYWdlIHBhcmFtZW5ldHMuXG4gKlxuICogQHJldHVybiB7RHJhZnR5fSB1cGRhdGVkIGRvY3VtZW50LlxuICovXG5EcmFmdHkuYXBwZW5kSW1hZ2UgPSBmdW5jdGlvbihjb250ZW50LCBpbWFnZURlc2MpIHtcbiAgY29udGVudCA9IGNvbnRlbnQgfHwge1xuICAgIHR4dDogJydcbiAgfTtcbiAgY29udGVudC50eHQgKz0gJyAnO1xuICByZXR1cm4gRHJhZnR5Lmluc2VydEltYWdlKGNvbnRlbnQsIGNvbnRlbnQudHh0Lmxlbmd0aCAtIDEsIGltYWdlRGVzYyk7XG59XG5cbi8qKlxuICogQXBwZW5kIGF1ZGlvIHJlY29kcmluZyB0byBEcmFmdHkgZG9jdW1lbnQuXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtEcmFmdHl9IGNvbnRlbnQgLSBkb2N1bWVudCB0byBhZGQgcmVjb3JkaW5nIHRvLlxuICogQHBhcmFtIHtBdWRpb0Rlc2N9IGF1ZGlvRGVzYyAtIG9iamVjdCB3aXRoIGF1ZGlvIGRhdGEuXG4gKlxuICogQHJldHVybiB7RHJhZnR5fSB1cGRhdGVkIGRvY3VtZW50LlxuICovXG5EcmFmdHkuYXBwZW5kQXVkaW8gPSBmdW5jdGlvbihjb250ZW50LCBhdWRpb0Rlc2MpIHtcbiAgY29udGVudCA9IGNvbnRlbnQgfHwge1xuICAgIHR4dDogJydcbiAgfTtcbiAgY29udGVudC50eHQgKz0gJyAnO1xuICByZXR1cm4gRHJhZnR5Lmluc2VydEF1ZGlvKGNvbnRlbnQsIGNvbnRlbnQudHh0Lmxlbmd0aCAtIDEsIGF1ZGlvRGVzYyk7XG59XG5cbi8qKlxuICogQHR5cGVkZWYgRHJhZnR5LkF0dGFjaG1lbnREZXNjXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAdHlwZSBPYmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfSBtaW1lIC0gbWltZS10eXBlIG9mIHRoZSBhdHRhY2htZW50LCBlLmcuIFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCJcbiAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhIC0gYmFzZTY0LWVuY29kZWQgaW4tYmFuZCBjb250ZW50IG9mIHNtYWxsIGF0dGFjaG1lbnRzLiBDb3VsZCBiZSBudWxsL3VuZGVmaW5lZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIGZpbGUgbmFtZSBzdWdnZXN0aW9uIGZvciBkb3dubG9hZGluZyB0aGUgYXR0YWNobWVudC5cbiAqIEBwYXJhbSB7aW50ZWdlcn0gc2l6ZSAtIHNpemUgb2YgdGhlIGZpbGUgaW4gYnl0ZXMuIFRyZWF0IGlzIGFzIGFuIHVudHJ1c3RlZCBoaW50LlxuICogQHBhcmFtIHtzdHJpbmd9IHJlZnVybCAtIHJlZmVyZW5jZSB0byB0aGUgb3V0LW9mLWJhbmQgY29udGVudC4gQ291bGQgYmUgbnVsbC91bmRlZmluZWQuXG4gKiBAcGFyYW0ge1Byb21pc2V9IHVybFByb21pc2UgLSBQcm9taXNlIHdoaWNoIHJldHVybnMgY29udGVudCBVUkwgd2hlbiByZXNvbHZlZC5cbiAqL1xuXG4vKipcbiAqIEF0dGFjaCBmaWxlIHRvIERyYWZ0eSBjb250ZW50LiBFaXRoZXIgYXMgYSBibG9iIG9yIGFzIGEgcmVmZXJlbmNlLlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fSBjb250ZW50IC0gZG9jdW1lbnQgdG8gYXR0YWNoIGZpbGUgdG8uXG4gKiBAcGFyYW0ge0F0dGFjaG1lbnREZXNjfSBvYmplY3QgLSBjb250YWluaW5nIGF0dGFjaG1lbnQgZGVzY3JpcHRpb24gYW5kIGRhdGEuXG4gKlxuICogQHJldHVybiB7RHJhZnR5fSB1cGRhdGVkIGRvY3VtZW50LlxuICovXG5EcmFmdHkuYXR0YWNoRmlsZSA9IGZ1bmN0aW9uKGNvbnRlbnQsIGF0dGFjaG1lbnREZXNjKSB7XG4gIGNvbnRlbnQgPSBjb250ZW50IHx8IHtcbiAgICB0eHQ6ICcnXG4gIH07XG5cbiAgY29udGVudC5lbnQgPSBjb250ZW50LmVudCB8fCBbXTtcbiAgY29udGVudC5mbXQgPSBjb250ZW50LmZtdCB8fCBbXTtcblxuICBjb250ZW50LmZtdC5wdXNoKHtcbiAgICBhdDogLTEsXG4gICAgbGVuOiAwLFxuICAgIGtleTogY29udGVudC5lbnQubGVuZ3RoXG4gIH0pO1xuXG4gIGNvbnN0IGV4ID0ge1xuICAgIHRwOiAnRVgnLFxuICAgIGRhdGE6IHtcbiAgICAgIG1pbWU6IGF0dGFjaG1lbnREZXNjLm1pbWUsXG4gICAgICB2YWw6IGF0dGFjaG1lbnREZXNjLmRhdGEsXG4gICAgICBuYW1lOiBhdHRhY2htZW50RGVzYy5maWxlbmFtZSxcbiAgICAgIHJlZjogYXR0YWNobWVudERlc2MucmVmdXJsLFxuICAgICAgc2l6ZTogYXR0YWNobWVudERlc2Muc2l6ZSB8IDBcbiAgICB9XG4gIH1cbiAgaWYgKGF0dGFjaG1lbnREZXNjLnVybFByb21pc2UpIHtcbiAgICBleC5kYXRhLl9wcm9jZXNzaW5nID0gdHJ1ZTtcbiAgICBhdHRhY2htZW50RGVzYy51cmxQcm9taXNlLnRoZW4oXG4gICAgICAodXJsKSA9PiB7XG4gICAgICAgIGV4LmRhdGEucmVmID0gdXJsO1xuICAgICAgICBleC5kYXRhLl9wcm9jZXNzaW5nID0gdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICAgIChlcnIpID0+IHtcbiAgICAgICAgLyogY2F0Y2ggdGhlIGVycm9yLCBvdGhlcndpc2UgaXQgd2lsbCBhcHBlYXIgaW4gdGhlIGNvbnNvbGUuICovXG4gICAgICAgIGV4LmRhdGEuX3Byb2Nlc3NpbmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuICBjb250ZW50LmVudC5wdXNoKGV4KTtcblxuICByZXR1cm4gY29udGVudDtcbn1cblxuLyoqXG4gKiBXcmFwcyBkcmFmdHkgZG9jdW1lbnQgaW50byBhIHNpbXBsZSBmb3JtYXR0aW5nIHN0eWxlLlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fHN0cmluZ30gY29udGVudCAtIGRvY3VtZW50IG9yIHN0cmluZyB0byB3cmFwIGludG8gYSBzdHlsZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHlsZSAtIHR3by1sZXR0ZXIgc3R5bGUgdG8gd3JhcCBpbnRvLlxuICogQHBhcmFtIHtudW1iZXJ9IGF0IC0gaW5kZXggd2hlcmUgdGhlIHN0eWxlIHN0YXJ0cywgZGVmYXVsdCAwLlxuICogQHBhcmFtIHtudW1iZXJ9IGxlbiAtIGxlbmd0aCBvZiB0aGUgZm9ybSBjb250ZW50LCBkZWZhdWx0IGFsbCBvZiBpdC5cbiAqXG4gKiBAcmV0dXJuIHtEcmFmdHl9IHVwZGF0ZWQgZG9jdW1lbnQuXG4gKi9cbkRyYWZ0eS53cmFwSW50byA9IGZ1bmN0aW9uKGNvbnRlbnQsIHN0eWxlLCBhdCwgbGVuKSB7XG4gIGlmICh0eXBlb2YgY29udGVudCA9PSAnc3RyaW5nJykge1xuICAgIGNvbnRlbnQgPSB7XG4gICAgICB0eHQ6IGNvbnRlbnRcbiAgICB9O1xuICB9XG4gIGNvbnRlbnQuZm10ID0gY29udGVudC5mbXQgfHwgW107XG5cbiAgY29udGVudC5mbXQucHVzaCh7XG4gICAgYXQ6IGF0IHx8IDAsXG4gICAgbGVuOiBsZW4gfHwgY29udGVudC50eHQubGVuZ3RoLFxuICAgIHRwOiBzdHlsZSxcbiAgfSk7XG5cbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG5cbi8qKlxuICogV3JhcHMgY29udGVudCBpbnRvIGFuIGludGVyYWN0aXZlIGZvcm0uXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtEcmFmdHl8c3RyaW5nfSBjb250ZW50IC0gdG8gd3JhcCBpbnRvIGEgZm9ybS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBhdCAtIGluZGV4IHdoZXJlIHRoZSBmb3JtcyBzdGFydHMuXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuIC0gbGVuZ3RoIG9mIHRoZSBmb3JtIGNvbnRlbnQuXG4gKlxuICogQHJldHVybiB7RHJhZnR5fSB1cGRhdGVkIGRvY3VtZW50LlxuICovXG5EcmFmdHkud3JhcEFzRm9ybSA9IGZ1bmN0aW9uKGNvbnRlbnQsIGF0LCBsZW4pIHtcbiAgcmV0dXJuIERyYWZ0eS53cmFwSW50byhjb250ZW50LCAnRk0nLCBhdCwgbGVuKTtcbn1cblxuLyoqXG4gKiBJbnNlcnQgY2xpY2thYmxlIGJ1dHRvbiBpbnRvIERyYWZ0eSBkb2N1bWVudC5cbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEBzdGF0aWNcbiAqXG4gKiBAcGFyYW0ge0RyYWZ0eXxzdHJpbmd9IGNvbnRlbnQgLSBEcmFmdHkgZG9jdW1lbnQgdG8gaW5zZXJ0IGJ1dHRvbiB0byBvciBhIHN0cmluZyB0byBiZSB1c2VkIGFzIGJ1dHRvbiB0ZXh0LlxuICogQHBhcmFtIHtudW1iZXJ9IGF0IC0gbG9jYXRpb24gd2hlcmUgdGhlIGJ1dHRvbiBpcyBpbnNlcnRlZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gLSB0aGUgbGVuZ3RoIG9mIHRoZSB0ZXh0IHRvIGJlIHVzZWQgYXMgYnV0dG9uIHRpdGxlLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSB0aGUgYnV0dG9uLiBDbGllbnQgc2hvdWxkIHJldHVybiBpdCB0byB0aGUgc2VydmVyIHdoZW4gdGhlIGJ1dHRvbiBpcyBjbGlja2VkLlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvblR5cGUgLSB0aGUgdHlwZSBvZiB0aGUgYnV0dG9uLCBvbmUgb2YgJ3VybCcgb3IgJ3B1YicuXG4gKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uVmFsdWUgLSB0aGUgdmFsdWUgdG8gcmV0dXJuIG9uIGNsaWNrOlxuICogQHBhcmFtIHtzdHJpbmd9IHJlZlVybCAtIHRoZSBVUkwgdG8gZ28gdG8gd2hlbiB0aGUgJ3VybCcgYnV0dG9uIGlzIGNsaWNrZWQuXG4gKlxuICogQHJldHVybiB7RHJhZnR5fSB1cGRhdGVkIGRvY3VtZW50LlxuICovXG5EcmFmdHkuaW5zZXJ0QnV0dG9uID0gZnVuY3Rpb24oY29udGVudCwgYXQsIGxlbiwgbmFtZSwgYWN0aW9uVHlwZSwgYWN0aW9uVmFsdWUsIHJlZlVybCkge1xuICBpZiAodHlwZW9mIGNvbnRlbnQgPT0gJ3N0cmluZycpIHtcbiAgICBjb250ZW50ID0ge1xuICAgICAgdHh0OiBjb250ZW50XG4gICAgfTtcbiAgfVxuXG4gIGlmICghY29udGVudCB8fCAhY29udGVudC50eHQgfHwgY29udGVudC50eHQubGVuZ3RoIDwgYXQgKyBsZW4pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChsZW4gPD0gMCB8fCBbJ3VybCcsICdwdWInXS5pbmRleE9mKGFjdGlvblR5cGUpID09IC0xKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLy8gRW5zdXJlIHJlZlVybCBpcyBhIHN0cmluZy5cbiAgaWYgKGFjdGlvblR5cGUgPT0gJ3VybCcgJiYgIXJlZlVybCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJlZlVybCA9ICcnICsgcmVmVXJsO1xuXG4gIGNvbnRlbnQuZW50ID0gY29udGVudC5lbnQgfHwgW107XG4gIGNvbnRlbnQuZm10ID0gY29udGVudC5mbXQgfHwgW107XG5cbiAgY29udGVudC5mbXQucHVzaCh7XG4gICAgYXQ6IGF0IHwgMCxcbiAgICBsZW46IGxlbixcbiAgICBrZXk6IGNvbnRlbnQuZW50Lmxlbmd0aFxuICB9KTtcbiAgY29udGVudC5lbnQucHVzaCh7XG4gICAgdHA6ICdCTicsXG4gICAgZGF0YToge1xuICAgICAgYWN0OiBhY3Rpb25UeXBlLFxuICAgICAgdmFsOiBhY3Rpb25WYWx1ZSxcbiAgICAgIHJlZjogcmVmVXJsLFxuICAgICAgbmFtZTogbmFtZVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG5cbi8qKlxuICogQXBwZW5kIGNsaWNrYWJsZSBidXR0b24gdG8gRHJhZnR5IGRvY3VtZW50LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fHN0cmluZ30gY29udGVudCAtIERyYWZ0eSBkb2N1bWVudCB0byBpbnNlcnQgYnV0dG9uIHRvIG9yIGEgc3RyaW5nIHRvIGJlIHVzZWQgYXMgYnV0dG9uIHRleHQuXG4gKiBAcGFyYW0ge3N0cmluZ30gdGl0bGUgLSB0aGUgdGV4dCB0byBiZSB1c2VkIGFzIGJ1dHRvbiB0aXRsZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gdGhlIGJ1dHRvbi4gQ2xpZW50IHNob3VsZCByZXR1cm4gaXQgdG8gdGhlIHNlcnZlciB3aGVuIHRoZSBidXR0b24gaXMgY2xpY2tlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb25UeXBlIC0gdGhlIHR5cGUgb2YgdGhlIGJ1dHRvbiwgb25lIG9mICd1cmwnIG9yICdwdWInLlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvblZhbHVlIC0gdGhlIHZhbHVlIHRvIHJldHVybiBvbiBjbGljazpcbiAqIEBwYXJhbSB7c3RyaW5nfSByZWZVcmwgLSB0aGUgVVJMIHRvIGdvIHRvIHdoZW4gdGhlICd1cmwnIGJ1dHRvbiBpcyBjbGlja2VkLlxuICpcbiAqIEByZXR1cm4ge0RyYWZ0eX0gdXBkYXRlZCBkb2N1bWVudC5cbiAqL1xuRHJhZnR5LmFwcGVuZEJ1dHRvbiA9IGZ1bmN0aW9uKGNvbnRlbnQsIHRpdGxlLCBuYW1lLCBhY3Rpb25UeXBlLCBhY3Rpb25WYWx1ZSwgcmVmVXJsKSB7XG4gIGNvbnRlbnQgPSBjb250ZW50IHx8IHtcbiAgICB0eHQ6ICcnXG4gIH07XG4gIGNvbnN0IGF0ID0gY29udGVudC50eHQubGVuZ3RoO1xuICBjb250ZW50LnR4dCArPSB0aXRsZTtcbiAgcmV0dXJuIERyYWZ0eS5pbnNlcnRCdXR0b24oY29udGVudCwgYXQsIHRpdGxlLmxlbmd0aCwgbmFtZSwgYWN0aW9uVHlwZSwgYWN0aW9uVmFsdWUsIHJlZlVybCk7XG59XG5cbi8qKlxuICogQXR0YWNoIGEgZ2VuZXJpYyBKUyBvYmplY3QuIFRoZSBvYmplY3QgaXMgYXR0YWNoZWQgYXMgYSBqc29uIHN0cmluZy5cbiAqIEludGVuZGVkIGZvciByZXByZXNlbnRpbmcgYSBmb3JtIHJlc3BvbnNlLlxuICpcbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEBzdGF0aWNcbiAqXG4gKiBAcGFyYW0ge0RyYWZ0eX0gY29udGVudCAtIERyYWZ0eSBkb2N1bWVudCB0byBhdHRhY2ggZmlsZSB0by5cbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIC0gZGF0YSB0byBjb252ZXJ0IHRvIGpzb24gc3RyaW5nIGFuZCBhdHRhY2guXG4gKiBAcmV0dXJucyB7RHJhZnR5fSB0aGUgc2FtZSBkb2N1bWVudCBhcyA8Y29kZT5jb250ZW50PC9jb2RlPi5cbiAqL1xuRHJhZnR5LmF0dGFjaEpTT04gPSBmdW5jdGlvbihjb250ZW50LCBkYXRhKSB7XG4gIGNvbnRlbnQgPSBjb250ZW50IHx8IHtcbiAgICB0eHQ6ICcnXG4gIH07XG4gIGNvbnRlbnQuZW50ID0gY29udGVudC5lbnQgfHwgW107XG4gIGNvbnRlbnQuZm10ID0gY29udGVudC5mbXQgfHwgW107XG5cbiAgY29udGVudC5mbXQucHVzaCh7XG4gICAgYXQ6IC0xLFxuICAgIGxlbjogMCxcbiAgICBrZXk6IGNvbnRlbnQuZW50Lmxlbmd0aFxuICB9KTtcblxuICBjb250ZW50LmVudC5wdXNoKHtcbiAgICB0cDogJ0VYJyxcbiAgICBkYXRhOiB7XG4gICAgICBtaW1lOiBKU09OX01JTUVfVFlQRSxcbiAgICAgIHZhbDogZGF0YVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG4vKipcbiAqIEFwcGVuZCBsaW5lIGJyZWFrIHRvIGEgRHJhZnR5IGRvY3VtZW50LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fSBjb250ZW50IC0gRHJhZnR5IGRvY3VtZW50IHRvIGFwcGVuZCBsaW5lYnJlYWsgdG8uXG4gKiBAcmV0dXJucyB7RHJhZnR5fSB0aGUgc2FtZSBkb2N1bWVudCBhcyA8Y29kZT5jb250ZW50PC9jb2RlPi5cbiAqL1xuRHJhZnR5LmFwcGVuZExpbmVCcmVhayA9IGZ1bmN0aW9uKGNvbnRlbnQpIHtcbiAgY29udGVudCA9IGNvbnRlbnQgfHwge1xuICAgIHR4dDogJydcbiAgfTtcbiAgY29udGVudC5mbXQgPSBjb250ZW50LmZtdCB8fCBbXTtcbiAgY29udGVudC5mbXQucHVzaCh7XG4gICAgYXQ6IGNvbnRlbnQudHh0Lmxlbmd0aCxcbiAgICBsZW46IDEsXG4gICAgdHA6ICdCUidcbiAgfSk7XG4gIGNvbnRlbnQudHh0ICs9ICcgJztcblxuICByZXR1cm4gY29udGVudDtcbn1cbi8qKlxuICogR2l2ZW4gRHJhZnR5IGRvY3VtZW50LCBjb252ZXJ0IGl0IHRvIEhUTUwuXG4gKiBObyBhdHRlbXB0IGlzIG1hZGUgdG8gc3RyaXAgcHJlLWV4aXN0aW5nIGh0bWwgbWFya3VwLlxuICogVGhpcyBpcyBwb3RlbnRpYWxseSB1bnNhZmUgYmVjYXVzZSA8Y29kZT5jb250ZW50LnR4dDwvY29kZT4gbWF5IGNvbnRhaW4gbWFsaWNpb3VzIEhUTUxcbiAqIG1hcmt1cC5cbiAqIEBtZW1iZXJvZiBUaW5vZGUuRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtEcmFmdHl9IGRvYyAtIGRvY3VtZW50IHRvIGNvbnZlcnQuXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gSFRNTC1yZXByZXNlbnRhdGlvbiBvZiBjb250ZW50LlxuICovXG5EcmFmdHkuVU5TQUZFX3RvSFRNTCA9IGZ1bmN0aW9uKGRvYykge1xuICBsZXQgdHJlZSA9IGRyYWZ0eVRvVHJlZShkb2MpO1xuICBjb25zdCBodG1sRm9ybWF0dGVyID0gZnVuY3Rpb24odHlwZSwgZGF0YSwgdmFsdWVzKSB7XG4gICAgY29uc3QgdGFnID0gREVDT1JBVE9SU1t0eXBlXTtcbiAgICBsZXQgcmVzdWx0ID0gdmFsdWVzID8gdmFsdWVzLmpvaW4oJycpIDogJyc7XG4gICAgaWYgKHRhZykge1xuICAgICAgcmVzdWx0ID0gdGFnLm9wZW4oZGF0YSkgKyByZXN1bHQgKyB0YWcuY2xvc2UoZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIHJldHVybiB0cmVlQm90dG9tVXAodHJlZSwgaHRtbEZvcm1hdHRlciwgMCk7XG59XG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIGFwcGx5aW5nIGN1c3RvbSBmb3JtYXR0aW5nIHRvIGEgRHJhZnR5IGRvY3VtZW50LlxuICogQ2FsbGVkIG9uY2UgZm9yIGVhY2ggc3R5bGUgc3Bhbi5cbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEBzdGF0aWNcbiAqXG4gKiBAY2FsbGJhY2sgRm9ybWF0dGVyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3R5bGUgLSBzdHlsZSBjb2RlIHN1Y2ggYXMgXCJTVFwiIG9yIFwiSU1cIi5cbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIC0gZW50aXR5J3MgZGF0YS5cbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZXMgLSBwb3NzaWJseSBzdHlsZWQgc3Vic3BhbnMgY29udGFpbmVkIGluIHRoaXMgc3R5bGUgc3Bhbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIGluZGV4IG9mIHRoZSBlbGVtZW50IGd1YXJhbnRlZWQgdG8gYmUgdW5pcXVlLlxuICovXG5cbi8qKlxuICogQ29udmVydCBEcmFmdHkgZG9jdW1lbnQgdG8gYSByZXByZXNlbnRhdGlvbiBzdWl0YWJsZSBmb3IgZGlzcGxheS5cbiAqIFRoZSA8Y29kZT5jb250ZXh0PC9jb2RlPiBtYXkgZXhwb3NlIGEgZnVuY3Rpb24gPGNvZGU+Z2V0Rm9ybWF0dGVyKHN0eWxlKTwvY29kZT4uIElmIGl0J3MgYXZhaWxhYmxlXG4gKiBpdCB3aWxsIGNhbGwgaXQgdG8gb2J0YWluIGEgPGNvZGU+Zm9ybWF0dGVyPC9jb2RlPiBmb3IgYSBzdWJ0cmVlIG9mIHN0eWxlcyB1bmRlciB0aGUgPGNvZGU+c3R5bGU8L2NvZGU+LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fE9iamVjdH0gY29udGVudCAtIERyYWZ0eSBkb2N1bWVudCB0byB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0ge0Zvcm1hdHRlcn0gZm9ybWF0dGVyIC0gY2FsbGJhY2sgd2hpY2ggZm9ybWF0cyBpbmRpdmlkdWFsIGVsZW1lbnRzLlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgLSBjb250ZXh0IHByb3ZpZGVkIHRvIGZvcm1hdHRlciBhcyA8Y29kZT50aGlzPC9jb2RlPi5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRyYW5zZm9ybWVkIG9iamVjdFxuICovXG5EcmFmdHkuZm9ybWF0ID0gZnVuY3Rpb24ob3JpZ2luYWwsIGZvcm1hdHRlciwgY29udGV4dCkge1xuICByZXR1cm4gdHJlZUJvdHRvbVVwKGRyYWZ0eVRvVHJlZShvcmlnaW5hbCksIGZvcm1hdHRlciwgMCwgW10sIGNvbnRleHQpO1xufVxuXG4vKipcbiAqIFNob3J0ZW4gRHJhZnR5IGRvY3VtZW50IG1ha2luZyB0aGUgZHJhZnR5IHRleHQgbm8gbG9uZ2VyIHRoYW4gdGhlIGxpbWl0LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fHN0cmluZ30gb3JpZ2luYWwgLSBEcmFmdHkgb2JqZWN0IHRvIHNob3J0ZW4uXG4gKiBAcGFyYW0ge251bWJlcn0gbGltaXQgLSBsZW5ndGggaW4gY2hhcmFjcmV0cyB0byBzaG9ydGVuIHRvLlxuICogQHBhcmFtIHtib29sZWFufSBsaWdodCAtIHJlbW92ZSBoZWF2eSBkYXRhIGZyb20gZW50aXRpZXMuXG4gKiBAcmV0dXJucyBuZXcgc2hvcnRlbmVkIERyYWZ0eSBvYmplY3QgbGVhdmluZyB0aGUgb3JpZ2luYWwgaW50YWN0LlxuICovXG5EcmFmdHkuc2hvcnRlbiA9IGZ1bmN0aW9uKG9yaWdpbmFsLCBsaW1pdCwgbGlnaHQpIHtcbiAgbGV0IHRyZWUgPSBkcmFmdHlUb1RyZWUob3JpZ2luYWwpO1xuICB0cmVlID0gc2hvcnRlblRyZWUodHJlZSwgbGltaXQsICfigKYnKTtcbiAgaWYgKHRyZWUgJiYgbGlnaHQpIHtcbiAgICB0cmVlID0gbGlnaHRFbnRpdHkodHJlZSk7XG4gIH1cbiAgcmV0dXJuIHRyZWVUb0RyYWZ0eSh7fSwgdHJlZSwgW10pO1xufVxuXG4vKipcbiAqIFRyYW5zZm9ybSBEcmFmdHkgZG9jIGZvciBmb3J3YXJkaW5nOiBzdHJpcCBsZWFkaW5nIEBtZW50aW9uIGFuZCBhbnkgbGVhZGluZyBsaW5lIGJyZWFrcyBvciB3aGl0ZXNwYWNlLlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fHN0cmluZ30gb3JpZ2luYWwgLSBEcmFmdHkgb2JqZWN0IHRvIHNob3J0ZW4uXG4gKiBAcmV0dXJucyBjb252ZXJ0ZWQgRHJhZnR5IG9iamVjdCBsZWF2aW5nIHRoZSBvcmlnaW5hbCBpbnRhY3QuXG4gKi9cbkRyYWZ0eS5mb3J3YXJkZWRDb250ZW50ID0gZnVuY3Rpb24ob3JpZ2luYWwpIHtcbiAgbGV0IHRyZWUgPSBkcmFmdHlUb1RyZWUob3JpZ2luYWwpO1xuICBjb25zdCBybU1lbnRpb24gPSBmdW5jdGlvbihub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSA9PSAnTU4nKSB7XG4gICAgICBpZiAoIW5vZGUucGFyZW50IHx8ICFub2RlLnBhcmVudC50eXBlKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuICAvLyBTdHJpcCBsZWFkaW5nIG1lbnRpb24uXG4gIHRyZWUgPSB0cmVlVG9wRG93bih0cmVlLCBybU1lbnRpb24pO1xuICAvLyBSZW1vdmUgbGVhZGluZyB3aGl0ZXNwYWNlLlxuICB0cmVlID0gbFRyaW0odHJlZSk7XG4gIC8vIENvbnZlcnQgYmFjayB0byBEcmFmdHkuXG4gIHJldHVybiB0cmVlVG9EcmFmdHkoe30sIHRyZWUsIFtdKTtcbn1cblxuLyoqXG4gKiBQcmVwYXJlIERyYWZ0eSBkb2MgZm9yIHdyYXBwaW5nIGludG8gUVEgYXMgYSByZXBseTpcbiAqICAtIFJlcGxhY2UgZm9yd2FyZGluZyBtZW50aW9uIHdpdGggc3ltYm9sICfinqYnIGFuZCByZW1vdmUgZGF0YSAoVUlEKS5cbiAqICAtIFJlbW92ZSBxdW90ZWQgdGV4dCBjb21wbGV0ZWx5LlxuICogIC0gUmVwbGFjZSBsaW5lIGJyZWFrcyB3aXRoIHNwYWNlcy5cbiAqICAtIFN0cmlwIGVudGl0aWVzIG9mIGhlYXZ5IGNvbnRlbnQuXG4gKiAgLSBNb3ZlIGF0dGFjaG1lbnRzIHRvIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fHN0cmluZ30gb3JpZ2luYWwgLSBEcmFmdHkgb2JqZWN0IHRvIHNob3J0ZW4uXG4gKiBAcGFyYW0ge251bWJlcn0gbGltaXQgLSBsZW5ndGggaW4gY2hhcmFjdGVycyB0byBzaG9ydGVuIHRvLlxuICogQHJldHVybnMgY29udmVydGVkIERyYWZ0eSBvYmplY3QgbGVhdmluZyB0aGUgb3JpZ2luYWwgaW50YWN0LlxuICovXG5EcmFmdHkucmVwbHlDb250ZW50ID0gZnVuY3Rpb24ob3JpZ2luYWwsIGxpbWl0KSB7XG4gIGNvbnN0IGNvbnZNTm5RUW5CUiA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlID09ICdRUScpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAobm9kZS50eXBlID09ICdNTicpIHtcbiAgICAgIGlmICgoIW5vZGUucGFyZW50IHx8ICFub2RlLnBhcmVudC50eXBlKSAmJiAobm9kZS50ZXh0IHx8ICcnKS5zdGFydHNXaXRoKCfinqYnKSkge1xuICAgICAgICBub2RlLnRleHQgPSAn4p6mJztcbiAgICAgICAgZGVsZXRlIG5vZGUuY2hpbGRyZW47XG4gICAgICAgIGRlbGV0ZSBub2RlLmRhdGE7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChub2RlLnR5cGUgPT0gJ0JSJykge1xuICAgICAgbm9kZS50ZXh0ID0gJyAnO1xuICAgICAgZGVsZXRlIG5vZGUudHlwZTtcbiAgICAgIGRlbGV0ZSBub2RlLmNoaWxkcmVuO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIGxldCB0cmVlID0gZHJhZnR5VG9UcmVlKG9yaWdpbmFsKTtcbiAgaWYgKCF0cmVlKSB7XG4gICAgcmV0dXJuIG9yaWdpbmFsO1xuICB9XG5cbiAgLy8gU3RyaXAgbGVhZGluZyBtZW50aW9uLlxuICB0cmVlID0gdHJlZVRvcERvd24odHJlZSwgY29udk1OblFRbkJSKTtcbiAgLy8gTW92ZSBhdHRhY2htZW50cyB0byB0aGUgZW5kIG9mIHRoZSBkb2MuXG4gIHRyZWUgPSBhdHRhY2htZW50c1RvRW5kKHRyZWUsIE1BWF9QUkVWSUVXX0FUVEFDSE1FTlRTKTtcbiAgLy8gU2hvcnRlbiB0aGUgZG9jLlxuICB0cmVlID0gc2hvcnRlblRyZWUodHJlZSwgbGltaXQsICfigKYnKTtcbiAgLy8gU3RyaXAgaGVhdnkgZWxlbWVudHMgZXhjZXB0IElNLmRhdGFbJ3ZhbCddIChoYXZlIHRvIGtlZXAgdGhlbSB0byBnZW5lcmF0ZSBwcmV2aWV3cyBsYXRlcikuXG4gIHRyZWUgPSBsaWdodEVudGl0eSh0cmVlLCBub2RlID0+IChub2RlLnR5cGUgPT0gJ0lNJyA/IFsndmFsJ10gOiBudWxsKSk7XG4gIC8vIENvbnZlcnQgYmFjayB0byBEcmFmdHkuXG4gIHJldHVybiB0cmVlVG9EcmFmdHkoe30sIHRyZWUsIFtdKTtcbn1cblxuXG4vKipcbiAqIEdlbmVyYXRlIGRyYWZ0eSBwcmV2aWV3OlxuICogIC0gU2hvcnRlbiB0aGUgZG9jdW1lbnQuXG4gKiAgLSBTdHJpcCBhbGwgaGVhdnkgZW50aXR5IGRhdGEgbGVhdmluZyBqdXN0IGlubGluZSBzdHlsZXMgYW5kIGVudGl0eSByZWZlcmVuY2VzLlxuICogIC0gUmVwbGFjZSBsaW5lIGJyZWFrcyB3aXRoIHNwYWNlcy5cbiAqICAtIFJlcGxhY2UgY29udGVudCBvZiBRUSB3aXRoIGEgc3BhY2UuXG4gKiAgLSBSZXBsYWNlIGZvcndhcmRpbmcgbWVudGlvbiB3aXRoIHN5bWJvbCAn4p6mJy5cbiAqIG1vdmUgYWxsIGF0dGFjaG1lbnRzIHRvIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50IGFuZCBtYWtlIHRoZW0gdmlzaWJsZS5cbiAqIFRoZSA8Y29kZT5jb250ZXh0PC9jb2RlPiBtYXkgZXhwb3NlIGEgZnVuY3Rpb24gPGNvZGU+Z2V0Rm9ybWF0dGVyKHN0eWxlKTwvY29kZT4uIElmIGl0J3MgYXZhaWxhYmxlXG4gKiBpdCB3aWxsIGNhbGwgaXQgdG8gb2J0YWluIGEgPGNvZGU+Zm9ybWF0dGVyPC9jb2RlPiBmb3IgYSBzdWJ0cmVlIG9mIHN0eWxlcyB1bmRlciB0aGUgPGNvZGU+c3R5bGU8L2NvZGU+LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fHN0cmluZ30gb3JpZ2luYWwgLSBEcmFmdHkgb2JqZWN0IHRvIHNob3J0ZW4uXG4gKiBAcGFyYW0ge251bWJlcn0gbGltaXQgLSBsZW5ndGggaW4gY2hhcmFjdGVycyB0byBzaG9ydGVuIHRvLlxuICogQHBhcmFtIHtib29sZWFufSBmb3J3YXJkaW5nIC0gdGhpcyBhIGZvcndhcmRpbmcgbWVzc2FnZSBwcmV2aWV3LlxuICogQHJldHVybnMgbmV3IHNob3J0ZW5lZCBEcmFmdHkgb2JqZWN0IGxlYXZpbmcgdGhlIG9yaWdpbmFsIGludGFjdC5cbiAqL1xuRHJhZnR5LnByZXZpZXcgPSBmdW5jdGlvbihvcmlnaW5hbCwgbGltaXQsIGZvcndhcmRpbmcpIHtcbiAgbGV0IHRyZWUgPSBkcmFmdHlUb1RyZWUob3JpZ2luYWwpO1xuXG4gIC8vIE1vdmUgYXR0YWNobWVudHMgdG8gdGhlIGVuZC5cbiAgdHJlZSA9IGF0dGFjaG1lbnRzVG9FbmQodHJlZSwgTUFYX1BSRVZJRVdfQVRUQUNITUVOVFMpO1xuXG4gIC8vIENvbnZlcnQgbGVhZGluZyBtZW50aW9uIHRvICfinqYnIGFuZCByZXBsYWNlIFFRIGFuZCBCUiB3aXRoIGEgc3BhY2UgJyAnLlxuICBjb25zdCBjb252TU5uUVFuQlIgPSBmdW5jdGlvbihub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSA9PSAnTU4nKSB7XG4gICAgICBpZiAoKCFub2RlLnBhcmVudCB8fCAhbm9kZS5wYXJlbnQudHlwZSkgJiYgKG5vZGUudGV4dCB8fCAnJykuc3RhcnRzV2l0aCgn4p6mJykpIHtcbiAgICAgICAgbm9kZS50ZXh0ID0gJ+Kepic7XG4gICAgICAgIGRlbGV0ZSBub2RlLmNoaWxkcmVuO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobm9kZS50eXBlID09ICdRUScpIHtcbiAgICAgIG5vZGUudGV4dCA9ICcgJztcbiAgICAgIGRlbGV0ZSBub2RlLmNoaWxkcmVuO1xuICAgIH0gZWxzZSBpZiAobm9kZS50eXBlID09ICdCUicpIHtcbiAgICAgIG5vZGUudGV4dCA9ICcgJztcbiAgICAgIGRlbGV0ZSBub2RlLmNoaWxkcmVuO1xuICAgICAgZGVsZXRlIG5vZGUudHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cbiAgdHJlZSA9IHRyZWVUb3BEb3duKHRyZWUsIGNvbnZNTm5RUW5CUik7XG5cbiAgdHJlZSA9IHNob3J0ZW5UcmVlKHRyZWUsIGxpbWl0LCAn4oCmJyk7XG4gIGlmIChmb3J3YXJkaW5nKSB7XG4gICAgLy8gS2VlcCBJTSBkYXRhIGZvciBwcmV2aWV3LlxuICAgIHRyZWUgPSBsaWdodEVudGl0eSh0cmVlLCBub2RlID0+IChub2RlLnR5cGUgPT0gJ0lNJyA/IFsndmFsJ10gOiBudWxsKSk7XG4gIH0gZWxzZSB7XG4gICAgdHJlZSA9IGxpZ2h0RW50aXR5KHRyZWUpO1xuICB9XG5cbiAgLy8gQ29udmVydCBiYWNrIHRvIERyYWZ0eS5cbiAgcmV0dXJuIHRyZWVUb0RyYWZ0eSh7fSwgdHJlZSwgW10pO1xufVxuXG4vKipcbiAqIEdpdmVuIERyYWZ0eSBkb2N1bWVudCwgY29udmVydCBpdCB0byBwbGFpbiB0ZXh0LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fSBjb250ZW50IC0gZG9jdW1lbnQgdG8gY29udmVydCB0byBwbGFpbiB0ZXh0LlxuICogQHJldHVybnMge3N0cmluZ30gcGxhaW4tdGV4dCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZHJhZnR5IGRvY3VtZW50LlxuICovXG5EcmFmdHkudG9QbGFpblRleHQgPSBmdW5jdGlvbihjb250ZW50KSB7XG4gIHJldHVybiB0eXBlb2YgY29udGVudCA9PSAnc3RyaW5nJyA/IGNvbnRlbnQgOiBjb250ZW50LnR4dDtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB0aGUgZG9jdW1lbnQgaGFzIG5vIG1hcmt1cCBhbmQgbm8gZW50aXRpZXMuXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtEcmFmdHl9IGNvbnRlbnQgLSBjb250ZW50IHRvIGNoZWNrIGZvciBwcmVzZW5jZSBvZiBtYXJrdXAuXG4gKiBAcmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpcyBjb250ZW50IGlzIHBsYWluIHRleHQsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuXG4gKi9cbkRyYWZ0eS5pc1BsYWluVGV4dCA9IGZ1bmN0aW9uKGNvbnRlbnQpIHtcbiAgcmV0dXJuIHR5cGVvZiBjb250ZW50ID09ICdzdHJpbmcnIHx8ICEoY29udGVudC5mbXQgfHwgY29udGVudC5lbnQpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgb2JqZWN0IHJlcHJlc2V0cyBpcyBhIHZhbGlkIERyYWZ0eSBkb2N1bWVudC5cbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEBzdGF0aWNcbiAqXG4gKiBAcGFyYW0ge0RyYWZ0eX0gY29udGVudCAtIGNvbnRlbnQgdG8gY2hlY2sgZm9yIHZhbGlkaXR5LlxuICogQHJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaXMgY29udGVudCBpcyB2YWxpZCwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cbiAqL1xuRHJhZnR5LmlzVmFsaWQgPSBmdW5jdGlvbihjb250ZW50KSB7XG4gIGlmICghY29udGVudCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHtcbiAgICB0eHQsXG4gICAgZm10LFxuICAgIGVudFxuICB9ID0gY29udGVudDtcblxuICBpZiAoIXR4dCAmJiB0eHQgIT09ICcnICYmICFmbXQgJiYgIWVudCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHR4dF90eXBlID0gdHlwZW9mIHR4dDtcbiAgaWYgKHR4dF90eXBlICE9ICdzdHJpbmcnICYmIHR4dF90eXBlICE9ICd1bmRlZmluZWQnICYmIHR4dCAhPT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZm10ICE9ICd1bmRlZmluZWQnICYmICFBcnJheS5pc0FycmF5KGZtdCkgJiYgZm10ICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBlbnQgIT0gJ3VuZGVmaW5lZCcgJiYgIUFycmF5LmlzQXJyYXkoZW50KSAmJiBlbnQgIT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIGRyYWZ0eSBkb2N1bWVudCBoYXMgYXR0YWNobWVudHM6IHN0eWxlIEVYIGFuZCBvdXRzaWRlIG9mIG5vcm1hbCByZW5kZXJpbmcgZmxvdyxcbiAqIGkuZS4gPGNvZGU+YXQgPSAtMTwvY29kZT4uXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtEcmFmdHl9IGNvbnRlbnQgLSBkb2N1bWVudCB0byBjaGVjayBmb3IgYXR0YWNobWVudHMuXG4gKiBAcmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGVyZSBhcmUgYXR0YWNobWVudHMuXG4gKi9cbkRyYWZ0eS5oYXNBdHRhY2htZW50cyA9IGZ1bmN0aW9uKGNvbnRlbnQpIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGNvbnRlbnQuZm10KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBmb3IgKGxldCBpIGluIGNvbnRlbnQuZm10KSB7XG4gICAgY29uc3QgZm10ID0gY29udGVudC5mbXRbaV07XG4gICAgaWYgKGZtdCAmJiBmbXQuYXQgPCAwKSB7XG4gICAgICBjb25zdCBlbnQgPSBjb250ZW50LmVudFtmbXQua2V5IHwgMF07XG4gICAgICByZXR1cm4gZW50ICYmIGVudC50cCA9PSAnRVgnICYmIGVudC5kYXRhO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2FsbGJhY2sgZm9yIGFwcGx5aW5nIGN1c3RvbSBmb3JtYXR0aW5nL3RyYW5zZm9ybWF0aW9uIHRvIGEgRHJhZnR5IGRvY3VtZW50LlxuICogQ2FsbGVkIG9uY2UgZm9yIGVhY2ggZW50aXR5LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBjYWxsYmFjayBFbnRpdHlDYWxsYmFja1xuICogQHBhcmFtIHtPYmplY3R9IGRhdGEgZW50aXR5IGRhdGEuXG4gKiBAcGFyYW0ge3N0cmluZ30gZW50aXR5IHR5cGUuXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXggZW50aXR5J3MgaW5kZXggaW4gYGNvbnRlbnQuZW50YC5cbiAqL1xuXG4vKipcbiAqIEVudW1lcmF0ZSBhdHRhY2htZW50czogc3R5bGUgRVggYW5kIG91dHNpZGUgb2Ygbm9ybWFsIHJlbmRlcmluZyBmbG93LCBpLmUuIDxjb2RlPmF0ID0gLTE8L2NvZGU+LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fSBjb250ZW50IC0gZG9jdW1lbnQgdG8gcHJvY2VzcyBmb3IgYXR0YWNobWVudHMuXG4gKiBAcGFyYW0ge0VudGl0eUNhbGxiYWNrfSBjYWxsYmFjayAtIGNhbGxiYWNrIHRvIGNhbGwgZm9yIGVhY2ggYXR0YWNobWVudC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC0gdmFsdWUgb2YgXCJ0aGlzXCIgZm9yIGNhbGxiYWNrLlxuICovXG5EcmFmdHkuYXR0YWNobWVudHMgPSBmdW5jdGlvbihjb250ZW50LCBjYWxsYmFjaywgY29udGV4dCkge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoY29udGVudC5mbXQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBpID0gMDtcbiAgY29udGVudC5mbXQuZm9yRWFjaChmbXQgPT4ge1xuICAgIGlmIChmbXQgJiYgZm10LmF0IDwgMCkge1xuICAgICAgY29uc3QgZW50ID0gY29udGVudC5lbnRbZm10LmtleSB8IDBdO1xuICAgICAgaWYgKGVudCAmJiBlbnQudHAgPT0gJ0VYJyAmJiBlbnQuZGF0YSkge1xuICAgICAgICBjYWxsYmFjay5jYWxsKGNvbnRleHQsIGVudC5kYXRhLCBpKyssICdFWCcpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIGRyYWZ0eSBkb2N1bWVudCBoYXMgZW50aXRpZXMuXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtEcmFmdHl9IGNvbnRlbnQgLSBkb2N1bWVudCB0byBjaGVjayBmb3IgZW50aXRpZXMuXG4gKiBAcmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGVyZSBhcmUgZW50aXRpZXMuXG4gKi9cbkRyYWZ0eS5oYXNFbnRpdGllcyA9IGZ1bmN0aW9uKGNvbnRlbnQpIHtcbiAgcmV0dXJuIGNvbnRlbnQuZW50ICYmIGNvbnRlbnQuZW50Lmxlbmd0aCA+IDA7XG59XG5cbi8qKlxuICogRW51bWVyYXRlIGVudGl0aWVzLlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7RHJhZnR5fSBjb250ZW50IC0gZG9jdW1lbnQgd2l0aCBlbnRpdGllcyB0byBlbnVtZXJhdGUuXG4gKiBAcGFyYW0ge0VudGl0eUNhbGxiYWNrfSBjYWxsYmFjayAtIGNhbGxiYWNrIHRvIGNhbGwgZm9yIGVhY2ggZW50aXR5LlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgLSB2YWx1ZSBvZiBcInRoaXNcIiBmb3IgY2FsbGJhY2suXG4gKi9cbkRyYWZ0eS5lbnRpdGllcyA9IGZ1bmN0aW9uKGNvbnRlbnQsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gIGlmIChjb250ZW50LmVudCAmJiBjb250ZW50LmVudC5sZW5ndGggPiAwKSB7XG4gICAgZm9yIChsZXQgaSBpbiBjb250ZW50LmVudCkge1xuICAgICAgaWYgKGNvbnRlbnQuZW50W2ldKSB7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgY29udGVudC5lbnRbaV0uZGF0YSwgaSwgY29udGVudC5lbnRbaV0udHApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlbW92ZSB1bnJlY29nbml6ZWQgZmllbGRzIGZyb20gZW50aXR5IGRhdGFcbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEBzdGF0aWNcbiAqXG4gKiBAcGFyYW0ge0RyYWZ0eX0gY29udGVudCAtIGRvY3VtZW50IHdpdGggZW50aXRpZXMgdG8gZW51bWVyYXRlLlxuICogQHJldHVybnMgY29udGVudC5cbiAqL1xuRHJhZnR5LnNhbml0aXplRW50aXRpZXMgPSBmdW5jdGlvbihjb250ZW50KSB7XG4gIGlmIChjb250ZW50ICYmIGNvbnRlbnQuZW50ICYmIGNvbnRlbnQuZW50Lmxlbmd0aCA+IDApIHtcbiAgICBmb3IgKGxldCBpIGluIGNvbnRlbnQuZW50KSB7XG4gICAgICBjb25zdCBlbnQgPSBjb250ZW50LmVudFtpXTtcbiAgICAgIGlmIChlbnQgJiYgZW50LmRhdGEpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGNvcHlFbnREYXRhKGVudC5kYXRhKTtcbiAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICBjb250ZW50LmVudFtpXS5kYXRhID0gZGF0YTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgY29udGVudC5lbnRbaV0uZGF0YTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gY29udGVudDtcbn1cblxuLyoqXG4gKiBHaXZlbiB0aGUgZW50aXR5LCBnZXQgVVJMIHdoaWNoIGNhbiBiZSB1c2VkIGZvciBkb3dubG9hZGluZ1xuICogZW50aXR5IGRhdGEuXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGVudERhdGEgLSBlbnRpdHkuZGF0YSB0byBnZXQgdGhlIFVSbCBmcm9tLlxuICogQHJldHVybnMge3N0cmluZ30gVVJMIHRvIGRvd25sb2FkIGVudGl0eSBkYXRhIG9yIDxjb2RlPm51bGw8L2NvZGU+LlxuICovXG5EcmFmdHkuZ2V0RG93bmxvYWRVcmwgPSBmdW5jdGlvbihlbnREYXRhKSB7XG4gIGxldCB1cmwgPSBudWxsO1xuICBpZiAoZW50RGF0YS5taW1lICE9IEpTT05fTUlNRV9UWVBFICYmIGVudERhdGEudmFsKSB7XG4gICAgdXJsID0gYmFzZTY0dG9PYmplY3RVcmwoZW50RGF0YS52YWwsIGVudERhdGEubWltZSwgRHJhZnR5LmxvZ2dlcik7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVudERhdGEucmVmID09ICdzdHJpbmcnKSB7XG4gICAgdXJsID0gZW50RGF0YS5yZWY7XG4gIH1cbiAgcmV0dXJuIHVybDtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB0aGUgZW50aXR5IGRhdGEgaXMgbm90IHJlYWR5IGZvciBzZW5kaW5nLCBzdWNoIGFzIGJlaW5nIHVwbG9hZGVkIHRvIHRoZSBzZXJ2ZXIuXG4gKiBAbWVtYmVyb2YgRHJhZnR5XG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGVudGl0eS5kYXRhIHRvIGdldCB0aGUgVVJsIGZyb20uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB1cGxvYWQgaXMgaW4gcHJvZ3Jlc3MsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuRHJhZnR5LmlzUHJvY2Vzc2luZyA9IGZ1bmN0aW9uKGVudERhdGEpIHtcbiAgcmV0dXJuICEhZW50RGF0YS5fcHJvY2Vzc2luZztcbn1cblxuLyoqXG4gKiBHaXZlbiB0aGUgZW50aXR5LCBnZXQgVVJMIHdoaWNoIGNhbiBiZSB1c2VkIGZvciBwcmV2aWV3aW5nXG4gKiB0aGUgZW50aXR5LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBlbnRpdHkuZGF0YSB0byBnZXQgdGhlIFVSbCBmcm9tLlxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHVybCBmb3IgcHJldmlld2luZyBvciBudWxsIGlmIG5vIHN1Y2ggdXJsIGlzIGF2YWlsYWJsZS5cbiAqL1xuRHJhZnR5LmdldFByZXZpZXdVcmwgPSBmdW5jdGlvbihlbnREYXRhKSB7XG4gIHJldHVybiBlbnREYXRhLnZhbCA/IGJhc2U2NHRvT2JqZWN0VXJsKGVudERhdGEudmFsLCBlbnREYXRhLm1pbWUsIERyYWZ0eS5sb2dnZXIpIDogbnVsbDtcbn1cblxuLyoqXG4gKiBHZXQgYXBwcm94aW1hdGUgc2l6ZSBvZiB0aGUgZW50aXR5LlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBlbnREYXRhIC0gZW50aXR5LmRhdGEgdG8gZ2V0IHRoZSBzaXplIGZvci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IHNpemUgb2YgZW50aXR5IGRhdGEgaW4gYnl0ZXMuXG4gKi9cbkRyYWZ0eS5nZXRFbnRpdHlTaXplID0gZnVuY3Rpb24oZW50RGF0YSkge1xuICAvLyBFaXRoZXIgc2l6ZSBoaW50IG9yIGxlbmd0aCBvZiB2YWx1ZS4gVGhlIHZhbHVlIGlzIGJhc2U2NCBlbmNvZGVkLFxuICAvLyB0aGUgYWN0dWFsIG9iamVjdCBzaXplIGlzIHNtYWxsZXIgdGhhbiB0aGUgZW5jb2RlZCBsZW5ndGguXG4gIHJldHVybiBlbnREYXRhLnNpemUgPyBlbnREYXRhLnNpemUgOiBlbnREYXRhLnZhbCA/IChlbnREYXRhLnZhbC5sZW5ndGggKiAwLjc1KSB8IDAgOiAwO1xufVxuXG4vKipcbiAqIEdldCBlbnRpdHkgbWltZSB0eXBlLlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBlbnREYXRhIC0gZW50aXR5LmRhdGEgdG8gZ2V0IHRoZSB0eXBlIGZvci5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IG1pbWUgdHlwZSBvZiBlbnRpdHkuXG4gKi9cbkRyYWZ0eS5nZXRFbnRpdHlNaW1lVHlwZSA9IGZ1bmN0aW9uKGVudERhdGEpIHtcbiAgcmV0dXJuIGVudERhdGEubWltZSB8fCAndGV4dC9wbGFpbic7XG59XG5cbi8qKlxuICogR2V0IEhUTUwgdGFnIGZvciBhIGdpdmVuIHR3by1sZXR0ZXIgc3R5bGUgbmFtZS5cbiAqIEBtZW1iZXJvZiBEcmFmdHlcbiAqIEBzdGF0aWNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3R5bGUgLSB0d28tbGV0dGVyIHN0eWxlLCBsaWtlIFNUIG9yIExOLlxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IEhUTUwgdGFnIG5hbWUgaWYgc3R5bGUgaXMgZm91bmQsIHtjb2RlOiB1bmRlZmluZWR9IGlmIHN0eWxlIGlzIGZhbHNpc2ggb3Igbm90IGZvdW5kLlxuICovXG5EcmFmdHkudGFnTmFtZSA9IGZ1bmN0aW9uKHN0eWxlKSB7XG4gIHJldHVybiBIVE1MX1RBR1Nbc3R5bGVdICYmIEhUTUxfVEFHU1tzdHlsZV0ubmFtZTtcbn1cblxuLyoqXG4gKiBGb3IgYSBnaXZlbiBkYXRhIGJ1bmRsZSBnZW5lcmF0ZSBhbiBvYmplY3Qgd2l0aCBIVE1MIGF0dHJpYnV0ZXMsXG4gKiBmb3IgaW5zdGFuY2UsIGdpdmVuIHt1cmw6IFwiaHR0cDovL3d3dy5leGFtcGxlLmNvbS9cIn0gcmV0dXJuXG4gKiB7aHJlZjogXCJodHRwOi8vd3d3LmV4YW1wbGUuY29tL1wifVxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHlsZSAtIHR3by1sZXR0ZXIgc3R5bGUgdG8gZ2VuZXJhdGUgYXR0cmlidXRlcyBmb3IuXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YSAtIGRhdGEgYnVuZGxlIHRvIGNvbnZlcnQgdG8gYXR0cmlidXRlc1xuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IG9iamVjdCB3aXRoIEhUTUwgYXR0cmlidXRlcy5cbiAqL1xuRHJhZnR5LmF0dHJWYWx1ZSA9IGZ1bmN0aW9uKHN0eWxlLCBkYXRhKSB7XG4gIGlmIChkYXRhICYmIERFQ09SQVRPUlNbc3R5bGVdKSB7XG4gICAgcmV0dXJuIERFQ09SQVRPUlNbc3R5bGVdLnByb3BzKGRhdGEpO1xuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBEcmFmdHkgTUlNRSB0eXBlLlxuICogQG1lbWJlcm9mIERyYWZ0eVxuICogQHN0YXRpY1xuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IGNvbnRlbnQtVHlwZSBcInRleHQveC1kcmFmdHlcIi5cbiAqL1xuRHJhZnR5LmdldENvbnRlbnRUeXBlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBEUkFGVFlfTUlNRV9UWVBFO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PVxuLy8gVXRpbGl0eSBtZXRob2RzLlxuLy8gPT09PT09PT09PT09PT09PT1cblxuLy8gVGFrZSBhIHN0cmluZyBhbmQgZGVmaW5lZCBlYXJsaWVyIHN0eWxlIHNwYW5zLCByZS1jb21wb3NlIHRoZW0gaW50byBhIHRyZWUgd2hlcmUgZWFjaCBsZWFmIGlzXG4vLyBhIHNhbWUtc3R5bGUgKGluY2x1ZGluZyB1bnN0eWxlZCkgc3RyaW5nLiBJLmUuICdoZWxsbyAqYm9sZCBfaXRhbGljXyogYW5kIH5tb3JlfiB3b3JsZCcgLT5cbi8vICgnaGVsbG8gJywgKGI6ICdib2xkICcsIChpOiAnaXRhbGljJykpLCAnIGFuZCAnLCAoczogJ21vcmUnKSwgJyB3b3JsZCcpO1xuLy9cbi8vIFRoaXMgaXMgbmVlZGVkIGluIG9yZGVyIHRvIGNsZWFyIG1hcmt1cCwgaS5lLiAnaGVsbG8gKndvcmxkKicgLT4gJ2hlbGxvIHdvcmxkJyBhbmQgY29udmVydFxuLy8gcmFuZ2VzIGZyb20gbWFya3VwLWVkIG9mZnNldHMgdG8gcGxhaW4gdGV4dCBvZmZzZXRzLlxuZnVuY3Rpb24gY2h1bmtpZnkobGluZSwgc3RhcnQsIGVuZCwgc3BhbnMpIHtcbiAgY29uc3QgY2h1bmtzID0gW107XG5cbiAgaWYgKHNwYW5zLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgZm9yIChsZXQgaSBpbiBzcGFucykge1xuICAgIC8vIEdldCB0aGUgbmV4dCBjaHVuayBmcm9tIHRoZSBxdWV1ZVxuICAgIGNvbnN0IHNwYW4gPSBzcGFuc1tpXTtcblxuICAgIC8vIEdyYWIgdGhlIGluaXRpYWwgdW5zdHlsZWQgY2h1bmtcbiAgICBpZiAoc3Bhbi5hdCA+IHN0YXJ0KSB7XG4gICAgICBjaHVua3MucHVzaCh7XG4gICAgICAgIHR4dDogbGluZS5zbGljZShzdGFydCwgc3Bhbi5hdClcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEdyYWIgdGhlIHN0eWxlZCBjaHVuay4gSXQgbWF5IGluY2x1ZGUgc3ViY2h1bmtzLlxuICAgIGNvbnN0IGNodW5rID0ge1xuICAgICAgdHA6IHNwYW4udHBcbiAgICB9O1xuICAgIGNvbnN0IGNobGQgPSBjaHVua2lmeShsaW5lLCBzcGFuLmF0ICsgMSwgc3Bhbi5lbmQsIHNwYW4uY2hpbGRyZW4pO1xuICAgIGlmIChjaGxkLmxlbmd0aCA+IDApIHtcbiAgICAgIGNodW5rLmNoaWxkcmVuID0gY2hsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY2h1bmsudHh0ID0gc3Bhbi50eHQ7XG4gICAgfVxuICAgIGNodW5rcy5wdXNoKGNodW5rKTtcbiAgICBzdGFydCA9IHNwYW4uZW5kICsgMTsgLy8gJysxJyBpcyB0byBza2lwIHRoZSBmb3JtYXR0aW5nIGNoYXJhY3RlclxuICB9XG5cbiAgLy8gR3JhYiB0aGUgcmVtYWluaW5nIHVuc3R5bGVkIGNodW5rLCBhZnRlciB0aGUgbGFzdCBzcGFuXG4gIGlmIChzdGFydCA8IGVuZCkge1xuICAgIGNodW5rcy5wdXNoKHtcbiAgICAgIHR4dDogbGluZS5zbGljZShzdGFydCwgZW5kKVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGNodW5rcztcbn1cblxuLy8gRGV0ZWN0IHN0YXJ0cyBhbmQgZW5kcyBvZiBmb3JtYXR0aW5nIHNwYW5zLiBVbmZvcm1hdHRlZCBzcGFucyBhcmVcbi8vIGlnbm9yZWQgYXQgdGhpcyBzdGFnZS5cbmZ1bmN0aW9uIHNwYW5uaWZ5KG9yaWdpbmFsLCByZV9zdGFydCwgcmVfZW5kLCB0eXBlKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBsZXQgaW5kZXggPSAwO1xuICBsZXQgbGluZSA9IG9yaWdpbmFsLnNsaWNlKDApOyAvLyBtYWtlIGEgY29weTtcblxuICB3aGlsZSAobGluZS5sZW5ndGggPiAwKSB7XG4gICAgLy8gbWF0Y2hbMF07IC8vIG1hdGNoLCBsaWtlICcqYWJjKidcbiAgICAvLyBtYXRjaFsxXTsgLy8gbWF0Y2ggY2FwdHVyZWQgaW4gcGFyZW50aGVzaXMsIGxpa2UgJ2FiYydcbiAgICAvLyBtYXRjaFsnaW5kZXgnXTsgLy8gb2Zmc2V0IHdoZXJlIHRoZSBtYXRjaCBzdGFydGVkLlxuXG4gICAgLy8gRmluZCB0aGUgb3BlbmluZyB0b2tlbi5cbiAgICBjb25zdCBzdGFydCA9IHJlX3N0YXJ0LmV4ZWMobGluZSk7XG4gICAgaWYgKHN0YXJ0ID09IG51bGwpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIEJlY2F1c2UgamF2YXNjcmlwdCBSZWdFeHAgZG9lcyBub3Qgc3VwcG9ydCBsb29rYmVoaW5kLCB0aGUgYWN0dWFsIG9mZnNldCBtYXkgbm90IHBvaW50XG4gICAgLy8gYXQgdGhlIG1hcmt1cCBjaGFyYWN0ZXIuIEZpbmQgaXQgaW4gdGhlIG1hdGNoZWQgc3RyaW5nLlxuICAgIGxldCBzdGFydF9vZmZzZXQgPSBzdGFydFsnaW5kZXgnXSArIHN0YXJ0WzBdLmxhc3RJbmRleE9mKHN0YXJ0WzFdKTtcbiAgICAvLyBDbGlwIHRoZSBwcm9jZXNzZWQgcGFydCBvZiB0aGUgc3RyaW5nLlxuICAgIGxpbmUgPSBsaW5lLnNsaWNlKHN0YXJ0X29mZnNldCArIDEpO1xuICAgIC8vIHN0YXJ0X29mZnNldCBpcyBhbiBvZmZzZXQgd2l0aGluIHRoZSBjbGlwcGVkIHN0cmluZy4gQ29udmVydCB0byBvcmlnaW5hbCBpbmRleC5cbiAgICBzdGFydF9vZmZzZXQgKz0gaW5kZXg7XG4gICAgLy8gSW5kZXggbm93IHBvaW50IHRvIHRoZSBiZWdpbm5pbmcgb2YgJ2xpbmUnIHdpdGhpbiB0aGUgJ29yaWdpbmFsJyBzdHJpbmcuXG4gICAgaW5kZXggPSBzdGFydF9vZmZzZXQgKyAxO1xuXG4gICAgLy8gRmluZCB0aGUgbWF0Y2hpbmcgY2xvc2luZyB0b2tlbi5cbiAgICBjb25zdCBlbmQgPSByZV9lbmQgPyByZV9lbmQuZXhlYyhsaW5lKSA6IG51bGw7XG4gICAgaWYgKGVuZCA9PSBudWxsKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgbGV0IGVuZF9vZmZzZXQgPSBlbmRbJ2luZGV4J10gKyBlbmRbMF0uaW5kZXhPZihlbmRbMV0pO1xuICAgIC8vIENsaXAgdGhlIHByb2Nlc3NlZCBwYXJ0IG9mIHRoZSBzdHJpbmcuXG4gICAgbGluZSA9IGxpbmUuc2xpY2UoZW5kX29mZnNldCArIDEpO1xuICAgIC8vIFVwZGF0ZSBvZmZzZXRzXG4gICAgZW5kX29mZnNldCArPSBpbmRleDtcbiAgICAvLyBJbmRleCBub3cgcG9pbnRzIHRvIHRoZSBiZWdpbm5pbmcgb2YgJ2xpbmUnIHdpdGhpbiB0aGUgJ29yaWdpbmFsJyBzdHJpbmcuXG4gICAgaW5kZXggPSBlbmRfb2Zmc2V0ICsgMTtcblxuICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgIHR4dDogb3JpZ2luYWwuc2xpY2Uoc3RhcnRfb2Zmc2V0ICsgMSwgZW5kX29mZnNldCksXG4gICAgICBjaGlsZHJlbjogW10sXG4gICAgICBhdDogc3RhcnRfb2Zmc2V0LFxuICAgICAgZW5kOiBlbmRfb2Zmc2V0LFxuICAgICAgdHA6IHR5cGVcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIENvbnZlcnQgbGluZWFyIGFycmF5IG9yIHNwYW5zIGludG8gYSB0cmVlIHJlcHJlc2VudGF0aW9uLlxuLy8gS2VlcCBzdGFuZGFsb25lIGFuZCBuZXN0ZWQgc3BhbnMsIHRocm93IGF3YXkgcGFydGlhbGx5IG92ZXJsYXBwaW5nIHNwYW5zLlxuZnVuY3Rpb24gdG9TcGFuVHJlZShzcGFucykge1xuICBpZiAoc3BhbnMubGVuZ3RoID09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCB0cmVlID0gW3NwYW5zWzBdXTtcbiAgbGV0IGxhc3QgPSBzcGFuc1swXTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBzcGFucy5sZW5ndGg7IGkrKykge1xuICAgIC8vIEtlZXAgc3BhbnMgd2hpY2ggc3RhcnQgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgcHJldmlvdXMgc3BhbiBvciB0aG9zZSB3aGljaFxuICAgIC8vIGFyZSBjb21wbGV0ZSB3aXRoaW4gdGhlIHByZXZpb3VzIHNwYW4uXG4gICAgaWYgKHNwYW5zW2ldLmF0ID4gbGFzdC5lbmQpIHtcbiAgICAgIC8vIFNwYW4gaXMgY29tcGxldGVseSBvdXRzaWRlIG9mIHRoZSBwcmV2aW91cyBzcGFuLlxuICAgICAgdHJlZS5wdXNoKHNwYW5zW2ldKTtcbiAgICAgIGxhc3QgPSBzcGFuc1tpXTtcbiAgICB9IGVsc2UgaWYgKHNwYW5zW2ldLmVuZCA8PSBsYXN0LmVuZCkge1xuICAgICAgLy8gU3BhbiBpcyBmdWxseSBpbnNpZGUgb2YgdGhlIHByZXZpb3VzIHNwYW4uIFB1c2ggdG8gc3Vibm9kZS5cbiAgICAgIGxhc3QuY2hpbGRyZW4ucHVzaChzcGFuc1tpXSk7XG4gICAgfVxuICAgIC8vIFNwYW4gY291bGQgcGFydGlhbGx5IG92ZXJsYXAsIGlnbm9yaW5nIGl0IGFzIGludmFsaWQuXG4gIH1cblxuICAvLyBSZWN1cnNpdmVseSByZWFycmFuZ2UgdGhlIHN1Ym5vZGVzLlxuICBmb3IgKGxldCBpIGluIHRyZWUpIHtcbiAgICB0cmVlW2ldLmNoaWxkcmVuID0gdG9TcGFuVHJlZSh0cmVlW2ldLmNoaWxkcmVuKTtcbiAgfVxuXG4gIHJldHVybiB0cmVlO1xufVxuXG4vLyBDb252ZXJ0IGRyYWZ0eSBkb2N1bWVudCB0byBhIHRyZWUuXG5mdW5jdGlvbiBkcmFmdHlUb1RyZWUoZG9jKSB7XG4gIGlmICghZG9jKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBkb2MgPSAodHlwZW9mIGRvYyA9PSAnc3RyaW5nJykgPyB7XG4gICAgdHh0OiBkb2NcbiAgfSA6IGRvYztcbiAgbGV0IHtcbiAgICB0eHQsXG4gICAgZm10LFxuICAgIGVudFxuICB9ID0gZG9jO1xuXG4gIHR4dCA9IHR4dCB8fCAnJztcbiAgaWYgKCFBcnJheS5pc0FycmF5KGVudCkpIHtcbiAgICBlbnQgPSBbXTtcbiAgfVxuXG4gIGlmICghQXJyYXkuaXNBcnJheShmbXQpIHx8IGZtdC5sZW5ndGggPT0gMCkge1xuICAgIGlmIChlbnQubGVuZ3RoID09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRleHQ6IHR4dFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgc3BlY2lhbCBjYXNlIHdoZW4gYWxsIHZhbHVlcyBpbiBmbXQgYXJlIDAgYW5kIGZtdCB0aGVyZWZvcmUgaXMgc2tpcHBlZC5cbiAgICBmbXQgPSBbe1xuICAgICAgYXQ6IDAsXG4gICAgICBsZW46IDAsXG4gICAgICBrZXk6IDBcbiAgICB9XTtcbiAgfVxuXG4gIC8vIFNhbml0aXplIHNwYW5zLlxuICBjb25zdCBzcGFucyA9IFtdO1xuICBjb25zdCBhdHRhY2htZW50cyA9IFtdO1xuICBmbXQuZm9yRWFjaCgoc3BhbikgPT4ge1xuICAgIGlmICghc3BhbiB8fCB0eXBlb2Ygc3BhbiAhPSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghWyd1bmRlZmluZWQnLCAnbnVtYmVyJ10uaW5jbHVkZXModHlwZW9mIHNwYW4uYXQpKSB7XG4gICAgICAvLyBQcmVzZW50LCBidXQgbm9uLW51bWVyaWMgJ2F0Jy5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFbJ3VuZGVmaW5lZCcsICdudW1iZXInXS5pbmNsdWRlcyh0eXBlb2Ygc3Bhbi5sZW4pKSB7XG4gICAgICAvLyBQcmVzZW50LCBidXQgbm9uLW51bWVyaWMgJ2xlbicuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBhdCA9IHNwYW4uYXQgfCAwO1xuICAgIGxldCBsZW4gPSBzcGFuLmxlbiB8IDA7XG4gICAgaWYgKGxlbiA8IDApIHtcbiAgICAgIC8vIEludmFsaWQgc3BhbiBsZW5ndGguXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGtleSA9IHNwYW4ua2V5IHx8IDA7XG4gICAgaWYgKGVudC5sZW5ndGggPiAwICYmICh0eXBlb2Yga2V5ICE9ICdudW1iZXInIHx8IGtleSA8IDAgfHwga2V5ID49IGVudC5sZW5ndGgpKSB7XG4gICAgICAvLyBJbnZhbGlkIGtleSB2YWx1ZS5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoYXQgPD0gLTEpIHtcbiAgICAgIC8vIEF0dGFjaG1lbnQuIFN0b3JlIGF0dGFjaG1lbnRzIHNlcGFyYXRlbHkuXG4gICAgICBhdHRhY2htZW50cy5wdXNoKHtcbiAgICAgICAgc3RhcnQ6IC0xLFxuICAgICAgICBlbmQ6IDAsXG4gICAgICAgIGtleToga2V5XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKGF0ICsgbGVuID4gdHh0Lmxlbmd0aCkge1xuICAgICAgLy8gU3BhbiBpcyBvdXQgb2YgYm91bmRzLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghc3Bhbi50cCkge1xuICAgICAgaWYgKGVudC5sZW5ndGggPiAwICYmICh0eXBlb2YgZW50W2tleV0gPT0gJ29iamVjdCcpKSB7XG4gICAgICAgIHNwYW5zLnB1c2goe1xuICAgICAgICAgIHN0YXJ0OiBhdCxcbiAgICAgICAgICBlbmQ6IGF0ICsgbGVuLFxuICAgICAgICAgIGtleToga2V5XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzcGFucy5wdXNoKHtcbiAgICAgICAgdHlwZTogc3Bhbi50cCxcbiAgICAgICAgc3RhcnQ6IGF0LFxuICAgICAgICBlbmQ6IGF0ICsgbGVuXG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFNvcnQgc3BhbnMgZmlyc3QgYnkgc3RhcnQgaW5kZXggKGFzYykgdGhlbiBieSBsZW5ndGggKGRlc2MpLCB0aGVuIGJ5IHdlaWdodC5cbiAgc3BhbnMuc29ydCgoYSwgYikgPT4ge1xuICAgIGxldCBkaWZmID0gYS5zdGFydCAtIGIuc3RhcnQ7XG4gICAgaWYgKGRpZmYgIT0gMCkge1xuICAgICAgcmV0dXJuIGRpZmY7XG4gICAgfVxuICAgIGRpZmYgPSBiLmVuZCAtIGEuZW5kO1xuICAgIGlmIChkaWZmICE9IDApIHtcbiAgICAgIHJldHVybiBkaWZmO1xuICAgIH1cbiAgICByZXR1cm4gRk1UX1dFSUdIVC5pbmRleE9mKGIudHlwZSkgLSBGTVRfV0VJR0hULmluZGV4T2YoYS50eXBlKTtcbiAgfSk7XG5cbiAgLy8gTW92ZSBhdHRhY2htZW50cyB0byB0aGUgZW5kIG9mIHRoZSBsaXN0LlxuICBpZiAoYXR0YWNobWVudHMubGVuZ3RoID4gMCkge1xuICAgIHNwYW5zLnB1c2goLi4uYXR0YWNobWVudHMpO1xuICB9XG5cbiAgc3BhbnMuZm9yRWFjaCgoc3BhbikgPT4ge1xuICAgIGlmIChlbnQubGVuZ3RoID4gMCAmJiAhc3Bhbi50eXBlICYmIGVudFtzcGFuLmtleV0gJiYgdHlwZW9mIGVudFtzcGFuLmtleV0gPT0gJ29iamVjdCcpIHtcbiAgICAgIHNwYW4udHlwZSA9IGVudFtzcGFuLmtleV0udHA7XG4gICAgICBzcGFuLmRhdGEgPSBlbnRbc3Bhbi5rZXldLmRhdGE7XG4gICAgfVxuXG4gICAgLy8gSXMgdHlwZSBzdGlsbCB1bmRlZmluZWQ/IEhpZGUgdGhlIGludmFsaWQgZWxlbWVudCFcbiAgICBpZiAoIXNwYW4udHlwZSkge1xuICAgICAgc3Bhbi50eXBlID0gJ0hEJztcbiAgICB9XG4gIH0pO1xuXG4gIGxldCB0cmVlID0gc3BhbnNUb1RyZWUoe30sIHR4dCwgMCwgdHh0Lmxlbmd0aCwgc3BhbnMpO1xuXG4gIC8vIEZsYXR0ZW4gdHJlZSBub2Rlcy5cbiAgY29uc3QgZmxhdHRlbiA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShub2RlLmNoaWxkcmVuKSAmJiBub2RlLmNoaWxkcmVuLmxlbmd0aCA9PSAxKSB7XG4gICAgICAvLyBVbndyYXAuXG4gICAgICBjb25zdCBjaGlsZCA9IG5vZGUuY2hpbGRyZW5bMF07XG4gICAgICBpZiAoIW5vZGUudHlwZSkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudDtcbiAgICAgICAgbm9kZSA9IGNoaWxkO1xuICAgICAgICBub2RlLnBhcmVudCA9IHBhcmVudDtcbiAgICAgIH0gZWxzZSBpZiAoIWNoaWxkLnR5cGUgJiYgIWNoaWxkLmNoaWxkcmVuKSB7XG4gICAgICAgIG5vZGUudGV4dCA9IGNoaWxkLnRleHQ7XG4gICAgICAgIGRlbGV0ZSBub2RlLmNoaWxkcmVuO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuICB0cmVlID0gdHJlZVRvcERvd24odHJlZSwgZmxhdHRlbik7XG5cbiAgcmV0dXJuIHRyZWU7XG59XG5cbi8vIEFkZCB0cmVlIG5vZGUgdG8gYSBwYXJlbnQgdHJlZS5cbmZ1bmN0aW9uIGFkZE5vZGUocGFyZW50LCBuKSB7XG4gIGlmICghbikge1xuICAgIHJldHVybiBwYXJlbnQ7XG4gIH1cblxuICBpZiAoIXBhcmVudC5jaGlsZHJlbikge1xuICAgIHBhcmVudC5jaGlsZHJlbiA9IFtdO1xuICB9XG5cbiAgLy8gSWYgdGV4dCBpcyBwcmVzZW50LCBtb3ZlIGl0IHRvIGEgc3Vibm9kZS5cbiAgaWYgKHBhcmVudC50ZXh0KSB7XG4gICAgcGFyZW50LmNoaWxkcmVuLnB1c2goe1xuICAgICAgdGV4dDogcGFyZW50LnRleHQsXG4gICAgICBwYXJlbnQ6IHBhcmVudFxuICAgIH0pO1xuICAgIGRlbGV0ZSBwYXJlbnQudGV4dDtcbiAgfVxuXG4gIG4ucGFyZW50ID0gcGFyZW50O1xuICBwYXJlbnQuY2hpbGRyZW4ucHVzaChuKTtcblxuICByZXR1cm4gcGFyZW50O1xufVxuXG4vLyBSZXR1cm5zIGEgdHJlZSBvZiBub2Rlcy5cbmZ1bmN0aW9uIHNwYW5zVG9UcmVlKHBhcmVudCwgdGV4dCwgc3RhcnQsIGVuZCwgc3BhbnMpIHtcbiAgaWYgKCFzcGFucyB8fCBzcGFucy5sZW5ndGggPT0gMCkge1xuICAgIGlmIChzdGFydCA8IGVuZCkge1xuICAgICAgYWRkTm9kZShwYXJlbnQsIHtcbiAgICAgICAgdGV4dDogdGV4dC5zdWJzdHJpbmcoc3RhcnQsIGVuZClcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcGFyZW50O1xuICB9XG5cbiAgLy8gUHJvY2VzcyBzdWJzcGFucy5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGFucy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHNwYW4gPSBzcGFuc1tpXTtcbiAgICBpZiAoc3Bhbi5zdGFydCA8IDAgJiYgc3Bhbi50eXBlID09ICdFWCcpIHtcbiAgICAgIGFkZE5vZGUocGFyZW50LCB7XG4gICAgICAgIHR5cGU6IHNwYW4udHlwZSxcbiAgICAgICAgZGF0YTogc3Bhbi5kYXRhLFxuICAgICAgICBrZXk6IHNwYW4ua2V5LFxuICAgICAgICBhdHQ6IHRydWVcbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gQWRkIHVuLXN0eWxlZCByYW5nZSBiZWZvcmUgdGhlIHN0eWxlZCBzcGFuIHN0YXJ0cy5cbiAgICBpZiAoc3RhcnQgPCBzcGFuLnN0YXJ0KSB7XG4gICAgICBhZGROb2RlKHBhcmVudCwge1xuICAgICAgICB0ZXh0OiB0ZXh0LnN1YnN0cmluZyhzdGFydCwgc3Bhbi5zdGFydClcbiAgICAgIH0pO1xuICAgICAgc3RhcnQgPSBzcGFuLnN0YXJ0O1xuICAgIH1cblxuICAgIC8vIEdldCBhbGwgc3BhbnMgd2hpY2ggYXJlIHdpdGhpbiB0aGUgY3VycmVudCBzcGFuLlxuICAgIGNvbnN0IHN1YnNwYW5zID0gW107XG4gICAgd2hpbGUgKGkgPCBzcGFucy5sZW5ndGggLSAxKSB7XG4gICAgICBjb25zdCBpbm5lciA9IHNwYW5zW2kgKyAxXTtcbiAgICAgIGlmIChpbm5lci5zdGFydCA8IDApIHtcbiAgICAgICAgLy8gQXR0YWNobWVudHMgYXJlIGluIHRoZSBlbmQuIFN0b3AuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIGlmIChpbm5lci5zdGFydCA8IHNwYW4uZW5kKSB7XG4gICAgICAgIGlmIChpbm5lci5lbmQgPD0gc3Bhbi5lbmQpIHtcbiAgICAgICAgICBjb25zdCB0YWcgPSBIVE1MX1RBR1NbaW5uZXIudHBdIHx8IHt9O1xuICAgICAgICAgIGlmIChpbm5lci5zdGFydCA8IGlubmVyLmVuZCB8fCB0YWcuaXNWb2lkKSB7XG4gICAgICAgICAgICAvLyBWYWxpZCBzdWJzcGFuOiBjb21wbGV0ZWx5IHdpdGhpbiB0aGUgY3VycmVudCBzcGFuIGFuZFxuICAgICAgICAgICAgLy8gZWl0aGVyIG5vbi16ZXJvIGxlbmd0aCBvciB6ZXJvIGxlbmd0aCBpcyBhY2NlcHRhYmxlLlxuICAgICAgICAgICAgc3Vic3BhbnMucHVzaChpbm5lcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGkrKztcbiAgICAgICAgLy8gT3ZlcmxhcHBpbmcgc3Vic3BhbnMgYXJlIGlnbm9yZWQuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBQYXN0IHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgc3Bhbi4gU3RvcC5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYWRkTm9kZShwYXJlbnQsIHNwYW5zVG9UcmVlKHtcbiAgICAgIHR5cGU6IHNwYW4udHlwZSxcbiAgICAgIGRhdGE6IHNwYW4uZGF0YSxcbiAgICAgIGtleTogc3Bhbi5rZXlcbiAgICB9LCB0ZXh0LCBzdGFydCwgc3Bhbi5lbmQsIHN1YnNwYW5zKSk7XG4gICAgc3RhcnQgPSBzcGFuLmVuZDtcbiAgfVxuXG4gIC8vIEFkZCB0aGUgbGFzdCB1bmZvcm1hdHRlZCByYW5nZS5cbiAgaWYgKHN0YXJ0IDwgZW5kKSB7XG4gICAgYWRkTm9kZShwYXJlbnQsIHtcbiAgICAgIHRleHQ6IHRleHQuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcGFyZW50O1xufVxuXG4vLyBBcHBlbmQgYSB0cmVlIHRvIGEgRHJhZnR5IGRvYy5cbmZ1bmN0aW9uIHRyZWVUb0RyYWZ0eShkb2MsIHRyZWUsIGtleW1hcCkge1xuICBpZiAoIXRyZWUpIHtcbiAgICByZXR1cm4gZG9jO1xuICB9XG5cbiAgZG9jLnR4dCA9IGRvYy50eHQgfHwgJyc7XG5cbiAgLy8gQ2hlY2twb2ludCB0byBtZWFzdXJlIGxlbmd0aCBvZiB0aGUgY3VycmVudCB0cmVlIG5vZGUuXG4gIGNvbnN0IHN0YXJ0ID0gZG9jLnR4dC5sZW5ndGg7XG5cbiAgaWYgKHRyZWUudGV4dCkge1xuICAgIGRvYy50eHQgKz0gdHJlZS50ZXh0O1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodHJlZS5jaGlsZHJlbikpIHtcbiAgICB0cmVlLmNoaWxkcmVuLmZvckVhY2goKGMpID0+IHtcbiAgICAgIHRyZWVUb0RyYWZ0eShkb2MsIGMsIGtleW1hcCk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAodHJlZS50eXBlKSB7XG4gICAgY29uc3QgbGVuID0gZG9jLnR4dC5sZW5ndGggLSBzdGFydDtcbiAgICBkb2MuZm10ID0gZG9jLmZtdCB8fCBbXTtcbiAgICBpZiAoT2JqZWN0LmtleXModHJlZS5kYXRhIHx8IHt9KS5sZW5ndGggPiAwKSB7XG4gICAgICBkb2MuZW50ID0gZG9jLmVudCB8fCBbXTtcbiAgICAgIGNvbnN0IG5ld0tleSA9ICh0eXBlb2Yga2V5bWFwW3RyZWUua2V5XSA9PSAndW5kZWZpbmVkJykgPyBkb2MuZW50Lmxlbmd0aCA6IGtleW1hcFt0cmVlLmtleV07XG4gICAgICBrZXltYXBbdHJlZS5rZXldID0gbmV3S2V5O1xuICAgICAgZG9jLmVudFtuZXdLZXldID0ge1xuICAgICAgICB0cDogdHJlZS50eXBlLFxuICAgICAgICBkYXRhOiB0cmVlLmRhdGFcbiAgICAgIH07XG4gICAgICBpZiAodHJlZS5hdHQpIHtcbiAgICAgICAgLy8gQXR0YWNobWVudC5cbiAgICAgICAgZG9jLmZtdC5wdXNoKHtcbiAgICAgICAgICBhdDogLTEsXG4gICAgICAgICAgbGVuOiAwLFxuICAgICAgICAgIGtleTogbmV3S2V5XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG9jLmZtdC5wdXNoKHtcbiAgICAgICAgICBhdDogc3RhcnQsXG4gICAgICAgICAgbGVuOiBsZW4sXG4gICAgICAgICAga2V5OiBuZXdLZXlcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvYy5mbXQucHVzaCh7XG4gICAgICAgIHRwOiB0cmVlLnR5cGUsXG4gICAgICAgIGF0OiBzdGFydCxcbiAgICAgICAgbGVuOiBsZW5cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZG9jO1xufVxuXG4vLyBUcmF2ZXJzZSB0aGUgdHJlZSB0b3AgZG93biB0cmFuc2Zvcm1pbmcgdGhlIG5vZGVzOiBhcHBseSB0cmFuc2Zvcm1lciB0byBldmVyeSB0cmVlIG5vZGUuXG5mdW5jdGlvbiB0cmVlVG9wRG93bihzcmMsIHRyYW5zZm9ybWVyLCBjb250ZXh0KSB7XG4gIGlmICghc3JjKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBsZXQgZHN0ID0gdHJhbnNmb3JtZXIuY2FsbChjb250ZXh0LCBzcmMpO1xuICBpZiAoIWRzdCB8fCAhZHN0LmNoaWxkcmVuKSB7XG4gICAgcmV0dXJuIGRzdDtcbiAgfVxuXG4gIGNvbnN0IGNoaWxkcmVuID0gW107XG4gIGZvciAobGV0IGkgaW4gZHN0LmNoaWxkcmVuKSB7XG4gICAgbGV0IG4gPSBkc3QuY2hpbGRyZW5baV07XG4gICAgaWYgKG4pIHtcbiAgICAgIG4gPSB0cmVlVG9wRG93bihuLCB0cmFuc2Zvcm1lciwgY29udGV4dCk7XG4gICAgICBpZiAobikge1xuICAgICAgICBjaGlsZHJlbi5wdXNoKG4pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChjaGlsZHJlbi5sZW5ndGggPT0gMCkge1xuICAgIGRzdC5jaGlsZHJlbiA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgZHN0LmNoaWxkcmVuID0gY2hpbGRyZW47XG4gIH1cblxuICByZXR1cm4gZHN0O1xufVxuXG4vLyBUcmF2ZXJzZSB0aGUgdHJlZSBib3R0b20tdXA6IGFwcGx5IGZvcm1hdHRlciB0byBldmVyeSBub2RlLlxuLy8gVGhlIGZvcm1hdHRlciBtdXN0IG1haW50YWluIGl0cyBzdGF0ZSB0aHJvdWdoIGNvbnRleHQuXG5mdW5jdGlvbiB0cmVlQm90dG9tVXAoc3JjLCBmb3JtYXR0ZXIsIGluZGV4LCBzdGFjaywgY29udGV4dCkge1xuICBpZiAoIXNyYykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKHN0YWNrICYmIHNyYy50eXBlKSB7XG4gICAgc3RhY2sucHVzaChzcmMudHlwZSk7XG4gIH1cblxuICBsZXQgdmFsdWVzID0gW107XG4gIGZvciAobGV0IGkgaW4gc3JjLmNoaWxkcmVuKSB7XG4gICAgY29uc3QgbiA9IHRyZWVCb3R0b21VcChzcmMuY2hpbGRyZW5baV0sIGZvcm1hdHRlciwgaSwgc3RhY2ssIGNvbnRleHQpO1xuICAgIGlmIChuKSB7XG4gICAgICB2YWx1ZXMucHVzaChuKTtcbiAgICB9XG4gIH1cbiAgaWYgKHZhbHVlcy5sZW5ndGggPT0gMCkge1xuICAgIGlmIChzcmMudGV4dCkge1xuICAgICAgdmFsdWVzID0gW3NyYy50ZXh0XTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWVzID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhY2sgJiYgc3JjLnR5cGUpIHtcbiAgICBzdGFjay5wb3AoKTtcbiAgfVxuXG4gIHJldHVybiBmb3JtYXR0ZXIuY2FsbChjb250ZXh0LCBzcmMudHlwZSwgc3JjLmRhdGEsIHZhbHVlcywgaW5kZXgsIHN0YWNrKTtcbn1cblxuLy8gQ2xpcCB0cmVlIHRvIHRoZSBwcm92aWRlZCBsaW1pdC5cbmZ1bmN0aW9uIHNob3J0ZW5UcmVlKHRyZWUsIGxpbWl0LCB0YWlsKSB7XG4gIGlmICghdHJlZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKHRhaWwpIHtcbiAgICBsaW1pdCAtPSB0YWlsLmxlbmd0aDtcbiAgfVxuXG4gIGNvbnN0IHNob3J0ZW5lciA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAobGltaXQgPD0gLTEpIHtcbiAgICAgIC8vIExpbWl0IC0xIG1lYW5zIHRoZSBkb2Mgd2FzIGFscmVhZHkgY2xpcHBlZC5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChub2RlLmF0dCkge1xuICAgICAgLy8gQXR0YWNobWVudHMgYXJlIHVuY2hhbmdlZC5cbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbiAgICBpZiAobGltaXQgPT0gMCkge1xuICAgICAgbm9kZS50ZXh0ID0gdGFpbDtcbiAgICAgIGxpbWl0ID0gLTE7XG4gICAgfSBlbHNlIGlmIChub2RlLnRleHQpIHtcbiAgICAgIGNvbnN0IGxlbiA9IG5vZGUudGV4dC5sZW5ndGg7XG4gICAgICBpZiAobGVuID4gbGltaXQpIHtcbiAgICAgICAgbm9kZS50ZXh0ID0gbm9kZS50ZXh0LnN1YnN0cmluZygwLCBsaW1pdCkgKyB0YWlsO1xuICAgICAgICBsaW1pdCA9IC0xO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGltaXQgLT0gbGVuO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHJldHVybiB0cmVlVG9wRG93bih0cmVlLCBzaG9ydGVuZXIpO1xufVxuXG4vLyBTdHJpcCBoZWF2eSBlbnRpdGllcyBmcm9tIGEgdHJlZS5cbmZ1bmN0aW9uIGxpZ2h0RW50aXR5KHRyZWUsIGFsbG93KSB7XG4gIGNvbnN0IGxpZ2h0Q29weSA9IChub2RlKSA9PiB7XG4gICAgY29uc3QgZGF0YSA9IGNvcHlFbnREYXRhKG5vZGUuZGF0YSwgdHJ1ZSwgYWxsb3cgPyBhbGxvdyhub2RlKSA6IG51bGwpO1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBub2RlLmRhdGEgPSBkYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGUgbm9kZS5kYXRhO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuICByZXR1cm4gdHJlZVRvcERvd24odHJlZSwgbGlnaHRDb3B5KTtcbn1cblxuLy8gUmVtb3ZlIHNwYWNlcyBhbmQgYnJlYWtzIG9uIHRoZSBsZWZ0LlxuZnVuY3Rpb24gbFRyaW0odHJlZSkge1xuICBpZiAodHJlZS50eXBlID09ICdCUicpIHtcbiAgICB0cmVlID0gbnVsbDtcbiAgfSBlbHNlIGlmICh0cmVlLnRleHQpIHtcbiAgICBpZiAoIXRyZWUudHlwZSkge1xuICAgICAgdHJlZS50ZXh0ID0gdHJlZS50ZXh0LnRyaW1TdGFydCgpO1xuICAgICAgaWYgKCF0cmVlLnRleHQpIHtcbiAgICAgICAgdHJlZSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKCF0cmVlLnR5cGUgJiYgdHJlZS5jaGlsZHJlbiAmJiB0cmVlLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjID0gbFRyaW0odHJlZS5jaGlsZHJlblswXSk7XG4gICAgaWYgKGMpIHtcbiAgICAgIHRyZWUuY2hpbGRyZW5bMF0gPSBjO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cmVlLmNoaWxkcmVuLnNoaWZ0KCk7XG4gICAgICBpZiAoIXRyZWUudHlwZSAmJiB0cmVlLmNoaWxkcmVuLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIHRyZWUgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJlZTtcbn1cblxuLy8gTW92ZSBhdHRhY2htZW50cyB0byB0aGUgZW5kLiBBdHRhY2htZW50cyBtdXN0IGJlIGF0IHRoZSB0b3AgbGV2ZWwsIG5vIG5lZWQgdG8gdHJhdmVyc2UgdGhlIHRyZWUuXG5mdW5jdGlvbiBhdHRhY2htZW50c1RvRW5kKHRyZWUsIGxpbWl0KSB7XG4gIGlmICghdHJlZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKHRyZWUuYXR0KSB7XG4gICAgdHJlZS50ZXh0ID0gJyAnO1xuICAgIGRlbGV0ZSB0cmVlLmF0dDtcbiAgICBkZWxldGUgdHJlZS5jaGlsZHJlbjtcbiAgfSBlbHNlIGlmICh0cmVlLmNoaWxkcmVuKSB7XG4gICAgY29uc3QgYXR0YWNobWVudHMgPSBbXTtcbiAgICBjb25zdCBjaGlsZHJlbiA9IFtdO1xuICAgIGZvciAobGV0IGkgaW4gdHJlZS5jaGlsZHJlbikge1xuICAgICAgY29uc3QgYyA9IHRyZWUuY2hpbGRyZW5baV07XG4gICAgICBpZiAoYy5hdHQpIHtcbiAgICAgICAgaWYgKGF0dGFjaG1lbnRzLmxlbmd0aCA9PSBsaW1pdCkge1xuICAgICAgICAgIC8vIFRvbyBtYW55IGF0dGFjaG1lbnRzIHRvIHByZXZpZXc7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGMuZGF0YVsnbWltZSddID09IEpTT05fTUlNRV9UWVBFKSB7XG4gICAgICAgICAgLy8gSlNPTiBhdHRhY2htZW50cyBhcmUgbm90IHNob3duIGluIHByZXZpZXcuXG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBkZWxldGUgYy5hdHQ7XG4gICAgICAgIGRlbGV0ZSBjLmNoaWxkcmVuO1xuICAgICAgICBjLnRleHQgPSAnICc7XG4gICAgICAgIGF0dGFjaG1lbnRzLnB1c2goYyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGlsZHJlbi5wdXNoKGMpO1xuICAgICAgfVxuICAgIH1cbiAgICB0cmVlLmNoaWxkcmVuID0gY2hpbGRyZW4uY29uY2F0KGF0dGFjaG1lbnRzKTtcbiAgfVxuICByZXR1cm4gdHJlZTtcbn1cblxuLy8gR2V0IGEgbGlzdCBvZiBlbnRpdGllcyBmcm9tIGEgdGV4dC5cbmZ1bmN0aW9uIGV4dHJhY3RFbnRpdGllcyhsaW5lKSB7XG4gIGxldCBtYXRjaDtcbiAgbGV0IGV4dHJhY3RlZCA9IFtdO1xuICBFTlRJVFlfVFlQRVMuZm9yRWFjaCgoZW50aXR5KSA9PiB7XG4gICAgd2hpbGUgKChtYXRjaCA9IGVudGl0eS5yZS5leGVjKGxpbmUpKSAhPT0gbnVsbCkge1xuICAgICAgZXh0cmFjdGVkLnB1c2goe1xuICAgICAgICBvZmZzZXQ6IG1hdGNoWydpbmRleCddLFxuICAgICAgICBsZW46IG1hdGNoWzBdLmxlbmd0aCxcbiAgICAgICAgdW5pcXVlOiBtYXRjaFswXSxcbiAgICAgICAgZGF0YTogZW50aXR5LnBhY2sobWF0Y2hbMF0pLFxuICAgICAgICB0eXBlOiBlbnRpdHkubmFtZVxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICBpZiAoZXh0cmFjdGVkLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuIGV4dHJhY3RlZDtcbiAgfVxuXG4gIC8vIFJlbW92ZSBlbnRpdGllcyBkZXRlY3RlZCBpbnNpZGUgb3RoZXIgZW50aXRpZXMsIGxpa2UgI2hhc2h0YWcgaW4gYSBVUkwuXG4gIGV4dHJhY3RlZC5zb3J0KChhLCBiKSA9PiB7XG4gICAgcmV0dXJuIGEub2Zmc2V0IC0gYi5vZmZzZXQ7XG4gIH0pO1xuXG4gIGxldCBpZHggPSAtMTtcbiAgZXh0cmFjdGVkID0gZXh0cmFjdGVkLmZpbHRlcigoZWwpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSAoZWwub2Zmc2V0ID4gaWR4KTtcbiAgICBpZHggPSBlbC5vZmZzZXQgKyBlbC5sZW47XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSk7XG5cbiAgcmV0dXJuIGV4dHJhY3RlZDtcbn1cblxuLy8gQ29udmVydCB0aGUgY2h1bmtzIGludG8gZm9ybWF0IHN1aXRhYmxlIGZvciBzZXJpYWxpemF0aW9uLlxuZnVuY3Rpb24gZHJhZnRpZnkoY2h1bmtzLCBzdGFydEF0KSB7XG4gIGxldCBwbGFpbiA9ICcnO1xuICBsZXQgcmFuZ2VzID0gW107XG4gIGZvciAobGV0IGkgaW4gY2h1bmtzKSB7XG4gICAgY29uc3QgY2h1bmsgPSBjaHVua3NbaV07XG4gICAgaWYgKCFjaHVuay50eHQpIHtcbiAgICAgIGNvbnN0IGRyYWZ0eSA9IGRyYWZ0aWZ5KGNodW5rLmNoaWxkcmVuLCBwbGFpbi5sZW5ndGggKyBzdGFydEF0KTtcbiAgICAgIGNodW5rLnR4dCA9IGRyYWZ0eS50eHQ7XG4gICAgICByYW5nZXMgPSByYW5nZXMuY29uY2F0KGRyYWZ0eS5mbXQpO1xuICAgIH1cblxuICAgIGlmIChjaHVuay50cCkge1xuICAgICAgcmFuZ2VzLnB1c2goe1xuICAgICAgICBhdDogcGxhaW4ubGVuZ3RoICsgc3RhcnRBdCxcbiAgICAgICAgbGVuOiBjaHVuay50eHQubGVuZ3RoLFxuICAgICAgICB0cDogY2h1bmsudHBcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHBsYWluICs9IGNodW5rLnR4dDtcbiAgfVxuICByZXR1cm4ge1xuICAgIHR4dDogcGxhaW4sXG4gICAgZm10OiByYW5nZXNcbiAgfTtcbn1cblxuLy8gQ3JlYXRlIGEgY29weSBvZiBlbnRpdHkgZGF0YSB3aXRoIChsaWdodD1mYWxzZSkgb3Igd2l0aG91dCAobGlnaHQ9dHJ1ZSkgdGhlIGxhcmdlIHBheWxvYWQuXG4vLyBUaGUgYXJyYXkgJ2FsbG93JyBjb250YWlucyBhIGxpc3Qgb2YgZmllbGRzIGV4ZW1wdCBmcm9tIHN0cmlwcGluZy5cbmZ1bmN0aW9uIGNvcHlFbnREYXRhKGRhdGEsIGxpZ2h0LCBhbGxvdykge1xuICBpZiAoZGF0YSAmJiBPYmplY3QuZW50cmllcyhkYXRhKS5sZW5ndGggPiAwKSB7XG4gICAgYWxsb3cgPSBhbGxvdyB8fCBbXTtcbiAgICBjb25zdCBkYyA9IHt9O1xuICAgIEFMTE9XRURfRU5UX0ZJRUxEUy5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgIGlmIChkYXRhW2tleV0pIHtcbiAgICAgICAgaWYgKGxpZ2h0ICYmICFhbGxvdy5pbmNsdWRlcyhrZXkpICYmXG4gICAgICAgICAgKHR5cGVvZiBkYXRhW2tleV0gPT0gJ3N0cmluZycgfHwgQXJyYXkuaXNBcnJheShkYXRhW2tleV0pKSAmJlxuICAgICAgICAgIGRhdGFba2V5XS5sZW5ndGggPiBNQVhfUFJFVklFV19EQVRBX1NJWkUpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhW2tleV0gPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgZGNba2V5XSA9IGRhdGFba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChPYmplY3QuZW50cmllcyhkYykubGVuZ3RoICE9IDApIHtcbiAgICAgIHJldHVybiBkYztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmlmICh0eXBlb2YgbW9kdWxlICE9ICd1bmRlZmluZWQnKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gRHJhZnR5O1xufVxuIiwiLyoqXG4gKiBAZmlsZSBVdGlsaXRpZXMgZm9yIHVwbG9hZGluZyBhbmQgZG93bmxvYWRpbmcgZmlsZXMuXG4gKlxuICogQGNvcHlyaWdodCAyMDE1LTIwMjIgVGlub2RlIExMQy5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge1xuICBqc29uUGFyc2VIZWxwZXJcbn0gZnJvbSAnLi91dGlscy5qcyc7XG5cbmxldCBYSFJQcm92aWRlcjtcblxuLyoqXG4gKiBAY2xhc3MgTGFyZ2VGaWxlSGVscGVyIC0gdXRpbGl0aWVzIGZvciB1cGxvYWRpbmcgYW5kIGRvd25sb2FkaW5nIGZpbGVzIG91dCBvZiBiYW5kLlxuICogRG9uJ3QgaW5zdGFudGlhdGUgdGhpcyBjbGFzcyBkaXJlY3RseS4gVXNlIHtUaW5vZGUuZ2V0TGFyZ2VGaWxlSGVscGVyfSBpbnN0ZWFkLlxuICogQG1lbWJlcm9mIFRpbm9kZVxuICpcbiAqIEBwYXJhbSB7VGlub2RlfSB0aW5vZGUgLSB0aGUgbWFpbiBUaW5vZGUgb2JqZWN0LlxuICogQHBhcmFtIHtzdHJpbmd9IHZlcnNpb24gLSBwcm90b2NvbCB2ZXJzaW9uLCBpLmUuICcwJy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGFyZ2VGaWxlSGVscGVyIHtcbiAgY29uc3RydWN0b3IodGlub2RlLCB2ZXJzaW9uKSB7XG4gICAgdGhpcy5fdGlub2RlID0gdGlub2RlO1xuICAgIHRoaXMuX3ZlcnNpb24gPSB2ZXJzaW9uO1xuXG4gICAgdGhpcy5fYXBpS2V5ID0gdGlub2RlLl9hcGlLZXk7XG4gICAgdGhpcy5fYXV0aFRva2VuID0gdGlub2RlLmdldEF1dGhUb2tlbigpO1xuICAgIHRoaXMuX3JlcUlkID0gdGlub2RlLmdldE5leHRVbmlxdWVJZCgpO1xuICAgIHRoaXMueGhyID0gbmV3IFhIUlByb3ZpZGVyKCk7XG5cbiAgICAvLyBQcm9taXNlXG4gICAgdGhpcy50b1Jlc29sdmUgPSBudWxsO1xuICAgIHRoaXMudG9SZWplY3QgPSBudWxsO1xuXG4gICAgLy8gQ2FsbGJhY2tzXG4gICAgdGhpcy5vblByb2dyZXNzID0gbnVsbDtcbiAgICB0aGlzLm9uU3VjY2VzcyA9IG51bGw7XG4gICAgdGhpcy5vbkZhaWx1cmUgPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHVwbG9hZGluZyB0aGUgZmlsZSB0byBhIG5vbi1kZWZhdWx0IGVuZHBvaW50LlxuICAgKlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkxhcmdlRmlsZUhlbHBlciNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVcmwgYWx0ZXJuYXRpdmUgYmFzZSBVUkwgb2YgdXBsb2FkIHNlcnZlci5cbiAgICogQHBhcmFtIHtGaWxlfEJsb2J9IGRhdGEgdG8gdXBsb2FkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXZhdGFyRm9yIHRvcGljIG5hbWUgaWYgdGhlIHVwbG9hZCByZXByZXNlbnRzIGFuIGF2YXRhci5cbiAgICogQHBhcmFtIHtDYWxsYmFja30gb25Qcm9ncmVzcyBjYWxsYmFjay4gVGFrZXMgb25lIHtmbG9hdH0gcGFyYW1ldGVyIDAuLjFcbiAgICogQHBhcmFtIHtDYWxsYmFja30gb25TdWNjZXNzIGNhbGxiYWNrLiBDYWxsZWQgd2hlbiB0aGUgZmlsZSBpcyBzdWNjZXNzZnVsbHkgdXBsb2FkZWQuXG4gICAqIEBwYXJhbSB7Q2FsbGJhY2t9IG9uRmFpbHVyZSBjYWxsYmFjay4gQ2FsbGVkIGluIGNhc2Ugb2YgYSBmYWlsdXJlLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgdXBsb2FkIGlzIGNvbXBsZXRlZC9mYWlsZWQuXG4gICAqL1xuICB1cGxvYWRXaXRoQmFzZVVybChiYXNlVXJsLCBkYXRhLCBhdmF0YXJGb3IsIG9uUHJvZ3Jlc3MsIG9uU3VjY2Vzcywgb25GYWlsdXJlKSB7XG4gICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzO1xuXG4gICAgbGV0IHVybCA9IGAvdiR7dGhpcy5fdmVyc2lvbn0vZmlsZS91L2A7XG4gICAgaWYgKGJhc2VVcmwpIHtcbiAgICAgIGxldCBiYXNlID0gYmFzZVVybDtcbiAgICAgIGlmIChiYXNlLmVuZHNXaXRoKCcvJykpIHtcbiAgICAgICAgLy8gUmVtb3ZpbmcgdHJhaWxpbmcgc2xhc2guXG4gICAgICAgIGJhc2UgPSBiYXNlLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIGlmIChiYXNlLnN0YXJ0c1dpdGgoJ2h0dHA6Ly8nKSB8fCBiYXNlLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJykpIHtcbiAgICAgICAgdXJsID0gYmFzZSArIHVybDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBiYXNlIFVSTCAnJHtiYXNlVXJsfSdgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy54aHIub3BlbignUE9TVCcsIHVybCwgdHJ1ZSk7XG4gICAgdGhpcy54aHIuc2V0UmVxdWVzdEhlYWRlcignWC1UaW5vZGUtQVBJS2V5JywgdGhpcy5fYXBpS2V5KTtcbiAgICBpZiAodGhpcy5fYXV0aFRva2VuKSB7XG4gICAgICB0aGlzLnhoci5zZXRSZXF1ZXN0SGVhZGVyKCdYLVRpbm9kZS1BdXRoJywgYFRva2VuICR7dGhpcy5fYXV0aFRva2VuLnRva2VufWApO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnRvUmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICB0aGlzLnRvUmVqZWN0ID0gcmVqZWN0O1xuICAgIH0pO1xuXG4gICAgdGhpcy5vblByb2dyZXNzID0gb25Qcm9ncmVzcztcbiAgICB0aGlzLm9uU3VjY2VzcyA9IG9uU3VjY2VzcztcbiAgICB0aGlzLm9uRmFpbHVyZSA9IG9uRmFpbHVyZTtcblxuICAgIHRoaXMueGhyLnVwbG9hZC5vbnByb2dyZXNzID0gKGUpID0+IHtcbiAgICAgIGlmIChlLmxlbmd0aENvbXB1dGFibGUgJiYgaW5zdGFuY2Uub25Qcm9ncmVzcykge1xuICAgICAgICBpbnN0YW5jZS5vblByb2dyZXNzKGUubG9hZGVkIC8gZS50b3RhbCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMueGhyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgbGV0IHBrdDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHBrdCA9IEpTT04ucGFyc2UodGhpcy5yZXNwb25zZSwganNvblBhcnNlSGVscGVyKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpbnN0YW5jZS5fdGlub2RlLmxvZ2dlcihcIkVSUk9SOiBJbnZhbGlkIHNlcnZlciByZXNwb25zZSBpbiBMYXJnZUZpbGVIZWxwZXJcIiwgdGhpcy5yZXNwb25zZSk7XG4gICAgICAgIHBrdCA9IHtcbiAgICAgICAgICBjdHJsOiB7XG4gICAgICAgICAgICBjb2RlOiB0aGlzLnN0YXR1cyxcbiAgICAgICAgICAgIHRleHQ6IHRoaXMuc3RhdHVzVGV4dFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RhdHVzID49IDIwMCAmJiB0aGlzLnN0YXR1cyA8IDMwMCkge1xuICAgICAgICBpZiAoaW5zdGFuY2UudG9SZXNvbHZlKSB7XG4gICAgICAgICAgaW5zdGFuY2UudG9SZXNvbHZlKHBrdC5jdHJsLnBhcmFtcy51cmwpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbnN0YW5jZS5vblN1Y2Nlc3MpIHtcbiAgICAgICAgICBpbnN0YW5jZS5vblN1Y2Nlc3MocGt0LmN0cmwpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdHVzID49IDQwMCkge1xuICAgICAgICBpZiAoaW5zdGFuY2UudG9SZWplY3QpIHtcbiAgICAgICAgICBpbnN0YW5jZS50b1JlamVjdChuZXcgRXJyb3IoYCR7cGt0LmN0cmwudGV4dH0gKCR7cGt0LmN0cmwuY29kZX0pYCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbnN0YW5jZS5vbkZhaWx1cmUpIHtcbiAgICAgICAgICBpbnN0YW5jZS5vbkZhaWx1cmUocGt0LmN0cmwpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbnN0YW5jZS5fdGlub2RlLmxvZ2dlcihcIkVSUk9SOiBVbmV4cGVjdGVkIHNlcnZlciByZXNwb25zZSBzdGF0dXNcIiwgdGhpcy5zdGF0dXMsIHRoaXMucmVzcG9uc2UpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLnhoci5vbmVycm9yID0gZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKGluc3RhbmNlLnRvUmVqZWN0KSB7XG4gICAgICAgIGluc3RhbmNlLnRvUmVqZWN0KG5ldyBFcnJvcihcImZhaWxlZFwiKSk7XG4gICAgICB9XG4gICAgICBpZiAoaW5zdGFuY2Uub25GYWlsdXJlKSB7XG4gICAgICAgIGluc3RhbmNlLm9uRmFpbHVyZShudWxsKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy54aHIub25hYm9ydCA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGlmIChpbnN0YW5jZS50b1JlamVjdCkge1xuICAgICAgICBpbnN0YW5jZS50b1JlamVjdChuZXcgRXJyb3IoXCJ1cGxvYWQgY2FuY2VsbGVkIGJ5IHVzZXJcIikpO1xuICAgICAgfVxuICAgICAgaWYgKGluc3RhbmNlLm9uRmFpbHVyZSkge1xuICAgICAgICBpbnN0YW5jZS5vbkZhaWx1cmUobnVsbCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBmb3JtID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICBmb3JtLmFwcGVuZCgnZmlsZScsIGRhdGEpO1xuICAgICAgZm9ybS5zZXQoJ2lkJywgdGhpcy5fcmVxSWQpO1xuICAgICAgaWYgKGF2YXRhckZvcikge1xuICAgICAgICBmb3JtLnNldCgndG9waWMnLCBhdmF0YXJGb3IpO1xuICAgICAgfVxuICAgICAgdGhpcy54aHIuc2VuZChmb3JtKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmICh0aGlzLnRvUmVqZWN0KSB7XG4gICAgICAgIHRoaXMudG9SZWplY3QoZXJyKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm9uRmFpbHVyZSkge1xuICAgICAgICB0aGlzLm9uRmFpbHVyZShudWxsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIC8qKlxuICAgKiBTdGFydCB1cGxvYWRpbmcgdGhlIGZpbGUgdG8gZGVmYXVsdCBlbmRwb2ludC5cbiAgICpcbiAgICogQG1lbWJlcm9mIFRpbm9kZS5MYXJnZUZpbGVIZWxwZXIjXG4gICAqXG4gICAqIEBwYXJhbSB7RmlsZXxCbG9ifSBkYXRhIHRvIHVwbG9hZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXZhdGFyRm9yIHRvcGljIG5hbWUgaWYgdGhlIHVwbG9hZCByZXByZXNlbnRzIGFuIGF2YXRhci5cbiAgICogQHBhcmFtIHtDYWxsYmFja30gb25Qcm9ncmVzcyBjYWxsYmFjay4gVGFrZXMgb25lIHtmbG9hdH0gcGFyYW1ldGVyIDAuLjFcbiAgICogQHBhcmFtIHtDYWxsYmFja30gb25TdWNjZXNzIGNhbGxiYWNrLiBDYWxsZWQgd2hlbiB0aGUgZmlsZSBpcyBzdWNjZXNzZnVsbHkgdXBsb2FkZWQuXG4gICAqIEBwYXJhbSB7Q2FsbGJhY2t9IG9uRmFpbHVyZSBjYWxsYmFjay4gQ2FsbGVkIGluIGNhc2Ugb2YgYSBmYWlsdXJlLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgdXBsb2FkIGlzIGNvbXBsZXRlZC9mYWlsZWQuXG4gICAqL1xuICB1cGxvYWQoZGF0YSwgYXZhdGFyRm9yLCBvblByb2dyZXNzLCBvblN1Y2Nlc3MsIG9uRmFpbHVyZSkge1xuICAgIGNvbnN0IGJhc2VVcmwgPSAodGhpcy5fdGlub2RlLl9zZWN1cmUgPyAnaHR0cHM6Ly8nIDogJ2h0dHA6Ly8nKSArIHRoaXMuX3Rpbm9kZS5faG9zdDtcbiAgICByZXR1cm4gdGhpcy51cGxvYWRXaXRoQmFzZVVybChiYXNlVXJsLCBkYXRhLCBhdmF0YXJGb3IsIG9uUHJvZ3Jlc3MsIG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgfVxuICAvKipcbiAgICogRG93bmxvYWQgdGhlIGZpbGUgZnJvbSBhIGdpdmVuIFVSTCB1c2luZyBHRVQgcmVxdWVzdC4gVGhpcyBtZXRob2Qgd29ya3Mgd2l0aCB0aGUgVGlub2RlIHNlcnZlciBvbmx5LlxuICAgKlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkxhcmdlRmlsZUhlbHBlciNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlbGF0aXZlVXJsIC0gVVJMIHRvIGRvd25sb2FkIHRoZSBmaWxlIGZyb20uIE11c3QgYmUgcmVsYXRpdmUgdXJsLCBpLmUuIG11c3Qgbm90IGNvbnRhaW4gdGhlIGhvc3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gZmlsZW5hbWUgLSBmaWxlIG5hbWUgdG8gdXNlIGZvciB0aGUgZG93bmxvYWRlZCBmaWxlLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgZG93bmxvYWQgaXMgY29tcGxldGVkL2ZhaWxlZC5cbiAgICovXG4gIGRvd25sb2FkKHJlbGF0aXZlVXJsLCBmaWxlbmFtZSwgbWltZXR5cGUsIG9uUHJvZ3Jlc3MsIG9uRXJyb3IpIHtcbiAgICBpZiAoIVRpbm9kZS5pc1JlbGF0aXZlVVJMKHJlbGF0aXZlVXJsKSkge1xuICAgICAgLy8gQXMgYSBzZWN1cml0eSBtZWFzdXJlIHJlZnVzZSB0byBkb3dubG9hZCBmcm9tIGFuIGFic29sdXRlIFVSTC5cbiAgICAgIGlmIChvbkVycm9yKSB7XG4gICAgICAgIG9uRXJyb3IoYFRoZSBVUkwgJyR7cmVsYXRpdmVVcmx9JyBtdXN0IGJlIHJlbGF0aXZlLCBub3QgYWJzb2x1dGVgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0aGlzLl9hdXRoVG9rZW4pIHtcbiAgICAgIGlmIChvbkVycm9yKSB7XG4gICAgICAgIG9uRXJyb3IoXCJNdXN0IGF1dGhlbnRpY2F0ZSBmaXJzdFwiKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzO1xuICAgIC8vIEdldCBkYXRhIGFzIGJsb2IgKHN0b3JlZCBieSB0aGUgYnJvd3NlciBhcyBhIHRlbXBvcmFyeSBmaWxlKS5cbiAgICB0aGlzLnhoci5vcGVuKCdHRVQnLCByZWxhdGl2ZVVybCwgdHJ1ZSk7XG4gICAgdGhpcy54aHIuc2V0UmVxdWVzdEhlYWRlcignWC1UaW5vZGUtQVBJS2V5JywgdGhpcy5fYXBpS2V5KTtcbiAgICB0aGlzLnhoci5zZXRSZXF1ZXN0SGVhZGVyKCdYLVRpbm9kZS1BdXRoJywgJ1Rva2VuICcgKyB0aGlzLl9hdXRoVG9rZW4udG9rZW4pO1xuICAgIHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9ICdibG9iJztcblxuICAgIHRoaXMub25Qcm9ncmVzcyA9IG9uUHJvZ3Jlc3M7XG4gICAgdGhpcy54aHIub25wcm9ncmVzcyA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGlmIChpbnN0YW5jZS5vblByb2dyZXNzKSB7XG4gICAgICAgIC8vIFBhc3NpbmcgZS5sb2FkZWQgaW5zdGVhZCBvZiBlLmxvYWRlZC9lLnRvdGFsIGJlY2F1c2UgZS50b3RhbFxuICAgICAgICAvLyBpcyBhbHdheXMgMCB3aXRoIGd6aXAgY29tcHJlc3Npb24gZW5hYmxlZCBieSB0aGUgc2VydmVyLlxuICAgICAgICBpbnN0YW5jZS5vblByb2dyZXNzKGUubG9hZGVkKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy50b1Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgdGhpcy50b1JlamVjdCA9IHJlamVjdDtcbiAgICB9KTtcblxuICAgIC8vIFRoZSBibG9iIG5lZWRzIHRvIGJlIHNhdmVkIGFzIGZpbGUuIFRoZXJlIGlzIG5vIGtub3duIHdheSB0b1xuICAgIC8vIHNhdmUgdGhlIGJsb2IgYXMgZmlsZSBvdGhlciB0aGFuIHRvIGZha2UgYSBjbGljayBvbiBhbiA8YSBocmVmLi4uIGRvd25sb2FkPS4uLj4uXG4gICAgdGhpcy54aHIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5zdGF0dXMgPT0gMjAwKSB7XG4gICAgICAgIGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgIC8vIFVSTC5jcmVhdGVPYmplY3RVUkwgaXMgbm90IGF2YWlsYWJsZSBpbiBub24tYnJvd3NlciBlbnZpcm9ubWVudC4gVGhpcyBjYWxsIHdpbGwgZmFpbC5cbiAgICAgICAgbGluay5ocmVmID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW3RoaXMucmVzcG9uc2VdLCB7XG4gICAgICAgICAgdHlwZTogbWltZXR5cGVcbiAgICAgICAgfSkpO1xuICAgICAgICBsaW5rLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIGxpbmsuc2V0QXR0cmlidXRlKCdkb3dubG9hZCcsIGZpbGVuYW1lKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChsaW5rKTtcbiAgICAgICAgbGluay5jbGljaygpO1xuICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGxpbmspO1xuICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTChsaW5rLmhyZWYpO1xuICAgICAgICBpZiAoaW5zdGFuY2UudG9SZXNvbHZlKSB7XG4gICAgICAgICAgaW5zdGFuY2UudG9SZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0dXMgPj0gNDAwICYmIGluc3RhbmNlLnRvUmVqZWN0KSB7XG4gICAgICAgIC8vIFRoZSB0aGlzLnJlc3BvbnNlVGV4dCBpcyB1bmRlZmluZWQsIG11c3QgdXNlIHRoaXMucmVzcG9uc2Ugd2hpY2ggaXMgYSBibG9iLlxuICAgICAgICAvLyBOZWVkIHRvIGNvbnZlcnQgdGhpcy5yZXNwb25zZSB0byBKU09OLiBUaGUgYmxvYiBjYW4gb25seSBiZSBhY2Nlc3NlZCBieSB0aGVcbiAgICAgICAgLy8gRmlsZVJlYWRlci5cbiAgICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwa3QgPSBKU09OLnBhcnNlKHRoaXMucmVzdWx0LCBqc29uUGFyc2VIZWxwZXIpO1xuICAgICAgICAgICAgaW5zdGFuY2UudG9SZWplY3QobmV3IEVycm9yKGAke3BrdC5jdHJsLnRleHR9ICgke3BrdC5jdHJsLmNvZGV9KWApKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGluc3RhbmNlLl90aW5vZGUubG9nZ2VyKFwiRVJST1I6IEludmFsaWQgc2VydmVyIHJlc3BvbnNlIGluIExhcmdlRmlsZUhlbHBlclwiLCB0aGlzLnJlc3VsdCk7XG4gICAgICAgICAgICBpbnN0YW5jZS50b1JlamVjdChlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmVhZGVyLnJlYWRBc1RleHQodGhpcy5yZXNwb25zZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMueGhyLm9uZXJyb3IgPSBmdW5jdGlvbihlKSB7XG4gICAgICBpZiAoaW5zdGFuY2UudG9SZWplY3QpIHtcbiAgICAgICAgaW5zdGFuY2UudG9SZWplY3QobmV3IEVycm9yKFwiZmFpbGVkXCIpKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy54aHIub25hYm9ydCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGluc3RhbmNlLnRvUmVqZWN0KSB7XG4gICAgICAgIGluc3RhbmNlLnRvUmVqZWN0KG51bGwpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy54aHIuc2VuZCgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKHRoaXMudG9SZWplY3QpIHtcbiAgICAgICAgdGhpcy50b1JlamVjdChlcnIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgLyoqXG4gICAqIFRyeSB0byBjYW5jZWwgYW4gb25nb2luZyB1cGxvYWQgb3IgZG93bmxvYWQuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuTGFyZ2VGaWxlSGVscGVyI1xuICAgKi9cbiAgY2FuY2VsKCkge1xuICAgIGlmICh0aGlzLnhociAmJiB0aGlzLnhoci5yZWFkeVN0YXRlIDwgNCkge1xuICAgICAgdGhpcy54aHIuYWJvcnQoKTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEdldCB1bmlxdWUgaWQgb2YgdGhpcyByZXF1ZXN0LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLkxhcmdlRmlsZUhlbHBlciNcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gdW5pcXVlIGlkXG4gICAqL1xuICBnZXRJZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVxSWQ7XG4gIH1cbiAgLyoqXG4gICAqIFRvIHVzZSBMYXJnZUZpbGVIZWxwZXIgaW4gYSBub24gYnJvd3NlciBjb250ZXh0LCBzdXBwbHkgWE1MSHR0cFJlcXVlc3QgcHJvdmlkZXIuXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlcm9mIExhcmdlRmlsZUhlbHBlclxuICAgKiBAcGFyYW0geGhyUHJvdmlkZXIgWE1MSHR0cFJlcXVlc3QgcHJvdmlkZXIsIGUuZy4gZm9yIG5vZGUgPGNvZGU+cmVxdWlyZSgneGhyJyk8L2NvZGU+LlxuICAgKi9cbiAgc3RhdGljIHNldE5ldHdvcmtQcm92aWRlcih4aHJQcm92aWRlcikge1xuICAgIFhIUlByb3ZpZGVyID0geGhyUHJvdmlkZXI7XG4gIH1cbn1cbiIsIi8qKlxuICogQGZpbGUgSGVscGVyIGNsYXNzIGZvciBjb25zdHJ1Y3Rpbmcge0BsaW5rIFRpbm9kZS5HZXRRdWVyeX0uXG4gKlxuICogQGNvcHlyaWdodCAyMDE1LTIwMjIgVGlub2RlIExMQy5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEhlbHBlciBjbGFzcyBmb3IgY29uc3RydWN0aW5nIHtAbGluayBUaW5vZGUuR2V0UXVlcnl9LlxuICpcbiAqIEBjbGFzcyBNZXRhR2V0QnVpbGRlclxuICogQG1lbWJlcm9mIFRpbm9kZVxuICpcbiAqIEBwYXJhbSB7VGlub2RlLlRvcGljfSBwYXJlbnQgdG9waWMgd2hpY2ggaW5zdGFudGlhdGVkIHRoaXMgYnVpbGRlci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWV0YUdldEJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcihwYXJlbnQpIHtcbiAgICB0aGlzLnRvcGljID0gcGFyZW50O1xuICAgIHRoaXMud2hhdCA9IHt9O1xuICB9XG5cbiAgLy8gR2V0IHRpbWVzdGFtcCBvZiB0aGUgbW9zdCByZWNlbnQgZGVzYyB1cGRhdGUuXG4gICNnZXRfZGVzY19pbXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9waWMudXBkYXRlZDtcbiAgfVxuXG4gIC8vIEdldCB0aW1lc3RhbXAgb2YgdGhlIG1vc3QgcmVjZW50IHN1YnMgdXBkYXRlLlxuICAjZ2V0X3N1YnNfaW1zKCkge1xuICAgIGlmICh0aGlzLnRvcGljLmlzUDJQVHlwZSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy4jZ2V0X2Rlc2NfaW1zKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRvcGljLl9sYXN0U3Vic1VwZGF0ZTtcbiAgfVxuICAvKipcbiAgICogQWRkIHF1ZXJ5IHBhcmFtZXRlcnMgdG8gZmV0Y2ggbWVzc2FnZXMgd2l0aGluIGV4cGxpY2l0IGxpbWl0cy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5NZXRhR2V0QnVpbGRlciNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXI9fSBzaW5jZSAtIG1lc3NhZ2VzIG5ld2VyIHRoYW4gdGhpcyAoaW5jbHVzaXZlKTtcbiAgICogQHBhcmFtIHtudW1iZXI9fSBiZWZvcmUgLSBvbGRlciB0aGFuIHRoaXMgKGV4Y2x1c2l2ZSlcbiAgICogQHBhcmFtIHtudW1iZXI9fSBsaW1pdCAtIG51bWJlciBvZiBtZXNzYWdlcyB0byBmZXRjaFxuICAgKiBAcmV0dXJucyB7VGlub2RlLk1ldGFHZXRCdWlsZGVyfSA8Y29kZT50aGlzPC9jb2RlPiBvYmplY3QuXG4gICAqL1xuICB3aXRoRGF0YShzaW5jZSwgYmVmb3JlLCBsaW1pdCkge1xuICAgIHRoaXMud2hhdFsnZGF0YSddID0ge1xuICAgICAgc2luY2U6IHNpbmNlLFxuICAgICAgYmVmb3JlOiBiZWZvcmUsXG4gICAgICBsaW1pdDogbGltaXRcbiAgICB9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgcXVlcnkgcGFyYW1ldGVycyB0byBmZXRjaCBtZXNzYWdlcyBuZXdlciB0aGFuIHRoZSBsYXRlc3Qgc2F2ZWQgbWVzc2FnZS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5NZXRhR2V0QnVpbGRlciNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXI9fSBsaW1pdCAtIG51bWJlciBvZiBtZXNzYWdlcyB0byBmZXRjaFxuICAgKlxuICAgKiBAcmV0dXJucyB7VGlub2RlLk1ldGFHZXRCdWlsZGVyfSA8Y29kZT50aGlzPC9jb2RlPiBvYmplY3QuXG4gICAqL1xuICB3aXRoTGF0ZXJEYXRhKGxpbWl0KSB7XG4gICAgcmV0dXJuIHRoaXMud2l0aERhdGEodGhpcy50b3BpYy5fbWF4U2VxID4gMCA/IHRoaXMudG9waWMuX21heFNlcSArIDEgOiB1bmRlZmluZWQsIHVuZGVmaW5lZCwgbGltaXQpO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgcXVlcnkgcGFyYW1ldGVycyB0byBmZXRjaCBtZXNzYWdlcyBvbGRlciB0aGFuIHRoZSBlYXJsaWVzdCBzYXZlZCBtZXNzYWdlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLk1ldGFHZXRCdWlsZGVyI1xuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcj19IGxpbWl0IC0gbWF4aW11bSBudW1iZXIgb2YgbWVzc2FnZXMgdG8gZmV0Y2guXG4gICAqXG4gICAqIEByZXR1cm5zIHtUaW5vZGUuTWV0YUdldEJ1aWxkZXJ9IDxjb2RlPnRoaXM8L2NvZGU+IG9iamVjdC5cbiAgICovXG4gIHdpdGhFYXJsaWVyRGF0YShsaW1pdCkge1xuICAgIHJldHVybiB0aGlzLndpdGhEYXRhKHVuZGVmaW5lZCwgdGhpcy50b3BpYy5fbWluU2VxID4gMCA/IHRoaXMudG9waWMuX21pblNlcSA6IHVuZGVmaW5lZCwgbGltaXQpO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgcXVlcnkgcGFyYW1ldGVycyB0byBmZXRjaCB0b3BpYyBkZXNjcmlwdGlvbiBpZiBpdCdzIG5ld2VyIHRoYW4gdGhlIGdpdmVuIHRpbWVzdGFtcC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5NZXRhR2V0QnVpbGRlciNcbiAgICpcbiAgICogQHBhcmFtIHtEYXRlPX0gaW1zIC0gZmV0Y2ggbWVzc2FnZXMgbmV3ZXIgdGhhbiB0aGlzIHRpbWVzdGFtcC5cbiAgICpcbiAgICogQHJldHVybnMge1Rpbm9kZS5NZXRhR2V0QnVpbGRlcn0gPGNvZGU+dGhpczwvY29kZT4gb2JqZWN0LlxuICAgKi9cbiAgd2l0aERlc2MoaW1zKSB7XG4gICAgdGhpcy53aGF0WydkZXNjJ10gPSB7XG4gICAgICBpbXM6IGltc1xuICAgIH07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEFkZCBxdWVyeSBwYXJhbWV0ZXJzIHRvIGZldGNoIHRvcGljIGRlc2NyaXB0aW9uIGlmIGl0J3MgbmV3ZXIgdGhhbiB0aGUgbGFzdCB1cGRhdGUuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuTWV0YUdldEJ1aWxkZXIjXG4gICAqXG4gICAqIEByZXR1cm5zIHtUaW5vZGUuTWV0YUdldEJ1aWxkZXJ9IDxjb2RlPnRoaXM8L2NvZGU+IG9iamVjdC5cbiAgICovXG4gIHdpdGhMYXRlckRlc2MoKSB7XG4gICAgcmV0dXJuIHRoaXMud2l0aERlc2ModGhpcy4jZ2V0X2Rlc2NfaW1zKCkpO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgcXVlcnkgcGFyYW1ldGVycyB0byBmZXRjaCBzdWJzY3JpcHRpb25zLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLk1ldGFHZXRCdWlsZGVyI1xuICAgKlxuICAgKiBAcGFyYW0ge0RhdGU9fSBpbXMgLSBmZXRjaCBzdWJzY3JpcHRpb25zIG1vZGlmaWVkIG1vcmUgcmVjZW50bHkgdGhhbiB0aGlzIHRpbWVzdGFtcFxuICAgKiBAcGFyYW0ge251bWJlcj19IGxpbWl0IC0gbWF4aW11bSBudW1iZXIgb2Ygc3Vic2NyaXB0aW9ucyB0byBmZXRjaC5cbiAgICogQHBhcmFtIHtzdHJpbmc9fSB1c2VyT3JUb3BpYyAtIHVzZXIgSUQgb3IgdG9waWMgbmFtZSB0byBmZXRjaCBmb3IgZmV0Y2hpbmcgb25lIHN1YnNjcmlwdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMge1Rpbm9kZS5NZXRhR2V0QnVpbGRlcn0gPGNvZGU+dGhpczwvY29kZT4gb2JqZWN0LlxuICAgKi9cbiAgd2l0aFN1YihpbXMsIGxpbWl0LCB1c2VyT3JUb3BpYykge1xuICAgIGNvbnN0IG9wdHMgPSB7XG4gICAgICBpbXM6IGltcyxcbiAgICAgIGxpbWl0OiBsaW1pdFxuICAgIH07XG4gICAgaWYgKHRoaXMudG9waWMuZ2V0VHlwZSgpID09ICdtZScpIHtcbiAgICAgIG9wdHMudG9waWMgPSB1c2VyT3JUb3BpYztcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0cy51c2VyID0gdXNlck9yVG9waWM7XG4gICAgfVxuICAgIHRoaXMud2hhdFsnc3ViJ10gPSBvcHRzO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgcXVlcnkgcGFyYW1ldGVycyB0byBmZXRjaCBhIHNpbmdsZSBzdWJzY3JpcHRpb24uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuTWV0YUdldEJ1aWxkZXIjXG4gICAqXG4gICAqIEBwYXJhbSB7RGF0ZT19IGltcyAtIGZldGNoIHN1YnNjcmlwdGlvbnMgbW9kaWZpZWQgbW9yZSByZWNlbnRseSB0aGFuIHRoaXMgdGltZXN0YW1wXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gdXNlck9yVG9waWMgLSB1c2VyIElEIG9yIHRvcGljIG5hbWUgdG8gZmV0Y2ggZm9yIGZldGNoaW5nIG9uZSBzdWJzY3JpcHRpb24uXG4gICAqXG4gICAqIEByZXR1cm5zIHtUaW5vZGUuTWV0YUdldEJ1aWxkZXJ9IDxjb2RlPnRoaXM8L2NvZGU+IG9iamVjdC5cbiAgICovXG4gIHdpdGhPbmVTdWIoaW1zLCB1c2VyT3JUb3BpYykge1xuICAgIHJldHVybiB0aGlzLndpdGhTdWIoaW1zLCB1bmRlZmluZWQsIHVzZXJPclRvcGljKTtcbiAgfVxuICAvKipcbiAgICogQWRkIHF1ZXJ5IHBhcmFtZXRlcnMgdG8gZmV0Y2ggYSBzaW5nbGUgc3Vic2NyaXB0aW9uIGlmIGl0J3MgYmVlbiB1cGRhdGVkIHNpbmNlIHRoZSBsYXN0IHVwZGF0ZS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5NZXRhR2V0QnVpbGRlciNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmc9fSB1c2VyT3JUb3BpYyAtIHVzZXIgSUQgb3IgdG9waWMgbmFtZSB0byBmZXRjaCBmb3IgZmV0Y2hpbmcgb25lIHN1YnNjcmlwdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMge1Rpbm9kZS5NZXRhR2V0QnVpbGRlcn0gPGNvZGU+dGhpczwvY29kZT4gb2JqZWN0LlxuICAgKi9cbiAgd2l0aExhdGVyT25lU3ViKHVzZXJPclRvcGljKSB7XG4gICAgcmV0dXJuIHRoaXMud2l0aE9uZVN1Yih0aGlzLnRvcGljLl9sYXN0U3Vic1VwZGF0ZSwgdXNlck9yVG9waWMpO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgcXVlcnkgcGFyYW1ldGVycyB0byBmZXRjaCBzdWJzY3JpcHRpb25zIHVwZGF0ZWQgc2luY2UgdGhlIGxhc3QgdXBkYXRlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLk1ldGFHZXRCdWlsZGVyI1xuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcj19IGxpbWl0IC0gbWF4aW11bSBudW1iZXIgb2Ygc3Vic2NyaXB0aW9ucyB0byBmZXRjaC5cbiAgICpcbiAgICogQHJldHVybnMge1Rpbm9kZS5NZXRhR2V0QnVpbGRlcn0gPGNvZGU+dGhpczwvY29kZT4gb2JqZWN0LlxuICAgKi9cbiAgd2l0aExhdGVyU3ViKGxpbWl0KSB7XG4gICAgcmV0dXJuIHRoaXMud2l0aFN1Yih0aGlzLiNnZXRfc3Vic19pbXMoKSwgbGltaXQpO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgcXVlcnkgcGFyYW1ldGVycyB0byBmZXRjaCB0b3BpYyB0YWdzLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLk1ldGFHZXRCdWlsZGVyI1xuICAgKlxuICAgKiBAcmV0dXJucyB7VGlub2RlLk1ldGFHZXRCdWlsZGVyfSA8Y29kZT50aGlzPC9jb2RlPiBvYmplY3QuXG4gICAqL1xuICB3aXRoVGFncygpIHtcbiAgICB0aGlzLndoYXRbJ3RhZ3MnXSA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEFkZCBxdWVyeSBwYXJhbWV0ZXJzIHRvIGZldGNoIHVzZXIncyBjcmVkZW50aWFscy4gPGNvZGU+J21lJzwvY29kZT4gdG9waWMgb25seS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5NZXRhR2V0QnVpbGRlciNcbiAgICpcbiAgICogQHJldHVybnMge1Rpbm9kZS5NZXRhR2V0QnVpbGRlcn0gPGNvZGU+dGhpczwvY29kZT4gb2JqZWN0LlxuICAgKi9cbiAgd2l0aENyZWQoKSB7XG4gICAgaWYgKHRoaXMudG9waWMuZ2V0VHlwZSgpID09ICdtZScpIHtcbiAgICAgIHRoaXMud2hhdFsnY3JlZCddID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50b3BpYy5fdGlub2RlLmxvZ2dlcihcIkVSUk9SOiBJbnZhbGlkIHRvcGljIHR5cGUgZm9yIE1ldGFHZXRCdWlsZGVyOndpdGhDcmVkc1wiLCB0aGlzLnRvcGljLmdldFR5cGUoKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgcXVlcnkgcGFyYW1ldGVycyB0byBmZXRjaCBkZWxldGVkIG1lc3NhZ2VzIHdpdGhpbiBleHBsaWNpdCBsaW1pdHMuIEFueS9hbGwgcGFyYW1ldGVycyBjYW4gYmUgbnVsbC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5NZXRhR2V0QnVpbGRlciNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXI9fSBzaW5jZSAtIGlkcyBvZiBtZXNzYWdlcyBkZWxldGVkIHNpbmNlIHRoaXMgJ2RlbCcgaWQgKGluY2x1c2l2ZSlcbiAgICogQHBhcmFtIHtudW1iZXI9fSBsaW1pdCAtIG51bWJlciBvZiBkZWxldGVkIG1lc3NhZ2UgaWRzIHRvIGZldGNoXG4gICAqXG4gICAqIEByZXR1cm5zIHtUaW5vZGUuTWV0YUdldEJ1aWxkZXJ9IDxjb2RlPnRoaXM8L2NvZGU+IG9iamVjdC5cbiAgICovXG4gIHdpdGhEZWwoc2luY2UsIGxpbWl0KSB7XG4gICAgaWYgKHNpbmNlIHx8IGxpbWl0KSB7XG4gICAgICB0aGlzLndoYXRbJ2RlbCddID0ge1xuICAgICAgICBzaW5jZTogc2luY2UsXG4gICAgICAgIGxpbWl0OiBsaW1pdFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEFkZCBxdWVyeSBwYXJhbWV0ZXJzIHRvIGZldGNoIG1lc3NhZ2VzIGRlbGV0ZWQgYWZ0ZXIgdGhlIHNhdmVkIDxjb2RlPidkZWwnPC9jb2RlPiBpZC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5NZXRhR2V0QnVpbGRlciNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXI9fSBsaW1pdCAtIG51bWJlciBvZiBkZWxldGVkIG1lc3NhZ2UgaWRzIHRvIGZldGNoXG4gICAqXG4gICAqIEByZXR1cm5zIHtUaW5vZGUuTWV0YUdldEJ1aWxkZXJ9IDxjb2RlPnRoaXM8L2NvZGU+IG9iamVjdC5cbiAgICovXG4gIHdpdGhMYXRlckRlbChsaW1pdCkge1xuICAgIC8vIFNwZWNpZnkgJ3NpbmNlJyBvbmx5IGlmIHdlIGhhdmUgYWxyZWFkeSByZWNlaXZlZCBzb21lIG1lc3NhZ2VzLiBJZlxuICAgIC8vIHdlIGhhdmUgbm8gbG9jYWxseSBjYWNoZWQgbWVzc2FnZXMgdGhlbiB3ZSBkb24ndCBjYXJlIGlmIGFueSBtZXNzYWdlcyB3ZXJlIGRlbGV0ZWQuXG4gICAgcmV0dXJuIHRoaXMud2l0aERlbCh0aGlzLnRvcGljLl9tYXhTZXEgPiAwID8gdGhpcy50b3BpYy5fbWF4RGVsICsgMSA6IHVuZGVmaW5lZCwgbGltaXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3Qgc3VicXVlcnk6IGdldCBhbiBvYmplY3QgdGhhdCBjb250YWlucyBzcGVjaWZpZWQgc3VicXVlcnkuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuTWV0YUdldEJ1aWxkZXIjXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB3aGF0IC0gc3VicXVlcnkgdG8gcmV0dXJuOiBvbmUgb2YgJ2RhdGEnLCAnc3ViJywgJ2Rlc2MnLCAndGFncycsICdjcmVkJywgJ2RlbCcuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IHJlcXVlc3RlZCBzdWJxdWVyeSBvciA8Y29kZT51bmRlZmluZWQ8L2NvZGU+LlxuICAgKi9cbiAgZXh0cmFjdCh3aGF0KSB7XG4gICAgcmV0dXJuIHRoaXMud2hhdFt3aGF0XTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgcGFyYW1ldGVycy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5NZXRhR2V0QnVpbGRlciNcbiAgICpcbiAgICogQHJldHVybnMge1Rpbm9kZS5HZXRRdWVyeX0gR2V0IHF1ZXJ5XG4gICAqL1xuICBidWlsZCgpIHtcbiAgICBjb25zdCB3aGF0ID0gW107XG4gICAgbGV0IHBhcmFtcyA9IHt9O1xuICAgIFsnZGF0YScsICdzdWInLCAnZGVzYycsICd0YWdzJywgJ2NyZWQnLCAnZGVsJ10uZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBpZiAodGhpcy53aGF0Lmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgd2hhdC5wdXNoKGtleSk7XG4gICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0aGlzLndoYXRba2V5XSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHBhcmFtc1trZXldID0gdGhpcy53aGF0W2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAod2hhdC5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJhbXMud2hhdCA9IHdoYXQuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJhbXMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBwYXJhbXM7XG4gIH1cbn1cbiIsIi8qKlxuICogQG1vZHVsZSB0aW5vZGUtc2RrXG4gKlxuICogQGNvcHlyaWdodCAyMDE1LTIwMjIgVGlub2RlIExMQy5cbiAqIEBzdW1tYXJ5IEphdmFzY3JpcHQgYmluZGluZ3MgZm9yIFRpbm9kZS5cbiAqIEBsaWNlbnNlIEFwYWNoZSAyLjBcbiAqIEB2ZXJzaW9uIDAuMjBcbiAqXG4gKiBTZWUgPGEgaHJlZj1cImh0dHBzOi8vZ2l0aHViLmNvbS90aW5vZGUvd2ViYXBwXCI+aHR0cHM6Ly9naXRodWIuY29tL3Rpbm9kZS93ZWJhcHA8L2E+IGZvciByZWFsLWxpZmUgdXNhZ2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIDxoZWFkPlxuICogPHNjcmlwdCBzcmM9XCIuLi4vdGlub2RlLmpzXCI+PC9zY3JpcHQ+XG4gKiA8L2hlYWQ+XG4gKlxuICogPGJvZHk+XG4gKiAgLi4uXG4gKiA8c2NyaXB0PlxuICogIC8vIEluc3RhbnRpYXRlIHRpbm9kZS5cbiAqICBjb25zdCB0aW5vZGUgPSBuZXcgVGlub2RlKGNvbmZpZywgKCkgPT4ge1xuICogICAgLy8gQ2FsbGVkIG9uIGluaXQgY29tcGxldGlvbi5cbiAqICB9KTtcbiAqICB0aW5vZGUuZW5hYmxlTG9nZ2luZyh0cnVlKTtcbiAqICB0aW5vZGUub25EaXNjb25uZWN0ID0gKGVycikgPT4ge1xuICogICAgLy8gSGFuZGxlIGRpc2Nvbm5lY3QuXG4gKiAgfTtcbiAqICAvLyBDb25uZWN0IHRvIHRoZSBzZXJ2ZXIuXG4gKiAgdGlub2RlLmNvbm5lY3QoJ2h0dHBzOi8vZXhhbXBsZS5jb20vJykudGhlbigoKSA9PiB7XG4gKiAgICAvLyBDb25uZWN0ZWQuIExvZ2luIG5vdy5cbiAqICAgIHJldHVybiB0aW5vZGUubG9naW5CYXNpYyhsb2dpbiwgcGFzc3dvcmQpO1xuICogIH0pLnRoZW4oKGN0cmwpID0+IHtcbiAqICAgIC8vIExvZ2dlZCBpbiBmaW5lLCBhdHRhY2ggY2FsbGJhY2tzLCBzdWJzY3JpYmUgdG8gJ21lJy5cbiAqICAgIGNvbnN0IG1lID0gdGlub2RlLmdldE1lVG9waWMoKTtcbiAqICAgIG1lLm9uTWV0YURlc2MgPSBmdW5jdGlvbihtZXRhKSB7IC4uLiB9O1xuICogICAgLy8gU3Vic2NyaWJlLCBmZXRjaCB0b3BpYyBkZXNjcmlwdGlvbiBhbmQgdGhlIGxpc3Qgb2YgY29udGFjdHMuXG4gKiAgICBtZS5zdWJzY3JpYmUoe2dldDoge2Rlc2M6IHt9LCBzdWI6IHt9fX0pO1xuICogIH0pLmNhdGNoKChlcnIpID0+IHtcbiAqICAgIC8vIExvZ2luIG9yIHN1YnNjcmlwdGlvbiBmYWlsZWQsIGRvIHNvbWV0aGluZy5cbiAqICAgIC4uLlxuICogIH0pO1xuICogIC4uLlxuICogPC9zY3JpcHQ+XG4gKiA8L2JvZHk+XG4gKi9cbid1c2Ugc3RyaWN0JztcblxuLy8gTk9URSBUTyBERVZFTE9QRVJTOlxuLy8gTG9jYWxpemFibGUgc3RyaW5ncyBzaG91bGQgYmUgZG91YmxlIHF1b3RlZCBcItGB0YLRgNC+0LrQsCDQvdCwINC00YDRg9Cz0L7QvCDRj9C30YvQutC1XCIsXG4vLyBub24tbG9jYWxpemFibGUgc3RyaW5ncyBzaG91bGQgYmUgc2luZ2xlIHF1b3RlZCAnbm9uLWxvY2FsaXplZCcuXG5cbmltcG9ydCBBY2Nlc3NNb2RlIGZyb20gJy4vYWNjZXNzLW1vZGUuanMnO1xuaW1wb3J0ICogYXMgQ29uc3QgZnJvbSAnLi9jb25maWcuanMnO1xuaW1wb3J0IENvbm5lY3Rpb24gZnJvbSAnLi9jb25uZWN0aW9uLmpzJztcbmltcG9ydCBEQkNhY2hlIGZyb20gJy4vZGIuanMnO1xuaW1wb3J0IERyYWZ0eSBmcm9tICcuL2RyYWZ0eS5qcyc7XG5pbXBvcnQgTGFyZ2VGaWxlSGVscGVyIGZyb20gJy4vbGFyZ2UtZmlsZS5qcyc7XG5pbXBvcnQgTWV0YUdldEJ1aWxkZXIgZnJvbSAnLi9tZXRhLWJ1aWxkZXIuanMnO1xuaW1wb3J0IHtcbiAgVG9waWMsXG4gIFRvcGljTWUsXG4gIFRvcGljRm5kXG59IGZyb20gJy4vdG9waWMuanMnO1xuXG5pbXBvcnQge1xuICBqc29uUGFyc2VIZWxwZXIsXG4gIG1lcmdlT2JqLFxuICByZmMzMzM5RGF0ZVN0cmluZyxcbiAgc2ltcGxpZnlcbn0gZnJvbSAnLi91dGlscy5qcyc7XG5cbi8vIFJlLWV4cG9ydCBBY2Nlc3NNb2RlXG5leHBvcnQge1xuICBBY2Nlc3NNb2RlXG59O1xuXG5sZXQgV2ViU29ja2V0UHJvdmlkZXI7XG5pZiAodHlwZW9mIFdlYlNvY2tldCAhPSAndW5kZWZpbmVkJykge1xuICBXZWJTb2NrZXRQcm92aWRlciA9IFdlYlNvY2tldDtcbn1cblxubGV0IFhIUlByb3ZpZGVyO1xuaWYgKHR5cGVvZiBYTUxIdHRwUmVxdWVzdCAhPSAndW5kZWZpbmVkJykge1xuICBYSFJQcm92aWRlciA9IFhNTEh0dHBSZXF1ZXN0O1xufVxuXG5sZXQgSW5kZXhlZERCUHJvdmlkZXI7XG5pZiAodHlwZW9mIGluZGV4ZWREQiAhPSAndW5kZWZpbmVkJykge1xuICBJbmRleGVkREJQcm92aWRlciA9IGluZGV4ZWREQjtcbn1cblxuLy8gUmUtZXhwb3J0IERyYWZ0eS5cbmV4cG9ydCB7XG4gIERyYWZ0eVxufVxuXG5pbml0Rm9yTm9uQnJvd3NlckFwcCgpO1xuXG4vLyBVdGlsaXR5IGZ1bmN0aW9uc1xuXG4vLyBQb2x5ZmlsbCBmb3Igbm9uLWJyb3dzZXIgY29udGV4dCwgZS5nLiBOb2RlSnMuXG5mdW5jdGlvbiBpbml0Rm9yTm9uQnJvd3NlckFwcCgpIHtcbiAgLy8gVGlub2RlIHJlcXVpcmVtZW50IGluIG5hdGl2ZSBtb2RlIGJlY2F1c2UgcmVhY3QgbmF0aXZlIGRvZXNuJ3QgcHJvdmlkZSBCYXNlNjQgbWV0aG9kXG4gIGNvbnN0IGNoYXJzID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89JztcblxuICBpZiAodHlwZW9mIGJ0b2EgPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBnbG9iYWwuYnRvYSA9IGZ1bmN0aW9uKGlucHV0ID0gJycpIHtcbiAgICAgIGxldCBzdHIgPSBpbnB1dDtcbiAgICAgIGxldCBvdXRwdXQgPSAnJztcblxuICAgICAgZm9yIChsZXQgYmxvY2sgPSAwLCBjaGFyQ29kZSwgaSA9IDAsIG1hcCA9IGNoYXJzOyBzdHIuY2hhckF0KGkgfCAwKSB8fCAobWFwID0gJz0nLCBpICUgMSk7IG91dHB1dCArPSBtYXAuY2hhckF0KDYzICYgYmxvY2sgPj4gOCAtIGkgJSAxICogOCkpIHtcblxuICAgICAgICBjaGFyQ29kZSA9IHN0ci5jaGFyQ29kZUF0KGkgKz0gMyAvIDQpO1xuXG4gICAgICAgIGlmIChjaGFyQ29kZSA+IDB4RkYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCInYnRvYScgZmFpbGVkOiBUaGUgc3RyaW5nIHRvIGJlIGVuY29kZWQgY29udGFpbnMgY2hhcmFjdGVycyBvdXRzaWRlIG9mIHRoZSBMYXRpbjEgcmFuZ2UuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJsb2NrID0gYmxvY2sgPDwgOCB8IGNoYXJDb2RlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG4gIH1cblxuICBpZiAodHlwZW9mIGF0b2IgPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBnbG9iYWwuYXRvYiA9IGZ1bmN0aW9uKGlucHV0ID0gJycpIHtcbiAgICAgIGxldCBzdHIgPSBpbnB1dC5yZXBsYWNlKC89KyQvLCAnJyk7XG4gICAgICBsZXQgb3V0cHV0ID0gJyc7XG5cbiAgICAgIGlmIChzdHIubGVuZ3RoICUgNCA9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIidhdG9iJyBmYWlsZWQ6IFRoZSBzdHJpbmcgdG8gYmUgZGVjb2RlZCBpcyBub3QgY29ycmVjdGx5IGVuY29kZWQuXCIpO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgYmMgPSAwLCBicyA9IDAsIGJ1ZmZlciwgaSA9IDA7IGJ1ZmZlciA9IHN0ci5jaGFyQXQoaSsrKTtcblxuICAgICAgICB+YnVmZmVyICYmIChicyA9IGJjICUgNCA/IGJzICogNjQgKyBidWZmZXIgOiBidWZmZXIsXG4gICAgICAgICAgYmMrKyAlIDQpID8gb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMjU1ICYgYnMgPj4gKC0yICogYmMgJiA2KSkgOiAwXG4gICAgICApIHtcbiAgICAgICAgYnVmZmVyID0gY2hhcnMuaW5kZXhPZihidWZmZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG4gIH1cblxuICBpZiAodHlwZW9mIHdpbmRvdyA9PSAndW5kZWZpbmVkJykge1xuICAgIGdsb2JhbC53aW5kb3cgPSB7XG4gICAgICBXZWJTb2NrZXQ6IFdlYlNvY2tldFByb3ZpZGVyLFxuICAgICAgWE1MSHR0cFJlcXVlc3Q6IFhIUlByb3ZpZGVyLFxuICAgICAgaW5kZXhlZERCOiBJbmRleGVkREJQcm92aWRlcixcbiAgICAgIFVSTDoge1xuICAgICAgICBjcmVhdGVPYmplY3RVUkw6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuYWJsZSB0byB1c2UgVVJMLmNyZWF0ZU9iamVjdFVSTCBpbiBhIG5vbi1icm93c2VyIGFwcGxpY2F0aW9uXCIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgQ29ubmVjdGlvbi5zZXROZXR3b3JrUHJvdmlkZXJzKFdlYlNvY2tldFByb3ZpZGVyLCBYSFJQcm92aWRlcik7XG4gIExhcmdlRmlsZUhlbHBlci5zZXROZXR3b3JrUHJvdmlkZXIoWEhSUHJvdmlkZXIpO1xuICBEQkNhY2hlLnNldERhdGFiYXNlUHJvdmlkZXIoSW5kZXhlZERCUHJvdmlkZXIpO1xufVxuXG4vLyBEZXRlY3QgZmluZCBtb3N0IHVzZWZ1bCBuZXR3b3JrIHRyYW5zcG9ydC5cbmZ1bmN0aW9uIGRldGVjdFRyYW5zcG9ydCgpIHtcbiAgaWYgKHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcpIHtcbiAgICBpZiAod2luZG93WydXZWJTb2NrZXQnXSkge1xuICAgICAgcmV0dXJuICd3cyc7XG4gICAgfSBlbHNlIGlmICh3aW5kb3dbJ1hNTEh0dHBSZXF1ZXN0J10pIHtcbiAgICAgIC8vIFRoZSBicm93c2VyIG9yIG5vZGUgaGFzIG5vIHdlYnNvY2tldHMsIHVzaW5nIGxvbmcgcG9sbGluZy5cbiAgICAgIHJldHVybiAnbHAnO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLy8gYnRvYSByZXBsYWNlbWVudC4gU3RvY2sgYnRvYSBmYWlscyBvbiBvbiBub24tTGF0aW4xIHN0cmluZ3MuXG5mdW5jdGlvbiBiNjRFbmNvZGVVbmljb2RlKHN0cikge1xuICAvLyBUaGUgZW5jb2RlVVJJQ29tcG9uZW50IHBlcmNlbnQtZW5jb2RlcyBVVEYtOCBzdHJpbmcsXG4gIC8vIHRoZW4gdGhlIHBlcmNlbnQgZW5jb2RpbmcgaXMgY29udmVydGVkIGludG8gcmF3IGJ5dGVzIHdoaWNoXG4gIC8vIGNhbiBiZSBmZWQgaW50byBidG9hLlxuICByZXR1cm4gYnRvYShlbmNvZGVVUklDb21wb25lbnQoc3RyKS5yZXBsYWNlKC8lKFswLTlBLUZdezJ9KS9nLFxuICAgIGZ1bmN0aW9uIHRvU29saWRCeXRlcyhtYXRjaCwgcDEpIHtcbiAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKCcweCcgKyBwMSk7XG4gICAgfSkpO1xufVxuXG4vLyBKU09OIHN0cmluZ2lmeSBoZWxwZXIgLSBwcmUtcHJvY2Vzc29yIGZvciBKU09OLnN0cmluZ2lmeVxuZnVuY3Rpb24ganNvbkJ1aWxkSGVscGVyKGtleSwgdmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgLy8gQ29udmVydCBqYXZhc2NyaXB0IERhdGUgb2JqZWN0cyB0byByZmMzMzM5IHN0cmluZ3NcbiAgICB2YWwgPSByZmMzMzM5RGF0ZVN0cmluZyh2YWwpO1xuICB9IGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIEFjY2Vzc01vZGUpIHtcbiAgICB2YWwgPSB2YWwuanNvbkhlbHBlcigpO1xuICB9IGVsc2UgaWYgKHZhbCA9PT0gdW5kZWZpbmVkIHx8IHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IGZhbHNlIHx8XG4gICAgKEFycmF5LmlzQXJyYXkodmFsKSAmJiB2YWwubGVuZ3RoID09IDApIHx8XG4gICAgKCh0eXBlb2YgdmFsID09ICdvYmplY3QnKSAmJiAoT2JqZWN0LmtleXModmFsKS5sZW5ndGggPT0gMCkpKSB7XG4gICAgLy8gc3RyaXAgb3V0IGVtcHR5IGVsZW1lbnRzIHdoaWxlIHNlcmlhbGl6aW5nIG9iamVjdHMgdG8gSlNPTlxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gdmFsO1xufTtcblxuLy8gVHJpbXMgdmVyeSBsb25nIHN0cmluZ3MgKGVuY29kZWQgaW1hZ2VzKSB0byBtYWtlIGxvZ2dlZCBwYWNrZXRzIG1vcmUgcmVhZGFibGUuXG5mdW5jdGlvbiBqc29uTG9nZ2VySGVscGVyKGtleSwgdmFsKSB7XG4gIGlmICh0eXBlb2YgdmFsID09ICdzdHJpbmcnICYmIHZhbC5sZW5ndGggPiAxMjgpIHtcbiAgICByZXR1cm4gJzwnICsgdmFsLmxlbmd0aCArICcsIGJ5dGVzOiAnICsgdmFsLnN1YnN0cmluZygwLCAxMikgKyAnLi4uJyArIHZhbC5zdWJzdHJpbmcodmFsLmxlbmd0aCAtIDEyKSArICc+JztcbiAgfVxuICByZXR1cm4ganNvbkJ1aWxkSGVscGVyKGtleSwgdmFsKTtcbn07XG5cbi8vIFBhcnNlIGJyb3dzZXIgdXNlciBhZ2VudCB0byBleHRyYWN0IGJyb3dzZXIgbmFtZSBhbmQgdmVyc2lvbi5cbmZ1bmN0aW9uIGdldEJyb3dzZXJJbmZvKHVhLCBwcm9kdWN0KSB7XG4gIHVhID0gdWEgfHwgJyc7XG4gIGxldCByZWFjdG5hdGl2ZSA9ICcnO1xuICAvLyBDaGVjayBpZiB0aGlzIGlzIGEgUmVhY3ROYXRpdmUgYXBwLlxuICBpZiAoL3JlYWN0bmF0aXZlL2kudGVzdChwcm9kdWN0KSkge1xuICAgIHJlYWN0bmF0aXZlID0gJ1JlYWN0TmF0aXZlOyAnO1xuICB9XG4gIGxldCByZXN1bHQ7XG4gIC8vIFJlbW92ZSB1c2VsZXNzIHN0cmluZy5cbiAgdWEgPSB1YS5yZXBsYWNlKCcgKEtIVE1MLCBsaWtlIEdlY2tvKScsICcnKTtcbiAgLy8gVGVzdCBmb3IgV2ViS2l0LWJhc2VkIGJyb3dzZXIuXG4gIGxldCBtID0gdWEubWF0Y2goLyhBcHBsZVdlYktpdFxcL1suXFxkXSspL2kpO1xuICBpZiAobSkge1xuICAgIC8vIExpc3Qgb2YgY29tbW9uIHN0cmluZ3MsIGZyb20gbW9yZSB1c2VmdWwgdG8gbGVzcyB1c2VmdWwuXG4gICAgLy8gQWxsIHVua25vd24gc3RyaW5ncyBnZXQgdGhlIGhpZ2hlc3QgKC0xKSBwcmlvcml0eS5cbiAgICBjb25zdCBwcmlvcml0eSA9IFsnZWRnJywgJ2Nocm9tZScsICdzYWZhcmknLCAnbW9iaWxlJywgJ3ZlcnNpb24nXTtcbiAgICBsZXQgdG1wID0gdWEuc3Vic3RyKG0uaW5kZXggKyBtWzBdLmxlbmd0aCkuc3BsaXQoJyAnKTtcbiAgICBsZXQgdG9rZW5zID0gW107XG4gICAgbGV0IHZlcnNpb247IC8vIDEuMCBpbiBWZXJzaW9uLzEuMCBvciB1bmRlZmluZWQ7XG4gICAgLy8gU3BsaXQgc3RyaW5nIGxpa2UgJ05hbWUvMC4wLjAnIGludG8gWydOYW1lJywgJzAuMC4wJywgM10gd2hlcmUgdGhlIGxhc3QgZWxlbWVudCBpcyB0aGUgcHJpb3JpdHkuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0bXAubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBtMiA9IC8oW1xcdy5dKylbXFwvXShbXFwuXFxkXSspLy5leGVjKHRtcFtpXSk7XG4gICAgICBpZiAobTIpIHtcbiAgICAgICAgLy8gVW5rbm93biB2YWx1ZXMgYXJlIGhpZ2hlc3QgcHJpb3JpdHkgKC0xKS5cbiAgICAgICAgdG9rZW5zLnB1c2goW20yWzFdLCBtMlsyXSwgcHJpb3JpdHkuZmluZEluZGV4KChlKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIG0yWzFdLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChlKTtcbiAgICAgICAgfSldKTtcbiAgICAgICAgaWYgKG0yWzFdID09ICdWZXJzaW9uJykge1xuICAgICAgICAgIHZlcnNpb24gPSBtMlsyXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBTb3J0IGJ5IHByaW9yaXR5OiBtb3JlIGludGVyZXN0aW5nIGlzIGVhcmxpZXIgdGhhbiBsZXNzIGludGVyZXN0aW5nLlxuICAgIHRva2Vucy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICByZXR1cm4gYVsyXSAtIGJbMl07XG4gICAgfSk7XG4gICAgaWYgKHRva2Vucy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBSZXR1cm4gdGhlIGxlYXN0IGNvbW1vbiBicm93c2VyIHN0cmluZyBhbmQgdmVyc2lvbi5cbiAgICAgIGlmICh0b2tlbnNbMF1bMF0udG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKCdlZGcnKSkge1xuICAgICAgICB0b2tlbnNbMF1bMF0gPSAnRWRnZSc7XG4gICAgICB9IGVsc2UgaWYgKHRva2Vuc1swXVswXSA9PSAnT1BSJykge1xuICAgICAgICB0b2tlbnNbMF1bMF0gPSAnT3BlcmEnO1xuICAgICAgfSBlbHNlIGlmICh0b2tlbnNbMF1bMF0gPT0gJ1NhZmFyaScgJiYgdmVyc2lvbikge1xuICAgICAgICB0b2tlbnNbMF1bMV0gPSB2ZXJzaW9uO1xuICAgICAgfVxuICAgICAgcmVzdWx0ID0gdG9rZW5zWzBdWzBdICsgJy8nICsgdG9rZW5zWzBdWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGYWlsZWQgdG8gSUQgdGhlIGJyb3dzZXIuIFJldHVybiB0aGUgd2Via2l0IHZlcnNpb24uXG4gICAgICByZXN1bHQgPSBtWzFdO1xuICAgIH1cbiAgfSBlbHNlIGlmICgvZmlyZWZveC9pLnRlc3QodWEpKSB7XG4gICAgbSA9IC9GaXJlZm94XFwvKFsuXFxkXSspL2cuZXhlYyh1YSk7XG4gICAgaWYgKG0pIHtcbiAgICAgIHJlc3VsdCA9ICdGaXJlZm94LycgKyBtWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgPSAnRmlyZWZveC8/JztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gTmVpdGhlciBBcHBsZVdlYktpdCBub3IgRmlyZWZveC4gVHJ5IHRoZSBsYXN0IHJlc29ydC5cbiAgICBtID0gLyhbXFx3Ll0rKVxcLyhbLlxcZF0rKS8uZXhlYyh1YSk7XG4gICAgaWYgKG0pIHtcbiAgICAgIHJlc3VsdCA9IG1bMV0gKyAnLycgKyBtWzJdO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdWEuc3BsaXQoJyAnKTtcbiAgICAgIHJlc3VsdCA9IG1bMF07XG4gICAgfVxuICB9XG5cbiAgLy8gU2hvcnRlbiB0aGUgdmVyc2lvbiB0byBvbmUgZG90ICdhLmJiLmNjYy5kIC0+IGEuYmInIGF0IG1vc3QuXG4gIG0gPSByZXN1bHQuc3BsaXQoJy8nKTtcbiAgaWYgKG0ubGVuZ3RoID4gMSkge1xuICAgIGNvbnN0IHYgPSBtWzFdLnNwbGl0KCcuJyk7XG4gICAgY29uc3QgbWlub3IgPSB2WzFdID8gJy4nICsgdlsxXS5zdWJzdHIoMCwgMikgOiAnJztcbiAgICByZXN1bHQgPSBgJHttWzBdfS8ke3ZbMF19JHttaW5vcn1gO1xuICB9XG4gIHJldHVybiByZWFjdG5hdGl2ZSArIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBUaGUgbWFpbiBjbGFzcyBmb3IgaW50ZXJhY3Rpbmcgd2l0aCBUaW5vZGUgc2VydmVyLlxuICovXG5leHBvcnQgY2xhc3MgVGlub2RlIHtcbiAgX2hvc3Q7XG4gIF9zZWN1cmU7XG5cbiAgX2FwcE5hbWU7XG5cbiAgLy8gQVBJIEtleS5cbiAgX2FwaUtleTtcblxuICAvLyBOYW1lIGFuZCB2ZXJzaW9uIG9mIHRoZSBicm93c2VyLlxuICBfYnJvd3NlciA9ICcnO1xuICBfcGxhdGZvcm07XG4gIC8vIEhhcmR3YXJlXG4gIF9od29zID0gJ3VuZGVmaW5lZCc7XG4gIF9odW1hbkxhbmd1YWdlID0gJ3h4JztcblxuICAvLyBMb2dnaW5nIHRvIGNvbnNvbGUgZW5hYmxlZFxuICBfbG9nZ2luZ0VuYWJsZWQgPSBmYWxzZTtcbiAgLy8gV2hlbiBsb2dnaW5nLCB0cmlwIGxvbmcgc3RyaW5ncyAoYmFzZTY0LWVuY29kZWQgaW1hZ2VzKSBmb3IgcmVhZGFiaWxpdHlcbiAgX3RyaW1Mb25nU3RyaW5ncyA9IGZhbHNlO1xuICAvLyBVSUQgb2YgdGhlIGN1cnJlbnRseSBhdXRoZW50aWNhdGVkIHVzZXIuXG4gIF9teVVJRCA9IG51bGw7XG4gIC8vIFN0YXR1cyBvZiBjb25uZWN0aW9uOiBhdXRoZW50aWNhdGVkIG9yIG5vdC5cbiAgX2F1dGhlbnRpY2F0ZWQgPSBmYWxzZTtcbiAgLy8gTG9naW4gdXNlZCBpbiB0aGUgbGFzdCBzdWNjZXNzZnVsIGJhc2ljIGF1dGhlbnRpY2F0aW9uXG4gIF9sb2dpbiA9IG51bGw7XG4gIC8vIFRva2VuIHdoaWNoIGNhbiBiZSB1c2VkIGZvciBsb2dpbiBpbnN0ZWFkIG9mIGxvZ2luL3Bhc3N3b3JkLlxuICBfYXV0aFRva2VuID0gbnVsbDtcbiAgLy8gQ291bnRlciBvZiByZWNlaXZlZCBwYWNrZXRzXG4gIF9pblBhY2tldENvdW50ID0gMDtcbiAgLy8gQ291bnRlciBmb3IgZ2VuZXJhdGluZyB1bmlxdWUgbWVzc2FnZSBJRHNcbiAgX21lc3NhZ2VJZCA9IE1hdGguZmxvb3IoKE1hdGgucmFuZG9tKCkgKiAweEZGRkYpICsgMHhGRkZGKTtcbiAgLy8gSW5mb3JtYXRpb24gYWJvdXQgdGhlIHNlcnZlciwgaWYgY29ubmVjdGVkXG4gIF9zZXJ2ZXJJbmZvID0gbnVsbDtcbiAgLy8gUHVzaCBub3RpZmljYXRpb24gdG9rZW4uIENhbGxlZCBkZXZpY2VUb2tlbiBmb3IgY29uc2lzdGVuY3kgd2l0aCB0aGUgQW5kcm9pZCBTREsuXG4gIF9kZXZpY2VUb2tlbiA9IG51bGw7XG5cbiAgLy8gQ2FjaGUgb2YgcGVuZGluZyBwcm9taXNlcyBieSBtZXNzYWdlIGlkLlxuICBfcGVuZGluZ1Byb21pc2VzID0ge307XG4gIC8vIFRoZSBUaW1lb3V0IG9iamVjdCByZXR1cm5lZCBieSB0aGUgcmVqZWN0IGV4cGlyZWQgcHJvbWlzZXMgc2V0SW50ZXJ2YWwuXG4gIF9leHBpcmVQcm9taXNlcyA9IG51bGw7XG5cbiAgLy8gV2Vic29ja2V0IG9yIGxvbmcgcG9sbGluZyBjb25uZWN0aW9uLlxuICBfY29ubmVjdGlvbiA9IG51bGw7XG5cbiAgLy8gVXNlIGluZGV4REIgZm9yIGNhY2hpbmcgdG9waWNzIGFuZCBtZXNzYWdlcy5cbiAgX3BlcnNpc3QgPSBmYWxzZTtcbiAgLy8gSW5kZXhlZERCIHdyYXBwZXIgb2JqZWN0LlxuICBfZGIgPSBudWxsO1xuXG4gIC8vIFRpbm9kZSdzIGNhY2hlIG9mIG9iamVjdHNcbiAgX2NhY2hlID0ge307XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBUaW5vZGUgb2JqZWN0LlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIC0gY29uZmlndXJhdGlvbiBwYXJhbWV0ZXJzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnLmFwcE5hbWUgLSBOYW1lIG9mIHRoZSBjYWxsaW5nIGFwcGxpY2F0aW9uIHRvIGJlIHJlcG9ydGVkIGluIHRoZSBVc2VyIEFnZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnLmhvc3QgLSBIb3N0IG5hbWUgYW5kIG9wdGlvbmFsIHBvcnQgbnVtYmVyIHRvIGNvbm5lY3QgdG8uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb25maWcuYXBpS2V5IC0gQVBJIGtleSBnZW5lcmF0ZWQgYnkgPGNvZGU+a2V5Z2VuPC9jb2RlPi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGNvbmZpZy50cmFuc3BvcnQgLSBTZWUge0BsaW5rIFRpbm9kZS5Db25uZWN0aW9uI3RyYW5zcG9ydH0uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gY29uZmlnLnNlY3VyZSAtIFVzZSBTZWN1cmUgV2ViU29ja2V0IGlmIDxjb2RlPnRydWU8L2NvZGU+LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnLnBsYXRmb3JtIC0gT3B0aW9uYWwgcGxhdGZvcm0gaWRlbnRpZmllciwgb25lIG9mIDxjb2RlPlwiaW9zXCI8L2NvZGU+LCA8Y29kZT5cIndlYlwiPC9jb2RlPiwgPGNvZGU+XCJhbmRyb2lkXCI8L2NvZGU+LlxuICAgKiBAcGFyYW0ge2Jvb2xlbn0gY29uZmlnLnBlcnNpc3QgLSBVc2UgSW5kZXhlZERCIHBlcnNpc3RlbnQgc3RvcmFnZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gb25Db21wbGV0ZSAtIGNhbGxiYWNrIHRvIGNhbGwgd2hlbiBpbml0aWFsaXphdGlvbiBpcyBjb21wbGV0ZWQuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWcsIG9uQ29tcGxldGUpIHtcbiAgICB0aGlzLl9ob3N0ID0gY29uZmlnLmhvc3Q7XG4gICAgdGhpcy5fc2VjdXJlID0gY29uZmlnLnNlY3VyZTtcblxuICAgIC8vIENsaWVudC1wcm92aWRlZCBhcHBsaWNhdGlvbiBuYW1lLCBmb3JtYXQgPE5hbWU+Lzx2ZXJzaW9uIG51bWJlcj5cbiAgICB0aGlzLl9hcHBOYW1lID0gY29uZmlnLmFwcE5hbWUgfHwgXCJVbmRlZmluZWRcIjtcblxuICAgIC8vIEFQSSBLZXkuXG4gICAgdGhpcy5fYXBpS2V5ID0gY29uZmlnLmFwaUtleTtcblxuICAgIC8vIE5hbWUgYW5kIHZlcnNpb24gb2YgdGhlIGJyb3dzZXIuXG4gICAgdGhpcy5fcGxhdGZvcm0gPSBjb25maWcucGxhdGZvcm0gfHwgJ3dlYic7XG4gICAgLy8gVW5kZXJseWluZyBPUy5cbiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5fYnJvd3NlciA9IGdldEJyb3dzZXJJbmZvKG5hdmlnYXRvci51c2VyQWdlbnQsIG5hdmlnYXRvci5wcm9kdWN0KTtcbiAgICAgIHRoaXMuX2h3b3MgPSBuYXZpZ2F0b3IucGxhdGZvcm07XG4gICAgICAvLyBUaGlzIGlzIHRoZSBkZWZhdWx0IGxhbmd1YWdlLiBJdCBjb3VsZCBiZSBjaGFuZ2VkIGJ5IGNsaWVudC5cbiAgICAgIHRoaXMuX2h1bWFuTGFuZ3VhZ2UgPSBuYXZpZ2F0b3IubGFuZ3VhZ2UgfHwgJ2VuLVVTJztcbiAgICB9XG5cbiAgICBDb25uZWN0aW9uLmxvZ2dlciA9IHRoaXMubG9nZ2VyO1xuICAgIERyYWZ0eS5sb2dnZXIgPSB0aGlzLmxvZ2dlcjtcblxuICAgIC8vIFdlYlNvY2tldCBvciBsb25nIHBvbGxpbmcgbmV0d29yayBjb25uZWN0aW9uLlxuICAgIGlmIChjb25maWcudHJhbnNwb3J0ICE9ICdscCcgJiYgY29uZmlnLnRyYW5zcG9ydCAhPSAnd3MnKSB7XG4gICAgICBjb25maWcudHJhbnNwb3J0ID0gZGV0ZWN0VHJhbnNwb3J0KCk7XG4gICAgfVxuICAgIHRoaXMuX2Nvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbihjb25maWcsIENvbnN0LlBST1RPQ09MX1ZFUlNJT04sIC8qIGF1dG9yZWNvbm5lY3QgKi8gdHJ1ZSk7XG4gICAgdGhpcy5fY29ubmVjdGlvbi5vbk1lc3NhZ2UgPSAoZGF0YSkgPT4ge1xuICAgICAgLy8gQ2FsbCB0aGUgbWFpbiBtZXNzYWdlIGRpc3BhdGNoZXIuXG4gICAgICB0aGlzLiNkaXNwYXRjaE1lc3NhZ2UoZGF0YSk7XG4gICAgfVxuICAgIHRoaXMuX2Nvbm5lY3Rpb24ub25PcGVuID0gKCkgPT4ge1xuICAgICAgLy8gUmVhZHkgdG8gc3RhcnQgc2VuZGluZy5cbiAgICAgIHRoaXMuI2Nvbm5lY3Rpb25PcGVuKCk7XG4gICAgfVxuICAgIHRoaXMuX2Nvbm5lY3Rpb24ub25EaXNjb25uZWN0ID0gKGVyciwgY29kZSkgPT4ge1xuICAgICAgdGhpcy4jZGlzY29ubmVjdGVkKGVyciwgY29kZSk7XG4gICAgfVxuICAgIC8vIFdyYXBwZXIgZm9yIHRoZSByZWNvbm5lY3QgaXRlcmF0b3IgY2FsbGJhY2suXG4gICAgdGhpcy5fY29ubmVjdGlvbi5vbkF1dG9yZWNvbm5lY3RJdGVyYXRpb24gPSAodGltZW91dCwgcHJvbWlzZSkgPT4ge1xuICAgICAgaWYgKHRoaXMub25BdXRvcmVjb25uZWN0SXRlcmF0aW9uKSB7XG4gICAgICAgIHRoaXMub25BdXRvcmVjb25uZWN0SXRlcmF0aW9uKHRpbWVvdXQsIHByb21pc2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX3BlcnNpc3QgPSBjb25maWcucGVyc2lzdDtcbiAgICAvLyBJbml0aWFsaXplIG9iamVjdCByZWdhcmRsZXNzLiBJdCBzaW1wbGlmaWVzIHRoZSBjb2RlLlxuICAgIHRoaXMuX2RiID0gbmV3IERCQ2FjaGUoZXJyID0+IHtcbiAgICAgIHRoaXMubG9nZ2VyKCdEQicsIGVycik7XG4gICAgfSwgdGhpcy5sb2dnZXIpO1xuXG4gICAgaWYgKHRoaXMuX3BlcnNpc3QpIHtcbiAgICAgIC8vIENyZWF0ZSB0aGUgcGVyc2lzdGVudCBjYWNoZS5cbiAgICAgIC8vIFN0b3JlIHByb21pc2VzIHRvIGJlIHJlc29sdmVkIHdoZW4gbWVzc2FnZXMgbG9hZCBpbnRvIG1lbW9yeS5cbiAgICAgIGNvbnN0IHByb20gPSBbXTtcbiAgICAgIHRoaXMuX2RiLmluaXREYXRhYmFzZSgpLnRoZW4oXyA9PiB7XG4gICAgICAgIC8vIEZpcnN0IGxvYWQgdG9waWNzIGludG8gbWVtb3J5LlxuICAgICAgICByZXR1cm4gdGhpcy5fZGIubWFwVG9waWNzKChkYXRhKSA9PiB7XG4gICAgICAgICAgbGV0IHRvcGljID0gdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgZGF0YS5uYW1lKTtcbiAgICAgICAgICBpZiAodG9waWMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRhdGEubmFtZSA9PSBDb25zdC5UT1BJQ19NRSkge1xuICAgICAgICAgICAgdG9waWMgPSBuZXcgVG9waWNNZSgpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZGF0YS5uYW1lID09IENvbnN0LlRPUElDX0ZORCkge1xuICAgICAgICAgICAgdG9waWMgPSBuZXcgVG9waWNGbmQoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdG9waWMgPSBuZXcgVG9waWMoZGF0YS5uYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5fZGIuZGVzZXJpYWxpemVUb3BpYyh0b3BpYywgZGF0YSk7XG4gICAgICAgICAgdGhpcy4jYXR0YWNoQ2FjaGVUb1RvcGljKHRvcGljKTtcbiAgICAgICAgICB0b3BpYy5fY2FjaGVQdXRTZWxmKCk7XG4gICAgICAgICAgLy8gVG9waWMgbG9hZGVkIGZyb20gREIgaXMgbm90IG5ldy5cbiAgICAgICAgICBkZWxldGUgdG9waWMuX25ldztcbiAgICAgICAgICAvLyBSZXF1ZXN0IHRvIGxvYWQgbWVzc2FnZXMgYW5kIHNhdmUgdGhlIHByb21pc2UuXG4gICAgICAgICAgcHJvbS5wdXNoKHRvcGljLl9sb2FkTWVzc2FnZXModGhpcy5fZGIpKTtcbiAgICAgICAgfSk7XG4gICAgICB9KS50aGVuKF8gPT4ge1xuICAgICAgICAvLyBUaGVuIGxvYWQgdXNlcnMuXG4gICAgICAgIHJldHVybiB0aGlzLl9kYi5tYXBVc2VycygoZGF0YSkgPT4ge1xuICAgICAgICAgIHRoaXMuI2NhY2hlUHV0KCd1c2VyJywgZGF0YS51aWQsIG1lcmdlT2JqKHt9LCBkYXRhLnB1YmxpYykpO1xuICAgICAgICB9KTtcbiAgICAgIH0pLnRoZW4oXyA9PiB7XG4gICAgICAgIC8vIE5vdyB3YWl0IGZvciBhbGwgbWVzc2FnZXMgdG8gZmluaXNoIGxvYWRpbmcuXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9tKTtcbiAgICAgIH0pLnRoZW4oXyA9PiB7XG4gICAgICAgIGlmIChvbkNvbXBsZXRlKSB7XG4gICAgICAgICAgb25Db21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubG9nZ2VyKFwiUGVyc2lzdGVudCBjYWNoZSBpbml0aWFsaXplZC5cIik7XG4gICAgICB9KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGlmIChvbkNvbXBsZXRlKSB7XG4gICAgICAgICAgb25Db21wbGV0ZShlcnIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubG9nZ2VyKFwiRmFpbGVkIHRvIGluaXRpYWxpemUgcGVyc2lzdGVudCBjYWNoZTpcIiwgZXJyKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9kYi5kZWxldGVEYXRhYmFzZSgpLnRoZW4oXyA9PiB7XG4gICAgICAgIGlmIChvbkNvbXBsZXRlKSB7XG4gICAgICAgICAgb25Db21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyBQcml2YXRlIG1ldGhvZHMuXG5cbiAgLy8gQ29uc29sZSBsb2dnZXIuIEJhYmVsIHNvbWVob3cgZmFpbHMgdG8gcGFyc2UgJy4uLnJlc3QnIHBhcmFtZXRlci5cbiAgbG9nZ2VyKHN0ciwgLi4uYXJncykge1xuICAgIGlmICh0aGlzLl9sb2dnaW5nRW5hYmxlZCkge1xuICAgICAgY29uc3QgZCA9IG5ldyBEYXRlKCk7XG4gICAgICBjb25zdCBkYXRlU3RyaW5nID0gKCcwJyArIGQuZ2V0VVRDSG91cnMoKSkuc2xpY2UoLTIpICsgJzonICtcbiAgICAgICAgKCcwJyArIGQuZ2V0VVRDTWludXRlcygpKS5zbGljZSgtMikgKyAnOicgK1xuICAgICAgICAoJzAnICsgZC5nZXRVVENTZWNvbmRzKCkpLnNsaWNlKC0yKSArICcuJyArXG4gICAgICAgICgnMDAnICsgZC5nZXRVVENNaWxsaXNlY29uZHMoKSkuc2xpY2UoLTMpO1xuXG4gICAgICBjb25zb2xlLmxvZygnWycgKyBkYXRlU3RyaW5nICsgJ10nLCBzdHIsIGFyZ3Muam9pbignICcpKTtcbiAgICB9XG4gIH1cblxuICAvLyBHZW5lcmF0b3Igb2YgZGVmYXVsdCBwcm9taXNlcyBmb3Igc2VudCBwYWNrZXRzLlxuICAjbWFrZVByb21pc2UoaWQpIHtcbiAgICBsZXQgcHJvbWlzZSA9IG51bGw7XG4gICAgaWYgKGlkKSB7XG4gICAgICBwcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAvLyBTdG9yZWQgY2FsbGJhY2tzIHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIHJlc3BvbnNlIHBhY2tldCB3aXRoIHRoaXMgSWQgYXJyaXZlc1xuICAgICAgICB0aGlzLl9wZW5kaW5nUHJvbWlzZXNbaWRdID0ge1xuICAgICAgICAgICdyZXNvbHZlJzogcmVzb2x2ZSxcbiAgICAgICAgICAncmVqZWN0JzogcmVqZWN0LFxuICAgICAgICAgICd0cyc6IG5ldyBEYXRlKClcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfTtcblxuICAvLyBSZXNvbHZlIG9yIHJlamVjdCBhIHBlbmRpbmcgcHJvbWlzZS5cbiAgLy8gVW5yZXNvbHZlZCBwcm9taXNlcyBhcmUgc3RvcmVkIGluIF9wZW5kaW5nUHJvbWlzZXMuXG4gICNleGVjUHJvbWlzZShpZCwgY29kZSwgb25PSywgZXJyb3JUZXh0KSB7XG4gICAgY29uc3QgY2FsbGJhY2tzID0gdGhpcy5fcGVuZGluZ1Byb21pc2VzW2lkXTtcbiAgICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgICBkZWxldGUgdGhpcy5fcGVuZGluZ1Byb21pc2VzW2lkXTtcbiAgICAgIGlmIChjb2RlID49IDIwMCAmJiBjb2RlIDwgNDAwKSB7XG4gICAgICAgIGlmIChjYWxsYmFja3MucmVzb2x2ZSkge1xuICAgICAgICAgIGNhbGxiYWNrcy5yZXNvbHZlKG9uT0spO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGNhbGxiYWNrcy5yZWplY3QpIHtcbiAgICAgICAgY2FsbGJhY2tzLnJlamVjdChuZXcgRXJyb3IoYCR7ZXJyb3JUZXh0fSAoJHtjb2RlfSlgKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gU2VuZCBhIHBhY2tldC4gSWYgcGFja2V0IGlkIGlzIHByb3ZpZGVkIHJldHVybiBhIHByb21pc2UuXG4gICNzZW5kKHBrdCwgaWQpIHtcbiAgICBsZXQgcHJvbWlzZTtcbiAgICBpZiAoaWQpIHtcbiAgICAgIHByb21pc2UgPSB0aGlzLiNtYWtlUHJvbWlzZShpZCk7XG4gICAgfVxuICAgIHBrdCA9IHNpbXBsaWZ5KHBrdCk7XG4gICAgbGV0IG1zZyA9IEpTT04uc3RyaW5naWZ5KHBrdCk7XG4gICAgdGhpcy5sb2dnZXIoXCJvdXQ6IFwiICsgKHRoaXMuX3RyaW1Mb25nU3RyaW5ncyA/IEpTT04uc3RyaW5naWZ5KHBrdCwganNvbkxvZ2dlckhlbHBlcikgOiBtc2cpKTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5fY29ubmVjdGlvbi5zZW5kVGV4dChtc2cpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgLy8gSWYgc2VuZFRleHQgdGhyb3dzLCB3cmFwIHRoZSBlcnJvciBpbiBhIHByb21pc2Ugb3IgcmV0aHJvdy5cbiAgICAgIGlmIChpZCkge1xuICAgICAgICB0aGlzLiNleGVjUHJvbWlzZShpZCwgQ29ubmVjdGlvbi5ORVRXT1JLX0VSUk9SLCBudWxsLCBlcnIubWVzc2FnZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLy8gVGhlIG1haW4gbWVzc2FnZSBkaXNwYXRjaGVyLlxuICAjZGlzcGF0Y2hNZXNzYWdlKGRhdGEpIHtcbiAgICAvLyBTa2lwIGVtcHR5IHJlc3BvbnNlLiBUaGlzIGhhcHBlbnMgd2hlbiBMUCB0aW1lcyBvdXQuXG4gICAgaWYgKCFkYXRhKVxuICAgICAgcmV0dXJuO1xuXG4gICAgdGhpcy5faW5QYWNrZXRDb3VudCsrO1xuXG4gICAgLy8gU2VuZCByYXcgbWVzc2FnZSB0byBsaXN0ZW5lclxuICAgIGlmICh0aGlzLm9uUmF3TWVzc2FnZSkge1xuICAgICAgdGhpcy5vblJhd01lc3NhZ2UoZGF0YSk7XG4gICAgfVxuXG4gICAgaWYgKGRhdGEgPT09ICcwJykge1xuICAgICAgLy8gU2VydmVyIHJlc3BvbnNlIHRvIGEgbmV0d29yayBwcm9iZS5cbiAgICAgIGlmICh0aGlzLm9uTmV0d29ya1Byb2JlKSB7XG4gICAgICAgIHRoaXMub25OZXR3b3JrUHJvYmUoKTtcbiAgICAgIH1cbiAgICAgIC8vIE5vIHByb2Nlc3NpbmcgaXMgbmVjZXNzYXJ5LlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBwa3QgPSBKU09OLnBhcnNlKGRhdGEsIGpzb25QYXJzZUhlbHBlcik7XG4gICAgaWYgKCFwa3QpIHtcbiAgICAgIHRoaXMubG9nZ2VyKFwiaW46IFwiICsgZGF0YSk7XG4gICAgICB0aGlzLmxvZ2dlcihcIkVSUk9SOiBmYWlsZWQgdG8gcGFyc2UgZGF0YVwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2dnZXIoXCJpbjogXCIgKyAodGhpcy5fdHJpbUxvbmdTdHJpbmdzID8gSlNPTi5zdHJpbmdpZnkocGt0LCBqc29uTG9nZ2VySGVscGVyKSA6IGRhdGEpKTtcblxuICAgICAgLy8gU2VuZCBjb21wbGV0ZSBwYWNrZXQgdG8gbGlzdGVuZXJcbiAgICAgIGlmICh0aGlzLm9uTWVzc2FnZSkge1xuICAgICAgICB0aGlzLm9uTWVzc2FnZShwa3QpO1xuICAgICAgfVxuXG4gICAgICBpZiAocGt0LmN0cmwpIHtcbiAgICAgICAgLy8gSGFuZGxpbmcge2N0cmx9IG1lc3NhZ2VcbiAgICAgICAgaWYgKHRoaXMub25DdHJsTWVzc2FnZSkge1xuICAgICAgICAgIHRoaXMub25DdHJsTWVzc2FnZShwa3QuY3RybCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXNvbHZlIG9yIHJlamVjdCBhIHBlbmRpbmcgcHJvbWlzZSwgaWYgYW55XG4gICAgICAgIGlmIChwa3QuY3RybC5pZCkge1xuICAgICAgICAgIHRoaXMuI2V4ZWNQcm9taXNlKHBrdC5jdHJsLmlkLCBwa3QuY3RybC5jb2RlLCBwa3QuY3RybCwgcGt0LmN0cmwudGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgaWYgKHBrdC5jdHJsLmNvZGUgPT0gMjA1ICYmIHBrdC5jdHJsLnRleHQgPT0gJ2V2aWN0ZWQnKSB7XG4gICAgICAgICAgICAvLyBVc2VyIGV2aWN0ZWQgZnJvbSB0b3BpYy5cbiAgICAgICAgICAgIGNvbnN0IHRvcGljID0gdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgcGt0LmN0cmwudG9waWMpO1xuICAgICAgICAgICAgaWYgKHRvcGljKSB7XG4gICAgICAgICAgICAgIHRvcGljLl9yZXNldFN1YigpO1xuICAgICAgICAgICAgICBpZiAocGt0LmN0cmwucGFyYW1zICYmIHBrdC5jdHJsLnBhcmFtcy51bnN1Yikge1xuICAgICAgICAgICAgICAgIHRvcGljLl9nb25lKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKHBrdC5jdHJsLmNvZGUgPCAzMDAgJiYgcGt0LmN0cmwucGFyYW1zKSB7XG4gICAgICAgICAgICBpZiAocGt0LmN0cmwucGFyYW1zLndoYXQgPT0gJ2RhdGEnKSB7XG4gICAgICAgICAgICAgIC8vIGNvZGU9MjA4LCBhbGwgbWVzc2FnZXMgcmVjZWl2ZWQ6IFwicGFyYW1zXCI6e1wiY291bnRcIjoxMSxcIndoYXRcIjpcImRhdGFcIn0sXG4gICAgICAgICAgICAgIGNvbnN0IHRvcGljID0gdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgcGt0LmN0cmwudG9waWMpO1xuICAgICAgICAgICAgICBpZiAodG9waWMpIHtcbiAgICAgICAgICAgICAgICB0b3BpYy5fYWxsTWVzc2FnZXNSZWNlaXZlZChwa3QuY3RybC5wYXJhbXMuY291bnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBrdC5jdHJsLnBhcmFtcy53aGF0ID09ICdzdWInKSB7XG4gICAgICAgICAgICAgIC8vIGNvZGU9MjA0LCB0aGUgdG9waWMgaGFzIG5vIChyZWZyZXNoZWQpIHN1YnNjcmlwdGlvbnMuXG4gICAgICAgICAgICAgIGNvbnN0IHRvcGljID0gdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgcGt0LmN0cmwudG9waWMpO1xuICAgICAgICAgICAgICBpZiAodG9waWMpIHtcbiAgICAgICAgICAgICAgICAvLyBUcmlnZ2VyIHRvcGljLm9uU3Vic1VwZGF0ZWQuXG4gICAgICAgICAgICAgICAgdG9waWMuX3Byb2Nlc3NNZXRhU3ViKFtdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBpZiAocGt0Lm1ldGEpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsaW5nIGEge21ldGF9IG1lc3NhZ2UuXG4gICAgICAgICAgICAvLyBQcmVmZXJyZWQgQVBJOiBSb3V0ZSBtZXRhIHRvIHRvcGljLCBpZiBvbmUgaXMgcmVnaXN0ZXJlZFxuICAgICAgICAgICAgY29uc3QgdG9waWMgPSB0aGlzLiNjYWNoZUdldCgndG9waWMnLCBwa3QubWV0YS50b3BpYyk7XG4gICAgICAgICAgICBpZiAodG9waWMpIHtcbiAgICAgICAgICAgICAgdG9waWMuX3JvdXRlTWV0YShwa3QubWV0YSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwa3QubWV0YS5pZCkge1xuICAgICAgICAgICAgICB0aGlzLiNleGVjUHJvbWlzZShwa3QubWV0YS5pZCwgMjAwLCBwa3QubWV0YSwgJ01FVEEnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gU2Vjb25kYXJ5IEFQSTogY2FsbGJhY2tcbiAgICAgICAgICAgIGlmICh0aGlzLm9uTWV0YU1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgdGhpcy5vbk1ldGFNZXNzYWdlKHBrdC5tZXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKHBrdC5kYXRhKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGluZyB7ZGF0YX0gbWVzc2FnZVxuICAgICAgICAgICAgLy8gUHJlZmVycmVkIEFQSTogUm91dGUgZGF0YSB0byB0b3BpYywgaWYgb25lIGlzIHJlZ2lzdGVyZWRcbiAgICAgICAgICAgIGNvbnN0IHRvcGljID0gdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgcGt0LmRhdGEudG9waWMpO1xuICAgICAgICAgICAgaWYgKHRvcGljKSB7XG4gICAgICAgICAgICAgIHRvcGljLl9yb3V0ZURhdGEocGt0LmRhdGEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTZWNvbmRhcnkgQVBJOiBDYWxsIGNhbGxiYWNrXG4gICAgICAgICAgICBpZiAodGhpcy5vbkRhdGFNZXNzYWdlKSB7XG4gICAgICAgICAgICAgIHRoaXMub25EYXRhTWVzc2FnZShwa3QuZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChwa3QucHJlcykge1xuICAgICAgICAgICAgLy8gSGFuZGxpbmcge3ByZXN9IG1lc3NhZ2VcbiAgICAgICAgICAgIC8vIFByZWZlcnJlZCBBUEk6IFJvdXRlIHByZXNlbmNlIHRvIHRvcGljLCBpZiBvbmUgaXMgcmVnaXN0ZXJlZFxuICAgICAgICAgICAgY29uc3QgdG9waWMgPSB0aGlzLiNjYWNoZUdldCgndG9waWMnLCBwa3QucHJlcy50b3BpYyk7XG4gICAgICAgICAgICBpZiAodG9waWMpIHtcbiAgICAgICAgICAgICAgdG9waWMuX3JvdXRlUHJlcyhwa3QucHJlcyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNlY29uZGFyeSBBUEkgLSBjYWxsYmFja1xuICAgICAgICAgICAgaWYgKHRoaXMub25QcmVzTWVzc2FnZSkge1xuICAgICAgICAgICAgICB0aGlzLm9uUHJlc01lc3NhZ2UocGt0LnByZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAocGt0LmluZm8pIHtcbiAgICAgICAgICAgIC8vIHtpbmZvfSBtZXNzYWdlIC0gcmVhZC9yZWNlaXZlZCBub3RpZmljYXRpb25zIGFuZCBrZXkgcHJlc3Nlc1xuICAgICAgICAgICAgLy8gUHJlZmVycmVkIEFQSTogUm91dGUge2luZm99fSB0byB0b3BpYywgaWYgb25lIGlzIHJlZ2lzdGVyZWRcbiAgICAgICAgICAgIGNvbnN0IHRvcGljID0gdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgcGt0LmluZm8udG9waWMpO1xuICAgICAgICAgICAgaWYgKHRvcGljKSB7XG4gICAgICAgICAgICAgIHRvcGljLl9yb3V0ZUluZm8ocGt0LmluZm8pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTZWNvbmRhcnkgQVBJIC0gY2FsbGJhY2tcbiAgICAgICAgICAgIGlmICh0aGlzLm9uSW5mb01lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgdGhpcy5vbkluZm9NZXNzYWdlKHBrdC5pbmZvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIoXCJFUlJPUjogVW5rbm93biBwYWNrZXQgcmVjZWl2ZWQuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgMCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQ29ubmVjdGlvbiBvcGVuLCByZWFkeSB0byBzdGFydCBzZW5kaW5nLlxuICAjY29ubmVjdGlvbk9wZW4oKSB7XG4gICAgaWYgKCF0aGlzLl9leHBpcmVQcm9taXNlcykge1xuICAgICAgLy8gUmVqZWN0IHByb21pc2VzIHdoaWNoIGhhdmUgbm90IGJlZW4gcmVzb2x2ZWQgZm9yIHRvbyBsb25nLlxuICAgICAgdGhpcy5fZXhwaXJlUHJvbWlzZXMgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihcIlRpbWVvdXQgKDUwNClcIik7XG4gICAgICAgIGNvbnN0IGV4cGlyZXMgPSBuZXcgRGF0ZShuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIENvbnN0LkVYUElSRV9QUk9NSVNFU19USU1FT1VUKTtcbiAgICAgICAgZm9yIChsZXQgaWQgaW4gdGhpcy5fcGVuZGluZ1Byb21pc2VzKSB7XG4gICAgICAgICAgbGV0IGNhbGxiYWNrcyA9IHRoaXMuX3BlbmRpbmdQcm9taXNlc1tpZF07XG4gICAgICAgICAgaWYgKGNhbGxiYWNrcyAmJiBjYWxsYmFja3MudHMgPCBleHBpcmVzKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlcihcIlByb21pc2UgZXhwaXJlZFwiLCBpZCk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fcGVuZGluZ1Byb21pc2VzW2lkXTtcbiAgICAgICAgICAgIGlmIChjYWxsYmFja3MucmVqZWN0KSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrcy5yZWplY3QoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIENvbnN0LkVYUElSRV9QUk9NSVNFU19QRVJJT0QpO1xuICAgIH1cbiAgICB0aGlzLmhlbGxvKCk7XG4gIH1cblxuICAjZGlzY29ubmVjdGVkKGVyciwgY29kZSkge1xuICAgIHRoaXMuX2luUGFja2V0Q291bnQgPSAwO1xuICAgIHRoaXMuX3NlcnZlckluZm8gPSBudWxsO1xuICAgIHRoaXMuX2F1dGhlbnRpY2F0ZWQgPSBmYWxzZTtcblxuICAgIGlmICh0aGlzLl9leHBpcmVQcm9taXNlcykge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLl9leHBpcmVQcm9taXNlcyk7XG4gICAgICB0aGlzLl9leHBpcmVQcm9taXNlcyA9IG51bGw7XG4gICAgfVxuXG4gICAgLy8gTWFyayBhbGwgdG9waWNzIGFzIHVuc3Vic2NyaWJlZFxuICAgIHRoaXMuI2NhY2hlTWFwKCd0b3BpYycsICh0b3BpYywga2V5KSA9PiB7XG4gICAgICB0b3BpYy5fcmVzZXRTdWIoKTtcbiAgICB9KTtcblxuICAgIC8vIFJlamVjdCBhbGwgcGVuZGluZyBwcm9taXNlc1xuICAgIGZvciAobGV0IGtleSBpbiB0aGlzLl9wZW5kaW5nUHJvbWlzZXMpIHtcbiAgICAgIGNvbnN0IGNhbGxiYWNrcyA9IHRoaXMuX3BlbmRpbmdQcm9taXNlc1trZXldO1xuICAgICAgaWYgKGNhbGxiYWNrcyAmJiBjYWxsYmFja3MucmVqZWN0KSB7XG4gICAgICAgIGNhbGxiYWNrcy5yZWplY3QoZXJyKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5fcGVuZGluZ1Byb21pc2VzID0ge307XG5cbiAgICBpZiAodGhpcy5vbkRpc2Nvbm5lY3QpIHtcbiAgICAgIHRoaXMub25EaXNjb25uZWN0KGVycik7XG4gICAgfVxuICB9XG5cbiAgLy8gR2V0IFVzZXIgQWdlbnQgc3RyaW5nXG4gICNnZXRVc2VyQWdlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FwcE5hbWUgKyAnICgnICsgKHRoaXMuX2Jyb3dzZXIgPyB0aGlzLl9icm93c2VyICsgJzsgJyA6ICcnKSArIHRoaXMuX2h3b3MgKyAnKTsgJyArIENvbnN0LkxJQlJBUlk7XG4gIH1cblxuICAvLyBHZW5lcmF0b3Igb2YgcGFja2V0cyBzdHVic1xuICAjaW5pdFBhY2tldCh0eXBlLCB0b3BpYykge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnaGknOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICdoaSc6IHtcbiAgICAgICAgICAgICdpZCc6IHRoaXMuZ2V0TmV4dFVuaXF1ZUlkKCksXG4gICAgICAgICAgICAndmVyJzogQ29uc3QuVkVSU0lPTixcbiAgICAgICAgICAgICd1YSc6IHRoaXMuI2dldFVzZXJBZ2VudCgpLFxuICAgICAgICAgICAgJ2Rldic6IHRoaXMuX2RldmljZVRva2VuLFxuICAgICAgICAgICAgJ2xhbmcnOiB0aGlzLl9odW1hbkxhbmd1YWdlLFxuICAgICAgICAgICAgJ3BsYXRmJzogdGhpcy5fcGxhdGZvcm1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgIGNhc2UgJ2FjYyc6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgJ2FjYyc6IHtcbiAgICAgICAgICAgICdpZCc6IHRoaXMuZ2V0TmV4dFVuaXF1ZUlkKCksXG4gICAgICAgICAgICAndXNlcic6IG51bGwsXG4gICAgICAgICAgICAnc2NoZW1lJzogbnVsbCxcbiAgICAgICAgICAgICdzZWNyZXQnOiBudWxsLFxuICAgICAgICAgICAgJ2xvZ2luJzogZmFsc2UsXG4gICAgICAgICAgICAndGFncyc6IG51bGwsXG4gICAgICAgICAgICAnZGVzYyc6IHt9LFxuICAgICAgICAgICAgJ2NyZWQnOiB7fVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgY2FzZSAnbG9naW4nOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICdsb2dpbic6IHtcbiAgICAgICAgICAgICdpZCc6IHRoaXMuZ2V0TmV4dFVuaXF1ZUlkKCksXG4gICAgICAgICAgICAnc2NoZW1lJzogbnVsbCxcbiAgICAgICAgICAgICdzZWNyZXQnOiBudWxsXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICBjYXNlICdzdWInOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICdzdWInOiB7XG4gICAgICAgICAgICAnaWQnOiB0aGlzLmdldE5leHRVbmlxdWVJZCgpLFxuICAgICAgICAgICAgJ3RvcGljJzogdG9waWMsXG4gICAgICAgICAgICAnc2V0Jzoge30sXG4gICAgICAgICAgICAnZ2V0Jzoge31cbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgIGNhc2UgJ2xlYXZlJzpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAnbGVhdmUnOiB7XG4gICAgICAgICAgICAnaWQnOiB0aGlzLmdldE5leHRVbmlxdWVJZCgpLFxuICAgICAgICAgICAgJ3RvcGljJzogdG9waWMsXG4gICAgICAgICAgICAndW5zdWInOiBmYWxzZVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgY2FzZSAncHViJzpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAncHViJzoge1xuICAgICAgICAgICAgJ2lkJzogdGhpcy5nZXROZXh0VW5pcXVlSWQoKSxcbiAgICAgICAgICAgICd0b3BpYyc6IHRvcGljLFxuICAgICAgICAgICAgJ25vZWNobyc6IGZhbHNlLFxuICAgICAgICAgICAgJ2hlYWQnOiBudWxsLFxuICAgICAgICAgICAgJ2NvbnRlbnQnOiB7fVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgY2FzZSAnZ2V0JzpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAnZ2V0Jzoge1xuICAgICAgICAgICAgJ2lkJzogdGhpcy5nZXROZXh0VW5pcXVlSWQoKSxcbiAgICAgICAgICAgICd0b3BpYyc6IHRvcGljLFxuICAgICAgICAgICAgJ3doYXQnOiBudWxsLFxuICAgICAgICAgICAgJ2Rlc2MnOiB7fSxcbiAgICAgICAgICAgICdzdWInOiB7fSxcbiAgICAgICAgICAgICdkYXRhJzoge31cbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgIGNhc2UgJ3NldCc6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgJ3NldCc6IHtcbiAgICAgICAgICAgICdpZCc6IHRoaXMuZ2V0TmV4dFVuaXF1ZUlkKCksXG4gICAgICAgICAgICAndG9waWMnOiB0b3BpYyxcbiAgICAgICAgICAgICdkZXNjJzoge30sXG4gICAgICAgICAgICAnc3ViJzoge30sXG4gICAgICAgICAgICAndGFncyc6IFtdLFxuICAgICAgICAgICAgJ2VwaGVtZXJhbCc6IHt9XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICBjYXNlICdkZWwnOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICdkZWwnOiB7XG4gICAgICAgICAgICAnaWQnOiB0aGlzLmdldE5leHRVbmlxdWVJZCgpLFxuICAgICAgICAgICAgJ3RvcGljJzogdG9waWMsXG4gICAgICAgICAgICAnd2hhdCc6IG51bGwsXG4gICAgICAgICAgICAnZGVsc2VxJzogbnVsbCxcbiAgICAgICAgICAgICd1c2VyJzogbnVsbCxcbiAgICAgICAgICAgICdoYXJkJzogZmFsc2VcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgIGNhc2UgJ25vdGUnOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICdub3RlJzoge1xuICAgICAgICAgICAgLy8gbm8gaWQgYnkgZGVzaWduIChleGNlcHQgY2FsbHMpLlxuICAgICAgICAgICAgJ3RvcGljJzogdG9waWMsXG4gICAgICAgICAgICAnd2hhdCc6IG51bGwsIC8vIG9uZSBvZiBcInJlY3ZcIiwgXCJyZWFkXCIsIFwia3BcIiwgXCJjYWxsXCJcbiAgICAgICAgICAgICdzZXEnOiB1bmRlZmluZWQgLy8gdGhlIHNlcnZlci1zaWRlIG1lc3NhZ2UgaWQgYWNrbm93bGVkZ2VkIGFzIHJlY2VpdmVkIG9yIHJlYWQuXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcGFja2V0IHR5cGUgcmVxdWVzdGVkOiAke3R5cGV9YCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2FjaGUgbWFuYWdlbWVudFxuICAjY2FjaGVQdXQodHlwZSwgbmFtZSwgb2JqKSB7XG4gICAgdGhpcy5fY2FjaGVbdHlwZSArICc6JyArIG5hbWVdID0gb2JqO1xuICB9XG4gICNjYWNoZUdldCh0eXBlLCBuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlW3R5cGUgKyAnOicgKyBuYW1lXTtcbiAgfVxuICAjY2FjaGVEZWwodHlwZSwgbmFtZSkge1xuICAgIGRlbGV0ZSB0aGlzLl9jYWNoZVt0eXBlICsgJzonICsgbmFtZV07XG4gIH1cblxuICAvLyBFbnVtZXJhdGUgYWxsIGl0ZW1zIGluIGNhY2hlLCBjYWxsIGZ1bmMgZm9yIGVhY2ggaXRlbS5cbiAgLy8gRW51bWVyYXRpb24gc3RvcHMgaWYgZnVuYyByZXR1cm5zIHRydWUuXG4gICNjYWNoZU1hcCh0eXBlLCBmdW5jLCBjb250ZXh0KSB7XG4gICAgY29uc3Qga2V5ID0gdHlwZSA/IHR5cGUgKyAnOicgOiB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgaWR4IGluIHRoaXMuX2NhY2hlKSB7XG4gICAgICBpZiAoIWtleSB8fCBpZHguaW5kZXhPZihrZXkpID09IDApIHtcbiAgICAgICAgaWYgKGZ1bmMuY2FsbChjb250ZXh0LCB0aGlzLl9jYWNoZVtpZHhdLCBpZHgpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBNYWtlIGxpbWl0ZWQgY2FjaGUgbWFuYWdlbWVudCBhdmFpbGFibGUgdG8gdG9waWMuXG4gIC8vIENhY2hpbmcgdXNlci5wdWJsaWMgb25seS4gRXZlcnl0aGluZyBlbHNlIGlzIHBlci10b3BpYy5cbiAgI2F0dGFjaENhY2hlVG9Ub3BpYyh0b3BpYykge1xuICAgIHRvcGljLl90aW5vZGUgPSB0aGlzO1xuXG4gICAgdG9waWMuX2NhY2hlR2V0VXNlciA9ICh1aWQpID0+IHtcbiAgICAgIGNvbnN0IHB1YiA9IHRoaXMuI2NhY2hlR2V0KCd1c2VyJywgdWlkKTtcbiAgICAgIGlmIChwdWIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB1c2VyOiB1aWQsXG4gICAgICAgICAgcHVibGljOiBtZXJnZU9iaih7fSwgcHViKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9O1xuICAgIHRvcGljLl9jYWNoZVB1dFVzZXIgPSAodWlkLCB1c2VyKSA9PiB7XG4gICAgICB0aGlzLiNjYWNoZVB1dCgndXNlcicsIHVpZCwgbWVyZ2VPYmooe30sIHVzZXIucHVibGljKSk7XG4gICAgfTtcbiAgICB0b3BpYy5fY2FjaGVEZWxVc2VyID0gKHVpZCkgPT4ge1xuICAgICAgdGhpcy4jY2FjaGVEZWwoJ3VzZXInLCB1aWQpO1xuICAgIH07XG4gICAgdG9waWMuX2NhY2hlUHV0U2VsZiA9IF8gPT4ge1xuICAgICAgdGhpcy4jY2FjaGVQdXQoJ3RvcGljJywgdG9waWMubmFtZSwgdG9waWMpO1xuICAgIH07XG4gICAgdG9waWMuX2NhY2hlRGVsU2VsZiA9IF8gPT4ge1xuICAgICAgdGhpcy4jY2FjaGVEZWwoJ3RvcGljJywgdG9waWMubmFtZSk7XG4gICAgfTtcbiAgfVxuXG4gIC8vIE9uIHN1Y2Nlc3NmdWwgbG9naW4gc2F2ZSBzZXJ2ZXItcHJvdmlkZWQgZGF0YS5cbiAgI2xvZ2luU3VjY2Vzc2Z1bChjdHJsKSB7XG4gICAgaWYgKCFjdHJsLnBhcmFtcyB8fCAhY3RybC5wYXJhbXMudXNlcikge1xuICAgICAgcmV0dXJuIGN0cmw7XG4gICAgfVxuICAgIC8vIFRoaXMgaXMgYSByZXNwb25zZSB0byBhIHN1Y2Nlc3NmdWwgbG9naW4sXG4gICAgLy8gZXh0cmFjdCBVSUQgYW5kIHNlY3VyaXR5IHRva2VuLCBzYXZlIGl0IGluIFRpbm9kZSBtb2R1bGVcbiAgICB0aGlzLl9teVVJRCA9IGN0cmwucGFyYW1zLnVzZXI7XG4gICAgdGhpcy5fYXV0aGVudGljYXRlZCA9IChjdHJsICYmIGN0cmwuY29kZSA+PSAyMDAgJiYgY3RybC5jb2RlIDwgMzAwKTtcbiAgICBpZiAoY3RybC5wYXJhbXMgJiYgY3RybC5wYXJhbXMudG9rZW4gJiYgY3RybC5wYXJhbXMuZXhwaXJlcykge1xuICAgICAgdGhpcy5fYXV0aFRva2VuID0ge1xuICAgICAgICB0b2tlbjogY3RybC5wYXJhbXMudG9rZW4sXG4gICAgICAgIGV4cGlyZXM6IGN0cmwucGFyYW1zLmV4cGlyZXNcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2F1dGhUb2tlbiA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub25Mb2dpbikge1xuICAgICAgdGhpcy5vbkxvZ2luKGN0cmwuY29kZSwgY3RybC50ZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3RybDtcbiAgfVxuXG4gIC8vIFN0YXRpYyBtZXRob2RzLlxuICAvKipcbiAgICogSGVscGVyIG1ldGhvZCB0byBwYWNrYWdlIGFjY291bnQgY3JlZGVudGlhbC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBDcmVkZW50aWFsfSBtZXRoIC0gdmFsaWRhdGlvbiBtZXRob2Qgb3Igb2JqZWN0IHdpdGggdmFsaWRhdGlvbiBkYXRhLlxuICAgKiBAcGFyYW0ge3N0cmluZz19IHZhbCAtIHZhbGlkYXRpb24gdmFsdWUgKGUuZy4gZW1haWwgb3IgcGhvbmUgbnVtYmVyKS5cbiAgICogQHBhcmFtIHtPYmplY3Q9fSBwYXJhbXMgLSB2YWxpZGF0aW9uIHBhcmFtZXRlcnMuXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gcmVzcCAtIHZhbGlkYXRpb24gcmVzcG9uc2UuXG4gICAqXG4gICAqIEByZXR1cm5zIHtBcnJheS48Q3JlZGVudGlhbD59IGFycmF5IHdpdGggYSBzaW5nbGUgY3JlZGVudGlhbCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyB2YWxpZCBjcmVkZW50aWFscyB3ZXJlIGdpdmVuLlxuICAgKi9cbiAgc3RhdGljIGNyZWRlbnRpYWwobWV0aCwgdmFsLCBwYXJhbXMsIHJlc3ApIHtcbiAgICBpZiAodHlwZW9mIG1ldGggPT0gJ29iamVjdCcpIHtcbiAgICAgICh7XG4gICAgICAgIHZhbCxcbiAgICAgICAgcGFyYW1zLFxuICAgICAgICByZXNwLFxuICAgICAgICBtZXRoXG4gICAgICB9ID0gbWV0aCk7XG4gICAgfVxuICAgIGlmIChtZXRoICYmICh2YWwgfHwgcmVzcCkpIHtcbiAgICAgIHJldHVybiBbe1xuICAgICAgICAnbWV0aCc6IG1ldGgsXG4gICAgICAgICd2YWwnOiB2YWwsXG4gICAgICAgICdyZXNwJzogcmVzcCxcbiAgICAgICAgJ3BhcmFtcyc6IHBhcmFtc1xuICAgICAgfV07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSB0b3BpYyB0eXBlIGZyb20gdG9waWMncyBuYW1lOiBncnAsIHAycCwgbWUsIGZuZCwgc3lzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIHRlc3QuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IE9uZSBvZiA8Y29kZT5cIm1lXCI8L2NvZGU+LCA8Y29kZT5cImZuZFwiPC9jb2RlPiwgPGNvZGU+XCJzeXNcIjwvY29kZT4sIDxjb2RlPlwiZ3JwXCI8L2NvZGU+LFxuICAgKiAgICA8Y29kZT5cInAycFwiPC9jb2RlPiBvciA8Y29kZT51bmRlZmluZWQ8L2NvZGU+LlxuICAgKi9cbiAgc3RhdGljIHRvcGljVHlwZShuYW1lKSB7XG4gICAgcmV0dXJuIFRvcGljLnRvcGljVHlwZShuYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gdG9waWMgbmFtZSBpcyBhIG5hbWUgb2YgYSAnbWUnIHRvcGljLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIHRlc3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbmFtZSBpcyBhIG5hbWUgb2YgYSAnbWUnIHRvcGljLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxuICAgKi9cbiAgc3RhdGljIGlzTWVUb3BpY05hbWUobmFtZSkge1xuICAgIHJldHVybiBUb3BpYy5pc01lVG9waWNOYW1lKG5hbWUpO1xuICB9XG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gdG9waWMgbmFtZSBpcyBhIG5hbWUgb2YgYSBncm91cCB0b3BpYy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSB0b3BpYyB0byB0ZXN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5hbWUgaXMgYSBuYW1lIG9mIGEgZ3JvdXAgdG9waWMsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuXG4gICAqL1xuICBzdGF0aWMgaXNHcm91cFRvcGljTmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIFRvcGljLmlzR3JvdXBUb3BpY05hbWUobmFtZSk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRoZSBnaXZlbiB0b3BpYyBuYW1lIGlzIGEgbmFtZSBvZiBhIHAycCB0b3BpYy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSB0b3BpYyB0byB0ZXN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5hbWUgaXMgYSBuYW1lIG9mIGEgcDJwIHRvcGljLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxuICAgKi9cbiAgc3RhdGljIGlzUDJQVG9waWNOYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gVG9waWMuaXNQMlBUb3BpY05hbWUobmFtZSk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRoZSBnaXZlbiB0b3BpYyBuYW1lIGlzIGEgbmFtZSBvZiBhIGNvbW11bmljYXRpb24gdG9waWMsIGkuZS4gUDJQIG9yIGdyb3VwLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIHRlc3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbmFtZSBpcyBhIG5hbWUgb2YgYSBwMnAgb3IgZ3JvdXAgdG9waWMsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuXG4gICAqL1xuICBzdGF0aWMgaXNDb21tVG9waWNOYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gVG9waWMuaXNDb21tVG9waWNOYW1lKG5hbWUpO1xuICB9XG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGUgdG9waWMgbmFtZSBpcyBhIG5hbWUgb2YgYSBuZXcgdG9waWMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gdG9waWMgbmFtZSB0byBjaGVjay5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBuYW1lIGlzIGEgbmFtZSBvZiBhIG5ldyB0b3BpYywgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cbiAgICovXG4gIHN0YXRpYyBpc05ld0dyb3VwVG9waWNOYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gVG9waWMuaXNOZXdHcm91cFRvcGljTmFtZShuYW1lKTtcbiAgfVxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIHRvcGljIG5hbWUgaXMgYSBuYW1lIG9mIGEgY2hhbm5lbC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSB0b3BpYyBuYW1lIHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5hbWUgaXMgYSBuYW1lIG9mIGEgY2hhbm5lbCwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cbiAgICovXG4gIHN0YXRpYyBpc0NoYW5uZWxUb3BpY05hbWUobmFtZSkge1xuICAgIHJldHVybiBUb3BpYy5pc0NoYW5uZWxUb3BpY05hbWUobmFtZSk7XG4gIH1cbiAgLyoqXG4gICAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoaXMgVGlub2RlIGNsaWVudCBsaWJyYXJ5LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBzZW1hbnRpYyB2ZXJzaW9uIG9mIHRoZSBsaWJyYXJ5LCBlLmcuIDxjb2RlPlwiMC4xNS41LXJjMVwiPC9jb2RlPi5cbiAgICovXG4gIHN0YXRpYyBnZXRWZXJzaW9uKCkge1xuICAgIHJldHVybiBDb25zdC5WRVJTSU9OO1xuICB9XG4gIC8qKlxuICAgKiBUbyB1c2UgVGlub2RlIGluIGEgbm9uIGJyb3dzZXIgY29udGV4dCwgc3VwcGx5IFdlYlNvY2tldCBhbmQgWE1MSHR0cFJlcXVlc3QgcHJvdmlkZXJzLlxuICAgKiBAc3RhdGljXG4gICAqXG4gICAqIEBwYXJhbSB3c1Byb3ZpZGVyIDxjb2RlPldlYlNvY2tldDwvY29kZT4gcHJvdmlkZXIsIGUuZy4gZm9yIG5vZGVKUyAsIDxjb2RlPnJlcXVpcmUoJ3dzJyk8L2NvZGU+LlxuICAgKiBAcGFyYW0geGhyUHJvdmlkZXIgPGNvZGU+WE1MSHR0cFJlcXVlc3Q8L2NvZGU+IHByb3ZpZGVyLCBlLmcuIGZvciBub2RlIDxjb2RlPnJlcXVpcmUoJ3hocicpPC9jb2RlPi5cbiAgICovXG4gIHN0YXRpYyBzZXROZXR3b3JrUHJvdmlkZXJzKHdzUHJvdmlkZXIsIHhoclByb3ZpZGVyKSB7XG4gICAgV2ViU29ja2V0UHJvdmlkZXIgPSB3c1Byb3ZpZGVyO1xuICAgIFhIUlByb3ZpZGVyID0geGhyUHJvdmlkZXI7XG5cbiAgICBDb25uZWN0aW9uLnNldE5ldHdvcmtQcm92aWRlcnMoV2ViU29ja2V0UHJvdmlkZXIsIFhIUlByb3ZpZGVyKTtcbiAgICBMYXJnZUZpbGVIZWxwZXIuc2V0TmV0d29ya1Byb3ZpZGVyKFhIUlByb3ZpZGVyKTtcbiAgfVxuICAvKipcbiAgICogVG8gdXNlIFRpbm9kZSBpbiBhIG5vbiBicm93c2VyIGNvbnRleHQsIHN1cHBseSA8Y29kZT5pbmRleGVkREI8L2NvZGU+IHByb3ZpZGVyLlxuICAgKiBAc3RhdGljXG4gICAqXG4gICAqIEBwYXJhbSBpZGJQcm92aWRlciA8Y29kZT5pbmRleGVkREI8L2NvZGU+IHByb3ZpZGVyLCBlLmcuIGZvciBub2RlSlMgLCA8Y29kZT5yZXF1aXJlKCdmYWtlLWluZGV4ZWRkYicpPC9jb2RlPi5cbiAgICovXG4gIHN0YXRpYyBzZXREYXRhYmFzZVByb3ZpZGVyKGlkYlByb3ZpZGVyKSB7XG4gICAgSW5kZXhlZERCUHJvdmlkZXIgPSBpZGJQcm92aWRlcjtcblxuICAgIERCQ2FjaGUuc2V0RGF0YWJhc2VQcm92aWRlcihJbmRleGVkREJQcm92aWRlcik7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY3VycmVudCBuYW1lIGFuZCB2ZXJzaW9uIG9mIHRoaXMgVGlub2RlIGxpYnJhcnkuXG4gICAqIEBzdGF0aWNcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gdGhlIG5hbWUgb2YgdGhlIGxpYnJhcnkgYW5kIGl0J3MgdmVyc2lvbi5cbiAgICovXG4gIHN0YXRpYyBnZXRMaWJyYXJ5KCkge1xuICAgIHJldHVybiBDb25zdC5MSUJSQVJZO1xuICB9XG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gc3RyaW5nIHJlcHJlc2VudHMgPGNvZGU+TlVMTDwvY29kZT4gdmFsdWUgYXMgZGVmaW5lZCBieSBUaW5vZGUgKDxjb2RlPidcXHUyNDIxJzwvY29kZT4pLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gc3RyaW5nIHRvIGNoZWNrIGZvciA8Y29kZT5OVUxMPC9jb2RlPiB2YWx1ZS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IDxjb2RlPnRydWU8L2NvZGU+IGlmIHN0cmluZyByZXByZXNlbnRzIDxjb2RlPk5VTEw8L2NvZGU+IHZhbHVlLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxuICAgKi9cbiAgc3RhdGljIGlzTnVsbFZhbHVlKHN0cikge1xuICAgIHJldHVybiBzdHIgPT09IENvbnN0LkRFTF9DSEFSO1xuICB9XG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gVVJMIHN0cmluZyBpcyBhIHJlbGF0aXZlIFVSTC5cbiAgICogQ2hlY2sgZm9yIGNhc2VzIGxpa2U6XG4gICAqICA8Y29kZT4naHR0cDovL2V4YW1wbGUuY29tJzwvY29kZT5cbiAgICogIDxjb2RlPicgaHR0cDovL2V4YW1wbGUuY29tJzwvY29kZT5cbiAgICogIDxjb2RlPicvL2V4YW1wbGUuY29tLyc8L2NvZGU+XG4gICAqICA8Y29kZT4naHR0cDpleGFtcGxlLmNvbSc8L2NvZGU+XG4gICAqICA8Y29kZT4naHR0cDovZXhhbXBsZS5jb20nPC9jb2RlPlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIC0gVVJMIHN0cmluZyB0byBjaGVjay5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBVUkwgaXMgcmVsYXRpdmUsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuXG4gICAqL1xuICBzdGF0aWMgaXNSZWxhdGl2ZVVSTCh1cmwpIHtcbiAgICByZXR1cm4gIS9eXFxzKihbYS16XVthLXowLTkrLi1dKjp8XFwvXFwvKS9pbS50ZXN0KHVybCk7XG4gIH1cblxuICAvLyBJbnN0YW5jZSBtZXRob2RzLlxuXG4gIC8vIEdlbmVyYXRlcyB1bmlxdWUgbWVzc2FnZSBJRHNcbiAgZ2V0TmV4dFVuaXF1ZUlkKCkge1xuICAgIHJldHVybiAodGhpcy5fbWVzc2FnZUlkICE9IDApID8gJycgKyB0aGlzLl9tZXNzYWdlSWQrKyA6IHVuZGVmaW5lZDtcbiAgfTtcblxuICAvKipcbiAgICogQ29ubmVjdCB0byB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaG9zdF8gLSBuYW1lIG9mIHRoZSBob3N0IHRvIGNvbm5lY3QgdG8uXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgY29ubmVjdGlvbiBjYWxsIGNvbXBsZXRlczpcbiAgICogICAgPGNvZGU+cmVzb2x2ZSgpPC9jb2RlPiBpcyBjYWxsZWQgd2l0aG91dCBwYXJhbWV0ZXJzLCA8Y29kZT5yZWplY3QoKTwvY29kZT4gcmVjZWl2ZXMgdGhlXG4gICAqICAgIDxjb2RlPkVycm9yPC9jb2RlPiBhcyBhIHNpbmdsZSBwYXJhbWV0ZXIuXG4gICAqL1xuICBjb25uZWN0KGhvc3RfKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Nvbm5lY3Rpb24uY29ubmVjdChob3N0Xyk7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byByZWNvbm5lY3QgdG8gdGhlIHNlcnZlciBpbW1lZGlhdGVseS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZvcmNlIC0gcmVjb25uZWN0IGV2ZW4gaWYgdGhlcmUgaXMgYSBjb25uZWN0aW9uIGFscmVhZHkuXG4gICAqL1xuICByZWNvbm5lY3QoZm9yY2UpIHtcbiAgICB0aGlzLl9jb25uZWN0aW9uLnJlY29ubmVjdChmb3JjZSk7XG4gIH1cblxuICAvKipcbiAgICogRGlzY29ubmVjdCBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqL1xuICBkaXNjb25uZWN0KCkge1xuICAgIHRoaXMuX2Nvbm5lY3Rpb24uZGlzY29ubmVjdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIHBlcnNpc3RlbnQgY2FjaGU6IHJlbW92ZSBJbmRleGVkREIuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IFByb21pc2UgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgb3BlcmF0aW9uIGlzIGNvbXBsZXRlZC5cbiAgICovXG4gIGNsZWFyU3RvcmFnZSgpIHtcbiAgICBpZiAodGhpcy5fZGIuaXNSZWFkeSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZGIuZGVsZXRlRGF0YWJhc2UoKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgcGVyc2lzdGVudCBjYWNoZTogY3JlYXRlIEluZGV4ZWREQiBjYWNoZS5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gUHJvbWlzZSByZXNvbHZlZC9yZWplY3RlZCB3aGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGVkLlxuICAgKi9cbiAgaW5pdFN0b3JhZ2UoKSB7XG4gICAgaWYgKCF0aGlzLl9kYi5pc1JlYWR5KCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9kYi5pbml0RGF0YWJhc2UoKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgYSBuZXR3b3JrIHByb2JlIG1lc3NhZ2UgdG8gbWFrZSBzdXJlIHRoZSBjb25uZWN0aW9uIGlzIGFsaXZlLlxuICAgKi9cbiAgbmV0d29ya1Byb2JlKCkge1xuICAgIHRoaXMuX2Nvbm5lY3Rpb24ucHJvYmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBmb3IgbGl2ZSBjb25uZWN0aW9uIHRvIHNlcnZlci5cbiAgICpcbiAgICogQHJldHVybnMge2Jvb2xlYW59IDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZXJlIGlzIGEgbGl2ZSBjb25uZWN0aW9uLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxuICAgKi9cbiAgaXNDb25uZWN0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Nvbm5lY3Rpb24uaXNDb25uZWN0ZWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBjb25uZWN0aW9uIGlzIGF1dGhlbnRpY2F0ZWQgKGxhc3QgbG9naW4gd2FzIHN1Y2Nlc3NmdWwpLlxuICAgKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYXV0aGVudGljYXRlZCwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cbiAgICovXG4gIGlzQXV0aGVudGljYXRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fYXV0aGVudGljYXRlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgQVBJIGtleSBhbmQgYXV0aCB0b2tlbiB0byB0aGUgcmVsYXRpdmUgVVJMIG1ha2luZyBpdCB1c2FibGUgZm9yIGdldHRpbmcgZGF0YVxuICAgKiBmcm9tIHRoZSBzZXJ2ZXIgaW4gYSBzaW1wbGUgPGNvZGU+SFRUUCBHRVQ8L2NvZGU+IHJlcXVlc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBVUkwgLSBVUkwgdG8gd3JhcC5cbiAgICogQHJldHVybnMge3N0cmluZ30gVVJMIHdpdGggYXBwZW5kZWQgQVBJIGtleSBhbmQgdG9rZW4sIGlmIHZhbGlkIHRva2VuIGlzIHByZXNlbnQuXG4gICAqL1xuICBhdXRob3JpemVVUkwodXJsKSB7XG4gICAgaWYgKHR5cGVvZiB1cmwgIT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB1cmw7XG4gICAgfVxuXG4gICAgaWYgKFRpbm9kZS5pc1JlbGF0aXZlVVJMKHVybCkpIHtcbiAgICAgIC8vIEZha2UgYmFzZSB0byBtYWtlIHRoZSByZWxhdGl2ZSBVUkwgcGFyc2VhYmxlLlxuICAgICAgY29uc3QgYmFzZSA9ICdzY2hlbWU6Ly9ob3N0Lyc7XG4gICAgICBjb25zdCBwYXJzZWQgPSBuZXcgVVJMKHVybCwgYmFzZSk7XG4gICAgICBpZiAodGhpcy5fYXBpS2V5KSB7XG4gICAgICAgIHBhcnNlZC5zZWFyY2hQYXJhbXMuYXBwZW5kKCdhcGlrZXknLCB0aGlzLl9hcGlLZXkpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX2F1dGhUb2tlbiAmJiB0aGlzLl9hdXRoVG9rZW4udG9rZW4pIHtcbiAgICAgICAgcGFyc2VkLnNlYXJjaFBhcmFtcy5hcHBlbmQoJ2F1dGgnLCAndG9rZW4nKTtcbiAgICAgICAgcGFyc2VkLnNlYXJjaFBhcmFtcy5hcHBlbmQoJ3NlY3JldCcsIHRoaXMuX2F1dGhUb2tlbi50b2tlbik7XG4gICAgICB9XG4gICAgICAvLyBDb252ZXJ0IGJhY2sgdG8gc3RyaW5nIGFuZCBzdHJpcCBmYWtlIGJhc2UgVVJMIGV4Y2VwdCBmb3IgdGhlIHJvb3Qgc2xhc2guXG4gICAgICB1cmwgPSBwYXJzZWQudG9TdHJpbmcoKS5zdWJzdHJpbmcoYmFzZS5sZW5ndGggLSAxKTtcbiAgICB9XG4gICAgcmV0dXJuIHVybDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAdHlwZWRlZiBBY2NvdW50UGFyYW1zXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBwcm9wZXJ0eSB7RGVmQWNzPX0gZGVmYWNzIC0gRGVmYXVsdCBhY2Nlc3MgcGFyYW1ldGVycyBmb3IgdXNlcidzIDxjb2RlPm1lPC9jb2RlPiB0b3BpYy5cbiAgICogQHByb3BlcnR5IHtPYmplY3Q9fSBwdWJsaWMgLSBQdWJsaWMgYXBwbGljYXRpb24tZGVmaW5lZCBkYXRhIGV4cG9zZWQgb24gPGNvZGU+bWU8L2NvZGU+IHRvcGljLlxuICAgKiBAcHJvcGVydHkge09iamVjdD19IHByaXZhdGUgLSBQcml2YXRlIGFwcGxpY2F0aW9uLWRlZmluZWQgZGF0YSBhY2Nlc3NpYmxlIG9uIDxjb2RlPm1lPC9jb2RlPiB0b3BpYy5cbiAgICogQHByb3BlcnR5IHtPYmplY3Q9fSB0cnVzdGVkIC0gVHJ1c3RlZCB1c2VyIGRhdGEgd2hpY2ggY2FuIGJlIHNldCBieSBhIHJvb3QgdXNlciBvbmx5LlxuICAgKiBAcHJvcGVydHkge0FycmF5LjxzdHJpbmc+fSB0YWdzIC0gYXJyYXkgb2Ygc3RyaW5nIHRhZ3MgZm9yIHVzZXIgZGlzY292ZXJ5LlxuICAgKiBAcHJvcGVydHkge3N0cmluZz19IHRva2VuIC0gYXV0aGVudGljYXRpb24gdG9rZW4gdG8gdXNlLlxuICAgKiBAcHJvcGVydHkge0FycmF5LjxzdHJpbmc+PX0gYXR0YWNobWVudHMgLSBBcnJheSBvZiByZWZlcmVuY2VzIHRvIG91dCBvZiBiYW5kIGF0dGFjaG1lbnRzIHVzZWQgaW4gYWNjb3VudCBkZXNjcmlwdGlvbi5cbiAgICovXG4gIC8qKlxuICAgKiBAdHlwZWRlZiBEZWZBY3NcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQHByb3BlcnR5IHtzdHJpbmc9fSBhdXRoIC0gQWNjZXNzIG1vZGUgZm9yIDxjb2RlPm1lPC9jb2RlPiBmb3IgYXV0aGVudGljYXRlZCB1c2Vycy5cbiAgICogQHByb3BlcnR5IHtzdHJpbmc9fSBhbm9uIC0gQWNjZXNzIG1vZGUgZm9yIDxjb2RlPm1lPC9jb2RlPiBmb3IgYW5vbnltb3VzIHVzZXJzLlxuICAgKi9cblxuICAvKipcbiAgICogQ3JlYXRlIG9yIHVwZGF0ZSBhbiBhY2NvdW50LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdWlkIC0gVXNlciBpZCB0byB1cGRhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNjaGVtZSAtIEF1dGhlbnRpY2F0aW9uIHNjaGVtZTsgPGNvZGU+XCJiYXNpY1wiPC9jb2RlPiBhbmQgPGNvZGU+XCJhbm9ueW1vdXNcIjwvY29kZT4gYXJlIHRoZSBjdXJyZW50bHkgc3VwcG9ydGVkIHNjaGVtZXMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzZWNyZXQgLSBBdXRoZW50aWNhdGlvbiBzZWNyZXQsIGFzc3VtZWQgdG8gYmUgYWxyZWFkeSBiYXNlNjQgZW5jb2RlZC5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gbG9naW4gLSBVc2UgbmV3IGFjY291bnQgdG8gYXV0aGVudGljYXRlIGN1cnJlbnQgc2Vzc2lvblxuICAgKiBAcGFyYW0ge0FjY291bnRQYXJhbXM9fSBwYXJhbXMgLSBVc2VyIGRhdGEgdG8gcGFzcyB0byB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB3aGljaCB3aWxsIGJlIHJlc29sdmVkL3JlamVjdGVkIHdoZW4gc2VydmVyIHJlcGx5IGlzIHJlY2VpdmVkLlxuICAgKi9cbiAgYWNjb3VudCh1aWQsIHNjaGVtZSwgc2VjcmV0LCBsb2dpbiwgcGFyYW1zKSB7XG4gICAgY29uc3QgcGt0ID0gdGhpcy4jaW5pdFBhY2tldCgnYWNjJyk7XG4gICAgcGt0LmFjYy51c2VyID0gdWlkO1xuICAgIHBrdC5hY2Muc2NoZW1lID0gc2NoZW1lO1xuICAgIHBrdC5hY2Muc2VjcmV0ID0gc2VjcmV0O1xuICAgIC8vIExvZyBpbiB0byB0aGUgbmV3IGFjY291bnQgdXNpbmcgc2VsZWN0ZWQgc2NoZW1lXG4gICAgcGt0LmFjYy5sb2dpbiA9IGxvZ2luO1xuXG4gICAgaWYgKHBhcmFtcykge1xuICAgICAgcGt0LmFjYy5kZXNjLmRlZmFjcyA9IHBhcmFtcy5kZWZhY3M7XG4gICAgICBwa3QuYWNjLmRlc2MucHVibGljID0gcGFyYW1zLnB1YmxpYztcbiAgICAgIHBrdC5hY2MuZGVzYy5wcml2YXRlID0gcGFyYW1zLnByaXZhdGU7XG4gICAgICBwa3QuYWNjLmRlc2MudHJ1c3RlZCA9IHBhcmFtcy50cnVzdGVkO1xuXG4gICAgICBwa3QuYWNjLnRhZ3MgPSBwYXJhbXMudGFncztcbiAgICAgIHBrdC5hY2MuY3JlZCA9IHBhcmFtcy5jcmVkO1xuXG4gICAgICBwa3QuYWNjLnRva2VuID0gcGFyYW1zLnRva2VuO1xuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShwYXJhbXMuYXR0YWNobWVudHMpICYmIHBhcmFtcy5hdHRhY2htZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHBrdC5leHRyYSA9IHtcbiAgICAgICAgICBhdHRhY2htZW50czogcGFyYW1zLmF0dGFjaG1lbnRzLmZpbHRlcihyZWYgPT4gVGlub2RlLmlzUmVsYXRpdmVVUkwocmVmKSlcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy4jc2VuZChwa3QsIHBrdC5hY2MuaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyB1c2VyLiBXcmFwcGVyIGZvciB7QGxpbmsgVGlub2RlI2FjY291bnR9LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2NoZW1lIC0gQXV0aGVudGljYXRpb24gc2NoZW1lOyA8Y29kZT5cImJhc2ljXCI8L2NvZGU+IGlzIHRoZSBvbmx5IGN1cnJlbnRseSBzdXBwb3J0ZWQgc2NoZW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2VjcmV0IC0gQXV0aGVudGljYXRpb24uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxvZ2luIC0gVXNlIG5ldyBhY2NvdW50IHRvIGF1dGhlbnRpY2F0ZSBjdXJyZW50IHNlc3Npb25cbiAgICogQHBhcmFtIHtBY2NvdW50UGFyYW1zPX0gcGFyYW1zIC0gVXNlciBkYXRhIHRvIHBhc3MgdG8gdGhlIHNlcnZlci5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2Ugd2hpY2ggd2lsbCBiZSByZXNvbHZlZC9yZWplY3RlZCB3aGVuIHNlcnZlciByZXBseSBpcyByZWNlaXZlZC5cbiAgICovXG4gIGNyZWF0ZUFjY291bnQoc2NoZW1lLCBzZWNyZXQsIGxvZ2luLCBwYXJhbXMpIHtcbiAgICBsZXQgcHJvbWlzZSA9IHRoaXMuYWNjb3VudChDb25zdC5VU0VSX05FVywgc2NoZW1lLCBzZWNyZXQsIGxvZ2luLCBwYXJhbXMpO1xuICAgIGlmIChsb2dpbikge1xuICAgICAgcHJvbWlzZSA9IHByb21pc2UudGhlbigoY3RybCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy4jbG9naW5TdWNjZXNzZnVsKGN0cmwpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSB1c2VyIHdpdGggPGNvZGU+J2Jhc2ljJzwvY29kZT4gYXV0aGVudGljYXRpb24gc2NoZW1lIGFuZCBpbW1lZGlhdGVseVxuICAgKiB1c2UgaXQgZm9yIGF1dGhlbnRpY2F0aW9uLiBXcmFwcGVyIGZvciB7QGxpbmsgVGlub2RlI2FjY291bnR9LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcm5hbWUgLSBMb2dpbiB0byB1c2UgZm9yIHRoZSBuZXcgYWNjb3VudC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIC0gVXNlcidzIHBhc3N3b3JkLlxuICAgKiBAcGFyYW0ge0FjY291bnRQYXJhbXM9fSBwYXJhbXMgLSBVc2VyIGRhdGEgdG8gcGFzcyB0byB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB3aGljaCB3aWxsIGJlIHJlc29sdmVkL3JlamVjdGVkIHdoZW4gc2VydmVyIHJlcGx5IGlzIHJlY2VpdmVkLlxuICAgKi9cbiAgY3JlYXRlQWNjb3VudEJhc2ljKHVzZXJuYW1lLCBwYXNzd29yZCwgcGFyYW1zKSB7XG4gICAgLy8gTWFrZSBzdXJlIHdlIGFyZSBub3QgdXNpbmcgJ251bGwnIG9yICd1bmRlZmluZWQnO1xuICAgIHVzZXJuYW1lID0gdXNlcm5hbWUgfHwgJyc7XG4gICAgcGFzc3dvcmQgPSBwYXNzd29yZCB8fCAnJztcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVBY2NvdW50KCdiYXNpYycsXG4gICAgICBiNjRFbmNvZGVVbmljb2RlKHVzZXJuYW1lICsgJzonICsgcGFzc3dvcmQpLCB0cnVlLCBwYXJhbXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB1c2VyJ3MgY3JlZGVudGlhbHMgZm9yIDxjb2RlPidiYXNpYyc8L2NvZGU+IGF1dGhlbnRpY2F0aW9uIHNjaGVtZS4gV3JhcHBlciBmb3Ige0BsaW5rIFRpbm9kZSNhY2NvdW50fS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVpZCAtIFVzZXIgSUQgdG8gdXBkYXRlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcm5hbWUgLSBMb2dpbiB0byB1c2UgZm9yIHRoZSBuZXcgYWNjb3VudC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIC0gVXNlcidzIHBhc3N3b3JkLlxuICAgKiBAcGFyYW0ge0FjY291bnRQYXJhbXM9fSBwYXJhbXMgLSBkYXRhIHRvIHBhc3MgdG8gdGhlIHNlcnZlci5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2Ugd2hpY2ggd2lsbCBiZSByZXNvbHZlZC9yZWplY3RlZCB3aGVuIHNlcnZlciByZXBseSBpcyByZWNlaXZlZC5cbiAgICovXG4gIHVwZGF0ZUFjY291bnRCYXNpYyh1aWQsIHVzZXJuYW1lLCBwYXNzd29yZCwgcGFyYW1zKSB7XG4gICAgLy8gTWFrZSBzdXJlIHdlIGFyZSBub3QgdXNpbmcgJ251bGwnIG9yICd1bmRlZmluZWQnO1xuICAgIHVzZXJuYW1lID0gdXNlcm5hbWUgfHwgJyc7XG4gICAgcGFzc3dvcmQgPSBwYXNzd29yZCB8fCAnJztcbiAgICByZXR1cm4gdGhpcy5hY2NvdW50KHVpZCwgJ2Jhc2ljJyxcbiAgICAgIGI2NEVuY29kZVVuaWNvZGUodXNlcm5hbWUgKyAnOicgKyBwYXNzd29yZCksIGZhbHNlLCBwYXJhbXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgaGFuZHNoYWtlIHRvIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHdoaWNoIHdpbGwgYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiBzZXJ2ZXIgcmVwbHkgaXMgcmVjZWl2ZWQuXG4gICAqL1xuICBoZWxsbygpIHtcbiAgICBjb25zdCBwa3QgPSB0aGlzLiNpbml0UGFja2V0KCdoaScpO1xuXG4gICAgcmV0dXJuIHRoaXMuI3NlbmQocGt0LCBwa3QuaGkuaWQpXG4gICAgICAudGhlbigoY3RybCkgPT4ge1xuICAgICAgICAvLyBSZXNldCBiYWNrb2ZmIGNvdW50ZXIgb24gc3VjY2Vzc2Z1bCBjb25uZWN0aW9uLlxuICAgICAgICB0aGlzLl9jb25uZWN0aW9uLmJhY2tvZmZSZXNldCgpO1xuXG4gICAgICAgIC8vIFNlcnZlciByZXNwb25zZSBjb250YWlucyBzZXJ2ZXIgcHJvdG9jb2wgdmVyc2lvbiwgYnVpbGQsIGNvbnN0cmFpbnRzLFxuICAgICAgICAvLyBzZXNzaW9uIElEIGZvciBsb25nIHBvbGxpbmcuIFNhdmUgdGhlbS5cbiAgICAgICAgaWYgKGN0cmwucGFyYW1zKSB7XG4gICAgICAgICAgdGhpcy5fc2VydmVySW5mbyA9IGN0cmwucGFyYW1zO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub25Db25uZWN0KSB7XG4gICAgICAgICAgdGhpcy5vbkNvbm5lY3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjdHJsO1xuICAgICAgfSkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICB0aGlzLl9jb25uZWN0aW9uLnJlY29ubmVjdCh0cnVlKTtcblxuICAgICAgICBpZiAodGhpcy5vbkRpc2Nvbm5lY3QpIHtcbiAgICAgICAgICB0aGlzLm9uRGlzY29ubmVjdChlcnIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgb3IgcmVmcmVzaCB0aGUgcHVzaCBub3RpZmljYXRpb25zL2RldmljZSB0b2tlbi4gSWYgdGhlIGNsaWVudCBpcyBjb25uZWN0ZWQsXG4gICAqIHRoZSBkZXZpY2VUb2tlbiBjYW4gYmUgc2VudCB0byB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZHQgLSB0b2tlbiBvYnRhaW5lZCBmcm9tIHRoZSBwcm92aWRlciBvciA8Y29kZT5mYWxzZTwvY29kZT4sXG4gICAqICAgIDxjb2RlPm51bGw8L2NvZGU+IG9yIDxjb2RlPnVuZGVmaW5lZDwvY29kZT4gdG8gY2xlYXIgdGhlIHRva2VuLlxuICAgKlxuICAgKiBAcmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhdHRlbXB0IHdhcyBtYWRlIHRvIHNlbmQgdGhlIHVwZGF0ZSB0byB0aGUgc2VydmVyLlxuICAgKi9cbiAgc2V0RGV2aWNlVG9rZW4oZHQpIHtcbiAgICBsZXQgc2VudCA9IGZhbHNlO1xuICAgIC8vIENvbnZlcnQgYW55IGZhbHNpc2ggdmFsdWUgdG8gbnVsbC5cbiAgICBkdCA9IGR0IHx8IG51bGw7XG4gICAgaWYgKGR0ICE9IHRoaXMuX2RldmljZVRva2VuKSB7XG4gICAgICB0aGlzLl9kZXZpY2VUb2tlbiA9IGR0O1xuICAgICAgaWYgKHRoaXMuaXNDb25uZWN0ZWQoKSAmJiB0aGlzLmlzQXV0aGVudGljYXRlZCgpKSB7XG4gICAgICAgIHRoaXMuI3NlbmQoe1xuICAgICAgICAgICdoaSc6IHtcbiAgICAgICAgICAgICdkZXYnOiBkdCB8fCBUaW5vZGUuREVMX0NIQVJcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBzZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNlbnQ7XG4gIH1cblxuICAvKipcbiAgICogQHR5cGVkZWYgQ3JlZGVudGlhbFxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAcHJvcGVydHkge3N0cmluZ30gbWV0aCAtIHZhbGlkYXRpb24gbWV0aG9kLlxuICAgKiBAcHJvcGVydHkge3N0cmluZ30gdmFsIC0gdmFsdWUgdG8gdmFsaWRhdGUgKGUuZy4gZW1haWwgb3IgcGhvbmUgbnVtYmVyKS5cbiAgICogQHByb3BlcnR5IHtzdHJpbmd9IHJlc3AgLSB2YWxpZGF0aW9uIHJlc3BvbnNlLlxuICAgKiBAcHJvcGVydHkge09iamVjdH0gcGFyYW1zIC0gdmFsaWRhdGlvbiBwYXJhbWV0ZXJzLlxuICAgKi9cbiAgLyoqXG4gICAqIEF1dGhlbnRpY2F0ZSBjdXJyZW50IHNlc3Npb24uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzY2hlbWUgLSBBdXRoZW50aWNhdGlvbiBzY2hlbWU7IDxjb2RlPlwiYmFzaWNcIjwvY29kZT4gaXMgdGhlIG9ubHkgY3VycmVudGx5IHN1cHBvcnRlZCBzY2hlbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzZWNyZXQgLSBBdXRoZW50aWNhdGlvbiBzZWNyZXQsIGFzc3VtZWQgdG8gYmUgYWxyZWFkeSBiYXNlNjQgZW5jb2RlZC5cbiAgICogQHBhcmFtIHtDcmVkZW50aWFsPX0gY3JlZCAtIGNyZWRlbnRpYWwgY29uZmlybWF0aW9uLCBpZiByZXF1aXJlZC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2Ugd2hpY2ggd2lsbCBiZSByZXNvbHZlZC9yZWplY3RlZCB3aGVuIHNlcnZlciByZXBseSBpcyByZWNlaXZlZC5cbiAgICovXG4gIGxvZ2luKHNjaGVtZSwgc2VjcmV0LCBjcmVkKSB7XG4gICAgY29uc3QgcGt0ID0gdGhpcy4jaW5pdFBhY2tldCgnbG9naW4nKTtcbiAgICBwa3QubG9naW4uc2NoZW1lID0gc2NoZW1lO1xuICAgIHBrdC5sb2dpbi5zZWNyZXQgPSBzZWNyZXQ7XG4gICAgcGt0LmxvZ2luLmNyZWQgPSBjcmVkO1xuXG4gICAgcmV0dXJuIHRoaXMuI3NlbmQocGt0LCBwa3QubG9naW4uaWQpXG4gICAgICAudGhlbigoY3RybCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy4jbG9naW5TdWNjZXNzZnVsKGN0cmwpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogV3JhcHBlciBmb3Ige0BsaW5rIFRpbm9kZSNsb2dpbn0gd2l0aCBiYXNpYyBhdXRoZW50aWNhdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdW5hbWUgLSBVc2VyIG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCAgLSBQYXNzd29yZC5cbiAgICogQHBhcmFtIHtDcmVkZW50aWFsPX0gY3JlZCAtIGNyZWRlbnRpYWwgY29uZmlybWF0aW9uLCBpZiByZXF1aXJlZC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2Ugd2hpY2ggd2lsbCBiZSByZXNvbHZlZC9yZWplY3RlZCBvbiByZWNlaXZpbmcgc2VydmVyIHJlcGx5LlxuICAgKi9cbiAgbG9naW5CYXNpYyh1bmFtZSwgcGFzc3dvcmQsIGNyZWQpIHtcbiAgICByZXR1cm4gdGhpcy5sb2dpbignYmFzaWMnLCBiNjRFbmNvZGVVbmljb2RlKHVuYW1lICsgJzonICsgcGFzc3dvcmQpLCBjcmVkKVxuICAgICAgLnRoZW4oKGN0cmwpID0+IHtcbiAgICAgICAgdGhpcy5fbG9naW4gPSB1bmFtZTtcbiAgICAgICAgcmV0dXJuIGN0cmw7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXcmFwcGVyIGZvciB7QGxpbmsgVGlub2RlI2xvZ2lufSB3aXRoIHRva2VuIGF1dGhlbnRpY2F0aW9uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlbiAtIFRva2VuIHJlY2VpdmVkIGluIHJlc3BvbnNlIHRvIGVhcmxpZXIgbG9naW4uXG4gICAqIEBwYXJhbSB7Q3JlZGVudGlhbD19IGNyZWQgLSBjcmVkZW50aWFsIGNvbmZpcm1hdGlvbiwgaWYgcmVxdWlyZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHdoaWNoIHdpbGwgYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gcmVjZWl2aW5nIHNlcnZlciByZXBseS5cbiAgICovXG4gIGxvZ2luVG9rZW4odG9rZW4sIGNyZWQpIHtcbiAgICByZXR1cm4gdGhpcy5sb2dpbigndG9rZW4nLCB0b2tlbiwgY3JlZCk7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBhIHJlcXVlc3QgZm9yIHJlc2V0dGluZyBhbiBhdXRoZW50aWNhdGlvbiBzZWNyZXQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzY2hlbWUgLSBhdXRoZW50aWNhdGlvbiBzY2hlbWUgdG8gcmVzZXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2QgLSBtZXRob2QgdG8gdXNlIGZvciByZXNldHRpbmcgdGhlIHNlY3JldCwgc3VjaCBhcyBcImVtYWlsXCIgb3IgXCJ0ZWxcIi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gdmFsdWUgb2YgdGhlIGNyZWRlbnRpYWwgdG8gdXNlLCBhIHNwZWNpZmljIGVtYWlsIGFkZHJlc3Mgb3IgYSBwaG9uZSBudW1iZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHdoaWNoIHdpbGwgYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gcmVjZWl2aW5nIHRoZSBzZXJ2ZXIgcmVwbHkuXG4gICAqL1xuICByZXF1ZXN0UmVzZXRBdXRoU2VjcmV0KHNjaGVtZSwgbWV0aG9kLCB2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLmxvZ2luKCdyZXNldCcsIGI2NEVuY29kZVVuaWNvZGUoc2NoZW1lICsgJzonICsgbWV0aG9kICsgJzonICsgdmFsdWUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAdHlwZWRlZiBBdXRoVG9rZW5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQHByb3BlcnR5IHtzdHJpbmd9IHRva2VuIC0gVG9rZW4gdmFsdWUuXG4gICAqIEBwcm9wZXJ0eSB7RGF0ZX0gZXhwaXJlcyAtIFRva2VuIGV4cGlyYXRpb24gdGltZS5cbiAgICovXG4gIC8qKlxuICAgKiBHZXQgc3RvcmVkIGF1dGhlbnRpY2F0aW9uIHRva2VuLlxuICAgKlxuICAgKiBAcmV0dXJucyB7QXV0aFRva2VufSBhdXRoZW50aWNhdGlvbiB0b2tlbi5cbiAgICovXG4gIGdldEF1dGhUb2tlbigpIHtcbiAgICBpZiAodGhpcy5fYXV0aFRva2VuICYmICh0aGlzLl9hdXRoVG9rZW4uZXhwaXJlcy5nZXRUaW1lKCkgPiBEYXRlLm5vdygpKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2F1dGhUb2tlbjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fYXV0aFRva2VuID0gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQXBwbGljYXRpb24gbWF5IHByb3ZpZGUgYSBzYXZlZCBhdXRoZW50aWNhdGlvbiB0b2tlbi5cbiAgICpcbiAgICogQHBhcmFtIHtBdXRoVG9rZW59IHRva2VuIC0gYXV0aGVudGljYXRpb24gdG9rZW4uXG4gICAqL1xuICBzZXRBdXRoVG9rZW4odG9rZW4pIHtcbiAgICB0aGlzLl9hdXRoVG9rZW4gPSB0b2tlbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAdHlwZWRlZiBTZXRQYXJhbXNcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQHByb3BlcnR5IHtTZXREZXNjPX0gZGVzYyAtIFRvcGljIGluaXRpYWxpemF0aW9uIHBhcmFtZXRlcnMgd2hlbiBjcmVhdGluZyBhIG5ldyB0b3BpYyBvciBhIG5ldyBzdWJzY3JpcHRpb24uXG4gICAqIEBwcm9wZXJ0eSB7U2V0U3ViPX0gc3ViIC0gU3Vic2NyaXB0aW9uIGluaXRpYWxpemF0aW9uIHBhcmFtZXRlcnMuXG4gICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz49fSBhdHRhY2htZW50cyAtIFVSTHMgb2Ygb3V0IG9mIGJhbmQgYXR0YWNobWVudHMgdXNlZCBpbiBwYXJhbWV0ZXJzLlxuICAgKi9cbiAgLyoqXG4gICAqIEB0eXBlZGVmIFNldERlc2NcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQHByb3BlcnR5IHtEZWZBY3M9fSBkZWZhY3MgLSBEZWZhdWx0IGFjY2VzcyBtb2RlLlxuICAgKiBAcHJvcGVydHkge09iamVjdD19IHB1YmxpYyAtIEZyZWUtZm9ybSB0b3BpYyBkZXNjcmlwdGlvbiwgcHVibGljYWxseSBhY2Nlc3NpYmxlLlxuICAgKiBAcHJvcGVydHkge09iamVjdD19IHByaXZhdGUgLSBGcmVlLWZvcm0gdG9waWMgZGVzY3JpcHRpb24gYWNjZXNzaWJsZSBvbmx5IHRvIHRoZSBvd25lci5cbiAgICogQHByb3BlcnR5IHtPYmplY3Q9fSB0cnVzdGVkIC0gVHJ1c3RlZCB1c2VyIGRhdGEgd2hpY2ggY2FuIGJlIHNldCBieSBhIHJvb3QgdXNlciBvbmx5LlxuICAgKi9cbiAgLyoqXG4gICAqIEB0eXBlZGVmIFNldFN1YlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAcHJvcGVydHkge3N0cmluZz19IHVzZXIgLSBVSUQgb2YgdGhlIHVzZXIgYWZmZWN0ZWQgYnkgdGhlIHJlcXVlc3QuIERlZmF1bHQgKGVtcHR5KSAtIGN1cnJlbnQgdXNlci5cbiAgICogQHByb3BlcnR5IHtzdHJpbmc9fSBtb2RlIC0gVXNlciBhY2Nlc3MgbW9kZSwgZWl0aGVyIHJlcXVlc3RlZCBvciBhc3NpZ25lZCBkZXBlbmRlbnQgb24gY29udGV4dC5cbiAgICovXG4gIC8qKlxuICAgKiBTZW5kIGEgdG9waWMgc3Vic2NyaXB0aW9uIHJlcXVlc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpYyAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIHN1YnNjcmliZSB0by5cbiAgICogQHBhcmFtIHtHZXRRdWVyeT19IGdldFBhcmFtcyAtIE9wdGlvbmFsIHN1YnNjcmlwdGlvbiBtZXRhZGF0YSBxdWVyeVxuICAgKiBAcGFyYW0ge1NldFBhcmFtcz19IHNldFBhcmFtcyAtIE9wdGlvbmFsIGluaXRpYWxpemF0aW9uIHBhcmFtZXRlcnNcbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2Ugd2hpY2ggd2lsbCBiZSByZXNvbHZlZC9yZWplY3RlZCBvbiByZWNlaXZpbmcgc2VydmVyIHJlcGx5LlxuICAgKi9cbiAgc3Vic2NyaWJlKHRvcGljTmFtZSwgZ2V0UGFyYW1zLCBzZXRQYXJhbXMpIHtcbiAgICBjb25zdCBwa3QgPSB0aGlzLiNpbml0UGFja2V0KCdzdWInLCB0b3BpY05hbWUpXG4gICAgaWYgKCF0b3BpY05hbWUpIHtcbiAgICAgIHRvcGljTmFtZSA9IENvbnN0LlRPUElDX05FVztcbiAgICB9XG5cbiAgICBwa3Quc3ViLmdldCA9IGdldFBhcmFtcztcblxuICAgIGlmIChzZXRQYXJhbXMpIHtcbiAgICAgIGlmIChzZXRQYXJhbXMuc3ViKSB7XG4gICAgICAgIHBrdC5zdWIuc2V0LnN1YiA9IHNldFBhcmFtcy5zdWI7XG4gICAgICB9XG5cbiAgICAgIGlmIChzZXRQYXJhbXMuZGVzYykge1xuICAgICAgICBjb25zdCBkZXNjID0gc2V0UGFyYW1zLmRlc2M7XG4gICAgICAgIGlmIChUaW5vZGUuaXNOZXdHcm91cFRvcGljTmFtZSh0b3BpY05hbWUpKSB7XG4gICAgICAgICAgLy8gRnVsbCBzZXQuZGVzYyBwYXJhbXMgYXJlIHVzZWQgZm9yIG5ldyB0b3BpY3Mgb25seVxuICAgICAgICAgIHBrdC5zdWIuc2V0LmRlc2MgPSBkZXNjO1xuICAgICAgICB9IGVsc2UgaWYgKFRpbm9kZS5pc1AyUFRvcGljTmFtZSh0b3BpY05hbWUpICYmIGRlc2MuZGVmYWNzKSB7XG4gICAgICAgICAgLy8gVXNlIG9wdGlvbmFsIGRlZmF1bHQgcGVybWlzc2lvbnMgb25seS5cbiAgICAgICAgICBwa3Quc3ViLnNldC5kZXNjID0ge1xuICAgICAgICAgICAgZGVmYWNzOiBkZXNjLmRlZmFjc1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU2VlIGlmIGV4dGVybmFsIG9iamVjdHMgd2VyZSB1c2VkIGluIHRvcGljIGRlc2NyaXB0aW9uLlxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc2V0UGFyYW1zLmF0dGFjaG1lbnRzKSAmJiBzZXRQYXJhbXMuYXR0YWNobWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICBwa3QuZXh0cmEgPSB7XG4gICAgICAgICAgYXR0YWNobWVudHM6IHNldFBhcmFtcy5hdHRhY2htZW50cy5maWx0ZXIocmVmID0+IFRpbm9kZS5pc1JlbGF0aXZlVVJMKHJlZikpXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGlmIChzZXRQYXJhbXMudGFncykge1xuICAgICAgICBwa3Quc3ViLnNldC50YWdzID0gc2V0UGFyYW1zLnRhZ3M7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLiNzZW5kKHBrdCwgcGt0LnN1Yi5pZCk7XG4gIH1cblxuICAvKipcbiAgICogRGV0YWNoIGFuZCBvcHRpb25hbGx5IHVuc3Vic2NyaWJlIGZyb20gdGhlIHRvcGljXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpYyAtIFRvcGljIHRvIGRldGFjaCBmcm9tLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHVuc3ViIC0gSWYgPGNvZGU+dHJ1ZTwvY29kZT4sIGRldGFjaCBhbmQgdW5zdWJzY3JpYmUsIG90aGVyd2lzZSBqdXN0IGRldGFjaC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2Ugd2hpY2ggd2lsbCBiZSByZXNvbHZlZC9yZWplY3RlZCBvbiByZWNlaXZpbmcgc2VydmVyIHJlcGx5LlxuICAgKi9cbiAgbGVhdmUodG9waWMsIHVuc3ViKSB7XG4gICAgY29uc3QgcGt0ID0gdGhpcy4jaW5pdFBhY2tldCgnbGVhdmUnLCB0b3BpYyk7XG4gICAgcGt0LmxlYXZlLnVuc3ViID0gdW5zdWI7XG5cbiAgICByZXR1cm4gdGhpcy4jc2VuZChwa3QsIHBrdC5sZWF2ZS5pZCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIG1lc3NhZ2UgZHJhZnQgd2l0aG91dCBzZW5kaW5nIGl0IHRvIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpYyAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIHB1Ymxpc2ggdG8uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZW50IC0gUGF5bG9hZCB0byBwdWJsaXNoLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0VjaG8gLSBJZiA8Y29kZT50cnVlPC9jb2RlPiwgdGVsbCB0aGUgc2VydmVyIG5vdCB0byBlY2hvIHRoZSBtZXNzYWdlIHRvIHRoZSBvcmlnaW5hbCBzZXNzaW9uLlxuICAgKlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBuZXcgbWVzc2FnZSB3aGljaCBjYW4gYmUgc2VudCB0byB0aGUgc2VydmVyIG9yIG90aGVyd2lzZSB1c2VkLlxuICAgKi9cbiAgY3JlYXRlTWVzc2FnZSh0b3BpYywgY29udGVudCwgbm9FY2hvKSB7XG4gICAgY29uc3QgcGt0ID0gdGhpcy4jaW5pdFBhY2tldCgncHViJywgdG9waWMpO1xuXG4gICAgbGV0IGRmdCA9IHR5cGVvZiBjb250ZW50ID09ICdzdHJpbmcnID8gRHJhZnR5LnBhcnNlKGNvbnRlbnQpIDogY29udGVudDtcbiAgICBpZiAoZGZ0ICYmICFEcmFmdHkuaXNQbGFpblRleHQoZGZ0KSkge1xuICAgICAgcGt0LnB1Yi5oZWFkID0ge1xuICAgICAgICBtaW1lOiBEcmFmdHkuZ2V0Q29udGVudFR5cGUoKVxuICAgICAgfTtcbiAgICAgIGNvbnRlbnQgPSBkZnQ7XG4gICAgfVxuICAgIHBrdC5wdWIubm9lY2hvID0gbm9FY2hvO1xuICAgIHBrdC5wdWIuY29udGVudCA9IGNvbnRlbnQ7XG5cbiAgICByZXR1cm4gcGt0LnB1YjtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoIHtkYXRhfSBtZXNzYWdlIHRvIHRvcGljLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWNOYW1lIC0gTmFtZSBvZiB0aGUgdG9waWMgdG8gcHVibGlzaCB0by5cbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRlbnQgLSBQYXlsb2FkIHRvIHB1Ymxpc2guXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vRWNobyAtIElmIDxjb2RlPnRydWU8L2NvZGU+LCB0ZWxsIHRoZSBzZXJ2ZXIgbm90IHRvIGVjaG8gdGhlIG1lc3NhZ2UgdG8gdGhlIG9yaWdpbmFsIHNlc3Npb24uXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHdoaWNoIHdpbGwgYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gcmVjZWl2aW5nIHNlcnZlciByZXBseS5cbiAgICovXG4gIHB1Ymxpc2godG9waWNOYW1lLCBjb250ZW50LCBub0VjaG8pIHtcbiAgICByZXR1cm4gdGhpcy5wdWJsaXNoTWVzc2FnZShcbiAgICAgIHRoaXMuY3JlYXRlTWVzc2FnZSh0b3BpY05hbWUsIGNvbnRlbnQsIG5vRWNobylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggbWVzc2FnZSB0byB0b3BpYy4gVGhlIG1lc3NhZ2Ugc2hvdWxkIGJlIGNyZWF0ZWQgYnkge0BsaW5rIFRpbm9kZSNjcmVhdGVNZXNzYWdlfS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHB1YiAtIE1lc3NhZ2UgdG8gcHVibGlzaC5cbiAgICogQHBhcmFtIHtBcnJheS48c3RyaW5nPj19IGF0dGFjaG1lbnRzIC0gYXJyYXkgb2YgVVJMcyB3aXRoIGF0dGFjaG1lbnRzLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB3aGljaCB3aWxsIGJlIHJlc29sdmVkL3JlamVjdGVkIG9uIHJlY2VpdmluZyBzZXJ2ZXIgcmVwbHkuXG4gICAqL1xuICBwdWJsaXNoTWVzc2FnZShwdWIsIGF0dGFjaG1lbnRzKSB7XG4gICAgLy8gTWFrZSBhIHNoYWxsb3cgY29weS4gTmVlZGVkIGluIG9yZGVyIHRvIGNsZWFyIGxvY2FsbHktYXNzaWduZWQgdGVtcCB2YWx1ZXM7XG4gICAgcHViID0gT2JqZWN0LmFzc2lnbih7fSwgcHViKTtcbiAgICBwdWIuc2VxID0gdW5kZWZpbmVkO1xuICAgIHB1Yi5mcm9tID0gdW5kZWZpbmVkO1xuICAgIHB1Yi50cyA9IHVuZGVmaW5lZDtcbiAgICBjb25zdCBtc2cgPSB7XG4gICAgICBwdWI6IHB1YixcbiAgICB9O1xuICAgIGlmIChhdHRhY2htZW50cykge1xuICAgICAgbXNnLmV4dHJhID0ge1xuICAgICAgICBhdHRhY2htZW50czogYXR0YWNobWVudHMuZmlsdGVyKHJlZiA9PiBUaW5vZGUuaXNSZWxhdGl2ZVVSTChyZWYpKVxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuI3NlbmQobXNnLCBwdWIuaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIE91dCBvZiBiYW5kIG5vdGlmaWNhdGlvbjogbm90aWZ5IHRvcGljIHRoYXQgYW4gZXh0ZXJuYWwgKHB1c2gpIG5vdGlmaWNhdGlvbiB3YXMgcmVjaXZlZCBieSB0aGUgY2xpZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gZGF0YSAtIG5vdGlmaWNhdGlvbiBwYXlsb2FkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YS53aGF0IC0gbm90aWZpY2F0aW9uIHR5cGUsICdtc2cnLCAncmVhZCcsICdzdWInLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YS50b3BpYyAtIG5hbWUgb2YgdGhlIHVwZGF0ZWQgdG9waWMuXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gZGF0YS5zZXEgLSBzZXEgSUQgb2YgdGhlIGFmZmVjdGVkIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gZGF0YS54ZnJvbSAtIFVJRCBvZiB0aGUgc2VuZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdD19IGRhdGEuZ2l2ZW4gLSBuZXcgc3Vic2NyaXB0aW9uICdnaXZlbicsIGUuZy4gJ0FTV1AuLi4nLlxuICAgKiBAcGFyYW0ge29iamVjdD19IGRhdGEud2FudCAtIG5ldyBzdWJzY3JpcHRpb24gJ3dhbnQnLCBlLmcuICdSV0ouLi4nLlxuICAgKi9cbiAgb29iTm90aWZpY2F0aW9uKGRhdGEpIHtcbiAgICB0aGlzLmxvZ2dlcihcIm9vYjogXCIgKyAodGhpcy5fdHJpbUxvbmdTdHJpbmdzID8gSlNPTi5zdHJpbmdpZnkoZGF0YSwganNvbkxvZ2dlckhlbHBlcikgOiBkYXRhKSk7XG5cbiAgICBzd2l0Y2ggKGRhdGEud2hhdCkge1xuICAgICAgY2FzZSAnbXNnJzpcbiAgICAgICAgaWYgKCFkYXRhLnNlcSB8fCBkYXRhLnNlcSA8IDEgfHwgIWRhdGEudG9waWMpIHtcbiAgICAgICAgICAvLyBTZXJ2ZXIgc2VudCBpbnZhbGlkIGRhdGEuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgICAgIC8vIExldCdzIGlnbm9yZSB0aGUgbWVzc2FnZSBpcyB0aGVyZSBpcyBubyBjb25uZWN0aW9uOiBubyBjb25uZWN0aW9uIG1lYW5zIHRoZXJlIGFyZSBubyBvcGVuXG4gICAgICAgICAgLy8gdGFicyB3aXRoIFRpbm9kZS5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvcGljID0gdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgZGF0YS50b3BpYyk7XG4gICAgICAgIGlmICghdG9waWMpIHtcbiAgICAgICAgICAvLyBUT0RPOiBjaGVjayBpZiB0aGVyZSBpcyBhIGNhc2Ugd2hlbiBhIG1lc3NhZ2UgY2FuIGFycml2ZSBmcm9tIGFuIHVua25vd24gdG9waWMuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodG9waWMuaXNTdWJzY3JpYmVkKCkpIHtcbiAgICAgICAgICAvLyBObyBuZWVkIHRvIGZldGNoOiB0b3BpYyBpcyBhbHJlYWR5IHN1YnNjcmliZWQgYW5kIGdvdCBkYXRhIHRocm91Z2ggbm9ybWFsIGNoYW5uZWwuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodG9waWMubWF4TXNnU2VxKCkgPCBkYXRhLnNlcSkge1xuICAgICAgICAgIGlmICh0b3BpYy5pc0NoYW5uZWxUeXBlKCkpIHtcbiAgICAgICAgICAgIHRvcGljLl91cGRhdGVSZWNlaXZlZChkYXRhLnNlcSwgJ2Zha2UtdWlkJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gTmV3IG1lc3NhZ2UuXG4gICAgICAgICAgaWYgKGRhdGEueGZyb20gJiYgIXRoaXMuI2NhY2hlR2V0KCd1c2VyJywgZGF0YS54ZnJvbSkpIHtcbiAgICAgICAgICAgIC8vIE1lc3NhZ2UgZnJvbSB1bmtub3duIHNlbmRlciwgZmV0Y2ggZGVzY3JpcHRpb24gZnJvbSB0aGUgc2VydmVyLlxuICAgICAgICAgICAgLy8gU2VuZGluZyBhc3luY2hyb25vdXNseSB3aXRob3V0IGEgc3Vic2NyaXB0aW9uLlxuICAgICAgICAgICAgdGhpcy5nZXRNZXRhKGRhdGEueGZyb20sIG5ldyBNZXRhR2V0QnVpbGRlcigpLndpdGhEZXNjKCkuYnVpbGQoKSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5sb2dnZXIoXCJGYWlsZWQgdG8gZ2V0IHRoZSBuYW1lIG9mIGEgbmV3IHNlbmRlclwiLCBlcnIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdG9waWMuc3Vic2NyaWJlKG51bGwpLnRoZW4oXyA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdG9waWMuZ2V0TWV0YShuZXcgTWV0YUdldEJ1aWxkZXIodG9waWMpLndpdGhMYXRlckRhdGEoMjQpLndpdGhMYXRlckRlbCgyNCkuYnVpbGQoKSk7XG4gICAgICAgICAgfSkudGhlbihfID0+IHtcbiAgICAgICAgICAgIC8vIEFsbG93IGRhdGEgZmV0Y2ggdG8gY29tcGxldGUgYW5kIGdldCBwcm9jZXNzZWQgc3VjY2Vzc2Z1bGx5LlxuICAgICAgICAgICAgdG9waWMubGVhdmVEZWxheWVkKGZhbHNlLCAxMDAwKTtcbiAgICAgICAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIoXCJPbiBwdXNoIGRhdGEgZmV0Y2ggZmFpbGVkXCIsIGVycik7XG4gICAgICAgICAgfSkuZmluYWxseShfID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ2V0TWVUb3BpYygpLl9yZWZyZXNoQ29udGFjdCgnbXNnJywgdG9waWMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdyZWFkJzpcbiAgICAgICAgdGhpcy5nZXRNZVRvcGljKCkuX3JvdXRlUHJlcyh7XG4gICAgICAgICAgd2hhdDogJ3JlYWQnLFxuICAgICAgICAgIHNlcTogZGF0YS5zZXFcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzdWInOlxuICAgICAgICBpZiAoIXRoaXMuaXNNZShkYXRhLnhmcm9tKSkge1xuICAgICAgICAgIC8vIFRPRE86IGhhbmRsZSB1cGRhdGVzIGZyb20gb3RoZXIgdXNlcnMuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbW9kZSA9IHtcbiAgICAgICAgICBnaXZlbjogZGF0YS5tb2RlR2l2ZW4sXG4gICAgICAgICAgd2FudDogZGF0YS5tb2RlV2FudFxuICAgICAgICB9O1xuICAgICAgICBsZXQgYWNzID0gbmV3IEFjY2Vzc01vZGUobW9kZSk7XG4gICAgICAgIGxldCBwcmVzID0gKCFhY3MubW9kZSB8fCBhY3MubW9kZSA9PSBBY2Nlc3NNb2RlLl9OT05FKSA/XG4gICAgICAgICAgLy8gU3Vic2NyaXB0aW9uIGRlbGV0ZWQuXG4gICAgICAgICAge1xuICAgICAgICAgICAgd2hhdDogJ2dvbmUnLFxuICAgICAgICAgICAgc3JjOiBkYXRhLnRvcGljXG4gICAgICAgICAgfSA6XG4gICAgICAgICAgLy8gTmV3IHN1YnNjcmlwdGlvbiBvciBzdWJzY3JpcHRpb24gdXBkYXRlZC5cbiAgICAgICAgICB7XG4gICAgICAgICAgICB3aGF0OiAnYWNzJyxcbiAgICAgICAgICAgIHNyYzogZGF0YS50b3BpYyxcbiAgICAgICAgICAgIGRhY3M6IG1vZGVcbiAgICAgICAgICB9O1xuICAgICAgICB0aGlzLmdldE1lVG9waWMoKS5fcm91dGVQcmVzKHByZXMpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhpcy5sb2dnZXIoXCJVbmtub3duIHB1c2ggdHlwZSBpZ25vcmVkXCIsIGRhdGEud2hhdCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEB0eXBlZGVmIEdldFF1ZXJ5XG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBwcm9wZXJ0eSB7R2V0T3B0c1R5cGU9fSBkZXNjIC0gSWYgcHJvdmlkZWQgKGV2ZW4gaWYgZW1wdHkpLCBmZXRjaCB0b3BpYyBkZXNjcmlwdGlvbi5cbiAgICogQHByb3BlcnR5IHtHZXRPcHRzVHlwZT19IHN1YiAtIElmIHByb3ZpZGVkIChldmVuIGlmIGVtcHR5KSwgZmV0Y2ggdG9waWMgc3Vic2NyaXB0aW9ucy5cbiAgICogQHByb3BlcnR5IHtHZXREYXRhVHlwZT19IGRhdGEgLSBJZiBwcm92aWRlZCAoZXZlbiBpZiBlbXB0eSksIGdldCBtZXNzYWdlcy5cbiAgICovXG5cbiAgLyoqXG4gICAqIEB0eXBlZGVmIEdldE9wdHNUeXBlXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBwcm9wZXJ0eSB7RGF0ZT19IGltcyAtIFwiSWYgbW9kaWZpZWQgc2luY2VcIiwgZmV0Y2ggZGF0YSBvbmx5IGl0IHdhcyB3YXMgbW9kaWZpZWQgc2luY2Ugc3RhdGVkIGRhdGUuXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyPX0gbGltaXQgLSBNYXhpbXVtIG51bWJlciBvZiByZXN1bHRzIHRvIHJldHVybi4gSWdub3JlZCB3aGVuIHF1ZXJ5aW5nIHRvcGljIGRlc2NyaXB0aW9uLlxuICAgKi9cblxuICAvKipcbiAgICogQHR5cGVkZWYgR2V0RGF0YVR5cGVcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQHByb3BlcnR5IHtudW1iZXI9fSBzaW5jZSAtIExvYWQgbWVzc2FnZXMgd2l0aCBzZXEgaWQgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIHRoaXMgdmFsdWUuXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyPX0gYmVmb3JlIC0gTG9hZCBtZXNzYWdlcyB3aXRoIHNlcSBpZCBsb3dlciB0aGFuIHRoaXMgbnVtYmVyLlxuICAgKiBAcHJvcGVydHkge251bWJlcj19IGxpbWl0IC0gTWF4aW11bSBudW1iZXIgb2YgcmVzdWx0cyB0byByZXR1cm4uXG4gICAqL1xuXG4gIC8qKlxuICAgKiBSZXF1ZXN0IHRvcGljIG1ldGFkYXRhXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpYyAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge0dldFF1ZXJ5fSBwYXJhbXMgLSBQYXJhbWV0ZXJzIG9mIHRoZSBxdWVyeS4gVXNlIHtAbGluayBUaW5vZGUuTWV0YUdldEJ1aWxkZXJ9IHRvIGdlbmVyYXRlLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB3aGljaCB3aWxsIGJlIHJlc29sdmVkL3JlamVjdGVkIG9uIHJlY2VpdmluZyBzZXJ2ZXIgcmVwbHkuXG4gICAqL1xuICBnZXRNZXRhKHRvcGljLCBwYXJhbXMpIHtcbiAgICBjb25zdCBwa3QgPSB0aGlzLiNpbml0UGFja2V0KCdnZXQnLCB0b3BpYyk7XG5cbiAgICBwa3QuZ2V0ID0gbWVyZ2VPYmoocGt0LmdldCwgcGFyYW1zKTtcblxuICAgIHJldHVybiB0aGlzLiNzZW5kKHBrdCwgcGt0LmdldC5pZCk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRvcGljJ3MgbWV0YWRhdGE6IGRlc2NyaXB0aW9uLCBzdWJzY3JpYnRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWMgLSBUb3BpYyB0byB1cGRhdGUuXG4gICAqIEBwYXJhbSB7U2V0UGFyYW1zfSBwYXJhbXMgLSB0b3BpYyBtZXRhZGF0YSB0byB1cGRhdGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHdoaWNoIHdpbGwgYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gcmVjZWl2aW5nIHNlcnZlciByZXBseS5cbiAgICovXG4gIHNldE1ldGEodG9waWMsIHBhcmFtcykge1xuICAgIGNvbnN0IHBrdCA9IHRoaXMuI2luaXRQYWNrZXQoJ3NldCcsIHRvcGljKTtcbiAgICBjb25zdCB3aGF0ID0gW107XG5cbiAgICBpZiAocGFyYW1zKSB7XG4gICAgICBbJ2Rlc2MnLCAnc3ViJywgJ3RhZ3MnLCAnY3JlZCcsICdlcGhlbWVyYWwnXS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAocGFyYW1zLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICB3aGF0LnB1c2goa2V5KTtcbiAgICAgICAgICBwa3Quc2V0W2tleV0gPSBwYXJhbXNba2V5XTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHBhcmFtcy5hdHRhY2htZW50cykgJiYgcGFyYW1zLmF0dGFjaG1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcGt0LmV4dHJhID0ge1xuICAgICAgICAgIGF0dGFjaG1lbnRzOiBwYXJhbXMuYXR0YWNobWVudHMuZmlsdGVyKHJlZiA9PiBUaW5vZGUuaXNSZWxhdGl2ZVVSTChyZWYpKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3aGF0Lmxlbmd0aCA9PSAwKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCB7c2V0fSBwYXJhbWV0ZXJzXCIpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy4jc2VuZChwa3QsIHBrdC5zZXQuaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJhbmdlIG9mIG1lc3NhZ2UgSURzIHRvIGRlbGV0ZS5cbiAgICpcbiAgICogQHR5cGVkZWYgRGVsUmFuZ2VcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IGxvdyAtIGxvdyBlbmQgb2YgdGhlIHJhbmdlLCBpbmNsdXNpdmUgKGNsb3NlZCkuXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyPX0gaGkgLSBoaWdoIGVuZCBvZiB0aGUgcmFuZ2UsIGV4Y2x1c2l2ZSAob3BlbikuXG4gICAqL1xuICAvKipcbiAgICogRGVsZXRlIHNvbWUgb3IgYWxsIG1lc3NhZ2VzIGluIGEgdG9waWMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpYyAtIFRvcGljIG5hbWUgdG8gZGVsZXRlIG1lc3NhZ2VzIGZyb20uXG4gICAqIEBwYXJhbSB7RGVsUmFuZ2VbXX0gbGlzdCAtIFJhbmdlcyBvZiBtZXNzYWdlIElEcyB0byBkZWxldGUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IGhhcmQgLSBIYXJkIG9yIHNvZnQgZGVsZXRlXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHdoaWNoIHdpbGwgYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgb24gcmVjZWl2aW5nIHNlcnZlciByZXBseS5cbiAgICovXG4gIGRlbE1lc3NhZ2VzKHRvcGljLCByYW5nZXMsIGhhcmQpIHtcbiAgICBjb25zdCBwa3QgPSB0aGlzLiNpbml0UGFja2V0KCdkZWwnLCB0b3BpYyk7XG5cbiAgICBwa3QuZGVsLndoYXQgPSAnbXNnJztcbiAgICBwa3QuZGVsLmRlbHNlcSA9IHJhbmdlcztcbiAgICBwa3QuZGVsLmhhcmQgPSBoYXJkO1xuXG4gICAgcmV0dXJuIHRoaXMuI3NlbmQocGt0LCBwa3QuZGVsLmlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIHRvcGljIGFsbHRvZ2V0aGVyLiBSZXF1aXJlcyBPd25lciBwZXJtaXNzaW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWNOYW1lIC0gTmFtZSBvZiB0aGUgdG9waWMgdG8gZGVsZXRlXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaGFyZCAtIGhhcmQtZGVsZXRlIHRvcGljLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB3aGljaCB3aWxsIGJlIHJlc29sdmVkL3JlamVjdGVkIG9uIHJlY2VpdmluZyBzZXJ2ZXIgcmVwbHkuXG4gICAqL1xuICBkZWxUb3BpYyh0b3BpY05hbWUsIGhhcmQpIHtcbiAgICBjb25zdCBwa3QgPSB0aGlzLiNpbml0UGFja2V0KCdkZWwnLCB0b3BpY05hbWUpO1xuICAgIHBrdC5kZWwud2hhdCA9ICd0b3BpYyc7XG4gICAgcGt0LmRlbC5oYXJkID0gaGFyZDtcblxuICAgIHJldHVybiB0aGlzLiNzZW5kKHBrdCwgcGt0LmRlbC5pZCk7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHN1YnNjcmlwdGlvbi4gUmVxdWlyZXMgU2hhcmUgcGVybWlzc2lvbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljTmFtZSAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIGRlbGV0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlciAtIFVzZXIgSUQgdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB3aGljaCB3aWxsIGJlIHJlc29sdmVkL3JlamVjdGVkIG9uIHJlY2VpdmluZyBzZXJ2ZXIgcmVwbHkuXG4gICAqL1xuICBkZWxTdWJzY3JpcHRpb24odG9waWNOYW1lLCB1c2VyKSB7XG4gICAgY29uc3QgcGt0ID0gdGhpcy4jaW5pdFBhY2tldCgnZGVsJywgdG9waWNOYW1lKTtcbiAgICBwa3QuZGVsLndoYXQgPSAnc3ViJztcbiAgICBwa3QuZGVsLnVzZXIgPSB1c2VyO1xuXG4gICAgcmV0dXJuIHRoaXMuI3NlbmQocGt0LCBwa3QuZGVsLmlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgY3JlZGVudGlhbC4gQWx3YXlzIHNlbnQgb24gPGNvZGU+J21lJzwvY29kZT4gdG9waWMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2QgLSB2YWxpZGF0aW9uIG1ldGhvZCBzdWNoIGFzIDxjb2RlPidlbWFpbCc8L2NvZGU+IG9yIDxjb2RlPid0ZWwnPC9jb2RlPi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gdmFsaWRhdGlvbiB2YWx1ZSwgaS5lLiA8Y29kZT4nYWxpY2VAZXhhbXBsZS5jb20nPC9jb2RlPi5cbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2Ugd2hpY2ggd2lsbCBiZSByZXNvbHZlZC9yZWplY3RlZCBvbiByZWNlaXZpbmcgc2VydmVyIHJlcGx5LlxuICAgKi9cbiAgZGVsQ3JlZGVudGlhbChtZXRob2QsIHZhbHVlKSB7XG4gICAgY29uc3QgcGt0ID0gdGhpcy4jaW5pdFBhY2tldCgnZGVsJywgQ29uc3QuVE9QSUNfTUUpO1xuICAgIHBrdC5kZWwud2hhdCA9ICdjcmVkJztcbiAgICBwa3QuZGVsLmNyZWQgPSB7XG4gICAgICBtZXRoOiBtZXRob2QsXG4gICAgICB2YWw6IHZhbHVlXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLiNzZW5kKHBrdCwgcGt0LmRlbC5pZCk7XG4gIH1cblxuICAvKipcbiAgICogUmVxdWVzdCB0byBkZWxldGUgYWNjb3VudCBvZiB0aGUgY3VycmVudCB1c2VyLlxuICAgKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGhhcmQgLSBoYXJkLWRlbGV0ZSB1c2VyLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB3aGljaCB3aWxsIGJlIHJlc29sdmVkL3JlamVjdGVkIG9uIHJlY2VpdmluZyBzZXJ2ZXIgcmVwbHkuXG4gICAqL1xuICBkZWxDdXJyZW50VXNlcihoYXJkKSB7XG4gICAgY29uc3QgcGt0ID0gdGhpcy4jaW5pdFBhY2tldCgnZGVsJywgbnVsbCk7XG4gICAgcGt0LmRlbC53aGF0ID0gJ3VzZXInO1xuICAgIHBrdC5kZWwuaGFyZCA9IGhhcmQ7XG5cbiAgICByZXR1cm4gdGhpcy4jc2VuZChwa3QsIHBrdC5kZWwuaWQpLnRoZW4oKGN0cmwpID0+IHtcbiAgICAgIHRoaXMuX215VUlEID0gbnVsbDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RpZnkgc2VydmVyIHRoYXQgYSBtZXNzYWdlIG9yIG1lc3NhZ2VzIHdlcmUgcmVhZCBvciByZWNlaXZlZC4gRG9lcyBOT1QgcmV0dXJuIHByb21pc2UuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpY05hbWUgLSBOYW1lIG9mIHRoZSB0b3BpYyB3aGVyZSB0aGUgbWVzYWdlIGlzIGJlaW5nIGFrbm93bGVkZ2VkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gd2hhdCAtIEFjdGlvbiBiZWluZyBha25vd2xlZGdlZCwgZWl0aGVyIDxjb2RlPlwicmVhZFwiPC9jb2RlPiBvciA8Y29kZT5cInJlY3ZcIjwvY29kZT4uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzZXEgLSBNYXhpbXVtIGlkIG9mIHRoZSBtZXNzYWdlIGJlaW5nIGFja25vd2xlZGdlZC5cbiAgICovXG4gIG5vdGUodG9waWNOYW1lLCB3aGF0LCBzZXEpIHtcbiAgICBpZiAoc2VxIDw9IDAgfHwgc2VxID49IENvbnN0LkxPQ0FMX1NFUUlEKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbWVzc2FnZSBpZCAke3NlcX1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBwa3QgPSB0aGlzLiNpbml0UGFja2V0KCdub3RlJywgdG9waWNOYW1lKTtcbiAgICBwa3Qubm90ZS53aGF0ID0gd2hhdDtcbiAgICBwa3Qubm90ZS5zZXEgPSBzZXE7XG4gICAgdGhpcy4jc2VuZChwa3QpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJyb2FkY2FzdCBhIGtleS1wcmVzcyBub3RpZmljYXRpb24gdG8gdG9waWMgc3Vic2NyaWJlcnMuIFVzZWQgdG8gc2hvd1xuICAgKiB0eXBpbmcgbm90aWZpY2F0aW9ucyBcInVzZXIgWCBpcyB0eXBpbmcuLi5cIi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljTmFtZSAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIGJyb2FkY2FzdCB0by5cbiAgICovXG4gIG5vdGVLZXlQcmVzcyh0b3BpY05hbWUpIHtcbiAgICBjb25zdCBwa3QgPSB0aGlzLiNpbml0UGFja2V0KCdub3RlJywgdG9waWNOYW1lKTtcbiAgICBwa3Qubm90ZS53aGF0ID0gJ2twJztcbiAgICB0aGlzLiNzZW5kKHBrdCk7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBhIHZpZGVvIGNhbGwgbm90aWZpY2F0aW9uIHRvIHRvcGljIHN1YnNjcmliZXJzIChpbmNsdWRpbmcgZGlhbGluZyxcbiAgICogaGFuZ3VwLCBldGMuKS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljTmFtZSAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIGJyb2FkY2FzdCB0by5cbiAgICogQHBhcmFtIHtpbnR9IHNlcSAtIElEIG9mIHRoZSBjYWxsIG1lc3NhZ2UgdGhlIGV2ZW50IHBlcnRhaW5zIHRvLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZ0IC0gQ2FsbCBldmVudC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBheWxvYWQgLSBQYXlsb2FkIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGV2ZW50IChlLmcuIFNEUCBzdHJpbmcpLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSAoZm9yIHNvbWUgY2FsbCBldmVudHMpIHdoaWNoIHdpbGxcbiAgICogICAgICAgICAgICAgICAgICAgIGJlIHJlc29sdmVkL3JlamVjdGVkIG9uIHJlY2VpdmluZyBzZXJ2ZXIgcmVwbHlcbiAgICovXG4gIHZpZGVvQ2FsbCh0b3BpY05hbWUsIHNlcSwgZXZ0LCBwYXlsb2FkKSB7XG4gICAgY29uc3QgcGt0ID0gdGhpcy4jaW5pdFBhY2tldCgnbm90ZScsIHRvcGljTmFtZSk7XG4gICAgcGt0Lm5vdGUuc2VxID0gc2VxO1xuICAgIHBrdC5ub3RlLndoYXQgPSAnY2FsbCc7XG4gICAgcGt0Lm5vdGUuZXZlbnQgPSBldnQ7XG4gICAgcGt0Lm5vdGUucGF5bG9hZCA9IHBheWxvYWQ7XG4gICAgdGhpcy4jc2VuZChwa3QsIHBrdC5ub3RlLmlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBuYW1lZCB0b3BpYywgZWl0aGVyIHB1bGwgaXQgZnJvbSBjYWNoZSBvciBjcmVhdGUgYSBuZXcgaW5zdGFuY2UuXG4gICAqIFRoZXJlIGlzIGEgc2luZ2xlIGluc3RhbmNlIG9mIHRvcGljIGZvciBlYWNoIG5hbWUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpY05hbWUgLSBOYW1lIG9mIHRoZSB0b3BpYyB0byBnZXQuXG4gICAqXG4gICAqIEByZXR1cm5zIHtUb3BpY30gUmVxdWVzdGVkIG9yIG5ld2x5IGNyZWF0ZWQgdG9waWMgb3IgPGNvZGU+dW5kZWZpbmVkPC9jb2RlPiBpZiB0b3BpYyBuYW1lIGlzIGludmFsaWQuXG4gICAqL1xuICBnZXRUb3BpYyh0b3BpY05hbWUpIHtcbiAgICBsZXQgdG9waWMgPSB0aGlzLiNjYWNoZUdldCgndG9waWMnLCB0b3BpY05hbWUpO1xuICAgIGlmICghdG9waWMgJiYgdG9waWNOYW1lKSB7XG4gICAgICBpZiAodG9waWNOYW1lID09IENvbnN0LlRPUElDX01FKSB7XG4gICAgICAgIHRvcGljID0gbmV3IFRvcGljTWUoKTtcbiAgICAgIH0gZWxzZSBpZiAodG9waWNOYW1lID09IENvbnN0LlRPUElDX0ZORCkge1xuICAgICAgICB0b3BpYyA9IG5ldyBUb3BpY0ZuZCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9waWMgPSBuZXcgVG9waWModG9waWNOYW1lKTtcbiAgICAgIH1cbiAgICAgIC8vIENhY2hlIG1hbmFnZW1lbnQuXG4gICAgICB0aGlzLiNhdHRhY2hDYWNoZVRvVG9waWModG9waWMpO1xuICAgICAgdG9waWMuX2NhY2hlUHV0U2VsZigpO1xuICAgICAgLy8gRG9uJ3Qgc2F2ZSB0byBEQiBoZXJlOiBhIHJlY29yZCB3aWxsIGJlIGFkZGVkIHdoZW4gdGhlIHRvcGljIGlzIHN1YnNjcmliZWQuXG4gICAgfVxuICAgIHJldHVybiB0b3BpYztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBuYW1lZCB0b3BpYyBmcm9tIGNhY2hlLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWNOYW1lIC0gTmFtZSBvZiB0aGUgdG9waWMgdG8gZ2V0LlxuICAgKlxuICAgKiBAcmV0dXJucyB7VG9waWN9IFJlcXVlc3RlZCB0b3BpYyBvciA8Y29kZT51bmRlZmluZWQ8L2NvZGU+IGlmIHRvcGljIGlzIG5vdCBmb3VuZCBpbiBjYWNoZS5cbiAgICovXG4gIGNhY2hlR2V0VG9waWModG9waWNOYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuI2NhY2hlR2V0KCd0b3BpYycsIHRvcGljTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIG5hbWVkIHRvcGljIGZyb20gY2FjaGUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpY05hbWUgLSBOYW1lIG9mIHRoZSB0b3BpYyB0byByZW1vdmUgZnJvbSBjYWNoZS5cbiAgICovXG4gIGNhY2hlUmVtVG9waWModG9waWNOYW1lKSB7XG4gICAgdGhpcy4jY2FjaGVEZWwoJ3RvcGljJywgdG9waWNOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJdGVyYXRlIG92ZXIgY2FjaGVkIHRvcGljcy5cbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyAtIGNhbGxiYWNrIHRvIGNhbGwgZm9yIGVhY2ggdG9waWMuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC0gJ3RoaXMnIGluc2lkZSB0aGUgJ2Z1bmMnLlxuICAgKi9cbiAgbWFwVG9waWNzKGZ1bmMsIGNvbnRleHQpIHtcbiAgICB0aGlzLiNjYWNoZU1hcCgndG9waWMnLCBmdW5jLCBjb250ZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBuYW1lZCB0b3BpYyBpcyBhbHJlYWR5IHByZXNlbnQgaW4gY2FjaGUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpY05hbWUgLSBOYW1lIG9mIHRoZSB0b3BpYyB0byBjaGVjay5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgdG9waWMgaXMgZm91bmQgaW4gY2FjaGUsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIGlzVG9waWNDYWNoZWQodG9waWNOYW1lKSB7XG4gICAgcmV0dXJuICEhdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgdG9waWNOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSB1bmlxdWUgbmFtZSBsaWtlIDxjb2RlPiduZXcxMjM0NTYnPC9jb2RlPiBzdWl0YWJsZSBmb3IgY3JlYXRpbmcgYSBuZXcgZ3JvdXAgdG9waWMuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNDaGFuIC0gaWYgdGhlIHRvcGljIGlzIGNoYW5uZWwtZW5hYmxlZC5cbiAgICogQHJldHVybnMge3N0cmluZ30gbmFtZSB3aGljaCBjYW4gYmUgdXNlZCBmb3IgY3JlYXRpbmcgYSBuZXcgZ3JvdXAgdG9waWMuXG4gICAqL1xuICBuZXdHcm91cFRvcGljTmFtZShpc0NoYW4pIHtcbiAgICByZXR1cm4gKGlzQ2hhbiA/IENvbnN0LlRPUElDX05FV19DSEFOIDogQ29uc3QuVE9QSUNfTkVXKSArIHRoaXMuZ2V0TmV4dFVuaXF1ZUlkKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5zdGFudGlhdGUgPGNvZGU+J21lJzwvY29kZT4gdG9waWMgb3IgZ2V0IGl0IGZyb20gY2FjaGUuXG4gICAqXG4gICAqIEByZXR1cm5zIHtUb3BpY01lfSBJbnN0YW5jZSBvZiA8Y29kZT4nbWUnPC9jb2RlPiB0b3BpYy5cbiAgICovXG4gIGdldE1lVG9waWMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VG9waWMoQ29uc3QuVE9QSUNfTUUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEluc3RhbnRpYXRlIDxjb2RlPidmbmQnPC9jb2RlPiAoZmluZCkgdG9waWMgb3IgZ2V0IGl0IGZyb20gY2FjaGUuXG4gICAqXG4gICAqIEByZXR1cm5zIHtUb3BpY30gSW5zdGFuY2Ugb2YgPGNvZGU+J2ZuZCc8L2NvZGU+IHRvcGljLlxuICAgKi9cbiAgZ2V0Rm5kVG9waWMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VG9waWMoQ29uc3QuVE9QSUNfRk5EKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcge0BsaW5rIExhcmdlRmlsZUhlbHBlcn0gaW5zdGFuY2VcbiAgICpcbiAgICogQHJldHVybnMge0xhcmdlRmlsZUhlbHBlcn0gaW5zdGFuY2Ugb2YgYSB7QGxpbmsgVGlub2RlLkxhcmdlRmlsZUhlbHBlcn0uXG4gICAqL1xuICBnZXRMYXJnZUZpbGVIZWxwZXIoKSB7XG4gICAgcmV0dXJuIG5ldyBMYXJnZUZpbGVIZWxwZXIodGhpcywgQ29uc3QuUFJPVE9DT0xfVkVSU0lPTik7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBVSUQgb2YgdGhlIHRoZSBjdXJyZW50IGF1dGhlbnRpY2F0ZWQgdXNlci5cbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gVUlEIG9mIHRoZSBjdXJyZW50IHVzZXIgb3IgPGNvZGU+dW5kZWZpbmVkPC9jb2RlPiBpZiB0aGUgc2Vzc2lvbiBpcyBub3QgeWV0XG4gICAqIGF1dGhlbnRpY2F0ZWQgb3IgaWYgdGhlcmUgaXMgbm8gc2Vzc2lvbi5cbiAgICovXG4gIGdldEN1cnJlbnRVc2VySUQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX215VUlEO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRoZSBnaXZlbiB1c2VyIElEIGlzIGVxdWFsIHRvIHRoZSBjdXJyZW50IHVzZXIncyBVSUQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1aWQgLSBVSUQgdG8gY2hlY2suXG4gICAqXG4gICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSBnaXZlbiBVSUQgYmVsb25ncyB0byB0aGUgY3VycmVudCBsb2dnZWQgaW4gdXNlci5cbiAgICovXG4gIGlzTWUodWlkKSB7XG4gICAgcmV0dXJuIHRoaXMuX215VUlEID09PSB1aWQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGxvZ2luIHVzZWQgZm9yIGxhc3Qgc3VjY2Vzc2Z1bCBhdXRoZW50aWNhdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gbG9naW4gbGFzdCB1c2VkIHN1Y2Nlc3NmdWxseSBvciA8Y29kZT51bmRlZmluZWQ8L2NvZGU+LlxuICAgKi9cbiAgZ2V0Q3VycmVudExvZ2luKCkge1xuICAgIHJldHVybiB0aGlzLl9sb2dpbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNlcnZlcjogcHJvdG9jb2wgdmVyc2lvbiBhbmQgYnVpbGQgdGltZXN0YW1wLlxuICAgKlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBidWlsZCBhbmQgdmVyc2lvbiBvZiB0aGUgc2VydmVyIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIGNvbm5lY3Rpb24gb3JcbiAgICogaWYgdGhlIGZpcnN0IHNlcnZlciByZXNwb25zZSBoYXMgbm90IGJlZW4gcmVjZWl2ZWQgeWV0LlxuICAgKi9cbiAgZ2V0U2VydmVySW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5fc2VydmVySW5mbztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBvcnQgYSB0b3BpYyBmb3IgYWJ1c2UuIFdyYXBwZXIgZm9yIHtAbGluayBUaW5vZGUjcHVibGlzaH0uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24gLSB0aGUgb25seSBzdXBwb3J0ZWQgYWN0aW9uIGlzICdyZXBvcnQnLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFyZ2V0IC0gbmFtZSBvZiB0aGUgdG9waWMgYmVpbmcgcmVwb3J0ZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHRvIGJlIHJlc29sdmVkL3JlamVjdGVkIHdoZW4gdGhlIHNlcnZlciByZXNwb25kcyB0byByZXF1ZXN0LlxuICAgKi9cbiAgcmVwb3J0KGFjdGlvbiwgdGFyZ2V0KSB7XG4gICAgcmV0dXJuIHRoaXMucHVibGlzaChDb25zdC5UT1BJQ19TWVMsIERyYWZ0eS5hdHRhY2hKU09OKG51bGwsIHtcbiAgICAgICdhY3Rpb24nOiBhY3Rpb24sXG4gICAgICAndGFyZ2V0JzogdGFyZ2V0XG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBzZXJ2ZXItcHJvdmlkZWQgY29uZmlndXJhdGlvbiB2YWx1ZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgb2YgdGhlIHZhbHVlIHRvIHJldHVybi5cbiAgICogQHBhcmFtIHtPYmplY3R9IGRlZmF1bHRWYWx1ZSB0byByZXR1cm4gaW4gY2FzZSB0aGUgcGFyYW1ldGVyIGlzIG5vdCBzZXQgb3Igbm90IGZvdW5kLlxuICAgKlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBuYW1lZCB2YWx1ZS5cbiAgICovXG4gIGdldFNlcnZlclBhcmFtKG5hbWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9zZXJ2ZXJJbmZvICYmIHRoaXMuX3NlcnZlckluZm9bbmFtZV0gfHwgZGVmYXVsdFZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZSBjb25zb2xlIGxvZ2dpbmcuIExvZ2dpbmcgaXMgb2ZmIGJ5IGRlZmF1bHQuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZW5hYmxlZCAtIFNldCB0byA8Y29kZT50cnVlPC9jb2RlPiB0byBlbmFibGUgbG9nZ2luZyB0byBjb25zb2xlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHRyaW1Mb25nU3RyaW5ncyAtIFNldCB0byA8Y29kZT50cnVlPC9jb2RlPiB0byB0cmltIGxvbmcgc3RyaW5ncy5cbiAgICovXG4gIGVuYWJsZUxvZ2dpbmcoZW5hYmxlZCwgdHJpbUxvbmdTdHJpbmdzKSB7XG4gICAgdGhpcy5fbG9nZ2luZ0VuYWJsZWQgPSBlbmFibGVkO1xuICAgIHRoaXMuX3RyaW1Mb25nU3RyaW5ncyA9IGVuYWJsZWQgJiYgdHJpbUxvbmdTdHJpbmdzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCBVSSBsYW5ndWFnZSB0byByZXBvcnQgdG8gdGhlIHNlcnZlci4gTXVzdCBiZSBjYWxsZWQgYmVmb3JlIDxjb2RlPidoaSc8L2NvZGU+IGlzIHNlbnQsIG90aGVyd2lzZSBpdCB3aWxsIG5vdCBiZSB1c2VkLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaGwgLSBodW1hbiAoVUkpIGxhbmd1YWdlLCBsaWtlIDxjb2RlPlwiZW5fVVNcIjwvY29kZT4gb3IgPGNvZGU+XCJ6aC1IYW5zXCI8L2NvZGU+LlxuICAgKi9cbiAgc2V0SHVtYW5MYW5ndWFnZShobCkge1xuICAgIGlmIChobCkge1xuICAgICAgdGhpcy5faHVtYW5MYW5ndWFnZSA9IGhsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBnaXZlbiB0b3BpYyBpcyBvbmxpbmUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIG9mIHRoZSB0b3BpYyB0byB0ZXN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0b3BpYyBpcyBvbmxpbmUsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIGlzVG9waWNPbmxpbmUobmFtZSkge1xuICAgIGNvbnN0IHRvcGljID0gdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgbmFtZSk7XG4gICAgcmV0dXJuIHRvcGljICYmIHRvcGljLm9ubGluZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWNjZXNzIG1vZGUgZm9yIHRoZSBnaXZlbiBjb250YWN0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBvZiB0aGUgdG9waWMgdG8gcXVlcnkuXG4gICAqIEByZXR1cm5zIHtBY2Nlc3NNb2RlfSBhY2Nlc3MgbW9kZSBpZiB0b3BpYyBpcyBmb3VuZCwgbnVsbCBvdGhlcndpc2UuXG4gICAqL1xuICBnZXRUb3BpY0FjY2Vzc01vZGUobmFtZSkge1xuICAgIGNvbnN0IHRvcGljID0gdGhpcy4jY2FjaGVHZXQoJ3RvcGljJywgbmFtZSk7XG4gICAgcmV0dXJuIHRvcGljID8gdG9waWMuYWNzIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbmNsdWRlIG1lc3NhZ2UgSUQgaW50byBhbGwgc3Vic2VxdWVzdCBtZXNzYWdlcyB0byBzZXJ2ZXIgaW5zdHJ1Y3RpbiBpdCB0byBzZW5kIGFrbm93bGVkZ2VtZW5zLlxuICAgKiBSZXF1aXJlZCBmb3IgcHJvbWlzZXMgdG8gZnVuY3Rpb24uIERlZmF1bHQgaXMgPGNvZGU+XCJvblwiPC9jb2RlPi5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufSBzdGF0dXMgLSBUdXJuIGFrbm93bGVkZ2VtZW5zIG9uIG9yIG9mZi5cbiAgICogQGRlcHJlY2F0ZWRcbiAgICovXG4gIHdhbnRBa24oc3RhdHVzKSB7XG4gICAgaWYgKHN0YXR1cykge1xuICAgICAgdGhpcy5fbWVzc2FnZUlkID0gTWF0aC5mbG9vcigoTWF0aC5yYW5kb20oKSAqIDB4RkZGRkZGKSArIDB4RkZGRkZGKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbWVzc2FnZUlkID0gMDtcbiAgICB9XG4gIH1cblxuICAvLyBDYWxsYmFja3M6XG4gIC8qKlxuICAgKiBDYWxsYmFjayB0byByZXBvcnQgd2hlbiB0aGUgd2Vic29ja2V0IGlzIG9wZW5lZC4gVGhlIGNhbGxiYWNrIGhhcyBubyBwYXJhbWV0ZXJzLlxuICAgKlxuICAgKiBAdHlwZSB7b25XZWJzb2NrZXRPcGVufVxuICAgKi9cbiAgb25XZWJzb2NrZXRPcGVuID0gdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAdHlwZWRlZiBTZXJ2ZXJQYXJhbXNcbiAgICpcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQHByb3BlcnR5IHtzdHJpbmd9IHZlciAtIFNlcnZlciB2ZXJzaW9uXG4gICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBidWlsZCAtIFNlcnZlciBidWlsZFxuICAgKiBAcHJvcGVydHkge3N0cmluZz19IHNpZCAtIFNlc3Npb24gSUQsIGxvbmcgcG9sbGluZyBjb25uZWN0aW9ucyBvbmx5LlxuICAgKi9cblxuICAvKipcbiAgICogQGNhbGxiYWNrIG9uQ29ubmVjdFxuICAgKiBAcGFyYW0ge251bWJlcn0gY29kZSAtIFJlc3VsdCBjb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGV4dCBlcHhwbGFpbmluZyB0aGUgY29tcGxldGlvbiwgaS5lIFwiT0tcIiBvciBhbiBlcnJvciBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge1NlcnZlclBhcmFtc30gcGFyYW1zIC0gUGFyYW1ldGVycyByZXR1cm5lZCBieSB0aGUgc2VydmVyLlxuICAgKi9cbiAgLyoqXG4gICAqIENhbGxiYWNrIHRvIHJlcG9ydCB3aGVuIGNvbm5lY3Rpb24gd2l0aCBUaW5vZGUgc2VydmVyIGlzIGVzdGFibGlzaGVkLlxuICAgKiBAdHlwZSB7b25Db25uZWN0fVxuICAgKi9cbiAgb25Db25uZWN0ID0gdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBDYWxsYmFjayB0byByZXBvcnQgd2hlbiBjb25uZWN0aW9uIGlzIGxvc3QuIFRoZSBjYWxsYmFjayBoYXMgbm8gcGFyYW1ldGVycy5cbiAgICogQHR5cGUge29uRGlzY29ubmVjdH1cbiAgICovXG4gIG9uRGlzY29ubmVjdCA9IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGNhbGxiYWNrIG9uTG9naW5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvZGUgLSBOVW1lcmljIGNvbXBsZXRpb24gY29kZSwgc2FtZSBhcyBIVFRQIHN0YXR1cyBjb2Rlcy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBFeHBsYW5hdGlvbiBvZiB0aGUgY29tcGxldGlvbiBjb2RlLlxuICAgKi9cbiAgLyoqXG4gICAqIENhbGxiYWNrIHRvIHJlcG9ydCBsb2dpbiBjb21wbGV0aW9uLlxuICAgKiBAdHlwZSB7b25Mb2dpbn1cbiAgICovXG4gIG9uTG9naW4gPSB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIHRvIHJlY2VpdmUgPGNvZGU+e2N0cmx9PC9jb2RlPiAoY29udHJvbCkgbWVzc2FnZXMuXG4gICAqIEB0eXBlIHtvbkN0cmxNZXNzYWdlfVxuICAgKi9cbiAgb25DdHJsTWVzc2FnZSA9IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQ2FsbGJhY2sgdG8gcmVjaWV2ZSA8Y29kZT57ZGF0YX08L2NvZGU+IChjb250ZW50KSBtZXNzYWdlcy5cbiAgICogQHR5cGUge29uRGF0YU1lc3NhZ2V9XG4gICAqL1xuICBvbkRhdGFNZXNzYWdlID0gdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBDYWxsYmFjayB0byByZWNlaXZlIDxjb2RlPntwcmVzfTwvY29kZT4gKHByZXNlbmNlKSBtZXNzYWdlcy5cbiAgICogQHR5cGUge29uUHJlc01lc3NhZ2V9XG4gICAqL1xuICBvblByZXNNZXNzYWdlID0gdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBDYWxsYmFjayB0byByZWNlaXZlIGFsbCBtZXNzYWdlcyBhcyBvYmplY3RzLlxuICAgKiBAdHlwZSB7b25NZXNzYWdlfVxuICAgKi9cbiAgb25NZXNzYWdlID0gdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBDYWxsYmFjayB0byByZWNlaXZlIGFsbCBtZXNzYWdlcyBhcyB1bnBhcnNlZCB0ZXh0LlxuICAgKiBAdHlwZSB7b25SYXdNZXNzYWdlfVxuICAgKi9cbiAgb25SYXdNZXNzYWdlID0gdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBDYWxsYmFjayB0byByZWNlaXZlIHNlcnZlciByZXNwb25zZXMgdG8gbmV0d29yayBwcm9iZXMuIFNlZSB7QGxpbmsgVGlub2RlI25ldHdvcmtQcm9iZX1cbiAgICogQHR5cGUge29uTmV0d29ya1Byb2JlfVxuICAgKi9cbiAgb25OZXR3b3JrUHJvYmUgPSB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIHRvIGJlIG5vdGlmaWVkIHdoZW4gZXhwb25lbnRpYWwgYmFja29mZiBpcyBpdGVyYXRpbmcuXG4gICAqIEB0eXBlIHtvbkF1dG9yZWNvbm5lY3RJdGVyYXRpb259XG4gICAqL1xuICBvbkF1dG9yZWNvbm5lY3RJdGVyYXRpb24gPSB1bmRlZmluZWQ7XG59O1xuXG4vLyBFeHBvcnRlZCBjb25zdGFudHNcblRpbm9kZS5NRVNTQUdFX1NUQVRVU19OT05FID0gQ29uc3QuTUVTU0FHRV9TVEFUVVNfTk9ORTtcblRpbm9kZS5NRVNTQUdFX1NUQVRVU19RVUVVRUQgPSBDb25zdC5NRVNTQUdFX1NUQVRVU19RVUVVRUQ7XG5UaW5vZGUuTUVTU0FHRV9TVEFUVVNfU0VORElORyA9IENvbnN0Lk1FU1NBR0VfU1RBVFVTX1NFTkRJTkc7XG5UaW5vZGUuTUVTU0FHRV9TVEFUVVNfRkFJTEVEID0gQ29uc3QuTUVTU0FHRV9TVEFUVVNfRkFJTEVEO1xuVGlub2RlLk1FU1NBR0VfU1RBVFVTX1NFTlQgPSBDb25zdC5NRVNTQUdFX1NUQVRVU19TRU5UO1xuVGlub2RlLk1FU1NBR0VfU1RBVFVTX1JFQ0VJVkVEID0gQ29uc3QuTUVTU0FHRV9TVEFUVVNfUkVDRUlWRUQ7XG5UaW5vZGUuTUVTU0FHRV9TVEFUVVNfUkVBRCA9IENvbnN0Lk1FU1NBR0VfU1RBVFVTX1JFQUQ7XG5UaW5vZGUuTUVTU0FHRV9TVEFUVVNfVE9fTUUgPSBDb25zdC5NRVNTQUdFX1NUQVRVU19UT19NRTtcblRpbm9kZS5NRVNTQUdFX1NUQVRVU19ERUxfUkFOR0UgPSBDb25zdC5NRVNTQUdFX1NUQVRVU19ERUxfUkFOR0U7XG5cbi8vIFVuaWNvZGUgW2RlbF0gc3ltYm9sLlxuVGlub2RlLkRFTF9DSEFSID0gQ29uc3QuREVMX0NIQVI7XG5cbi8vIE5hbWVzIG9mIGtleXMgdG8gc2VydmVyLXByb3ZpZGVkIGNvbmZpZ3VyYXRpb24gbGltaXRzLlxuVGlub2RlLk1BWF9NRVNTQUdFX1NJWkUgPSAnbWF4TWVzc2FnZVNpemUnO1xuVGlub2RlLk1BWF9TVUJTQ1JJQkVSX0NPVU5UID0gJ21heFN1YnNjcmliZXJDb3VudCc7XG5UaW5vZGUuTUFYX1RBR19DT1VOVCA9ICdtYXhUYWdDb3VudCc7XG5UaW5vZGUuTUFYX0ZJTEVfVVBMT0FEX1NJWkUgPSAnbWF4RmlsZVVwbG9hZFNpemUnO1xuIiwiLyoqXG4gKiBAZmlsZSBUb3BpYyBtYW5hZ2VtZW50LlxuICpcbiAqIEBjb3B5cmlnaHQgMjAxNS0yMDIyIFRpbm9kZSBMTEMuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IEFjY2Vzc01vZGUgZnJvbSAnLi9hY2Nlc3MtbW9kZS5qcyc7XG5pbXBvcnQgQ0J1ZmZlciBmcm9tICcuL2NidWZmZXIuanMnO1xuaW1wb3J0ICogYXMgQ29uc3QgZnJvbSAnLi9jb25maWcuanMnO1xuaW1wb3J0IERyYWZ0eSBmcm9tICcuL2RyYWZ0eS5qcyc7XG5pbXBvcnQgTWV0YUdldEJ1aWxkZXIgZnJvbSAnLi9tZXRhLWJ1aWxkZXIuanMnO1xuaW1wb3J0IHtcbiAgbWVyZ2VPYmosXG4gIG1lcmdlVG9DYWNoZSxcbiAgbm9ybWFsaXplQXJyYXlcbn0gZnJvbSAnLi91dGlscy5qcyc7XG5cbmV4cG9ydCBjbGFzcyBUb3BpYyB7XG4gIC8qKlxuICAgKiBAY2FsbGJhY2sgVGlub2RlLlRvcGljLm9uRGF0YVxuICAgKiBAcGFyYW0ge0RhdGF9IGRhdGEgLSBEYXRhIHBhY2tldFxuICAgKi9cbiAgLyoqXG4gICAqIFRvcGljIGlzIGEgY2xhc3MgcmVwcmVzZW50aW5nIGEgbG9naWNhbCBjb21tdW5pY2F0aW9uIGNoYW5uZWwuXG4gICAqIEBjbGFzcyBUb3BpY1xuICAgKiBAbWVtYmVyb2YgVGlub2RlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTmFtZSBvZiB0aGUgdG9waWMgdG8gY3JlYXRlLlxuICAgKiBAcGFyYW0ge09iamVjdD19IGNhbGxiYWNrcyAtIE9iamVjdCB3aXRoIHZhcmlvdXMgZXZlbnQgY2FsbGJhY2tzLlxuICAgKiBAcGFyYW0ge1Rpbm9kZS5Ub3BpYy5vbkRhdGF9IGNhbGxiYWNrcy5vbkRhdGEgLSBDYWxsYmFjayB3aGljaCByZWNlaXZlcyBhIDxjb2RlPntkYXRhfTwvY29kZT4gbWVzc2FnZS5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gY2FsbGJhY2tzLm9uTWV0YSAtIENhbGxiYWNrIHdoaWNoIHJlY2VpdmVzIGEgPGNvZGU+e21ldGF9PC9jb2RlPiBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge2NhbGxiYWNrfSBjYWxsYmFja3Mub25QcmVzIC0gQ2FsbGJhY2sgd2hpY2ggcmVjZWl2ZXMgYSA8Y29kZT57cHJlc308L2NvZGU+IG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7Y2FsbGJhY2t9IGNhbGxiYWNrcy5vbkluZm8gLSBDYWxsYmFjayB3aGljaCByZWNlaXZlcyBhbiA8Y29kZT57aW5mb308L2NvZGU+IG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7Y2FsbGJhY2t9IGNhbGxiYWNrcy5vbk1ldGFEZXNjIC0gQ2FsbGJhY2sgd2hpY2ggcmVjZWl2ZXMgY2hhbmdlcyB0byB0b3BpYyBkZXNjdGlvcHRpb24ge0BsaW5rIGRlc2N9LlxuICAgKiBAcGFyYW0ge2NhbGxiYWNrfSBjYWxsYmFja3Mub25NZXRhU3ViIC0gQ2FsbGVkIGZvciBhIHNpbmdsZSBzdWJzY3JpcHRpb24gcmVjb3JkIGNoYW5nZS5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gY2FsbGJhY2tzLm9uU3Vic1VwZGF0ZWQgLSBDYWxsZWQgYWZ0ZXIgYSBiYXRjaCBvZiBzdWJzY3JpcHRpb24gY2hhbmdlcyBoYXZlIGJlZW4gcmVjaWV2ZWQgYW5kIGNhY2hlZC5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gY2FsbGJhY2tzLm9uRGVsZXRlVG9waWMgLSBDYWxsZWQgYWZ0ZXIgdGhlIHRvcGljIGlzIGRlbGV0ZWQuXG4gICAqIEBwYXJhbSB7Y2FsbGJhY2t9IGNhbGxiYWNscy5vbkFsbE1lc3NhZ2VzUmVjZWl2ZWQgLSBDYWxsZWQgd2hlbiBhbGwgcmVxdWVzdGVkIDxjb2RlPntkYXRhfTwvY29kZT4gbWVzc2FnZXMgaGF2ZSBiZWVuIHJlY2l2ZWQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihuYW1lLCBjYWxsYmFja3MpIHtcbiAgICAvLyBQYXJlbnQgVGlub2RlIG9iamVjdC5cbiAgICB0aGlzLl90aW5vZGUgPSBudWxsO1xuXG4gICAgLy8gU2VydmVyLXByb3ZpZGVkIGRhdGEsIGxvY2FsbHkgaW1tdXRhYmxlLlxuICAgIC8vIHRvcGljIG5hbWVcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIC8vIFRpbWVzdGFtcCB3aGVuIHRoZSB0b3BpYyB3YXMgY3JlYXRlZC5cbiAgICB0aGlzLmNyZWF0ZWQgPSBudWxsO1xuICAgIC8vIFRpbWVzdGFtcCB3aGVuIHRoZSB0b3BpYyB3YXMgbGFzdCB1cGRhdGVkLlxuICAgIHRoaXMudXBkYXRlZCA9IG51bGw7XG4gICAgLy8gVGltZXN0YW1wIG9mIHRoZSBsYXN0IG1lc3NhZ2VzXG4gICAgdGhpcy50b3VjaGVkID0gbmV3IERhdGUoMCk7XG4gICAgLy8gQWNjZXNzIG1vZGUsIHNlZSBBY2Nlc3NNb2RlXG4gICAgdGhpcy5hY3MgPSBuZXcgQWNjZXNzTW9kZShudWxsKTtcbiAgICAvLyBQZXItdG9waWMgcHJpdmF0ZSBkYXRhIChhY2Nlc3NpYmxlIGJ5IGN1cnJlbnQgdXNlciBvbmx5KS5cbiAgICB0aGlzLnByaXZhdGUgPSBudWxsO1xuICAgIC8vIFBlci10b3BpYyBwdWJsaWMgZGF0YSAoYWNjZXNzaWJsZSBieSBhbGwgdXNlcnMpLlxuICAgIHRoaXMucHVibGljID0gbnVsbDtcbiAgICAvLyBQZXItdG9waWMgc3lzdGVtLXByb3ZpZGVkIGRhdGEgKGFjY2Vzc2libGUgYnkgYWxsIHVzZXJzKS5cbiAgICB0aGlzLnRydXN0ZWQgPSBudWxsO1xuXG4gICAgLy8gTG9jYWxseSBjYWNoZWQgZGF0YVxuICAgIC8vIFN1YnNjcmliZWQgdXNlcnMsIGZvciB0cmFja2luZyByZWFkL3JlY3YvbXNnIG5vdGlmaWNhdGlvbnMuXG4gICAgdGhpcy5fdXNlcnMgPSB7fTtcblxuICAgIC8vIEN1cnJlbnQgdmFsdWUgb2YgbG9jYWxseSBpc3N1ZWQgc2VxSWQsIHVzZWQgZm9yIHBlbmRpbmcgbWVzc2FnZXMuXG4gICAgdGhpcy5fcXVldWVkU2VxSWQgPSBDb25zdC5MT0NBTF9TRVFJRDtcblxuICAgIC8vIFRoZSBtYXhpbXVtIGtub3duIHtkYXRhLnNlcX0gdmFsdWUuXG4gICAgdGhpcy5fbWF4U2VxID0gMDtcbiAgICAvLyBUaGUgbWluaW11bSBrbm93biB7ZGF0YS5zZXF9IHZhbHVlLlxuICAgIHRoaXMuX21pblNlcSA9IDA7XG4gICAgLy8gSW5kaWNhdG9yIHRoYXQgdGhlIGxhc3QgcmVxdWVzdCBmb3IgZWFybGllciBtZXNzYWdlcyByZXR1cm5lZCAwLlxuICAgIHRoaXMuX25vRWFybGllck1zZ3MgPSBmYWxzZTtcbiAgICAvLyBUaGUgbWF4aW11bSBrbm93biBkZWxldGlvbiBJRC5cbiAgICB0aGlzLl9tYXhEZWwgPSAwO1xuICAgIC8vIFRpbWVyIG9iamVjdCB1c2VkIHRvIHNlbmQgJ3JlY3YnIG5vdGlmaWNhdGlvbnMuXG4gICAgdGhpcy5fcmVjdk5vdGlmaWNhdGlvblRpbWVyID0gbnVsbDtcblxuICAgIC8vIFVzZXIgZGlzY292ZXJ5IHRhZ3NcbiAgICB0aGlzLl90YWdzID0gW107XG4gICAgLy8gQ3JlZGVudGlhbHMgc3VjaCBhcyBlbWFpbCBvciBwaG9uZSBudW1iZXIuXG4gICAgdGhpcy5fY3JlZGVudGlhbHMgPSBbXTtcbiAgICAvLyBNZXNzYWdlIHZlcnNpb25zIGNhY2hlIChlLmcuIGZvciBlZGl0ZWQgbWVzc2FnZXMpLlxuICAgIC8vIEtleXM6IG9yaWdpbmFsIG1lc3NhZ2Ugc2VxIGlkcy5cbiAgICAvLyBWYWx1ZXM6IENCdWZmZXJzIGNvbnRhaW5pbmcgbmV3ZXIgdmVyc2lvbnMgb2YgdGhlIG9yaWdpbmFsIG1lc3NhZ2VcbiAgICAvLyBvcmRlcmVkIGJ5IHNlcSBpZC5cbiAgICB0aGlzLl9tZXNzYWdlVmVyc2lvbnMgPSB7fTtcbiAgICAvLyBNZXNzYWdlIGNhY2hlLCBzb3J0ZWQgYnkgbWVzc2FnZSBzZXEgdmFsdWVzLCBmcm9tIG9sZCB0byBuZXcuXG4gICAgdGhpcy5fbWVzc2FnZXMgPSBuZXcgQ0J1ZmZlcigoYSwgYikgPT4ge1xuICAgICAgcmV0dXJuIGEuc2VxIC0gYi5zZXE7XG4gICAgfSwgdHJ1ZSk7XG4gICAgLy8gQm9vbGVhbiwgdHJ1ZSBpZiB0aGUgdG9waWMgaXMgY3VycmVudGx5IGxpdmVcbiAgICB0aGlzLl9hdHRhY2hlZCA9IGZhbHNlO1xuICAgIC8vIFRpbWVzdGFwIG9mIHRoZSBtb3N0IHJlY2VudGx5IHVwZGF0ZWQgc3Vic2NyaXB0aW9uLlxuICAgIHRoaXMuX2xhc3RTdWJzVXBkYXRlID0gbmV3IERhdGUoMCk7XG4gICAgLy8gVG9waWMgY3JlYXRlZCBidXQgbm90IHlldCBzeW5jZWQgd2l0aCB0aGUgc2VydmVyLiBVc2VkIG9ubHkgZHVyaW5nIGluaXRpYWxpemF0aW9uLlxuICAgIHRoaXMuX25ldyA9IHRydWU7XG4gICAgLy8gVGhlIHRvcGljIGlzIGRlbGV0ZWQgYXQgdGhlIHNlcnZlciwgdGhpcyBpcyBhIGxvY2FsIGNvcHkuXG4gICAgdGhpcy5fZGVsZXRlZCA9IGZhbHNlO1xuXG4gICAgLy8gVGltZXIgdXNlZCB0byB0cmdnZXIge2xlYXZlfSByZXF1ZXN0IGFmdGVyIGEgZGVsYXkuXG4gICAgdGhpcy5fZGVsYXllZExlYXZlVGltZXIgPSBudWxsO1xuXG4gICAgLy8gQ2FsbGJhY2tzXG4gICAgaWYgKGNhbGxiYWNrcykge1xuICAgICAgdGhpcy5vbkRhdGEgPSBjYWxsYmFja3Mub25EYXRhO1xuICAgICAgdGhpcy5vbk1ldGEgPSBjYWxsYmFja3Mub25NZXRhO1xuICAgICAgdGhpcy5vblByZXMgPSBjYWxsYmFja3Mub25QcmVzO1xuICAgICAgdGhpcy5vbkluZm8gPSBjYWxsYmFja3Mub25JbmZvO1xuICAgICAgLy8gQSBzaW5nbGUgZGVzYyB1cGRhdGU7XG4gICAgICB0aGlzLm9uTWV0YURlc2MgPSBjYWxsYmFja3Mub25NZXRhRGVzYztcbiAgICAgIC8vIEEgc2luZ2xlIHN1YnNjcmlwdGlvbiByZWNvcmQ7XG4gICAgICB0aGlzLm9uTWV0YVN1YiA9IGNhbGxiYWNrcy5vbk1ldGFTdWI7XG4gICAgICAvLyBBbGwgc3Vic2NyaXB0aW9uIHJlY29yZHMgcmVjZWl2ZWQ7XG4gICAgICB0aGlzLm9uU3Vic1VwZGF0ZWQgPSBjYWxsYmFja3Mub25TdWJzVXBkYXRlZDtcbiAgICAgIHRoaXMub25UYWdzVXBkYXRlZCA9IGNhbGxiYWNrcy5vblRhZ3NVcGRhdGVkO1xuICAgICAgdGhpcy5vbkNyZWRzVXBkYXRlZCA9IGNhbGxiYWNrcy5vbkNyZWRzVXBkYXRlZDtcbiAgICAgIHRoaXMub25EZWxldGVUb3BpYyA9IGNhbGxiYWNrcy5vbkRlbGV0ZVRvcGljO1xuICAgICAgdGhpcy5vbkFsbE1lc3NhZ2VzUmVjZWl2ZWQgPSBjYWxsYmFja3Mub25BbGxNZXNzYWdlc1JlY2VpdmVkO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN0YXRpYyBtZXRob2RzLlxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgdG9waWMgdHlwZSBmcm9tIHRvcGljJ3MgbmFtZTogZ3JwLCBwMnAsIG1lLCBmbmQsIHN5cy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICogQHN0YXRpY1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIHRlc3QuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IE9uZSBvZiA8Y29kZT5cIm1lXCI8L2NvZGU+LCA8Y29kZT5cImZuZFwiPC9jb2RlPiwgPGNvZGU+XCJzeXNcIjwvY29kZT4sIDxjb2RlPlwiZ3JwXCI8L2NvZGU+LFxuICAgKiAgICA8Y29kZT5cInAycFwiPC9jb2RlPiBvciA8Y29kZT51bmRlZmluZWQ8L2NvZGU+LlxuICAgKi9cbiAgc3RhdGljIHRvcGljVHlwZShuYW1lKSB7XG4gICAgY29uc3QgdHlwZXMgPSB7XG4gICAgICAnbWUnOiBDb25zdC5UT1BJQ19NRSxcbiAgICAgICdmbmQnOiBDb25zdC5UT1BJQ19GTkQsXG4gICAgICAnZ3JwJzogQ29uc3QuVE9QSUNfR1JQLFxuICAgICAgJ25ldyc6IENvbnN0LlRPUElDX0dSUCxcbiAgICAgICduY2gnOiBDb25zdC5UT1BJQ19HUlAsXG4gICAgICAnY2huJzogQ29uc3QuVE9QSUNfR1JQLFxuICAgICAgJ3Vzcic6IENvbnN0LlRPUElDX1AyUCxcbiAgICAgICdzeXMnOiBDb25zdC5UT1BJQ19TWVNcbiAgICB9O1xuICAgIHJldHVybiB0eXBlc1sodHlwZW9mIG5hbWUgPT0gJ3N0cmluZycpID8gbmFtZS5zdWJzdHJpbmcoMCwgMykgOiAneHh4J107XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIGdpdmVuIHRvcGljIG5hbWUgaXMgYSBuYW1lIG9mIGEgJ21lJyB0b3BpYy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICogQHN0YXRpY1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE5hbWUgb2YgdGhlIHRvcGljIHRvIHRlc3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbmFtZSBpcyBhIG5hbWUgb2YgYSAnbWUnIHRvcGljLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxuICAgKi9cbiAgc3RhdGljIGlzTWVUb3BpY05hbWUobmFtZSkge1xuICAgIHJldHVybiBUb3BpYy50b3BpY1R5cGUobmFtZSkgPT0gQ29uc3QuVE9QSUNfTUU7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIGdpdmVuIHRvcGljIG5hbWUgaXMgYSBuYW1lIG9mIGEgZ3JvdXAgdG9waWMuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqIEBzdGF0aWNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSB0b3BpYyB0byB0ZXN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5hbWUgaXMgYSBuYW1lIG9mIGEgZ3JvdXAgdG9waWMsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuXG4gICAqL1xuICBzdGF0aWMgaXNHcm91cFRvcGljTmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIFRvcGljLnRvcGljVHlwZShuYW1lKSA9PSBDb25zdC5UT1BJQ19HUlA7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIGdpdmVuIHRvcGljIG5hbWUgaXMgYSBuYW1lIG9mIGEgcDJwIHRvcGljLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKiBAc3RhdGljXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTmFtZSBvZiB0aGUgdG9waWMgdG8gdGVzdC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBuYW1lIGlzIGEgbmFtZSBvZiBhIHAycCB0b3BpYywgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cbiAgICovXG4gIHN0YXRpYyBpc1AyUFRvcGljTmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIFRvcGljLnRvcGljVHlwZShuYW1lKSA9PSBDb25zdC5UT1BJQ19QMlA7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIGdpdmVuIHRvcGljIG5hbWUgaXMgYSBuYW1lIG9mIGEgY29tbXVuaWNhdGlvbiB0b3BpYywgaS5lLiBQMlAgb3IgZ3JvdXAuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqIEBzdGF0aWNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSB0b3BpYyB0byB0ZXN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG5hbWUgaXMgYSBuYW1lIG9mIGEgcDJwIG9yIGdyb3VwIHRvcGljLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxuICAgKi9cbiAgc3RhdGljIGlzQ29tbVRvcGljTmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIFRvcGljLmlzUDJQVG9waWNOYW1lKG5hbWUpIHx8IFRvcGljLmlzR3JvdXBUb3BpY05hbWUobmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIHRvcGljIG5hbWUgaXMgYSBuYW1lIG9mIGEgbmV3IHRvcGljLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKiBAc3RhdGljXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gdG9waWMgbmFtZSB0byBjaGVjay5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBuYW1lIGlzIGEgbmFtZSBvZiBhIG5ldyB0b3BpYywgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cbiAgICovXG4gIHN0YXRpYyBpc05ld0dyb3VwVG9waWNOYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBuYW1lID09ICdzdHJpbmcnKSAmJlxuICAgICAgKG5hbWUuc3Vic3RyaW5nKDAsIDMpID09IENvbnN0LlRPUElDX05FVyB8fCBuYW1lLnN1YnN0cmluZygwLCAzKSA9PSBDb25zdC5UT1BJQ19ORVdfQ0hBTik7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIHRvcGljIG5hbWUgaXMgYSBuYW1lIG9mIGEgY2hhbm5lbC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICogQHN0YXRpY1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIHRvcGljIG5hbWUgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbmFtZSBpcyBhIG5hbWUgb2YgYSBjaGFubmVsLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxuICAgKi9cbiAgc3RhdGljIGlzQ2hhbm5lbFRvcGljTmFtZShuYW1lKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgbmFtZSA9PSAnc3RyaW5nJykgJiZcbiAgICAgIChuYW1lLnN1YnN0cmluZygwLCAzKSA9PSBDb25zdC5UT1BJQ19DSEFOIHx8IG5hbWUuc3Vic3RyaW5nKDAsIDMpID09IENvbnN0LlRPUElDX05FV19DSEFOKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGUgdG9waWMgaXMgc3Vic2NyaWJlZC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaXMgdG9waWMgaXMgYXR0YWNoZWQvc3Vic2NyaWJlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgaXNTdWJzY3JpYmVkKCkge1xuICAgIHJldHVybiB0aGlzLl9hdHRhY2hlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1ZXN0IHRvcGljIHRvIHN1YnNjcmliZS4gV3JhcHBlciBmb3Ige0BsaW5rIFRpbm9kZSNzdWJzY3JpYmV9LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge1Rpbm9kZS5HZXRRdWVyeT19IGdldFBhcmFtcyAtIGdldCBxdWVyeSBwYXJhbWV0ZXJzLlxuICAgKiBAcGFyYW0ge1Rpbm9kZS5TZXRQYXJhbXM9fSBzZXRQYXJhbXMgLSBzZXQgcGFyYW1ldGVycy5cbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdG8gYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgc2VydmVyIHJlc3BvbmRzIHRvIHRoZSByZXF1ZXN0LlxuICAgKi9cbiAgc3Vic2NyaWJlKGdldFBhcmFtcywgc2V0UGFyYW1zKSB7XG4gICAgLy8gQ2xlYXIgcmVxdWVzdCB0byBsZWF2ZSB0b3BpYy5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5fZGVsYXllZExlYXZlVGltZXIpO1xuICAgIHRoaXMuX2RlbGF5ZWRMZWF2ZVRpbWVyID0gbnVsbDtcblxuICAgIC8vIElmIHRoZSB0b3BpYyBpcyBhbHJlYWR5IHN1YnNjcmliZWQsIHJldHVybiByZXNvbHZlZCBwcm9taXNlXG4gICAgaWYgKHRoaXMuX2F0dGFjaGVkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSB0b3BpYyBpcyBkZWxldGVkLCByZWplY3Qgc3Vic2NyaXB0aW9uIHJlcXVlc3RzLlxuICAgIGlmICh0aGlzLl9kZWxldGVkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQ29udmVyc2F0aW9uIGRlbGV0ZWRcIikpO1xuICAgIH1cblxuICAgIC8vIFNlbmQgc3Vic2NyaWJlIG1lc3NhZ2UsIGhhbmRsZSBhc3luYyByZXNwb25zZS5cbiAgICAvLyBJZiB0b3BpYyBuYW1lIGlzIGV4cGxpY2l0bHkgcHJvdmlkZWQsIHVzZSBpdC4gSWYgbm8gbmFtZSwgdGhlbiBpdCdzIGEgbmV3IGdyb3VwIHRvcGljLFxuICAgIC8vIHVzZSBcIm5ld1wiLlxuICAgIHJldHVybiB0aGlzLl90aW5vZGUuc3Vic2NyaWJlKHRoaXMubmFtZSB8fCBDb25zdC5UT1BJQ19ORVcsIGdldFBhcmFtcywgc2V0UGFyYW1zKS50aGVuKChjdHJsKSA9PiB7XG4gICAgICBpZiAoY3RybC5jb2RlID49IDMwMCkge1xuICAgICAgICAvLyBEbyBub3RoaW5nIGlmIHN1YnNjcmlwdGlvbiBzdGF0dXMgaGFzIG5vdCBjaGFuZ2VkLlxuICAgICAgICByZXR1cm4gY3RybDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fYXR0YWNoZWQgPSB0cnVlO1xuICAgICAgdGhpcy5fZGVsZXRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5hY3MgPSAoY3RybC5wYXJhbXMgJiYgY3RybC5wYXJhbXMuYWNzKSA/IGN0cmwucGFyYW1zLmFjcyA6IHRoaXMuYWNzO1xuXG4gICAgICAvLyBTZXQgdG9waWMgbmFtZSBmb3IgbmV3IHRvcGljcyBhbmQgYWRkIGl0IHRvIGNhY2hlLlxuICAgICAgaWYgKHRoaXMuX25ldykge1xuICAgICAgICBkZWxldGUgdGhpcy5fbmV3O1xuXG4gICAgICAgIGlmICh0aGlzLm5hbWUgIT0gY3RybC50b3BpYykge1xuICAgICAgICAgIC8vIE5hbWUgbWF5IGNoYW5nZSBuZXcxMjM0NTYgLT4gZ3JwQWJDZEVmLiBSZW1vdmUgZnJvbSBjYWNoZSB1bmRlciB0aGUgb2xkIG5hbWUuXG4gICAgICAgICAgdGhpcy5fY2FjaGVEZWxTZWxmKCk7XG4gICAgICAgICAgdGhpcy5uYW1lID0gY3RybC50b3BpYztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9jYWNoZVB1dFNlbGYoKTtcblxuICAgICAgICB0aGlzLmNyZWF0ZWQgPSBjdHJsLnRzO1xuICAgICAgICB0aGlzLnVwZGF0ZWQgPSBjdHJsLnRzO1xuXG4gICAgICAgIGlmICh0aGlzLm5hbWUgIT0gQ29uc3QuVE9QSUNfTUUgJiYgdGhpcy5uYW1lICE9IENvbnN0LlRPUElDX0ZORCkge1xuICAgICAgICAgIC8vIEFkZCB0aGUgbmV3IHRvcGljIHRvIHRoZSBsaXN0IG9mIGNvbnRhY3RzIG1haW50YWluZWQgYnkgdGhlICdtZScgdG9waWMuXG4gICAgICAgICAgY29uc3QgbWUgPSB0aGlzLl90aW5vZGUuZ2V0TWVUb3BpYygpO1xuICAgICAgICAgIGlmIChtZS5vbk1ldGFTdWIpIHtcbiAgICAgICAgICAgIG1lLm9uTWV0YVN1Yih0aGlzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG1lLm9uU3Vic1VwZGF0ZWQpIHtcbiAgICAgICAgICAgIG1lLm9uU3Vic1VwZGF0ZWQoW3RoaXMubmFtZV0sIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZXRQYXJhbXMgJiYgc2V0UGFyYW1zLmRlc2MpIHtcbiAgICAgICAgICBzZXRQYXJhbXMuZGVzYy5fbm9Gb3J3YXJkaW5nID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLl9wcm9jZXNzTWV0YURlc2Moc2V0UGFyYW1zLmRlc2MpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gY3RybDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBkcmFmdCBvZiBhIG1lc3NhZ2Ugd2l0aG91dCBzZW5kaW5nIGl0IHRvIHRoZSBzZXJ2ZXIuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgT2JqZWN0fSBkYXRhIC0gQ29udGVudCB0byB3cmFwIGluIGEgZHJhZnQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vRWNobyAtIElmIDxjb2RlPnRydWU8L2NvZGU+IHNlcnZlciB3aWxsIG5vdCBlY2hvIG1lc3NhZ2UgYmFjayB0byBvcmlnaW5hdGluZ1xuICAgKiBzZXNzaW9uLiBPdGhlcndpc2UgdGhlIHNlcnZlciB3aWxsIHNlbmQgYSBjb3B5IG9mIHRoZSBtZXNzYWdlIHRvIHNlbmRlci5cbiAgICpcbiAgICogQHJldHVybnMge09iamVjdH0gbWVzc2FnZSBkcmFmdC5cbiAgICovXG4gIGNyZWF0ZU1lc3NhZ2UoZGF0YSwgbm9FY2hvKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Rpbm9kZS5jcmVhdGVNZXNzYWdlKHRoaXMubmFtZSwgZGF0YSwgbm9FY2hvKTtcbiAgfVxuICAvKipcbiAgICogSW1tZWRpYXRlbHkgcHVibGlzaCBkYXRhIHRvIHRvcGljLiBXcmFwcGVyIGZvciB7QGxpbmsgVGlub2RlI3B1Ymxpc2h9LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IE9iamVjdH0gZGF0YSAtIERhdGEgdG8gcHVibGlzaCwgZWl0aGVyIHBsYWluIHN0cmluZyBvciBhIERyYWZ0eSBvYmplY3QuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vRWNobyAtIElmIDxjb2RlPnRydWU8L2NvZGU+IHNlcnZlciB3aWxsIG5vdCBlY2hvIG1lc3NhZ2UgYmFjayB0byBvcmlnaW5hdGluZ1xuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB0byBiZSByZXNvbHZlZC9yZWplY3RlZCB3aGVuIHRoZSBzZXJ2ZXIgcmVzcG9uZHMgdG8gdGhlIHJlcXVlc3QuXG4gICAqL1xuICBwdWJsaXNoKGRhdGEsIG5vRWNobykge1xuICAgIHJldHVybiB0aGlzLnB1Ymxpc2hNZXNzYWdlKHRoaXMuY3JlYXRlTWVzc2FnZShkYXRhLCBub0VjaG8pKTtcbiAgfVxuICAvKipcbiAgICogUHVibGlzaCBtZXNzYWdlIGNyZWF0ZWQgYnkge0BsaW5rIFRpbm9kZS5Ub3BpYyNjcmVhdGVNZXNzYWdlfS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHB1YiAtIHtkYXRhfSBvYmplY3QgdG8gcHVibGlzaC4gTXVzdCBiZSBjcmVhdGVkIGJ5IHtAbGluayBUaW5vZGUuVG9waWMjY3JlYXRlTWVzc2FnZX1cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdG8gYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgc2VydmVyIHJlc3BvbmRzIHRvIHRoZSByZXF1ZXN0LlxuICAgKi9cbiAgcHVibGlzaE1lc3NhZ2UocHViKSB7XG4gICAgaWYgKCF0aGlzLl9hdHRhY2hlZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkNhbm5vdCBwdWJsaXNoIG9uIGluYWN0aXZlIHRvcGljXCIpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX3NlbmRpbmcpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJUaGUgbWVzc2FnZSBpcyBhbHJlYWR5IGJlaW5nIHNlbnRcIikpO1xuICAgIH1cblxuICAgIC8vIFNlbmQgZGF0YS5cbiAgICBwdWIuX3NlbmRpbmcgPSB0cnVlO1xuICAgIHB1Yi5fZmFpbGVkID0gZmFsc2U7XG5cbiAgICAvLyBFeHRyYWN0IHJlZmVyZWNlcyB0byBhdHRhY2htZW50cyBhbmQgb3V0IG9mIGJhbmQgaW1hZ2UgcmVjb3Jkcy5cbiAgICBsZXQgYXR0YWNobWVudHMgPSBudWxsO1xuICAgIGlmIChEcmFmdHkuaGFzRW50aXRpZXMocHViLmNvbnRlbnQpKSB7XG4gICAgICBhdHRhY2htZW50cyA9IFtdO1xuICAgICAgRHJhZnR5LmVudGl0aWVzKHB1Yi5jb250ZW50LCAoZGF0YSkgPT4ge1xuICAgICAgICBpZiAoZGF0YSAmJiBkYXRhLnJlZikge1xuICAgICAgICAgIGF0dGFjaG1lbnRzLnB1c2goZGF0YS5yZWYpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChhdHRhY2htZW50cy5sZW5ndGggPT0gMCkge1xuICAgICAgICBhdHRhY2htZW50cyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3Rpbm9kZS5wdWJsaXNoTWVzc2FnZShwdWIsIGF0dGFjaG1lbnRzKS50aGVuKChjdHJsKSA9PiB7XG4gICAgICBwdWIuX3NlbmRpbmcgPSBmYWxzZTtcbiAgICAgIHB1Yi50cyA9IGN0cmwudHM7XG4gICAgICB0aGlzLnN3YXBNZXNzYWdlSWQocHViLCBjdHJsLnBhcmFtcy5zZXEpO1xuICAgICAgdGhpcy5fcm91dGVEYXRhKHB1Yik7XG4gICAgICByZXR1cm4gY3RybDtcbiAgICB9KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICB0aGlzLl90aW5vZGUubG9nZ2VyKFwiV0FSTklORzogTWVzc2FnZSByZWplY3RlZCBieSB0aGUgc2VydmVyXCIsIGVycik7XG4gICAgICBwdWIuX3NlbmRpbmcgPSBmYWxzZTtcbiAgICAgIHB1Yi5fZmFpbGVkID0gdHJ1ZTtcbiAgICAgIGlmICh0aGlzLm9uRGF0YSkge1xuICAgICAgICB0aGlzLm9uRGF0YSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgbWVzc2FnZSB0byBsb2NhbCBtZXNzYWdlIGNhY2hlLCBzZW5kIHRvIHRoZSBzZXJ2ZXIgd2hlbiB0aGUgcHJvbWlzZSBpcyByZXNvbHZlZC5cbiAgICogSWYgcHJvbWlzZSBpcyBudWxsIG9yIHVuZGVmaW5lZCwgdGhlIG1lc3NhZ2Ugd2lsbCBiZSBzZW50IGltbWVkaWF0ZWx5LlxuICAgKiBUaGUgbWVzc2FnZSBpcyBzZW50IHdoZW4gdGhlXG4gICAqIFRoZSBtZXNzYWdlIHNob3VsZCBiZSBjcmVhdGVkIGJ5IHtAbGluayBUaW5vZGUuVG9waWMjY3JlYXRlTWVzc2FnZX0uXG4gICAqIFRoaXMgaXMgcHJvYmFibHkgbm90IHRoZSBmaW5hbCBBUEkuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwdWIgLSBNZXNzYWdlIHRvIHVzZSBhcyBhIGRyYWZ0LlxuICAgKiBAcGFyYW0ge1Byb21pc2V9IHByb20gLSBNZXNzYWdlIHdpbGwgYmUgc2VudCB3aGVuIHRoaXMgcHJvbWlzZSBpcyByZXNvbHZlZCwgZGlzY2FyZGVkIGlmIHJlamVjdGVkLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gZGVyaXZlZCBwcm9taXNlLlxuICAgKi9cbiAgcHVibGlzaERyYWZ0KHB1YiwgcHJvbSkge1xuICAgIGNvbnN0IHNlcSA9IHB1Yi5zZXEgfHwgdGhpcy5fZ2V0UXVldWVkU2VxSWQoKTtcbiAgICBpZiAoIXB1Yi5fbm9Gb3J3YXJkaW5nKSB7XG4gICAgICAvLyBUaGUgJ3NlcScsICd0cycsIGFuZCAnZnJvbScgYXJlIGFkZGVkIHRvIG1pbWljIHtkYXRhfS4gVGhleSBhcmUgcmVtb3ZlZCBsYXRlclxuICAgICAgLy8gYmVmb3JlIHRoZSBtZXNzYWdlIGlzIHNlbnQuXG4gICAgICBwdWIuX25vRm9yd2FyZGluZyA9IHRydWU7XG4gICAgICBwdWIuc2VxID0gc2VxO1xuICAgICAgcHViLnRzID0gbmV3IERhdGUoKTtcbiAgICAgIHB1Yi5mcm9tID0gdGhpcy5fdGlub2RlLmdldEN1cnJlbnRVc2VySUQoKTtcblxuICAgICAgLy8gRG9uJ3QgbmVlZCBhbiBlY2hvIG1lc3NhZ2UgYmVjYXVzZSB0aGUgbWVzc2FnZSBpcyBhZGRlZCB0byBsb2NhbCBjYWNoZSByaWdodCBhd2F5LlxuICAgICAgcHViLm5vZWNobyA9IHRydWU7XG4gICAgICAvLyBBZGQgdG8gY2FjaGUuXG4gICAgICB0aGlzLl9tZXNzYWdlcy5wdXQocHViKTtcbiAgICAgIHRoaXMuX3Rpbm9kZS5fZGIuYWRkTWVzc2FnZShwdWIpO1xuXG4gICAgICBpZiAodGhpcy5vbkRhdGEpIHtcbiAgICAgICAgdGhpcy5vbkRhdGEocHViKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gSWYgcHJvbWlzZSBpcyBwcm92aWRlZCwgc2VuZCB0aGUgcXVldWVkIG1lc3NhZ2Ugd2hlbiBpdCdzIHJlc29sdmVkLlxuICAgIC8vIElmIG5vIHByb21pc2UgaXMgcHJvdmlkZWQsIGNyZWF0ZSBhIHJlc29sdmVkIG9uZSBhbmQgc2VuZCBpbW1lZGlhdGVseS5cbiAgICByZXR1cm4gKHByb20gfHwgUHJvbWlzZS5yZXNvbHZlKCkpXG4gICAgICAudGhlbihfID0+IHtcbiAgICAgICAgaWYgKHB1Yi5fY2FuY2VsbGVkKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvZGU6IDMwMCxcbiAgICAgICAgICAgIHRleHQ6IFwiY2FuY2VsbGVkXCJcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnB1Ymxpc2hNZXNzYWdlKHB1Yik7XG4gICAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgICB0aGlzLl90aW5vZGUubG9nZ2VyKFwiV0FSTklORzogTWVzc2FnZSBkcmFmdCByZWplY3RlZFwiLCBlcnIpO1xuICAgICAgICBwdWIuX3NlbmRpbmcgPSBmYWxzZTtcbiAgICAgICAgcHViLl9mYWlsZWQgPSB0cnVlO1xuICAgICAgICBpZiAodGhpcy5vbkRhdGEpIHtcbiAgICAgICAgICB0aGlzLm9uRGF0YSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJldGhyb3cgdG8gbGV0IGNhbGxlciBrbm93IHRoYXQgdGhlIG9wZXJhdGlvbiBmYWlsZWQuXG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExlYXZlIHRoZSB0b3BpYywgb3B0aW9uYWxseSB1bnNpYnNjcmliZS4gTGVhdmluZyB0aGUgdG9waWMgbWVhbnMgdGhlIHRvcGljIHdpbGwgc3RvcFxuICAgKiByZWNlaXZpbmcgdXBkYXRlcyBmcm9tIHRoZSBzZXJ2ZXIuIFVuc3Vic2NyaWJpbmcgd2lsbCB0ZXJtaW5hdGUgdXNlcidzIHJlbGF0aW9uc2hpcCB3aXRoIHRoZSB0b3BpYy5cbiAgICogV3JhcHBlciBmb3Ige0BsaW5rIFRpbm9kZSNsZWF2ZX0uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc3ViIC0gSWYgdHJ1ZSwgdW5zdWJzY3JpYmUsIG90aGVyd2lzZSBqdXN0IGxlYXZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB0byBiZSByZXNvbHZlZC9yZWplY3RlZCB3aGVuIHRoZSBzZXJ2ZXIgcmVzcG9uZHMgdG8gdGhlIHJlcXVlc3QuXG4gICAqL1xuICBsZWF2ZSh1bnN1Yikge1xuICAgIC8vIEl0J3MgcG9zc2libGUgdG8gdW5zdWJzY3JpYmUgKHVuc3ViPT10cnVlKSBmcm9tIGluYWN0aXZlIHRvcGljLlxuICAgIGlmICghdGhpcy5fYXR0YWNoZWQgJiYgIXVuc3ViKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQ2Fubm90IGxlYXZlIGluYWN0aXZlIHRvcGljXCIpKTtcbiAgICB9XG5cbiAgICAvLyBTZW5kIGEgJ2xlYXZlJyBtZXNzYWdlLCBoYW5kbGUgYXN5bmMgcmVzcG9uc2VcbiAgICByZXR1cm4gdGhpcy5fdGlub2RlLmxlYXZlKHRoaXMubmFtZSwgdW5zdWIpLnRoZW4oKGN0cmwpID0+IHtcbiAgICAgIHRoaXMuX3Jlc2V0U3ViKCk7XG4gICAgICBpZiAodW5zdWIpIHtcbiAgICAgICAgdGhpcy5fZ29uZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGN0cmw7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTGVhdmUgdGhlIHRvcGljLCBvcHRpb25hbGx5IHVuc2lic2NyaWJlIGFmdGVyIGEgZGVsYXkuIExlYXZpbmcgdGhlIHRvcGljIG1lYW5zIHRoZSB0b3BpYyB3aWxsIHN0b3BcbiAgICogcmVjZWl2aW5nIHVwZGF0ZXMgZnJvbSB0aGUgc2VydmVyLiBVbnN1YnNjcmliaW5nIHdpbGwgdGVybWluYXRlIHVzZXIncyByZWxhdGlvbnNoaXAgd2l0aCB0aGUgdG9waWMuXG4gICAqIFdyYXBwZXIgZm9yIHtAbGluayBUaW5vZGUjbGVhdmV9LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHVuc3ViIC0gSWYgdHJ1ZSwgdW5zdWJzY3JpYmUsIG90aGVyd2lzZSBqdXN0IGxlYXZlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVsYXkgLSB0aW1lIGluIG1pbGxpc2Vjb25kcyB0byBkZWxheSBsZWF2ZSByZXF1ZXN0LlxuICAgKi9cbiAgbGVhdmVEZWxheWVkKHVuc3ViLCBkZWxheSkge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLl9kZWxheWVkTGVhdmVUaW1lcik7XG4gICAgdGhpcy5fZGVsYXllZExlYXZlVGltZXIgPSBzZXRUaW1lb3V0KF8gPT4ge1xuICAgICAgdGhpcy5fZGVsYXllZExlYXZlVGltZXIgPSBudWxsO1xuICAgICAgdGhpcy5sZWF2ZSh1bnN1YilcbiAgICB9LCBkZWxheSk7XG4gIH1cblxuICAvKipcbiAgICogUmVxdWVzdCB0b3BpYyBtZXRhZGF0YSBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7VGlub2RlLkdldFF1ZXJ5fSByZXF1ZXN0IHBhcmFtZXRlcnNcbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdG8gYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgc2VydmVyIHJlc3BvbmRzIHRvIHJlcXVlc3QuXG4gICAqL1xuICBnZXRNZXRhKHBhcmFtcykge1xuICAgIC8vIFNlbmQge2dldH0gbWVzc2FnZSwgcmV0dXJuIHByb21pc2UuXG4gICAgcmV0dXJuIHRoaXMuX3Rpbm9kZS5nZXRNZXRhKHRoaXMubmFtZSwgcGFyYW1zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1ZXN0IG1vcmUgbWVzc2FnZXMgZnJvbSB0aGUgc2VydmVyXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBsaW1pdCBudW1iZXIgb2YgbWVzc2FnZXMgdG8gZ2V0LlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZvcndhcmQgaWYgdHJ1ZSwgcmVxdWVzdCBuZXdlciBtZXNzYWdlcy5cbiAgICovXG4gIGdldE1lc3NhZ2VzUGFnZShsaW1pdCwgZm9yd2FyZCkge1xuICAgIGxldCBxdWVyeSA9IGZvcndhcmQgP1xuICAgICAgdGhpcy5zdGFydE1ldGFRdWVyeSgpLndpdGhMYXRlckRhdGEobGltaXQpIDpcbiAgICAgIHRoaXMuc3RhcnRNZXRhUXVlcnkoKS53aXRoRWFybGllckRhdGEobGltaXQpO1xuXG4gICAgLy8gRmlyc3QgdHJ5IGZldGNoaW5nIGZyb20gREIsIHRoZW4gZnJvbSB0aGUgc2VydmVyLlxuICAgIHJldHVybiB0aGlzLl9sb2FkTWVzc2FnZXModGhpcy5fdGlub2RlLl9kYiwgcXVlcnkuZXh0cmFjdCgnZGF0YScpKVxuICAgICAgLnRoZW4oKGNvdW50KSA9PiB7XG4gICAgICAgIGlmIChjb3VudCA9PSBsaW1pdCkge1xuICAgICAgICAgIC8vIEdvdCBlbm91Z2ggbWVzc2FnZXMgZnJvbSBsb2NhbCBjYWNoZS5cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgIHRvcGljOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICBjb2RlOiAyMDAsXG4gICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgY291bnQ6IGNvdW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWR1Y2UgdGhlIGNvdW50IG9mIHJlcXVlc3RlZCBtZXNzYWdlcy5cbiAgICAgICAgbGltaXQgLT0gY291bnQ7XG4gICAgICAgIC8vIFVwZGF0ZSBxdWVyeSB3aXRoIG5ldyB2YWx1ZXMgbG9hZGVkIGZyb20gREIuXG4gICAgICAgIHF1ZXJ5ID0gZm9yd2FyZCA/IHRoaXMuc3RhcnRNZXRhUXVlcnkoKS53aXRoTGF0ZXJEYXRhKGxpbWl0KSA6XG4gICAgICAgICAgdGhpcy5zdGFydE1ldGFRdWVyeSgpLndpdGhFYXJsaWVyRGF0YShsaW1pdCk7XG4gICAgICAgIGxldCBwcm9taXNlID0gdGhpcy5nZXRNZXRhKHF1ZXJ5LmJ1aWxkKCkpO1xuICAgICAgICBpZiAoIWZvcndhcmQpIHtcbiAgICAgICAgICBwcm9taXNlID0gcHJvbWlzZS50aGVuKChjdHJsKSA9PiB7XG4gICAgICAgICAgICBpZiAoY3RybCAmJiBjdHJsLnBhcmFtcyAmJiAhY3RybC5wYXJhbXMuY291bnQpIHtcbiAgICAgICAgICAgICAgdGhpcy5fbm9FYXJsaWVyTXNncyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICB9KTtcbiAgfVxuICAvKipcbiAgICogVXBkYXRlIHRvcGljIG1ldGFkYXRhLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge1Rpbm9kZS5TZXRQYXJhbXN9IHBhcmFtcyBwYXJhbWV0ZXJzIHRvIHVwZGF0ZS5cbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdG8gYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgc2VydmVyIHJlc3BvbmRzIHRvIHJlcXVlc3QuXG4gICAqL1xuICBzZXRNZXRhKHBhcmFtcykge1xuICAgIGlmIChwYXJhbXMudGFncykge1xuICAgICAgcGFyYW1zLnRhZ3MgPSBub3JtYWxpemVBcnJheShwYXJhbXMudGFncyk7XG4gICAgfVxuICAgIC8vIFNlbmQgU2V0IG1lc3NhZ2UsIGhhbmRsZSBhc3luYyByZXNwb25zZS5cbiAgICByZXR1cm4gdGhpcy5fdGlub2RlLnNldE1ldGEodGhpcy5uYW1lLCBwYXJhbXMpXG4gICAgICAudGhlbigoY3RybCkgPT4ge1xuICAgICAgICBpZiAoY3RybCAmJiBjdHJsLmNvZGUgPj0gMzAwKSB7XG4gICAgICAgICAgLy8gTm90IG1vZGlmaWVkXG4gICAgICAgICAgcmV0dXJuIGN0cmw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFyYW1zLnN1Yikge1xuICAgICAgICAgIHBhcmFtcy5zdWIudG9waWMgPSB0aGlzLm5hbWU7XG4gICAgICAgICAgaWYgKGN0cmwucGFyYW1zICYmIGN0cmwucGFyYW1zLmFjcykge1xuICAgICAgICAgICAgcGFyYW1zLnN1Yi5hY3MgPSBjdHJsLnBhcmFtcy5hY3M7XG4gICAgICAgICAgICBwYXJhbXMuc3ViLnVwZGF0ZWQgPSBjdHJsLnRzO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIXBhcmFtcy5zdWIudXNlcikge1xuICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHN1YnNjcmlwdGlvbiB1cGRhdGUgb2YgdGhlIGN1cnJlbnQgdXNlci5cbiAgICAgICAgICAgIC8vIEFzc2lnbiB1c2VyIElEIG90aGVyd2lzZSB0aGUgdXBkYXRlIHdpbGwgYmUgaWdub3JlZCBieSBfcHJvY2Vzc01ldGFTdWIuXG4gICAgICAgICAgICBwYXJhbXMuc3ViLnVzZXIgPSB0aGlzLl90aW5vZGUuZ2V0Q3VycmVudFVzZXJJRCgpO1xuICAgICAgICAgICAgaWYgKCFwYXJhbXMuZGVzYykge1xuICAgICAgICAgICAgICAvLyBGb3JjZSB1cGRhdGUgdG8gdG9waWMncyBhc2MuXG4gICAgICAgICAgICAgIHBhcmFtcy5kZXNjID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHBhcmFtcy5zdWIuX25vRm9yd2FyZGluZyA9IHRydWU7XG4gICAgICAgICAgdGhpcy5fcHJvY2Vzc01ldGFTdWIoW3BhcmFtcy5zdWJdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJhbXMuZGVzYykge1xuICAgICAgICAgIGlmIChjdHJsLnBhcmFtcyAmJiBjdHJsLnBhcmFtcy5hY3MpIHtcbiAgICAgICAgICAgIHBhcmFtcy5kZXNjLmFjcyA9IGN0cmwucGFyYW1zLmFjcztcbiAgICAgICAgICAgIHBhcmFtcy5kZXNjLnVwZGF0ZWQgPSBjdHJsLnRzO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLl9wcm9jZXNzTWV0YURlc2MocGFyYW1zLmRlc2MpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcmFtcy50YWdzKSB7XG4gICAgICAgICAgdGhpcy5fcHJvY2Vzc01ldGFUYWdzKHBhcmFtcy50YWdzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyYW1zLmNyZWQpIHtcbiAgICAgICAgICB0aGlzLl9wcm9jZXNzTWV0YUNyZWRzKFtwYXJhbXMuY3JlZF0sIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGN0cmw7XG4gICAgICB9KTtcbiAgfVxuICAvKipcbiAgICogVXBkYXRlIGFjY2VzcyBtb2RlIG9mIHRoZSBjdXJyZW50IHVzZXIgb3Igb2YgYW5vdGhlciB0b3BpYyBzdWJzcmliZXIuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1aWQgLSBVSUQgb2YgdGhlIHVzZXIgdG8gdXBkYXRlIG9yIG51bGwgdG8gdXBkYXRlIGN1cnJlbnQgdXNlci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHVwZGF0ZSAtIHRoZSB1cGRhdGUgdmFsdWUsIGZ1bGwgb3IgZGVsdGEuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHRvIGJlIHJlc29sdmVkL3JlamVjdGVkIHdoZW4gdGhlIHNlcnZlciByZXNwb25kcyB0byByZXF1ZXN0LlxuICAgKi9cbiAgdXBkYXRlTW9kZSh1aWQsIHVwZGF0ZSkge1xuICAgIGNvbnN0IHVzZXIgPSB1aWQgPyB0aGlzLnN1YnNjcmliZXIodWlkKSA6IG51bGw7XG4gICAgY29uc3QgYW0gPSB1c2VyID9cbiAgICAgIHVzZXIuYWNzLnVwZGF0ZUdpdmVuKHVwZGF0ZSkuZ2V0R2l2ZW4oKSA6XG4gICAgICB0aGlzLmdldEFjY2Vzc01vZGUoKS51cGRhdGVXYW50KHVwZGF0ZSkuZ2V0V2FudCgpO1xuXG4gICAgcmV0dXJuIHRoaXMuc2V0TWV0YSh7XG4gICAgICBzdWI6IHtcbiAgICAgICAgdXNlcjogdWlkLFxuICAgICAgICBtb2RlOiBhbVxuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBDcmVhdGUgbmV3IHRvcGljIHN1YnNjcmlwdGlvbi4gV3JhcHBlciBmb3Ige0BsaW5rIFRpbm9kZSNzZXRNZXRhfS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVpZCAtIElEIG9mIHRoZSB1c2VyIHRvIGludml0ZVxuICAgKiBAcGFyYW0ge3N0cmluZz19IG1vZGUgLSBBY2Nlc3MgbW9kZS4gPGNvZGU+bnVsbDwvY29kZT4gbWVhbnMgdG8gdXNlIGRlZmF1bHQuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHRvIGJlIHJlc29sdmVkL3JlamVjdGVkIHdoZW4gdGhlIHNlcnZlciByZXNwb25kcyB0byByZXF1ZXN0LlxuICAgKi9cbiAgaW52aXRlKHVpZCwgbW9kZSkge1xuICAgIHJldHVybiB0aGlzLnNldE1ldGEoe1xuICAgICAgc3ViOiB7XG4gICAgICAgIHVzZXI6IHVpZCxcbiAgICAgICAgbW9kZTogbW9kZVxuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBBcmNoaXZlIG9yIHVuLWFyY2hpdmUgdGhlIHRvcGljLiBXcmFwcGVyIGZvciB7QGxpbmsgVGlub2RlI3NldE1ldGF9LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGFyY2ggLSB0cnVlIHRvIGFyY2hpdmUgdGhlIHRvcGljLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHRvIGJlIHJlc29sdmVkL3JlamVjdGVkIHdoZW4gdGhlIHNlcnZlciByZXNwb25kcyB0byByZXF1ZXN0LlxuICAgKi9cbiAgYXJjaGl2ZShhcmNoKSB7XG4gICAgaWYgKHRoaXMucHJpdmF0ZSAmJiAoIXRoaXMucHJpdmF0ZS5hcmNoID09ICFhcmNoKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShhcmNoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TWV0YSh7XG4gICAgICBkZXNjOiB7XG4gICAgICAgIHByaXZhdGU6IHtcbiAgICAgICAgICBhcmNoOiBhcmNoID8gdHJ1ZSA6IENvbnN0LkRFTF9DSEFSXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogRGVsZXRlIG1lc3NhZ2VzLiBIYXJkLWRlbGV0aW5nIG1lc3NhZ2VzIHJlcXVpcmVzIE93bmVyIHBlcm1pc3Npb24uXG4gICAqIFdyYXBwZXIgZm9yIHtAbGluayBUaW5vZGUjZGVsTWVzc2FnZXN9LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge1Rpbm9kZS5EZWxSYW5nZVtdfSByYW5nZXMgLSBSYW5nZXMgb2YgbWVzc2FnZSBJRHMgdG8gZGVsZXRlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBoYXJkIC0gSGFyZCBvciBzb2Z0IGRlbGV0ZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB0byBiZSByZXNvbHZlZC9yZWplY3RlZCB3aGVuIHRoZSBzZXJ2ZXIgcmVzcG9uZHMgdG8gcmVxdWVzdC5cbiAgICovXG4gIGRlbE1lc3NhZ2VzKHJhbmdlcywgaGFyZCkge1xuICAgIGlmICghdGhpcy5fYXR0YWNoZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJDYW5ub3QgZGVsZXRlIG1lc3NhZ2VzIGluIGluYWN0aXZlIHRvcGljXCIpKTtcbiAgICB9XG5cbiAgICAvLyBTb3J0IHJhbmdlcyBpbiBhY2NlbmRpbmcgb3JkZXIgYnkgbG93LCB0aGUgZGVzY2VuZGluZyBieSBoaS5cbiAgICByYW5nZXMuc29ydCgocjEsIHIyKSA9PiB7XG4gICAgICBpZiAocjEubG93IDwgcjIubG93KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHIxLmxvdyA9PSByMi5sb3cpIHtcbiAgICAgICAgcmV0dXJuICFyMi5oaSB8fCAocjEuaGkgPj0gcjIuaGkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuXG4gICAgLy8gUmVtb3ZlIHBlbmRpbmcgbWVzc2FnZXMgZnJvbSByYW5nZXMgcG9zc2libHkgY2xpcHBpbmcgc29tZSByYW5nZXMuXG4gICAgbGV0IHRvc2VuZCA9IHJhbmdlcy5yZWR1Y2UoKG91dCwgcikgPT4ge1xuICAgICAgaWYgKHIubG93IDwgQ29uc3QuTE9DQUxfU0VRSUQpIHtcbiAgICAgICAgaWYgKCFyLmhpIHx8IHIuaGkgPCBDb25zdC5MT0NBTF9TRVFJRCkge1xuICAgICAgICAgIG91dC5wdXNoKHIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIENsaXAgaGkgdG8gbWF4IGFsbG93ZWQgdmFsdWUuXG4gICAgICAgICAgb3V0LnB1c2goe1xuICAgICAgICAgICAgbG93OiByLmxvdyxcbiAgICAgICAgICAgIGhpOiB0aGlzLl9tYXhTZXEgKyAxXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfSwgW10pO1xuXG4gICAgLy8gU2VuZCB7ZGVsfSBtZXNzYWdlLCByZXR1cm4gcHJvbWlzZVxuICAgIGxldCByZXN1bHQ7XG4gICAgaWYgKHRvc2VuZC5sZW5ndGggPiAwKSB7XG4gICAgICByZXN1bHQgPSB0aGlzLl90aW5vZGUuZGVsTWVzc2FnZXModGhpcy5uYW1lLCB0b3NlbmQsIGhhcmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgPSBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBkZWw6IDBcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIFVwZGF0ZSBsb2NhbCBjYWNoZS5cbiAgICByZXR1cm4gcmVzdWx0LnRoZW4oKGN0cmwpID0+IHtcbiAgICAgIGlmIChjdHJsLnBhcmFtcy5kZWwgPiB0aGlzLl9tYXhEZWwpIHtcbiAgICAgICAgdGhpcy5fbWF4RGVsID0gY3RybC5wYXJhbXMuZGVsO1xuICAgICAgfVxuXG4gICAgICByYW5nZXMuZm9yRWFjaCgocikgPT4ge1xuICAgICAgICBpZiAoci5oaSkge1xuICAgICAgICAgIHRoaXMuZmx1c2hNZXNzYWdlUmFuZ2Uoci5sb3csIHIuaGkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZmx1c2hNZXNzYWdlKHIubG93KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuX3VwZGF0ZURlbGV0ZWRSYW5nZXMoKTtcblxuICAgICAgaWYgKHRoaXMub25EYXRhKSB7XG4gICAgICAgIC8vIENhbGxpbmcgd2l0aCBubyBwYXJhbWV0ZXJzIHRvIGluZGljYXRlIHRoZSBtZXNzYWdlcyB3ZXJlIGRlbGV0ZWQuXG4gICAgICAgIHRoaXMub25EYXRhKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3RybDtcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogRGVsZXRlIGFsbCBtZXNzYWdlcy4gSGFyZC1kZWxldGluZyBtZXNzYWdlcyByZXF1aXJlcyBPd25lciBwZXJtaXNzaW9uLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGhhcmREZWwgLSB0cnVlIGlmIG1lc3NhZ2VzIHNob3VsZCBiZSBoYXJkLWRlbGV0ZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHRvIGJlIHJlc29sdmVkL3JlamVjdGVkIHdoZW4gdGhlIHNlcnZlciByZXNwb25kcyB0byByZXF1ZXN0LlxuICAgKi9cbiAgZGVsTWVzc2FnZXNBbGwoaGFyZERlbCkge1xuICAgIGlmICghdGhpcy5fbWF4U2VxIHx8IHRoaXMuX21heFNlcSA8PSAwKSB7XG4gICAgICAvLyBUaGVyZSBhcmUgbm8gbWVzc2FnZXMgdG8gZGVsZXRlLlxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5kZWxNZXNzYWdlcyhbe1xuICAgICAgbG93OiAxLFxuICAgICAgaGk6IHRoaXMuX21heFNlcSArIDEsXG4gICAgICBfYWxsOiB0cnVlXG4gICAgfV0sIGhhcmREZWwpO1xuICB9XG4gIC8qKlxuICAgKiBEZWxldGUgbXVsdGlwbGUgbWVzc2FnZXMgZGVmaW5lZCBieSB0aGVpciBJRHMuIEhhcmQtZGVsZXRpbmcgbWVzc2FnZXMgcmVxdWlyZXMgT3duZXIgcGVybWlzc2lvbi5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtUaW5vZGUuRGVsUmFuZ2VbXX0gbGlzdCAtIGxpc3Qgb2Ygc2VxIElEcyB0byBkZWxldGVcbiAgICogQHBhcmFtIHtib29sZWFuPX0gaGFyZERlbCAtIHRydWUgaWYgbWVzc2FnZXMgc2hvdWxkIGJlIGhhcmQtZGVsZXRlZC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdG8gYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgc2VydmVyIHJlc3BvbmRzIHRvIHJlcXVlc3QuXG4gICAqL1xuICBkZWxNZXNzYWdlc0xpc3QobGlzdCwgaGFyZERlbCkge1xuICAgIC8vIFNvcnQgdGhlIGxpc3QgaW4gYXNjZW5kaW5nIG9yZGVyXG4gICAgbGlzdC5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG4gICAgLy8gQ29udmVydCB0aGUgYXJyYXkgb2YgSURzIHRvIHJhbmdlcy5cbiAgICBsZXQgcmFuZ2VzID0gbGlzdC5yZWR1Y2UoKG91dCwgaWQpID0+IHtcbiAgICAgIGlmIChvdXQubGVuZ3RoID09IDApIHtcbiAgICAgICAgLy8gRmlyc3QgZWxlbWVudC5cbiAgICAgICAgb3V0LnB1c2goe1xuICAgICAgICAgIGxvdzogaWRcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgcHJldiA9IG91dFtvdXQubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmICgoIXByZXYuaGkgJiYgKGlkICE9IHByZXYubG93ICsgMSkpIHx8IChpZCA+IHByZXYuaGkpKSB7XG4gICAgICAgICAgLy8gTmV3IHJhbmdlLlxuICAgICAgICAgIG91dC5wdXNoKHtcbiAgICAgICAgICAgIGxvdzogaWRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBFeHBhbmQgZXhpc3RpbmcgcmFuZ2UuXG4gICAgICAgICAgcHJldi5oaSA9IHByZXYuaGkgPyBNYXRoLm1heChwcmV2LmhpLCBpZCArIDEpIDogaWQgKyAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0O1xuICAgIH0sIFtdKTtcbiAgICAvLyBTZW5kIHtkZWx9IG1lc3NhZ2UsIHJldHVybiBwcm9taXNlXG4gICAgcmV0dXJuIHRoaXMuZGVsTWVzc2FnZXMocmFuZ2VzLCBoYXJkRGVsKTtcbiAgfVxuICAvKipcbiAgICogRGVsZXRlIHRvcGljLiBSZXF1aXJlcyBPd25lciBwZXJtaXNzaW9uLiBXcmFwcGVyIGZvciB7QGxpbmsgVGlub2RlI2RlbFRvcGljfS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufSBoYXJkIC0gaGFkLWRlbGV0ZSB0b3BpYy5cbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdG8gYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgc2VydmVyIHJlc3BvbmRzIHRvIHRoZSByZXF1ZXN0LlxuICAgKi9cbiAgZGVsVG9waWMoaGFyZCkge1xuICAgIGlmICh0aGlzLl9kZWxldGVkKSB7XG4gICAgICAvLyBUaGUgdG9waWMgaXMgYWxyZWFkeSBkZWxldGVkIGF0IHRoZSBzZXJ2ZXIsIGp1c3QgcmVtb3ZlIGZyb20gREIuXG4gICAgICB0aGlzLl9nb25lKCk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl90aW5vZGUuZGVsVG9waWModGhpcy5uYW1lLCBoYXJkKS50aGVuKChjdHJsKSA9PiB7XG4gICAgICB0aGlzLl9kZWxldGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMuX3Jlc2V0U3ViKCk7XG4gICAgICB0aGlzLl9nb25lKCk7XG4gICAgICByZXR1cm4gY3RybDtcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogRGVsZXRlIHN1YnNjcmlwdGlvbi4gUmVxdWlyZXMgU2hhcmUgcGVybWlzc2lvbi4gV3JhcHBlciBmb3Ige0BsaW5rIFRpbm9kZSNkZWxTdWJzY3JpcHRpb259LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlciAtIElEIG9mIHRoZSB1c2VyIHRvIHJlbW92ZSBzdWJzY3JpcHRpb24gZm9yLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB0byBiZSByZXNvbHZlZC9yZWplY3RlZCB3aGVuIHRoZSBzZXJ2ZXIgcmVzcG9uZHMgdG8gcmVxdWVzdC5cbiAgICovXG4gIGRlbFN1YnNjcmlwdGlvbih1c2VyKSB7XG4gICAgaWYgKCF0aGlzLl9hdHRhY2hlZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkNhbm5vdCBkZWxldGUgc3Vic2NyaXB0aW9uIGluIGluYWN0aXZlIHRvcGljXCIpKTtcbiAgICB9XG4gICAgLy8gU2VuZCB7ZGVsfSBtZXNzYWdlLCByZXR1cm4gcHJvbWlzZVxuICAgIHJldHVybiB0aGlzLl90aW5vZGUuZGVsU3Vic2NyaXB0aW9uKHRoaXMubmFtZSwgdXNlcikudGhlbigoY3RybCkgPT4ge1xuICAgICAgLy8gUmVtb3ZlIHRoZSBvYmplY3QgZnJvbSB0aGUgc3Vic2NyaXB0aW9uIGNhY2hlO1xuICAgICAgZGVsZXRlIHRoaXMuX3VzZXJzW3VzZXJdO1xuICAgICAgLy8gTm90aWZ5IGxpc3RlbmVyc1xuICAgICAgaWYgKHRoaXMub25TdWJzVXBkYXRlZCkge1xuICAgICAgICB0aGlzLm9uU3Vic1VwZGF0ZWQoT2JqZWN0LmtleXModGhpcy5fdXNlcnMpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjdHJsO1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBTZW5kIGEgcmVhZC9yZWN2IG5vdGlmaWNhdGlvbi5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHdoYXQgLSB3aGF0IG5vdGlmaWNhdGlvbiB0byBzZW5kOiA8Y29kZT5yZWN2PC9jb2RlPiwgPGNvZGU+cmVhZDwvY29kZT4uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzZXEgLSBJRCBvciB0aGUgbWVzc2FnZSByZWFkIG9yIHJlY2VpdmVkLlxuICAgKi9cbiAgbm90ZSh3aGF0LCBzZXEpIHtcbiAgICBpZiAoIXRoaXMuX2F0dGFjaGVkKSB7XG4gICAgICAvLyBDYW5ub3Qgc2VuZGluZyB7bm90ZX0gb24gYW4gaW5hY3RpdmUgdG9waWNcIi5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgbG9jYWwgY2FjaGUgd2l0aCB0aGUgbmV3IGNvdW50LlxuICAgIGNvbnN0IHVzZXIgPSB0aGlzLl91c2Vyc1t0aGlzLl90aW5vZGUuZ2V0Q3VycmVudFVzZXJJRCgpXTtcbiAgICBsZXQgdXBkYXRlID0gZmFsc2U7XG4gICAgaWYgKHVzZXIpIHtcbiAgICAgIC8vIFNlbGYtc3Vic2NyaXB0aW9uIGlzIGZvdW5kLlxuICAgICAgaWYgKCF1c2VyW3doYXRdIHx8IHVzZXJbd2hhdF0gPCBzZXEpIHtcbiAgICAgICAgdXNlclt3aGF0XSA9IHNlcTtcbiAgICAgICAgdXBkYXRlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2VsZi1zdWJzY3JpcHRpb24gaXMgbm90IGZvdW5kLlxuICAgICAgdXBkYXRlID0gKHRoaXNbd2hhdF0gfCAwKSA8IHNlcTtcbiAgICB9XG5cbiAgICBpZiAodXBkYXRlKSB7XG4gICAgICAvLyBTZW5kIG5vdGlmaWNhdGlvbiB0byB0aGUgc2VydmVyLlxuICAgICAgdGhpcy5fdGlub2RlLm5vdGUodGhpcy5uYW1lLCB3aGF0LCBzZXEpO1xuICAgICAgLy8gVXBkYXRlIGxvY2FsbHkgY2FjaGVkIGNvbnRhY3Qgd2l0aCB0aGUgbmV3IGNvdW50LlxuICAgICAgdGhpcy5fdXBkYXRlUmVhZFJlY3Yod2hhdCwgc2VxKTtcblxuICAgICAgaWYgKHRoaXMuYWNzICE9IG51bGwgJiYgIXRoaXMuYWNzLmlzTXV0ZWQoKSkge1xuICAgICAgICBjb25zdCBtZSA9IHRoaXMuX3Rpbm9kZS5nZXRNZVRvcGljKCk7XG4gICAgICAgIC8vIFNlbnQgYSBub3RpZmljYXRpb24gdG8gJ21lJyBsaXN0ZW5lcnMuXG4gICAgICAgIG1lLl9yZWZyZXNoQ29udGFjdCh3aGF0LCB0aGlzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBhICdyZWN2JyByZWNlaXB0LiBXcmFwcGVyIGZvciB7QGxpbmsgVGlub2RlI25vdGVSZWN2fS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNlcSAtIElEIG9mIHRoZSBtZXNzYWdlIHRvIGFrbm93bGVkZ2UuXG4gICAqL1xuICBub3RlUmVjdihzZXEpIHtcbiAgICB0aGlzLm5vdGUoJ3JlY3YnLCBzZXEpO1xuICB9XG4gIC8qKlxuICAgKiBTZW5kIGEgJ3JlYWQnIHJlY2VpcHQuIFdyYXBwZXIgZm9yIHtAbGluayBUaW5vZGUjbm90ZVJlYWR9LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gc2VxIC0gSUQgb2YgdGhlIG1lc3NhZ2UgdG8gYWtub3dsZWRnZSBvciAwL3VuZGVmaW5lZCB0byBhY2tub3dsZWRnZSB0aGUgbGF0ZXN0IG1lc3NhZ2VzLlxuICAgKi9cbiAgbm90ZVJlYWQoc2VxKSB7XG4gICAgc2VxID0gc2VxIHx8IHRoaXMuX21heFNlcTtcbiAgICBpZiAoc2VxID4gMCkge1xuICAgICAgdGhpcy5ub3RlKCdyZWFkJywgc2VxKTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIFNlbmQgYSBrZXktcHJlc3Mgbm90aWZpY2F0aW9uLiBXcmFwcGVyIGZvciB7QGxpbmsgVGlub2RlI25vdGVLZXlQcmVzc30uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqL1xuICBub3RlS2V5UHJlc3MoKSB7XG4gICAgaWYgKHRoaXMuX2F0dGFjaGVkKSB7XG4gICAgICB0aGlzLl90aW5vZGUubm90ZUtleVByZXNzKHRoaXMubmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3Rpbm9kZS5sb2dnZXIoXCJJTkZPOiBDYW5ub3Qgc2VuZCBub3RpZmljYXRpb24gaW4gaW5hY3RpdmUgdG9waWNcIik7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBTZW5kIGEge25vdGUgd2hhdD0nY2FsbCd9LiBXcmFwcGVyIGZvciB7QGxpbmsgVGlub2RlI3ZpZGVvQ2FsbH0uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUjXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldnQgLSBDYWxsIGV2ZW50LlxuICAgKiBAcGFyYW0ge2ludH0gc2VxIC0gSUQgb2YgdGhlIGNhbGwgbWVzc2FnZSB0aGUgZXZlbnQgcGVydGFpbnMgdG8uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXlsb2FkIC0gUGF5bG9hZCBhc3NvY2lhdGVkIHdpdGggdGhpcyBldmVudCAoZS5nLiBTRFAgc3RyaW5nKS5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgKGZvciBzb21lIGNhbGwgZXZlbnRzKSB3aGljaCB3aWxsXG4gICAqICAgICAgICAgICAgICAgICAgICBiZSByZXNvbHZlZC9yZWplY3RlZCBvbiByZWNlaXZpbmcgc2VydmVyIHJlcGx5XG4gICAqL1xuICB2aWRlb0NhbGwoZXZ0LCBzZXEsIHBheWxvYWQpIHtcbiAgICBpZiAoIXRoaXMuX2F0dGFjaGVkICYmICFbJ3JpbmdpbmcnLCAnaGFuZy11cCddLmluY2x1ZGVzKGV2dCkpIHtcbiAgICAgIC8vIENhbm5vdCB7Y2FsbH0gb24gYW4gaW5hY3RpdmUgdG9waWNcIi5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Rpbm9kZS52aWRlb0NhbGwodGhpcy5uYW1lLCBzZXEsIGV2dCwgcGF5bG9hZCk7XG4gIH1cblxuICAvLyBVcGRhdGUgY2FjaGVkIHJlYWQvcmVjdi91bnJlYWQgY291bnRzLlxuICBfdXBkYXRlUmVhZFJlY3Yod2hhdCwgc2VxLCB0cykge1xuICAgIGxldCBvbGRWYWwsIGRvVXBkYXRlID0gZmFsc2U7XG5cbiAgICBzZXEgPSBzZXEgfCAwO1xuICAgIHRoaXMuc2VxID0gdGhpcy5zZXEgfCAwO1xuICAgIHRoaXMucmVhZCA9IHRoaXMucmVhZCB8IDA7XG4gICAgdGhpcy5yZWN2ID0gdGhpcy5yZWN2IHwgMDtcbiAgICBzd2l0Y2ggKHdoYXQpIHtcbiAgICAgIGNhc2UgJ3JlY3YnOlxuICAgICAgICBvbGRWYWwgPSB0aGlzLnJlY3Y7XG4gICAgICAgIHRoaXMucmVjdiA9IE1hdGgubWF4KHRoaXMucmVjdiwgc2VxKTtcbiAgICAgICAgZG9VcGRhdGUgPSAob2xkVmFsICE9IHRoaXMucmVjdik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncmVhZCc6XG4gICAgICAgIG9sZFZhbCA9IHRoaXMucmVhZDtcbiAgICAgICAgdGhpcy5yZWFkID0gTWF0aC5tYXgodGhpcy5yZWFkLCBzZXEpO1xuICAgICAgICBkb1VwZGF0ZSA9IChvbGRWYWwgIT0gdGhpcy5yZWFkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtc2cnOlxuICAgICAgICBvbGRWYWwgPSB0aGlzLnNlcTtcbiAgICAgICAgdGhpcy5zZXEgPSBNYXRoLm1heCh0aGlzLnNlcSwgc2VxKTtcbiAgICAgICAgaWYgKCF0aGlzLnRvdWNoZWQgfHwgdGhpcy50b3VjaGVkIDwgdHMpIHtcbiAgICAgICAgICB0aGlzLnRvdWNoZWQgPSB0cztcbiAgICAgICAgfVxuICAgICAgICBkb1VwZGF0ZSA9IChvbGRWYWwgIT0gdGhpcy5zZXEpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyBTYW5pdHkgY2hlY2tzLlxuICAgIGlmICh0aGlzLnJlY3YgPCB0aGlzLnJlYWQpIHtcbiAgICAgIHRoaXMucmVjdiA9IHRoaXMucmVhZDtcbiAgICAgIGRvVXBkYXRlID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2VxIDwgdGhpcy5yZWN2KSB7XG4gICAgICB0aGlzLnNlcSA9IHRoaXMucmVjdjtcbiAgICAgIGlmICghdGhpcy50b3VjaGVkIHx8IHRoaXMudG91Y2hlZCA8IHRzKSB7XG4gICAgICAgIHRoaXMudG91Y2hlZCA9IHRzO1xuICAgICAgfVxuICAgICAgZG9VcGRhdGUgPSB0cnVlO1xuICAgIH1cbiAgICB0aGlzLnVucmVhZCA9IHRoaXMuc2VxIC0gdGhpcy5yZWFkO1xuICAgIHJldHVybiBkb1VwZGF0ZTtcbiAgfVxuICAvKipcbiAgICogR2V0IHVzZXIgZGVzY3JpcHRpb24gZnJvbSBnbG9iYWwgY2FjaGUuIFRoZSB1c2VyIGRvZXMgbm90IG5lZWQgdG8gYmUgYVxuICAgKiBzdWJzY3JpYmVyIG9mIHRoaXMgdG9waWMuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1aWQgLSBJRCBvZiB0aGUgdXNlciB0byBmZXRjaC5cbiAgICogQHJldHVybiB7T2JqZWN0fSB1c2VyIGRlc2NyaXB0aW9uIG9yIHVuZGVmaW5lZC5cbiAgICovXG4gIHVzZXJEZXNjKHVpZCkge1xuICAgIC8vIFRPRE86IGhhbmRsZSBhc3luY2hyb25vdXMgcmVxdWVzdHNcbiAgICBjb25zdCB1c2VyID0gdGhpcy5fY2FjaGVHZXRVc2VyKHVpZCk7XG4gICAgaWYgKHVzZXIpIHtcbiAgICAgIHJldHVybiB1c2VyOyAvLyBQcm9taXNlLnJlc29sdmUodXNlcilcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEdldCBkZXNjcmlwdGlvbiBvZiB0aGUgcDJwIHBlZXIgZnJvbSBzdWJzY3JpcHRpb24gY2FjaGUuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEByZXR1cm4ge09iamVjdH0gcGVlcidzIGRlc2NyaXB0aW9uIG9yIHVuZGVmaW5lZC5cbiAgICovXG4gIHAycFBlZXJEZXNjKCkge1xuICAgIGlmICghdGhpcy5pc1AyUFR5cGUoKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3VzZXJzW3RoaXMubmFtZV07XG4gIH1cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBjYWNoZWQgc3Vic2NyaWJlcnMuIElmIGNhbGxiYWNrIGlzIHVuZGVmaW5lZCwgdXNlIHRoaXMub25NZXRhU3ViLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayAtIENhbGxiYWNrIHdoaWNoIHdpbGwgcmVjZWl2ZSBzdWJzY3JpYmVycyBvbmUgYnkgb25lLlxuICAgKiBAcGFyYW0ge09iamVjdD19IGNvbnRleHQgLSBWYWx1ZSBvZiBgdGhpc2AgaW5zaWRlIHRoZSBgY2FsbGJhY2tgLlxuICAgKi9cbiAgc3Vic2NyaWJlcnMoY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICBjb25zdCBjYiA9IChjYWxsYmFjayB8fCB0aGlzLm9uTWV0YVN1Yik7XG4gICAgaWYgKGNiKSB7XG4gICAgICBmb3IgKGxldCBpZHggaW4gdGhpcy5fdXNlcnMpIHtcbiAgICAgICAgY2IuY2FsbChjb250ZXh0LCB0aGlzLl91c2Vyc1tpZHhdLCBpZHgsIHRoaXMuX3VzZXJzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEdldCBhIGNvcHkgb2YgY2FjaGVkIHRhZ3MuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEByZXR1cm4ge0FycmF5LjxzdHJpbmc+fSBhIGNvcHkgb2YgdGFnc1xuICAgKi9cbiAgdGFncygpIHtcbiAgICAvLyBSZXR1cm4gYSBjb3B5LlxuICAgIHJldHVybiB0aGlzLl90YWdzLnNsaWNlKDApO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgY2FjaGVkIHN1YnNjcmlwdGlvbiBmb3IgdGhlIGdpdmVuIHVzZXIgSUQuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1aWQgLSBpZCBvZiB0aGUgdXNlciB0byBxdWVyeSBmb3JcbiAgICogQHJldHVybiB1c2VyIGRlc2NyaXB0aW9uIG9yIHVuZGVmaW5lZC5cbiAgICovXG4gIHN1YnNjcmliZXIodWlkKSB7XG4gICAgcmV0dXJuIHRoaXMuX3VzZXJzW3VpZF07XG4gIH1cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciB2ZXJzaW9ucyBvZiA8Y29kZT5tZXNzYWdlPC9jb2RlPjogY2FsbCA8Y29kZT5jYWxsYmFjazwvY29kZT4gZm9yIGVhY2ggbWVzc2FnZS5cbiAgICogSWYgPGNvZGU+Y2FsbGJhY2s8L2NvZGU+IGlzIHVuZGVmaW5lZCwgZG9lcyBub3RoaW5nLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge1Rpbm9kZS5Gb3JFYWNoQ2FsbGJhY2tUeXBlfSBjYWxsYmFjayAtIENhbGxiYWNrIHdoaWNoIHdpbGwgcmVjZWl2ZSBtZXNzYWdlcyBvbmUgYnkgb25lLiBTZWUge0BsaW5rIFRpbm9kZS5DQnVmZmVyI2ZvckVhY2h9XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC0gVmFsdWUgb2YgYHRoaXNgIGluc2lkZSB0aGUgYGNhbGxiYWNrYC5cbiAgICovXG4gIG1lc3NhZ2VWZXJzaW9ucyhtZXNzYWdlLCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGlmICghY2FsbGJhY2spIHtcbiAgICAgIC8vIE5vIGNhbGxiYWNrPyBXZSBhcmUgZG9uZSB0aGVuLlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBvcmlnU2VxID0gdGhpcy5faXNSZXBsYWNlbWVudE1zZyhtZXNzYWdlKSA/IHBhcnNlSW50KG1lc3NhZ2UuaGVhZC5yZXBsYWNlLnNwbGl0KCc6JylbMV0pIDogbWVzc2FnZS5zZXE7XG4gICAgY29uc3QgdmVyc2lvbnMgPSB0aGlzLl9tZXNzYWdlVmVyc2lvbnNbb3JpZ1NlcV07XG4gICAgaWYgKCF2ZXJzaW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2ZXJzaW9ucy5mb3JFYWNoKGNhbGxiYWNrLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgY29udGV4dCk7XG4gIH1cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBjYWNoZWQgbWVzc2FnZXM6IGNhbGwgPGNvZGU+Y2FsbGJhY2s8L2NvZGU+IGZvciBlYWNoIG1lc3NhZ2UgaW4gdGhlIHJhbmdlIFtzaW5jZUlkeCwgYmVmb3JlSWR4KS5cbiAgICogSWYgPGNvZGU+Y2FsbGJhY2s8L2NvZGU+IGlzIHVuZGVmaW5lZCwgdXNlIDxjb2RlPnRoaXMub25EYXRhPC9jb2RlPi5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtUaW5vZGUuRm9yRWFjaENhbGxiYWNrVHlwZX0gY2FsbGJhY2sgLSBDYWxsYmFjayB3aGljaCB3aWxsIHJlY2VpdmUgbWVzc2FnZXMgb25lIGJ5IG9uZS4gU2VlIHtAbGluayBUaW5vZGUuQ0J1ZmZlciNmb3JFYWNofVxuICAgKiBAcGFyYW0ge251bWJlcn0gc2luY2VJZCAtIE9wdGlvbmFsIHNlcUlkIHRvIHN0YXJ0IGl0ZXJhdGluZyBmcm9tIChpbmNsdXNpdmUpLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYmVmb3JlSWQgLSBPcHRpb25hbCBzZXFJZCB0byBzdG9wIGl0ZXJhdGluZyBiZWZvcmUgaXQgaXMgcmVhY2hlZCAoZXhjbHVzaXZlKS5cbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgLSBWYWx1ZSBvZiBgdGhpc2AgaW5zaWRlIHRoZSBgY2FsbGJhY2tgLlxuICAgKi9cbiAgbWVzc2FnZXMoY2FsbGJhY2ssIHNpbmNlSWQsIGJlZm9yZUlkLCBjb250ZXh0KSB7XG4gICAgY29uc3QgY2IgPSAoY2FsbGJhY2sgfHwgdGhpcy5vbkRhdGEpO1xuICAgIGlmIChjYikge1xuICAgICAgY29uc3Qgc3RhcnRJZHggPSB0eXBlb2Ygc2luY2VJZCA9PSAnbnVtYmVyJyA/IHRoaXMuX21lc3NhZ2VzLmZpbmQoe1xuICAgICAgICBzZXE6IHNpbmNlSWRcbiAgICAgIH0sIHRydWUpIDogdW5kZWZpbmVkO1xuICAgICAgY29uc3QgYmVmb3JlSWR4ID0gdHlwZW9mIGJlZm9yZUlkID09ICdudW1iZXInID8gdGhpcy5fbWVzc2FnZXMuZmluZCh7XG4gICAgICAgIHNlcTogYmVmb3JlSWRcbiAgICAgIH0sIHRydWUpIDogdW5kZWZpbmVkO1xuICAgICAgaWYgKHN0YXJ0SWR4ICE9IC0xICYmIGJlZm9yZUlkeCAhPSAtMSkge1xuICAgICAgICAvLyBTdGVwIDEuIEZpbHRlciBvdXQgYWxsIHJlcGxhY2VtZW50IG1lc3NhZ2VzIGFuZFxuICAgICAgICAvLyBzYXZlIGRpc3BsYXlhYmxlIG1lc3NhZ2VzIGluIGEgdGVtcG9yYXJ5IGJ1ZmZlci5cbiAgICAgICAgbGV0IG1zZ3MgPSBbXTtcbiAgICAgICAgdGhpcy5fbWVzc2FnZXMuZm9yRWFjaCgobXNnLCB1bnVzZWQxLCB1bnVzZWQyLCBpKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuX2lzUmVwbGFjZW1lbnRNc2cobXNnKSkge1xuICAgICAgICAgICAgLy8gU2tpcCByZXBsYWNlbWVudHMuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIG1zZ3MucHVzaCh7XG4gICAgICAgICAgICBkYXRhOiB0aGlzLmxhdGVzdE1zZ1ZlcnNpb24obXNnLnNlcSkgfHwgbXNnLFxuICAgICAgICAgICAgaWR4OiBpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sIHN0YXJ0SWR4LCBiZWZvcmVJZHgsIHt9KTtcbiAgICAgICAgLy8gU3RlcCAyLiBMb29wIG92ZXIgZGlzcGxheWJsZSBtZXNzYWdlcyBpbnZva2luZyBjYiBvbiBlYWNoIG9mIHRoZW0uXG4gICAgICAgIG1zZ3MuZm9yRWFjaCgodmFsLCBpKSA9PiB7XG4gICAgICAgICAgY2IuY2FsbChjb250ZXh0LCB2YWwuZGF0YSxcbiAgICAgICAgICAgIChpID4gMCA/IG1zZ3NbaSAtIDFdLmRhdGEgOiB1bmRlZmluZWQpLFxuICAgICAgICAgICAgKGkgPCBtc2dzLmxlbmd0aCAtIDEgPyBtc2dzW2kgKyAxXS5kYXRhIDogdW5kZWZpbmVkKSwgdmFsLmlkeCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICAvKipcbiAgICogR2V0IHRoZSBtZXNzYWdlIGZyb20gY2FjaGUgYnkgPGNvZGU+c2VxPC9jb2RlPi5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNlcSAtIG1lc3NhZ2Ugc2VxSWQgdG8gc2VhcmNoIGZvci5cbiAgICogQHJldHVybnMge09iamVjdH0gdGhlIG1lc3NhZ2Ugd2l0aCB0aGUgZ2l2ZW4gPGNvZGU+c2VxPC9jb2RlPiBvciA8Y29kZT51bmRlZmluZWQ8L2NvZGU+LCBpZiBubyBzdWNoIG1lc3NhZ2UgaXMgZm91bmQuXG4gICAqL1xuICBmaW5kTWVzc2FnZShzZXEpIHtcbiAgICBjb25zdCBpZHggPSB0aGlzLl9tZXNzYWdlcy5maW5kKHtcbiAgICAgIHNlcTogc2VxXG4gICAgfSk7XG4gICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbWVzc2FnZXMuZ2V0QXQoaWR4KTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICAvKipcbiAgICogR2V0IHRoZSBtb3N0IHJlY2VudCBtZXNzYWdlIGZyb20gY2FjaGUuIFRoaXMgbWV0aG9kIGNvdW50cyBhbGwgbWVzc2FnZXMsIGluY2x1ZGluZyBkZWxldGVkIHJhbmdlcy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtib29sZW59IHNraXBEZWxldGVkIC0gaWYgdGhlIGxhc3QgbWVzc2FnZSBpcyBhIGRlbGV0ZWQgcmFuZ2UsIGdldCB0aGUgb25lIGJlZm9yZSBpdC5cbiAgICogQHJldHVybnMge09iamVjdH0gdGhlIG1vc3QgcmVjZW50IGNhY2hlZCBtZXNzYWdlIG9yIDxjb2RlPnVuZGVmaW5lZDwvY29kZT4sIGlmIG5vIG1lc3NhZ2VzIGFyZSBjYWNoZWQuXG4gICAqL1xuICBsYXRlc3RNZXNzYWdlKHNraXBEZWxldGVkKSB7XG4gICAgY29uc3QgbXNnID0gdGhpcy5fbWVzc2FnZXMuZ2V0TGFzdCgpO1xuICAgIGlmICghc2tpcERlbGV0ZWQgfHwgIW1zZyB8fCBtc2cuX3N0YXR1cyAhPSBDb25zdC5NRVNTQUdFX1NUQVRVU19ERUxfUkFOR0UpIHtcbiAgICAgIHJldHVybiBtc2c7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9tZXNzYWdlcy5nZXRMYXN0KDEpO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIGxhdGVzdCB2ZXJzaW9uIGZvciBtZXNzYWdlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gc2VxIC0gb3JpZ2luYWwgc2VxIElEIG9mIHRoZSBtZXNzYWdlLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSB0aGUgbGF0ZXN0IHZlcnNpb24gb2YgdGhlIG1lc3NhZ2Ugb3IgbnVsbCBpZiBtZXNzYWdlIG5vdCBmb3VuZC5cbiAgICovXG4gIGxhdGVzdE1zZ1ZlcnNpb24oc2VxKSB7XG4gICAgY29uc3QgdmVyc2lvbnMgPSB0aGlzLl9tZXNzYWdlVmVyc2lvbnNbc2VxXTtcbiAgICByZXR1cm4gdmVyc2lvbnMgPyB2ZXJzaW9ucy5nZXRMYXN0KCkgOiBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1heGltdW0gY2FjaGVkIHNlcSBJRC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHJldHVybnMge251bWJlcn0gdGhlIGdyZWF0ZXN0IHNlcSBJRCBpbiBjYWNoZS5cbiAgICovXG4gIG1heE1zZ1NlcSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbWF4U2VxO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1heGltdW0gZGVsZXRpb24gSUQuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IHRoZSBncmVhdGVzdCBkZWxldGlvbiBJRC5cbiAgICovXG4gIG1heENsZWFySWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX21heERlbDtcbiAgfVxuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2YgbWVzc2FnZXMgaW4gdGhlIGNhY2hlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBjb3VudCBvZiBjYWNoZWQgbWVzc2FnZXMuXG4gICAqL1xuICBtZXNzYWdlQ291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX21lc3NhZ2VzLmxlbmd0aCgpO1xuICB9XG4gIC8qKlxuICAgKiBJdGVyYXRlIG92ZXIgY2FjaGVkIHVuc2VudCBtZXNzYWdlcy4gV3JhcHMge0BsaW5rIFRpbm9kZS5Ub3BpYyNtZXNzYWdlc30uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrIC0gQ2FsbGJhY2sgd2hpY2ggd2lsbCByZWNlaXZlIG1lc3NhZ2VzIG9uZSBieSBvbmUuIFNlZSB7QGxpbmsgVGlub2RlLkNCdWZmZXIjZm9yRWFjaH1cbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgLSBWYWx1ZSBvZiA8Y29kZT50aGlzPC9jb2RlPiBpbnNpZGUgdGhlIDxjb2RlPmNhbGxiYWNrPC9jb2RlPi5cbiAgICovXG4gIHF1ZXVlZE1lc3NhZ2VzKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgaWYgKCFjYWxsYmFjaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FsbGJhY2sgbXVzdCBiZSBwcm92aWRlZFwiKTtcbiAgICB9XG4gICAgdGhpcy5tZXNzYWdlcyhjYWxsYmFjaywgQ29uc3QuTE9DQUxfU0VRSUQsIHVuZGVmaW5lZCwgY29udGV4dCk7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0aGUgbnVtYmVyIG9mIHRvcGljIHN1YnNjcmliZXJzIHdobyBtYXJrZWQgdGhpcyBtZXNzYWdlIGFzIGVpdGhlciByZWN2IG9yIHJlYWRcbiAgICogQ3VycmVudCB1c2VyIGlzIGV4Y2x1ZGVkIGZyb20gdGhlIGNvdW50LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gd2hhdCAtIHdoYXQgYWN0aW9uIHRvIGNvbnNpZGVyOiByZWNlaXZlZCA8Y29kZT5cInJlY3ZcIjwvY29kZT4gb3IgcmVhZCA8Y29kZT5cInJlYWRcIjwvY29kZT4uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzZXEgLSBJRCBvciB0aGUgbWVzc2FnZSByZWFkIG9yIHJlY2VpdmVkLlxuICAgKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSB0aGUgbnVtYmVyIG9mIHN1YnNjcmliZXJzIHdobyBtYXJrZWQgdGhlIG1lc3NhZ2Ugd2l0aCB0aGUgZ2l2ZW4gSUQgYXMgcmVhZCBvciByZWNlaXZlZC5cbiAgICovXG4gIG1zZ1JlY2VpcHRDb3VudCh3aGF0LCBzZXEpIHtcbiAgICBsZXQgY291bnQgPSAwO1xuICAgIGlmIChzZXEgPiAwKSB7XG4gICAgICBjb25zdCBtZSA9IHRoaXMuX3Rpbm9kZS5nZXRDdXJyZW50VXNlcklEKCk7XG4gICAgICBmb3IgKGxldCBpZHggaW4gdGhpcy5fdXNlcnMpIHtcbiAgICAgICAgY29uc3QgdXNlciA9IHRoaXMuX3VzZXJzW2lkeF07XG4gICAgICAgIGlmICh1c2VyLnVzZXIgIT09IG1lICYmIHVzZXJbd2hhdF0gPj0gc2VxKSB7XG4gICAgICAgICAgY291bnQrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY291bnQ7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0aGUgbnVtYmVyIG9mIHRvcGljIHN1YnNjcmliZXJzIHdobyBtYXJrZWQgdGhpcyBtZXNzYWdlIChhbmQgYWxsIG9sZGVyIG1lc3NhZ2VzKSBhcyByZWFkLlxuICAgKiBUaGUgY3VycmVudCB1c2VyIGlzIGV4Y2x1ZGVkIGZyb20gdGhlIGNvdW50LlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gc2VxIC0gbWVzc2FnZSBpZCB0byBjaGVjay5cbiAgICogQHJldHVybnMge251bWJlcn0gbnVtYmVyIG9mIHN1YnNjcmliZXJzIHdobyBjbGFpbSB0byBoYXZlIHJlY2VpdmVkIHRoZSBtZXNzYWdlLlxuICAgKi9cbiAgbXNnUmVhZENvdW50KHNlcSkge1xuICAgIHJldHVybiB0aGlzLm1zZ1JlY2VpcHRDb3VudCgncmVhZCcsIHNlcSk7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0aGUgbnVtYmVyIG9mIHRvcGljIHN1YnNjcmliZXJzIHdobyBtYXJrZWQgdGhpcyBtZXNzYWdlIChhbmQgYWxsIG9sZGVyIG1lc3NhZ2VzKSBhcyByZWNlaXZlZC5cbiAgICogVGhlIGN1cnJlbnQgdXNlciBpcyBleGNsdWRlZCBmcm9tIHRoZSBjb3VudC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNlcSAtIE1lc3NhZ2UgaWQgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBzdWJzY3JpYmVycyB3aG8gY2xhaW0gdG8gaGF2ZSByZWNlaXZlZCB0aGUgbWVzc2FnZS5cbiAgICovXG4gIG1zZ1JlY3ZDb3VudChzZXEpIHtcbiAgICByZXR1cm4gdGhpcy5tc2dSZWNlaXB0Q291bnQoJ3JlY3YnLCBzZXEpO1xuICB9XG4gIC8qKlxuICAgKiBDaGVjayBpZiBjYWNoZWQgbWVzc2FnZSBJRHMgaW5kaWNhdGUgdGhhdCB0aGUgc2VydmVyIG1heSBoYXZlIG1vcmUgbWVzc2FnZXMuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gbmV3ZXIgLSBpZiA8Y29kZT50cnVlPC9jb2RlPiwgY2hlY2sgZm9yIG5ld2VyIG1lc3NhZ2VzIG9ubHkuXG4gICAqL1xuICBtc2dIYXNNb3JlTWVzc2FnZXMobmV3ZXIpIHtcbiAgICByZXR1cm4gbmV3ZXIgPyB0aGlzLnNlcSA+IHRoaXMuX21heFNlcSA6XG4gICAgICAvLyBfbWluU2VxIGNvdWxkIGJlIG1vcmUgdGhhbiAxLCBidXQgZWFybGllciBtZXNzYWdlcyBjb3VsZCBoYXZlIGJlZW4gZGVsZXRlZC5cbiAgICAgICh0aGlzLl9taW5TZXEgPiAxICYmICF0aGlzLl9ub0VhcmxpZXJNc2dzKTtcbiAgfVxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIGdpdmVuIHNlcSBJZCBpcyBpZCBvZiB0aGUgbW9zdCByZWNlbnQgbWVzc2FnZS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNlcUlkIGlkIG9mIHRoZSBtZXNzYWdlIHRvIGNoZWNrXG4gICAqL1xuICBpc05ld01lc3NhZ2Uoc2VxSWQpIHtcbiAgICByZXR1cm4gdGhpcy5fbWF4U2VxIDw9IHNlcUlkO1xuICB9XG4gIC8qKlxuICAgKiBSZW1vdmUgb25lIG1lc3NhZ2UgZnJvbSBsb2NhbCBjYWNoZS5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNlcUlkIGlkIG9mIHRoZSBtZXNzYWdlIHRvIHJlbW92ZSBmcm9tIGNhY2hlLlxuICAgKiBAcmV0dXJucyB7TWVzc2FnZX0gcmVtb3ZlZCBtZXNzYWdlIG9yIHVuZGVmaW5lZCBpZiBzdWNoIG1lc3NhZ2Ugd2FzIG5vdCBmb3VuZC5cbiAgICovXG4gIGZsdXNoTWVzc2FnZShzZXFJZCkge1xuICAgIGNvbnN0IGlkeCA9IHRoaXMuX21lc3NhZ2VzLmZpbmQoe1xuICAgICAgc2VxOiBzZXFJZFxuICAgIH0pO1xuICAgIGlmIChpZHggPj0gMCkge1xuICAgICAgdGhpcy5fdGlub2RlLl9kYi5yZW1NZXNzYWdlcyh0aGlzLm5hbWUsIHNlcUlkKTtcbiAgICAgIHJldHVybiB0aGlzLl9tZXNzYWdlcy5kZWxBdChpZHgpO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIC8qKlxuICAgKiBVcGRhdGUgbWVzc2FnZSdzIHNlcUlkLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHViIG1lc3NhZ2Ugb2JqZWN0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gbmV3U2VxSWQgbmV3IHNlcSBpZCBmb3IgcHViLlxuICAgKi9cbiAgc3dhcE1lc3NhZ2VJZChwdWIsIG5ld1NlcUlkKSB7XG4gICAgY29uc3QgaWR4ID0gdGhpcy5fbWVzc2FnZXMuZmluZChwdWIpO1xuICAgIGNvbnN0IG51bU1lc3NhZ2VzID0gdGhpcy5fbWVzc2FnZXMubGVuZ3RoKCk7XG4gICAgaWYgKDAgPD0gaWR4ICYmIGlkeCA8IG51bU1lc3NhZ2VzKSB7XG4gICAgICAvLyBSZW1vdmUgbWVzc2FnZSB3aXRoIHRoZSBvbGQgc2VxIElELlxuICAgICAgdGhpcy5fbWVzc2FnZXMuZGVsQXQoaWR4KTtcbiAgICAgIHRoaXMuX3Rpbm9kZS5fZGIucmVtTWVzc2FnZXModGhpcy5uYW1lLCBwdWIuc2VxKTtcbiAgICAgIC8vIEFkZCBtZXNzYWdlIHdpdGggdGhlIG5ldyBzZXEgSUQuXG4gICAgICBwdWIuc2VxID0gbmV3U2VxSWQ7XG4gICAgICB0aGlzLl9tZXNzYWdlcy5wdXQocHViKTtcbiAgICAgIHRoaXMuX3Rpbm9kZS5fZGIuYWRkTWVzc2FnZShwdWIpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogUmVtb3ZlIGEgcmFuZ2Ugb2YgbWVzc2FnZXMgZnJvbSB0aGUgbG9jYWwgY2FjaGUuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSWQgc2VxIElEIG9mIHRoZSBmaXJzdCBtZXNzYWdlIHRvIHJlbW92ZSAoaW5jbHVzaXZlKS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHVudGlsSWQgc2VxSUQgb2YgdGhlIGxhc3QgbWVzc2FnZSB0byByZW1vdmUgKGV4Y2x1c2l2ZSkuXG4gICAqXG4gICAqIEByZXR1cm5zIHtNZXNzYWdlW119IGFycmF5IG9mIHJlbW92ZWQgbWVzc2FnZXMgKGNvdWxkIGJlIGVtcHR5KS5cbiAgICovXG4gIGZsdXNoTWVzc2FnZVJhbmdlKGZyb21JZCwgdW50aWxJZCkge1xuICAgIC8vIFJlbW92ZSByYW5nZSBmcm9tIHBlcnNpc3RlbnQgY2FjaGUuXG4gICAgdGhpcy5fdGlub2RlLl9kYi5yZW1NZXNzYWdlcyh0aGlzLm5hbWUsIGZyb21JZCwgdW50aWxJZCk7XG4gICAgLy8gc3RhcnQsIGVuZDogZmluZCBpbnNlcnRpb24gcG9pbnRzIChuZWFyZXN0ID09IHRydWUpLlxuICAgIGNvbnN0IHNpbmNlID0gdGhpcy5fbWVzc2FnZXMuZmluZCh7XG4gICAgICBzZXE6IGZyb21JZFxuICAgIH0sIHRydWUpO1xuICAgIHJldHVybiBzaW5jZSA+PSAwID8gdGhpcy5fbWVzc2FnZXMuZGVsUmFuZ2Uoc2luY2UsIHRoaXMuX21lc3NhZ2VzLmZpbmQoe1xuICAgICAgc2VxOiB1bnRpbElkXG4gICAgfSwgdHJ1ZSkpIDogW107XG4gIH1cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gc3RvcCBtZXNzYWdlIGZyb20gYmVpbmcgc2VudC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNlcUlkIGlkIG9mIHRoZSBtZXNzYWdlIHRvIHN0b3Agc2VuZGluZyBhbmQgcmVtb3ZlIGZyb20gY2FjaGUuXG4gICAqXG4gICAqIEByZXR1cm5zIHtib29sZWFufSA8Y29kZT50cnVlPC9jb2RlPiBpZiBtZXNzYWdlIHdhcyBjYW5jZWxsZWQsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuXG4gICAqL1xuICBjYW5jZWxTZW5kKHNlcUlkKSB7XG4gICAgY29uc3QgaWR4ID0gdGhpcy5fbWVzc2FnZXMuZmluZCh7XG4gICAgICBzZXE6IHNlcUlkXG4gICAgfSk7XG4gICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICBjb25zdCBtc2cgPSB0aGlzLl9tZXNzYWdlcy5nZXRBdChpZHgpO1xuICAgICAgY29uc3Qgc3RhdHVzID0gdGhpcy5tc2dTdGF0dXMobXNnKTtcbiAgICAgIGlmIChzdGF0dXMgPT0gQ29uc3QuTUVTU0FHRV9TVEFUVVNfUVVFVUVEIHx8IHN0YXR1cyA9PSBDb25zdC5NRVNTQUdFX1NUQVRVU19GQUlMRUQpIHtcbiAgICAgICAgdGhpcy5fdGlub2RlLl9kYi5yZW1NZXNzYWdlcyh0aGlzLm5hbWUsIHNlcUlkKTtcbiAgICAgICAgbXNnLl9jYW5jZWxsZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLl9tZXNzYWdlcy5kZWxBdChpZHgpO1xuICAgICAgICBpZiAodGhpcy5vbkRhdGEpIHtcbiAgICAgICAgICAvLyBDYWxsaW5nIHdpdGggbm8gcGFyYW1ldGVycyB0byBpbmRpY2F0ZSB0aGUgbWVzc2FnZSB3YXMgZGVsZXRlZC5cbiAgICAgICAgICB0aGlzLm9uRGF0YSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0eXBlIG9mIHRoZSB0b3BpYzogbWUsIHAycCwgZ3JwLCBmbmQuLi5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gT25lIG9mICdtZScsICdwMnAnLCAnZ3JwJywgJ2ZuZCcsICdzeXMnIG9yIDxjb2RlPnVuZGVmaW5lZDwvY29kZT4uXG4gICAqL1xuICBnZXRUeXBlKCkge1xuICAgIHJldHVybiBUb3BpYy50b3BpY1R5cGUodGhpcy5uYW1lKTtcbiAgfVxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgdXNlcidzIGFjY2VzcyBtb2RlIG9mIHRoZSB0b3BpYy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHJldHVybnMge1Rpbm9kZS5BY2Nlc3NNb2RlfSAtIHVzZXIncyBhY2Nlc3MgbW9kZVxuICAgKi9cbiAgZ2V0QWNjZXNzTW9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5hY3M7XG4gIH1cbiAgLyoqXG4gICAqIFNldCBjdXJyZW50IHVzZXIncyBhY2Nlc3MgbW9kZSBvZiB0aGUgdG9waWMuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEBwYXJhbSB7QWNjZXNzTW9kZSB8IE9iamVjdH0gYWNzIC0gYWNjZXNzIG1vZGUgdG8gc2V0LlxuICAgKi9cbiAgc2V0QWNjZXNzTW9kZShhY3MpIHtcbiAgICByZXR1cm4gdGhpcy5hY3MgPSBuZXcgQWNjZXNzTW9kZShhY3MpO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdG9waWMncyBkZWZhdWx0IGFjY2VzcyBtb2RlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcmV0dXJucyB7VGlub2RlLkRlZkFjc30gLSBhY2Nlc3MgbW9kZSwgc3VjaCBhcyB7YXV0aDogYFJXUGAsIGFub246IGBOYH0uXG4gICAqL1xuICBnZXREZWZhdWx0QWNjZXNzKCkge1xuICAgIHJldHVybiB0aGlzLmRlZmFjcztcbiAgfVxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBuZXcgbWV0YSB7QGxpbmsgVGlub2RlLkdldFF1ZXJ5fSBidWlsZGVyLiBUaGUgcXVlcnkgaXMgYXR0Y2hlZCB0byB0aGUgY3VycmVudCB0b3BpYy5cbiAgICogSXQgd2lsbCBub3Qgd29yayBjb3JyZWN0bHkgaWYgdXNlZCB3aXRoIGEgZGlmZmVyZW50IHRvcGljLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcmV0dXJucyB7VGlub2RlLk1ldGFHZXRCdWlsZGVyfSBxdWVyeSBhdHRhY2hlZCB0byB0aGUgY3VycmVudCB0b3BpYy5cbiAgICovXG4gIHN0YXJ0TWV0YVF1ZXJ5KCkge1xuICAgIHJldHVybiBuZXcgTWV0YUdldEJ1aWxkZXIodGhpcyk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRvcGljIGlzIGFyY2hpdmVkLCBpLmUuIHByaXZhdGUuYXJjaCA9PSB0cnVlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSA8Y29kZT50cnVlPC9jb2RlPiBpZiB0b3BpYyBpcyBhcmNoaXZlZCwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cbiAgICovXG4gIGlzQXJjaGl2ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMucHJpdmF0ZSAmJiAhIXRoaXMucHJpdmF0ZS5hcmNoO1xuICB9XG4gIC8qKlxuICAgKiBDaGVjayBpZiB0b3BpYyBpcyBhICdtZScgdG9waWMuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRvcGljIGlzIGEgJ21lJyB0b3BpYywgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cbiAgICovXG4gIGlzTWVUeXBlKCkge1xuICAgIHJldHVybiBUb3BpYy5pc01lVG9waWNOYW1lKHRoaXMubmFtZSk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRvcGljIGlzIGEgY2hhbm5lbC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdG9waWMgaXMgYSBjaGFubmVsLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxuICAgKi9cbiAgaXNDaGFubmVsVHlwZSgpIHtcbiAgICByZXR1cm4gVG9waWMuaXNDaGFubmVsVG9waWNOYW1lKHRoaXMubmFtZSk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRvcGljIGlzIGEgZ3JvdXAgdG9waWMuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWMjXG4gICAqXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRvcGljIGlzIGEgZ3JvdXAsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuXG4gICAqL1xuICBpc0dyb3VwVHlwZSgpIHtcbiAgICByZXR1cm4gVG9waWMuaXNHcm91cFRvcGljTmFtZSh0aGlzLm5hbWUpO1xuICB9XG4gIC8qKlxuICAgKiBDaGVjayBpZiB0b3BpYyBpcyBhIHAycCB0b3BpYy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdG9waWMgaXMgYSBwMnAgdG9waWMsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuXG4gICAqL1xuICBpc1AyUFR5cGUoKSB7XG4gICAgcmV0dXJuIFRvcGljLmlzUDJQVG9waWNOYW1lKHRoaXMubmFtZSk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRvcGljIGlzIGEgY29tbXVuaWNhdGlvbiB0b3BpYywgaS5lLiBhIGdyb3VwIG9yIHAycCB0b3BpYy5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpYyNcbiAgICpcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdG9waWMgaXMgYSBwMnAgb3IgZ3JvdXAgdG9waWMsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuXG4gICAqL1xuICBpc0NvbW1UeXBlKCkge1xuICAgIHJldHVybiBUb3BpYy5pc0NvbW1Ub3BpY05hbWUodGhpcy5uYW1lKTtcbiAgfVxuICAvKipcbiAgICogR2V0IHN0YXR1cyAocXVldWVkLCBzZW50LCByZWNlaXZlZCBldGMpIG9mIGEgZ2l2ZW4gbWVzc2FnZSBpbiB0aGUgY29udGV4dFxuICAgKiBvZiB0aGlzIHRvcGljLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljI1xuICAgKlxuICAgKiBAcGFyYW0ge01lc3NhZ2V9IG1zZyAtIG1lc3NhZ2UgdG8gY2hlY2sgZm9yIHN0YXR1cy5cbiAgICogQHBhcmFtIHtib29sZWFufSB1cGQgLSB1cGRhdGUgY2hhY2hlZCBtZXNzYWdlIHN0YXR1cy5cbiAgICpcbiAgICogQHJldHVybnMgbWVzc2FnZSBzdGF0dXMgY29uc3RhbnQuXG4gICAqL1xuICBtc2dTdGF0dXMobXNnLCB1cGQpIHtcbiAgICBsZXQgc3RhdHVzID0gQ29uc3QuTUVTU0FHRV9TVEFUVVNfTk9ORTtcbiAgICBpZiAodGhpcy5fdGlub2RlLmlzTWUobXNnLmZyb20pKSB7XG4gICAgICBpZiAobXNnLl9zZW5kaW5nKSB7XG4gICAgICAgIHN0YXR1cyA9IENvbnN0Lk1FU1NBR0VfU1RBVFVTX1NFTkRJTkc7XG4gICAgICB9IGVsc2UgaWYgKG1zZy5fZmFpbGVkIHx8IG1zZy5fY2FuY2VsbGVkKSB7XG4gICAgICAgIHN0YXR1cyA9IENvbnN0Lk1FU1NBR0VfU1RBVFVTX0ZBSUxFRDtcbiAgICAgIH0gZWxzZSBpZiAobXNnLnNlcSA+PSBDb25zdC5MT0NBTF9TRVFJRCkge1xuICAgICAgICBzdGF0dXMgPSBDb25zdC5NRVNTQUdFX1NUQVRVU19RVUVVRUQ7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMubXNnUmVhZENvdW50KG1zZy5zZXEpID4gMCkge1xuICAgICAgICBzdGF0dXMgPSBDb25zdC5NRVNTQUdFX1NUQVRVU19SRUFEO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLm1zZ1JlY3ZDb3VudChtc2cuc2VxKSA+IDApIHtcbiAgICAgICAgc3RhdHVzID0gQ29uc3QuTUVTU0FHRV9TVEFUVVNfUkVDRUlWRUQ7XG4gICAgICB9IGVsc2UgaWYgKG1zZy5zZXEgPiAwKSB7XG4gICAgICAgIHN0YXR1cyA9IENvbnN0Lk1FU1NBR0VfU1RBVFVTX1NFTlQ7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChtc2cuX3N0YXR1cyA9PSBDb25zdC5NRVNTQUdFX1NUQVRVU19ERUxfUkFOR0UpIHtcbiAgICAgIHN0YXR1cyA9PSBDb25zdC5NRVNTQUdFX1NUQVRVU19ERUxfUkFOR0U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXR1cyA9IENvbnN0Lk1FU1NBR0VfU1RBVFVTX1RPX01FO1xuICAgIH1cblxuICAgIGlmICh1cGQgJiYgbXNnLl9zdGF0dXMgIT0gc3RhdHVzKSB7XG4gICAgICBtc2cuX3N0YXR1cyA9IHN0YXR1cztcbiAgICAgIHRoaXMuX3Rpbm9kZS5fZGIudXBkTWVzc2FnZVN0YXR1cyh0aGlzLm5hbWUsIG1zZy5zZXEsIHN0YXR1cyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXR1cztcbiAgfVxuXG4gIC8vIFJldHVybnMgdHJ1ZSBpZiBwdWIgaXMgbWVhbnQgdG8gcmVwbGFjZSBhbm90aGVyIG1lc3NhZ2UgKGUuZy4gb3JpZ2luYWwgbWVzc2FnZSB3YXMgZWRpdGVkKS5cbiAgX2lzUmVwbGFjZW1lbnRNc2cocHViKSB7XG4gICAgcmV0dXJuIHB1Yi5oZWFkICYmIHB1Yi5oZWFkLnJlcGxhY2U7XG4gIH1cblxuICAvLyBJZiBtc2cgaXMgYSByZXBsYWNlbWVudCBmb3IgYW5vdGhlciBtZXNzYWdlLCBzYXZlcyBtc2cgaW4gdGhlIG1lc3NhZ2UgdmVyc2lvbnMgY2FjaGVcbiAgLy8gYXMgYSBuZXdlciB2ZXJzaW9uIGZvciB0aGUgbWVzc2FnZSBpdCdzIHN1cHBvc2VkIHRvIHJlcGxhY2UuXG4gIF9tYXliZVVwZGF0ZU1lc3NhZ2VWZXJzaW9uc0NhY2hlKG1zZykge1xuICAgIGlmICghdGhpcy5faXNSZXBsYWNlbWVudE1zZyhtc2cpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRhcmdldFNlcSA9IHBhcnNlSW50KG1zZy5oZWFkLnJlcGxhY2Uuc3BsaXQoJzonKVsxXSk7XG4gICAgaWYgKHRhcmdldFNlcSA+IG1zZy5zZXEpIHtcbiAgICAgIC8vIFN1YnN0aXR1dGVzIGFyZSBzdXBwb3NlZCB0byBoYXZlIGhpZ2hlciBzZXEgaWRzLlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBsZXQgdmVyc2lvbnMgPSB0aGlzLl9tZXNzYWdlVmVyc2lvbnNbdGFyZ2V0U2VxXSB8fCBuZXcgQ0J1ZmZlcigoYSwgYikgPT4ge1xuICAgICAgcmV0dXJuIGEuc2VxIC0gYi5zZXE7XG4gICAgfSwgdHJ1ZSk7XG4gICAgdmVyc2lvbnMucHV0KG1zZyk7XG4gICAgdGhpcy5fbWVzc2FnZVZlcnNpb25zW3RhcmdldFNlcV0gPSB2ZXJzaW9ucztcbiAgfVxuXG4gIC8vIFByb2Nlc3MgZGF0YSBtZXNzYWdlXG4gIF9yb3V0ZURhdGEoZGF0YSkge1xuICAgIGlmIChkYXRhLmNvbnRlbnQpIHtcbiAgICAgIGlmICghdGhpcy50b3VjaGVkIHx8IHRoaXMudG91Y2hlZCA8IGRhdGEudHMpIHtcbiAgICAgICAgdGhpcy50b3VjaGVkID0gZGF0YS50cztcbiAgICAgICAgdGhpcy5fdGlub2RlLl9kYi51cGRUb3BpYyh0aGlzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZGF0YS5zZXEgPiB0aGlzLl9tYXhTZXEpIHtcbiAgICAgIHRoaXMuX21heFNlcSA9IGRhdGEuc2VxO1xuICAgICAgdGhpcy5tc2dTdGF0dXMoZGF0YSwgdHJ1ZSk7XG4gICAgICAvLyBBY2tuIHJlY2VpdmluZyB0aGUgbWVzc2FnZS5cbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9yZWN2Tm90aWZpY2F0aW9uVGltZXIpO1xuICAgICAgdGhpcy5fcmVjdk5vdGlmaWNhdGlvblRpbWVyID0gc2V0VGltZW91dChfID0+IHtcbiAgICAgICAgdGhpcy5fcmVjdk5vdGlmaWNhdGlvblRpbWVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5ub3RlUmVjdih0aGlzLl9tYXhTZXEpO1xuICAgICAgfSwgQ29uc3QuUkVDVl9USU1FT1VUKTtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5zZXEgPCB0aGlzLl9taW5TZXEgfHwgdGhpcy5fbWluU2VxID09IDApIHtcbiAgICAgIHRoaXMuX21pblNlcSA9IGRhdGEuc2VxO1xuICAgIH1cblxuICAgIGNvbnN0IG91dGdvaW5nID0gKCghdGhpcy5pc0NoYW5uZWxUeXBlKCkgJiYgIWRhdGEuZnJvbSkgfHwgdGhpcy5fdGlub2RlLmlzTWUoZGF0YS5mcm9tKSk7XG5cbiAgICBpZiAoZGF0YS5oZWFkICYmIGRhdGEuaGVhZC53ZWJydGMgJiYgZGF0YS5oZWFkLm1pbWUgPT0gRHJhZnR5LmdldENvbnRlbnRUeXBlKCkgJiYgZGF0YS5jb250ZW50KSB7XG4gICAgICAvLyBSZXdyaXRlIFZDIGJvZHkgd2l0aCBpbmZvIGZyb20gdGhlIGhlYWRlcnMuXG4gICAgICBkYXRhLmNvbnRlbnQgPSBEcmFmdHkudXBkYXRlVmlkZW9FbnQoZGF0YS5jb250ZW50LCB7XG4gICAgICAgIHN0YXRlOiBkYXRhLmhlYWQud2VicnRjLFxuICAgICAgICBkdXJhdGlvbjogZGF0YS5oZWFkWyd3ZWJydGMtZHVyYXRpb24nXSxcbiAgICAgICAgaW5jb21pbmc6ICFvdXRnb2luZyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICghZGF0YS5fbm9Gb3J3YXJkaW5nKSB7XG4gICAgICB0aGlzLl9tZXNzYWdlcy5wdXQoZGF0YSk7XG4gICAgICB0aGlzLl90aW5vZGUuX2RiLmFkZE1lc3NhZ2UoZGF0YSk7XG4gICAgICB0aGlzLl9tYXliZVVwZGF0ZU1lc3NhZ2VWZXJzaW9uc0NhY2hlKGRhdGEpO1xuICAgICAgdGhpcy5fdXBkYXRlRGVsZXRlZFJhbmdlcygpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9uRGF0YSkge1xuICAgICAgdGhpcy5vbkRhdGEoZGF0YSk7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIGxvY2FsbHkgY2FjaGVkIGNvbnRhY3Qgd2l0aCB0aGUgbmV3IG1lc3NhZ2UgY291bnQuXG4gICAgY29uc3Qgd2hhdCA9IG91dGdvaW5nID8gJ3JlYWQnIDogJ21zZyc7XG4gICAgdGhpcy5fdXBkYXRlUmVhZFJlY3Yod2hhdCwgZGF0YS5zZXEsIGRhdGEudHMpO1xuICAgIC8vIE5vdGlmeSAnbWUnIGxpc3RlbmVycyBvZiB0aGUgY2hhbmdlLlxuICAgIHRoaXMuX3Rpbm9kZS5nZXRNZVRvcGljKCkuX3JlZnJlc2hDb250YWN0KHdoYXQsIHRoaXMpO1xuICB9XG5cbiAgLy8gUHJvY2VzcyBtZXRhZGF0YSBtZXNzYWdlXG4gIF9yb3V0ZU1ldGEobWV0YSkge1xuICAgIGlmIChtZXRhLmRlc2MpIHtcbiAgICAgIHRoaXMuX3Byb2Nlc3NNZXRhRGVzYyhtZXRhLmRlc2MpO1xuICAgIH1cbiAgICBpZiAobWV0YS5zdWIgJiYgbWV0YS5zdWIubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5fcHJvY2Vzc01ldGFTdWIobWV0YS5zdWIpO1xuICAgIH1cbiAgICBpZiAobWV0YS5kZWwpIHtcbiAgICAgIHRoaXMuX3Byb2Nlc3NEZWxNZXNzYWdlcyhtZXRhLmRlbC5jbGVhciwgbWV0YS5kZWwuZGVsc2VxKTtcbiAgICB9XG4gICAgaWYgKG1ldGEudGFncykge1xuICAgICAgdGhpcy5fcHJvY2Vzc01ldGFUYWdzKG1ldGEudGFncyk7XG4gICAgfVxuICAgIGlmIChtZXRhLmNyZWQpIHtcbiAgICAgIHRoaXMuX3Byb2Nlc3NNZXRhQ3JlZHMobWV0YS5jcmVkKTtcbiAgICB9XG4gICAgaWYgKHRoaXMub25NZXRhKSB7XG4gICAgICB0aGlzLm9uTWV0YShtZXRhKTtcbiAgICB9XG4gIH1cbiAgLy8gUHJvY2VzcyBwcmVzZW5jZSBjaGFuZ2UgbWVzc2FnZVxuICBfcm91dGVQcmVzKHByZXMpIHtcbiAgICBsZXQgdXNlciwgdWlkO1xuICAgIHN3aXRjaCAocHJlcy53aGF0KSB7XG4gICAgICBjYXNlICdkZWwnOlxuICAgICAgICAvLyBEZWxldGUgY2FjaGVkIG1lc3NhZ2VzLlxuICAgICAgICB0aGlzLl9wcm9jZXNzRGVsTWVzc2FnZXMocHJlcy5jbGVhciwgcHJlcy5kZWxzZXEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ29uJzpcbiAgICAgIGNhc2UgJ29mZic6XG4gICAgICAgIC8vIFVwZGF0ZSBvbmxpbmUgc3RhdHVzIG9mIGEgc3Vic2NyaXB0aW9uLlxuICAgICAgICB1c2VyID0gdGhpcy5fdXNlcnNbcHJlcy5zcmNdO1xuICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgIHVzZXIub25saW5lID0gcHJlcy53aGF0ID09ICdvbic7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fdGlub2RlLmxvZ2dlcihcIldBUk5JTkc6IFByZXNlbmNlIHVwZGF0ZSBmb3IgYW4gdW5rbm93biB1c2VyXCIsIHRoaXMubmFtZSwgcHJlcy5zcmMpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndGVybSc6XG4gICAgICAgIC8vIEF0dGFjaG1lbnQgdG8gdG9waWMgaXMgdGVybWluYXRlZCBwcm9iYWJseSBkdWUgdG8gY2x1c3RlciByZWhhc2hpbmcuXG4gICAgICAgIHRoaXMuX3Jlc2V0U3ViKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndXBkJzpcbiAgICAgICAgLy8gQSB0b3BpYyBzdWJzY3JpYmVyIGhhcyB1cGRhdGVkIGhpcyBkZXNjcmlwdGlvbi5cbiAgICAgICAgLy8gSXNzdWUge2dldCBzdWJ9IG9ubHkgaWYgdGhlIGN1cnJlbnQgdXNlciBoYXMgbm8gcDJwIHRvcGljcyB3aXRoIHRoZSB1cGRhdGVkIHVzZXIgKHAycCBuYW1lIGlzIG5vdCBpbiBjYWNoZSkuXG4gICAgICAgIC8vIE90aGVyd2lzZSAnbWUnIHdpbGwgaXNzdWUgYSB7Z2V0IGRlc2N9IHJlcXVlc3QuXG4gICAgICAgIGlmIChwcmVzLnNyYyAmJiAhdGhpcy5fdGlub2RlLmlzVG9waWNDYWNoZWQocHJlcy5zcmMpKSB7XG4gICAgICAgICAgdGhpcy5nZXRNZXRhKHRoaXMuc3RhcnRNZXRhUXVlcnkoKS53aXRoTGF0ZXJPbmVTdWIocHJlcy5zcmMpLmJ1aWxkKCkpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYWNzJzpcbiAgICAgICAgdWlkID0gcHJlcy5zcmMgfHwgdGhpcy5fdGlub2RlLmdldEN1cnJlbnRVc2VySUQoKTtcbiAgICAgICAgdXNlciA9IHRoaXMuX3VzZXJzW3VpZF07XG4gICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgIC8vIFVwZGF0ZSBmb3IgYW4gdW5rbm93biB1c2VyOiBub3RpZmljYXRpb24gb2YgYSBuZXcgc3Vic2NyaXB0aW9uLlxuICAgICAgICAgIGNvbnN0IGFjcyA9IG5ldyBBY2Nlc3NNb2RlKCkudXBkYXRlQWxsKHByZXMuZGFjcyk7XG4gICAgICAgICAgaWYgKGFjcyAmJiBhY3MubW9kZSAhPSBBY2Nlc3NNb2RlLl9OT05FKSB7XG4gICAgICAgICAgICB1c2VyID0gdGhpcy5fY2FjaGVHZXRVc2VyKHVpZCk7XG4gICAgICAgICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgICAgICAgdXNlciA9IHtcbiAgICAgICAgICAgICAgICB1c2VyOiB1aWQsXG4gICAgICAgICAgICAgICAgYWNzOiBhY3NcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgdGhpcy5nZXRNZXRhKHRoaXMuc3RhcnRNZXRhUXVlcnkoKS53aXRoT25lU3ViKHVuZGVmaW5lZCwgdWlkKS5idWlsZCgpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHVzZXIuYWNzID0gYWNzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXNlci51cGRhdGVkID0gbmV3IERhdGUoKTtcbiAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3NNZXRhU3ViKFt1c2VyXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEtub3duIHVzZXJcbiAgICAgICAgICB1c2VyLmFjcy51cGRhdGVBbGwocHJlcy5kYWNzKTtcbiAgICAgICAgICAvLyBVcGRhdGUgdXNlcidzIGFjY2VzcyBtb2RlLlxuICAgICAgICAgIHRoaXMuX3Byb2Nlc3NNZXRhU3ViKFt7XG4gICAgICAgICAgICB1c2VyOiB1aWQsXG4gICAgICAgICAgICB1cGRhdGVkOiBuZXcgRGF0ZSgpLFxuICAgICAgICAgICAgYWNzOiB1c2VyLmFjc1xuICAgICAgICAgIH1dKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRoaXMuX3Rpbm9kZS5sb2dnZXIoXCJJTkZPOiBJZ25vcmVkIHByZXNlbmNlIHVwZGF0ZVwiLCBwcmVzLndoYXQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9uUHJlcykge1xuICAgICAgdGhpcy5vblByZXMocHJlcyk7XG4gICAgfVxuICB9XG4gIC8vIFByb2Nlc3Mge2luZm99IG1lc3NhZ2VcbiAgX3JvdXRlSW5mbyhpbmZvKSB7XG4gICAgaWYgKGluZm8ud2hhdCAhPT0gJ2twJykge1xuICAgICAgY29uc3QgdXNlciA9IHRoaXMuX3VzZXJzW2luZm8uZnJvbV07XG4gICAgICBpZiAodXNlcikge1xuICAgICAgICB1c2VyW2luZm8ud2hhdF0gPSBpbmZvLnNlcTtcbiAgICAgICAgaWYgKHVzZXIucmVjdiA8IHVzZXIucmVhZCkge1xuICAgICAgICAgIHVzZXIucmVjdiA9IHVzZXIucmVhZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgbXNnID0gdGhpcy5sYXRlc3RNZXNzYWdlKCk7XG4gICAgICBpZiAobXNnKSB7XG4gICAgICAgIHRoaXMubXNnU3RhdHVzKG1zZywgdHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIElmIHRoaXMgaXMgYW4gdXBkYXRlIGZyb20gdGhlIGN1cnJlbnQgdXNlciwgdXBkYXRlIHRoZSBjYWNoZSB3aXRoIHRoZSBuZXcgY291bnQuXG4gICAgICBpZiAodGhpcy5fdGlub2RlLmlzTWUoaW5mby5mcm9tKSkge1xuICAgICAgICB0aGlzLl91cGRhdGVSZWFkUmVjdihpbmZvLndoYXQsIGluZm8uc2VxKTtcbiAgICAgIH1cblxuICAgICAgLy8gTm90aWZ5ICdtZScgbGlzdGVuZXIgb2YgdGhlIHN0YXR1cyBjaGFuZ2UuXG4gICAgICB0aGlzLl90aW5vZGUuZ2V0TWVUb3BpYygpLl9yZWZyZXNoQ29udGFjdChpbmZvLndoYXQsIHRoaXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5vbkluZm8pIHtcbiAgICAgIHRoaXMub25JbmZvKGluZm8pO1xuICAgIH1cbiAgfVxuICAvLyBDYWxsZWQgYnkgVGlub2RlIHdoZW4gbWV0YS5kZXNjIHBhY2tldCBpcyByZWNlaXZlZC5cbiAgLy8gQ2FsbGVkIGJ5ICdtZScgdG9waWMgb24gY29udGFjdCB1cGRhdGUgKGRlc2MuX25vRm9yd2FyZGluZyBpcyB0cnVlKS5cbiAgX3Byb2Nlc3NNZXRhRGVzYyhkZXNjKSB7XG4gICAgaWYgKHRoaXMuaXNQMlBUeXBlKCkpIHtcbiAgICAgIC8vIFN5bnRoZXRpYyBkZXNjIG1heSBpbmNsdWRlIGRlZmFjcyBmb3IgcDJwIHRvcGljcyB3aGljaCBpcyB1c2VsZXNzLlxuICAgICAgLy8gUmVtb3ZlIGl0LlxuICAgICAgZGVsZXRlIGRlc2MuZGVmYWNzO1xuXG4gICAgICAvLyBVcGRhdGUgdG8gcDJwIGRlc2MgaXMgdGhlIHNhbWUgYXMgdXNlciB1cGRhdGUuIFVwZGF0ZSBjYWNoZWQgdXNlci5cbiAgICAgIHRoaXMuX3Rpbm9kZS5fZGIudXBkVXNlcih0aGlzLm5hbWUsIGRlc2MucHVibGljKTtcbiAgICB9XG5cbiAgICAvLyBDb3B5IHBhcmFtZXRlcnMgZnJvbSBkZXNjIG9iamVjdCB0byB0aGlzIHRvcGljLlxuICAgIG1lcmdlT2JqKHRoaXMsIGRlc2MpO1xuICAgIC8vIFVwZGF0ZSBwZXJzaXN0ZW50IGNhY2hlLlxuICAgIHRoaXMuX3Rpbm9kZS5fZGIudXBkVG9waWModGhpcyk7XG5cbiAgICAvLyBOb3RpZnkgJ21lJyBsaXN0ZW5lciwgaWYgYXZhaWxhYmxlOlxuICAgIGlmICh0aGlzLm5hbWUgIT09IENvbnN0LlRPUElDX01FICYmICFkZXNjLl9ub0ZvcndhcmRpbmcpIHtcbiAgICAgIGNvbnN0IG1lID0gdGhpcy5fdGlub2RlLmdldE1lVG9waWMoKTtcbiAgICAgIGlmIChtZS5vbk1ldGFTdWIpIHtcbiAgICAgICAgbWUub25NZXRhU3ViKHRoaXMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lLm9uU3Vic1VwZGF0ZWQpIHtcbiAgICAgICAgbWUub25TdWJzVXBkYXRlZChbdGhpcy5uYW1lXSwgMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub25NZXRhRGVzYykge1xuICAgICAgdGhpcy5vbk1ldGFEZXNjKHRoaXMpO1xuICAgIH1cbiAgfVxuICAvLyBDYWxsZWQgYnkgVGlub2RlIHdoZW4gbWV0YS5zdWIgaXMgcmVjaXZlZCBvciBpbiByZXNwb25zZSB0byByZWNlaXZlZFxuICAvLyB7Y3RybH0gYWZ0ZXIgc2V0TWV0YS1zdWIuXG4gIF9wcm9jZXNzTWV0YVN1YihzdWJzKSB7XG4gICAgZm9yIChsZXQgaWR4IGluIHN1YnMpIHtcbiAgICAgIGNvbnN0IHN1YiA9IHN1YnNbaWR4XTtcblxuICAgICAgLy8gRmlsbCBkZWZhdWx0cy5cbiAgICAgIHN1Yi5vbmxpbmUgPSAhIXN1Yi5vbmxpbmU7XG4gICAgICAvLyBVcGRhdGUgdGltZXN0YW1wIG9mIHRoZSBtb3N0IHJlY2VudCBzdWJzY3JpcHRpb24gdXBkYXRlLlxuICAgICAgdGhpcy5fbGFzdFN1YnNVcGRhdGUgPSBuZXcgRGF0ZShNYXRoLm1heCh0aGlzLl9sYXN0U3Vic1VwZGF0ZSwgc3ViLnVwZGF0ZWQpKTtcblxuICAgICAgbGV0IHVzZXIgPSBudWxsO1xuICAgICAgaWYgKCFzdWIuZGVsZXRlZCkge1xuICAgICAgICAvLyBJZiB0aGlzIGlzIGEgY2hhbmdlIHRvIHVzZXIncyBvd24gcGVybWlzc2lvbnMsIHVwZGF0ZSB0aGVtIGluIHRvcGljIHRvby5cbiAgICAgICAgLy8gRGVzYyB3aWxsIHVwZGF0ZSAnbWUnIHRvcGljLlxuICAgICAgICBpZiAodGhpcy5fdGlub2RlLmlzTWUoc3ViLnVzZXIpICYmIHN1Yi5hY3MpIHtcbiAgICAgICAgICB0aGlzLl9wcm9jZXNzTWV0YURlc2Moe1xuICAgICAgICAgICAgdXBkYXRlZDogc3ViLnVwZGF0ZWQsXG4gICAgICAgICAgICB0b3VjaGVkOiBzdWIudG91Y2hlZCxcbiAgICAgICAgICAgIGFjczogc3ViLmFjc1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHVzZXIgPSB0aGlzLl91cGRhdGVDYWNoZWRVc2VyKHN1Yi51c2VyLCBzdWIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gU3Vic2NyaXB0aW9uIGlzIGRlbGV0ZWQsIHJlbW92ZSBpdCBmcm9tIHRvcGljIChidXQgbGVhdmUgaW4gVXNlcnMgY2FjaGUpXG4gICAgICAgIGRlbGV0ZSB0aGlzLl91c2Vyc1tzdWIudXNlcl07XG4gICAgICAgIHVzZXIgPSBzdWI7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLm9uTWV0YVN1Yikge1xuICAgICAgICB0aGlzLm9uTWV0YVN1Yih1c2VyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5vblN1YnNVcGRhdGVkKSB7XG4gICAgICB0aGlzLm9uU3Vic1VwZGF0ZWQoT2JqZWN0LmtleXModGhpcy5fdXNlcnMpKTtcbiAgICB9XG4gIH1cbiAgLy8gQ2FsbGVkIGJ5IFRpbm9kZSB3aGVuIG1ldGEudGFncyBpcyByZWNpdmVkLlxuICBfcHJvY2Vzc01ldGFUYWdzKHRhZ3MpIHtcbiAgICBpZiAodGFncy5sZW5ndGggPT0gMSAmJiB0YWdzWzBdID09IENvbnN0LkRFTF9DSEFSKSB7XG4gICAgICB0YWdzID0gW107XG4gICAgfVxuICAgIHRoaXMuX3RhZ3MgPSB0YWdzO1xuICAgIGlmICh0aGlzLm9uVGFnc1VwZGF0ZWQpIHtcbiAgICAgIHRoaXMub25UYWdzVXBkYXRlZCh0YWdzKTtcbiAgICB9XG4gIH1cbiAgLy8gRG8gbm90aGluZyBmb3IgdG9waWNzIG90aGVyIHRoYW4gJ21lJ1xuICBfcHJvY2Vzc01ldGFDcmVkcyhjcmVkcykge31cbiAgLy8gRGVsZXRlIGNhY2hlZCBtZXNzYWdlcyBhbmQgdXBkYXRlIGNhY2hlZCB0cmFuc2FjdGlvbiBJRHNcbiAgX3Byb2Nlc3NEZWxNZXNzYWdlcyhjbGVhciwgZGVsc2VxKSB7XG4gICAgdGhpcy5fbWF4RGVsID0gTWF0aC5tYXgoY2xlYXIsIHRoaXMuX21heERlbCk7XG4gICAgdGhpcy5jbGVhciA9IE1hdGgubWF4KGNsZWFyLCB0aGlzLmNsZWFyKTtcbiAgICBjb25zdCB0b3BpYyA9IHRoaXM7XG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShkZWxzZXEpKSB7XG4gICAgICBkZWxzZXEuZm9yRWFjaChmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICBpZiAoIXJhbmdlLmhpKSB7XG4gICAgICAgICAgY291bnQrKztcbiAgICAgICAgICB0b3BpYy5mbHVzaE1lc3NhZ2UocmFuZ2UubG93KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gcmFuZ2UubG93OyBpIDwgcmFuZ2UuaGk7IGkrKykge1xuICAgICAgICAgICAgY291bnQrKztcbiAgICAgICAgICAgIHRvcGljLmZsdXNoTWVzc2FnZShpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChjb3VudCA+IDApIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURlbGV0ZWRSYW5nZXMoKTtcblxuICAgICAgaWYgKHRoaXMub25EYXRhKSB7XG4gICAgICAgIHRoaXMub25EYXRhKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIFRvcGljIGlzIGluZm9ybWVkIHRoYXQgdGhlIGVudGlyZSByZXNwb25zZSB0byB7Z2V0IHdoYXQ9ZGF0YX0gaGFzIGJlZW4gcmVjZWl2ZWQuXG4gIF9hbGxNZXNzYWdlc1JlY2VpdmVkKGNvdW50KSB7XG4gICAgdGhpcy5fdXBkYXRlRGVsZXRlZFJhbmdlcygpO1xuXG4gICAgaWYgKHRoaXMub25BbGxNZXNzYWdlc1JlY2VpdmVkKSB7XG4gICAgICB0aGlzLm9uQWxsTWVzc2FnZXNSZWNlaXZlZChjb3VudCk7XG4gICAgfVxuICB9XG4gIC8vIFJlc2V0IHN1YnNjcmliZWQgc3RhdGVcbiAgX3Jlc2V0U3ViKCkge1xuICAgIHRoaXMuX2F0dGFjaGVkID0gZmFsc2U7XG4gIH1cbiAgLy8gVGhpcyB0b3BpYyBpcyBlaXRoZXIgZGVsZXRlZCBvciB1bnN1YnNjcmliZWQgZnJvbS5cbiAgX2dvbmUoKSB7XG4gICAgdGhpcy5fbWVzc2FnZXMucmVzZXQoKTtcbiAgICB0aGlzLl90aW5vZGUuX2RiLnJlbU1lc3NhZ2VzKHRoaXMubmFtZSk7XG4gICAgdGhpcy5fdXNlcnMgPSB7fTtcbiAgICB0aGlzLmFjcyA9IG5ldyBBY2Nlc3NNb2RlKG51bGwpO1xuICAgIHRoaXMucHJpdmF0ZSA9IG51bGw7XG4gICAgdGhpcy5wdWJsaWMgPSBudWxsO1xuICAgIHRoaXMudHJ1c3RlZCA9IG51bGw7XG4gICAgdGhpcy5fbWF4U2VxID0gMDtcbiAgICB0aGlzLl9taW5TZXEgPSAwO1xuICAgIHRoaXMuX2F0dGFjaGVkID0gZmFsc2U7XG5cbiAgICBjb25zdCBtZSA9IHRoaXMuX3Rpbm9kZS5nZXRNZVRvcGljKCk7XG4gICAgaWYgKG1lKSB7XG4gICAgICBtZS5fcm91dGVQcmVzKHtcbiAgICAgICAgX25vRm9yd2FyZGluZzogdHJ1ZSxcbiAgICAgICAgd2hhdDogJ2dvbmUnLFxuICAgICAgICB0b3BpYzogQ29uc3QuVE9QSUNfTUUsXG4gICAgICAgIHNyYzogdGhpcy5uYW1lXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHRoaXMub25EZWxldGVUb3BpYykge1xuICAgICAgdGhpcy5vbkRlbGV0ZVRvcGljKCk7XG4gICAgfVxuICB9XG4gIC8vIFVwZGF0ZSBnbG9iYWwgdXNlciBjYWNoZSBhbmQgbG9jYWwgc3Vic2NyaWJlcnMgY2FjaGUuXG4gIC8vIERvbid0IGNhbGwgdGhpcyBtZXRob2QgZm9yIG5vbi1zdWJzY3JpYmVycy5cbiAgX3VwZGF0ZUNhY2hlZFVzZXIodWlkLCBvYmopIHtcbiAgICAvLyBGZXRjaCB1c2VyIG9iamVjdCBmcm9tIHRoZSBnbG9iYWwgY2FjaGUuXG4gICAgLy8gVGhpcyBpcyBhIGNsb25lIG9mIHRoZSBzdG9yZWQgb2JqZWN0XG4gICAgbGV0IGNhY2hlZCA9IHRoaXMuX2NhY2hlR2V0VXNlcih1aWQpO1xuICAgIGNhY2hlZCA9IG1lcmdlT2JqKGNhY2hlZCB8fCB7fSwgb2JqKTtcbiAgICAvLyBTYXZlIHRvIGdsb2JhbCBjYWNoZVxuICAgIHRoaXMuX2NhY2hlUHV0VXNlcih1aWQsIGNhY2hlZCk7XG4gICAgLy8gU2F2ZSB0byB0aGUgbGlzdCBvZiB0b3BpYyBzdWJzcmliZXJzLlxuICAgIHJldHVybiBtZXJnZVRvQ2FjaGUodGhpcy5fdXNlcnMsIHVpZCwgY2FjaGVkKTtcbiAgfVxuICAvLyBHZXQgbG9jYWwgc2VxSWQgZm9yIGEgcXVldWVkIG1lc3NhZ2UuXG4gIF9nZXRRdWV1ZWRTZXFJZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcXVldWVkU2VxSWQrKztcbiAgfVxuICAvLyBDYWxjdWxhdGUgcmFuZ2VzIG9mIG1pc3NpbmcgbWVzc2FnZXMuXG4gIF91cGRhdGVEZWxldGVkUmFuZ2VzKCkge1xuICAgIGNvbnN0IHJhbmdlcyA9IFtdO1xuXG4gICAgLy8gR2FwIG1hcmtlciwgcG9zc2libHkgZW1wdHkuXG4gICAgbGV0IHByZXYgPSBudWxsO1xuXG4gICAgLy8gQ2hlY2sgZm9yIGdhcCBpbiB0aGUgYmVnaW5uaW5nLCBiZWZvcmUgdGhlIGZpcnN0IG1lc3NhZ2UuXG4gICAgY29uc3QgZmlyc3QgPSB0aGlzLl9tZXNzYWdlcy5nZXRBdCgwKTtcbiAgICBpZiAoZmlyc3QgJiYgdGhpcy5fbWluU2VxID4gMSAmJiAhdGhpcy5fbm9FYXJsaWVyTXNncykge1xuICAgICAgLy8gU29tZSBtZXNzYWdlcyBhcmUgbWlzc2luZyBpbiB0aGUgYmVnaW5uaW5nLlxuICAgICAgaWYgKGZpcnN0LmhpKSB7XG4gICAgICAgIC8vIFRoZSBmaXJzdCBtZXNzYWdlIGFscmVhZHkgcmVwcmVzZW50cyBhIGdhcC5cbiAgICAgICAgaWYgKGZpcnN0LnNlcSA+IDEpIHtcbiAgICAgICAgICBmaXJzdC5zZXEgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaXJzdC5oaSA8IHRoaXMuX21pblNlcSAtIDEpIHtcbiAgICAgICAgICBmaXJzdC5oaSA9IHRoaXMuX21pblNlcSAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgcHJldiA9IGZpcnN0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ3JlYXRlIG5ldyBnYXAuXG4gICAgICAgIHByZXYgPSB7XG4gICAgICAgICAgc2VxOiAxLFxuICAgICAgICAgIGhpOiB0aGlzLl9taW5TZXEgLSAxXG4gICAgICAgIH07XG4gICAgICAgIHJhbmdlcy5wdXNoKHByZXYpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyBnYXAgaW4gdGhlIGJlZ2lubmluZy5cbiAgICAgIHByZXYgPSB7XG4gICAgICAgIHNlcTogMCxcbiAgICAgICAgaGk6IDBcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gRmluZCBuZXcgZ2FwcyBpbiB0aGUgbGlzdCBvZiByZWNlaXZlZCBtZXNzYWdlcy4gVGhlIGxpc3QgY29udGFpbnMgbWVzc2FnZXMtcHJvcGVyIGFzIHdlbGxcbiAgICAvLyBhcyBwbGFjZWhvbGRlcnMgZm9yIGRlbGV0ZWQgcmFuZ2VzLlxuICAgIC8vIFRoZSBtZXNzYWdlcyBhcmUgaXRlcmF0ZWQgYnkgc2VxIElEIGluIGFzY2VuZGluZyBvcmRlci5cbiAgICB0aGlzLl9tZXNzYWdlcy5maWx0ZXIoKGRhdGEpID0+IHtcbiAgICAgIC8vIERvIG5vdCBjcmVhdGUgYSBnYXAgYmV0d2VlbiB0aGUgbGFzdCBzZW50IG1lc3NhZ2UgYW5kIHRoZSBmaXJzdCB1bnNlbnQgYXMgd2VsbCBhcyBiZXR3ZWVuIHVuc2VudCBtZXNzYWdlcy5cbiAgICAgIGlmIChkYXRhLnNlcSA+PSBDb25zdC5MT0NBTF9TRVFJRCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgZm9yIGEgZ2FwIGJldHdlZW4gdGhlIHByZXZpb3VzIG1lc3NhZ2UvbWFya2VyIGFuZCB0aGlzIG1lc3NhZ2UvbWFya2VyLlxuICAgICAgaWYgKGRhdGEuc2VxID09IChwcmV2LmhpIHx8IHByZXYuc2VxKSArIDEpIHtcbiAgICAgICAgLy8gTm8gZ2FwIGJldHdlZW4gdGhpcyBtZXNzYWdlIGFuZCB0aGUgcHJldmlvdXMuXG4gICAgICAgIGlmIChkYXRhLmhpICYmIHByZXYuaGkpIHtcbiAgICAgICAgICAvLyBUd28gZ2FwIG1hcmtlcnMgaW4gYSByb3cuIEV4dGVuZCB0aGUgcHJldmlvdXMgb25lLCBkaXNjYXJkIHRoZSBjdXJyZW50LlxuICAgICAgICAgIHByZXYuaGkgPSBkYXRhLmhpO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBwcmV2ID0gZGF0YTtcblxuICAgICAgICAvLyBLZWVwIGN1cnJlbnQuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3VuZCBhIG5ldyBnYXAuXG4gICAgICAvLyBDaGVjayBpZiB0aGUgcHJldmlvdXMgaXMgYWxzbyBhIGdhcCBtYXJrZXIuXG4gICAgICBpZiAocHJldi5oaSkge1xuICAgICAgICAvLyBBbHRlciBpdCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IG9uZS5cbiAgICAgICAgcHJldi5oaSA9IGRhdGEuaGkgfHwgZGF0YS5zZXE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBQcmV2aW91cyBpcyBub3QgYSBnYXAgbWFya2VyLiBDcmVhdGUgYSBuZXcgb25lLlxuICAgICAgICBwcmV2ID0ge1xuICAgICAgICAgIHNlcTogcHJldi5zZXEgKyAxLFxuICAgICAgICAgIGhpOiBkYXRhLmhpIHx8IGRhdGEuc2VxXG4gICAgICAgIH07XG4gICAgICAgIHJhbmdlcy5wdXNoKHByZXYpO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBtYXJrZXIsIHJlbW92ZTsga2VlcCBpZiByZWd1bGFyIG1lc3NhZ2UuXG4gICAgICBpZiAoIWRhdGEuaGkpIHtcbiAgICAgICAgLy8gS2VlcGluZyB0aGUgY3VycmVudCByZWd1bGFyIG1lc3NhZ2UsIHNhdmUgaXQgYXMgcHJldmlvdXMuXG4gICAgICAgIHByZXYgPSBkYXRhO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gRGlzY2FyZCB0aGUgY3VycmVudCBnYXAgbWFya2VyOiB3ZSBlaXRoZXIgY3JlYXRlZCBhbiBlYXJsaWVyIGdhcCwgb3IgZXh0ZW5kZWQgdGhlIHByZXZvdXMgb25lLlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuXG4gICAgLy8gQ2hlY2sgZm9yIG1pc3NpbmcgbWVzc2FnZXMgYXQgdGhlIGVuZC5cbiAgICAvLyBBbGwgbWVzc2FnZXMgY291bGQgYmUgbWlzc2luZyBvciBpdCBjb3VsZCBiZSBhIG5ldyB0b3BpYyB3aXRoIG5vIG1lc3NhZ2VzLlxuICAgIGNvbnN0IGxhc3QgPSB0aGlzLl9tZXNzYWdlcy5nZXRMYXN0KCk7XG4gICAgY29uc3QgbWF4U2VxID0gTWF0aC5tYXgodGhpcy5zZXEsIHRoaXMuX21heFNlcSkgfHwgMDtcbiAgICBpZiAoKG1heFNlcSA+IDAgJiYgIWxhc3QpIHx8IChsYXN0ICYmICgobGFzdC5oaSB8fCBsYXN0LnNlcSkgPCBtYXhTZXEpKSkge1xuICAgICAgaWYgKGxhc3QgJiYgbGFzdC5oaSkge1xuICAgICAgICAvLyBFeHRlbmQgZXhpc3RpbmcgZ2FwXG4gICAgICAgIGxhc3QuaGkgPSBtYXhTZXE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDcmVhdGUgbmV3IGdhcC5cbiAgICAgICAgcmFuZ2VzLnB1c2goe1xuICAgICAgICAgIHNlcTogbGFzdCA/IGxhc3Quc2VxICsgMSA6IDEsXG4gICAgICAgICAgaGk6IG1heFNlcVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJbnNlcnQgbmV3IGdhcHMgaW50byBjYWNoZS5cbiAgICByYW5nZXMuZm9yRWFjaCgoZ2FwKSA9PiB7XG4gICAgICBnYXAuX3N0YXR1cyA9IENvbnN0Lk1FU1NBR0VfU1RBVFVTX0RFTF9SQU5HRTtcbiAgICAgIHRoaXMuX21lc3NhZ2VzLnB1dChnYXApO1xuICAgIH0pO1xuICB9XG4gIC8vIExvYWQgbW9zdCByZWNlbnQgbWVzc2FnZXMgZnJvbSBwZXJzaXN0ZW50IGNhY2hlLlxuICBfbG9hZE1lc3NhZ2VzKGRiLCBwYXJhbXMpIHtcbiAgICBjb25zdCB7XG4gICAgICBzaW5jZSxcbiAgICAgIGJlZm9yZSxcbiAgICAgIGxpbWl0XG4gICAgfSA9IHBhcmFtcyB8fCB7fTtcbiAgICByZXR1cm4gZGIucmVhZE1lc3NhZ2VzKHRoaXMubmFtZSwge1xuICAgICAgICBzaW5jZTogc2luY2UsXG4gICAgICAgIGJlZm9yZTogYmVmb3JlLFxuICAgICAgICBsaW1pdDogbGltaXQgfHwgQ29uc3QuREVGQVVMVF9NRVNTQUdFU19QQUdFXG4gICAgICB9KVxuICAgICAgLnRoZW4oKG1zZ3MpID0+IHtcbiAgICAgICAgbXNncy5mb3JFYWNoKChkYXRhKSA9PiB7XG4gICAgICAgICAgaWYgKGRhdGEuc2VxID4gdGhpcy5fbWF4U2VxKSB7XG4gICAgICAgICAgICB0aGlzLl9tYXhTZXEgPSBkYXRhLnNlcTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRhdGEuc2VxIDwgdGhpcy5fbWluU2VxIHx8IHRoaXMuX21pblNlcSA9PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9taW5TZXEgPSBkYXRhLnNlcTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5fbWVzc2FnZXMucHV0KGRhdGEpO1xuICAgICAgICAgIHRoaXMuX21heWJlVXBkYXRlTWVzc2FnZVZlcnNpb25zQ2FjaGUoZGF0YSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAobXNncy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5fdXBkYXRlRGVsZXRlZFJhbmdlcygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtc2dzLmxlbmd0aDtcbiAgICAgIH0pO1xuICB9XG4gIC8vIFB1c2ggb3Ige3ByZXN9OiBtZXNzYWdlIHJlY2VpdmVkLlxuICBfdXBkYXRlUmVjZWl2ZWQoc2VxLCBhY3QpIHtcbiAgICB0aGlzLnRvdWNoZWQgPSBuZXcgRGF0ZSgpO1xuICAgIHRoaXMuc2VxID0gc2VxIHwgMDtcbiAgICAvLyBDaGVjayBpZiBtZXNzYWdlIGlzIHNlbnQgYnkgdGhlIGN1cnJlbnQgdXNlci4gSWYgc28gaXQncyBiZWVuIHJlYWQgYWxyZWFkeS5cbiAgICBpZiAoIWFjdCB8fCB0aGlzLl90aW5vZGUuaXNNZShhY3QpKSB7XG4gICAgICB0aGlzLnJlYWQgPSB0aGlzLnJlYWQgPyBNYXRoLm1heCh0aGlzLnJlYWQsIHRoaXMuc2VxKSA6IHRoaXMuc2VxO1xuICAgICAgdGhpcy5yZWN2ID0gdGhpcy5yZWN2ID8gTWF0aC5tYXgodGhpcy5yZWFkLCB0aGlzLnJlY3YpIDogdGhpcy5yZWFkO1xuICAgIH1cbiAgICB0aGlzLnVucmVhZCA9IHRoaXMuc2VxIC0gKHRoaXMucmVhZCB8IDApO1xuICAgIHRoaXMuX3Rpbm9kZS5fZGIudXBkVG9waWModGhpcyk7XG4gIH1cbn1cblxuXG4vKipcbiAqIEBjbGFzcyBUb3BpY01lIC0gc3BlY2lhbCBjYXNlIG9mIHtAbGluayBUaW5vZGUuVG9waWN9IGZvclxuICogbWFuYWdpbmcgZGF0YSBvZiB0aGUgY3VycmVudCB1c2VyLCBpbmNsdWRpbmcgY29udGFjdCBsaXN0LlxuICogQGV4dGVuZHMgVGlub2RlLlRvcGljXG4gKiBAbWVtYmVyb2YgVGlub2RlXG4gKlxuICogQHBhcmFtIHtUb3BpY01lLkNhbGxiYWNrc30gY2FsbGJhY2tzIC0gQ2FsbGJhY2tzIHRvIHJlY2VpdmUgdmFyaW91cyBldmVudHMuXG4gKi9cbi8qKlxuICogQGNsYXNzIFRvcGljTWUgLSBzcGVjaWFsIGNhc2Ugb2Yge0BsaW5rIFRpbm9kZS5Ub3BpY30gZm9yXG4gKiBtYW5hZ2luZyBkYXRhIG9mIHRoZSBjdXJyZW50IHVzZXIsIGluY2x1ZGluZyBjb250YWN0IGxpc3QuXG4gKiBAZXh0ZW5kcyBUaW5vZGUuVG9waWNcbiAqIEBtZW1iZXJvZiBUaW5vZGVcbiAqXG4gKiBAcGFyYW0ge1RvcGljTWUuQ2FsbGJhY2tzfSBjYWxsYmFja3MgLSBDYWxsYmFja3MgdG8gcmVjZWl2ZSB2YXJpb3VzIGV2ZW50cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRvcGljTWUgZXh0ZW5kcyBUb3BpYyB7XG4gIG9uQ29udGFjdFVwZGF0ZTtcblxuICBjb25zdHJ1Y3RvcihjYWxsYmFja3MpIHtcbiAgICBzdXBlcihDb25zdC5UT1BJQ19NRSwgY2FsbGJhY2tzKTtcblxuICAgIC8vIG1lLXNwZWNpZmljIGNhbGxiYWNrc1xuICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgIHRoaXMub25Db250YWN0VXBkYXRlID0gY2FsbGJhY2tzLm9uQ29udGFjdFVwZGF0ZTtcbiAgICB9XG4gIH1cblxuICAvLyBPdmVycmlkZSB0aGUgb3JpZ2luYWwgVG9waWMuX3Byb2Nlc3NNZXRhRGVzYy5cbiAgX3Byb2Nlc3NNZXRhRGVzYyhkZXNjKSB7XG4gICAgLy8gQ2hlY2sgaWYgb25saW5lIGNvbnRhY3RzIG5lZWQgdG8gYmUgdHVybmVkIG9mZiBiZWNhdXNlIFAgcGVybWlzc2lvbiB3YXMgcmVtb3ZlZC5cbiAgICBjb25zdCB0dXJuT2ZmID0gKGRlc2MuYWNzICYmICFkZXNjLmFjcy5pc1ByZXNlbmNlcigpKSAmJiAodGhpcy5hY3MgJiYgdGhpcy5hY3MuaXNQcmVzZW5jZXIoKSk7XG5cbiAgICAvLyBDb3B5IHBhcmFtZXRlcnMgZnJvbSBkZXNjIG9iamVjdCB0byB0aGlzIHRvcGljLlxuICAgIG1lcmdlT2JqKHRoaXMsIGRlc2MpO1xuICAgIHRoaXMuX3Rpbm9kZS5fZGIudXBkVG9waWModGhpcyk7XG4gICAgLy8gVXBkYXRlIGN1cnJlbnQgdXNlcidzIHJlY29yZCBpbiB0aGUgZ2xvYmFsIGNhY2hlLlxuICAgIHRoaXMuX3VwZGF0ZUNhY2hlZFVzZXIodGhpcy5fdGlub2RlLl9teVVJRCwgZGVzYyk7XG5cbiAgICAvLyAnUCcgcGVybWlzc2lvbiB3YXMgcmVtb3ZlZC4gQWxsIHRvcGljcyBhcmUgb2ZmbGluZSBub3cuXG4gICAgaWYgKHR1cm5PZmYpIHtcbiAgICAgIHRoaXMuX3Rpbm9kZS5tYXBUb3BpY3MoKGNvbnQpID0+IHtcbiAgICAgICAgaWYgKGNvbnQub25saW5lKSB7XG4gICAgICAgICAgY29udC5vbmxpbmUgPSBmYWxzZTtcbiAgICAgICAgICBjb250LnNlZW4gPSBPYmplY3QuYXNzaWduKGNvbnQuc2VlbiB8fCB7fSwge1xuICAgICAgICAgICAgd2hlbjogbmV3IERhdGUoKVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuX3JlZnJlc2hDb250YWN0KCdvZmYnLCBjb250KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub25NZXRhRGVzYykge1xuICAgICAgdGhpcy5vbk1ldGFEZXNjKHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIC8vIE92ZXJyaWRlIHRoZSBvcmlnaW5hbCBUb3BpYy5fcHJvY2Vzc01ldGFTdWJcbiAgX3Byb2Nlc3NNZXRhU3ViKHN1YnMpIHtcbiAgICBsZXQgdXBkYXRlQ291bnQgPSAwO1xuICAgIHN1YnMuZm9yRWFjaCgoc3ViKSA9PiB7XG4gICAgICBjb25zdCB0b3BpY05hbWUgPSBzdWIudG9waWM7XG4gICAgICAvLyBEb24ndCBzaG93ICdtZScgYW5kICdmbmQnIHRvcGljcyBpbiB0aGUgbGlzdCBvZiBjb250YWN0cy5cbiAgICAgIGlmICh0b3BpY05hbWUgPT0gQ29uc3QuVE9QSUNfRk5EIHx8IHRvcGljTmFtZSA9PSBDb25zdC5UT1BJQ19NRSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzdWIub25saW5lID0gISFzdWIub25saW5lO1xuXG4gICAgICBsZXQgY29udCA9IG51bGw7XG4gICAgICBpZiAoc3ViLmRlbGV0ZWQpIHtcbiAgICAgICAgY29udCA9IHN1YjtcbiAgICAgICAgdGhpcy5fdGlub2RlLmNhY2hlUmVtVG9waWModG9waWNOYW1lKTtcbiAgICAgICAgdGhpcy5fdGlub2RlLl9kYi5yZW1Ub3BpYyh0b3BpY05hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRW5zdXJlIHRoZSB2YWx1ZXMgYXJlIGRlZmluZWQgYW5kIGFyZSBpbnRlZ2Vycy5cbiAgICAgICAgaWYgKHR5cGVvZiBzdWIuc2VxICE9ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgc3ViLnNlcSA9IHN1Yi5zZXEgfCAwO1xuICAgICAgICAgIHN1Yi5yZWN2ID0gc3ViLnJlY3YgfCAwO1xuICAgICAgICAgIHN1Yi5yZWFkID0gc3ViLnJlYWQgfCAwO1xuICAgICAgICAgIHN1Yi51bnJlYWQgPSBzdWIuc2VxIC0gc3ViLnJlYWQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0b3BpYyA9IHRoaXMuX3Rpbm9kZS5nZXRUb3BpYyh0b3BpY05hbWUpO1xuICAgICAgICBpZiAodG9waWMuX25ldykge1xuICAgICAgICAgIGRlbGV0ZSB0b3BpYy5fbmV3O1xuICAgICAgICB9XG5cbiAgICAgICAgY29udCA9IG1lcmdlT2JqKHRvcGljLCBzdWIpO1xuICAgICAgICB0aGlzLl90aW5vZGUuX2RiLnVwZFRvcGljKGNvbnQpO1xuXG4gICAgICAgIGlmIChUb3BpYy5pc1AyUFRvcGljTmFtZSh0b3BpY05hbWUpKSB7XG4gICAgICAgICAgdGhpcy5fY2FjaGVQdXRVc2VyKHRvcGljTmFtZSwgY29udCk7XG4gICAgICAgICAgdGhpcy5fdGlub2RlLl9kYi51cGRVc2VyKHRvcGljTmFtZSwgY29udC5wdWJsaWMpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vdGlmeSB0b3BpYyBvZiB0aGUgdXBkYXRlIGlmIGl0J3MgYW4gZXh0ZXJuYWwgdXBkYXRlLlxuICAgICAgICBpZiAoIXN1Yi5fbm9Gb3J3YXJkaW5nICYmIHRvcGljKSB7XG4gICAgICAgICAgc3ViLl9ub0ZvcndhcmRpbmcgPSB0cnVlO1xuICAgICAgICAgIHRvcGljLl9wcm9jZXNzTWV0YURlc2Moc3ViKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB1cGRhdGVDb3VudCsrO1xuXG4gICAgICBpZiAodGhpcy5vbk1ldGFTdWIpIHtcbiAgICAgICAgdGhpcy5vbk1ldGFTdWIoY29udCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5vblN1YnNVcGRhdGVkICYmIHVwZGF0ZUNvdW50ID4gMCkge1xuICAgICAgY29uc3Qga2V5cyA9IFtdO1xuICAgICAgc3Vicy5mb3JFYWNoKChzKSA9PiB7XG4gICAgICAgIGtleXMucHVzaChzLnRvcGljKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5vblN1YnNVcGRhdGVkKGtleXMsIHVwZGF0ZUNvdW50KTtcbiAgICB9XG4gIH1cblxuICAvLyBDYWxsZWQgYnkgVGlub2RlIHdoZW4gbWV0YS5zdWIgaXMgcmVjaXZlZC5cbiAgX3Byb2Nlc3NNZXRhQ3JlZHMoY3JlZHMsIHVwZCkge1xuICAgIGlmIChjcmVkcy5sZW5ndGggPT0gMSAmJiBjcmVkc1swXSA9PSBDb25zdC5ERUxfQ0hBUikge1xuICAgICAgY3JlZHMgPSBbXTtcbiAgICB9XG4gICAgaWYgKHVwZCkge1xuICAgICAgY3JlZHMuZm9yRWFjaCgoY3IpID0+IHtcbiAgICAgICAgaWYgKGNyLnZhbCkge1xuICAgICAgICAgIC8vIEFkZGluZyBhIGNyZWRlbnRpYWwuXG4gICAgICAgICAgbGV0IGlkeCA9IHRoaXMuX2NyZWRlbnRpYWxzLmZpbmRJbmRleCgoZWwpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBlbC5tZXRoID09IGNyLm1ldGggJiYgZWwudmFsID09IGNyLnZhbDtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAoaWR4IDwgMCkge1xuICAgICAgICAgICAgLy8gTm90IGZvdW5kLlxuICAgICAgICAgICAgaWYgKCFjci5kb25lKSB7XG4gICAgICAgICAgICAgIC8vIFVuY29uZmlybWVkIGNyZWRlbnRpYWwgcmVwbGFjZXMgcHJldmlvdXMgdW5jb25maXJtZWQgY3JlZGVudGlhbCBvZiB0aGUgc2FtZSBtZXRob2QuXG4gICAgICAgICAgICAgIGlkeCA9IHRoaXMuX2NyZWRlbnRpYWxzLmZpbmRJbmRleCgoZWwpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZWwubWV0aCA9PSBjci5tZXRoICYmICFlbC5kb25lO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHByZXZpb3VzIHVuY29uZmlybWVkIGNyZWRlbnRpYWwuXG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlZGVudGlhbHMuc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2NyZWRlbnRpYWxzLnB1c2goY3IpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBGb3VuZC4gTWF5YmUgY2hhbmdlICdkb25lJyBzdGF0dXMuXG4gICAgICAgICAgICB0aGlzLl9jcmVkZW50aWFsc1tpZHhdLmRvbmUgPSBjci5kb25lO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChjci5yZXNwKSB7XG4gICAgICAgICAgLy8gSGFuZGxlIGNyZWRlbnRpYWwgY29uZmlybWF0aW9uLlxuICAgICAgICAgIGNvbnN0IGlkeCA9IHRoaXMuX2NyZWRlbnRpYWxzLmZpbmRJbmRleCgoZWwpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBlbC5tZXRoID09IGNyLm1ldGggJiYgIWVsLmRvbmU7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVkZW50aWFsc1tpZHhdLmRvbmUgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2NyZWRlbnRpYWxzID0gY3JlZHM7XG4gICAgfVxuICAgIGlmICh0aGlzLm9uQ3JlZHNVcGRhdGVkKSB7XG4gICAgICB0aGlzLm9uQ3JlZHNVcGRhdGVkKHRoaXMuX2NyZWRlbnRpYWxzKTtcbiAgICB9XG4gIH1cblxuICAvLyBQcm9jZXNzIHByZXNlbmNlIGNoYW5nZSBtZXNzYWdlXG4gIF9yb3V0ZVByZXMocHJlcykge1xuICAgIGlmIChwcmVzLndoYXQgPT0gJ3Rlcm0nKSB7XG4gICAgICAvLyBUaGUgJ21lJyB0b3BpYyBpdHNlbGYgaXMgZGV0YWNoZWQuIE1hcmsgYXMgdW5zdWJzY3JpYmVkLlxuICAgICAgdGhpcy5fcmVzZXRTdWIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocHJlcy53aGF0ID09ICd1cGQnICYmIHByZXMuc3JjID09IENvbnN0LlRPUElDX01FKSB7XG4gICAgICAvLyBVcGRhdGUgdG8gbWUncyBkZXNjcmlwdGlvbi4gUmVxdWVzdCB1cGRhdGVkIHZhbHVlLlxuICAgICAgdGhpcy5nZXRNZXRhKHRoaXMuc3RhcnRNZXRhUXVlcnkoKS53aXRoRGVzYygpLmJ1aWxkKCkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnQgPSB0aGlzLl90aW5vZGUuY2FjaGVHZXRUb3BpYyhwcmVzLnNyYyk7XG4gICAgaWYgKGNvbnQpIHtcbiAgICAgIHN3aXRjaCAocHJlcy53aGF0KSB7XG4gICAgICAgIGNhc2UgJ29uJzogLy8gdG9waWMgY2FtZSBvbmxpbmVcbiAgICAgICAgICBjb250Lm9ubGluZSA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ29mZic6IC8vIHRvcGljIHdlbnQgb2ZmbGluZVxuICAgICAgICAgIGlmIChjb250Lm9ubGluZSkge1xuICAgICAgICAgICAgY29udC5vbmxpbmUgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnQuc2VlbiA9IE9iamVjdC5hc3NpZ24oY29udC5zZWVuIHx8IHt9LCB7XG4gICAgICAgICAgICAgIHdoZW46IG5ldyBEYXRlKClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbXNnJzogLy8gbmV3IG1lc3NhZ2UgcmVjZWl2ZWRcbiAgICAgICAgICBjb250Ll91cGRhdGVSZWNlaXZlZChwcmVzLnNlcSwgcHJlcy5hY3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1cGQnOiAvLyBkZXNjIHVwZGF0ZWRcbiAgICAgICAgICAvLyBSZXF1ZXN0IHVwZGF0ZWQgc3Vic2NyaXB0aW9uLlxuICAgICAgICAgIHRoaXMuZ2V0TWV0YSh0aGlzLnN0YXJ0TWV0YVF1ZXJ5KCkud2l0aExhdGVyT25lU3ViKHByZXMuc3JjKS5idWlsZCgpKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnYWNzJzogLy8gYWNjZXNzIG1vZGUgY2hhbmdlZFxuICAgICAgICAgIGlmIChjb250LmFjcykge1xuICAgICAgICAgICAgY29udC5hY3MudXBkYXRlQWxsKHByZXMuZGFjcyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnQuYWNzID0gbmV3IEFjY2Vzc01vZGUoKS51cGRhdGVBbGwocHJlcy5kYWNzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udC50b3VjaGVkID0gbmV3IERhdGUoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndWEnOlxuICAgICAgICAgIC8vIHVzZXIgYWdlbnQgY2hhbmdlZC5cbiAgICAgICAgICBjb250LnNlZW4gPSB7XG4gICAgICAgICAgICB3aGVuOiBuZXcgRGF0ZSgpLFxuICAgICAgICAgICAgdWE6IHByZXMudWFcbiAgICAgICAgICB9O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdyZWN2JzpcbiAgICAgICAgICAvLyB1c2VyJ3Mgb3RoZXIgc2Vzc2lvbiBtYXJrZWQgc29tZSBtZXNzZ2VzIGFzIHJlY2VpdmVkLlxuICAgICAgICAgIHByZXMuc2VxID0gcHJlcy5zZXEgfCAwO1xuICAgICAgICAgIGNvbnQucmVjdiA9IGNvbnQucmVjdiA/IE1hdGgubWF4KGNvbnQucmVjdiwgcHJlcy5zZXEpIDogcHJlcy5zZXE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3JlYWQnOlxuICAgICAgICAgIC8vIHVzZXIncyBvdGhlciBzZXNzaW9uIG1hcmtlZCBzb21lIG1lc3NhZ2VzIGFzIHJlYWQuXG4gICAgICAgICAgcHJlcy5zZXEgPSBwcmVzLnNlcSB8IDA7XG4gICAgICAgICAgY29udC5yZWFkID0gY29udC5yZWFkID8gTWF0aC5tYXgoY29udC5yZWFkLCBwcmVzLnNlcSkgOiBwcmVzLnNlcTtcbiAgICAgICAgICBjb250LnJlY3YgPSBjb250LnJlY3YgPyBNYXRoLm1heChjb250LnJlYWQsIGNvbnQucmVjdikgOiBjb250LnJlY3Y7XG4gICAgICAgICAgY29udC51bnJlYWQgPSBjb250LnNlcSAtIGNvbnQucmVhZDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZ29uZSc6XG4gICAgICAgICAgLy8gdG9waWMgZGVsZXRlZCBvciB1bnN1YnNjcmliZWQgZnJvbS5cbiAgICAgICAgICBpZiAoIWNvbnQuX2RlbGV0ZWQpIHtcbiAgICAgICAgICAgIGNvbnQuX2RlbGV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgY29udC5fYXR0YWNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX3Rpbm9kZS5fZGIubWFya1RvcGljQXNEZWxldGVkKHByZXMuc3JjKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fdGlub2RlLl9kYi5yZW1Ub3BpYyhwcmVzLnNyYyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkZWwnOlxuICAgICAgICAgIC8vIFVwZGF0ZSB0b3BpYy5kZWwgdmFsdWUuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhpcy5fdGlub2RlLmxvZ2dlcihcIklORk86IFVuc3VwcG9ydGVkIHByZXNlbmNlIHVwZGF0ZSBpbiAnbWUnXCIsIHByZXMud2hhdCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3JlZnJlc2hDb250YWN0KHByZXMud2hhdCwgY29udCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChwcmVzLndoYXQgPT0gJ2FjcycpIHtcbiAgICAgICAgLy8gTmV3IHN1YnNjcmlwdGlvbnMgYW5kIGRlbGV0ZWQvYmFubmVkIHN1YnNjcmlwdGlvbnMgaGF2ZSBmdWxsXG4gICAgICAgIC8vIGFjY2VzcyBtb2RlIChubyArIG9yIC0gaW4gdGhlIGRhY3Mgc3RyaW5nKS4gQ2hhbmdlcyB0byBrbm93biBzdWJzY3JpcHRpb25zIGFyZSBzZW50IGFzXG4gICAgICAgIC8vIGRlbHRhcywgYnV0IHRoZXkgc2hvdWxkIG5vdCBoYXBwZW4gaGVyZS5cbiAgICAgICAgY29uc3QgYWNzID0gbmV3IEFjY2Vzc01vZGUocHJlcy5kYWNzKTtcbiAgICAgICAgaWYgKCFhY3MgfHwgYWNzLm1vZGUgPT0gQWNjZXNzTW9kZS5fSU5WQUxJRCkge1xuICAgICAgICAgIHRoaXMuX3Rpbm9kZS5sb2dnZXIoXCJFUlJPUjogSW52YWxpZCBhY2Nlc3MgbW9kZSB1cGRhdGVcIiwgcHJlcy5zcmMsIHByZXMuZGFjcyk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2UgaWYgKGFjcy5tb2RlID09IEFjY2Vzc01vZGUuX05PTkUpIHtcbiAgICAgICAgICB0aGlzLl90aW5vZGUubG9nZ2VyKFwiV0FSTklORzogUmVtb3Zpbmcgbm9uLWV4aXN0ZW50IHN1YnNjcmlwdGlvblwiLCBwcmVzLnNyYywgcHJlcy5kYWNzKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gTmV3IHN1YnNjcmlwdGlvbi4gU2VuZCByZXF1ZXN0IGZvciB0aGUgZnVsbCBkZXNjcmlwdGlvbi5cbiAgICAgICAgICAvLyBVc2luZyAud2l0aE9uZVN1YiAobm90IC53aXRoTGF0ZXJPbmVTdWIpIHRvIG1ha2Ugc3VyZSBJZk1vZGlmaWVkU2luY2UgaXMgbm90IHNldC5cbiAgICAgICAgICB0aGlzLmdldE1ldGEodGhpcy5zdGFydE1ldGFRdWVyeSgpLndpdGhPbmVTdWIodW5kZWZpbmVkLCBwcmVzLnNyYykuYnVpbGQoKSk7XG4gICAgICAgICAgLy8gQ3JlYXRlIGEgZHVtbXkgZW50cnkgdG8gY2F0Y2ggb25saW5lIHN0YXR1cyB1cGRhdGUuXG4gICAgICAgICAgY29uc3QgZHVtbXkgPSB0aGlzLl90aW5vZGUuZ2V0VG9waWMocHJlcy5zcmMpO1xuICAgICAgICAgIGR1bW15LnRvcGljID0gcHJlcy5zcmM7XG4gICAgICAgICAgZHVtbXkub25saW5lID0gZmFsc2U7XG4gICAgICAgICAgZHVtbXkuYWNzID0gYWNzO1xuICAgICAgICAgIHRoaXMuX3Rpbm9kZS5fZGIudXBkVG9waWMoZHVtbXkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHByZXMud2hhdCA9PSAndGFncycpIHtcbiAgICAgICAgdGhpcy5nZXRNZXRhKHRoaXMuc3RhcnRNZXRhUXVlcnkoKS53aXRoVGFncygpLmJ1aWxkKCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9uUHJlcykge1xuICAgICAgdGhpcy5vblByZXMocHJlcyk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ29udGFjdCBpcyB1cGRhdGVkLCBleGVjdXRlIGNhbGxiYWNrcy5cbiAgX3JlZnJlc2hDb250YWN0KHdoYXQsIGNvbnQpIHtcbiAgICBpZiAodGhpcy5vbkNvbnRhY3RVcGRhdGUpIHtcbiAgICAgIHRoaXMub25Db250YWN0VXBkYXRlKHdoYXQsIGNvbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoaW5nIHRvIFRvcGljTWUgaXMgbm90IHN1cHBvcnRlZC4ge0BsaW5rIFRvcGljI3B1Ymxpc2h9IGlzIG92ZXJyaWRlbiBhbmQgdGhvd3MgYW4ge0Vycm9yfSBpZiBjYWxsZWQuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWNNZSNcbiAgICogQHRocm93cyB7RXJyb3J9IEFsd2F5cyB0aHJvd3MgYW4gZXJyb3IuXG4gICAqL1xuICBwdWJsaXNoKCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJQdWJsaXNoaW5nIHRvICdtZScgaXMgbm90IHN1cHBvcnRlZFwiKSk7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHZhbGlkYXRpb24gY3JlZGVudGlhbC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpY01lI1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWMgLSBOYW1lIG9mIHRoZSB0b3BpYyB0byBkZWxldGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXIgLSBVc2VyIElEIHRvIHJlbW92ZS5cbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2Ugd2hpY2ggd2lsbCBiZSByZXNvbHZlZC9yZWplY3RlZCBvbiByZWNlaXZpbmcgc2VydmVyIHJlcGx5LlxuICAgKi9cbiAgZGVsQ3JlZGVudGlhbChtZXRob2QsIHZhbHVlKSB7XG4gICAgaWYgKCF0aGlzLl9hdHRhY2hlZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkNhbm5vdCBkZWxldGUgY3JlZGVudGlhbCBpbiBpbmFjdGl2ZSAnbWUnIHRvcGljXCIpKTtcbiAgICB9XG4gICAgLy8gU2VuZCB7ZGVsfSBtZXNzYWdlLCByZXR1cm4gcHJvbWlzZVxuICAgIHJldHVybiB0aGlzLl90aW5vZGUuZGVsQ3JlZGVudGlhbChtZXRob2QsIHZhbHVlKS50aGVuKChjdHJsKSA9PiB7XG4gICAgICAvLyBSZW1vdmUgZGVsZXRlZCBjcmVkZW50aWFsIGZyb20gdGhlIGNhY2hlLlxuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9jcmVkZW50aWFscy5maW5kSW5kZXgoKGVsKSA9PiB7XG4gICAgICAgIHJldHVybiBlbC5tZXRoID09IG1ldGhvZCAmJiBlbC52YWwgPT0gdmFsdWU7XG4gICAgICB9KTtcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgIHRoaXMuX2NyZWRlbnRpYWxzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICB9XG4gICAgICAvLyBOb3RpZnkgbGlzdGVuZXJzXG4gICAgICBpZiAodGhpcy5vbkNyZWRzVXBkYXRlZCkge1xuICAgICAgICB0aGlzLm9uQ3JlZHNVcGRhdGVkKHRoaXMuX2NyZWRlbnRpYWxzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjdHJsO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBjYWxsYmFjayBjb250YWN0RmlsdGVyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250YWN0IHRvIGNoZWNrIGZvciBpbmNsdXNpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFufSA8Y29kZT50cnVlPC9jb2RlPiBpZiBjb250YWN0IHNob3VsZCBiZSBwcm9jZXNzZWQsIDxjb2RlPmZhbHNlPC9jb2RlPiB0byBleGNsdWRlIGl0LlxuICAgKi9cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBjYWNoZWQgY29udGFjdHMuXG4gICAqXG4gICAqIEBmdW5jdGlvblxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljTWUjXG4gICAqIEBwYXJhbSB7VG9waWNNZS5Db250YWN0Q2FsbGJhY2t9IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gY2FsbCBmb3IgZWFjaCBjb250YWN0LlxuICAgKiBAcGFyYW0ge2NvbnRhY3RGaWx0ZXI9fSBmaWx0ZXIgLSBPcHRpb25hbGx5IGZpbHRlciBjb250YWN0czsgaW5jbHVkZSBhbGwgaWYgZmlsdGVyIGlzIGZhbHNlLWlzaCwgb3RoZXJ3aXNlXG4gICAqICAgICAgaW5jbHVkZSB0aG9zZSBmb3Igd2hpY2ggZmlsdGVyIHJldHVybnMgdHJ1ZS1pc2guXG4gICAqIEBwYXJhbSB7T2JqZWN0PX0gY29udGV4dCAtIENvbnRleHQgdG8gdXNlIGZvciBjYWxsaW5nIHRoZSBgY2FsbGJhY2tgLCBpLmUuIHRoZSB2YWx1ZSBvZiBgdGhpc2AgaW5zaWRlIHRoZSBjYWxsYmFjay5cbiAgICovXG4gIGNvbnRhY3RzKGNhbGxiYWNrLCBmaWx0ZXIsIGNvbnRleHQpIHtcbiAgICB0aGlzLl90aW5vZGUubWFwVG9waWNzKChjLCBpZHgpID0+IHtcbiAgICAgIGlmIChjLmlzQ29tbVR5cGUoKSAmJiAoIWZpbHRlciB8fCBmaWx0ZXIoYykpKSB7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgYywgaWR4KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBjb250YWN0IGZyb20gY2FjaGUuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWNNZSNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSBjb250YWN0IHRvIGdldCwgZWl0aGVyIGEgVUlEIChmb3IgcDJwIHRvcGljcykgb3IgYSB0b3BpYyBuYW1lLlxuICAgKiBAcmV0dXJucyB7VGlub2RlLkNvbnRhY3R9IC0gQ29udGFjdCBvciBgdW5kZWZpbmVkYC5cbiAgICovXG4gIGdldENvbnRhY3QobmFtZSkge1xuICAgIHJldHVybiB0aGlzLl90aW5vZGUuY2FjaGVHZXRUb3BpYyhuYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWNjZXNzIG1vZGUgb2YgYSBnaXZlbiBjb250YWN0IGZyb20gY2FjaGUuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWNNZSNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSBjb250YWN0IHRvIGdldCBhY2Nlc3MgbW9kZSBmb3IsIGVpdGhlciBhIFVJRCAoZm9yIHAycCB0b3BpY3MpXG4gICAqICAgICAgICBvciBhIHRvcGljIG5hbWU7IGlmIG1pc3NpbmcsIGFjY2VzcyBtb2RlIGZvciB0aGUgJ21lJyB0b3BpYyBpdHNlbGYuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gYWNjZXNzIG1vZGUsIHN1Y2ggYXMgYFJXUGAuXG4gICAqL1xuICBnZXRBY2Nlc3NNb2RlKG5hbWUpIHtcbiAgICBpZiAobmFtZSkge1xuICAgICAgY29uc3QgY29udCA9IHRoaXMuX3Rpbm9kZS5jYWNoZUdldFRvcGljKG5hbWUpO1xuICAgICAgcmV0dXJuIGNvbnQgPyBjb250LmFjcyA6IG51bGw7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFjcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBjb250YWN0IGlzIGFyY2hpdmVkLCBpLmUuIGNvbnRhY3QucHJpdmF0ZS5hcmNoID09IHRydWUuXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWNNZSNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSBjb250YWN0IHRvIGNoZWNrIGFyY2hpdmVkIHN0YXR1cywgZWl0aGVyIGEgVUlEIChmb3IgcDJwIHRvcGljcykgb3IgYSB0b3BpYyBuYW1lLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0cnVlIGlmIGNvbnRhY3QgaXMgYXJjaGl2ZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIGlzQXJjaGl2ZWQobmFtZSkge1xuICAgIGNvbnN0IGNvbnQgPSB0aGlzLl90aW5vZGUuY2FjaGVHZXRUb3BpYyhuYW1lKTtcbiAgICByZXR1cm4gY29udCAmJiBjb250LnByaXZhdGUgJiYgISFjb250LnByaXZhdGUuYXJjaDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAdHlwZWRlZiBUaW5vZGUuQ3JlZGVudGlhbFxuICAgKiBAbWVtYmVyb2YgVGlub2RlXG4gICAqIEB0eXBlIE9iamVjdFxuICAgKiBAcHJvcGVydHkge3N0cmluZ30gbWV0aCAtIHZhbGlkYXRpb24gbWV0aG9kIHN1Y2ggYXMgJ2VtYWlsJyBvciAndGVsJy5cbiAgICogQHByb3BlcnR5IHtzdHJpbmd9IHZhbCAtIGNyZWRlbnRpYWwgdmFsdWUsIGkuZS4gJ2pkb2VAZXhhbXBsZS5jb20nIG9yICcrMTcwMjU1NTEyMzQnXG4gICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZG9uZSAtIHRydWUgaWYgY3JlZGVudGlhbCBpcyB2YWxpZGF0ZWQuXG4gICAqL1xuICAvKipcbiAgICogR2V0IHRoZSB1c2VyJ3MgY3JlZGVudGlhbHM6IGVtYWlsLCBwaG9uZSwgZXRjLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljTWUjXG4gICAqXG4gICAqIEByZXR1cm5zIHtUaW5vZGUuQ3JlZGVudGlhbFtdfSAtIGFycmF5IG9mIGNyZWRlbnRpYWxzLlxuICAgKi9cbiAgZ2V0Q3JlZGVudGlhbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NyZWRlbnRpYWxzO1xuICB9XG59XG5cbi8qKlxuICogQGNsYXNzIFRvcGljRm5kIC0gc3BlY2lhbCBjYXNlIG9mIHtAbGluayBUaW5vZGUuVG9waWN9IGZvciBzZWFyY2hpbmcgZm9yXG4gKiBjb250YWN0cyBhbmQgZ3JvdXAgdG9waWNzLlxuICogQGV4dGVuZHMgVGlub2RlLlRvcGljXG4gKiBAbWVtYmVyb2YgVGlub2RlXG4gKlxuICogQHBhcmFtIHtUb3BpY0ZuZC5DYWxsYmFja3N9IGNhbGxiYWNrcyAtIENhbGxiYWNrcyB0byByZWNlaXZlIHZhcmlvdXMgZXZlbnRzLlxuICovXG5leHBvcnQgY2xhc3MgVG9waWNGbmQgZXh0ZW5kcyBUb3BpYyB7XG4gIC8vIExpc3Qgb2YgdXNlcnMgYW5kIHRvcGljcyB1aWQgb3IgdG9waWNfbmFtZSAtPiBDb250YWN0IG9iamVjdClcbiAgX2NvbnRhY3RzID0ge307XG5cbiAgY29uc3RydWN0b3IoY2FsbGJhY2tzKSB7XG4gICAgc3VwZXIoQ29uc3QuVE9QSUNfRk5ELCBjYWxsYmFja3MpO1xuICB9XG5cbiAgLy8gT3ZlcnJpZGUgdGhlIG9yaWdpbmFsIFRvcGljLl9wcm9jZXNzTWV0YVN1YlxuICBfcHJvY2Vzc01ldGFTdWIoc3Vicykge1xuICAgIGxldCB1cGRhdGVDb3VudCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMuX2NvbnRhY3RzKS5sZW5ndGg7XG4gICAgLy8gUmVzZXQgY29udGFjdCBsaXN0LlxuICAgIHRoaXMuX2NvbnRhY3RzID0ge307XG4gICAgZm9yIChsZXQgaWR4IGluIHN1YnMpIHtcbiAgICAgIGxldCBzdWIgPSBzdWJzW2lkeF07XG4gICAgICBjb25zdCBpbmRleEJ5ID0gc3ViLnRvcGljID8gc3ViLnRvcGljIDogc3ViLnVzZXI7XG5cbiAgICAgIHN1YiA9IG1lcmdlVG9DYWNoZSh0aGlzLl9jb250YWN0cywgaW5kZXhCeSwgc3ViKTtcbiAgICAgIHVwZGF0ZUNvdW50Kys7XG5cbiAgICAgIGlmICh0aGlzLm9uTWV0YVN1Yikge1xuICAgICAgICB0aGlzLm9uTWV0YVN1YihzdWIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh1cGRhdGVDb3VudCA+IDAgJiYgdGhpcy5vblN1YnNVcGRhdGVkKSB7XG4gICAgICB0aGlzLm9uU3Vic1VwZGF0ZWQoT2JqZWN0LmtleXModGhpcy5fY29udGFjdHMpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHVibGlzaGluZyB0byBUb3BpY0ZuZCBpcyBub3Qgc3VwcG9ydGVkLiB7QGxpbmsgVG9waWMjcHVibGlzaH0gaXMgb3ZlcnJpZGVuIGFuZCB0aG93cyBhbiB7RXJyb3J9IGlmIGNhbGxlZC5cbiAgICogQG1lbWJlcm9mIFRpbm9kZS5Ub3BpY0ZuZCNcbiAgICogQHRocm93cyB7RXJyb3J9IEFsd2F5cyB0aHJvd3MgYW4gZXJyb3IuXG4gICAqL1xuICBwdWJsaXNoKCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJQdWJsaXNoaW5nIHRvICdmbmQnIGlzIG5vdCBzdXBwb3J0ZWRcIikpO1xuICB9XG5cbiAgLyoqXG4gICAqIHNldE1ldGEgdG8gVG9waWNGbmQgcmVzZXRzIGNvbnRhY3QgbGlzdCBpbiBhZGRpdGlvbiB0byBzZW5kaW5nIHRoZSBtZXNzYWdlLlxuICAgKiBAbWVtYmVyb2YgVGlub2RlLlRvcGljRm5kI1xuICAgKiBAcGFyYW0ge1Rpbm9kZS5TZXRQYXJhbXN9IHBhcmFtcyBwYXJhbWV0ZXJzIHRvIHVwZGF0ZS5cbiAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdG8gYmUgcmVzb2x2ZWQvcmVqZWN0ZWQgd2hlbiB0aGUgc2VydmVyIHJlc3BvbmRzIHRvIHJlcXVlc3QuXG4gICAqL1xuICBzZXRNZXRhKHBhcmFtcykge1xuICAgIHJldHVybiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVG9waWNGbmQucHJvdG90eXBlKS5zZXRNZXRhLmNhbGwodGhpcywgcGFyYW1zKS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLl9jb250YWN0cykubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLl9jb250YWN0cyA9IHt9O1xuICAgICAgICBpZiAodGhpcy5vblN1YnNVcGRhdGVkKSB7XG4gICAgICAgICAgdGhpcy5vblN1YnNVcGRhdGVkKFtdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBmb3VuZCBjb250YWN0cy4gSWYgY2FsbGJhY2sgaXMgdW5kZWZpbmVkLCB1c2Uge0BsaW5rIHRoaXMub25NZXRhU3VifS5cbiAgICogQGZ1bmN0aW9uXG4gICAqIEBtZW1iZXJvZiBUaW5vZGUuVG9waWNGbmQjXG4gICAqIEBwYXJhbSB7VG9waWNGbmQuQ29udGFjdENhbGxiYWNrfSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIGNhbGwgZm9yIGVhY2ggY29udGFjdC5cbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgLSBDb250ZXh0IHRvIHVzZSBmb3IgY2FsbGluZyB0aGUgYGNhbGxiYWNrYCwgaS5lLiB0aGUgdmFsdWUgb2YgYHRoaXNgIGluc2lkZSB0aGUgY2FsbGJhY2suXG4gICAqL1xuICBjb250YWN0cyhjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGNvbnN0IGNiID0gKGNhbGxiYWNrIHx8IHRoaXMub25NZXRhU3ViKTtcbiAgICBpZiAoY2IpIHtcbiAgICAgIGZvciAobGV0IGlkeCBpbiB0aGlzLl9jb250YWN0cykge1xuICAgICAgICBjYi5jYWxsKGNvbnRleHQsIHRoaXMuX2NvbnRhY3RzW2lkeF0sIGlkeCwgdGhpcy5fY29udGFjdHMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBAZmlsZSBVdGlsaXRpZXMgdXNlZCBpbiBtdWx0aXBsZSBwbGFjZXMuXG4gKlxuICogQGNvcHlyaWdodCAyMDE1LTIwMjIgVGlub2RlIExMQy5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgQWNjZXNzTW9kZSBmcm9tICcuL2FjY2Vzcy1tb2RlLmpzJztcbmltcG9ydCB7XG4gIERFTF9DSEFSXG59IGZyb20gJy4vY29uZmlnLmpzJztcblxuLy8gQXR0ZW1wdCB0byBjb252ZXJ0IGRhdGUgYW5kIEFjY2Vzc01vZGUgc3RyaW5ncyB0byBvYmplY3RzLlxuZXhwb3J0IGZ1bmN0aW9uIGpzb25QYXJzZUhlbHBlcihrZXksIHZhbCkge1xuICAvLyBUcnkgdG8gY29udmVydCBzdHJpbmcgdGltZXN0YW1wcyB3aXRoIG9wdGlvbmFsIG1pbGxpc2Vjb25kcyB0byBEYXRlLFxuICAvLyBlLmcuIDIwMTUtMDktMDJUMDE6NDU6NDNbLjEyM11aXG4gIGlmICh0eXBlb2YgdmFsID09ICdzdHJpbmcnICYmIHZhbC5sZW5ndGggPj0gMjAgJiYgdmFsLmxlbmd0aCA8PSAyNCAmJiBbJ3RzJywgJ3RvdWNoZWQnLCAndXBkYXRlZCcsICdjcmVhdGVkJywgJ3doZW4nLCAnZGVsZXRlZCcsICdleHBpcmVzJ10uaW5jbHVkZXMoa2V5KSkge1xuXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHZhbCk7XG4gICAgaWYgKCFpc05hTihkYXRlKSkge1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuICB9IGVsc2UgaWYgKGtleSA9PT0gJ2FjcycgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gbmV3IEFjY2Vzc01vZGUodmFsKTtcbiAgfVxuICByZXR1cm4gdmFsO1xufVxuXG4vLyBDaGVja3MgaWYgVVJMIGlzIGEgcmVsYXRpdmUgdXJsLCBpLmUuIGhhcyBubyAnc2NoZW1lOi8vJywgaW5jbHVkaW5nIHRoZSBjYXNlIG9mIG1pc3Npbmcgc2NoZW1lICcvLycuXG4vLyBUaGUgc2NoZW1lIGlzIGV4cGVjdGVkIHRvIGJlIFJGQy1jb21wbGlhbnQsIGUuZy4gW2Etel1bYS16MC05Ky4tXSpcbi8vIGV4YW1wbGUuaHRtbCAtIG9rXG4vLyBodHRwczpleGFtcGxlLmNvbSAtIG5vdCBvay5cbi8vIGh0dHA6L2V4YW1wbGUuY29tIC0gbm90IG9rLlxuLy8gJyDihrIgaHR0cHM6Ly9leGFtcGxlLmNvbScgLSBub3Qgb2suICjihrIgbWVhbnMgY2FycmlhZ2UgcmV0dXJuKVxuZXhwb3J0IGZ1bmN0aW9uIGlzVXJsUmVsYXRpdmUodXJsKSB7XG4gIHJldHVybiB1cmwgJiYgIS9eXFxzKihbYS16XVthLXowLTkrLi1dKjp8XFwvXFwvKS9pbS50ZXN0KHVybCk7XG59XG5cbmZ1bmN0aW9uIGlzVmFsaWREYXRlKGQpIHtcbiAgcmV0dXJuIChkIGluc3RhbmNlb2YgRGF0ZSkgJiYgIWlzTmFOKGQpICYmIChkLmdldFRpbWUoKSAhPSAwKTtcbn1cblxuLy8gUkZDMzMzOSBmb3JtYXRlciBvZiBEYXRlXG5leHBvcnQgZnVuY3Rpb24gcmZjMzMzOURhdGVTdHJpbmcoZCkge1xuICBpZiAoIWlzVmFsaWREYXRlKGQpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IHBhZCA9IGZ1bmN0aW9uKHZhbCwgc3ApIHtcbiAgICBzcCA9IHNwIHx8IDI7XG4gICAgcmV0dXJuICcwJy5yZXBlYXQoc3AgLSAoJycgKyB2YWwpLmxlbmd0aCkgKyB2YWw7XG4gIH07XG5cbiAgY29uc3QgbWlsbGlzID0gZC5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgcmV0dXJuIGQuZ2V0VVRDRnVsbFllYXIoKSArICctJyArIHBhZChkLmdldFVUQ01vbnRoKCkgKyAxKSArICctJyArIHBhZChkLmdldFVUQ0RhdGUoKSkgK1xuICAgICdUJyArIHBhZChkLmdldFVUQ0hvdXJzKCkpICsgJzonICsgcGFkKGQuZ2V0VVRDTWludXRlcygpKSArICc6JyArIHBhZChkLmdldFVUQ1NlY29uZHMoKSkgK1xuICAgIChtaWxsaXMgPyAnLicgKyBwYWQobWlsbGlzLCAzKSA6ICcnKSArICdaJztcbn1cblxuLy8gUmVjdXJzaXZlbHkgbWVyZ2Ugc3JjJ3Mgb3duIHByb3BlcnRpZXMgdG8gZHN0LlxuLy8gSWdub3JlIHByb3BlcnRpZXMgd2hlcmUgaWdub3JlW3Byb3BlcnR5XSBpcyB0cnVlLlxuLy8gQXJyYXkgYW5kIERhdGUgb2JqZWN0cyBhcmUgc2hhbGxvdy1jb3BpZWQuXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VPYmooZHN0LCBzcmMsIGlnbm9yZSkge1xuICBpZiAodHlwZW9mIHNyYyAhPSAnb2JqZWN0Jykge1xuICAgIGlmIChzcmMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGRzdDtcbiAgICB9XG4gICAgaWYgKHNyYyA9PT0gREVMX0NIQVIpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBzcmM7XG4gIH1cbiAgLy8gSlMgaXMgY3Jhenk6IHR5cGVvZiBudWxsIGlzICdvYmplY3QnLlxuICBpZiAoc3JjID09PSBudWxsKSB7XG4gICAgcmV0dXJuIHNyYztcbiAgfVxuXG4gIC8vIEhhbmRsZSBEYXRlXG4gIGlmIChzcmMgaW5zdGFuY2VvZiBEYXRlICYmICFpc05hTihzcmMpKSB7XG4gICAgcmV0dXJuICghZHN0IHx8ICEoZHN0IGluc3RhbmNlb2YgRGF0ZSkgfHwgaXNOYU4oZHN0KSB8fCBkc3QgPCBzcmMpID8gc3JjIDogZHN0O1xuICB9XG5cbiAgLy8gQWNjZXNzIG1vZGVcbiAgaWYgKHNyYyBpbnN0YW5jZW9mIEFjY2Vzc01vZGUpIHtcbiAgICByZXR1cm4gbmV3IEFjY2Vzc01vZGUoc3JjKTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBBcnJheVxuICBpZiAoc3JjIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICByZXR1cm4gc3JjO1xuICB9XG5cbiAgaWYgKCFkc3QgfHwgZHN0ID09PSBERUxfQ0hBUikge1xuICAgIGRzdCA9IHNyYy5jb25zdHJ1Y3RvcigpO1xuICB9XG5cbiAgZm9yIChsZXQgcHJvcCBpbiBzcmMpIHtcbiAgICBpZiAoc3JjLmhhc093blByb3BlcnR5KHByb3ApICYmICghaWdub3JlIHx8ICFpZ25vcmVbcHJvcF0pICYmIChwcm9wICE9ICdfbm9Gb3J3YXJkaW5nJykpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGRzdFtwcm9wXSA9IG1lcmdlT2JqKGRzdFtwcm9wXSwgc3JjW3Byb3BdKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAvLyBGSVhNRTogcHJvYmFibHkgbmVlZCB0byBsb2cgc29tZXRoaW5nIGhlcmUuXG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBkc3Q7XG59XG5cbi8vIFVwZGF0ZSBvYmplY3Qgc3RvcmVkIGluIGEgY2FjaGUuIFJldHVybnMgdXBkYXRlZCB2YWx1ZS5cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZVRvQ2FjaGUoY2FjaGUsIGtleSwgbmV3dmFsLCBpZ25vcmUpIHtcbiAgY2FjaGVba2V5XSA9IG1lcmdlT2JqKGNhY2hlW2tleV0sIG5ld3ZhbCwgaWdub3JlKTtcbiAgcmV0dXJuIGNhY2hlW2tleV07XG59XG5cbi8vIFN0cmlwcyBhbGwgdmFsdWVzIGZyb20gYW4gb2JqZWN0IG9mIHRoZXkgZXZhbHVhdGUgdG8gZmFsc2Ugb3IgaWYgdGhlaXIgbmFtZSBzdGFydHMgd2l0aCAnXycuXG4vLyBVc2VkIG9uIGFsbCBvdXRnb2luZyBvYmplY3QgYmVmb3JlIHNlcmlhbGl6YXRpb24gdG8gc3RyaW5nLlxuZXhwb3J0IGZ1bmN0aW9uIHNpbXBsaWZ5KG9iaikge1xuICBPYmplY3Qua2V5cyhvYmopLmZvckVhY2goKGtleSkgPT4ge1xuICAgIGlmIChrZXlbMF0gPT0gJ18nKSB7XG4gICAgICAvLyBTdHJpcCBmaWVsZHMgbGlrZSBcIm9iai5fa2V5XCIuXG4gICAgICBkZWxldGUgb2JqW2tleV07XG4gICAgfSBlbHNlIGlmICghb2JqW2tleV0pIHtcbiAgICAgIC8vIFN0cmlwIGZpZWxkcyB3aGljaCBldmFsdWF0ZSB0byBmYWxzZS5cbiAgICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkob2JqW2tleV0pICYmIG9ialtrZXldLmxlbmd0aCA9PSAwKSB7XG4gICAgICAvLyBTdHJpcCBlbXB0eSBhcnJheXMuXG4gICAgICBkZWxldGUgb2JqW2tleV07XG4gICAgfSBlbHNlIGlmICghb2JqW2tleV0pIHtcbiAgICAgIC8vIFN0cmlwIGZpZWxkcyB3aGljaCBldmFsdWF0ZSB0byBmYWxzZS5cbiAgICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICB9IGVsc2UgaWYgKG9ialtrZXldIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgLy8gU3RyaXAgaW52YWxpZCBvciB6ZXJvIGRhdGUuXG4gICAgICBpZiAoIWlzVmFsaWREYXRlKG9ialtrZXldKSkge1xuICAgICAgICBkZWxldGUgb2JqW2tleV07XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqW2tleV0gPT0gJ29iamVjdCcpIHtcbiAgICAgIHNpbXBsaWZ5KG9ialtrZXldKTtcbiAgICAgIC8vIFN0cmlwIGVtcHR5IG9iamVjdHMuXG4gICAgICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqW2tleV0pLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb2JqO1xufTtcblxuXG4vLyBUcmltIHdoaXRlc3BhY2UsIHN0cmlwIGVtcHR5IGFuZCBkdXBsaWNhdGUgZWxlbWVudHMgZWxlbWVudHMuXG4vLyBJZiB0aGUgcmVzdWx0IGlzIGFuIGVtcHR5IGFycmF5LCBhZGQgYSBzaW5nbGUgZWxlbWVudCBcIlxcdTI0MjFcIiAoVW5pY29kZSBEZWwgY2hhcmFjdGVyKS5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVBcnJheShhcnIpIHtcbiAgbGV0IG91dCA9IFtdO1xuICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSB7XG4gICAgLy8gVHJpbSwgdGhyb3cgYXdheSB2ZXJ5IHNob3J0IGFuZCBlbXB0eSB0YWdzLlxuICAgIGZvciAobGV0IGkgPSAwLCBsID0gYXJyLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgbGV0IHQgPSBhcnJbaV07XG4gICAgICBpZiAodCkge1xuICAgICAgICB0ID0gdC50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgaWYgKHQubGVuZ3RoID4gMSkge1xuICAgICAgICAgIG91dC5wdXNoKHQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIG91dC5zb3J0KCkuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0sIHBvcywgYXJ5KSB7XG4gICAgICByZXR1cm4gIXBvcyB8fCBpdGVtICE9IGFyeVtwb3MgLSAxXTtcbiAgICB9KTtcbiAgfVxuICBpZiAob3V0Lmxlbmd0aCA9PSAwKSB7XG4gICAgLy8gQWRkIHNpbmdsZSB0YWcgd2l0aCBhIFVuaWNvZGUgRGVsIGNoYXJhY3Rlciwgb3RoZXJ3aXNlIGFuIGFtcHR5IGFycmF5XG4gICAgLy8gaXMgYW1iaWd1b3MuIFRoZSBEZWwgdGFnIHdpbGwgYmUgc3RyaXBwZWQgYnkgdGhlIHNlcnZlci5cbiAgICBvdXQucHVzaChERUxfQ0hBUik7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cbiIsIm1vZHVsZS5leHBvcnRzPXtcInZlcnNpb25cIjogXCIwLjIwLjAtcmMyXCJ9XG4iXX0=
|